From 106d332c71f5d82b5a2748a2cb46771cff78e46c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Fri, 8 May 2020 19:00:05 +0200 Subject: [PATCH] backend/xcursor: Support a "blank" cursor type We don't have enough Xlib code in mutter ... Joking aside, it can be useful to make the cursor invisible without hiding it, for example for replacing the actual cursor with an actor in gnome-shell; the real cursor should still update the focus surface in that case, and not sneak into screenshots or -casts. https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1244 --- src/backends/meta-cursor-sprite-xcursor.c | 49 +++++++++++++++++++++++ src/meta/common.h | 2 + 2 files changed, 51 insertions(+) diff --git a/src/backends/meta-cursor-sprite-xcursor.c b/src/backends/meta-cursor-sprite-xcursor.c index 599d0e697..730d32351 100644 --- a/src/backends/meta-cursor-sprite-xcursor.c +++ b/src/backends/meta-cursor-sprite-xcursor.c @@ -84,6 +84,7 @@ translate_meta_cursor (MetaCursor cursor) return "crosshair"; case META_CURSOR_IBEAM: return "xterm"; + case META_CURSOR_BLANK: case META_CURSOR_NONE: case META_CURSOR_LAST: break; @@ -93,6 +94,48 @@ translate_meta_cursor (MetaCursor cursor) 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) { @@ -103,12 +146,18 @@ Cursor meta_create_x_cursor (Display *xdisplay, MetaCursor cursor) { + if (cursor == META_CURSOR_BLANK) + return create_blank_cursor (xdisplay); + return XcursorLibraryLoadCursor (xdisplay, translate_meta_cursor (cursor)); } static XcursorImages * load_cursor_on_client (MetaCursor cursor, int scale) { + if (cursor == META_CURSOR_BLANK) + return create_blank_cursor_images (); + return XcursorLibraryLoadImages (translate_meta_cursor (cursor), meta_prefs_get_cursor_theme (), meta_prefs_get_cursor_size () * scale); diff --git a/src/meta/common.h b/src/meta/common.h index 908dc9337..c4f634bd7 100644 --- a/src/meta/common.h +++ b/src/meta/common.h @@ -204,6 +204,7 @@ typedef enum * @META_CURSOR_POINTING_HAND: pointing hand * @META_CURSOR_CROSSHAIR: crosshair (action forbidden) * @META_CURSOR_IBEAM: I-beam (text input) + * @META_CURSOR_BLANK: Invisible cursor */ typedef enum { @@ -226,6 +227,7 @@ typedef enum META_CURSOR_POINTING_HAND, META_CURSOR_CROSSHAIR, META_CURSOR_IBEAM, + META_CURSOR_BLANK, META_CURSOR_LAST } MetaCursor;