cursor-tracker: Force the grab cursor on grab ops

This makes window moving have a 'window move' cursor, and similar.
This commit is contained in:
Jasper St. Pierre 2013-11-18 19:34:04 -05:00
parent d96b053c9d
commit 4091f5493d
3 changed files with 43 additions and 31 deletions

View File

@ -53,6 +53,7 @@
#include <X11/Xatom.h> #include <X11/Xatom.h>
#include "mutter-enum-types.h" #include "mutter-enum-types.h"
#include "meta-idle-monitor-private.h" #include "meta-idle-monitor-private.h"
#include "meta-cursor-tracker-private.h"
#ifdef HAVE_RANDR #ifdef HAVE_RANDR
#include <X11/extensions/Xrandr.h> #include <X11/extensions/Xrandr.h>
@ -3879,59 +3880,53 @@ meta_display_xwindow_is_a_no_focus_window (MetaDisplay *display,
return is_a_no_focus_window; return is_a_no_focus_window;
} }
static Cursor static MetaCursor
xcursor_for_op (MetaDisplay *display, meta_cursor_for_grab_op (MetaGrabOp op)
MetaGrabOp op)
{ {
MetaCursor cursor = META_CURSOR_DEFAULT;
switch (op) switch (op)
{ {
case META_GRAB_OP_RESIZING_SE: case META_GRAB_OP_RESIZING_SE:
case META_GRAB_OP_KEYBOARD_RESIZING_SE: case META_GRAB_OP_KEYBOARD_RESIZING_SE:
cursor = META_CURSOR_SE_RESIZE; return META_CURSOR_SE_RESIZE;
break; break;
case META_GRAB_OP_RESIZING_S: case META_GRAB_OP_RESIZING_S:
case META_GRAB_OP_KEYBOARD_RESIZING_S: case META_GRAB_OP_KEYBOARD_RESIZING_S:
cursor = META_CURSOR_SOUTH_RESIZE; return META_CURSOR_SOUTH_RESIZE;
break; break;
case META_GRAB_OP_RESIZING_SW: case META_GRAB_OP_RESIZING_SW:
case META_GRAB_OP_KEYBOARD_RESIZING_SW: case META_GRAB_OP_KEYBOARD_RESIZING_SW:
cursor = META_CURSOR_SW_RESIZE; return META_CURSOR_SW_RESIZE;
break; break;
case META_GRAB_OP_RESIZING_N: case META_GRAB_OP_RESIZING_N:
case META_GRAB_OP_KEYBOARD_RESIZING_N: case META_GRAB_OP_KEYBOARD_RESIZING_N:
cursor = META_CURSOR_NORTH_RESIZE; return META_CURSOR_NORTH_RESIZE;
break; break;
case META_GRAB_OP_RESIZING_NE: case META_GRAB_OP_RESIZING_NE:
case META_GRAB_OP_KEYBOARD_RESIZING_NE: case META_GRAB_OP_KEYBOARD_RESIZING_NE:
cursor = META_CURSOR_NE_RESIZE; return META_CURSOR_NE_RESIZE;
break; break;
case META_GRAB_OP_RESIZING_NW: case META_GRAB_OP_RESIZING_NW:
case META_GRAB_OP_KEYBOARD_RESIZING_NW: case META_GRAB_OP_KEYBOARD_RESIZING_NW:
cursor = META_CURSOR_NW_RESIZE; return META_CURSOR_NW_RESIZE;
break; break;
case META_GRAB_OP_RESIZING_W: case META_GRAB_OP_RESIZING_W:
case META_GRAB_OP_KEYBOARD_RESIZING_W: case META_GRAB_OP_KEYBOARD_RESIZING_W:
cursor = META_CURSOR_WEST_RESIZE; return META_CURSOR_WEST_RESIZE;
break; break;
case META_GRAB_OP_RESIZING_E: case META_GRAB_OP_RESIZING_E:
case META_GRAB_OP_KEYBOARD_RESIZING_E: case META_GRAB_OP_KEYBOARD_RESIZING_E:
cursor = META_CURSOR_EAST_RESIZE; return META_CURSOR_EAST_RESIZE;
break; break;
case META_GRAB_OP_MOVING: case META_GRAB_OP_MOVING:
case META_GRAB_OP_KEYBOARD_MOVING: case META_GRAB_OP_KEYBOARD_MOVING:
case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN: case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN:
cursor = META_CURSOR_MOVE_OR_RESIZE_WINDOW; return META_CURSOR_MOVE_OR_RESIZE_WINDOW;
break; break;
default: default:
break; break;
} }
if (cursor == META_CURSOR_DEFAULT) return META_CURSOR_DEFAULT;
return None;
return meta_display_create_x_cursor (display, cursor);
} }
void void
@ -3941,7 +3936,6 @@ meta_display_set_grab_op_cursor (MetaDisplay *display,
Window grab_xwindow, Window grab_xwindow,
guint32 timestamp) guint32 timestamp)
{ {
Cursor cursor = xcursor_for_op (display, op);
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; 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, META_VIRTUAL_CORE_POINTER_ID,
grab_xwindow, grab_xwindow,
timestamp, timestamp,
cursor, None,
XIGrabModeAsync, XIGrabModeAsync, XIGrabModeAsync, XIGrabModeAsync,
False, /* owner_events */ False, /* owner_events */
&mask) == Success) &mask) == Success)
@ -3974,10 +3968,10 @@ meta_display_set_grab_op_cursor (MetaDisplay *display,
"XIGrabDevice() failed time %u\n", "XIGrabDevice() failed time %u\n",
timestamp); timestamp);
} }
meta_error_trap_pop (display); meta_error_trap_pop (display);
if (cursor != None) meta_cursor_tracker_set_grab_cursor (screen->cursor_tracker, meta_cursor_for_grab_op (op));
XFreeCursor (display->xdisplay, cursor);
} }
gboolean gboolean
@ -4239,7 +4233,8 @@ meta_display_end_grab_op (MetaDisplay *display,
meta_screen_ungrab_all_keys (display->grab_screen, timestamp); 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_timestamp = 0;
display->grab_window = NULL; display->grab_window = NULL;
display->grab_screen = NULL; display->grab_screen = NULL;

View File

@ -31,6 +31,8 @@
gboolean meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker, gboolean meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker,
XEvent *xevent); XEvent *xevent);
void meta_cursor_tracker_set_grab_cursor (MetaCursorTracker *tracker,
MetaCursor cursor);
void meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker, void meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker,
struct wl_resource *buffer, struct wl_resource *buffer,
int hot_x, int hot_x,

