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.

https://bugzilla.gnome.org/show_bug.cgi?id=700735
This commit is contained in:
Jasper St. Pierre
2013-05-24 17:58:55 -04:00
parent 7fdfbad6d4
commit 96221e6c04
4 changed files with 34 additions and 5 deletions

View File

@ -113,6 +113,9 @@ struct _MetaDisplay
* or event that caused this.
*/
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;
/* last timestamp passed to XSetInputFocus */

View File

@ -1468,11 +1468,11 @@ meta_display_get_current_time (MetaDisplay *display)
}
static Bool
find_timestamp_predicate (Display *display,
find_timestamp_predicate (Display *xdisplay,
XEvent *ev,
XPointer arg)
{
MetaDisplay *display = arg;
MetaDisplay *display = (MetaDisplay *) arg;
return (ev->type == PropertyNotify &&
ev->xproperty.atom == display->atom__MUTTER_TIMESTAMP_PING);
@ -1495,7 +1495,7 @@ meta_display_get_current_time_roundtrip (MetaDisplay *display)
XIfEvent (display->xdisplay,
&property_event,
find_timestamp_predicate,
display);
(XPointer) display);
timestamp = property_event.xproperty.time;
}
@ -1883,11 +1883,12 @@ get_input_event (MetaDisplay *display,
static void
update_focus_window (MetaDisplay *display,
MetaWindow *window,
Window xwindow,
gulong serial)
{
display->focus_serial = serial;
if (window == display->focus_window)
if (display->focus_xwindow == xwindow)
return;
if (display->focus_window)
@ -1904,11 +1905,13 @@ update_focus_window (MetaDisplay *display,
*/
previous = display->focus_window;
display->focus_window = NULL;
display->focus_xwindow = None;
meta_window_set_focused_internal (previous, FALSE);
}
display->focus_window = window;
display->focus_xwindow = xwindow;
if (display->focus_window)
{
@ -1993,6 +1996,7 @@ request_xserver_input_focus_change (MetaDisplay *display,
update_focus_window (display,
meta_window,
xwindow,
serial);
meta_error_trap_pop (display);
@ -2109,7 +2113,9 @@ handle_window_focus_event (MetaDisplay *display,
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);
}
}
@ -2165,6 +2171,7 @@ event_callback (XEvent *event,
display->focus_window->desc);
update_focus_window (display,
meta_display_lookup_x_window (display, display->server_focus_window),
display->server_focus_window,
display->server_focus_serial);
}