Window manager test for tiled-console scenario

This commit is contained in:
Christian Helmuth 2018-09-26 16:44:46 +02:00 committed by Norman Feske
parent 21a61cd583
commit 745ee04583
28 changed files with 1312 additions and 0 deletions

View File

@ -0,0 +1,18 @@
MIRROR_FROM_REP_DIR := src/test/tiled_wm
content: $(MIRROR_FROM_REP_DIR) LICENSE
$(MIRROR_FROM_REP_DIR):
$(mirror_from_rep_dir)
MIRROR_FROM_LIBPORTS := src/app/qt5/tmpl/target_defaults.inc \
src/app/qt5/tmpl/target_final.inc
content: $(MIRROR_FROM_LIBPORTS)
$(MIRROR_FROM_LIBPORTS):
mkdir -p $(dir $@)
cp -r $(GENODE_DIR)/repos/libports/$@ $(dir $@)
LICENSE:
cp $(GENODE_DIR)/LICENSE $@

View File

@ -0,0 +1 @@
2018-10-02 0741bbe9067957b8884dfc14708e0dbcce6f5285

View File

@ -0,0 +1,13 @@
base
libc
os
qoost
qt5_core
qt5_gui
qt5_qjpeg
qt5_qpa_nitpicker
qt5_widgets
report_session
stdcxx
timer_session
vfs

248
repos/gems/run/tiled_wm.run Normal file
View File

