blob: 287a87e4984a5d4c0f794c6db5fcf5d8cddd1e87 [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:
14 *
15 * (C) 2002,2003 Jason Hildebrand <jason@peaceworks.ca>
16 * Daniel Elstner <daniel.elstner@gmx.net>
17 *
Bram Moolenaar933eb392007-05-10 17:52:45 +000018 * This is a special purpose container widget, which manages arbitrary
19 * children at arbitrary positions width arbitrary sizes. This finally puts
20 * an end on our resize problems with which we where struggling for such a
21 * long time.
Bram Moolenaar98921892016-02-23 17:14:37 +010022 *
23 * Support for GTK+ 3 was added by:
24 *
25 * 2016 Kazunobu Kuriyama <kazunobu.kuriyama@gmail.com>
Bram Moolenaar071d4272004-06-13 20:20:40 +000026 */
27
28#include "vim.h"
29#include <gtk/gtk.h> /* without this it compiles, but gives errors at
30 runtime! */
31#include "gui_gtk_f.h"
Bram Moolenaar98921892016-02-23 17:14:37 +010032#if !GTK_CHECK_VERSION(3,0,0)
33# include <gtk/gtksignal.h>
34#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +000035#ifdef WIN3264
36# include <gdk/gdkwin32.h>
37#else
38# include <gdk/gdkx.h>
39#endif
40
41typedef struct _GtkFormChild GtkFormChild;
42
43struct _GtkFormChild
44{
45 GtkWidget *widget;
46 GdkWindow *window;
47 gint x; /* relative subwidget x position */
48 gint y; /* relative subwidget y position */
49 gint mapped;
50};
51
52
53static void gtk_form_class_init(GtkFormClass *klass);
54static void gtk_form_init(GtkForm *form);
55
56static void gtk_form_realize(GtkWidget *widget);
57static void gtk_form_unrealize(GtkWidget *widget);
58static void gtk_form_map(GtkWidget *widget);
59static void gtk_form_size_request(GtkWidget *widget,
60 GtkRequisition *requisition);
Bram Moolenaar98921892016-02-23 17:14:37 +010061#if GTK_CHECK_VERSION(3,0,0)
62static void gtk_form_get_preferred_width(GtkWidget *widget,
63 gint *minimal_width,
64 gint *natural_width);
65static void gtk_form_get_preferred_height(GtkWidget *widget,
66 gint *minimal_height,
67 gint *natural_height);
68#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +000069static void gtk_form_size_allocate(GtkWidget *widget,
70 GtkAllocation *allocation);
Bram Moolenaar98921892016-02-23 17:14:37 +010071#if GTK_CHECK_VERSION(3,0,0)
72static gboolean gtk_form_draw(GtkWidget *widget,
73 cairo_t *cr);
74#else
Bram Moolenaar071d4272004-06-13 20:20:40 +000075static gint gtk_form_expose(GtkWidget *widget,
76 GdkEventExpose *event);
Bram Moolenaar98921892016-02-23 17:14:37 +010077#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +000078
79static void gtk_form_remove(GtkContainer *container,
80 GtkWidget *widget);
81static void gtk_form_forall(GtkContainer *container,
82 gboolean include_internals,
83 GtkCallback callback,
84 gpointer callback_data);
85
86static void gtk_form_attach_child_window(GtkForm *form,
87 GtkFormChild *child);
88static void gtk_form_realize_child(GtkForm *form,
89 GtkFormChild *child);
90static void gtk_form_position_child(GtkForm *form,
91 GtkFormChild *child,
92 gboolean force_allocate);
93static void gtk_form_position_children(GtkForm *form);
94
Bram Moolenaar98921892016-02-23 17:14:37 +010095#if !GTK_CHECK_VERSION(3,16,0)
Bram Moolenaar071d4272004-06-13 20:20:40 +000096static void gtk_form_set_static_gravity(GdkWindow *window,
97 gboolean use_static);
Bram Moolenaar98921892016-02-23 17:14:37 +010098#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +000099
100static void gtk_form_send_configure(GtkForm *form);
101
102static void gtk_form_child_map(GtkWidget *widget, gpointer user_data);
103static void gtk_form_child_unmap(GtkWidget *widget, gpointer user_data);
104
Bram Moolenaar98921892016-02-23 17:14:37 +0100105#if !GTK_CHECK_VERSION(3,0,0)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000106static GtkWidgetClass *parent_class = NULL;
Bram Moolenaar98921892016-02-23 17:14:37 +0100107#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000108
109/* Public interface
110 */
111
112 GtkWidget *
113gtk_form_new(void)
114{
115 GtkForm *form;
116
Bram Moolenaar98921892016-02-23 17:14:37 +0100117#if GTK_CHECK_VERSION(3,0,0)
118 form = g_object_new(GTK_TYPE_FORM, NULL);
119#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000120 form = gtk_type_new(gtk_form_get_type());
Bram Moolenaar98921892016-02-23 17:14:37 +0100121#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000122
123 return GTK_WIDGET(form);
124}
125
126 void
127gtk_form_put(GtkForm *form,
128 GtkWidget *child_widget,
129 gint x,
130 gint y)
131{
132 GtkFormChild *child;
133
134 g_return_if_fail(GTK_IS_FORM(form));
135
Bram Moolenaar9d75c832005-01-25 21:57:23 +0000136 /* LINTED: avoid warning: conversion to 'unsigned long' */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000137 child = g_new(GtkFormChild, 1);
138
139 child->widget = child_widget;
140 child->window = NULL;
141 child->x = x;
142 child->y = y;
Bram Moolenaar98921892016-02-23 17:14:37 +0100143#if GTK_CHECK_VERSION(3,0,0)
144 gtk_widget_set_size_request(child->widget, -1, -1);
145#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000146 child->widget->requisition.width = 0;
147 child->widget->requisition.height = 0;
Bram Moolenaar98921892016-02-23 17:14:37 +0100148#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000149 child->mapped = FALSE;
150
151 form->children = g_list_append(form->children, child);
152
153 /* child->window must be created and attached to the widget _before_
154 * it has been realized, or else things will break with GTK2. Note
155 * that gtk_widget_set_parent() realizes the widget if it's visible
156 * and its parent is mapped.
157 */
Bram Moolenaar98921892016-02-23 17:14:37 +0100158#if GTK_CHECK_VERSION(3,0,0)
159 if (gtk_widget_get_realized(GTK_WIDGET(form)))
160#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000161 if (GTK_WIDGET_REALIZED(form))
Bram Moolenaar98921892016-02-23 17:14:37 +0100162#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000163 gtk_form_attach_child_window(form, child);
164
165 gtk_widget_set_parent(child_widget, GTK_WIDGET(form));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000166
Bram Moolenaar98921892016-02-23 17:14:37 +0100167#if GTK_CHECK_VERSION(3,0,0)
168 if (gtk_widget_get_realized(GTK_WIDGET(form))
169 && !gtk_widget_get_realized(child_widget))
170#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000171 if (GTK_WIDGET_REALIZED(form) && !GTK_WIDGET_REALIZED(child_widget))
Bram Moolenaar98921892016-02-23 17:14:37 +0100172#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000173 gtk_form_realize_child(form, child);
174
175 gtk_form_position_child(form, child, TRUE);
176}
177
178 void
179gtk_form_move(GtkForm *form,
180 GtkWidget *child_widget,
181 gint x,
182 gint y)
183{
184 GList *tmp_list;
185 GtkFormChild *child;
186
187 g_return_if_fail(GTK_IS_FORM(form));
188
189 for (tmp_list = form->children; tmp_list; tmp_list = tmp_list->next)
190 {
191 child = tmp_list->data;
192 if (child->widget == child_widget)
193 {
194 child->x = x;
195 child->y = y;
196
197 gtk_form_position_child(form, child, TRUE);
198 return;
199 }
200 }
201}
202
Bram Moolenaar071d4272004-06-13 20:20:40 +0000203 void
204gtk_form_freeze(GtkForm *form)
205{
206 g_return_if_fail(GTK_IS_FORM(form));
207
208 ++form->freeze_count;
209}
210
211 void
212gtk_form_thaw(GtkForm *form)
213{
214 g_return_if_fail(GTK_IS_FORM(form));
215
216 if (form->freeze_count)
217 {
218 if (!(--form->freeze_count))
219 {
220 gtk_form_position_children(form);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000221 gtk_widget_queue_draw(GTK_WIDGET(form));
Bram Moolenaar071d4272004-06-13 20:20:40 +0000222 }
223 }
224}
225
226/* Basic Object handling procedures
227 */
Bram Moolenaar98921892016-02-23 17:14:37 +0100228#if GTK_CHECK_VERSION(3,0,0)
229G_DEFINE_TYPE(GtkForm, gtk_form, GTK_TYPE_CONTAINER)
230#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000231 GtkType
232gtk_form_get_type(void)
233{
234 static GtkType form_type = 0;
235
236 if (!form_type)
237 {
Bram Moolenaarb85cb212009-05-17 14:24:23 +0000238 GtkTypeInfo form_info;
239
Bram Moolenaara9d45512009-05-17 21:25:42 +0000240 vim_memset(&form_info, 0, sizeof(form_info));
Bram Moolenaarb85cb212009-05-17 14:24:23 +0000241 form_info.type_name = "GtkForm";
242 form_info.object_size = sizeof(GtkForm);
243 form_info.class_size = sizeof(GtkFormClass);
244 form_info.class_init_func = (GtkClassInitFunc)gtk_form_class_init;
245 form_info.object_init_func = (GtkObjectInitFunc)gtk_form_init;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000246
247 form_type = gtk_type_unique(GTK_TYPE_CONTAINER, &form_info);
248 }
249 return form_type;
250}
Bram Moolenaar98921892016-02-23 17:14:37 +0100251#endif /* !GTK_CHECK_VERSION(3,0,0) */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000252
253 static void
254gtk_form_class_init(GtkFormClass *klass)
255{
256 GtkWidgetClass *widget_class;
257 GtkContainerClass *container_class;
258
259 widget_class = (GtkWidgetClass *) klass;
260 container_class = (GtkContainerClass *) klass;
261
Bram Moolenaar98921892016-02-23 17:14:37 +0100262#if !GTK_CHECK_VERSION(3,0,0)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000263 parent_class = gtk_type_class(gtk_container_get_type());
Bram Moolenaar98921892016-02-23 17:14:37 +0100264#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000265
266 widget_class->realize = gtk_form_realize;
267 widget_class->unrealize = gtk_form_unrealize;
268 widget_class->map = gtk_form_map;
Bram Moolenaar98921892016-02-23 17:14:37 +0100269#if GTK_CHECK_VERSION(3,0,0)
270 widget_class->get_preferred_width = gtk_form_get_preferred_width;
271 widget_class->get_preferred_height = gtk_form_get_preferred_height;
272#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000273 widget_class->size_request = gtk_form_size_request;
Bram Moolenaar98921892016-02-23 17:14:37 +0100274#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000275 widget_class->size_allocate = gtk_form_size_allocate;
Bram Moolenaar98921892016-02-23 17:14:37 +0100276#if GTK_CHECK_VERSION(3,0,0)
277 widget_class->draw = gtk_form_draw;
278#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000279 widget_class->expose_event = gtk_form_expose;
Bram Moolenaar98921892016-02-23 17:14:37 +0100280#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000281
282 container_class->remove = gtk_form_remove;
283 container_class->forall = gtk_form_forall;
284}
285
286 static void
287gtk_form_init(GtkForm *form)
288{
Bram Moolenaar98921892016-02-23 17:14:37 +0100289#if GTK_CHECK_VERSION(3,0,0)
290 gtk_widget_set_has_window(GTK_WIDGET(form), TRUE);
291#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000292 form->children = NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000293 form->bin_window = NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000294 form->freeze_count = 0;
295}
296
297/*
298 * Widget methods
299 */
300
301 static void
302gtk_form_realize(GtkWidget *widget)
303{
304 GList *tmp_list;
305 GtkForm *form;
306 GdkWindowAttr attributes;
307 gint attributes_mask;
308
309 g_return_if_fail(GTK_IS_FORM(widget));
310
311 form = GTK_FORM(widget);
Bram Moolenaar98921892016-02-23 17:14:37 +0100312#if GTK_CHECK_VERSION(3,0,0)
313 gtk_widget_set_realized(widget, TRUE);
314#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000315 GTK_WIDGET_SET_FLAGS(form, GTK_REALIZED);
Bram Moolenaar98921892016-02-23 17:14:37 +0100316#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000317
318 attributes.window_type = GDK_WINDOW_CHILD;
Bram Moolenaar98921892016-02-23 17:14:37 +0100319#if GTK_CHECK_VERSION(3,0,0)
320 {
321 GtkAllocation allocation;
322 gtk_widget_get_allocation(widget, &allocation);
323 attributes.x = allocation.x;
324 attributes.y = allocation.y;
325 attributes.width = allocation.width;
326 attributes.height = allocation.height;
327 }
328#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000329 attributes.x = widget->allocation.x;
330 attributes.y = widget->allocation.y;
331 attributes.width = widget->allocation.width;
332 attributes.height = widget->allocation.height;
Bram Moolenaar98921892016-02-23 17:14:37 +0100333#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000334 attributes.wclass = GDK_INPUT_OUTPUT;
335 attributes.visual = gtk_widget_get_visual(widget);
Bram Moolenaar98921892016-02-23 17:14:37 +0100336#if GTK_CHECK_VERSION(3,0,0)
337 attributes.event_mask = GDK_EXPOSURE_MASK;
338#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000339 attributes.colormap = gtk_widget_get_colormap(widget);
340 attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK;
Bram Moolenaar98921892016-02-23 17:14:37 +0100341#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000342
Bram Moolenaar98921892016-02-23 17:14:37 +0100343#if GTK_CHECK_VERSION(3,0,0)
344 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
345#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000346 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
Bram Moolenaar98921892016-02-23 17:14:37 +0100347#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000348
Bram Moolenaar98921892016-02-23 17:14:37 +0100349#if GTK_CHECK_VERSION(3,0,0)
350 gtk_widget_set_window(widget,
351 gdk_window_new(gtk_widget_get_parent_window(widget),
352 &attributes, attributes_mask));
353 gdk_window_set_user_data(gtk_widget_get_window(widget), widget);
354#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000355 widget->window = gdk_window_new(gtk_widget_get_parent_window(widget),
356 &attributes, attributes_mask);
357 gdk_window_set_user_data(widget->window, widget);
Bram Moolenaar98921892016-02-23 17:14:37 +0100358#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000359
360 attributes.x = 0;
361 attributes.y = 0;
362 attributes.event_mask = gtk_widget_get_events(widget);
363
Bram Moolenaar98921892016-02-23 17:14:37 +0100364#if GTK_CHECK_VERSION(3,0,0)
365 form->bin_window = gdk_window_new(gtk_widget_get_window(widget),
366 &attributes, attributes_mask);
367#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000368 form->bin_window = gdk_window_new(widget->window,
369 &attributes, attributes_mask);
Bram Moolenaar98921892016-02-23 17:14:37 +0100370#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000371 gdk_window_set_user_data(form->bin_window, widget);
372
Bram Moolenaar98921892016-02-23 17:14:37 +0100373#if !GTK_CHECK_VERSION(3,16,0)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000374 gtk_form_set_static_gravity(form->bin_window, TRUE);
Bram Moolenaar98921892016-02-23 17:14:37 +0100375#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000376
Bram Moolenaar98921892016-02-23 17:14:37 +0100377#if GTK_CHECK_VERSION(3,0,0)
378 {
379 GtkStyleContext * const sctx = gtk_widget_get_style_context(widget);
380
381 gtk_style_context_add_class(sctx, "gtk-form");
382 gtk_style_context_set_state(sctx, GTK_STATE_FLAG_NORMAL);
383# if !GTK_CHECK_VERSION(3,18,0)
384 gtk_style_context_set_background(sctx, gtk_widget_get_window(widget));
385 gtk_style_context_set_background(sctx, form->bin_window);
386# endif
387 }
388#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000389 widget->style = gtk_style_attach(widget->style, widget->window);
390 gtk_style_set_background(widget->style, widget->window, GTK_STATE_NORMAL);
391 gtk_style_set_background(widget->style, form->bin_window, GTK_STATE_NORMAL);
Bram Moolenaar98921892016-02-23 17:14:37 +0100392#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000393
Bram Moolenaar071d4272004-06-13 20:20:40 +0000394 for (tmp_list = form->children; tmp_list; tmp_list = tmp_list->next)
395 {
396 GtkFormChild *child = tmp_list->data;
397
398 gtk_form_attach_child_window(form, child);
399
Bram Moolenaar98921892016-02-23 17:14:37 +0100400#if GTK_CHECK_VERSION(3,0,0)
401 if (gtk_widget_get_visible(child->widget))
402#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000403 if (GTK_WIDGET_VISIBLE(child->widget))
Bram Moolenaar98921892016-02-23 17:14:37 +0100404#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000405 gtk_form_realize_child(form, child);
406 }
407}
408
409
410/* After reading the documentation at
411 * http://developer.gnome.org/doc/API/2.0/gtk/gtk-changes-2-0.html
412 * I think it should be possible to remove this function when compiling
413 * against gtk-2.0. It doesn't seem to cause problems, though.
414 *
415 * Well, I reckon at least the gdk_window_show(form->bin_window)
416 * is necessary. GtkForm is anything but a usual container widget.
417 */
418 static void
419gtk_form_map(GtkWidget *widget)
420{
421 GList *tmp_list;
422 GtkForm *form;
423
424 g_return_if_fail(GTK_IS_FORM(widget));
425
426 form = GTK_FORM(widget);
427
Bram Moolenaar98921892016-02-23 17:14:37 +0100428#if GTK_CHECK_VERSION(3,0,0)
429 gtk_widget_set_mapped(widget, TRUE);
430#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000431 GTK_WIDGET_SET_FLAGS(widget, GTK_MAPPED);
Bram Moolenaar98921892016-02-23 17:14:37 +0100432#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000433
Bram Moolenaar98921892016-02-23 17:14:37 +0100434#if GTK_CHECK_VERSION(3,0,0)
435 gdk_window_show(gtk_widget_get_window(widget));
436#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000437 gdk_window_show(widget->window);
Bram Moolenaar98921892016-02-23 17:14:37 +0100438#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000439 gdk_window_show(form->bin_window);
440
441 for (tmp_list = form->children; tmp_list; tmp_list = tmp_list->next)
442 {
443 GtkFormChild *child = tmp_list->data;
444
Bram Moolenaar98921892016-02-23 17:14:37 +0100445#if GTK_CHECK_VERSION(3,0,0)
446 if (gtk_widget_get_visible(child->widget)
447 && !gtk_widget_get_mapped(child->widget))
448#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000449 if (GTK_WIDGET_VISIBLE(child->widget)
450 && !GTK_WIDGET_MAPPED(child->widget))
Bram Moolenaar98921892016-02-23 17:14:37 +0100451#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000452 gtk_widget_map(child->widget);
453 }
454}
455
456 static void
457gtk_form_unrealize(GtkWidget *widget)
458{
459 GList *tmp_list;
460 GtkForm *form;
461
462 g_return_if_fail(GTK_IS_FORM(widget));
463
464 form = GTK_FORM(widget);
465
466 tmp_list = form->children;
467
468 gdk_window_set_user_data(form->bin_window, NULL);
469 gdk_window_destroy(form->bin_window);
470 form->bin_window = NULL;
471
472 while (tmp_list)
473 {
474 GtkFormChild *child = tmp_list->data;
475
476 if (child->window != NULL)
477 {
Bram Moolenaar98921892016-02-23 17:14:37 +0100478#if GTK_CHECK_VERSION(3,0,0)
479 g_signal_handlers_disconnect_by_func(G_OBJECT(child->widget),
Bram Moolenaard47d8372016-09-09 22:13:24 +0200480 FUNC2GENERIC(gtk_form_child_map),
Bram Moolenaar98921892016-02-23 17:14:37 +0100481 child);
482 g_signal_handlers_disconnect_by_func(G_OBJECT(child->widget),
Bram Moolenaard47d8372016-09-09 22:13:24 +0200483 FUNC2GENERIC(gtk_form_child_unmap),
Bram Moolenaar98921892016-02-23 17:14:37 +0100484 child);
485#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000486 gtk_signal_disconnect_by_func(GTK_OBJECT(child->widget),
Bram Moolenaard47d8372016-09-09 22:13:24 +0200487 GTK_SIGNAL_FUNC(gtk_form_child_map),
488 child);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000489 gtk_signal_disconnect_by_func(GTK_OBJECT(child->widget),
Bram Moolenaard47d8372016-09-09 22:13:24 +0200490 GTK_SIGNAL_FUNC(gtk_form_child_unmap),
491 child);
Bram Moolenaar98921892016-02-23 17:14:37 +0100492#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000493
494 gdk_window_set_user_data(child->window, NULL);
495 gdk_window_destroy(child->window);
496
497 child->window = NULL;
498 }
499
500 tmp_list = tmp_list->next;
501 }
502
Bram Moolenaar98921892016-02-23 17:14:37 +0100503#if GTK_CHECK_VERSION(3,0,0)
504 if (GTK_WIDGET_CLASS (gtk_form_parent_class)->unrealize)
505 (* GTK_WIDGET_CLASS (gtk_form_parent_class)->unrealize) (widget);
506#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000507 if (GTK_WIDGET_CLASS (parent_class)->unrealize)
508 (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
Bram Moolenaar98921892016-02-23 17:14:37 +0100509#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000510}
511
Bram Moolenaar071d4272004-06-13 20:20:40 +0000512 static void
513gtk_form_size_request(GtkWidget *widget, GtkRequisition *requisition)
514{
Bram Moolenaar071d4272004-06-13 20:20:40 +0000515 g_return_if_fail(GTK_IS_FORM(widget));
Bram Moolenaar99a6e8d2017-03-29 18:07:40 +0200516 g_return_if_fail(requisition != NULL);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000517
Bram Moolenaar98921892016-02-23 17:14:37 +0100518 requisition->width = 1;
519 requisition->height = 1;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000520}
521
Bram Moolenaar98921892016-02-23 17:14:37 +0100522#if GTK_CHECK_VERSION(3,0,0)
523 static void
524gtk_form_get_preferred_width(GtkWidget *widget,
525 gint *minimal_width,
526 gint *natural_width)
527{
528 GtkRequisition requisition;
529
530 gtk_form_size_request(widget, &requisition);
531
532 *minimal_width = requisition.width;
533 *natural_width = requisition.width;
534}
535
536 static void
537gtk_form_get_preferred_height(GtkWidget *widget,
538 gint *minimal_height,
539 gint *natural_height)
540{
541 GtkRequisition requisition;
542
543 gtk_form_size_request(widget, &requisition);
544
545 *minimal_height = requisition.height;
546 *natural_height = requisition.height;
547}
548#endif /* GTK_CHECK_VERSION(3,0,0) */
549
Bram Moolenaar071d4272004-06-13 20:20:40 +0000550 static void
551gtk_form_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
552{
553 GList *tmp_list;
554 GtkForm *form;
555 gboolean need_reposition;
Bram Moolenaar98921892016-02-23 17:14:37 +0100556#if GTK_CHECK_VERSION(3,0,0)
557 GtkAllocation cur_alloc;
558#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000559
560 g_return_if_fail(GTK_IS_FORM(widget));
561
Bram Moolenaar98921892016-02-23 17:14:37 +0100562#if GTK_CHECK_VERSION(3,0,0)
563 gtk_widget_get_allocation(widget, &cur_alloc);
564
565 if (cur_alloc.x == allocation->x
566 && cur_alloc.y == allocation->y
567 && cur_alloc.width == allocation->width
568 && cur_alloc.height == allocation->height)
569#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000570 if (widget->allocation.x == allocation->x
571 && widget->allocation.y == allocation->y
572 && widget->allocation.width == allocation->width
573 && widget->allocation.height == allocation->height)
Bram Moolenaar98921892016-02-23 17:14:37 +0100574#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000575 return;
576
Bram Moolenaar98921892016-02-23 17:14:37 +0100577#if GTK_CHECK_VERSION(3,0,0)
578 need_reposition = cur_alloc.width != allocation->width
579 || cur_alloc.height != allocation->height;
580#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000581 need_reposition = widget->allocation.width != allocation->width
582 || widget->allocation.height != allocation->height;
Bram Moolenaar98921892016-02-23 17:14:37 +0100583#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000584 form = GTK_FORM(widget);
585
586 if (need_reposition)
587 {
588 tmp_list = form->children;
589
590 while (tmp_list)
591 {
592 GtkFormChild *child = tmp_list->data;
593 gtk_form_position_child(form, child, TRUE);
594
595 tmp_list = tmp_list->next;
596 }
597 }
598
Bram Moolenaar98921892016-02-23 17:14:37 +0100599#if GTK_CHECK_VERSION(3,0,0)
600 if (gtk_widget_get_realized(widget))
601#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000602 if (GTK_WIDGET_REALIZED(widget))
Bram Moolenaar98921892016-02-23 17:14:37 +0100603#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000604 {
Bram Moolenaar98921892016-02-23 17:14:37 +0100605#if GTK_CHECK_VERSION(3,0,0)
606 gdk_window_move_resize(gtk_widget_get_window(widget),
607 allocation->x, allocation->y,
608 allocation->width, allocation->height);
609#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000610 gdk_window_move_resize(widget->window,
611 allocation->x, allocation->y,
612 allocation->width, allocation->height);
Bram Moolenaar98921892016-02-23 17:14:37 +0100613#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000614 gdk_window_move_resize(GTK_FORM(widget)->bin_window,
615 0, 0,
616 allocation->width, allocation->height);
617 }
Bram Moolenaar98921892016-02-23 17:14:37 +0100618#if GTK_CHECK_VERSION(3,0,0)
619 gtk_widget_set_allocation(widget, allocation);
620#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000621 widget->allocation = *allocation;
Bram Moolenaar98921892016-02-23 17:14:37 +0100622#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000623 if (need_reposition)
624 gtk_form_send_configure(form);
625}
626
Bram Moolenaar98921892016-02-23 17:14:37 +0100627#if GTK_CHECK_VERSION(3,0,0)
628 static void
629gtk_form_render_background(GtkWidget *widget, cairo_t *cr)
630{
631 gtk_render_background(gtk_widget_get_style_context(widget), cr,
632 0, 0,
633 gtk_widget_get_allocated_width(widget),
634 gtk_widget_get_allocated_height(widget));
635}
636
637 static gboolean
638gtk_form_draw(GtkWidget *widget, cairo_t *cr)
639{
640 GList *tmp_list = NULL;
641 GtkForm *form = NULL;
642
643 g_return_val_if_fail(GTK_IS_FORM(widget), FALSE);
644
645 gtk_form_render_background(widget, cr);
646
647 form = GTK_FORM(widget);
648 for (tmp_list = form->children; tmp_list; tmp_list = tmp_list->next)
649 {
650 GtkFormChild * const formchild = tmp_list->data;
651
652 if (!gtk_widget_get_has_window(formchild->widget) &&
653 gtk_cairo_should_draw_window(cr, formchild->window))
654 {
655 /* To get gtk_widget_draw() to work, it is required to call
656 * gtk_widget_size_allocate() in advance with a well-posed
657 * allocation for a given child widget in order to set a
658 * certain private GtkWidget variable, called
659 * widget->priv->alloc_need, to the proper value; othewise,
660 * gtk_widget_draw() fails and the relevant scrollbar won't
661 * appear on the screen.
662 *
663 * Calling gtk_form_position_child() like this is one of ways
664 * to make sure of that. */
665 gtk_form_position_child(form, formchild, TRUE);
666
667 gtk_form_render_background(formchild->widget, cr);
668 }
669 }
670
671 return GTK_WIDGET_CLASS(gtk_form_parent_class)->draw(widget, cr);
672}
673#else /* !GTK_CHECK_VERSION(3,0,0) */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000674 static gint
675gtk_form_expose(GtkWidget *widget, GdkEventExpose *event)
676{
677 GList *tmp_list;
678 GtkForm *form;
679
680 g_return_val_if_fail(GTK_IS_FORM(widget), FALSE);
681
682 form = GTK_FORM(widget);
683
684 if (event->window == form->bin_window)
685 return FALSE;
686
687 for (tmp_list = form->children; tmp_list; tmp_list = tmp_list->next)
Bram Moolenaar99a6e8d2017-03-29 18:07:40 +0200688 gtk_container_propagate_expose(GTK_CONTAINER(widget),
689 GTK_WIDGET(((GtkFormChild *)tmp_list->data)->widget),
690 event);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000691
692 return FALSE;
693}
Bram Moolenaar98921892016-02-23 17:14:37 +0100694#endif /* !GTK_CHECK_VERSION(3,0,0) */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000695
696/* Container method
697 */
698 static void
699gtk_form_remove(GtkContainer *container, GtkWidget *widget)
700{
701 GList *tmp_list;
702 GtkForm *form;
703 GtkFormChild *child = NULL; /* init for gcc */
704
705 g_return_if_fail(GTK_IS_FORM(container));
706
707 form = GTK_FORM(container);
708
709 tmp_list = form->children;
710 while (tmp_list)
711 {
712 child = tmp_list->data;
713 if (child->widget == widget)
714 break;
715 tmp_list = tmp_list->next;
716 }
717
718 if (tmp_list)
719 {
Bram Moolenaar98921892016-02-23 17:14:37 +0100720#if GTK_CHECK_VERSION(3,0,0)
721 const gboolean was_visible = gtk_widget_get_visible(widget);
722#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000723 if (child->window)
724 {
Bram Moolenaar98921892016-02-23 17:14:37 +0100725#if GTK_CHECK_VERSION(3,0,0)
726 g_signal_handlers_disconnect_by_func(G_OBJECT(child->widget),
Bram Moolenaard47d8372016-09-09 22:13:24 +0200727 FUNC2GENERIC(&gtk_form_child_map), child);
Bram Moolenaar98921892016-02-23 17:14:37 +0100728 g_signal_handlers_disconnect_by_func(G_OBJECT(child->widget),
Bram Moolenaard47d8372016-09-09 22:13:24 +0200729 FUNC2GENERIC(&gtk_form_child_unmap), child);
Bram Moolenaar98921892016-02-23 17:14:37 +0100730#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000731 gtk_signal_disconnect_by_func(GTK_OBJECT(child->widget),
Bram Moolenaard47d8372016-09-09 22:13:24 +0200732 GTK_SIGNAL_FUNC(&gtk_form_child_map), child);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000733 gtk_signal_disconnect_by_func(GTK_OBJECT(child->widget),
Bram Moolenaard47d8372016-09-09 22:13:24 +0200734 GTK_SIGNAL_FUNC(&gtk_form_child_unmap), child);
Bram Moolenaar98921892016-02-23 17:14:37 +0100735#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000736
737 /* FIXME: This will cause problems for reparenting NO_WINDOW
738 * widgets out of a GtkForm
739 */
740 gdk_window_set_user_data(child->window, NULL);
741 gdk_window_destroy(child->window);
742 }
743 gtk_widget_unparent(widget);
Bram Moolenaar98921892016-02-23 17:14:37 +0100744#if GTK_CHECK_VERSION(3,0,0)
745 if (was_visible)
746 gtk_widget_queue_resize(GTK_WIDGET(container));
747#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000748 form->children = g_list_remove_link(form->children, tmp_list);
749 g_list_free_1(tmp_list);
750 g_free(child);
751 }
752}
753
Bram Moolenaar071d4272004-06-13 20:20:40 +0000754 static void
755gtk_form_forall(GtkContainer *container,
Bram Moolenaarb85cb212009-05-17 14:24:23 +0000756 gboolean include_internals UNUSED,
Bram Moolenaar071d4272004-06-13 20:20:40 +0000757 GtkCallback callback,
758 gpointer callback_data)
759{
760 GtkForm *form;
761 GtkFormChild *child;
762 GList *tmp_list;
763
764 g_return_if_fail(GTK_IS_FORM(container));
765 g_return_if_fail(callback != NULL);
766
767 form = GTK_FORM(container);
768
769 tmp_list = form->children;
770 while (tmp_list)
771 {
772 child = tmp_list->data;
773 tmp_list = tmp_list->next;
774
775 (*callback) (child->widget, callback_data);
776 }
777}
778
779/* Operations on children
780 */
781
782 static void
783gtk_form_attach_child_window(GtkForm *form, GtkFormChild *child)
784{
785 if (child->window != NULL)
786 return; /* been there, done that */
787
Bram Moolenaar98921892016-02-23 17:14:37 +0100788#if GTK_CHECK_VERSION(3,0,0)
789 if (!gtk_widget_get_has_window(child->widget))
790#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000791 if (GTK_WIDGET_NO_WINDOW(child->widget))
Bram Moolenaar98921892016-02-23 17:14:37 +0100792#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000793 {
794 GtkWidget *widget;
795 GdkWindowAttr attributes;
796 gint attributes_mask;
797
798 widget = GTK_WIDGET(form);
799
800 attributes.window_type = GDK_WINDOW_CHILD;
801 attributes.x = child->x;
802 attributes.y = child->y;
Bram Moolenaar98921892016-02-23 17:14:37 +0100803#if GTK_CHECK_VERSION(3,0,0)
804 {
805 GtkRequisition requisition;
806
807 gtk_widget_get_preferred_size(child->widget, &requisition, NULL);
808
809 attributes.width = requisition.width;
810 attributes.height = requisition.height;
811 }
812#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000813 attributes.width = child->widget->requisition.width;
814 attributes.height = child->widget->requisition.height;
Bram Moolenaar98921892016-02-23 17:14:37 +0100815#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000816 attributes.wclass = GDK_INPUT_OUTPUT;
817 attributes.visual = gtk_widget_get_visual(widget);
Bram Moolenaar98921892016-02-23 17:14:37 +0100818#if !GTK_CHECK_VERSION(3,0,0)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000819 attributes.colormap = gtk_widget_get_colormap(widget);
Bram Moolenaar98921892016-02-23 17:14:37 +0100820#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000821 attributes.event_mask = GDK_EXPOSURE_MASK;
822
Bram Moolenaar98921892016-02-23 17:14:37 +0100823#if GTK_CHECK_VERSION(3,0,0)
824 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
825#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000826 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
Bram Moolenaar98921892016-02-23 17:14:37 +0100827#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000828 child->window = gdk_window_new(form->bin_window,
829 &attributes, attributes_mask);
830 gdk_window_set_user_data(child->window, widget);
831
Bram Moolenaar98921892016-02-23 17:14:37 +0100832#if GTK_CHECK_VERSION(3,0,0)
833 {
834 GtkStyleContext * const sctx = gtk_widget_get_style_context(widget);
835
836 gtk_style_context_set_state(sctx, GTK_STATE_FLAG_NORMAL);
837# if !GTK_CHECK_VERSION(3,18,0)
838 gtk_style_context_set_background(sctx, child->window);
839# endif
840 }
841#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000842 gtk_style_set_background(widget->style,
843 child->window,
844 GTK_STATE_NORMAL);
Bram Moolenaar98921892016-02-23 17:14:37 +0100845#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000846
847 gtk_widget_set_parent_window(child->widget, child->window);
Bram Moolenaar98921892016-02-23 17:14:37 +0100848#if !GTK_CHECK_VERSION(3,16,0)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000849 gtk_form_set_static_gravity(child->window, TRUE);
Bram Moolenaar98921892016-02-23 17:14:37 +0100850#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000851 /*
852 * Install signal handlers to map/unmap child->window
853 * alongside with the actual widget.
854 */
Bram Moolenaar98921892016-02-23 17:14:37 +0100855#if GTK_CHECK_VERSION(3,0,0)
856 g_signal_connect(G_OBJECT(child->widget), "map",
857 G_CALLBACK(&gtk_form_child_map), child);
858 g_signal_connect(G_OBJECT(child->widget), "unmap",
859 G_CALLBACK(&gtk_form_child_unmap), child);
860#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000861 gtk_signal_connect(GTK_OBJECT(child->widget), "map",
862 GTK_SIGNAL_FUNC(&gtk_form_child_map), child);
863 gtk_signal_connect(GTK_OBJECT(child->widget), "unmap",
864 GTK_SIGNAL_FUNC(&gtk_form_child_unmap), child);
Bram Moolenaar98921892016-02-23 17:14:37 +0100865#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000866 }
Bram Moolenaar98921892016-02-23 17:14:37 +0100867#if GTK_CHECK_VERSION(3,0,0)
868 else if (!gtk_widget_get_realized(child->widget))
869#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000870 else if (!GTK_WIDGET_REALIZED(child->widget))
Bram Moolenaar98921892016-02-23 17:14:37 +0100871#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000872 {
873 gtk_widget_set_parent_window(child->widget, form->bin_window);
874 }
875}
876
877 static void
878gtk_form_realize_child(GtkForm *form, GtkFormChild *child)
879{
880 gtk_form_attach_child_window(form, child);
881 gtk_widget_realize(child->widget);
882
Bram Moolenaar98921892016-02-23 17:14:37 +0100883#if !GTK_CHECK_VERSION(3,16,0)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000884 if (child->window == NULL) /* might be already set, see above */
Bram Moolenaar98921892016-02-23 17:14:37 +0100885# if GTK_CHECK_VERSION(3,0,0)
886 gtk_form_set_static_gravity(gtk_widget_get_window(child->widget), TRUE);
887# else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000888 gtk_form_set_static_gravity(child->widget->window, TRUE);
Bram Moolenaar98921892016-02-23 17:14:37 +0100889# endif
890#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000891}
892
893 static void
894gtk_form_position_child(GtkForm *form, GtkFormChild *child,
895 gboolean force_allocate)
896{
897 gint x;
898 gint y;
899
900 x = child->x;
901 y = child->y;
902
903 if ((x >= G_MINSHORT) && (x <= G_MAXSHORT) &&
904 (y >= G_MINSHORT) && (y <= G_MAXSHORT))
905 {
906 if (!child->mapped)
907 {
Bram Moolenaar98921892016-02-23 17:14:37 +0100908#if GTK_CHECK_VERSION(3,0,0)
909 if (gtk_widget_get_mapped(GTK_WIDGET(form))
910 && gtk_widget_get_visible(child->widget))
911#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000912 if (GTK_WIDGET_MAPPED(form) && GTK_WIDGET_VISIBLE(child->widget))
Bram Moolenaar98921892016-02-23 17:14:37 +0100913#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000914 {
Bram Moolenaar98921892016-02-23 17:14:37 +0100915#if GTK_CHECK_VERSION(3,0,0)
916 if (!gtk_widget_get_mapped(child->widget))
917#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000918 if (!GTK_WIDGET_MAPPED(child->widget))
Bram Moolenaar98921892016-02-23 17:14:37 +0100919#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000920 gtk_widget_map(child->widget);
921
922 child->mapped = TRUE;
923 force_allocate = TRUE;
924 }
925 }
926
927 if (force_allocate)
928 {
929 GtkAllocation allocation;
Bram Moolenaar98921892016-02-23 17:14:37 +0100930#if GTK_CHECK_VERSION(3,0,0)
931 GtkRequisition requisition;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000932
Bram Moolenaar98921892016-02-23 17:14:37 +0100933 gtk_widget_get_preferred_size(child->widget, &requisition, NULL);
934#endif
935
936#if GTK_CHECK_VERSION(3,0,0)
937 if (!gtk_widget_get_has_window(child->widget))
938#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000939 if (GTK_WIDGET_NO_WINDOW(child->widget))
Bram Moolenaar98921892016-02-23 17:14:37 +0100940#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000941 {
942 if (child->window)
943 {
Bram Moolenaar98921892016-02-23 17:14:37 +0100944#if GTK_CHECK_VERSION(3,0,0)
945 gdk_window_move_resize(child->window,
946 x, y,
947 requisition.width,
948 requisition.height);
949#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000950 gdk_window_move_resize(child->window,
951 x, y,
952 child->widget->requisition.width,
953 child->widget->requisition.height);
Bram Moolenaar98921892016-02-23 17:14:37 +0100954#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000955 }
956
957 allocation.x = 0;
958 allocation.y = 0;
959 }
960 else
961 {
962 allocation.x = x;
963 allocation.y = y;
964 }
965
Bram Moolenaar98921892016-02-23 17:14:37 +0100966#if GTK_CHECK_VERSION(3,0,0)
967 allocation.width = requisition.width;
968 allocation.height = requisition.height;
969#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000970 allocation.width = child->widget->requisition.width;
971 allocation.height = child->widget->requisition.height;
Bram Moolenaar98921892016-02-23 17:14:37 +0100972#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000973
974 gtk_widget_size_allocate(child->widget, &allocation);
975 }
976 }
977 else
978 {
979 if (child->mapped)
980 {
981 child->mapped = FALSE;
982
Bram Moolenaar98921892016-02-23 17:14:37 +0100983#if GTK_CHECK_VERSION(3,0,0)
984 if (gtk_widget_get_mapped(child->widget))
985#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000986 if (GTK_WIDGET_MAPPED(child->widget))
Bram Moolenaar98921892016-02-23 17:14:37 +0100987#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000988 gtk_widget_unmap(child->widget);
989 }
990 }
991}
992
993 static void
994gtk_form_position_children(GtkForm *form)
995{
996 GList *tmp_list;
997
998 for (tmp_list = form->children; tmp_list; tmp_list = tmp_list->next)
999 gtk_form_position_child(form, tmp_list->data, FALSE);
1000}
1001
Bram Moolenaar98921892016-02-23 17:14:37 +01001002#if !GTK_CHECK_VERSION(3,16,0)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001003 static void
1004gtk_form_set_static_gravity(GdkWindow *window, gboolean use_static)
1005{
Bram Moolenaar5e69de42009-09-11 14:17:54 +00001006 /* We don't check if static gravity is actually supported, because it
1007 * results in an annoying assertion error message. */
1008 gdk_window_set_static_gravities(window, use_static);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001009}
Bram Moolenaar98921892016-02-23 17:14:37 +01001010#endif /* !GTK_CHECK_VERSION(3,16,0) */
Bram Moolenaar071d4272004-06-13 20:20:40 +00001011
1012 void
1013gtk_form_move_resize(GtkForm *form, GtkWidget *widget,
1014 gint x, gint y, gint w, gint h)
1015{
Bram Moolenaar98921892016-02-23 17:14:37 +01001016#if GTK_CHECK_VERSION(3,0,0)
1017 gtk_widget_set_size_request(widget, w, h);
1018#else
Bram Moolenaar071d4272004-06-13 20:20:40 +00001019 widget->requisition.width = w;
1020 widget->requisition.height = h;
Bram Moolenaar98921892016-02-23 17:14:37 +01001021#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00001022
1023 gtk_form_move(form, widget, x, y);
1024}
1025
1026 static void
1027gtk_form_send_configure(GtkForm *form)
1028{
1029 GtkWidget *widget;
1030 GdkEventConfigure event;
1031
1032 widget = GTK_WIDGET(form);
1033
1034 event.type = GDK_CONFIGURE;
Bram Moolenaar98921892016-02-23 17:14:37 +01001035#if GTK_CHECK_VERSION(3,0,0)
1036 event.window = gtk_widget_get_window(widget);
1037 {
1038 GtkAllocation allocation;
1039
1040 gtk_widget_get_allocation(widget, &allocation);
1041 event.x = allocation.x;
1042 event.y = allocation.y;
1043 event.width = allocation.width;
1044 event.height = allocation.height;
1045 }
1046#else
Bram Moolenaar071d4272004-06-13 20:20:40 +00001047 event.window = widget->window;
1048 event.x = widget->allocation.x;
1049 event.y = widget->allocation.y;
1050 event.width = widget->allocation.width;
1051 event.height = widget->allocation.height;
Bram Moolenaar98921892016-02-23 17:14:37 +01001052#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00001053
Bram Moolenaar071d4272004-06-13 20:20:40 +00001054 gtk_main_do_event((GdkEvent*)&event);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001055}
1056
Bram Moolenaar071d4272004-06-13 20:20:40 +00001057 static void
Bram Moolenaarb85cb212009-05-17 14:24:23 +00001058gtk_form_child_map(GtkWidget *widget UNUSED, gpointer user_data)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001059{
1060 GtkFormChild *child;
1061
1062 child = (GtkFormChild *)user_data;
1063
1064 child->mapped = TRUE;
1065 gdk_window_show(child->window);
1066}
1067
Bram Moolenaar071d4272004-06-13 20:20:40 +00001068 static void
Bram Moolenaarb85cb212009-05-17 14:24:23 +00001069gtk_form_child_unmap(GtkWidget *widget UNUSED, gpointer user_data)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001070{
1071 GtkFormChild *child;
1072
1073 child = (GtkFormChild *)user_data;
1074
1075 child->mapped = FALSE;
1076 gdk_window_hide(child->window);
1077}