nitpicker: postpone focus updates until idle

This patch ensures that focus changes performed via the Session::focus
call are made effective the next time, the user is idle. Previously,
focus changes during drag operations were simply discarded.
This commit is contained in:
Norman Feske 2015-10-08 00:09:10 +02:00 committed by Christian Helmuth
parent 7c968d4c60
commit f01b205c30
2 changed files with 34 additions and 11 deletions

View File

@ -908,23 +908,20 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>,
return;
}
/* prevent focus changes during drag operations */
if (_mode.drag())
return;
/* lookup targeted session object */
auto lambda = [this] (Session_component *session)
{
_mode.focused_session(session);
report_session(_focus_reporter, session);
_mode.next_focused_session(session);
};
_ep.apply(session_cap, lambda);
/*
* XXX We may skip this if all domains are configured to show the
* raw client content.
* To avoid changing the focus in the middle of a drag operation,
* we cannot perform the focus change immediately. Instead, it
* comes into effect via the 'Mode::apply_pending_focus_change()'
* function called the next time when the user input is handled and
* no drag operation is in flight.
*/
_view_stack.update_all_views();
}
void session_control(Label suffix, Session_control control) override
@ -1256,10 +1253,15 @@ void Nitpicker::Main::handle_input(unsigned)
user_active = true;
}
user_state.Mode::apply_pending_focus_change();
Point const new_pointer_pos = user_state.pointer_pos();
::Session * const new_pointed_session = user_state.pointed_session();
::Session * const new_focused_session = user_state.Mode::focused_session();
if (old_focused_session != new_focused_session)
user_state.update_all_views();
/* flag user as inactive after activity threshold is reached */
if (period_cnt == last_active_period + activity_threshold)
user_active = false;

View File

@ -28,6 +28,8 @@ class Mode
Session *_focused_session = nullptr;
Session *_next_focused_session = nullptr;
public:
virtual ~Mode() { }
@ -47,16 +49,35 @@ class Mode
Session *focused_session() { return _focused_session; }
Session const *focused_session() const { return _focused_session; }
virtual void focused_session(Session *session) { _focused_session = session; }
virtual void focused_session(Session *session)
{
_focused_session = session;
_next_focused_session = session;
}
bool is_focused(Session const &session) const { return &session == _focused_session; }
void next_focused_session(Session *session) { _next_focused_session = session; }
/**
* Apply pending focus-change request that was issued during drag state
*/
void apply_pending_focus_change()
{
if (key_is_pressed())
return;
if (_focused_session != _next_focused_session)
_focused_session = _next_focused_session;
}
/**
* Discard all references to specified view
*/
virtual void forget(Session const &session)
{
if (is_focused(session)) _focused_session = nullptr;
if (&session == _focused_session) _focused_session = nullptr;
if (&session == _next_focused_session) _next_focused_session = nullptr;
}
};