mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-18 21:27:56 +00:00
nitpicker: handle Input::Session::exclusive
While the focused client has enabled exclusive input, nitpicker does not translate relative motion to absolute motion but routes relative motion directly to the client. Additionally, the pointer origin is forcibly moved to a position outside the screen boundaries, making the pointer invisible. Issue #5355
This commit is contained in:
parent
996d9b300c
commit
92227df624
@ -44,7 +44,8 @@ class Nitpicker::Gui_session : public Session_object<Gui::Session>,
|
||||
public View_owner,
|
||||
public Buffer_provider,
|
||||
private Session_list::Element,
|
||||
private Dynamic_rom_session::Xml_producer
|
||||
private Dynamic_rom_session::Xml_producer,
|
||||
private Input::Session_component::Action
|
||||
{
|
||||
public:
|
||||
|
||||
@ -54,6 +55,8 @@ class Nitpicker::Gui_session : public Session_object<Gui::Session>,
|
||||
* \param rect domain-specific panorama rectangle
|
||||
*/
|
||||
virtual void gen_capture_info(Xml_generator &xml, Rect rect) const = 0;
|
||||
|
||||
virtual void exclusive_input_changed() = 0;
|
||||
};
|
||||
|
||||
private:
|
||||
@ -116,7 +119,7 @@ class Nitpicker::Gui_session : public Session_object<Gui::Session>,
|
||||
bool const _input_session_accounted = (
|
||||
withdraw(Ram_quota{Input::Session_component::ev_ds_size()}), true );
|
||||
|
||||
Input::Session_component _input_session_component { _env };
|
||||
Input::Session_component _input_session_component { _env, *this };
|
||||
|
||||
View_stack &_view_stack;
|
||||
|
||||
@ -201,6 +204,19 @@ class Nitpicker::Gui_session : public Session_object<Gui::Session>,
|
||||
*/
|
||||
void produce_xml(Xml_generator &) override;
|
||||
|
||||
bool _exclusive_input_requested = false;
|
||||
|
||||
/**
|
||||
* Input::Session_component::Action interface
|
||||
*/
|
||||
void exclusive_input_requested(bool const requested) override
|
||||
{
|
||||
bool const orig = _exclusive_input_requested;
|
||||
_exclusive_input_requested = requested;
|
||||
if (orig != requested)
|
||||
_action.exclusive_input_changed();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Gui_session(Env &env,
|
||||
@ -318,6 +334,11 @@ class Nitpicker::Gui_session : public Session_object<Gui::Session>,
|
||||
|
||||
void submit_input_event(Input::Event e) override;
|
||||
|
||||
bool exclusive_input_requested() const override
|
||||
{
|
||||
return _exclusive_input_requested;
|
||||
}
|
||||
|
||||
void report(Xml_generator &xml) const override
|
||||
{
|
||||
xml.attribute("label", _label);
|
||||
|
@ -32,6 +32,11 @@ class Input::Session_component : public Rpc_object<Session>
|
||||
{
|
||||
public:
|
||||
|
||||
struct Action : Interface
|
||||
{
|
||||
virtual void exclusive_input_requested(bool) = 0;
|
||||
};
|
||||
|
||||
enum { MAX_EVENTS = 200 };
|
||||
|
||||
static size_t ev_ds_size() {
|
||||
@ -40,6 +45,7 @@ class Input::Session_component : public Rpc_object<Session>
|
||||
private:
|
||||
|
||||
Entrypoint &_ep;
|
||||
Action &_action;
|
||||
|
||||
/*
|
||||
* Exported event buffer dataspace
|
||||
@ -58,9 +64,10 @@ class Input::Session_component : public Rpc_object<Session>
|
||||
|
||||
public:
|
||||
|
||||
Session_component(Env &env)
|
||||
Session_component(Env &env, Action &action)
|
||||
:
|
||||
_ep(env.ep()), _ev_ram_ds(env.ram(), env.rm(), ev_ds_size())
|
||||
_ep(env.ep()), _action(action),
|
||||
_ev_ram_ds(env.ram(), env.rm(), ev_ds_size())
|
||||
{
|
||||
_ep.manage(*this);
|
||||
}
|
||||
@ -114,7 +121,10 @@ class Input::Session_component : public Rpc_object<Session>
|
||||
|
||||
void sigh(Signal_context_capability sigh) override { _sigh = sigh; }
|
||||
|
||||
void exclusive(bool) override { }
|
||||
void exclusive(bool requested) override
|
||||
{
|
||||
_action.exclusive_input_requested(requested);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _INPUT_SESSION_COMPONENT_H_ */
|
||||
|
@ -760,6 +760,22 @@ struct Nitpicker::Main : Focus_updater, Hover_updater,
|
||||
capture_buffer_size_changed();
|
||||
}
|
||||
|
||||
bool _exclusive_input = false;
|
||||
|
||||
/**
|
||||
* Input::Session_component::Action interface
|
||||
*/
|
||||
void exclusive_input_changed() override
|
||||
{
|
||||
if (_user_state.exclusive_input() != _exclusive_input) {
|
||||
_exclusive_input = _user_state.exclusive_input();
|
||||
|
||||
/* toggle pointer visibility */
|
||||
_update_pointer_position();
|
||||
_view_stack.update_all_views();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Signal handler for externally triggered focus changes
|
||||
*/
|
||||
@ -797,6 +813,11 @@ struct Nitpicker::Main : Focus_updater, Hover_updater,
|
||||
|
||||
void _update_pointer_position()
|
||||
{
|
||||
/* move pointer out of the way while a client receives exclusive input */
|
||||
if (_user_state.exclusive_input()) {
|
||||
_view_stack.geometry(_pointer_origin, Rect { { -1000*1000, 0 }, { } });
|
||||
return;
|
||||
}
|
||||
_user_state.pointer().with_result(
|
||||
[&] (Point p) {
|
||||
_view_stack.geometry(_pointer_origin, Rect(p, Area{})); },
|
||||
|
@ -93,13 +93,13 @@ void User_state::_handle_input_event(Input::Event ev)
|
||||
_last_seq_number.construct(seq); });
|
||||
|
||||
/* transparently convert relative into absolute motion event */
|
||||
ev.handle_relative_motion([&] (int x, int y) {
|
||||
_pointer.with_result(
|
||||
[&] (Point orig_pos) {
|
||||
Point const p = orig_pos + Point { x, y };
|
||||
ev = Absolute_motion { p.x, p.y }; },
|
||||
[&] (Nowhere) { });
|
||||
});
|
||||
if (!exclusive_input())
|
||||
ev.handle_relative_motion([&] (int x, int y) {
|
||||
_pointer.with_result(
|
||||
[&] (Point orig_pos) {
|
||||
Point const p = orig_pos + Point { x, y };
|
||||
ev = Absolute_motion { p.x, p.y }; },
|
||||
[&] (Nowhere) { }); });
|
||||
|
||||
/* respond to motion events by updating the pointer position */
|
||||
ev.handle_absolute_motion([&] (int x, int y) {
|
||||
@ -249,27 +249,31 @@ void User_state::_handle_input_event(Input::Event ev)
|
||||
/*
|
||||
* Deliver event to session
|
||||
*/
|
||||
bool const forward_to_session = (ev.absolute_motion() || ev.wheel() ||
|
||||
ev.touch() || ev.touch_release() ||
|
||||
ev.seq_number());
|
||||
bool const forward_to_session = ev.absolute_motion() || ev.relative_motion()
|
||||
|| ev.touch() || ev.touch_release()
|
||||
|| ev.wheel() || ev.seq_number();
|
||||
if (forward_to_session) {
|
||||
|
||||
if (_key_cnt == 0) {
|
||||
View_owner *receiver = _input_receiver;
|
||||
|
||||
if (_hovered) {
|
||||
if (_key_cnt == 0 && _hovered) {
|
||||
/*
|
||||
* Unless the domain of the pointed session is configured to
|
||||
* always receive hover events, we deliver motion events only
|
||||
* to the focused domain.
|
||||
*/
|
||||
if (_hovered->hover_always() || _hovered->has_same_domain(_focused))
|
||||
receiver = _hovered;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unless the domain of the pointed session is configured to
|
||||
* always receive hover events, we deliver motion events only
|
||||
* to the focused domain.
|
||||
*/
|
||||
if (_hovered->hover_always()
|
||||
|| _hovered->has_same_domain(_focused))
|
||||
_hovered->submit_input_event(ev);
|
||||
}
|
||||
/*
|
||||
* Route relative motion (exclusive input) to the focused client
|
||||
*/
|
||||
if (ev.relative_motion() && _focused)
|
||||
receiver = _focused;
|
||||
|
||||
} else if (_input_receiver)
|
||||
_input_receiver->submit_input_event(ev);
|
||||
if (receiver)
|
||||
receiver->submit_input_event(ev);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -252,6 +252,12 @@ class Nitpicker::User_state
|
||||
|
||||
Handle_input_result handle_input_events(Input_batch);
|
||||
|
||||
bool exclusive_input() const
|
||||
{
|
||||
return (_focused && _focused->exclusive_input_requested())
|
||||
|| (_input_receiver && _input_receiver->exclusive_input_requested());
|
||||
}
|
||||
|
||||
/**
|
||||
* Discard all references to specified view owner
|
||||
*/
|
||||
|
@ -86,6 +86,8 @@ struct Nitpicker::View_owner : Interface
|
||||
|
||||
virtual void submit_input_event(Input::Event) { }
|
||||
|
||||
virtual bool exclusive_input_requested() const { return false; }
|
||||
|
||||
/**
|
||||
* Produce report with the owner's information
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user