Commit: patch 9.2.0865: GTK4: non-hardware accelerated UI is too slow
Christian Brabandt <[email protected]> Mon, 27 Jul 2026 23:00:05 +0200
| Newsgroups | gmane.editors.vim.devel |
|---|---|
| Message-ID | <[email protected]> |
patch 9.2.0865: GTK4: non-hardware accelerated UI is too slow Commit: https://github.com/vim/vim/commit/b56b4a3a6691a610f53f6d7a1ba721af3ad46b35 Author: Foxe Chen <[email protected]> Date: Mon Jul 27 20:43:18 2026 +0000 patch 9.2.0865: GTK4: non-hardware accelerated UI is too slow Problem: GTK4: non-hardware accelerated UI is too slow Solution: Remove the sofware rendering (cairo) backend, make the GTK4 hardware accelerated rendering the default (Foxe Chen). closes: #20844 Signed-off-by: Foxe Chen <[email protected]> Signed-off-by: Christian Brabandt <[email protected]> diff --git a/runtime/doc/gui_x11.txt b/runtime/doc/gui_x11.txt index 58467023a..8f37a154c 100644 --- a/runtime/doc/gui_x11.txt +++ b/runtime/doc/gui_x11.txt @@ -1,4 +1,4 @@ -*gui_x11.txt* For Vim version 9.2. Last change: 2026 Jun 29 +*gui_x11.txt* For Vim version 9.2. Last change: 2026 Jul 27 VIM REFERENCE MANUAL by Bram Moolenaar @@ -371,14 +371,6 @@ to use software rendering: > $ GSK_RENDERER=cairo gvim $ LIBGL_ALWAYS_SOFTWARE=true gvim < - *gtk4-hwaccel* -If Vim is compiled with the configure option "--enable-gtk4-hwaccel" set, then -the GTK4 GUI will use GtkSnapshot instead of Cairo, allowing for hardware -accelerated rendering, which is much faster. Enabling this configure option -also makes the GTK4 GUI use |+image_gdk| instead of |+image_cairo| for -rendering popup window images. Note that this feature is currently -experimental. - Tooltip Colors ~ *gtk-tooltip-colors* Example, which sets the tooltip colors to black on light-yellow: > diff --git a/runtime/doc/tags b/runtime/doc/tags index b01ae4204..28c30f03c 100644 --- a/runtime/doc/tags +++ b/runtime/doc/tags @@ -8260,7 +8260,6 @@ gt tabpage.txt /*gt* gtk-css gui_x11.txt /*gtk-css* gtk-tooltip-colors gui_x11.txt /*gtk-tooltip-colors* gtk3-slow gui_x11.txt /*gtk3-slow* -gtk4-hwaccel gui_x11.txt /*gtk4-hwaccel* gtk4-menu-navigation gui_x11.txt /*gtk4-menu-navigation* gtk4-slow gui_x11.txt /*gtk4-slow* gu change.txt /*gu* diff --git a/runtime/doc/version9.txt b/runtime/doc/version9.txt index efe88e949..738e95bdb 100644 --- a/runtime/doc/version9.txt +++ b/runtime/doc/version9.txt @@ -1,4 +1,4 @@ -*version9.txt* For Vim version 9.2. Last change: 2026 Jul 22 +*version9.txt* For Vim version 9.2. Last change: 2026 Jul 27 VIM REFERENCE MANUAL by Bram Moolenaar @@ -52663,7 +52663,6 @@ Platform specific ~ ----------------- - support OpenType font features in 'guifont' for DirectWrite (Win32) - Include strptime() fallback for MS-Windows -- Hardware-accelerated rendering for the GTK4 GUI via |gtk4-hwaccel|. - The NSIS installer has been reworked (Win32): - Support per-user and per-machine install. - Change the install directory structure. diff --git a/src/auto/configure b/src/auto/configure index ffdff9662..8fd4ba3b7 100755 --- a/src/auto/configure +++ b/src/auto/configure @@ -862,7 +862,6 @@ enable_gui enable_gtk2_check enable_gnome_check enable_gtk4_check -enable_gtk4_hwaccel enable_gtk3_check enable_motif_check enable_gtktest @@ -1542,7 +1541,6 @@ Optional Features: --enable-gtk2-check If auto-select GUI, check for GTK+ 2 default=yes --enable-gnome-check If GTK GUI, check for GNOME default=no --enable-gtk4-check If auto-select GUI, check for GTK 4 default=yes - --enable-gtk4-hwaccel Use hardware accelerated rendering backend for GTK4 default=no --enable-gtk3-check If auto-select GUI, check for GTK+ 3 default=yes --enable-motif-check If auto-select GUI, check for Motif default=yes --disable-gtktest Do not try to compile and run a test GTK program @@ -10583,28 +10581,6 @@ printf "%s " "$enable_gtk4_check" >&6; } fi fi -if test "x$SKIP_GTK4" != "xYES" -a "$enable_gui_canon" = "gtk4"; then - { printf "%s " "$as_me:${as_lineno-$LINENO}: checking --enable-gtk4-hwaccel argument" >&5 -printf %s "checking --enable-gtk4-hwaccel argument... " >&6; } - # Check whether --enable-gtk4-hwaccel was given. -if test ${enable_gtk4_hwaccel+y} -then : - enableval=$enable_gtk4_hwaccel; -else case e in #( - e) enable_gtk4_hwaccel="no" ;; -esac -fi - - { printf "%s " "$as_me:${as_lineno-$LINENO}: result: $enable_gtk4_hwaccel" >&5 -printf "%s " "$enable_gtk4_hwaccel" >&6; } - - if test "x$enable_gtk4_hwaccel" = "xyes"; then - printf "%s " "#define USE_GTK4_SNAPSHOT 1" >>confdefs.h - - fi -fi - - if test "x$SKIP_GTK3" != "xYES" -a "$enable_gui_canon" != "gtk3"; then { printf "%s " "$as_me:${as_lineno-$LINENO}: checking whether or not to look for GTK+ 3" >&5 printf %s "checking whether or not to look for GTK+ 3... " >&6; } diff --git a/src/config.h.in b/src/config.h.in index bb16501ea..d26bd2078 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -499,9 +499,6 @@ /* Define if GTK GUI is to be linked against GTK 4 */ #undef USE_GTK4 -/* Define if GTK4 GUI should use hardware accelerated backend */ -#undef USE_GTK4_SNAPSHOT - /* Define if we have isinf() */ #undef HAVE_ISINF diff --git a/src/configure.ac b/src/configure.ac index 0cf75308b..654959874 100644 --- a/src/configure.ac +++ b/src/configure.ac @@ -2715,19 +2715,6 @@ if test "x$SKIP_GTK4" != "xYES" -a "$enable_gui_canon" != "gtk4"; then fi fi -if test "x$SKIP_GTK4" != "xYES" -a "$enable_gui_canon" = "gtk4"; then - AC_MSG_CHECKING(--enable-gtk4-hwaccel argument) - AC_ARG_ENABLE(gtk4-hwaccel, - [ --enable-gtk4-hwaccel Use hardware accelerated rendering backend for GTK4 [default=no]], - , enable_gtk4_hwaccel="no") - AC_MSG_RESULT($enable_gtk4_hwaccel) - - if test "x$enable_gtk4_hwaccel" = "xyes"; then - AC_DEFINE(USE_GTK4_SNAPSHOT) - fi -fi - - if test "x$SKIP_GTK3" != "xYES" -a "$enable_gui_canon" != "gtk3"; then AC_MSG_CHECKING(whether or not to look for GTK+ 3) AC_ARG_ENABLE(gtk3-check, diff --git a/src/feature.h b/src/feature.h index 3a0b6931c..5d5512615 100644 --- a/src/feature.h +++ b/src/feature.h @@ -1132,7 +1132,7 @@ #endif #if defined(FEAT_IMAGE) && defined(FEAT_GUI_GTK) -# ifdef USE_GTK4_SNAPSHOT +# ifdef USE_GTK4 # define FEAT_IMAGE_GDK # else # define FEAT_IMAGE_CAIRO diff --git a/src/gui.c b/src/gui.c index d58f9f2cc..5d6eae105 100644 --- a/src/gui.c +++ b/src/gui.c @@ -24,7 +24,7 @@ static void set_guifontwide(char_u *font_name); static void gui_check_pos(void); static void gui_reset_scroll_region(void); static void gui_outstr(char_u *, int); -#ifndef USE_GTK4_SNAPSHOT +#ifndef USE_GTK4 static int gui_screenchar(int off, int flags, guicolor_T fg, guicolor_T bg, int back); #endif static int gui_outstr_nowrap(char_u *s, int len, int flags, guicolor_T fg, guicolor_T bg, int back); @@ -1199,7 +1199,7 @@ gui_update_cursor( int cattr; // cursor attributes int attr; attrentry_T *aep = NULL; -#if (defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MSWIN)) && !defined(USE_GTK4_SNAPSHOT) +#if (defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MSWIN)) && !defined(USE_GTK4) bool lig_left = false, lig_right = false; #endif @@ -1367,7 +1367,7 @@ gui_update_cursor( */ if (!gui.in_focus) { -#ifdef USE_GTK4_SNAPSHOT +#ifdef USE_GTK4 gui_gtk4_draw_cursor(cbg, cfg, -1, -1); #else gui_mch_draw_hollow_cursor(cbg); @@ -1375,7 +1375,7 @@ gui_update_cursor( return; } -#ifdef USE_GTK4_SNAPSHOT +#ifdef USE_GTK4 // Make sure that character underneath is drawn again in case it is part of // a ligature. gui_redraw_block(gui.row, gui.col, gui.row, gui.col, GUI_MON_NOCLEAR); @@ -1392,7 +1392,7 @@ gui_update_cursor( { gui_redraw_block(gui.row, c + 1, gui.row, gui.col - 1, GUI_MON_NOCLEAR); -# ifndef USE_GTK4_SNAPSHOT +# ifndef USE_GTK4 lig_left = true; # endif } @@ -1406,7 +1406,7 @@ gui_update_cursor( { gui_redraw_block(gui.row, gui.col + 1, gui.row, c - 1, GUI_MON_NOCLEAR); -# ifndef USE_GTK4_SNAPSHOT +# ifndef USE_GTK4 lig_right = true; # endif } @@ -1416,7 +1416,7 @@ gui_update_cursor( // it again. gui.cursor_is_valid = true; -# ifndef USE_GTK4_SNAPSHOT +# ifndef USE_GTK4 if ((lig_left || lig_right) && shape->shape != SHAPE_BLOCK) { // Because the cursor is not drawn with gui_screenchar(), must blit the @@ -1435,7 +1435,7 @@ gui_update_cursor( old_hl_mask = gui.highlight_mask; if (shape->shape == SHAPE_BLOCK) { -#ifdef USE_GTK4_SNAPSHOT +#ifdef USE_GTK4 gui_gtk4_draw_cursor(cbg, cfg, 0, 0); #else /* @@ -1484,7 +1484,7 @@ gui_update_cursor( } #endif } -#ifdef USE_GTK4_SNAPSHOT +#ifdef USE_GTK4 gui_gtk4_draw_cursor(cbg, cfg, cur_width, cur_height); #else gui_mch_draw_part_cursor(cur_width, cur_height, cbg); @@ -1496,7 +1496,7 @@ gui_update_cursor( // Doesn't seem to work for MSWindows. We call gui_redraw_block() above // for GtkSnapshot. -#if !defined(FEAT_GUI_MSWIN) && !defined(USE_GTK4_SNAPSHOT) +#if !defined(FEAT_GUI_MSWIN) && !defined(USE_GTK4) gui.highlight_mask = ScreenAttrs[LineOffset[gui.row] + gui.col]; (void)gui_screenchar(LineOffset[gui.row] + gui.col, GUI_MON_TRS_CURSOR | GUI_MON_NOCLEAR, @@ -1689,14 +1689,14 @@ again: gui.num_cols = (pixel_width - gui_get_base_width()) / gui.char_width; gui.num_rows = (pixel_height - gui_get_base_height()) / gui.char_height; -#ifdef USE_GTK4_SNAPSHOT +#ifdef USE_GTK4 gui_gtk4_update_size(); #endif gui_position_components(pixel_width); gui_reset_scroll_region(); -#if defined(FEAT_GUI_GTK) && defined(USE_GTK4) && !defined(USE_GTK4_SNAPSHOT) +#if defined(FEAT_GUI_GTK) && defined(USE_GTK4) && !defined(USE_GTK4) // We do not resize the draw area via the "resize" signal. This is because // when the window is resized, the form widget is the one that is resized, // so let that call gui_resize_shell() which will allocate the surface and @@ -1726,7 +1726,7 @@ again: gui_update_scrollbars(TRUE); gui_update_cursor(FALSE, TRUE); -#if defined(FEAT_GUI_GTK) && defined(USE_GTK4_SNAPSHOT) +#if defined(FEAT_GUI_GTK) && defined(USE_GTK4) gui_gtk4_calculate_bleed(pixel_width, pixel_height); #endif #if defined(FEAT_XIM) && !defined(FEAT_GUI_GTK) @@ -1899,7 +1899,7 @@ gui_set_shellsize( gui_update_scrollbars(TRUE); gui_reset_scroll_region(); -#if defined(FEAT_GUI_GTK) && defined(USE_GTK4_SNAPSHOT) +#if defined(FEAT_GUI_GTK) && defined(USE_GTK4) gui_gtk4_calculate_bleed(width, height); #endif } @@ -2293,7 +2293,7 @@ gui_outstr(char_u *s, int len) } } -#ifndef USE_GTK4_SNAPSHOT +#ifndef USE_GTK4 /* * Output one character (may be one or two display cells). * Caller must check for valid "off". diff --git a/src/gui.h b/src/gui.h index 16f13e477..e2232982e 100644 --- a/src/gui.h +++ b/src/gui.h @@ -285,7 +285,7 @@ typedef struct Gui #ifdef FEAT_DIRECTX bool directx_enabled; // DirectX (DirectWrite) rendering active #endif -#if defined(FEAT_GUI_GTK) && defined(USE_GTK4_SNAPSHOT) +#if defined(FEAT_GUI_GTK) && defined(USE_GTK4) int bleed_right; // Number of pixels to bleed bg color right int bleed_bot; // Number of pixels to bleed bg color down #endif @@ -400,11 +400,9 @@ typedef struct Gui GdkColor *bgcolor; // GDK-styled background color GdkColor *spcolor; // GDK-styled special color # endif -# if defined(USE_GTK3) || defined(USE_GTK4) -# ifndef USE_GTK4_SNAPSHOT +# if defined(USE_GTK3) && !defined(USE_GTK4) cairo_surface_t *surface; // drawarea surface -# endif -# else +# elif !defined(USE_GTK4) GdkGC *text_gc; // cached GC for normal text # endif PangoContext *text_context; // the context used for all text diff --git a/src/gui_gtk4.c b/src/gui_gtk4.c index 6e5dbfda1..93851af7c 100644 --- a/src/gui_gtk4.c +++ b/src/gui_gtk4.c @@ -30,9 +30,7 @@ #include <gtk/gtk.h> #include "gui_gtk4_f.h" #include "gui_gtk4_cb.h" -#ifdef USE_GTK4_SNAPSHOT -# include "gui_gtk4_da.h" -#endif +#include "gui_gtk4_da.h" #ifdef FEAT_TOOLBAR # include "gui_gtk4_tb.h" #endif @@ -271,9 +269,6 @@ modifiers_gdk2vim(guint state) static GtkWidget *vbox; // the main vertical box // Forward declarations for event callbacks -#ifndef USE_GTK4_SNAPSHOT -static void draw_event(GtkDrawingArea *area, cairo_t *cr, int width, int height, gpointer data); -#endif static gboolean key_press_event(GtkEventControllerKey *controller, guint keyval, guint keycode, GdkModifierType state, gpointer data); static void key_release_event(GtkEventControllerKey *controller, guint keyval, guint keycode, GdkModifierType state, gpointer data); static void button_press_event(GtkGestureClick *gesture, int n_press, double x, double y, gpointer data); @@ -299,9 +294,6 @@ static int query_pointer_pos(int *x, int *y, GdkModifierType *state); static void mainwin_fullscreened_cb(GObject *obj, GParamSpec *pspec, gpointer user_data); static void drawarea_realize_cb(GtkWidget *widget, gpointer data); static void drawarea_unrealize_cb(GtkWidget *widget, gpointer data); -#ifndef USE_GTK4_SNAPSHOT -static cairo_surface_t *create_backing_surface(int width, int height); -#endif static void scale_factor_cb(GdkSurface *surface, GParamSpec *pspec, void *udata); static void clipboard_changed_cb(GdkClipboard *clipboard, gpointer user_data); #ifdef FEAT_MENU @@ -554,22 +546,12 @@ gui_mch_init(void) gtk_box_append(GTK_BOX(vbox), gui.formwin); // The drawing area for the editor content. -#ifdef USE_GTK4_SNAPSHOT gui.drawarea = vim_draw_area_new(); -#else - gui.drawarea = gtk_drawing_area_new(); - gui.surface = NULL; -#endif gtk_widget_set_focusable(gui.drawarea, TRUE); gtk_widget_set_vexpand(gui.drawarea, TRUE); gtk_widget_set_hexpand(gui.drawarea, TRUE); vim_form_put(VIM_FORM(gui.formwin), gui.drawarea, 0, 0); -#ifndef USE_GTK4_SNAPSHOT - // Set up drawing. - gtk_drawing_area_set_draw_func(GTK_DRAWING_AREA(gui.drawarea), - (GtkDrawingAreaDrawFunc)draw_event, NULL, NULL); -#endif g_signal_connect(G_OBJECT(gui.drawarea), "realize", G_CALLBACK(drawarea_realize_cb), NULL); g_signal_connect(G_OBJECT(gui.drawarea), "unrealize", @@ -664,31 +646,9 @@ gui_mch_init(void) return OK; } -#ifndef USE_GTK4_SNAPSHOT -/* - * Called when the foreground or background color has been changed. - */ - static void -surface_fill_bg(void) -{ - if (gui.surface != NULL) - { - cairo_t *cr = cairo_create(gui.surface); - cairo_set_source_rgba(cr, - gui.bgcolor->red, gui.bgcolor->green, - gui.bgcolor->blue, gui.bgcolor->alpha); - cairo_paint(cr); - cairo_destroy(cr); - } -} -#endif - void gui_mch_new_colors(void) { -#ifndef USE_GTK4_SNAPSHOT - surface_fill_bg(); -#endif if (gui.drawarea != NULL && gtk_widget_get_realized(gui.drawarea)) gtk_widget_queue_draw(gui.drawarea); } @@ -1427,7 +1387,6 @@ gui_mch_get_rgb(guicolor_T pixel) * ============================================================ */ -#ifdef USE_GTK4_SNAPSHOT void gui_gtk4_update_size(void) { @@ -1435,7 +1394,7 @@ gui_gtk4_update_size(void) gui.num_rows, gui.num_cols); } -# ifdef FEAT_NETBEANS_INTG +#ifdef FEAT_NETBEANS_INTG void gui_gtk4_add_multisign( cairo_surface_t *surf, @@ -1447,90 +1406,13 @@ gui_gtk4_add_multisign( vim_draw_area_add_multisign(VIM_DRAW_AREA(gui.drawarea), surf, row, col, width, height); } -# endif -#else // USE_GTK4_SNAPSHOT -static void set_cairo_source_from_pixel(cairo_t *cr, guicolor_T pixel); - - static void -draw_event(GtkDrawingArea *area UNUSED, cairo_t *cr, - int width, int height, gpointer data UNUSED) -{ - // Surface creation/resizing is handled by drawarea_resize_cb. - // Here we only paint the surface to the widget. - - // Fill background with Vim's background color - set_cairo_source_from_pixel(cr, gui.back_pixel); - cairo_rectangle(cr, 0, 0, width, height); - cairo_fill(cr); - - // Paint the Vim surface on top - if (gui.surface != NULL) - { - cairo_set_source_surface(cr, gui.surface, 0, 0); - cairo_paint(cr); - } -} - - static void -set_cairo_source_from_pixel(cairo_t *cr, guicolor_T pixel) -{ - cairo_set_source_rgb(cr, - ((pixel & 0xff0000) >> 16) / 255.0, - ((pixel & 0xff00) >> 8) / 255.0, - (pixel & 0xff) / 255.0); -} - - static int -get_drawarea_scale(void) -{ - int scale = 1; - - if (gui.drawarea != NULL) - scale = gtk_widget_get_scale_factor(gui.drawarea); - if (scale < 1) - scale = 1; - return scale; -} - - static cairo_surface_t * -create_backing_surface(int width, int height) -{ - cairo_surface_t *surf; - int scale; - - if (width <= 0 || height <= 0) - return NULL; - - scale = get_drawarea_scale(); - surf = cairo_image_surface_create( - CAIRO_FORMAT_ARGB32, width * scale, height * scale); - cairo_surface_set_device_scale(surf, (double)scale, (double)scale); - return surf; -} -#endif // !USE_GTK4_SNAPSHOT +#endif void gui_mch_clear_block(int row1, int col1, int row2, int col2) { -#ifdef USE_GTK4_SNAPSHOT vim_draw_area_clear_block(VIM_DRAW_AREA(gui.drawarea), row1, col1, row2, col2); -#else - cairo_t *cr; - - if (gui.surface == NULL) - return; - - cr = cairo_create(gui.surface); - set_cairo_source_from_pixel(cr, gui.back_pixel); - cairo_rectangle(cr, - FILL_X(col1), FILL_Y(row1), - (col2 - col1 + 1) * gui.char_width, - (row2 - row1 + 1) * gui.char_height); - cairo_fill(cr); - cairo_destroy(cr); -#endif - if (gui.drawarea != NULL) gtk_widget_queue_draw(gui.drawarea); } @@ -1538,20 +1420,7 @@ gui_mch_clear_block(int row1, int col1, int row2, int col2) void gui_mch_clear_all(void) { -#ifdef USE_GTK4_SNAPSHOT vim_draw_area_clear(VIM_DRAW_AREA(gui.drawarea)); -#else - cairo_t *cr; - - if (gui.surface == NULL) - return; - - cr = cairo_create(gui.surface); - set_cairo_source_from_pixel(cr, gui.back_pixel); - cairo_paint(cr); - cairo_destroy(cr); -#endif - if (gui.drawarea != NULL) gtk_widget_queue_draw(gui.drawarea); } @@ -1687,52 +1556,12 @@ gui_mch_draw_popup_image( } #endif // FEAT_IMAGE_CAIRO -#ifndef USE_GTK4_SNAPSHOT - static void -surface_copy_rect(int dest_x, int dest_y, - int src_x, int src_y, - int width, int height) -{ - cairo_t *cr; - cairo_surface_t *tmp; - - if (gui.surface == NULL || width <= 0 || height <= 0) - return; - - // Use a temporary surface to avoid overlap issues - tmp = create_backing_surface(width, height); - if (tmp == NULL) - return; - cr = cairo_create(tmp); - cairo_set_source_surface(cr, gui.surface, -src_x, -src_y); - cairo_paint(cr); - cairo_destroy(cr); - - cr = cairo_create(gui.surface); - cairo_set_source_surface(cr, tmp, dest_x, dest_y); - cairo_paint(cr); - cairo_destroy(cr); - cairo_surface_destroy(tmp); -} -#endif - void gui_mch_delete_lines(int row, int num_lines) { -#ifdef USE_GTK4_SNAPSHOT vim_draw_area_move_block(VIM_DRAW_AREA(gui.drawarea), row, row + num_lines, gui.scroll_region_bot, gui.scroll_region_left, gui.scroll_region_right); -#else - int ncols = gui.scroll_region_right - gui.scroll_region_left + 1; - int nrows = gui.scroll_region_bot - row + 1; - int src_nrows = nrows - num_lines; - - surface_copy_rect( - FILL_X(gui.scroll_region_left), FILL_Y(row), - FILL_X(gui.scroll_region_left), FILL_Y(row + num_lines), - gui.char_width * ncols + 1, gui.char_height * src_nrows); -#endif gui_clear_block( gui.scroll_region_bot - num_lines + 1, gui.scroll_region_left, gui.scroll_region_bot, gui.scroll_region_right); @@ -1743,20 +1572,9 @@ gui_mch_delete_lines(int row, int num_lines) void gui_mch_insert_lines(int row, int num_lines) { -#ifdef USE_GTK4_SNAPSHOT vim_draw_area_move_block(VIM_DRAW_AREA(gui.drawarea), row + num_lines, row, gui.scroll_region_bot - num_lines, gui.scroll_region_left, gui.scroll_region_right); -#else - int ncols = gui.scroll_region_right - gui.scroll_region_left + 1; - int nrows = gui.scroll_region_bot - row + 1; - int src_nrows = nrows - num_lines; - - surface_copy_rect( - FILL_X(gui.scroll_region_left), FILL_Y(row + num_lines), - FILL_X(gui.scroll_region_left), FILL_Y(row), - gui.char_width * ncols + 1, gui.char_height * src_nrows); -#endif gui_clear_block( row, gui.scroll_region_left, row + num_lines - 1, gui.scroll_region_right); @@ -1764,7 +1582,6 @@ gui_mch_insert_lines(int row, int num_lines) gtk_widget_queue_draw(gui.drawarea); } -#if defined(USE_GTK4_SNAPSHOT) || defined(PROTO) /* * See vim_draw_area_set_cursor() for more information */ @@ -1776,70 +1593,11 @@ gui_gtk4_draw_cursor(guicolor_T bg, guicolor_T fg, int w, int h) vim_draw_area_set_cursor(VIM_DRAW_AREA(gui.drawarea), w, h); gtk_widget_queue_draw(gui.drawarea); } -#endif - -#if !defined(USE_GTK4_SNAPSHOT) || defined(PROTO) - void -gui_mch_draw_hollow_cursor(guicolor_T color) -{ - cairo_t *cr; - int i = 1; - - if (gui.surface == NULL) - return; - - cr = cairo_create(gui.surface); - gui_mch_set_fg_color(color); - cairo_set_source_rgba(cr, - gui.fgcolor->red, gui.fgcolor->green, - gui.fgcolor->blue, gui.fgcolor->alpha); - if (mb_lefthalve(gui.row, gui.col)) - i = 2; - cairo_set_line_width(cr, 1.0); - cairo_rectangle(cr, - FILL_X(gui.col) + 0.5, FILL_Y(gui.row) + 0.5, - i * gui.char_width - 1, gui.char_height - 1); - cairo_stroke(cr); - cairo_destroy(cr); - - gtk_widget_queue_draw(gui.drawarea); -} - - void -gui_mch_draw_part_cursor(int w, int h, guicolor_T color) -{ - cairo_t *cr; - - if (gui.surface == NULL) - return; - - gui_mch_set_fg_color(color); - cr = cairo_create(gui.surface); - cairo_set_source_rgba(cr, - gui.fgcolor->red, gui.fgcolor->green, - gui.fgcolor->blue, gui.fgcolor->alpha); - cairo_rectangle(cr, -# ifdef FEAT_RIGHTLEFT - CURSOR_BAR_RIGHT ? FILL_X(gui.col + 1) - w : -# endif - FILL_X(gui.col), FILL_Y(gui.row) + gui.char_height - h, - w, h); - cairo_fill(cr); - cairo_destroy(cr); - - gtk_widget_queue_draw(gui.drawarea); -} -#endif void gui_mch_flash(int msec) { // Invert the screen, wait, then invert back -#ifndef USE_GTK4_SNAPSHOT - if (gui.surface == NULL) - return; -#endif - gui_mch_invert_rectangle(0, 0, (int)Rows - 1, (int)Columns - 1); gui_mch_flush(); ui_delay((long)msec, TRUE); @@ -1849,24 +1607,7 @@ gui_mch_flash(int msec) void gui_mch_invert_rectangle(int r, int c, int nr, int nc) { -#ifdef USE_GTK4_SNAPSHOT vim_draw_area_invert_block(VIM_DRAW_AREA(gui.drawarea), r, c, nr, nc); -#else - cairo_t *cr; - - if (gui.surface == NULL) - return; - - cr = cairo_create(gui.surface); - cairo_set_operator(cr, CAIRO_OPERATOR_DIFFERENCE); - cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); - cairo_rectangle(cr, - FILL_X(c), FILL_Y(r), - (nc + 1) * gui.char_width, (nr + 1) * gui.char_height); - cairo_fill(cr); - cairo_destroy(cr); -#endif - gtk_widget_queue_draw(gui.drawarea); } @@ -2318,39 +2059,15 @@ focus_out_event(GtkEventControllerFocus *controller UNUSED, static void drawarea_realize_cb(GtkWidget *widget UNUSED, gpointer data UNUSED) { -#ifndef USE_GTK4_SNAPSHOT - int w, h; - - // Use formwin size since drawarea may not have its final size yet - if (gui.formwin != NULL) - { - w = gtk_widget_get_width(gui.formwin); - h = gtk_widget_get_height(gui.formwin); - } - else - { - w = gtk_widget_get_width(widget); - h = gtk_widget_get_height(widget); - } - - if (w <= 0) w = 800; - if (h <= 0) h = 600; + // Use GdkSurface, as that handles fractional scale values. + GdkSurface *surface = gtk_native_get_surface( + gtk_widget_get_native(gui.drawarea)); + double old = gui.scale; - if (gui.surface != NULL) - cairo_surface_destroy(gui.surface); - gui.surface = create_backing_surface(w, h); -#endif - { - // Use GdkSurface, as that handles fractional scale values. - GdkSurface *surface = gtk_native_get_surface( - gtk_widget_get_native(gui.drawarea)); - double old = gui.scale; - - gui.scale = gdk_surface_get_scale(surface); - popup_update_scale(old); - g_signal_connect(G_OBJECT(surface), "notify::scale", - G_CALLBACK(scale_factor_cb), NULL); - } + gui.scale = gdk_surface_get_scale(surface); + popup_update_scale(old); + g_signal_connect(G_OBJECT(surface), "notify::scale", + G_CALLBACK(scale_factor_cb), NULL); gui_mch_new_colors(); } @@ -2361,98 +2078,18 @@ drawarea_unrealize_cb(GtkWidget *widget UNUSED, gpointer data UNUSED) #ifdef FEAT_XIM im_shutdown(); #endif -#ifndef USE_GTK4_SNAPSHOT - if (gui.surface != NULL) - { - cairo_surface_destroy(gui.surface); - gui.surface = NULL; - } -#endif -} - -#ifndef USE_GTK4_SNAPSHOT - void -gui_gtk4_resize(int width, int height) -{ - cairo_t *cr; - cairo_surface_t *old_surface; - int scale = get_drawarea_scale(); - - if (width <= 0 || height <= 0) - return; - - // Keep the backing surface in sync with the drawing area so GTK keeps - // showing the previous frame. Re-creating it preserves the old - // contents. - if (gui.surface != NULL) - { - int sw = cairo_image_surface_get_width(gui.surface) / scale; - int sh = cairo_image_surface_get_height(gui.surface) / scale; - if (sw != width || sh != height) - { - old_surface = gui.surface; - gui.surface = create_backing_surface(width, height); - if (gui.surface != NULL) - { - cr = cairo_create(gui.surface); - set_cairo_source_from_pixel(cr, gui.back_pixel); - cairo_paint(cr); - cairo_set_source_surface(cr, old_surface, 0, 0); - cairo_paint(cr); - cairo_destroy(cr); - } - cairo_surface_destroy(old_surface); - } - } - else - { - gui.surface = create_backing_surface(width, height); - if (gui.surface != NULL) - { - cr = cairo_create(gui.surface); - set_cairo_source_from_pixel(cr, gui.back_pixel); - cairo_paint(cr); - cairo_destroy(cr); - } - } } -#endif static void scale_factor_cb(GdkSurface *surface, GParamSpec *pspec UNUSED, void *udata UNUSED) { -#ifndef USE_GTK4_SNAPSHOT - int w, h; - - w = gtk_widget_get_width(gui.drawarea); - h = gtk_widget_get_height(gui.drawarea); - if (w <= 0 || h <= 0) - return; - - if (gui.surface != NULL) - cairo_surface_destroy(gui.surface); - gui.surface = create_backing_surface(w, h); - - if (gui.surface != NULL) - { - cairo_t *cr = cairo_create(gui.surface); - set_cairo_source_from_pixel(cr, gui.back_pixel); - cairo_paint(cr); - cairo_destroy(cr); - } - gtk_widget_queue_draw(gui.drawarea); - if (gui.in_use) - redraw_all_later(UPD_CLEAR); -#endif #if defined(FEAT_IMAGE) - { - double old = gui.scale; + double old = gui.scale; - gui.scale = gdk_surface_get_scale(surface); - popup_update_scale(old); - } + gui.scale = gdk_surface_get_scale(surface); + popup_update_scale(old); #endif } @@ -3454,7 +3091,6 @@ tabline_menu_press_event( void gui_mch_drawsign(int row, int col, int typenr) { -# ifdef USE_GTK4_SNAPSHOT GdkTexture *sign; sign = (GdkTexture *)sign_get_image(typenr); @@ -3463,42 +3099,6 @@ gui_mch_drawsign(int row, int col, int typenr) vim_draw_area_add_sign(VIM_DRAW_AREA(gui.drawarea), sign, row, col, SIGN_WIDTH, SIGN_HEIGHT); -# else - GdkPixbuf *sign; - cairo_t *cr; - int width, height; - - sign = (GdkPixbuf *)sign_get_image(typenr); - if (sign == NULL || gui.surface == NULL) - return; - - cr = cairo_create(gui.surface); - - width = gdk_pixbuf_get_width(sign); - height = gdk_pixbuf_get_height(sign); - - // Scale to fit the sign area if needed - if (width != SIGN_WIDTH || height != SIGN_HEIGHT) - { - GdkPixbuf *scaled = gdk_pixbuf_scale_simple(sign, - SIGN_WIDTH, SIGN_HEIGHT, GDK_INTERP_BILINEAR); - if (scaled != NULL) - { - gdk_cairo_set_source_pixbuf(cr, scaled, - FILL_X(col), FILL_Y(row)); - g_object_unref(scaled); - } - else - gdk_cairo_set_source_pixbuf(cr, sign, - FILL_X(col), FILL_Y(row)); - } - else - gdk_cairo_set_source_pixbuf(cr, sign, - FILL_X(col), FILL_Y(row)); - - cairo_paint(cr); - cairo_destroy(cr); -# endif gtk_widget_queue_draw(gui.drawarea); } @@ -3508,21 +3108,13 @@ gui_mch_register_sign(char_u *signfile) { if (signfile[0] != NUL && signfile[0] != '-' && gui.in_use) { - GError *error = NULL; -# ifdef USE_GTK4_SNAPSHOT + GError *error = NULL; GdkTexture *sign; sign = gdk_texture_new_from_filename((const char *)signfile, &error); if (sign != NULL) return sign; -# else - GdkPixbuf *sign; - - sign = gdk_pixbuf_new_from_file((const char *)signfile, &error); - if (error == NULL) - return sign; -# endif semsg("E255: %s", error->message); g_error_free(error); @@ -3544,417 +3136,6 @@ gui_mch_destroy_sign(void *sign) * ============================================================ */ -#ifndef USE_GTK4_SNAPSHOT -/* - * Ligature and text drawing support. - * Ported from gui_gtk_x11.c (GTK3) to support 'guiligatures' in GTK4. - */ - -# define INSERT_PANGO_ATTR(Attribute, AttrList, Start, End) \ - G_STMT_START{ \ - PangoAttribute *tmp_attr_; \ - tmp_attr_ = (Attribute); \ - tmp_attr_->start_index = (Start); \ - tmp_attr_->end_index = (End); \ - pango_attr_list_insert((AttrList), tmp_attr_); \ - }G_STMT_END - -/* - * Apply the 'guifontwide' font to double-width characters in the string. - */ - static void -apply_wide_font_attr(char_u *s, int len, PangoAttrList *attr_list) -{ - char_u *start = NULL; - char_u *p; - int uc; - - for (p = s; p < s + len; p += utf_byte2len(*p)) - { - uc = utf_ptr2char(p); - - if (start == NULL) - { - if (uc >= 0x80 && utf_char2cells(uc) == 2) - start = p; - } - else if (uc < 0x80 - || (utf_char2cells(uc) != 2 && !utf_iscomposing(uc))) - { - INSERT_PANGO_ATTR(pango_attr_font_desc_new(gui.wide_font), - attr_list, start - s, p - s); - start = NULL; - } - } - - if (start != NULL) - INSERT_PANGO_ATTR(pango_attr_font_desc_new(gui.wide_font), - attr_list, start - s, len); -} - -/* - * Count the number of display cells occupied by a glyph cluster. - */ - static int -count_cluster_cells(char_u *s, PangoItem *item, - PangoGlyphString *glyphs, int i, - int *cluster_width, - int *last_glyph_rbearing) -{ - char_u *p; - int next; - int start, end; - int width; - int uc; - int cellcount = 0; - - width = glyphs->glyphs[i].geometry.width; - - for (next = i + 1; next < glyphs->num_glyphs; ++next) - { - if (glyphs->glyphs[next].attr.is_cluster_start) - break; - else if (glyphs->glyphs[next].geometry.width > width) - width = glyphs->glyphs[next].geometry.width; - } - - start = item->offset + glyphs->log_clusters[i]; - end = item->offset + ((next < glyphs->num_glyphs) ? - glyphs->log_clusters[next] : item->length); - - for (p = s + start; p < s + end; p += utf_byte2len(*p)) - { - uc = utf_ptr2char(p); - if (uc < 0x80) - ++cellcount; - else if (!utf_iscomposing(uc)) - cellcount += utf_char2cells(uc); - } - - if (last_glyph_rbearing != NULL - && cellcount > 0 && next == glyphs->num_glyphs) - { - PangoRectangle ink_rect; - - pango_font_get_glyph_extents(item->analysis.font, - glyphs->glyphs[i].glyph, - &ink_rect, NULL); - - if (PANGO_RBEARING(ink_rect) > 0) - *last_glyph_rbearing = PANGO_RBEARING(ink_rect); - } - - if (cellcount > 0) - *cluster_width = width; - - return cellcount; -} - -/* - * Handle combining characters that form a zero-width cluster. - */ - static void -setup_zero_width_cluster(PangoItem *item, PangoGlyphInfo *glyph, - int last_cellcount, int last_cluster_width, - int last_glyph_rbearing) -{ - PangoRectangle ink_rect; - PangoRectangle logical_rect; - int width; - - width = last_cellcount * gui.char_width * PANGO_SCALE; - glyph->geometry.x_offset = -width + MAX(0, width - last_cluster_width) / 2; - glyph->geometry.width = 0; - - pango_font_get_glyph_extents(item->analysis.font, - glyph->glyph, - &ink_rect, &logical_rect); - if (ink_rect.x < 0) - { - glyph->geometry.x_offset += last_glyph_rbearing; - glyph->geometry.y_offset = logical_rect.height - - (gui.char_height - p_linespace) * PANGO_SCALE; - } - else - glyph->geometry.x_offset = -width + MAX(0, width - ink_rect.width) / 2; -} - -/* - * Draw a single glyph string segment: background, foreground, and fake bold. - */ - static void -draw_glyph_string(int row, int col, int num_cells, int flags, - PangoFont *font, PangoGlyphString *glyphs, - cairo_t *cr) -{ - if (!(flags & DRAW_TRANSP)) - { - cairo_set_source_rgba(cr, - gui.bgcolor->red, gui.bgcolor->green, gui.bgcolor->blue, - gui.bgcolor->alpha); - cairo_rectangle(cr, - FILL_X(col), FILL_Y(row), - num_cells * gui.char_width, gui.char_height); - cairo_fill(cr); - } - - cairo_set_source_rgba(cr, - gui.fgcolor->red, gui.fgcolor->green, gui.fgcolor->blue, - gui.fgcolor->alpha); - cairo_move_to(cr, TEXT_X(col), TEXT_Y(row)); - pango_cairo_show_glyph_string(cr, font, glyphs); - - // Redraw with offset of 1 to emulate bold - if ((flags & DRAW_BOLD) && !gui.font_can_bold) - { - cairo_move_to(cr, TEXT_X(col) + 1, TEXT_Y(row)); - pango_cairo_show_glyph_string(cr, font, glyphs); - } -} - -/* - * Draw underline, undercurl, and strikethrough decorations. - */ - static void -draw_under(int flags, int row, int col, int cells, cairo_t *cr) -{ - // Draw underline - if (flags & DRAW_UNDERL) - { - int y = FILL_Y(row + 1) - 1; - cairo_set_source_rgba(cr, - gui.fgcolor->red, gui.fgcolor->green, - gui.fgcolor->blue, gui.fgcolor->alpha); - cairo_set_line_width(cr, 1.0); - cairo_move_to(cr, FILL_X(col), y + 0.5); - cairo_line_to(cr, FILL_X(col + cells), y + 0.5); - cairo_stroke(cr); - } - - // Draw undercurl - if (flags & DRAW_UNDERC) - { - static const int val[8] = {1, 0, 0, 0, 1, 2, 2, 2}; - int y = FILL_Y(row + 1) - 1; - int i, offset; - - cairo_set_line_width(cr, 1.0); - cairo_set_source_rgba(cr, - gui.spcolor->red, gui.spcolor->green, - gui.spcolor->blue, gui.spcolor->alpha); - cairo_move_to(cr, FILL_X(col) + 1, y - 2 + 0.5); - for (i = FILL_X(col) + 1; i < FILL_X(col + cells); ++i) - { - offset = val[i % 8]; - cairo_line_to(cr, i, y - offset + 0.5); - } - cairo_stroke(cr); - } - - // Draw strikethrough - if (flags & DRAW_STRIKE) - { - int y = FILL_Y(row) + gui.char_height / 2; - cairo_set_source_rgba(cr, - gui.fgcolor->red, gui.fgcolor->green, - gui.fgcolor->blue, gui.fgcolor->alpha); - cairo_set_line_width(cr, 1.0); - cairo_move_to(cr, FILL_X(col), y + 0.5); - cairo_line_to(cr, FILL_X(col + cells), y + 0.5); - cairo_stroke(cr); - } -} - -/* - * Draw a string of characters on the screen. - * "force_pango" is set when ligature characters require Pango shaping - * instead of the fast ASCII glyph cache path. - * Returns the number of display cells used. - */ - int -gui_gtk_draw_string_ext( - int row, - int col, - char_u *s, - int len, - int flags, - int force_pango) -{ - PangoGlyphString *glyphs; - int column_offset = 0; - int i; - GdkRectangle area; - cairo_t *cr; - - if (gui.text_context == NULL || gui.surface == NULL) - return len; - - // Restrict all drawing to the current screen line. - area.x = gui.border_offset; - area.y = FILL_Y(row); - area.width = gui.num_cols * gui.char_width; - area.height = gui.char_height; - - cr = cairo_create(gui.surface); - cairo_rectangle(cr, area.x, area.y, area.width, area.height); - cairo_clip(cr); - - glyphs = pango_glyph_string_new(); - - // Fast path for pure ASCII: use cached glyph table. - // Skip this path when force_pango is set (ligatures need shaping). - if (!(flags & DRAW_ITALIC) - && !((flags & DRAW_BOLD) && gui.font_can_bold) - && gui.ascii_glyphs != NULL - && !force_pango) - { - char_u *p; - - for (p = s; p < s + len; ++p) - if (*p & 0x80) - goto not_ascii; - - pango_glyph_string_set_size(glyphs, len); - - for (i = 0; i < len; ++i) - { - glyphs->glyphs[i] = gui.ascii_glyphs->glyphs[2 * s[i]]; - glyphs->log_clusters[i] = i; - } - - draw_glyph_string(row, col, len, flags, gui.ascii_font, glyphs, cr); - - column_offset = len; - } - else - { -not_ascii:; - PangoAttrList *attr_list; - GList *item_list; - int cluster_width; - int last_glyph_rbearing; - int cells = 0; - - // Safety check: pango crashes with invalid utf-8. - if (!utf_valid_string(s, s + len)) - { - column_offset = len; - goto skipitall; - } - - cluster_width = PANGO_SCALE * gui.char_width; - last_glyph_rbearing = PANGO_SCALE * gui.char_width; - - attr_list = pango_attr_list_new(); - - // If 'guifontwide' is set then use that for double-width characters. - if (gui.wide_font != NULL) - apply_wide_font_attr(s, len, attr_list); - - if ((flags & DRAW_BOLD) && gui.font_can_bold) - INSERT_PANGO_ATTR(pango_attr_weight_new(PANGO_WEIGHT_BOLD), - attr_list, 0, len); - if (flags & DRAW_ITALIC) - INSERT_PANGO_ATTR(pango_attr_style_new(PANGO_STYLE_ITALIC), - attr_list, 0, len); - - item_list = pango_itemize(gui.text_context, - (const char *)s, 0, len, attr_list, NULL); - - while (item_list != NULL) - { - PangoItem *item; - int item_cells = 0; - - item = (PangoItem *)item_list->data; - item_list = g_list_delete_link(item_list, item_list); - - // Force LTR direction; Vim handles bidi on its own. - item->analysis.level = (item->analysis.level + 1) & (~1U); - - pango_shape_full((const char *)s + item->offset, item->length, - (const char *)s, len, &item->analysis, glyphs); - - // Fixed-width hack: assign a fixed width to each glyph based on - // the number of cells it occupies, handling composing characters - // and cluster boundaries properly. - for (i = 0; i < glyphs->num_glyphs; ++i) - { - PangoGlyphInfo *glyph; - - glyph = &glyphs->glyphs[i]; - - if (glyph->attr.is_cluster_start) - { - int cellcount; - - cellcount = count_cluster_cells( - s, item, glyphs, i, &cluster_width, - (item_list != NULL) ? &last_glyph_rbearing : NULL); - - if (cellcount > 0) - { - int width; - - width = cellcount * gui.char_width * PANGO_SCALE; - glyph->geometry.x_offset += - MAX(0, width - cluster_width) / 2; - glyph->geometry.width = width; - } - else - { - setup_zero_width_cluster(item, glyph, cells, - cluster_width, - last_glyph_rbearing); - } - - item_cells += cellcount; - cells = cellcount; - } - else if (i > 0) - { - int width; - - if (glyph->geometry.x_offset >= 0) - { - glyphs->glyphs[i].geometry.width = - glyphs->glyphs[i - 1].geometry.width; - glyphs->glyphs[i - 1].geometry.width = 0; - } - width = cells * gui.char_width * PANGO_SCALE; - glyph->geometry.x_offset += - MAX(0, width - cluster_width) / 2; - } - else - { - glyph->geometry.width = 0; - } - } - - draw_glyph_string(row, col + column_offset, item_cells, - flags, item->analysis.font, glyphs, cr); - - pango_item_free(item); - - column_offset += item_cells; - } - - pango_attr_list_unref(attr_list); - } - -skipitall: - draw_under(flags, row, col, column_offset, cr); - cairo_destroy(cr); - - pango_glyph_string_free(glyphs); - - if (gui.drawarea != NULL) - gtk_widget_queue_draw(gui.drawarea); - - return column_offset; -} -#endif // !USE_GTK4_SNAPSHOT - /* * Draw a string of characters on the screen using the current font and colors. * Splits the string into ASCII and ligature/UTF-8 segments so that ligature @@ -3965,7 +3146,6 @@ skipitall: int gui_gtk_draw_string(int row, int col, char_u *s, int len, int flags) { -#ifdef USE_GTK4_SNAPSHOT int cells; cells = vim_draw_area_draw_string(VIM_DRAW_AREA(gui.drawarea), @@ -3975,120 +3155,6 @@ gui_gtk_draw_string(int row, int col, char_u *s, int len, int flags) gtk_widget_queue_draw(gui.drawarea); return cells; -#else - char_u *conv_buf = NULL; - int convlen; - int len_sum; - int byte_sum; - char_u *cs; - int needs_pango; - int should_need_pango = FALSE; - int slen; - int is_ligature; - int is_utf8; - char_u backup_ch; - - if (gui.text_context == NULL || gui.surface == NULL) - return len; - - if (output_conv.vc_type != CONV_NONE) - { - convlen = len; - conv_buf = string_convert(&output_conv, s, &convlen); - if (conv_buf != NULL) - { - s = conv_buf; - len = convlen; - } - } - - /* - * Ligature support: - * Split the string into segments that are either pure ASCII (fast path) - * or ligature/UTF-8 (Pango path). A single ligature character between - * ASCII characters is treated as ASCII since it can't form a ligature - * on its own. - */ - len_sum = 0; - byte_sum = 0; - cs = s; - - // First char decides starting mode. - is_utf8 = (*cs & 0x80); - is_ligature = gui.ligatures_map[*cs] && (len > 1); - if (is_ligature) - is_ligature = gui.ligatures_map[*(cs + 1)]; - if (!is_utf8 && len > 1) - is_utf8 = (*(cs + 1) & 0x80) != 0; - needs_pango = is_utf8 || is_ligature; - - while (cs < s + len) - { - slen = 0; - while (slen < (len - byte_sum)) - { - is_ligature = gui.ligatures_map[*(cs + slen)]; - // Look ahead: single ligature char between ASCII is ASCII. - if (is_ligature && !needs_pango) - { - if ((slen + 1) < (len - byte_sum)) - is_ligature = gui.ligatures_map[*(cs + slen + 1)]; - else - is_ligature = 0; - } - is_utf8 = *(cs + slen) & 0x80; - // ASCII followed by UTF-8 could be combining. - if ((!is_utf8) && ((slen + 1) < (len - byte_sum))) - is_utf8 = (*(cs + slen + 1) & 0x80); - should_need_pango = (is_ligature || is_utf8); - if (needs_pango != should_need_pango) - break; - if (needs_pango) - { - if (is_ligature) - { - slen++; - } - else - { - if ((*(cs + slen) & 0xC0) == 0x80) - { - while ((slen < (len - byte_sum)) - && ((*(cs + slen) & 0xC0) == 0x80)) - slen++; - } - else if ((*(cs + slen) & 0xE0) == 0xC0) - slen++; - else if ((*(cs + slen) & 0xF0) == 0xE0) - slen += 2; - else if ((*(cs + slen) & 0xF8) == 0xF0) - slen += 3; - else - slen++; - } - } - else - { - slen++; - } - } - - if (slen < len) - { - backup_ch = *(cs + slen); - *(cs + slen) = NUL; - } - len_sum += gui_gtk_draw_string_ext(row, col + len_sum, cs, slen, - flags, needs_pango); - if (slen < len) - *(cs + slen) = backup_ch; - cs += slen; - byte_sum += slen; - needs_pango = should_need_pango; - } - vim_free(conv_buf); - return len_sum; -#endif } int @@ -5012,7 +4078,6 @@ gui_mch_set_text_area_pos(int x, int y, int w, int h) vim_form_move_resize(VIM_FORM(gui.formwin), gui.drawarea, x, y, w, h); } -#ifdef USE_GTK4_SNAPSHOT /* * Calculate the number of pixels to bleed background color to. Should be called * after all UI elements are positioned and resized. @@ -5043,7 +4108,6 @@ gui_gtk4_calculate_bleed(int width, int height) if (old_right != gui.bleed_right || old_bot != gui.bleed_bot) gtk_widget_queue_draw(GTK_WIDGET(gui.drawarea)); } -#endif /* * ============================================================ diff --git a/src/gui_gtk4_da.c b/src/gui_gtk4_da.c index 7a082cedf..80d3044cb 100644 --- a/src/gui_gtk4_da.c +++ b/src/gui_gtk4_da.c @@ -9,8 +9,6 @@ #include "vim.h" -#ifdef USE_GTK4_SNAPSHOT - #include <gtk/gtk.h> #include "gui_gtk4_da.h" @@ -2024,5 +2022,3 @@ vim_draw_area_snapshot(GtkWidget *widget, GtkSnapshot *snapshot) } #endif } - -#endif // USE_GTK4_SNAPSHOT diff --git a/src/gui_gtk4_da.h b/src/gui_gtk4_da.h index a214729a8..5708849f9 100644 --- a/src/gui_gtk4_da.h +++ b/src/gui_gtk4_da.h @@ -12,11 +12,9 @@ #include "vim.h" -#ifdef USE_GTK4_SNAPSHOT +#include <gtk/gtk.h> -# include <gtk/gtk.h> - -# define VIM_TYPE_DRAW_AREA (vim_draw_area_get_type()) +#define VIM_TYPE_DRAW_AREA (vim_draw_area_get_type()) G_DECLARE_FINAL_TYPE(VimDrawArea, vim_draw_area, VIM, DRAW_AREA, GtkWidget) GtkWidget *vim_draw_area_new(void); @@ -27,17 +25,15 @@ void vim_draw_area_clear(VimDrawArea *self); void vim_draw_area_move_block(VimDrawArea *self, int to, int row1, int row2, int col1, int col2); void vim_draw_area_set_cursor(VimDrawArea *self, int w, int h); void vim_draw_area_invert_block(VimDrawArea *self, int row, int col, int nrows, int ncols); -# if defined(FEAT_SIGN_ICONS) +#if defined(FEAT_SIGN_ICONS) void vim_draw_area_add_sign(VimDrawArea *self, GdkTexture *sign, int row, int col, int width, int height); -# endif -# ifdef FEAT_NETBEANS_INTG +#endif +#ifdef FEAT_NETBEANS_INTG void vim_draw_area_add_multisign(VimDrawArea *self, cairo_surface_t *surf, int row, int col, int width, int height); -# endif -# ifdef FEAT_IMAGE_GDK +#endif +#ifdef FEAT_IMAGE_GDK void vim_draw_area_add_image(VimDrawArea *self, GdkTexture *image, int row, int col, double src_x, double src_y, double draw_w, double draw_h, int zindex, int id); void vim_draw_area_remove_image(VimDrawArea *self, int id); -# endif - #endif #endif diff --git a/src/netbeans.c b/src/netbeans.c index abe5d11bc..9aec66490 100644 --- a/src/netbeans.c +++ b/src/netbeans.c @@ -3100,7 +3100,7 @@ netbeans_draw_multisign_indicator(int row) # else GdkDrawable *drawable = gui.drawarea->window; # endif -# ifdef USE_GTK4_SNAPSHOT +# ifdef USE_GTK4 cairo_surface_t *surf; # endif @@ -3108,14 +3108,14 @@ netbeans_draw_multisign_indicator(int row) return; x = 0; -# ifdef USE_GTK4_SNAPSHOT +# ifdef USE_GTK4 y = 2; # else y = row * gui.char_height + 2; # endif # if GTK_CHECK_VERSION(3,0,0) -# ifdef USE_GTK4_SNAPSHOT +# ifdef USE_GTK4 surf = cairo_image_surface_create( CAIRO_FORMAT_ARGB32, 5, gui.char_height); cr = cairo_create(surf); @@ -3152,7 +3152,7 @@ netbeans_draw_multisign_indicator(int row) gdk_draw_point(drawable, gui.text_gc, x+2, y); # endif -# ifdef USE_GTK4_SNAPSHOT +# ifdef USE_GTK4 cairo_fill(cr); gui_gtk4_add_multisign(surf, row, 0, 5, gui.char_height); # endif @@ -3160,7 +3160,7 @@ netbeans_draw_multisign_indicator(int row) # if GTK_CHECK_VERSION(3,0,0) cairo_destroy(cr); # endif -# ifdef USE_GTK4_SNAPSHOT +# ifdef USE_GTK4 cairo_surface_destroy(surf); # endif } diff --git a/src/po/vim.pot b/src/po/vim.pot index 358f4bb61..b6ded2132 100644 --- a/src/po/vim.pot +++ b/src/po/vim.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Vim " "Report-Msgid-Bugs-To: [email protected] " -"POT-Creation-Date: 2026-07-23 20:13+0000 " +"POT-Creation-Date: 2026-07-27 20:48+0000 " "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE " "Last-Translator: FULL NAME <EMAIL@ADDRESS> " "Language-Team: LANGUAGE <[email protected]> " @@ -3469,9 +3469,6 @@ msgstr "" msgid "without GUI." msgstr "" -msgid "with GTK4 GUI (hwaccel)." -msgstr "" - msgid "with GTK4 GUI." msgstr "" diff --git a/src/proto/gui_gtk4.pro b/src/proto/gui_gtk4.pro index 1541e4564..3c5f7a925 100644 --- a/src/proto/gui_gtk4.pro +++ b/src/proto/gui_gtk4.pro @@ -49,11 +49,8 @@ void gui_mch_draw_popup_image(win_T *wp, int row, int col, int src_x, int src_y, void gui_mch_delete_lines(int row, int num_lines); void gui_mch_insert_lines(int row, int num_lines); void gui_gtk4_draw_cursor(guicolor_T bg, guicolor_T fg, int w, int h); -void gui_mch_draw_hollow_cursor(guicolor_T color); -void gui_mch_draw_part_cursor(int w, int h, guicolor_T color); void gui_mch_flash(int msec); void gui_mch_invert_rectangle(int r, int c, int nr, int nc); -void gui_gtk4_resize(int width, int height); void gui_gtk_set_dnd_targets(void); void gui_mch_update(void); int gui_mch_wait_for_chars(long wtime); @@ -78,7 +75,6 @@ void gui_mch_set_curtab(int nr); void gui_mch_drawsign(int row, int col, int typenr); void *gui_mch_register_sign(char_u *signfile); void gui_mch_destroy_sign(void *sign); -int gui_gtk_draw_string_ext(int row, int col, char_u *s, int len, int flags, int force_pango); int gui_gtk_draw_string(int row, int col, char_u *s, int len, int flags); int gui_get_x11_windis(Window *win, Display **dis); void gui_gtk_set_mnemonics(int enable); diff --git a/src/version.c b/src/version.c index 692175247..3f239da85 100644 --- a/src/version.c +++ b/src/version.c @@ -758,6 +758,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 865, /**/ 864, /**/ @@ -2835,11 +2837,7 @@ list_version(void) msg_puts(_("without GUI.")); #elif defined(FEAT_GUI_GTK) # if defined(USE_GTK4) -# ifdef USE_GTK4_SNAPSHOT - msg_puts(_("with GTK4 GUI (hwaccel).")); -# else msg_puts(_("with GTK4 GUI.")); -# endif # elif defined(USE_GTK3) msg_puts(_("with GTK3 GUI.")); # elif defined(FEAT_GUI_GNOME) -- -- You received this message from the "vim_dev" maillist. Do not top-post! Type your reply below the text you are replying to. For more information, visit http://www.vim.org/maillist.php --- You received this message because you are subscribed to the Google Groups "vim_dev" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion visit https://groups.google.com/d/msgid/vim_dev/E1woSQf-00HEGs-EI%40256bit.org.