@ -0,0 +1,248 @@
source ${genode_dir}/repos/libports/run/qt5_common.inc
import_from_depot [depot_user]/src/qt5_component \
[depot_user]/src/qt5_printsupport \
[depot_user]/src/qt5_textedit \
[depot_user]/src/qt5_widgets \
[depot_user]/src/dynamic_rom \
[depot_user]/src/test-tiled_wm
if {[have_spec odroid_xu]} {
puts "Run script does not support this platform."
exit 0
}
#
# Generate config
#
proc qt5_layouter_config { } {
return { <config rules="rom"> <report rules="no"/> </config>}
}
proc qt5_decorator_binary { } { return "themed_decorator" }
proc qt5_decorator_config { } {
return {
<config>
<vfs>
<dir name="theme">
<inline name="metadata">
<theme>
<aura top="0" bottom="0" left="0" right="0"/>
<decor top="0" bottom="0" left="0" right="0"/>
</theme>
</inline>
</dir>
</vfs>
<libc/>
</config>}
}
append config {
<config>
<parent-provides>} [qt5_parent_provides feature] {
</parent-provides>
<default caps="100"/>
<default-route>
<any-service> <parent/> <any-child/> </any-service>
</default-route>} [qt5_start_nodes feature] {
<start name="test_reports">
<binary name="report_rom"/>
<resource name="RAM" quantum="1M"/>
<provides> <service name="Report"/> <service name="ROM"/> </provides>
<config verbose="no">
<policy label="test-tiled_wm-panel -> apps" report="test-tiled_wm-manager -> apps"/>
<policy label="test-tiled_wm-panel -> overlay" report="test-tiled_wm-manager -> overlay"/>
<policy label="test-tiled_wm-manager -> content_request" report="test-tiled_wm-panel -> content_request"/>
<policy label="test-tiled_wm-manager -> overlay_request" report="test-tiled_wm-panel -> overlay_request"/>
</config>
</start>
<start name="wifi_reports">
<binary name="dynamic_rom"/>
<resource name="RAM" quantum="4M"/>
<provides> <service name="ROM"/> </provides>
<config verbose="no">
<rom name="accesspoints">
<inline>
<accesspoints>
<accesspoint ssid="skynet" bssid="00:01:02:03:04:05" quality="40"/>
<accesspoint ssid="foobar" bssid="01:02:03:04:05:06" quality="70" protection="WPA2"/>
<accesspoint ssid="foobar" bssid="01:02:03:04:05:07" quality="10" protection="WPA2"/>
</accesspoints>
</inline>
<sleep milliseconds="60000" />
<inline>
<accesspoints>
</accesspoints>
</inline>
<sleep milliseconds="60000" />
</rom>
<rom name="state">
<inline>
<state>
<accesspoint ssid="foobar" bssid="01:02:03:04:05:06" quality="70" freq="2418" state="disconnected"/>
</state>
</inline>
<sleep milliseconds="60000" />
<inline>
<state>
<accesspoint ssid="foobar" bssid="01:02:03:04:05:06" quality="70" freq="2418" state="connecting"/>
</state>
</inline>
<sleep milliseconds="60000" />
</rom>
</config>
</start>
<start name="test-tiled_wm-manager" caps="120">
<resource name="RAM" quantum="8M"/>
<route>
<service name="ROM" label="content_request"> <child name="test_reports" /> </service>
<service name="ROM" label="overlay_request"> <child name="test_reports" /> </service>
<service name="Report" label="layout_rules"> <child name="wm_report_rom" label="layout_rules"/> </service>
<service name="Report"> <child name="test_reports"/> </service>
<any-service> <parent /> <any-child/> </any-service>
</route>
</start>
<start name="test-tiled_wm-panel" caps="250">
<resource name="RAM" quantum="32M"/>
<config>
<libc stdout="/dev/log" stderr="/dev/log" rtc="/dev/rtc"/>
<vfs>
<dir name="dev">
<log/>
<inline name="rtc">2018-01-01 00:01</inline>
</dir>
<dir name="fs"> <ram/> </dir>
<tar name="qt5_dejavusans.tar"/>
</vfs>
</config>
<route>
<service name="Nitpicker"> <child name="wm"/> </service>
<service name="Report" label="shape">
<child name="pointer" label="wm -> test-tiled_wm-panel -> shape"/>
</service>
<service name="ROM" label="egl_drv.lib.so"> <parent label="egl_swrast.lib.so" /> </service>
<service name="ROM" label="apps"> <child name="test_reports" /> </service>
<service name="ROM" label="overlay"> <child name="test_reports" /> </service>
<service name="Report"> <child name="test_reports"/> </service>
<any-service> <parent /> <any-child/> </any-service>
</route>
</start>
<start name="test-tiled_wm-overlay" caps="250">
<resource name="RAM" quantum="32M"/>
<config>
<libc stdout="/dev/log" stderr="/dev/log" rtc="/dev/rtc"/>
<vfs>
<dir name="dev">
<log/>
<inline name="rtc">2018-01-01 00:01</inline>
</dir>
<dir name="fs"> <ram/> </dir>
<tar name="qt5_dejavusans.tar"/>
</vfs>
</config>
<route>
<service name="Nitpicker"> <child name="wm"/> </service>
<service name="Report" label="shape">
<child name="pointer" label="wm -> test-tiled_wm-overlay -> shape"/>
</service>
<service name="ROM" label="egl_drv.lib.so"> <parent label="egl_swrast.lib.so" /> </service>
<any-service> <parent /> <any-child/> </any-service>
</route>
</start>
<start name="test-tiled_wm-app-1" caps="250">
<binary name="test-tiled_wm-app"/>
<resource name="RAM" quantum="32M"/>
<config name="app1">
<libc stdout="/dev/log" stderr="/dev/log" rtc="/dev/rtc"/>
<vfs>
<dir name="dev">
<log/>
<inline name="rtc">2018-01-01 00:01</inline>
</dir>
<dir name="fs"> <ram/> </dir>
<tar name="qt5_dejavusans.tar"/>
</vfs>
</config>
<route>
<service name="Nitpicker"> <child name="wm"/> </service>
<service name="Report" label="shape">
<child name="pointer" label="wm -> test-tiled_wm-app-1 -> shape"/>
</service>
<service name="ROM" label="egl_drv.lib.so"> <parent label="egl_swrast.lib.so" /> </service>
<any-service> <parent /> <any-child/> </any-service>
</route>
</start>
<start name="test-tiled_wm-app-2" caps="250">
<binary name="test-tiled_wm-app"/>
<resource name="RAM" quantum="32M"/>
<config name="app2">
<libc stdout="/dev/log" stderr="/dev/log" rtc="/dev/rtc"/>
<vfs>
<dir name="dev">
<log/>
<inline name="rtc">2018-01-01 00:01</inline>
</dir>
<dir name="fs"> <ram/> </dir>
<tar name="qt5_dejavusans.tar"/>
</vfs>
</config>
<route>
<service name="Nitpicker"> <child name="wm"/> </service>
<service name="Report" label="shape">
<child name="pointer" label="wm -> test-tiled_wm-app-2 -> shape"/>
</service>
<service name="ROM" label="egl_drv.lib.so"> <parent label="egl_swrast.lib.so" /> </service>
<any-service> <parent /> <any-child/> </any-service>
</route>
</start>
<start name="textedit" caps="250">
<resource name="RAM" quantum="70M"/>
<config>
<libc stdout="/dev/log" stderr="/dev/log" rtc="/dev/rtc"/>
<vfs>
<dir name="dev">
<log/>
<inline name="rtc">2018-01-01 00:01</inline>
</dir>
<dir name="fs"> <ram/> </dir>
<tar name="qt5_dejavusans.tar"/>
</vfs>
</config>
<route>
<service name="Nitpicker"> <child name="wm"/> </service>
<service name="Report" label="shape">
<child name="pointer" label="wm -> textedit -> shape"/>
</service>
<service name="ROM" label="egl_drv.lib.so"> <parent label="egl_swrast.lib.so" /> </service>
<any-service> <parent /> <any-child/> </any-service>
</route>
</start>
</config>
}
install_config $config
append build_components [qt5_build_components feature]
# for debugging only
#append build_components { app/window_layouter app/themed_decorator }
build $build_components
append boot_modules [qt5_boot_modules feature]
# for debugging only
#append boot_modules { window_layouter themed_decorator }
build_boot_image $boot_modules
append qemu_args " -usbdevice tablet "
run_genode_until forever
# vi: set ft=tcl :

