From 1530f2751308eaeead81b5fe4e6c7add64b0a0c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Armin=20Krezovi=C4=87?= Date: Sat, 26 Aug 2017 20:54:39 +0200 Subject: [PATCH] Move X11 event, icon cache and property handling to MetaX11Display https://bugzilla.gnome.org/show_bug.cgi?id=759538 --- src/core/display.c | 5 - src/core/screen-private.h | 3 - src/core/screen.c | 167 ----------------------- src/x11/events.c | 268 +++++++++++++++++++------------------ src/x11/events.h | 4 +- src/x11/iconcache.c | 74 +++++----- src/x11/iconcache.h | 14 +- src/x11/meta-x11-display.c | 148 ++++++++++++++++++++ src/x11/window-props.c | 4 +- src/x11/window-x11.c | 2 +- 10 files changed, 333 insertions(+), 356 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index 4a661b491..491f36e6a 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -687,8 +687,6 @@ meta_display_open (void) meta_bell_init (display); - meta_display_init_events_x11 (display); - display->last_focus_time = timestamp; display->last_user_time = timestamp; display->compositor = NULL; @@ -913,9 +911,6 @@ meta_display_close (MetaDisplay *display, if (display->compositor) meta_compositor_destroy (display->compositor); - /* Stop caring about events */ - meta_display_free_events_x11 (display); - if (display->x11_display) { g_signal_emit (display, display_signals[X11_DISPLAY_CLOSING], 0); diff --git a/src/core/screen-private.h b/src/core/screen-private.h index 6dbf5a30d..1239d5a58 100644 --- a/src/core/screen-private.h +++ b/src/core/screen-private.h @@ -137,9 +137,6 @@ void meta_screen_workspace_switched (MetaScreen *screen, void meta_screen_set_active_workspace_hint (MetaScreen *screen); -gboolean meta_screen_handle_xevent (MetaScreen *screen, - XEvent *xevent); - MetaLogicalMonitor * meta_screen_xinerama_index_to_logical_monitor (MetaScreen *screen, int index); diff --git a/src/core/screen.c b/src/core/screen.c index a690cd9e6..78f275f67 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -69,9 +69,6 @@ static void set_workspace_names (MetaScreen *screen); static void prefs_changed_callback (MetaPreference pref, gpointer data); -static void set_desktop_geometry_hint (MetaScreen *screen); -static void set_desktop_viewport_hint (MetaScreen *screen); - enum { PROP_N_WORKSPACES = 1, @@ -250,95 +247,6 @@ meta_screen_init (MetaScreen *screen) { } -static int -set_wm_check_hint (MetaScreen *screen) -{ - MetaX11Display *x11_display = screen->display->x11_display; - unsigned long data[1]; - - g_return_val_if_fail (x11_display->leader_window != None, 0); - - data[0] = x11_display->leader_window; - - XChangeProperty (x11_display->xdisplay, - x11_display->xroot, - x11_display->atom__NET_SUPPORTING_WM_CHECK, - XA_WINDOW, - 32, PropModeReplace, (guchar*) data, 1); - - return Success; -} - -static void -unset_wm_check_hint (MetaScreen *screen) -{ - MetaX11Display *x11_display = screen->display->x11_display; - - XDeleteProperty (x11_display->xdisplay, - x11_display->xroot, - x11_display->atom__NET_SUPPORTING_WM_CHECK); -} - -static int -set_supported_hint (MetaScreen *screen) -{ - MetaX11Display *x11_display = screen->display->x11_display; - - Atom atoms[] = { -#define EWMH_ATOMS_ONLY -#define item(x) x11_display->atom_##x, -#include -#undef item -#undef EWMH_ATOMS_ONLY - - x11_display->atom__GTK_FRAME_EXTENTS, - x11_display->atom__GTK_SHOW_WINDOW_MENU, - x11_display->atom__GTK_EDGE_CONSTRAINTS, - }; - - XChangeProperty (x11_display->xdisplay, - x11_display->xroot, - x11_display->atom__NET_SUPPORTED, - XA_ATOM, - 32, PropModeReplace, - (guchar*) atoms, G_N_ELEMENTS(atoms)); - - return Success; -} - -static int -set_wm_icon_size_hint (MetaScreen *screen) -{ - MetaX11Display *x11_display = screen->display->x11_display; - -#define N_VALS 6 - gulong vals[N_VALS]; - - /* We've bumped the real icon size up to 96x96, but - * we really should not add these sorts of constraints - * on clients still using the legacy WM_HINTS interface. - */ -#define LEGACY_ICON_SIZE 32 - - /* min width, min height, max w, max h, width inc, height inc */ - vals[0] = LEGACY_ICON_SIZE; - vals[1] = LEGACY_ICON_SIZE; - vals[2] = LEGACY_ICON_SIZE; - vals[3] = LEGACY_ICON_SIZE; - vals[4] = 0; - vals[5] = 0; -#undef LEGACY_ICON_SIZE - - XChangeProperty (x11_display->xdisplay, - x11_display->xroot, - x11_display->atom_WM_ICON_SIZE, - XA_CARDINAL, - 32, PropModeReplace, (guchar*) vals, N_VALS); - - return Success; -#undef N_VALS -} - static MetaScreenX11LogicalMonitorData * get_screen_x11_logical_monitor_data (MetaLogicalMonitor *logical_monitor) { @@ -505,16 +413,6 @@ meta_screen_new (MetaDisplay *display, reload_logical_monitors (screen); - set_wm_icon_size_hint (screen); - - set_supported_hint (screen); - - set_wm_check_hint (screen); - - set_desktop_viewport_hint (screen); - - set_desktop_geometry_hint (screen); - meta_screen_update_workspace_layout (screen); /* Screens must have at least one workspace at all times, @@ -586,8 +484,6 @@ meta_screen_free (MetaScreen *screen, meta_ui_free (screen->ui); - unset_wm_check_hint (screen); - if (screen->work_area_later != 0) meta_later_remove (screen->work_area_later); if (screen->check_fullscreen_later != 0) @@ -670,55 +566,6 @@ set_number_of_spaces_hint (MetaScreen *screen, meta_error_trap_pop (x11_display); } -static void -set_desktop_geometry_hint (MetaScreen *screen) -{ - MetaX11Display *x11_display = screen->display->x11_display; - unsigned long data[2]; - - if (screen->closing > 0) - return; - - data[0] = screen->display->rect.width; - data[1] = screen->display->rect.height; - - meta_verbose ("Setting _NET_DESKTOP_GEOMETRY to %lu, %lu\n", data[0], data[1]); - - meta_error_trap_push (x11_display); - XChangeProperty (x11_display->xdisplay, - x11_display->xroot, - x11_display->atom__NET_DESKTOP_GEOMETRY, - XA_CARDINAL, - 32, PropModeReplace, (guchar*) data, 2); - meta_error_trap_pop (x11_display); -} - -static void -set_desktop_viewport_hint (MetaScreen *screen) -{ - MetaX11Display *x11_display = screen->display->x11_display; - unsigned long data[2]; - - if (screen->closing > 0) - return; - - /* - * Mutter does not implement viewports, so this is a fixed 0,0 - */ - data[0] = 0; - data[1] = 0; - - meta_verbose ("Setting _NET_DESKTOP_VIEWPORT to 0, 0\n"); - - meta_error_trap_push (x11_display); - XChangeProperty (x11_display->xdisplay, - x11_display->xroot, - x11_display->atom__NET_DESKTOP_VIEWPORT, - XA_CARDINAL, - 32, PropModeReplace, (guchar*) data, 2); - meta_error_trap_pop (x11_display); -} - void meta_screen_remove_workspace (MetaScreen *screen, MetaWorkspace *workspace, guint32 timestamp) @@ -1768,7 +1615,6 @@ void meta_screen_on_monitors_changed (MetaScreen *screen) { reload_logical_monitors (screen); - set_desktop_geometry_hint (screen); meta_screen_queue_check_fullscreen (screen); } @@ -2268,16 +2114,3 @@ meta_screen_get_monitor_in_fullscreen (MetaScreen *screen, /* We use -1 as a flag to mean "not known yet" for notification purposes */ return logical_monitor->in_fullscreen == TRUE; } - -gboolean -meta_screen_handle_xevent (MetaScreen *screen, - XEvent *xevent) -{ - MetaBackend *backend = meta_get_backend (); - MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend); - - if (meta_cursor_tracker_handle_xevent (cursor_tracker, xevent)) - return TRUE; - - return FALSE; -} diff --git a/src/x11/events.c b/src/x11/events.c index 811276841..9aaaed4f8 100644 --- a/src/x11/events.c +++ b/src/x11/events.c @@ -33,6 +33,7 @@ #include "display-private.h" #include "window-private.h" #include "workspace-private.h" +#include "backends/meta-cursor-tracker-private.h" #include "backends/x11/meta-backend-x11.h" #include "x11/meta-x11-display-private.h" #include "x11/window-x11.h" @@ -45,11 +46,11 @@ #endif static XIEvent * -get_input_event (MetaDisplay *display, - XEvent *event) +get_input_event (MetaX11Display *x11_display, + XEvent *event) { if (event->type == GenericEvent && - event->xcookie.extension == display->x11_display->xinput_opcode) + event->xcookie.extension == x11_display->xinput_opcode) { XIEvent *input_event; @@ -97,8 +98,8 @@ get_input_event (MetaDisplay *display, } static Window -xievent_get_modified_window (MetaDisplay *display, - XIEvent *input_event) +xievent_get_modified_window (MetaX11Display *x11_display, + XIEvent *input_event) { switch (input_event->evtype) { @@ -128,13 +129,13 @@ xievent_get_modified_window (MetaDisplay *display, * for substructure */ static Window -event_get_modified_window (MetaDisplay *display, +event_get_modified_window (MetaX11Display *x11_display, XEvent *event) { - XIEvent *input_event = get_input_event (display, event); + XIEvent *input_event = get_input_event (x11_display, event); if (input_event) - return xievent_get_modified_window (display, input_event); + return xievent_get_modified_window (x11_display, input_event); switch (event->type) { @@ -189,8 +190,8 @@ event_get_modified_window (MetaDisplay *display, return None; default: - if (META_X11_DISPLAY_HAS_SHAPE (display->x11_display) && - event->type == (display->x11_display->shape_event_base + ShapeNotify)) + if (META_X11_DISPLAY_HAS_SHAPE (x11_display) && + event->type == (x11_display->shape_event_base + ShapeNotify)) { XShapeEvent *sev = (XShapeEvent*) event; return sev->window; @@ -201,10 +202,10 @@ event_get_modified_window (MetaDisplay *display, } static guint32 -event_get_time (MetaDisplay *display, - XEvent *event) +event_get_time (MetaX11Display *x11_display, + XEvent *event) { - XIEvent *input_event = get_input_event (display, event); + XIEvent *input_event = get_input_event (x11_display, event); if (input_event) return input_event->time; @@ -352,10 +353,10 @@ alarm_state_to_string (XSyncAlarmState state) } static void -meta_spew_xi2_event (MetaDisplay *display, - XIEvent *input_event, - const char **name_p, - char **extra_p) +meta_spew_xi2_event (MetaX11Display *x11_display, + XIEvent *input_event, + const char **name_p, + char **extra_p) { const char *name = NULL; char *extra = NULL; @@ -412,10 +413,10 @@ meta_spew_xi2_event (MetaDisplay *display, } static void -meta_spew_core_event (MetaDisplay *display, - XEvent *event, - const char **name_p, - char **extra_p) +meta_spew_core_event (MetaX11Display *x11_display, + XEvent *event, + const char **name_p, + char **extra_p) { const char *name = NULL; char *extra = NULL; @@ -535,10 +536,10 @@ meta_spew_core_event (MetaDisplay *display, name = "PropertyNotify"; - meta_error_trap_push (display->x11_display); - str = XGetAtomName (display->x11_display->xdisplay, + meta_error_trap_push (x11_display); + str = XGetAtomName (x11_display->xdisplay, event->xproperty.atom); - meta_error_trap_pop (display->x11_display); + meta_error_trap_pop (x11_display); if (event->xproperty.state == PropertyNewValue) state = "PropertyNewValue"; @@ -569,10 +570,10 @@ meta_spew_core_event (MetaDisplay *display, { char *str; name = "ClientMessage"; - meta_error_trap_push (display->x11_display); - str = XGetAtomName (display->x11_display->xdisplay, + meta_error_trap_push (x11_display); + str = XGetAtomName (x11_display->xdisplay, event->xclient.message_type); - meta_error_trap_pop (display->x11_display); + meta_error_trap_pop (x11_display); extra = g_strdup_printf ("type: %s format: %d\n", str ? str : "(unknown atom)", event->xclient.format); @@ -583,8 +584,8 @@ meta_spew_core_event (MetaDisplay *display, name = "MappingNotify"; break; default: - if (META_X11_DISPLAY_HAS_XSYNC (display->x11_display) && - event->type == (display->x11_display->xsync_event_base + XSyncAlarmNotify)) + if (META_X11_DISPLAY_HAS_XSYNC (x11_display) && + event->type == (x11_display->xsync_event_base + XSyncAlarmNotify)) { XSyncAlarmNotifyEvent *aevent = (XSyncAlarmNotifyEvent*) event; @@ -601,8 +602,8 @@ meta_spew_core_event (MetaDisplay *display, alarm_state_to_string (aevent->state)); } else - if (META_X11_DISPLAY_HAS_SHAPE (display->x11_display) && - event->type == (display->x11_display->shape_event_base + ShapeNotify)) + if (META_X11_DISPLAY_HAS_SHAPE (x11_display) && + event->type == (x11_display->shape_event_base + ShapeNotify)) { XShapeEvent *sev = (XShapeEvent*) event; @@ -632,8 +633,8 @@ meta_spew_core_event (MetaDisplay *display, } static char * -meta_spew_event (MetaDisplay *display, - XEvent *event) +meta_spew_event (MetaX11Display *x11_display, + XEvent *event) { const char *name = NULL; char *extra = NULL; @@ -641,14 +642,14 @@ meta_spew_event (MetaDisplay *display, char *ret; XIEvent *input_event; - input_event = get_input_event (display, event); + input_event = get_input_event (x11_display, event); if (input_event) - meta_spew_xi2_event (display, input_event, &name, &extra); + meta_spew_xi2_event (x11_display, input_event, &name, &extra); else - meta_spew_core_event (display, event, &name, &extra); + meta_spew_core_event (x11_display, event, &name, &extra); - if (event->xany.window == display->x11_display->xroot) + if (event->xany.window == x11_display->xroot) winname = g_strdup_printf ("root"); else winname = g_strdup_printf ("0x%lx", event->xany.window); @@ -665,8 +666,8 @@ meta_spew_event (MetaDisplay *display, } G_GNUC_UNUSED static void -meta_spew_event_print (MetaDisplay *display, - XEvent *event) +meta_spew_event_print (MetaX11Display *x11_display, + XEvent *event) { char *event_str; @@ -675,27 +676,28 @@ meta_spew_event_print (MetaDisplay *display, event->type == NoExpose) return; - if (event->type == (display->x11_display->damage_event_base + XDamageNotify)) + if (event->type == (x11_display->damage_event_base + XDamageNotify)) return; - if (event->type == (display->x11_display->xsync_event_base + XSyncAlarmNotify)) + if (event->type == (x11_display->xsync_event_base + XSyncAlarmNotify)) return; if (event->type == PropertyNotify && - event->xproperty.atom == display->x11_display->atom__NET_WM_USER_TIME) + event->xproperty.atom == x11_display->atom__NET_WM_USER_TIME) return; - event_str = meta_spew_event (display, event); + event_str = meta_spew_event (x11_display, event); g_print ("%s\n", event_str); g_free (event_str); } static gboolean -handle_window_focus_event (MetaDisplay *display, - MetaWindow *window, - XIEnterEvent *event, - unsigned long serial) +handle_window_focus_event (MetaX11Display *x11_display, + MetaWindow *window, + XIEnterEvent *event, + unsigned long serial) { + MetaDisplay *display = x11_display->display; MetaWindow *focus_window; #ifdef WITH_VERBOSE_MODE const char *window_type; @@ -712,10 +714,10 @@ handle_window_focus_event (MetaDisplay *display, else window_type = "unknown client window"; } - else if (meta_x11_display_xwindow_is_a_no_focus_window (display->x11_display, + else if (meta_x11_display_xwindow_is_a_no_focus_window (x11_display, event->event)) window_type = "no_focus_window"; - else if (event->event == display->x11_display->xroot) + else if (event->event == x11_display->xroot) window_type = "root window"; else window_type = "unknown window"; @@ -773,8 +775,8 @@ handle_window_focus_event (MetaDisplay *display, if (event->evtype == XI_FocusIn) { - display->x11_display->server_focus_window = event->event; - display->x11_display->server_focus_serial = serial; + x11_display->server_focus_window = event->event; + x11_display->server_focus_serial = serial; focus_window = window; } else if (event->evtype == XI_FocusOut) @@ -787,8 +789,8 @@ handle_window_focus_event (MetaDisplay *display, return FALSE; } - display->x11_display->server_focus_window = None; - display->x11_display->server_focus_serial = serial; + x11_display->server_focus_window = None; + x11_display->server_focus_serial = serial; focus_window = NULL; } else @@ -799,14 +801,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->x11_display->server_focus_serial > display->x11_display->focus_serial || + if (x11_display->server_focus_serial > x11_display->focus_serial || (!display->focused_by_us && - display->x11_display->server_focus_serial == display->x11_display->focus_serial)) + x11_display->server_focus_serial == x11_display->focus_serial)) { meta_display_update_focus_window (display, focus_window, focus_window ? focus_window->xwindow : None, - display->x11_display->server_focus_serial, + x11_display->server_focus_serial, FALSE); return TRUE; } @@ -817,15 +819,15 @@ handle_window_focus_event (MetaDisplay *display, } static gboolean -crossing_serial_is_ignored (MetaDisplay *display, - unsigned long serial) +crossing_serial_is_ignored (MetaX11Display *x11_display, + unsigned long serial) { int i; i = 0; while (i < N_IGNORED_CROSSING_SERIALS) { - if (display->ignored_crossing_serials[i] == serial) + if (x11_display->display->ignored_crossing_serials[i] == serial) return TRUE; ++i; } @@ -833,13 +835,14 @@ crossing_serial_is_ignored (MetaDisplay *display, } static gboolean -handle_input_xevent (MetaDisplay *display, - XIEvent *input_event, - unsigned long serial) +handle_input_xevent (MetaX11Display *x11_display, + XIEvent *input_event, + unsigned long serial) { XIEnterEvent *enter_event = (XIEnterEvent *) input_event; Window modified; MetaWindow *window; + MetaDisplay *display = x11_display->display; MetaScreen *screen = display->screen; if (input_event == NULL) @@ -856,13 +859,13 @@ handle_input_xevent (MetaDisplay *display, return FALSE; } - modified = xievent_get_modified_window (display, input_event); + modified = xievent_get_modified_window (x11_display, input_event); window = modified != None ? - meta_x11_display_lookup_x_window (display->x11_display, modified) : + meta_x11_display_lookup_x_window (x11_display, modified) : NULL; /* If this is an event for a GTK+ widget, let GTK+ handle it. */ - if (meta_ui_window_is_widget (display->screen->ui, modified)) + if (meta_ui_window_is_widget (screen->ui, modified)) return FALSE; switch (input_event->evtype) @@ -874,7 +877,7 @@ handle_input_xevent (MetaDisplay *display, /* Check if we've entered a window; do this even if window->has_focus to * avoid races. */ - if (window && !crossing_serial_is_ignored (display, serial) && + if (window && !crossing_serial_is_ignored (x11_display, serial) && enter_event->mode != XINotifyGrab && enter_event->mode != XINotifyUngrab && enter_event->detail != XINotifyInferior && @@ -899,7 +902,7 @@ handle_input_xevent (MetaDisplay *display, break; case XI_FocusIn: case XI_FocusOut: - if (handle_window_focus_event (display, window, enter_event, serial) && + if (handle_window_focus_event (x11_display, window, enter_event, serial) && enter_event->event == enter_event->root) { if (enter_event->evtype == XI_FocusIn && @@ -911,7 +914,7 @@ handle_input_xevent (MetaDisplay *display, "125492). Setting the default focus window.\n"); meta_workspace_focus_default_window (screen->active_workspace, NULL, - meta_display_get_current_time_roundtrip (display)); + meta_x11_display_get_current_time_roundtrip (x11_display)); } else if (enter_event->evtype == XI_FocusIn && enter_event->mode == XINotifyNormal && @@ -923,7 +926,7 @@ handle_input_xevent (MetaDisplay *display, "153220). Setting the default focus window.\n"); meta_workspace_focus_default_window (screen->active_workspace, NULL, - meta_display_get_current_time_roundtrip (display)); + meta_x11_display_get_current_time_roundtrip (x11_display)); } } break; @@ -938,9 +941,10 @@ handle_input_xevent (MetaDisplay *display, } static void -process_request_frame_extents (MetaDisplay *display, +process_request_frame_extents (MetaX11Display *x11_display, XEvent *event) { + MetaDisplay *display = x11_display->display; /* The X window whose frame extents will be set. */ Window xwindow = event->xclient.window; unsigned long data[4] = { 0, 0, 0, 0 }; @@ -951,9 +955,9 @@ 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->x11_display, + hints_set = meta_prop_get_motif_hints (x11_display, xwindow, - display->x11_display->atom__MOTIF_WM_HINTS, + x11_display->atom__MOTIF_WM_HINTS, &hints); if ((hints_set && hints->decorations) || !hints_set) { @@ -975,25 +979,23 @@ process_request_frame_extents (MetaDisplay *display, "to top = %lu, left = %lu, bottom = %lu, right = %lu\n", xwindow, data[0], data[1], data[2], data[3]); - meta_error_trap_push (display->x11_display); - XChangeProperty (display->x11_display->xdisplay, xwindow, - display->x11_display->atom__NET_FRAME_EXTENTS, + meta_error_trap_push (x11_display); + XChangeProperty (x11_display->xdisplay, xwindow, + x11_display->atom__NET_FRAME_EXTENTS, XA_CARDINAL, 32, PropModeReplace, (guchar*) data, 4); - meta_error_trap_pop (display->x11_display); + meta_error_trap_pop (x11_display); meta_XFree (hints); } /* from fvwm2, Copyright Matthias Clasen, Dominik Vogt */ static gboolean -convert_property (MetaDisplay *display, - MetaScreen *screen, - Window w, - Atom target, - Atom property) +convert_property (MetaX11Display *x11_display, + Window w, + Atom target, + Atom property) { - MetaX11Display *x11_display = display->x11_display; #define N_TARGETS 4 Atom conversion_targets[N_TARGETS]; long icccm_version[] = { 2, 0 }; @@ -1037,11 +1039,9 @@ convert_property (MetaDisplay *display, /* from fvwm2, Copyright Matthias Clasen, Dominik Vogt */ static void -process_selection_request (MetaDisplay *display, - XEvent *event) +process_selection_request (MetaX11Display *x11_display, + XEvent *event) { - MetaX11Display *x11_display = display->x11_display; - MetaScreen *screen = display->screen; XSelectionEvent reply; if (x11_display->wm_sn_selection_window != event->xselectionrequest.owner || @@ -1100,7 +1100,7 @@ process_selection_request (MetaDisplay *display, i = 0; while (i < (int) num) { - if (!convert_property (display, screen, + if (!convert_property (x11_display, event->xselectionrequest.requestor, adata[i], adata[i+1])) adata[i+1] = None; @@ -1123,7 +1123,7 @@ process_selection_request (MetaDisplay *display, if (event->xselectionrequest.property == None) event->xselectionrequest.property = event->xselectionrequest.target; - if (convert_property (display, screen, + if (convert_property (x11_display, event->xselectionrequest.requestor, event->xselectionrequest.target, event->xselectionrequest.property)) @@ -1138,18 +1138,18 @@ process_selection_request (MetaDisplay *display, } static gboolean -process_selection_clear (MetaDisplay *display, - XEvent *event) +process_selection_clear (MetaX11Display *x11_display, + XEvent *event) { - if (display->x11_display->wm_sn_selection_window != event->xselectionclear.window || - display->x11_display->wm_sn_atom != event->xselectionclear.selection) + if (x11_display->wm_sn_selection_window != event->xselectionclear.window || + x11_display->wm_sn_atom != event->xselectionclear.selection) { char *str; - meta_error_trap_push (display->x11_display); - str = XGetAtomName (display->x11_display->xdisplay, + meta_error_trap_push (x11_display); + str = XGetAtomName (x11_display->xdisplay, event->xselectionclear.selection); - meta_error_trap_pop (display->x11_display); + meta_error_trap_pop (x11_display); meta_verbose ("Selection clear with selection %s window 0x%lx not a WM_Sn selection we recognize\n", str ? str : "(bad atom)", event->xselectionclear.window); @@ -1160,9 +1160,10 @@ process_selection_clear (MetaDisplay *display, } meta_verbose ("Got selection clear for on display %s\n", - display->x11_display->name); + x11_display->name); - meta_display_unmanage_screen (display, display->screen, + meta_display_unmanage_screen (x11_display->display, + x11_display->display->screen, event->xselectionclear.time); return TRUE; } @@ -1193,17 +1194,17 @@ notify_bell (MetaDisplay *display, } static gboolean -handle_other_xevent (MetaDisplay *display, - XEvent *event) +handle_other_xevent (MetaX11Display *x11_display, + XEvent *event) { - MetaX11Display *x11_display = display->x11_display; + MetaDisplay *display = x11_display->display; Window modified; MetaWindow *window; MetaWindow *property_for_window; gboolean frame_was_receiver; gboolean bypass_gtk = FALSE; - modified = event_get_modified_window (display, event); + modified = event_get_modified_window (x11_display, event); window = modified != None ? meta_x11_display_lookup_x_window (x11_display, modified) : NULL; frame_was_receiver = (window && window->frame && modified == window->frame->xwindow); @@ -1237,7 +1238,7 @@ handle_other_xevent (MetaDisplay *display, if (x11_display->alarm_filter && x11_display->alarm_filter (x11_display, (XSyncAlarmNotifyEvent*)event, - x11_display->alarm_filter_data)) + x11_display->alarm_filter_data)) bypass_gtk = TRUE; } @@ -1506,7 +1507,7 @@ handle_other_xevent (MetaDisplay *display, } break; case SelectionRequest: - process_selection_request (display, event); + process_selection_request (x11_display, event); break; case SelectionNotify: break; @@ -1560,7 +1561,7 @@ handle_other_xevent (MetaDisplay *display, meta_warning ("Received a NET_CURRENT_DESKTOP message " "from a broken (outdated) client who sent " "a 0 timestamp\n"); - time = meta_display_get_current_time_roundtrip (display); + time = meta_x11_display_get_current_time_roundtrip (x11_display); } if (workspace) @@ -1588,7 +1589,7 @@ handle_other_xevent (MetaDisplay *display, showing_desktop = event->xclient.data.l[0] != 0; /* FIXME: Braindead protocol doesn't have a timestamp */ - timestamp = meta_display_get_current_time_roundtrip (display); + timestamp = meta_x11_display_get_current_time_roundtrip (x11_display); meta_verbose ("Request to %s desktop\n", showing_desktop ? "show" : "hide"); @@ -1624,7 +1625,7 @@ handle_other_xevent (MetaDisplay *display, x11_display->atom__NET_REQUEST_FRAME_EXTENTS) { meta_verbose ("Received _NET_REQUEST_FRAME_EXTENTS message\n"); - process_request_frame_extents (display, event); + process_request_frame_extents (x11_display, event); } } break; @@ -1709,16 +1710,18 @@ window_has_xwindow (MetaWindow *window, * dealing with all the kinds of events that might turn up. */ static gboolean -meta_display_handle_xevent (MetaDisplay *display, - XEvent *event) +meta_x11_display_handle_xevent (MetaX11Display *x11_display, + XEvent *event) { + MetaDisplay *display = x11_display->display; MetaBackend *backend = meta_get_backend (); Window modified; gboolean bypass_compositor = FALSE, bypass_gtk = FALSE; XIEvent *input_event; + MetaCursorTracker *cursor_tracker; #if 0 - meta_spew_event_print (display, event); + meta_spew_event_print (x11_display, event); #endif if (meta_startup_notification_handle_xevent (display->startup_notification, @@ -1737,42 +1740,43 @@ meta_display_handle_xevent (MetaDisplay *display, } #endif - display->current_time = event_get_time (display, event); + display->current_time = event_get_time (x11_display, event); if (META_IS_BACKEND_X11 (backend)) meta_backend_x11_handle_event (META_BACKEND_X11 (backend), event); if (display->focused_by_us && - event->xany.serial > display->x11_display->focus_serial && + event->xany.serial > x11_display->focus_serial && display->focus_window && - !window_has_xwindow (display->focus_window, display->x11_display->server_focus_window)) + !window_has_xwindow (display->focus_window, 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->x11_display->server_focus_window), - display->x11_display->server_focus_window, - display->x11_display->server_focus_serial, + meta_x11_display_lookup_x_window (x11_display, + x11_display->server_focus_window), + x11_display->server_focus_window, + x11_display->server_focus_serial, FALSE); } - if (event->xany.window == display->x11_display->xroot) + if (event->xany.window == x11_display->xroot) { - if (meta_screen_handle_xevent (display->screen, event)) + cursor_tracker = meta_backend_get_cursor_tracker (backend); + if (meta_cursor_tracker_handle_xevent (cursor_tracker, event)) { bypass_gtk = bypass_compositor = TRUE; goto out; } } - modified = event_get_modified_window (display, event); + modified = event_get_modified_window (x11_display, event); - input_event = get_input_event (display, event); + input_event = get_input_event (x11_display, event); if (event->type == UnmapNotify) { - if (meta_ui_window_should_not_cause_focus (display->x11_display->xdisplay, + if (meta_ui_window_should_not_cause_focus (x11_display->xdisplay, modified)) { meta_display_add_ignored_crossing_serial (display, event->xany.serial); @@ -1783,20 +1787,20 @@ meta_display_handle_xevent (MetaDisplay *display, } #ifdef HAVE_XI23 - if (meta_x11_display_process_barrier_xevent (display->x11_display, input_event)) + if (meta_x11_display_process_barrier_xevent (x11_display, input_event)) { bypass_gtk = bypass_compositor = TRUE; goto out; } #endif /* HAVE_XI23 */ - if (handle_input_xevent (display, input_event, event->xany.serial)) + if (handle_input_xevent (x11_display, input_event, event->xany.serial)) { bypass_gtk = bypass_compositor = TRUE; goto out; } - if (handle_other_xevent (display, event)) + if (handle_other_xevent (x11_display, event)) { bypass_gtk = TRUE; goto out; @@ -1804,7 +1808,7 @@ meta_display_handle_xevent (MetaDisplay *display, if (event->type == SelectionClear) { - if (process_selection_clear (display, event)) + if (process_selection_clear (x11_display, event)) { /* This means we called meta_display_unmanage_screen, which * means the MetaDisplay is effectively dead. We don't want @@ -1818,7 +1822,7 @@ meta_display_handle_xevent (MetaDisplay *display, if (!bypass_compositor) { MetaWindow *window = modified != None ? - meta_x11_display_lookup_x_window (display->x11_display, modified) : + meta_x11_display_lookup_x_window (x11_display, modified) : NULL; if (meta_compositor_process_event (display->compositor, event, window)) @@ -1835,22 +1839,22 @@ xevent_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data) { - MetaDisplay *display = data; + MetaX11Display *x11_display = data; - if (meta_display_handle_xevent (display, xevent)) + if (meta_x11_display_handle_xevent (x11_display, xevent)) return GDK_FILTER_REMOVE; else return GDK_FILTER_CONTINUE; } void -meta_display_init_events_x11 (MetaDisplay *display) +meta_x11_display_init_events (MetaX11Display *x11_display) { - gdk_window_add_filter (NULL, xevent_filter, display); + gdk_window_add_filter (NULL, xevent_filter, x11_display); } void -meta_display_free_events_x11 (MetaDisplay *display) +meta_x11_display_free_events (MetaX11Display *x11_display) { - gdk_window_remove_filter (NULL, xevent_filter, display); + gdk_window_remove_filter (NULL, xevent_filter, x11_display); } diff --git a/src/x11/events.h b/src/x11/events.h index 6aa073b1d..ee15253a6 100644 --- a/src/x11/events.h +++ b/src/x11/events.h @@ -25,7 +25,7 @@ #ifndef META_EVENTS_X11_H #define META_EVENTS_X11_H -void meta_display_init_events_x11 (MetaDisplay *display); -void meta_display_free_events_x11 (MetaDisplay *display); +void meta_x11_display_init_events (MetaX11Display *x11_display); +void meta_x11_display_free_events (MetaX11Display *x11_display); #endif diff --git a/src/x11/iconcache.c b/src/x11/iconcache.c index 636a2d1e7..7c9cf5225 100644 --- a/src/x11/iconcache.c +++ b/src/x11/iconcache.c @@ -189,7 +189,7 @@ argbdata_to_surface (gulong *argb_data, int w, int h) } static gboolean -read_rgb_icon (MetaDisplay *display, +read_rgb_icon (MetaX11Display *x11_display, Window xwindow, int ideal_width, int ideal_height, @@ -210,16 +210,16 @@ read_rgb_icon (MetaDisplay *display, int mini_w, mini_h; gulong *data_as_long; - meta_error_trap_push (display->x11_display); + meta_error_trap_push (x11_display); type = None; data = NULL; - result = XGetWindowProperty (display->x11_display->xdisplay, + result = XGetWindowProperty (x11_display->xdisplay, xwindow, - display->x11_display->atom__NET_WM_ICON, + x11_display->atom__NET_WM_ICON, 0, G_MAXLONG, False, XA_CARDINAL, &type, &format, &nitems, &bytes_after, &data); - err = meta_error_trap_pop_with_return (display->x11_display); + err = meta_error_trap_pop_with_return (x11_display); if (err != Success || result != Success) @@ -258,11 +258,11 @@ read_rgb_icon (MetaDisplay *display, } static void -get_pixmap_geometry (MetaDisplay *display, - Pixmap pixmap, - int *w, - int *h, - int *d) +get_pixmap_geometry (MetaX11Display *x11_display, + Pixmap pixmap, + int *w, + int *h, + int *d) { Window root_ignored; int x_ignored, y_ignored; @@ -277,7 +277,7 @@ get_pixmap_geometry (MetaDisplay *display, if (d) *d = 1; - XGetGeometry (display->x11_display->xdisplay, + XGetGeometry (x11_display->xdisplay, pixmap, &root_ignored, &x_ignored, &y_ignored, &width, &height, &border_width_ignored, &depth); @@ -328,32 +328,32 @@ surface_from_pixmap (Display *xdisplay, Pixmap xpixmap, } static gboolean -try_pixmap_and_mask (MetaDisplay *display, +try_pixmap_and_mask (MetaX11Display *x11_display, Pixmap src_pixmap, Pixmap src_mask, cairo_surface_t **iconp) { - Display *xdisplay = display->x11_display->xdisplay; + Display *xdisplay = x11_display->xdisplay; cairo_surface_t *icon, *mask = NULL; int w, h, d; if (src_pixmap == None) return FALSE; - meta_error_trap_push (display->x11_display); + meta_error_trap_push (x11_display); - get_pixmap_geometry (display, src_pixmap, &w, &h, &d); + get_pixmap_geometry (x11_display, src_pixmap, &w, &h, &d); icon = surface_from_pixmap (xdisplay, src_pixmap, w, h); if (icon && src_mask != None) { - get_pixmap_geometry (display, src_mask, &w, &h, &d); + get_pixmap_geometry (x11_display, src_mask, &w, &h, &d); if (d == 1) mask = surface_from_pixmap (xdisplay, src_mask, w, h); } - meta_error_trap_pop (display->x11_display); + meta_error_trap_pop (x11_display); if (icon && mask) { @@ -388,10 +388,10 @@ try_pixmap_and_mask (MetaDisplay *display, } static void -get_kwm_win_icon (MetaDisplay *display, - Window xwindow, - Pixmap *pixmap, - Pixmap *mask) +get_kwm_win_icon (MetaX11Display *x11_display, + Window xwindow, + Pixmap *pixmap, + Pixmap *mask) { Atom type; int format; @@ -404,23 +404,23 @@ get_kwm_win_icon (MetaDisplay *display, *pixmap = None; *mask = None; - meta_error_trap_push (display->x11_display); + meta_error_trap_push (x11_display); icons = NULL; - result = XGetWindowProperty (display->x11_display->xdisplay, xwindow, - display->x11_display->atom__KWM_WIN_ICON, + result = XGetWindowProperty (x11_display->xdisplay, xwindow, + x11_display->atom__KWM_WIN_ICON, 0, G_MAXLONG, False, - display->x11_display->atom__KWM_WIN_ICON, + x11_display->atom__KWM_WIN_ICON, &type, &format, &nitems, &bytes_after, &data); icons = (Pixmap *)data; - err = meta_error_trap_pop_with_return (display->x11_display); + err = meta_error_trap_pop_with_return (x11_display); if (err != Success || result != Success) return; - if (type != display->x11_display->atom__KWM_WIN_ICON) + if (type != x11_display->atom__KWM_WIN_ICON) { XFree (icons); return; @@ -448,13 +448,13 @@ meta_icon_cache_init (MetaIconCache *icon_cache) } void -meta_icon_cache_property_changed (MetaIconCache *icon_cache, - MetaDisplay *display, - Atom atom) +meta_icon_cache_property_changed (MetaIconCache *icon_cache, + MetaX11Display *x11_display, + Atom atom) { - if (atom == display->x11_display->atom__NET_WM_ICON) + if (atom == x11_display->atom__NET_WM_ICON) icon_cache->net_wm_icon_dirty = TRUE; - else if (atom == display->x11_display->atom__KWM_WIN_ICON) + else if (atom == x11_display->atom__KWM_WIN_ICON) icon_cache->kwm_win_icon_dirty = TRUE; else if (atom == XA_WM_HINTS) icon_cache->wm_hints_dirty = TRUE; @@ -479,7 +479,7 @@ meta_icon_cache_get_icon_invalidated (MetaIconCache *icon_cache) } gboolean -meta_read_icons (MetaScreen *screen, +meta_read_icons (MetaX11Display *x11_display, Window xwindow, MetaIconCache *icon_cache, Pixmap wm_hints_pixmap, @@ -515,7 +515,7 @@ meta_read_icons (MetaScreen *screen, { icon_cache->net_wm_icon_dirty = FALSE; - if (read_rgb_icon (screen->display, xwindow, + if (read_rgb_icon (x11_display, xwindow, ideal_width, ideal_height, ideal_mini_width, ideal_mini_height, iconp, mini_iconp)) @@ -544,7 +544,7 @@ meta_read_icons (MetaScreen *screen, mask != icon_cache->prev_mask) && pixmap != None) { - if (try_pixmap_and_mask (screen->display, pixmap, mask, iconp)) + if (try_pixmap_and_mask (x11_display, pixmap, mask, iconp)) { *mini_iconp = cairo_surface_reference (*iconp); icon_cache->prev_pixmap = pixmap; @@ -563,13 +563,13 @@ meta_read_icons (MetaScreen *screen, icon_cache->kwm_win_icon_dirty = FALSE; - get_kwm_win_icon (screen->display, xwindow, &pixmap, &mask); + get_kwm_win_icon (x11_display, xwindow, &pixmap, &mask); if ((pixmap != icon_cache->prev_pixmap || mask != icon_cache->prev_mask) && pixmap != None) { - if (try_pixmap_and_mask (screen->display, pixmap, mask, iconp)) + if (try_pixmap_and_mask (x11_display, pixmap, mask, iconp)) { *mini_iconp = cairo_surface_reference (*iconp); icon_cache->prev_pixmap = pixmap; diff --git a/src/x11/iconcache.h b/src/x11/iconcache.h index f5ba4060b..a4b63edf0 100644 --- a/src/x11/iconcache.h +++ b/src/x11/iconcache.h @@ -22,7 +22,7 @@ #ifndef META_ICON_CACHE_H #define META_ICON_CACHE_H -#include "screen-private.h" +#include "x11/meta-x11-display-private.h" typedef struct _MetaIconCache MetaIconCache; @@ -50,13 +50,13 @@ struct _MetaIconCache guint net_wm_icon_dirty : 1; }; -void meta_icon_cache_init (MetaIconCache *icon_cache); -void meta_icon_cache_property_changed (MetaIconCache *icon_cache, - MetaDisplay *display, - Atom atom); -gboolean meta_icon_cache_get_icon_invalidated (MetaIconCache *icon_cache); +void meta_icon_cache_init (MetaIconCache *icon_cache); +void meta_icon_cache_property_changed (MetaIconCache *icon_cache, + MetaX11Display *x11_display, + Atom atom); +gboolean meta_icon_cache_get_icon_invalidated (MetaIconCache *icon_cache); -gboolean meta_read_icons (MetaScreen *screen, +gboolean meta_read_icons (MetaX11Display *x11_display, Window xwindow, MetaIconCache *icon_cache, Pixmap wm_hints_pixmap, diff --git a/src/x11/meta-x11-display.c b/src/x11/meta-x11-display.c index 062977541..c454a562a 100644 --- a/src/x11/meta-x11-display.c +++ b/src/x11/meta-x11-display.c @@ -54,6 +54,7 @@ #include "meta/errors.h" #include "meta/main.h" +#include "x11/events.h" #include "x11/group-props.h" #include "x11/window-props.h" #include "x11/xprops.h" @@ -74,6 +75,7 @@ static void on_monitors_changed (MetaDisplay *display, MetaX11Display *x11_display); static void update_cursor_theme (MetaX11Display *x11_display); +static void unset_wm_check_hint (MetaX11Display *x11_display); static void meta_x11_display_dispose (GObject *object) @@ -157,6 +159,8 @@ meta_x11_display_dispose (GObject *object) if (x11_display->xroot != None) { + unset_wm_check_hint (x11_display); + meta_error_trap_push (x11_display); XSelectInput (x11_display->xdisplay, x11_display->xroot, 0); if (meta_error_trap_pop_with_return (x11_display) != Success) @@ -169,6 +173,8 @@ meta_x11_display_dispose (GObject *object) if (x11_display->xdisplay) { + meta_x11_display_free_events (x11_display); + x11_display->xdisplay = NULL; } @@ -371,6 +377,134 @@ query_xi_extension (MetaX11Display *x11_display) meta_fatal ("X server doesn't have the XInput extension, version 2.2 or newer\n"); } +static void +set_desktop_geometry_hint (MetaX11Display *x11_display) +{ + unsigned long data[2]; + + if (x11_display->display->closing > 0) + return; + + data[0] = x11_display->display->rect.width; + data[1] = x11_display->display->rect.height; + + meta_verbose ("Setting _NET_DESKTOP_GEOMETRY to %lu, %lu\n", data[0], data[1]); + + meta_error_trap_push (x11_display); + XChangeProperty (x11_display->xdisplay, + x11_display->xroot, + x11_display->atom__NET_DESKTOP_GEOMETRY, + XA_CARDINAL, + 32, PropModeReplace, (guchar*) data, 2); + meta_error_trap_pop (x11_display); +} + +static void +set_desktop_viewport_hint (MetaX11Display *x11_display) +{ + unsigned long data[2]; + + if (x11_display->display->closing > 0) + return; + + /* + * Mutter does not implement viewports, so this is a fixed 0,0 + */ + data[0] = 0; + data[1] = 0; + + meta_verbose ("Setting _NET_DESKTOP_VIEWPORT to 0, 0\n"); + + meta_error_trap_push (x11_display); + XChangeProperty (x11_display->xdisplay, + x11_display->xroot, + x11_display->atom__NET_DESKTOP_VIEWPORT, + XA_CARDINAL, + 32, PropModeReplace, (guchar*) data, 2); + meta_error_trap_pop (x11_display); +} + +static int +set_wm_check_hint (MetaX11Display *x11_display) +{ + unsigned long data[1]; + + g_return_val_if_fail (x11_display->leader_window != None, 0); + + data[0] = x11_display->leader_window; + + XChangeProperty (x11_display->xdisplay, + x11_display->xroot, + x11_display->atom__NET_SUPPORTING_WM_CHECK, + XA_WINDOW, + 32, PropModeReplace, (guchar*) data, 1); + + return Success; +} + +static void +unset_wm_check_hint (MetaX11Display *x11_display) +{ + XDeleteProperty (x11_display->xdisplay, + x11_display->xroot, + x11_display->atom__NET_SUPPORTING_WM_CHECK); +} + +static int +set_supported_hint (MetaX11Display *x11_display) +{ + Atom atoms[] = { +#define EWMH_ATOMS_ONLY +#define item(x) x11_display->atom_##x, +#include "x11/atomnames.h" +#undef item +#undef EWMH_ATOMS_ONLY + + x11_display->atom__GTK_FRAME_EXTENTS, + x11_display->atom__GTK_SHOW_WINDOW_MENU, + }; + + XChangeProperty (x11_display->xdisplay, + x11_display->xroot, + x11_display->atom__NET_SUPPORTED, + XA_ATOM, + 32, PropModeReplace, + (guchar*) atoms, G_N_ELEMENTS(atoms)); + + return Success; +} + +static int +set_wm_icon_size_hint (MetaX11Display *x11_display) +{ +#define N_VALS 6 + gulong vals[N_VALS]; + + /* We've bumped the real icon size up to 96x96, but + * we really should not add these sorts of constraints + * on clients still using the legacy WM_HINTS interface. + */ +#define LEGACY_ICON_SIZE 32 + + /* min width, min height, max w, max h, width inc, height inc */ + vals[0] = LEGACY_ICON_SIZE; + vals[1] = LEGACY_ICON_SIZE; + vals[2] = LEGACY_ICON_SIZE; + vals[3] = LEGACY_ICON_SIZE; + vals[4] = 0; + vals[5] = 0; +#undef LEGACY_ICON_SIZE + + XChangeProperty (x11_display->xdisplay, + x11_display->xroot, + x11_display->atom_WM_ICON_SIZE, + XA_CARDINAL, + 32, PropModeReplace, (guchar*) vals, N_VALS); + + return Success; +#undef N_VALS +} + static Window take_manager_selection (MetaX11Display *x11_display, Window xroot, @@ -755,6 +889,18 @@ meta_x11_display_new (MetaDisplay *display, GError **error) XMapWindow (xdisplay, x11_display->no_focus_window); /* Done with no_focus_window stuff */ + meta_x11_display_init_events (x11_display); + + set_wm_icon_size_hint (x11_display); + + set_supported_hint (x11_display); + + set_wm_check_hint (x11_display); + + set_desktop_viewport_hint (x11_display); + + set_desktop_geometry_hint (x11_display); + return x11_display; } @@ -1064,6 +1210,8 @@ static void on_monitors_changed (MetaDisplay *display, MetaX11Display *x11_display) { + set_desktop_geometry_hint (x11_display); + /* Resize the guard window to fill the screen again. */ if (x11_display->guard_window != None) { diff --git a/src/x11/window-props.c b/src/x11/window-props.c index 8b238a92e..b16c34984 100644 --- a/src/x11/window-props.c +++ b/src/x11/window-props.c @@ -289,7 +289,7 @@ reload_icon (MetaWindow *window, MetaWindowX11Private *priv = window_x11->priv; meta_icon_cache_property_changed (&priv->icon_cache, - window->display, + window->display->x11_display, atom); meta_window_queue(window, META_QUEUE_UPDATE_ICON); } @@ -1615,7 +1615,7 @@ reload_wm_hints (MetaWindow *window, meta_window_set_urgent (window, urgent); meta_icon_cache_property_changed (&priv->icon_cache, - window->display, + window->display->x11_display, XA_WM_HINTS); meta_window_queue (window, META_QUEUE_UPDATE_ICON | META_QUEUE_MOVE_RESIZE); diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c index 894dab785..7dc998d8e 100644 --- a/src/x11/window-x11.c +++ b/src/x11/window-x11.c @@ -1485,7 +1485,7 @@ meta_window_x11_update_icon (MetaWindow *window, MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); - return meta_read_icons (window->screen, + return meta_read_icons (window->display->x11_display, window->xwindow, &priv->icon_cache, priv->wm_hints_pixmap,