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.
This commit is contained in:
Jasper St. Pierre 2013-10-03 17:13:48 -04:00
parent b722274886
commit d69d566087

View File

@ -2597,108 +2597,19 @@ reload_xkb_rules (MetaScreen *screen)
g_strfreev (names); g_strfreev (names);
} }
/** static gboolean
* meta_display_handle_xevent: handle_other_xevent (MetaDisplay *display,
* @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) XEvent *event)
{ {
Window modified;
MetaWindow *window; MetaWindow *window;
MetaWindow *property_for_window; MetaWindow *property_for_window;
Window modified;
gboolean frame_was_receiver; gboolean frame_was_receiver;
gboolean bypass_compositor = FALSE, bypass_gtk = FALSE; gboolean 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); modified = event_get_modified_window (display, event);
window = modified != None ? meta_display_lookup_x_window (display, modified) : NULL;
input_event = get_input_event (display, event); frame_was_receiver = (window && window->frame && modified == window->frame->xwindow);
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;
/* We only want to respond to _NET_WM_USER_TIME property notify /* We only want to respond to _NET_WM_USER_TIME property notify
* events on _NET_WM_USER_TIME_WINDOW windows; in particular, * events on _NET_WM_USER_TIME_WINDOW windows; in particular,
@ -2711,20 +2622,6 @@ meta_display_handle_xevent (MetaDisplay *display,
window = NULL; 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 #ifdef HAVE_XSYNC
if (META_DISPLAY_HAS_XSYNC (display) && if (META_DISPLAY_HAS_XSYNC (display) &&
event->type == (display->xsync_event_base + XSyncAlarmNotify)) event->type == (display->xsync_event_base + XSyncAlarmNotify))
@ -2774,25 +2671,6 @@ meta_display_handle_xevent (MetaDisplay *display,
} }
#endif /* HAVE_SHAPE */ #endif /* HAVE_SHAPE */
#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;
}
else
{
switch (event->type) switch (event->type)
{ {
case KeymapNotify: case KeymapNotify:
@ -3235,14 +3113,136 @@ meta_display_handle_xevent (MetaDisplay *display,
#endif #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: out:
if (display->compositor && !bypass_compositor) if (display->compositor && !bypass_compositor)
{ {
if (meta_compositor_process_event (display->compositor, MetaWindow *window = modified != None ? meta_display_lookup_x_window (display, modified) : NULL;
event,
window)) if (meta_compositor_process_event (display->compositor, event, window))
bypass_gtk = TRUE; bypass_gtk = TRUE;
} }