View File

@ -0,0 +1,45 @@
/*
* \brief Tiled-WM test: example application widget
* \author Christian Helmuth
* \date 2018-09-28
*/
/*
* Copyright (C) 2018 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
/* Qt includes */
#include <QApplication>
#include <QDesktopWidget>
/* local includes */
#include "app.h"
App::App(QString name)
{
_name->setText("This is <b>" + name + "</b> an example application for the tiled-WM test.");
_entry->setPlaceholderText("Placeholder text");
_layout->addWidget(new Spacer(), 1);
_layout->addWidget(_name);
_layout->addWidget(new Spacer(), 1);
_layout->addWidget(_entry);
_layout->addWidget(new Spacer(), 1);
for (int i = 0; i < 3; ++i) {
QLabel *l = new QLabel(QString("QLabel No." + QString::number(i)));
l->setToolTip(QString::number(i) + " is just a number.");
_layout->addWidget(l);
}
_layout->addWidget(new Spacer(), 1);
}
App::~App()
{
}

View File

@ -0,0 +1,46 @@
/*
* \brief TIled-WM test: example application widget
* \author Christian Helmuth
* \date 2018-09-28
*/
/*
* Copyright (C) 2018 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _TEST__TILED_WM__APP__APP_H_
#define _TEST__TILED_WM__APP__APP_H_
/* Qt includes */
#include <QVBoxLayout>
#include <QLabel>
#include <QWidget>
#include <QLineEdit>
/* Qoost includes */
#include <qoost/compound_widget.h>
#include <qoost/qmember.h>
/* local includes */
#include <util.h>
class App : public Compound_widget<QWidget, QVBoxLayout>
{
Q_OBJECT
private:
QMember<QLabel> _name;
QMember<QLineEdit> _entry;
public:
App(QString name);
~App();
};
#endif /* _TEST__TILED_WM__APP__APP_H_ */

View File

@ -0,0 +1,6 @@
TEMPLATE = app
TARGET = test-tiled_wm-app
QT = core gui widgets
SOURCES += main.cpp app.cpp
HEADERS += app.h ../util.h
RESOURCES = app.qrc

View File

@ -0,0 +1,8 @@
<!DOCTYPE RCC>
<RCC version="1.0">
<qresource prefix="/">
<file>../style.qss</file>
</qresource>
</RCC>
<!-- vi: set ft=xml : -->

View File

