mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-08 11:55:24 +00:00
wm: improve focus handling
This patch addresses the corner case where hovering changes while a button is held, e.g., when accidentially moving the pointer out of a application window's area during a drag-and-drop operation. The patch makes the window manager aware of the drag/idle state. Only when idle, the pointer position is propagated to the decorator now.
This commit is contained in:
parent
b748c4186d
commit
0b370671af
@ -178,6 +178,8 @@ struct Wm::Decorator_nitpicker_session : Genode::Rpc_object<Nitpicker::Session>,
|
||||
|
||||
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<Nitpicker::Session>,
|
||||
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()) {
|
||||
|
@ -453,6 +453,7 @@ class Wm::Nitpicker::Session_component : public Rpc_object<Nitpicker::Session>,
|
||||
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<Nitpicker::Session>,
|
||||
|
||||
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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user