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:
parent
58f6ab0a27
commit
4ea4658abf
@ -2597,108 +2597,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,
|
||||
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,
|
||||
@ -2711,20 +2622,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))
|
||||
@ -2774,25 +2671,6 @@ meta_display_handle_xevent (MetaDisplay *display,
|
||||
}
|
||||
#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)
|
||||
{
|
||||
case KeymapNotify:
|
||||
@ -3235,14 +3113,136 @@ meta_display_handle_xevent (MetaDisplay *display,
|
||||
#endif
|
||||
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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user