@ -0,0 +1,55 @@
/*
* \brief Tiled-WM test: example application
* \author Christian Helmuth
* \date 2018-09-26
*/
/*
* Copyright (C) 2018 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
/* Genode includes */
#include <base/attached_rom_dataspace.h>
/* local includes */
#include <util.h>
#include "app.h"
struct Main
{
Libc::Env &env;
Genode::Attached_rom_dataspace config { env, "config" };
QApplication &app { qt5_initialization(env) };
QMember<App> widget { name_from_config() };
QString name_from_config()
{
Name name = config.xml().attribute_value("name", Name("no name"));
return QString(name.string());
}
Main(Libc::Env &env) : env(env)
{
widget->show();
}
};
void Libc::Component::construct(Libc::Env &env)
{
Libc::with_libc([&] {
static Main main { env };
exit(main.app.exec());
});
}

View File

@ -0,0 +1 @@
include $(PRG_DIR)/../target.inc

View File

@ -0,0 +1,211 @@
/*
* \brief Tiled-WM test: GUI manager
* \author Christian Helmuth
* \date 2018-09-26
*
* GUI manager implements the user-visible display state machine.
*/
/*
* Copyright (C) 2018 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
/* Genode includes */
#include <base/component.h>
#include <util/string.h>
#include <base/log.h>
#include <base/attached_rom_dataspace.h>
#include <os/reporter.h>
typedef Genode::String<32> Name;
namespace Test { struct Manager; }
struct Test::Manager
{
Genode::Env &env;
Genode::Attached_rom_dataspace content_request_rom { env, "content_request" };
Genode::Attached_rom_dataspace overlay_request_rom { env, "overlay_request" };
Genode::Signal_handler<Manager> content_request_handler {
env.ep(), *this, &Manager::handle_content_request };
Genode::Signal_handler<Manager> overlay_request_handler {
env.ep(), *this, &Manager::handle_overlay_request };
Genode::Reporter apps_report { env, "apps" };
Genode::Reporter overlay_report { env, "overlay" };
Genode::Reporter layout_rules_report { env, "rules", "layout_rules" };
struct App {
char const *label;
char const *name;
bool visible;
} apps[3] {
{ "test-tiled_wm-app-1", "app1", true },
{ "test-tiled_wm-app-2", "app2", false },
{ "textedit", "textedit", false }
};
bool overlay_visible { false };
void report_apps();
void report_overlay();
void report_layout_rules();
void handle_content_request();
void handle_overlay_request();
Manager(Genode::Env &env);
};
void Test::Manager::handle_content_request()
{
content_request_rom.update();
Name requested_app =
content_request_rom.xml().attribute_value("name", Name());
if (!requested_app.valid()) return;
App *found = nullptr;
for (App &app : apps) {
if (requested_app != app.name) continue;
found = &app;
break;
}
if (!found || found->visible) return;
for (App &app : apps) {
if (&app == found) {
app.visible = true;
} else {
app.visible = false;
}
}
report_apps();
report_layout_rules();
}
void Test::Manager::handle_overlay_request()
{
overlay_request_rom.update();
bool const request_visible =
overlay_request_rom.xml().attribute_value("visible", false);
if (request_visible == overlay_visible) return;
overlay_visible = request_visible;
report_overlay();
report_layout_rules();
}
void Test::Manager::report_apps()
{
Genode::Reporter::Xml_generator xml(apps_report, [&] () {
for (App &app : apps) {
xml.node("app", [&] () {
xml.attribute("name", app.name);
xml.attribute("visible", app.visible);
});
}
});
}
void Test::Manager::report_overlay()
{
Genode::Reporter::Xml_generator xml(overlay_report, [&] () {
xml.attribute("visible", overlay_visible);
});
}
void Test::Manager::report_layout_rules()
{
Genode::Reporter::Xml_generator xml(layout_rules_report, [&] () {
xml.node("screen", [&] () {
xml.node("column", [&] () {
xml.attribute("name", "screen");
xml.attribute("layer", "1");
xml.node("row", [&] () {
xml.attribute("name", "content");
xml.attribute("layer", "4");
xml.node("column", [&] () {
xml.attribute("weight", "2");
});
xml.node("column", [&] () {
xml.attribute("name", "overlay");
xml.attribute("layer", "3");
xml.attribute("weight", "1");
});
});
xml.node("row", [&] () {
xml.attribute("name", "panel");
xml.attribute("layer", "2");
xml.attribute("height", "24");
});
});
});
xml.node("assign", [&] () {
xml.attribute("label_prefix", "test-tiled_wm-panel");
xml.attribute("target", "panel");
});
if (overlay_visible) {
xml.node("assign", [&] () {
xml.attribute("label_prefix", "test-tiled_wm-overlay");
xml.attribute("target", "overlay");
});
}
/* debug */
if (false) {
xml.node("assign", [&] () {
xml.attribute("label_prefix", "");
xml.attribute("target", "screen");
xml.attribute("xpos", "any");
xml.attribute("ypos", "any");
});
}
for (App &app : apps) {
if (!app.visible) continue;
xml.node("assign", [&] () {
xml.attribute("label_prefix", app.label);
xml.attribute("target", "content");
});
break;
}
});
}
Test::Manager::Manager(Genode::Env &env) : env(env)
{
apps_report.enabled(true);
overlay_report.enabled(true);
layout_rules_report.enabled(true);
content_request_rom.sigh(content_request_handler);
overlay_request_rom.sigh(overlay_request_handler);
report_apps();
report_overlay();
report_layout_rules();
}
void Component::construct(Genode::Env &env) { static Test::Manager manager(env); }

