[mutter/wip/wayland-clutter-events-2: 7/19] display: Split out other event handling as well
- From: Jasper St. Pierre <jstpierre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wip/wayland-clutter-events-2: 7/19] display: Split out other event handling as well
- Date: Sat, 5 Oct 2013 14:15:24 +0000 (UTC)
commit dbe979a2b9edcb91c9594ba1c331ab9a69e21e8e
Author: Jasper St. Pierre <jstpierre mecheye net>
Date: Thu Oct 3 17:13:48 2013 -0400
display: Split out other event handling as well
This vastly simplifies the code in event_callback and allows us to potentially
take more of this logic and punt it to Wayland-specific backends.
src/core/display.c | 1046 ++++++++++++++++++++++++++--------------------------
1 files changed, 523 insertions(+), 523 deletions(-)
---
diff --git a/src/core/display.c b/src/core/display.c
index c78bb8e..164cf71 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -2595,108 +2595,19 @@ reload_xkb_rules (MetaScreen *screen)
g_strfreev (names);
}
-/**
- * meta_display_handle_xevent:
- * @display: The MetaDisplay that events are coming from
- * @event: The event that just happened
- *
- * This is the most important function in the whole program. It is the heart,
- * it is the nexus, it is the Grand Central Station of Mutter's world.
- * When we create a #MetaDisplay, we ask GDK to pass *all* events for *all*
- * windows to this function. So every time anything happens that we might
- * want to know about, this function gets called. You see why it gets a bit
- * busy around here. Most of this function is a ginormous switch statement
- * dealing with all the kinds of events that might turn up.
- */
-gboolean
-meta_display_handle_xevent (MetaDisplay *display,
- XEvent *event)
+static gboolean
+handle_other_xevent (MetaDisplay *display,
+ XEvent *event)
{
+ Window modified;
MetaWindow *window;
MetaWindow *property_for_window;
- Window modified;
gboolean frame_was_receiver;
- gboolean bypass_compositor = FALSE, bypass_gtk = FALSE;
- XIEvent *input_event;
- MetaMonitorManager *monitor;
- MetaScreen *screen;
-
-#ifdef WITH_VERBOSE_MODE
- if (dump_events)
- meta_spew_event (display, event);
-#endif
-
-#ifdef HAVE_STARTUP_NOTIFICATION
- sn_display_process_event (display->sn_display, event);
-#endif
-
- /* Intercept XRandR events early and don't attempt any
- processing for them. We still let them through to Gdk though,
- so it can update its own internal state.
- */
- monitor = meta_monitor_manager_get ();
- if (meta_monitor_manager_handle_xevent (monitor, event))
- {
- bypass_compositor = TRUE;
- goto out;
- }
-
- display->current_time = event_get_time (display, event);
- display->monitor_cache_invalidated = TRUE;
-
- if (event->xany.serial > display->focus_serial &&
- display->focus_window &&
- display->focus_window->xwindow != display->server_focus_window)
- {
- meta_topic (META_DEBUG_FOCUS, "Earlier attempt to focus %s failed\n",
- display->focus_window->desc);
- update_focus_window (display,
- META_FOCUS_NONE,
- meta_display_lookup_x_window (display, display->server_focus_window),
- display->server_focus_window,
- display->server_focus_serial);
- }
-
- screen = meta_display_screen_for_root (display, event->xany.window);
- if (screen)
- {
- if (meta_screen_handle_xevent (screen, event))
- {
- bypass_gtk = bypass_compositor = TRUE;
- goto out;
- }
- }
+ gboolean bypass_gtk = FALSE;
modified = event_get_modified_window (display, event);
-
- input_event = get_input_event (display, event);
-
- if (event->type == UnmapNotify)
- {
- if (meta_ui_window_should_not_cause_focus (display->xdisplay,
- modified))
- {
- meta_display_add_ignored_crossing_serial (display, event->xany.serial);
- meta_topic (META_DEBUG_FOCUS,
- "Adding EnterNotify serial %lu to ignored focus serials\n",
- event->xany.serial);
- }
- }
- else if (input_event &&
- input_event->evtype == XI_Leave &&
- ((XILeaveEvent *)input_event)->mode == XINotifyUngrab &&
- modified == display->ungrab_should_not_cause_focus_window)
- {
- meta_display_add_ignored_crossing_serial (display, event->xany.serial);
- meta_topic (META_DEBUG_FOCUS,
- "Adding LeaveNotify serial %lu to ignored focus serials\n",
- event->xany.serial);
- }
-
- if (modified != None)
- window = meta_display_lookup_x_window (display, modified);
- else
- window = NULL;
+ window = modified != None ? meta_display_lookup_x_window (display, modified) : NULL;
+ frame_was_receiver = (window && window->frame && modified == window->frame->xwindow);
/* We only want to respond to _NET_WM_USER_TIME property notify
* events on _NET_WM_USER_TIME_WINDOW windows; in particular,
@@ -2709,20 +2620,6 @@ meta_display_handle_xevent (MetaDisplay *display,
window = NULL;
}
- frame_was_receiver = FALSE;
- if (window &&
- window->frame &&
- modified == window->frame->xwindow)
- {
- /* Note that if the frame and the client both have an
- * XGrabButton (as is normal with our setup), the event
- * goes to the frame.
- */
- frame_was_receiver = TRUE;
- meta_topic (META_DEBUG_EVENTS, "Frame was receiver of event for %s\n",
- window->desc);
- }
-
#ifdef HAVE_XSYNC
if (META_DISPLAY_HAS_XSYNC (display) &&
event->type == (display->xsync_event_base + XSyncAlarmNotify))
@@ -2772,475 +2669,578 @@ meta_display_handle_xevent (MetaDisplay *display,
}
#endif /* HAVE_SHAPE */
-#ifdef HAVE_XI23
- if (meta_display_process_barrier_event (display, input_event))
+ switch (event->type)
{
- bypass_gtk = bypass_compositor = TRUE;
- goto out;
- }
-#endif /* HAVE_XI23 */
+ case KeymapNotify:
+ break;
+ case Expose:
+ break;
+ case GraphicsExpose:
+ break;
+ case NoExpose:
+ break;
+ case VisibilityNotify:
+ break;
+ case CreateNotify:
+ {
+ MetaScreen *screen;
- /* libXi does not properly copy the serial to XI2 events, so pull it
- * from the parent XAnyEvent and pass it to handle_input_xevent.
- * See: https://bugs.freedesktop.org/show_bug.cgi?id=64687
- */
- if (handle_input_xevent (display, input_event, event->xany.serial))
- {
- bypass_gtk = bypass_compositor = TRUE;
- goto out;
- }
- else
- {
- switch (event->type)
+ screen = meta_display_screen_for_root (display,
+ event->xcreatewindow.parent);
+ if (screen)
+ meta_stack_tracker_create_event (screen->stack_tracker,
+ &event->xcreatewindow);
+ }
+ break;
+
+ case DestroyNotify:
+ {
+ MetaScreen *screen;
+
+ screen = meta_display_screen_for_root (display,
+ event->xdestroywindow.event);
+ if (screen)
+ meta_stack_tracker_destroy_event (screen->stack_tracker,
+ &event->xdestroywindow);
+ }
+ if (window)
{
- case KeymapNotify:
- break;
- case Expose:
- break;
- case GraphicsExpose:
- break;
- case NoExpose:
- break;
- case VisibilityNotify:
- break;
- case CreateNotify:
- {
- MetaScreen *screen;
+ /* FIXME: It sucks that DestroyNotify events don't come with
+ * a timestamp; could we do something better here? Maybe X
+ * will change one day?
+ */
+ guint32 timestamp;
+ timestamp = meta_display_get_current_time_roundtrip (display);
- screen = meta_display_screen_for_root (display,
- event->xcreatewindow.parent);
- if (screen)
- meta_stack_tracker_create_event (screen->stack_tracker,
- &event->xcreatewindow);
- }
- break;
-
- case DestroyNotify:
- {
- MetaScreen *screen;
+ if (display->grab_op != META_GRAB_OP_NONE &&
+ display->grab_window == window)
+ meta_display_end_grab_op (display, timestamp);
- screen = meta_display_screen_for_root (display,
- event->xdestroywindow.event);
- if (screen)
- meta_stack_tracker_destroy_event (screen->stack_tracker,
- &event->xdestroywindow);
- }
- if (window)
+ if (frame_was_receiver)
{
- /* FIXME: It sucks that DestroyNotify events don't come with
- * a timestamp; could we do something better here? Maybe X
- * will change one day?
- */
- guint32 timestamp;
- timestamp = meta_display_get_current_time_roundtrip (display);
+ meta_warning ("Unexpected destruction of frame 0x%lx, not sure if this should silently fail or
be considered a bug\n",
+ window->frame->xwindow);
+ meta_error_trap_push (display);
+ meta_window_destroy_frame (window->frame->window);
+ meta_error_trap_pop (display);
+ }
+ else
+ {
+ /* Unmanage destroyed window */
+ meta_window_unmanage (window, timestamp);
+ window = NULL;
+ }
+ }
+ break;
+ case UnmapNotify:
+ if (window)
+ {
+ /* FIXME: It sucks that UnmapNotify events don't come with
+ * a timestamp; could we do something better here? Maybe X
+ * will change one day?
+ */
+ guint32 timestamp;
+ timestamp = meta_display_get_current_time_roundtrip (display);
- if (display->grab_op != META_GRAB_OP_NONE &&
- display->grab_window == window)
- meta_display_end_grab_op (display, timestamp);
-
- if (frame_was_receiver)
- {
- meta_warning ("Unexpected destruction of frame 0x%lx, not sure if this should silently
fail or be considered a bug\n",
- window->frame->xwindow);
- meta_error_trap_push (display);
- meta_window_destroy_frame (window->frame->window);
- meta_error_trap_pop (display);
- }
- else
+ if (display->grab_op != META_GRAB_OP_NONE &&
+ display->grab_window == window &&
+ ((window->frame == NULL) || !window->frame->mapped))
+ meta_display_end_grab_op (display, timestamp);
+
+ if (!frame_was_receiver)
+ {
+ if (window->unmaps_pending == 0)
{
- /* Unmanage destroyed window */
+ meta_topic (META_DEBUG_WINDOW_STATE,
+ "Window %s withdrawn\n",
+ window->desc);
+
+ /* Unmanage withdrawn window */
+ window->withdrawn = TRUE;
meta_window_unmanage (window, timestamp);
window = NULL;
}
- }
- break;
- case UnmapNotify:
- if (window)
- {
- /* FIXME: It sucks that UnmapNotify events don't come with
- * a timestamp; could we do something better here? Maybe X
- * will change one day?
- */
- guint32 timestamp;
- timestamp = meta_display_get_current_time_roundtrip (display);
-
- if (display->grab_op != META_GRAB_OP_NONE &&
- display->grab_window == window &&
- ((window->frame == NULL) || !window->frame->mapped))
- meta_display_end_grab_op (display, timestamp);
-
- if (!frame_was_receiver)
+ else
{
- if (window->unmaps_pending == 0)
- {
- meta_topic (META_DEBUG_WINDOW_STATE,
- "Window %s withdrawn\n",
- window->desc);
-
- /* Unmanage withdrawn window */
- window->withdrawn = TRUE;
- meta_window_unmanage (window, timestamp);
- window = NULL;
- }
- else
- {
- window->unmaps_pending -= 1;
- meta_topic (META_DEBUG_WINDOW_STATE,
- "Received pending unmap, %d now pending\n",
- window->unmaps_pending);
- }
+ window->unmaps_pending -= 1;
+ meta_topic (META_DEBUG_WINDOW_STATE,
+ "Received pending unmap, %d now pending\n",
+ window->unmaps_pending);
}
}
- break;
- case MapNotify:
- /* NB: override redirect windows wont cause a map request so we
- * watch out for map notifies against any root windows too if a
- * compositor is enabled: */
- if (display->compositor && window == NULL
- && meta_display_screen_for_root (display, event->xmap.event))
- {
- window = meta_window_new (display, event->xmap.window,
- FALSE);
- }
- break;
- case MapRequest:
- if (window == NULL)
- {
- window = meta_window_new (display, event->xmaprequest.window,
- FALSE);
- }
- /* if frame was receiver it's some malicious send event or something */
- else if (!frame_was_receiver && window)
+ }
+ break;
+ case MapNotify:
+ /* NB: override redirect windows wont cause a map request so we
+ * watch out for map notifies against any root windows too if a
+ * compositor is enabled: */
+ if (display->compositor && window == NULL
+ && meta_display_screen_for_root (display, event->xmap.event))
+ {
+ window = meta_window_new (display, event->xmap.window,
+ FALSE);
+ }
+ break;
+ case MapRequest:
+ if (window == NULL)
+ {
+ window = meta_window_new (display, event->xmaprequest.window,
+ FALSE);
+ }
+ /* if frame was receiver it's some malicious send event or something */
+ else if (!frame_was_receiver && window)
+ {
+ meta_verbose ("MapRequest on %s mapped = %d minimized = %d\n",
+ window->desc, window->mapped, window->minimized);
+ if (window->minimized)
{
- meta_verbose ("MapRequest on %s mapped = %d minimized = %d\n",
- window->desc, window->mapped, window->minimized);
- if (window->minimized)
+ meta_window_unminimize (window);
+ if (window->workspace != window->screen->active_workspace)
{
- meta_window_unminimize (window);
- if (window->workspace != window->screen->active_workspace)
- {
- meta_verbose ("Changing workspace due to MapRequest mapped = %d minimized = %d\n",
- window->mapped, window->minimized);
- meta_window_change_workspace (window,
- window->screen->active_workspace);
- }
+ meta_verbose ("Changing workspace due to MapRequest mapped = %d minimized = %d\n",
+ window->mapped, window->minimized);
+ meta_window_change_workspace (window,
+ window->screen->active_workspace);
}
}
- break;
- case ReparentNotify:
- {
- MetaScreen *screen;
-
- screen = meta_display_screen_for_root (display,
- event->xconfigure.event);
- if (screen)
- meta_stack_tracker_reparent_event (screen->stack_tracker,
- &event->xreparent);
- }
- break;
- case ConfigureNotify:
- if (event->xconfigure.event != event->xconfigure.window)
- {
- MetaScreen *screen;
-
- screen = meta_display_screen_for_root (display,
- event->xconfigure.event);
- if (screen)
- meta_stack_tracker_configure_event (screen->stack_tracker,
- &event->xconfigure);
- }
+ }
+ break;
+ case ReparentNotify:
+ {
+ MetaScreen *screen;
- if (window && window->override_redirect)
- meta_window_configure_notify (window, &event->xconfigure);
+ screen = meta_display_screen_for_root (display,
+ event->xconfigure.event);
+ if (screen)
+ meta_stack_tracker_reparent_event (screen->stack_tracker,
+ &event->xreparent);
+ }
+ break;
+ case ConfigureNotify:
+ if (event->xconfigure.event != event->xconfigure.window)
+ {
+ MetaScreen *screen;
- break;
- case ConfigureRequest:
- /* This comment and code is found in both twm and fvwm */
- /*
- * According to the July 27, 1988 ICCCM draft, we should ignore size and
- * position fields in the WM_NORMAL_HINTS property when we map a window.
- * Instead, we'll read the current geometry. Therefore, we should respond
- * to configuration requests for windows which have never been mapped.
- */
- if (window == NULL)
- {
- unsigned int xwcm;
- XWindowChanges xwc;
-
- xwcm = event->xconfigurerequest.value_mask &
- (CWX | CWY | CWWidth | CWHeight | CWBorderWidth);
+ screen = meta_display_screen_for_root (display,
+ event->xconfigure.event);
+ if (screen)
+ meta_stack_tracker_configure_event (screen->stack_tracker,
+ &event->xconfigure);
+ }
- xwc.x = event->xconfigurerequest.x;
- xwc.y = event->xconfigurerequest.y;
- xwc.width = event->xconfigurerequest.width;
- xwc.height = event->xconfigurerequest.height;
- xwc.border_width = event->xconfigurerequest.border_width;
+ if (window && window->override_redirect)
+ meta_window_configure_notify (window, &event->xconfigure);
- meta_verbose ("Configuring withdrawn window to %d,%d %dx%d border %d (some values may not be
in mask)\n",
- xwc.x, xwc.y, xwc.width, xwc.height, xwc.border_width);
- meta_error_trap_push (display);
- XConfigureWindow (display->xdisplay, event->xconfigurerequest.window,
- xwcm, &xwc);
- meta_error_trap_pop (display);
- }
- else
- {
- if (!frame_was_receiver)
- meta_window_configure_request (window, event);
- }
- break;
- case GravityNotify:
- break;
- case ResizeRequest:
- break;
- case CirculateNotify:
- break;
- case CirculateRequest:
- break;
- case PropertyNotify:
+ break;
+ case ConfigureRequest:
+ /* This comment and code is found in both twm and fvwm */
+ /*
+ * According to the July 27, 1988 ICCCM draft, we should ignore size and
+ * position fields in the WM_NORMAL_HINTS property when we map a window.
+ * Instead, we'll read the current geometry. Therefore, we should respond
+ * to configuration requests for windows which have never been mapped.
+ */
+ if (window == NULL)
+ {
+ unsigned int xwcm;
+ XWindowChanges xwc;
+
+ xwcm = event->xconfigurerequest.value_mask &
+ (CWX | CWY | CWWidth | CWHeight | CWBorderWidth);
+
+ xwc.x = event->xconfigurerequest.x;
+ xwc.y = event->xconfigurerequest.y;
+ xwc.width = event->xconfigurerequest.width;
+ xwc.height = event->xconfigurerequest.height;
+ xwc.border_width = event->xconfigurerequest.border_width;
+
+ meta_verbose ("Configuring withdrawn window to %d,%d %dx%d border %d (some values may not be in
mask)\n",
+ xwc.x, xwc.y, xwc.width, xwc.height, xwc.border_width);
+ meta_error_trap_push (display);
+ XConfigureWindow (display->xdisplay, event->xconfigurerequest.window,
+ xwcm, &xwc);
+ meta_error_trap_pop (display);
+ }
+ else
+ {
+ if (!frame_was_receiver)
+ meta_window_configure_request (window, event);
+ }
+ break;
+ case GravityNotify:
+ break;
+ case ResizeRequest:
+ break;
+ case CirculateNotify:
+ break;
+ case CirculateRequest:
+ break;
+ case PropertyNotify:
+ {
+ MetaGroup *group;
+ MetaScreen *screen;
+
+ if (window && !frame_was_receiver)
+ meta_window_property_notify (window, event);
+ else if (property_for_window && !frame_was_receiver)
+ meta_window_property_notify (property_for_window, event);
+
+ group = meta_display_lookup_group (display,
+ event->xproperty.window);
+ if (group != NULL)
+ meta_group_property_notify (group, event);
+
+ screen = NULL;
+ if (window == NULL &&
+ group == NULL) /* window/group != NULL means it wasn't a root window */
+ screen = meta_display_screen_for_root (display,
+ event->xproperty.window);
+
+ if (screen != NULL)
{
- MetaGroup *group;
- MetaScreen *screen;
-
- if (window && !frame_was_receiver)
- meta_window_property_notify (window, event);
- else if (property_for_window && !frame_was_receiver)
- meta_window_property_notify (property_for_window, event);
-
- group = meta_display_lookup_group (display,
- event->xproperty.window);
- if (group != NULL)
- meta_group_property_notify (group, event);
-
- screen = NULL;
- if (window == NULL &&
- group == NULL) /* window/group != NULL means it wasn't a root window */
- screen = meta_display_screen_for_root (display,
- event->xproperty.window);
-
- if (screen != NULL)
- {
- if (event->xproperty.atom ==
- display->atom__NET_DESKTOP_LAYOUT)
- meta_screen_update_workspace_layout (screen);
- else if (event->xproperty.atom ==
- display->atom__NET_DESKTOP_NAMES)
- meta_screen_update_workspace_names (screen);
- else if (meta_is_wayland_compositor () &&
- event->xproperty.atom ==
- display->atom__XKB_RULES_NAMES)
- reload_xkb_rules (screen);
+ if (event->xproperty.atom ==
+ display->atom__NET_DESKTOP_LAYOUT)
+ meta_screen_update_workspace_layout (screen);
+ else if (event->xproperty.atom ==
+ display->atom__NET_DESKTOP_NAMES)
+ meta_screen_update_workspace_names (screen);
+ else if (meta_is_wayland_compositor () &&
+ event->xproperty.atom ==
+ display->atom__XKB_RULES_NAMES)
+ reload_xkb_rules (screen);
#if 0
- else if (event->xproperty.atom ==
- display->atom__NET_RESTACK_WINDOW)
- handle_net_restack_window (display, event);
+ else if (event->xproperty.atom ==
+ display->atom__NET_RESTACK_WINDOW)
+ handle_net_restack_window (display, event);
#endif
- /* we just use this property as a sentinel to avoid
- * certain race conditions. See the comment for the
- * sentinel_counter variable declaration in display.h
- */
- if (event->xproperty.atom ==
- display->atom__MUTTER_SENTINEL)
- {
- meta_display_decrement_focus_sentinel (display);
- }
+ /* we just use this property as a sentinel to avoid
+ * certain race conditions. See the comment for the
+ * sentinel_counter variable declaration in display.h
+ */
+ if (event->xproperty.atom ==
+ display->atom__MUTTER_SENTINEL)
+ {
+ meta_display_decrement_focus_sentinel (display);
}
}
- break;
- case SelectionClear:
- /* do this here instead of at end of function
- * so we can return
- */
+ }
+ break;
+ case SelectionClear:
+ /* do this here instead of at end of function
+ * so we can return
+ */
- /* FIXME: Clearing display->current_time here makes no sense to
- * me; who put this here and why?
- */
- display->current_time = CurrentTime;
+ /* FIXME: Clearing display->current_time here makes no sense to
+ * me; who put this here and why?
+ */
+ display->current_time = CurrentTime;
- process_selection_clear (display, event);
- /* Note that processing that may have resulted in
- * closing the display... so return right away.
- */
- return FALSE;
- case SelectionRequest:
- process_selection_request (display, event);
- break;
- case SelectionNotify:
- break;
- case ColormapNotify:
- if (window && !frame_was_receiver)
- window->colormap = event->xcolormap.colormap;
- break;
- case ClientMessage:
- if (window)
- {
- if (!frame_was_receiver)
- meta_window_client_message (window, event);
- }
- else
- {
- MetaScreen *screen;
+ process_selection_clear (display, event);
+ /* Note that processing that may have resulted in
+ * closing the display... so return right away.
+ */
+ return FALSE;
+ case SelectionRequest:
+ process_selection_request (display, event);
+ break;
+ case SelectionNotify:
+ break;
+ case ColormapNotify:
+ if (window && !frame_was_receiver)
+ window->colormap = event->xcolormap.colormap;
+ break;
+ case ClientMessage:
+ if (window)
+ {
+ if (!frame_was_receiver)
+ meta_window_client_message (window, event);
+ }
+ else
+ {
+ MetaScreen *screen;
- screen = meta_display_screen_for_root (display,
- event->xclient.window);
-
- if (screen)
+ screen = meta_display_screen_for_root (display,
+ event->xclient.window);
+
+ if (screen)
+ {
+ if (event->xclient.message_type ==
+ display->atom__NET_CURRENT_DESKTOP)
{
- if (event->xclient.message_type ==
- display->atom__NET_CURRENT_DESKTOP)
- {
- int space;
- MetaWorkspace *workspace;
- guint32 time;
-
- space = event->xclient.data.l[0];
- time = event->xclient.data.l[1];
-
- meta_verbose ("Request to change current workspace to %d with "
- "specified timestamp of %u\n",
- space, time);
-
- workspace =
- meta_screen_get_workspace_by_index (screen,
- space);
-
- /* Handle clients using the older version of the spec... */
- if (time == 0 && workspace)
- {
- 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);
- }
-
- if (workspace)
- meta_workspace_activate (workspace, time);
- else
- meta_verbose ("Don't know about workspace %d\n", space);
- }
- else if (event->xclient.message_type ==
- display->atom__NET_NUMBER_OF_DESKTOPS)
+ int space;
+ MetaWorkspace *workspace;
+ guint32 time;
+
+ space = event->xclient.data.l[0];
+ time = event->xclient.data.l[1];
+
+ meta_verbose ("Request to change current workspace to %d with "
+ "specified timestamp of %u\n",
+ space, time);
+
+ workspace =
+ meta_screen_get_workspace_by_index (screen,
+ space);
+
+ /* Handle clients using the older version of the spec... */
+ if (time == 0 && workspace)
{
- int num_spaces;
-
- num_spaces = event->xclient.data.l[0];
-
- meta_verbose ("Request to set number of workspaces to %d\n",
- num_spaces);
-
- meta_prefs_set_num_workspaces (num_spaces);
+ 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);
}
- else if (event->xclient.message_type ==
- display->atom__NET_SHOWING_DESKTOP)
+
+ if (workspace)
+ meta_workspace_activate (workspace, time);
+ else
+ meta_verbose ("Don't know about workspace %d\n", space);
+ }
+ else if (event->xclient.message_type ==
+ display->atom__NET_NUMBER_OF_DESKTOPS)
+ {
+ int num_spaces;
+
+ num_spaces = event->xclient.data.l[0];
+
+ meta_verbose ("Request to set number of workspaces to %d\n",
+ num_spaces);
+
+ meta_prefs_set_num_workspaces (num_spaces);
+ }
+ else if (event->xclient.message_type ==
+ display->atom__NET_SHOWING_DESKTOP)
+ {
+ gboolean showing_desktop;
+ guint32 timestamp;
+
+ showing_desktop = event->xclient.data.l[0] != 0;
+ /* FIXME: Braindead protocol doesn't have a timestamp */
+ timestamp = meta_display_get_current_time_roundtrip (display);
+ meta_verbose ("Request to %s desktop\n",
+ showing_desktop ? "show" : "hide");
+
+ if (showing_desktop)
+ meta_screen_show_desktop (screen, timestamp);
+ else
{
- gboolean showing_desktop;
- guint32 timestamp;
-
- showing_desktop = event->xclient.data.l[0] != 0;
- /* FIXME: Braindead protocol doesn't have a timestamp */
- timestamp = meta_display_get_current_time_roundtrip (display);
- meta_verbose ("Request to %s desktop\n",
- showing_desktop ? "show" : "hide");
-
- if (showing_desktop)
- meta_screen_show_desktop (screen, timestamp);
- else
- {
- meta_screen_unshow_desktop (screen);
- meta_workspace_focus_default_window (screen->active_workspace, NULL, timestamp);
- }
+ meta_screen_unshow_desktop (screen);
+ meta_workspace_focus_default_window (screen->active_workspace, NULL, timestamp);
}
- else if (event->xclient.message_type ==
- display->atom_WM_PROTOCOLS)
+ }
+ else if (event->xclient.message_type ==
+ display->atom_WM_PROTOCOLS)
+ {
+ meta_verbose ("Received WM_PROTOCOLS message\n");
+
+ if ((Atom)event->xclient.data.l[0] == display->atom__NET_WM_PING)
{
- meta_verbose ("Received WM_PROTOCOLS message\n");
-
- if ((Atom)event->xclient.data.l[0] == display->atom__NET_WM_PING)
- {
- process_pong_message (display, event);
-
- /* We don't want ping reply events going into
- * the GTK+ event loop because gtk+ will treat
- * them as ping requests and send more replies.
- */
- bypass_gtk = TRUE;
- }
+ process_pong_message (display, event);
+
+ /* We don't want ping reply events going into
+ * the GTK+ event loop because gtk+ will treat
+ * them as ping requests and send more replies.
+ */
+ bypass_gtk = TRUE;
}
}
+ }
- if (event->xclient.message_type ==
- display->atom__NET_REQUEST_FRAME_EXTENTS)
- {
- meta_verbose ("Received _NET_REQUEST_FRAME_EXTENTS message\n");
- process_request_frame_extents (display, event);
- }
+ if (event->xclient.message_type ==
+ display->atom__NET_REQUEST_FRAME_EXTENTS)
+ {
+ meta_verbose ("Received _NET_REQUEST_FRAME_EXTENTS message\n");
+ process_request_frame_extents (display, event);
}
- break;
- case MappingNotify:
+ }
+ break;
+ case MappingNotify:
+ {
+ gboolean ignore_current;
+
+ ignore_current = FALSE;
+
+ /* Check whether the next event is an identical MappingNotify
+ * event. If it is, ignore the current event, we'll update
+ * when we get the next one.
+ */
+ if (XPending (display->xdisplay))
{
- gboolean ignore_current;
+ XEvent next_event;
- ignore_current = FALSE;
-
- /* Check whether the next event is an identical MappingNotify
- * event. If it is, ignore the current event, we'll update
- * when we get the next one.
- */
- if (XPending (display->xdisplay))
- {
- XEvent next_event;
-
- XPeekEvent (display->xdisplay, &next_event);
-
- if (next_event.type == MappingNotify &&
- next_event.xmapping.request == event->xmapping.request)
- ignore_current = TRUE;
- }
+ XPeekEvent (display->xdisplay, &next_event);
- if (!ignore_current)
- {
- /* Let XLib know that there is a new keyboard mapping.
- */
- XRefreshKeyboardMapping (&event->xmapping);
- meta_display_process_mapping_event (display, event);
- }
+ if (next_event.type == MappingNotify &&
+ next_event.xmapping.request == event->xmapping.request)
+ ignore_current = TRUE;
}
- break;
- default:
+
+ if (!ignore_current)
+ {
+ /* Let XLib know that there is a new keyboard mapping.
+ */
+ XRefreshKeyboardMapping (&event->xmapping);
+ meta_display_process_mapping_event (display, event);
+ }
+ }
+ break;
+ default:
#ifdef HAVE_XKB
- if (event->type == display->xkb_base_event_type)
- {
- XkbAnyEvent *xkb_ev = (XkbAnyEvent *) event;
+ if (event->type == display->xkb_base_event_type)
+ {
+ XkbAnyEvent *xkb_ev = (XkbAnyEvent *) event;
- switch (xkb_ev->xkb_type)
+ switch (xkb_ev->xkb_type)
+ {
+ case XkbBellNotify:
+ if (XSERVER_TIME_IS_BEFORE(display->last_bell_time,
+ xkb_ev->time - 100))
{
- case XkbBellNotify:
- if (XSERVER_TIME_IS_BEFORE(display->last_bell_time,
- xkb_ev->time - 100))
- {
- display->last_bell_time = xkb_ev->time;
- meta_bell_notify (display, xkb_ev);
- }
- break;
- case XkbNewKeyboardNotify:
- case XkbMapNotify:
- if (xkb_ev->device == META_VIRTUAL_CORE_KEYBOARD_ID)
- meta_display_process_mapping_event (display, event);
- break;
+ display->last_bell_time = xkb_ev->time;
+ meta_bell_notify (display, xkb_ev);
}
- }
+ break;
+ case XkbNewKeyboardNotify:
+ case XkbMapNotify:
+ if (xkb_ev->device == META_VIRTUAL_CORE_KEYBOARD_ID)
+ meta_display_process_mapping_event (display, event);
+ break;
+ }
+ }
#endif
- break;
+ break;
+ }
+
+ out:
+ return bypass_gtk;
+}
+
+/**
+ * meta_display_handle_xevent:
+ * @display: The MetaDisplay that events are coming from
+ * @event: The event that just happened
+ *
+ * This is the most important function in the whole program. It is the heart,
+ * it is the nexus, it is the Grand Central Station of Mutter's world.
+ * When we create a #MetaDisplay, we ask GDK to pass *all* events for *all*
+ * windows to this function. So every time anything happens that we might
+ * want to know about, this function gets called. You see why it gets a bit
+ * busy around here. Most of this function is a ginormous switch statement
+ * dealing with all the kinds of events that might turn up.
+ */
+gboolean
+meta_display_handle_xevent (MetaDisplay *display,
+ XEvent *event)
+{
+ Window modified;
+ gboolean bypass_compositor = FALSE, bypass_gtk = FALSE;
+ XIEvent *input_event;
+ MetaMonitorManager *monitor;
+ MetaScreen *screen;
+
+#ifdef WITH_VERBOSE_MODE
+ if (dump_events)
+ meta_spew_event (display, event);
+#endif
+
+#ifdef HAVE_STARTUP_NOTIFICATION
+ sn_display_process_event (display->sn_display, event);
+#endif
+
+ /* Intercept XRandR events early and don't attempt any
+ processing for them. We still let them through to Gdk though,
+ so it can update its own internal state.
+ */
+ monitor = meta_monitor_manager_get ();
+ if (meta_monitor_manager_handle_xevent (monitor, event))
+ {
+ bypass_compositor = TRUE;
+ goto out;
+ }
+
+ display->current_time = event_get_time (display, event);
+ display->monitor_cache_invalidated = TRUE;
+
+ if (event->xany.serial > display->focus_serial &&
+ display->focus_window &&
+ display->focus_window->xwindow != display->server_focus_window)
+ {
+ meta_topic (META_DEBUG_FOCUS, "Earlier attempt to focus %s failed\n",
+ display->focus_window->desc);
+ update_focus_window (display,
+ META_FOCUS_NONE,
+ meta_display_lookup_x_window (display, display->server_focus_window),
+ display->server_focus_window,
+ display->server_focus_serial);
+ }
+
+ screen = meta_display_screen_for_root (display, event->xany.window);
+ if (screen)
+ {
+ if (meta_screen_handle_xevent (screen, event))
+ {
+ bypass_gtk = bypass_compositor = TRUE;
+ goto out;
+ }
+ }
+
+ modified = event_get_modified_window (display, event);
+
+ input_event = get_input_event (display, event);
+
+ if (event->type == UnmapNotify)
+ {
+ if (meta_ui_window_should_not_cause_focus (display->xdisplay,
+ modified))
+ {
+ meta_display_add_ignored_crossing_serial (display, event->xany.serial);
+ meta_topic (META_DEBUG_FOCUS,
+ "Adding EnterNotify serial %lu to ignored focus serials\n",
+ event->xany.serial);
}
}
+ else if (input_event &&
+ input_event->evtype == XI_Leave &&
+ ((XILeaveEvent *)input_event)->mode == XINotifyUngrab &&
+ modified == display->ungrab_should_not_cause_focus_window)
+ {
+ meta_display_add_ignored_crossing_serial (display, event->xany.serial);
+ meta_topic (META_DEBUG_FOCUS,
+ "Adding LeaveNotify serial %lu to ignored focus serials\n",
+ event->xany.serial);
+ }
+
+#ifdef HAVE_XI23
+ if (meta_display_process_barrier_event (display, input_event))
+ {
+ bypass_gtk = bypass_compositor = TRUE;
+ goto out;
+ }
+#endif /* HAVE_XI23 */
+
+ /* libXi does not properly copy the serial to XI2 events, so pull it
+ * from the parent XAnyEvent and pass it to handle_input_xevent.
+ * See: https://bugs.freedesktop.org/show_bug.cgi?id=64687
+ */
+ if (handle_input_xevent (display, input_event, event->xany.serial))
+ {
+ bypass_gtk = bypass_compositor = TRUE;
+ goto out;
+ }
+
+ if (handle_other_xevent (display, event))
+ {
+ bypass_gtk = TRUE;
+ goto out;
+ }
out:
if (display->compositor && !bypass_compositor)
{
- if (meta_compositor_process_event (display->compositor,
- event,
- window))
+ MetaWindow *window = modified != None ? meta_display_lookup_x_window (display, modified) : NULL;
+
+ if (meta_compositor_process_event (display->compositor, event, window))
bypass_gtk = TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]