mirror of
https://github.com/brl/mutter.git
synced 2024-11-29 03:20:46 -05:00
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
b722274886
commit
d69d566087
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user