mirror of
https://github.com/brl/mutter.git
synced 2024-11-21 23:50:41 -05:00
window: Separate pointer-focus operations and explicit-focus operations
Some clients, like on-screen keyboards, don't want their windows to be activated on click, as that would steal focus from the window they're trying to send events to. They do this by setting the Input Hint in WM_HINTS to be FALSE, along with not specifying WM_TAKE_FOCUS in their WM_PROTOCOLS. However, in this case, when a window tries to get focus in this scenario, we focus the frame so that a11y and key navigation works properly. Both policies aren't acceptable -- we can't make OSK steal focus from windows on click, and we can't make an OSK un-Alt-Tabbable-to. To solve this, split meta_window_focus() into two different focus policies: * meta_window_focus_implicitly() should be called on pointer click or focus-follows-mouse or similar cases where we may not want to forcibly set focus for clients that don't want it. * meta_window_focus_explicitly() should be called by pagers, like the gnome-shell overview, or Alt-Tab. In this case, most of the existing clients are using meta_window_activate(), so simply adapting that so it calls meta_window_focus_explicitly() should be enough. https://bugzilla.gnome.org/show_bug.cgi?id=715030
This commit is contained in:
parent
91c2225ecd
commit
48b74b86ec
@ -303,7 +303,7 @@ meta_core_user_focus (Display *xdisplay,
|
|||||||
{
|
{
|
||||||
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
||||||
|
|
||||||
meta_window_focus (window, timestamp);
|
meta_window_focus_implicitly (window, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -482,7 +482,7 @@ meta_core_show_window_menu (Display *xdisplay,
|
|||||||
|
|
||||||
if (meta_prefs_get_raise_on_click ())
|
if (meta_prefs_get_raise_on_click ())
|
||||||
meta_window_raise (window);
|
meta_window_raise (window);
|
||||||
meta_window_focus (window, timestamp);
|
meta_window_focus_implicitly (window, timestamp);
|
||||||
|
|
||||||
meta_window_show_menu (window, root_x, root_y, button, timestamp);
|
meta_window_show_menu (window, root_x, root_y, button, timestamp);
|
||||||
}
|
}
|
||||||
|
@ -2244,7 +2244,7 @@ event_callback (XEvent *event,
|
|||||||
meta_topic (META_DEBUG_FOCUS,
|
meta_topic (META_DEBUG_FOCUS,
|
||||||
"Focusing %s due to unmodified button %u press (display.c)\n",
|
"Focusing %s due to unmodified button %u press (display.c)\n",
|
||||||
window->desc, device_event->detail);
|
window->desc, device_event->detail);
|
||||||
meta_window_focus (window, device_event->time);
|
meta_window_focus_implicitly (window, device_event->time);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* However, do allow terminals to lose focus due to new
|
/* However, do allow terminals to lose focus due to new
|
||||||
|
@ -1578,7 +1578,7 @@ meta_window_grab_all_keys (MetaWindow *window,
|
|||||||
meta_topic (META_DEBUG_FOCUS,
|
meta_topic (META_DEBUG_FOCUS,
|
||||||
"Focusing %s because we're grabbing all its keys\n",
|
"Focusing %s because we're grabbing all its keys\n",
|
||||||
window->desc);
|
window->desc);
|
||||||
meta_window_focus (window, timestamp);
|
meta_window_focus_implicitly (window, timestamp);
|
||||||
|
|
||||||
grabwindow = window->frame ? window->frame->xwindow : window->xwindow;
|
grabwindow = window->frame ? window->frame->xwindow : window->xwindow;
|
||||||
|
|
||||||
|
@ -2984,7 +2984,7 @@ meta_screen_show_desktop (MetaScreen *screen,
|
|||||||
if (w->screen == screen &&
|
if (w->screen == screen &&
|
||||||
w->type == META_WINDOW_DESKTOP)
|
w->type == META_WINDOW_DESKTOP)
|
||||||
{
|
{
|
||||||
meta_window_focus (w, timestamp);
|
meta_window_focus_explicitly (w, timestamp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -701,4 +701,7 @@ void meta_window_handle_enter (MetaWindow *window,
|
|||||||
guint root_x,
|
guint root_x,
|
||||||
guint root_y);
|
guint root_y);
|
||||||
|
|
||||||
|
void meta_window_focus_implicitly (MetaWindow *window,
|
||||||
|
guint32 timestamp);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -3183,7 +3183,7 @@ meta_window_show (MetaWindow *window)
|
|||||||
|
|
||||||
timestamp = meta_display_get_current_time_roundtrip (window->display);
|
timestamp = meta_display_get_current_time_roundtrip (window->display);
|
||||||
|
|
||||||
meta_window_focus (window, timestamp);
|
meta_window_focus_explicitly (window, timestamp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -4225,7 +4225,7 @@ meta_window_shade (MetaWindow *window,
|
|||||||
meta_topic (META_DEBUG_FOCUS,
|
meta_topic (META_DEBUG_FOCUS,
|
||||||
"Re-focusing window %s after shading it\n",
|
"Re-focusing window %s after shading it\n",
|
||||||
window->desc);
|
window->desc);
|
||||||
meta_window_focus (window, timestamp);
|
meta_window_focus_explicitly (window, timestamp);
|
||||||
|
|
||||||
set_net_wm_state (window);
|
set_net_wm_state (window);
|
||||||
}
|
}
|
||||||
@ -4249,7 +4249,7 @@ meta_window_unshade (MetaWindow *window,
|
|||||||
meta_topic (META_DEBUG_FOCUS,
|
meta_topic (META_DEBUG_FOCUS,
|
||||||
"Focusing window %s after unshading it\n",
|
"Focusing window %s after unshading it\n",
|
||||||
window->desc);
|
window->desc);
|
||||||
meta_window_focus (window, timestamp);
|
meta_window_focus_explicitly (window, timestamp);
|
||||||
|
|
||||||
set_net_wm_state (window);
|
set_net_wm_state (window);
|
||||||
}
|
}
|
||||||
@ -4348,7 +4348,7 @@ window_activate (MetaWindow *window,
|
|||||||
meta_topic (META_DEBUG_FOCUS,
|
meta_topic (META_DEBUG_FOCUS,
|
||||||
"Focusing window %s due to activation\n",
|
"Focusing window %s due to activation\n",
|
||||||
window->desc);
|
window->desc);
|
||||||
meta_window_focus (window, timestamp);
|
meta_window_focus_explicitly (window, timestamp);
|
||||||
|
|
||||||
meta_window_check_alive (window, timestamp);
|
meta_window_check_alive (window, timestamp);
|
||||||
}
|
}
|
||||||
@ -5972,17 +5972,18 @@ get_modal_transient (MetaWindow *window)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* XXX META_EFFECT_FOCUS */
|
/* XXX META_EFFECT_FOCUS */
|
||||||
void
|
static void
|
||||||
meta_window_focus (MetaWindow *window,
|
meta_window_focus_internal (MetaWindow *window,
|
||||||
guint32 timestamp)
|
guint32 timestamp,
|
||||||
|
gboolean explicit_focus)
|
||||||
{
|
{
|
||||||
MetaWindow *modal_transient;
|
MetaWindow *modal_transient;
|
||||||
|
|
||||||
g_return_if_fail (!window->override_redirect);
|
g_return_if_fail (!window->override_redirect);
|
||||||
|
|
||||||
meta_topic (META_DEBUG_FOCUS,
|
meta_topic (META_DEBUG_FOCUS,
|
||||||
"Setting input focus to window %s, input: %d take_focus: %d\n",
|
"%s setting input focus to window %s, input: %d take_focus: %d\n",
|
||||||
window->desc, window->input, window->take_focus);
|
explicit_focus ? "Explicitly" : "Implicitly", window->desc, window->input, window->take_focus);
|
||||||
|
|
||||||
if (window->display->grab_window &&
|
if (window->display->grab_window &&
|
||||||
window->display->grab_window->all_keys_grabbed)
|
window->display->grab_window->all_keys_grabbed)
|
||||||
@ -6017,15 +6018,16 @@ meta_window_focus (MetaWindow *window,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For output-only or shaded windows, focus the frame.
|
/* For output-only or shaded windows, focus the frame if it was
|
||||||
* This seems to result in the client window getting key events
|
* an explicit focus event. This seems to result in the client
|
||||||
* though, so I don't know if it's icccm-compliant.
|
* window getting key events though, so I don't know if it's
|
||||||
|
* icccm-compliant.
|
||||||
*
|
*
|
||||||
* Still, we have to do this or keynav breaks for these windows.
|
* Still, we have to do this or keynav breaks for these windows.
|
||||||
*/
|
*/
|
||||||
if (window->frame &&
|
if (window->frame &&
|
||||||
(window->shaded ||
|
(window->shaded ||
|
||||||
(!window->input && !window->take_focus)))
|
(explicit_focus && !window->input && !window->take_focus)))
|
||||||
{
|
{
|
||||||
if (window->frame)
|
if (window->frame)
|
||||||
{
|
{
|
||||||
@ -6068,6 +6070,40 @@ meta_window_focus (MetaWindow *window,
|
|||||||
/* meta_effect_run_focus(window, NULL, NULL); */
|
/* meta_effect_run_focus(window, NULL, NULL); */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* meta_window_focus_explicitly:
|
||||||
|
* @window: A #MetaWindow
|
||||||
|
* @timestamp: The timestamp to focus the window with
|
||||||
|
*
|
||||||
|
* Explicitly grab the window's focus. This should be used in cases
|
||||||
|
* where the user wants to focus the window with Alt-Tab, pagers,
|
||||||
|
* or other means like that, as opposed to simply clicking on the
|
||||||
|
* window or other focus-modes like focus-follows-mouse.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
meta_window_focus_explicitly (MetaWindow *window,
|
||||||
|
guint32 timestamp)
|
||||||
|
{
|
||||||
|
meta_window_focus_internal (window, timestamp, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* meta_window_focus_implicitly:
|
||||||
|
* @window: A #MetaWindow
|
||||||
|
* @timestamp: The timestamp to focus the window with
|
||||||
|
*
|
||||||
|
* Implicitly focus the window. This should be done if the user
|
||||||
|
* simply clicks on the window. Most of the time, this should be
|
||||||
|
* handled by mutter internally, and you should never have to
|
||||||
|
* call this.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
meta_window_focus_implicitly (MetaWindow *window,
|
||||||
|
guint32 timestamp)
|
||||||
|
{
|
||||||
|
meta_window_focus_internal (window, timestamp, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_window_change_workspace_without_transients (MetaWindow *window,
|
meta_window_change_workspace_without_transients (MetaWindow *window,
|
||||||
MetaWorkspace *workspace)
|
MetaWorkspace *workspace)
|
||||||
@ -11467,7 +11503,7 @@ mouse_mode_focus (MetaWindow *window,
|
|||||||
meta_topic (META_DEBUG_FOCUS,
|
meta_topic (META_DEBUG_FOCUS,
|
||||||
"Focusing %s at time %u.\n", window->desc, timestamp);
|
"Focusing %s at time %u.\n", window->desc, timestamp);
|
||||||
|
|
||||||
meta_window_focus (window, timestamp);
|
meta_window_focus_implicitly (window, timestamp);
|
||||||
|
|
||||||
if (meta_prefs_get_auto_raise ())
|
if (meta_prefs_get_auto_raise ())
|
||||||
meta_display_queue_autoraise_callback (display, window);
|
meta_display_queue_autoraise_callback (display, window);
|
||||||
|
@ -1256,7 +1256,7 @@ meta_workspace_focus_default_window (MetaWorkspace *workspace,
|
|||||||
{
|
{
|
||||||
meta_topic (META_DEBUG_FOCUS,
|
meta_topic (META_DEBUG_FOCUS,
|
||||||
"Focusing mouse window %s\n", window->desc);
|
"Focusing mouse window %s\n", window->desc);
|
||||||
meta_window_focus (window, timestamp);
|
meta_window_focus_explicitly (window, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (workspace->screen->display->autoraise_window != window &&
|
if (workspace->screen->display->autoraise_window != window &&
|
||||||
@ -1319,7 +1319,7 @@ focus_ancestor_or_top_window (MetaWorkspace *workspace,
|
|||||||
"Focusing %s, ancestor of %s\n",
|
"Focusing %s, ancestor of %s\n",
|
||||||
ancestor->desc, not_this_one->desc);
|
ancestor->desc, not_this_one->desc);
|
||||||
|
|
||||||
meta_window_focus (ancestor, timestamp);
|
meta_window_focus_explicitly (ancestor, timestamp);
|
||||||
|
|
||||||
/* Also raise the window if in click-to-focus */
|
/* Also raise the window if in click-to-focus */
|
||||||
if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK)
|
if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK)
|
||||||
@ -1338,7 +1338,7 @@ focus_ancestor_or_top_window (MetaWorkspace *workspace,
|
|||||||
meta_topic (META_DEBUG_FOCUS,
|
meta_topic (META_DEBUG_FOCUS,
|
||||||
"Focusing workspace MRU window %s\n", window->desc);
|
"Focusing workspace MRU window %s\n", window->desc);
|
||||||
|
|
||||||
meta_window_focus (window, timestamp);
|
meta_window_focus_explicitly (window, timestamp);
|
||||||
|
|
||||||
/* Also raise the window if in click-to-focus */
|
/* Also raise the window if in click-to-focus */
|
||||||
if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK)
|
if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK)
|
||||||
|
@ -227,7 +227,7 @@ void meta_window_stick (MetaWindow *window);
|
|||||||
void meta_window_unstick (MetaWindow *window);
|
void meta_window_unstick (MetaWindow *window);
|
||||||
|
|
||||||
void meta_window_kill (MetaWindow *window);
|
void meta_window_kill (MetaWindow *window);
|
||||||
void meta_window_focus (MetaWindow *window,
|
void meta_window_focus_explicitly (MetaWindow *window,
|
||||||
guint32 timestamp);
|
guint32 timestamp);
|
||||||
|
|
||||||
void meta_window_check_alive (MetaWindow *window,
|
void meta_window_check_alive (MetaWindow *window,
|
||||||
|
Loading…
Reference in New Issue
Block a user