mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-24 15:56:41 +00:00
nitpicker: fix interplay of hover with dragging
This patch extends the notion of having only one uniquely hovered client in the presence of held keys. If motion occurs once a key is pressed (e.g., while dragging), the receiver of the key sequence observes the motion events. In this case, we have to submit an artificial leave event to the originally hovered client so that no more than one client observes itself as being hovered at the same time. Once the key sequence is finished, the hovering is updated again, eventually presenting a motion event to the originally hovered client and a leave event to the receiver of the key sequence. Issue #4176
This commit is contained in:
parent
1088035f8e
commit
ee463b21ae
@ -105,11 +105,9 @@ void User_state::_handle_input_event(Input::Event ev)
|
||||
ev.handle_absolute_motion([&] (int x, int y) {
|
||||
_pointer_pos = Point(x, y); });
|
||||
|
||||
bool const drag = _key_cnt > 0;
|
||||
|
||||
/* count keys */
|
||||
if (ev.press()) _key_cnt++;
|
||||
if (ev.release() && drag) _key_cnt--;
|
||||
if (ev.press()) _key_cnt++;
|
||||
if (ev.release() && (_key_cnt > 0)) _key_cnt--;
|
||||
|
||||
/* track key states */
|
||||
ev.handle_press([&] (Keycode key, Codepoint) {
|
||||
@ -124,9 +122,25 @@ void User_state::_handle_input_event(Input::Event ev)
|
||||
_key_array.pressed(key, false);
|
||||
});
|
||||
|
||||
if (ev.absolute_motion() || ev.relative_motion())
|
||||
if (ev.absolute_motion() || ev.relative_motion()) {
|
||||
update_hover();
|
||||
|
||||
if (_key_cnt > 0) {
|
||||
_drag = true;
|
||||
|
||||
/*
|
||||
* Submit leave event to the originally hovered client if motion
|
||||
* occurs while a key is held. Otherwise, both the hovered client
|
||||
* and the receiver of the key sequence would observe a motion
|
||||
* event last, each appearing as being hovered at the same time.
|
||||
*/
|
||||
if (_hovered && (_input_receiver != _hovered)) {
|
||||
_hovered->submit_input_event(Hover_leave());
|
||||
_hovered = nullptr; /* updated when _key_cnt reaches 0 */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle start of a key sequence
|
||||
*/
|
||||
@ -252,11 +266,21 @@ void User_state::_handle_input_event(Input::Event ev)
|
||||
_input_receiver->submit_input_event(ev);
|
||||
|
||||
/*
|
||||
* Detect end of global key sequence
|
||||
* Detect end of key sequence
|
||||
*/
|
||||
if (ev.release() && (_key_cnt == 0) && _global_key_sequence) {
|
||||
_input_receiver = _focused;
|
||||
_global_key_sequence = false;
|
||||
if (ev.release() && (_key_cnt == 0)) {
|
||||
|
||||
update_hover();
|
||||
|
||||
if (_drag && _input_receiver && (_input_receiver != _hovered))
|
||||
_input_receiver->submit_input_event(Hover_leave());
|
||||
|
||||
_drag = false;
|
||||
|
||||
if (_global_key_sequence) {
|
||||
_input_receiver = _focused;
|
||||
_global_key_sequence = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,6 +52,11 @@ class Nitpicker::User_state
|
||||
*/
|
||||
bool _global_key_sequence = false;
|
||||
|
||||
/*
|
||||
* True if motion events occur while a key is presse
|
||||
*/
|
||||
bool _drag = false;
|
||||
|
||||
/*
|
||||
* True if the input focus should change directly whenever the user
|
||||
* clicks on an unfocused client. This is the traditional behaviour
|
||||
|
Loading…
Reference in New Issue
Block a user