diff --git a/repos/gems/src/server/wm/decorator_nitpicker.h b/repos/gems/src/server/wm/decorator_nitpicker.h index 5eb48e3560..34f7cc146e 100644 --- a/repos/gems/src/server/wm/decorator_nitpicker.h +++ b/repos/gems/src/server/wm/decorator_nitpicker.h @@ -178,6 +178,8 @@ struct Wm::Decorator_nitpicker_session : Genode::Rpc_object, Decorator_content_callback &_content_callback; + unsigned _key_cnt = 0; + /* XXX don't allocate content-registry entries from heap */ Decorator_content_registry _content_registry { _heap }; @@ -225,15 +227,21 @@ struct Wm::Decorator_nitpicker_session : Genode::Rpc_object, 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--; + ev.handle_absolute_motion([&] (int x, int y) { _last_motion = LAST_MOTION_DECORATOR; - Reporter::Xml_generator xml(_pointer_reporter, [&] () - { - xml.attribute("xpos", x); - xml.attribute("ypos", 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 (ev.hover_leave()) { diff --git a/repos/gems/src/server/wm/nitpicker.h b/repos/gems/src/server/wm/nitpicker.h index 8e1aedf40d..660bf47ba4 100644 --- a/repos/gems/src/server/wm/nitpicker.h +++ b/repos/gems/src/server/wm/nitpicker.h @@ -453,6 +453,7 @@ class Wm::Nitpicker::Session_component : public Rpc_object, bool _has_alpha = false; Point const _initial_pointer_pos { -1, -1 }; Point _pointer_pos = _initial_pointer_pos; + unsigned _key_cnt = 0; /* * Command buffer @@ -537,23 +538,37 @@ class Wm::Nitpicker::Session_component : public Rpc_object, Input::Event const ev = events[i]; - /* keep track of pointer position */ + if (ev.press()) _key_cnt++; + if (ev.release()) _key_cnt--; + + /* keep track of pointer position when hovering */ ev.handle_absolute_motion([&] (int x, int y) { _pointer_pos = Point(x, y); }); /* propagate layout-affecting events to the layouter */ - if (_click_into_unfocused_view(ev)) + if (_click_into_unfocused_view(ev) && _key_cnt == 1) _click_handler.handle_click(_pointer_pos); /* * Reset pointer model for the decorator once the pointer * enters the application area of a window. */ - if (ev.absolute_motion() && _first_motion) { + if (ev.absolute_motion() && _first_motion && _key_cnt == 0) { _click_handler.handle_enter(_pointer_pos); _first_motion = false; } + /* + * We may leave the dragged state on another window than + * the clicked one. During the dragging, the decorator + * remained unaware of pointer movements. Now, when leaving + * the drag stage, we need to make the decorator aware of + * the most recent pointer position to update the hover + * model. + */ + if (ev.release() && _key_cnt == 0) + _click_handler.handle_enter(_pointer_pos); + if (ev.hover_leave()) _first_motion = true;