Commit 05899596 authored by Armin Krezović's avatar Armin Krezović Committed by Jonas Ådahl

Move X11 helper windows and xprops to MetaX11Display

https://bugzilla.gnome.org/show_bug.cgi?id=759538
parent 98d912ba
......@@ -281,10 +281,9 @@ meta_focus_stage_window (MetaScreen *screen,
if (window == None)
return;
meta_display_set_input_focus_xwindow (screen->display,
screen,
window,
timestamp);
meta_x11_display_set_input_focus_xwindow (screen->display->x11_display,
window,
timestamp);
}
gboolean
......@@ -305,7 +304,7 @@ meta_stage_is_focused (MetaScreen *screen)
if (window == None)
return FALSE;
return (screen->display->focus_xwindow == window);
return (screen->display->x11_display->focus_xwindow == window);
}
static gboolean
......@@ -498,7 +497,7 @@ meta_compositor_manage (MetaCompositor *compositor)
MetaScreen *screen = display->screen;
MetaBackend *backend = meta_get_backend ();
meta_screen_set_cm_selection (display->screen);
meta_x11_display_set_cm_selection (display->x11_display);
compositor->stage = meta_backend_get_stage (backend);
......@@ -538,7 +537,7 @@ meta_compositor_manage (MetaCompositor *compositor)
{
Window xwin;
compositor->output = screen->composite_overlay_window;
compositor->output = display->x11_display->composite_overlay_window;
xwin = meta_backend_x11_get_xwindow (META_BACKEND_X11 (backend));
......
......@@ -111,23 +111,12 @@ struct _MetaDisplay
int clutter_event_filter;
Window leader_window;
Window timestamp_pinging_window;
/* The window and serial of the most recent FocusIn event. */
Window server_focus_window;
gulong server_focus_serial;
/* Our best guess as to the "currently" focused window (that is, the
* window that we expect will be focused at the point when the X
* server processes our next request), and the serial of the request
* 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 */
guint32 last_focus_time;
......@@ -338,11 +327,6 @@ void meta_display_ungrab_focus_window_button (MetaDisplay *display,
/* Next function is defined in edge-resistance.c */
void meta_display_cleanup_edges (MetaDisplay *display);
/* make a request to ensure the event serial has changed */
void meta_display_increment_event_serial (MetaDisplay *display);
void meta_display_update_active_window_hint (MetaDisplay *display);
/* utility goo */
const char* meta_event_mode_to_string (int m);
const char* meta_event_detail_to_string (int d);
......@@ -376,11 +360,6 @@ void meta_display_accelerator_activate (MetaDisplay *display,
ClutterKeyEvent *event);
gboolean meta_display_modifiers_accelerator_activate (MetaDisplay *display);
void meta_display_set_input_focus_xwindow (MetaDisplay *display,
MetaScreen *screen,
Window window,
guint32 timestamp);
void meta_display_sync_wayland_input_focus (MetaDisplay *display);
void meta_display_update_focus_window (MetaDisplay *display,
MetaWindow *window,
......
......@@ -157,10 +157,6 @@ static guint display_signals [LAST_SIGNAL] = { 0 };
*/
static MetaDisplay *the_display = NULL;
static const char *gnome_wm_keybindings = "Mutter";
static const char *net_wm_name = "Mutter";
static void on_monitors_changed_internal (MetaMonitorManager *monitor_manager,
MetaDisplay *display);
......@@ -534,36 +530,6 @@ meta_display_init (MetaDisplay *disp)
* but it doesn't really matter. */
}
/**
* meta_set_wm_name: (skip)
* @wm_name: value for _NET_WM_NAME
*
* Set the value to use for the _NET_WM_NAME property. To take effect,
* it is necessary to call this function before meta_init().
*/
void
meta_set_wm_name (const char *wm_name)
{
g_return_if_fail (the_display == NULL);
net_wm_name = wm_name;
}
/**
* meta_set_gnome_wm_keybindings: (skip)
* @wm_keybindings: value for _GNOME_WM_KEYBINDINGS
*
* Set the value to use for the _GNOME_WM_KEYBINDINGS property. To take
* effect, it is necessary to call this function before meta_init().
*/
void
meta_set_gnome_wm_keybindings (const char *wm_keybindings)
{
g_return_if_fail (the_display == NULL);
gnome_wm_keybindings = wm_keybindings;
}
void
meta_display_cancel_touch (MetaDisplay *display)
{
......@@ -638,7 +604,6 @@ meta_display_open (void)
GError *error = NULL;
MetaDisplay *display;
MetaX11Display *x11_display;
Display *xdisplay;
MetaScreen *screen;
int i;
guint32 timestamp;
......@@ -715,88 +680,15 @@ meta_display_open (void)
display->x11_display = x11_display;
g_signal_emit (display, display_signals[X11_DISPLAY_OPENED], 0);
xdisplay = display->x11_display->xdisplay;
timestamp = display->x11_display->timestamp;
display->stack = meta_stack_new (display);
display->stack_tracker = meta_stack_tracker_new (display);
display->focus_serial = 0;
display->server_focus_window = None;
display->server_focus_serial = 0;
meta_bell_init (display);
/* Offscreen unmapped window used for _NET_SUPPORTING_WM_CHECK,
* created in screen_new
*/
display->leader_window = None;
display->timestamp_pinging_window = None;
meta_display_init_events_x11 (display);
/* Create the leader window here. Set its properties and
* use the timestamp from one of the PropertyNotify events
* that will follow.
*/
{
gulong data[1];
XEvent event;
/* We only care about the PropertyChangeMask in the next 30 or so lines of
* code. Note that gdk will at some point unset the PropertyChangeMask for
* this window, so we can't rely on it still being set later. See bug
* 354213 for details.
*/
display->leader_window =
meta_x11_display_create_offscreen_window (display->x11_display,
DefaultRootWindow (xdisplay),
PropertyChangeMask);
meta_prop_set_utf8_string_hint (display,
display->leader_window,
display->x11_display->atom__NET_WM_NAME,
net_wm_name);
meta_prop_set_utf8_string_hint (display,
display->leader_window,
display->x11_display->atom__GNOME_WM_KEYBINDINGS,
gnome_wm_keybindings);
meta_prop_set_utf8_string_hint (display,
display->leader_window,
display->x11_display->atom__MUTTER_VERSION,
VERSION);
data[0] = display->leader_window;
XChangeProperty (xdisplay,
display->leader_window,
display->x11_display->atom__NET_SUPPORTING_WM_CHECK,
XA_WINDOW,
32, PropModeReplace, (guchar*) data, 1);
XWindowEvent (xdisplay,
display->leader_window,
PropertyChangeMask,
&event);
timestamp = event.xproperty.time;
/* Make it painfully clear that we can't rely on PropertyNotify events on
* this window, as per bug 354213.
*/
XSelectInput(xdisplay,
display->leader_window,
NoEventMask);
}
/* Make a little window used only for pinging the server for timestamps; note
* that meta_create_offscreen_window already selects for PropertyChangeMask.
*/
display->timestamp_pinging_window =
meta_x11_display_create_offscreen_window (display->x11_display,
DefaultRootWindow (xdisplay),
PropertyChangeMask);
display->last_focus_time = timestamp;
display->last_user_time = timestamp;
display->compositor = NULL;
......@@ -819,7 +711,8 @@ meta_display_open (void)
display->screen = screen;
if (!meta_is_wayland_compositor ())
meta_prop_get_window (display, display->x11_display->xroot,
meta_prop_get_window (display->x11_display,
display->x11_display->xroot,
display->x11_display->atom__NET_ACTIVE_WINDOW,
&old_active_xwindow);
......@@ -852,10 +745,10 @@ meta_display_open (void)
if (old_active_window)
meta_window_focus (old_active_window, timestamp);
else
meta_display_focus_the_no_focus_window (display, display->screen, timestamp);
meta_x11_display_focus_the_no_focus_window (display->x11_display, timestamp);
}
else
meta_display_focus_the_no_focus_window (display, display->screen, timestamp);
meta_x11_display_focus_the_no_focus_window (display->x11_display, timestamp);
meta_idle_monitor_init_dbus ();
......@@ -1023,9 +916,6 @@ meta_display_close (MetaDisplay *display,
/* Stop caring about events */
meta_display_free_events_x11 (display);
if (display->leader_window != None)
XDestroyWindow (display->x11_display->xdisplay, display->leader_window);
if (display->x11_display)
{
g_signal_emit (display, display_signals[X11_DISPLAY_CLOSING], 0);
......@@ -1185,42 +1075,10 @@ meta_display_get_current_time (MetaDisplay *display)
return display->current_time;
}
static Bool
find_timestamp_predicate (Display *xdisplay,
XEvent *ev,
XPointer arg)
{
MetaDisplay *display = (MetaDisplay *) arg;
return (ev->type == PropertyNotify &&
ev->xproperty.atom == display->x11_display->atom__MUTTER_TIMESTAMP_PING);
}
/* Get a timestamp, even if it means a roundtrip */
guint32
meta_display_get_current_time_roundtrip (MetaDisplay *display)
{
guint32 timestamp;
timestamp = meta_display_get_current_time (display);
if (timestamp == CurrentTime)
{
XEvent property_event;
XChangeProperty (display->x11_display->xdisplay,
display->timestamp_pinging_window,
display->x11_display->atom__MUTTER_TIMESTAMP_PING,
XA_STRING, 8, PropModeAppend, NULL, 0);
XIfEvent (display->x11_display->xdisplay,
&property_event,
find_timestamp_predicate,
(XPointer) display);
timestamp = property_event.xproperty.time;
}
meta_display_sanity_check_timestamps (display, timestamp);
return timestamp;
return meta_x11_display_get_current_time_roundtrip (display->x11_display);
}
/**
......@@ -1308,10 +1166,13 @@ meta_display_sync_wayland_input_focus (MetaDisplay *display)
MetaWindow *focus_window = NULL;
MetaBackend *backend = meta_get_backend ();
MetaStage *stage = META_STAGE (meta_backend_get_stage (backend));
gboolean is_focus_xwindow =
meta_x11_display_xwindow_is_a_no_focus_window (display->x11_display,
display->x11_display->focus_xwindow);
if (!meta_display_windows_are_interactable (display))
focus_window = NULL;
else if (meta_display_xwindow_is_a_no_focus_window (display, display->focus_xwindow))
else if (is_focus_xwindow)
focus_window = NULL;
else if (display->focus_window && display->focus_window->surface)
focus_window = display->focus_window;
......@@ -1332,10 +1193,10 @@ meta_display_update_focus_window (MetaDisplay *display,
gulong serial,
gboolean focused_by_us)
{
display->focus_serial = serial;
display->x11_display->focus_serial = serial;
display->focused_by_us = focused_by_us;
if (display->focus_xwindow == xwindow &&
if (display->x11_display->focus_xwindow == xwindow &&
display->focus_window == window)
return;
......@@ -1353,13 +1214,13 @@ meta_display_update_focus_window (MetaDisplay *display,
*/
previous = display->focus_window;
display->focus_window = NULL;
display->focus_xwindow = None;
display->x11_display->focus_xwindow = None;
meta_window_set_focused_internal (previous, FALSE);
}
display->focus_window = window;
display->focus_xwindow = xwindow;
display->x11_display->focus_xwindow = xwindow;
if (display->focus_window)
{
......@@ -1374,7 +1235,7 @@ meta_display_update_focus_window (MetaDisplay *display,
meta_display_sync_wayland_input_focus (display);
g_object_notify (G_OBJECT (display), "focus-window");
meta_display_update_active_window_hint (display);
meta_x11_display_update_active_window_hint (display->x11_display);
}
gboolean
......@@ -1406,59 +1267,6 @@ meta_display_timestamp_too_old (MetaDisplay *display,
return FALSE;
}
static void
request_xserver_input_focus_change (MetaDisplay *display,
MetaScreen *screen,
MetaWindow *meta_window,
Window xwindow,
guint32 timestamp)
{
gulong serial;
if (meta_display_timestamp_too_old (display, &timestamp))
return;
meta_error_trap_push (display->x11_display);
/* In order for mutter to know that the focus request succeeded, we track
* the serial of the "focus request" we made, but if we take the serial
* of the XSetInputFocus request, then there's no way to determine the
* difference between focus events as a result of the SetInputFocus and
* focus events that other clients send around the same time. Ensure that
* we know which is which by making two requests that the server will
* process at the same time.
*/
XGrabServer (display->x11_display->xdisplay);
serial = XNextRequest (display->x11_display->xdisplay);
XSetInputFocus (display->x11_display->xdisplay,
xwindow,
RevertToPointerRoot,
timestamp);
XChangeProperty (display->x11_display->xdisplay,
display->timestamp_pinging_window,
display->x11_display->atom__MUTTER_FOCUS_SET,
XA_STRING, 8, PropModeAppend, NULL, 0);
XUngrabServer (display->x11_display->xdisplay);
XFlush (display->x11_display->xdisplay);
meta_display_update_focus_window (display,
meta_window,
xwindow,
serial,
TRUE);
meta_error_trap_pop (display->x11_display);
display->last_focus_time = timestamp;
if (meta_window == NULL || meta_window != display->autoraise_window)
meta_display_remove_autoraise_callback (display);
}
void
meta_display_register_wayland_window (MetaDisplay *display,
MetaWindow *window)
......@@ -1543,22 +1351,6 @@ meta_display_notify_window_created (MetaDisplay *display,
g_signal_emit (display, display_signals[WINDOW_CREATED], 0, window);
}
/**
* meta_display_xwindow_is_a_no_focus_window:
* @display: A #MetaDisplay
* @xwindow: An X11 window
*
* Returns: %TRUE iff window is one of mutter's internal "no focus" windows
* (there is one per screen) which will have the focus when there is no
* actual client window focused.
*/
gboolean
meta_display_xwindow_is_a_no_focus_window (MetaDisplay *display,
Window xwindow)
{
return xwindow == display->screen->no_focus_window;
}
static MetaCursor
meta_cursor_for_grab_op (MetaGrabOp op)
{
......@@ -2013,37 +1805,6 @@ meta_display_check_threshold_reached (MetaDisplay *display,
display->grab_threshold_movement_reached = TRUE;
}
void
meta_display_increment_event_serial (MetaDisplay *display)
{
/* We just make some random X request */
XDeleteProperty (display->x11_display->xdisplay,
display->leader_window,
display->x11_display->atom__MOTIF_WM_HINTS);
}
void
meta_display_update_active_window_hint (MetaDisplay *display)
{
gulong data[1];
if (display->closing)
return; /* Leave old value for a replacement */
if (display->focus_window)
data[0] = display->focus_window->xwindow;
else
data[0] = None;
meta_error_trap_push (display->x11_display);
XChangeProperty (display->x11_display->xdisplay,
display->x11_display->xroot,
display->x11_display->atom__NET_ACTIVE_WINDOW,
XA_WINDOW,
32, PropModeReplace, (guchar*) data, 1);
meta_error_trap_pop (display->x11_display);
}
void
meta_display_queue_retheme_all_windows (MetaDisplay *display)
{
......@@ -2766,44 +2527,6 @@ meta_display_sanity_check_timestamps (MetaDisplay *display,
}
}
void
meta_display_set_input_focus_window (MetaDisplay *display,
MetaWindow *window,
gboolean focus_frame,
guint32 timestamp)
{
request_xserver_input_focus_change (display,
window->screen,
window,
focus_frame ? window->frame->xwindow : window->xwindow,
timestamp);
}
void
meta_display_set_input_focus_xwindow (MetaDisplay *display,
MetaScreen *screen,
Window window,
guint32 timestamp)
{
request_xserver_input_focus_change (display,
screen,
NULL,
window,
timestamp);
}
void
meta_display_focus_the_no_focus_window (MetaDisplay *display,
MetaScreen *screen,
guint32 timestamp)
{
request_xserver_input_focus_change (display,
screen,
NULL,
screen->no_focus_window,
timestamp);
}
void
meta_display_remove_autoraise_callback (MetaDisplay *display)
{
......
......@@ -52,22 +52,12 @@ struct _MetaScreen
MetaWorkspace *active_workspace;
/* This window holds the focus when we don't want to focus
* any actual clients
*/
Window no_focus_window;
GList *workspaces;
Window wm_sn_selection_window;
Atom wm_sn_atom;
guint32 wm_sn_timestamp;
gboolean has_xinerama_indices;
GSList *startup_sequences;
Window wm_cm_selection_window;
guint work_area_later;
guint check_fullscreen_later;
......@@ -80,8 +70,6 @@ struct _MetaScreen
guint keys_grabbed : 1;
int closing;
Window composite_overlay_window;
};
struct _MetaScreenClass
......
......@@ -256,11 +256,12 @@ set_wm_check_hint (MetaScreen *screen)
MetaX11Display *x11_display = screen->display->x11_display;
unsigned long data[1];
g_return_val_if_fail (screen->display->leader_window != None, 0);
g_return_val_if_fail (x11_display->leader_window != None, 0);
data[0] = screen->display->leader_window;
data[0] = x11_display->leader_window;
XChangeProperty (x11_display->xdisplay, x11_display->xroot,
XChangeProperty (x11_display->xdisplay,
x11_display->xroot,
x11_display->atom__NET_SUPPORTING_WM_CHECK,
XA_WINDOW,
32, PropModeReplace, (guchar*) data, 1);
......@@ -273,7 +274,8 @@ unset_wm_check_hint (MetaScreen *screen)
{
MetaX11Display *x11_display = screen->display->x11_display;
XDeleteProperty (x11_display->xdisplay, x11_display->xroot,
XDeleteProperty (x11_display->xdisplay,
x11_display->xroot,
x11_display->atom__NET_SUPPORTING_WM_CHECK);
}
......@@ -472,81 +474,6 @@ reload_logical_monitors (MetaScreen *screen)
screen->has_xinerama_indices = FALSE;
}
static Window
take_manager_selection (MetaDisplay *display,
Window xroot,
Atom manager_atom,
int timestamp,
gboolean should_replace)
{
MetaX11Display *x11_display = display->x11_display;
Window current_owner, new_owner;
current_owner = XGetSelectionOwner (x11_display->xdisplay, manager_atom);
if (current_owner != None)
{
XSetWindowAttributes attrs;
if (should_replace)
{
/* We want to find out when the current selection owner dies */
meta_error_trap_push (x11_display);
attrs.event_mask = StructureNotifyMask;
XChangeWindowAttributes (x11_display->xdisplay, current_owner, CWEventMask, &attrs);
if (meta_error_trap_pop_with_return (x11_display) != Success)
current_owner = None; /* don't wait for it to die later on */
}
else
{
meta_warning (_("Display “%s” already has a window manager; try using the --replace option to replace the current window manager."),
x11_display->name);
return None;
}
}
/* We need SelectionClear and SelectionRequest events on the new owner,
* but those cannot be masked, so we only need NoEventMask.
*/
new_owner = meta_x11_display_create_offscreen_window (x11_display, xroot, NoEventMask);
XSetSelectionOwner (x11_display->xdisplay, manager_atom, new_owner, timestamp);
if (XGetSelectionOwner (x11_display->xdisplay, manager_atom) != new_owner)
{
meta_warning ("Could not acquire selection: %s", XGetAtomName (x11_display->xdisplay, manager_atom));
return None;
}