diff options
-rw-r--r-- | src/compositor/compositor.c | 13 | ||||
-rw-r--r-- | src/core/display-private.h | 21 | ||||
-rw-r--r-- | src/core/display.c | 307 | ||||
-rw-r--r-- | src/core/screen-private.h | 12 | ||||
-rw-r--r-- | src/core/screen.c | 175 | ||||
-rw-r--r-- | src/core/window.c | 5 | ||||
-rw-r--r-- | src/core/workspace.c | 18 | ||||
-rw-r--r-- | src/meta/display.h | 25 | ||||
-rw-r--r-- | src/meta/meta-x11-display.h | 26 | ||||
-rw-r--r-- | src/meta/screen.h | 2 | ||||
-rw-r--r-- | src/wayland/meta-window-wayland.c | 8 | ||||
-rw-r--r-- | src/x11/events.c | 43 | ||||
-rw-r--r-- | src/x11/group-props.c | 2 | ||||
-rw-r--r-- | src/x11/meta-x11-display-private.h | 38 | ||||
-rw-r--r-- | src/x11/meta-x11-display.c | 482 | ||||
-rw-r--r-- | src/x11/window-props.c | 6 | ||||
-rw-r--r-- | src/x11/window-x11.c | 52 | ||||
-rw-r--r-- | src/x11/xprops.c | 142 | ||||
-rw-r--r-- | src/x11/xprops.h | 78 |
19 files changed, 751 insertions, 704 deletions
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 694b27e3f..3dab0dedf 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -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)); diff --git a/src/core/display-private.h b/src/core/display-private.h index e025b2316..14fee983a 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -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, diff --git a/src/core/display.c b/src/core/display.c index 2e7e6d064..4a661b491 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -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, ×tamp)) - 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) { @@ -2014,37 +1806,6 @@ meta_display_check_threshold_reached (MetaDisplay *display, } 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) { GSList* windows; @@ -2767,44 +2528,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) { if (display->autoraise_timeout_id != 0) diff --git a/src/core/screen-private.h b/src/core/screen-private.h index bf2fbb0fe..6dbf5a30d 100644 --- a/src/core/screen-private.h +++ b/src/core/screen-private.h @@ -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 diff --git a/src/core/screen.c b/src/core/screen.c index 70aa9169d..a690cd9e6 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -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; - } - - { - /* Send client message indicating that we are now the selection owner */ - XClientMessageEvent ev; - - ev.type = ClientMessage; - ev.window = xroot; - ev.message_type = x11_display->atom_MANAGER; - ev.format = 32; - ev.data.l[0] = timestamp; - ev.data.l[1] = manager_atom; - - XSendEvent (x11_display->xdisplay, xroot, False, StructureNotifyMask, (XEvent *) &ev); - } - - /* Wait for old window manager to go away */ - if (current_owner != None) - { - XEvent event; - - /* We sort of block infinitely here which is probably lame. */ - - meta_verbose ("Waiting for old window manager to exit\n"); - do - XWindowEvent (x11_display->xdisplay, current_owner, StructureNotifyMask, &event); - while (event.type != DestroyNotify); - } - - return new_owner; -} - MetaScreen* meta_screen_new (MetaDisplay *display, guint32 timestamp) @@ -555,59 +482,17 @@ meta_screen_new (MetaDisplay *display, int number; Window xroot = meta_x11_display_get_xroot (display->x11_display); Display *xdisplay = meta_x11_display_get_xdisplay (display->x11_display); - Window new_wm_sn_owner; - gboolean replace_current_wm; - Atom wm_sn_atom; - char buf[128]; - - replace_current_wm = meta_get_replace_current_wm (); number = meta_ui_get_screen_number (); meta_verbose ("Trying screen %d on display '%s'\n", number, display->x11_display->name); - sprintf (buf, "WM_S%d", number); - - wm_sn_atom = XInternAtom (xdisplay, buf, False); - new_wm_sn_owner = take_manager_selection (display, xroot, wm_sn_atom, timestamp, replace_current_wm); - if (new_wm_sn_owner == None) - return NULL; - - { - long event_mask; - unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; - XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; - - XISetMask (mask.mask, XI_Enter); - XISetMask (mask.mask, XI_Leave); - XISetMask (mask.mask, XI_FocusIn); - XISetMask (mask.mask, XI_FocusOut); -#ifdef HAVE_XI23 - if (META_X11_DISPLAY_HAS_XINPUT_23 (display->x11_display)) - { - XISetMask (mask.mask, XI_BarrierHit); - XISetMask (mask.mask, XI_BarrierLeave); - } -#endif /* HAVE_XI23 */ - XISelectEvents (xdisplay, xroot, &mask, 1); - - event_mask = (SubstructureRedirectMask | SubstructureNotifyMask | - StructureNotifyMask | ColormapChangeMask | PropertyChangeMask); - XSelectInput (xdisplay, xroot, event_mask); - } - - /* Select for cursor changes so the cursor tracker is up to date. */ - XFixesSelectCursorInput (xdisplay, xroot, XFixesDisplayCursorNotifyMask); - screen = g_object_new (META_TYPE_SCREEN, NULL); screen->closing = 0; screen->display = display; - screen->wm_sn_selection_window = new_wm_sn_owner; - screen->wm_sn_atom = wm_sn_atom; - screen->wm_sn_timestamp = timestamp; screen->work_area_later = 0; screen->check_fullscreen_later = 0; @@ -618,25 +503,8 @@ meta_screen_new (MetaDisplay *display, screen->vertical_workspaces = FALSE; screen->starting_corner = META_SCREEN_TOPLEFT; - /* If we're a Wayland compositor, then we don't grab the COW, since it - * will map it. */ - if (!meta_is_wayland_compositor ()) - screen->composite_overlay_window = XCompositeGetOverlayWindow (xdisplay, xroot); - - /* Now that we've gotten taken a reference count on the COW, we - * can close the helper that is holding on to it */ - meta_restart_finish (); - reload_logical_monitors (screen); - /* Handle creating a no_focus_window for this screen */ - screen->no_focus_window = - meta_x11_display_create_offscreen_window (display->x11_display, - xroot, - FocusChangeMask|KeyPressMask|KeyReleaseMask); - XMapWindow (xdisplay, screen->no_focus_window); - /* Done with no_focus_window stuff */ - set_wm_icon_size_hint (screen); set_supported_hint (screen); @@ -680,10 +548,10 @@ meta_screen_init_workspaces (MetaScreen *screen) g_return_if_fail (META_IS_SCREEN (screen)); - timestamp = screen->wm_sn_timestamp; + timestamp = screen->display->x11_display->wm_sn_timestamp; /* Get current workspace */ - if (meta_prop_get_cardinal (display, + if (meta_prop_get_cardinal (display->x11_display, display->x11_display->xroot, display->x11_display->atom__NET_CURRENT_DESKTOP, ¤t_workspace_index)) @@ -710,9 +578,6 @@ void meta_screen_free (MetaScreen *screen, guint32 timestamp) { - MetaDisplay *display = screen->display; - MetaX11Display *x11_display = display->x11_display; - screen->closing += 1; meta_prefs_remove_listener (prefs_changed_callback, screen); @@ -723,9 +588,6 @@ meta_screen_free (MetaScreen *screen, unset_wm_check_hint (screen); - XDestroyWindow (x11_display->xdisplay, - screen->wm_sn_selection_window); - if (screen->work_area_later != 0) meta_later_remove (screen->work_area_later); if (screen->check_fullscreen_later != 0) @@ -986,7 +848,7 @@ update_num_workspaces (MetaScreen *screen, n_items = 0; list = NULL; - if (meta_prop_get_cardinal_list (display, + if (meta_prop_get_cardinal_list (display->x11_display, display->x11_display->xroot, display->x11_display->atom__NET_NUMBER_OF_DESKTOPS, &list, &n_items)) @@ -1340,7 +1202,7 @@ meta_screen_update_workspace_layout (MetaScreen *screen) list = NULL; n_items = 0; - if (meta_prop_get_cardinal_list (display, + if (meta_prop_get_cardinal_list (display->x11_display, display->x11_display->xroot, display->x11_display->atom__NET_DESKTOP_LAYOUT, &list, &n_items)) @@ -1516,7 +1378,7 @@ meta_screen_update_workspace_names (MetaScreen *screen) names = NULL; n_names = 0; - if (!meta_prop_get_utf8_list (screen->display, + if (!meta_prop_get_utf8_list (x11_display, x11_display->xroot, x11_display->atom__NET_DESKTOP_NAMES, &names, &n_names)) @@ -2168,21 +2030,6 @@ meta_screen_get_display (MetaScreen *screen) return screen->display; } -void -meta_screen_set_cm_selection (MetaScreen *screen) -{ - MetaX11Display *x11_display = screen->display->x11_display; - char selection[32]; - Atom a; - guint32 timestamp; - - timestamp = meta_display_get_current_time_roundtrip (screen->display); - g_snprintf (selection, sizeof (selection), "_NET_WM_CM_S%d", - meta_ui_get_screen_number ()); - a = XInternAtom (x11_display->xdisplay, selection, False); - screen->wm_cm_selection_window = take_manager_selection (screen->display, x11_display->xroot, a, timestamp, TRUE); -} - /** * meta_screen_get_workspaces: (skip) * @screen: a #MetaScreen diff --git a/src/core/window.c b/src/core/window.c index 3f7224f59..cda6aa887 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -8027,9 +8027,8 @@ mouse_mode_focus (MetaWindow *window, "Unsetting focus from %s due to mouse entering " "the DESKTOP window\n", display->focus_window->desc); - meta_display_focus_the_no_focus_window (display, - window->screen, - timestamp); + meta_x11_display_focus_the_no_focus_window (display->x11_display, + timestamp); } } } diff --git a/src/core/workspace.c b/src/core/workspace.c index 5b44ce3d2..c9cb1579c 100644 --- a/src/core/workspace.c +++ b/src/core/workspace.c @@ -1262,6 +1262,8 @@ meta_workspace_focus_default_window (MetaWorkspace *workspace, MetaWindow *not_this_one, guint32 timestamp) { + MetaDisplay *display = workspace->screen->display; + if (timestamp == CurrentTime) meta_warning ("CurrentTime used to choose focus window; " "focus window may not be correct.\n"); @@ -1300,8 +1302,7 @@ meta_workspace_focus_default_window (MetaWorkspace *workspace, if (workspace->screen->display->autoraise_window != window && meta_prefs_get_auto_raise ()) { - meta_display_queue_autoraise_callback (workspace->screen->display, - window); + meta_display_queue_autoraise_callback (display, window); } } else if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_SLOPPY) @@ -1311,9 +1312,8 @@ meta_workspace_focus_default_window (MetaWorkspace *workspace, meta_topic (META_DEBUG_FOCUS, "Setting focus to no_focus_window, since no valid " "window to focus found.\n"); - meta_display_focus_the_no_focus_window (workspace->screen->display, - workspace->screen, - timestamp); + meta_x11_display_focus_the_no_focus_window (display->x11_display, + timestamp); } } } @@ -1334,6 +1334,7 @@ focus_ancestor_or_top_window (MetaWorkspace *workspace, MetaWindow *not_this_one, guint32 timestamp) { + MetaDisplay *display = workspace->screen->display; MetaWindow *window = NULL; if (not_this_one) @@ -1367,7 +1368,7 @@ focus_ancestor_or_top_window (MetaWorkspace *workspace, } } - window = meta_stack_get_default_focus_window (workspace->screen->display->stack, + window = meta_stack_get_default_focus_window (display->stack, workspace, not_this_one); @@ -1385,9 +1386,8 @@ focus_ancestor_or_top_window (MetaWorkspace *workspace, else { meta_topic (META_DEBUG_FOCUS, "No MRU window to focus found; focusing no_focus_window.\n"); - meta_display_focus_the_no_focus_window (workspace->screen->display, - workspace->screen, - timestamp); + meta_x11_display_focus_the_no_focus_window (display->x11_display, + timestamp); } } diff --git a/src/meta/display.h b/src/meta/display.h index 1a7805685..f172bc904 100644 --- a/src/meta/display.h +++ b/src/meta/display.h @@ -80,9 +80,6 @@ MetaX11Display *meta_display_get_x11_display (MetaDisplay *display); MetaWindow *meta_display_get_focus_window (MetaDisplay *display); -gboolean meta_display_xwindow_is_a_no_focus_window (MetaDisplay *display, - Window xwindow); - gboolean meta_display_xserver_time_is_before (MetaDisplay *display, guint32 time1, guint32 time2); @@ -140,28 +137,6 @@ guint meta_display_get_keybinding_action (MetaDisplay *display, unsigned int keycode, unsigned long mask); -/* meta_display_set_input_focus_window is like XSetInputFocus, except - * that (a) it can't detect timestamps later than the current time, - * since Mutter isn't part of the XServer, and thus gives erroneous - * behavior in this circumstance (so don't do it), (b) it uses - * display->last_focus_time since we don't have access to the true - * Xserver one, (c) it makes use of display->user_time since checking - * whether a window should be allowed to be focused should depend - * on user_time events (see bug 167358, comment 15 in particular) - */ -void meta_display_set_input_focus_window (MetaDisplay *display, - MetaWindow *window, - gboolean focus_frame, - guint32 timestamp); - -/* meta_display_focus_the_no_focus_window is called when the - * designated no_focus_window should be focused, but is otherwise the - * same as meta_display_set_input_focus_window - */ -void meta_display_focus_the_no_focus_window (MetaDisplay *display, - MetaScreen *screen, - guint32 timestamp); - GSList *meta_display_sort_windows_by_stacking (MetaDisplay *display, GSList *windows); diff --git a/src/meta/meta-x11-display.h b/src/meta/meta-x11-display.h index f1bda49e6..9aeb60cb6 100644 --- a/src/meta/meta-x11-display.h +++ b/src/meta/meta-x11-display.h @@ -39,4 +39,30 @@ int meta_x11_display_get_damage_event_base (MetaX11Display *x11_display); int meta_x11_display_get_shape_event_base (MetaX11Display *x11_display); gboolean meta_x11_display_has_shape (MetaX11Display *x11_display); +void meta_x11_display_set_cm_selection (MetaX11Display *x11_display); + +gboolean meta_x11_display_xwindow_is_a_no_focus_window (MetaX11Display *x11_display, + Window xwindow); + +/* meta_x11_display_set_input_focus_window is like XSetInputFocus, except + * that (a) it can't detect timestamps later than the current time, + * since Mutter isn't part of the XServer, and thus gives erroneous + * behavior in this circumstance (so don't do it), (b) it uses + * display->last_focus_time since we don't have access to the true + * Xserver one, (c) it makes use of display->user_time since checking + * whether a window should be allowed to be focused should depend + * on user_time events (see bug 167358, comment 15 in particular) + */ +void meta_x11_display_set_input_focus_window (MetaX11Display *x11_display, + MetaWindow *window, + gboolean focus_frame, + guint32 timestamp); + +/* meta_x11_display_focus_the_no_focus_window is called when the + * designated no_focus_window should be focused, but is otherwise the + * same as meta_display_set_input_focus_window + */ +void meta_x11_display_focus_the_no_focus_window (MetaX11Display *x11_display, + guint32 timestamp); + #endif /* META_X11_DISPLAY_H */ diff --git a/src/meta/screen.h b/src/meta/screen.h index b056be5ca..37a85b8c3 100644 --- a/src/meta/screen.h +++ b/src/meta/screen.h @@ -38,8 +38,6 @@ GType meta_screen_get_type (void); MetaDisplay *meta_screen_get_display (MetaScreen *screen); -void meta_screen_set_cm_selection (MetaScreen *screen); - GSList *meta_screen_get_startup_sequences (MetaScreen *screen); GList *meta_screen_get_workspaces (MetaScreen *screen); diff --git a/src/wayland/meta-window-wayland.c b/src/wayland/meta-window-wayland.c index e50af5c94..3a7344baa 100644 --- a/src/wayland/meta-window-wayland.c +++ b/src/wayland/meta-window-wayland.c @@ -139,10 +139,10 @@ meta_window_wayland_focus (MetaWindow *window, guint32 timestamp) { if (window->input) - meta_display_set_input_focus_window (window->display, - window, - FALSE, - timestamp); + meta_x11_display_set_input_focus_window (window->display->x11_display, + window, + FALSE, + timestamp); } static void diff --git a/src/x11/events.c b/src/x11/events.c index f19e829e0..811276841 100644 --- a/src/x11/events.c +++ b/src/x11/events.c @@ -712,7 +712,8 @@ handle_window_focus_event (MetaDisplay *display, else window_type = "unknown client window"; } - else if (meta_display_xwindow_is_a_no_focus_window (display, event->event)) + else if (meta_x11_display_xwindow_is_a_no_focus_window (display->x11_display, + event->event)) window_type = "no_focus_window"; else if (event->event == display->x11_display->xroot) window_type = "root window"; @@ -772,8 +773,8 @@ handle_window_focus_event (MetaDisplay *display, if (event->evtype == XI_FocusIn) { - display->server_focus_window = event->event; - display->server_focus_serial = serial; + display->x11_display->server_focus_window = event->event; + display->x11_display->server_focus_serial = serial; focus_window = window; } else if (event->evtype == XI_FocusOut) @@ -786,8 +787,8 @@ handle_window_focus_event (MetaDisplay *display, return FALSE; } - display->server_focus_window = None; - display->server_focus_serial = serial; + display->x11_display->server_focus_window = None; + display->x11_display->server_focus_serial = serial; focus_window = NULL; } else @@ -798,14 +799,14 @@ handle_window_focus_event (MetaDisplay *display, * (See request_xserver_input_focus_change().) Otherwise, we can get * multiple focus events with the same serial. */ - if (display->server_focus_serial > display->focus_serial || + if (display->x11_display->server_focus_serial > display->x11_display->focus_serial || (!display->focused_by_us && - display->server_focus_serial == display->focus_serial)) + display->x11_display->server_focus_serial == display->x11_display->focus_serial)) { meta_display_update_focus_window (display, focus_window, focus_window ? focus_window->xwindow : None, - display->server_focus_serial, + display->x11_display->server_focus_serial, FALSE); return TRUE; } @@ -950,7 +951,7 @@ process_request_frame_extents (MetaDisplay *display, meta_verbose ("Setting frame extents for 0x%lx\n", xwindow); /* See if the window is decorated. */ - hints_set = meta_prop_get_motif_hints (display, + hints_set = meta_prop_get_motif_hints (display->x11_display, xwindow, display->x11_display->atom__MOTIF_WM_HINTS, &hints); @@ -1010,7 +1011,7 @@ convert_property (MetaDisplay *display, else if (target == x11_display->atom_TIMESTAMP) XChangeProperty (x11_display->xdisplay, w, property, XA_INTEGER, 32, PropModeReplace, - (unsigned char *)&screen->wm_sn_timestamp, 1); + (unsigned char *)&x11_display->wm_sn_timestamp, 1); else if (target == x11_display->atom_VERSION) XChangeProperty (x11_display->xdisplay, w, property, XA_INTEGER, 32, PropModeReplace, @@ -1043,8 +1044,8 @@ process_selection_request (MetaDisplay *display, MetaScreen *screen = display->screen; XSelectionEvent reply; - if (screen->wm_sn_selection_window != event->xselectionrequest.owner || - screen->wm_sn_atom != event->xselectionrequest.selection) + if (x11_display->wm_sn_selection_window != event->xselectionrequest.owner || + x11_display->wm_sn_atom != event->xselectionrequest.selection) { char *str; @@ -1140,10 +1141,8 @@ static gboolean process_selection_clear (MetaDisplay *display, XEvent *event) { - MetaScreen *screen = display->screen; - - if (screen->wm_sn_selection_window != event->xselectionclear.window || - screen->wm_sn_atom != event->xselectionclear.selection) + if (display->x11_display->wm_sn_selection_window != event->xselectionclear.window || + display->x11_display->wm_sn_atom != event->xselectionclear.selection) { char *str; @@ -1419,7 +1418,7 @@ handle_other_xevent (MetaDisplay *display, if (event->xconfigure.event != event->xconfigure.window) { if (event->xconfigure.event == x11_display->xroot && - event->xconfigure.window != display->screen->composite_overlay_window) + event->xconfigure.window != x11_display->composite_overlay_window) meta_stack_tracker_configure_event (display->stack_tracker, &event->xconfigure); } @@ -1744,17 +1743,17 @@ meta_display_handle_xevent (MetaDisplay *display, meta_backend_x11_handle_event (META_BACKEND_X11 (backend), event); if (display->focused_by_us && - event->xany.serial > display->focus_serial && + event->xany.serial > display->x11_display->focus_serial && display->focus_window && - !window_has_xwindow (display->focus_window, display->server_focus_window)) + !window_has_xwindow (display->focus_window, display->x11_display->server_focus_window)) { meta_topic (META_DEBUG_FOCUS, "Earlier attempt to focus %s failed\n", display->focus_window->desc); meta_display_update_focus_window (display, meta_x11_display_lookup_x_window (display->x11_display, - display->server_focus_window), - display->server_focus_window, - display->server_focus_serial, + display->x11_display->server_focus_window), + display->x11_display->server_focus_window, + display->x11_display->server_focus_serial, FALSE); } diff --git a/src/x11/group-props.c b/src/x11/group-props.c index 0169ea6ae..391cc661e 100644 --- a/src/x11/group-props.c +++ b/src/x11/group-props.c @@ -74,7 +74,7 @@ meta_group_reload_properties (MetaGroup *group, ++i; } - meta_prop_get_values (group->x11_display->display, + meta_prop_get_values (group->x11_display, group->group_leader, values, n_properties); diff --git a/src/x11/meta-x11-display-private.h b/src/x11/meta-x11-display-private.h index a0cee7123..f2f6cb57b 100644 --- a/src/x11/meta-x11-display-private.h +++ b/src/x11/meta-x11-display-private.h @@ -54,6 +54,8 @@ struct _MetaX11Display int default_depth; Visual *default_xvisual; + guint32 timestamp; + /* Pull in all the names of atoms as fields; we will intern them when the * class is constructed. */ @@ -61,11 +63,36 @@ struct _MetaX11Display #include "x11/atomnames.h" #undef item + 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; + + /* 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; + + /* This window holds the focus when we don't want to focus + * any actual clients + */ + Window no_focus_window; + /* Instead of unmapping withdrawn windows we can leave them mapped * and restack them below a guard window. When using a compositor * this allows us to provide live previews of unmapped windows */ Window guard_window; + Window wm_sn_selection_window; + Atom wm_sn_atom; + guint32 wm_sn_timestamp; + + Window wm_cm_selection_window; + + Window composite_overlay_window; + GHashTable *xids; /* Managed by group.c */ @@ -151,4 +178,15 @@ void meta_x11_display_set_alarm_filter (MetaX11Display *x11_display, void meta_x11_display_create_guard_window (MetaX11Display *x11_display); +/* make a request to ensure the event serial has changed */ +void meta_x11_display_increment_event_serial (MetaX11Display *x11_display); +void meta_x11_display_update_active_window_hint (MetaX11Display *x11_display); + +guint32 meta_x11_display_get_current_time_roundtrip (MetaX11Display *x11_display); + +void meta_x11_display_set_input_focus_xwindow (MetaX11Display *x11_display, + Window window, + guint32 timestamp); + + #endif /* META_X11_DISPLAY_PRIVATE_H */ diff --git a/src/x11/meta-x11-display.c b/src/x11/meta-x11-display.c index 61be15d0a..062977541 100644 --- a/src/x11/meta-x11-display.c +++ b/src/x11/meta-x11-display.c @@ -49,11 +49,14 @@ #include "backends/meta-backend-private.h" #include "backends/x11/meta-backend-x11.h" +#include "core/frame.h" #include "core/util-private.h" #include "meta/errors.h" +#include "meta/main.h" #include "x11/group-props.h" #include "x11/window-props.h" +#include "x11/xprops.h" #ifdef HAVE_WAYLAND #include "wayland/meta-xwayland-private.h" @@ -61,6 +64,9 @@ G_DEFINE_TYPE (MetaX11Display, meta_x11_display, G_TYPE_OBJECT) +static const char *gnome_wm_keybindings = "Mutter"; +static const char *net_wm_name = "Mutter"; + static char *get_screen_name (Display *xdisplay, int number); @@ -74,6 +80,40 @@ meta_x11_display_dispose (GObject *object) { MetaX11Display *x11_display = META_X11_DISPLAY (object); + if (x11_display->no_focus_window != None) + { + XUnmapWindow (x11_display->xdisplay, x11_display->no_focus_window); + XDestroyWindow (x11_display->xdisplay, x11_display->no_focus_window); + + x11_display->no_focus_window = None; + } + + if (x11_display->composite_overlay_window != None) + { + XCompositeReleaseOverlayWindow (x11_display->xdisplay, + x11_display->composite_overlay_window); + + x11_display->composite_overlay_window = None; + } + + if (x11_display->wm_sn_selection_window != None) + { + XDestroyWindow (x11_display->xdisplay, x11_display->wm_sn_selection_window); + x11_display->wm_sn_selection_window = None; + } + + if (x11_display->timestamp_pinging_window != None) + { + XDestroyWindow (x11_display->xdisplay, x11_display->timestamp_pinging_window); + x11_display->timestamp_pinging_window = None; + } + + if (x11_display->leader_window != None) + { + XDestroyWindow (x11_display->xdisplay, x11_display->leader_window); + x11_display->leader_window = None; + } + if (x11_display->guard_window != None) { MetaStackTracker *stack_tracker = x11_display->display->stack_tracker; @@ -331,6 +371,194 @@ query_xi_extension (MetaX11Display *x11_display) meta_fatal ("X server doesn't have the XInput extension, version 2.2 or newer\n"); } +static Window +take_manager_selection (MetaX11Display *x11_display, + Window xroot, + Atom manager_atom, + int timestamp, + gboolean should_replace) +{ + 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; + } + + { + /* Send client message indicating that we are now the selection owner */ + XClientMessageEvent ev; + + ev.type = ClientMessage; + ev.window = xroot; + ev.message_type = x11_display->atom_MANAGER; + ev.format = 32; + ev.data.l[0] = timestamp; + ev.data.l[1] = manager_atom; + + XSendEvent (x11_display->xdisplay, xroot, False, StructureNotifyMask, (XEvent *) &ev); + } + + /* Wait for old window manager to go away */ + if (current_owner != None) + { + XEvent event; + + /* We sort of block infinitely here which is probably lame. */ + + meta_verbose ("Waiting for old window manager to exit\n"); + do + XWindowEvent (x11_display->xdisplay, current_owner, StructureNotifyMask, &event); + while (event.type != DestroyNotify); + } + + return new_owner; +} + +/* Create the leader window here. Set its properties and + * use the timestamp from one of the PropertyNotify events + * that will follow. + */ +static void +init_leader_window (MetaX11Display *x11_display, + guint32 *timestamp) +{ + 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. + */ + x11_display->leader_window = + meta_x11_display_create_offscreen_window (x11_display, + x11_display->xroot, + PropertyChangeMask); + + meta_prop_set_utf8_string_hint (x11_display, + x11_display->leader_window, + x11_display->atom__NET_WM_NAME, + net_wm_name); + + meta_prop_set_utf8_string_hint (x11_display, + x11_display->leader_window, + x11_display->atom__GNOME_WM_KEYBINDINGS, + gnome_wm_keybindings); + + meta_prop_set_utf8_string_hint (x11_display, + x11_display->leader_window, + x11_display->atom__MUTTER_VERSION, + VERSION); + + data[0] = x11_display->leader_window; + XChangeProperty (x11_display->xdisplay, + x11_display->leader_window, + x11_display->atom__NET_SUPPORTING_WM_CHECK, + XA_WINDOW, + 32, PropModeReplace, (guchar*) data, 1); + + XWindowEvent (x11_display->xdisplay, + x11_display->leader_window, + PropertyChangeMask, + &event); + + if (timestamp) + *timestamp = event.xproperty.time; + + /* Make it painfully clear that we can't rely on PropertyNotify events on + * this window, as per bug 354213. + */ + XSelectInput (x11_display->xdisplay, + x11_display->leader_window, + NoEventMask); +} + +static void +init_event_masks (MetaX11Display *x11_display) +{ + long event_mask; + unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; + XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; + + XISetMask (mask.mask, XI_Enter); + XISetMask (mask.mask, XI_Leave); + XISetMask (mask.mask, XI_FocusIn); + XISetMask (mask.mask, XI_FocusOut); +#ifdef HAVE_XI23 + if (META_X11_DISPLAY_HAS_XINPUT_23 (x11_display)) + { + XISetMask (mask.mask, XI_BarrierHit); + XISetMask (mask.mask, XI_BarrierLeave); + } +#endif /* HAVE_XI23 */ + XISelectEvents (x11_display->xdisplay, x11_display->xroot, &mask, 1); + + event_mask = (SubstructureRedirectMask | SubstructureNotifyMask | + StructureNotifyMask | ColormapChangeMask | PropertyChangeMask); + XSelectInput (x11_display->xdisplay, x11_display->xroot, event_mask); +} + +/** + * 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 (meta_get_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 (meta_get_display () == NULL); + + gnome_wm_keybindings = wm_keybindings; +} + /** * meta_x11_display_new: * @@ -349,6 +577,11 @@ meta_x11_display_new (MetaDisplay *display, GError **error) Screen *xscreen; Window xroot; int i, number; + Window new_wm_sn_owner; + gboolean replace_current_wm; + Atom wm_sn_atom; + char buf[128]; + guint32 timestamp; /* A list of all atom names, so that we can intern them in one go. */ const char *atom_names[] = { @@ -381,6 +614,8 @@ meta_x11_display_new (MetaDisplay *display, GError **error) if (meta_is_syncing ()) XSynchronize (xdisplay, True); + replace_current_wm = meta_get_replace_current_wm (); + number = meta_ui_get_screen_number (); xroot = RootWindow (xdisplay, number); @@ -390,7 +625,6 @@ meta_x11_display_new (MetaDisplay *display, GError **error) */ if (xroot == None) { - meta_warning (_("Screen %d on display ā%sā is invalid\n"), number, XDisplayName (NULL)); @@ -448,7 +682,15 @@ meta_x11_display_new (MetaDisplay *display, GError **error) meta_unsigned_long_equal); x11_display->groups_by_leader = NULL; + x11_display->composite_overlay_window = None; x11_display->guard_window = None; + x11_display->leader_window = None; + x11_display->timestamp_pinging_window = None; + x11_display->wm_sn_selection_window = None; + + x11_display->focus_serial = 0; + x11_display->server_focus_window = None; + x11_display->server_focus_serial = 0; x11_display->prop_hooks = NULL; meta_x11_display_init_window_prop_hooks (x11_display); @@ -461,6 +703,58 @@ meta_x11_display_new (MetaDisplay *display, GError **error) x11_display, 0); + init_leader_window (x11_display, ×tamp); + x11_display->timestamp = timestamp; + + /* Make a little window used only for pinging the server for timestamps; note + * that meta_create_offscreen_window already selects for PropertyChangeMask. + */ + x11_display->timestamp_pinging_window = + meta_x11_display_create_offscreen_window (x11_display, + xroot, + PropertyChangeMask); + + sprintf (buf, "WM_S%d", number); + + wm_sn_atom = XInternAtom (xdisplay, buf, False); + new_wm_sn_owner = take_manager_selection (x11_display, xroot, wm_sn_atom, timestamp, replace_current_wm); + if (new_wm_sn_owner == None) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Failed to acquire window manager ownership"); + + g_object_run_dispose (G_OBJECT (x11_display)); + g_clear_object (&x11_display); + + return NULL; + } + + x11_display->wm_sn_selection_window = new_wm_sn_owner; + x11_display->wm_sn_atom = wm_sn_atom; + x11_display->wm_sn_timestamp = timestamp; + + init_event_masks (x11_display); + + /* Select for cursor changes so the cursor tracker is up to date. */ + XFixesSelectCursorInput (xdisplay, xroot, XFixesDisplayCursorNotifyMask); + + /* If we're a Wayland compositor, then we don't grab the COW, since it + * will map it. */ + if (!meta_is_wayland_compositor ()) + x11_display->composite_overlay_window = XCompositeGetOverlayWindow (xdisplay, xroot); + + /* Now that we've gotten taken a reference count on the COW, we + * can close the helper that is holding on to it */ + meta_restart_finish (); + + /* Handle creating a no_focus_window for this screen */ + x11_display->no_focus_window = + meta_x11_display_create_offscreen_window (x11_display, + xroot, + FocusChangeMask|KeyPressMask|KeyReleaseMask); + XMapWindow (xdisplay, x11_display->no_focus_window); + /* Done with no_focus_window stuff */ + return x11_display; } @@ -786,3 +1080,189 @@ on_monitors_changed (MetaDisplay *display, &changes); } } + +void +meta_x11_display_set_cm_selection (MetaX11Display *x11_display) +{ + char selection[32]; + Atom a; + guint32 timestamp; + + timestamp = meta_x11_display_get_current_time_roundtrip (x11_display); + g_snprintf (selection, sizeof (selection), "_NET_WM_CM_S%d", + meta_ui_get_screen_number ()); + a = XInternAtom (x11_display->xdisplay, selection, False); + + x11_display->wm_cm_selection_window = take_manager_selection (x11_display, x11_display->xroot, a, timestamp, TRUE); +} + +static Bool +find_timestamp_predicate (Display *xdisplay, + XEvent *ev, + XPointer arg) +{ + MetaX11Display *x11_display = (MetaX11Display *) arg; + + return (ev->type == PropertyNotify && + ev->xproperty.atom == x11_display->atom__MUTTER_TIMESTAMP_PING); +} + +/* Get a timestamp, even if it means a roundtrip */ +guint32 +meta_x11_display_get_current_time_roundtrip (MetaX11Display *x11_display) +{ + guint32 timestamp; + + timestamp = meta_display_get_current_time (x11_display->display); + if (timestamp == CurrentTime) + { + XEvent property_event; + + XChangeProperty (x11_display->xdisplay, + x11_display->timestamp_pinging_window, + x11_display->atom__MUTTER_TIMESTAMP_PING, + XA_STRING, 8, PropModeAppend, NULL, 0); + XIfEvent (x11_display->xdisplay, + &property_event, + find_timestamp_predicate, + (XPointer) x11_display); + timestamp = property_event.xproperty.time; + } + + meta_display_sanity_check_timestamps (x11_display->display, timestamp); + + return timestamp; +} + +/** + * meta_x11_display_xwindow_is_a_no_focus_window: + * @x11_display: A #MetaX11Display + * @xwindow: An X11 window + * + * Returns: %TRUE iff window is one of mutter's internal "no focus" windows + * which will have the focus when there is no actual client window focused. + */ +gboolean +meta_x11_display_xwindow_is_a_no_focus_window (MetaX11Display *x11_display, + Window xwindow) +{ + return xwindow == x11_display->no_focus_window; +} + +void +meta_x11_display_increment_event_serial (MetaX11Display *x11_display) + +{ + /* We just make some random X request */ + XDeleteProperty (x11_display->xdisplay, + x11_display->leader_window, + x11_display->atom__MOTIF_WM_HINTS); +} + +void +meta_x11_display_update_active_window_hint (MetaX11Display *x11_display) +{ + MetaWindow *focus_window = x11_display->display->focus_window; + gulong data[1]; + + if (x11_display->display->closing) + return; /* Leave old value for a replacement */ + + if (focus_window) + data[0] = focus_window->xwindow; + else + data[0] = None; + + meta_error_trap_push (x11_display); + XChangeProperty (x11_display->xdisplay, + x11_display->xroot, + x11_display->atom__NET_ACTIVE_WINDOW, + XA_WINDOW, + 32, PropModeReplace, (guchar*) data, 1); + meta_error_trap_pop (x11_display); +} + +static void +request_xserver_input_focus_change (MetaX11Display *x11_display, + MetaWindow *meta_window, + Window xwindow, + guint32 timestamp) +{ + gulong serial; + + if (meta_display_timestamp_too_old (x11_display->display, ×tamp)) + return; + + meta_error_trap_push (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 (x11_display->xdisplay); + + serial = XNextRequest (x11_display->xdisplay); + + XSetInputFocus (x11_display->xdisplay, + xwindow, + RevertToPointerRoot, + timestamp); + + XChangeProperty (x11_display->xdisplay, + x11_display->timestamp_pinging_window, + x11_display->atom__MUTTER_FOCUS_SET, + XA_STRING, 8, PropModeAppend, NULL, 0); + + XUngrabServer (x11_display->xdisplay); + XFlush (x11_display->xdisplay); + + meta_display_update_focus_window (x11_display->display, + meta_window, + xwindow, + serial, + TRUE); + + meta_error_trap_pop (x11_display); + + x11_display->display->last_focus_time = timestamp; + + if (meta_window == NULL || meta_window != x11_display->display->autoraise_window) + meta_display_remove_autoraise_callback (x11_display->display); +} + +void +meta_x11_display_set_input_focus_window (MetaX11Display *x11_display, + MetaWindow *window, + gboolean focus_frame, + guint32 timestamp) +{ + request_xserver_input_focus_change (x11_display, + window, + focus_frame ? window->frame->xwindow : window->xwindow, + timestamp); +} + +void +meta_x11_display_set_input_focus_xwindow (MetaX11Display *x11_display, + Window window, + guint32 timestamp) +{ + request_xserver_input_focus_change (x11_display, + NULL, + window, + timestamp); +} + +void +meta_x11_display_focus_the_no_focus_window (MetaX11Display *x11_display, + guint32 timestamp) +{ + request_xserver_input_focus_change (x11_display, + NULL, + x11_display->no_focus_window, + timestamp); +} diff --git a/src/x11/window-props.c b/src/x11/window-props.c index 601bdac07..8b238a92e 100644 --- a/src/x11/window-props.c +++ b/src/x11/window-props.c @@ -104,7 +104,7 @@ meta_window_reload_property_from_xwindow (MetaWindow *window, init_prop_value (window, hooks, &value); - meta_prop_get_values (window->display, xwindow, + meta_prop_get_values (window->display->x11_display, xwindow, &value, 1); reload_prop_value (window, hooks, &value, @@ -146,7 +146,7 @@ meta_window_load_initial_properties (MetaWindow *window) } n_properties = j; - meta_prop_get_values (window->display, window->xwindow, + meta_prop_get_values (window->display->x11_display, window->xwindow, values, n_properties); j = 0; @@ -569,7 +569,7 @@ set_title_text (MetaWindow *window, *target = g_strdup (title); if (modified && atom != None) - meta_prop_set_utf8_string_hint (window->display, + meta_prop_set_utf8_string_hint (window->display->x11_display, window->xwindow, atom, *target); diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c index 16b09b565..894dab785 100644 --- a/src/x11/window-x11.c +++ b/src/x11/window-x11.c @@ -105,7 +105,7 @@ read_client_leader (MetaDisplay *display, { Window retval = None; - meta_prop_get_window (display, xwindow, + meta_prop_get_window (display->x11_display, xwindow, display->x11_display->atom_WM_CLIENT_LEADER, &retval); @@ -160,7 +160,7 @@ update_sm_hints (MetaWindow *window) window->xclient_leader = leader; - if (meta_prop_get_latin1_string (window->display, leader, + if (meta_prop_get_latin1_string (window->display->x11_display, leader, window->display->x11_display->atom_SM_CLIENT_ID, &str)) { @@ -180,7 +180,7 @@ update_sm_hints (MetaWindow *window) char *str; str = NULL; - if (meta_prop_get_latin1_string (window->display, window->xwindow, + if (meta_prop_get_latin1_string (window->display->x11_display, window->xwindow, window->display->x11_display->atom_SM_CLIENT_ID, &str)) { @@ -748,10 +748,10 @@ meta_window_x11_focus (MetaWindow *window, { meta_topic (META_DEBUG_FOCUS, "Focusing frame of %s\n", window->desc); - meta_display_set_input_focus_window (window->display, - window, - TRUE, - timestamp); + meta_x11_display_set_input_focus_window (window->display->x11_display, + window, + TRUE, + timestamp); } else { @@ -760,10 +760,10 @@ meta_window_x11_focus (MetaWindow *window, meta_topic (META_DEBUG_FOCUS, "Setting input focus on %s since input = true\n", window->desc); - meta_display_set_input_focus_window (window->display, - window, - FALSE, - timestamp); + meta_x11_display_set_input_focus_window (window->display->x11_display, + window, + FALSE, + timestamp); } if (window->take_focus) @@ -786,9 +786,8 @@ meta_window_x11_focus (MetaWindow *window, */ if (window->display->focus_window != NULL && window->display->focus_window->unmanaging) - meta_display_focus_the_no_focus_window (window->display, - window->screen, - timestamp); + meta_x11_display_focus_the_no_focus_window (window->display->x11_display, + timestamp); } request_take_focus (window, timestamp); @@ -1320,7 +1319,7 @@ meta_window_x11_update_struts (MetaWindow *window) old_struts = window->struts; new_struts = NULL; - if (meta_prop_get_cardinal_list (window->display, + if (meta_prop_get_cardinal_list (window->display->x11_display, window->xwindow, window->display->x11_display->atom__NET_WM_STRUT_PARTIAL, &struts, &nitems)) @@ -1386,7 +1385,7 @@ meta_window_x11_update_struts (MetaWindow *window) } if (!new_struts && - meta_prop_get_cardinal_list (window->display, + meta_prop_get_cardinal_list (window->display->x11_display, window->xwindow, window->display->x11_display->atom__NET_WM_STRUT, &struts, &nitems)) @@ -2950,7 +2949,7 @@ maybe_filter_xwindow (MetaDisplay *display, { uint32_t old_state; - if (!meta_prop_get_cardinal_with_atom_type (display, xwindow, + if (!meta_prop_get_cardinal_with_atom_type (display->x11_display, xwindow, display->x11_display->atom_WM_STATE, display->x11_display->atom_WM_STATE, &old_state)) @@ -2970,24 +2969,23 @@ maybe_filter_xwindow (MetaDisplay *display, } static gboolean -is_our_xwindow (MetaDisplay *display, - MetaScreen *screen, +is_our_xwindow (MetaX11Display *x11_display, Window xwindow, XWindowAttributes *attrs) { - if (xwindow == screen->no_focus_window) + if (xwindow == x11_display->no_focus_window) return TRUE; - if (xwindow == screen->wm_sn_selection_window) + if (xwindow == x11_display->wm_sn_selection_window) return TRUE; - if (xwindow == screen->wm_cm_selection_window) + if (xwindow == x11_display->wm_cm_selection_window) return TRUE; - if (xwindow == display->x11_display->guard_window) + if (xwindow == x11_display->guard_window) return TRUE; - if (xwindow == screen->composite_overlay_window) + if (xwindow == x11_display->composite_overlay_window) return TRUE; { @@ -3040,7 +3038,7 @@ meta_window_x11_new (MetaDisplay *display, meta_verbose ("Attempting to manage 0x%lx\n", xwindow); - if (meta_display_xwindow_is_a_no_focus_window (display, xwindow)) + if (meta_x11_display_xwindow_is_a_no_focus_window (x11_display, xwindow)) { meta_verbose ("Not managing no_focus_window 0x%lx\n", xwindow); @@ -3075,7 +3073,7 @@ meta_window_x11_new (MetaDisplay *display, goto error; } - if (is_our_xwindow (display, screen, xwindow, &attrs)) + if (is_our_xwindow (x11_display, xwindow, &attrs)) { meta_verbose ("Not managing our own windows\n"); goto error; @@ -3094,7 +3092,7 @@ meta_window_x11_new (MetaDisplay *display, uint32_t state; /* WM_STATE isn't a cardinal, it's type WM_STATE, but is an int */ - if (!(meta_prop_get_cardinal_with_atom_type (display, xwindow, + if (!(meta_prop_get_cardinal_with_atom_type (x11_display, xwindow, x11_display->atom_WM_STATE, x11_display->atom_WM_STATE, &state) && diff --git a/src/x11/xprops.c b/src/x11/xprops.c index be0d47423..db42386dc 100644 --- a/src/x11/xprops.c +++ b/src/x11/xprops.c @@ -96,14 +96,14 @@ from The Open Group. typedef struct { - MetaDisplay *display; - Window xwindow; - Atom xatom; - Atom type; - int format; - unsigned long n_items; - unsigned long bytes_after; - unsigned char *prop; + MetaX11Display *x11_display; + Window xwindow; + Atom xatom; + Atom type; + int format; + unsigned long n_items; + unsigned long bytes_after; + unsigned char *prop; } GetPropertyResults; static gboolean @@ -112,7 +112,7 @@ validate_or_free_results (GetPropertyResults *results, Atom expected_type, gboolean must_have_items) { - MetaX11Display *x11_display = results->display->x11_display; + MetaX11Display *x11_display = results->x11_display; char *type_name; char *expected_name; char *prop_name; @@ -227,16 +227,16 @@ async_get_property_finish (xcb_connection_t *xcb_conn, } static gboolean -get_property (MetaDisplay *display, +get_property (MetaX11Display *x11_display, Window xwindow, Atom xatom, Atom req_type, GetPropertyResults *results) { xcb_get_property_cookie_t cookie; - xcb_connection_t *xcb_conn = XGetXCBConnection (display->x11_display->xdisplay); + xcb_connection_t *xcb_conn = XGetXCBConnection (x11_display->xdisplay); - results->display = display; + results->x11_display = x11_display; results->xwindow = xwindow; results->xatom = xatom; results->prop = NULL; @@ -280,18 +280,18 @@ cardinal_list_from_results (GetPropertyResults *results, } gboolean -meta_prop_get_cardinal_list (MetaDisplay *display, - Window xwindow, - Atom xatom, - uint32_t **cardinals_p, - int *n_cardinals_p) +meta_prop_get_cardinal_list (MetaX11Display *x11_display, + Window xwindow, + Atom xatom, + uint32_t **cardinals_p, + int *n_cardinals_p) { GetPropertyResults results; *cardinals_p = NULL; *n_cardinals_p = 0; - if (!get_property (display, xwindow, xatom, XA_CARDINAL, + if (!get_property (x11_display, xwindow, xatom, XA_CARDINAL, &results)) return FALSE; @@ -334,16 +334,16 @@ motif_hints_from_results (GetPropertyResults *results, } gboolean -meta_prop_get_motif_hints (MetaDisplay *display, - Window xwindow, - Atom xatom, - MotifWmHints **hints_p) +meta_prop_get_motif_hints (MetaX11Display *x11_display, + Window xwindow, + Atom xatom, + MotifWmHints **hints_p) { GetPropertyResults results; *hints_p = NULL; - if (!get_property (display, xwindow, xatom, AnyPropertyType, + if (!get_property (x11_display, xwindow, xatom, AnyPropertyType, &results)) return FALSE; @@ -368,16 +368,16 @@ latin1_string_from_results (GetPropertyResults *results, } gboolean -meta_prop_get_latin1_string (MetaDisplay *display, - Window xwindow, - Atom xatom, - char **str_p) +meta_prop_get_latin1_string (MetaX11Display *x11_display, + Window xwindow, + Atom xatom, + char **str_p) { GetPropertyResults results; *str_p = NULL; - if (!get_property (display, xwindow, xatom, XA_STRING, + if (!get_property (x11_display, xwindow, xatom, XA_STRING, &results)) return FALSE; @@ -391,7 +391,7 @@ utf8_string_from_results (GetPropertyResults *results, *str_p = NULL; if (!validate_or_free_results (results, 8, - results->display->x11_display->atom_UTF8_STRING, FALSE)) + results->x11_display->atom_UTF8_STRING, FALSE)) return FALSE; if (results->n_items > 0 && @@ -399,7 +399,7 @@ utf8_string_from_results (GetPropertyResults *results, { char *name; - name = XGetAtomName (results->display->x11_display->xdisplay, results->xatom); + name = XGetAtomName (results->x11_display->xdisplay, results->xatom); meta_warning ("Property %s on window 0x%lx contained invalid UTF-8\n", name, results->xwindow); meta_XFree (name); @@ -432,7 +432,7 @@ utf8_list_from_results (GetPropertyResults *results, *n_str_p = 0; if (!validate_or_free_results (results, 8, - results->display->x11_display->atom_UTF8_STRING, FALSE)) + results->x11_display->atom_UTF8_STRING, FALSE)) return FALSE; /* I'm not sure this is right, but I'm guessing the @@ -464,9 +464,9 @@ utf8_list_from_results (GetPropertyResults *results, { char *name; - meta_error_trap_push (results->display->x11_display); - name = XGetAtomName (results->display->x11_display->xdisplay, results->xatom); - meta_error_trap_pop (results->display->x11_display); + meta_error_trap_push (results->x11_display); + name = XGetAtomName (results->x11_display->xdisplay, results->xatom); + meta_error_trap_pop (results->x11_display); meta_warning ("Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n", name, results->xwindow, i); meta_XFree (name); @@ -494,18 +494,18 @@ utf8_list_from_results (GetPropertyResults *results, /* returns g_malloc not Xmalloc memory */ gboolean -meta_prop_get_utf8_list (MetaDisplay *display, - Window xwindow, - Atom xatom, - char ***str_p, - int *n_str_p) +meta_prop_get_utf8_list (MetaX11Display *x11_display, + Window xwindow, + Atom xatom, + char ***str_p, + int *n_str_p) { GetPropertyResults results; *str_p = NULL; - if (!get_property (display, xwindow, xatom, - display->x11_display->atom_UTF8_STRING, + if (!get_property (x11_display, xwindow, xatom, + x11_display->atom_UTF8_STRING, &results)) return FALSE; @@ -513,13 +513,11 @@ meta_prop_get_utf8_list (MetaDisplay *display, } void -meta_prop_set_utf8_string_hint (MetaDisplay *display, - Window xwindow, - Atom atom, - const char *val) +meta_prop_set_utf8_string_hint (MetaX11Display *x11_display, + Window xwindow, + Atom atom, + const char *val) { - MetaX11Display *x11_display = display->x11_display; - meta_error_trap_push (x11_display); XChangeProperty (x11_display->xdisplay, xwindow, atom, @@ -576,16 +574,16 @@ counter_list_from_results (GetPropertyResults *results, } gboolean -meta_prop_get_window (MetaDisplay *display, - Window xwindow, - Atom xatom, - Window *window_p) +meta_prop_get_window (MetaX11Display *x11_display, + Window xwindow, + Atom xatom, + Window *window_p) { GetPropertyResults results; *window_p = None; - if (!get_property (display, xwindow, xatom, XA_WINDOW, + if (!get_property (x11_display, xwindow, xatom, XA_WINDOW, &results)) return FALSE; @@ -593,12 +591,12 @@ meta_prop_get_window (MetaDisplay *display, } gboolean -meta_prop_get_cardinal (MetaDisplay *display, - Window xwindow, - Atom xatom, - uint32_t *cardinal_p) +meta_prop_get_cardinal (MetaX11Display *x11_display, + Window xwindow, + Atom xatom, + uint32_t *cardinal_p) { - return meta_prop_get_cardinal_with_atom_type (display, xwindow, xatom, + return meta_prop_get_cardinal_with_atom_type (x11_display, xwindow, xatom, XA_CARDINAL, cardinal_p); } @@ -618,17 +616,17 @@ cardinal_with_atom_type_from_results (GetPropertyResults *results, } gboolean -meta_prop_get_cardinal_with_atom_type (MetaDisplay *display, - Window xwindow, - Atom xatom, - Atom prop_type, - uint32_t *cardinal_p) +meta_prop_get_cardinal_with_atom_type (MetaX11Display *x11_display, + Window xwindow, + Atom xatom, + Atom prop_type, + uint32_t *cardinal_p) { GetPropertyResults results; *cardinal_p = 0; - if (!get_property (display, xwindow, xatom, prop_type, + if (!get_property (x11_display, xwindow, xatom, prop_type, &results)) return FALSE; @@ -672,7 +670,7 @@ text_property_from_results (GetPropertyResults *results, tp.format = results->format; tp.nitems = results->n_items; - *utf8_str_p = text_property_to_utf8 (results->display->x11_display->xdisplay, &tp); + *utf8_str_p = text_property_to_utf8 (results->x11_display->xdisplay, &tp); if (tp.value != NULL) XFree (tp.value); @@ -856,14 +854,14 @@ latin1_to_utf8 (const char *text) } void -meta_prop_get_values (MetaDisplay *display, - Window xwindow, - MetaPropValue *values, - int n_values) +meta_prop_get_values (MetaX11Display *x11_display, + Window xwindow, + MetaPropValue *values, + int n_values) { int i; xcb_get_property_cookie_t *tasks; - xcb_connection_t *xcb_conn = XGetXCBConnection (display->x11_display->xdisplay); + xcb_connection_t *xcb_conn = XGetXCBConnection (x11_display->xdisplay); meta_verbose ("Requesting %d properties of 0x%lx at once\n", n_values, xwindow); @@ -892,7 +890,7 @@ meta_prop_get_values (MetaDisplay *display, break; case META_PROP_VALUE_UTF8_LIST: case META_PROP_VALUE_UTF8: - values[i].required_type = display->x11_display->atom_UTF8_STRING; + values[i].required_type = x11_display->atom_UTF8_STRING; break; case META_PROP_VALUE_STRING: case META_PROP_VALUE_STRING_AS_UTF8: @@ -938,7 +936,7 @@ meta_prop_get_values (MetaDisplay *display, /* Get replies for all our tasks */ meta_topic (META_DEBUG_SYNC, "Syncing to get %d GetProperty replies in %s\n", n_values, G_STRFUNC); - XSync (display->x11_display->xdisplay, False); + XSync (x11_display->xdisplay, False); /* Collect results, should arrive in order requested */ i = 0; @@ -957,7 +955,7 @@ meta_prop_get_values (MetaDisplay *display, goto next; } - results.display = display; + results.x11_display = x11_display; results.xwindow = xwindow; results.xatom = values[i].atom; results.prop = NULL; diff --git a/src/x11/xprops.h b/src/x11/xprops.h index d52a90c0f..5a1c90071 100644 --- a/src/x11/xprops.h +++ b/src/x11/xprops.h @@ -71,42 +71,42 @@ typedef struct { /* These all return the memory from Xlib, so require an XFree() * when they return TRUE. They return TRUE on success. */ -gboolean meta_prop_get_motif_hints (MetaDisplay *display, - Window xwindow, - Atom xatom, - MotifWmHints **hints_p); -gboolean meta_prop_get_cardinal_list (MetaDisplay *display, - Window xwindow, - Atom xatom, - uint32_t **cardinals_p, - int *n_cardinals_p); -gboolean meta_prop_get_latin1_string (MetaDisplay *display, - Window xwindow, - Atom xatom, - char **str_p); -gboolean meta_prop_get_utf8_list (MetaDisplay *display, - Window xwindow, - Atom xatom, - char ***str_p, - int *n_str_p); +gboolean meta_prop_get_motif_hints (MetaX11Display *x11_display, + Window xwindow, + Atom xatom, + MotifWmHints **hints_p); +gboolean meta_prop_get_cardinal_list (MetaX11Display *x11_display, + Window xwindow, + Atom xatom, + uint32_t **cardinals_p, + int *n_cardinals_p); +gboolean meta_prop_get_latin1_string (MetaX11Display *x11_display, + Window xwindow, + Atom xatom, + char **str_p); +gboolean meta_prop_get_utf8_list (MetaX11Display *x11_display, + Window xwindow, + Atom xatom, + char ***str_p, + int *n_str_p); void meta_prop_set_utf8_string_hint - (MetaDisplay *display, - Window xwindow, - Atom atom, - const char *val); -gboolean meta_prop_get_window (MetaDisplay *display, - Window xwindow, - Atom xatom, - Window *window_p); -gboolean meta_prop_get_cardinal (MetaDisplay *display, - Window xwindow, - Atom xatom, - uint32_t *cardinal_p); -gboolean meta_prop_get_cardinal_with_atom_type (MetaDisplay *display, - Window xwindow, - Atom xatom, - Atom prop_type, - uint32_t *cardinal_p); + (MetaX11Display *x11_display, + Window xwindow, + Atom atom, + const char *val); +gboolean meta_prop_get_window (MetaX11Display *x11_display, + Window xwindow, + Atom xatom, + Window *window_p); +gboolean meta_prop_get_cardinal (MetaX11Display *x11_display, + Window xwindow, + Atom xatom, + uint32_t *cardinal_p); +gboolean meta_prop_get_cardinal_with_atom_type (MetaX11Display *x11_display, + Window xwindow, + Atom xatom, + Atom prop_type, + uint32_t *cardinal_p); typedef enum { @@ -183,10 +183,10 @@ typedef struct * else type comes back as it originated, and the data * is filled in. */ -void meta_prop_get_values (MetaDisplay *display, - Window xwindow, - MetaPropValue *values, - int n_values); +void meta_prop_get_values (MetaX11Display *x11_display, + Window xwindow, + MetaPropValue *values, + int n_values); void meta_prop_free_values (MetaPropValue *values, int n_values); |