From a636f90240eb92c4ebd064093a1a76c1866284af Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Thu, 27 Dec 2018 22:09:03 +0100 Subject: [PATCH] wm: update hover after drag operation This patch improves the consistency of the hover handling after finishing a drag operation. Normally, the window manager hides pointer updates while the user is performing a drag operation with the mouse from the decorator. However, in the special case where a drag operation results in a window-layout change, the decorator's hover model may be affected. Hence, the window manager must supply the current pointer position when leaving the drag state. Issue #3097 --- .../gems/src/server/wm/decorator_nitpicker.h | 37 ++++++++++++++----- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/repos/gems/src/server/wm/decorator_nitpicker.h b/repos/gems/src/server/wm/decorator_nitpicker.h index 676d1cd4fb..9cb631c3a4 100644 --- a/repos/gems/src/server/wm/decorator_nitpicker.h +++ b/repos/gems/src/server/wm/decorator_nitpicker.h @@ -174,6 +174,8 @@ struct Wm::Decorator_nitpicker_session : Genode::Rpc_object, Command_buffer &_command_buffer = *_command_ds.local_addr(); + Point _pointer_position { }; + Reporter &_pointer_reporter; Last_motion &_last_motion; @@ -228,24 +230,41 @@ struct Wm::Decorator_nitpicker_session : Genode::Rpc_object, void _handle_input() { + auto report_pointer_position = [&] () { + Reporter::Xml_generator xml(_pointer_reporter, [&] () + { + xml.attribute("xpos", _pointer_position.x()); + xml.attribute("ypos", _pointer_position.y()); + }); + }; + while (_nitpicker_session.input()->pending()) _nitpicker_session.input()->for_each_event([&] (Input::Event const &ev) { - if (ev.press()) _key_cnt++; - if (ev.release()) _key_cnt--; + if (ev.press()) _key_cnt++; + + if (ev.release()) { + _key_cnt--; + + /* + * When returning from a drag operation to idle state, the + * pointer position may have moved to another window + * element. Propagate the least recent pointer position to + * the decorator to update its hover model. + */ + if (_key_cnt == 0) + report_pointer_position(); + } ev.handle_absolute_motion([&] (int x, int y) { _last_motion = LAST_MOTION_DECORATOR; + _pointer_position = Point(x, y); + /* update pointer model, but only when hovering */ - if (_key_cnt == 0) { - Reporter::Xml_generator xml(_pointer_reporter, [&] () - { - xml.attribute("xpos", x); - xml.attribute("ypos", y); - }); - } + if (_key_cnt == 0) + report_pointer_position(); }); if (ev.hover_leave()) {