blob: dd5c1b25962bf3c041efd5de0fb23f647489e089 [file] [log] [blame]
Bram Moolenaaredf3f972016-08-29 22:49:24 +02001/* vi:set ts=8 sts=4 sw=4 noet:
Bram Moolenaar071d4272004-06-13 20:20:40 +00002 *
3 * VIM - Vi IMproved by Bram Moolenaar
4 *
5 * Do ":help uganda" in Vim to read copying and usage conditions.
6 * Do ":help credits" in Vim to see a list of people who contributed.
7 * See README.txt for an overview of the Vim source code.
8 */
9
10/*
Bram Moolenaara0a83be2005-01-04 21:26:43 +000011 * (C) 1998,1999 by Marcin Dalecki <martin@dalecki.de>
Bram Moolenaar071d4272004-06-13 20:20:40 +000012 *
13 * Support for GTK+ 2 was added by:
Bram Moolenaar071d4272004-06-13 20:20:40 +000014 * (C) 2002,2003 Jason Hildebrand <jason@peaceworks.ca>
15 * Daniel Elstner <daniel.elstner@gmx.net>
16 *
Bram Moolenaar933eb392007-05-10 17:52:45 +000017 * This is a special purpose container widget, which manages arbitrary
18 * children at arbitrary positions width arbitrary sizes. This finally puts
19 * an end on our resize problems with which we where struggling for such a
20 * long time.
Bram Moolenaar98921892016-02-23 17:14:37 +010021 *
22 * Support for GTK+ 3 was added by:
Bram Moolenaar98921892016-02-23 17:14:37 +010023 * 2016 Kazunobu Kuriyama <kazunobu.kuriyama@gmail.com>
Bram Moolenaar071d4272004-06-13 20:20:40 +000024 */
25
26#include "vim.h"
Bram Moolenaar30613902019-12-01 22:11:18 +010027#include <gtk/gtk.h> // without this it compiles, but gives errors at
28 // runtime!
Bram Moolenaar071d4272004-06-13 20:20:40 +000029#include "gui_gtk_f.h"
Bram Moolenaar98921892016-02-23 17:14:37 +010030#if !GTK_CHECK_VERSION(3,0,0)
31# include <gtk/gtksignal.h>
32#endif
Bram Moolenaar4f974752019-02-17 17:44:42 +010033#ifdef MSWIN
Bram Moolenaar071d4272004-06-13 20:20:40 +000034# include <gdk/gdkwin32.h>
35#else
36# include <gdk/gdkx.h>
37#endif
38
39typedef struct _GtkFormChild GtkFormChild;
40
41struct _GtkFormChild
42{
43 GtkWidget *widget;
44 GdkWindow *window;
Bram Moolenaar30613902019-12-01 22:11:18 +010045 gint x; // relative subwidget x position
46 gint y; // relative subwidget y position
Bram Moolenaar071d4272004-06-13 20:20:40 +000047 gint mapped;
48};
49
50
Bram Moolenaar8a99e662020-10-21 16:10:21 +020051static void form_class_init(GtkFormClass *klass);
52static void form_init(GtkForm *form, void *g_class);
Bram Moolenaar071d4272004-06-13 20:20:40 +000053
Bram Moolenaar8a99e662020-10-21 16:10:21 +020054static void form_realize(GtkWidget *widget);
55static void form_unrealize(GtkWidget *widget);
56static void form_map(GtkWidget *widget);
57static void form_size_request(GtkWidget *widget, GtkRequisition *requisition);
Bram Moolenaar98921892016-02-23 17:14:37 +010058#if GTK_CHECK_VERSION(3,0,0)
Bram Moolenaar8a99e662020-10-21 16:10:21 +020059static void form_get_preferred_width(GtkWidget *widget, gint *minimal_width, gint *natural_width);
60static void form_get_preferred_height(GtkWidget *widget, gint *minimal_height, gint *natural_height);
Bram Moolenaar98921892016-02-23 17:14:37 +010061#endif
Bram Moolenaar8a99e662020-10-21 16:10:21 +020062static void form_size_allocate(GtkWidget *widget, GtkAllocation *allocation);
Bram Moolenaar98921892016-02-23 17:14:37 +010063#if GTK_CHECK_VERSION(3,0,0)
Bram Moolenaar8a99e662020-10-21 16:10:21 +020064static gboolean form_draw(GtkWidget *widget, cairo_t *cr);
Bram Moolenaar98921892016-02-23 17:14:37 +010065#else
Bram Moolenaar8a99e662020-10-21 16:10:21 +020066static gint form_expose(GtkWidget *widget, GdkEventExpose *event);
Bram Moolenaar98921892016-02-23 17:14:37 +010067#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +000068
Bram Moolenaar8a99e662020-10-21 16:10:21 +020069static void form_remove(GtkContainer *container, GtkWidget *widget);
70static void form_forall(GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data);
Bram Moolenaar071d4272004-06-13 20:20:40 +000071
Bram Moolenaar8a99e662020-10-21 16:10:21 +020072static void form_attach_child_window(GtkForm *form, GtkFormChild *child);
73static void form_realize_child(GtkForm *form, GtkFormChild *child);
74static void form_position_child(GtkForm *form, GtkFormChild *child, gboolean force_allocate);
75static void form_position_children(GtkForm *form);
Bram Moolenaar071d4272004-06-13 20:20:40 +000076
Bram Moolenaar8a99e662020-10-21 16:10:21 +020077static void form_send_configure(GtkForm *form);
Bram Moolenaar071d4272004-06-13 20:20:40 +000078
Bram Moolenaar8a99e662020-10-21 16:10:21 +020079static void form_child_map(GtkWidget *widget, gpointer user_data);
80static void form_child_unmap(GtkWidget *widget, gpointer user_data);
Bram Moolenaar071d4272004-06-13 20:20:40 +000081
Bram Moolenaar98921892016-02-23 17:14:37 +010082#if !GTK_CHECK_VERSION(3,0,0)
Bram Moolenaar071d4272004-06-13 20:20:40 +000083static GtkWidgetClass *parent_class = NULL;
Bram Moolenaar98921892016-02-23 17:14:37 +010084#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +000085
Bram Moolenaar30613902019-12-01 22:11:18 +010086// Public interface
Bram Moolenaar071d4272004-06-13 20:20:40 +000087
88 GtkWidget *
Bram Moolenaar8a99e662020-10-21 16:10:21 +020089gui_gtk_form_new(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +000090{
91 GtkForm *form;
92
Bram Moolenaar98921892016-02-23 17:14:37 +010093#if GTK_CHECK_VERSION(3,0,0)
94 form = g_object_new(GTK_TYPE_FORM, NULL);
95#else
Bram Moolenaar8a99e662020-10-21 16:10:21 +020096 form = gtk_type_new(gui_gtk_form_get_type());
Bram Moolenaar98921892016-02-23 17:14:37 +010097#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +000098
99 return GTK_WIDGET(form);
100}
101
102 void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200103gui_gtk_form_put(
104 GtkForm *form,
105 GtkWidget *child_widget,
106 gint x,
107 gint y)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000108{
109 GtkFormChild *child;
110
111 g_return_if_fail(GTK_IS_FORM(form));
112
Bram Moolenaar30613902019-12-01 22:11:18 +0100113 // LINTED: avoid warning: conversion to 'unsigned long'
Bram Moolenaar071d4272004-06-13 20:20:40 +0000114 child = g_new(GtkFormChild, 1);
Bram Moolenaar6ee96582019-04-27 22:06:37 +0200115 if (child == NULL)
116 return;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000117
118 child->widget = child_widget;
119 child->window = NULL;
120 child->x = x;
121 child->y = y;
Bram Moolenaar98921892016-02-23 17:14:37 +0100122#if GTK_CHECK_VERSION(3,0,0)
123 gtk_widget_set_size_request(child->widget, -1, -1);
124#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000125 child->widget->requisition.width = 0;
126 child->widget->requisition.height = 0;
Bram Moolenaar98921892016-02-23 17:14:37 +0100127#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000128 child->mapped = FALSE;
129
130 form->children = g_list_append(form->children, child);
131
Bram Moolenaar30613902019-12-01 22:11:18 +0100132 // child->window must be created and attached to the widget _before_
133 // it has been realized, or else things will break with GTK2. Note
134 // that gtk_widget_set_parent() realizes the widget if it's visible
135 // and its parent is mapped.
Bram Moolenaar98921892016-02-23 17:14:37 +0100136 if (gtk_widget_get_realized(GTK_WIDGET(form)))
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200137 form_attach_child_window(form, child);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000138
139 gtk_widget_set_parent(child_widget, GTK_WIDGET(form));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000140
Bram Moolenaar98921892016-02-23 17:14:37 +0100141 if (gtk_widget_get_realized(GTK_WIDGET(form))
142 && !gtk_widget_get_realized(child_widget))
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200143 form_realize_child(form, child);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000144
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200145 form_position_child(form, child, TRUE);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000146}
147
148 void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200149gui_gtk_form_move(
150 GtkForm *form,
151 GtkWidget *child_widget,
152 gint x,
153 gint y)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000154{
155 GList *tmp_list;
156 GtkFormChild *child;
157
158 g_return_if_fail(GTK_IS_FORM(form));
159
160 for (tmp_list = form->children; tmp_list; tmp_list = tmp_list->next)
161 {
162 child = tmp_list->data;
163 if (child->widget == child_widget)
164 {
165 child->x = x;
166 child->y = y;
167
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200168 form_position_child(form, child, TRUE);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000169 return;
170 }
171 }
172}
173
Bram Moolenaar071d4272004-06-13 20:20:40 +0000174 void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200175gui_gtk_form_freeze(GtkForm *form)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000176{
177 g_return_if_fail(GTK_IS_FORM(form));
178
179 ++form->freeze_count;
180}
181
182 void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200183gui_gtk_form_thaw(GtkForm *form)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000184{
185 g_return_if_fail(GTK_IS_FORM(form));
186
187 if (form->freeze_count)
188 {
189 if (!(--form->freeze_count))
190 {
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200191 form_position_children(form);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000192 gtk_widget_queue_draw(GTK_WIDGET(form));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000193 }
194 }
195}
196
Bram Moolenaar30613902019-12-01 22:11:18 +0100197// Basic Object handling procedures
Bram Moolenaar98921892016-02-23 17:14:37 +0100198#if GTK_CHECK_VERSION(3,0,0)
199G_DEFINE_TYPE(GtkForm, gtk_form, GTK_TYPE_CONTAINER)
200#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000201 GtkType
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200202gui_gtk_form_get_type(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000203{
204 static GtkType form_type = 0;
205
206 if (!form_type)
207 {
Bram Moolenaarb85cb212009-05-17 14:24:23 +0000208 GtkTypeInfo form_info;
209
Bram Moolenaara80faa82020-04-12 19:37:17 +0200210 CLEAR_FIELD(form_info);
Bram Moolenaarb85cb212009-05-17 14:24:23 +0000211 form_info.type_name = "GtkForm";
212 form_info.object_size = sizeof(GtkForm);
213 form_info.class_size = sizeof(GtkFormClass);
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200214 form_info.class_init_func = (GtkClassInitFunc)form_class_init;
215 form_info.object_init_func = (GtkObjectInitFunc)form_init;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000216
217 form_type = gtk_type_unique(GTK_TYPE_CONTAINER, &form_info);
218 }
219 return form_type;
220}
Bram Moolenaar30613902019-12-01 22:11:18 +0100221#endif // !GTK_CHECK_VERSION(3,0,0)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000222
223 static void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200224form_class_init(GtkFormClass *klass)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000225{
226 GtkWidgetClass *widget_class;
227 GtkContainerClass *container_class;
228
229 widget_class = (GtkWidgetClass *) klass;
230 container_class = (GtkContainerClass *) klass;
231
Bram Moolenaar98921892016-02-23 17:14:37 +0100232#if !GTK_CHECK_VERSION(3,0,0)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000233 parent_class = gtk_type_class(gtk_container_get_type());
Bram Moolenaar98921892016-02-23 17:14:37 +0100234#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000235
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200236 widget_class->realize = form_realize;
237 widget_class->unrealize = form_unrealize;
238 widget_class->map = form_map;
Bram Moolenaar98921892016-02-23 17:14:37 +0100239#if GTK_CHECK_VERSION(3,0,0)
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200240 widget_class->get_preferred_width = form_get_preferred_width;
241 widget_class->get_preferred_height = form_get_preferred_height;
Bram Moolenaar98921892016-02-23 17:14:37 +0100242#else
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200243 widget_class->size_request = form_size_request;
Bram Moolenaar98921892016-02-23 17:14:37 +0100244#endif
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200245 widget_class->size_allocate = form_size_allocate;
Bram Moolenaar98921892016-02-23 17:14:37 +0100246#if GTK_CHECK_VERSION(3,0,0)
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200247 widget_class->draw = form_draw;
Bram Moolenaar98921892016-02-23 17:14:37 +0100248#else
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200249 widget_class->expose_event = form_expose;
Bram Moolenaar98921892016-02-23 17:14:37 +0100250#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000251
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200252 container_class->remove = form_remove;
253 container_class->forall = form_forall;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000254}
255
256 static void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200257form_init(GtkForm *form, void *g_class UNUSED)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000258{
Bram Moolenaar98921892016-02-23 17:14:37 +0100259#if GTK_CHECK_VERSION(3,0,0)
260 gtk_widget_set_has_window(GTK_WIDGET(form), TRUE);
261#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000262 form->children = NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000263 form->bin_window = NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000264 form->freeze_count = 0;
265}
266
267/*
268 * Widget methods
269 */
270
271 static void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200272form_realize(GtkWidget *widget)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000273{
274 GList *tmp_list;
275 GtkForm *form;
276 GdkWindowAttr attributes;
277 gint attributes_mask;
Bram Moolenaar664323e2018-09-18 22:30:07 +0200278 GtkAllocation allocation;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000279
280 g_return_if_fail(GTK_IS_FORM(widget));
281
282 form = GTK_FORM(widget);
Bram Moolenaar98921892016-02-23 17:14:37 +0100283 gtk_widget_set_realized(widget, TRUE);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000284
Bram Moolenaar664323e2018-09-18 22:30:07 +0200285 gtk_widget_get_allocation(widget, &allocation);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000286 attributes.window_type = GDK_WINDOW_CHILD;
Bram Moolenaar664323e2018-09-18 22:30:07 +0200287 attributes.x = allocation.x;
288 attributes.y = allocation.y;
289 attributes.width = allocation.width;
290 attributes.height = allocation.height;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000291 attributes.wclass = GDK_INPUT_OUTPUT;
292 attributes.visual = gtk_widget_get_visual(widget);
Bram Moolenaar98921892016-02-23 17:14:37 +0100293#if GTK_CHECK_VERSION(3,0,0)
294 attributes.event_mask = GDK_EXPOSURE_MASK;
295#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000296 attributes.colormap = gtk_widget_get_colormap(widget);
297 attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK;
Bram Moolenaar98921892016-02-23 17:14:37 +0100298#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000299
Bram Moolenaar98921892016-02-23 17:14:37 +0100300#if GTK_CHECK_VERSION(3,0,0)
301 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
302#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000303 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
Bram Moolenaar98921892016-02-23 17:14:37 +0100304#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000305
Bram Moolenaar98921892016-02-23 17:14:37 +0100306 gtk_widget_set_window(widget,
307 gdk_window_new(gtk_widget_get_parent_window(widget),
308 &attributes, attributes_mask));
Bram Moolenaar25328e32018-09-11 21:30:09 +0200309 gdk_window_set_user_data(gtk_widget_get_window(widget), widget);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000310
311 attributes.x = 0;
312 attributes.y = 0;
313 attributes.event_mask = gtk_widget_get_events(widget);
314
Bram Moolenaar98921892016-02-23 17:14:37 +0100315 form->bin_window = gdk_window_new(gtk_widget_get_window(widget),
316 &attributes, attributes_mask);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000317 gdk_window_set_user_data(form->bin_window, widget);
318
Bram Moolenaar98921892016-02-23 17:14:37 +0100319#if GTK_CHECK_VERSION(3,0,0)
320 {
321 GtkStyleContext * const sctx = gtk_widget_get_style_context(widget);
322
323 gtk_style_context_add_class(sctx, "gtk-form");
324 gtk_style_context_set_state(sctx, GTK_STATE_FLAG_NORMAL);
325# if !GTK_CHECK_VERSION(3,18,0)
326 gtk_style_context_set_background(sctx, gtk_widget_get_window(widget));
327 gtk_style_context_set_background(sctx, form->bin_window);
328# endif
329 }
330#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000331 widget->style = gtk_style_attach(widget->style, widget->window);
332 gtk_style_set_background(widget->style, widget->window, GTK_STATE_NORMAL);
333 gtk_style_set_background(widget->style, form->bin_window, GTK_STATE_NORMAL);
Bram Moolenaar98921892016-02-23 17:14:37 +0100334#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000335
Bram Moolenaar071d4272004-06-13 20:20:40 +0000336 for (tmp_list = form->children; tmp_list; tmp_list = tmp_list->next)
337 {
338 GtkFormChild *child = tmp_list->data;
339
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200340 form_attach_child_window(form, child);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000341
Bram Moolenaar98921892016-02-23 17:14:37 +0100342 if (gtk_widget_get_visible(child->widget))
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200343 form_realize_child(form, child);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000344 }
345}
346
347
Bram Moolenaar30613902019-12-01 22:11:18 +0100348// After reading the documentation at
349// http://developer.gnome.org/doc/API/2.0/gtk/gtk-changes-2-0.html
350// I think it should be possible to remove this function when compiling
351// against gtk-2.0. It doesn't seem to cause problems, though.
352//
353// Well, I reckon at least the gdk_window_show(form->bin_window)
354// is necessary. GtkForm is anything but a usual container widget.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000355 static void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200356form_map(GtkWidget *widget)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000357{
358 GList *tmp_list;
359 GtkForm *form;
360
361 g_return_if_fail(GTK_IS_FORM(widget));
362
363 form = GTK_FORM(widget);
364
Bram Moolenaar98921892016-02-23 17:14:37 +0100365 gtk_widget_set_mapped(widget, TRUE);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000366
Bram Moolenaar98921892016-02-23 17:14:37 +0100367 gdk_window_show(gtk_widget_get_window(widget));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000368 gdk_window_show(form->bin_window);
369
370 for (tmp_list = form->children; tmp_list; tmp_list = tmp_list->next)
371 {
372 GtkFormChild *child = tmp_list->data;
373
Bram Moolenaar98921892016-02-23 17:14:37 +0100374 if (gtk_widget_get_visible(child->widget)
375 && !gtk_widget_get_mapped(child->widget))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000376 gtk_widget_map(child->widget);
377 }
378}
379
380 static void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200381form_unrealize(GtkWidget *widget)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000382{
383 GList *tmp_list;
384 GtkForm *form;
385
386 g_return_if_fail(GTK_IS_FORM(widget));
387
388 form = GTK_FORM(widget);
389
390 tmp_list = form->children;
391
392 gdk_window_set_user_data(form->bin_window, NULL);
393 gdk_window_destroy(form->bin_window);
394 form->bin_window = NULL;
395
396 while (tmp_list)
397 {
398 GtkFormChild *child = tmp_list->data;
399
400 if (child->window != NULL)
401 {
Bram Moolenaar98921892016-02-23 17:14:37 +0100402 g_signal_handlers_disconnect_by_func(G_OBJECT(child->widget),
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200403 FUNC2GENERIC(form_child_map),
Bram Moolenaar98921892016-02-23 17:14:37 +0100404 child);
405 g_signal_handlers_disconnect_by_func(G_OBJECT(child->widget),
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200406 FUNC2GENERIC(form_child_unmap),
Bram Moolenaar98921892016-02-23 17:14:37 +0100407 child);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000408
409 gdk_window_set_user_data(child->window, NULL);
410 gdk_window_destroy(child->window);
411
412 child->window = NULL;
413 }
414
415 tmp_list = tmp_list->next;
416 }
417
Bram Moolenaar98921892016-02-23 17:14:37 +0100418#if GTK_CHECK_VERSION(3,0,0)
419 if (GTK_WIDGET_CLASS (gtk_form_parent_class)->unrealize)
420 (* GTK_WIDGET_CLASS (gtk_form_parent_class)->unrealize) (widget);
421#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000422 if (GTK_WIDGET_CLASS (parent_class)->unrealize)
423 (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
Bram Moolenaar98921892016-02-23 17:14:37 +0100424#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000425}
426
Bram Moolenaar071d4272004-06-13 20:20:40 +0000427 static void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200428form_size_request(GtkWidget *widget, GtkRequisition *requisition)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000429{
Bram Moolenaar071d4272004-06-13 20:20:40 +0000430 g_return_if_fail(GTK_IS_FORM(widget));
Bram Moolenaar99a6e8d2017-03-29 18:07:40 +0200431 g_return_if_fail(requisition != NULL);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000432
Bram Moolenaar98921892016-02-23 17:14:37 +0100433 requisition->width = 1;
434 requisition->height = 1;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000435}
436
Bram Moolenaar98921892016-02-23 17:14:37 +0100437#if GTK_CHECK_VERSION(3,0,0)
438 static void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200439form_get_preferred_width(GtkWidget *widget,
Bram Moolenaar98921892016-02-23 17:14:37 +0100440 gint *minimal_width,
441 gint *natural_width)
442{
443 GtkRequisition requisition;
444
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200445 form_size_request(widget, &requisition);
Bram Moolenaar98921892016-02-23 17:14:37 +0100446
447 *minimal_width = requisition.width;
448 *natural_width = requisition.width;
449}
450
451 static void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200452form_get_preferred_height(GtkWidget *widget,
Bram Moolenaar98921892016-02-23 17:14:37 +0100453 gint *minimal_height,
454 gint *natural_height)
455{
456 GtkRequisition requisition;
457
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200458 form_size_request(widget, &requisition);
Bram Moolenaar98921892016-02-23 17:14:37 +0100459
460 *minimal_height = requisition.height;
461 *natural_height = requisition.height;
462}
Bram Moolenaar30613902019-12-01 22:11:18 +0100463#endif // GTK_CHECK_VERSION(3,0,0)
Bram Moolenaar98921892016-02-23 17:14:37 +0100464
Bram Moolenaar071d4272004-06-13 20:20:40 +0000465 static void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200466form_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000467{
468 GList *tmp_list;
469 GtkForm *form;
470 gboolean need_reposition;
Bram Moolenaar98921892016-02-23 17:14:37 +0100471 GtkAllocation cur_alloc;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000472
473 g_return_if_fail(GTK_IS_FORM(widget));
474
Bram Moolenaar98921892016-02-23 17:14:37 +0100475 gtk_widget_get_allocation(widget, &cur_alloc);
476
477 if (cur_alloc.x == allocation->x
478 && cur_alloc.y == allocation->y
479 && cur_alloc.width == allocation->width
480 && cur_alloc.height == allocation->height)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000481 return;
482
Bram Moolenaar98921892016-02-23 17:14:37 +0100483 need_reposition = cur_alloc.width != allocation->width
484 || cur_alloc.height != allocation->height;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000485 form = GTK_FORM(widget);
486
487 if (need_reposition)
488 {
489 tmp_list = form->children;
490
491 while (tmp_list)
492 {
493 GtkFormChild *child = tmp_list->data;
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200494 form_position_child(form, child, TRUE);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000495
496 tmp_list = tmp_list->next;
497 }
498 }
499
Bram Moolenaar98921892016-02-23 17:14:37 +0100500 if (gtk_widget_get_realized(widget))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000501 {
Bram Moolenaar98921892016-02-23 17:14:37 +0100502 gdk_window_move_resize(gtk_widget_get_window(widget),
503 allocation->x, allocation->y,
504 allocation->width, allocation->height);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000505 gdk_window_move_resize(GTK_FORM(widget)->bin_window,
506 0, 0,
507 allocation->width, allocation->height);
508 }
Bram Moolenaar98921892016-02-23 17:14:37 +0100509 gtk_widget_set_allocation(widget, allocation);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000510 if (need_reposition)
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200511 form_send_configure(form);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000512}
513
Bram Moolenaar98921892016-02-23 17:14:37 +0100514#if GTK_CHECK_VERSION(3,0,0)
515 static void
516gtk_form_render_background(GtkWidget *widget, cairo_t *cr)
517{
518 gtk_render_background(gtk_widget_get_style_context(widget), cr,
519 0, 0,
520 gtk_widget_get_allocated_width(widget),
521 gtk_widget_get_allocated_height(widget));
522}
523
524 static gboolean
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200525form_draw(GtkWidget *widget, cairo_t *cr)
Bram Moolenaar98921892016-02-23 17:14:37 +0100526{
527 GList *tmp_list = NULL;
528 GtkForm *form = NULL;
529
530 g_return_val_if_fail(GTK_IS_FORM(widget), FALSE);
531
532 gtk_form_render_background(widget, cr);
533
534 form = GTK_FORM(widget);
535 for (tmp_list = form->children; tmp_list; tmp_list = tmp_list->next)
536 {
537 GtkFormChild * const formchild = tmp_list->data;
538
539 if (!gtk_widget_get_has_window(formchild->widget) &&
540 gtk_cairo_should_draw_window(cr, formchild->window))
541 {
Bram Moolenaar30613902019-12-01 22:11:18 +0100542 // To get gtk_widget_draw() to work, it is required to call
543 // gtk_widget_size_allocate() in advance with a well-posed
544 // allocation for a given child widget in order to set a
545 // certain private GtkWidget variable, called
546 // widget->priv->alloc_need, to the proper value; otherwise,
547 // gtk_widget_draw() fails and the relevant scrollbar won't
548 // appear on the screen.
549 //
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200550 // Calling form_position_child() like this is one of ways
Bram Moolenaar30613902019-12-01 22:11:18 +0100551 // to make sure of that.
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200552 form_position_child(form, formchild, TRUE);
Bram Moolenaar98921892016-02-23 17:14:37 +0100553
554 gtk_form_render_background(formchild->widget, cr);
555 }
556 }
557
558 return GTK_WIDGET_CLASS(gtk_form_parent_class)->draw(widget, cr);
559}
Bram Moolenaar30613902019-12-01 22:11:18 +0100560#else // !GTK_CHECK_VERSION(3,0,0)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000561 static gint
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200562form_expose(GtkWidget *widget, GdkEventExpose *event)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000563{
564 GList *tmp_list;
565 GtkForm *form;
566
567 g_return_val_if_fail(GTK_IS_FORM(widget), FALSE);
568
569 form = GTK_FORM(widget);
570
571 if (event->window == form->bin_window)
572 return FALSE;
573
574 for (tmp_list = form->children; tmp_list; tmp_list = tmp_list->next)
Bram Moolenaar99a6e8d2017-03-29 18:07:40 +0200575 gtk_container_propagate_expose(GTK_CONTAINER(widget),
576 GTK_WIDGET(((GtkFormChild *)tmp_list->data)->widget),
577 event);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000578
579 return FALSE;
580}
Bram Moolenaar30613902019-12-01 22:11:18 +0100581#endif // !GTK_CHECK_VERSION(3,0,0)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000582
Bram Moolenaar30613902019-12-01 22:11:18 +0100583// Container method
Bram Moolenaar071d4272004-06-13 20:20:40 +0000584 static void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200585form_remove(GtkContainer *container, GtkWidget *widget)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000586{
587 GList *tmp_list;
588 GtkForm *form;
Bram Moolenaar30613902019-12-01 22:11:18 +0100589 GtkFormChild *child = NULL; // init for gcc
Bram Moolenaar071d4272004-06-13 20:20:40 +0000590
591 g_return_if_fail(GTK_IS_FORM(container));
592
593 form = GTK_FORM(container);
594
595 tmp_list = form->children;
596 while (tmp_list)
597 {
598 child = tmp_list->data;
599 if (child->widget == widget)
600 break;
601 tmp_list = tmp_list->next;
602 }
603
604 if (tmp_list)
605 {
Bram Moolenaar98921892016-02-23 17:14:37 +0100606#if GTK_CHECK_VERSION(3,0,0)
607 const gboolean was_visible = gtk_widget_get_visible(widget);
608#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000609 if (child->window)
610 {
Bram Moolenaar98921892016-02-23 17:14:37 +0100611 g_signal_handlers_disconnect_by_func(G_OBJECT(child->widget),
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200612 FUNC2GENERIC(&form_child_map), child);
Bram Moolenaar98921892016-02-23 17:14:37 +0100613 g_signal_handlers_disconnect_by_func(G_OBJECT(child->widget),
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200614 FUNC2GENERIC(&form_child_unmap), child);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000615
Bram Moolenaar30613902019-12-01 22:11:18 +0100616 // FIXME: This will cause problems for reparenting NO_WINDOW
617 // widgets out of a GtkForm
Bram Moolenaar071d4272004-06-13 20:20:40 +0000618 gdk_window_set_user_data(child->window, NULL);
619 gdk_window_destroy(child->window);
620 }
621 gtk_widget_unparent(widget);
Bram Moolenaar98921892016-02-23 17:14:37 +0100622#if GTK_CHECK_VERSION(3,0,0)
623 if (was_visible)
624 gtk_widget_queue_resize(GTK_WIDGET(container));
625#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000626 form->children = g_list_remove_link(form->children, tmp_list);
627 g_list_free_1(tmp_list);
628 g_free(child);
629 }
630}
631
Bram Moolenaar071d4272004-06-13 20:20:40 +0000632 static void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200633form_forall(GtkContainer *container,
Bram Moolenaarb85cb212009-05-17 14:24:23 +0000634 gboolean include_internals UNUSED,
Bram Moolenaar071d4272004-06-13 20:20:40 +0000635 GtkCallback callback,
636 gpointer callback_data)
637{
638 GtkForm *form;
639 GtkFormChild *child;
640 GList *tmp_list;
641
642 g_return_if_fail(GTK_IS_FORM(container));
643 g_return_if_fail(callback != NULL);
644
645 form = GTK_FORM(container);
646
647 tmp_list = form->children;
648 while (tmp_list)
649 {
650 child = tmp_list->data;
651 tmp_list = tmp_list->next;
652
653 (*callback) (child->widget, callback_data);
654 }
655}
656
Bram Moolenaar30613902019-12-01 22:11:18 +0100657// Operations on children
Bram Moolenaar071d4272004-06-13 20:20:40 +0000658
659 static void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200660form_attach_child_window(GtkForm *form, GtkFormChild *child)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000661{
662 if (child->window != NULL)
Bram Moolenaar30613902019-12-01 22:11:18 +0100663 return; // been there, done that
Bram Moolenaar071d4272004-06-13 20:20:40 +0000664
Bram Moolenaar98921892016-02-23 17:14:37 +0100665 if (!gtk_widget_get_has_window(child->widget))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000666 {
667 GtkWidget *widget;
668 GdkWindowAttr attributes;
669 gint attributes_mask;
Bram Moolenaar664323e2018-09-18 22:30:07 +0200670 GtkRequisition requisition;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000671
672 widget = GTK_WIDGET(form);
673
Bram Moolenaar664323e2018-09-18 22:30:07 +0200674#if GTK_CHECK_VERSION(3,0,0)
675 gtk_widget_get_preferred_size(child->widget, &requisition, NULL);
676#else
677 requisition = child->widget->requisition;
678#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000679 attributes.window_type = GDK_WINDOW_CHILD;
680 attributes.x = child->x;
681 attributes.y = child->y;
Bram Moolenaar664323e2018-09-18 22:30:07 +0200682 attributes.width = requisition.width;
683 attributes.height = requisition.height;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000684 attributes.wclass = GDK_INPUT_OUTPUT;
685 attributes.visual = gtk_widget_get_visual(widget);
Bram Moolenaar98921892016-02-23 17:14:37 +0100686#if !GTK_CHECK_VERSION(3,0,0)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000687 attributes.colormap = gtk_widget_get_colormap(widget);
Bram Moolenaar98921892016-02-23 17:14:37 +0100688#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000689 attributes.event_mask = GDK_EXPOSURE_MASK;
690
Bram Moolenaar98921892016-02-23 17:14:37 +0100691#if GTK_CHECK_VERSION(3,0,0)
692 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
693#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000694 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
Bram Moolenaar98921892016-02-23 17:14:37 +0100695#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000696 child->window = gdk_window_new(form->bin_window,
697 &attributes, attributes_mask);
698 gdk_window_set_user_data(child->window, widget);
699
Bram Moolenaar98921892016-02-23 17:14:37 +0100700#if GTK_CHECK_VERSION(3,0,0)
701 {
702 GtkStyleContext * const sctx = gtk_widget_get_style_context(widget);
703
704 gtk_style_context_set_state(sctx, GTK_STATE_FLAG_NORMAL);
705# if !GTK_CHECK_VERSION(3,18,0)
706 gtk_style_context_set_background(sctx, child->window);
707# endif
708 }
709#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000710 gtk_style_set_background(widget->style,
711 child->window,
712 GTK_STATE_NORMAL);
Bram Moolenaar98921892016-02-23 17:14:37 +0100713#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000714
715 gtk_widget_set_parent_window(child->widget, child->window);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000716 /*
717 * Install signal handlers to map/unmap child->window
718 * alongside with the actual widget.
719 */
Bram Moolenaar98921892016-02-23 17:14:37 +0100720 g_signal_connect(G_OBJECT(child->widget), "map",
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200721 G_CALLBACK(&form_child_map), child);
Bram Moolenaar98921892016-02-23 17:14:37 +0100722 g_signal_connect(G_OBJECT(child->widget), "unmap",
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200723 G_CALLBACK(&form_child_unmap), child);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000724 }
Bram Moolenaar98921892016-02-23 17:14:37 +0100725 else if (!gtk_widget_get_realized(child->widget))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000726 {
727 gtk_widget_set_parent_window(child->widget, form->bin_window);
728 }
729}
730
731 static void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200732form_realize_child(GtkForm *form, GtkFormChild *child)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000733{
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200734 form_attach_child_window(form, child);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000735 gtk_widget_realize(child->widget);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000736}
737
738 static void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200739form_position_child(GtkForm *form, GtkFormChild *child, gboolean force_allocate)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000740{
741 gint x;
742 gint y;
743
744 x = child->x;
745 y = child->y;
746
747 if ((x >= G_MINSHORT) && (x <= G_MAXSHORT) &&
748 (y >= G_MINSHORT) && (y <= G_MAXSHORT))
749 {
750 if (!child->mapped)
751 {
Bram Moolenaar98921892016-02-23 17:14:37 +0100752 if (gtk_widget_get_mapped(GTK_WIDGET(form))
753 && gtk_widget_get_visible(child->widget))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000754 {
Bram Moolenaar98921892016-02-23 17:14:37 +0100755 if (!gtk_widget_get_mapped(child->widget))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000756 gtk_widget_map(child->widget);
757
758 child->mapped = TRUE;
759 force_allocate = TRUE;
760 }
761 }
762
763 if (force_allocate)
764 {
765 GtkAllocation allocation;
Bram Moolenaar98921892016-02-23 17:14:37 +0100766 GtkRequisition requisition;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000767
Bram Moolenaar664323e2018-09-18 22:30:07 +0200768#if GTK_CHECK_VERSION(3,0,0)
Bram Moolenaar98921892016-02-23 17:14:37 +0100769 gtk_widget_get_preferred_size(child->widget, &requisition, NULL);
Bram Moolenaar664323e2018-09-18 22:30:07 +0200770#else
771 requisition = child->widget->requisition;
Bram Moolenaar98921892016-02-23 17:14:37 +0100772#endif
773
Bram Moolenaar98921892016-02-23 17:14:37 +0100774 if (!gtk_widget_get_has_window(child->widget))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000775 {
776 if (child->window)
777 {
Bram Moolenaar98921892016-02-23 17:14:37 +0100778 gdk_window_move_resize(child->window,
779 x, y,
780 requisition.width,
781 requisition.height);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000782 }
783
784 allocation.x = 0;
785 allocation.y = 0;
786 }
787 else
788 {
789 allocation.x = x;
790 allocation.y = y;
791 }
792
Bram Moolenaar98921892016-02-23 17:14:37 +0100793 allocation.width = requisition.width;
794 allocation.height = requisition.height;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000795
796 gtk_widget_size_allocate(child->widget, &allocation);
797 }
798 }
799 else
800 {
801 if (child->mapped)
802 {
803 child->mapped = FALSE;
804
Bram Moolenaar98921892016-02-23 17:14:37 +0100805 if (gtk_widget_get_mapped(child->widget))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000806 gtk_widget_unmap(child->widget);
807 }
808 }
809}
810
811 static void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200812form_position_children(GtkForm *form)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000813{
814 GList *tmp_list;
815
816 for (tmp_list = form->children; tmp_list; tmp_list = tmp_list->next)
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200817 form_position_child(form, tmp_list->data, FALSE);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000818}
819
Bram Moolenaar071d4272004-06-13 20:20:40 +0000820 void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200821gui_gtk_form_move_resize(GtkForm *form, GtkWidget *widget,
Bram Moolenaar071d4272004-06-13 20:20:40 +0000822 gint x, gint y, gint w, gint h)
823{
Bram Moolenaar98921892016-02-23 17:14:37 +0100824#if GTK_CHECK_VERSION(3,0,0)
825 gtk_widget_set_size_request(widget, w, h);
826#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000827 widget->requisition.width = w;
828 widget->requisition.height = h;
Bram Moolenaar98921892016-02-23 17:14:37 +0100829#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000830
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200831 gui_gtk_form_move(form, widget, x, y);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000832}
833
834 static void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200835form_send_configure(GtkForm *form)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000836{
837 GtkWidget *widget;
838 GdkEventConfigure event;
Bram Moolenaar664323e2018-09-18 22:30:07 +0200839 GtkAllocation allocation;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000840
841 widget = GTK_WIDGET(form);
842
Bram Moolenaar664323e2018-09-18 22:30:07 +0200843 gtk_widget_get_allocation(widget, &allocation);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000844 event.type = GDK_CONFIGURE;
Bram Moolenaar98921892016-02-23 17:14:37 +0100845 event.window = gtk_widget_get_window(widget);
Bram Moolenaar664323e2018-09-18 22:30:07 +0200846 event.x = allocation.x;
847 event.y = allocation.y;
848 event.width = allocation.width;
849 event.height = allocation.height;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000850
Bram Moolenaar071d4272004-06-13 20:20:40 +0000851 gtk_main_do_event((GdkEvent*)&event);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000852}
853
Bram Moolenaar071d4272004-06-13 20:20:40 +0000854 static void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200855form_child_map(GtkWidget *widget UNUSED, gpointer user_data)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000856{
857 GtkFormChild *child;
858
859 child = (GtkFormChild *)user_data;
860
861 child->mapped = TRUE;
862 gdk_window_show(child->window);
863}
864
Bram Moolenaar071d4272004-06-13 20:20:40 +0000865 static void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200866form_child_unmap(GtkWidget *widget UNUSED, gpointer user_data)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000867{
868 GtkFormChild *child;
869
870 child = (GtkFormChild *)user_data;
871
872 child->mapped = FALSE;
873 gdk_window_hide(child->window);
874}