Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
239 changes: 208 additions & 31 deletions src/backends/meta-cursor-sprite-xcursor.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,56 +43,220 @@ struct _MetaCursorSpriteXcursor
G_DEFINE_TYPE (MetaCursorSpriteXcursor, meta_cursor_sprite_xcursor,
META_TYPE_CURSOR_SPRITE)

static const char *
translate_meta_cursor (MetaCursor cursor)
const char *
meta_cursor_get_name (MetaCursor cursor)
{
switch (cursor)
{
case META_CURSOR_DEFAULT:
return "left_ptr";
case META_CURSOR_NORTH_RESIZE:
case META_CURSOR_CONTEXT_MENU:
return "left_ptr";
case META_CURSOR_HELP:
return "question_arrow";
case META_CURSOR_POINTER:
return "hand";
case META_CURSOR_PROGRESS:
return "left_ptr_watch";
case META_CURSOR_WAIT:
return "watch";
case META_CURSOR_CELL:
return "crosshair";
case META_CURSOR_CROSSHAIR:
return "cross";
case META_CURSOR_TEXT:
return "xterm";
case META_CURSOR_VERTICAL_TEXT:
return "xterm";
case META_CURSOR_ALIAS:
return "dnd-link";
case META_CURSOR_COPY:
return "dnd-copy";
case META_CURSOR_MOVE:
return "dnd-move";
case META_CURSOR_NO_DROP:
return "dnd-none";
case META_CURSOR_NOT_ALLOWED:
return "crossed_circle";
case META_CURSOR_GRAB:
return "hand2";
case META_CURSOR_GRABBING:
return "hand2";
case META_CURSOR_E_RESIZE:
return "right_side";
case META_CURSOR_N_RESIZE:
return "top_side";
case META_CURSOR_SOUTH_RESIZE:
case META_CURSOR_NE_RESIZE:
return "top_right_corner";
case META_CURSOR_NW_RESIZE:
return "top_left_corner";
case META_CURSOR_S_RESIZE:
return "bottom_side";
case META_CURSOR_WEST_RESIZE:
return "left_side";
case META_CURSOR_EAST_RESIZE:
return "right_side";
case META_CURSOR_SE_RESIZE:
return "bottom_right_corner";
case META_CURSOR_SW_RESIZE:
return "bottom_left_corner";
case META_CURSOR_W_RESIZE:
return "left_side";
case META_CURSOR_EW_RESIZE:
return "h_double_arrow";
case META_CURSOR_NS_RESIZE:
return "v_double_arrow";
case META_CURSOR_NESW_RESIZE:
return "fd_double_arrow";
case META_CURSOR_NWSE_RESIZE:
return "bd_double_arrow";
case META_CURSOR_COL_RESIZE:
return "h_double_arrow";
case META_CURSOR_ROW_RESIZE:
return "v_double_arrow";
case META_CURSOR_ALL_SCROLL:
return "left_ptr";
case META_CURSOR_ZOOM_IN:
return "left_ptr";
case META_CURSOR_ZOOM_OUT:
return "left_ptr";
case META_CURSOR_DND_ASK:
return "dnd-copy";
case META_CURSOR_ALL_RESIZE:
return "dnd-move";
case META_CURSOR_INVALID:
case META_CURSOR_NONE:
break;
}

g_assert_not_reached ();
return NULL;
}