View File

@ -0,0 +1,3 @@
TARGET = test-tiled_wm-manager
SRC_CC = main.cc
LIBS = base

View File

@ -0,0 +1,43 @@
/*
* \brief Tiled-WM test: example overlay
* \author Christian Helmuth
* \date 2018-09-28
*/
/*
* Copyright (C) 2018 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
/* local includes */
#include <util.h>
#include "overlay.h"
struct Main
{
Libc::Env &env;
QApplication &app { qt5_initialization(env) };
QMember<Overlay> widget { };
Main(Libc::Env &env) : env(env)
{
widget->show();
}
};
void Libc::Component::construct(Libc::Env &env)
{
Libc::with_libc([&] {
static Main main { env };
exit(main.app.exec());
});
}

View File

@ -0,0 +1,37 @@
/*
* \brief Tiled-WM test: overlay widget
* \author Christian Helmuth
* \date 2018-09-28
*/
/*
* Copyright (C) 2018 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
/* Qt includes */
#include <QApplication>
#include <QDesktopWidget>
/* local includes */
#include "overlay.h"
Overlay::Overlay()
{
_label->setText("WiFi overlay");
_entry->setEchoMode(QLineEdit::Password);
_layout->addWidget(new Spacer(), 1);
_layout->addWidget(_label);
_layout->addWidget(new Spacer(), 1);
_layout->addWidget(_entry);
_layout->addWidget(new Spacer(), 1);
}
Overlay::~Overlay()
{
}

View File

@ -0,0 +1,46 @@
/*
* \brief Tiled-WM test: overlay widget
* \author Christian Helmuth
* \date 2018-09-28
*/
/*
* Copyright (C) 2018 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _TEST__TILED_WM__OVERLAY__OVERLAY_H_
#define _TEST__TILED_WM__OVERLAY__OVERLAY_H_
/* Qt includes */
#include <QHBoxLayout>
#include <QLabel>
#include <QWidget>
#include <QLineEdit>
/* Qoost includes */
#include <qoost/compound_widget.h>
#include <qoost/qmember.h>
/* local includes */
#include <util.h>
class Overlay : public Compound_widget<QWidget, QHBoxLayout>
{
Q_OBJECT
private:
QMember<QLabel> _label;
QMember<QLineEdit> _entry;
public:
Overlay();
~Overlay();
};
#endif /* _TEST__TILED_WM__OVERLAY__OVERLAY_H_ */

View File

@ -0,0 +1,6 @@
TEMPLATE = app
TARGET = test-tiled_wm-overlay
QT = core gui widgets
SOURCES += main.cpp overlay.cpp
HEADERS += overlay.h ../util.h
RESOURCES = overlay.qrc

View File