View File

@ -70,19 +70,22 @@ struct _MetaCursorTracker {
gboolean is_showing; gboolean is_showing;
gboolean has_hw_cursor; gboolean has_hw_cursor;
/* The cursor tracker stores the cursor for the window with /* The cursor tracker stores the cursor for the current grab
* pointer focus, and the cursor for the root window, which * operation, the cursor for the window with pointer focus, and
* contains either the default arrow cursor or the 'busy' * the cursor for the root window, which contains either the
* hourglass if we're launching an app. * default arrow cursor or the 'busy' hourglass if we're launching
* an app.
* *
* We choose the first one available -- if there's a window * We choose the first one available -- if there's a grab cursor,
* cursor, we choose that, otherwise we choose the root * we choose that cursor, if there's window cursor, we choose that,
* cursor. * otherwise we choose the root cursor.
* *
* The displayed_cursor contains the chosen cursor. * The displayed_cursor contains the chosen cursor.
*/ */
MetaCursorReference *displayed_cursor; MetaCursorReference *displayed_cursor;
MetaCursorReference *grab_cursor;
/* Wayland clients can set a NULL buffer as their cursor /* Wayland clients can set a NULL buffer as their cursor
* explicitly, which means that we shouldn't display anything. * explicitly, which means that we shouldn't display anything.
* So, we can't simply store a NULL in window_cursor to * 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]; 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 void
meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker, meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker,
struct wl_resource *buffer, struct wl_resource *buffer,
@ -937,6 +949,9 @@ get_displayed_cursor (MetaCursorTracker *tracker)
if (!tracker->is_showing) if (!tracker->is_showing)
return NULL; return NULL;
if (tracker->grab_cursor)
return tracker->grab_cursor;
if (tracker->has_window_cursor) if (tracker->has_window_cursor)
return tracker->window_cursor; return tracker->window_cursor;