const char *
meta_cursor_get_legacy_name (MetaCursor cursor)
{
switch (cursor)
{
case META_CURSOR_DEFAULT:
return "left_ptr";
case META_CURSOR_CONTEXT_MENU:
return "left_ptr";
case META_CURSOR_HELP:
return "question_arrow";
case META_CURSOR_POINTER:
return "hand";
case META_CURSOR_PROGRESS:
return "left_ptr_watch";
case META_CURSOR_WAIT:
return "watch";
case META_CURSOR_CELL:
return "crosshair";
case META_CURSOR_CROSSHAIR:
return "cross";
case META_CURSOR_TEXT:
return "xterm";
case META_CURSOR_VERTICAL_TEXT:
return "xterm";
case META_CURSOR_ALIAS:
return "dnd-link";
case META_CURSOR_COPY:
return "dnd-copy";
case META_CURSOR_MOVE:
return "dnd-move";
case META_CURSOR_NO_DROP:
return "dnd-none";
case META_CURSOR_NOT_ALLOWED:
return "crossed_circle";
case META_CURSOR_GRAB:
return "hand2";
case META_CURSOR_GRABBING:
return "hand2";
case META_CURSOR_E_RESIZE:
return "right_side";
case META_CURSOR_N_RESIZE:
return "top_side";
case META_CURSOR_NE_RESIZE:
return "top_right_corner";
case META_CURSOR_NW_RESIZE:
return "top_left_corner";
case META_CURSOR_MOVE_OR_RESIZE_WINDOW:
return "fleur";
case META_CURSOR_BUSY:
return "watch";
case META_CURSOR_DND_IN_DRAG:
return "dnd-none";
case META_CURSOR_DND_MOVE:
return "dnd-move";
case META_CURSOR_DND_COPY:
case META_CURSOR_S_RESIZE:
return "bottom_side";
case META_CURSOR_SE_RESIZE:
return "bottom_right_corner";
case META_CURSOR_SW_RESIZE:
return "bottom_left_corner";
case META_CURSOR_W_RESIZE:
return "left_side";
case META_CURSOR_EW_RESIZE:
return "h_double_arrow";
case META_CURSOR_NS_RESIZE:
return "v_double_arrow";
case META_CURSOR_NESW_RESIZE:
return "fd_double_arrow";
case META_CURSOR_NWSE_RESIZE:
return "bd_double_arrow";
case META_CURSOR_COL_RESIZE:
return "h_double_arrow";
case META_CURSOR_ROW_RESIZE:
return "v_double_arrow";
case META_CURSOR_ALL_SCROLL:
return "left_ptr";
case META_CURSOR_ZOOM_IN:
return "left_ptr";
case META_CURSOR_ZOOM_OUT:
return "left_ptr";
case META_CURSOR_DND_ASK:
return "dnd-copy";
case META_CURSOR_DND_UNSUPPORTED_TARGET:
return "dnd-none";
case META_CURSOR_POINTING_HAND:
return "hand2";
case META_CURSOR_CROSSHAIR:
return "crosshair";
case META_CURSOR_IBEAM:
return "xterm";
case META_CURSOR_ALL_RESIZE:
return "dnd-move";
case META_CURSOR_INVALID:
case META_CURSOR_NONE:
case META_CURSOR_LAST:
break;
}
}

g_assert_not_reached ();
return NULL;
}

static Cursor
create_blank_cursor (Display *xdisplay)
{
Pixmap pixmap;
XColor color;
Cursor cursor;
XGCValues gc_values;
GC gc;

pixmap = XCreatePixmap (xdisplay, DefaultRootWindow (xdisplay), 1, 1, 1);

gc_values.foreground = BlackPixel (xdisplay, DefaultScreen (xdisplay));
gc = XCreateGC (xdisplay, pixmap, GCForeground, &gc_values);

XFillRectangle (xdisplay, pixmap, gc, 0, 0, 1, 1);

color.pixel = 0;
color.red = color.blue = color.green = 0;

cursor = XCreatePixmapCursor (xdisplay, pixmap, pixmap, &color, &color, 1, 1);

XFreeGC (xdisplay, gc);
XFreePixmap (xdisplay, pixmap);

return cursor;
}

static XcursorImages *
create_blank_cursor_images (void)
{
XcursorImages *images;

images = XcursorImagesCreate (1);
images->images[0] = XcursorImageCreate (1, 1);

images->images[0]->xhot = 0;
images->images[0]->yhot = 0;
memset (images->images[0]->pixels, 0, sizeof(int32_t));

return images;
}