@ -0,0 +1,8 @@
<!DOCTYPE RCC>
<RCC version="1.0">
<qresource prefix="/">
<file>../style.qss</file>
</qresource>
</RCC>
<!-- vi: set ft=xml : -->

View File

@ -0,0 +1 @@
include $(PRG_DIR)/../target.inc

View File

@ -0,0 +1,45 @@
/*
* \brief Tiled-WM test: panel
* \author Christian Helmuth
* \date 2018-09-26
*
* Panel is a Qt5-based example panel at the bottom of the screen.
*/
/*
* Copyright (C) 2018 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
/* local includes */
#include "panel.h"
struct Main
{
Libc::Env &env;
Genode_signal_dispatcher dispatcher { env };
QApplication &app { qt5_initialization(env) };
QMember<Panel> widget { env, dispatcher.signal_receiver() };
Main(Libc::Env &env) : env(env)
{
widget->show();
}
};
void Libc::Component::construct(Libc::Env &env)
{
Libc::with_libc([&] {
static Main main { env };
exit(main.app.exec());
});
}

View File

@ -0,0 +1,144 @@
/*
* \brief Tiled-WM test: panel widget
* \author Christian Helmuth
* \date 2018-09-28
*/
/*
* Copyright (C) 2018 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
/* Qt includes */
#include <QApplication>
#include <QDesktopWidget>
/* local includes */
#include "panel.h"
void Panel_button::_clicked() { Q_EMIT clicked(text()); }
void Panel_button::_toggled(bool checked) { Q_EMIT toggled(checked, text()); }
Panel_button::Panel_button(QString label)
{
if (!label.isNull()) {
setText(label);
}
setCheckable(true);
setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
_layout->addWidget(_icon, 0, Qt::AlignCenter);
connect(this, SIGNAL(clicked()), SLOT(_clicked()));
connect(this, SIGNAL(toggled(bool)), SLOT(_toggled(bool)));
}
Panel_button::~Panel_button() { }
void App_bar::_app_button(QAbstractButton *b, bool checked)
{
if (!checked) return;
if (Panel_button *button = qobject_cast<Panel_button *>(b)) {
Name name { button->text().toUtf8().constData() };
Genode::Reporter::Xml_generator xml(_content_request, [&] () {
xml.attribute("name", name);
});
}
}
void App_bar::_handle_apps()
{
/* empty bar before adding current apps */
while (QLayoutItem *item = _layout->takeAt(0)) {
if (Panel_button *button = qobject_cast<Panel_button *>(item->widget())) {
_button_group->removeButton(button);
button->deleteLater();
}
delete item;
}
_apps.update();
Panel_button *visible_app_button = nullptr;
_apps.xml().for_each_sub_node("app", [&] (Genode::Xml_node node) {
QString const name { node.attribute_value("name", Name("no name")).string() };
bool const visible { node.attribute_value("visible", false) };
Panel_button *button { new Panel_button(name) };
if (visible) visible_app_button = button;
_button_group->addButton(button);
_layout->addWidget(button);
});
if (visible_app_button) visible_app_button->setChecked(true);
}
App_bar::App_bar(Genode::Env &env, Genode::Signal_receiver &sig_rec)
:
_apps(env, "apps"), _content_request(env, "content_request"),
_apps_proxy(sig_rec)
{
_content_request.enabled(true);
_button_group->setExclusive(true);
_handle_apps();
_apps.sigh(*_apps_proxy);
connect(_apps_proxy, SIGNAL(signal()), SLOT(_handle_apps()));
connect(_button_group, SIGNAL(buttonToggled(QAbstractButton *, bool)),
SLOT(_app_button(QAbstractButton *, bool)));
}
App_bar::~App_bar() { }
void Panel::_wifi_toggled(bool checked)
{
Genode::Reporter::Xml_generator xml(_overlay_request, [&] () {
xml.attribute("visible", checked);
});
}
Panel::Panel(Genode::Env &env, Genode::Signal_receiver &sig_rec)
:
_overlay(env, "overlay"), _overlay_request(env, "overlay_request"),
_panel_button("Panel"), _app_bar(env, sig_rec)
{
_layout->addWidget(_panel_button);
_layout->addWidget(new Spacer(), 1);
_layout->addWidget(_app_bar);
_layout->addWidget(new Spacer(), 1);
_layout->addWidget(_wifi_button);
_panel_button->setCheckable(false);
_panel_button->setToolTip("This panel is just an example.");
_wifi_button->setObjectName("wifi");
_wifi_button->setToolTip("Open WiFi overlay");
_overlay_request.enabled(true);
_wifi_toggled(_wifi_button->isChecked());
connect(_wifi_button, SIGNAL(toggled(bool)), SLOT(_wifi_toggled(bool)));
}
Panel::~Panel() { }

