nitpicker: add version attribute in clicked report
This patch addresses a corner case where the nitpicker focus is not solely defined by mouse clicks or (exclusively) by a window manager, but by a policy component that takes mouse clicks and other policy (e.g., a lock screen) into account. It ensures that each click that follows a focus change (however initiated) results in a new "clicked" report even when the report looks the same. To allow the policy component to uniquely distiguish subsequent reports, the report features a new 'version' attribute. Fixes #3493
This commit is contained in:
parent
972e1893c9
commit
4622ddb46f
|
@ -152,6 +152,9 @@ void User_state::_handle_input_event(Input::Event ev)
|
||||||
|
|
||||||
View_owner *global_receiver = nullptr;
|
View_owner *global_receiver = nullptr;
|
||||||
|
|
||||||
|
if (_mouse_button(keycode))
|
||||||
|
_clicked_count++;
|
||||||
|
|
||||||
/* update focused session */
|
/* update focused session */
|
||||||
if (_mouse_button(keycode)
|
if (_mouse_button(keycode)
|
||||||
&& _hovered
|
&& _hovered
|
||||||
|
@ -282,6 +285,7 @@ User_state::handle_input_events(Input::Event const * const ev_buf,
|
||||||
View_owner const * const old_focused = _focused;
|
View_owner const * const old_focused = _focused;
|
||||||
View_owner const * const old_input_receiver = _input_receiver;
|
View_owner const * const old_input_receiver = _input_receiver;
|
||||||
View_owner const * const old_last_clicked = _last_clicked;
|
View_owner const * const old_last_clicked = _last_clicked;
|
||||||
|
unsigned const old_clicked_count = _clicked_count;
|
||||||
|
|
||||||
bool button_activity = false;
|
bool button_activity = false;
|
||||||
|
|
||||||
|
@ -333,6 +337,21 @@ User_state::handle_input_events(Input::Event const * const ev_buf,
|
||||||
|
|
||||||
_apply_pending_focus_change();
|
_apply_pending_focus_change();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determine condition for generating an updated "clicked" report
|
||||||
|
*/
|
||||||
|
bool const click_occurred = (old_clicked_count != _clicked_count);
|
||||||
|
|
||||||
|
bool const clicked_report_up_to_date =
|
||||||
|
(_last_clicked == old_last_clicked) && !_last_clicked_redeliver;
|
||||||
|
|
||||||
|
bool const last_clicked_changed = (click_occurred && !clicked_report_up_to_date);
|
||||||
|
|
||||||
|
if (last_clicked_changed) {
|
||||||
|
_last_clicked_version++;
|
||||||
|
_last_clicked_redeliver = false;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
.hover_changed = _hovered != old_hovered,
|
.hover_changed = _hovered != old_hovered,
|
||||||
.focus_changed = (_focused != old_focused) ||
|
.focus_changed = (_focused != old_focused) ||
|
||||||
|
@ -341,7 +360,7 @@ User_state::handle_input_events(Input::Event const * const ev_buf,
|
||||||
.button_activity = button_activity,
|
.button_activity = button_activity,
|
||||||
.motion_activity = (_pointer_pos != old_pointer_pos),
|
.motion_activity = (_pointer_pos != old_pointer_pos),
|
||||||
.key_pressed = _key_pressed(),
|
.key_pressed = _key_pressed(),
|
||||||
.last_clicked_changed = (_last_clicked != old_last_clicked)
|
.last_clicked_changed = last_clicked_changed
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -383,6 +402,8 @@ void User_state::report_last_clicked_view_owner(Xml_generator &xml) const
|
||||||
{
|
{
|
||||||
if (_last_clicked)
|
if (_last_clicked)
|
||||||
_last_clicked->report(xml);
|
_last_clicked->report(xml);
|
||||||
|
|
||||||
|
xml.attribute("version", _last_clicked_version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -95,6 +95,28 @@ class Nitpicker::User_state
|
||||||
*/
|
*/
|
||||||
View_owner *_last_clicked = nullptr;
|
View_owner *_last_clicked = nullptr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of clicks, used to detect whether a focus-relevant click
|
||||||
|
* happened during '_handle_input_event'.
|
||||||
|
*/
|
||||||
|
unsigned _clicked_count = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Version supplement for the "clicked" report
|
||||||
|
*
|
||||||
|
* The value allows the receiver of the report to detect the situation
|
||||||
|
* where two consecutive clicks refer to the same client but both
|
||||||
|
* events require a distinct focus response, i.e., if the focus (focus
|
||||||
|
* ROM) was changed in-between both clicks by other means than a click.
|
||||||
|
*/
|
||||||
|
unsigned _last_clicked_version = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If set, a "clicked" report is generated even if the clicked-on view
|
||||||
|
* is the same as the previously clicked-on view.
|
||||||
|
*/
|
||||||
|
bool _last_clicked_redeliver = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Array for tracking the state of each key
|
* Array for tracking the state of each key
|
||||||
*/
|
*/
|
||||||
|
@ -148,6 +170,14 @@ class Nitpicker::User_state
|
||||||
if (_focused != _next_focused) {
|
if (_focused != _next_focused) {
|
||||||
_focused = _next_focused;
|
_focused = _next_focused;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enforce the generation of a new "clicked" report for any click
|
||||||
|
* that follows a focus change. This is needed in situations
|
||||||
|
* where the focus is defined by clicks as well as other means
|
||||||
|
* (e.g., the appearance of a lock screen).
|
||||||
|
*/
|
||||||
|
_last_clicked_redeliver = true;
|
||||||
|
|
||||||
/* propagate changed focus to view stack */
|
/* propagate changed focus to view stack */
|
||||||
if (_focused)
|
if (_focused)
|
||||||
_focus.assign(*_focused);
|
_focus.assign(*_focused);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user