MetaCursor
meta_cursor_sprite_xcursor_get_cursor (MetaCursorSpriteXcursor *sprite_xcursor)
{
Expand All @@ -103,17 +267,30 @@ Cursor
meta_create_x_cursor (Display *xdisplay,
MetaCursor cursor)
{
return XcursorLibraryLoadCursor (xdisplay, translate_meta_cursor (cursor));
Cursor result;

if (cursor == META_CURSOR_NONE)
return create_blank_cursor (xdisplay);

result = XcursorLibraryLoadCursor (xdisplay, meta_cursor_get_name (cursor));
if (!result)
result = XcursorLibraryLoadCursor (xdisplay, meta_cursor_get_legacy_name (cursor));

return result;
}

static XcursorImages *
load_cursor_on_client (MetaCursor cursor, int scale)
load_cursor_on_client (MetaCursor cursor,
int scale)
{
if (cursor == META_CURSOR_INVALID)
return create_blank_cursor_images ();

XcursorImages *xcursor_images;
int fallback_size;

xcursor_images =
XcursorLibraryLoadImages (translate_meta_cursor (cursor),
XcursorLibraryLoadImages (meta_cursor_get_name (cursor),
meta_prefs_get_cursor_theme (),
meta_prefs_get_cursor_size () * scale);
if (xcursor_images)
Expand Down Expand Up @@ -248,7 +425,7 @@ load_cursor_from_theme (MetaCursorSprite *sprite)
{
MetaCursorSpriteXcursor *sprite_xcursor = META_CURSOR_SPRITE_XCURSOR (sprite);

g_assert (sprite_xcursor->cursor != META_CURSOR_NONE);
g_assert (sprite_xcursor->cursor != META_CURSOR_INVALID);

sprite_xcursor->theme_dirty = FALSE;

Expand Down
4 changes: 4 additions & 0 deletions src/backends/meta-cursor-sprite-xcursor.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,8 @@ XcursorImage * meta_cursor_sprite_xcursor_get_current_image (MetaCursorSpriteXcu
Cursor meta_create_x_cursor (Display *xdisplay,
MetaCursor cursor);

const char * meta_cursor_get_name (MetaCursor cursor);

const char * meta_cursor_get_legacy_name (MetaCursor cursor);

#endif /* META_CURSOR_SPRITE_XCURSOR_H */
13 changes: 8 additions & 5 deletions src/backends/x11/meta-cursor-renderer-x11.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,14 @@ meta_cursor_renderer_x11_update_cursor (MetaCursorRenderer *renderer,
Cursor xcursor;

xcursor = meta_create_x_cursor (xdisplay, cursor);
XDefineCursor (xdisplay, xwindow, xcursor);
XFlush (xdisplay);
XFreeCursor (xdisplay, xcursor);

has_server_cursor = TRUE;
if (xcursor)
{
XDefineCursor (xdisplay, xwindow, xcursor);
XFlush (xdisplay);
XFreeCursor (xdisplay, xcursor);

has_server_cursor = TRUE;
}
}
}

Expand Down
10 changes: 5 additions & 5 deletions src/core/display.c
Original file line number Diff line number Diff line change
Expand Up @@ -1662,15 +1662,15 @@ meta_cursor_for_grab_op (MetaGrabOp op)
break;
case META_GRAB_OP_RESIZING_S:
case META_GRAB_OP_KEYBOARD_RESIZING_S:
return META_CURSOR_SOUTH_RESIZE;
return META_CURSOR_S_RESIZE;
break;
case META_GRAB_OP_RESIZING_SW:
case META_GRAB_OP_KEYBOARD_RESIZING_SW:
return META_CURSOR_SW_RESIZE;
break;
case META_GRAB_OP_RESIZING_N:
case META_GRAB_OP_KEYBOARD_RESIZING_N:
return META_CURSOR_NORTH_RESIZE;
return META_CURSOR_N_RESIZE;
break;
case META_GRAB_OP_RESIZING_NE:
case META_GRAB_OP_KEYBOARD_RESIZING_NE:
Expand All @@ -1682,16 +1682,16 @@ meta_cursor_for_grab_op (MetaGrabOp op)
break;
case META_GRAB_OP_RESIZING_W:
case META_GRAB_OP_KEYBOARD_RESIZING_W:
return META_CURSOR_WEST_RESIZE;
return META_CURSOR_W_RESIZE;
break;
case META_GRAB_OP_RESIZING_E:
case META_GRAB_OP_KEYBOARD_RESIZING_E:
return META_CURSOR_EAST_RESIZE;
return META_CURSOR_E_RESIZE;
break;
case META_GRAB_OP_MOVING:
case META_GRAB_OP_KEYBOARD_MOVING:
case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN:
return META_CURSOR_MOVE_OR_RESIZE_WINDOW;
return META_CURSOR_MOVE;
break;
default:
break;
Expand Down
2 changes: 1 addition & 1 deletion src/core/startup-notification.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ meta_startup_notification_update_feedback (MetaStartupNotification *sn)
{
meta_topic (META_DEBUG_STARTUP,
"Setting busy cursor\n");
meta_display_set_cursor (display, META_CURSOR_BUSY);
meta_display_set_cursor (display, META_CURSOR_WAIT);
}
else
{
Expand Down
3 changes: 3 additions & 0 deletions src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,8 @@ if have_wayland
'wayland/meta-wayland.c',
'wayland/meta-wayland-cursor-surface.c',
'wayland/meta-wayland-cursor-surface.h',
'wayland/meta-wayland-cursor-shape.c',
'wayland/meta-wayland-cursor-shape.h',
'wayland/meta-wayland-data-device.c',
'wayland/meta-wayland-data-device.h',
'wayland/meta-wayland-data-device-primary.c',
Expand Down Expand Up @@ -798,6 +800,7 @@ if have_wayland
# - protocol stability ('private', 'stable' or 'unstable')
# - protocol version (if stability is 'unstable')
wayland_protocols = [
['cursor-shape-v1', 'private', ],
['gtk-shell', 'private', ],
['keyboard-shortcuts-inhibit', 'unstable', 'v1', ],
['linux-dmabuf', 'unstable', 'v1', ],
Expand Down
Loading
Loading