compositor: Add an API to query if the stage is focused

gnome-shell needs to know whether the stage window is focused so
it can synchronize between stage window focus and Clutter key actor
focus. Track all X windows, even those without MetaWindows, when
tracking the focus window, and add a compositor-level API to determine
when the stage is focused.
This commit is contained in:
Jasper St. Pierre 2013-05-24 17:58:55 -04:00
parent 8747b97ba3
commit c7b8f26cad
4 changed files with 31 additions and 2 deletions

View File

@ -391,6 +391,24 @@ meta_focus_stage_window (MetaScreen *screen,
timestamp); timestamp);
} }
gboolean
meta_stage_is_focused (MetaScreen *screen)
{
ClutterStage *stage;
Window window;
stage = CLUTTER_STAGE (meta_get_stage_for_screen (screen));
if (!stage)
return FALSE;
window = clutter_x11_get_stage_window (stage);
if (window == None)
return FALSE;
return (screen->display->focus_xwindow == window);
}
gboolean gboolean
meta_begin_modal_for_plugin (MetaScreen *screen, meta_begin_modal_for_plugin (MetaScreen *screen,
MetaPlugin *plugin, MetaPlugin *plugin,

View File

@ -113,6 +113,9 @@ struct _MetaDisplay
* or event that caused this. * or event that caused this.
*/ */
MetaWindow *focus_window; MetaWindow *focus_window;
/* For windows we've focused that don't necessarily have an X window,
* like the no_focus_window or the stage X window. */
Window focus_xwindow;
gulong focus_serial; gulong focus_serial;
/* last timestamp passed to XSetInputFocus */ /* last timestamp passed to XSetInputFocus */

View File

@ -1876,11 +1876,12 @@ get_input_event (MetaDisplay *display,
static void static void
update_focus_window (MetaDisplay *display, update_focus_window (MetaDisplay *display,
MetaWindow *window, MetaWindow *window,
Window xwindow,
gulong serial) gulong serial)
{ {
display->focus_serial = serial; display->focus_serial = serial;
if (window == display->focus_window) if (display->focus_xwindow == xwindow)
return; return;
if (display->focus_window) if (display->focus_window)
@ -1897,11 +1898,13 @@ update_focus_window (MetaDisplay *display,
*/ */
previous = display->focus_window; previous = display->focus_window;
display->focus_window = NULL; display->focus_window = NULL;
display->focus_xwindow = None;
meta_window_set_focused_internal (previous, FALSE); meta_window_set_focused_internal (previous, FALSE);
} }
display->focus_window = window; display->focus_window = window;
display->focus_xwindow = xwindow;
if (display->focus_window) if (display->focus_window)
{ {
@ -1991,6 +1994,7 @@ request_xserver_input_focus_change (MetaDisplay *display,
update_focus_window (display, update_focus_window (display,
meta_window, meta_window,
xwindow,
serial); serial);
meta_error_trap_pop (display); meta_error_trap_pop (display);
@ -2107,7 +2111,9 @@ handle_window_focus_event (MetaDisplay *display,
if (display->server_focus_serial >= display->focus_serial) if (display->server_focus_serial >= display->focus_serial)
{ {
update_focus_window (display, focus_window, update_focus_window (display,
focus_window,
focus_window ? focus_window->xwindow : None,
display->server_focus_serial); display->server_focus_serial);
} }
} }
@ -2163,6 +2169,7 @@ event_callback (XEvent *event,
display->focus_window->desc); display->focus_window->desc);
update_focus_window (display, update_focus_window (display,
meta_display_lookup_x_window (display, display->server_focus_window), meta_display_lookup_x_window (display, display->server_focus_window),
display->server_focus_window,
display->server_focus_serial); display->server_focus_serial);
} }

View File

@ -48,5 +48,6 @@ void meta_set_stage_input_region (MetaScreen *screen,
void meta_empty_stage_input_region (MetaScreen *screen); void meta_empty_stage_input_region (MetaScreen *screen);
void meta_focus_stage_window (MetaScreen *screen, void meta_focus_stage_window (MetaScreen *screen,
guint32 timestamp); guint32 timestamp);
gboolean meta_stage_is_focused (MetaScreen *screen);
#endif #endif