diff --git a/src/gui.c b/src/gui.c index b0235eec28..2b5c0f24a7 100644 --- a/src/gui.c +++ b/src/gui.c @@ -1703,6 +1703,11 @@ gui_set_shellsize( if (!gui.shell_created) return; +#if defined(FEAT_GUI_GTK) && defined(USE_GTK4) + // Get the scrollbar width + height if possible + gui_mch_update_scrollbar_size(); +#endif + #if defined(MSWIN) || defined(FEAT_GUI_GTK) // If not setting to a user specified size and maximized, calculate the // number of characters that fit in the maximized window. diff --git a/src/gui_gtk4.c b/src/gui_gtk4.c index d6d32b7ccc..20390879af 100644 --- a/src/gui_gtk4.c +++ b/src/gui_gtk4.c @@ -499,30 +499,21 @@ gui_mch_init(void) G_CALLBACK(on_tab_reordered), NULL); #endif - // The form widget manages absolute positioning of scrollbars. - gui.formwin = gui_gtk_form_new(); + // The form widget manages absolute positioning of scrollbars and the draw + // area. + gui.formwin = vim_form_new(); gtk_widget_set_name(gui.formwin, "vim-gtk-form"); - // formwin is overlaid on top of drawarea for scrollbar positioning. - // GtkForm's contains() returns FALSE so empty-area clicks fall through - // to the drawarea, while the scrollbar children still receive events. + gtk_widget_set_vexpand(gui.formwin, TRUE); + gtk_widget_set_hexpand(gui.formwin, TRUE); + gtk_box_append(GTK_BOX(vbox), gui.formwin); // The drawing area for the editor content. - // Placed in an overlay so it fills the formwin, with scrollbars on top. gui.drawarea = gtk_drawing_area_new(); gui.surface = NULL; gtk_widget_set_focusable(gui.drawarea, TRUE); gtk_widget_set_vexpand(gui.drawarea, TRUE); gtk_widget_set_hexpand(gui.drawarea, TRUE); - - { - // Use GtkOverlay: drawarea as the main child, formwin as overlay - GtkWidget *overlay = gtk_overlay_new(); - gtk_overlay_set_child(GTK_OVERLAY(overlay), gui.drawarea); - gtk_overlay_add_overlay(GTK_OVERLAY(overlay), gui.formwin); - gtk_widget_set_vexpand(overlay, TRUE); - gtk_widget_set_hexpand(overlay, TRUE); - gtk_box_append(GTK_BOX(vbox), overlay); - } + vim_form_put(VIM_FORM(gui.formwin), gui.drawarea, 0, 0); // Set up drawing. gtk_drawing_area_set_draw_func(GTK_DRAWING_AREA(gui.drawarea), @@ -3007,8 +2998,8 @@ gui_gtk_draw_string_ext( column_offset = len; } else -not_ascii: { +not_ascii:; PangoAttrList *attr_list; GList *item_list; int cluster_width; @@ -4269,10 +4260,7 @@ gui_mch_set_scrollbar_thumb(scrollbar_T *sb, long val, long size, long max) gui_mch_set_scrollbar_pos(scrollbar_T *sb, int x, int y, int w, int h) { if (sb->id != NULL) - { - gtk_widget_set_size_request(sb->id, w, h); - gui_gtk_form_move(GTK_FORM(gui.formwin), sb->id, x, y); - } + vim_form_move_resize(VIM_FORM(gui.formwin), sb->id, x, y, w, h); } int @@ -4317,24 +4305,21 @@ adjustment_value_changed(GtkAdjustment *adj, gpointer data UNUSED) void gui_mch_create_scrollbar(scrollbar_T *sb, int orient) { + GtkAdjustment *adj; if (orient == SBAR_HORIZ) sb->id = gtk_scrollbar_new(GTK_ORIENTATION_HORIZONTAL, NULL); else sb->id = gtk_scrollbar_new(GTK_ORIENTATION_VERTICAL, NULL); - if (sb->id != NULL && GTK_IS_SCROLLBAR(sb->id)) - { - GtkAdjustment *adj = gtk_scrollbar_get_adjustment(GTK_SCROLLBAR(sb->id)); + gtk_widget_add_css_class(sb->id, "vim-scrollbar"); + adj = gtk_scrollbar_get_adjustment(GTK_SCROLLBAR(sb->id)); - gtk_widget_set_visible(sb->id, FALSE); - gui_gtk_form_put(GTK_FORM(gui.formwin), sb->id, 0, 0); - if (adj != NULL && G_IS_OBJECT(adj)) - { - g_object_set_data(G_OBJECT(adj), "vim-sb", (gpointer)sb); - g_signal_connect(G_OBJECT(adj), "value-changed", - G_CALLBACK(adjustment_value_changed), NULL); - } - } + gtk_widget_set_visible(sb->id, FALSE); + vim_form_put(VIM_FORM(gui.formwin), sb->id, 0, 0); + + g_object_set_data(G_OBJECT(adj), "vim-sb", (gpointer)sb); + g_signal_connect(G_OBJECT(adj), "value-changed", + G_CALLBACK(adjustment_value_changed), NULL); } void @@ -4342,11 +4327,68 @@ gui_mch_destroy_scrollbar(scrollbar_T *sb) { if (sb->id != NULL) { - gui_gtk_form_remove(GTK_FORM(gui.formwin), sb->id); + vim_form_remove(VIM_FORM(gui.formwin), sb->id); sb->id = NULL; } } +/* + * Try getting the actual size of the scrollbar, and update gui.scrollbar_width + * and gui.scrollbar_height. + */ + void +gui_mch_update_scrollbar_size(void) +{ + win_T *wp; + int w = -1, h = -1; + GtkWidget *sbar; + + FOR_ALL_WINDOWS(wp) + { + sbar = wp->w_scrollbars[SBAR_LEFT].id; + + if (sbar == NULL || !gtk_widget_get_visible(sbar) + || (!gui.which_scrollbars[SBAR_LEFT] + && wp->w_scrollbars[SBAR_RIGHT].id != NULL)) + sbar = wp->w_scrollbars[SBAR_RIGHT].id; + + if (sbar != NULL && gtk_widget_get_visible(sbar)) + { + GtkRequisition min, nat; + int sw; + + // Use preferred size, since widget may not have its size allocated + // yet. + gtk_widget_get_preferred_size(sbar, &min, &nat); + sw = MAX(min.width, nat.width); + if (sw > 0) + { + w = sw; + break; + } + } + + } + + sbar = gui.bottom_sbar.id; + if (sbar != NULL && gtk_widget_get_visible(sbar)) + { + GtkRequisition min, nat; + int sh; + + gtk_widget_get_preferred_size(sbar, &min, &nat); + sh = MAX(min.height, nat.height); + + if (sh > 0) + h = sh; + } + + if (w != -1) + gui.scrollbar_width = w; + if (h != -1) + gui.scrollbar_height = h; +} + /* * ============================================================ * Text area position @@ -4358,11 +4400,11 @@ gui_mch_set_text_area_pos(int x, int y, int w, int h) { last_text_area_w = w; last_text_area_h = h; - // Don't use gui_gtk_form_move_resize for drawarea because its + // Don't use vim_form_move_resize for drawarea because its // set_size_request would prevent the window from shrinking. // Just update position; the actual allocation is handled by - // form_size_allocate which gives drawarea the formwin's full size. - gui_gtk_form_move(GTK_FORM(gui.formwin), gui.drawarea, x, y); + // vim_form_size_allocate which gives drawarea the formwin's full size. + vim_form_move(VIM_FORM(gui.formwin), gui.drawarea, x, y); // Surface sizing is owned by drawarea_resize_cb; don't recreate it // here. Recreating on every text-area change wiped any preserved @@ -4704,7 +4746,7 @@ find_replace_dialog_create(char_u *arg, int do_replace) char_u *entry_text; int wword = FALSE; int mcase = !p_ic; - GtkWidget *vbox, *grid, *hbox, *tmp, *btn; + GtkWidget *vertbox, *grid, *hbox, *tmp, *btn; gboolean sensitive; frdp = do_replace ? &repl_widgets : &find_widgets; @@ -4748,18 +4790,18 @@ find_replace_dialog_create(char_u *arg, int do_replace) g_signal_connect(frdp->dialog, "destroy", G_CALLBACK(dialog_destroyed_cb), &frdp->dialog); - vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6); - gtk_widget_set_margin_start(vbox, 12); - gtk_widget_set_margin_end(vbox, 12); - gtk_widget_set_margin_top(vbox, 12); - gtk_widget_set_margin_bottom(vbox, 12); - gtk_window_set_child(GTK_WINDOW(frdp->dialog), vbox); + vertbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6); + gtk_widget_set_margin_start(vertbox, 12); + gtk_widget_set_margin_end(vertbox, 12); + gtk_widget_set_margin_top(vertbox, 12); + gtk_widget_set_margin_bottom(vertbox, 12); + gtk_window_set_child(GTK_WINDOW(frdp->dialog), vertbox); // Grid for labels + entries grid = gtk_grid_new(); gtk_grid_set_row_spacing(GTK_GRID(grid), 6); gtk_grid_set_column_spacing(GTK_GRID(grid), 6); - gtk_box_append(GTK_BOX(vbox), grid); + gtk_box_append(GTK_BOX(vertbox), grid); // "Find what:" label + entry tmp = gtk_label_new(_("Find what:")); @@ -4787,7 +4829,7 @@ find_replace_dialog_create(char_u *arg, int do_replace) // Checkboxes hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12); - gtk_box_append(GTK_BOX(vbox), hbox); + gtk_box_append(GTK_BOX(vertbox), hbox); frdp->wword = gtk_check_button_new_with_label(_("Match whole word only")); gtk_check_button_set_active(GTK_CHECK_BUTTON(frdp->wword), @@ -4801,7 +4843,7 @@ find_replace_dialog_create(char_u *arg, int do_replace) // Direction radio buttons hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12); - gtk_box_append(GTK_BOX(vbox), hbox); + gtk_box_append(GTK_BOX(vertbox), hbox); tmp = gtk_label_new(_("Direction:")); gtk_box_append(GTK_BOX(hbox), tmp); @@ -4818,7 +4860,7 @@ find_replace_dialog_create(char_u *arg, int do_replace) // Action buttons hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6); gtk_widget_set_halign(hbox, GTK_ALIGN_END); - gtk_box_append(GTK_BOX(vbox), hbox); + gtk_box_append(GTK_BOX(vertbox), hbox); btn = gtk_button_new_with_label(_("Find Next")); gtk_widget_set_sensitive(btn, sensitive); diff --git a/src/gui_gtk4_f.c b/src/gui_gtk4_f.c index 80aa7a48d0..14ff85f625 100644 --- a/src/gui_gtk4_f.c +++ b/src/gui_gtk4_f.c @@ -5,106 +5,168 @@ * Do ":help uganda" in Vim to read copying and usage conditions. * Do ":help credits" in Vim to see a list of people who contributed. * See README.txt for an overview of the Vim source code. - * - * GTK4 GtkForm widget - a simple container for absolute child positioning. - * This is a clean rewrite of gui_gtk_f.c for GTK4. - * - * In GTK4, widgets no longer have their own GdkWindows (now GdkSurface), - * GtkContainer is removed, and child positioning uses GskTransform via - * gtk_widget_allocate(). This makes the form widget much simpler. */ #include "vim.h" #include #include "gui_gtk4_f.h" -typedef struct _GtkFormChild GtkFormChild; - -struct _GtkFormChild +/* + * Child widget at position (x, y). + */ +typedef struct { - GtkWidget *widget; - gint x; - gint y; + GtkWidget *widget; + int x; + int y; +} VimFormChild; + +/* + * Similar to the GtkFixed widget, allows absolute position and sizing of child + * widgets within. Vim already has logic for positioning and sizing UI elements, + * so this is needed to take advantage of that. We don't use GtkFixed directly + * since we need to override some vfuncs. + */ +struct _VimForm +{ + GtkWidget parent; + + GList *children; + + // See vim_form_size_allocate() + guint resize_idle_id; + int last_width; + int last_height; }; -// Forward declarations -static void gui_gtk_form_class_init(GtkFormClass *klass); -static void gui_gtk_form_init(GtkForm *form); -static void form_measure(GtkWidget *widget, GtkOrientation orientation, - int for_size, int *minimum, int *natural, - int *minimum_baseline, int *natural_baseline); -static void form_size_allocate(GtkWidget *widget, int width, int height, - int baseline); -static void form_snapshot(GtkWidget *widget, GtkSnapshot *snapshot); -static gboolean form_contains(GtkWidget *widget, double x, double y); -static void form_dispose(GObject *object); -static void form_position_child(GtkForm *form, GtkFormChild *child, - gboolean force_allocate); +G_DEFINE_TYPE(VimForm, vim_form, GTK_TYPE_WIDGET) -G_DEFINE_TYPE(GtkForm, gui_gtk_form, GTK_TYPE_WIDGET) +static void vim_form_snapshot(GtkWidget *widget, GtkSnapshot *snapshot); +static void vim_form_size_allocate(GtkWidget *widget, int width, int height, int baseline); +static void vim_form_measure(GtkWidget *widget, GtkOrientation orientation, int for_size, int *minimum, int *natural, int *minimum_baseline, int *natural_baseline); +static gboolean vim_form_contains(GtkWidget *widget, double x, double y); -// Public interface - - GtkWidget * -gui_gtk_form_new(void) + static void +vim_form_dispose(GObject *obj) { - return GTK_WIDGET(g_object_new(GTK_TYPE_FORM, NULL)); + VimForm *self = VIM_FORM(obj); + GList *ele = self->children; + + while (ele != NULL) + { + VimFormChild *child = ele->data; + + ele = ele->next; + gtk_widget_unparent(child->widget); + g_free(child); + } + g_list_free(self->children); + self->children = NULL; + + G_OBJECT_CLASS(vim_form_parent_class)->dispose(obj); } - void -gui_gtk_form_put( - GtkForm *form, - GtkWidget *child_widget, - gint x, - gint y) + static void +vim_form_class_init(VimFormClass *class) { - GtkFormChild *child; + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(class); + GObjectClass *obj_class = G_OBJECT_CLASS(class); - g_return_if_fail(GTK_IS_FORM(form)); + widget_class->snapshot = vim_form_snapshot; + widget_class->size_allocate = vim_form_size_allocate; + widget_class->measure = vim_form_measure; + widget_class->contains = vim_form_contains; - child = g_new(GtkFormChild, 1); - if (child == NULL) - return; + obj_class->dispose = vim_form_dispose; +} - child->widget = child_widget; + static void +vim_form_init(VimForm *self) +{ + +} + + GtkWidget * +vim_form_new(void) +{ + return g_object_new(VIM_TYPE_FORM, NULL); +} + +/* + * Transform the child + */ + static void +vim_form_position_child(VimForm *self, VimFormChild *child) +{ + GtkRequisition requisition; + GskTransform *transform; + int w, h; + + gtk_widget_get_preferred_size(child->widget, &requisition, NULL); + w = requisition.width; + h = requisition.height; + + // If widget has no size request, use parent size + if (w <= 0) + w = gtk_widget_get_width(GTK_WIDGET(self)); + if (h <= 0) + h = gtk_widget_get_height(GTK_WIDGET(self)); + if (w <= 0) w = 1; + if (h <= 0) h = 1; + + transform = gsk_transform_translate(NULL, + &GRAPHENE_POINT_INIT((float)child->x, (float)child->y)); + gtk_widget_allocate(child->widget, w, h, -1, transform); +} + +/* + * Place the given widget at the point (x, y). + */ + void +vim_form_put(VimForm *self, GtkWidget *widget, int x, int y) +{ + VimFormChild *child; + + child = g_new(VimFormChild, 1); + + child->widget = widget; child->x = x; child->y = y; gtk_widget_set_size_request(child->widget, -1, -1); - form->children = g_list_append(form->children, child); + self->children = g_list_append(self->children, child); - gtk_widget_set_parent(child_widget, GTK_WIDGET(form)); - form_position_child(form, child, TRUE); + gtk_widget_set_parent(widget, GTK_WIDGET(self)); + vim_form_position_child(self, child); } +/* + * Move the widget (which should have already been added using vim_form_put()) + * to the given point (x, y). + */ void -gui_gtk_form_move( - GtkForm *form, - GtkWidget *child_widget, - gint x, - gint y) +vim_form_move(VimForm *self, GtkWidget *widget, int x, int y) { - GList *tmp_list; - - g_return_if_fail(GTK_IS_FORM(form)); - - for (tmp_list = form->children; tmp_list; tmp_list = tmp_list->next) + for (GList *ele = self->children; ele != NULL; ele = ele->next) { - GtkFormChild *child = tmp_list->data; - if (child->widget == child_widget) + VimFormChild *child = ele->data; + if (child->widget == widget) { child->x = x; child->y = y; - form_position_child(form, child, TRUE); + vim_form_position_child(self, child); return; } } } +/* + * Move and resize the child. + */ void -gui_gtk_form_move_resize( - GtkForm *form, +vim_form_move_resize( + VimForm *self, GtkWidget *widget, gint x, gint y, @@ -112,80 +174,85 @@ gui_gtk_form_move_resize( gint h) { gtk_widget_set_size_request(widget, w, h); - gui_gtk_form_move(form, widget, x, y); + vim_form_move(self, widget, x, y); } void -gui_gtk_form_remove(GtkForm *form, GtkWidget *child_widget) +vim_form_remove(VimForm *self, GtkWidget *widget) { - GList *tmp_list; - - g_return_if_fail(GTK_IS_FORM(form)); - - for (tmp_list = form->children; tmp_list; tmp_list = tmp_list->next) + for (GList *ele = self->children; ele != NULL; ele = ele->next) { - GtkFormChild *child = tmp_list->data; - if (child->widget == child_widget) + VimFormChild *child = ele->data; + if (child->widget == widget) { - form->children = g_list_remove_link(form->children, tmp_list); - g_list_free_1(tmp_list); - gtk_widget_unparent(child_widget); + self->children = g_list_remove_link(self->children, ele); + g_list_free_1(ele); + gtk_widget_unparent(widget); g_free(child); return; } } } - void -gui_gtk_form_freeze(GtkForm *form) + static void +vim_form_snapshot(GtkWidget *widget, GtkSnapshot *snapshot) { - g_return_if_fail(GTK_IS_FORM(form)); - ++form->freeze_count; -} + VimForm *self = VIM_FORM(widget); - void -gui_gtk_form_thaw(GtkForm *form) -{ - g_return_if_fail(GTK_IS_FORM(form)); - - if (!form->freeze_count) - return; - - if (!(--form->freeze_count)) + for (GList *ele = self->children; ele != NULL; ele = ele->next) { - GList *tmp_list; - - for (tmp_list = form->children; tmp_list; tmp_list = tmp_list->next) - form_position_child(form, tmp_list->data, FALSE); - gtk_widget_queue_draw(GTK_WIDGET(form)); + VimFormChild *child = ele->data; + gtk_widget_snapshot_child(widget, child->widget, snapshot); } } -// GObject/GtkWidget class implementation - - static void -gui_gtk_form_class_init(GtkFormClass *klass) + static gboolean +vim_form_resize_idle_cb(VimForm *self) { - GObjectClass *gobject_class = G_OBJECT_CLASS(klass); - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); + int w, h; - gobject_class->dispose = form_dispose; + self->resize_idle_id = 0; - widget_class->measure = form_measure; - widget_class->size_allocate = form_size_allocate; - widget_class->snapshot = form_snapshot; - widget_class->contains = form_contains; + // Use drawarea's actual allocation, not formwin's + if (gui.drawarea == NULL) + goto exit; + w = gtk_widget_get_width(gui.drawarea); + h = gtk_widget_get_height(gui.drawarea); + + if (w > 1 && h > 1) + gui_resize_shell(w, h); + +exit: + g_object_unref(self); + return G_SOURCE_REMOVE; } static void -gui_gtk_form_init(GtkForm *form) +vim_form_size_allocate( + GtkWidget *widget, + int width, + int height, + int baseline) { - form->children = NULL; - form->freeze_count = 0; + VimForm *self = VIM_FORM(widget); + + for (GList *ele = self->children; ele != NULL; ele = ele->next) + vim_form_position_child(self, ele->data); + + // Notify Vim about size change via idle callback + if (width != self->last_width || height != self->last_height) + { + self->last_width = width; + self->last_height = height; + + if (self->resize_idle_id == 0) + self->resize_idle_id = g_idle_add( + (GSourceFunc)vim_form_resize_idle_cb, g_object_ref(self)); + } } static void -form_measure( +vim_form_measure( GtkWidget *widget UNUSED, GtkOrientation orientation UNUSED, int for_size UNUSED, @@ -200,135 +267,13 @@ form_measure( *natural_baseline = -1; } -static guint form_resize_idle_id = 0; -static int form_last_width = 0; -static int form_last_height = 0; +/* + * Make the form itself input-transparent so clicks on its empty area fall + * through to the drawarea below, while the scrollbar children stay pickable. + */ static gboolean -form_resize_idle_cb(gpointer data UNUSED) -{ - int w, h; - - form_resize_idle_id = 0; - - // Use drawarea's actual allocation, not formwin's - if (gui.drawarea == NULL) - return FALSE; - w = gtk_widget_get_width(gui.drawarea); - h = gtk_widget_get_height(gui.drawarea); - - if (w > 1 && h > 1) - gui_resize_shell(w, h); - - return FALSE; -} - - static void -form_size_allocate(GtkWidget *widget, int width, int height, - int baseline UNUSED) -{ - GtkForm *form; - GList *tmp_list; - - g_return_if_fail(GTK_IS_FORM(widget)); - - form = GTK_FORM(widget); - - for (tmp_list = form->children; tmp_list; tmp_list = tmp_list->next) - form_position_child(form, tmp_list->data, TRUE); - - // Notify Vim about size change via idle callback - if (width != form_last_width || height != form_last_height) - { - form_last_width = width; - form_last_height = height; - if (form_resize_idle_id == 0) - form_resize_idle_id = g_idle_add(form_resize_idle_cb, NULL); - } -} - - static void -form_snapshot(GtkWidget *widget, GtkSnapshot *snapshot) -{ - GtkForm *form; - GList *tmp_list; - - g_return_if_fail(GTK_IS_FORM(widget)); - - form = GTK_FORM(widget); - - for (tmp_list = form->children; tmp_list; tmp_list = tmp_list->next) - { - GtkFormChild *child = tmp_list->data; - if (child->widget != NULL - && GTK_IS_WIDGET(child->widget) - && gtk_widget_get_parent(child->widget) == widget) - gtk_widget_snapshot_child(widget, child->widget, snapshot); - } -} - -// Make the form itself input-transparent so clicks on its empty area fall -// through to the drawarea below, while the scrollbar children stay pickable. - static gboolean -form_contains(GtkWidget *widget UNUSED, double x UNUSED, double y UNUSED) +vim_form_contains(GtkWidget *widget UNUSED, double x UNUSED, double y UNUSED) { return FALSE; } - - static void -form_dispose(GObject *object) -{ - GtkForm *form = GTK_FORM(object); - GList *tmp_list; - - tmp_list = form->children; - while (tmp_list) - { - GtkFormChild *child = tmp_list->data; - tmp_list = tmp_list->next; - - gtk_widget_unparent(child->widget); - g_free(child); - } - g_list_free(form->children); - form->children = NULL; - - G_OBJECT_CLASS(gui_gtk_form_parent_class)->dispose(object); -} - -// Child positioning using GskTransform - - static void -form_position_child( - GtkForm *form UNUSED, - GtkFormChild *child, - gboolean force_allocate) -{ - if (!force_allocate) - return; - - if (child->widget == NULL || !GTK_IS_WIDGET(child->widget)) - return; - - { - GtkRequisition requisition; - GskTransform *transform; - int w, h; - - gtk_widget_get_preferred_size(child->widget, &requisition, NULL); - w = requisition.width; - h = requisition.height; - - // If widget has no size request (e.g. drawarea), use parent size - if (w <= 0) - w = gtk_widget_get_width(GTK_WIDGET(form)); - if (h <= 0) - h = gtk_widget_get_height(GTK_WIDGET(form)); - if (w <= 0) w = 1; - if (h <= 0) h = 1; - - transform = gsk_transform_translate(NULL, - &GRAPHENE_POINT_INIT((float)child->x, (float)child->y)); - gtk_widget_allocate(child->widget, w, h, -1, transform); - } -} diff --git a/src/gui_gtk4_f.h b/src/gui_gtk4_f.h index a927061608..d795b86c2e 100644 --- a/src/gui_gtk4_f.h +++ b/src/gui_gtk4_f.h @@ -4,8 +4,7 @@ * * Do ":help uganda" in Vim to read copying and usage conditions. * Do ":help credits" in Vim to see a list of people who contributed. - * - * GTK4 GtkForm widget - a simple container for absolute positioning. + * See README.txt for an overview of the Vim source code. */ #ifndef GUI_GTK4_FORM_H @@ -13,47 +12,13 @@ #include -#ifdef __cplusplus -extern "C" { +#define VIM_TYPE_FORM (vim_form_get_type()) +G_DECLARE_FINAL_TYPE(VimForm, vim_form, VIM, FORM, GtkWidget) + +GtkWidget *vim_form_new(void); +void vim_form_put(VimForm *self, GtkWidget *widget, int x, int y); +void vim_form_move(VimForm *self, GtkWidget *widget, int x, int y); +void vim_form_move_resize(VimForm *self, GtkWidget *widget, gint x, gint y, gint w, gint h); +void vim_form_remove(VimForm *self, GtkWidget *widget); + #endif - -#define GTK_TYPE_FORM (gui_gtk_form_get_type()) -#define GTK_FORM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_FORM, GtkForm)) -#define GTK_FORM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_FORM, GtkFormClass)) -#define GTK_IS_FORM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_FORM)) - -typedef struct _GtkForm GtkForm; -typedef struct _GtkFormClass GtkFormClass; - -struct _GtkForm -{ - GtkWidget widget; - GList *children; - gint freeze_count; -}; - -struct _GtkFormClass -{ - GtkWidgetClass parent_class; -}; - -GType gui_gtk_form_get_type(void); - -GtkWidget *gui_gtk_form_new(void); - -void gui_gtk_form_put(GtkForm *form, GtkWidget *widget, gint x, gint y); - -void gui_gtk_form_move(GtkForm *form, GtkWidget *widget, gint x, gint y); - -void gui_gtk_form_move_resize(GtkForm *form, GtkWidget *widget, - gint x, gint y, gint w, gint h); - -void gui_gtk_form_remove(GtkForm *form, GtkWidget *widget); - -void gui_gtk_form_freeze(GtkForm *form); -void gui_gtk_form_thaw(GtkForm *form); - -#ifdef __cplusplus -} -#endif -#endif // GUI_GTK4_FORM_H diff --git a/src/proto/gui_gtk4.pro b/src/proto/gui_gtk4.pro index 4d21e6a703..0a1ba1296c 100644 --- a/src/proto/gui_gtk4.pro +++ b/src/proto/gui_gtk4.pro @@ -99,6 +99,7 @@ int gui_mch_get_scrollbar_xpadding(void); int gui_mch_get_scrollbar_ypadding(void); void gui_mch_create_scrollbar(scrollbar_T *sb, int orient); void gui_mch_destroy_scrollbar(scrollbar_T *sb); +void gui_mch_update_scrollbar_size(void); void gui_mch_set_text_area_pos(int x, int y, int w, int h); char_u *gui_mch_browse(int saving, char_u *title, char_u *dflt, char_u *ext, char_u *initdir, char_u *filter); char_u *gui_mch_browsedir(char_u *title, char_u *initdir); diff --git a/src/version.c b/src/version.c index e020aedc51..676c515f95 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 */ +/**/ + 587, /**/ 586, /**/