mirror of
https://github.com/brl/mutter.git
synced 2024-12-26 21:02:14 +00:00
display: Establish a separate state variable for routing events
We've long used a switch statement on the grab operation to determine where events should go. The issue with MetaGrabOp is that it's a mixture of a few different things, including event routing, state management, and the behavior to choose during operations. This leads to poorly defined event routing and hard-to-follow logic, since it's sometimes unclear what should point where, and our utility methods for determining grab operations apart can be poorly named. To fix this, establish the concept of a "event route", which describes where events should be routed to.
This commit is contained in:
parent
64a915a68d
commit
0e758a9e65
@ -61,7 +61,7 @@ get_displayed_cursor (MetaCursorTracker *tracker)
|
||||
if (!tracker->is_showing)
|
||||
return NULL;
|
||||
|
||||
if (meta_grab_op_windows_are_interactable (display->grab_op))
|
||||
if (meta_display_windows_are_interactable (display))
|
||||
{
|
||||
if (tracker->has_window_cursor)
|
||||
return tracker->window_cursor;
|
||||
|
@ -87,7 +87,7 @@
|
||||
static gboolean
|
||||
is_modal (MetaDisplay *display)
|
||||
{
|
||||
return display->grab_op == META_GRAB_OP_COMPOSITOR;
|
||||
return display->event_route == META_EVENT_ROUTE_COMPOSITOR_GRAB;
|
||||
}
|
||||
|
||||
static void sync_actor_stacking (MetaCompositor *compositor);
|
||||
@ -343,6 +343,7 @@ meta_begin_modal_for_plugin (MetaCompositor *compositor,
|
||||
return FALSE;
|
||||
|
||||
display->grab_op = META_GRAB_OP_COMPOSITOR;
|
||||
display->event_route = META_EVENT_ROUTE_COMPOSITOR_GRAB;
|
||||
display->grab_window = NULL;
|
||||
display->grab_have_pointer = TRUE;
|
||||
display->grab_have_keyboard = TRUE;
|
||||
@ -375,6 +376,7 @@ meta_end_modal_for_plugin (MetaCompositor *compositor,
|
||||
display->grab_window, display->grab_op);
|
||||
|
||||
display->grab_op = META_GRAB_OP_NONE;
|
||||
display->event_route = META_EVENT_ROUTE_NORMAL;
|
||||
display->grab_window = NULL;
|
||||
display->grab_have_pointer = FALSE;
|
||||
display->grab_have_keyboard = FALSE;
|
||||
|
@ -79,6 +79,24 @@ typedef enum {
|
||||
META_TILE_MAXIMIZED
|
||||
} MetaTileMode;
|
||||
|
||||
typedef enum {
|
||||
/* Normal interaction where you're interacting with windows.
|
||||
* Events go to windows normally. */
|
||||
META_EVENT_ROUTE_NORMAL,
|
||||
|
||||
/* In a compositor grab operation. All events go to the
|
||||
* compositor plugin. */
|
||||
META_EVENT_ROUTE_COMPOSITOR_GRAB,
|
||||
|
||||
/* A Wayland application has a popup open. All events go to
|
||||
* the Wayland application. */
|
||||
META_EVENT_ROUTE_WAYLAND_POPUP,
|
||||
|
||||
/* In a window operation like moving or resizing. All events
|
||||
* goes to MetaWindow, but not to the actual client window. */
|
||||
META_EVENT_ROUTE_WINDOW_OP,
|
||||
} MetaEventRoute;
|
||||
|
||||
struct _MetaDisplay
|
||||
{
|
||||
GObject parent_instance;
|
||||
@ -174,6 +192,9 @@ struct _MetaDisplay
|
||||
guint autoraise_timeout_id;
|
||||
MetaWindow* autoraise_window;
|
||||
|
||||
/* Event routing */
|
||||
MetaEventRoute event_route;
|
||||
|
||||
/* current window operation */
|
||||
MetaGrabOp grab_op;
|
||||
MetaWindow *grab_window;
|
||||
@ -380,7 +401,6 @@ gboolean meta_grab_op_is_resizing (MetaGrabOp op);
|
||||
gboolean meta_grab_op_is_moving_or_resizing (MetaGrabOp op);
|
||||
gboolean meta_grab_op_is_mouse (MetaGrabOp op);
|
||||
gboolean meta_grab_op_is_keyboard (MetaGrabOp op);
|
||||
gboolean meta_grab_op_windows_are_interactable (MetaGrabOp op);
|
||||
|
||||
void meta_display_increment_focus_sentinel (MetaDisplay *display);
|
||||
void meta_display_decrement_focus_sentinel (MetaDisplay *display);
|
||||
@ -432,4 +452,6 @@ void meta_restart_finish (void);
|
||||
|
||||
void meta_display_cancel_touch (MetaDisplay *display);
|
||||
|
||||
gboolean meta_display_windows_are_interactable (MetaDisplay *display);
|
||||
|
||||
#endif
|
||||
|
@ -1264,15 +1264,15 @@ meta_grab_op_is_moving_or_resizing (MetaGrabOp op)
|
||||
* meta_grab_op_windows_are_interactable:
|
||||
* @op: A #MetaGrabOp
|
||||
*
|
||||
* Whether windows can be interacted with in this grab operation.
|
||||
* Whether windows can be interacted with.
|
||||
*/
|
||||
gboolean
|
||||
meta_grab_op_windows_are_interactable (MetaGrabOp op)
|
||||
meta_display_windows_are_interactable (MetaDisplay *display)
|
||||
{
|
||||
switch (op)
|
||||
switch (display->event_route)
|
||||
{
|
||||
case META_GRAB_OP_WAYLAND_POPUP:
|
||||
case META_GRAB_OP_NONE:
|
||||
case META_EVENT_ROUTE_NORMAL:
|
||||
case META_EVENT_ROUTE_WAYLAND_POPUP:
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
@ -1444,7 +1444,7 @@ meta_display_sync_wayland_input_focus (MetaDisplay *display)
|
||||
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
|
||||
MetaWindow *focus_window = NULL;
|
||||
|
||||
if (!meta_grab_op_windows_are_interactable (display->grab_op))
|
||||
if (!meta_display_windows_are_interactable (display))
|
||||
focus_window = NULL;
|
||||
else if (meta_display_xwindow_is_a_no_focus_window (display, display->focus_xwindow))
|
||||
focus_window = NULL;
|
||||
@ -1753,6 +1753,48 @@ get_first_freefloating_window (MetaWindow *window)
|
||||
return window;
|
||||
}
|
||||
|
||||
static MetaEventRoute
|
||||
get_event_route_from_grab_op (MetaGrabOp op)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case META_GRAB_OP_NONE:
|
||||
/* begin_grab_op shouldn't be called with META_GRAB_OP_NONE. */
|
||||
g_assert_not_reached ();
|
||||
|
||||
case META_GRAB_OP_MOVING:
|
||||
case META_GRAB_OP_RESIZING_SE:
|
||||
case META_GRAB_OP_RESIZING_S:
|
||||
case META_GRAB_OP_RESIZING_SW:
|
||||
case META_GRAB_OP_RESIZING_N:
|
||||
case META_GRAB_OP_RESIZING_NE:
|
||||
case META_GRAB_OP_RESIZING_NW:
|
||||
case META_GRAB_OP_RESIZING_W:
|
||||
case META_GRAB_OP_RESIZING_E:
|
||||
case META_GRAB_OP_KEYBOARD_MOVING:
|
||||
case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN:
|
||||
case META_GRAB_OP_KEYBOARD_RESIZING_S:
|
||||
case META_GRAB_OP_KEYBOARD_RESIZING_N:
|
||||
case META_GRAB_OP_KEYBOARD_RESIZING_W:
|
||||
case META_GRAB_OP_KEYBOARD_RESIZING_E:
|
||||
case META_GRAB_OP_KEYBOARD_RESIZING_SE:
|
||||
case META_GRAB_OP_KEYBOARD_RESIZING_NE:
|
||||
case META_GRAB_OP_KEYBOARD_RESIZING_SW:
|
||||
case META_GRAB_OP_KEYBOARD_RESIZING_NW:
|
||||
return META_EVENT_ROUTE_WINDOW_OP;
|
||||
|
||||
case META_GRAB_OP_COMPOSITOR:
|
||||
/* begin_grab_op shouldn't be called with META_GRAB_OP_COMPOSITOR. */
|
||||
g_assert_not_reached ();
|
||||
|
||||
case META_GRAB_OP_WAYLAND_POPUP:
|
||||
return META_EVENT_ROUTE_WAYLAND_POPUP;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_display_begin_grab_op (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
@ -1768,6 +1810,7 @@ meta_display_begin_grab_op (MetaDisplay *display,
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
MetaWindow *grab_window = NULL;
|
||||
MetaEventRoute event_route;
|
||||
|
||||
g_assert (window != NULL);
|
||||
|
||||
@ -1784,7 +1827,9 @@ meta_display_begin_grab_op (MetaDisplay *display,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (meta_grab_op_is_moving_or_resizing (op))
|
||||
event_route = get_event_route_from_grab_op (op);
|
||||
|
||||
if (event_route == META_EVENT_ROUTE_WINDOW_OP)
|
||||
{
|
||||
if (meta_prefs_get_raise_on_click ())
|
||||
meta_window_raise (window);
|
||||
@ -1830,8 +1875,8 @@ meta_display_begin_grab_op (MetaDisplay *display,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Grab keys for keyboard ops and mouse move/resizes; see #126497 */
|
||||
if (meta_grab_op_is_moving_or_resizing (op))
|
||||
/* Grab keys when beginning window ops; see #126497 */
|
||||
if (event_route == META_EVENT_ROUTE_WINDOW_OP)
|
||||
{
|
||||
display->grab_have_keyboard = meta_window_grab_all_keys (grab_window, timestamp);
|
||||
|
||||
@ -1844,6 +1889,7 @@ meta_display_begin_grab_op (MetaDisplay *display,
|
||||
}
|
||||
}
|
||||
|
||||
display->event_route = event_route;
|
||||
display->grab_op = op;
|
||||
display->grab_window = grab_window;
|
||||
display->grab_button = button;
|
||||
@ -1884,7 +1930,8 @@ meta_display_begin_grab_op (MetaDisplay *display,
|
||||
g_signal_emit (display, display_signals[GRAB_OP_BEGIN], 0,
|
||||
screen, display->grab_window, display->grab_op);
|
||||
|
||||
meta_window_grab_op_began (display->grab_window, display->grab_op);
|
||||
if (display->event_route == META_EVENT_ROUTE_WINDOW_OP)
|
||||
meta_window_grab_op_began (display->grab_window, display->grab_op);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -1899,13 +1946,13 @@ meta_display_end_grab_op (MetaDisplay *display,
|
||||
meta_topic (META_DEBUG_WINDOW_OPS,
|
||||
"Ending grab op %u at time %u\n", grab_op, timestamp);
|
||||
|
||||
if (display->grab_op == META_GRAB_OP_NONE)
|
||||
if (display->event_route == META_EVENT_ROUTE_NORMAL)
|
||||
return;
|
||||
|
||||
g_signal_emit (display, display_signals[GRAB_OP_END], 0,
|
||||
display->screen, grab_window, grab_op);
|
||||
|
||||
if (meta_grab_op_is_moving_or_resizing (grab_op))
|
||||
if (display->event_route == META_EVENT_ROUTE_WINDOW_OP)
|
||||
{
|
||||
/* Clear out the edge cache */
|
||||
meta_display_cleanup_edges (display);
|
||||
@ -1919,6 +1966,8 @@ meta_display_end_grab_op (MetaDisplay *display,
|
||||
if (!meta_prefs_get_raise_on_click () &&
|
||||
display->grab_threshold_movement_reached)
|
||||
meta_window_raise (display->grab_window);
|
||||
|
||||
meta_window_grab_op_ended (grab_window, grab_op);
|
||||
}
|
||||
|
||||
if (display->grab_have_pointer)
|
||||
@ -1934,10 +1983,11 @@ meta_display_end_grab_op (MetaDisplay *display,
|
||||
meta_window_ungrab_all_keys (grab_window, timestamp);
|
||||
}
|
||||
|
||||
display->event_route = META_EVENT_ROUTE_NORMAL;
|
||||
display->grab_op = META_GRAB_OP_NONE;
|
||||
display->grab_window = NULL;
|
||||
display->grab_tile_mode = META_TILE_NONE;
|
||||
display->grab_tile_monitor_number = -1;
|
||||
display->grab_op = META_GRAB_OP_NONE;
|
||||
|
||||
meta_display_update_cursor (display);
|
||||
|
||||
@ -1947,8 +1997,6 @@ meta_display_end_grab_op (MetaDisplay *display,
|
||||
display->grab_resize_timeout_id = 0;
|
||||
}
|
||||
|
||||
meta_window_grab_op_ended (grab_window, grab_op);
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
meta_display_sync_wayland_input_focus (display);
|
||||
}
|
||||
|
@ -45,9 +45,6 @@ get_window_for_event (MetaDisplay *display,
|
||||
{
|
||||
ClutterActor *source;
|
||||
|
||||
if (display->grab_op != META_GRAB_OP_NONE)
|
||||
return display->grab_window;
|
||||
|
||||
/* Always use the key focused window for key events. */
|
||||
switch (event->type)
|
||||
{
|
||||
@ -214,8 +211,7 @@ meta_display_handle_event (MetaDisplay *display,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (display->grab_window == window &&
|
||||
meta_grab_op_is_moving_or_resizing (display->grab_op))
|
||||
if (display->event_route == META_EVENT_ROUTE_WINDOW_OP)
|
||||
{
|
||||
if (meta_window_handle_mouse_grab_op_event (window, event))
|
||||
{
|
||||
@ -256,8 +252,7 @@ meta_display_handle_event (MetaDisplay *display,
|
||||
* event, and if it doesn't, replay the event to release our
|
||||
* own sync grab. */
|
||||
|
||||
if (display->grab_window == window &&
|
||||
meta_grab_op_is_moving_or_resizing (display->grab_op))
|
||||
if (display->event_route == META_EVENT_ROUTE_WINDOW_OP)
|
||||
{
|
||||
bypass_clutter = TRUE;
|
||||
bypass_wayland = TRUE;
|
||||
@ -285,11 +280,11 @@ meta_display_handle_event (MetaDisplay *display,
|
||||
|
||||
out:
|
||||
/* If the compositor has a grab, don't pass that through to Wayland */
|
||||
if (display->grab_op == META_GRAB_OP_COMPOSITOR)
|
||||
if (display->event_route == META_EVENT_ROUTE_COMPOSITOR_GRAB)
|
||||
bypass_wayland = TRUE;
|
||||
|
||||
/* If a Wayland client has a grab, don't pass that through to Clutter */
|
||||
if (display->grab_op == META_GRAB_OP_WAYLAND_POPUP)
|
||||
if (display->event_route == META_EVENT_ROUTE_WAYLAND_POPUP)
|
||||
bypass_clutter = TRUE;
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
|
@ -246,14 +246,20 @@ sync_focus_surface (MetaWaylandPointer *pointer)
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
MetaWaylandSurface *focus_surface;
|
||||
|
||||
/* Don't update the focus surface while we have a move/resize grab. */
|
||||
if (meta_grab_op_is_moving_or_resizing (display->grab_op))
|
||||
return;
|
||||
switch (display->event_route)
|
||||
{
|
||||
case META_EVENT_ROUTE_WINDOW_OP:
|
||||
/* Don't update the focus surface while we're grabbing a window. */
|
||||
return;
|
||||
|
||||
if (!meta_grab_op_windows_are_interactable (display->grab_op))
|
||||
focus_surface = NULL;
|
||||
else
|
||||
focus_surface = pointer->current;
|
||||
case META_EVENT_ROUTE_COMPOSITOR_GRAB:
|
||||
/* The compositor has focus, so remove our focus... */
|
||||
focus_surface = NULL;
|
||||
|
||||
case META_EVENT_ROUTE_NORMAL:
|
||||
case META_EVENT_ROUTE_WAYLAND_POPUP:
|
||||
focus_surface = pointer->current;
|
||||
}
|
||||
|
||||
if (focus_surface != pointer->focus_surface)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user