mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 05:37:54 +00:00
nitpicker: Domain configuration
This patch introduces the notion of a "domain" to the nitpicker configuration concept. Session policies always refer to a domain where multiple session policies can refer to the same domain. Thereby a domain provides a way to express the grouping of sessions. This is useful for applications that open multiple nitpicker sessions (such as Qt5 apps that use one nitpicker session per window, menu, etc.). We want to assign all those sessions to a single domain. The configuration looks as follows: <config> ... <domain name="default" color="#ffffff"/> <policy label="" domain="default"/> ... </config>
This commit is contained in:
parent
91e01411a4
commit
dbebfd624e
@ -119,6 +119,9 @@ append config {
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides><service name="Nitpicker"/></provides>
|
||||
<config>
|
||||
<domain name="default" color="#ffffff"/>
|
||||
<policy label="" domain="default"/>
|
||||
|
||||
<global-keys>
|
||||
<key name="KEY_SCROLLLOCK" operation="xray" />
|
||||
<key name="KEY_SYSRQ" operation="kill" />
|
||||
|
119
repos/os/src/server/nitpicker/domain_registry.h
Normal file
119
repos/os/src/server/nitpicker/domain_registry.h
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* \brief Domain registry
|
||||
* \author Norman Feske
|
||||
* \date 2014-06-12
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _DOMAIN_REGISTRY_
|
||||
#define _DOMAIN_REGISTRY_
|
||||
|
||||
#include <util/xml_node.h>
|
||||
#include <util/color.h>
|
||||
|
||||
class Domain_registry
|
||||
{
|
||||
public:
|
||||
|
||||
class Entry : public Genode::List<Entry>::Element
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Genode::String<64> Name;
|
||||
typedef Genode::Color Color;
|
||||
|
||||
private:
|
||||
|
||||
Name _name;
|
||||
Color _color;
|
||||
|
||||
friend class Domain_registry;
|
||||
|
||||
Entry(Name const &name, Color color)
|
||||
:
|
||||
_name(name), _color(color)
|
||||
{ }
|
||||
|
||||
public:
|
||||
|
||||
bool has_name(Name const &name) const { return name == _name; }
|
||||
|
||||
Color color() const { return _color; }
|
||||
};
|
||||
|
||||
void _insert(Genode::Xml_node domain)
|
||||
{
|
||||
char buf[sizeof(Entry::Name)];
|
||||
buf[0] = 0;
|
||||
bool name_defined = false;
|
||||
try {
|
||||
domain.attribute("name").value(buf, sizeof(buf));
|
||||
name_defined = true;
|
||||
} catch (...) { }
|
||||
|
||||
if (!name_defined) {
|
||||
PERR("no valid domain name specified");
|
||||
return;
|
||||
}
|
||||
|
||||
Entry::Name const name(buf);
|
||||
|
||||
if (lookup(name)) {
|
||||
PERR("domain name \"%s\" is not unique", name.string());
|
||||
return;
|
||||
}
|
||||
|
||||
Entry::Color const color = domain.attribute_value("color", Entry::Color());
|
||||
|
||||
_entries.insert(new (_alloc) Entry(name, color));
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
Genode::List<Entry> _entries;
|
||||
Genode::Allocator &_alloc;
|
||||
|
||||
public:
|
||||
|
||||
Domain_registry(Genode::Allocator &alloc, Genode::Xml_node config)
|
||||
:
|
||||
_alloc(alloc)
|
||||
{
|
||||
char const *type = "domain";
|
||||
|
||||
if (!config.has_sub_node(type))
|
||||
return;
|
||||
|
||||
Genode::Xml_node domain = config.sub_node(type);
|
||||
|
||||
for (;; domain = domain.next(type)) {
|
||||
|
||||
_insert(domain);
|
||||
|
||||
if (domain.is_last(type))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
~Domain_registry()
|
||||
{
|
||||
while (Entry *e = _entries.first())
|
||||
Genode::destroy(_alloc, e);
|
||||
}
|
||||
|
||||
Entry const *lookup(Entry::Name const &name) const
|
||||
{
|
||||
for (Entry const *e = _entries.first(); e; e = e->next())
|
||||
if (e->has_name(name))
|
||||
return e;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _DOMAIN_REGISTRY_ */
|
@ -39,6 +39,7 @@
|
||||
#include "clip_guard.h"
|
||||
#include "mouse_cursor.h"
|
||||
#include "chunky_menubar.h"
|
||||
#include "domain_registry.h"
|
||||
|
||||
namespace Input { class Session_component; }
|
||||
namespace Framebuffer { class Session_component; }
|
||||
@ -895,13 +896,14 @@ class Nitpicker::Root : public Genode::Root_component<Session_component>
|
||||
{
|
||||
private:
|
||||
|
||||
Session_list &_session_list;
|
||||
Global_keys &_global_keys;
|
||||
Framebuffer::Mode _scr_mode;
|
||||
View_stack &_view_stack;
|
||||
Mode &_mode;
|
||||
Framebuffer::Session &_framebuffer;
|
||||
int _default_v_offset;
|
||||
Session_list &_session_list;
|
||||
Domain_registry const &_domain_registry;
|
||||
Global_keys &_global_keys;
|
||||
Framebuffer::Mode _scr_mode;
|
||||
View_stack &_view_stack;
|
||||
Mode &_mode;
|
||||
Framebuffer::Session &_framebuffer;
|
||||
int _default_v_offset;
|
||||
|
||||
protected:
|
||||
|
||||
@ -933,7 +935,7 @@ class Nitpicker::Root : public Genode::Root_component<Session_component>
|
||||
_framebuffer, v_offset, provides_default_bg,
|
||||
stay_top, *md_alloc(), unused_quota);
|
||||
|
||||
session->apply_session_color();
|
||||
session->apply_session_policy(_domain_registry);
|
||||
_session_list.insert(session);
|
||||
_global_keys.apply_config(_session_list);
|
||||
|
||||
@ -962,17 +964,16 @@ class Nitpicker::Root : public Genode::Root_component<Session_component>
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Root(Session_list &session_list, Global_keys &global_keys,
|
||||
Rpc_entrypoint &session_ep, View_stack &view_stack,
|
||||
Mode &mode, Allocator &md_alloc,
|
||||
Framebuffer::Session &framebuffer,
|
||||
Root(Session_list &session_list,
|
||||
Domain_registry const &domain_registry, Global_keys &global_keys,
|
||||
Rpc_entrypoint &session_ep, View_stack &view_stack, Mode &mode,
|
||||
Allocator &md_alloc, Framebuffer::Session &framebuffer,
|
||||
int default_v_offset)
|
||||
:
|
||||
Root_component<Session_component>(&session_ep, &md_alloc),
|
||||
_session_list(session_list), _global_keys(global_keys),
|
||||
_view_stack(view_stack), _mode(mode),
|
||||
_framebuffer(framebuffer),
|
||||
_default_v_offset(default_v_offset)
|
||||
_session_list(session_list), _domain_registry(domain_registry),
|
||||
_global_keys(global_keys), _view_stack(view_stack), _mode(mode),
|
||||
_framebuffer(framebuffer), _default_v_offset(default_v_offset)
|
||||
{ }
|
||||
};
|
||||
|
||||
@ -1046,6 +1047,13 @@ struct Nitpicker::Main
|
||||
|
||||
Session_list session_list;
|
||||
|
||||
/*
|
||||
* Construct empty domain registry. The initial version will be replaced
|
||||
* on the first call of 'handle_config'.
|
||||
*/
|
||||
Genode::Volatile_object<Domain_registry> domain_registry {
|
||||
*env()->heap(), Genode::Xml_node("<config/>") };
|
||||
|
||||
User_state user_state = { global_keys, fb_screen->screen.size(), fb_screen->menubar };
|
||||
|
||||
/*
|
||||
@ -1062,9 +1070,9 @@ struct Nitpicker::Main
|
||||
*/
|
||||
Genode::Sliced_heap sliced_heap = { env()->ram_session(), env()->rm_session() };
|
||||
|
||||
Root<PT> np_root = { session_list, global_keys, ep.rpc_ep(), user_state,
|
||||
user_state, sliced_heap, framebuffer,
|
||||
Framebuffer_screen::MENUBAR_HEIGHT };
|
||||
Root<PT> np_root = { session_list, *domain_registry, global_keys,
|
||||
ep.rpc_ep(), user_state, user_state, sliced_heap,
|
||||
framebuffer, Framebuffer_screen::MENUBAR_HEIGHT };
|
||||
|
||||
Genode::Reporter pointer_reporter = { "pointer" };
|
||||
|
||||
@ -1196,9 +1204,16 @@ void Nitpicker::Main::handle_config(unsigned)
|
||||
.has_value("yes"));
|
||||
} catch (...) { }
|
||||
|
||||
/* update session policies */
|
||||
/* update domain registry and session policies */
|
||||
for (::Session *s = session_list.first(); s; s = s->next())
|
||||
s->apply_session_color();
|
||||
s->reset_domain();
|
||||
|
||||
try {
|
||||
domain_registry.construct(*env()->heap(), config()->xml_node()); }
|
||||
catch (...) { }
|
||||
|
||||
for (::Session *s = session_list.first(); s; s = s->next())
|
||||
s->apply_session_policy(*domain_registry);
|
||||
|
||||
/* redraw */
|
||||
user_state.update_all_views();
|
||||
|
@ -53,7 +53,8 @@ class Mode
|
||||
|
||||
bool has_key_cnt(unsigned cnt) const { return cnt == _key_cnt; }
|
||||
|
||||
Session *focused_session() { return _focused_session; }
|
||||
Session *focused_session() { return _focused_session; }
|
||||
Session const *focused_session() const { return _focused_session; }
|
||||
|
||||
virtual void focused_session(Session *session) { _focused_session = session; }
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
/* local includes */
|
||||
#include "color.h"
|
||||
#include "canvas.h"
|
||||
#include "domain_registry.h"
|
||||
|
||||
class View;
|
||||
class Session;
|
||||
@ -34,14 +35,14 @@ class Session : public Session_list::Element
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Session_label const _label;
|
||||
Color _color;
|
||||
Texture_base const *_texture = { 0 };
|
||||
bool _uses_alpha = { false };
|
||||
View *_background = 0;
|
||||
int _v_offset;
|
||||
unsigned char const *_input_mask = { 0 };
|
||||
bool const _stay_top;
|
||||
Genode::Session_label const _label;
|
||||
Domain_registry::Entry const *_domain;
|
||||
Texture_base const *_texture = { 0 };
|
||||
bool _uses_alpha = { false };
|
||||
View *_background = 0;
|
||||
int _v_offset;
|
||||
unsigned char const *_input_mask = { 0 };
|
||||
bool const _stay_top;
|
||||
|
||||
public:
|
||||
|
||||
@ -87,7 +88,7 @@ class Session : public Session_list::Element
|
||||
*/
|
||||
void input_mask(unsigned char const *mask) { _input_mask = mask; }
|
||||
|
||||
Color color() const { return _color; }
|
||||
Color color() const { return _domain ? _domain->color() : WHITE; }
|
||||
|
||||
View *background() const { return _background; }
|
||||
|
||||
@ -120,22 +121,51 @@ class Session : public Session_list::Element
|
||||
return _input_mask[p.y()*_texture->size().w() + p.x()];
|
||||
}
|
||||
|
||||
bool has_same_domain(Session const *s) const
|
||||
{
|
||||
return s && (s->_domain == _domain);
|
||||
}
|
||||
|
||||
bool has_valid_domain() const
|
||||
{
|
||||
return _domain;
|
||||
}
|
||||
|
||||
void reset_domain()
|
||||
{
|
||||
_domain = nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set session color according to the list of configured policies
|
||||
* Set session domain according to the list of configured policies
|
||||
*
|
||||
* Select the policy that matches the label. If multiple policies
|
||||
* match, select the one with the largest number of characters.
|
||||
*/
|
||||
void apply_session_color()
|
||||
void apply_session_policy(Domain_registry const &domain_registry)
|
||||
{
|
||||
/* use white by default */
|
||||
_color = WHITE;
|
||||
reset_domain();
|
||||
|
||||
try {
|
||||
Genode::Session_policy policy(_label);
|
||||
|
||||
/* read color attribute */
|
||||
policy.attribute("color").value(&_color);
|
||||
/* read domain attribute */
|
||||
if (!policy.has_attribute("domain")) {
|
||||
PERR("policy for label \"%s\" lacks domain declaration",
|
||||
_label.string());
|
||||
return;
|
||||
}
|
||||
|
||||
typedef Domain_registry::Entry::Name Domain_name;
|
||||
char buf[sizeof(Domain_name)];
|
||||
buf[0] = 0;
|
||||
try {
|
||||
policy.attribute("domain").value(buf, sizeof(buf)); }
|
||||
catch (...) { }
|
||||
|
||||
Domain_name name(buf);
|
||||
_domain = domain_registry.lookup(name);
|
||||
|
||||
} catch (...) { }
|
||||
}
|
||||
};
|
||||
|
@ -79,8 +79,7 @@ void View::frame(Canvas_base &canvas, Mode const &mode) const
|
||||
|
||||
void View::draw(Canvas_base &canvas, Mode const &mode) const
|
||||
{
|
||||
/* is this the currently focused view? */
|
||||
bool const session_is_focused = mode.is_focused(_session);
|
||||
bool const is_focused = _session.has_same_domain(mode.focused_session());
|
||||
|
||||
Color const frame_color = _session.color();
|
||||
|
||||
@ -88,7 +87,7 @@ void View::draw(Canvas_base &canvas, Mode const &mode) const
|
||||
* Use dimming in x-ray and kill mode, but do not dim the focused view in
|
||||
* x-ray mode.
|
||||
*/
|
||||
Texture_painter::Mode const op = mode.flat() || (mode.xray() && session_is_focused)
|
||||
Texture_painter::Mode const op = mode.flat() || (mode.xray() && is_focused)
|
||||
? Texture_painter::SOLID : Texture_painter::MIXED;
|
||||
|
||||
Rect const view_rect = abs_geometry();
|
||||
|
Loading…
Reference in New Issue
Block a user