From: Foxe Chen Date: Sun, 31 May 2026 20:09:52 +0000 (+0000) Subject: patch 9.2.0577: GTK4: window resizing issues X-Git-Tag: v9.2.0577^0 X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=568daf65b82173605aeecf799ebe46cec54d77a8;p=thirdparty%2Fvim.git patch 9.2.0577: GTK4: window resizing issues Problem: GTK4: window size does not account for client-side decorations Solution: Compute the client side decoration height from gui_resize_shell() (Foxe Chen) fixes: #20365 closes: #20388 Signed-off-by: Foxe Chen Signed-off-by: Christian Brabandt --- diff --git a/src/gui.c b/src/gui.c index 8cf4c8fa48..b0235eec28 100644 --- a/src/gui.c +++ b/src/gui.c @@ -1594,6 +1594,9 @@ again: // Flush pending output before redrawing out_flush(); +#if defined(FEAT_GUI_GTK) && defined(USE_GTK4) + gui_gtk_init_decor_height(); +#endif gui.num_cols = (pixel_width - gui_get_base_width()) / gui.char_width; gui.num_rows = (pixel_height - gui_get_base_height()) / gui.char_height; diff --git a/src/gui.h b/src/gui.h index d1e5d2d5c0..609100a172 100644 --- a/src/gui.h +++ b/src/gui.h @@ -475,6 +475,9 @@ typedef struct Gui char *rsrc_input_method; char *rsrc_preedit_type_name; #endif +#if defined(FEAT_GUI_GTK) && defined(USE_GTK4) + int decor_height; +#endif } gui_T; extern gui_T gui; // this is defined in gui.c diff --git a/src/gui_gtk4.c b/src/gui_gtk4.c index 1596f19e5c..e7bbd9ad56 100644 --- a/src/gui_gtk4.c +++ b/src/gui_gtk4.c @@ -816,6 +816,28 @@ gui_mch_settitle(char_u *title, char_u *icon UNUSED) static int in_set_shellsize = FALSE; +/* + * Get height of window decorations, that we cannot determine directly. For + * example, the GtkHeaderBar widget. This is called in gui_resize_shell(), we + * cannot call it in gui_set_shellsize(), because that may be called before the + * drawarea/formwin is resized, which may cause the drawarea to be bigger than + * it actually is (while the window size is up to date), causing a negative + * "decor_height". + */ + void +gui_gtk_init_decor_height(void) +{ + int h = gtk_widget_get_height(gui.mainwin); + + if (h == 0) + return; + + h -= get_menu_tool_height(); + h -= gtk_widget_get_height(gui.formwin); + + gui.decor_height = h; +} + void gui_mch_set_shellsize(int width, int height, int min_width UNUSED, int min_height UNUSED, @@ -824,6 +846,11 @@ gui_mch_set_shellsize(int width, int height, { width += get_menu_tool_width(); height += get_menu_tool_height(); + + // GtkWindow default size also includes client side decorations, so must + // include it also. + height += gui.decor_height; + gtk_window_set_default_size(GTK_WINDOW(gui.mainwin), width, height); } @@ -3240,24 +3267,45 @@ get_menu_tool_width(void) int get_menu_tool_height(void) { - int height = 0; - + GtkWidget *widgets[] = { #ifdef FEAT_MENU - if (gui.menubar != NULL && gtk_widget_get_visible(gui.menubar)) - { - GtkRequisition req; - gtk_widget_get_preferred_size(gui.menubar, &req, NULL); - height += req.height; - } + gui.menubar, #endif #ifdef FEAT_TOOLBAR - if (gui.toolbar != NULL && gtk_widget_get_visible(gui.toolbar)) + gui.toolbar, +#endif +#ifdef FEAT_GUI_TABLINE + gui.tabline +#endif + }; + + int height = 0; + + for (int i = 0; i < ARRAY_LENGTH(widgets); i++) { - GtkRequisition req; - gtk_widget_get_preferred_size(gui.toolbar, &req, NULL); - height += req.height; + GtkRequisition min; + GtkRequisition nat; + int h; + + if (widgets[i] == NULL || !gtk_widget_get_visible(widgets[i])) + continue; + + h = gtk_widget_get_height(widgets[i]); + + if (h == 0) + { + // Allocation hasn't been updated yet (widget just became visible). + // Query the preferred height so the caller gets a valid value + // before the layout pass runs. Use the maximum of minimum and + // natural height: GTK may allocate min_h even when natural_h is + // smaller (e.g. GtkNotebook tab bar has min_h > natural_h due to + // CSS). + gtk_widget_get_preferred_size(widgets[i], &min, &nat); + height += MAX(min.height, nat.height); + } + else + height += h; } -#endif return height; } diff --git a/src/proto/gui_gtk4.pro b/src/proto/gui_gtk4.pro index 10f3ccc202..4d21e6a703 100644 --- a/src/proto/gui_gtk4.pro +++ b/src/proto/gui_gtk4.pro @@ -19,6 +19,7 @@ void gui_mch_unmaximize(void); void gui_mch_set_fullscreen(int flag); void gui_mch_newfont(void); void gui_mch_settitle(char_u *title, char_u *icon); +void gui_gtk_init_decor_height(void); void gui_mch_set_shellsize(int width, int height, int min_width, int min_height, int base_width, int base_height, int direction); void gui_mch_get_screen_dimensions(int *screen_w, int *screen_h); void gui_mch_enable_menu(int showit); diff --git a/src/version.c b/src/version.c index dab821ad64..b97066f50b 100644 --- a/src/version.c +++ b/src/version.c @@ -729,6 +729,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 577, /**/ 576, /**/