blob: c8f90c2d79d93110ebbc9de7c5e53a7093f9c4da [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 Moolenaar692d1a52020-10-21 17:28:27 +020051static void gui_gtk_form_class_init(GtkFormClass *klass);
52#if GTK_CHECK_VERSION(3,0,0)
53static void gui_gtk_form_init(GtkForm *form);
54#else
55static void gui_gtk_form_init(GtkForm *form, void *g_class);
56#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +000057
Bram Moolenaar8a99e662020-10-21 16:10:21 +020058static void form_realize(GtkWidget *widget);
59static void form_unrealize(GtkWidget *widget);
60static void form_map(GtkWidget *widget);
61static void form_size_request(GtkWidget *widget, GtkRequisition *requisition);
Bram Moolenaar98921892016-02-23 17:14:37 +010062#if GTK_CHECK_VERSION(3,0,0)
Bram Moolenaar8a99e662020-10-21 16:10:21 +020063static void form_get_preferred_width(GtkWidget *widget, gint *minimal_width, gint *natural_width);
64static void form_get_preferred_height(GtkWidget *widget, gint *minimal_height, gint *natural_height);
Bram Moolenaar98921892016-02-23 17:14:37 +010065#endif
Bram Moolenaar8a99e662020-10-21 16:10:21 +020066static void form_size_allocate(GtkWidget *widget, GtkAllocation *allocation);
Bram Moolenaar98921892016-02-23 17:14:37 +010067#if GTK_CHECK_VERSION(3,0,0)
Bram Moolenaar8a99e662020-10-21 16:10:21 +020068static gboolean form_draw(GtkWidget *widget, cairo_t *cr);
Bram Moolenaar98921892016-02-23 17:14:37 +010069#else
Bram Moolenaar8a99e662020-10-21 16:10:21 +020070static gint form_expose(GtkWidget *widget, GdkEventExpose *event);
Bram Moolenaar98921892016-02-23 17:14:37 +010071#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +000072
Bram Moolenaar8a99e662020-10-21 16:10:21 +020073static void form_remove(GtkContainer *container, GtkWidget *widget);
74static void form_forall(GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data);
Bram Moolenaar071d4272004-06-13 20:20:40 +000075
Bram Moolenaar8a99e662020-10-21 16:10:21 +020076static void form_attach_child_window(GtkForm *form, GtkFormChild *child);
77static void form_realize_child(GtkForm *form, GtkFormChild *child);
78static void form_position_child(GtkForm *form, GtkFormChild *child, gboolean force_allocate);
79static void form_position_children(GtkForm *form);
Bram Moolenaar071d4272004-06-13 20:20:40 +000080
Bram Moolenaar8a99e662020-10-21 16:10:21 +020081static void form_send_configure(GtkForm *form);
Bram Moolenaar071d4272004-06-13 20:20:40 +000082
Bram Moolenaar8a99e662020-10-21 16:10:21 +020083static void form_child_map(GtkWidget *widget, gpointer user_data);
84static void form_child_unmap(GtkWidget *widget, gpointer user_data);
Bram Moolenaar071d4272004-06-13 20:20:40 +000085
Bram Moolenaar98921892016-02-23 17:14:37 +010086#if !GTK_CHECK_VERSION(3,0,0)
Bram Moolenaar071d4272004-06-13 20:20:40 +000087static GtkWidgetClass *parent_class = NULL;
Bram Moolenaar98921892016-02-23 17:14:37 +010088#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +000089
Bram Moolenaar30613902019-12-01 22:11:18 +010090// Public interface
Bram Moolenaar071d4272004-06-13 20:20:40 +000091
92 GtkWidget *
Bram Moolenaar8a99e662020-10-21 16:10:21 +020093gui_gtk_form_new(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +000094{
95 GtkForm *form;
96
Bram Moolenaar98921892016-02-23 17:14:37 +010097#if GTK_CHECK_VERSION(3,0,0)
98 form = g_object_new(GTK_TYPE_FORM, NULL);
99#else
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200100 form = gtk_type_new(gui_gtk_form_get_type());
Bram Moolenaar98921892016-02-23 17:14:37 +0100101#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000102
103 return GTK_WIDGET(form);
104}
105
106 void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200107gui_gtk_form_put(
108 GtkForm *form,
109 GtkWidget *child_widget,
110 gint x,
111 gint y)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000112{
113 GtkFormChild *child;
114
115 g_return_if_fail(GTK_IS_FORM(form));
116
Bram Moolenaar30613902019-12-01 22:11:18 +0100117 // LINTED: avoid warning: conversion to 'unsigned long'
Bram Moolenaar071d4272004-06-13 20:20:40 +0000118 child = g_new(GtkFormChild, 1);
Bram Moolenaar6ee96582019-04-27 22:06:37 +0200119 if (child == NULL)
120 return;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000121
122 child->widget = child_widget;
123 child->window = NULL;
124 child->x = x;
125 child->y = y;
Bram Moolenaar98921892016-02-23 17:14:37 +0100126#if GTK_CHECK_VERSION(3,0,0)
127 gtk_widget_set_size_request(child->widget, -1, -1);
128#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000129 child->widget->requisition.width = 0;
130 child->widget->requisition.height = 0;
Bram Moolenaar98921892016-02-23 17:14:37 +0100131#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000132 child->mapped = FALSE;
133
134 form->children = g_list_append(form->children, child);
135
Bram Moolenaar30613902019-12-01 22:11:18 +0100136 // child->window must be created and attached to the widget _before_
137 // it has been realized, or else things will break with GTK2. Note
138 // that gtk_widget_set_parent() realizes the widget if it's visible
139 // and its parent is mapped.
Bram Moolenaar98921892016-02-23 17:14:37 +0100140 if (gtk_widget_get_realized(GTK_WIDGET(form)))
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200141 form_attach_child_window(form, child);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000142
143 gtk_widget_set_parent(child_widget, GTK_WIDGET(form));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000144
Bram Moolenaar98921892016-02-23 17:14:37 +0100145 if (gtk_widget_get_realized(GTK_WIDGET(form))
146 && !gtk_widget_get_realized(child_widget))
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200147 form_realize_child(form, child);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000148
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200149 form_position_child(form, child, TRUE);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000150}
151
152 void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200153gui_gtk_form_move(
154 GtkForm *form,
155 GtkWidget *child_widget,
156 gint x,
157 gint y)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000158{
159 GList *tmp_list;
160 GtkFormChild *child;
161
162 g_return_if_fail(GTK_IS_FORM(form));
163
164 for (tmp_list = form->children; tmp_list; tmp_list = tmp_list->next)
165 {
166 child = tmp_list->data;
167 if (child->widget == child_widget)
168 {
169 child->x = x;
170 child->y = y;
171
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200172 form_position_child(form, child, TRUE);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000173 return;
174 }
175 }
176}
177
Bram Moolenaar071d4272004-06-13 20:20:40 +0000178 void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200179gui_gtk_form_freeze(GtkForm *form)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000180{
181 g_return_if_fail(GTK_IS_FORM(form));
182
183 ++form->freeze_count;
184}
185
186 void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200187gui_gtk_form_thaw(GtkForm *form)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000188{
189 g_return_if_fail(GTK_IS_FORM(form));
190
191 if (form->freeze_count)
192 {
193 if (!(--form->freeze_count))
194 {
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200195 form_position_children(form);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000196 gtk_widget_queue_draw(GTK_WIDGET(form));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000197 }
198 }
199}
200
Bram Moolenaar30613902019-12-01 22:11:18 +0100201// Basic Object handling procedures
Bram Moolenaar692d1a52020-10-21 17:28:27 +0200202
Bram Moolenaar98921892016-02-23 17:14:37 +0100203#if GTK_CHECK_VERSION(3,0,0)
Bram Moolenaar692d1a52020-10-21 17:28:27 +0200204G_DEFINE_TYPE(GtkForm, gui_gtk_form, GTK_TYPE_CONTAINER)
Bram Moolenaar98921892016-02-23 17:14:37 +0100205#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000206 GtkType
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200207gui_gtk_form_get_type(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000208{
209 static GtkType form_type = 0;
210
211 if (!form_type)
212 {
Bram Moolenaarb85cb212009-05-17 14:24:23 +0000213 GtkTypeInfo form_info;
214
Bram Moolenaara80faa82020-04-12 19:37:17 +0200215 CLEAR_FIELD(form_info);
Bram Moolenaarb85cb212009-05-17 14:24:23 +0000216 form_info.type_name = "GtkForm";
217 form_info.object_size = sizeof(GtkForm);
218 form_info.class_size = sizeof(GtkFormClass);
Bram Moolenaar692d1a52020-10-21 17:28:27 +0200219 form_info.class_init_func = (GtkClassInitFunc)gui_gtk_form_class_init;
220 form_info.object_init_func = (GtkObjectInitFunc)gui_gtk_form_init;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000221
222 form_type = gtk_type_unique(GTK_TYPE_CONTAINER, &form_info);
223 }
224 return form_type;
225}
Bram Moolenaar30613902019-12-01 22:11:18 +0100226#endif // !GTK_CHECK_VERSION(3,0,0)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000227
228 static void
Bram Moolenaar692d1a52020-10-21 17:28:27 +0200229gui_gtk_form_class_init(GtkFormClass *klass)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000230{
231 GtkWidgetClass *widget_class;
232 GtkContainerClass *container_class;
233
234 widget_class = (GtkWidgetClass *) klass;
235 container_class = (GtkContainerClass *) klass;
236
Bram Moolenaar98921892016-02-23 17:14:37 +0100237#if !GTK_CHECK_VERSION(3,0,0)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000238 parent_class = gtk_type_class(gtk_container_get_type());
Bram Moolenaar98921892016-02-23 17:14:37 +0100239#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000240
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200241 widget_class->realize = form_realize;
242 widget_class->unrealize = form_unrealize;
243 widget_class->map = form_map;
Bram Moolenaar98921892016-02-23 17:14:37 +0100244#if GTK_CHECK_VERSION(3,0,0)
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200245 widget_class->get_preferred_width = form_get_preferred_width;
246 widget_class->get_preferred_height = form_get_preferred_height;
Bram Moolenaar98921892016-02-23 17:14:37 +0100247#else
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200248 widget_class->size_request = form_size_request;
Bram Moolenaar98921892016-02-23 17:14:37 +0100249#endif
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200250 widget_class->size_allocate = form_size_allocate;
Bram Moolenaar98921892016-02-23 17:14:37 +0100251#if GTK_CHECK_VERSION(3,0,0)
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200252 widget_class->draw = form_draw;
Bram Moolenaar98921892016-02-23 17:14:37 +0100253#else
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200254 widget_class->expose_event = form_expose;
Bram Moolenaar98921892016-02-23 17:14:37 +0100255#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000256
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200257 container_class->remove = form_remove;
258 container_class->forall = form_forall;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000259}
260
261 static void
Bram Moolenaar692d1a52020-10-21 17:28:27 +0200262gui_gtk_form_init(GtkForm *form
263#if !GTK_CHECK_VERSION(3,0,0)
264 , void *g_class UNUSED
265#endif
266 )
Bram Moolenaar071d4272004-06-13 20:20:40 +0000267{
Bram Moolenaar98921892016-02-23 17:14:37 +0100268#if GTK_CHECK_VERSION(3,0,0)
269 gtk_widget_set_has_window(GTK_WIDGET(form), TRUE);
270#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000271 form->children = NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000272 form->bin_window = NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000273 form->freeze_count = 0;
274}
275
276/*
277 * Widget methods
278 */
279
280 static void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200281form_realize(GtkWidget *widget)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000282{
283 GList *tmp_list;
284 GtkForm *form;
285 GdkWindowAttr attributes;
286 gint attributes_mask;
Bram Moolenaar664323e2018-09-18 22:30:07 +0200287 GtkAllocation allocation;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000288
289 g_return_if_fail(GTK_IS_FORM(widget));
290
291 form = GTK_FORM(widget);
Bram Moolenaar98921892016-02-23 17:14:37 +0100292 gtk_widget_set_realized(widget, TRUE);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000293
Bram Moolenaar664323e2018-09-18 22:30:07 +0200294 gtk_widget_get_allocation(widget, &allocation);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000295 attributes.window_type = GDK_WINDOW_CHILD;
Bram Moolenaar664323e2018-09-18 22:30:07 +0200296 attributes.x = allocation.x;
297 attributes.y = allocation.y;
298 attributes.width = allocation.width;
299 attributes.height = allocation.height;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000300 attributes.wclass = GDK_INPUT_OUTPUT;
301 attributes.visual = gtk_widget_get_visual(widget);
Bram Moolenaar98921892016-02-23 17:14:37 +0100302#if GTK_CHECK_VERSION(3,0,0)
303 attributes.event_mask = GDK_EXPOSURE_MASK;
304#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000305 attributes.colormap = gtk_widget_get_colormap(widget);
306 attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK;
Bram Moolenaar98921892016-02-23 17:14:37 +0100307#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000308
Bram Moolenaar98921892016-02-23 17:14:37 +0100309#if GTK_CHECK_VERSION(3,0,0)
310 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
311#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000312 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
Bram Moolenaar98921892016-02-23 17:14:37 +0100313#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000314
Bram Moolenaar98921892016-02-23 17:14:37 +0100315 gtk_widget_set_window(widget,
316 gdk_window_new(gtk_widget_get_parent_window(widget),
317 &attributes, attributes_mask));
Bram Moolenaar25328e32018-09-11 21:30:09 +0200318 gdk_window_set_user_data(gtk_widget_get_window(widget), widget);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000319
320 attributes.x = 0;
321 attributes.y = 0;
322 attributes.event_mask = gtk_widget_get_events(widget);
323
Bram Moolenaar98921892016-02-23 17:14:37 +0100324 form->bin_window = gdk_window_new(gtk_widget_get_window(widget),
325 &attributes, attributes_mask);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000326 gdk_window_set_user_data(form->bin_window, widget);
327
Bram Moolenaar98921892016-02-23 17:14:37 +0100328#if GTK_CHECK_VERSION(3,0,0)
329 {
330 GtkStyleContext * const sctx = gtk_widget_get_style_context(widget);
331
332 gtk_style_context_add_class(sctx, "gtk-form");
333 gtk_style_context_set_state(sctx, GTK_STATE_FLAG_NORMAL);
334# if !GTK_CHECK_VERSION(3,18,0)
335 gtk_style_context_set_background(sctx, gtk_widget_get_window(widget));
336 gtk_style_context_set_background(sctx, form->bin_window);
337# endif
338 }
339#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000340 widget->style = gtk_style_attach(widget->style, widget->window);
341 gtk_style_set_background(widget->style, widget->window, GTK_STATE_NORMAL);
342 gtk_style_set_background(widget->style, form->bin_window, GTK_STATE_NORMAL);
Bram Moolenaar98921892016-02-23 17:14:37 +0100343#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000344
Bram Moolenaar071d4272004-06-13 20:20:40 +0000345 for (tmp_list = form->children; tmp_list; tmp_list = tmp_list->next)
346 {
347 GtkFormChild *child = tmp_list->data;
348
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200349 form_attach_child_window(form, child);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000350
Bram Moolenaar98921892016-02-23 17:14:37 +0100351 if (gtk_widget_get_visible(child->widget))
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200352 form_realize_child(form, child);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000353 }
354}
355
356
Bram Moolenaar30613902019-12-01 22:11:18 +0100357// After reading the documentation at
358// http://developer.gnome.org/doc/API/2.0/gtk/gtk-changes-2-0.html
359// I think it should be possible to remove this function when compiling
360// against gtk-2.0. It doesn't seem to cause problems, though.
361//
362// Well, I reckon at least the gdk_window_show(form->bin_window)
363// is necessary. GtkForm is anything but a usual container widget.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000364 static void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200365form_map(GtkWidget *widget)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000366{
367 GList *tmp_list;
368 GtkForm *form;
369
370 g_return_if_fail(GTK_IS_FORM(widget));
371
372 form = GTK_FORM(widget);
373
Bram Moolenaar98921892016-02-23 17:14:37 +0100374 gtk_widget_set_mapped(widget, TRUE);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000375
Bram Moolenaar98921892016-02-23 17:14:37 +0100376 gdk_window_show(gtk_widget_get_window(widget));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000377 gdk_window_show(form->bin_window);
378
379 for (tmp_list = form->children; tmp_list; tmp_list = tmp_list->next)
380 {
381 GtkFormChild *child = tmp_list->data;
382
Bram Moolenaar98921892016-02-23 17:14:37 +0100383 if (gtk_widget_get_visible(child->widget)
384 && !gtk_widget_get_mapped(child->widget))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000385 gtk_widget_map(child->widget);
386 }
387}
388
389 static void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200390form_unrealize(GtkWidget *widget)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000391{
392 GList *tmp_list;
393 GtkForm *form;
394
395 g_return_if_fail(GTK_IS_FORM(widget));
396
397 form = GTK_FORM(widget);
398
399 tmp_list = form->children;
400
401 gdk_window_set_user_data(form->bin_window, NULL);
402 gdk_window_destroy(form->bin_window);
403 form->bin_window = NULL;
404
405 while (tmp_list)
406 {
407 GtkFormChild *child = tmp_list->data;
408
409 if (child->window != NULL)
410 {
Bram Moolenaar98921892016-02-23 17:14:37 +0100411 g_signal_handlers_disconnect_by_func(G_OBJECT(child->widget),
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200412 FUNC2GENERIC(form_child_map),
Bram Moolenaar98921892016-02-23 17:14:37 +0100413 child);
414 g_signal_handlers_disconnect_by_func(G_OBJECT(child->widget),
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200415 FUNC2GENERIC(form_child_unmap),
Bram Moolenaar98921892016-02-23 17:14:37 +0100416 child);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000417
418 gdk_window_set_user_data(child->window, NULL);
419 gdk_window_destroy(child->window);
420
421 child->window = NULL;
422 }
423
424 tmp_list = tmp_list->next;
425 }
426
Bram Moolenaar98921892016-02-23 17:14:37 +0100427#if GTK_CHECK_VERSION(3,0,0)
Bram Moolenaar692d1a52020-10-21 17:28:27 +0200428 if (GTK_WIDGET_CLASS (gui_gtk_form_parent_class)->unrealize)
429 (* GTK_WIDGET_CLASS (gui_gtk_form_parent_class)->unrealize) (widget);
Bram Moolenaar98921892016-02-23 17:14:37 +0100430#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000431 if (GTK_WIDGET_CLASS (parent_class)->unrealize)
432 (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
Bram Moolenaar98921892016-02-23 17:14:37 +0100433#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000434}
435
Bram Moolenaar071d4272004-06-13 20:20:40 +0000436 static void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200437form_size_request(GtkWidget *widget, GtkRequisition *requisition)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000438{
Bram Moolenaar071d4272004-06-13 20:20:40 +0000439 g_return_if_fail(GTK_IS_FORM(widget));
Bram Moolenaar99a6e8d2017-03-29 18:07:40 +0200440 g_return_if_fail(requisition != NULL);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000441
Bram Moolenaar98921892016-02-23 17:14:37 +0100442 requisition->width = 1;
443 requisition->height = 1;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000444}
445
Bram Moolenaar98921892016-02-23 17:14:37 +0100446#if GTK_CHECK_VERSION(3,0,0)
447 static void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200448form_get_preferred_width(GtkWidget *widget,
Bram Moolenaar98921892016-02-23 17:14:37 +0100449 gint *minimal_width,
450 gint *natural_width)
451{
452 GtkRequisition requisition;
453
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200454 form_size_request(widget, &requisition);
Bram Moolenaar98921892016-02-23 17:14:37 +0100455
456 *minimal_width = requisition.width;
457 *natural_width = requisition.width;
458}
459
460 static void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200461form_get_preferred_height(GtkWidget *widget,
Bram Moolenaar98921892016-02-23 17:14:37 +0100462 gint *minimal_height,
463 gint *natural_height)
464{
465 GtkRequisition requisition;
466
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200467 form_size_request(widget, &requisition);
Bram Moolenaar98921892016-02-23 17:14:37 +0100468
469 *minimal_height = requisition.height;
470 *natural_height = requisition.height;
471}
Bram Moolenaar30613902019-12-01 22:11:18 +0100472#endif // GTK_CHECK_VERSION(3,0,0)
Bram Moolenaar98921892016-02-23 17:14:37 +0100473
Bram Moolenaar071d4272004-06-13 20:20:40 +0000474 static void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200475form_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000476{
477 GList *tmp_list;
478 GtkForm *form;
479 gboolean need_reposition;
Bram Moolenaar98921892016-02-23 17:14:37 +0100480 GtkAllocation cur_alloc;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000481
482 g_return_if_fail(GTK_IS_FORM(widget));
483
Bram Moolenaar98921892016-02-23 17:14:37 +0100484 gtk_widget_get_allocation(widget, &cur_alloc);
485
486 if (cur_alloc.x == allocation->x
487 && cur_alloc.y == allocation->y
488 && cur_alloc.width == allocation->width
489 && cur_alloc.height == allocation->height)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000490 return;
491
Bram Moolenaar98921892016-02-23 17:14:37 +0100492 need_reposition = cur_alloc.width != allocation->width
493 || cur_alloc.height != allocation->height;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000494 form = GTK_FORM(widget);
495
496 if (need_reposition)
497 {
498 tmp_list = form->children;
499
500 while (tmp_list)
501 {
502 GtkFormChild *child = tmp_list->data;
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200503 form_position_child(form, child, TRUE);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000504
505 tmp_list = tmp_list->next;
506 }
507 }
508
Bram Moolenaar98921892016-02-23 17:14:37 +0100509 if (gtk_widget_get_realized(widget))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000510 {
Bram Moolenaar98921892016-02-23 17:14:37 +0100511 gdk_window_move_resize(gtk_widget_get_window(widget),
512 allocation->x, allocation->y,
513 allocation->width, allocation->height);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000514 gdk_window_move_resize(GTK_FORM(widget)->bin_window,
515 0, 0,
516 allocation->width, allocation->height);
517 }
Bram Moolenaar98921892016-02-23 17:14:37 +0100518 gtk_widget_set_allocation(widget, allocation);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000519 if (need_reposition)
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200520 form_send_configure(form);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000521}
522
Bram Moolenaar98921892016-02-23 17:14:37 +0100523#if GTK_CHECK_VERSION(3,0,0)
524 static void
525gtk_form_render_background(GtkWidget *widget, cairo_t *cr)
526{
527 gtk_render_background(gtk_widget_get_style_context(widget), cr,
528 0, 0,
529 gtk_widget_get_allocated_width(widget),
530 gtk_widget_get_allocated_height(widget));
531}
532
533 static gboolean
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200534form_draw(GtkWidget *widget, cairo_t *cr)
Bram Moolenaar98921892016-02-23 17:14:37 +0100535{
536 GList *tmp_list = NULL;
537 GtkForm *form = NULL;
538
539 g_return_val_if_fail(GTK_IS_FORM(widget), FALSE);
540
541 gtk_form_render_background(widget, cr);
542
543 form = GTK_FORM(widget);
544 for (tmp_list = form->children; tmp_list; tmp_list = tmp_list->next)
545 {
546 GtkFormChild * const formchild = tmp_list->data;
547
548 if (!gtk_widget_get_has_window(formchild->widget) &&
549 gtk_cairo_should_draw_window(cr, formchild->window))
550 {
Bram Moolenaar30613902019-12-01 22:11:18 +0100551 // To get gtk_widget_draw() to work, it is required to call
552 // gtk_widget_size_allocate() in advance with a well-posed
553 // allocation for a given child widget in order to set a
554 // certain private GtkWidget variable, called
555 // widget->priv->alloc_need, to the proper value; otherwise,
556 // gtk_widget_draw() fails and the relevant scrollbar won't
557 // appear on the screen.
558 //
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200559 // Calling form_position_child() like this is one of ways
Bram Moolenaar30613902019-12-01 22:11:18 +0100560 // to make sure of that.
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200561 form_position_child(form, formchild, TRUE);
Bram Moolenaar98921892016-02-23 17:14:37 +0100562
563 gtk_form_render_background(formchild->widget, cr);
564 }
565 }
566
Bram Moolenaar692d1a52020-10-21 17:28:27 +0200567 return GTK_WIDGET_CLASS(gui_gtk_form_parent_class)->draw(widget, cr);
Bram Moolenaar98921892016-02-23 17:14:37 +0100568}
Bram Moolenaar30613902019-12-01 22:11:18 +0100569#else // !GTK_CHECK_VERSION(3,0,0)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000570 static gint
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200571form_expose(GtkWidget *widget, GdkEventExpose *event)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000572{
573 GList *tmp_list;
574 GtkForm *form;
575
576 g_return_val_if_fail(GTK_IS_FORM(widget), FALSE);
577
578 form = GTK_FORM(widget);
579
580 if (event->window == form->bin_window)
581 return FALSE;
582
583 for (tmp_list = form->children; tmp_list; tmp_list = tmp_list->next)
Bram Moolenaar99a6e8d2017-03-29 18:07:40 +0200584 gtk_container_propagate_expose(GTK_CONTAINER(widget),
585 GTK_WIDGET(((GtkFormChild *)tmp_list->data)->widget),
586 event);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000587
588 return FALSE;
589}
Bram Moolenaar30613902019-12-01 22:11:18 +0100590#endif // !GTK_CHECK_VERSION(3,0,0)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000591
Bram Moolenaar30613902019-12-01 22:11:18 +0100592// Container method
Bram Moolenaar071d4272004-06-13 20:20:40 +0000593 static void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200594form_remove(GtkContainer *container, GtkWidget *widget)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000595{
596 GList *tmp_list;
597 GtkForm *form;
Bram Moolenaar30613902019-12-01 22:11:18 +0100598 GtkFormChild *child = NULL; // init for gcc
Bram Moolenaar071d4272004-06-13 20:20:40 +0000599
600 g_return_if_fail(GTK_IS_FORM(container));
601
602 form = GTK_FORM(container);
603
604 tmp_list = form->children;
605 while (tmp_list)
606 {
607 child = tmp_list->data;
608 if (child->widget == widget)
609 break;
610 tmp_list = tmp_list->next;
611 }
612
613 if (tmp_list)
614 {
Bram Moolenaar98921892016-02-23 17:14:37 +0100615#if GTK_CHECK_VERSION(3,0,0)
616 const gboolean was_visible = gtk_widget_get_visible(widget);
617#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000618 if (child->window)
619 {
Bram Moolenaar98921892016-02-23 17:14:37 +0100620 g_signal_handlers_disconnect_by_func(G_OBJECT(child->widget),
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200621 FUNC2GENERIC(&form_child_map), child);
Bram Moolenaar98921892016-02-23 17:14:37 +0100622 g_signal_handlers_disconnect_by_func(G_OBJECT(child->widget),
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200623 FUNC2GENERIC(&form_child_unmap), child);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000624
Bram Moolenaar30613902019-12-01 22:11:18 +0100625 // FIXME: This will cause problems for reparenting NO_WINDOW
626 // widgets out of a GtkForm
Bram Moolenaar071d4272004-06-13 20:20:40 +0000627 gdk_window_set_user_data(child->window, NULL);
628 gdk_window_destroy(child->window);
629 }
630 gtk_widget_unparent(widget);
Bram Moolenaar98921892016-02-23 17:14:37 +0100631#if GTK_CHECK_VERSION(3,0,0)
632 if (was_visible)
633 gtk_widget_queue_resize(GTK_WIDGET(container));
634#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000635 form->children = g_list_remove_link(form->children, tmp_list);
636 g_list_free_1(tmp_list);
637 g_free(child);
638 }
639}
640
Bram Moolenaar071d4272004-06-13 20:20:40 +0000641 static void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200642form_forall(GtkContainer *container,
Bram Moolenaarb85cb212009-05-17 14:24:23 +0000643 gboolean include_internals UNUSED,
Bram Moolenaar071d4272004-06-13 20:20:40 +0000644 GtkCallback callback,
645 gpointer callback_data)
646{
647 GtkForm *form;
648 GtkFormChild *child;
649 GList *tmp_list;
650
651 g_return_if_fail(GTK_IS_FORM(container));
652 g_return_if_fail(callback != NULL);
653
654 form = GTK_FORM(container);
655
656 tmp_list = form->children;
657 while (tmp_list)
658 {
659 child = tmp_list->data;
660 tmp_list = tmp_list->next;
661
662 (*callback) (child->widget, callback_data);
663 }
664}
665
Bram Moolenaar30613902019-12-01 22:11:18 +0100666// Operations on children
Bram Moolenaar071d4272004-06-13 20:20:40 +0000667
668 static void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200669form_attach_child_window(GtkForm *form, GtkFormChild *child)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000670{
671 if (child->window != NULL)
Bram Moolenaar30613902019-12-01 22:11:18 +0100672 return; // been there, done that
Bram Moolenaar071d4272004-06-13 20:20:40 +0000673
Bram Moolenaar98921892016-02-23 17:14:37 +0100674 if (!gtk_widget_get_has_window(child->widget))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000675 {
676 GtkWidget *widget;
677 GdkWindowAttr attributes;
678 gint attributes_mask;
Bram Moolenaar664323e2018-09-18 22:30:07 +0200679 GtkRequisition requisition;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000680
681 widget = GTK_WIDGET(form);
682
Bram Moolenaar664323e2018-09-18 22:30:07 +0200683#if GTK_CHECK_VERSION(3,0,0)
684 gtk_widget_get_preferred_size(child->widget, &requisition, NULL);
685#else
686 requisition = child->widget->requisition;
687#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000688 attributes.window_type = GDK_WINDOW_CHILD;
689 attributes.x = child->x;
690 attributes.y = child->y;
Bram Moolenaar664323e2018-09-18 22:30:07 +0200691 attributes.width = requisition.width;
692 attributes.height = requisition.height;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000693 attributes.wclass = GDK_INPUT_OUTPUT;
694 attributes.visual = gtk_widget_get_visual(widget);
Bram Moolenaar98921892016-02-23 17:14:37 +0100695#if !GTK_CHECK_VERSION(3,0,0)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000696 attributes.colormap = gtk_widget_get_colormap(widget);
Bram Moolenaar98921892016-02-23 17:14:37 +0100697#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000698 attributes.event_mask = GDK_EXPOSURE_MASK;
699
Bram Moolenaar98921892016-02-23 17:14:37 +0100700#if GTK_CHECK_VERSION(3,0,0)
701 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
702#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000703 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
Bram Moolenaar98921892016-02-23 17:14:37 +0100704#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000705 child->window = gdk_window_new(form->bin_window,
706 &attributes, attributes_mask);
707 gdk_window_set_user_data(child->window, widget);
708
Bram Moolenaar98921892016-02-23 17:14:37 +0100709#if GTK_CHECK_VERSION(3,0,0)
710 {
711 GtkStyleContext * const sctx = gtk_widget_get_style_context(widget);
712
713 gtk_style_context_set_state(sctx, GTK_STATE_FLAG_NORMAL);
714# if !GTK_CHECK_VERSION(3,18,0)
715 gtk_style_context_set_background(sctx, child->window);
716# endif
717 }
718#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000719 gtk_style_set_background(widget->style,
720 child->window,
721 GTK_STATE_NORMAL);
Bram Moolenaar98921892016-02-23 17:14:37 +0100722#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000723
724 gtk_widget_set_parent_window(child->widget, child->window);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000725 /*
726 * Install signal handlers to map/unmap child->window
727 * alongside with the actual widget.
728 */
Bram Moolenaar98921892016-02-23 17:14:37 +0100729 g_signal_connect(G_OBJECT(child->widget), "map",
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200730 G_CALLBACK(&form_child_map), child);
Bram Moolenaar98921892016-02-23 17:14:37 +0100731 g_signal_connect(G_OBJECT(child->widget), "unmap",
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200732 G_CALLBACK(&form_child_unmap), child);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000733 }
Bram Moolenaar98921892016-02-23 17:14:37 +0100734 else if (!gtk_widget_get_realized(child->widget))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000735 {
736 gtk_widget_set_parent_window(child->widget, form->bin_window);
737 }
738}
739
740 static void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200741form_realize_child(GtkForm *form, GtkFormChild *child)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000742{
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200743 form_attach_child_window(form, child);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000744 gtk_widget_realize(child->widget);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000745}
746
747 static void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200748form_position_child(GtkForm *form, GtkFormChild *child, gboolean force_allocate)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000749{
750 gint x;
751 gint y;
752
753 x = child->x;
754 y = child->y;
755
756 if ((x >= G_MINSHORT) && (x <= G_MAXSHORT) &&
757 (y >= G_MINSHORT) && (y <= G_MAXSHORT))
758 {
759 if (!child->mapped)
760 {
Bram Moolenaar98921892016-02-23 17:14:37 +0100761 if (gtk_widget_get_mapped(GTK_WIDGET(form))
762 && gtk_widget_get_visible(child->widget))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000763 {
Bram Moolenaar98921892016-02-23 17:14:37 +0100764 if (!gtk_widget_get_mapped(child->widget))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000765 gtk_widget_map(child->widget);
766
767 child->mapped = TRUE;
768 force_allocate = TRUE;
769 }
770 }
771
772 if (force_allocate)
773 {
774 GtkAllocation allocation;
Bram Moolenaar98921892016-02-23 17:14:37 +0100775 GtkRequisition requisition;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000776
Bram Moolenaar664323e2018-09-18 22:30:07 +0200777#if GTK_CHECK_VERSION(3,0,0)
Bram Moolenaar98921892016-02-23 17:14:37 +0100778 gtk_widget_get_preferred_size(child->widget, &requisition, NULL);
Bram Moolenaar664323e2018-09-18 22:30:07 +0200779#else
780 requisition = child->widget->requisition;
Bram Moolenaar98921892016-02-23 17:14:37 +0100781#endif
782
Bram Moolenaar98921892016-02-23 17:14:37 +0100783 if (!gtk_widget_get_has_window(child->widget))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000784 {
785 if (child->window)
786 {
Bram Moolenaar98921892016-02-23 17:14:37 +0100787 gdk_window_move_resize(child->window,
788 x, y,
789 requisition.width,
790 requisition.height);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000791 }
792
793 allocation.x = 0;
794 allocation.y = 0;
795 }
796 else
797 {
798 allocation.x = x;
799 allocation.y = y;
800 }
801
Bram Moolenaar98921892016-02-23 17:14:37 +0100802 allocation.width = requisition.width;
803 allocation.height = requisition.height;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000804
805 gtk_widget_size_allocate(child->widget, &allocation);
806 }
807 }
808 else
809 {
810 if (child->mapped)
811 {
812 child->mapped = FALSE;
813
Bram Moolenaar98921892016-02-23 17:14:37 +0100814 if (gtk_widget_get_mapped(child->widget))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000815 gtk_widget_unmap(child->widget);
816 }
817 }
818}
819
820 static void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200821form_position_children(GtkForm *form)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000822{
823 GList *tmp_list;
824
825 for (tmp_list = form->children; tmp_list; tmp_list = tmp_list->next)
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200826 form_position_child(form, tmp_list->data, FALSE);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000827}
828
Bram Moolenaar071d4272004-06-13 20:20:40 +0000829 void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200830gui_gtk_form_move_resize(GtkForm *form, GtkWidget *widget,
Bram Moolenaar071d4272004-06-13 20:20:40 +0000831 gint x, gint y, gint w, gint h)
832{
Bram Moolenaar98921892016-02-23 17:14:37 +0100833#if GTK_CHECK_VERSION(3,0,0)
834 gtk_widget_set_size_request(widget, w, h);
835#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000836 widget->requisition.width = w;
837 widget->requisition.height = h;
Bram Moolenaar98921892016-02-23 17:14:37 +0100838#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000839
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200840 gui_gtk_form_move(form, widget, x, y);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000841}
842
843 static void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200844form_send_configure(GtkForm *form)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000845{
846 GtkWidget *widget;
847 GdkEventConfigure event;
Bram Moolenaar664323e2018-09-18 22:30:07 +0200848 GtkAllocation allocation;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000849
850 widget = GTK_WIDGET(form);
851
Bram Moolenaar664323e2018-09-18 22:30:07 +0200852 gtk_widget_get_allocation(widget, &allocation);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000853 event.type = GDK_CONFIGURE;
Bram Moolenaar98921892016-02-23 17:14:37 +0100854 event.window = gtk_widget_get_window(widget);
Bram Moolenaar664323e2018-09-18 22:30:07 +0200855 event.x = allocation.x;
856 event.y = allocation.y;
857 event.width = allocation.width;
858 event.height = allocation.height;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000859
Bram Moolenaar071d4272004-06-13 20:20:40 +0000860 gtk_main_do_event((GdkEvent*)&event);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000861}
862
Bram Moolenaar071d4272004-06-13 20:20:40 +0000863 static void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200864form_child_map(GtkWidget *widget UNUSED, gpointer user_data)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000865{
866 GtkFormChild *child;
867
868 child = (GtkFormChild *)user_data;
869
870 child->mapped = TRUE;
871 gdk_window_show(child->window);
872}
873
Bram Moolenaar071d4272004-06-13 20:20:40 +0000874 static void
Bram Moolenaar8a99e662020-10-21 16:10:21 +0200875form_child_unmap(GtkWidget *widget UNUSED, gpointer user_data)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000876{
877 GtkFormChild *child;
878
879 child = (GtkFormChild *)user_data;
880
881 child->mapped = FALSE;
882 gdk_window_hide(child->window);
883}