View File

@ -0,0 +1,109 @@
/*
* \brief Tiled-WM test: panel widget
* \author Christian Helmuth
* \date 2018-09-27
*/
/*
* Copyright (C) 2018 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _TEST__TILED_WM__PANEL__PANEL_H_
#define _TEST__TILED_WM__PANEL__PANEL_H_
/* Qt includes */
#include <QHBoxLayout>
#include <QPushButton>
#include <QWidget>
#include <QButtonGroup>
/* Qoost includes */
#include <qoost/compound_widget.h>
#include <qoost/qmember.h>
/* Genode includes */
#include <base/attached_rom_dataspace.h>
#include <os/reporter.h>
/* local includes */
#include <util.h>
#include <icon.h> /* build-dir copy of qoost/icon.h works around missing "vtable for Icon" */
class Panel_button : public Compound_widget<QPushButton, QHBoxLayout>
{
Q_OBJECT
private:
QMember<Icon> _icon;
private Q_SLOTS:
void _clicked();
void _toggled(bool);
public:
Panel_button(QString label = QString());
~Panel_button();
Q_SIGNALS:
void clicked(QString label);
void toggled(bool checked, QString label);
};
class App_bar : public Compound_widget<QWidget, QHBoxLayout>
{
Q_OBJECT
private:
Genode::Attached_rom_dataspace _apps;
Genode::Reporter _content_request;
QMember<QButtonGroup> _button_group;
QMember<Genode_signal_proxy> _apps_proxy;
private Q_SLOTS:
void _handle_apps();
void _app_button(QAbstractButton *, bool);
public:
App_bar(Genode::Env &, Genode::Signal_receiver &);
~App_bar();
};
class Panel : public Compound_widget<QWidget, QHBoxLayout>
{
Q_OBJECT
private:
Genode::Attached_rom_dataspace _overlay;
Genode::Reporter _overlay_request;
QMember<Panel_button> _panel_button;
QMember<App_bar> _app_bar;
QMember<Panel_button> _wifi_button;
private Q_SLOTS:
void _wifi_toggled(bool);
public:
Panel(Genode::Env &, Genode::Signal_receiver &);
~Panel();
};
#endif /* _TEST__TILED_WM__PANEL__PANEL_H_ */

View File

@ -0,0 +1,6 @@
TEMPLATE = app
TARGET = test-tiled_wm-panel
QT = core gui widgets
SOURCES += main.cpp panel.cpp
HEADERS += panel.h icon.h ../util.h
RESOURCES = panel.qrc

View File

@ -0,0 +1,9 @@
<!DOCTYPE RCC>
<RCC version="1.0">
<qresource prefix="/">
<file>../style.qss</file>
<file>wifi.png</file>
</qresource>
</RCC>
<!-- vi: set ft=xml : -->

View File

@ -0,0 +1,3 @@
include $(PRG_DIR)/../target.inc
panel.o main.o: icon.h

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@ -0,0 +1,22 @@
Panel, Overlay, App { min-width: 100px; min-height: 100px; }
QFrame { padding: 5px; }
QLabel { color: white; }
/*QPushButton { border: none; outline: none; }*/
Panel {
background-color: rgb(51, 93, 128);
}
Panel_button Icon { qproperty-iconSize: 18px; }
Panel_button#wifi Icon { qproperty-iconFile: url(:/wifi.png); }
Overlay {
background-color: rgba(25, 69, 105, 100);
}
App {
background-color: rgb(96, 130, 159);
}
/* vi: set ft=css : */

View File

