diff --git a/src/core/display.c b/src/core/display.c index b54fd9db8..a763df7fe 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -53,6 +53,7 @@ #include #include "mutter-enum-types.h" #include "meta-idle-monitor-private.h" +#include "meta-cursor-tracker-private.h" #ifdef HAVE_RANDR #include @@ -3879,59 +3880,53 @@ meta_display_xwindow_is_a_no_focus_window (MetaDisplay *display, return is_a_no_focus_window; } -static Cursor -xcursor_for_op (MetaDisplay *display, - MetaGrabOp op) +static MetaCursor +meta_cursor_for_grab_op (MetaGrabOp op) { - MetaCursor cursor = META_CURSOR_DEFAULT; - switch (op) { case META_GRAB_OP_RESIZING_SE: case META_GRAB_OP_KEYBOARD_RESIZING_SE: - cursor = META_CURSOR_SE_RESIZE; + return META_CURSOR_SE_RESIZE; break; case META_GRAB_OP_RESIZING_S: case META_GRAB_OP_KEYBOARD_RESIZING_S: - cursor = META_CURSOR_SOUTH_RESIZE; + return META_CURSOR_SOUTH_RESIZE; break; case META_GRAB_OP_RESIZING_SW: case META_GRAB_OP_KEYBOARD_RESIZING_SW: - cursor = META_CURSOR_SW_RESIZE; + return META_CURSOR_SW_RESIZE; break; case META_GRAB_OP_RESIZING_N: case META_GRAB_OP_KEYBOARD_RESIZING_N: - cursor = META_CURSOR_NORTH_RESIZE; + return META_CURSOR_NORTH_RESIZE; break; case META_GRAB_OP_RESIZING_NE: case META_GRAB_OP_KEYBOARD_RESIZING_NE: - cursor = META_CURSOR_NE_RESIZE; + return META_CURSOR_NE_RESIZE; break; case META_GRAB_OP_RESIZING_NW: case META_GRAB_OP_KEYBOARD_RESIZING_NW: - cursor = META_CURSOR_NW_RESIZE; + return META_CURSOR_NW_RESIZE; break; case META_GRAB_OP_RESIZING_W: case META_GRAB_OP_KEYBOARD_RESIZING_W: - cursor = META_CURSOR_WEST_RESIZE; + return META_CURSOR_WEST_RESIZE; break; case META_GRAB_OP_RESIZING_E: case META_GRAB_OP_KEYBOARD_RESIZING_E: - cursor = META_CURSOR_EAST_RESIZE; + return META_CURSOR_EAST_RESIZE; break; case META_GRAB_OP_MOVING: case META_GRAB_OP_KEYBOARD_MOVING: case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN: - cursor = META_CURSOR_MOVE_OR_RESIZE_WINDOW; + return META_CURSOR_MOVE_OR_RESIZE_WINDOW; break; - default: break; } - if (cursor == META_CURSOR_DEFAULT) - return None; - return meta_display_create_x_cursor (display, cursor); + return META_CURSOR_DEFAULT; } void @@ -3941,7 +3936,6 @@ meta_display_set_grab_op_cursor (MetaDisplay *display, Window grab_xwindow, guint32 timestamp) { - Cursor cursor = xcursor_for_op (display, op); unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; @@ -3958,7 +3952,7 @@ meta_display_set_grab_op_cursor (MetaDisplay *display, META_VIRTUAL_CORE_POINTER_ID, grab_xwindow, timestamp, - cursor, + None, XIGrabModeAsync, XIGrabModeAsync, False, /* owner_events */ &mask) == Success) @@ -3974,10 +3968,10 @@ meta_display_set_grab_op_cursor (MetaDisplay *display, "XIGrabDevice() failed time %u\n", timestamp); } + meta_error_trap_pop (display); - - if (cursor != None) - XFreeCursor (display->xdisplay, cursor); + + meta_cursor_tracker_set_grab_cursor (screen->cursor_tracker, meta_cursor_for_grab_op (op)); } gboolean @@ -4239,7 +4233,8 @@ meta_display_end_grab_op (MetaDisplay *display, meta_screen_ungrab_all_keys (display->grab_screen, timestamp); } - + meta_cursor_tracker_set_grab_cursor (display->grab_screen->cursor_tracker, META_CURSOR_DEFAULT); + display->grab_timestamp = 0; display->grab_window = NULL; display->grab_screen = NULL; diff --git a/src/core/meta-cursor-tracker-private.h b/src/core/meta-cursor-tracker-private.h index ffa08df2b..b0ad11e6a 100644 --- a/src/core/meta-cursor-tracker-private.h +++ b/src/core/meta-cursor-tracker-private.h @@ -31,6 +31,8 @@ gboolean meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker, XEvent *xevent); +void meta_cursor_tracker_set_grab_cursor (MetaCursorTracker *tracker, + MetaCursor cursor); void meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker, struct wl_resource *buffer, int hot_x, diff --git a/src/core/meta-cursor-tracker.c b/src/core/meta-cursor-tracker.c index e4cf92f50..bbdba907a 100644 --- a/src/core/meta-cursor-tracker.c +++ b/src/core/meta-cursor-tracker.c @@ -70,19 +70,22 @@ struct _MetaCursorTracker { gboolean is_showing; gboolean has_hw_cursor; - /* The cursor tracker stores the cursor for the window with - * pointer focus, and the cursor for the root window, which - * contains either the default arrow cursor or the 'busy' - * hourglass if we're launching an app. + /* The cursor tracker stores the cursor for the current grab + * operation, the cursor for the window with pointer focus, and + * the cursor for the root window, which contains either the + * default arrow cursor or the 'busy' hourglass if we're launching + * an app. * - * We choose the first one available -- if there's a window - * cursor, we choose that, otherwise we choose the root - * cursor. + * We choose the first one available -- if there's a grab cursor, + * we choose that cursor, if there's window cursor, we choose that, + * otherwise we choose the root cursor. * * The displayed_cursor contains the chosen cursor. */ MetaCursorReference *displayed_cursor; + MetaCursorReference *grab_cursor; + /* Wayland clients can set a NULL buffer as their cursor * explicitly, which means that we shouldn't display anything. * So, we can't simply store a NULL in window_cursor to @@ -829,6 +832,15 @@ ensure_wayland_cursor (MetaCursorTracker *tracker, return tracker->default_cursors[cursor]; } +void +meta_cursor_tracker_set_grab_cursor (MetaCursorTracker *tracker, + MetaCursor cursor) +{ + g_clear_pointer (&tracker->grab_cursor, meta_cursor_reference_unref); + if (cursor != META_CURSOR_DEFAULT) + tracker->grab_cursor = ensure_wayland_cursor (tracker, cursor); +} + void meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker, struct wl_resource *buffer, @@ -937,6 +949,9 @@ get_displayed_cursor (MetaCursorTracker *tracker) if (!tracker->is_showing) return NULL; + if (tracker->grab_cursor) + return tracker->grab_cursor; + if (tracker->has_window_cursor) return tracker->window_cursor;