patch 9.1.1368: GTK3 and GTK4 will drop numeric cursor support.
Problem: GTK3 and GTK4 will drop numeric cursor support.
Solution: Adopt GTK3 code and use CSS cursor convention (Drew Vogel).
closes: #14610
Signed-off-by: Drew Vogel <dvogel@github>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 6c60b58..bed14ab 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -1,4 +1,4 @@
-*options.txt* For Vim version 9.1. Last change: 2025 Apr 30
+*options.txt* For Vim version 9.1. Last change: 2025 May 07
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -6038,7 +6038,7 @@
feature}
This option tells Vim what the mouse pointer should look like in
different modes. The option is a comma-separated list of parts, much
- like used for 'guicursor'. Each part consist of a mode/location-list
+ like used for 'guicursor'. Each part consists of a mode/location-list
and an argument-list:
mode-list:shape,mode-list:shape,..
The mode-list is a dash separated list of these modes/locations:
@@ -6066,26 +6066,26 @@
The shape is one of the following:
avail name looks like ~
- w x arrow Normal mouse pointer
- w x blank no pointer at all (use with care!)
- w x beam I-beam
- w x updown up-down sizing arrows
- w x leftright left-right sizing arrows
- w x busy The system's usual busy pointer
- w x no The system's usual 'no input' pointer
- x udsizing indicates up-down resizing
- x lrsizing indicates left-right resizing
- x crosshair like a big thin +
- x hand1 black hand
- x hand2 white hand
- x pencil what you write with
- x question big ?
- x rightup-arrow arrow pointing right-up
- w x up-arrow arrow pointing up
+ w x g arrow Normal mouse pointer
+ w x blank no pointer at all (use with care!)
+ w x g beam I-beam
+ w x g updown up-down sizing arrows
+ w x g leftright left-right sizing arrows
+ w x g busy The system's usual busy pointer
+ w x g no The system's usual 'no input' pointer
+ x g udsizing indicates up-down resizing
+ x g lrsizing indicates left-right resizing
+ x g crosshair like a big thin +
+ x g hand1 black hand
+ x g hand2 white hand
+ x pencil what you write with
+ x g question big ?
+ x rightup-arrow arrow pointing right-up
+ w x up-arrow arrow pointing up
x <number> any X11 pointer number (see X11/cursorfont.h)
The "avail" column contains a 'w' if the shape is available for Win32,
- x for X11.
+ x for X11 (including GTK+ 2), g for GTK+ 3.
Any modes not specified or shapes not available use the normal mouse
pointer.
diff --git a/runtime/doc/version9.txt b/runtime/doc/version9.txt
index 9560b1d..afa800d 100644
--- a/runtime/doc/version9.txt
+++ b/runtime/doc/version9.txt
@@ -1,4 +1,4 @@
-*version9.txt* For Vim version 9.1. Last change: 2025 Apr 24
+*version9.txt* For Vim version 9.1. Last change: 2025 May 07
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -41641,6 +41641,7 @@
- New option value for 'fillchars':
"trunc" - configure truncation indicator, 'pummaxwidth'
"truncrl" - like "trunc" but in 'rl' mode, 'pummaxwidth'
+- adjust for GTK3 dropping some mouse cursors 'mouseshape'
Ex commands: ~
- allow to specify a priority when defining a new sign |:sign-define|
diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c
index f9d593f..2a11c4a 100644
--- a/src/gui_gtk_x11.c
+++ b/src/gui_gtk_x11.c
@@ -2767,57 +2767,19 @@
static GdkCursor *
create_blank_pointer(void)
{
- GdkWindow *root_window = NULL;
-#if GTK_CHECK_VERSION(3,0,0)
- GdkPixbuf *blank_mask;
-#else
- GdkPixmap *blank_mask;
-#endif
GdkCursor *cursor;
+
#if GTK_CHECK_VERSION(3,0,0)
- GdkRGBA color = { 0.0, 0.0, 0.0, 0.0 };
+ GdkDisplay *disp = gtk_widget_get_display(gui.mainwin);
+ cursor = gdk_cursor_new_from_name(disp, "none");
#else
- GdkColor color = { 0, 0, 0, 0 };
- char blank_data[] = { 0x0 };
-#endif
-
-#if GTK_CHECK_VERSION(3,12,0)
- {
- GdkWindow * const win = gtk_widget_get_window(gui.mainwin);
- GdkScreen * const scrn = gdk_window_get_screen(win);
- root_window = gdk_screen_get_root_window(scrn);
- }
-#else
- root_window = gtk_widget_get_root_window(gui.mainwin);
-#endif
-
// Create a pseudo blank pointer, which is in fact one pixel by one pixel
// in size.
-#if GTK_CHECK_VERSION(3,0,0)
- {
- cairo_surface_t *surf;
- cairo_t *cr;
-
- surf = cairo_image_surface_create(CAIRO_FORMAT_A1, 1, 1);
- cr = cairo_create(surf);
-
- cairo_set_source_rgba(cr,
- color.red,
- color.green,
- color.blue,
- color.alpha);
- cairo_rectangle(cr, 0, 0, 1, 1);
- cairo_fill(cr);
- cairo_destroy(cr);
-
- blank_mask = gdk_pixbuf_get_from_surface(surf, 0, 0, 1, 1);
- cairo_surface_destroy(surf);
-
- cursor = gdk_cursor_new_from_pixbuf(gdk_window_get_display(root_window),
- blank_mask, 0, 0);
- g_object_unref(blank_mask);
- }
-#else
+ GdkWindow *root_window = NULL;
+ GdkColor color = { 0, 0, 0, 0 };
+ GdkPixmap *blank_mask;
+ char blank_data[] = { 0x0 };
+ root_window = gtk_widget_get_root_window(gui.mainwin);
blank_mask = gdk_bitmap_create_from_data(root_window, blank_data, 1, 1);
cursor = gdk_cursor_new_from_pixmap(blank_mask, blank_mask,
&color, &color, 0, 0);
@@ -7242,6 +7204,28 @@
#if defined(FEAT_MOUSESHAPE) || defined(PROTO)
+# if GTK_CHECK_VERSION(3,0,0)
+static const char * mshape_css_names[] =
+{
+ "default", // arrow aka GDK_LEFT_PTR
+ "blank", // blank aka GDK_CURSOR_IS_PIXMAP
+ "text", // beam aka GDK_XTERM
+ "ns-resize", // updown aka GDK_SB_V_DOUBLE_ARROW
+ "nwse-resize", // udsizing aka GDK_SIZING
+ "ew-resize", // leftright aka GDK_SB_H_DOUBLE_ARROW
+ "ew-resize", // lrsizing aka GDK_SIZING
+ "progress", // busy aka GDK_WATCH
+ "not-allowed", // no aka GDK_X_CURSOR
+ "crosshair", // crosshair aka GDK_CROSSHAIR
+ "pointer", // hand1 aka GDK_HAND1
+ "pointer", // hand2 aka GDK_HAND2
+ "default", // pencil aka GDK_PENCIL (no css analogue)
+ "help", // question aka GDK_QUESTION_ARROW
+ "default", // right-arrow aka GDK_RIGHT_PTR (no css analogue)
+ "default", // up-arrow aka GDK_CENTER_PTR (no css analogue)
+ "default" // GDK_LEFT_PTR (no css analogue)
+};
+# else
// Table for shape IDs. Keep in sync with the mshape_names[] table in
// misc2.c!
static const int mshape_ids[] =
@@ -7264,12 +7248,17 @@
GDK_CENTER_PTR, // up-arrow
GDK_LEFT_PTR // last one
};
+# endif // GTK_CHECK_VERSION(3,0,0)
void
mch_set_mouse_shape(int shape)
{
- int id;
GdkCursor *c;
+ int id; // Only id or css_name is used.
+# if GTK_CHECK_VERSION(3,0,0)
+ const char *css_name = "default";
+ GdkDisplay *disp;
+# endif
if (gtk_widget_get_window(gui.drawarea) == NULL)
return;
@@ -7287,12 +7276,22 @@
else
id &= ~1; // they are always even (why?)
}
+# if GTK_CHECK_VERSION(3,0,0)
+ else if (shape < (int)ARRAY_LENGTH(mshape_css_names))
+ css_name = mshape_css_names[shape];
+# else
else if (shape < (int)ARRAY_LENGTH(mshape_ids))
id = mshape_ids[shape];
+# endif
else
return;
+# if GTK_CHECK_VERSION(3,0,0)
+ disp = gtk_widget_get_display(gui.drawarea);
+ c = gdk_cursor_new_from_name(disp, css_name);
+# else
c = gdk_cursor_new_for_display(
gtk_widget_get_display(gui.drawarea), (GdkCursorType)id);
+# endif
gdk_window_set_cursor(gtk_widget_get_window(gui.drawarea), c);
# if GTK_CHECK_VERSION(3,0,0)
g_object_unref(G_OBJECT(c));
diff --git a/src/version.c b/src/version.c
index 7210073..0805703 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1368,
+/**/
1367,
/**/
1366,