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
This commit is contained in:
Norman Feske 2018-12-27 22:09:03 +01:00
parent 7c79bfc903
commit a636f90240

View File

@ -174,6 +174,8 @@ struct Wm::Decorator_nitpicker_session : Genode::Rpc_object<Nitpicker::Session>,
Command_buffer &_command_buffer = *_command_ds.local_addr<Command_buffer>();
Point _pointer_position { };
Reporter &_pointer_reporter;
Last_motion &_last_motion;
@ -228,24 +230,41 @@ struct Wm::Decorator_nitpicker_session : Genode::Rpc_object<Nitpicker::Session>,
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()) {