From 7ca56a62fd708d8c2ed11339cf62af6785f510b2 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Sun, 19 Nov 2017 20:11:50 +0100 Subject: [PATCH] nitpicker: report last clicked-on client The new report can be activated via the 'clicked' attribute of the '' configuration node. --- repos/os/src/server/nitpicker/README | 3 +++ repos/os/src/server/nitpicker/main.cc | 11 +++++++++++ repos/os/src/server/nitpicker/user_state.cc | 18 +++++++++++++++--- repos/os/src/server/nitpicker/user_state.h | 9 ++++++++- 4 files changed, 37 insertions(+), 4 deletions(-) diff --git a/repos/os/src/server/nitpicker/README b/repos/os/src/server/nitpicker/README index 6de5a5896..a55beff49 100644 --- a/repos/os/src/server/nitpicker/README +++ b/repos/os/src/server/nitpicker/README @@ -214,3 +214,6 @@ The 'focus' attribute enables the reporting of the currently focused session. The 'pointer' attribute enables the reporting of the current absolute pointer position. The 'keystate' attribute enables the reporting of the currently pressed keys. +The 'clicked' attribute enables the reporting of the last clicked-on unfocused +client. This report is useful for a focus-managing component to implement a +focus-on-click policy. diff --git a/repos/os/src/server/nitpicker/main.cc b/repos/os/src/server/nitpicker/main.cc index 7ca6be9de..dc4b93eac 100644 --- a/repos/os/src/server/nitpicker/main.cc +++ b/repos/os/src/server/nitpicker/main.cc @@ -266,6 +266,7 @@ struct Nitpicker::Main Reporter _hover_reporter = { _env, "hover" }; Reporter _focus_reporter = { _env, "focus" }; Reporter _keystate_reporter = { _env, "keystate" }; + Reporter _clicked_reporter = { _env, "clicked" }; Attached_rom_dataspace _config { _env, "config" }; @@ -368,6 +369,15 @@ void Nitpicker::Main::_handle_input() _user_state.report_keystate(xml); }); } + /* + * Report whenever a non-focused view owner received a click. This report + * can be consumed by a focus-managing component. + */ + if (_clicked_reporter.enabled() && result.last_clicked_changed) { + Reporter::Xml_generator xml(_clicked_reporter, [&] () { + _user_state.report_last_clicked_view_owner(xml); }); + } + if (result.focus_changed) _view_stack.update_all_views(); @@ -443,6 +453,7 @@ void Nitpicker::Main::_handle_config() configure_reporter(config, _hover_reporter); configure_reporter(config, _focus_reporter); configure_reporter(config, _keystate_reporter); + configure_reporter(config, _clicked_reporter); /* update domain registry and session policies */ for (Session_component *s = _session_list.first(); s; s = s->next()) diff --git a/repos/os/src/server/nitpicker/user_state.cc b/repos/os/src/server/nitpicker/user_state.cc index 5c0c85239..fc6aeffb3 100644 --- a/repos/os/src/server/nitpicker/user_state.cc +++ b/repos/os/src/server/nitpicker/user_state.cc @@ -173,10 +173,12 @@ void User_state::_handle_input_event(Input::Event ev) _hovered->submit_input_event(focus_ev); } - if (_hovered->has_transient_focusable_domain()) + if (_hovered->has_transient_focusable_domain()) { global_receiver = _hovered; - else + } else { _focus_view_owner_via_click(*_hovered); + _last_clicked = _hovered; + } } /* @@ -269,6 +271,7 @@ User_state::handle_input_events(Input::Event const * const ev_buf, View_owner * const old_hovered = _hovered; View_owner const * const old_focused = _focused; View_owner const * const old_input_receiver = _input_receiver; + View_owner const * const old_last_clicked = _last_clicked; bool user_active = false; @@ -336,7 +339,8 @@ User_state::handle_input_events(Input::Event const * const ev_buf, (_input_receiver != old_input_receiver), .key_state_affected = key_state_affected, .user_active = user_active, - .key_pressed = _key_pressed() + .key_pressed = _key_pressed(), + .last_clicked_changed = (_last_clicked != old_last_clicked) }; } @@ -372,12 +376,20 @@ void User_state::report_focused_view_owner(Xml_generator &xml, bool active) cons } +void User_state::report_last_clicked_view_owner(Xml_generator &xml) const +{ + if (_last_clicked) + _last_clicked->report(xml); +} + + void User_state::forget(View_owner const &owner) { _focus.forget(owner); if (&owner == _focused) _focused = nullptr; if (&owner == _next_focused) _next_focused = nullptr; + if (&owner == _last_clicked) _last_clicked = nullptr; if (_hovered == &owner) { View_component * const pointed_view = _view_stack.find_view(_pointer_pos); diff --git a/repos/os/src/server/nitpicker/user_state.h b/repos/os/src/server/nitpicker/user_state.h index 35979c538..9fa0e2442 100644 --- a/repos/os/src/server/nitpicker/user_state.h +++ b/repos/os/src/server/nitpicker/user_state.h @@ -72,10 +72,15 @@ class Nitpicker::User_state : public Focus_controller View_owner *_hovered = nullptr; /* - * Session that receives the current stream of input events + * View owner that receives the current stream of input events */ View_owner *_input_receiver = nullptr; + /** + * View owner that was last clicked-on by the user + */ + View_owner *_last_clicked = nullptr; + /** * Array for tracking the state of each key */ @@ -182,6 +187,7 @@ class Nitpicker::User_state : public Focus_controller bool const key_state_affected; bool const user_active; bool const key_pressed; + bool const last_clicked_changed; }; Handle_input_result handle_input_events(Input::Event const *ev_buf, @@ -196,6 +202,7 @@ class Nitpicker::User_state : public Focus_controller void report_pointer_position(Xml_generator &) const; void report_hovered_view_owner(Xml_generator &) const; void report_focused_view_owner(Xml_generator &, bool user_active) const; + void report_last_clicked_view_owner(Xml_generator &) const; Point pointer_pos() { return _pointer_pos; } };