diff --git a/repos/os/include/nitpicker_session/client.h b/repos/os/include/nitpicker_session/client.h index b66c74600..fd94a6a21 100644 --- a/repos/os/include/nitpicker_session/client.h +++ b/repos/os/include/nitpicker_session/client.h @@ -25,26 +25,29 @@ struct Nitpicker::Session_client : public Genode::Rpc_client explicit Session_client(Session_capability session) : Rpc_client(session) { } - Framebuffer::Session_capability framebuffer_session() { + Framebuffer::Session_capability framebuffer_session() override { return call(); } - Input::Session_capability input_session() { + Input::Session_capability input_session() override { return call(); } - View_capability create_view(View_capability parent = View_capability()) { + View_capability create_view(View_capability parent = View_capability()) override { return call(parent); } - void destroy_view(View_capability view) { + void destroy_view(View_capability view) override { call(view); } - int background(View_capability view) { + int background(View_capability view) override { return call(view); } - Framebuffer::Mode mode() { + Framebuffer::Mode mode() override { return call(); } - void buffer(Framebuffer::Mode mode, bool alpha) { + void buffer(Framebuffer::Mode mode, bool alpha) override { call(mode, alpha); } + + void focus(Nitpicker::Session_capability session) override { + call(session); } }; #endif /* _INCLUDE__NITPICKER_SESSION__CLIENT_H_ */ diff --git a/repos/os/include/nitpicker_session/nitpicker_session.h b/repos/os/include/nitpicker_session/nitpicker_session.h index 96be3a9b9..cde05aa4c 100644 --- a/repos/os/include/nitpicker_session/nitpicker_session.h +++ b/repos/os/include/nitpicker_session/nitpicker_session.h @@ -85,6 +85,20 @@ struct Nitpicker::Session : Genode::Session */ virtual void buffer(Framebuffer::Mode mode, bool use_alpha) = 0; + /** + * Set focused session + * + * Normally, the focused session is defined by the user by clicking on a + * view. The 'focus' function allows a client to set the focus without user + * action. However, the change of the focus is performed only is the + * currently focused session belongs to a child or the same process as the + * called session. This relationship is checked by comparing the session + * labels of the currently focused session and the caller. This way, a + * common parent can manage the focus among its child processes. But a + * session cannot steal the focus from an unrelated session. + */ + virtual void focus(Genode::Capability focused) = 0; + /** * Return number of bytes needed for virtual framebuffer of specified size */ @@ -108,12 +122,13 @@ struct Nitpicker::Session : Genode::Session GENODE_RPC(Rpc_destroy_view, void, destroy_view, View_capability); GENODE_RPC(Rpc_background, int, background, View_capability); GENODE_RPC(Rpc_mode, Framebuffer::Mode, mode); + GENODE_RPC(Rpc_focus, void, focus, Genode::Capability); GENODE_RPC_THROW(Rpc_buffer, void, buffer, GENODE_TYPE_LIST(Out_of_metadata), Framebuffer::Mode, bool); GENODE_RPC_INTERFACE(Rpc_framebuffer_session, Rpc_input_session, Rpc_create_view, Rpc_destroy_view, Rpc_background, - Rpc_mode, Rpc_buffer); + Rpc_mode, Rpc_buffer, Rpc_focus); }; #endif /* _INCLUDE__NITPICKER_SESSION__NITPICKER_SESSION_H_ */ diff --git a/repos/os/src/server/loader/nitpicker.h b/repos/os/src/server/loader/nitpicker.h index 6d9ad68b7..5cef2bd42 100644 --- a/repos/os/src/server/loader/nitpicker.h +++ b/repos/os/src/server/loader/nitpicker.h @@ -216,33 +216,33 @@ namespace Nitpicker { ** Nitpicker session interface ** *********************************/ - Framebuffer::Session_capability framebuffer_session() + Framebuffer::Session_capability framebuffer_session() override { return _nitpicker.framebuffer_session(); } - Input::Session_capability input_session() + Input::Session_capability input_session() override { return _proxy_input_cap; } - View_capability create_view(View_capability) + View_capability create_view(View_capability) override { return _proxy_view_cap; } - void destroy_view(View_capability view) + void destroy_view(View_capability view) override { _nitpicker.destroy_view(_nitpicker_view); } - int background(View_capability view) + int background(View_capability view) override { /* not forwarding to real nitpicker session */ return 0; } - Framebuffer::Mode mode() + Framebuffer::Mode mode() override { int mode_width = (_max_width > -1) ? _max_width : @@ -256,11 +256,13 @@ namespace Nitpicker { _nitpicker.mode().format()); } - void buffer(Framebuffer::Mode mode, bool use_alpha) + void buffer(Framebuffer::Mode mode, bool use_alpha) override { _nitpicker.buffer(mode, use_alpha); } + void focus(Capability) override { } + /********************************** ** Input::Transformer interface ** diff --git a/repos/os/src/server/nitpicker/chunky_menubar.h b/repos/os/src/server/nitpicker/chunky_menubar.h index 5c268f360..6fe234f75 100644 --- a/repos/os/src/server/nitpicker/chunky_menubar.h +++ b/repos/os/src/server/nitpicker/chunky_menubar.h @@ -100,9 +100,8 @@ class Chunky_menubar : public Texture, Color(r / 4, g / 4, b / 4)); /* draw label */ - draw_label(_canvas, view_rect.center(label_size(session_label.string(), - view_title.string())), session_label.string(), - WHITE, view_title.string(), session_color); + draw_label(_canvas, view_rect.center(label_size(session_label.string(), "")), + session_label.string(), WHITE, "", session_color); } using Menubar::state; diff --git a/repos/os/src/server/nitpicker/main.cc b/repos/os/src/server/nitpicker/main.cc index 5bd31eef0..8118bd108 100644 --- a/repos/os/src/server/nitpicker/main.cc +++ b/repos/os/src/server/nitpicker/main.cc @@ -456,6 +456,8 @@ class Nitpicker::Session_component : public Genode::Rpc_object, View_stack &_view_stack; + Mode &_mode; + List _view_list; /* capabilities for sub sessions */ @@ -487,6 +489,38 @@ class Nitpicker::Session_component : public Genode::Rpc_object, _buffer_size = 0; } + bool _focus_change_permitted() const + { + ::Session * const focused_session = _mode.focused_session(); + + /* + * If no session is focused, we allow any client to assign it. This + * is useful for programs such as an initial login window that + * should receive input events without prior manual selection via + * the mouse. + * + * In principle, a client could steal the focus during time between + * a currently focused session gets closed and before the user + * manually picks a new session. However, in practice, the focus + * policy during application startup and exit is managed by a + * window manager that sits between nitpicker and the application. + */ + if (!focused_session) + return true; + + /* + * Check if the currently focused session label belongs to a + * session subordinated to the caller, i.e., it originated from + * a child of the caller or from the same process. This is the + * case if the first part of the focused session label is + * identical to the caller's label. + */ + char const * const focused_label = focused_session->label().string(); + char const * const caller_label = label().string(); + + return strcmp(focused_label, caller_label, Genode::strlen(caller_label)) == 0; + } + public: /** @@ -494,6 +528,7 @@ class Nitpicker::Session_component : public Genode::Rpc_object, */ Session_component(Session_label const &label, View_stack &view_stack, + Mode &mode, Rpc_entrypoint &ep, Framebuffer::Session &framebuffer, int v_offset, @@ -506,7 +541,7 @@ class Nitpicker::Session_component : public Genode::Rpc_object, _buffer_alloc(&buffer_alloc, ram_quota), _framebuffer(framebuffer), _framebuffer_session_component(view_stack, *this, framebuffer, *this), - _ep(ep), _view_stack(view_stack), + _ep(ep), _view_stack(view_stack), _mode(mode), _framebuffer_session_cap(_ep.manage(&_framebuffer_session_component)), _input_session_cap(_ep.manage(&_input_session_component)), _provides_default_bg(provides_default_bg) @@ -560,13 +595,13 @@ class Nitpicker::Session_component : public Genode::Rpc_object, ** Nitpicker session interface ** *********************************/ - Framebuffer::Session_capability framebuffer_session() { + Framebuffer::Session_capability framebuffer_session() override { return _framebuffer_session_cap; } - Input::Session_capability input_session() { + Input::Session_capability input_session() override { return _input_session_cap; } - View_capability create_view(View_capability parent_cap) + View_capability create_view(View_capability parent_cap) override { /* lookup parent view */ View_component *parent_view = @@ -590,7 +625,7 @@ class Nitpicker::Session_component : public Genode::Rpc_object, return _ep.manage(view); } - void destroy_view(View_capability view_cap) + void destroy_view(View_capability view_cap) override { View_component *vc = dynamic_cast(_ep.lookup_and_lock(view_cap)); if (!vc) return; @@ -601,7 +636,7 @@ class Nitpicker::Session_component : public Genode::Rpc_object, destroy(env()->heap(), vc); } - int background(View_capability view_cap) + int background(View_capability view_cap) override { if (_provides_default_bg) { Object_pool::Guard vc(_ep.lookup_and_lock(view_cap)); @@ -623,7 +658,7 @@ class Nitpicker::Session_component : public Genode::Rpc_object, return 0; } - Framebuffer::Mode mode() + Framebuffer::Mode mode() override { unsigned const width = _framebuffer.mode().width(); unsigned const height = _framebuffer.mode().height() @@ -633,7 +668,7 @@ class Nitpicker::Session_component : public Genode::Rpc_object, _framebuffer.mode().format()); } - void buffer(Framebuffer::Mode mode, bool use_alpha) + void buffer(Framebuffer::Mode mode, bool use_alpha) override { /* check if the session quota suffices for the specified mode */ if (_buffer_alloc.quota() < ram_quota(mode, use_alpha)) @@ -642,6 +677,28 @@ class Nitpicker::Session_component : public Genode::Rpc_object, _framebuffer_session_component.notify_mode_change(mode, use_alpha); } + void focus(Genode::Capability session_cap) override + { + /* check permission by comparing session labels */ + if (!_focus_change_permitted()) { + PWRN("unauthorized focus change requesed by %s", label().string()); + return; + } + + /* prevent focus changes during drag operations */ + if (_mode.drag()) + return; + + /* lookup targeted session object */ + Session_component * const session = + session_cap.valid() ? dynamic_cast(_ep.lookup_and_lock(session_cap)) : 0; + + _mode.focused_session(session); + + if (session) + session->release(); + } + /******************************* ** Buffer_provider interface ** @@ -684,6 +741,7 @@ class Nitpicker::Root : public Genode::Root_component Global_keys &_global_keys; Framebuffer::Mode _scr_mode; View_stack &_view_stack; + Mode &_mode; Framebuffer::Session &_framebuffer; int _default_v_offset; @@ -712,7 +770,7 @@ class Nitpicker::Root : public Genode::Root_component bool const provides_default_bg = (strcmp(label.string(), "backdrop") == 0); Session_component *session = new (md_alloc()) - Session_component(Session_label(args), _view_stack, *ep(), + Session_component(Session_label(args), _view_stack, _mode, *ep(), _framebuffer, v_offset, provides_default_bg, stay_top, *md_alloc(), unused_quota); @@ -733,6 +791,7 @@ class Nitpicker::Root : public Genode::Root_component { _session_list.remove(session); _global_keys.apply_config(_session_list); + _mode.forget(*session); destroy(md_alloc(), session); } @@ -744,13 +803,13 @@ class Nitpicker::Root : public Genode::Root_component */ Root(Session_list &session_list, Global_keys &global_keys, Rpc_entrypoint &session_ep, View_stack &view_stack, - Allocator &md_alloc, + Mode &mode, Allocator &md_alloc, Framebuffer::Session &framebuffer, int default_v_offset) : Root_component(&session_ep, &md_alloc), _session_list(session_list), _global_keys(global_keys), - _view_stack(view_stack), + _view_stack(view_stack), _mode(mode), _framebuffer(framebuffer), _default_v_offset(default_v_offset) { } @@ -843,7 +902,8 @@ struct Nitpicker::Main Genode::Sliced_heap sliced_heap = { env()->ram_session(), env()->rm_session() }; Root np_root = { session_list, global_keys, ep.rpc_ep(), user_state, - sliced_heap, framebuffer, Framebuffer_screen::MENUBAR_HEIGHT }; + user_state, sliced_heap, framebuffer, + Framebuffer_screen::MENUBAR_HEIGHT }; Genode::Reporter pointer_reporter = { "pointer" }; @@ -874,7 +934,7 @@ struct Nitpicker::Main { // tmp_fb = &framebuffer; - fb_screen->menubar.state(Menubar_state(user_state, "", "", BLACK)); + fb_screen->menubar.state(Menubar_state(user_state, "", BLACK)); user_state.default_background(background); user_state.stack(mouse_cursor); diff --git a/repos/os/src/server/nitpicker/menubar.h b/repos/os/src/server/nitpicker/menubar.h index d60a4bb29..ff051100d 100644 --- a/repos/os/src/server/nitpicker/menubar.h +++ b/repos/os/src/server/nitpicker/menubar.h @@ -21,15 +21,12 @@ struct Menubar_state { Genode::String<128> session_label; - Genode::String<128> view_title; Mode mode; Color session_color; - Menubar_state(Mode mode, char const *session_label, - char const *view_title, Color session_color) + Menubar_state(Mode mode, char const *session_label, Color session_color) : - session_label(session_label), view_title(view_title), - mode(mode), session_color(session_color) + session_label(session_label), mode(mode), session_color(session_color) { } Menubar_state() : session_color(BLACK) { } diff --git a/repos/os/src/server/nitpicker/mode.h b/repos/os/src/server/nitpicker/mode.h index 4cb0e0a1b..c41c8b504 100644 --- a/repos/os/src/server/nitpicker/mode.h +++ b/repos/os/src/server/nitpicker/mode.h @@ -14,26 +14,26 @@ #ifndef _MODE_H_ #define _MODE_H_ -class View; -class Canvas_base; +class Session; class Mode { private: - bool _xray; - bool _kill; + bool _xray = false; + bool _kill = false; /* - * Last clicked view. This view is receiving keyboard input, except - * for global keys. + * Number of currently pressed keys. + * This counter is used to determine if the user + * is dragging an item. */ - View const *_focused_view; + unsigned _key_cnt = 0; + + Session *_focused_session = nullptr; public: - Mode(): _xray(false), _kill(false), _focused_view(0) { } - virtual ~Mode() { } /** @@ -42,20 +42,30 @@ class Mode bool xray() const { return _xray; } bool kill() const { return _kill; } bool flat() const { return !_xray && !_kill; } + bool drag() const { return _key_cnt > 0; } - void leave_kill() { _kill = false; } + void leave_kill() { _kill = false; } void toggle_kill() { _kill = !_kill; } void toggle_xray() { _xray = !_xray; } - View const *focused_view() const { return _focused_view; } + void inc_key_cnt() { _key_cnt++; } + void dec_key_cnt() { _key_cnt--; } - void focused_view(View const *view) { _focused_view = view; } + bool has_key_cnt(unsigned cnt) const { return cnt == _key_cnt; } + + Session *focused_session() { return _focused_session; } + + virtual void focused_session(Session *session) { _focused_session = session; } + + bool is_focused(Session const &session) const { return &session == _focused_session; } /** * Discard all references to specified view */ - virtual void forget(View const &v) { - if (&v == _focused_view) _focused_view = 0; } + virtual void forget(Session const &session) + { + if (is_focused(session)) _focused_session = nullptr; + } }; #endif diff --git a/repos/os/src/server/nitpicker/user_state.cc b/repos/os/src/server/nitpicker/user_state.cc index a23d2f31e..40a66885e 100644 --- a/repos/os/src/server/nitpicker/user_state.cc +++ b/repos/os/src/server/nitpicker/user_state.cc @@ -37,12 +37,24 @@ static inline bool _mouse_button(Keycode keycode) { User_state::User_state(Global_keys &global_keys, Area view_stack_size, Menubar &menubar) : - View_stack(view_stack_size, *this), _global_keys(global_keys), _key_cnt(0), - _menubar(menubar), _pointed_view(0), _input_receiver(0), - _global_key_sequence(false) + View_stack(view_stack_size, *this), _global_keys(global_keys), _menubar(menubar) { } +void User_state::_update_all() +{ + Menubar_state state(*this, "", BLACK); + + if (_input_receiver) + state = Menubar_state(*this, + _input_receiver->label().string(), + _input_receiver->color()); + + _menubar.state(state); + update_all_views(); +} + + void User_state::handle_event(Input::Event ev) { Input::Keycode const keycode = ev.keycode(); @@ -77,22 +89,22 @@ void User_state::handle_event(Input::Event ev) _mouse_pos = Point(ax, ay); /* count keys */ - if (type == Event::PRESS) _key_cnt++; - if (type == Event::RELEASE && _key_cnt > 0) _key_cnt--; + if (type == Event::PRESS) Mode::inc_key_cnt(); + if (type == Event::RELEASE && Mode::drag()) Mode::dec_key_cnt(); - View const * const pointed_view = find_view(_mouse_pos); + View const * const pointed_view = find_view(_mouse_pos); + Session * const pointed_session = pointed_view ? &pointed_view->session() : 0; /* * Deliver a leave event if pointed-to session changed */ - if (pointed_view && _pointed_view && - !pointed_view->same_session_as(*_pointed_view)) { + if (_pointed_session && (pointed_session != _pointed_session)) { Input::Event leave_ev(Input::Event::LEAVE, 0, ax, ay, 0, 0); - _pointed_view->session().submit_input_event(leave_ev); + _pointed_session->submit_input_event(leave_ev); } - _pointed_view = pointed_view; + _pointed_session = pointed_session; /** * Guard that, when 'enabled' is set to true, performs a whole-screen @@ -101,96 +113,63 @@ void User_state::handle_event(Input::Event ev) struct Update_all_guard { User_state &user_state; - bool update_menubar = false; - bool update_views = false; - char const *menu_title = ""; + bool update = false; Update_all_guard(User_state &user_state) : user_state(user_state) { } ~Update_all_guard() { - Menubar_state state(user_state, "", "", BLACK); - - if (user_state._input_receiver) - state = Menubar_state(user_state, - user_state._input_receiver->label().string(), - menu_title, - user_state._input_receiver->color()); - - if (update_menubar) - user_state._menubar.state(state); - - if (update_menubar || update_views) - user_state.update_all_views(); + if (update) + user_state._update_all(); } } update_all_guard(*this); /* * Handle start of a key sequence */ - if (type == Event::PRESS && _key_cnt == 1) { + if (type == Event::PRESS && Mode::has_key_cnt(1)) { /* * Detect mouse press event in kill mode, used to select the session * to lock out. */ if (kill() && keycode == Input::BTN_LEFT) { - if (pointed_view) - lock_out_session(pointed_view->session()); + if (_pointed_session) + lock_out_session(*_pointed_session); /* leave kill mode */ - update_all_guard.update_menubar = true; - update_all_guard.update_views = true; + update_all_guard.update = true; Mode::leave_kill(); return; } - /* update focused view */ - if (pointed_view != focused_view() && _mouse_button(keycode)) { + /* update focused session */ + if (pointed_session != Mode::focused_session() && _mouse_button(keycode)) { - bool const focus_stays_in_session = - focused_view() && pointed_view && - focused_view()->belongs_to(pointed_view->session()); + update_all_guard.update = true; /* - * Update the whole screen when the focus change results in - * changing the focus to another session. + * Notify both the old focused session and the new one. */ - if (flat() && !focus_stays_in_session) { - update_all_guard.update_menubar = true; - update_all_guard.update_views = true; + if (Mode::focused_session()) { + Input::Event unfocus_ev(Input::Event::FOCUS, 0, ax, ay, 0, 0); + Mode::focused_session()->submit_input_event(unfocus_ev); } - /* - * Notify both the old focussed session and the new one. - */ - if (!focus_stays_in_session) { - - if (focused_view()) { - Input::Event unfocus_ev(Input::Event::FOCUS, 0, ax, ay, 0, 0); - focused_view()->session().submit_input_event(unfocus_ev); - } - - if (pointed_view) { - Input::Event focus_ev(Input::Event::FOCUS, 1, ax, ay, 0, 0); - pointed_view->session().submit_input_event(focus_ev); - } + if (_pointed_session) { + Input::Event focus_ev(Input::Event::FOCUS, 1, ax, ay, 0, 0); + pointed_session->submit_input_event(focus_ev); } - update_all_guard.update_menubar = true; - - if (!flat() || !focused_view() || !pointed_view) - update_all_guard.update_views = true; - - focused_view(pointed_view); + focused_session(_pointed_session); } /* * If there exists a global rule for the pressed key, set the * corresponding session as receiver of the input stream until the key * count reaches zero. Otherwise, the input stream is directed to the - * pointed-at view. + * pointed-at session. * * If we deliver a global key sequence, we temporarily change the focus * to the global receiver. To reflect that change, we need to update @@ -198,20 +177,17 @@ void User_state::handle_event(Input::Event ev) */ Session * const global_receiver = _global_keys.global_receiver(keycode); if (global_receiver) { - _global_key_sequence = true; - _input_receiver = global_receiver; - update_all_guard.menu_title = ""; - update_all_guard.update_menubar = true; - update_all_guard.update_views = true; + _global_key_sequence = true; + _input_receiver = global_receiver; + update_all_guard.update = true; } /* * No global rule matched, so the input stream gets directed to the - * focused view or refers to a built-in operation. + * focused session or refers to a built-in operation. */ - if (!global_receiver && focused_view()) { - _input_receiver = &focused_view()->session(); - update_all_guard.menu_title = focused_view()->title(); + if (!global_receiver) { + _input_receiver = Mode::focused_session(); } /* @@ -220,13 +196,14 @@ void User_state::handle_event(Input::Event ev) */ if (_global_keys.is_operation_key(keycode)) { - if (_global_keys.is_kill_key(keycode)) Mode::toggle_kill(); + if (_global_keys.is_kill_key(keycode)) { + Mode::toggle_kill(); + _input_receiver = 0; + } + if (_global_keys.is_xray_key(keycode)) Mode::toggle_xray(); - update_all_guard.update_menubar = true; - update_all_guard.update_views = true; - - _input_receiver = 0; + update_all_guard.update = true; } } @@ -237,22 +214,22 @@ void User_state::handle_event(Input::Event ev) if (type == Event::MOTION || type == Event::WHEEL) { - if (_key_cnt == 0) { + if (Mode::has_key_cnt(0)) { /* - * In flat mode, we deliver motion events to the session of - * the pointed view. In xray mode, we deliver motion - * events only to the session with the focused view. + * In flat mode, we deliver motion events to the pointed-at + * session. In xray mode, we deliver motion events only to the + * focused session. */ - if (flat() || (xray() && focused_view() == pointed_view)) - if (pointed_view) - pointed_view->session().submit_input_event(ev); + if (flat() || (xray() && Mode::focused_session() == pointed_session)) + if (pointed_session) + pointed_session->submit_input_event(ev); } else if (_input_receiver) _input_receiver->submit_input_event(ev); } - /* deliver press/release event to session with focused view */ + /* deliver press/release event to focused session */ if (type == Event::PRESS || type == Event::RELEASE) if (_input_receiver) _input_receiver->submit_input_event(ev); @@ -260,13 +237,11 @@ void User_state::handle_event(Input::Event ev) /* * Detect end of global key sequence */ - if (ev.type() == Event::RELEASE && _key_cnt == 0 && _global_key_sequence) { + if (ev.type() == Event::RELEASE && Mode::has_key_cnt(0) && _global_key_sequence) { - _input_receiver = focused_view() ? &focused_view()->session() : 0; + _input_receiver = Mode::focused_session(); - update_all_guard.menu_title = focused_view() ? focused_view()->title() : ""; - update_all_guard.update_menubar = true; - update_all_guard.update_views = true; + update_all_guard.update = true; _global_key_sequence = false; } @@ -277,17 +252,23 @@ void User_state::handle_event(Input::Event ev) ** Mode interface ** ********************/ -void User_state::forget(View const &view) +void User_state::forget(Session const &session) { - if (focused_view() == &view) { - Mode::forget(view); - _menubar.state(Menubar_state(*this, "", "", BLACK)); - update_all_views(); - } - if (_input_receiver && view.belongs_to(*_input_receiver)) - _input_receiver = 0; + Mode::forget(session); - if (_pointed_view == &view) - _pointed_view = find_view(_mouse_pos); + if (_pointed_session == &session) { + View * const pointed_view = find_view(_mouse_pos); + _pointed_session = pointed_view ? &pointed_view->session() : nullptr; + } } + +void User_state::focused_session(Session *session) +{ + Mode::focused_session(session); + + if (!_global_key_sequence) + _input_receiver = session; + + _update_all(); +} diff --git a/repos/os/src/server/nitpicker/user_state.h b/repos/os/src/server/nitpicker/user_state.h index 4e6d00d5d..c9497b3bc 100644 --- a/repos/os/src/server/nitpicker/user_state.h +++ b/repos/os/src/server/nitpicker/user_state.h @@ -32,17 +32,10 @@ class User_state : public Mode, public View_stack */ Global_keys &_global_keys; - /* - * Number of currently pressed keys. - * This counter is used to determine if the user - * is dragging an item. - */ - unsigned _key_cnt; - /* * Menubar to display trusted labeling information * according to the current Mitpicker mode and the - * focused view. + * focused session. */ Menubar &_menubar; @@ -52,19 +45,21 @@ class User_state : public Mode, public View_stack Point _mouse_pos; /* - * Currently pointed-at view + * Currently pointed-at session */ - View const *_pointed_view; + Session *_pointed_session = nullptr; /* * Session that receives the current stream of input events */ - Session *_input_receiver; + Session *_input_receiver = nullptr; /* * True while a global key sequence is processed */ - bool _global_key_sequence; + bool _global_key_sequence = false; + + void _update_all(); public: @@ -89,7 +84,8 @@ class User_state : public Mode, public View_stack /** * Mode interface */ - void forget(View const &) override; + void forget(Session const &) override; + void focused_session(Session *) override; }; #endif diff --git a/repos/os/src/server/nitpicker/view.cc b/repos/os/src/server/nitpicker/view.cc index 59538daee..b07ddb89d 100644 --- a/repos/os/src/server/nitpicker/view.cc +++ b/repos/os/src/server/nitpicker/view.cc @@ -80,8 +80,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 view_is_focused = mode.focused_view() - && mode.focused_view()->belongs_to(_session); + bool const session_is_focused = mode.is_focused(_session); Color const frame_color = _session.color(); @@ -89,7 +88,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() && view_is_focused) + Texture_painter::Mode const op = mode.flat() || (mode.xray() && session_is_focused) ? Texture_painter::SOLID : Texture_painter::MIXED; Rect const view_rect = abs_geometry(); diff --git a/repos/os/src/server/nitpicker/view.h b/repos/os/src/server/nitpicker/view.h index 19522a5a4..d08f126d7 100644 --- a/repos/os/src/server/nitpicker/view.h +++ b/repos/os/src/server/nitpicker/view.h @@ -140,11 +140,7 @@ class View : public Same_buffer_list_elem, */ virtual int frame_size(Mode const &mode) const { - if (mode.focused_view() - && mode.focused_view()->belongs_to(_session)) - return 5; - - return 3; + return mode.is_focused(_session) ? 5 : 3; } /** diff --git a/repos/os/src/server/nitpicker/view_stack.cc b/repos/os/src/server/nitpicker/view_stack.cc index 39a6def48..8fd9c4268 100644 --- a/repos/os/src/server/nitpicker/view_stack.cc +++ b/repos/os/src/server/nitpicker/view_stack.cc @@ -40,11 +40,10 @@ static View const *last_stay_top_view(View const *view) template VIEW *View_stack::_next_view(VIEW &view) const { - Session * const active_session = _mode.focused_view() ? - &_mode.focused_view()->session() : 0; + Session * const focused_session = _mode.focused_session(); - View * const active_background = active_session ? - active_session->background() : 0; + View * const active_background = focused_session ? + focused_session->background() : 0; for (VIEW *next_view = &view; ;) { @@ -298,16 +297,5 @@ void View_stack::remove_view(View const &view, bool redraw) /* exclude view from view stack */ _views.remove(&view); - /* - * Reset focused and pointed-at view if necessary - * - * Thus must be done after calling '_views.remove' because the new focused - * pointer is determined by traversing the view stack. If the to-be-removed - * view would still be there, we would re-assign the old pointed-to view as - * the current one, resulting in a dangling pointer right after the view - * gets destructed by the caller of 'removed_view'. - */ - _mode.forget(view); - _dirty_rect.mark_as_dirty(rect); }