@ -0,0 +1,25 @@
include $(call select_from_repositories,src/app/qt5/tmpl/target_defaults.inc)
include $(call select_from_repositories,src/app/qt5/tmpl/target_final.inc)
CC_CXX_WARN_STRICT =
INC_DIR += $(PRG_DIR)/..
LIBS += qoost
#
# We need Qt headers in a local directory for MOC to work correctly
#
# icon.h from the qoost API package
ICON_H = $(call select_from_repositories,include/qoost/icon.h)
# fall-back to the qoost port directory if that fails
ifeq ($(ICON_H),)
ICON_H = $(call select_from_ports,qoost)/include/qoost/icon.h
endif
icon.h: $(ICON_H)
$(VERBOSE)cp $(ICON_H) .

View File

@ -0,0 +1,153 @@
/*
* \brief Tiled-WM test: utilities
* \author Christian Helmuth
* \date 2018-09-26
*/
/*
* Copyright (C) 2018 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _TEST__TILED_WM__UTIL_H_
#define _TEST__TILED_WM__UTIL_H_
/* Genode includes */
#include <base/signal.h>
#include <base/thread.h>
#include <base/log.h>
#include <util/string.h>
/* Qt includes */
#include <QApplication>
#include <QObject>
#include <QFile>
#include <QDebug>
#include <QFrame>
/* Qoost includes */
#include <qoost/qmember.h>
/* Libc includes */
#include <libc/component.h>
typedef Genode::String<32> Name;
/*
* Genode signal to queued Qt signal proxy
*/
class Genode_signal_proxy : public QObject,
public Genode::Signal_dispatcher<Genode_signal_proxy>
{
Q_OBJECT
public:
Genode_signal_proxy(Genode::Signal_receiver &sig_rec)
:
Genode::Signal_dispatcher<Genode_signal_proxy>(
sig_rec, *this, &Genode_signal_proxy::handle_genode_signal)
{
connect(this, SIGNAL(internal_signal()),
this, SIGNAL(signal()),
Qt::QueuedConnection);
}
/* called by signal dispatcher / emits internal signal in context of
* signal-dispatcher thread */
void handle_genode_signal(unsigned = 0) { Q_EMIT internal_signal(); }
Q_SIGNALS:
/* internal_signal() is Qt::QueuedConnection to signal() */
void internal_signal();
/* finally signal() is emitted in the context of the Qt main thread */
void signal();
};
/*
* Genode signal dispatcher thread
*/
class Genode_signal_dispatcher : public Genode::Thread
{
private:
Genode::Signal_receiver _sig_rec;
void entry()
{
/* dispatch signals */
while (true) {
Genode::Signal sig = _sig_rec.wait_for_signal();
Genode::Signal_dispatcher_base *dispatcher {
dynamic_cast<Genode::Signal_dispatcher_base *>(sig.context()) };
if (dispatcher)
dispatcher->dispatch(sig.num());
}
}
public:
Genode_signal_dispatcher(Genode::Env &env)
:
Genode::Thread(env, "signal_dispatcher", 0x4000)
{
start();
}
Genode::Signal_receiver &signal_receiver() { return _sig_rec; }
};
/*
* Qt initialization
*/
extern void initialize_qt_core(Genode::Env &);
extern void initialize_qt_gui(Genode::Env &);
static inline QApplication & qt5_initialization(Libc::Env &env)
{
initialize_qt_core(env);
initialize_qt_gui(env);
char const *argv[] = { "qt5_app", 0 };
int argc = sizeof(argv)/sizeof(*argv);
static QApplication app(argc, (char**)argv);
QFile file(":style.qss");
if (!file.open(QFile::ReadOnly)) {
qWarning() << "Warning:" << file.errorString()
<< "opening file" << file.fileName();
} else {
qApp->setStyleSheet(QLatin1String(file.readAll()));
}
app.connect(&app, SIGNAL(lastWindowClosed()), SLOT(quit()));
return app;
}
/*
* Widget utilities
*/
struct Spacer : QFrame
{
Q_OBJECT public:
Spacer(QString const &style_id = "") { setObjectName(style_id); }
~Spacer() { }
};
#endif /* _TEST__TILED_WM__UTIL_H_ */