1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 /*
19  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
20  * file for a list of people on the GTK+ Team.  See the ChangeLog
21  * files for a list of changes.  These files are distributed with
22  * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
23  */
24 
25 #include "config.h"
26 
27 #include <stdarg.h>
28 #include <string.h>
29 #include <locale.h>
30 #include <math.h>
31 
32 #include <gobject/gvaluecollector.h>
33 #include <gobject/gobjectnotifyqueue.c>
34 #include <cairo-gobject.h>
35 
36 #include "gtkcontainer.h"
37 #include "gtkaccelmapprivate.h"
38 #include "gtkaccelgroupprivate.h"
39 #include "gtkclipboard.h"
40 #include "gtkcssstylepropertyprivate.h"
41 #include "gtkcssnumbervalueprivate.h"
42 #include "gtkcssshadowsvalueprivate.h"
43 #include "gtkintl.h"
44 #include "gtkmarshalers.h"
45 #include "gtkselectionprivate.h"
46 #include "gtksettingsprivate.h"
47 #include "gtksizegroup-private.h"
48 #include "gtkwidget.h"
49 #include "gtkwidgetprivate.h"
50 #include "gtkwindowprivate.h"
51 #include "gtkcontainerprivate.h"
52 #include "gtkbindings.h"
53 #include "gtkprivate.h"
54 #include "gtkaccessible.h"
55 #include "gtktooltipprivate.h"
56 #include "gtkinvisible.h"
57 #include "gtkbuildable.h"
58 #include "gtkbuilderprivate.h"
59 #include "gtksizerequest.h"
60 #include "gtkstylecontextprivate.h"
61 #include "gtkcssprovider.h"
62 #include "gtkcsswidgetnodeprivate.h"
63 #include "gtkmodifierstyle.h"
64 #include "gtkversion.h"
65 #include "gtkdebug.h"
66 #include "gtkplug.h"
67 #include "gtktypebuiltins.h"
68 #include "a11y/gtkwidgetaccessible.h"
69 #include "gtkapplicationprivate.h"
70 #include "gtkgestureprivate.h"
71 #include "gtkwidgetpathprivate.h"
72 
73 /* for the use of round() */
74 #include "fallback-c89.c"
75 
76 /**
77  * SECTION:gtkwidget
78  * @Short_description: Base class for all widgets
79  * @Title: GtkWidget
80  *
81  * GtkWidget is the base class all widgets in GTK+ derive from. It manages the
82  * widget lifecycle, states and style.
83  *
84  * # Height-for-width Geometry Management # {#geometry-management}
85  *
86  * GTK+ uses a height-for-width (and width-for-height) geometry management
87  * system. Height-for-width means that a widget can change how much
88  * vertical space it needs, depending on the amount of horizontal space
89  * that it is given (and similar for width-for-height). The most common
90  * example is a label that reflows to fill up the available width, wraps
91  * to fewer lines, and therefore needs less height.
92  *
93  * Height-for-width geometry management is implemented in GTK+ by way
94  * of five virtual methods:
95  *
96  * - #GtkWidgetClass.get_request_mode()
97  * - #GtkWidgetClass.get_preferred_width()
98  * - #GtkWidgetClass.get_preferred_height()
99  * - #GtkWidgetClass.get_preferred_height_for_width()
100  * - #GtkWidgetClass.get_preferred_width_for_height()
101  * - #GtkWidgetClass.get_preferred_height_and_baseline_for_width()
102  *
103  * There are some important things to keep in mind when implementing
104  * height-for-width and when using it in container implementations.
105  *
106  * The geometry management system will query a widget hierarchy in
107  * only one orientation at a time. When widgets are initially queried
108  * for their minimum sizes it is generally done in two initial passes
109  * in the #GtkSizeRequestMode chosen by the toplevel.
110  *
111  * For example, when queried in the normal
112  * %GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH mode:
113  * First, the default minimum and natural width for each widget
114  * in the interface will be computed using gtk_widget_get_preferred_width().
115  * Because the preferred widths for each container depend on the preferred
116  * widths of their children, this information propagates up the hierarchy,
117  * and finally a minimum and natural width is determined for the entire
118  * toplevel. Next, the toplevel will use the minimum width to query for the
119  * minimum height contextual to that width using
120  * gtk_widget_get_preferred_height_for_width(), which will also be a highly
121  * recursive operation. The minimum height for the minimum width is normally
122  * used to set the minimum size constraint on the toplevel
123  * (unless gtk_window_set_geometry_hints() is explicitly used instead).
124  *
125  * After the toplevel window has initially requested its size in both
126  * dimensions it can go on to allocate itself a reasonable size (or a size
127  * previously specified with gtk_window_set_default_size()). During the
128  * recursive allocation process it’s important to note that request cycles
129  * will be recursively executed while container widgets allocate their children.
130  * Each container widget, once allocated a size, will go on to first share the
131  * space in one orientation among its children and then request each child's
132  * height for its target allocated width or its width for allocated height,
133  * depending. In this way a #GtkWidget will typically be requested its size
134  * a number of times before actually being allocated a size. The size a
135  * widget is finally allocated can of course differ from the size it has
136  * requested. For this reason, #GtkWidget caches a  small number of results
137  * to avoid re-querying for the same sizes in one allocation cycle.
138  *
139  * See
140  * [GtkContainer’s geometry management section][container-geometry-management]
141  * to learn more about how height-for-width allocations are performed
142  * by container widgets.
143  *
144  * If a widget does move content around to intelligently use up the
145  * allocated size then it must support the request in both
146  * #GtkSizeRequestModes even if the widget in question only
147  * trades sizes in a single orientation.
148  *
149  * For instance, a #GtkLabel that does height-for-width word wrapping
150  * will not expect to have #GtkWidgetClass.get_preferred_height() called
151  * because that call is specific to a width-for-height request. In this
152  * case the label must return the height required for its own minimum
153  * possible width. By following this rule any widget that handles
154  * height-for-width or width-for-height requests will always be allocated
155  * at least enough space to fit its own content.
156  *
157  * Here are some examples of how a %GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH widget
158  * generally deals with width-for-height requests, for #GtkWidgetClass.get_preferred_height()
159  * it will do:
160  *
161  * |[<!-- language="C" -->
162  * static void
163  * foo_widget_get_preferred_height (GtkWidget *widget,
164  *                                  gint *min_height,
165  *                                  gint *nat_height)
166  * {
167  *    if (i_am_in_height_for_width_mode)
168  *      {
169  *        gint min_width, nat_width;
170  *
171  *        GTK_WIDGET_GET_CLASS (widget)->get_preferred_width (widget,
172  *                                                            &min_width,
173  *                                                            &nat_width);
174  *        GTK_WIDGET_GET_CLASS (widget)->get_preferred_height_for_width
175  *                                                           (widget,
176  *                                                            min_width,
177  *                                                            min_height,
178  *                                                            nat_height);
179  *      }
180  *    else
181  *      {
182  *         ... some widgets do both. For instance, if a GtkLabel is
183  *         rotated to 90 degrees it will return the minimum and
184  *         natural height for the rotated label here.
185  *      }
186  * }
187  * ]|
188  *
189  * And in #GtkWidgetClass.get_preferred_width_for_height() it will simply return
190  * the minimum and natural width:
191  * |[<!-- language="C" -->
192  * static void
193  * foo_widget_get_preferred_width_for_height (GtkWidget *widget,
194  *                                            gint for_height,
195  *                                            gint *min_width,
196  *                                            gint *nat_width)
197  * {
198  *    if (i_am_in_height_for_width_mode)
199  *      {
200  *        GTK_WIDGET_GET_CLASS (widget)->get_preferred_width (widget,
201  *                                                            min_width,
202  *                                                            nat_width);
203  *      }
204  *    else
205  *      {
206  *         ... again if a widget is sometimes operating in
207  *         width-for-height mode (like a rotated GtkLabel) it can go
208  *         ahead and do its real width for height calculation here.
209  *      }
210  * }
211  * ]|
212  *
213  * Often a widget needs to get its own request during size request or
214  * allocation. For example, when computing height it may need to also
215  * compute width. Or when deciding how to use an allocation, the widget
216  * may need to know its natural size. In these cases, the widget should
217  * be careful to call its virtual methods directly, like this:
218  *
219  * |[<!-- language="C" -->
220  * GTK_WIDGET_GET_CLASS(widget)->get_preferred_width (widget,
221  *                                                    &min,
222  *                                                    &natural);
223  * ]|
224  *
225  * It will not work to use the wrapper functions, such as
226  * gtk_widget_get_preferred_width() inside your own size request
227  * implementation. These return a request adjusted by #GtkSizeGroup
228  * and by the #GtkWidgetClass.adjust_size_request() virtual method. If a
229  * widget used the wrappers inside its virtual method implementations,
230  * then the adjustments (such as widget margins) would be applied
231  * twice. GTK+ therefore does not allow this and will warn if you try
232  * to do it.
233  *
234  * Of course if you are getting the size request for
235  * another widget, such as a child of a
236  * container, you must use the wrapper APIs.
237  * Otherwise, you would not properly consider widget margins,
238  * #GtkSizeGroup, and so forth.
239  *
240  * Since 3.10 GTK+ also supports baseline vertical alignment of widgets. This
241  * means that widgets are positioned such that the typographical baseline of
242  * widgets in the same row are aligned. This happens if a widget supports baselines,
243  * has a vertical alignment of %GTK_ALIGN_BASELINE, and is inside a container
244  * that supports baselines and has a natural “row” that it aligns to the baseline,
245  * or a baseline assigned to it by the grandparent.
246  *
247  * Baseline alignment support for a widget is done by the #GtkWidgetClass.get_preferred_height_and_baseline_for_width()
248  * virtual function. It allows you to report a baseline in combination with the
249  * minimum and natural height. If there is no baseline you can return -1 to indicate
250  * this. The default implementation of this virtual function calls into the
251  * #GtkWidgetClass.get_preferred_height() and #GtkWidgetClass.get_preferred_height_for_width(),
252  * so if baselines are not supported it doesn’t need to be implemented.
253  *
254  * If a widget ends up baseline aligned it will be allocated all the space in the parent
255  * as if it was %GTK_ALIGN_FILL, but the selected baseline can be found via gtk_widget_get_allocated_baseline().
256  * If this has a value other than -1 you need to align the widget such that the baseline
257  * appears at the position.
258  *
259  * # Style Properties
260  *
261  * #GtkWidget introduces “style
262  * properties” - these are basically object properties that are stored
263  * not on the object, but in the style object associated to the widget. Style
264  * properties are set in [resource files][gtk3-Resource-Files].
265  * This mechanism is used for configuring such things as the location of the
266  * scrollbar arrows through the theme, giving theme authors more control over the
267  * look of applications without the need to write a theme engine in C.
268  *
269  * Use gtk_widget_class_install_style_property() to install style properties for
270  * a widget class, gtk_widget_class_find_style_property() or
271  * gtk_widget_class_list_style_properties() to get information about existing
272  * style properties and gtk_widget_style_get_property(), gtk_widget_style_get() or
273  * gtk_widget_style_get_valist() to obtain the value of a style property.
274  *
275  * # GtkWidget as GtkBuildable
276  *
277  * The GtkWidget implementation of the GtkBuildable interface supports a
278  * custom `<accelerator>` element, which has attributes named ”key”, ”modifiers”
279  * and ”signal” and allows to specify accelerators.
280  *
281  * An example of a UI definition fragment specifying an accelerator:
282  *
283  * |[<!-- language="xml" -->
284  * <object class="GtkButton">
285  *   <accelerator key="q" modifiers="GDK_CONTROL_MASK" signal="clicked"/>
286  * </object>
287  * ]|
288  *
289  * In addition to accelerators, GtkWidget also support a custom `<accessible>`
290  * element, which supports actions and relations. Properties on the accessible
291  * implementation of an object can be set by accessing the internal child
292  * “accessible” of a #GtkWidget.
293  *
294  * An example of a UI definition fragment specifying an accessible:
295  *
296  * |[<!-- language="xml" -->
297  * <object class="GtkLabel" id="label1"/>
298  *   <property name="label">I am a Label for a Button</property>
299  * </object>
300  * <object class="GtkButton" id="button1">
301  *   <accessibility>
302  *     <action action_name="click" translatable="yes">Click the button.</action>
303  *     <relation target="label1" type="labelled-by"/>
304  *   </accessibility>
305  *   <child internal-child="accessible">
306  *     <object class="AtkObject" id="a11y-button1">
307  *       <property name="accessible-name">Clickable Button</property>
308  *     </object>
309  *   </child>
310  * </object>
311  * ]|
312  *
313  * Finally, GtkWidget allows style information such as style classes to
314  * be associated with widgets, using the custom `<style>` element:
315  *
316  * |[<!-- language="xml" -->
317  * <object class="GtkButton" id="button1">
318  *   <style>
319  *     <class name="my-special-button-class"/>
320  *     <class name="dark-button"/>
321  *   </style>
322  * </object>
323  * ]|
324  *
325  * # Building composite widgets from template XML ## {#composite-templates}
326  *
327  * GtkWidget exposes some facilities to automate the procedure
328  * of creating composite widgets using #GtkBuilder interface description
329  * language.
330  *
331  * To create composite widgets with #GtkBuilder XML, one must associate
332  * the interface description with the widget class at class initialization
333  * time using gtk_widget_class_set_template().
334  *
335  * The interface description semantics expected in composite template descriptions
336  * is slightly different from regular #GtkBuilder XML.
337  *
338  * Unlike regular interface descriptions, gtk_widget_class_set_template() will
339  * expect a `<template>` tag as a direct child of the toplevel `<interface>`
340  * tag. The `<template>` tag must specify the “class” attribute which must be
341  * the type name of the widget. Optionally, the “parent” attribute may be
342  * specified to specify the direct parent type of the widget type, this is
343  * ignored by the GtkBuilder but required for Glade to introspect what kind
344  * of properties and internal children exist for a given type when the actual
345  * type does not exist.
346  *
347  * The XML which is contained inside the `<template>` tag behaves as if it were
348  * added to the `<object>` tag defining "widget" itself. You may set properties
349  * on @widget by inserting `<property>` tags into the `<template>` tag, and also
350  * add `<child>` tags to add children and extend "widget" in the normal way you
351  * would with `<object>` tags.
352  *
353  * Additionally, `<object>` tags can also be added before and after the initial
354  * `<template>` tag in the normal way, allowing one to define auxiliary objects
355  * which might be referenced by other widgets declared as children of the
356  * `<template>` tag.
357  *
358  * An example of a GtkBuilder Template Definition:
359  *
360  * |[<!-- language="xml" -->
361  * <interface>
362  *   <template class="FooWidget" parent="GtkBox">
363  *     <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
364  *     <property name="spacing">4</property>
365  *     <child>
366  *       <object class="GtkButton" id="hello_button">
367  *         <property name="label">Hello World</property>
368  *         <signal name="clicked" handler="hello_button_clicked" object="FooWidget" swapped="yes"/>
369  *       </object>
370  *     </child>
371  *     <child>
372  *       <object class="GtkButton" id="goodbye_button">
373  *         <property name="label">Goodbye World</property>
374  *       </object>
375  *     </child>
376  *   </template>
377  * </interface>
378  * ]|
379  *
380  * Typically, you'll place the template fragment into a file that is
381  * bundled with your project, using #GResource. In order to load the
382  * template, you need to call gtk_widget_class_set_template_from_resource()
383  * from the class initialization of your #GtkWidget type:
384  *
385  * |[<!-- language="C" -->
386  * static void
387  * foo_widget_class_init (FooWidgetClass *klass)
388  * {
389  *   // ...
390  *
391  *   gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass),
392  *                                                "/com/example/ui/foowidget.ui");
393  * }
394  * ]|
395  *
396  * You will also need to call gtk_widget_init_template() from the instance
397  * initialization function:
398  *
399  * |[<!-- language="C" -->
400  * static void
401  * foo_widget_init (FooWidget *self)
402  * {
403  *   // ...
404  *   gtk_widget_init_template (GTK_WIDGET (self));
405  * }
406  * ]|
407  *
408  * You can access widgets defined in the template using the
409  * gtk_widget_get_template_child() function, but you will typically declare
410  * a pointer in the instance private data structure of your type using the same
411  * name as the widget in the template definition, and call
412  * gtk_widget_class_bind_template_child_private() with that name, e.g.
413  *
414  * |[<!-- language="C" -->
415  * typedef struct {
416  *   GtkWidget *hello_button;
417  *   GtkWidget *goodbye_button;
418  * } FooWidgetPrivate;
419  *
420  * G_DEFINE_TYPE_WITH_PRIVATE (FooWidget, foo_widget, GTK_TYPE_BOX)
421  *
422  * static void
423  * foo_widget_class_init (FooWidgetClass *klass)
424  * {
425  *   // ...
426  *   gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass),
427  *                                                "/com/example/ui/foowidget.ui");
428  *   gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass),
429  *                                                 FooWidget, hello_button);
430  *   gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass),
431  *                                                 FooWidget, goodbye_button);
432  * }
433  *
434  * static void
435  * foo_widget_init (FooWidget *widget)
436  * {
437  *
438  * }
439  * ]|
440  *
441  * You can also use gtk_widget_class_bind_template_callback() to connect a signal
442  * callback defined in the template with a function visible in the scope of the
443  * class, e.g.
444  *
445  * |[<!-- language="C" -->
446  * // the signal handler has the instance and user data swapped
447  * // because of the swapped="yes" attribute in the template XML
448  * static void
449  * hello_button_clicked (FooWidget *self,
450  *                       GtkButton *button)
451  * {
452  *   g_print ("Hello, world!\n");
453  * }
454  *
455  * static void
456  * foo_widget_class_init (FooWidgetClass *klass)
457  * {
458  *   // ...
459  *   gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass),
460  *                                                "/com/example/ui/foowidget.ui");
461  *   gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (klass), hello_button_clicked);
462  * }
463  * ]|
464  */
465 
466 #define GTK_STATE_FLAGS_DO_PROPAGATE (GTK_STATE_FLAG_INSENSITIVE|GTK_STATE_FLAG_BACKDROP)
467 
468 #define WIDGET_CLASS(w)	 GTK_WIDGET_GET_CLASS (w)
469 
470 typedef struct {
471   gchar               *name;           /* Name of the template automatic child */
472   gboolean             internal_child; /* Whether the automatic widget should be exported as an <internal-child> */
473   gssize               offset;         /* Instance private data offset where to set the automatic child (or 0) */
474 } AutomaticChildClass;
475 
476 typedef struct {
477   gchar     *callback_name;
478   GCallback  callback_symbol;
479 } CallbackSymbol;
480 
481 typedef struct {
482   GBytes               *data;
483   GSList               *children;
484   GSList               *callbacks;
485   GtkBuilderConnectFunc connect_func;
486   gpointer              connect_data;
487   GDestroyNotify        destroy_notify;
488 } GtkWidgetTemplate;
489 
490 typedef struct {
491   GtkEventController *controller;
492   guint grab_notify_id;
493   guint sequence_state_changed_id;
494 } EventControllerData;
495 
496 struct _GtkWidgetClassPrivate
497 {
498   GtkWidgetTemplate *template;
499   GType accessible_type;
500   AtkRole accessible_role;
501   const char *css_name;
502 };
503 
504 enum {
505   DESTROY,
506   SHOW,
507   HIDE,
508   MAP,
509   UNMAP,
510   REALIZE,
511   UNREALIZE,
512   SIZE_ALLOCATE,
513   STATE_FLAGS_CHANGED,
514   STATE_CHANGED,
515   PARENT_SET,
516   HIERARCHY_CHANGED,
517   STYLE_SET,
518   DIRECTION_CHANGED,
519   GRAB_NOTIFY,
520   CHILD_NOTIFY,
521   DRAW,
522   MNEMONIC_ACTIVATE,
523   GRAB_FOCUS,
524   FOCUS,
525   MOVE_FOCUS,
526   KEYNAV_FAILED,
527   EVENT,
528   EVENT_AFTER,
529   BUTTON_PRESS_EVENT,
530   BUTTON_RELEASE_EVENT,
531   SCROLL_EVENT,
532   MOTION_NOTIFY_EVENT,
533   DELETE_EVENT,
534   DESTROY_EVENT,
535   KEY_PRESS_EVENT,
536   KEY_RELEASE_EVENT,
537   ENTER_NOTIFY_EVENT,
538   LEAVE_NOTIFY_EVENT,
539   CONFIGURE_EVENT,
540   FOCUS_IN_EVENT,
541   FOCUS_OUT_EVENT,
542   MAP_EVENT,
543   UNMAP_EVENT,
544   PROPERTY_NOTIFY_EVENT,
545   SELECTION_CLEAR_EVENT,
546   SELECTION_REQUEST_EVENT,
547   SELECTION_NOTIFY_EVENT,
548   SELECTION_GET,
549   SELECTION_RECEIVED,
550   PROXIMITY_IN_EVENT,
551   PROXIMITY_OUT_EVENT,
552   VISIBILITY_NOTIFY_EVENT,
553   WINDOW_STATE_EVENT,
554   DAMAGE_EVENT,
555   GRAB_BROKEN_EVENT,
556   DRAG_BEGIN,
557   DRAG_END,
558   DRAG_DATA_DELETE,
559   DRAG_LEAVE,
560   DRAG_MOTION,
561   DRAG_DROP,
562   DRAG_DATA_GET,
563   DRAG_DATA_RECEIVED,
564   POPUP_MENU,
565   SHOW_HELP,
566   ACCEL_CLOSURES_CHANGED,
567   SCREEN_CHANGED,
568   CAN_ACTIVATE_ACCEL,
569   COMPOSITED_CHANGED,
570   QUERY_TOOLTIP,
571   DRAG_FAILED,
572   STYLE_UPDATED,
573   TOUCH_EVENT,
574   LAST_SIGNAL
575 };
576 
577 enum {
578   PROP_0,
579   PROP_NAME,
580   PROP_PARENT,
581   PROP_WIDTH_REQUEST,
582   PROP_HEIGHT_REQUEST,
583   PROP_VISIBLE,
584   PROP_SENSITIVE,
585   PROP_APP_PAINTABLE,
586   PROP_CAN_FOCUS,
587   PROP_HAS_FOCUS,
588   PROP_IS_FOCUS,
589   PROP_FOCUS_ON_CLICK,
590   PROP_CAN_DEFAULT,
591   PROP_HAS_DEFAULT,
592   PROP_RECEIVES_DEFAULT,
593   PROP_COMPOSITE_CHILD,
594   PROP_STYLE,
595   PROP_EVENTS,
596   PROP_NO_SHOW_ALL,
597   PROP_HAS_TOOLTIP,
598   PROP_TOOLTIP_MARKUP,
599   PROP_TOOLTIP_TEXT,
600   PROP_WINDOW,
601   PROP_OPACITY,
602   PROP_DOUBLE_BUFFERED,
603   PROP_HALIGN,
604   PROP_VALIGN,
605   PROP_MARGIN_LEFT,
606   PROP_MARGIN_RIGHT,
607   PROP_MARGIN_START,
608   PROP_MARGIN_END,
609   PROP_MARGIN_TOP,
610   PROP_MARGIN_BOTTOM,
611   PROP_MARGIN,
612   PROP_HEXPAND,
613   PROP_VEXPAND,
614   PROP_HEXPAND_SET,
615   PROP_VEXPAND_SET,
616   PROP_EXPAND,
617   PROP_SCALE_FACTOR,
618   NUM_PROPERTIES
619 };
620 
621 static GParamSpec *widget_props[NUM_PROPERTIES] = { NULL, };
622 
623 typedef	struct	_GtkStateData	 GtkStateData;
624 
625 struct _GtkStateData
626 {
627   guint         flags_to_set;
628   guint         flags_to_unset;
629 
630   gint          old_scale_factor;
631 };
632 
633 /* --- prototypes --- */
634 static void	gtk_widget_base_class_init	(gpointer            g_class);
635 static void	gtk_widget_class_init		(GtkWidgetClass     *klass);
636 static void	gtk_widget_base_class_finalize	(GtkWidgetClass     *klass);
637 static void     gtk_widget_init                  (GTypeInstance     *instance,
638                                                   gpointer           g_class);
639 static void	gtk_widget_set_property		 (GObject           *object,
640 						  guint              prop_id,
641 						  const GValue      *value,
642 						  GParamSpec        *pspec);
643 static void	gtk_widget_get_property		 (GObject           *object,
644 						  guint              prop_id,
645 						  GValue            *value,
646 						  GParamSpec        *pspec);
647 static void	gtk_widget_constructed           (GObject	    *object);
648 static void	gtk_widget_dispose		 (GObject	    *object);
649 static void	gtk_widget_real_destroy		 (GtkWidget	    *object);
650 static void	gtk_widget_finalize		 (GObject	    *object);
651 static void	gtk_widget_real_show		 (GtkWidget	    *widget);
652 static void	gtk_widget_real_hide		 (GtkWidget	    *widget);
653 static void	gtk_widget_real_map		 (GtkWidget	    *widget);
654 static void	gtk_widget_real_unmap		 (GtkWidget	    *widget);
655 static void	gtk_widget_real_realize		 (GtkWidget	    *widget);
656 static void	gtk_widget_real_unrealize	 (GtkWidget	    *widget);
657 static void	gtk_widget_real_size_allocate	 (GtkWidget	    *widget,
658                                                   GtkAllocation	    *allocation);
659 static void	gtk_widget_real_style_set        (GtkWidget         *widget,
660                                                   GtkStyle          *previous_style);
661 static void	gtk_widget_real_direction_changed(GtkWidget         *widget,
662                                                   GtkTextDirection   previous_direction);
663 
664 static void	gtk_widget_real_grab_focus	 (GtkWidget         *focus_widget);
665 static gboolean gtk_widget_real_query_tooltip    (GtkWidget         *widget,
666 						  gint               x,
667 						  gint               y,
668 						  gboolean           keyboard_tip,
669 						  GtkTooltip        *tooltip);
670 static void     gtk_widget_real_style_updated    (GtkWidget         *widget);
671 static gboolean gtk_widget_real_show_help        (GtkWidget         *widget,
672                                                   GtkWidgetHelpType  help_type);
673 static gboolean _gtk_widget_run_controllers      (GtkWidget           *widget,
674                                                   const GdkEvent      *event,
675                                                   GtkPropagationPhase  phase);
676 
677 static void	gtk_widget_dispatch_child_properties_changed	(GtkWidget        *object,
678 								 guint             n_pspecs,
679 								 GParamSpec      **pspecs);
680 static gboolean         gtk_widget_real_scroll_event            (GtkWidget        *widget,
681                                                                  GdkEventScroll   *event);
682 static gboolean         gtk_widget_real_button_event            (GtkWidget        *widget,
683                                                                  GdkEventButton   *event);
684 static gboolean         gtk_widget_real_motion_event            (GtkWidget        *widget,
685                                                                  GdkEventMotion   *event);
686 static gboolean		gtk_widget_real_key_press_event   	(GtkWidget        *widget,
687 								 GdkEventKey      *event);
688 static gboolean		gtk_widget_real_key_release_event 	(GtkWidget        *widget,
689 								 GdkEventKey      *event);
690 static gboolean		gtk_widget_real_focus_in_event   	 (GtkWidget       *widget,
691 								  GdkEventFocus   *event);
692 static gboolean		gtk_widget_real_focus_out_event   	(GtkWidget        *widget,
693 								 GdkEventFocus    *event);
694 static gboolean         gtk_widget_real_touch_event             (GtkWidget        *widget,
695                                                                  GdkEventTouch    *event);
696 static gboolean         gtk_widget_real_grab_broken_event       (GtkWidget          *widget,
697                                                                  GdkEventGrabBroken *event);
698 static gboolean		gtk_widget_real_focus			(GtkWidget        *widget,
699 								 GtkDirectionType  direction);
700 static void             gtk_widget_real_move_focus              (GtkWidget        *widget,
701                                                                  GtkDirectionType  direction);
702 static gboolean		gtk_widget_real_keynav_failed		(GtkWidget        *widget,
703 								 GtkDirectionType  direction);
704 #ifdef G_ENABLE_CONSISTENCY_CHECKS
705 static void             gtk_widget_verify_invariants            (GtkWidget        *widget);
706 static void             gtk_widget_push_verify_invariants       (GtkWidget        *widget);
707 static void             gtk_widget_pop_verify_invariants        (GtkWidget        *widget);
708 #else
709 #define                 gtk_widget_verify_invariants(widget)
710 #define                 gtk_widget_push_verify_invariants(widget)
711 #define                 gtk_widget_pop_verify_invariants(widget)
712 #endif
713 static PangoContext*	gtk_widget_peek_pango_context		(GtkWidget	  *widget);
714 static void     	gtk_widget_update_pango_context		(GtkWidget	  *widget);
715 static void		gtk_widget_propagate_state		(GtkWidget	  *widget,
716 								 GtkStateData 	  *data);
717 static void             gtk_widget_update_alpha                 (GtkWidget        *widget);
718 
719 static gint		gtk_widget_event_internal		(GtkWidget	  *widget,
720 								 GdkEvent	  *event);
721 static gboolean		gtk_widget_real_mnemonic_activate	(GtkWidget	  *widget,
722 								 gboolean	   group_cycling);
723 static void             gtk_widget_real_get_width               (GtkWidget        *widget,
724                                                                  gint             *minimum_size,
725                                                                  gint             *natural_size);
726 static void             gtk_widget_real_get_height              (GtkWidget        *widget,
727                                                                  gint             *minimum_size,
728                                                                  gint             *natural_size);
729 static void             gtk_widget_real_get_height_for_width    (GtkWidget        *widget,
730                                                                  gint              width,
731                                                                  gint             *minimum_height,
732                                                                  gint             *natural_height);
733 static void             gtk_widget_real_get_width_for_height    (GtkWidget        *widget,
734                                                                  gint              height,
735                                                                  gint             *minimum_width,
736                                                                  gint             *natural_width);
737 static void             gtk_widget_real_state_flags_changed     (GtkWidget        *widget,
738                                                                  GtkStateFlags     old_state);
739 static void             gtk_widget_real_queue_draw_region       (GtkWidget         *widget,
740 								 const cairo_region_t *region);
741 static AtkObject*	gtk_widget_real_get_accessible		(GtkWidget	  *widget);
742 static void		gtk_widget_accessible_interface_init	(AtkImplementorIface *iface);
743 static AtkObject*	gtk_widget_ref_accessible		(AtkImplementor *implementor);
744 static void             gtk_widget_invalidate_widget_windows    (GtkWidget        *widget,
745 								 cairo_region_t        *region);
746 static GdkScreen *      gtk_widget_get_screen_unchecked         (GtkWidget        *widget);
747 static gboolean         gtk_widget_real_can_activate_accel      (GtkWidget *widget,
748                                                                  guint      signal_id);
749 
750 static void             gtk_widget_real_set_has_tooltip         (GtkWidget *widget,
751 								 gboolean   has_tooltip,
752 								 gboolean   force);
753 static void             gtk_widget_buildable_interface_init     (GtkBuildableIface *iface);
754 static void             gtk_widget_buildable_set_name           (GtkBuildable     *buildable,
755                                                                  const gchar      *name);
756 static const gchar *    gtk_widget_buildable_get_name           (GtkBuildable     *buildable);
757 static GObject *        gtk_widget_buildable_get_internal_child (GtkBuildable *buildable,
758 								 GtkBuilder   *builder,
759 								 const gchar  *childname);
760 static void             gtk_widget_buildable_set_buildable_property (GtkBuildable     *buildable,
761 								     GtkBuilder       *builder,
762 								     const gchar      *name,
763 								     const GValue     *value);
764 static gboolean         gtk_widget_buildable_custom_tag_start   (GtkBuildable     *buildable,
765                                                                  GtkBuilder       *builder,
766                                                                  GObject          *child,
767                                                                  const gchar      *tagname,
768                                                                  GMarkupParser    *parser,
769                                                                  gpointer         *data);
770 static void             gtk_widget_buildable_custom_finished    (GtkBuildable     *buildable,
771                                                                  GtkBuilder       *builder,
772                                                                  GObject          *child,
773                                                                  const gchar      *tagname,
774                                                                  gpointer          data);
775 static void             gtk_widget_buildable_parser_finished    (GtkBuildable     *buildable,
776                                                                  GtkBuilder       *builder);
777 
778 static GtkSizeRequestMode gtk_widget_real_get_request_mode      (GtkWidget         *widget);
779 static void             gtk_widget_real_get_width               (GtkWidget         *widget,
780                                                                  gint              *minimum_size,
781                                                                  gint              *natural_size);
782 static void             gtk_widget_real_get_height              (GtkWidget         *widget,
783                                                                  gint              *minimum_size,
784                                                                  gint              *natural_size);
785 
786 static void             gtk_widget_queue_tooltip_query          (GtkWidget *widget);
787 
788 
789 static void             gtk_widget_real_adjust_size_request     (GtkWidget         *widget,
790                                                                  GtkOrientation     orientation,
791                                                                  gint              *minimum_size,
792                                                                  gint              *natural_size);
793 static void             gtk_widget_real_adjust_baseline_request (GtkWidget         *widget,
794 								 gint              *minimum_baseline,
795 								 gint              *natural_baseline);
796 static void             gtk_widget_real_adjust_size_allocation  (GtkWidget         *widget,
797                                                                  GtkOrientation     orientation,
798                                                                  gint              *minimum_size,
799                                                                  gint              *natural_size,
800                                                                  gint              *allocated_pos,
801                                                                  gint              *allocated_size);
802 static void             gtk_widget_real_adjust_baseline_allocation (GtkWidget         *widget,
803 								    gint              *baseline);
804 
805 static void                  template_data_free                 (GtkWidgetTemplate    *template_data);
806 
807 static void gtk_widget_set_usize_internal (GtkWidget          *widget,
808 					   gint                width,
809 					   gint                height);
810 
811 static void gtk_widget_add_events_internal (GtkWidget *widget,
812                                             GdkDevice *device,
813                                             gint       events);
814 static void gtk_widget_set_device_enabled_internal (GtkWidget *widget,
815                                                     GdkDevice *device,
816                                                     gboolean   recurse,
817                                                     gboolean   enabled);
818 
819 static void gtk_widget_on_frame_clock_update (GdkFrameClock *frame_clock,
820                                               GtkWidget     *widget);
821 
822 static gboolean event_window_is_still_viewable (GdkEvent *event);
823 
824 static void gtk_widget_update_input_shape (GtkWidget *widget);
825 
826 /* --- variables --- */
827 static gint             GtkWidget_private_offset = 0;
828 static gpointer         gtk_widget_parent_class = NULL;
829 static guint            widget_signals[LAST_SIGNAL] = { 0 };
830 static guint            composite_child_stack = 0;
831 GtkTextDirection gtk_default_direction = GTK_TEXT_DIR_LTR;
832 static GParamSpecPool  *style_property_spec_pool = NULL;
833 
834 static GQuark		quark_property_parser = 0;
835 static GQuark		quark_accel_path = 0;
836 static GQuark		quark_accel_closures = 0;
837 static GQuark		quark_event_mask = 0;
838 static GQuark           quark_device_event_mask = 0;
839 static GQuark		quark_parent_window = 0;
840 static GQuark		quark_shape_info = 0;
841 static GQuark		quark_input_shape_info = 0;
842 static GQuark		quark_pango_context = 0;
843 static GQuark		quark_mnemonic_labels = 0;
844 static GQuark		quark_tooltip_markup = 0;
845 static GQuark		quark_tooltip_window = 0;
846 static GQuark		quark_visual = 0;
847 static GQuark           quark_modifier_style = 0;
848 static GQuark           quark_enabled_devices = 0;
849 static GQuark           quark_size_groups = 0;
850 static GQuark           quark_auto_children = 0;
851 static GQuark           quark_widget_path = 0;
852 static GQuark           quark_action_muxer = 0;
853 static GQuark           quark_font_options = 0;
854 static GQuark           quark_font_map = 0;
855 
856 GParamSpecPool         *_gtk_widget_child_property_pool = NULL;
857 GObjectNotifyContext   *_gtk_widget_child_property_notify_context = NULL;
858 
859 /* --- functions --- */
860 GType
gtk_widget_get_type(void)861 gtk_widget_get_type (void)
862 {
863   static GType widget_type = 0;
864 
865   if (G_UNLIKELY (widget_type == 0))
866     {
867       const GTypeInfo widget_info =
868       {
869 	sizeof (GtkWidgetClass),
870 	gtk_widget_base_class_init,
871 	(GBaseFinalizeFunc) gtk_widget_base_class_finalize,
872 	(GClassInitFunc) gtk_widget_class_init,
873 	NULL,		/* class_finalize */
874 	NULL,		/* class_init */
875 	sizeof (GtkWidget),
876 	0,		/* n_preallocs */
877 	gtk_widget_init,
878 	NULL,		/* value_table */
879       };
880 
881       const GInterfaceInfo accessibility_info =
882       {
883 	(GInterfaceInitFunc) gtk_widget_accessible_interface_init,
884 	(GInterfaceFinalizeFunc) NULL,
885 	NULL /* interface data */
886       };
887 
888       const GInterfaceInfo buildable_info =
889       {
890 	(GInterfaceInitFunc) gtk_widget_buildable_interface_init,
891 	(GInterfaceFinalizeFunc) NULL,
892 	NULL /* interface data */
893       };
894 
895       widget_type = g_type_register_static (G_TYPE_INITIALLY_UNOWNED, "GtkWidget",
896                                             &widget_info, G_TYPE_FLAG_ABSTRACT);
897 
898       g_type_add_class_private (widget_type, sizeof (GtkWidgetClassPrivate));
899 
900       GtkWidget_private_offset =
901         g_type_add_instance_private (widget_type, sizeof (GtkWidgetPrivate));
902 
903       g_type_add_interface_static (widget_type, ATK_TYPE_IMPLEMENTOR,
904                                    &accessibility_info) ;
905       g_type_add_interface_static (widget_type, GTK_TYPE_BUILDABLE,
906                                    &buildable_info) ;
907     }
908 
909   return widget_type;
910 }
911 
912 static inline gpointer
gtk_widget_get_instance_private(GtkWidget * self)913 gtk_widget_get_instance_private (GtkWidget *self)
914 {
915   return (G_STRUCT_MEMBER_P (self, GtkWidget_private_offset));
916 }
917 
918 static void
gtk_widget_base_class_init(gpointer g_class)919 gtk_widget_base_class_init (gpointer g_class)
920 {
921   GtkWidgetClass *klass = g_class;
922 
923   klass->priv = G_TYPE_CLASS_GET_PRIVATE (g_class, GTK_TYPE_WIDGET, GtkWidgetClassPrivate);
924   klass->priv->template = NULL;
925 }
926 
927 static void
child_property_notify_dispatcher(GObject * object,guint n_pspecs,GParamSpec ** pspecs)928 child_property_notify_dispatcher (GObject     *object,
929 				  guint        n_pspecs,
930 				  GParamSpec **pspecs)
931 {
932   GTK_WIDGET_GET_CLASS (object)->dispatch_child_properties_changed (GTK_WIDGET (object), n_pspecs, pspecs);
933 }
934 
935 /* We guard against the draw signal callbacks modifying the state of the
936  * cairo context by surrounding it with save/restore.
937  * Maybe we should also cairo_new_path() just to be sure?
938  */
939 static void
gtk_widget_draw_marshaller(GClosure * closure,GValue * return_value,guint n_param_values,const GValue * param_values,gpointer invocation_hint,gpointer marshal_data)940 gtk_widget_draw_marshaller (GClosure     *closure,
941                             GValue       *return_value,
942                             guint         n_param_values,
943                             const GValue *param_values,
944                             gpointer      invocation_hint,
945                             gpointer      marshal_data)
946 {
947   cairo_t *cr = g_value_get_boxed (&param_values[1]);
948 
949   cairo_save (cr);
950 
951   _gtk_marshal_BOOLEAN__BOXED (closure,
952                                return_value,
953                                n_param_values,
954                                param_values,
955                                invocation_hint,
956                                marshal_data);
957 
958 
959   cairo_restore (cr);
960 }
961 
962 static void
gtk_widget_draw_marshallerv(GClosure * closure,GValue * return_value,gpointer instance,va_list args,gpointer marshal_data,int n_params,GType * param_types)963 gtk_widget_draw_marshallerv (GClosure     *closure,
964 			     GValue       *return_value,
965 			     gpointer      instance,
966 			     va_list       args,
967 			     gpointer      marshal_data,
968 			     int           n_params,
969 			     GType        *param_types)
970 {
971   cairo_t *cr;
972   va_list args_copy;
973 
974   G_VA_COPY (args_copy, args);
975   cr = va_arg (args_copy, gpointer);
976 
977   cairo_save (cr);
978 
979   _gtk_marshal_BOOLEAN__BOXEDv (closure,
980 				return_value,
981 				instance,
982 				args,
983 				marshal_data,
984 				n_params,
985 				param_types);
986 
987 
988   cairo_restore (cr);
989 
990   va_end (args_copy);
991 }
992 
993 static void
gtk_widget_class_init(GtkWidgetClass * klass)994 gtk_widget_class_init (GtkWidgetClass *klass)
995 {
996   static GObjectNotifyContext cpn_context = { 0, NULL, NULL };
997   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
998   GtkBindingSet *binding_set;
999 
1000   g_type_class_adjust_private_offset (klass, &GtkWidget_private_offset);
1001   gtk_widget_parent_class = g_type_class_peek_parent (klass);
1002 
1003   quark_property_parser = g_quark_from_static_string ("gtk-rc-property-parser");
1004   quark_accel_path = g_quark_from_static_string ("gtk-accel-path");
1005   quark_accel_closures = g_quark_from_static_string ("gtk-accel-closures");
1006   quark_event_mask = g_quark_from_static_string ("gtk-event-mask");
1007   quark_device_event_mask = g_quark_from_static_string ("gtk-device-event-mask");
1008   quark_parent_window = g_quark_from_static_string ("gtk-parent-window");
1009   quark_shape_info = g_quark_from_static_string ("gtk-shape-info");
1010   quark_input_shape_info = g_quark_from_static_string ("gtk-input-shape-info");
1011   quark_pango_context = g_quark_from_static_string ("gtk-pango-context");
1012   quark_mnemonic_labels = g_quark_from_static_string ("gtk-mnemonic-labels");
1013   quark_tooltip_markup = g_quark_from_static_string ("gtk-tooltip-markup");
1014   quark_tooltip_window = g_quark_from_static_string ("gtk-tooltip-window");
1015   quark_visual = g_quark_from_static_string ("gtk-widget-visual");
1016   quark_modifier_style = g_quark_from_static_string ("gtk-widget-modifier-style");
1017   quark_enabled_devices = g_quark_from_static_string ("gtk-widget-enabled-devices");
1018   quark_size_groups = g_quark_from_static_string ("gtk-widget-size-groups");
1019   quark_auto_children = g_quark_from_static_string ("gtk-widget-auto-children");
1020   quark_widget_path = g_quark_from_static_string ("gtk-widget-path");
1021   quark_action_muxer = g_quark_from_static_string ("gtk-widget-action-muxer");
1022   quark_font_options = g_quark_from_static_string ("gtk-widget-font-options");
1023   quark_font_map = g_quark_from_static_string ("gtk-widget-font-map");
1024 
1025   style_property_spec_pool = g_param_spec_pool_new (FALSE);
1026   _gtk_widget_child_property_pool = g_param_spec_pool_new (TRUE);
1027   cpn_context.quark_notify_queue = g_quark_from_static_string ("GtkWidget-child-property-notify-queue");
1028   cpn_context.dispatcher = child_property_notify_dispatcher;
1029   _gtk_widget_child_property_notify_context = &cpn_context;
1030 
1031   gobject_class->constructed = gtk_widget_constructed;
1032   gobject_class->dispose = gtk_widget_dispose;
1033   gobject_class->finalize = gtk_widget_finalize;
1034   gobject_class->set_property = gtk_widget_set_property;
1035   gobject_class->get_property = gtk_widget_get_property;
1036 
1037   klass->destroy = gtk_widget_real_destroy;
1038 
1039   klass->activate_signal = 0;
1040   klass->dispatch_child_properties_changed = gtk_widget_dispatch_child_properties_changed;
1041   klass->show = gtk_widget_real_show;
1042   klass->show_all = gtk_widget_show;
1043   klass->hide = gtk_widget_real_hide;
1044   klass->map = gtk_widget_real_map;
1045   klass->unmap = gtk_widget_real_unmap;
1046   klass->realize = gtk_widget_real_realize;
1047   klass->unrealize = gtk_widget_real_unrealize;
1048   klass->size_allocate = gtk_widget_real_size_allocate;
1049   klass->get_request_mode = gtk_widget_real_get_request_mode;
1050   klass->get_preferred_width = gtk_widget_real_get_width;
1051   klass->get_preferred_height = gtk_widget_real_get_height;
1052   klass->get_preferred_width_for_height = gtk_widget_real_get_width_for_height;
1053   klass->get_preferred_height_for_width = gtk_widget_real_get_height_for_width;
1054   klass->get_preferred_height_and_baseline_for_width = NULL;
1055   klass->state_changed = NULL;
1056   klass->state_flags_changed = gtk_widget_real_state_flags_changed;
1057   klass->parent_set = NULL;
1058   klass->hierarchy_changed = NULL;
1059   klass->style_set = gtk_widget_real_style_set;
1060   klass->direction_changed = gtk_widget_real_direction_changed;
1061   klass->grab_notify = NULL;
1062   klass->child_notify = NULL;
1063   klass->draw = NULL;
1064   klass->mnemonic_activate = gtk_widget_real_mnemonic_activate;
1065   klass->grab_focus = gtk_widget_real_grab_focus;
1066   klass->focus = gtk_widget_real_focus;
1067   klass->move_focus = gtk_widget_real_move_focus;
1068   klass->keynav_failed = gtk_widget_real_keynav_failed;
1069   klass->event = NULL;
1070   klass->scroll_event = gtk_widget_real_scroll_event;
1071   klass->button_press_event = gtk_widget_real_button_event;
1072   klass->button_release_event = gtk_widget_real_button_event;
1073   klass->motion_notify_event = gtk_widget_real_motion_event;
1074   klass->touch_event = gtk_widget_real_touch_event;
1075   klass->delete_event = NULL;
1076   klass->destroy_event = NULL;
1077   klass->key_press_event = gtk_widget_real_key_press_event;
1078   klass->key_release_event = gtk_widget_real_key_release_event;
1079   klass->enter_notify_event = NULL;
1080   klass->leave_notify_event = NULL;
1081   klass->configure_event = NULL;
1082   klass->focus_in_event = gtk_widget_real_focus_in_event;
1083   klass->focus_out_event = gtk_widget_real_focus_out_event;
1084   klass->map_event = NULL;
1085   klass->unmap_event = NULL;
1086   klass->window_state_event = NULL;
1087   klass->property_notify_event = _gtk_selection_property_notify;
1088   klass->selection_clear_event = _gtk_selection_clear;
1089   klass->selection_request_event = _gtk_selection_request;
1090   klass->selection_notify_event = _gtk_selection_notify;
1091   klass->selection_received = NULL;
1092   klass->proximity_in_event = NULL;
1093   klass->proximity_out_event = NULL;
1094   klass->drag_begin = NULL;
1095   klass->drag_end = NULL;
1096   klass->drag_data_delete = NULL;
1097   klass->drag_leave = NULL;
1098   klass->drag_motion = NULL;
1099   klass->drag_drop = NULL;
1100   klass->drag_data_received = NULL;
1101   klass->screen_changed = NULL;
1102   klass->can_activate_accel = gtk_widget_real_can_activate_accel;
1103   klass->grab_broken_event = gtk_widget_real_grab_broken_event;
1104   klass->query_tooltip = gtk_widget_real_query_tooltip;
1105   klass->style_updated = gtk_widget_real_style_updated;
1106 
1107   klass->show_help = gtk_widget_real_show_help;
1108 
1109   /* Accessibility support */
1110   klass->priv->accessible_type = GTK_TYPE_ACCESSIBLE;
1111   klass->priv->accessible_role = ATK_ROLE_INVALID;
1112   klass->get_accessible = gtk_widget_real_get_accessible;
1113 
1114   klass->adjust_size_request = gtk_widget_real_adjust_size_request;
1115   klass->adjust_baseline_request = gtk_widget_real_adjust_baseline_request;
1116   klass->adjust_size_allocation = gtk_widget_real_adjust_size_allocation;
1117   klass->adjust_baseline_allocation = gtk_widget_real_adjust_baseline_allocation;
1118   klass->queue_draw_region = gtk_widget_real_queue_draw_region;
1119 
1120   widget_props[PROP_NAME] =
1121       g_param_spec_string ("name",
1122                            P_("Widget name"),
1123                            P_("The name of the widget"),
1124                            NULL,
1125                            GTK_PARAM_READWRITE);
1126 
1127   widget_props[PROP_PARENT] =
1128       g_param_spec_object ("parent",
1129                            P_("Parent widget"),
1130                            P_("The parent widget of this widget. Must be a Container widget"),
1131                            GTK_TYPE_CONTAINER,
1132                            GTK_PARAM_READWRITE);
1133 
1134   widget_props[PROP_WIDTH_REQUEST] =
1135       g_param_spec_int ("width-request",
1136                         P_("Width request"),
1137                         P_("Override for width request of the widget, or -1 if natural request should be used"),
1138                         -1, G_MAXINT,
1139                         -1,
1140                         GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
1141 
1142   widget_props[PROP_HEIGHT_REQUEST] =
1143       g_param_spec_int ("height-request",
1144                         P_("Height request"),
1145                         P_("Override for height request of the widget, or -1 if natural request should be used"),
1146                         -1, G_MAXINT,
1147                         -1,
1148                         GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
1149 
1150   widget_props[PROP_VISIBLE] =
1151       g_param_spec_boolean ("visible",
1152                             P_("Visible"),
1153                             P_("Whether the widget is visible"),
1154                             FALSE,
1155                             GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
1156 
1157   widget_props[PROP_SENSITIVE] =
1158       g_param_spec_boolean ("sensitive",
1159                             P_("Sensitive"),
1160                             P_("Whether the widget responds to input"),
1161                             TRUE,
1162                             GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
1163 
1164   widget_props[PROP_APP_PAINTABLE] =
1165       g_param_spec_boolean ("app-paintable",
1166                             P_("Application paintable"),
1167                             P_("Whether the application will paint directly on the widget"),
1168                             FALSE,
1169                             GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
1170 
1171   widget_props[PROP_CAN_FOCUS] =
1172       g_param_spec_boolean ("can-focus",
1173                             P_("Can focus"),
1174                             P_("Whether the widget can accept the input focus"),
1175                             FALSE,
1176                             GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
1177 
1178   widget_props[PROP_HAS_FOCUS] =
1179       g_param_spec_boolean ("has-focus",
1180                             P_("Has focus"),
1181                             P_("Whether the widget has the input focus"),
1182                             FALSE,
1183                             GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
1184 
1185   widget_props[PROP_IS_FOCUS] =
1186       g_param_spec_boolean ("is-focus",
1187                             P_("Is focus"),
1188                             P_("Whether the widget is the focus widget within the toplevel"),
1189                             FALSE,
1190                             GTK_PARAM_READWRITE);
1191 
1192   /**
1193    * GtkWidget:focus-on-click:
1194    *
1195    * Whether the widget should grab focus when it is clicked with the mouse.
1196    *
1197    * This property is only relevant for widgets that can take focus.
1198    *
1199    * Before 3.20, several widgets (GtkButton, GtkFileChooserButton,
1200    * GtkComboBox) implemented this property individually.
1201    *
1202    * Since: 3.20
1203    */
1204   widget_props[PROP_FOCUS_ON_CLICK] =
1205       g_param_spec_boolean ("focus-on-click",
1206                             P_("Focus on click"),
1207                             P_("Whether the widget should grab focus when it is clicked with the mouse"),
1208                             TRUE,
1209                             GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
1210 
1211   widget_props[PROP_CAN_DEFAULT] =
1212       g_param_spec_boolean ("can-default",
1213                             P_("Can default"),
1214                             P_("Whether the widget can be the default widget"),
1215                             FALSE,
1216                             GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
1217 
1218   widget_props[PROP_HAS_DEFAULT] =
1219       g_param_spec_boolean ("has-default",
1220                             P_("Has default"),
1221                             P_("Whether the widget is the default widget"),
1222                             FALSE,
1223                             GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
1224 
1225   widget_props[PROP_RECEIVES_DEFAULT] =
1226       g_param_spec_boolean ("receives-default",
1227                             P_("Receives default"),
1228                             P_("If TRUE, the widget will receive the default action when it is focused"),
1229                             FALSE,
1230                             GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
1231 
1232   widget_props[PROP_COMPOSITE_CHILD] =
1233       g_param_spec_boolean ("composite-child",
1234                             P_("Composite child"),
1235                             P_("Whether the widget is part of a composite widget"),
1236                             FALSE,
1237                             GTK_PARAM_READABLE);
1238 
1239 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
1240 
1241   /**
1242    * GtkWidget:style:
1243    *
1244    * The style of the widget, which contains information about how it will look (colors, etc).
1245    *
1246    * Deprecated: Use #GtkStyleContext instead
1247    */
1248   widget_props[PROP_STYLE] =
1249       g_param_spec_object ("style",
1250                            P_("Style"),
1251                            P_("The style of the widget, which contains information about how it will look (colors etc)"),
1252                            GTK_TYPE_STYLE,
1253                            GTK_PARAM_READWRITE|G_PARAM_DEPRECATED);
1254 
1255 G_GNUC_END_IGNORE_DEPRECATIONS
1256 
1257   widget_props[PROP_EVENTS] =
1258       g_param_spec_flags ("events",
1259                           P_("Events"),
1260                           P_("The event mask that decides what kind of GdkEvents this widget gets"),
1261                           GDK_TYPE_EVENT_MASK,
1262                           GDK_STRUCTURE_MASK,
1263                           GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
1264 
1265   widget_props[PROP_NO_SHOW_ALL] =
1266       g_param_spec_boolean ("no-show-all",
1267                             P_("No show all"),
1268                             P_("Whether gtk_widget_show_all() should not affect this widget"),
1269                             FALSE,
1270                             GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
1271 
1272 /**
1273  * GtkWidget:has-tooltip:
1274  *
1275  * Enables or disables the emission of #GtkWidget::query-tooltip on @widget.
1276  * A value of %TRUE indicates that @widget can have a tooltip, in this case
1277  * the widget will be queried using #GtkWidget::query-tooltip to determine
1278  * whether it will provide a tooltip or not.
1279  *
1280  * Note that setting this property to %TRUE for the first time will change
1281  * the event masks of the GdkWindows of this widget to include leave-notify
1282  * and motion-notify events.  This cannot and will not be undone when the
1283  * property is set to %FALSE again.
1284  *
1285  * Since: 2.12
1286  */
1287   widget_props[PROP_HAS_TOOLTIP] =
1288       g_param_spec_boolean ("has-tooltip",
1289                             P_("Has tooltip"),
1290                             P_("Whether this widget has a tooltip"),
1291                             FALSE,
1292                             GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
1293 
1294   /**
1295    * GtkWidget:tooltip-text:
1296    *
1297    * Sets the text of tooltip to be the given string.
1298    *
1299    * Also see gtk_tooltip_set_text().
1300    *
1301    * This is a convenience property which will take care of getting the
1302    * tooltip shown if the given string is not %NULL: #GtkWidget:has-tooltip
1303    * will automatically be set to %TRUE and there will be taken care of
1304    * #GtkWidget::query-tooltip in the default signal handler.
1305    *
1306    * Note that if both #GtkWidget:tooltip-text and #GtkWidget:tooltip-markup
1307    * are set, the last one wins.
1308    *
1309    * Since: 2.12
1310    */
1311   widget_props[PROP_TOOLTIP_TEXT] =
1312       g_param_spec_string ("tooltip-text",
1313                            P_("Tooltip Text"),
1314                            P_("The contents of the tooltip for this widget"),
1315                            NULL,
1316                            GTK_PARAM_READWRITE);
1317 
1318   /**
1319    * GtkWidget:tooltip-markup:
1320    *
1321    * Sets the text of tooltip to be the given string, which is marked up
1322    * with the [Pango text markup language][PangoMarkupFormat].
1323    * Also see gtk_tooltip_set_markup().
1324    *
1325    * This is a convenience property which will take care of getting the
1326    * tooltip shown if the given string is not %NULL: #GtkWidget:has-tooltip
1327    * will automatically be set to %TRUE and there will be taken care of
1328    * #GtkWidget::query-tooltip in the default signal handler.
1329    *
1330    * Note that if both #GtkWidget:tooltip-text and #GtkWidget:tooltip-markup
1331    * are set, the last one wins.
1332    *
1333    * Since: 2.12
1334    */
1335   widget_props[PROP_TOOLTIP_MARKUP] =
1336       g_param_spec_string ("tooltip-markup",
1337                            P_("Tooltip markup"),
1338                            P_("The contents of the tooltip for this widget"),
1339                            NULL,
1340                            GTK_PARAM_READWRITE);
1341 
1342   /**
1343    * GtkWidget:window:
1344    *
1345    * The widget's window if it is realized, %NULL otherwise.
1346    *
1347    * Since: 2.14
1348    */
1349   widget_props[PROP_WINDOW] =
1350       g_param_spec_object ("window",
1351                            P_("Window"),
1352                            P_("The widget's window if it is realized"),
1353                            GDK_TYPE_WINDOW,
1354                            GTK_PARAM_READABLE);
1355 
1356   /**
1357    * GtkWidget:double-buffered:
1358    *
1359    * Whether the widget is double buffered.
1360    *
1361    * Since: 2.18
1362    *
1363    * Deprecated: 3.14: Widgets should not use this property.
1364    */
1365   widget_props[PROP_DOUBLE_BUFFERED] =
1366       g_param_spec_boolean ("double-buffered",
1367                             P_("Double Buffered"),
1368                             P_("Whether the widget is double buffered"),
1369                             TRUE,
1370                             GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY|G_PARAM_DEPRECATED);
1371 
1372   /**
1373    * GtkWidget:halign:
1374    *
1375    * How to distribute horizontal space if widget gets extra space, see #GtkAlign
1376    *
1377    * Since: 3.0
1378    */
1379   widget_props[PROP_HALIGN] =
1380       g_param_spec_enum ("halign",
1381                          P_("Horizontal Alignment"),
1382                          P_("How to position in extra horizontal space"),
1383                          GTK_TYPE_ALIGN,
1384                          GTK_ALIGN_FILL,
1385                          GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
1386 
1387   /**
1388    * GtkWidget:valign:
1389    *
1390    * How to distribute vertical space if widget gets extra space, see #GtkAlign
1391    *
1392    * Since: 3.0
1393    */
1394   widget_props[PROP_VALIGN] =
1395       g_param_spec_enum ("valign",
1396                          P_("Vertical Alignment"),
1397                          P_("How to position in extra vertical space"),
1398                          GTK_TYPE_ALIGN,
1399                          GTK_ALIGN_FILL,
1400                          GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
1401 
1402   /**
1403    * GtkWidget:margin-left:
1404    *
1405    * Margin on left side of widget.
1406    *
1407    * This property adds margin outside of the widget's normal size
1408    * request, the margin will be added in addition to the size from
1409    * gtk_widget_set_size_request() for example.
1410    *
1411    * Deprecated: 3.12: Use #GtkWidget:margin-start instead.
1412    *
1413    * Since: 3.0
1414    */
1415   widget_props[PROP_MARGIN_LEFT] =
1416       g_param_spec_int ("margin-left",
1417                         P_("Margin on Left"),
1418                         P_("Pixels of extra space on the left side"),
1419                         0, G_MAXINT16,
1420                         0,
1421                         GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY|G_PARAM_DEPRECATED);
1422 
1423   /**
1424    * GtkWidget:margin-right:
1425    *
1426    * Margin on right side of widget.
1427    *
1428    * This property adds margin outside of the widget's normal size
1429    * request, the margin will be added in addition to the size from
1430    * gtk_widget_set_size_request() for example.
1431    *
1432    * Deprecated: 3.12: Use #GtkWidget:margin-end instead.
1433    *
1434    * Since: 3.0
1435    */
1436   widget_props[PROP_MARGIN_RIGHT] =
1437       g_param_spec_int ("margin-right",
1438                         P_("Margin on Right"),
1439                         P_("Pixels of extra space on the right side"),
1440                         0, G_MAXINT16,
1441                         0,
1442                         GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY|G_PARAM_DEPRECATED);
1443 
1444   /**
1445    * GtkWidget:margin-start:
1446    *
1447    * Margin on start of widget, horizontally. This property supports
1448    * left-to-right and right-to-left text directions.
1449    *
1450    * This property adds margin outside of the widget's normal size
1451    * request, the margin will be added in addition to the size from
1452    * gtk_widget_set_size_request() for example.
1453    *
1454    * Since: 3.12
1455    */
1456   widget_props[PROP_MARGIN_START] =
1457       g_param_spec_int ("margin-start",
1458                         P_("Margin on Start"),
1459                         P_("Pixels of extra space on the start"),
1460                         0, G_MAXINT16,
1461                         0,
1462                         GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
1463 
1464   /**
1465    * GtkWidget:margin-end:
1466    *
1467    * Margin on end of widget, horizontally. This property supports
1468    * left-to-right and right-to-left text directions.
1469    *
1470    * This property adds margin outside of the widget's normal size
1471    * request, the margin will be added in addition to the size from
1472    * gtk_widget_set_size_request() for example.
1473    *
1474    * Since: 3.12
1475    */
1476   widget_props[PROP_MARGIN_END] =
1477       g_param_spec_int ("margin-end",
1478                         P_("Margin on End"),
1479                         P_("Pixels of extra space on the end"),
1480                         0, G_MAXINT16,
1481                         0,
1482                         GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
1483 
1484   /**
1485    * GtkWidget:margin-top:
1486    *
1487    * Margin on top side of widget.
1488    *
1489    * This property adds margin outside of the widget's normal size
1490    * request, the margin will be added in addition to the size from
1491    * gtk_widget_set_size_request() for example.
1492    *
1493    * Since: 3.0
1494    */
1495   widget_props[PROP_MARGIN_TOP] =
1496       g_param_spec_int ("margin-top",
1497                         P_("Margin on Top"),
1498                         P_("Pixels of extra space on the top side"),
1499                         0, G_MAXINT16,
1500                         0,
1501                         GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
1502 
1503   /**
1504    * GtkWidget:margin-bottom:
1505    *
1506    * Margin on bottom side of widget.
1507    *
1508    * This property adds margin outside of the widget's normal size
1509    * request, the margin will be added in addition to the size from
1510    * gtk_widget_set_size_request() for example.
1511    *
1512    * Since: 3.0
1513    */
1514   widget_props[PROP_MARGIN_BOTTOM] =
1515       g_param_spec_int ("margin-bottom",
1516                         P_("Margin on Bottom"),
1517                         P_("Pixels of extra space on the bottom side"),
1518                         0, G_MAXINT16,
1519                         0,
1520                         GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
1521 
1522   /**
1523    * GtkWidget:margin:
1524    *
1525    * Sets all four sides' margin at once. If read, returns max
1526    * margin on any side.
1527    *
1528    * Since: 3.0
1529    */
1530   widget_props[PROP_MARGIN] =
1531       g_param_spec_int ("margin",
1532                         P_("All Margins"),
1533                         P_("Pixels of extra space on all four sides"),
1534                         0, G_MAXINT16,
1535                         0,
1536                         GTK_PARAM_READWRITE);
1537 
1538   /**
1539    * GtkWidget:hexpand:
1540    *
1541    * Whether to expand horizontally. See gtk_widget_set_hexpand().
1542    *
1543    * Since: 3.0
1544    */
1545   widget_props[PROP_HEXPAND] =
1546       g_param_spec_boolean ("hexpand",
1547                             P_("Horizontal Expand"),
1548                             P_("Whether widget wants more horizontal space"),
1549                             FALSE,
1550                             GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
1551 
1552   /**
1553    * GtkWidget:hexpand-set:
1554    *
1555    * Whether to use the #GtkWidget:hexpand property. See gtk_widget_get_hexpand_set().
1556    *
1557    * Since: 3.0
1558    */
1559   widget_props[PROP_HEXPAND_SET] =
1560       g_param_spec_boolean ("hexpand-set",
1561                             P_("Horizontal Expand Set"),
1562                             P_("Whether to use the hexpand property"),
1563                             FALSE,
1564                             GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
1565 
1566   /**
1567    * GtkWidget:vexpand:
1568    *
1569    * Whether to expand vertically. See gtk_widget_set_vexpand().
1570    *
1571    * Since: 3.0
1572    */
1573   widget_props[PROP_VEXPAND] =
1574       g_param_spec_boolean ("vexpand",
1575                             P_("Vertical Expand"),
1576                             P_("Whether widget wants more vertical space"),
1577                             FALSE,
1578                             GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
1579 
1580   /**
1581    * GtkWidget:vexpand-set:
1582    *
1583    * Whether to use the #GtkWidget:vexpand property. See gtk_widget_get_vexpand_set().
1584    *
1585    * Since: 3.0
1586    */
1587   widget_props[PROP_VEXPAND_SET] =
1588       g_param_spec_boolean ("vexpand-set",
1589                             P_("Vertical Expand Set"),
1590                             P_("Whether to use the vexpand property"),
1591                             FALSE,
1592                             GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
1593 
1594   /**
1595    * GtkWidget:expand:
1596    *
1597    * Whether to expand in both directions. Setting this sets both #GtkWidget:hexpand and #GtkWidget:vexpand
1598    *
1599    * Since: 3.0
1600    */
1601   widget_props[PROP_EXPAND] =
1602       g_param_spec_boolean ("expand",
1603                             P_("Expand Both"),
1604                             P_("Whether widget wants to expand in both directions"),
1605                             FALSE,
1606                             GTK_PARAM_READWRITE);
1607 
1608   /**
1609    * GtkWidget:opacity:
1610    *
1611    * The requested opacity of the widget. See gtk_widget_set_opacity() for
1612    * more details about window opacity.
1613    *
1614    * Before 3.8 this was only available in GtkWindow
1615    *
1616    * Since: 3.8
1617    */
1618   widget_props[PROP_OPACITY] =
1619       g_param_spec_double ("opacity",
1620                            P_("Opacity for Widget"),
1621                            P_("The opacity of the widget, from 0 to 1"),
1622                            0.0, 1.0,
1623                            1.0,
1624                            GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
1625 
1626   /**
1627    * GtkWidget:scale-factor:
1628    *
1629    * The scale factor of the widget. See gtk_widget_get_scale_factor() for
1630    * more details about widget scaling.
1631    *
1632    * Since: 3.10
1633    */
1634   widget_props[PROP_SCALE_FACTOR] =
1635       g_param_spec_int ("scale-factor",
1636                         P_("Scale factor"),
1637                         P_("The scaling factor of the window"),
1638                         1, G_MAXINT,
1639                         1,
1640                         GTK_PARAM_READABLE);
1641 
1642   g_object_class_install_properties (gobject_class, NUM_PROPERTIES, widget_props);
1643 
1644   /**
1645    * GtkWidget::destroy:
1646    * @object: the object which received the signal
1647    *
1648    * Signals that all holders of a reference to the widget should release
1649    * the reference that they hold. May result in finalization of the widget
1650    * if all references are released.
1651    *
1652    * This signal is not suitable for saving widget state.
1653    */
1654   widget_signals[DESTROY] =
1655     g_signal_new (I_("destroy"),
1656                   G_TYPE_FROM_CLASS (gobject_class),
1657                   G_SIGNAL_RUN_CLEANUP | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
1658                   G_STRUCT_OFFSET (GtkWidgetClass, destroy),
1659                   NULL, NULL,
1660                   NULL,
1661                   G_TYPE_NONE, 0);
1662 
1663   /**
1664    * GtkWidget::show:
1665    * @widget: the object which received the signal.
1666    *
1667    * The ::show signal is emitted when @widget is shown, for example with
1668    * gtk_widget_show().
1669    */
1670   widget_signals[SHOW] =
1671     g_signal_new (I_("show"),
1672 		  G_TYPE_FROM_CLASS (gobject_class),
1673 		  G_SIGNAL_RUN_FIRST,
1674 		  G_STRUCT_OFFSET (GtkWidgetClass, show),
1675 		  NULL, NULL,
1676 		  NULL,
1677 		  G_TYPE_NONE, 0);
1678 
1679   /**
1680    * GtkWidget::hide:
1681    * @widget: the object which received the signal.
1682    *
1683    * The ::hide signal is emitted when @widget is hidden, for example with
1684    * gtk_widget_hide().
1685    */
1686   widget_signals[HIDE] =
1687     g_signal_new (I_("hide"),
1688 		  G_TYPE_FROM_CLASS (gobject_class),
1689 		  G_SIGNAL_RUN_FIRST,
1690 		  G_STRUCT_OFFSET (GtkWidgetClass, hide),
1691 		  NULL, NULL,
1692 		  NULL,
1693 		  G_TYPE_NONE, 0);
1694 
1695   /**
1696    * GtkWidget::map:
1697    * @widget: the object which received the signal.
1698    *
1699    * The ::map signal is emitted when @widget is going to be mapped, that is
1700    * when the widget is visible (which is controlled with
1701    * gtk_widget_set_visible()) and all its parents up to the toplevel widget
1702    * are also visible. Once the map has occurred, #GtkWidget::map-event will
1703    * be emitted.
1704    *
1705    * The ::map signal can be used to determine whether a widget will be drawn,
1706    * for instance it can resume an animation that was stopped during the
1707    * emission of #GtkWidget::unmap.
1708    */
1709   widget_signals[MAP] =
1710     g_signal_new (I_("map"),
1711 		  G_TYPE_FROM_CLASS (gobject_class),
1712 		  G_SIGNAL_RUN_FIRST,
1713 		  G_STRUCT_OFFSET (GtkWidgetClass, map),
1714 		  NULL, NULL,
1715 		  NULL,
1716 		  G_TYPE_NONE, 0);
1717 
1718   /**
1719    * GtkWidget::unmap:
1720    * @widget: the object which received the signal.
1721    *
1722    * The ::unmap signal is emitted when @widget is going to be unmapped, which
1723    * means that either it or any of its parents up to the toplevel widget have
1724    * been set as hidden.
1725    *
1726    * As ::unmap indicates that a widget will not be shown any longer, it can be
1727    * used to, for example, stop an animation on the widget.
1728    */
1729   widget_signals[UNMAP] =
1730     g_signal_new (I_("unmap"),
1731 		  G_TYPE_FROM_CLASS (gobject_class),
1732 		  G_SIGNAL_RUN_FIRST,
1733 		  G_STRUCT_OFFSET (GtkWidgetClass, unmap),
1734 		  NULL, NULL,
1735 		  NULL,
1736 		  G_TYPE_NONE, 0);
1737 
1738   /**
1739    * GtkWidget::realize:
1740    * @widget: the object which received the signal.
1741    *
1742    * The ::realize signal is emitted when @widget is associated with a
1743    * #GdkWindow, which means that gtk_widget_realize() has been called or the
1744    * widget has been mapped (that is, it is going to be drawn).
1745    */
1746   widget_signals[REALIZE] =
1747     g_signal_new (I_("realize"),
1748 		  G_TYPE_FROM_CLASS (gobject_class),
1749 		  G_SIGNAL_RUN_FIRST,
1750 		  G_STRUCT_OFFSET (GtkWidgetClass, realize),
1751 		  NULL, NULL,
1752 		  NULL,
1753 		  G_TYPE_NONE, 0);
1754 
1755   /**
1756    * GtkWidget::unrealize:
1757    * @widget: the object which received the signal.
1758    *
1759    * The ::unrealize signal is emitted when the #GdkWindow associated with
1760    * @widget is destroyed, which means that gtk_widget_unrealize() has been
1761    * called or the widget has been unmapped (that is, it is going to be
1762    * hidden).
1763    */
1764   widget_signals[UNREALIZE] =
1765     g_signal_new (I_("unrealize"),
1766 		  G_TYPE_FROM_CLASS (gobject_class),
1767 		  G_SIGNAL_RUN_LAST,
1768 		  G_STRUCT_OFFSET (GtkWidgetClass, unrealize),
1769 		  NULL, NULL,
1770 		  NULL,
1771 		  G_TYPE_NONE, 0);
1772 
1773   /**
1774    * GtkWidget::size-allocate:
1775    * @widget: the object which received the signal.
1776    * @allocation: (type Gtk.Allocation): the region which has been
1777    *   allocated to the widget.
1778    */
1779   widget_signals[SIZE_ALLOCATE] =
1780     g_signal_new (I_("size-allocate"),
1781 		  G_TYPE_FROM_CLASS (gobject_class),
1782 		  G_SIGNAL_RUN_FIRST,
1783 		  G_STRUCT_OFFSET (GtkWidgetClass, size_allocate),
1784 		  NULL, NULL,
1785 		  NULL,
1786 		  G_TYPE_NONE, 1,
1787 		  GDK_TYPE_RECTANGLE | G_SIGNAL_TYPE_STATIC_SCOPE);
1788 
1789   /**
1790    * GtkWidget::state-changed:
1791    * @widget: the object which received the signal.
1792    * @state: the previous state
1793    *
1794    * The ::state-changed signal is emitted when the widget state changes.
1795    * See gtk_widget_get_state().
1796    *
1797    * Deprecated: 3.0: Use #GtkWidget::state-flags-changed instead.
1798    */
1799   widget_signals[STATE_CHANGED] =
1800     g_signal_new (I_("state-changed"),
1801 		  G_TYPE_FROM_CLASS (gobject_class),
1802 		  G_SIGNAL_RUN_FIRST | G_SIGNAL_DEPRECATED,
1803 		  G_STRUCT_OFFSET (GtkWidgetClass, state_changed),
1804 		  NULL, NULL,
1805 		  NULL,
1806 		  G_TYPE_NONE, 1,
1807 		  GTK_TYPE_STATE_TYPE);
1808 
1809   /**
1810    * GtkWidget::state-flags-changed:
1811    * @widget: the object which received the signal.
1812    * @flags: The previous state flags.
1813    *
1814    * The ::state-flags-changed signal is emitted when the widget state
1815    * changes, see gtk_widget_get_state_flags().
1816    *
1817    * Since: 3.0
1818    */
1819   widget_signals[STATE_FLAGS_CHANGED] =
1820     g_signal_new (I_("state-flags-changed"),
1821                   G_TYPE_FROM_CLASS (gobject_class),
1822                   G_SIGNAL_RUN_FIRST,
1823                   G_STRUCT_OFFSET (GtkWidgetClass, state_flags_changed),
1824                   NULL, NULL,
1825                   NULL,
1826                   G_TYPE_NONE, 1,
1827                   GTK_TYPE_STATE_FLAGS);
1828 
1829   /**
1830    * GtkWidget::parent-set:
1831    * @widget: the object on which the signal is emitted
1832    * @old_parent: (allow-none): the previous parent, or %NULL if the widget
1833    *   just got its initial parent.
1834    *
1835    * The ::parent-set signal is emitted when a new parent
1836    * has been set on a widget.
1837    */
1838   widget_signals[PARENT_SET] =
1839     g_signal_new (I_("parent-set"),
1840 		  G_TYPE_FROM_CLASS (gobject_class),
1841 		  G_SIGNAL_RUN_FIRST,
1842 		  G_STRUCT_OFFSET (GtkWidgetClass, parent_set),
1843 		  NULL, NULL,
1844 		  NULL,
1845 		  G_TYPE_NONE, 1,
1846 		  GTK_TYPE_WIDGET);
1847 
1848   /**
1849    * GtkWidget::hierarchy-changed:
1850    * @widget: the object on which the signal is emitted
1851    * @previous_toplevel: (allow-none): the previous toplevel ancestor, or %NULL
1852    *   if the widget was previously unanchored
1853    *
1854    * The ::hierarchy-changed signal is emitted when the
1855    * anchored state of a widget changes. A widget is
1856    * “anchored” when its toplevel
1857    * ancestor is a #GtkWindow. This signal is emitted when
1858    * a widget changes from un-anchored to anchored or vice-versa.
1859    */
1860   widget_signals[HIERARCHY_CHANGED] =
1861     g_signal_new (I_("hierarchy-changed"),
1862 		  G_TYPE_FROM_CLASS (gobject_class),
1863 		  G_SIGNAL_RUN_LAST,
1864 		  G_STRUCT_OFFSET (GtkWidgetClass, hierarchy_changed),
1865 		  NULL, NULL,
1866 		  NULL,
1867 		  G_TYPE_NONE, 1,
1868 		  GTK_TYPE_WIDGET);
1869 
1870   /**
1871    * GtkWidget::style-set:
1872    * @widget: the object on which the signal is emitted
1873    * @previous_style: (allow-none): the previous style, or %NULL if the widget
1874    *   just got its initial style
1875    *
1876    * The ::style-set signal is emitted when a new style has been set
1877    * on a widget. Note that style-modifying functions like
1878    * gtk_widget_modify_base() also cause this signal to be emitted.
1879    *
1880    * Note that this signal is emitted for changes to the deprecated
1881    * #GtkStyle. To track changes to the #GtkStyleContext associated
1882    * with a widget, use the #GtkWidget::style-updated signal.
1883    *
1884    * Deprecated:3.0: Use the #GtkWidget::style-updated signal
1885    */
1886 
1887 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
1888 
1889   widget_signals[STYLE_SET] =
1890     g_signal_new (I_("style-set"),
1891 		  G_TYPE_FROM_CLASS (gobject_class),
1892 		  G_SIGNAL_RUN_FIRST | G_SIGNAL_DEPRECATED,
1893 		  G_STRUCT_OFFSET (GtkWidgetClass, style_set),
1894 		  NULL, NULL,
1895 		  NULL,
1896 		  G_TYPE_NONE, 1,
1897 		  GTK_TYPE_STYLE);
1898 
1899 G_GNUC_END_IGNORE_DEPRECATIONS
1900 
1901   /**
1902    * GtkWidget::style-updated:
1903    * @widget: the object on which the signal is emitted
1904    *
1905    * The ::style-updated signal is a convenience signal that is emitted when the
1906    * #GtkStyleContext::changed signal is emitted on the @widget's associated
1907    * #GtkStyleContext as returned by gtk_widget_get_style_context().
1908    *
1909    * Note that style-modifying functions like gtk_widget_override_color() also
1910    * cause this signal to be emitted.
1911    *
1912    * Since: 3.0
1913    */
1914   widget_signals[STYLE_UPDATED] =
1915     g_signal_new (I_("style-updated"),
1916                   G_TYPE_FROM_CLASS (gobject_class),
1917                   G_SIGNAL_RUN_FIRST,
1918                   G_STRUCT_OFFSET (GtkWidgetClass, style_updated),
1919                   NULL, NULL,
1920                   NULL,
1921                   G_TYPE_NONE, 0);
1922 
1923   /**
1924    * GtkWidget::direction-changed:
1925    * @widget: the object on which the signal is emitted
1926    * @previous_direction: the previous text direction of @widget
1927    *
1928    * The ::direction-changed signal is emitted when the text direction
1929    * of a widget changes.
1930    */
1931   widget_signals[DIRECTION_CHANGED] =
1932     g_signal_new (I_("direction-changed"),
1933 		  G_TYPE_FROM_CLASS (gobject_class),
1934 		  G_SIGNAL_RUN_FIRST,
1935 		  G_STRUCT_OFFSET (GtkWidgetClass, direction_changed),
1936 		  NULL, NULL,
1937 		  NULL,
1938 		  G_TYPE_NONE, 1,
1939 		  GTK_TYPE_TEXT_DIRECTION);
1940 
1941   /**
1942    * GtkWidget::grab-notify:
1943    * @widget: the object which received the signal
1944    * @was_grabbed: %FALSE if the widget becomes shadowed, %TRUE
1945    *               if it becomes unshadowed
1946    *
1947    * The ::grab-notify signal is emitted when a widget becomes
1948    * shadowed by a GTK+ grab (not a pointer or keyboard grab) on
1949    * another widget, or when it becomes unshadowed due to a grab
1950    * being removed.
1951    *
1952    * A widget is shadowed by a gtk_grab_add() when the topmost
1953    * grab widget in the grab stack of its window group is not
1954    * its ancestor.
1955    */
1956   widget_signals[GRAB_NOTIFY] =
1957     g_signal_new (I_("grab-notify"),
1958 		  G_TYPE_FROM_CLASS (gobject_class),
1959 		  G_SIGNAL_RUN_FIRST,
1960                   G_STRUCT_OFFSET (GtkWidgetClass, grab_notify),
1961 		  NULL, NULL,
1962 		  NULL,
1963 		  G_TYPE_NONE, 1,
1964 		  G_TYPE_BOOLEAN);
1965 
1966   /**
1967    * GtkWidget::child-notify:
1968    * @widget: the object which received the signal
1969    * @child_property: the #GParamSpec of the changed child property
1970    *
1971    * The ::child-notify signal is emitted for each
1972    * [child property][child-properties]  that has
1973    * changed on an object. The signal's detail holds the property name.
1974    */
1975   widget_signals[CHILD_NOTIFY] =
1976     g_signal_new (I_("child-notify"),
1977 		   G_TYPE_FROM_CLASS (gobject_class),
1978 		   G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED | G_SIGNAL_NO_HOOKS,
1979 		   G_STRUCT_OFFSET (GtkWidgetClass, child_notify),
1980 		   NULL, NULL,
1981 		   NULL,
1982 		   G_TYPE_NONE, 1,
1983 		   G_TYPE_PARAM);
1984 
1985   /**
1986    * GtkWidget::draw:
1987    * @widget: the object which received the signal
1988    * @cr: the cairo context to draw to
1989    *
1990    * This signal is emitted when a widget is supposed to render itself.
1991    * The @widget's top left corner must be painted at the origin of
1992    * the passed in context and be sized to the values returned by
1993    * gtk_widget_get_allocated_width() and
1994    * gtk_widget_get_allocated_height().
1995    *
1996    * Signal handlers connected to this signal can modify the cairo
1997    * context passed as @cr in any way they like and don't need to
1998    * restore it. The signal emission takes care of calling cairo_save()
1999    * before and cairo_restore() after invoking the handler.
2000    *
2001    * The signal handler will get a @cr with a clip region already set to the
2002    * widget's dirty region, i.e. to the area that needs repainting.  Complicated
2003    * widgets that want to avoid redrawing themselves completely can get the full
2004    * extents of the clip region with gdk_cairo_get_clip_rectangle(), or they can
2005    * get a finer-grained representation of the dirty region with
2006    * cairo_copy_clip_rectangle_list().
2007    *
2008    * Returns: %TRUE to stop other handlers from being invoked for the event.
2009    * %FALSE to propagate the event further.
2010    *
2011    * Since: 3.0
2012    */
2013   widget_signals[DRAW] =
2014     g_signal_new (I_("draw"),
2015 		   G_TYPE_FROM_CLASS (gobject_class),
2016 		   G_SIGNAL_RUN_LAST,
2017 		   G_STRUCT_OFFSET (GtkWidgetClass, draw),
2018                    _gtk_boolean_handled_accumulator, NULL,
2019                    gtk_widget_draw_marshaller,
2020 		   G_TYPE_BOOLEAN, 1,
2021 		   CAIRO_GOBJECT_TYPE_CONTEXT);
2022   g_signal_set_va_marshaller (widget_signals[DRAW], G_TYPE_FROM_CLASS (klass),
2023                               gtk_widget_draw_marshallerv);
2024 
2025   /**
2026    * GtkWidget::mnemonic-activate:
2027    * @widget: the object which received the signal.
2028    * @group_cycling: %TRUE if there are other widgets with the same mnemonic
2029    *
2030    * The default handler for this signal activates @widget if @group_cycling
2031    * is %FALSE, or just makes @widget grab focus if @group_cycling is %TRUE.
2032    *
2033    * Returns: %TRUE to stop other handlers from being invoked for the event.
2034    * %FALSE to propagate the event further.
2035    */
2036   widget_signals[MNEMONIC_ACTIVATE] =
2037     g_signal_new (I_("mnemonic-activate"),
2038 		  G_TYPE_FROM_CLASS (gobject_class),
2039 		  G_SIGNAL_RUN_LAST,
2040 		  G_STRUCT_OFFSET (GtkWidgetClass, mnemonic_activate),
2041 		  _gtk_boolean_handled_accumulator, NULL,
2042 		  _gtk_marshal_BOOLEAN__BOOLEAN,
2043 		  G_TYPE_BOOLEAN, 1,
2044 		  G_TYPE_BOOLEAN);
2045   g_signal_set_va_marshaller (widget_signals[MNEMONIC_ACTIVATE],
2046                               G_TYPE_FROM_CLASS (gobject_class),
2047                               _gtk_marshal_BOOLEAN__BOOLEANv);
2048 
2049   /**
2050    * GtkWidget::grab-focus:
2051    * @widget: the object which received the signal.
2052    */
2053   widget_signals[GRAB_FOCUS] =
2054     g_signal_new (I_("grab-focus"),
2055 		  G_TYPE_FROM_CLASS (gobject_class),
2056 		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
2057 		  G_STRUCT_OFFSET (GtkWidgetClass, grab_focus),
2058 		  NULL, NULL,
2059 		  NULL,
2060 		  G_TYPE_NONE, 0);
2061 
2062   /**
2063    * GtkWidget::focus:
2064    * @widget: the object which received the signal.
2065    * @direction:
2066    *
2067    * Returns: %TRUE to stop other handlers from being invoked for the event. %FALSE to propagate the event further.
2068    */
2069   widget_signals[FOCUS] =
2070     g_signal_new (I_("focus"),
2071 		  G_TYPE_FROM_CLASS (klass),
2072 		  G_SIGNAL_RUN_LAST,
2073 		  G_STRUCT_OFFSET (GtkWidgetClass, focus),
2074 		  _gtk_boolean_handled_accumulator, NULL,
2075 		  _gtk_marshal_BOOLEAN__ENUM,
2076 		  G_TYPE_BOOLEAN, 1,
2077 		  GTK_TYPE_DIRECTION_TYPE);
2078   g_signal_set_va_marshaller (widget_signals[FOCUS],
2079                               G_TYPE_FROM_CLASS (gobject_class),
2080                               _gtk_marshal_BOOLEAN__ENUMv);
2081 
2082   /**
2083    * GtkWidget::move-focus:
2084    * @widget: the object which received the signal.
2085    * @direction:
2086    */
2087   widget_signals[MOVE_FOCUS] =
2088     g_signal_new (I_("move-focus"),
2089                   G_TYPE_FROM_CLASS (klass),
2090                   G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
2091                   G_STRUCT_OFFSET (GtkWidgetClass, move_focus),
2092                   NULL, NULL,
2093                   NULL,
2094                   G_TYPE_NONE,
2095                   1,
2096                   GTK_TYPE_DIRECTION_TYPE);
2097 
2098   /**
2099    * GtkWidget::keynav-failed:
2100    * @widget: the object which received the signal
2101    * @direction: the direction of movement
2102    *
2103    * Gets emitted if keyboard navigation fails.
2104    * See gtk_widget_keynav_failed() for details.
2105    *
2106    * Returns: %TRUE if stopping keyboard navigation is fine, %FALSE
2107    *          if the emitting widget should try to handle the keyboard
2108    *          navigation attempt in its parent container(s).
2109    *
2110    * Since: 2.12
2111    **/
2112   widget_signals[KEYNAV_FAILED] =
2113     g_signal_new (I_("keynav-failed"),
2114                   G_TYPE_FROM_CLASS (klass),
2115                   G_SIGNAL_RUN_LAST,
2116                   G_STRUCT_OFFSET (GtkWidgetClass, keynav_failed),
2117                   _gtk_boolean_handled_accumulator, NULL,
2118                   _gtk_marshal_BOOLEAN__ENUM,
2119                   G_TYPE_BOOLEAN, 1,
2120                   GTK_TYPE_DIRECTION_TYPE);
2121   g_signal_set_va_marshaller (widget_signals[KEYNAV_FAILED],
2122                               G_TYPE_FROM_CLASS (klass),
2123                               _gtk_marshal_BOOLEAN__ENUMv);
2124 
2125   /**
2126    * GtkWidget::event:
2127    * @widget: the object which received the signal.
2128    * @event: the #GdkEvent which triggered this signal
2129    *
2130    * The GTK+ main loop will emit three signals for each GDK event delivered
2131    * to a widget: one generic ::event signal, another, more specific,
2132    * signal that matches the type of event delivered (e.g.
2133    * #GtkWidget::key-press-event) and finally a generic
2134    * #GtkWidget::event-after signal.
2135    *
2136    * Returns: %TRUE to stop other handlers from being invoked for the event
2137    * and to cancel the emission of the second specific ::event signal.
2138    *   %FALSE to propagate the event further and to allow the emission of
2139    *   the second signal. The ::event-after signal is emitted regardless of
2140    *   the return value.
2141    */
2142   widget_signals[EVENT] =
2143     g_signal_new (I_("event"),
2144 		  G_TYPE_FROM_CLASS (klass),
2145 		  G_SIGNAL_RUN_LAST,
2146 		  G_STRUCT_OFFSET (GtkWidgetClass, event),
2147 		  _gtk_boolean_handled_accumulator, NULL,
2148 		  _gtk_marshal_BOOLEAN__BOXED,
2149 		  G_TYPE_BOOLEAN, 1,
2150 		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
2151   g_signal_set_va_marshaller (widget_signals[EVENT], G_TYPE_FROM_CLASS (klass),
2152                               _gtk_marshal_BOOLEAN__BOXEDv);
2153 
2154   /**
2155    * GtkWidget::event-after:
2156    * @widget: the object which received the signal.
2157    * @event: the #GdkEvent which triggered this signal
2158    *
2159    * After the emission of the #GtkWidget::event signal and (optionally)
2160    * the second more specific signal, ::event-after will be emitted
2161    * regardless of the previous two signals handlers return values.
2162    *
2163    */
2164   widget_signals[EVENT_AFTER] =
2165     g_signal_new (I_("event-after"),
2166 		  G_TYPE_FROM_CLASS (klass),
2167 		  0,
2168 		  0,
2169 		  NULL, NULL,
2170 		  NULL,
2171 		  G_TYPE_NONE, 1,
2172 		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
2173 
2174   /**
2175    * GtkWidget::button-press-event:
2176    * @widget: the object which received the signal.
2177    * @event: (type Gdk.EventButton): the #GdkEventButton which triggered
2178    *   this signal.
2179    *
2180    * The ::button-press-event signal will be emitted when a button
2181    * (typically from a mouse) is pressed.
2182    *
2183    * To receive this signal, the #GdkWindow associated to the
2184    * widget needs to enable the #GDK_BUTTON_PRESS_MASK mask.
2185    *
2186    * This signal will be sent to the grab widget if there is one.
2187    *
2188    * Returns: %TRUE to stop other handlers from being invoked for the event.
2189    *   %FALSE to propagate the event further.
2190    */
2191   widget_signals[BUTTON_PRESS_EVENT] =
2192     g_signal_new (I_("button-press-event"),
2193 		  G_TYPE_FROM_CLASS (klass),
2194 		  G_SIGNAL_RUN_LAST,
2195 		  G_STRUCT_OFFSET (GtkWidgetClass, button_press_event),
2196 		  _gtk_boolean_handled_accumulator, NULL,
2197 		  _gtk_marshal_BOOLEAN__BOXED,
2198 		  G_TYPE_BOOLEAN, 1,
2199 		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
2200   g_signal_set_va_marshaller (widget_signals[BUTTON_PRESS_EVENT], G_TYPE_FROM_CLASS (klass),
2201                               _gtk_marshal_BOOLEAN__BOXEDv);
2202 
2203   /**
2204    * GtkWidget::button-release-event:
2205    * @widget: the object which received the signal.
2206    * @event: (type Gdk.EventButton): the #GdkEventButton which triggered
2207    *   this signal.
2208    *
2209    * The ::button-release-event signal will be emitted when a button
2210    * (typically from a mouse) is released.
2211    *
2212    * To receive this signal, the #GdkWindow associated to the
2213    * widget needs to enable the #GDK_BUTTON_RELEASE_MASK mask.
2214    *
2215    * This signal will be sent to the grab widget if there is one.
2216    *
2217    * Returns: %TRUE to stop other handlers from being invoked for the event.
2218    *   %FALSE to propagate the event further.
2219    */
2220   widget_signals[BUTTON_RELEASE_EVENT] =
2221     g_signal_new (I_("button-release-event"),
2222 		  G_TYPE_FROM_CLASS (klass),
2223 		  G_SIGNAL_RUN_LAST,
2224 		  G_STRUCT_OFFSET (GtkWidgetClass, button_release_event),
2225 		  _gtk_boolean_handled_accumulator, NULL,
2226 		  _gtk_marshal_BOOLEAN__BOXED,
2227 		  G_TYPE_BOOLEAN, 1,
2228 		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
2229   g_signal_set_va_marshaller (widget_signals[BUTTON_RELEASE_EVENT], G_TYPE_FROM_CLASS (klass),
2230                               _gtk_marshal_BOOLEAN__BOXEDv);
2231 
2232   widget_signals[TOUCH_EVENT] =
2233     g_signal_new (I_("touch-event"),
2234                   G_TYPE_FROM_CLASS (klass),
2235                   G_SIGNAL_RUN_LAST,
2236                   G_STRUCT_OFFSET (GtkWidgetClass, touch_event),
2237                   _gtk_boolean_handled_accumulator, NULL,
2238                   _gtk_marshal_BOOLEAN__BOXED,
2239                   G_TYPE_BOOLEAN, 1,
2240                   GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
2241   g_signal_set_va_marshaller (widget_signals[TOUCH_EVENT], G_TYPE_FROM_CLASS (klass),
2242                               _gtk_marshal_BOOLEAN__BOXEDv);
2243 
2244   /**
2245    * GtkWidget::scroll-event:
2246    * @widget: the object which received the signal.
2247    * @event: (type Gdk.EventScroll): the #GdkEventScroll which triggered
2248    *   this signal.
2249    *
2250    * The ::scroll-event signal is emitted when a button in the 4 to 7
2251    * range is pressed. Wheel mice are usually configured to generate
2252    * button press events for buttons 4 and 5 when the wheel is turned.
2253    *
2254    * To receive this signal, the #GdkWindow associated to the widget needs
2255    * to enable the #GDK_SCROLL_MASK mask.
2256    *
2257    * This signal will be sent to the grab widget if there is one.
2258    *
2259    * Returns: %TRUE to stop other handlers from being invoked for the event.
2260    *   %FALSE to propagate the event further.
2261    */
2262   widget_signals[SCROLL_EVENT] =
2263     g_signal_new (I_("scroll-event"),
2264 		  G_TYPE_FROM_CLASS (klass),
2265 		  G_SIGNAL_RUN_LAST,
2266 		  G_STRUCT_OFFSET (GtkWidgetClass, scroll_event),
2267 		  _gtk_boolean_handled_accumulator, NULL,
2268 		  _gtk_marshal_BOOLEAN__BOXED,
2269 		  G_TYPE_BOOLEAN, 1,
2270 		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
2271   g_signal_set_va_marshaller (widget_signals[SCROLL_EVENT], G_TYPE_FROM_CLASS (klass),
2272                               _gtk_marshal_BOOLEAN__BOXEDv);
2273 
2274   /**
2275    * GtkWidget::motion-notify-event:
2276    * @widget: the object which received the signal.
2277    * @event: (type Gdk.EventMotion): the #GdkEventMotion which triggered
2278    *   this signal.
2279    *
2280    * The ::motion-notify-event signal is emitted when the pointer moves
2281    * over the widget's #GdkWindow.
2282    *
2283    * To receive this signal, the #GdkWindow associated to the widget
2284    * needs to enable the #GDK_POINTER_MOTION_MASK mask.
2285    *
2286    * This signal will be sent to the grab widget if there is one.
2287    *
2288    * Returns: %TRUE to stop other handlers from being invoked for the event.
2289    *   %FALSE to propagate the event further.
2290    */
2291   widget_signals[MOTION_NOTIFY_EVENT] =
2292     g_signal_new (I_("motion-notify-event"),
2293 		  G_TYPE_FROM_CLASS (klass),
2294 		  G_SIGNAL_RUN_LAST,
2295 		  G_STRUCT_OFFSET (GtkWidgetClass, motion_notify_event),
2296 		  _gtk_boolean_handled_accumulator, NULL,
2297 		  _gtk_marshal_BOOLEAN__BOXED,
2298 		  G_TYPE_BOOLEAN, 1,
2299 		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
2300   g_signal_set_va_marshaller (widget_signals[MOTION_NOTIFY_EVENT], G_TYPE_FROM_CLASS (klass),
2301                               _gtk_marshal_BOOLEAN__BOXEDv);
2302 
2303   /**
2304    * GtkWidget::composited-changed:
2305    * @widget: the object on which the signal is emitted
2306    *
2307    * The ::composited-changed signal is emitted when the composited
2308    * status of @widgets screen changes.
2309    * See gdk_screen_is_composited().
2310    *
2311    * Deprecated: 3.22: Use GdkScreen::composited-changed instead.
2312    */
2313   widget_signals[COMPOSITED_CHANGED] =
2314     g_signal_new (I_("composited-changed"),
2315 		  G_TYPE_FROM_CLASS (klass),
2316 		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION | G_SIGNAL_DEPRECATED,
2317 		  G_STRUCT_OFFSET (GtkWidgetClass, composited_changed),
2318 		  NULL, NULL,
2319 		  NULL,
2320 		  G_TYPE_NONE, 0);
2321 
2322   /**
2323    * GtkWidget::delete-event:
2324    * @widget: the object which received the signal
2325    * @event: the event which triggered this signal
2326    *
2327    * The ::delete-event signal is emitted if a user requests that
2328    * a toplevel window is closed. The default handler for this signal
2329    * destroys the window. Connecting gtk_widget_hide_on_delete() to
2330    * this signal will cause the window to be hidden instead, so that
2331    * it can later be shown again without reconstructing it.
2332    *
2333    * Returns: %TRUE to stop other handlers from being invoked for the event.
2334    *   %FALSE to propagate the event further.
2335    */
2336   widget_signals[DELETE_EVENT] =
2337     g_signal_new (I_("delete-event"),
2338 		  G_TYPE_FROM_CLASS (klass),
2339 		  G_SIGNAL_RUN_LAST,
2340 		  G_STRUCT_OFFSET (GtkWidgetClass, delete_event),
2341 		  _gtk_boolean_handled_accumulator, NULL,
2342 		  _gtk_marshal_BOOLEAN__BOXED,
2343 		  G_TYPE_BOOLEAN, 1,
2344 		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
2345   g_signal_set_va_marshaller (widget_signals[DELETE_EVENT], G_TYPE_FROM_CLASS (klass),
2346                               _gtk_marshal_BOOLEAN__BOXEDv);
2347 
2348   /**
2349    * GtkWidget::destroy-event:
2350    * @widget: the object which received the signal.
2351    * @event: the event which triggered this signal
2352    *
2353    * The ::destroy-event signal is emitted when a #GdkWindow is destroyed.
2354    * You rarely get this signal, because most widgets disconnect themselves
2355    * from their window before they destroy it, so no widget owns the
2356    * window at destroy time.
2357    *
2358    * To receive this signal, the #GdkWindow associated to the widget needs
2359    * to enable the #GDK_STRUCTURE_MASK mask. GDK will enable this mask
2360    * automatically for all new windows.
2361    *
2362    * Returns: %TRUE to stop other handlers from being invoked for the event.
2363    *   %FALSE to propagate the event further.
2364    */
2365   widget_signals[DESTROY_EVENT] =
2366     g_signal_new (I_("destroy-event"),
2367 		  G_TYPE_FROM_CLASS (klass),
2368 		  G_SIGNAL_RUN_LAST,
2369 		  G_STRUCT_OFFSET (GtkWidgetClass, destroy_event),
2370 		  _gtk_boolean_handled_accumulator, NULL,
2371 		  _gtk_marshal_BOOLEAN__BOXED,
2372 		  G_TYPE_BOOLEAN, 1,
2373 		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
2374   g_signal_set_va_marshaller (widget_signals[DESTROY_EVENT], G_TYPE_FROM_CLASS (klass),
2375                               _gtk_marshal_BOOLEAN__BOXEDv);
2376 
2377   /**
2378    * GtkWidget::key-press-event:
2379    * @widget: the object which received the signal
2380    * @event: (type Gdk.EventKey): the #GdkEventKey which triggered this signal.
2381    *
2382    * The ::key-press-event signal is emitted when a key is pressed. The signal
2383    * emission will reoccur at the key-repeat rate when the key is kept pressed.
2384    *
2385    * To receive this signal, the #GdkWindow associated to the widget needs
2386    * to enable the #GDK_KEY_PRESS_MASK mask.
2387    *
2388    * This signal will be sent to the grab widget if there is one.
2389    *
2390    * Returns: %TRUE to stop other handlers from being invoked for the event.
2391    *   %FALSE to propagate the event further.
2392    */
2393   widget_signals[KEY_PRESS_EVENT] =
2394     g_signal_new (I_("key-press-event"),
2395 		  G_TYPE_FROM_CLASS (klass),
2396 		  G_SIGNAL_RUN_LAST,
2397 		  G_STRUCT_OFFSET (GtkWidgetClass, key_press_event),
2398 		  _gtk_boolean_handled_accumulator, NULL,
2399 		  _gtk_marshal_BOOLEAN__BOXED,
2400 		  G_TYPE_BOOLEAN, 1,
2401 		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
2402   g_signal_set_va_marshaller (widget_signals[KEY_PRESS_EVENT], G_TYPE_FROM_CLASS (klass),
2403                               _gtk_marshal_BOOLEAN__BOXEDv);
2404 
2405   /**
2406    * GtkWidget::key-release-event:
2407    * @widget: the object which received the signal
2408    * @event: (type Gdk.EventKey): the #GdkEventKey which triggered this signal.
2409    *
2410    * The ::key-release-event signal is emitted when a key is released.
2411    *
2412    * To receive this signal, the #GdkWindow associated to the widget needs
2413    * to enable the #GDK_KEY_RELEASE_MASK mask.
2414    *
2415    * This signal will be sent to the grab widget if there is one.
2416    *
2417    * Returns: %TRUE to stop other handlers from being invoked for the event.
2418    *   %FALSE to propagate the event further.
2419    */
2420   widget_signals[KEY_RELEASE_EVENT] =
2421     g_signal_new (I_("key-release-event"),
2422 		  G_TYPE_FROM_CLASS (klass),
2423 		  G_SIGNAL_RUN_LAST,
2424 		  G_STRUCT_OFFSET (GtkWidgetClass, key_release_event),
2425 		  _gtk_boolean_handled_accumulator, NULL,
2426 		  _gtk_marshal_BOOLEAN__BOXED,
2427 		  G_TYPE_BOOLEAN, 1,
2428 		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
2429   g_signal_set_va_marshaller (widget_signals[KEY_RELEASE_EVENT], G_TYPE_FROM_CLASS (klass),
2430                               _gtk_marshal_BOOLEAN__BOXEDv);
2431 
2432   /**
2433    * GtkWidget::enter-notify-event:
2434    * @widget: the object which received the signal
2435    * @event: (type Gdk.EventCrossing): the #GdkEventCrossing which triggered
2436    *   this signal.
2437    *
2438    * The ::enter-notify-event will be emitted when the pointer enters
2439    * the @widget's window.
2440    *
2441    * To receive this signal, the #GdkWindow associated to the widget needs
2442    * to enable the #GDK_ENTER_NOTIFY_MASK mask.
2443    *
2444    * This signal will be sent to the grab widget if there is one.
2445    *
2446    * Returns: %TRUE to stop other handlers from being invoked for the event.
2447    *   %FALSE to propagate the event further.
2448    */
2449   widget_signals[ENTER_NOTIFY_EVENT] =
2450     g_signal_new (I_("enter-notify-event"),
2451 		  G_TYPE_FROM_CLASS (klass),
2452 		  G_SIGNAL_RUN_LAST,
2453 		  G_STRUCT_OFFSET (GtkWidgetClass, enter_notify_event),
2454 		  _gtk_boolean_handled_accumulator, NULL,
2455 		  _gtk_marshal_BOOLEAN__BOXED,
2456 		  G_TYPE_BOOLEAN, 1,
2457 		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
2458   g_signal_set_va_marshaller (widget_signals[ENTER_NOTIFY_EVENT], G_TYPE_FROM_CLASS (klass),
2459                               _gtk_marshal_BOOLEAN__BOXEDv);
2460 
2461   /**
2462    * GtkWidget::leave-notify-event:
2463    * @widget: the object which received the signal
2464    * @event: (type Gdk.EventCrossing): the #GdkEventCrossing which triggered
2465    *   this signal.
2466    *
2467    * The ::leave-notify-event will be emitted when the pointer leaves
2468    * the @widget's window.
2469    *
2470    * To receive this signal, the #GdkWindow associated to the widget needs
2471    * to enable the #GDK_LEAVE_NOTIFY_MASK mask.
2472    *
2473    * This signal will be sent to the grab widget if there is one.
2474    *
2475    * Returns: %TRUE to stop other handlers from being invoked for the event.
2476    *   %FALSE to propagate the event further.
2477    */
2478   widget_signals[LEAVE_NOTIFY_EVENT] =
2479     g_signal_new (I_("leave-notify-event"),
2480 		  G_TYPE_FROM_CLASS (klass),
2481 		  G_SIGNAL_RUN_LAST,
2482 		  G_STRUCT_OFFSET (GtkWidgetClass, leave_notify_event),
2483 		  _gtk_boolean_handled_accumulator, NULL,
2484 		  _gtk_marshal_BOOLEAN__BOXED,
2485 		  G_TYPE_BOOLEAN, 1,
2486 		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
2487   g_signal_set_va_marshaller (widget_signals[LEAVE_NOTIFY_EVENT], G_TYPE_FROM_CLASS (klass),
2488                               _gtk_marshal_BOOLEAN__BOXEDv);
2489 
2490   /**
2491    * GtkWidget::configure-event:
2492    * @widget: the object which received the signal
2493    * @event: (type Gdk.EventConfigure): the #GdkEventConfigure which triggered
2494    *   this signal.
2495    *
2496    * The ::configure-event signal will be emitted when the size, position or
2497    * stacking of the @widget's window has changed.
2498    *
2499    * To receive this signal, the #GdkWindow associated to the widget needs
2500    * to enable the #GDK_STRUCTURE_MASK mask. GDK will enable this mask
2501    * automatically for all new windows.
2502    *
2503    * Returns: %TRUE to stop other handlers from being invoked for the event.
2504    *   %FALSE to propagate the event further.
2505    */
2506   widget_signals[CONFIGURE_EVENT] =
2507     g_signal_new (I_("configure-event"),
2508 		  G_TYPE_FROM_CLASS (klass),
2509 		  G_SIGNAL_RUN_LAST,
2510 		  G_STRUCT_OFFSET (GtkWidgetClass, configure_event),
2511 		  _gtk_boolean_handled_accumulator, NULL,
2512 		  _gtk_marshal_BOOLEAN__BOXED,
2513 		  G_TYPE_BOOLEAN, 1,
2514 		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
2515   g_signal_set_va_marshaller (widget_signals[CONFIGURE_EVENT], G_TYPE_FROM_CLASS (klass),
2516                               _gtk_marshal_BOOLEAN__BOXEDv);
2517 
2518   /**
2519    * GtkWidget::focus-in-event:
2520    * @widget: the object which received the signal
2521    * @event: (type Gdk.EventFocus): the #GdkEventFocus which triggered
2522    *   this signal.
2523    *
2524    * The ::focus-in-event signal will be emitted when the keyboard focus
2525    * enters the @widget's window.
2526    *
2527    * To receive this signal, the #GdkWindow associated to the widget needs
2528    * to enable the #GDK_FOCUS_CHANGE_MASK mask.
2529    *
2530    * Returns: %TRUE to stop other handlers from being invoked for the event.
2531    *   %FALSE to propagate the event further.
2532    */
2533   widget_signals[FOCUS_IN_EVENT] =
2534     g_signal_new (I_("focus-in-event"),
2535 		  G_TYPE_FROM_CLASS (klass),
2536 		  G_SIGNAL_RUN_LAST,
2537 		  G_STRUCT_OFFSET (GtkWidgetClass, focus_in_event),
2538 		  _gtk_boolean_handled_accumulator, NULL,
2539 		  _gtk_marshal_BOOLEAN__BOXED,
2540 		  G_TYPE_BOOLEAN, 1,
2541 		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
2542   g_signal_set_va_marshaller (widget_signals[FOCUS_IN_EVENT], G_TYPE_FROM_CLASS (klass),
2543                               _gtk_marshal_BOOLEAN__BOXEDv);
2544 
2545   /**
2546    * GtkWidget::focus-out-event:
2547    * @widget: the object which received the signal
2548    * @event: (type Gdk.EventFocus): the #GdkEventFocus which triggered this
2549    *   signal.
2550    *
2551    * The ::focus-out-event signal will be emitted when the keyboard focus
2552    * leaves the @widget's window.
2553    *
2554    * To receive this signal, the #GdkWindow associated to the widget needs
2555    * to enable the #GDK_FOCUS_CHANGE_MASK mask.
2556    *
2557    * Returns: %TRUE to stop other handlers from being invoked for the event.
2558    *   %FALSE to propagate the event further.
2559    */
2560   widget_signals[FOCUS_OUT_EVENT] =
2561     g_signal_new (I_("focus-out-event"),
2562 		  G_TYPE_FROM_CLASS (klass),
2563 		  G_SIGNAL_RUN_LAST,
2564 		  G_STRUCT_OFFSET (GtkWidgetClass, focus_out_event),
2565 		  _gtk_boolean_handled_accumulator, NULL,
2566 		  _gtk_marshal_BOOLEAN__BOXED,
2567 		  G_TYPE_BOOLEAN, 1,
2568 		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
2569   g_signal_set_va_marshaller (widget_signals[FOCUS_OUT_EVENT], G_TYPE_FROM_CLASS (klass),
2570                               _gtk_marshal_BOOLEAN__BOXEDv);
2571 
2572   /**
2573    * GtkWidget::map-event:
2574    * @widget: the object which received the signal
2575    * @event: (type Gdk.EventAny): the #GdkEventAny which triggered this signal.
2576    *
2577    * The ::map-event signal will be emitted when the @widget's window is
2578    * mapped. A window is mapped when it becomes visible on the screen.
2579    *
2580    * To receive this signal, the #GdkWindow associated to the widget needs
2581    * to enable the #GDK_STRUCTURE_MASK mask. GDK will enable this mask
2582    * automatically for all new windows.
2583    *
2584    * Returns: %TRUE to stop other handlers from being invoked for the event.
2585    *   %FALSE to propagate the event further.
2586    */
2587   widget_signals[MAP_EVENT] =
2588     g_signal_new (I_("map-event"),
2589 		  G_TYPE_FROM_CLASS (klass),
2590 		  G_SIGNAL_RUN_LAST,
2591 		  G_STRUCT_OFFSET (GtkWidgetClass, map_event),
2592 		  _gtk_boolean_handled_accumulator, NULL,
2593 		  _gtk_marshal_BOOLEAN__BOXED,
2594 		  G_TYPE_BOOLEAN, 1,
2595 		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
2596   g_signal_set_va_marshaller (widget_signals[MAP_EVENT], G_TYPE_FROM_CLASS (klass),
2597                               _gtk_marshal_BOOLEAN__BOXEDv);
2598 
2599   /**
2600    * GtkWidget::unmap-event:
2601    * @widget: the object which received the signal
2602    * @event: (type Gdk.EventAny): the #GdkEventAny which triggered this signal
2603    *
2604    * The ::unmap-event signal will be emitted when the @widget's window is
2605    * unmapped. A window is unmapped when it becomes invisible on the screen.
2606    *
2607    * To receive this signal, the #GdkWindow associated to the widget needs
2608    * to enable the #GDK_STRUCTURE_MASK mask. GDK will enable this mask
2609    * automatically for all new windows.
2610    *
2611    * Returns: %TRUE to stop other handlers from being invoked for the event.
2612    *   %FALSE to propagate the event further.
2613    */
2614   widget_signals[UNMAP_EVENT] =
2615     g_signal_new (I_("unmap-event"),
2616 		  G_TYPE_FROM_CLASS (klass),
2617 		  G_SIGNAL_RUN_LAST,
2618 		  G_STRUCT_OFFSET (GtkWidgetClass, unmap_event),
2619 		  _gtk_boolean_handled_accumulator, NULL,
2620 		  _gtk_marshal_BOOLEAN__BOXED,
2621 		  G_TYPE_BOOLEAN, 1,
2622 		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
2623   g_signal_set_va_marshaller (widget_signals[UNMAP_EVENT], G_TYPE_FROM_CLASS (klass),
2624                               _gtk_marshal_BOOLEAN__BOXEDv);
2625 
2626   /**
2627    * GtkWidget::property-notify-event:
2628    * @widget: the object which received the signal
2629    * @event: (type Gdk.EventProperty): the #GdkEventProperty which triggered
2630    *   this signal.
2631    *
2632    * The ::property-notify-event signal will be emitted when a property on
2633    * the @widget's window has been changed or deleted.
2634    *
2635    * To receive this signal, the #GdkWindow associated to the widget needs
2636    * to enable the #GDK_PROPERTY_CHANGE_MASK mask.
2637    *
2638    * Returns: %TRUE to stop other handlers from being invoked for the event.
2639    *   %FALSE to propagate the event further.
2640    */
2641   widget_signals[PROPERTY_NOTIFY_EVENT] =
2642     g_signal_new (I_("property-notify-event"),
2643 		  G_TYPE_FROM_CLASS (klass),
2644 		  G_SIGNAL_RUN_LAST,
2645 		  G_STRUCT_OFFSET (GtkWidgetClass, property_notify_event),
2646 		  _gtk_boolean_handled_accumulator, NULL,
2647 		  _gtk_marshal_BOOLEAN__BOXED,
2648 		  G_TYPE_BOOLEAN, 1,
2649 		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
2650   g_signal_set_va_marshaller (widget_signals[PROPERTY_NOTIFY_EVENT], G_TYPE_FROM_CLASS (klass),
2651                               _gtk_marshal_BOOLEAN__BOXEDv);
2652 
2653   /**
2654    * GtkWidget::selection-clear-event:
2655    * @widget: the object which received the signal
2656    * @event: (type Gdk.EventSelection): the #GdkEventSelection which triggered
2657    *   this signal.
2658    *
2659    * The ::selection-clear-event signal will be emitted when the
2660    * the @widget's window has lost ownership of a selection.
2661    *
2662    * Returns: %TRUE to stop other handlers from being invoked for the event.
2663    *   %FALSE to propagate the event further.
2664    */
2665   widget_signals[SELECTION_CLEAR_EVENT] =
2666     g_signal_new (I_("selection-clear-event"),
2667 		  G_TYPE_FROM_CLASS (klass),
2668 		  G_SIGNAL_RUN_LAST,
2669 		  G_STRUCT_OFFSET (GtkWidgetClass, selection_clear_event),
2670 		  _gtk_boolean_handled_accumulator, NULL,
2671 		  _gtk_marshal_BOOLEAN__BOXED,
2672 		  G_TYPE_BOOLEAN, 1,
2673 		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
2674   g_signal_set_va_marshaller (widget_signals[SELECTION_CLEAR_EVENT], G_TYPE_FROM_CLASS (klass),
2675                               _gtk_marshal_BOOLEAN__BOXEDv);
2676 
2677   /**
2678    * GtkWidget::selection-request-event:
2679    * @widget: the object which received the signal
2680    * @event: (type Gdk.EventSelection): the #GdkEventSelection which triggered
2681    *   this signal.
2682    *
2683    * The ::selection-request-event signal will be emitted when
2684    * another client requests ownership of the selection owned by
2685    * the @widget's window.
2686    *
2687    * Returns: %TRUE to stop other handlers from being invoked for the event.
2688    *   %FALSE to propagate the event further.
2689    */
2690   widget_signals[SELECTION_REQUEST_EVENT] =
2691     g_signal_new (I_("selection-request-event"),
2692 		  G_TYPE_FROM_CLASS (klass),
2693 		  G_SIGNAL_RUN_LAST,
2694 		  G_STRUCT_OFFSET (GtkWidgetClass, selection_request_event),
2695 		  _gtk_boolean_handled_accumulator, NULL,
2696 		  _gtk_marshal_BOOLEAN__BOXED,
2697 		  G_TYPE_BOOLEAN, 1,
2698 		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
2699   g_signal_set_va_marshaller (widget_signals[SELECTION_REQUEST_EVENT], G_TYPE_FROM_CLASS (klass),
2700                               _gtk_marshal_BOOLEAN__BOXEDv);
2701 
2702   /**
2703    * GtkWidget::selection-notify-event:
2704    * @widget: the object which received the signal.
2705    * @event: (type Gdk.EventSelection):
2706    *
2707    * Returns: %TRUE to stop other handlers from being invoked for the event. %FALSE to propagate the event further.
2708    */
2709   widget_signals[SELECTION_NOTIFY_EVENT] =
2710     g_signal_new (I_("selection-notify-event"),
2711 		  G_TYPE_FROM_CLASS (klass),
2712 		  G_SIGNAL_RUN_LAST,
2713 		  G_STRUCT_OFFSET (GtkWidgetClass, selection_notify_event),
2714 		  _gtk_boolean_handled_accumulator, NULL,
2715 		  _gtk_marshal_BOOLEAN__BOXED,
2716 		  G_TYPE_BOOLEAN, 1,
2717 		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
2718   g_signal_set_va_marshaller (widget_signals[SELECTION_NOTIFY_EVENT], G_TYPE_FROM_CLASS (klass),
2719                               _gtk_marshal_BOOLEAN__BOXEDv);
2720 
2721   /**
2722    * GtkWidget::selection-received:
2723    * @widget: the object which received the signal.
2724    * @data:
2725    * @time:
2726    */
2727   widget_signals[SELECTION_RECEIVED] =
2728     g_signal_new (I_("selection-received"),
2729 		  G_TYPE_FROM_CLASS (klass),
2730 		  G_SIGNAL_RUN_LAST,
2731 		  G_STRUCT_OFFSET (GtkWidgetClass, selection_received),
2732 		  NULL, NULL,
2733 		  _gtk_marshal_VOID__BOXED_UINT,
2734 		  G_TYPE_NONE, 2,
2735 		  GTK_TYPE_SELECTION_DATA | G_SIGNAL_TYPE_STATIC_SCOPE,
2736 		  G_TYPE_UINT);
2737   g_signal_set_va_marshaller (widget_signals[SELECTION_RECEIVED],
2738                               G_TYPE_FROM_CLASS (klass),
2739                               _gtk_marshal_VOID__BOXED_UINTv);
2740 
2741   /**
2742    * GtkWidget::selection-get:
2743    * @widget: the object which received the signal.
2744    * @data:
2745    * @info:
2746    * @time:
2747    */
2748   widget_signals[SELECTION_GET] =
2749     g_signal_new (I_("selection-get"),
2750 		  G_TYPE_FROM_CLASS (klass),
2751 		  G_SIGNAL_RUN_LAST,
2752 		  G_STRUCT_OFFSET (GtkWidgetClass, selection_get),
2753 		  NULL, NULL,
2754 		  _gtk_marshal_VOID__BOXED_UINT_UINT,
2755 		  G_TYPE_NONE, 3,
2756 		  GTK_TYPE_SELECTION_DATA | G_SIGNAL_TYPE_STATIC_SCOPE,
2757 		  G_TYPE_UINT,
2758 		  G_TYPE_UINT);
2759   g_signal_set_va_marshaller (widget_signals[SELECTION_GET],
2760                               G_TYPE_FROM_CLASS (klass),
2761                               _gtk_marshal_VOID__BOXED_UINT_UINTv);
2762 
2763   /**
2764    * GtkWidget::proximity-in-event:
2765    * @widget: the object which received the signal
2766    * @event: (type Gdk.EventProximity): the #GdkEventProximity which triggered
2767    *   this signal.
2768    *
2769    * To receive this signal the #GdkWindow associated to the widget needs
2770    * to enable the #GDK_PROXIMITY_IN_MASK mask.
2771    *
2772    * This signal will be sent to the grab widget if there is one.
2773    *
2774    * Returns: %TRUE to stop other handlers from being invoked for the event.
2775    *   %FALSE to propagate the event further.
2776    */
2777   widget_signals[PROXIMITY_IN_EVENT] =
2778     g_signal_new (I_("proximity-in-event"),
2779 		  G_TYPE_FROM_CLASS (klass),
2780 		  G_SIGNAL_RUN_LAST,
2781 		  G_STRUCT_OFFSET (GtkWidgetClass, proximity_in_event),
2782 		  _gtk_boolean_handled_accumulator, NULL,
2783 		  _gtk_marshal_BOOLEAN__BOXED,
2784 		  G_TYPE_BOOLEAN, 1,
2785 		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
2786   g_signal_set_va_marshaller (widget_signals[PROXIMITY_IN_EVENT], G_TYPE_FROM_CLASS (klass),
2787                               _gtk_marshal_BOOLEAN__BOXEDv);
2788 
2789   /**
2790    * GtkWidget::proximity-out-event:
2791    * @widget: the object which received the signal
2792    * @event: (type Gdk.EventProximity): the #GdkEventProximity which triggered
2793    *   this signal.
2794    *
2795    * To receive this signal the #GdkWindow associated to the widget needs
2796    * to enable the #GDK_PROXIMITY_OUT_MASK mask.
2797    *
2798    * This signal will be sent to the grab widget if there is one.
2799    *
2800    * Returns: %TRUE to stop other handlers from being invoked for the event.
2801    *   %FALSE to propagate the event further.
2802    */
2803   widget_signals[PROXIMITY_OUT_EVENT] =
2804     g_signal_new (I_("proximity-out-event"),
2805 		  G_TYPE_FROM_CLASS (klass),
2806 		  G_SIGNAL_RUN_LAST,
2807 		  G_STRUCT_OFFSET (GtkWidgetClass, proximity_out_event),
2808 		  _gtk_boolean_handled_accumulator, NULL,
2809 		  _gtk_marshal_BOOLEAN__BOXED,
2810 		  G_TYPE_BOOLEAN, 1,
2811 		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
2812   g_signal_set_va_marshaller (widget_signals[PROXIMITY_OUT_EVENT], G_TYPE_FROM_CLASS (klass),
2813                               _gtk_marshal_BOOLEAN__BOXEDv);
2814 
2815   /**
2816    * GtkWidget::drag-leave:
2817    * @widget: the object which received the signal.
2818    * @context: the drag context
2819    * @time: the timestamp of the motion event
2820    *
2821    * The ::drag-leave signal is emitted on the drop site when the cursor
2822    * leaves the widget. A typical reason to connect to this signal is to
2823    * undo things done in #GtkWidget::drag-motion, e.g. undo highlighting
2824    * with gtk_drag_unhighlight().
2825    *
2826    *
2827    * Likewise, the #GtkWidget::drag-leave signal is also emitted before the
2828    * ::drag-drop signal, for instance to allow cleaning up of a preview item
2829    * created in the #GtkWidget::drag-motion signal handler.
2830    */
2831   widget_signals[DRAG_LEAVE] =
2832     g_signal_new (I_("drag-leave"),
2833 		  G_TYPE_FROM_CLASS (klass),
2834 		  G_SIGNAL_RUN_LAST,
2835 		  G_STRUCT_OFFSET (GtkWidgetClass, drag_leave),
2836 		  NULL, NULL,
2837 		  _gtk_marshal_VOID__OBJECT_UINT,
2838 		  G_TYPE_NONE, 2,
2839 		  GDK_TYPE_DRAG_CONTEXT,
2840 		  G_TYPE_UINT);
2841   g_signal_set_va_marshaller (widget_signals[DRAG_LEAVE],
2842                               G_TYPE_FROM_CLASS (klass),
2843                               _gtk_marshal_VOID__OBJECT_UINTv);
2844 
2845   /**
2846    * GtkWidget::drag-begin:
2847    * @widget: the object which received the signal
2848    * @context: the drag context
2849    *
2850    * The ::drag-begin signal is emitted on the drag source when a drag is
2851    * started. A typical reason to connect to this signal is to set up a
2852    * custom drag icon with e.g. gtk_drag_source_set_icon_pixbuf().
2853    *
2854    * Note that some widgets set up a drag icon in the default handler of
2855    * this signal, so you may have to use g_signal_connect_after() to
2856    * override what the default handler did.
2857    */
2858   widget_signals[DRAG_BEGIN] =
2859     g_signal_new (I_("drag-begin"),
2860 		  G_TYPE_FROM_CLASS (klass),
2861 		  G_SIGNAL_RUN_LAST,
2862 		  G_STRUCT_OFFSET (GtkWidgetClass, drag_begin),
2863 		  NULL, NULL,
2864 		  NULL,
2865 		  G_TYPE_NONE, 1,
2866 		  GDK_TYPE_DRAG_CONTEXT);
2867 
2868   /**
2869    * GtkWidget::drag-end:
2870    * @widget: the object which received the signal
2871    * @context: the drag context
2872    *
2873    * The ::drag-end signal is emitted on the drag source when a drag is
2874    * finished.  A typical reason to connect to this signal is to undo
2875    * things done in #GtkWidget::drag-begin.
2876    */
2877   widget_signals[DRAG_END] =
2878     g_signal_new (I_("drag-end"),
2879 		  G_TYPE_FROM_CLASS (klass),
2880 		  G_SIGNAL_RUN_LAST,
2881 		  G_STRUCT_OFFSET (GtkWidgetClass, drag_end),
2882 		  NULL, NULL,
2883 		  NULL,
2884 		  G_TYPE_NONE, 1,
2885 		  GDK_TYPE_DRAG_CONTEXT);
2886 
2887   /**
2888    * GtkWidget::drag-data-delete:
2889    * @widget: the object which received the signal
2890    * @context: the drag context
2891    *
2892    * The ::drag-data-delete signal is emitted on the drag source when a drag
2893    * with the action %GDK_ACTION_MOVE is successfully completed. The signal
2894    * handler is responsible for deleting the data that has been dropped. What
2895    * "delete" means depends on the context of the drag operation.
2896    */
2897   widget_signals[DRAG_DATA_DELETE] =
2898     g_signal_new (I_("drag-data-delete"),
2899 		  G_TYPE_FROM_CLASS (klass),
2900 		  G_SIGNAL_RUN_LAST,
2901 		  G_STRUCT_OFFSET (GtkWidgetClass, drag_data_delete),
2902 		  NULL, NULL,
2903 		  NULL,
2904 		  G_TYPE_NONE, 1,
2905 		  GDK_TYPE_DRAG_CONTEXT);
2906 
2907   /**
2908    * GtkWidget::drag-failed:
2909    * @widget: the object which received the signal
2910    * @context: the drag context
2911    * @result: the result of the drag operation
2912    *
2913    * The ::drag-failed signal is emitted on the drag source when a drag has
2914    * failed. The signal handler may hook custom code to handle a failed DnD
2915    * operation based on the type of error, it returns %TRUE is the failure has
2916    * been already handled (not showing the default "drag operation failed"
2917    * animation), otherwise it returns %FALSE.
2918    *
2919    * Returns: %TRUE if the failed drag operation has been already handled.
2920    *
2921    * Since: 2.12
2922    */
2923   widget_signals[DRAG_FAILED] =
2924     g_signal_new (I_("drag-failed"),
2925 		  G_TYPE_FROM_CLASS (klass),
2926 		  G_SIGNAL_RUN_LAST,
2927 		  G_STRUCT_OFFSET (GtkWidgetClass, drag_failed),
2928 		  _gtk_boolean_handled_accumulator, NULL,
2929 		  _gtk_marshal_BOOLEAN__OBJECT_ENUM,
2930 		  G_TYPE_BOOLEAN, 2,
2931 		  GDK_TYPE_DRAG_CONTEXT,
2932 		  GTK_TYPE_DRAG_RESULT);
2933   g_signal_set_va_marshaller (widget_signals[DRAG_FAILED],
2934                               G_TYPE_FROM_CLASS (klass),
2935                               _gtk_marshal_BOOLEAN__OBJECT_ENUMv);
2936 
2937   /**
2938    * GtkWidget::drag-motion:
2939    * @widget: the object which received the signal
2940    * @context: the drag context
2941    * @x: the x coordinate of the current cursor position
2942    * @y: the y coordinate of the current cursor position
2943    * @time: the timestamp of the motion event
2944    *
2945    * The ::drag-motion signal is emitted on the drop site when the user
2946    * moves the cursor over the widget during a drag. The signal handler
2947    * must determine whether the cursor position is in a drop zone or not.
2948    * If it is not in a drop zone, it returns %FALSE and no further processing
2949    * is necessary. Otherwise, the handler returns %TRUE. In this case, the
2950    * handler is responsible for providing the necessary information for
2951    * displaying feedback to the user, by calling gdk_drag_status().
2952    *
2953    * If the decision whether the drop will be accepted or rejected can't be
2954    * made based solely on the cursor position and the type of the data, the
2955    * handler may inspect the dragged data by calling gtk_drag_get_data() and
2956    * defer the gdk_drag_status() call to the #GtkWidget::drag-data-received
2957    * handler. Note that you must pass #GTK_DEST_DEFAULT_DROP,
2958    * #GTK_DEST_DEFAULT_MOTION or #GTK_DEST_DEFAULT_ALL to gtk_drag_dest_set()
2959    * when using the drag-motion signal that way.
2960    *
2961    * Also note that there is no drag-enter signal. The drag receiver has to
2962    * keep track of whether he has received any drag-motion signals since the
2963    * last #GtkWidget::drag-leave and if not, treat the drag-motion signal as
2964    * an "enter" signal. Upon an "enter", the handler will typically highlight
2965    * the drop site with gtk_drag_highlight().
2966    * |[<!-- language="C" -->
2967    * static void
2968    * drag_motion (GtkWidget      *widget,
2969    *              GdkDragContext *context,
2970    *              gint            x,
2971    *              gint            y,
2972    *              guint           time)
2973    * {
2974    *   GdkAtom target;
2975    *
2976    *   PrivateData *private_data = GET_PRIVATE_DATA (widget);
2977    *
2978    *   if (!private_data->drag_highlight)
2979    *    {
2980    *      private_data->drag_highlight = 1;
2981    *      gtk_drag_highlight (widget);
2982    *    }
2983    *
2984    *   target = gtk_drag_dest_find_target (widget, context, NULL);
2985    *   if (target == GDK_NONE)
2986    *     gdk_drag_status (context, 0, time);
2987    *   else
2988    *    {
2989    *      private_data->pending_status
2990    *         = gdk_drag_context_get_suggested_action (context);
2991    *      gtk_drag_get_data (widget, context, target, time);
2992    *    }
2993    *
2994    *   return TRUE;
2995    * }
2996    *
2997    * static void
2998    * drag_data_received (GtkWidget        *widget,
2999    *                     GdkDragContext   *context,
3000    *                     gint              x,
3001    *                     gint              y,
3002    *                     GtkSelectionData *selection_data,
3003    *                     guint             info,
3004    *                     guint             time)
3005    * {
3006    *   PrivateData *private_data = GET_PRIVATE_DATA (widget);
3007    *
3008    *   if (private_data->suggested_action)
3009    *    {
3010    *      private_data->suggested_action = 0;
3011    *
3012    *      // We are getting this data due to a request in drag_motion,
3013    *      // rather than due to a request in drag_drop, so we are just
3014    *      // supposed to call gdk_drag_status(), not actually paste in
3015    *      // the data.
3016    *
3017    *      str = gtk_selection_data_get_text (selection_data);
3018    *      if (!data_is_acceptable (str))
3019    *        gdk_drag_status (context, 0, time);
3020    *      else
3021    *        gdk_drag_status (context,
3022    *                         private_data->suggested_action,
3023    *                         time);
3024    *    }
3025    *   else
3026    *    {
3027    *      // accept the drop
3028    *    }
3029    * }
3030    * ]|
3031    *
3032    * Returns: whether the cursor position is in a drop zone
3033    */
3034   widget_signals[DRAG_MOTION] =
3035     g_signal_new (I_("drag-motion"),
3036 		  G_TYPE_FROM_CLASS (klass),
3037 		  G_SIGNAL_RUN_LAST,
3038 		  G_STRUCT_OFFSET (GtkWidgetClass, drag_motion),
3039 		  _gtk_boolean_handled_accumulator, NULL,
3040 		  _gtk_marshal_BOOLEAN__OBJECT_INT_INT_UINT,
3041 		  G_TYPE_BOOLEAN, 4,
3042 		  GDK_TYPE_DRAG_CONTEXT,
3043 		  G_TYPE_INT,
3044 		  G_TYPE_INT,
3045 		  G_TYPE_UINT);
3046   g_signal_set_va_marshaller (widget_signals[DRAG_MOTION],
3047                               G_TYPE_FROM_CLASS (klass),
3048                               _gtk_marshal_BOOLEAN__OBJECT_INT_INT_UINTv);
3049 
3050   /**
3051    * GtkWidget::drag-drop:
3052    * @widget: the object which received the signal
3053    * @context: the drag context
3054    * @x: the x coordinate of the current cursor position
3055    * @y: the y coordinate of the current cursor position
3056    * @time: the timestamp of the motion event
3057    *
3058    * The ::drag-drop signal is emitted on the drop site when the user drops
3059    * the data onto the widget. The signal handler must determine whether
3060    * the cursor position is in a drop zone or not. If it is not in a drop
3061    * zone, it returns %FALSE and no further processing is necessary.
3062    * Otherwise, the handler returns %TRUE. In this case, the handler must
3063    * ensure that gtk_drag_finish() is called to let the source know that
3064    * the drop is done. The call to gtk_drag_finish() can be done either
3065    * directly or in a #GtkWidget::drag-data-received handler which gets
3066    * triggered by calling gtk_drag_get_data() to receive the data for one
3067    * or more of the supported targets.
3068    *
3069    * Returns: whether the cursor position is in a drop zone
3070    */
3071   widget_signals[DRAG_DROP] =
3072     g_signal_new (I_("drag-drop"),
3073 		  G_TYPE_FROM_CLASS (klass),
3074 		  G_SIGNAL_RUN_LAST,
3075 		  G_STRUCT_OFFSET (GtkWidgetClass, drag_drop),
3076 		  _gtk_boolean_handled_accumulator, NULL,
3077 		  _gtk_marshal_BOOLEAN__OBJECT_INT_INT_UINT,
3078 		  G_TYPE_BOOLEAN, 4,
3079 		  GDK_TYPE_DRAG_CONTEXT,
3080 		  G_TYPE_INT,
3081 		  G_TYPE_INT,
3082 		  G_TYPE_UINT);
3083   g_signal_set_va_marshaller (widget_signals[DRAG_DROP],
3084                               G_TYPE_FROM_CLASS (klass),
3085                               _gtk_marshal_BOOLEAN__OBJECT_INT_INT_UINTv);
3086 
3087   /**
3088    * GtkWidget::drag-data-get:
3089    * @widget: the object which received the signal
3090    * @context: the drag context
3091    * @data: the #GtkSelectionData to be filled with the dragged data
3092    * @info: the info that has been registered with the target in the
3093    *        #GtkTargetList
3094    * @time: the timestamp at which the data was requested
3095    *
3096    * The ::drag-data-get signal is emitted on the drag source when the drop
3097    * site requests the data which is dragged. It is the responsibility of
3098    * the signal handler to fill @data with the data in the format which
3099    * is indicated by @info. See gtk_selection_data_set() and
3100    * gtk_selection_data_set_text().
3101    */
3102   widget_signals[DRAG_DATA_GET] =
3103     g_signal_new (I_("drag-data-get"),
3104 		  G_TYPE_FROM_CLASS (klass),
3105 		  G_SIGNAL_RUN_LAST,
3106 		  G_STRUCT_OFFSET (GtkWidgetClass, drag_data_get),
3107 		  NULL, NULL,
3108 		  _gtk_marshal_VOID__OBJECT_BOXED_UINT_UINT,
3109 		  G_TYPE_NONE, 4,
3110 		  GDK_TYPE_DRAG_CONTEXT,
3111 		  GTK_TYPE_SELECTION_DATA | G_SIGNAL_TYPE_STATIC_SCOPE,
3112 		  G_TYPE_UINT,
3113 		  G_TYPE_UINT);
3114   g_signal_set_va_marshaller (widget_signals[DRAG_DATA_GET],
3115                               G_TYPE_FROM_CLASS (klass),
3116                               _gtk_marshal_VOID__OBJECT_BOXED_UINT_UINTv);
3117 
3118   /**
3119    * GtkWidget::drag-data-received:
3120    * @widget: the object which received the signal
3121    * @context: the drag context
3122    * @x: where the drop happened
3123    * @y: where the drop happened
3124    * @data: the received data
3125    * @info: the info that has been registered with the target in the
3126    *        #GtkTargetList
3127    * @time: the timestamp at which the data was received
3128    *
3129    * The ::drag-data-received signal is emitted on the drop site when the
3130    * dragged data has been received. If the data was received in order to
3131    * determine whether the drop will be accepted, the handler is expected
3132    * to call gdk_drag_status() and not finish the drag.
3133    * If the data was received in response to a #GtkWidget::drag-drop signal
3134    * (and this is the last target to be received), the handler for this
3135    * signal is expected to process the received data and then call
3136    * gtk_drag_finish(), setting the @success parameter depending on
3137    * whether the data was processed successfully.
3138    *
3139    * Applications must create some means to determine why the signal was emitted
3140    * and therefore whether to call gdk_drag_status() or gtk_drag_finish().
3141    *
3142    * The handler may inspect the selected action with
3143    * gdk_drag_context_get_selected_action() before calling
3144    * gtk_drag_finish(), e.g. to implement %GDK_ACTION_ASK as
3145    * shown in the following example:
3146    * |[<!-- language="C" -->
3147    * void
3148    * drag_data_received (GtkWidget          *widget,
3149    *                     GdkDragContext     *context,
3150    *                     gint                x,
3151    *                     gint                y,
3152    *                     GtkSelectionData   *data,
3153    *                     guint               info,
3154    *                     guint               time)
3155    * {
3156    *   if ((data->length >= 0) && (data->format == 8))
3157    *     {
3158    *       GdkDragAction action;
3159    *
3160    *       // handle data here
3161    *
3162    *       action = gdk_drag_context_get_selected_action (context);
3163    *       if (action == GDK_ACTION_ASK)
3164    *         {
3165    *           GtkWidget *dialog;
3166    *           gint response;
3167    *
3168    *           dialog = gtk_message_dialog_new (NULL,
3169    *                                            GTK_DIALOG_MODAL |
3170    *                                            GTK_DIALOG_DESTROY_WITH_PARENT,
3171    *                                            GTK_MESSAGE_INFO,
3172    *                                            GTK_BUTTONS_YES_NO,
3173    *                                            "Move the data ?\n");
3174    *           response = gtk_dialog_run (GTK_DIALOG (dialog));
3175    *           gtk_widget_destroy (dialog);
3176    *
3177    *           if (response == GTK_RESPONSE_YES)
3178    *             action = GDK_ACTION_MOVE;
3179    *           else
3180    *             action = GDK_ACTION_COPY;
3181    *          }
3182    *
3183    *       gtk_drag_finish (context, TRUE, action == GDK_ACTION_MOVE, time);
3184    *     }
3185    *   else
3186    *     gtk_drag_finish (context, FALSE, FALSE, time);
3187    *  }
3188    * ]|
3189    */
3190   widget_signals[DRAG_DATA_RECEIVED] =
3191     g_signal_new (I_("drag-data-received"),
3192 		  G_TYPE_FROM_CLASS (klass),
3193 		  G_SIGNAL_RUN_LAST,
3194 		  G_STRUCT_OFFSET (GtkWidgetClass, drag_data_received),
3195 		  NULL, NULL,
3196 		  _gtk_marshal_VOID__OBJECT_INT_INT_BOXED_UINT_UINT,
3197 		  G_TYPE_NONE, 6,
3198 		  GDK_TYPE_DRAG_CONTEXT,
3199 		  G_TYPE_INT,
3200 		  G_TYPE_INT,
3201 		  GTK_TYPE_SELECTION_DATA | G_SIGNAL_TYPE_STATIC_SCOPE,
3202 		  G_TYPE_UINT,
3203 		  G_TYPE_UINT);
3204    g_signal_set_va_marshaller (widget_signals[DRAG_DATA_RECEIVED],
3205                                G_TYPE_FROM_CLASS (klass),
3206                                _gtk_marshal_VOID__OBJECT_INT_INT_BOXED_UINT_UINTv);
3207 
3208   /**
3209    * GtkWidget::visibility-notify-event:
3210    * @widget: the object which received the signal
3211    * @event: (type Gdk.EventVisibility): the #GdkEventVisibility which
3212    *   triggered this signal.
3213    *
3214    * The ::visibility-notify-event will be emitted when the @widget's
3215    * window is obscured or unobscured.
3216    *
3217    * To receive this signal the #GdkWindow associated to the widget needs
3218    * to enable the #GDK_VISIBILITY_NOTIFY_MASK mask.
3219    *
3220    * Returns: %TRUE to stop other handlers from being invoked for the event.
3221    *   %FALSE to propagate the event further.
3222    *
3223    * Deprecated: 3.12: Modern composited windowing systems with pervasive
3224    *     transparency make it impossible to track the visibility of a window
3225    *     reliably, so this signal can not be guaranteed to provide useful
3226    *     information.
3227    */
3228   widget_signals[VISIBILITY_NOTIFY_EVENT] =
3229     g_signal_new (I_("visibility-notify-event"),
3230 		  G_TYPE_FROM_CLASS (klass),
3231 		  G_SIGNAL_RUN_LAST | G_SIGNAL_DEPRECATED,
3232 		  G_STRUCT_OFFSET (GtkWidgetClass, visibility_notify_event),
3233 		  _gtk_boolean_handled_accumulator, NULL,
3234 		  _gtk_marshal_BOOLEAN__BOXED,
3235 		  G_TYPE_BOOLEAN, 1,
3236 		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
3237   g_signal_set_va_marshaller (widget_signals[VISIBILITY_NOTIFY_EVENT],
3238                               G_TYPE_FROM_CLASS (klass),
3239                               _gtk_marshal_BOOLEAN__BOXEDv);
3240 
3241   /**
3242    * GtkWidget::window-state-event:
3243    * @widget: the object which received the signal
3244    * @event: (type Gdk.EventWindowState): the #GdkEventWindowState which
3245    *   triggered this signal.
3246    *
3247    * The ::window-state-event will be emitted when the state of the
3248    * toplevel window associated to the @widget changes.
3249    *
3250    * To receive this signal the #GdkWindow associated to the widget
3251    * needs to enable the #GDK_STRUCTURE_MASK mask. GDK will enable
3252    * this mask automatically for all new windows.
3253    *
3254    * Returns: %TRUE to stop other handlers from being invoked for the
3255    *   event. %FALSE to propagate the event further.
3256    */
3257   widget_signals[WINDOW_STATE_EVENT] =
3258     g_signal_new (I_("window-state-event"),
3259 		  G_TYPE_FROM_CLASS (klass),
3260 		  G_SIGNAL_RUN_LAST,
3261 		  G_STRUCT_OFFSET (GtkWidgetClass, window_state_event),
3262 		  _gtk_boolean_handled_accumulator, NULL,
3263 		  _gtk_marshal_BOOLEAN__BOXED,
3264 		  G_TYPE_BOOLEAN, 1,
3265 		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
3266   g_signal_set_va_marshaller (widget_signals[WINDOW_STATE_EVENT], G_TYPE_FROM_CLASS (klass),
3267                               _gtk_marshal_BOOLEAN__BOXEDv);
3268 
3269   /**
3270    * GtkWidget::damage-event:
3271    * @widget: the object which received the signal
3272    * @event: (type Gdk.EventExpose): the #GdkEventExpose event
3273    *
3274    * Emitted when a redirected window belonging to @widget gets drawn into.
3275    * The region/area members of the event shows what area of the redirected
3276    * drawable was drawn into.
3277    *
3278    * Returns: %TRUE to stop other handlers from being invoked for the event.
3279    *   %FALSE to propagate the event further.
3280    *
3281    * Since: 2.14
3282    */
3283   widget_signals[DAMAGE_EVENT] =
3284     g_signal_new (I_("damage-event"),
3285 		  G_TYPE_FROM_CLASS (klass),
3286 		  G_SIGNAL_RUN_LAST,
3287 		  G_STRUCT_OFFSET (GtkWidgetClass, damage_event),
3288 		  _gtk_boolean_handled_accumulator, NULL,
3289 		  _gtk_marshal_BOOLEAN__BOXED,
3290 		  G_TYPE_BOOLEAN, 1,
3291 		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
3292   g_signal_set_va_marshaller (widget_signals[DAMAGE_EVENT], G_TYPE_FROM_CLASS (klass),
3293                               _gtk_marshal_BOOLEAN__BOXEDv);
3294 
3295 /**
3296    * GtkWidget::grab-broken-event:
3297    * @widget: the object which received the signal
3298    * @event: (type Gdk.EventGrabBroken): the #GdkEventGrabBroken event
3299    *
3300    * Emitted when a pointer or keyboard grab on a window belonging
3301    * to @widget gets broken.
3302    *
3303    * On X11, this happens when the grab window becomes unviewable
3304    * (i.e. it or one of its ancestors is unmapped), or if the same
3305    * application grabs the pointer or keyboard again.
3306    *
3307    * Returns: %TRUE to stop other handlers from being invoked for
3308    *   the event. %FALSE to propagate the event further.
3309    *
3310    * Since: 2.8
3311    */
3312   widget_signals[GRAB_BROKEN_EVENT] =
3313     g_signal_new (I_("grab-broken-event"),
3314 		  G_TYPE_FROM_CLASS (klass),
3315 		  G_SIGNAL_RUN_LAST,
3316 		  G_STRUCT_OFFSET (GtkWidgetClass, grab_broken_event),
3317 		  _gtk_boolean_handled_accumulator, NULL,
3318 		  _gtk_marshal_BOOLEAN__BOXED,
3319 		  G_TYPE_BOOLEAN, 1,
3320 		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
3321   g_signal_set_va_marshaller (widget_signals[GRAB_BROKEN_EVENT], G_TYPE_FROM_CLASS (klass),
3322                               _gtk_marshal_BOOLEAN__BOXEDv);
3323 
3324   /**
3325    * GtkWidget::query-tooltip:
3326    * @widget: the object which received the signal
3327    * @x: the x coordinate of the cursor position where the request has
3328    *     been emitted, relative to @widget's left side
3329    * @y: the y coordinate of the cursor position where the request has
3330    *     been emitted, relative to @widget's top
3331    * @keyboard_mode: %TRUE if the tooltip was triggered using the keyboard
3332    * @tooltip: a #GtkTooltip
3333    *
3334    * Emitted when #GtkWidget:has-tooltip is %TRUE and the hover timeout
3335    * has expired with the cursor hovering "above" @widget; or emitted when @widget got
3336    * focus in keyboard mode.
3337    *
3338    * Using the given coordinates, the signal handler should determine
3339    * whether a tooltip should be shown for @widget. If this is the case
3340    * %TRUE should be returned, %FALSE otherwise.  Note that if
3341    * @keyboard_mode is %TRUE, the values of @x and @y are undefined and
3342    * should not be used.
3343    *
3344    * The signal handler is free to manipulate @tooltip with the therefore
3345    * destined function calls.
3346    *
3347    * Returns: %TRUE if @tooltip should be shown right now, %FALSE otherwise.
3348    *
3349    * Since: 2.12
3350    */
3351   widget_signals[QUERY_TOOLTIP] =
3352     g_signal_new (I_("query-tooltip"),
3353 		  G_TYPE_FROM_CLASS (klass),
3354 		  G_SIGNAL_RUN_LAST,
3355 		  G_STRUCT_OFFSET (GtkWidgetClass, query_tooltip),
3356 		  _gtk_boolean_handled_accumulator, NULL,
3357 		  _gtk_marshal_BOOLEAN__INT_INT_BOOLEAN_OBJECT,
3358 		  G_TYPE_BOOLEAN, 4,
3359 		  G_TYPE_INT,
3360 		  G_TYPE_INT,
3361 		  G_TYPE_BOOLEAN,
3362 		  GTK_TYPE_TOOLTIP);
3363   g_signal_set_va_marshaller (widget_signals[QUERY_TOOLTIP],
3364                               G_TYPE_FROM_CLASS (klass),
3365                               _gtk_marshal_BOOLEAN__INT_INT_BOOLEAN_OBJECTv);
3366 
3367   /**
3368    * GtkWidget::popup-menu:
3369    * @widget: the object which received the signal
3370    *
3371    * This signal gets emitted whenever a widget should pop up a context
3372    * menu. This usually happens through the standard key binding mechanism;
3373    * by pressing a certain key while a widget is focused, the user can cause
3374    * the widget to pop up a menu.  For example, the #GtkEntry widget creates
3375    * a menu with clipboard commands. See the
3376    * [Popup Menu Migration Checklist][checklist-popup-menu]
3377    * for an example of how to use this signal.
3378    *
3379    * Returns: %TRUE if a menu was activated
3380    */
3381   widget_signals[POPUP_MENU] =
3382     g_signal_new (I_("popup-menu"),
3383 		  G_TYPE_FROM_CLASS (klass),
3384 		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
3385 		  G_STRUCT_OFFSET (GtkWidgetClass, popup_menu),
3386 		  _gtk_boolean_handled_accumulator, NULL,
3387 		  _gtk_marshal_BOOLEAN__VOID,
3388 		  G_TYPE_BOOLEAN, 0);
3389   g_signal_set_va_marshaller (widget_signals[POPUP_MENU],
3390                               G_TYPE_FROM_CLASS (klass),
3391                               _gtk_marshal_BOOLEAN__VOIDv);
3392 
3393   /**
3394    * GtkWidget::show-help:
3395    * @widget: the object which received the signal.
3396    * @help_type:
3397    *
3398    * Returns: %TRUE to stop other handlers from being invoked for the event.
3399    * %FALSE to propagate the event further.
3400    */
3401   widget_signals[SHOW_HELP] =
3402     g_signal_new (I_("show-help"),
3403 		  G_TYPE_FROM_CLASS (klass),
3404 		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
3405 		  G_STRUCT_OFFSET (GtkWidgetClass, show_help),
3406 		  _gtk_boolean_handled_accumulator, NULL,
3407 		  _gtk_marshal_BOOLEAN__ENUM,
3408 		  G_TYPE_BOOLEAN, 1,
3409 		  GTK_TYPE_WIDGET_HELP_TYPE);
3410   g_signal_set_va_marshaller (widget_signals[SHOW_HELP],
3411                               G_TYPE_FROM_CLASS (klass),
3412                               _gtk_marshal_BOOLEAN__ENUMv);
3413 
3414   /**
3415    * GtkWidget::accel-closures-changed:
3416    * @widget: the object which received the signal.
3417    */
3418   widget_signals[ACCEL_CLOSURES_CHANGED] =
3419     g_signal_new (I_("accel-closures-changed"),
3420 		  G_TYPE_FROM_CLASS (klass),
3421 		  0,
3422 		  0,
3423 		  NULL, NULL,
3424 		  NULL,
3425 		  G_TYPE_NONE, 0);
3426 
3427   /**
3428    * GtkWidget::screen-changed:
3429    * @widget: the object on which the signal is emitted
3430    * @previous_screen: (allow-none): the previous screen, or %NULL if the
3431    *   widget was not associated with a screen before
3432    *
3433    * The ::screen-changed signal gets emitted when the
3434    * screen of a widget has changed.
3435    */
3436   widget_signals[SCREEN_CHANGED] =
3437     g_signal_new (I_("screen-changed"),
3438 		  G_TYPE_FROM_CLASS (klass),
3439 		  G_SIGNAL_RUN_LAST,
3440 		  G_STRUCT_OFFSET (GtkWidgetClass, screen_changed),
3441 		  NULL, NULL,
3442 		  NULL,
3443 		  G_TYPE_NONE, 1,
3444 		  GDK_TYPE_SCREEN);
3445 
3446   /**
3447    * GtkWidget::can-activate-accel:
3448    * @widget: the object which received the signal
3449    * @signal_id: the ID of a signal installed on @widget
3450    *
3451    * Determines whether an accelerator that activates the signal
3452    * identified by @signal_id can currently be activated.
3453    * This signal is present to allow applications and derived
3454    * widgets to override the default #GtkWidget handling
3455    * for determining whether an accelerator can be activated.
3456    *
3457    * Returns: %TRUE if the signal can be activated.
3458    */
3459   widget_signals[CAN_ACTIVATE_ACCEL] =
3460      g_signal_new (I_("can-activate-accel"),
3461 		  G_TYPE_FROM_CLASS (klass),
3462 		  G_SIGNAL_RUN_LAST,
3463 		  G_STRUCT_OFFSET (GtkWidgetClass, can_activate_accel),
3464                   _gtk_boolean_handled_accumulator, NULL,
3465 		  _gtk_marshal_BOOLEAN__UINT,
3466                   G_TYPE_BOOLEAN, 1, G_TYPE_UINT);
3467 
3468   binding_set = gtk_binding_set_by_class (klass);
3469   gtk_binding_entry_add_signal (binding_set, GDK_KEY_F10, GDK_SHIFT_MASK,
3470                                 "popup-menu", 0);
3471   gtk_binding_entry_add_signal (binding_set, GDK_KEY_Menu, 0,
3472                                 "popup-menu", 0);
3473 
3474   gtk_binding_entry_add_signal (binding_set, GDK_KEY_F1, GDK_CONTROL_MASK,
3475                                 "show-help", 1,
3476                                 GTK_TYPE_WIDGET_HELP_TYPE,
3477                                 GTK_WIDGET_HELP_TOOLTIP);
3478   gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_F1, GDK_CONTROL_MASK,
3479                                 "show-help", 1,
3480                                 GTK_TYPE_WIDGET_HELP_TYPE,
3481                                 GTK_WIDGET_HELP_TOOLTIP);
3482   gtk_binding_entry_add_signal (binding_set, GDK_KEY_F1, GDK_SHIFT_MASK,
3483                                 "show-help", 1,
3484                                 GTK_TYPE_WIDGET_HELP_TYPE,
3485                                 GTK_WIDGET_HELP_WHATS_THIS);
3486   gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_F1, GDK_SHIFT_MASK,
3487                                 "show-help", 1,
3488                                 GTK_TYPE_WIDGET_HELP_TYPE,
3489                                 GTK_WIDGET_HELP_WHATS_THIS);
3490 
3491   /**
3492    * GtkWidget:interior-focus:
3493    *
3494    * The "interior-focus" style property defines whether
3495    * to draw the focus indicator inside widgets.
3496    *
3497    * Deprecated: 3.14: use the outline CSS properties instead.
3498    */
3499   gtk_widget_class_install_style_property (klass,
3500 					   g_param_spec_boolean ("interior-focus",
3501 								 P_("Interior Focus"),
3502 								 P_("Whether to draw the focus indicator inside widgets"),
3503 								 TRUE,
3504 								 GTK_PARAM_READABLE | G_PARAM_DEPRECATED));
3505   /**
3506    * GtkWidget:focus-line-width:
3507    *
3508    * The "focus-line-width" style property defines the width,
3509    * in pixels, of the focus indicator line
3510    *
3511    * Deprecated: 3.14: use the outline-width and padding CSS properties instead.
3512    */
3513   gtk_widget_class_install_style_property (klass,
3514 					   g_param_spec_int ("focus-line-width",
3515 							     P_("Focus linewidth"),
3516 							     P_("Width, in pixels, of the focus indicator line"),
3517 							     0, G_MAXINT, 1,
3518 							     GTK_PARAM_READABLE | G_PARAM_DEPRECATED));
3519   /**
3520    * GtkWidget:focus-line-pattern:
3521    *
3522    * The "focus-line-pattern" style property defines the dash pattern used to
3523    * draw the focus indicator. The character values are interpreted as pixel
3524    * widths of alternating on and off segments of the line.
3525    *
3526    * Deprecated: 3.14: use the outline-style CSS property instead.
3527    */
3528   gtk_widget_class_install_style_property (klass,
3529 					   g_param_spec_string ("focus-line-pattern",
3530 								P_("Focus line dash pattern"),
3531 								P_("Dash pattern used to draw the focus indicator. The character values are interpreted as pixel widths of alternating on and off segments of the line."),
3532 								"\1\1",
3533 								GTK_PARAM_READABLE | G_PARAM_DEPRECATED));
3534   /**
3535    * GtkWidget:focus-padding:
3536    *
3537    * The "focus-padding" style property defines the width, in pixels,
3538    * between focus indicator and the widget 'box'.
3539    *
3540    * Deprecated: 3.14: use the outline-offset CSS properties instead.
3541    */
3542   gtk_widget_class_install_style_property (klass,
3543 					   g_param_spec_int ("focus-padding",
3544 							     P_("Focus padding"),
3545 							     P_("Width, in pixels, between focus indicator and the widget 'box'"),
3546 							     0, G_MAXINT, 1,
3547 							     GTK_PARAM_READABLE | G_PARAM_DEPRECATED));
3548 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
3549   /**
3550    * GtkWidget:cursor-color:
3551    *
3552    * The color with which to draw the insertion cursor in entries and
3553    * text views.
3554    *
3555    * Deprecated: 3.20: Use the caret-color CSS property
3556    */
3557   gtk_widget_class_install_style_property (klass,
3558 					   g_param_spec_boxed ("cursor-color",
3559 							       P_("Cursor color"),
3560 							       P_("Color with which to draw insertion cursor"),
3561 							       GDK_TYPE_COLOR,
3562 							       GTK_PARAM_READABLE|G_PARAM_DEPRECATED));
3563   /**
3564    * GtkWidget:secondary-cursor-color:
3565    *
3566    * The color with which to draw the secondary insertion cursor in entries and
3567    * text views when editing mixed right-to-left and left-to-right text.
3568    *
3569    * Deprecated: 3.20: Use the -gtk-secondary-caret-color CSS property
3570    */
3571   gtk_widget_class_install_style_property (klass,
3572 					   g_param_spec_boxed ("secondary-cursor-color",
3573 							       P_("Secondary cursor color"),
3574 							       P_("Color with which to draw the secondary insertion cursor when editing mixed right-to-left and left-to-right text"),
3575 							       GDK_TYPE_COLOR,
3576 							       GTK_PARAM_READABLE|G_PARAM_DEPRECATED));
3577 G_GNUC_END_IGNORE_DEPRECATIONS
3578   gtk_widget_class_install_style_property (klass,
3579 					   g_param_spec_float ("cursor-aspect-ratio",
3580 							       P_("Cursor line aspect ratio"),
3581 							       P_("Aspect ratio with which to draw insertion cursor"),
3582 							       0.0, 1.0, 0.04,
3583 							       GTK_PARAM_READABLE));
3584 
3585   gtk_widget_class_install_style_property (klass,
3586                                            g_param_spec_boolean ("window-dragging",
3587                                                                  P_("Window dragging"),
3588                                                                  P_("Whether windows can be dragged and maximized by clicking on empty areas"),
3589                                                                  FALSE,
3590                                                                  GTK_PARAM_READABLE));
3591 
3592 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
3593   /**
3594    * GtkWidget:link-color:
3595    *
3596    * The "link-color" style property defines the color of unvisited links.
3597    *
3598    * Since: 2.10
3599    *
3600    * Deprecated: 3.12: Links now use a separate state flags for selecting
3601    *     different theming, this style property is ignored
3602    */
3603   gtk_widget_class_install_style_property (klass,
3604 					   g_param_spec_boxed ("link-color",
3605 							       P_("Unvisited Link Color"),
3606 							       P_("Color of unvisited links"),
3607 							       GDK_TYPE_COLOR,
3608 							       GTK_PARAM_READABLE|G_PARAM_DEPRECATED));
3609 
3610   /**
3611    * GtkWidget:visited-link-color:
3612    *
3613    * The "visited-link-color" style property defines the color of visited links.
3614    *
3615    * Since: 2.10
3616    *
3617    * Deprecated: 3.12: Links now use a separate state flags for selecting
3618    *     different theming, this style property is ignored
3619    */
3620   gtk_widget_class_install_style_property (klass,
3621 					   g_param_spec_boxed ("visited-link-color",
3622 							       P_("Visited Link Color"),
3623 							       P_("Color of visited links"),
3624 							       GDK_TYPE_COLOR,
3625 							       GTK_PARAM_READABLE|G_PARAM_DEPRECATED));
3626 G_GNUC_END_IGNORE_DEPRECATIONS
3627 
3628   /**
3629    * GtkWidget:wide-separators:
3630    *
3631    * The "wide-separators" style property defines whether separators have
3632    * configurable width and should be drawn using a box instead of a line.
3633    *
3634    * Since: 2.10
3635    *
3636    * Deprecated: 3.20: Use CSS properties on the separator elements to style
3637    *   separators; the value of this style property is ignored.
3638    */
3639   gtk_widget_class_install_style_property (klass,
3640                                            g_param_spec_boolean ("wide-separators",
3641                                                                  P_("Wide Separators"),
3642                                                                  P_("Whether separators have configurable width and should be drawn using a box instead of a line"),
3643                                                                  FALSE,
3644                                                                  GTK_PARAM_READABLE|G_PARAM_DEPRECATED));
3645 
3646   /**
3647    * GtkWidget:separator-width:
3648    *
3649    * The "separator-width" style property defines the width of separators.
3650    * This property only takes effect if the "wide-separators" style property is %TRUE.
3651    *
3652    * Since: 2.10
3653    *
3654    * Deprecated: 3.20: Use the standard min-width CSS property on the separator
3655    *   elements to size separators; the value of this style property is ignored.
3656    */
3657   gtk_widget_class_install_style_property (klass,
3658                                            g_param_spec_int ("separator-width",
3659                                                              P_("Separator Width"),
3660                                                              P_("The width of separators if wide-separators is TRUE"),
3661                                                              0, G_MAXINT, 0,
3662                                                              GTK_PARAM_READABLE|G_PARAM_DEPRECATED));
3663 
3664   /**
3665    * GtkWidget:separator-height:
3666    *
3667    * The "separator-height" style property defines the height of separators.
3668    * This property only takes effect if the "wide-separators" style property is %TRUE.
3669    *
3670    * Since: 2.10
3671    *
3672    * Deprecated: 3.20: Use the standard min-height CSS property on the separator
3673    *   elements to size separators; the value of this style property is ignored.
3674    */
3675   gtk_widget_class_install_style_property (klass,
3676                                            g_param_spec_int ("separator-height",
3677                                                              P_("Separator Height"),
3678                                                              P_("The height of separators if \"wide-separators\" is TRUE"),
3679                                                              0, G_MAXINT, 0,
3680                                                              GTK_PARAM_READABLE|G_PARAM_DEPRECATED));
3681 
3682   /**
3683    * GtkWidget:scroll-arrow-hlength:
3684    *
3685    * The "scroll-arrow-hlength" style property defines the length of
3686    * horizontal scroll arrows.
3687    *
3688    * Since: 2.10
3689    */
3690   gtk_widget_class_install_style_property (klass,
3691                                            g_param_spec_int ("scroll-arrow-hlength",
3692                                                              P_("Horizontal Scroll Arrow Length"),
3693                                                              P_("The length of horizontal scroll arrows"),
3694                                                              1, G_MAXINT, 16,
3695                                                              GTK_PARAM_READABLE));
3696 
3697   /**
3698    * GtkWidget:scroll-arrow-vlength:
3699    *
3700    * The "scroll-arrow-vlength" style property defines the length of
3701    * vertical scroll arrows.
3702    *
3703    * Since: 2.10
3704    */
3705   gtk_widget_class_install_style_property (klass,
3706                                            g_param_spec_int ("scroll-arrow-vlength",
3707                                                              P_("Vertical Scroll Arrow Length"),
3708                                                              P_("The length of vertical scroll arrows"),
3709                                                              1, G_MAXINT, 16,
3710                                                              GTK_PARAM_READABLE));
3711 
3712   gtk_widget_class_install_style_property (klass,
3713                                            g_param_spec_int ("text-handle-width",
3714                                                              P_("Width of text selection handles"),
3715                                                              P_("Width of text selection handles"),
3716                                                              1, G_MAXINT, 16,
3717                                                              GTK_PARAM_READABLE));
3718   gtk_widget_class_install_style_property (klass,
3719                                            g_param_spec_int ("text-handle-height",
3720                                                              P_("Height of text selection handles"),
3721                                                              P_("Height of text selection handles"),
3722                                                              1, G_MAXINT, 20,
3723                                                              GTK_PARAM_READABLE));
3724 
3725   gtk_widget_class_set_accessible_type (klass, GTK_TYPE_WIDGET_ACCESSIBLE);
3726   gtk_widget_class_set_css_name (klass, "widget");
3727 }
3728 
3729 static void
gtk_widget_base_class_finalize(GtkWidgetClass * klass)3730 gtk_widget_base_class_finalize (GtkWidgetClass *klass)
3731 {
3732   GList *list, *node;
3733 
3734   list = g_param_spec_pool_list_owned (style_property_spec_pool, G_OBJECT_CLASS_TYPE (klass));
3735   for (node = list; node; node = node->next)
3736     {
3737       GParamSpec *pspec = node->data;
3738 
3739       g_param_spec_pool_remove (style_property_spec_pool, pspec);
3740       g_param_spec_unref (pspec);
3741     }
3742   g_list_free (list);
3743 
3744   template_data_free (klass->priv->template);
3745 }
3746 
3747 static void
gtk_widget_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)3748 gtk_widget_set_property (GObject         *object,
3749 			 guint            prop_id,
3750 			 const GValue    *value,
3751 			 GParamSpec      *pspec)
3752 {
3753   GtkWidget *widget = GTK_WIDGET (object);
3754 
3755   switch (prop_id)
3756     {
3757       gboolean tmp;
3758       gchar *tooltip_markup;
3759       const gchar *tooltip_text;
3760       GtkWindow *tooltip_window;
3761 
3762     case PROP_NAME:
3763       gtk_widget_set_name (widget, g_value_get_string (value));
3764       break;
3765     case PROP_PARENT:
3766       gtk_container_add (GTK_CONTAINER (g_value_get_object (value)), widget);
3767       break;
3768     case PROP_WIDTH_REQUEST:
3769       gtk_widget_set_usize_internal (widget, g_value_get_int (value), -2);
3770       break;
3771     case PROP_HEIGHT_REQUEST:
3772       gtk_widget_set_usize_internal (widget, -2, g_value_get_int (value));
3773       break;
3774     case PROP_VISIBLE:
3775       gtk_widget_set_visible (widget, g_value_get_boolean (value));
3776       break;
3777     case PROP_SENSITIVE:
3778       gtk_widget_set_sensitive (widget, g_value_get_boolean (value));
3779       break;
3780     case PROP_APP_PAINTABLE:
3781       gtk_widget_set_app_paintable (widget, g_value_get_boolean (value));
3782       break;
3783     case PROP_CAN_FOCUS:
3784       gtk_widget_set_can_focus (widget, g_value_get_boolean (value));
3785       break;
3786     case PROP_HAS_FOCUS:
3787       if (g_value_get_boolean (value))
3788 	gtk_widget_grab_focus (widget);
3789       break;
3790     case PROP_IS_FOCUS:
3791       if (g_value_get_boolean (value))
3792 	gtk_widget_grab_focus (widget);
3793       break;
3794     case PROP_FOCUS_ON_CLICK:
3795       gtk_widget_set_focus_on_click (widget, g_value_get_boolean (value));
3796       break;
3797     case PROP_CAN_DEFAULT:
3798       gtk_widget_set_can_default (widget, g_value_get_boolean (value));
3799       break;
3800     case PROP_HAS_DEFAULT:
3801       if (g_value_get_boolean (value))
3802 	gtk_widget_grab_default (widget);
3803       break;
3804     case PROP_RECEIVES_DEFAULT:
3805       gtk_widget_set_receives_default (widget, g_value_get_boolean (value));
3806       break;
3807     case PROP_STYLE:
3808       G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
3809       gtk_widget_set_style (widget, g_value_get_object (value));
3810       G_GNUC_END_IGNORE_DEPRECATIONS;
3811       break;
3812     case PROP_EVENTS:
3813       if (!_gtk_widget_get_realized (widget) && _gtk_widget_get_has_window (widget))
3814 	gtk_widget_set_events (widget, g_value_get_flags (value));
3815       break;
3816     case PROP_NO_SHOW_ALL:
3817       gtk_widget_set_no_show_all (widget, g_value_get_boolean (value));
3818       break;
3819     case PROP_HAS_TOOLTIP:
3820       gtk_widget_real_set_has_tooltip (widget,
3821 				       g_value_get_boolean (value), FALSE);
3822       break;
3823     case PROP_TOOLTIP_MARKUP:
3824       tooltip_window = g_object_get_qdata (object, quark_tooltip_window);
3825       tooltip_markup = g_value_dup_string (value);
3826 
3827       /* Treat an empty string as a NULL string,
3828        * because an empty string would be useless for a tooltip:
3829        */
3830       if (tooltip_markup && (strlen (tooltip_markup) == 0))
3831         {
3832 	  g_free (tooltip_markup);
3833           tooltip_markup = NULL;
3834         }
3835 
3836       g_object_set_qdata_full (object, quark_tooltip_markup,
3837 			       tooltip_markup, g_free);
3838 
3839       tmp = (tooltip_window != NULL || tooltip_markup != NULL);
3840       gtk_widget_real_set_has_tooltip (widget, tmp, FALSE);
3841       if (_gtk_widget_get_visible (widget))
3842         gtk_widget_queue_tooltip_query (widget);
3843       break;
3844     case PROP_TOOLTIP_TEXT:
3845       tooltip_window = g_object_get_qdata (object, quark_tooltip_window);
3846 
3847       tooltip_text = g_value_get_string (value);
3848 
3849       /* Treat an empty string as a NULL string,
3850        * because an empty string would be useless for a tooltip:
3851        */
3852       if (tooltip_text && (strlen (tooltip_text) == 0))
3853         tooltip_text = NULL;
3854 
3855       tooltip_markup = tooltip_text ? g_markup_escape_text (tooltip_text, -1) : NULL;
3856 
3857       g_object_set_qdata_full (object, quark_tooltip_markup,
3858                                tooltip_markup, g_free);
3859 
3860       tmp = (tooltip_window != NULL || tooltip_markup != NULL);
3861       gtk_widget_real_set_has_tooltip (widget, tmp, FALSE);
3862       if (_gtk_widget_get_visible (widget))
3863         gtk_widget_queue_tooltip_query (widget);
3864       break;
3865     case PROP_DOUBLE_BUFFERED:
3866       G_GNUC_BEGIN_IGNORE_DEPRECATIONS
3867       gtk_widget_set_double_buffered (widget, g_value_get_boolean (value));
3868       G_GNUC_END_IGNORE_DEPRECATIONS
3869       break;
3870     case PROP_HALIGN:
3871       gtk_widget_set_halign (widget, g_value_get_enum (value));
3872       break;
3873     case PROP_VALIGN:
3874       gtk_widget_set_valign (widget, g_value_get_enum (value));
3875       break;
3876     case PROP_MARGIN_LEFT:
3877       G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
3878       gtk_widget_set_margin_left (widget, g_value_get_int (value));
3879       G_GNUC_END_IGNORE_DEPRECATIONS;
3880       break;
3881     case PROP_MARGIN_RIGHT:
3882       G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
3883       gtk_widget_set_margin_right (widget, g_value_get_int (value));
3884       G_GNUC_END_IGNORE_DEPRECATIONS;
3885       break;
3886     case PROP_MARGIN_START:
3887       gtk_widget_set_margin_start (widget, g_value_get_int (value));
3888       break;
3889     case PROP_MARGIN_END:
3890       gtk_widget_set_margin_end (widget, g_value_get_int (value));
3891       break;
3892     case PROP_MARGIN_TOP:
3893       gtk_widget_set_margin_top (widget, g_value_get_int (value));
3894       break;
3895     case PROP_MARGIN_BOTTOM:
3896       gtk_widget_set_margin_bottom (widget, g_value_get_int (value));
3897       break;
3898     case PROP_MARGIN:
3899       g_object_freeze_notify (G_OBJECT (widget));
3900       gtk_widget_set_margin_start (widget, g_value_get_int (value));
3901       gtk_widget_set_margin_end (widget, g_value_get_int (value));
3902       gtk_widget_set_margin_top (widget, g_value_get_int (value));
3903       gtk_widget_set_margin_bottom (widget, g_value_get_int (value));
3904       g_object_thaw_notify (G_OBJECT (widget));
3905       break;
3906     case PROP_HEXPAND:
3907       gtk_widget_set_hexpand (widget, g_value_get_boolean (value));
3908       break;
3909     case PROP_HEXPAND_SET:
3910       gtk_widget_set_hexpand_set (widget, g_value_get_boolean (value));
3911       break;
3912     case PROP_VEXPAND:
3913       gtk_widget_set_vexpand (widget, g_value_get_boolean (value));
3914       break;
3915     case PROP_VEXPAND_SET:
3916       gtk_widget_set_vexpand_set (widget, g_value_get_boolean (value));
3917       break;
3918     case PROP_EXPAND:
3919       g_object_freeze_notify (G_OBJECT (widget));
3920       gtk_widget_set_hexpand (widget, g_value_get_boolean (value));
3921       gtk_widget_set_vexpand (widget, g_value_get_boolean (value));
3922       g_object_thaw_notify (G_OBJECT (widget));
3923       break;
3924     case PROP_OPACITY:
3925       gtk_widget_set_opacity (widget, g_value_get_double (value));
3926       break;
3927     default:
3928       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
3929       break;
3930     }
3931 }
3932 
3933 static void
gtk_widget_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)3934 gtk_widget_get_property (GObject         *object,
3935 			 guint            prop_id,
3936 			 GValue          *value,
3937 			 GParamSpec      *pspec)
3938 {
3939   GtkWidget *widget = GTK_WIDGET (object);
3940   GtkWidgetPrivate *priv = widget->priv;
3941 
3942   switch (prop_id)
3943     {
3944       gpointer *eventp;
3945 
3946     case PROP_NAME:
3947       if (priv->name)
3948 	g_value_set_string (value, priv->name);
3949       else
3950 	g_value_set_static_string (value, "");
3951       break;
3952     case PROP_PARENT:
3953       g_value_set_object (value, priv->parent);
3954       break;
3955     case PROP_WIDTH_REQUEST:
3956       {
3957         int w;
3958         gtk_widget_get_size_request (widget, &w, NULL);
3959         g_value_set_int (value, w);
3960       }
3961       break;
3962     case PROP_HEIGHT_REQUEST:
3963       {
3964         int h;
3965         gtk_widget_get_size_request (widget, NULL, &h);
3966         g_value_set_int (value, h);
3967       }
3968       break;
3969     case PROP_VISIBLE:
3970       g_value_set_boolean (value, _gtk_widget_get_visible (widget));
3971       break;
3972     case PROP_SENSITIVE:
3973       g_value_set_boolean (value, gtk_widget_get_sensitive (widget));
3974       break;
3975     case PROP_APP_PAINTABLE:
3976       g_value_set_boolean (value, gtk_widget_get_app_paintable (widget));
3977       break;
3978     case PROP_CAN_FOCUS:
3979       g_value_set_boolean (value, gtk_widget_get_can_focus (widget));
3980       break;
3981     case PROP_HAS_FOCUS:
3982       g_value_set_boolean (value, gtk_widget_has_focus (widget));
3983       break;
3984     case PROP_IS_FOCUS:
3985       g_value_set_boolean (value, gtk_widget_is_focus (widget));
3986       break;
3987     case PROP_FOCUS_ON_CLICK:
3988       g_value_set_boolean (value, gtk_widget_get_focus_on_click (widget));
3989       break;
3990     case PROP_CAN_DEFAULT:
3991       g_value_set_boolean (value, gtk_widget_get_can_default (widget));
3992       break;
3993     case PROP_HAS_DEFAULT:
3994       g_value_set_boolean (value, gtk_widget_has_default (widget));
3995       break;
3996     case PROP_RECEIVES_DEFAULT:
3997       g_value_set_boolean (value, gtk_widget_get_receives_default (widget));
3998       break;
3999     case PROP_COMPOSITE_CHILD:
4000       g_value_set_boolean (value, widget->priv->composite_child);
4001       break;
4002     case PROP_STYLE:
4003       G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
4004       g_value_set_object (value, gtk_widget_get_style (widget));
4005       G_GNUC_END_IGNORE_DEPRECATIONS;
4006       break;
4007     case PROP_EVENTS:
4008       eventp = g_object_get_qdata (G_OBJECT (widget), quark_event_mask);
4009       g_value_set_flags (value, GPOINTER_TO_INT (eventp));
4010       break;
4011     case PROP_NO_SHOW_ALL:
4012       g_value_set_boolean (value, gtk_widget_get_no_show_all (widget));
4013       break;
4014     case PROP_HAS_TOOLTIP:
4015       g_value_set_boolean (value, gtk_widget_get_has_tooltip (widget));
4016       break;
4017     case PROP_TOOLTIP_TEXT:
4018       {
4019         gchar *escaped = g_object_get_qdata (object, quark_tooltip_markup);
4020         gchar *text = NULL;
4021 
4022         if (escaped && !pango_parse_markup (escaped, -1, 0, NULL, &text, NULL, NULL))
4023           g_assert (NULL == text); /* text should still be NULL in case of markup errors */
4024 
4025         g_value_take_string (value, text);
4026       }
4027       break;
4028     case PROP_TOOLTIP_MARKUP:
4029       g_value_set_string (value, g_object_get_qdata (object, quark_tooltip_markup));
4030       break;
4031     case PROP_WINDOW:
4032       g_value_set_object (value, _gtk_widget_get_window (widget));
4033       break;
4034     case PROP_DOUBLE_BUFFERED:
4035       G_GNUC_BEGIN_IGNORE_DEPRECATIONS
4036       g_value_set_boolean (value, gtk_widget_get_double_buffered (widget));
4037       G_GNUC_END_IGNORE_DEPRECATIONS
4038       break;
4039     case PROP_HALIGN:
4040       g_value_set_enum (value, gtk_widget_get_halign (widget));
4041       break;
4042     case PROP_VALIGN:
4043       g_value_set_enum (value, gtk_widget_get_valign_with_baseline (widget));
4044       break;
4045     case PROP_MARGIN_LEFT:
4046       G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
4047       g_value_set_int (value, gtk_widget_get_margin_left (widget));
4048       G_GNUC_END_IGNORE_DEPRECATIONS;
4049       break;
4050     case PROP_MARGIN_RIGHT:
4051       G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
4052       g_value_set_int (value, gtk_widget_get_margin_right (widget));
4053       G_GNUC_END_IGNORE_DEPRECATIONS;
4054       break;
4055     case PROP_MARGIN_START:
4056       g_value_set_int (value, gtk_widget_get_margin_start (widget));
4057       break;
4058     case PROP_MARGIN_END:
4059       g_value_set_int (value, gtk_widget_get_margin_end (widget));
4060       break;
4061     case PROP_MARGIN_TOP:
4062       g_value_set_int (value, gtk_widget_get_margin_top (widget));
4063       break;
4064     case PROP_MARGIN_BOTTOM:
4065       g_value_set_int (value, gtk_widget_get_margin_bottom (widget));
4066       break;
4067     case PROP_MARGIN:
4068       g_value_set_int (value, MAX (MAX (priv->margin.left,
4069                                         priv->margin.right),
4070                                    MAX (priv->margin.top,
4071                                         priv->margin.bottom)));
4072       break;
4073     case PROP_HEXPAND:
4074       g_value_set_boolean (value, gtk_widget_get_hexpand (widget));
4075       break;
4076     case PROP_HEXPAND_SET:
4077       g_value_set_boolean (value, gtk_widget_get_hexpand_set (widget));
4078       break;
4079     case PROP_VEXPAND:
4080       g_value_set_boolean (value, gtk_widget_get_vexpand (widget));
4081       break;
4082     case PROP_VEXPAND_SET:
4083       g_value_set_boolean (value, gtk_widget_get_vexpand_set (widget));
4084       break;
4085     case PROP_EXPAND:
4086       g_value_set_boolean (value,
4087                            gtk_widget_get_hexpand (widget) &&
4088                            gtk_widget_get_vexpand (widget));
4089       break;
4090     case PROP_OPACITY:
4091       g_value_set_double (value, gtk_widget_get_opacity (widget));
4092       break;
4093     case PROP_SCALE_FACTOR:
4094       g_value_set_int (value, gtk_widget_get_scale_factor (widget));
4095       break;
4096     default:
4097       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
4098       break;
4099     }
4100 }
4101 
4102 static void
_gtk_widget_emulate_press(GtkWidget * widget,const GdkEvent * event)4103 _gtk_widget_emulate_press (GtkWidget      *widget,
4104                            const GdkEvent *event)
4105 {
4106   GtkWidget *event_widget, *next_child, *parent;
4107   GdkEvent *press;
4108 
4109   event_widget = gtk_get_event_widget ((GdkEvent *) event);
4110 
4111   if (event_widget == widget)
4112     return;
4113 
4114   if (event->type == GDK_TOUCH_BEGIN ||
4115       event->type == GDK_TOUCH_UPDATE ||
4116       event->type == GDK_TOUCH_END)
4117     {
4118       press = gdk_event_copy (event);
4119       press->type = GDK_TOUCH_BEGIN;
4120     }
4121   else if (event->type == GDK_BUTTON_PRESS ||
4122            event->type == GDK_BUTTON_RELEASE)
4123     {
4124       press = gdk_event_copy (event);
4125       press->type = GDK_BUTTON_PRESS;
4126     }
4127   else if (event->type == GDK_MOTION_NOTIFY)
4128     {
4129       press = gdk_event_new (GDK_BUTTON_PRESS);
4130       press->button.window = g_object_ref (event->motion.window);
4131       press->button.time = event->motion.time;
4132       press->button.x = event->motion.x;
4133       press->button.y = event->motion.y;
4134       press->button.x_root = event->motion.x_root;
4135       press->button.y_root = event->motion.y_root;
4136       press->button.state = event->motion.state;
4137 
4138       press->button.axes = g_memdup (event->motion.axes,
4139                                      sizeof (gdouble) *
4140                                      gdk_device_get_n_axes (event->motion.device));
4141 
4142       if (event->motion.state & GDK_BUTTON3_MASK)
4143         press->button.button = 3;
4144       else if (event->motion.state & GDK_BUTTON2_MASK)
4145         press->button.button = 2;
4146       else
4147         {
4148           if ((event->motion.state & GDK_BUTTON1_MASK) == 0)
4149             g_critical ("Guessing button number 1 on generated button press event");
4150 
4151           press->button.button = 1;
4152         }
4153 
4154       gdk_event_set_device (press, gdk_event_get_device (event));
4155       gdk_event_set_source_device (press, gdk_event_get_source_device (event));
4156     }
4157   else
4158     return;
4159 
4160   press->any.send_event = TRUE;
4161   next_child = event_widget;
4162   parent = _gtk_widget_get_parent (next_child);
4163 
4164   while (parent != widget)
4165     {
4166       next_child = parent;
4167       parent = _gtk_widget_get_parent (parent);
4168     }
4169 
4170   /* Perform propagation state starting from the next child in the chain */
4171   if (!_gtk_propagate_captured_event (event_widget, press, next_child))
4172     gtk_propagate_event (event_widget, press);
4173 
4174   gdk_event_free (press);
4175 }
4176 
4177 static const GdkEvent *
_gtk_widget_get_last_event(GtkWidget * widget,GdkEventSequence * sequence)4178 _gtk_widget_get_last_event (GtkWidget        *widget,
4179                             GdkEventSequence *sequence)
4180 {
4181   GtkWidgetPrivate *priv = widget->priv;
4182   EventControllerData *data;
4183   const GdkEvent *event;
4184   GList *l;
4185 
4186   for (l = priv->event_controllers; l; l = l->next)
4187     {
4188       data = l->data;
4189 
4190       if (!GTK_IS_GESTURE (data->controller))
4191         continue;
4192 
4193       event = gtk_gesture_get_last_event (GTK_GESTURE (data->controller),
4194                                           sequence);
4195       if (event)
4196         return event;
4197     }
4198 
4199   return NULL;
4200 }
4201 
4202 static gboolean
_gtk_widget_get_emulating_sequence(GtkWidget * widget,GdkEventSequence * sequence,GdkEventSequence ** sequence_out)4203 _gtk_widget_get_emulating_sequence (GtkWidget         *widget,
4204                                     GdkEventSequence  *sequence,
4205                                     GdkEventSequence **sequence_out)
4206 {
4207   GtkWidgetPrivate *priv = widget->priv;
4208   GList *l;
4209 
4210   *sequence_out = sequence;
4211 
4212   if (sequence)
4213     {
4214       const GdkEvent *last_event;
4215 
4216       last_event = _gtk_widget_get_last_event (widget, sequence);
4217 
4218       if (last_event &&
4219           (last_event->type == GDK_TOUCH_BEGIN ||
4220            last_event->type == GDK_TOUCH_UPDATE ||
4221            last_event->type == GDK_TOUCH_END) &&
4222           last_event->touch.emulating_pointer)
4223         return TRUE;
4224     }
4225   else
4226     {
4227       /* For a NULL(pointer) sequence, find the pointer emulating one */
4228       for (l = priv->event_controllers; l; l = l->next)
4229         {
4230           EventControllerData *data = l->data;
4231 
4232           if (!GTK_IS_GESTURE (data->controller))
4233             continue;
4234 
4235           if (_gtk_gesture_get_pointer_emulating_sequence (GTK_GESTURE (data->controller),
4236                                                            sequence_out))
4237             return TRUE;
4238         }
4239     }
4240 
4241   return FALSE;
4242 }
4243 
4244 static gboolean
gtk_widget_needs_press_emulation(GtkWidget * widget,GdkEventSequence * sequence)4245 gtk_widget_needs_press_emulation (GtkWidget        *widget,
4246                                   GdkEventSequence *sequence)
4247 {
4248   GtkWidgetPrivate *priv = widget->priv;
4249   gboolean sequence_press_handled = FALSE;
4250   GList *l;
4251 
4252   /* Check whether there is any remaining gesture in
4253    * the capture phase that handled the press event
4254    */
4255   for (l = priv->event_controllers; l; l = l->next)
4256     {
4257       EventControllerData *data;
4258       GtkPropagationPhase phase;
4259       GtkGesture *gesture;
4260 
4261       data = l->data;
4262       phase = gtk_event_controller_get_propagation_phase (data->controller);
4263 
4264       if (phase != GTK_PHASE_CAPTURE)
4265         continue;
4266       if (!GTK_IS_GESTURE (data->controller))
4267         continue;
4268 
4269       gesture = GTK_GESTURE (data->controller);
4270       sequence_press_handled |=
4271         (gtk_gesture_handles_sequence (gesture, sequence) &&
4272          _gtk_gesture_handled_sequence_press (gesture, sequence));
4273     }
4274 
4275   return !sequence_press_handled;
4276 }
4277 
4278 static gint
_gtk_widget_set_sequence_state_internal(GtkWidget * widget,GdkEventSequence * sequence,GtkEventSequenceState state,GtkGesture * emitter)4279 _gtk_widget_set_sequence_state_internal (GtkWidget             *widget,
4280                                          GdkEventSequence      *sequence,
4281                                          GtkEventSequenceState  state,
4282                                          GtkGesture            *emitter)
4283 {
4284   gboolean emulates_pointer, sequence_handled = FALSE;
4285   GtkWidgetPrivate *priv = widget->priv;
4286   const GdkEvent *mimic_event;
4287   GList *group = NULL, *l;
4288   GdkEventSequence *seq;
4289   gint n_handled = 0;
4290 
4291   if (!priv->event_controllers && state != GTK_EVENT_SEQUENCE_CLAIMED)
4292     return TRUE;
4293 
4294   if (emitter)
4295     group = gtk_gesture_get_group (emitter);
4296 
4297   emulates_pointer = _gtk_widget_get_emulating_sequence (widget, sequence, &seq);
4298   mimic_event = _gtk_widget_get_last_event (widget, seq);
4299 
4300   for (l = priv->event_controllers; l; l = l->next)
4301     {
4302       GtkEventSequenceState gesture_state;
4303       EventControllerData *data;
4304       GtkGesture *gesture;
4305       gboolean retval;
4306 
4307       seq = sequence;
4308       data = l->data;
4309       gesture_state = state;
4310 
4311       if (!GTK_IS_GESTURE (data->controller))
4312         continue;
4313 
4314       gesture = GTK_GESTURE (data->controller);
4315 
4316       if (gesture == emitter)
4317         {
4318           sequence_handled |=
4319             _gtk_gesture_handled_sequence_press (gesture, sequence);
4320           n_handled++;
4321           continue;
4322         }
4323 
4324       if (seq && emulates_pointer &&
4325           !gtk_gesture_handles_sequence (gesture, seq))
4326         seq = NULL;
4327 
4328       if (group && !g_list_find (group, data->controller))
4329         {
4330           /* If a group is provided, ensure only gestures pertaining to the group
4331            * get a "claimed" state, all other claiming gestures must deny the sequence.
4332            */
4333           if (gesture_state == GTK_EVENT_SEQUENCE_CLAIMED &&
4334               gtk_gesture_get_sequence_state (gesture, sequence) == GTK_EVENT_SEQUENCE_CLAIMED)
4335             gesture_state = GTK_EVENT_SEQUENCE_DENIED;
4336           else
4337             continue;
4338         }
4339       else if (!group &&
4340                gtk_gesture_get_sequence_state (gesture, sequence) != GTK_EVENT_SEQUENCE_CLAIMED)
4341         continue;
4342 
4343       g_signal_handler_block (data->controller, data->sequence_state_changed_id);
4344       retval = gtk_gesture_set_sequence_state (gesture, seq, gesture_state);
4345       g_signal_handler_unblock (data->controller, data->sequence_state_changed_id);
4346 
4347       if (retval || gesture == emitter)
4348         {
4349           sequence_handled |=
4350             _gtk_gesture_handled_sequence_press (gesture, seq);
4351           n_handled++;
4352         }
4353     }
4354 
4355   /* If the sequence goes denied, check whether this is a controller attached
4356    * to the capture phase, that additionally handled the button/touch press (i.e.
4357    * it was consumed), the corresponding press will be emulated for widgets
4358    * beneath, so the widgets beneath get a coherent stream of events from now on.
4359    */
4360   if (n_handled > 0 && sequence_handled &&
4361       state == GTK_EVENT_SEQUENCE_DENIED &&
4362       gtk_widget_needs_press_emulation (widget, sequence))
4363     _gtk_widget_emulate_press (widget, mimic_event);
4364 
4365   g_list_free (group);
4366 
4367   return n_handled;
4368 }
4369 
4370 static gboolean
_gtk_widget_cancel_sequence(GtkWidget * widget,GdkEventSequence * sequence)4371 _gtk_widget_cancel_sequence (GtkWidget        *widget,
4372                              GdkEventSequence *sequence)
4373 {
4374   GtkWidgetPrivate *priv = widget->priv;
4375   gboolean emulates_pointer;
4376   gboolean handled = FALSE;
4377   GdkEventSequence *seq;
4378   GList *l;
4379 
4380   emulates_pointer = _gtk_widget_get_emulating_sequence (widget, sequence, &seq);
4381 
4382   for (l = priv->event_controllers; l; l = l->next)
4383     {
4384       EventControllerData *data;
4385       GtkGesture *gesture;
4386 
4387       seq = sequence;
4388       data = l->data;
4389 
4390       if (!GTK_IS_GESTURE (data->controller))
4391         continue;
4392 
4393       gesture = GTK_GESTURE (data->controller);
4394 
4395       if (seq && emulates_pointer &&
4396           !gtk_gesture_handles_sequence (gesture, seq))
4397         seq = NULL;
4398 
4399       if (!gtk_gesture_handles_sequence (gesture, seq))
4400         continue;
4401 
4402       handled |= _gtk_gesture_cancel_sequence (gesture, seq);
4403     }
4404 
4405   return handled;
4406 }
4407 
4408 static void
gtk_widget_init(GTypeInstance * instance,gpointer g_class)4409 gtk_widget_init (GTypeInstance *instance, gpointer g_class)
4410 {
4411   GtkWidget *widget = GTK_WIDGET (instance);
4412   GtkWidgetPrivate *priv;
4413 
4414   widget->priv = gtk_widget_get_instance_private (widget);
4415   priv = widget->priv;
4416 
4417   priv->child_visible = TRUE;
4418   priv->name = NULL;
4419   priv->allocation.x = -1;
4420   priv->allocation.y = -1;
4421   priv->allocation.width = 1;
4422   priv->allocation.height = 1;
4423   priv->user_alpha = 255;
4424   priv->alpha = 255;
4425   priv->window = NULL;
4426   priv->parent = NULL;
4427 
4428   priv->sensitive = TRUE;
4429   priv->composite_child = composite_child_stack != 0;
4430   priv->double_buffered = TRUE;
4431   priv->redraw_on_alloc = TRUE;
4432   priv->alloc_needed = TRUE;
4433   priv->alloc_needed_on_child = TRUE;
4434   priv->focus_on_click = TRUE;
4435 #ifdef G_ENABLE_DEBUG
4436   priv->highlight_resize = FALSE;
4437 #endif
4438 
4439   switch (_gtk_widget_get_direction (widget))
4440     {
4441     case GTK_TEXT_DIR_LTR:
4442       priv->state_flags = GTK_STATE_FLAG_DIR_LTR;
4443       break;
4444 
4445     case GTK_TEXT_DIR_RTL:
4446       priv->state_flags = GTK_STATE_FLAG_DIR_RTL;
4447       break;
4448 
4449     case GTK_TEXT_DIR_NONE:
4450     default:
4451       g_assert_not_reached ();
4452       break;
4453     }
4454 
4455   /* this will be set to TRUE if the widget gets a child or if the
4456    * expand flag is set on the widget, but until one of those happen
4457    * we know the expand is already properly FALSE.
4458    *
4459    * We really want to default FALSE here to avoid computing expand
4460    * all over the place while initially building a widget tree.
4461    */
4462   priv->need_compute_expand = FALSE;
4463 
4464   priv->halign = GTK_ALIGN_FILL;
4465   priv->valign = GTK_ALIGN_FILL;
4466 
4467   priv->width = -1;
4468   priv->height = -1;
4469 
4470   _gtk_size_request_cache_init (&priv->requests);
4471 
4472   priv->cssnode = gtk_css_widget_node_new (widget);
4473   gtk_css_node_set_state (priv->cssnode, priv->state_flags);
4474   /* need to set correct type here, and only class has the correct type here */
4475   gtk_css_node_set_widget_type (priv->cssnode, G_TYPE_FROM_CLASS (g_class));
4476   gtk_css_node_set_name (priv->cssnode, GTK_WIDGET_CLASS (g_class)->priv->css_name);
4477 
4478   G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
4479   priv->style = gtk_widget_get_default_style ();
4480   G_GNUC_END_IGNORE_DEPRECATIONS;
4481   g_object_ref (priv->style);
4482 }
4483 
4484 
4485 static void
gtk_widget_dispatch_child_properties_changed(GtkWidget * widget,guint n_pspecs,GParamSpec ** pspecs)4486 gtk_widget_dispatch_child_properties_changed (GtkWidget   *widget,
4487 					      guint        n_pspecs,
4488 					      GParamSpec **pspecs)
4489 {
4490   GtkWidgetPrivate *priv = widget->priv;
4491   GtkWidget *container = priv->parent;
4492   guint i;
4493 
4494   for (i = 0; widget->priv->parent == container && i < n_pspecs; i++)
4495     g_signal_emit (widget, widget_signals[CHILD_NOTIFY], g_param_spec_get_name_quark (pspecs[i]), pspecs[i]);
4496 }
4497 
4498 /**
4499  * gtk_widget_freeze_child_notify:
4500  * @widget: a #GtkWidget
4501  *
4502  * Stops emission of #GtkWidget::child-notify signals on @widget. The
4503  * signals are queued until gtk_widget_thaw_child_notify() is called
4504  * on @widget.
4505  *
4506  * This is the analogue of g_object_freeze_notify() for child properties.
4507  **/
4508 void
gtk_widget_freeze_child_notify(GtkWidget * widget)4509 gtk_widget_freeze_child_notify (GtkWidget *widget)
4510 {
4511   g_return_if_fail (GTK_IS_WIDGET (widget));
4512 
4513   if (!G_OBJECT (widget)->ref_count)
4514     return;
4515 
4516   g_object_ref (widget);
4517   g_object_notify_queue_freeze (G_OBJECT (widget), _gtk_widget_child_property_notify_context);
4518   g_object_unref (widget);
4519 }
4520 
4521 /**
4522  * gtk_widget_child_notify:
4523  * @widget: a #GtkWidget
4524  * @child_property: the name of a child property installed on the
4525  *                  class of @widget’s parent
4526  *
4527  * Emits a #GtkWidget::child-notify signal for the
4528  * [child property][child-properties] @child_property
4529  * on @widget.
4530  *
4531  * This is the analogue of g_object_notify() for child properties.
4532  *
4533  * Also see gtk_container_child_notify().
4534  */
4535 void
gtk_widget_child_notify(GtkWidget * widget,const gchar * child_property)4536 gtk_widget_child_notify (GtkWidget    *widget,
4537                          const gchar  *child_property)
4538 {
4539   if (widget->priv->parent == NULL)
4540     return;
4541 
4542   gtk_container_child_notify (GTK_CONTAINER (widget->priv->parent), widget, child_property);
4543 }
4544 
4545 /**
4546  * gtk_widget_thaw_child_notify:
4547  * @widget: a #GtkWidget
4548  *
4549  * Reverts the effect of a previous call to gtk_widget_freeze_child_notify().
4550  * This causes all queued #GtkWidget::child-notify signals on @widget to be
4551  * emitted.
4552  */
4553 void
gtk_widget_thaw_child_notify(GtkWidget * widget)4554 gtk_widget_thaw_child_notify (GtkWidget *widget)
4555 {
4556   GObjectNotifyQueue *nqueue;
4557 
4558   g_return_if_fail (GTK_IS_WIDGET (widget));
4559 
4560   if (!G_OBJECT (widget)->ref_count)
4561     return;
4562 
4563   g_object_ref (widget);
4564   nqueue = g_object_notify_queue_from_object (G_OBJECT (widget), _gtk_widget_child_property_notify_context);
4565   if (!nqueue || !nqueue->freeze_count)
4566     g_warning (G_STRLOC ": child-property-changed notification for %s(%p) is not frozen",
4567 	       G_OBJECT_TYPE_NAME (widget), widget);
4568   else
4569     g_object_notify_queue_thaw (G_OBJECT (widget), nqueue);
4570   g_object_unref (widget);
4571 }
4572 
4573 
4574 /**
4575  * gtk_widget_new:
4576  * @type: type ID of the widget to create
4577  * @first_property_name: name of first property to set
4578  * @...: value of first property, followed by more properties,
4579  *     %NULL-terminated
4580  *
4581  * This is a convenience function for creating a widget and setting
4582  * its properties in one go. For example you might write:
4583  * `gtk_widget_new (GTK_TYPE_LABEL, "label", "Hello World", "xalign",
4584  * 0.0, NULL)` to create a left-aligned label. Equivalent to
4585  * g_object_new(), but returns a widget so you don’t have to
4586  * cast the object yourself.
4587  *
4588  * Returns: a new #GtkWidget of type @widget_type
4589  **/
4590 GtkWidget*
gtk_widget_new(GType type,const gchar * first_property_name,...)4591 gtk_widget_new (GType        type,
4592 		const gchar *first_property_name,
4593 		...)
4594 {
4595   GtkWidget *widget;
4596   va_list var_args;
4597 
4598   g_return_val_if_fail (g_type_is_a (type, GTK_TYPE_WIDGET), NULL);
4599 
4600   va_start (var_args, first_property_name);
4601   widget = (GtkWidget *)g_object_new_valist (type, first_property_name, var_args);
4602   va_end (var_args);
4603 
4604   return widget;
4605 }
4606 
4607 static inline void
gtk_widget_queue_draw_child(GtkWidget * widget)4608 gtk_widget_queue_draw_child (GtkWidget *widget)
4609 {
4610   GtkWidgetPrivate *priv = widget->priv;
4611   GtkWidget *parent;
4612 
4613   parent = priv->parent;
4614   if (parent && _gtk_widget_is_drawable (parent))
4615     gtk_widget_queue_draw_area (parent,
4616 				priv->clip.x,
4617 				priv->clip.y,
4618 				priv->clip.width,
4619 				priv->clip.height);
4620 }
4621 
4622 /**
4623  * gtk_widget_unparent:
4624  * @widget: a #GtkWidget
4625  *
4626  * This function is only for use in widget implementations.
4627  * Should be called by implementations of the remove method
4628  * on #GtkContainer, to dissociate a child from the container.
4629  **/
4630 void
gtk_widget_unparent(GtkWidget * widget)4631 gtk_widget_unparent (GtkWidget *widget)
4632 {
4633   GtkWidgetPrivate *priv;
4634   GObjectNotifyQueue *nqueue;
4635   GtkWidget *toplevel;
4636   GtkWidget *old_parent;
4637 
4638   g_return_if_fail (GTK_IS_WIDGET (widget));
4639 
4640   priv = widget->priv;
4641 
4642   if (priv->parent == NULL)
4643     return;
4644 
4645   /* keep this function in sync with gtk_menu_detach() */
4646 
4647   gtk_widget_push_verify_invariants (widget);
4648 
4649   g_object_freeze_notify (G_OBJECT (widget));
4650   nqueue = g_object_notify_queue_freeze (G_OBJECT (widget), _gtk_widget_child_property_notify_context);
4651 
4652   toplevel = _gtk_widget_get_toplevel (widget);
4653   if (_gtk_widget_is_toplevel (toplevel))
4654     _gtk_window_unset_focus_and_default (GTK_WINDOW (toplevel), widget);
4655 
4656   if (gtk_container_get_focus_child (GTK_CONTAINER (priv->parent)) == widget)
4657     gtk_container_set_focus_child (GTK_CONTAINER (priv->parent), NULL);
4658 
4659   gtk_widget_queue_draw_child (widget);
4660 
4661   /* Reset the width and height here, to force reallocation if we
4662    * get added back to a new parent. This won't work if our new
4663    * allocation is smaller than 1x1 and we actually want a size of 1x1...
4664    * (would 0x0 be OK here?)
4665    */
4666   priv->allocation.width = 1;
4667   priv->allocation.height = 1;
4668 
4669   if (_gtk_widget_get_realized (widget))
4670     {
4671       if (priv->in_reparent)
4672 	gtk_widget_unmap (widget);
4673       else
4674 	gtk_widget_unrealize (widget);
4675     }
4676 
4677   /* If we are unanchoring the child, we save around the toplevel
4678    * to emit hierarchy changed
4679    */
4680   if (priv->parent->priv->anchored)
4681     g_object_ref (toplevel);
4682   else
4683     toplevel = NULL;
4684 
4685   /* Removing a widget from a container restores the child visible
4686    * flag to the default state, so it doesn't affect the child
4687    * in the next parent.
4688    */
4689   priv->child_visible = TRUE;
4690 
4691   old_parent = priv->parent;
4692   priv->parent = NULL;
4693 
4694   /* parent may no longer expand if the removed
4695    * child was expand=TRUE and could therefore
4696    * be forcing it to.
4697    */
4698   if (_gtk_widget_get_visible (widget) &&
4699       (priv->need_compute_expand ||
4700        priv->computed_hexpand ||
4701        priv->computed_vexpand))
4702     {
4703       gtk_widget_queue_compute_expand (old_parent);
4704     }
4705 
4706   /* Unset BACKDROP since we are no longer inside a toplevel window */
4707   gtk_widget_unset_state_flags (widget, GTK_STATE_FLAG_BACKDROP);
4708   if (priv->context)
4709     gtk_style_context_set_parent (priv->context, NULL);
4710   gtk_css_node_set_parent (widget->priv->cssnode, NULL);
4711 
4712   _gtk_widget_update_parent_muxer (widget);
4713 
4714   g_signal_emit (widget, widget_signals[PARENT_SET], 0, old_parent);
4715   if (toplevel)
4716     {
4717       _gtk_widget_propagate_hierarchy_changed (widget, toplevel);
4718       g_object_unref (toplevel);
4719     }
4720 
4721   /* Now that the parent pointer is nullified and the hierarchy-changed
4722    * already passed, go ahead and unset the parent window, if we are unparenting
4723    * an embedded GtkWindow the window will become toplevel again and hierarchy-changed
4724    * will fire again for the new subhierarchy.
4725    */
4726   gtk_widget_set_parent_window (widget, NULL);
4727 
4728   g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_PARENT]);
4729   g_object_thaw_notify (G_OBJECT (widget));
4730   if (!priv->parent)
4731     g_object_notify_queue_clear (G_OBJECT (widget), nqueue);
4732   g_object_notify_queue_thaw (G_OBJECT (widget), nqueue);
4733 
4734   gtk_widget_pop_verify_invariants (widget);
4735   g_object_unref (widget);
4736 }
4737 
4738 /**
4739  * gtk_widget_destroy:
4740  * @widget: a #GtkWidget
4741  *
4742  * Destroys a widget.
4743  *
4744  * When a widget is destroyed all references it holds on other objects
4745  * will be released:
4746  *
4747  *  - if the widget is inside a container, it will be removed from its
4748  *  parent
4749  *  - if the widget is a container, all its children will be destroyed,
4750  *  recursively
4751  *  - if the widget is a top level, it will be removed from the list
4752  *  of top level widgets that GTK+ maintains internally
4753  *
4754  * It's expected that all references held on the widget will also
4755  * be released; you should connect to the #GtkWidget::destroy signal
4756  * if you hold a reference to @widget and you wish to remove it when
4757  * this function is called. It is not necessary to do so if you are
4758  * implementing a #GtkContainer, as you'll be able to use the
4759  * #GtkContainerClass.remove() virtual function for that.
4760  *
4761  * It's important to notice that gtk_widget_destroy() will only cause
4762  * the @widget to be finalized if no additional references, acquired
4763  * using g_object_ref(), are held on it. In case additional references
4764  * are in place, the @widget will be in an "inert" state after calling
4765  * this function; @widget will still point to valid memory, allowing you
4766  * to release the references you hold, but you may not query the widget's
4767  * own state.
4768  *
4769  * You should typically call this function on top level widgets, and
4770  * rarely on child widgets.
4771  *
4772  * See also: gtk_container_remove()
4773  */
4774 void
gtk_widget_destroy(GtkWidget * widget)4775 gtk_widget_destroy (GtkWidget *widget)
4776 {
4777   g_return_if_fail (GTK_IS_WIDGET (widget));
4778 
4779   if (!widget->priv->in_destruction)
4780     g_object_run_dispose (G_OBJECT (widget));
4781 }
4782 
4783 /**
4784  * gtk_widget_destroyed:
4785  * @widget: a #GtkWidget
4786  * @widget_pointer: (inout) (transfer none): address of a variable that contains @widget
4787  *
4788  * This function sets *@widget_pointer to %NULL if @widget_pointer !=
4789  * %NULL.  It’s intended to be used as a callback connected to the
4790  * “destroy” signal of a widget. You connect gtk_widget_destroyed()
4791  * as a signal handler, and pass the address of your widget variable
4792  * as user data. Then when the widget is destroyed, the variable will
4793  * be set to %NULL. Useful for example to avoid multiple copies
4794  * of the same dialog.
4795  **/
4796 void
gtk_widget_destroyed(GtkWidget * widget,GtkWidget ** widget_pointer)4797 gtk_widget_destroyed (GtkWidget      *widget,
4798 		      GtkWidget      **widget_pointer)
4799 {
4800   /* Don't make any assumptions about the
4801    *  value of widget!
4802    *  Even check widget_pointer.
4803    */
4804   if (widget_pointer)
4805     *widget_pointer = NULL;
4806 }
4807 
4808 /**
4809  * gtk_widget_show:
4810  * @widget: a #GtkWidget
4811  *
4812  * Flags a widget to be displayed. Any widget that isn’t shown will
4813  * not appear on the screen. If you want to show all the widgets in a
4814  * container, it’s easier to call gtk_widget_show_all() on the
4815  * container, instead of individually showing the widgets.
4816  *
4817  * Remember that you have to show the containers containing a widget,
4818  * in addition to the widget itself, before it will appear onscreen.
4819  *
4820  * When a toplevel container is shown, it is immediately realized and
4821  * mapped; other shown widgets are realized and mapped when their
4822  * toplevel container is realized and mapped.
4823  **/
4824 void
gtk_widget_show(GtkWidget * widget)4825 gtk_widget_show (GtkWidget *widget)
4826 {
4827   g_return_if_fail (GTK_IS_WIDGET (widget));
4828 
4829   if (!_gtk_widget_get_visible (widget))
4830     {
4831       GtkWidget *parent;
4832 
4833       g_object_ref (widget);
4834       gtk_widget_push_verify_invariants (widget);
4835 
4836       parent = _gtk_widget_get_parent (widget);
4837       if (parent)
4838         {
4839           gtk_widget_queue_resize (parent);
4840 
4841           /* see comment in set_parent() for why this should and can be
4842            * conditional
4843            */
4844           if (widget->priv->need_compute_expand ||
4845               widget->priv->computed_hexpand ||
4846               widget->priv->computed_vexpand)
4847             gtk_widget_queue_compute_expand (parent);
4848         }
4849 
4850       gtk_css_node_set_visible (widget->priv->cssnode, TRUE);
4851 
4852       g_signal_emit (widget, widget_signals[SHOW], 0);
4853       g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_VISIBLE]);
4854 
4855       gtk_widget_pop_verify_invariants (widget);
4856       g_object_unref (widget);
4857     }
4858 }
4859 
4860 static void
gtk_widget_real_show(GtkWidget * widget)4861 gtk_widget_real_show (GtkWidget *widget)
4862 {
4863   GtkWidgetPrivate *priv = widget->priv;
4864 
4865   if (!_gtk_widget_get_visible (widget))
4866     {
4867       priv->visible = TRUE;
4868 
4869       if (priv->parent &&
4870 	  _gtk_widget_get_mapped (priv->parent) &&
4871           _gtk_widget_get_child_visible (widget) &&
4872 	  !_gtk_widget_get_mapped (widget))
4873 	gtk_widget_map (widget);
4874     }
4875 }
4876 
4877 static void
gtk_widget_show_map_callback(GtkWidget * widget,GdkEvent * event,gint * flag)4878 gtk_widget_show_map_callback (GtkWidget *widget, GdkEvent *event, gint *flag)
4879 {
4880   *flag = TRUE;
4881   g_signal_handlers_disconnect_by_func (widget,
4882 					gtk_widget_show_map_callback,
4883 					flag);
4884 }
4885 
4886 /**
4887  * gtk_widget_show_now:
4888  * @widget: a #GtkWidget
4889  *
4890  * Shows a widget. If the widget is an unmapped toplevel widget
4891  * (i.e. a #GtkWindow that has not yet been shown), enter the main
4892  * loop and wait for the window to actually be mapped. Be careful;
4893  * because the main loop is running, anything can happen during
4894  * this function.
4895  **/
4896 void
gtk_widget_show_now(GtkWidget * widget)4897 gtk_widget_show_now (GtkWidget *widget)
4898 {
4899   gint flag = FALSE;
4900 
4901   g_return_if_fail (GTK_IS_WIDGET (widget));
4902 
4903   /* make sure we will get event */
4904   if (!_gtk_widget_get_mapped (widget) &&
4905       _gtk_widget_is_toplevel (widget))
4906     {
4907       gtk_widget_show (widget);
4908 
4909       g_signal_connect (widget, "map-event",
4910 			G_CALLBACK (gtk_widget_show_map_callback),
4911 			&flag);
4912 
4913       while (!flag)
4914 	gtk_main_iteration ();
4915     }
4916   else
4917     gtk_widget_show (widget);
4918 }
4919 
4920 /**
4921  * gtk_widget_hide:
4922  * @widget: a #GtkWidget
4923  *
4924  * Reverses the effects of gtk_widget_show(), causing the widget to be
4925  * hidden (invisible to the user).
4926  **/
4927 void
gtk_widget_hide(GtkWidget * widget)4928 gtk_widget_hide (GtkWidget *widget)
4929 {
4930   g_return_if_fail (GTK_IS_WIDGET (widget));
4931 
4932   if (_gtk_widget_get_visible (widget))
4933     {
4934       GtkWidget *toplevel = _gtk_widget_get_toplevel (widget);
4935       GtkWidget *parent;
4936 
4937       g_object_ref (widget);
4938       gtk_widget_push_verify_invariants (widget);
4939 
4940       if (toplevel != widget && _gtk_widget_is_toplevel (toplevel))
4941         _gtk_window_unset_focus_and_default (GTK_WINDOW (toplevel), widget);
4942 
4943       /* a parent may now be expand=FALSE since we're hidden. */
4944       if (widget->priv->need_compute_expand ||
4945           widget->priv->computed_hexpand ||
4946           widget->priv->computed_vexpand)
4947         {
4948           gtk_widget_queue_compute_expand (widget);
4949         }
4950 
4951       gtk_css_node_set_visible (widget->priv->cssnode, FALSE);
4952 
4953       g_signal_emit (widget, widget_signals[HIDE], 0);
4954       g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_VISIBLE]);
4955 
4956       parent = gtk_widget_get_parent (widget);
4957       if (parent)
4958 	gtk_widget_queue_resize (parent);
4959 
4960       gtk_widget_queue_allocate (widget);
4961 
4962       gtk_widget_pop_verify_invariants (widget);
4963       g_object_unref (widget);
4964     }
4965 }
4966 
4967 static void
gtk_widget_real_hide(GtkWidget * widget)4968 gtk_widget_real_hide (GtkWidget *widget)
4969 {
4970   if (_gtk_widget_get_visible (widget))
4971     {
4972       widget->priv->visible = FALSE;
4973 
4974       if (_gtk_widget_get_mapped (widget))
4975 	gtk_widget_unmap (widget);
4976     }
4977 }
4978 
4979 /**
4980  * gtk_widget_hide_on_delete:
4981  * @widget: a #GtkWidget
4982  *
4983  * Utility function; intended to be connected to the #GtkWidget::delete-event
4984  * signal on a #GtkWindow. The function calls gtk_widget_hide() on its
4985  * argument, then returns %TRUE. If connected to ::delete-event, the
4986  * result is that clicking the close button for a window (on the
4987  * window frame, top right corner usually) will hide but not destroy
4988  * the window. By default, GTK+ destroys windows when ::delete-event
4989  * is received.
4990  *
4991  * Returns: %TRUE
4992  **/
4993 gboolean
gtk_widget_hide_on_delete(GtkWidget * widget)4994 gtk_widget_hide_on_delete (GtkWidget *widget)
4995 {
4996   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
4997 
4998   gtk_widget_hide (widget);
4999 
5000   return TRUE;
5001 }
5002 
5003 /**
5004  * gtk_widget_show_all:
5005  * @widget: a #GtkWidget
5006  *
5007  * Recursively shows a widget, and any child widgets (if the widget is
5008  * a container).
5009  **/
5010 void
gtk_widget_show_all(GtkWidget * widget)5011 gtk_widget_show_all (GtkWidget *widget)
5012 {
5013   GtkWidgetClass *class;
5014 
5015   g_return_if_fail (GTK_IS_WIDGET (widget));
5016 
5017   if (gtk_widget_get_no_show_all (widget))
5018     return;
5019 
5020   class = GTK_WIDGET_GET_CLASS (widget);
5021 
5022   if (class->show_all)
5023     class->show_all (widget);
5024 }
5025 
5026 /**
5027  * gtk_widget_map:
5028  * @widget: a #GtkWidget
5029  *
5030  * This function is only for use in widget implementations. Causes
5031  * a widget to be mapped if it isn’t already.
5032  **/
5033 void
gtk_widget_map(GtkWidget * widget)5034 gtk_widget_map (GtkWidget *widget)
5035 {
5036   GtkWidgetPrivate *priv;
5037 
5038   g_return_if_fail (GTK_IS_WIDGET (widget));
5039   g_return_if_fail (_gtk_widget_get_visible (widget));
5040   g_return_if_fail (_gtk_widget_get_child_visible (widget));
5041 
5042   priv = widget->priv;
5043 
5044   if (!_gtk_widget_get_mapped (widget))
5045     {
5046       gtk_widget_push_verify_invariants (widget);
5047 
5048       if (!_gtk_widget_get_realized (widget))
5049         gtk_widget_realize (widget);
5050 
5051       g_signal_emit (widget, widget_signals[MAP], 0);
5052 
5053       if (!_gtk_widget_get_has_window (widget))
5054         gdk_window_invalidate_rect (priv->window, &priv->clip, FALSE);
5055 
5056       gtk_widget_pop_verify_invariants (widget);
5057     }
5058 }
5059 
5060 /**
5061  * gtk_widget_unmap:
5062  * @widget: a #GtkWidget
5063  *
5064  * This function is only for use in widget implementations. Causes
5065  * a widget to be unmapped if it’s currently mapped.
5066  **/
5067 void
gtk_widget_unmap(GtkWidget * widget)5068 gtk_widget_unmap (GtkWidget *widget)
5069 {
5070   GtkWidgetPrivate *priv;
5071 
5072   g_return_if_fail (GTK_IS_WIDGET (widget));
5073 
5074   priv = widget->priv;
5075 
5076   if (_gtk_widget_get_mapped (widget))
5077     {
5078       g_object_ref (widget);
5079       gtk_widget_push_verify_invariants (widget);
5080 
5081       if (!_gtk_widget_get_has_window (widget))
5082 	gdk_window_invalidate_rect (priv->window, &priv->clip, FALSE);
5083       _gtk_tooltip_hide (widget);
5084 
5085       g_signal_emit (widget, widget_signals[UNMAP], 0);
5086 
5087       gtk_widget_pop_verify_invariants (widget);
5088       g_object_unref (widget);
5089     }
5090 }
5091 
5092 static void
_gtk_widget_enable_device_events(GtkWidget * widget)5093 _gtk_widget_enable_device_events (GtkWidget *widget)
5094 {
5095   GHashTable *device_events;
5096   GHashTableIter iter;
5097   gpointer key, value;
5098 
5099   device_events = g_object_get_qdata (G_OBJECT (widget), quark_device_event_mask);
5100 
5101   if (!device_events)
5102     return;
5103 
5104   g_hash_table_iter_init (&iter, device_events);
5105 
5106   while (g_hash_table_iter_next (&iter, &key, &value))
5107     {
5108       GdkDevice *device;
5109       GdkEventMask event_mask;
5110 
5111       device = key;
5112       event_mask = GPOINTER_TO_UINT (value);
5113       gtk_widget_add_events_internal (widget, device, event_mask);
5114     }
5115 }
5116 
5117 typedef struct {
5118   GtkWidget *widget;
5119   GdkDevice *device;
5120   gboolean enabled;
5121 } DeviceEnableData;
5122 
5123 static void
device_enable_foreach(GtkWidget * widget,gpointer user_data)5124 device_enable_foreach (GtkWidget *widget,
5125                        gpointer   user_data)
5126 {
5127   DeviceEnableData *data = user_data;
5128   gtk_widget_set_device_enabled_internal (widget, data->device, TRUE, data->enabled);
5129 }
5130 
5131 static void
device_enable_foreach_window(gpointer win,gpointer user_data)5132 device_enable_foreach_window (gpointer win,
5133                               gpointer user_data)
5134 {
5135   GdkWindow *window = win;
5136   DeviceEnableData *data = user_data;
5137   GdkEventMask events;
5138   GtkWidget *window_widget;
5139   GList *window_list;
5140 
5141   gdk_window_get_user_data (window, (gpointer *) &window_widget);
5142   if (data->widget != window_widget)
5143     return;
5144 
5145   if (data->enabled)
5146     events = gdk_window_get_events (window);
5147   else
5148     events = 0;
5149 
5150   gdk_window_set_device_events (window, data->device, events);
5151 
5152   window_list = gdk_window_peek_children (window);
5153   g_list_foreach (window_list, device_enable_foreach_window, data);
5154 }
5155 
5156 void
gtk_widget_set_device_enabled_internal(GtkWidget * widget,GdkDevice * device,gboolean recurse,gboolean enabled)5157 gtk_widget_set_device_enabled_internal (GtkWidget *widget,
5158                                         GdkDevice *device,
5159                                         gboolean   recurse,
5160                                         gboolean   enabled)
5161 {
5162   DeviceEnableData data;
5163 
5164   data.widget = widget;
5165   data.device = device;
5166   data.enabled = enabled;
5167 
5168   if (_gtk_widget_get_has_window (widget))
5169     {
5170       GdkWindow *window;
5171 
5172       window = _gtk_widget_get_window (widget);
5173       device_enable_foreach_window (window, &data);
5174     }
5175   else
5176     {
5177       GList *window_list;
5178 
5179       window_list = gdk_window_peek_children (_gtk_widget_get_window (widget));
5180       g_list_foreach (window_list, device_enable_foreach_window, &data);
5181     }
5182 
5183   if (recurse && GTK_IS_CONTAINER (widget))
5184     gtk_container_forall (GTK_CONTAINER (widget), device_enable_foreach, &data);
5185 }
5186 
5187 static void
gtk_widget_update_devices_mask(GtkWidget * widget,gboolean recurse)5188 gtk_widget_update_devices_mask (GtkWidget *widget,
5189                                 gboolean   recurse)
5190 {
5191   GList *enabled_devices, *l;
5192 
5193   enabled_devices = g_object_get_qdata (G_OBJECT (widget), quark_enabled_devices);
5194 
5195   for (l = enabled_devices; l; l = l->next)
5196     gtk_widget_set_device_enabled_internal (widget, GDK_DEVICE (l->data), recurse, TRUE);
5197 }
5198 
5199 typedef struct _GtkTickCallbackInfo GtkTickCallbackInfo;
5200 
5201 struct _GtkTickCallbackInfo
5202 {
5203   guint refcount;
5204 
5205   guint id;
5206   GtkTickCallback callback;
5207   gpointer user_data;
5208   GDestroyNotify notify;
5209 
5210   guint destroyed : 1;
5211 };
5212 
5213 static void
ref_tick_callback_info(GtkTickCallbackInfo * info)5214 ref_tick_callback_info (GtkTickCallbackInfo *info)
5215 {
5216   info->refcount++;
5217 }
5218 
5219 static void
unref_tick_callback_info(GtkWidget * widget,GtkTickCallbackInfo * info,GList * link)5220 unref_tick_callback_info (GtkWidget           *widget,
5221                           GtkTickCallbackInfo *info,
5222                           GList               *link)
5223 {
5224   GtkWidgetPrivate *priv = widget->priv;
5225 
5226   info->refcount--;
5227   if (info->refcount == 0)
5228     {
5229       priv->tick_callbacks = g_list_delete_link (priv->tick_callbacks, link);
5230       if (info->notify)
5231         info->notify (info->user_data);
5232       g_slice_free (GtkTickCallbackInfo, info);
5233     }
5234 
5235   if (priv->tick_callbacks == NULL && priv->clock_tick_id)
5236     {
5237       GdkFrameClock *frame_clock = gtk_widget_get_frame_clock (widget);
5238       g_signal_handler_disconnect (frame_clock, priv->clock_tick_id);
5239       priv->clock_tick_id = 0;
5240       gdk_frame_clock_end_updating (frame_clock);
5241     }
5242 }
5243 
5244 static void
destroy_tick_callback_info(GtkWidget * widget,GtkTickCallbackInfo * info,GList * link)5245 destroy_tick_callback_info (GtkWidget           *widget,
5246                             GtkTickCallbackInfo *info,
5247                             GList               *link)
5248 {
5249   if (!info->destroyed)
5250     {
5251       info->destroyed = TRUE;
5252       unref_tick_callback_info (widget, info, link);
5253     }
5254 }
5255 
5256 static void
destroy_tick_callbacks(GtkWidget * widget)5257 destroy_tick_callbacks (GtkWidget *widget)
5258 {
5259   GtkWidgetPrivate *priv = widget->priv;
5260   GList *l;
5261 
5262   for (l = priv->tick_callbacks; l;)
5263     {
5264       GList *next = l->next;
5265       destroy_tick_callback_info (widget, l->data, l);
5266       l = next;
5267     }
5268 }
5269 
5270 static void
gtk_widget_on_frame_clock_update(GdkFrameClock * frame_clock,GtkWidget * widget)5271 gtk_widget_on_frame_clock_update (GdkFrameClock *frame_clock,
5272                                   GtkWidget     *widget)
5273 {
5274   GtkWidgetPrivate *priv = widget->priv;
5275   GList *l;
5276 
5277   g_object_ref (widget);
5278 
5279   for (l = priv->tick_callbacks; l;)
5280     {
5281       GtkTickCallbackInfo *info = l->data;
5282       GList *next;
5283 
5284       ref_tick_callback_info (info);
5285       if (!info->destroyed)
5286         {
5287           if (info->callback (widget,
5288                               frame_clock,
5289                               info->user_data) == G_SOURCE_REMOVE)
5290             {
5291               destroy_tick_callback_info (widget, info, l);
5292             }
5293         }
5294 
5295       next = l->next;
5296       unref_tick_callback_info (widget, info, l);
5297       l = next;
5298     }
5299 
5300   g_object_unref (widget);
5301 }
5302 
5303 static guint tick_callback_id;
5304 
5305 /**
5306  * gtk_widget_add_tick_callback:
5307  * @widget: a #GtkWidget
5308  * @callback: function to call for updating animations
5309  * @user_data: data to pass to @callback
5310  * @notify: function to call to free @user_data when the callback is removed.
5311  *
5312  * Queues an animation frame update and adds a callback to be called
5313  * before each frame. Until the tick callback is removed, it will be
5314  * called frequently (usually at the frame rate of the output device
5315  * or as quickly as the application can be repainted, whichever is
5316  * slower). For this reason, is most suitable for handling graphics
5317  * that change every frame or every few frames. The tick callback does
5318  * not automatically imply a relayout or repaint. If you want a
5319  * repaint or relayout, and aren’t changing widget properties that
5320  * would trigger that (for example, changing the text of a #GtkLabel),
5321  * then you will have to call gtk_widget_queue_resize() or
5322  * gtk_widget_queue_draw_area() yourself.
5323  *
5324  * gdk_frame_clock_get_frame_time() should generally be used for timing
5325  * continuous animations and
5326  * gdk_frame_timings_get_predicted_presentation_time() if you are
5327  * trying to display isolated frames at particular times.
5328  *
5329  * This is a more convenient alternative to connecting directly to the
5330  * #GdkFrameClock::update signal of #GdkFrameClock, since you don't
5331  * have to worry about when a #GdkFrameClock is assigned to a widget.
5332  *
5333  * Returns: an id for the connection of this callback. Remove the callback
5334  *     by passing it to gtk_widget_remove_tick_callback()
5335  *
5336  * Since: 3.8
5337  */
5338 guint
gtk_widget_add_tick_callback(GtkWidget * widget,GtkTickCallback callback,gpointer user_data,GDestroyNotify notify)5339 gtk_widget_add_tick_callback (GtkWidget       *widget,
5340                               GtkTickCallback  callback,
5341                               gpointer         user_data,
5342                               GDestroyNotify   notify)
5343 {
5344   GtkWidgetPrivate *priv;
5345   GtkTickCallbackInfo *info;
5346   GdkFrameClock *frame_clock;
5347 
5348   g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
5349 
5350   priv = widget->priv;
5351 
5352   if (priv->frameclock_connected && !priv->clock_tick_id)
5353     {
5354       frame_clock = gtk_widget_get_frame_clock (widget);
5355 
5356       if (frame_clock)
5357         {
5358           priv->clock_tick_id = g_signal_connect (frame_clock, "update",
5359                                                   G_CALLBACK (gtk_widget_on_frame_clock_update),
5360                                                   widget);
5361           gdk_frame_clock_begin_updating (frame_clock);
5362         }
5363     }
5364 
5365   info = g_slice_new0 (GtkTickCallbackInfo);
5366 
5367   info->refcount = 1;
5368   info->id = ++tick_callback_id;
5369   info->callback = callback;
5370   info->user_data = user_data;
5371   info->notify = notify;
5372 
5373   priv->tick_callbacks = g_list_prepend (priv->tick_callbacks,
5374                                          info);
5375 
5376   return info->id;
5377 }
5378 
5379 /**
5380  * gtk_widget_remove_tick_callback:
5381  * @widget: a #GtkWidget
5382  * @id: an id returned by gtk_widget_add_tick_callback()
5383  *
5384  * Removes a tick callback previously registered with
5385  * gtk_widget_add_tick_callback().
5386  *
5387  * Since: 3.8
5388  */
5389 void
gtk_widget_remove_tick_callback(GtkWidget * widget,guint id)5390 gtk_widget_remove_tick_callback (GtkWidget *widget,
5391                                  guint      id)
5392 {
5393   GtkWidgetPrivate *priv;
5394   GList *l;
5395 
5396   g_return_if_fail (GTK_IS_WIDGET (widget));
5397 
5398   priv = widget->priv;
5399 
5400   for (l = priv->tick_callbacks; l; l = l->next)
5401     {
5402       GtkTickCallbackInfo *info = l->data;
5403       if (info->id == id)
5404         {
5405           destroy_tick_callback_info (widget, info, l);
5406           return;
5407         }
5408     }
5409 }
5410 
5411 gboolean
gtk_widget_has_tick_callback(GtkWidget * widget)5412 gtk_widget_has_tick_callback (GtkWidget *widget)
5413 {
5414   return widget->priv->tick_callbacks != NULL;
5415 }
5416 
5417 static void
gtk_widget_connect_frame_clock(GtkWidget * widget,GdkFrameClock * frame_clock)5418 gtk_widget_connect_frame_clock (GtkWidget     *widget,
5419                                 GdkFrameClock *frame_clock)
5420 {
5421   GtkWidgetPrivate *priv = widget->priv;
5422 
5423   priv->frameclock_connected = TRUE;
5424 
5425   if (GTK_IS_CONTAINER (widget))
5426     _gtk_container_maybe_start_idle_sizer (GTK_CONTAINER (widget));
5427 
5428   if (priv->tick_callbacks != NULL && !priv->clock_tick_id)
5429     {
5430       priv->clock_tick_id = g_signal_connect (frame_clock, "update",
5431                                               G_CALLBACK (gtk_widget_on_frame_clock_update),
5432                                               widget);
5433       gdk_frame_clock_begin_updating (frame_clock);
5434     }
5435 
5436   gtk_css_node_invalidate_frame_clock (priv->cssnode, FALSE);
5437 
5438   if (priv->context)
5439     gtk_style_context_set_frame_clock (priv->context, frame_clock);
5440 }
5441 
5442 static void
gtk_widget_disconnect_frame_clock(GtkWidget * widget,GdkFrameClock * frame_clock)5443 gtk_widget_disconnect_frame_clock (GtkWidget     *widget,
5444                                    GdkFrameClock *frame_clock)
5445 {
5446   GtkWidgetPrivate *priv = widget->priv;
5447 
5448   if (GTK_IS_CONTAINER (widget))
5449     _gtk_container_stop_idle_sizer (GTK_CONTAINER (widget));
5450 
5451   gtk_css_node_invalidate_frame_clock (priv->cssnode, FALSE);
5452 
5453   if (priv->clock_tick_id)
5454     {
5455       g_signal_handler_disconnect (frame_clock, priv->clock_tick_id);
5456       priv->clock_tick_id = 0;
5457       gdk_frame_clock_end_updating (frame_clock);
5458     }
5459 
5460   priv->frameclock_connected = FALSE;
5461 
5462   if (priv->context)
5463     gtk_style_context_set_frame_clock (priv->context, NULL);
5464 }
5465 
5466 /**
5467  * gtk_widget_realize:
5468  * @widget: a #GtkWidget
5469  *
5470  * Creates the GDK (windowing system) resources associated with a
5471  * widget.  For example, @widget->window will be created when a widget
5472  * is realized.  Normally realization happens implicitly; if you show
5473  * a widget and all its parent containers, then the widget will be
5474  * realized and mapped automatically.
5475  *
5476  * Realizing a widget requires all
5477  * the widget’s parent widgets to be realized; calling
5478  * gtk_widget_realize() realizes the widget’s parents in addition to
5479  * @widget itself. If a widget is not yet inside a toplevel window
5480  * when you realize it, bad things will happen.
5481  *
5482  * This function is primarily used in widget implementations, and
5483  * isn’t very useful otherwise. Many times when you think you might
5484  * need it, a better approach is to connect to a signal that will be
5485  * called after the widget is realized automatically, such as
5486  * #GtkWidget::draw. Or simply g_signal_connect () to the
5487  * #GtkWidget::realize signal.
5488  **/
5489 void
gtk_widget_realize(GtkWidget * widget)5490 gtk_widget_realize (GtkWidget *widget)
5491 {
5492   GtkWidgetPrivate *priv;
5493   cairo_region_t *region;
5494 
5495   g_return_if_fail (GTK_IS_WIDGET (widget));
5496   g_return_if_fail (widget->priv->anchored ||
5497 		    GTK_IS_INVISIBLE (widget));
5498 
5499   priv = widget->priv;
5500 
5501   if (!_gtk_widget_get_realized (widget))
5502     {
5503       gtk_widget_push_verify_invariants (widget);
5504 
5505       /*
5506 	if (GTK_IS_CONTAINER (widget) && _gtk_widget_get_has_window (widget))
5507 	  g_message ("gtk_widget_realize(%s)", G_OBJECT_TYPE_NAME (widget));
5508       */
5509 
5510       if (priv->parent == NULL &&
5511           !_gtk_widget_is_toplevel (widget))
5512         g_warning ("Calling gtk_widget_realize() on a widget that isn't "
5513                    "inside a toplevel window is not going to work very well. "
5514                    "Widgets must be inside a toplevel container before realizing them.");
5515 
5516       if (priv->parent && !_gtk_widget_get_realized (priv->parent))
5517 	gtk_widget_realize (priv->parent);
5518 
5519       G_GNUC_BEGIN_IGNORE_DEPRECATIONS
5520       gtk_widget_ensure_style (widget);
5521       G_GNUC_END_IGNORE_DEPRECATIONS
5522 
5523       g_signal_emit (widget, widget_signals[REALIZE], 0);
5524 
5525       gtk_widget_real_set_has_tooltip (widget, gtk_widget_get_has_tooltip (widget), TRUE);
5526 
5527       if (priv->has_shape_mask)
5528 	{
5529 	  region = g_object_get_qdata (G_OBJECT (widget), quark_shape_info);
5530 	  gdk_window_shape_combine_region (priv->window, region, 0, 0);
5531 	}
5532 
5533       gtk_widget_update_input_shape (widget);
5534 
5535       if (priv->multidevice)
5536         gdk_window_set_support_multidevice (priv->window, TRUE);
5537 
5538       _gtk_widget_enable_device_events (widget);
5539       gtk_widget_update_devices_mask (widget, TRUE);
5540 
5541       gtk_widget_update_alpha (widget);
5542 
5543       if (priv->context)
5544 	gtk_style_context_set_scale (priv->context, gtk_widget_get_scale_factor (widget));
5545       gtk_widget_connect_frame_clock (widget,
5546                                       gtk_widget_get_frame_clock (widget));
5547 
5548       gtk_widget_pop_verify_invariants (widget);
5549     }
5550 }
5551 
5552 /**
5553  * gtk_widget_unrealize:
5554  * @widget: a #GtkWidget
5555  *
5556  * This function is only useful in widget implementations.
5557  * Causes a widget to be unrealized (frees all GDK resources
5558  * associated with the widget, such as @widget->window).
5559  **/
5560 void
gtk_widget_unrealize(GtkWidget * widget)5561 gtk_widget_unrealize (GtkWidget *widget)
5562 {
5563   g_return_if_fail (GTK_IS_WIDGET (widget));
5564 
5565   g_object_ref (widget);
5566   gtk_widget_push_verify_invariants (widget);
5567 
5568   if (widget->priv->has_shape_mask)
5569     gtk_widget_shape_combine_region (widget, NULL);
5570 
5571   if (g_object_get_qdata (G_OBJECT (widget), quark_input_shape_info))
5572     gtk_widget_input_shape_combine_region (widget, NULL);
5573 
5574   if (_gtk_widget_get_realized (widget))
5575     {
5576       if (widget->priv->mapped)
5577         gtk_widget_unmap (widget);
5578 
5579       gtk_widget_disconnect_frame_clock (widget,
5580                                          gtk_widget_get_frame_clock (widget));
5581 
5582       g_signal_emit (widget, widget_signals[UNREALIZE], 0);
5583       g_assert (!widget->priv->mapped);
5584       gtk_widget_set_realized (widget, FALSE);
5585     }
5586 
5587   gtk_widget_pop_verify_invariants (widget);
5588   g_object_unref (widget);
5589 }
5590 
5591 /*****************************************
5592  * Draw queueing.
5593  *****************************************/
5594 
5595 static void
gtk_widget_real_queue_draw_region(GtkWidget * widget,const cairo_region_t * region)5596 gtk_widget_real_queue_draw_region (GtkWidget         *widget,
5597 				   const cairo_region_t *region)
5598 {
5599   GtkWidgetPrivate *priv = widget->priv;
5600 
5601   gdk_window_invalidate_region (priv->window, region, TRUE);
5602 }
5603 
5604 /**
5605  * gtk_widget_queue_draw_region:
5606  * @widget: a #GtkWidget
5607  * @region: region to draw
5608  *
5609  * Invalidates the area of @widget defined by @region by calling
5610  * gdk_window_invalidate_region() on the widget’s window and all its
5611  * child windows. Once the main loop becomes idle (after the current
5612  * batch of events has been processed, roughly), the window will
5613  * receive expose events for the union of all regions that have been
5614  * invalidated.
5615  *
5616  * Normally you would only use this function in widget
5617  * implementations. You might also use it to schedule a redraw of a
5618  * #GtkDrawingArea or some portion thereof.
5619  *
5620  * Since: 3.0
5621  **/
5622 void
gtk_widget_queue_draw_region(GtkWidget * widget,const cairo_region_t * region)5623 gtk_widget_queue_draw_region (GtkWidget            *widget,
5624                               const cairo_region_t *region)
5625 {
5626   GtkWidget *w;
5627 
5628   g_return_if_fail (GTK_IS_WIDGET (widget));
5629 
5630   if (!_gtk_widget_get_realized (widget))
5631     return;
5632 
5633   /* Just return if the widget or one of its ancestors isn't mapped */
5634   for (w = widget; w != NULL; w = w->priv->parent)
5635     if (!_gtk_widget_get_mapped (w))
5636       return;
5637 
5638   WIDGET_CLASS (widget)->queue_draw_region (widget, region);
5639 }
5640 
5641 /**
5642  * gtk_widget_queue_draw_area:
5643  * @widget: a #GtkWidget
5644  * @x: x coordinate of upper-left corner of rectangle to redraw
5645  * @y: y coordinate of upper-left corner of rectangle to redraw
5646  * @width: width of region to draw
5647  * @height: height of region to draw
5648  *
5649  * Convenience function that calls gtk_widget_queue_draw_region() on
5650  * the region created from the given coordinates.
5651  *
5652  * The region here is specified in widget coordinates.
5653  * Widget coordinates are a bit odd; for historical reasons, they are
5654  * defined as @widget->window coordinates for widgets that return %TRUE for
5655  * gtk_widget_get_has_window(), and are relative to @widget->allocation.x,
5656  * @widget->allocation.y otherwise.
5657  *
5658  * @width or @height may be 0, in this case this function does
5659  * nothing. Negative values for @width and @height are not allowed.
5660  */
5661 void
gtk_widget_queue_draw_area(GtkWidget * widget,gint x,gint y,gint width,gint height)5662 gtk_widget_queue_draw_area (GtkWidget *widget,
5663 			    gint       x,
5664 			    gint       y,
5665 			    gint       width,
5666 			    gint       height)
5667 {
5668   GdkRectangle rect;
5669   cairo_region_t *region;
5670 
5671   g_return_if_fail (GTK_IS_WIDGET (widget));
5672   g_return_if_fail (width >= 0);
5673   g_return_if_fail (height >= 0);
5674 
5675   if (width == 0 || height == 0)
5676     return;
5677 
5678   rect.x = x;
5679   rect.y = y;
5680   rect.width = width;
5681   rect.height = height;
5682 
5683   region = cairo_region_create_rectangle (&rect);
5684   gtk_widget_queue_draw_region (widget, region);
5685   cairo_region_destroy (region);
5686 }
5687 
5688 /**
5689  * gtk_widget_queue_draw:
5690  * @widget: a #GtkWidget
5691  *
5692  * Equivalent to calling gtk_widget_queue_draw_area() for the
5693  * entire area of a widget.
5694  **/
5695 void
gtk_widget_queue_draw(GtkWidget * widget)5696 gtk_widget_queue_draw (GtkWidget *widget)
5697 {
5698   GdkRectangle rect;
5699 
5700   g_return_if_fail (GTK_IS_WIDGET (widget));
5701 
5702   gtk_widget_get_clip (widget, &rect);
5703 
5704   if (!_gtk_widget_get_has_window (widget))
5705     gtk_widget_queue_draw_area (widget,
5706                                 rect.x, rect.y, rect.width, rect.height);
5707   else
5708     gtk_widget_queue_draw_area (widget,
5709                                 0, 0, rect.width, rect.height);
5710 }
5711 
5712 static void
5713 gtk_widget_set_alloc_needed (GtkWidget *widget);
5714 /**
5715  * gtk_widget_queue_allocate:
5716  * @widget: a #GtkWidget
5717  *
5718  * This function is only for use in widget implementations.
5719  *
5720  * Flags the widget for a rerun of the GtkWidgetClass::size_allocate
5721  * function. Use this function instead of gtk_widget_queue_resize()
5722  * when the @widget's size request didn't change but it wants to
5723  * reposition its contents.
5724  *
5725  * An example user of this function is gtk_widget_set_halign().
5726  *
5727  * Since: 3.20
5728  */
5729 void
gtk_widget_queue_allocate(GtkWidget * widget)5730 gtk_widget_queue_allocate (GtkWidget *widget)
5731 {
5732   g_return_if_fail (GTK_IS_WIDGET (widget));
5733 
5734   if (_gtk_widget_get_realized (widget))
5735     gtk_widget_queue_draw (widget);
5736 
5737   gtk_widget_set_alloc_needed (widget);
5738 }
5739 
5740 /**
5741  * gtk_widget_queue_resize_internal:
5742  * @widget: a #GtkWidget
5743  *
5744  * Queue a resize on a widget, and on all other widgets grouped with this widget.
5745  **/
5746 void
gtk_widget_queue_resize_internal(GtkWidget * widget)5747 gtk_widget_queue_resize_internal (GtkWidget *widget)
5748 {
5749   GSList *groups, *l, *widgets;
5750 
5751   if (gtk_widget_get_resize_needed (widget))
5752     return;
5753 
5754   gtk_widget_queue_resize_on_widget (widget);
5755 
5756   groups = _gtk_widget_get_sizegroups (widget);
5757 
5758   for (l = groups; l; l = l->next)
5759   {
5760 
5761 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
5762     if (gtk_size_group_get_ignore_hidden (l->data) && !gtk_widget_is_visible (widget))
5763       continue;
5764 G_GNUC_END_IGNORE_DEPRECATIONS
5765 
5766     for (widgets = gtk_size_group_get_widgets (l->data); widgets; widgets = widgets->next)
5767       {
5768         gtk_widget_queue_resize_internal (widgets->data);
5769       }
5770   }
5771 
5772 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
5773   if (GTK_IS_RESIZE_CONTAINER (widget))
5774     {
5775       gtk_container_queue_resize_handler (GTK_CONTAINER (widget));
5776 G_GNUC_END_IGNORE_DEPRECATIONS;
5777     }
5778   else if (_gtk_widget_get_visible (widget))
5779     {
5780       GtkWidget *parent = _gtk_widget_get_parent (widget);
5781       if (parent)
5782         gtk_widget_queue_resize_internal (parent);
5783     }
5784 }
5785 
5786 /**
5787  * gtk_widget_queue_resize:
5788  * @widget: a #GtkWidget
5789  *
5790  * This function is only for use in widget implementations.
5791  * Flags a widget to have its size renegotiated; should
5792  * be called when a widget for some reason has a new size request.
5793  * For example, when you change the text in a #GtkLabel, #GtkLabel
5794  * queues a resize to ensure there’s enough space for the new text.
5795  *
5796  * Note that you cannot call gtk_widget_queue_resize() on a widget
5797  * from inside its implementation of the GtkWidgetClass::size_allocate
5798  * virtual method. Calls to gtk_widget_queue_resize() from inside
5799  * GtkWidgetClass::size_allocate will be silently ignored.
5800  **/
5801 void
gtk_widget_queue_resize(GtkWidget * widget)5802 gtk_widget_queue_resize (GtkWidget *widget)
5803 {
5804   g_return_if_fail (GTK_IS_WIDGET (widget));
5805 
5806   if (_gtk_widget_get_realized (widget))
5807     gtk_widget_queue_draw (widget);
5808 
5809   gtk_widget_queue_resize_internal (widget);
5810 }
5811 
5812 /**
5813  * gtk_widget_queue_resize_no_redraw:
5814  * @widget: a #GtkWidget
5815  *
5816  * This function works like gtk_widget_queue_resize(),
5817  * except that the widget is not invalidated.
5818  *
5819  * Since: 2.4
5820  **/
5821 void
gtk_widget_queue_resize_no_redraw(GtkWidget * widget)5822 gtk_widget_queue_resize_no_redraw (GtkWidget *widget)
5823 {
5824   g_return_if_fail (GTK_IS_WIDGET (widget));
5825 
5826   gtk_widget_queue_resize_internal (widget);
5827 }
5828 
5829 /**
5830  * gtk_widget_get_frame_clock:
5831  * @widget: a #GtkWidget
5832  *
5833  * Obtains the frame clock for a widget. The frame clock is a global
5834  * “ticker” that can be used to drive animations and repaints.  The
5835  * most common reason to get the frame clock is to call
5836  * gdk_frame_clock_get_frame_time(), in order to get a time to use for
5837  * animating. For example you might record the start of the animation
5838  * with an initial value from gdk_frame_clock_get_frame_time(), and
5839  * then update the animation by calling
5840  * gdk_frame_clock_get_frame_time() again during each repaint.
5841  *
5842  * gdk_frame_clock_request_phase() will result in a new frame on the
5843  * clock, but won’t necessarily repaint any widgets. To repaint a
5844  * widget, you have to use gtk_widget_queue_draw() which invalidates
5845  * the widget (thus scheduling it to receive a draw on the next
5846  * frame). gtk_widget_queue_draw() will also end up requesting a frame
5847  * on the appropriate frame clock.
5848  *
5849  * A widget’s frame clock will not change while the widget is
5850  * mapped. Reparenting a widget (which implies a temporary unmap) can
5851  * change the widget’s frame clock.
5852  *
5853  * Unrealized widgets do not have a frame clock.
5854  *
5855  * Returns: (nullable) (transfer none): a #GdkFrameClock,
5856  * or %NULL if widget is unrealized
5857  *
5858  * Since: 3.8
5859  */
5860 GdkFrameClock*
gtk_widget_get_frame_clock(GtkWidget * widget)5861 gtk_widget_get_frame_clock (GtkWidget *widget)
5862 {
5863   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
5864 
5865   if (widget->priv->realized)
5866     {
5867       /* We use gtk_widget_get_toplevel() here to make it explicit that
5868        * the frame clock is a property of the toplevel that a widget
5869        * is anchored to; gdk_window_get_toplevel() will go up the
5870        * hierarchy anyways, but should squash any funny business with
5871        * reparenting windows and widgets.
5872        */
5873       GtkWidget *toplevel = _gtk_widget_get_toplevel (widget);
5874       GdkWindow *window = _gtk_widget_get_window (toplevel);
5875       g_assert (window != NULL);
5876 
5877       return gdk_window_get_frame_clock (window);
5878     }
5879   else
5880     {
5881       return NULL;
5882     }
5883 }
5884 
5885 /**
5886  * gtk_widget_size_request:
5887  * @widget: a #GtkWidget
5888  * @requisition: (out): a #GtkRequisition to be filled in
5889  *
5890  * This function is typically used when implementing a #GtkContainer
5891  * subclass.  Obtains the preferred size of a widget. The container
5892  * uses this information to arrange its child widgets and decide what
5893  * size allocations to give them with gtk_widget_size_allocate().
5894  *
5895  * You can also call this function from an application, with some
5896  * caveats. Most notably, getting a size request requires the widget
5897  * to be associated with a screen, because font information may be
5898  * needed. Multihead-aware applications should keep this in mind.
5899  *
5900  * Also remember that the size request is not necessarily the size
5901  * a widget will actually be allocated.
5902  *
5903  * Deprecated: 3.0: Use gtk_widget_get_preferred_size() instead.
5904  **/
5905 void
gtk_widget_size_request(GtkWidget * widget,GtkRequisition * requisition)5906 gtk_widget_size_request (GtkWidget	*widget,
5907 			 GtkRequisition *requisition)
5908 {
5909   g_return_if_fail (GTK_IS_WIDGET (widget));
5910 
5911   gtk_widget_get_preferred_size (widget, requisition, NULL);
5912 }
5913 
5914 /**
5915  * gtk_widget_get_child_requisition:
5916  * @widget: a #GtkWidget
5917  * @requisition: (out): a #GtkRequisition to be filled in
5918  *
5919  * This function is only for use in widget implementations. Obtains
5920  * @widget->requisition, unless someone has forced a particular
5921  * geometry on the widget (e.g. with gtk_widget_set_size_request()),
5922  * in which case it returns that geometry instead of the widget's
5923  * requisition.
5924  *
5925  * This function differs from gtk_widget_size_request() in that
5926  * it retrieves the last size request value from @widget->requisition,
5927  * while gtk_widget_size_request() actually calls the "size_request" method
5928  * on @widget to compute the size request and fill in @widget->requisition,
5929  * and only then returns @widget->requisition.
5930  *
5931  * Because this function does not call the “size_request” method, it
5932  * can only be used when you know that @widget->requisition is
5933  * up-to-date, that is, gtk_widget_size_request() has been called
5934  * since the last time a resize was queued. In general, only container
5935  * implementations have this information; applications should use
5936  * gtk_widget_size_request().
5937  *
5938  *
5939  * Deprecated: 3.0: Use gtk_widget_get_preferred_size() instead.
5940  **/
5941 void
gtk_widget_get_child_requisition(GtkWidget * widget,GtkRequisition * requisition)5942 gtk_widget_get_child_requisition (GtkWidget	 *widget,
5943 				  GtkRequisition *requisition)
5944 {
5945   gtk_widget_get_preferred_size (widget, requisition, NULL);
5946 }
5947 
5948 static gboolean
invalidate_predicate(GdkWindow * window,gpointer data)5949 invalidate_predicate (GdkWindow *window,
5950 		      gpointer   data)
5951 {
5952   gpointer user_data;
5953 
5954   gdk_window_get_user_data (window, &user_data);
5955 
5956   return (user_data == data);
5957 }
5958 
5959 /* Invalidate @region in widget->window and all children
5960  * of widget->window owned by widget. @region is in the
5961  * same coordinates as widget->allocation and will be
5962  * modified by this call.
5963  */
5964 static void
gtk_widget_invalidate_widget_windows(GtkWidget * widget,cairo_region_t * region)5965 gtk_widget_invalidate_widget_windows (GtkWidget      *widget,
5966 				      cairo_region_t *region)
5967 {
5968   GtkWidgetPrivate *priv = widget->priv;
5969 
5970   if (!_gtk_widget_get_realized (widget))
5971     return;
5972 
5973   if (_gtk_widget_get_has_window (widget) && priv->parent)
5974     {
5975       int x, y;
5976 
5977       gdk_window_get_position (priv->window, &x, &y);
5978       cairo_region_translate (region, -x, -y);
5979     }
5980 
5981   gdk_window_invalidate_maybe_recurse (priv->window, region,
5982 				       invalidate_predicate, widget);
5983 }
5984 
5985 /**
5986  * gtk_widget_size_allocate_with_baseline:
5987  * @widget: a #GtkWidget
5988  * @allocation: position and size to be allocated to @widget
5989  * @baseline: The baseline of the child, or -1
5990  *
5991  * This function is only used by #GtkContainer subclasses, to assign a size,
5992  * position and (optionally) baseline to their child widgets.
5993  *
5994  * In this function, the allocation and baseline may be adjusted. It
5995  * will be forced to a 1x1 minimum size, and the
5996  * adjust_size_allocation virtual and adjust_baseline_allocation
5997  * methods on the child will be used to adjust the allocation and
5998  * baseline. Standard adjustments include removing the widget's
5999  * margins, and applying the widget’s #GtkWidget:halign and
6000  * #GtkWidget:valign properties.
6001  *
6002  * If the child widget does not have a valign of %GTK_ALIGN_BASELINE the
6003  * baseline argument is ignored and -1 is used instead.
6004  *
6005  * Since: 3.10
6006  **/
6007 void
gtk_widget_size_allocate_with_baseline(GtkWidget * widget,GtkAllocation * allocation,gint baseline)6008 gtk_widget_size_allocate_with_baseline (GtkWidget     *widget,
6009 					GtkAllocation *allocation,
6010 					gint           baseline)
6011 {
6012   GtkWidgetPrivate *priv;
6013   GdkRectangle real_allocation;
6014   GdkRectangle old_allocation, old_clip;
6015   GdkRectangle adjusted_allocation;
6016   gboolean alloc_needed;
6017   gboolean size_changed;
6018   gboolean baseline_changed;
6019   gboolean position_changed;
6020   gint natural_width, natural_height, dummy;
6021   gint min_width, min_height;
6022   gint old_baseline;
6023 
6024   g_return_if_fail (GTK_IS_WIDGET (widget));
6025 
6026   priv = widget->priv;
6027 
6028   if (!priv->visible && !_gtk_widget_is_toplevel (widget))
6029     return;
6030 
6031   gtk_widget_push_verify_invariants (widget);
6032 
6033 #ifdef G_ENABLE_DEBUG
6034   if (GTK_DISPLAY_DEBUG_CHECK (gtk_widget_get_display (widget), RESIZE))
6035     {
6036       priv->highlight_resize = TRUE;
6037       gtk_widget_queue_draw (widget);
6038     }
6039 
6040 #ifdef G_ENABLE_CONSISTENCY_CHECKS
6041   if (gtk_widget_get_resize_needed (widget))
6042     {
6043       g_warning ("Allocating size to %s %p without calling gtk_widget_get_preferred_width/height(). "
6044                  "How does the code know the size to allocate?",
6045                  gtk_widget_get_name (widget), widget);
6046     }
6047 #endif
6048 
6049   if (GTK_DEBUG_CHECK (GEOMETRY))
6050     {
6051       gint depth;
6052       GtkWidget *parent;
6053       const gchar *name;
6054 
6055       depth = 0;
6056       parent = widget;
6057       while (parent)
6058 	{
6059 	  depth++;
6060 	  parent = _gtk_widget_get_parent (parent);
6061 	}
6062 
6063       name = g_type_name (G_OBJECT_TYPE (G_OBJECT (widget)));
6064       g_message ("gtk_widget_size_allocate: %*s%s %d %d %d %d, baseline %d",
6065                  2 * depth, " ", name,
6066                  allocation->x, allocation->y,
6067                  allocation->width, allocation->height,
6068                  baseline);
6069     }
6070 #endif /* G_ENABLE_DEBUG */
6071 
6072   /* Never pass a baseline to a child unless it requested it.
6073      This means containers don't have to manually check for this. */
6074   if (baseline != -1 &&
6075       (gtk_widget_get_valign_with_baseline (widget) != GTK_ALIGN_BASELINE ||
6076        !_gtk_widget_has_baseline_support (widget)))
6077     baseline = -1;
6078 
6079   alloc_needed = priv->alloc_needed;
6080   /* Preserve request/allocate ordering */
6081   priv->alloc_needed = FALSE;
6082 
6083   old_allocation = priv->allocation;
6084   old_clip = priv->clip;
6085   old_baseline = priv->allocated_baseline;
6086   real_allocation = *allocation;
6087 
6088   priv->allocated_size = *allocation;
6089   priv->allocated_size_baseline = baseline;
6090 
6091   adjusted_allocation = real_allocation;
6092   if (gtk_widget_get_request_mode (widget) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
6093     {
6094       /* Go ahead and request the height for allocated width, note that the internals
6095        * of get_height_for_width will internally limit the for_size to natural size
6096        * when aligning implicitly.
6097        */
6098       gtk_widget_get_preferred_width (widget, &min_width, &natural_width);
6099       gtk_widget_get_preferred_height_for_width (widget, real_allocation.width, &min_height, &natural_height);
6100     }
6101   else
6102     {
6103       /* Go ahead and request the width for allocated height, note that the internals
6104        * of get_width_for_height will internally limit the for_size to natural size
6105        * when aligning implicitly.
6106        */
6107       gtk_widget_get_preferred_height (widget, &min_height, &natural_height);
6108       gtk_widget_get_preferred_width_for_height (widget, real_allocation.height, &min_width, &natural_width);
6109     }
6110 
6111 #ifdef G_ENABLE_CONSISTENCY_CHECKS
6112   if ((min_width > real_allocation.width || min_height > real_allocation.height) &&
6113       !GTK_IS_SCROLLABLE (widget))
6114     g_warning ("gtk_widget_size_allocate(): attempt to underallocate %s%s %s %p. "
6115                "Allocation is %dx%d, but minimum required size is %dx%d.",
6116                priv->parent ? G_OBJECT_TYPE_NAME (priv->parent) : "", priv->parent ? "'s child" : "toplevel",
6117                G_OBJECT_TYPE_NAME (widget), widget,
6118                real_allocation.width, real_allocation.height,
6119                min_width, min_height);
6120 #endif
6121   /* Now that we have the right natural height and width, go ahead and remove any margins from the
6122    * allocated sizes and possibly limit them to the natural sizes */
6123   GTK_WIDGET_GET_CLASS (widget)->adjust_size_allocation (widget,
6124 							 GTK_ORIENTATION_HORIZONTAL,
6125 							 &dummy,
6126 							 &natural_width,
6127 							 &adjusted_allocation.x,
6128 							 &adjusted_allocation.width);
6129   GTK_WIDGET_GET_CLASS (widget)->adjust_size_allocation (widget,
6130 							 GTK_ORIENTATION_VERTICAL,
6131 							 &dummy,
6132 							 &natural_height,
6133 							 &adjusted_allocation.y,
6134 							 &adjusted_allocation.height);
6135   if (baseline >= 0)
6136     GTK_WIDGET_GET_CLASS (widget)->adjust_baseline_allocation (widget,
6137 							       &baseline);
6138 
6139   if (adjusted_allocation.x < real_allocation.x ||
6140       adjusted_allocation.y < real_allocation.y ||
6141       (adjusted_allocation.x + adjusted_allocation.width) >
6142       (real_allocation.x + real_allocation.width) ||
6143       (adjusted_allocation.y + adjusted_allocation.height >
6144        real_allocation.y + real_allocation.height))
6145     {
6146       g_warning ("%s %p attempted to adjust its size allocation from %d,%d %dx%d to %d,%d %dx%d. adjust_size_allocation must keep allocation inside original bounds",
6147                  G_OBJECT_TYPE_NAME (widget), widget,
6148                  real_allocation.x, real_allocation.y, real_allocation.width, real_allocation.height,
6149                  adjusted_allocation.x, adjusted_allocation.y, adjusted_allocation.width, adjusted_allocation.height);
6150     }
6151   else
6152     {
6153       real_allocation = adjusted_allocation;
6154     }
6155 
6156   if (real_allocation.width < 0 || real_allocation.height < 0)
6157     {
6158       g_warning ("gtk_widget_size_allocate(): attempt to allocate widget with width %d and height %d",
6159 		 real_allocation.width,
6160 		 real_allocation.height);
6161     }
6162 
6163   real_allocation.width = MAX (real_allocation.width, 1);
6164   real_allocation.height = MAX (real_allocation.height, 1);
6165 
6166   baseline_changed = old_baseline != baseline;
6167   size_changed = (old_allocation.width != real_allocation.width ||
6168 		  old_allocation.height != real_allocation.height);
6169   position_changed = (old_allocation.x != real_allocation.x ||
6170 		      old_allocation.y != real_allocation.y);
6171 
6172   if (!alloc_needed && !size_changed && !position_changed && !baseline_changed)
6173     goto out;
6174 
6175   priv->allocated_baseline = baseline;
6176   if (g_signal_has_handler_pending (widget, widget_signals[SIZE_ALLOCATE], 0, FALSE))
6177     g_signal_emit (widget, widget_signals[SIZE_ALLOCATE], 0, &real_allocation);
6178   else
6179     GTK_WIDGET_GET_CLASS (widget)->size_allocate (widget, &real_allocation);
6180 
6181   /* Size allocation is god... after consulting god, no further requests or allocations are needed */
6182 #ifdef G_ENABLE_DEBUG
6183   if (GTK_DEBUG_CHECK (GEOMETRY) && gtk_widget_get_resize_needed (widget))
6184     {
6185       g_warning ("%s %p or a child called gtk_widget_queue_resize() during size_allocate().",
6186                  gtk_widget_get_name (widget), widget);
6187     }
6188 #endif
6189   gtk_widget_ensure_resize (widget);
6190   priv->alloc_needed = FALSE;
6191   priv->alloc_needed_on_child = FALSE;
6192 
6193   size_changed |= (old_clip.width != priv->clip.width ||
6194                    old_clip.height != priv->clip.height);
6195   position_changed |= (old_clip.x != priv->clip.x ||
6196                       old_clip.y != priv->clip.y);
6197 
6198   if (_gtk_widget_get_mapped (widget) && priv->redraw_on_alloc)
6199     {
6200       if (!_gtk_widget_get_has_window (widget) && position_changed)
6201 	{
6202 	  /* Invalidate union(old_clip,priv->clip) in priv->window
6203 	   */
6204 	  cairo_region_t *invalidate = cairo_region_create_rectangle (&priv->clip);
6205 	  cairo_region_union_rectangle (invalidate, &old_clip);
6206 
6207 	  gdk_window_invalidate_region (priv->window, invalidate, FALSE);
6208 	  cairo_region_destroy (invalidate);
6209 	}
6210 
6211       if (size_changed || baseline_changed)
6212 	{
6213           /* Invalidate union(old_clip,priv->clip) in priv->window and descendants owned by widget
6214            */
6215           cairo_region_t *invalidate = cairo_region_create_rectangle (&priv->clip);
6216           cairo_region_union_rectangle (invalidate, &old_clip);
6217 
6218           gtk_widget_invalidate_widget_windows (widget, invalidate);
6219           cairo_region_destroy (invalidate);
6220 	}
6221     }
6222 
6223   if ((size_changed || position_changed || baseline_changed) && priv->parent &&
6224       _gtk_widget_get_realized (priv->parent) && _gtk_container_get_reallocate_redraws (GTK_CONTAINER (priv->parent)))
6225     {
6226       cairo_region_t *invalidate = cairo_region_create_rectangle (&priv->parent->priv->clip);
6227       gtk_widget_invalidate_widget_windows (priv->parent, invalidate);
6228       cairo_region_destroy (invalidate);
6229     }
6230 
6231 out:
6232   if (priv->alloc_needed_on_child)
6233     gtk_widget_ensure_allocate (widget);
6234 
6235   gtk_widget_pop_verify_invariants (widget);
6236 }
6237 
6238 
6239 /**
6240  * gtk_widget_size_allocate:
6241  * @widget: a #GtkWidget
6242  * @allocation: position and size to be allocated to @widget
6243  *
6244  * This function is only used by #GtkContainer subclasses, to assign a size
6245  * and position to their child widgets.
6246  *
6247  * In this function, the allocation may be adjusted. It will be forced
6248  * to a 1x1 minimum size, and the adjust_size_allocation virtual
6249  * method on the child will be used to adjust the allocation. Standard
6250  * adjustments include removing the widget’s margins, and applying the
6251  * widget’s #GtkWidget:halign and #GtkWidget:valign properties.
6252  *
6253  * For baseline support in containers you need to use gtk_widget_size_allocate_with_baseline()
6254  * instead.
6255  **/
6256 void
gtk_widget_size_allocate(GtkWidget * widget,GtkAllocation * allocation)6257 gtk_widget_size_allocate (GtkWidget	*widget,
6258 			  GtkAllocation *allocation)
6259 {
6260   gtk_widget_size_allocate_with_baseline (widget, allocation, -1);
6261 }
6262 
6263 /**
6264  * gtk_widget_common_ancestor:
6265  * @widget_a: a #GtkWidget
6266  * @widget_b: a #GtkWidget
6267  *
6268  * Find the common ancestor of @widget_a and @widget_b that
6269  * is closest to the two widgets.
6270  *
6271  * Returns: (nullable): the closest common ancestor of @widget_a and
6272  *   @widget_b or %NULL if @widget_a and @widget_b do not
6273  *   share a common ancestor.
6274  **/
6275 static GtkWidget *
gtk_widget_common_ancestor(GtkWidget * widget_a,GtkWidget * widget_b)6276 gtk_widget_common_ancestor (GtkWidget *widget_a,
6277 			    GtkWidget *widget_b)
6278 {
6279   GtkWidget *parent_a;
6280   GtkWidget *parent_b;
6281   gint depth_a = 0;
6282   gint depth_b = 0;
6283 
6284   parent_a = widget_a;
6285   while (parent_a->priv->parent)
6286     {
6287       parent_a = parent_a->priv->parent;
6288       depth_a++;
6289     }
6290 
6291   parent_b = widget_b;
6292   while (parent_b->priv->parent)
6293     {
6294       parent_b = parent_b->priv->parent;
6295       depth_b++;
6296     }
6297 
6298   if (parent_a != parent_b)
6299     return NULL;
6300 
6301   while (depth_a > depth_b)
6302     {
6303       widget_a = widget_a->priv->parent;
6304       depth_a--;
6305     }
6306 
6307   while (depth_b > depth_a)
6308     {
6309       widget_b = widget_b->priv->parent;
6310       depth_b--;
6311     }
6312 
6313   while (widget_a != widget_b)
6314     {
6315       widget_a = widget_a->priv->parent;
6316       widget_b = widget_b->priv->parent;
6317     }
6318 
6319   return widget_a;
6320 }
6321 
6322 /**
6323  * gtk_widget_translate_coordinates:
6324  * @src_widget:  a #GtkWidget
6325  * @dest_widget: a #GtkWidget
6326  * @src_x: X position relative to @src_widget
6327  * @src_y: Y position relative to @src_widget
6328  * @dest_x: (out) (optional): location to store X position relative to @dest_widget
6329  * @dest_y: (out) (optional): location to store Y position relative to @dest_widget
6330  *
6331  * Translate coordinates relative to @src_widget’s allocation to coordinates
6332  * relative to @dest_widget’s allocations. In order to perform this
6333  * operation, both widgets must be realized, and must share a common
6334  * toplevel.
6335  *
6336  * Returns: %FALSE if either widget was not realized, or there
6337  *   was no common ancestor. In this case, nothing is stored in
6338  *   *@dest_x and *@dest_y. Otherwise %TRUE.
6339  **/
6340 gboolean
gtk_widget_translate_coordinates(GtkWidget * src_widget,GtkWidget * dest_widget,gint src_x,gint src_y,gint * dest_x,gint * dest_y)6341 gtk_widget_translate_coordinates (GtkWidget  *src_widget,
6342 				  GtkWidget  *dest_widget,
6343 				  gint        src_x,
6344 				  gint        src_y,
6345 				  gint       *dest_x,
6346 				  gint       *dest_y)
6347 {
6348   GtkWidgetPrivate *src_priv;
6349   GtkWidgetPrivate *dest_priv;
6350   GtkWidget *ancestor;
6351   GdkWindow *window;
6352   GList *dest_list = NULL;
6353 
6354   g_return_val_if_fail (GTK_IS_WIDGET (src_widget), FALSE);
6355   g_return_val_if_fail (GTK_IS_WIDGET (dest_widget), FALSE);
6356 
6357   ancestor = gtk_widget_common_ancestor (src_widget, dest_widget);
6358   if (!ancestor || !_gtk_widget_get_realized (src_widget) || !_gtk_widget_get_realized (dest_widget))
6359     return FALSE;
6360 
6361   src_priv = src_widget->priv;
6362   dest_priv = dest_widget->priv;
6363 
6364   /* Translate from allocation relative to window relative */
6365   if (_gtk_widget_get_has_window (src_widget) && src_priv->parent)
6366     {
6367       gint wx, wy;
6368       gdk_window_get_position (src_priv->window, &wx, &wy);
6369 
6370       src_x -= wx - src_priv->allocation.x;
6371       src_y -= wy - src_priv->allocation.y;
6372     }
6373   else
6374     {
6375       src_x += src_priv->allocation.x;
6376       src_y += src_priv->allocation.y;
6377     }
6378 
6379   /* Translate to the common ancestor */
6380   window = src_priv->window;
6381   while (window != ancestor->priv->window)
6382     {
6383       gdouble dx, dy;
6384 
6385       gdk_window_coords_to_parent (window, src_x, src_y, &dx, &dy);
6386 
6387       src_x = dx;
6388       src_y = dy;
6389 
6390       window = gdk_window_get_effective_parent (window);
6391 
6392       if (!window)		/* Handle GtkHandleBox */
6393 	return FALSE;
6394     }
6395 
6396   /* And back */
6397   window = dest_priv->window;
6398   while (window != ancestor->priv->window)
6399     {
6400       dest_list = g_list_prepend (dest_list, window);
6401 
6402       window = gdk_window_get_effective_parent (window);
6403 
6404       if (!window)		/* Handle GtkHandleBox */
6405         {
6406           g_list_free (dest_list);
6407           return FALSE;
6408         }
6409     }
6410 
6411   while (dest_list)
6412     {
6413       gdouble dx, dy;
6414 
6415       gdk_window_coords_from_parent (dest_list->data, src_x, src_y, &dx, &dy);
6416 
6417       src_x = dx;
6418       src_y = dy;
6419 
6420       dest_list = g_list_remove (dest_list, dest_list->data);
6421     }
6422 
6423   /* Translate from window relative to allocation relative */
6424   if (_gtk_widget_get_has_window (dest_widget) && dest_priv->parent)
6425     {
6426       gint wx, wy;
6427       gdk_window_get_position (dest_priv->window, &wx, &wy);
6428 
6429       src_x += wx - dest_priv->allocation.x;
6430       src_y += wy - dest_priv->allocation.y;
6431     }
6432   else
6433     {
6434       src_x -= dest_priv->allocation.x;
6435       src_y -= dest_priv->allocation.y;
6436     }
6437 
6438   if (dest_x)
6439     *dest_x = src_x;
6440   if (dest_y)
6441     *dest_y = src_y;
6442 
6443   return TRUE;
6444 }
6445 
6446 static void
gtk_widget_real_size_allocate(GtkWidget * widget,GtkAllocation * allocation)6447 gtk_widget_real_size_allocate (GtkWidget     *widget,
6448 			       GtkAllocation *allocation)
6449 {
6450   GtkWidgetPrivate *priv = widget->priv;
6451 
6452   gtk_widget_set_allocation (widget, allocation);
6453 
6454   if (_gtk_widget_get_realized (widget) &&
6455       _gtk_widget_get_has_window (widget))
6456      {
6457 	gdk_window_move_resize (priv->window,
6458 				allocation->x, allocation->y,
6459 				allocation->width, allocation->height);
6460      }
6461 }
6462 
6463 /* translate initial/final into start/end */
6464 static GtkAlign
effective_align(GtkAlign align,GtkTextDirection direction)6465 effective_align (GtkAlign         align,
6466                  GtkTextDirection direction)
6467 {
6468   switch (align)
6469     {
6470     case GTK_ALIGN_START:
6471       return direction == GTK_TEXT_DIR_RTL ? GTK_ALIGN_END : GTK_ALIGN_START;
6472     case GTK_ALIGN_END:
6473       return direction == GTK_TEXT_DIR_RTL ? GTK_ALIGN_START : GTK_ALIGN_END;
6474     default:
6475       return align;
6476     }
6477 }
6478 
6479 static void
adjust_for_align(GtkAlign align,gint * natural_size,gint * allocated_pos,gint * allocated_size)6480 adjust_for_align (GtkAlign  align,
6481                   gint     *natural_size,
6482                   gint     *allocated_pos,
6483                   gint     *allocated_size)
6484 {
6485   switch (align)
6486     {
6487     case GTK_ALIGN_BASELINE:
6488     case GTK_ALIGN_FILL:
6489       /* change nothing */
6490       break;
6491     case GTK_ALIGN_START:
6492       /* keep *allocated_pos where it is */
6493       *allocated_size = MIN (*allocated_size, *natural_size);
6494       break;
6495     case GTK_ALIGN_END:
6496       if (*allocated_size > *natural_size)
6497 	{
6498 	  *allocated_pos += (*allocated_size - *natural_size);
6499 	  *allocated_size = *natural_size;
6500 	}
6501       break;
6502     case GTK_ALIGN_CENTER:
6503       if (*allocated_size > *natural_size)
6504 	{
6505 	  *allocated_pos += (*allocated_size - *natural_size) / 2;
6506 	  *allocated_size = MIN (*allocated_size, *natural_size);
6507 	}
6508       break;
6509     }
6510 }
6511 
6512 static void
adjust_for_margin(gint start_margin,gint end_margin,gint * minimum_size,gint * natural_size,gint * allocated_pos,gint * allocated_size)6513 adjust_for_margin(gint               start_margin,
6514                   gint               end_margin,
6515                   gint              *minimum_size,
6516                   gint              *natural_size,
6517                   gint              *allocated_pos,
6518                   gint              *allocated_size)
6519 {
6520   *minimum_size -= (start_margin + end_margin);
6521   *natural_size -= (start_margin + end_margin);
6522   *allocated_pos += start_margin;
6523   *allocated_size -= (start_margin + end_margin);
6524 }
6525 
6526 static void
gtk_widget_real_adjust_size_allocation(GtkWidget * widget,GtkOrientation orientation,gint * minimum_size,gint * natural_size,gint * allocated_pos,gint * allocated_size)6527 gtk_widget_real_adjust_size_allocation (GtkWidget         *widget,
6528                                         GtkOrientation     orientation,
6529                                         gint              *minimum_size,
6530                                         gint              *natural_size,
6531                                         gint              *allocated_pos,
6532                                         gint              *allocated_size)
6533 {
6534   GtkWidgetPrivate *priv = widget->priv;
6535 
6536   if (orientation == GTK_ORIENTATION_HORIZONTAL)
6537     {
6538       adjust_for_margin (priv->margin.left,
6539                          priv->margin.right,
6540                          minimum_size, natural_size,
6541                          allocated_pos, allocated_size);
6542       adjust_for_align (effective_align (priv->halign, _gtk_widget_get_direction (widget)),
6543                         natural_size, allocated_pos, allocated_size);
6544     }
6545   else
6546     {
6547       adjust_for_margin (priv->margin.top,
6548                          priv->margin.bottom,
6549                          minimum_size, natural_size,
6550                          allocated_pos, allocated_size);
6551       adjust_for_align (effective_align (priv->valign, GTK_TEXT_DIR_NONE),
6552                         natural_size, allocated_pos, allocated_size);
6553     }
6554 }
6555 
6556 static void
gtk_widget_real_adjust_baseline_allocation(GtkWidget * widget,gint * baseline)6557 gtk_widget_real_adjust_baseline_allocation (GtkWidget *widget,
6558 					    gint      *baseline)
6559 {
6560   if (*baseline >= 0)
6561     *baseline -= widget->priv->margin.top;
6562 }
6563 
6564 static gboolean
gtk_widget_real_can_activate_accel(GtkWidget * widget,guint signal_id)6565 gtk_widget_real_can_activate_accel (GtkWidget *widget,
6566                                     guint      signal_id)
6567 {
6568   GtkWidgetPrivate *priv = widget->priv;
6569 
6570   /* widgets must be onscreen for accels to take effect */
6571   return gtk_widget_is_sensitive (widget) &&
6572          _gtk_widget_is_drawable (widget) &&
6573          gdk_window_is_viewable (priv->window);
6574 }
6575 
6576 /**
6577  * gtk_widget_can_activate_accel:
6578  * @widget: a #GtkWidget
6579  * @signal_id: the ID of a signal installed on @widget
6580  *
6581  * Determines whether an accelerator that activates the signal
6582  * identified by @signal_id can currently be activated.
6583  * This is done by emitting the #GtkWidget::can-activate-accel
6584  * signal on @widget; if the signal isn’t overridden by a
6585  * handler or in a derived widget, then the default check is
6586  * that the widget must be sensitive, and the widget and all
6587  * its ancestors mapped.
6588  *
6589  * Returns: %TRUE if the accelerator can be activated.
6590  *
6591  * Since: 2.4
6592  **/
6593 gboolean
gtk_widget_can_activate_accel(GtkWidget * widget,guint signal_id)6594 gtk_widget_can_activate_accel (GtkWidget *widget,
6595                                guint      signal_id)
6596 {
6597   gboolean can_activate = FALSE;
6598   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
6599   g_signal_emit (widget, widget_signals[CAN_ACTIVATE_ACCEL], 0, signal_id, &can_activate);
6600   return can_activate;
6601 }
6602 
6603 typedef struct {
6604   GClosure   closure;
6605   guint      signal_id;
6606 } AccelClosure;
6607 
6608 static void
closure_accel_activate(GClosure * closure,GValue * return_value,guint n_param_values,const GValue * param_values,gpointer invocation_hint,gpointer marshal_data)6609 closure_accel_activate (GClosure     *closure,
6610 			GValue       *return_value,
6611 			guint         n_param_values,
6612 			const GValue *param_values,
6613 			gpointer      invocation_hint,
6614 			gpointer      marshal_data)
6615 {
6616   AccelClosure *aclosure = (AccelClosure*) closure;
6617   gboolean can_activate = gtk_widget_can_activate_accel (closure->data, aclosure->signal_id);
6618 
6619   if (can_activate)
6620     g_signal_emit (closure->data, aclosure->signal_id, 0);
6621 
6622   /* whether accelerator was handled */
6623   g_value_set_boolean (return_value, can_activate);
6624 }
6625 
6626 static void
closures_destroy(gpointer data)6627 closures_destroy (gpointer data)
6628 {
6629   GSList *slist, *closures = data;
6630 
6631   for (slist = closures; slist; slist = slist->next)
6632     {
6633       g_closure_invalidate (slist->data);
6634       g_closure_unref (slist->data);
6635     }
6636   g_slist_free (closures);
6637 }
6638 
6639 static GClosure*
widget_new_accel_closure(GtkWidget * widget,guint signal_id)6640 widget_new_accel_closure (GtkWidget *widget,
6641 			  guint      signal_id)
6642 {
6643   AccelClosure *aclosure;
6644   GClosure *closure = NULL;
6645   GSList *slist, *closures;
6646 
6647   closures = g_object_steal_qdata (G_OBJECT (widget), quark_accel_closures);
6648   for (slist = closures; slist; slist = slist->next)
6649     if (!gtk_accel_group_from_accel_closure (slist->data))
6650       {
6651 	/* reuse this closure */
6652 	closure = slist->data;
6653 	break;
6654       }
6655   if (!closure)
6656     {
6657       closure = g_closure_new_object (sizeof (AccelClosure), G_OBJECT (widget));
6658       closures = g_slist_prepend (closures, g_closure_ref (closure));
6659       g_closure_sink (closure);
6660       g_closure_set_marshal (closure, closure_accel_activate);
6661     }
6662   g_object_set_qdata_full (G_OBJECT (widget), quark_accel_closures, closures, closures_destroy);
6663 
6664   aclosure = (AccelClosure*) closure;
6665   g_assert (closure->data == widget);
6666   g_assert (closure->marshal == closure_accel_activate);
6667   aclosure->signal_id = signal_id;
6668 
6669   return closure;
6670 }
6671 
6672 /**
6673  * gtk_widget_add_accelerator:
6674  * @widget:       widget to install an accelerator on
6675  * @accel_signal: widget signal to emit on accelerator activation
6676  * @accel_group:  accel group for this widget, added to its toplevel
6677  * @accel_key:    GDK keyval of the accelerator
6678  * @accel_mods:   modifier key combination of the accelerator
6679  * @accel_flags:  flag accelerators, e.g. %GTK_ACCEL_VISIBLE
6680  *
6681  * Installs an accelerator for this @widget in @accel_group that causes
6682  * @accel_signal to be emitted if the accelerator is activated.
6683  * The @accel_group needs to be added to the widget’s toplevel via
6684  * gtk_window_add_accel_group(), and the signal must be of type %G_SIGNAL_ACTION.
6685  * Accelerators added through this function are not user changeable during
6686  * runtime. If you want to support accelerators that can be changed by the
6687  * user, use gtk_accel_map_add_entry() and gtk_widget_set_accel_path() or
6688  * gtk_menu_item_set_accel_path() instead.
6689  */
6690 void
gtk_widget_add_accelerator(GtkWidget * widget,const gchar * accel_signal,GtkAccelGroup * accel_group,guint accel_key,GdkModifierType accel_mods,GtkAccelFlags accel_flags)6691 gtk_widget_add_accelerator (GtkWidget      *widget,
6692 			    const gchar    *accel_signal,
6693 			    GtkAccelGroup  *accel_group,
6694 			    guint           accel_key,
6695 			    GdkModifierType accel_mods,
6696 			    GtkAccelFlags   accel_flags)
6697 {
6698   GClosure *closure;
6699   GSignalQuery query;
6700 
6701   g_return_if_fail (GTK_IS_WIDGET (widget));
6702   g_return_if_fail (accel_signal != NULL);
6703   g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
6704 
6705   g_signal_query (g_signal_lookup (accel_signal, G_OBJECT_TYPE (widget)), &query);
6706   if (!query.signal_id ||
6707       !(query.signal_flags & G_SIGNAL_ACTION) ||
6708       query.return_type != G_TYPE_NONE ||
6709       query.n_params)
6710     {
6711       /* hmm, should be elaborate enough */
6712       g_warning (G_STRLOC ": widget '%s' has no activatable signal \"%s\" without arguments",
6713 		 G_OBJECT_TYPE_NAME (widget), accel_signal);
6714       return;
6715     }
6716 
6717   closure = widget_new_accel_closure (widget, query.signal_id);
6718 
6719   g_object_ref (widget);
6720 
6721   /* install the accelerator. since we don't map this onto an accel_path,
6722    * the accelerator will automatically be locked.
6723    */
6724   gtk_accel_group_connect (accel_group,
6725 			   accel_key,
6726 			   accel_mods,
6727 			   accel_flags | GTK_ACCEL_LOCKED,
6728 			   closure);
6729 
6730   g_signal_emit (widget, widget_signals[ACCEL_CLOSURES_CHANGED], 0);
6731 
6732   g_object_unref (widget);
6733 }
6734 
6735 /**
6736  * gtk_widget_remove_accelerator:
6737  * @widget:       widget to install an accelerator on
6738  * @accel_group:  accel group for this widget
6739  * @accel_key:    GDK keyval of the accelerator
6740  * @accel_mods:   modifier key combination of the accelerator
6741  *
6742  * Removes an accelerator from @widget, previously installed with
6743  * gtk_widget_add_accelerator().
6744  *
6745  * Returns: whether an accelerator was installed and could be removed
6746  */
6747 gboolean
gtk_widget_remove_accelerator(GtkWidget * widget,GtkAccelGroup * accel_group,guint accel_key,GdkModifierType accel_mods)6748 gtk_widget_remove_accelerator (GtkWidget      *widget,
6749 			       GtkAccelGroup  *accel_group,
6750 			       guint           accel_key,
6751 			       GdkModifierType accel_mods)
6752 {
6753   GtkAccelGroupEntry *ag_entry;
6754   GList *slist, *clist;
6755   guint n;
6756 
6757   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
6758   g_return_val_if_fail (GTK_IS_ACCEL_GROUP (accel_group), FALSE);
6759 
6760   ag_entry = gtk_accel_group_query (accel_group, accel_key, accel_mods, &n);
6761   clist = gtk_widget_list_accel_closures (widget);
6762   for (slist = clist; slist; slist = slist->next)
6763     {
6764       guint i;
6765 
6766       for (i = 0; i < n; i++)
6767 	if (slist->data == (gpointer) ag_entry[i].closure)
6768 	  {
6769 	    gboolean is_removed = gtk_accel_group_disconnect (accel_group, slist->data);
6770 
6771 	    g_signal_emit (widget, widget_signals[ACCEL_CLOSURES_CHANGED], 0);
6772 
6773 	    g_list_free (clist);
6774 
6775 	    return is_removed;
6776 	  }
6777     }
6778   g_list_free (clist);
6779 
6780   g_warning (G_STRLOC ": no accelerator (%u,%u) installed in accel group (%p) for %s (%p)",
6781 	     accel_key, accel_mods, accel_group,
6782 	     G_OBJECT_TYPE_NAME (widget), widget);
6783 
6784   return FALSE;
6785 }
6786 
6787 /**
6788  * gtk_widget_list_accel_closures:
6789  * @widget:  widget to list accelerator closures for
6790  *
6791  * Lists the closures used by @widget for accelerator group connections
6792  * with gtk_accel_group_connect_by_path() or gtk_accel_group_connect().
6793  * The closures can be used to monitor accelerator changes on @widget,
6794  * by connecting to the @GtkAccelGroup::accel-changed signal of the
6795  * #GtkAccelGroup of a closure which can be found out with
6796  * gtk_accel_group_from_accel_closure().
6797  *
6798  * Returns: (transfer container) (element-type GClosure):
6799  *     a newly allocated #GList of closures
6800  */
6801 GList*
gtk_widget_list_accel_closures(GtkWidget * widget)6802 gtk_widget_list_accel_closures (GtkWidget *widget)
6803 {
6804   GSList *slist;
6805   GList *clist = NULL;
6806 
6807   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
6808 
6809   for (slist = g_object_get_qdata (G_OBJECT (widget), quark_accel_closures); slist; slist = slist->next)
6810     if (gtk_accel_group_from_accel_closure (slist->data))
6811       clist = g_list_prepend (clist, slist->data);
6812   return clist;
6813 }
6814 
6815 typedef struct {
6816   GQuark         path_quark;
6817   GtkAccelGroup *accel_group;
6818   GClosure      *closure;
6819 } AccelPath;
6820 
6821 static void
destroy_accel_path(gpointer data)6822 destroy_accel_path (gpointer data)
6823 {
6824   AccelPath *apath = data;
6825 
6826   gtk_accel_group_disconnect (apath->accel_group, apath->closure);
6827 
6828   /* closures_destroy takes care of unrefing the closure */
6829   g_object_unref (apath->accel_group);
6830 
6831   g_slice_free (AccelPath, apath);
6832 }
6833 
6834 
6835 /**
6836  * gtk_widget_set_accel_path:
6837  * @widget: a #GtkWidget
6838  * @accel_path: (allow-none): path used to look up the accelerator
6839  * @accel_group: (allow-none): a #GtkAccelGroup.
6840  *
6841  * Given an accelerator group, @accel_group, and an accelerator path,
6842  * @accel_path, sets up an accelerator in @accel_group so whenever the
6843  * key binding that is defined for @accel_path is pressed, @widget
6844  * will be activated.  This removes any accelerators (for any
6845  * accelerator group) installed by previous calls to
6846  * gtk_widget_set_accel_path(). Associating accelerators with
6847  * paths allows them to be modified by the user and the modifications
6848  * to be saved for future use. (See gtk_accel_map_save().)
6849  *
6850  * This function is a low level function that would most likely
6851  * be used by a menu creation system like #GtkUIManager. If you
6852  * use #GtkUIManager, setting up accelerator paths will be done
6853  * automatically.
6854  *
6855  * Even when you you aren’t using #GtkUIManager, if you only want to
6856  * set up accelerators on menu items gtk_menu_item_set_accel_path()
6857  * provides a somewhat more convenient interface.
6858  *
6859  * Note that @accel_path string will be stored in a #GQuark. Therefore, if you
6860  * pass a static string, you can save some memory by interning it first with
6861  * g_intern_static_string().
6862  **/
6863 void
gtk_widget_set_accel_path(GtkWidget * widget,const gchar * accel_path,GtkAccelGroup * accel_group)6864 gtk_widget_set_accel_path (GtkWidget     *widget,
6865 			   const gchar   *accel_path,
6866 			   GtkAccelGroup *accel_group)
6867 {
6868   AccelPath *apath;
6869 
6870   g_return_if_fail (GTK_IS_WIDGET (widget));
6871   g_return_if_fail (GTK_WIDGET_GET_CLASS (widget)->activate_signal != 0);
6872 
6873   if (accel_path)
6874     {
6875       g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
6876       g_return_if_fail (_gtk_accel_path_is_valid (accel_path));
6877 
6878       gtk_accel_map_add_entry (accel_path, 0, 0);
6879       apath = g_slice_new (AccelPath);
6880       apath->accel_group = g_object_ref (accel_group);
6881       apath->path_quark = g_quark_from_string (accel_path);
6882       apath->closure = widget_new_accel_closure (widget, GTK_WIDGET_GET_CLASS (widget)->activate_signal);
6883     }
6884   else
6885     apath = NULL;
6886 
6887   /* also removes possible old settings */
6888   g_object_set_qdata_full (G_OBJECT (widget), quark_accel_path, apath, destroy_accel_path);
6889 
6890   if (apath)
6891     gtk_accel_group_connect_by_path (apath->accel_group, g_quark_to_string (apath->path_quark), apath->closure);
6892 
6893   g_signal_emit (widget, widget_signals[ACCEL_CLOSURES_CHANGED], 0);
6894 }
6895 
6896 const gchar*
_gtk_widget_get_accel_path(GtkWidget * widget,gboolean * locked)6897 _gtk_widget_get_accel_path (GtkWidget *widget,
6898 			    gboolean  *locked)
6899 {
6900   AccelPath *apath;
6901 
6902   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
6903 
6904   apath = g_object_get_qdata (G_OBJECT (widget), quark_accel_path);
6905   if (locked)
6906     *locked = apath ? gtk_accel_group_get_is_locked (apath->accel_group) : TRUE;
6907   return apath ? g_quark_to_string (apath->path_quark) : NULL;
6908 }
6909 
6910 /**
6911  * gtk_widget_mnemonic_activate:
6912  * @widget: a #GtkWidget
6913  * @group_cycling: %TRUE if there are other widgets with the same mnemonic
6914  *
6915  * Emits the #GtkWidget::mnemonic-activate signal.
6916  *
6917  * Returns: %TRUE if the signal has been handled
6918  */
6919 gboolean
gtk_widget_mnemonic_activate(GtkWidget * widget,gboolean group_cycling)6920 gtk_widget_mnemonic_activate (GtkWidget *widget,
6921                               gboolean   group_cycling)
6922 {
6923   gboolean handled;
6924 
6925   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
6926 
6927   group_cycling = group_cycling != FALSE;
6928   if (!gtk_widget_is_sensitive (widget))
6929     handled = TRUE;
6930   else
6931     g_signal_emit (widget,
6932 		   widget_signals[MNEMONIC_ACTIVATE],
6933 		   0,
6934 		   group_cycling,
6935 		   &handled);
6936   return handled;
6937 }
6938 
6939 static gboolean
gtk_widget_real_mnemonic_activate(GtkWidget * widget,gboolean group_cycling)6940 gtk_widget_real_mnemonic_activate (GtkWidget *widget,
6941                                    gboolean   group_cycling)
6942 {
6943   if (!group_cycling && GTK_WIDGET_GET_CLASS (widget)->activate_signal)
6944     gtk_widget_activate (widget);
6945   else if (gtk_widget_get_can_focus (widget))
6946     gtk_widget_grab_focus (widget);
6947   else
6948     {
6949       g_warning ("widget '%s' isn't suitable for mnemonic activation",
6950 		 G_OBJECT_TYPE_NAME (widget));
6951       gtk_widget_error_bell (widget);
6952     }
6953   return TRUE;
6954 }
6955 
6956 static const cairo_user_data_key_t mark_for_draw_key;
6957 
6958 static gboolean
gtk_cairo_is_marked_for_draw(cairo_t * cr)6959 gtk_cairo_is_marked_for_draw (cairo_t *cr)
6960 {
6961   return cairo_get_user_data (cr, &mark_for_draw_key) != NULL;
6962 }
6963 
6964 static void
gtk_cairo_set_marked_for_draw(cairo_t * cr,gboolean marked)6965 gtk_cairo_set_marked_for_draw (cairo_t  *cr,
6966                                gboolean  marked)
6967 {
6968   if (marked)
6969     cairo_set_user_data (cr, &mark_for_draw_key, GINT_TO_POINTER (1), NULL);
6970   else
6971     cairo_set_user_data (cr, &mark_for_draw_key, NULL, NULL);
6972 }
6973 
6974 /**
6975  * gtk_cairo_should_draw_window:
6976  * @cr: a cairo context
6977  * @window: the window to check. @window may not be an input-only
6978  *          window.
6979  *
6980  * This function is supposed to be called in #GtkWidget::draw
6981  * implementations for widgets that support multiple windows.
6982  * @cr must be untransformed from invoking of the draw function.
6983  * This function will return %TRUE if the contents of the given
6984  * @window are supposed to be drawn and %FALSE otherwise. Note
6985  * that when the drawing was not initiated by the windowing
6986  * system this function will return %TRUE for all windows, so
6987  * you need to draw the bottommost window first. Also, do not
6988  * use “else if” statements to check which window should be drawn.
6989  *
6990  * Returns: %TRUE if @window should be drawn
6991  *
6992  * Since: 3.0
6993  */
6994 gboolean
gtk_cairo_should_draw_window(cairo_t * cr,GdkWindow * window)6995 gtk_cairo_should_draw_window (cairo_t   *cr,
6996                               GdkWindow *window)
6997 {
6998   GdkDrawingContext *context;
6999   GdkWindow *tmp;
7000 
7001   g_return_val_if_fail (cr != NULL, FALSE);
7002   g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7003 
7004   if (gtk_cairo_is_marked_for_draw (cr))
7005     return TRUE;
7006 
7007   context = gdk_cairo_get_drawing_context (cr);
7008   if (context == NULL)
7009     return TRUE;
7010 
7011   tmp = gdk_drawing_context_get_window (context);
7012   if (tmp == NULL)
7013     return TRUE;
7014 
7015   while (!gdk_window_has_native (window))
7016     window = gdk_window_get_parent (window);
7017 
7018   return tmp == window;
7019 }
7020 
7021 void
gtk_widget_draw_internal(GtkWidget * widget,cairo_t * cr,gboolean clip_to_size)7022 gtk_widget_draw_internal (GtkWidget *widget,
7023                           cairo_t   *cr,
7024                           gboolean   clip_to_size)
7025 {
7026   if (!_gtk_widget_is_drawable (widget))
7027     return;
7028 
7029   if (clip_to_size)
7030     {
7031       cairo_rectangle (cr,
7032                        widget->priv->clip.x - widget->priv->allocation.x,
7033                        widget->priv->clip.y - widget->priv->allocation.y,
7034                        widget->priv->clip.width,
7035                        widget->priv->clip.height);
7036       cairo_clip (cr);
7037     }
7038 
7039   if (gdk_cairo_get_clip_rectangle (cr, NULL))
7040     {
7041       GdkWindow *event_window = NULL;
7042       gboolean result;
7043       gboolean push_group;
7044 
7045       /* If this was a cairo_t passed via gtk_widget_draw() then we don't
7046        * require a window; otherwise we check for the window associated
7047        * to the drawing context and mark it using the clip region of the
7048        * Cairo context.
7049        */
7050       if (!gtk_cairo_is_marked_for_draw (cr))
7051         {
7052           GdkDrawingContext *context = gdk_cairo_get_drawing_context (cr);
7053 
7054           if (context != NULL)
7055             {
7056               event_window = gdk_drawing_context_get_window (context);
7057               if (event_window != NULL)
7058                 gdk_window_mark_paint_from_clip (event_window, cr);
7059             }
7060         }
7061 
7062       push_group =
7063         widget->priv->alpha != 255 &&
7064         (!_gtk_widget_is_toplevel (widget) ||
7065          gtk_widget_get_visual (widget) == gdk_screen_get_rgba_visual (gtk_widget_get_screen (widget)));
7066 
7067       if (push_group)
7068         cairo_push_group (cr);
7069 
7070 #ifdef G_ENABLE_CONSISTENCY_CHECKS
7071       if (_gtk_widget_get_alloc_needed (widget))
7072         g_warning ("%s %p is drawn without a current allocation. This should not happen.", G_OBJECT_TYPE_NAME (widget), widget);
7073 #endif
7074 
7075       if (g_signal_has_handler_pending (widget, widget_signals[DRAW], 0, FALSE))
7076         {
7077           g_signal_emit (widget, widget_signals[DRAW],
7078                          0, cr,
7079                          &result);
7080         }
7081       else if (GTK_WIDGET_GET_CLASS (widget)->draw)
7082         {
7083           cairo_save (cr);
7084           GTK_WIDGET_GET_CLASS (widget)->draw (widget, cr);
7085           cairo_restore (cr);
7086         }
7087 
7088 #ifdef G_ENABLE_DEBUG
7089       if (GTK_DISPLAY_DEBUG_CHECK (gtk_widget_get_display (widget), BASELINES))
7090 	{
7091 	  gint baseline = gtk_widget_get_allocated_baseline (widget);
7092 	  gint width = gtk_widget_get_allocated_width (widget);
7093 
7094 	  if (baseline != -1)
7095 	    {
7096 	      cairo_save (cr);
7097 	      cairo_new_path (cr);
7098 	      cairo_move_to (cr, 0, baseline+0.5);
7099 	      cairo_line_to (cr, width, baseline+0.5);
7100 	      cairo_set_line_width (cr, 1.0);
7101 	      cairo_set_source_rgba (cr, 1.0, 0, 0, 0.25);
7102 	      cairo_stroke (cr);
7103 	      cairo_restore (cr);
7104 	    }
7105 	}
7106       if (widget->priv->highlight_resize)
7107         {
7108           GtkAllocation alloc;
7109           gtk_widget_get_allocation (widget, &alloc);
7110 
7111           cairo_rectangle (cr, 0, 0, alloc.width, alloc.height);
7112           cairo_set_source_rgba (cr, 1, 0, 0, 0.2);
7113           cairo_fill (cr);
7114 
7115           gtk_widget_queue_draw (widget);
7116 
7117           widget->priv->highlight_resize = FALSE;
7118         }
7119 #endif
7120 
7121       if (push_group)
7122         {
7123           cairo_pop_group_to_source (cr);
7124           cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
7125           cairo_paint_with_alpha (cr, widget->priv->alpha / 255.0);
7126         }
7127 
7128       if (cairo_status (cr) &&
7129           event_window != NULL)
7130         {
7131           /* We check the event so we only warn about internal GTK+ calls.
7132            * Errors might come from PDF streams having write failures and
7133            * we don't want to spam stderr in that case.
7134            * We do want to catch errors from
7135            */
7136           g_warning ("drawing failure for widget '%s': %s",
7137                      G_OBJECT_TYPE_NAME (widget),
7138                      cairo_status_to_string (cairo_status (cr)));
7139         }
7140     }
7141 }
7142 
7143 /**
7144  * gtk_widget_draw:
7145  * @widget: the widget to draw. It must be drawable (see
7146  *   gtk_widget_is_drawable()) and a size must have been allocated.
7147  * @cr: a cairo context to draw to
7148  *
7149  * Draws @widget to @cr. The top left corner of the widget will be
7150  * drawn to the currently set origin point of @cr.
7151  *
7152  * You should pass a cairo context as @cr argument that is in an
7153  * original state. Otherwise the resulting drawing is undefined. For
7154  * example changing the operator using cairo_set_operator() or the
7155  * line width using cairo_set_line_width() might have unwanted side
7156  * effects.
7157  * You may however change the context’s transform matrix - like with
7158  * cairo_scale(), cairo_translate() or cairo_set_matrix() and clip
7159  * region with cairo_clip() prior to calling this function. Also, it
7160  * is fine to modify the context with cairo_save() and
7161  * cairo_push_group() prior to calling this function.
7162  *
7163  * Note that special-purpose widgets may contain special code for
7164  * rendering to the screen and might appear differently on screen
7165  * and when rendered using gtk_widget_draw().
7166  *
7167  * Since: 3.0
7168  **/
7169 void
gtk_widget_draw(GtkWidget * widget,cairo_t * cr)7170 gtk_widget_draw (GtkWidget *widget,
7171                  cairo_t   *cr)
7172 {
7173   gboolean was_marked;
7174 
7175   g_return_if_fail (GTK_IS_WIDGET (widget));
7176   g_return_if_fail (!widget->priv->alloc_needed);
7177   g_return_if_fail (!widget->priv->alloc_needed_on_child);
7178   g_return_if_fail (cr != NULL);
7179 
7180   cairo_save (cr);
7181 
7182   was_marked = gtk_cairo_is_marked_for_draw (cr);
7183 
7184   /* We mark the window so that gtk_cairo_should_draw_window()
7185    * will always return TRUE, and all GdkWindows get drawn
7186    */
7187   gtk_cairo_set_marked_for_draw (cr, TRUE);
7188 
7189   gtk_widget_draw_internal (widget, cr, TRUE);
7190 
7191   gtk_cairo_set_marked_for_draw (cr, was_marked);
7192 
7193   cairo_restore (cr);
7194 }
7195 
7196 static gboolean
gtk_widget_real_scroll_event(GtkWidget * widget,GdkEventScroll * event)7197 gtk_widget_real_scroll_event (GtkWidget      *widget,
7198                               GdkEventScroll *event)
7199 {
7200   return _gtk_widget_run_controllers (widget, (GdkEvent *) event,
7201                                       GTK_PHASE_BUBBLE);
7202 }
7203 
7204 static gboolean
gtk_widget_real_button_event(GtkWidget * widget,GdkEventButton * event)7205 gtk_widget_real_button_event (GtkWidget      *widget,
7206                               GdkEventButton *event)
7207 {
7208   return _gtk_widget_run_controllers (widget, (GdkEvent *) event,
7209                                       GTK_PHASE_BUBBLE);
7210 }
7211 
7212 static gboolean
gtk_widget_real_motion_event(GtkWidget * widget,GdkEventMotion * event)7213 gtk_widget_real_motion_event (GtkWidget      *widget,
7214                               GdkEventMotion *event)
7215 {
7216   return _gtk_widget_run_controllers (widget, (GdkEvent *) event,
7217                                       GTK_PHASE_BUBBLE);
7218 }
7219 
7220 static gboolean
gtk_widget_real_key_press_event(GtkWidget * widget,GdkEventKey * event)7221 gtk_widget_real_key_press_event (GtkWidget         *widget,
7222 				 GdkEventKey       *event)
7223 {
7224   if (_gtk_widget_run_controllers (widget, (GdkEvent *) event,
7225                                    GTK_PHASE_BUBBLE))
7226     return GDK_EVENT_STOP;
7227 
7228   return gtk_bindings_activate_event (G_OBJECT (widget), event);
7229 }
7230 
7231 static gboolean
gtk_widget_real_key_release_event(GtkWidget * widget,GdkEventKey * event)7232 gtk_widget_real_key_release_event (GtkWidget         *widget,
7233 				   GdkEventKey       *event)
7234 {
7235   if (_gtk_widget_run_controllers (widget, (GdkEvent *) event,
7236                                    GTK_PHASE_BUBBLE))
7237     return GDK_EVENT_STOP;
7238 
7239   return gtk_bindings_activate_event (G_OBJECT (widget), event);
7240 }
7241 
7242 static gboolean
gtk_widget_real_focus_in_event(GtkWidget * widget,GdkEventFocus * event)7243 gtk_widget_real_focus_in_event (GtkWidget     *widget,
7244                                 GdkEventFocus *event)
7245 {
7246   gtk_widget_queue_draw (widget);
7247 
7248   return FALSE;
7249 }
7250 
7251 static gboolean
gtk_widget_real_focus_out_event(GtkWidget * widget,GdkEventFocus * event)7252 gtk_widget_real_focus_out_event (GtkWidget     *widget,
7253                                  GdkEventFocus *event)
7254 {
7255   gtk_widget_queue_draw (widget);
7256 
7257   return FALSE;
7258 }
7259 
7260 static gboolean
gtk_widget_real_touch_event(GtkWidget * widget,GdkEventTouch * event)7261 gtk_widget_real_touch_event (GtkWidget     *widget,
7262                              GdkEventTouch *event)
7263 {
7264   GdkEvent *bevent;
7265   gboolean return_val = FALSE;
7266 
7267   if (!event->emulating_pointer)
7268     return _gtk_widget_run_controllers (widget, (GdkEvent*) event,
7269                                         GTK_PHASE_BUBBLE);
7270 
7271   if (event->type == GDK_TOUCH_UPDATE ||
7272       event->type == GDK_TOUCH_BEGIN)
7273     {
7274       bevent = gdk_event_new (GDK_MOTION_NOTIFY);
7275       bevent->any.window = g_object_ref (event->window);
7276       bevent->any.send_event = FALSE;
7277       bevent->motion.time = event->time;
7278       bevent->button.state = event->state;
7279       bevent->motion.x_root = event->x_root;
7280       bevent->motion.y_root = event->y_root;
7281       bevent->motion.x = event->x;
7282       bevent->motion.y = event->y;
7283       bevent->motion.device = event->device;
7284       bevent->motion.is_hint = FALSE;
7285       bevent->motion.axes = g_memdup (event->axes,
7286                                       sizeof (gdouble) * gdk_device_get_n_axes (event->device));
7287       gdk_event_set_source_device (bevent, gdk_event_get_source_device ((GdkEvent*)event));
7288 
7289       if (event->type == GDK_TOUCH_UPDATE)
7290         bevent->motion.state |= GDK_BUTTON1_MASK;
7291 
7292       g_signal_emit (widget, widget_signals[MOTION_NOTIFY_EVENT], 0, bevent, &return_val);
7293 
7294       gdk_event_free (bevent);
7295     }
7296 
7297   if (event->type == GDK_TOUCH_BEGIN ||
7298       event->type == GDK_TOUCH_END)
7299     {
7300       GdkEventType type;
7301       gint signum;
7302 
7303       if (event->type == GDK_TOUCH_BEGIN)
7304         {
7305           type = GDK_BUTTON_PRESS;
7306           signum = BUTTON_PRESS_EVENT;
7307         }
7308       else
7309         {
7310           type = GDK_BUTTON_RELEASE;
7311           signum = BUTTON_RELEASE_EVENT;
7312         }
7313       bevent = gdk_event_new (type);
7314       bevent->any.window = g_object_ref (event->window);
7315       bevent->any.send_event = FALSE;
7316       bevent->button.time = event->time;
7317       bevent->button.state = event->state;
7318       bevent->button.button = 1;
7319       bevent->button.x_root = event->x_root;
7320       bevent->button.y_root = event->y_root;
7321       bevent->button.x = event->x;
7322       bevent->button.y = event->y;
7323       bevent->button.device = event->device;
7324       bevent->button.axes = g_memdup (event->axes,
7325                                       sizeof (gdouble) * gdk_device_get_n_axes (event->device));
7326       gdk_event_set_source_device (bevent, gdk_event_get_source_device ((GdkEvent*)event));
7327 
7328       if (event->type == GDK_TOUCH_END)
7329         bevent->button.state |= GDK_BUTTON1_MASK;
7330 
7331       g_signal_emit (widget, widget_signals[signum], 0, bevent, &return_val);
7332 
7333       gdk_event_free (bevent);
7334     }
7335 
7336   return return_val;
7337 }
7338 
7339 static gboolean
gtk_widget_real_grab_broken_event(GtkWidget * widget,GdkEventGrabBroken * event)7340 gtk_widget_real_grab_broken_event (GtkWidget          *widget,
7341                                    GdkEventGrabBroken *event)
7342 {
7343   return _gtk_widget_run_controllers (widget, (GdkEvent*) event,
7344                                       GTK_PHASE_BUBBLE);
7345 }
7346 
7347 #define WIDGET_REALIZED_FOR_EVENT(widget, event) \
7348      (event->type == GDK_FOCUS_CHANGE || _gtk_widget_get_realized(widget))
7349 
7350 /**
7351  * gtk_widget_event:
7352  * @widget: a #GtkWidget
7353  * @event: a #GdkEvent
7354  *
7355  * Rarely-used function. This function is used to emit
7356  * the event signals on a widget (those signals should never
7357  * be emitted without using this function to do so).
7358  * If you want to synthesize an event though, don’t use this function;
7359  * instead, use gtk_main_do_event() so the event will behave as if
7360  * it were in the event queue. Don’t synthesize expose events; instead,
7361  * use gdk_window_invalidate_rect() to invalidate a region of the
7362  * window.
7363  *
7364  * Returns: return from the event signal emission (%TRUE if
7365  *               the event was handled)
7366  **/
7367 gboolean
gtk_widget_event(GtkWidget * widget,GdkEvent * event)7368 gtk_widget_event (GtkWidget *widget,
7369 		  GdkEvent  *event)
7370 {
7371   g_return_val_if_fail (GTK_IS_WIDGET (widget), TRUE);
7372   g_return_val_if_fail (WIDGET_REALIZED_FOR_EVENT (widget, event), TRUE);
7373 
7374   if (event->type == GDK_EXPOSE)
7375     {
7376       g_warning ("Events of type GDK_EXPOSE cannot be synthesized. To get "
7377 		 "the same effect, call gdk_window_invalidate_rect/region(), "
7378 		 "followed by gdk_window_process_updates().");
7379       return TRUE;
7380     }
7381 
7382   return gtk_widget_event_internal (widget, event);
7383 }
7384 
7385 void
_gtk_widget_set_captured_event_handler(GtkWidget * widget,GtkCapturedEventHandler callback)7386 _gtk_widget_set_captured_event_handler (GtkWidget               *widget,
7387                                         GtkCapturedEventHandler  callback)
7388 {
7389   g_object_set_data (G_OBJECT (widget), "captured-event-handler", callback);
7390 }
7391 
7392 static GdkEventMask
_gtk_widget_get_controllers_evmask(GtkWidget * widget)7393 _gtk_widget_get_controllers_evmask (GtkWidget *widget)
7394 {
7395   EventControllerData *data;
7396   GdkEventMask evmask = 0;
7397   GtkWidgetPrivate *priv;
7398   GList *l;
7399 
7400   priv = widget->priv;
7401 
7402   for (l = priv->event_controllers; l; l = l->next)
7403     {
7404       data = l->data;
7405       if (data->controller)
7406         evmask |= gtk_event_controller_get_event_mask (GTK_EVENT_CONTROLLER (data->controller));
7407     }
7408 
7409   return evmask;
7410 }
7411 
7412 static gboolean
_gtk_widget_run_controllers(GtkWidget * widget,const GdkEvent * event,GtkPropagationPhase phase)7413 _gtk_widget_run_controllers (GtkWidget           *widget,
7414                              const GdkEvent      *event,
7415                              GtkPropagationPhase  phase)
7416 {
7417   EventControllerData *data;
7418   gboolean handled = FALSE;
7419   GtkWidgetPrivate *priv;
7420   GList *l;
7421 
7422   priv = widget->priv;
7423   g_object_ref (widget);
7424 
7425   l = priv->event_controllers;
7426   while (l != NULL)
7427     {
7428       GList *next = l->next;
7429 
7430       if (!WIDGET_REALIZED_FOR_EVENT (widget, event))
7431         break;
7432 
7433       data = l->data;
7434 
7435       if (data->controller == NULL)
7436         {
7437           priv->event_controllers = g_list_delete_link (priv->event_controllers, l);
7438           g_free (data);
7439         }
7440       else
7441         {
7442           GtkPropagationPhase controller_phase;
7443 
7444           controller_phase = gtk_event_controller_get_propagation_phase (data->controller);
7445 
7446           if (controller_phase == phase)
7447             handled |= gtk_event_controller_handle_event (data->controller, event);
7448         }
7449 
7450       l = next;
7451     }
7452 
7453   g_object_unref (widget);
7454 
7455   return handled;
7456 }
7457 
7458 static void
cancel_event_sequence_on_hierarchy(GtkWidget * widget,GtkWidget * event_widget,GdkEventSequence * sequence)7459 cancel_event_sequence_on_hierarchy (GtkWidget        *widget,
7460                                     GtkWidget        *event_widget,
7461                                     GdkEventSequence *sequence)
7462 {
7463   gboolean cancel = TRUE;
7464 
7465   while (event_widget)
7466     {
7467       if (event_widget == widget)
7468         cancel = FALSE;
7469       else if (cancel)
7470         _gtk_widget_cancel_sequence (event_widget, sequence);
7471       else
7472         _gtk_widget_set_sequence_state_internal (event_widget, sequence,
7473                                                  GTK_EVENT_SEQUENCE_DENIED,
7474                                                  NULL);
7475 
7476       event_widget = _gtk_widget_get_parent (event_widget);
7477     }
7478 }
7479 
7480 gboolean
_gtk_widget_captured_event(GtkWidget * widget,GdkEvent * event)7481 _gtk_widget_captured_event (GtkWidget *widget,
7482                             GdkEvent  *event)
7483 {
7484   gboolean return_val = FALSE;
7485   GtkCapturedEventHandler handler;
7486 
7487   g_return_val_if_fail (GTK_IS_WIDGET (widget), TRUE);
7488   g_return_val_if_fail (WIDGET_REALIZED_FOR_EVENT (widget, event), TRUE);
7489 
7490   if (event->type == GDK_EXPOSE)
7491     {
7492       g_warning ("Events of type GDK_EXPOSE cannot be synthesized. To get "
7493 		 "the same effect, call gdk_window_invalidate_rect/region(), "
7494 		 "followed by gdk_window_process_updates().");
7495       return TRUE;
7496     }
7497 
7498   if (!event_window_is_still_viewable (event))
7499     return TRUE;
7500 
7501   return_val = _gtk_widget_run_controllers (widget, event, GTK_PHASE_CAPTURE);
7502 
7503   handler = g_object_get_data (G_OBJECT (widget), "captured-event-handler");
7504   if (!handler)
7505     return return_val;
7506 
7507   g_object_ref (widget);
7508 
7509   return_val |= handler (widget, event);
7510   return_val |= !WIDGET_REALIZED_FOR_EVENT (widget, event);
7511 
7512   /* The widget that was originally to receive the event
7513    * handles motion hints, but the capturing widget might
7514    * not, so ensure we get further motion events.
7515    */
7516   if (return_val &&
7517       event->type == GDK_MOTION_NOTIFY &&
7518       event->motion.is_hint &&
7519       (gdk_window_get_events (event->any.window) &
7520        GDK_POINTER_MOTION_HINT_MASK) != 0)
7521     gdk_event_request_motions (&event->motion);
7522 
7523   g_object_unref (widget);
7524 
7525   return return_val;
7526 }
7527 
7528 /* Returns TRUE if a translation should be done */
7529 static gboolean
_gtk_widget_get_translation_to_window(GtkWidget * widget,GdkWindow * window,int * x,int * y)7530 _gtk_widget_get_translation_to_window (GtkWidget      *widget,
7531 				       GdkWindow      *window,
7532 				       int            *x,
7533 				       int            *y)
7534 {
7535   GdkWindow *w, *widget_window;
7536 
7537   if (!_gtk_widget_get_has_window (widget))
7538     {
7539       *x = -widget->priv->allocation.x;
7540       *y = -widget->priv->allocation.y;
7541     }
7542   else
7543     {
7544       *x = 0;
7545       *y = 0;
7546     }
7547 
7548   widget_window = _gtk_widget_get_window (widget);
7549 
7550   for (w = window; w && w != widget_window; w = gdk_window_get_parent (w))
7551     {
7552       int wx, wy;
7553       gdk_window_get_position (w, &wx, &wy);
7554       *x += wx;
7555       *y += wy;
7556     }
7557 
7558   if (w == NULL)
7559     {
7560       *x = 0;
7561       *y = 0;
7562       return FALSE;
7563     }
7564 
7565   return TRUE;
7566 }
7567 
7568 
7569 /**
7570  * gtk_cairo_transform_to_window:
7571  * @cr: the cairo context to transform
7572  * @widget: the widget the context is currently centered for
7573  * @window: the window to transform the context to
7574  *
7575  * Transforms the given cairo context @cr that from @widget-relative
7576  * coordinates to @window-relative coordinates.
7577  * If the @widget’s window is not an ancestor of @window, no
7578  * modification will be applied.
7579  *
7580  * This is the inverse to the transformation GTK applies when
7581  * preparing an expose event to be emitted with the #GtkWidget::draw
7582  * signal. It is intended to help porting multiwindow widgets from
7583  * GTK+ 2 to the rendering architecture of GTK+ 3.
7584  *
7585  * Since: 3.0
7586  **/
7587 void
gtk_cairo_transform_to_window(cairo_t * cr,GtkWidget * widget,GdkWindow * window)7588 gtk_cairo_transform_to_window (cairo_t   *cr,
7589                                GtkWidget *widget,
7590                                GdkWindow *window)
7591 {
7592   int x, y;
7593 
7594   g_return_if_fail (cr != NULL);
7595   g_return_if_fail (GTK_IS_WIDGET (widget));
7596   g_return_if_fail (GDK_IS_WINDOW (window));
7597 
7598   if (_gtk_widget_get_translation_to_window (widget, window, &x, &y))
7599     cairo_translate (cr, x, y);
7600 }
7601 
7602 /**
7603  * gtk_widget_send_expose:
7604  * @widget: a #GtkWidget
7605  * @event: a expose #GdkEvent
7606  *
7607  * Very rarely-used function. This function is used to emit
7608  * an expose event on a widget. This function is not normally used
7609  * directly. The only time it is used is when propagating an expose
7610  * event to a windowless child widget (gtk_widget_get_has_window() is %FALSE),
7611  * and that is normally done using gtk_container_propagate_draw().
7612  *
7613  * If you want to force an area of a window to be redrawn,
7614  * use gdk_window_invalidate_rect() or gdk_window_invalidate_region().
7615  * To cause the redraw to be done immediately, follow that call
7616  * with a call to gdk_window_process_updates().
7617  *
7618  * Returns: return from the event signal emission (%TRUE if
7619  *   the event was handled)
7620  *
7621  * Deprecated: 3.22: Application and widget code should not handle
7622  *   expose events directly; invalidation should use the #GtkWidget
7623  *   API, and drawing should only happen inside #GtkWidget::draw
7624  *   implementations
7625  */
7626 gint
gtk_widget_send_expose(GtkWidget * widget,GdkEvent * event)7627 gtk_widget_send_expose (GtkWidget *widget,
7628 			GdkEvent  *event)
7629 {
7630   g_return_val_if_fail (GTK_IS_WIDGET (widget), TRUE);
7631   g_return_val_if_fail (gtk_widget_get_realized (widget), TRUE);
7632   g_return_val_if_fail (event != NULL, TRUE);
7633   g_return_val_if_fail (event->type == GDK_EXPOSE, TRUE);
7634 
7635   gtk_widget_render (widget, event->any.window, event->expose.region);
7636 
7637   return FALSE;
7638 }
7639 
7640 static gboolean
event_window_is_still_viewable(GdkEvent * event)7641 event_window_is_still_viewable (GdkEvent *event)
7642 {
7643   /* Check that we think the event's window is viewable before
7644    * delivering the event, to prevent surprises. We do this here
7645    * at the last moment, since the event may have been queued
7646    * up behind other events, held over a recursive main loop, etc.
7647    */
7648   switch (event->type)
7649     {
7650     case GDK_EXPOSE:
7651     case GDK_MOTION_NOTIFY:
7652     case GDK_BUTTON_PRESS:
7653     case GDK_2BUTTON_PRESS:
7654     case GDK_3BUTTON_PRESS:
7655     case GDK_KEY_PRESS:
7656     case GDK_ENTER_NOTIFY:
7657     case GDK_PROXIMITY_IN:
7658     case GDK_SCROLL:
7659       return event->any.window && gdk_window_is_viewable (event->any.window);
7660 
7661 #if 0
7662     /* The following events are the second half of paired events;
7663      * we always deliver them to deal with widgets that clean up
7664      * on the second half.
7665      */
7666     case GDK_BUTTON_RELEASE:
7667     case GDK_KEY_RELEASE:
7668     case GDK_LEAVE_NOTIFY:
7669     case GDK_PROXIMITY_OUT:
7670 #endif
7671 
7672     default:
7673       /* Remaining events would make sense on an not-viewable window,
7674        * or don't have an associated window.
7675        */
7676       return TRUE;
7677     }
7678 }
7679 
7680 static gint
gtk_widget_event_internal(GtkWidget * widget,GdkEvent * event)7681 gtk_widget_event_internal (GtkWidget *widget,
7682 			   GdkEvent  *event)
7683 {
7684   gboolean return_val = FALSE, handled;
7685 
7686   /* We check only once for is-still-visible; if someone
7687    * hides the window in on of the signals on the widget,
7688    * they are responsible for returning TRUE to terminate
7689    * handling.
7690    */
7691   if (!event_window_is_still_viewable (event))
7692     return TRUE;
7693 
7694   g_object_ref (widget);
7695 
7696   if (widget == gtk_get_event_widget (event))
7697     return_val |= _gtk_widget_run_controllers (widget, event, GTK_PHASE_TARGET);
7698 
7699   g_signal_emit (widget, widget_signals[EVENT], 0, event, &handled);
7700   return_val |= handled | !WIDGET_REALIZED_FOR_EVENT (widget, event);
7701   if (!return_val)
7702     {
7703       gint signal_num;
7704 
7705       switch (event->type)
7706 	{
7707         case GDK_TOUCHPAD_SWIPE:
7708         case GDK_TOUCHPAD_PINCH:
7709           return_val |= _gtk_widget_run_controllers (widget, event, GTK_PHASE_BUBBLE);
7710           /* Fall through */
7711         case GDK_PAD_BUTTON_PRESS:
7712         case GDK_PAD_BUTTON_RELEASE:
7713         case GDK_PAD_RING:
7714         case GDK_PAD_STRIP:
7715         case GDK_PAD_GROUP_MODE:
7716 	case GDK_EXPOSE:
7717 	case GDK_NOTHING:
7718 	  signal_num = -1;
7719 	  break;
7720 	case GDK_BUTTON_PRESS:
7721 	case GDK_2BUTTON_PRESS:
7722 	case GDK_3BUTTON_PRESS:
7723 	  signal_num = BUTTON_PRESS_EVENT;
7724           break;
7725         case GDK_TOUCH_BEGIN:
7726         case GDK_TOUCH_UPDATE:
7727         case GDK_TOUCH_END:
7728         case GDK_TOUCH_CANCEL:
7729 	  signal_num = TOUCH_EVENT;
7730 	  break;
7731 	case GDK_SCROLL:
7732 	  signal_num = SCROLL_EVENT;
7733 	  break;
7734 	case GDK_BUTTON_RELEASE:
7735 	  signal_num = BUTTON_RELEASE_EVENT;
7736 	  break;
7737 	case GDK_MOTION_NOTIFY:
7738 	  signal_num = MOTION_NOTIFY_EVENT;
7739 	  break;
7740 	case GDK_DELETE:
7741 	  signal_num = DELETE_EVENT;
7742 	  break;
7743 	case GDK_DESTROY:
7744 	  signal_num = DESTROY_EVENT;
7745 	  _gtk_tooltip_hide (widget);
7746 	  break;
7747 	case GDK_KEY_PRESS:
7748 	  signal_num = KEY_PRESS_EVENT;
7749 	  break;
7750 	case GDK_KEY_RELEASE:
7751 	  signal_num = KEY_RELEASE_EVENT;
7752 	  break;
7753 	case GDK_ENTER_NOTIFY:
7754 	  signal_num = ENTER_NOTIFY_EVENT;
7755 	  break;
7756 	case GDK_LEAVE_NOTIFY:
7757 	  signal_num = LEAVE_NOTIFY_EVENT;
7758 	  break;
7759 	case GDK_FOCUS_CHANGE:
7760 	  signal_num = event->focus_change.in ? FOCUS_IN_EVENT : FOCUS_OUT_EVENT;
7761 	  if (event->focus_change.in)
7762 	    _gtk_tooltip_focus_in (widget);
7763 	  else
7764 	    _gtk_tooltip_focus_out (widget);
7765 	  break;
7766 	case GDK_CONFIGURE:
7767 	  signal_num = CONFIGURE_EVENT;
7768 	  break;
7769 	case GDK_MAP:
7770 	  signal_num = MAP_EVENT;
7771 	  break;
7772 	case GDK_UNMAP:
7773 	  signal_num = UNMAP_EVENT;
7774 	  break;
7775 	case GDK_WINDOW_STATE:
7776 	  signal_num = WINDOW_STATE_EVENT;
7777 	  break;
7778 	case GDK_PROPERTY_NOTIFY:
7779 	  signal_num = PROPERTY_NOTIFY_EVENT;
7780 	  break;
7781 	case GDK_SELECTION_CLEAR:
7782 	  signal_num = SELECTION_CLEAR_EVENT;
7783 	  break;
7784 	case GDK_SELECTION_REQUEST:
7785 	  signal_num = SELECTION_REQUEST_EVENT;
7786 	  break;
7787 	case GDK_SELECTION_NOTIFY:
7788 	  signal_num = SELECTION_NOTIFY_EVENT;
7789 	  break;
7790 	case GDK_PROXIMITY_IN:
7791 	  signal_num = PROXIMITY_IN_EVENT;
7792 	  break;
7793 	case GDK_PROXIMITY_OUT:
7794 	  signal_num = PROXIMITY_OUT_EVENT;
7795 	  break;
7796 	case GDK_VISIBILITY_NOTIFY:
7797 	  signal_num = VISIBILITY_NOTIFY_EVENT;
7798 	  break;
7799 	case GDK_GRAB_BROKEN:
7800 	  signal_num = GRAB_BROKEN_EVENT;
7801 	  break;
7802 	case GDK_DAMAGE:
7803 	  signal_num = DAMAGE_EVENT;
7804 	  break;
7805 	default:
7806 	  g_warning ("gtk_widget_event(): unhandled event type: %d", event->type);
7807 	  signal_num = -1;
7808 	  break;
7809 	}
7810       if (signal_num != -1)
7811         {
7812 	  g_signal_emit (widget, widget_signals[signal_num], 0, event, &handled);
7813           return_val |= handled;
7814         }
7815     }
7816   if (WIDGET_REALIZED_FOR_EVENT (widget, event))
7817     g_signal_emit (widget, widget_signals[EVENT_AFTER], 0, event);
7818   else
7819     return_val = TRUE;
7820 
7821   g_object_unref (widget);
7822 
7823   return return_val;
7824 }
7825 
7826 /**
7827  * gtk_widget_activate:
7828  * @widget: a #GtkWidget that’s activatable
7829  *
7830  * For widgets that can be “activated” (buttons, menu items, etc.)
7831  * this function activates them. Activation is what happens when you
7832  * press Enter on a widget during key navigation. If @widget isn't
7833  * activatable, the function returns %FALSE.
7834  *
7835  * Returns: %TRUE if the widget was activatable
7836  **/
7837 gboolean
gtk_widget_activate(GtkWidget * widget)7838 gtk_widget_activate (GtkWidget *widget)
7839 {
7840   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
7841 
7842   if (WIDGET_CLASS (widget)->activate_signal)
7843     {
7844       /* FIXME: we should eventually check the signals signature here */
7845       g_signal_emit (widget, WIDGET_CLASS (widget)->activate_signal, 0);
7846 
7847       return TRUE;
7848     }
7849   else
7850     return FALSE;
7851 }
7852 
7853 static void
gtk_widget_reparent_subwindows(GtkWidget * widget,GdkWindow * new_window)7854 gtk_widget_reparent_subwindows (GtkWidget *widget,
7855 				GdkWindow *new_window)
7856 {
7857   GtkWidgetPrivate *priv = widget->priv;
7858 
7859   if (!_gtk_widget_get_has_window (widget))
7860     {
7861       GList *children = gdk_window_get_children (priv->window);
7862       GList *tmp_list;
7863 
7864       for (tmp_list = children; tmp_list; tmp_list = tmp_list->next)
7865 	{
7866 	  GdkWindow *window = tmp_list->data;
7867 	  gpointer child;
7868 
7869 	  gdk_window_get_user_data (window, &child);
7870 	  while (child && child != widget)
7871 	    child = ((GtkWidget*) child)->priv->parent;
7872 
7873 	  if (child)
7874 	    gdk_window_reparent (window, new_window, 0, 0);
7875 	}
7876 
7877       g_list_free (children);
7878     }
7879   else
7880    {
7881      GdkWindow *parent;
7882      GList *tmp_list, *children;
7883 
7884      parent = gdk_window_get_parent (priv->window);
7885 
7886      if (parent == NULL)
7887        gdk_window_reparent (priv->window, new_window, 0, 0);
7888      else
7889        {
7890 	 children = gdk_window_get_children (parent);
7891 
7892 	 for (tmp_list = children; tmp_list; tmp_list = tmp_list->next)
7893 	   {
7894 	     GdkWindow *window = tmp_list->data;
7895 	     gpointer child;
7896 
7897 	     gdk_window_get_user_data (window, &child);
7898 
7899 	     if (child == widget)
7900 	       gdk_window_reparent (window, new_window, 0, 0);
7901 	   }
7902 
7903 	 g_list_free (children);
7904        }
7905    }
7906 }
7907 
7908 static void
gtk_widget_reparent_fixup_child(GtkWidget * widget,gpointer client_data)7909 gtk_widget_reparent_fixup_child (GtkWidget *widget,
7910 				 gpointer   client_data)
7911 {
7912   GtkWidgetPrivate *priv = widget->priv;
7913 
7914   g_assert (client_data != NULL);
7915 
7916   if (!_gtk_widget_get_has_window (widget))
7917     {
7918       if (priv->window)
7919 	g_object_unref (priv->window);
7920       priv->window = (GdkWindow*) client_data;
7921       if (priv->window)
7922 	g_object_ref (priv->window);
7923 
7924       if (GTK_IS_CONTAINER (widget))
7925         gtk_container_forall (GTK_CONTAINER (widget),
7926                               gtk_widget_reparent_fixup_child,
7927                               client_data);
7928     }
7929 }
7930 
7931 /**
7932  * gtk_widget_reparent:
7933  * @widget: a #GtkWidget
7934  * @new_parent: a #GtkContainer to move the widget into
7935  *
7936  * Moves a widget from one #GtkContainer to another, handling reference
7937  * count issues to avoid destroying the widget.
7938  *
7939  * Deprecated: 3.14: Use gtk_container_remove() and gtk_container_add().
7940  **/
7941 void
gtk_widget_reparent(GtkWidget * widget,GtkWidget * new_parent)7942 gtk_widget_reparent (GtkWidget *widget,
7943 		     GtkWidget *new_parent)
7944 {
7945   GtkWidgetPrivate *priv;
7946 
7947   g_return_if_fail (GTK_IS_WIDGET (widget));
7948   g_return_if_fail (GTK_IS_CONTAINER (new_parent));
7949   priv = widget->priv;
7950   g_return_if_fail (priv->parent != NULL);
7951 
7952   if (priv->parent != new_parent)
7953     {
7954       /* First try to see if we can get away without unrealizing
7955        * the widget as we reparent it. if so we set a flag so
7956        * that gtk_widget_unparent doesn't unrealize widget
7957        */
7958       if (_gtk_widget_get_realized (widget) && _gtk_widget_get_realized (new_parent))
7959 	priv->in_reparent = TRUE;
7960 
7961       g_object_ref (widget);
7962       gtk_container_remove (GTK_CONTAINER (priv->parent), widget);
7963       gtk_container_add (GTK_CONTAINER (new_parent), widget);
7964       g_object_unref (widget);
7965 
7966       if (priv->in_reparent)
7967 	{
7968           priv->in_reparent = FALSE;
7969 
7970 	  gtk_widget_reparent_subwindows (widget, gtk_widget_get_parent_window (widget));
7971 	  gtk_widget_reparent_fixup_child (widget,
7972 					   gtk_widget_get_parent_window (widget));
7973 	}
7974 
7975       g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_PARENT]);
7976     }
7977 }
7978 
7979 /**
7980  * gtk_widget_intersect:
7981  * @widget: a #GtkWidget
7982  * @area: a rectangle
7983  * @intersection: (out caller-allocates) (optional): rectangle to store
7984  *   intersection of @widget and @area
7985  *
7986  * Computes the intersection of a @widget’s area and @area, storing
7987  * the intersection in @intersection, and returns %TRUE if there was
7988  * an intersection.  @intersection may be %NULL if you’re only
7989  * interested in whether there was an intersection.
7990  *
7991  * Returns: %TRUE if there was an intersection
7992  **/
7993 gboolean
gtk_widget_intersect(GtkWidget * widget,const GdkRectangle * area,GdkRectangle * intersection)7994 gtk_widget_intersect (GtkWidget	         *widget,
7995 		      const GdkRectangle *area,
7996 		      GdkRectangle       *intersection)
7997 {
7998   GtkWidgetPrivate *priv;
7999   GdkRectangle *dest;
8000   GdkRectangle tmp;
8001   gint return_val;
8002 
8003   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
8004   g_return_val_if_fail (area != NULL, FALSE);
8005 
8006   priv = widget->priv;
8007 
8008   if (intersection)
8009     dest = intersection;
8010   else
8011     dest = &tmp;
8012 
8013   return_val = gdk_rectangle_intersect (&priv->allocation, area, dest);
8014 
8015   if (return_val && intersection && _gtk_widget_get_has_window (widget))
8016     {
8017       intersection->x -= priv->allocation.x;
8018       intersection->y -= priv->allocation.y;
8019     }
8020 
8021   return return_val;
8022 }
8023 
8024 /**
8025  * gtk_widget_region_intersect:
8026  * @widget: a #GtkWidget
8027  * @region: a #cairo_region_t, in the same coordinate system as
8028  *          @widget->allocation. That is, relative to @widget->window
8029  *          for widgets which return %FALSE from gtk_widget_get_has_window();
8030  *          relative to the parent window of @widget->window otherwise.
8031  *
8032  * Computes the intersection of a @widget’s area and @region, returning
8033  * the intersection. The result may be empty, use cairo_region_is_empty() to
8034  * check.
8035  *
8036  * Returns: A newly allocated region holding the intersection of @widget
8037  *     and @region.
8038  *
8039  * Deprecated: 3.14: Use gtk_widget_get_allocation() and
8040  *     cairo_region_intersect_rectangle() to get the same behavior.
8041  */
8042 cairo_region_t *
gtk_widget_region_intersect(GtkWidget * widget,const cairo_region_t * region)8043 gtk_widget_region_intersect (GtkWidget            *widget,
8044 			     const cairo_region_t *region)
8045 {
8046   GdkRectangle rect;
8047   cairo_region_t *dest;
8048 
8049   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
8050   g_return_val_if_fail (region != NULL, NULL);
8051 
8052   _gtk_widget_get_allocation (widget, &rect);
8053 
8054   dest = cairo_region_create_rectangle (&rect);
8055 
8056   cairo_region_intersect (dest, region);
8057 
8058   return dest;
8059 }
8060 
8061 /**
8062  * _gtk_widget_grab_notify:
8063  * @widget: a #GtkWidget
8064  * @was_grabbed: whether a grab is now in effect
8065  *
8066  * Emits the #GtkWidget::grab-notify signal on @widget.
8067  *
8068  * Since: 2.6
8069  **/
8070 void
_gtk_widget_grab_notify(GtkWidget * widget,gboolean was_grabbed)8071 _gtk_widget_grab_notify (GtkWidget *widget,
8072 			 gboolean   was_grabbed)
8073 {
8074   g_signal_emit (widget, widget_signals[GRAB_NOTIFY], 0, was_grabbed);
8075 }
8076 
8077 /**
8078  * gtk_widget_grab_focus:
8079  * @widget: a #GtkWidget
8080  *
8081  * Causes @widget to have the keyboard focus for the #GtkWindow it's
8082  * inside. @widget must be a focusable widget, such as a #GtkEntry;
8083  * something like #GtkFrame won’t work.
8084  *
8085  * More precisely, it must have the %GTK_CAN_FOCUS flag set. Use
8086  * gtk_widget_set_can_focus() to modify that flag.
8087  *
8088  * The widget also needs to be realized and mapped. This is indicated by the
8089  * related signals. Grabbing the focus immediately after creating the widget
8090  * will likely fail and cause critical warnings.
8091  **/
8092 void
gtk_widget_grab_focus(GtkWidget * widget)8093 gtk_widget_grab_focus (GtkWidget *widget)
8094 {
8095   g_return_if_fail (GTK_IS_WIDGET (widget));
8096 
8097   if (!gtk_widget_is_sensitive (widget))
8098     return;
8099 
8100   g_object_ref (widget);
8101   g_signal_emit (widget, widget_signals[GRAB_FOCUS], 0);
8102   g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_HAS_FOCUS]);
8103   g_object_unref (widget);
8104 }
8105 
8106 static void
reset_focus_recurse(GtkWidget * widget,gpointer data)8107 reset_focus_recurse (GtkWidget *widget,
8108 		     gpointer   data)
8109 {
8110   if (GTK_IS_CONTAINER (widget))
8111     {
8112       GtkContainer *container;
8113 
8114       container = GTK_CONTAINER (widget);
8115       gtk_container_set_focus_child (container, NULL);
8116 
8117       gtk_container_foreach (container,
8118 			     reset_focus_recurse,
8119 			     NULL);
8120     }
8121 }
8122 
8123 static void
gtk_widget_real_grab_focus(GtkWidget * focus_widget)8124 gtk_widget_real_grab_focus (GtkWidget *focus_widget)
8125 {
8126   if (gtk_widget_get_can_focus (focus_widget))
8127     {
8128       GtkWidget *toplevel;
8129       GtkWidget *widget;
8130 
8131       /* clear the current focus setting, break if the current widget
8132        * is the focus widget's parent, since containers above that will
8133        * be set by the next loop.
8134        */
8135       toplevel = _gtk_widget_get_toplevel (focus_widget);
8136       if (_gtk_widget_is_toplevel (toplevel) && GTK_IS_WINDOW (toplevel))
8137 	{
8138           widget = gtk_window_get_focus (GTK_WINDOW (toplevel));
8139 
8140 	  if (widget == focus_widget)
8141 	    {
8142 	      /* We call _gtk_window_internal_set_focus() here so that the
8143 	       * toplevel window can request the focus if necessary.
8144 	       * This is needed when the toplevel is a GtkPlug
8145 	       */
8146 	      if (!gtk_widget_has_focus (widget))
8147 		_gtk_window_internal_set_focus (GTK_WINDOW (toplevel), focus_widget);
8148 
8149 	      return;
8150 	    }
8151 
8152 	  if (widget)
8153 	    {
8154 	      GtkWidget *common_ancestor = gtk_widget_common_ancestor (widget, focus_widget);
8155 
8156 	      if (widget != common_ancestor)
8157 		{
8158 		  while (widget->priv->parent)
8159 		    {
8160 		      widget = widget->priv->parent;
8161 		      gtk_container_set_focus_child (GTK_CONTAINER (widget), NULL);
8162 		      if (widget == common_ancestor)
8163 		        break;
8164 		    }
8165 		}
8166 	    }
8167 	}
8168       else if (toplevel != focus_widget)
8169 	{
8170 	  /* gtk_widget_grab_focus() operates on a tree without window...
8171 	   * actually, this is very questionable behavior.
8172 	   */
8173 
8174 	  gtk_container_foreach (GTK_CONTAINER (toplevel),
8175 				 reset_focus_recurse,
8176 				 NULL);
8177 	}
8178 
8179       /* now propagate the new focus up the widget tree and finally
8180        * set it on the window
8181        */
8182       widget = focus_widget;
8183       while (widget->priv->parent)
8184 	{
8185 	  gtk_container_set_focus_child (GTK_CONTAINER (widget->priv->parent), widget);
8186 	  widget = widget->priv->parent;
8187 	}
8188       if (GTK_IS_WINDOW (widget))
8189 	_gtk_window_internal_set_focus (GTK_WINDOW (widget), focus_widget);
8190     }
8191 }
8192 
8193 static gboolean
gtk_widget_real_query_tooltip(GtkWidget * widget,gint x,gint y,gboolean keyboard_tip,GtkTooltip * tooltip)8194 gtk_widget_real_query_tooltip (GtkWidget  *widget,
8195 			       gint        x,
8196 			       gint        y,
8197 			       gboolean    keyboard_tip,
8198 			       GtkTooltip *tooltip)
8199 {
8200   gchar *tooltip_markup;
8201   gboolean has_tooltip;
8202 
8203   tooltip_markup = g_object_get_qdata (G_OBJECT (widget), quark_tooltip_markup);
8204   has_tooltip = gtk_widget_get_has_tooltip (widget);
8205 
8206   if (has_tooltip && tooltip_markup)
8207     {
8208       gtk_tooltip_set_markup (tooltip, tooltip_markup);
8209       return TRUE;
8210     }
8211 
8212   return FALSE;
8213 }
8214 
8215 gboolean
gtk_widget_query_tooltip(GtkWidget * widget,gint x,gint y,gboolean keyboard_mode,GtkTooltip * tooltip)8216 gtk_widget_query_tooltip (GtkWidget  *widget,
8217                           gint        x,
8218                           gint        y,
8219                           gboolean    keyboard_mode,
8220                           GtkTooltip *tooltip)
8221 {
8222   gboolean retval = FALSE;
8223 
8224   g_signal_emit (widget,
8225                  widget_signals[QUERY_TOOLTIP],
8226                  0,
8227                  x, y,
8228                  keyboard_mode,
8229                  tooltip,
8230                  &retval);
8231 
8232   return retval;
8233 }
8234 
8235 static void
gtk_widget_real_state_flags_changed(GtkWidget * widget,GtkStateFlags old_state)8236 gtk_widget_real_state_flags_changed (GtkWidget     *widget,
8237                                      GtkStateFlags  old_state)
8238 {
8239 }
8240 
8241 static void
gtk_widget_real_style_updated(GtkWidget * widget)8242 gtk_widget_real_style_updated (GtkWidget *widget)
8243 {
8244   GtkWidgetPrivate *priv = widget->priv;
8245 
8246   gtk_widget_update_alpha (widget);
8247 
8248   if (widget->priv->context)
8249     {
8250       GtkCssStyleChange *change = gtk_style_context_get_change (widget->priv->context);
8251       gboolean has_text = gtk_widget_peek_pango_context (widget) != NULL;
8252 
8253       if (change == NULL ||
8254           (has_text && gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_FONT)))
8255         gtk_widget_update_pango_context (widget);
8256 
8257       if (widget->priv->anchored)
8258         {
8259           if (change == NULL ||
8260               gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_SIZE) ||
8261               (has_text && gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_TEXT)))
8262             gtk_widget_queue_resize (widget);
8263           else if (gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_CLIP))
8264             gtk_widget_queue_allocate (widget);
8265           else if (gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_REDRAW))
8266             gtk_widget_queue_draw (widget);
8267         }
8268     }
8269   else
8270     {
8271       gtk_widget_update_pango_context (widget);
8272 
8273       if (widget->priv->anchored)
8274         gtk_widget_queue_resize (widget);
8275     }
8276 
8277   G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
8278   if (priv->style != NULL &&
8279       priv->style != gtk_widget_get_default_style ())
8280     {
8281       /* Trigger ::style-set for old
8282        * widgets not listening to this
8283        */
8284       g_signal_emit (widget,
8285                      widget_signals[STYLE_SET],
8286                      0,
8287                      widget->priv->style);
8288     }
8289   G_GNUC_END_IGNORE_DEPRECATIONS;
8290 
8291 }
8292 
8293 static gboolean
gtk_widget_real_show_help(GtkWidget * widget,GtkWidgetHelpType help_type)8294 gtk_widget_real_show_help (GtkWidget        *widget,
8295                            GtkWidgetHelpType help_type)
8296 {
8297   if (help_type == GTK_WIDGET_HELP_TOOLTIP)
8298     {
8299       _gtk_tooltip_toggle_keyboard_mode (widget);
8300 
8301       return TRUE;
8302     }
8303   else
8304     return FALSE;
8305 }
8306 
8307 static gboolean
gtk_widget_real_focus(GtkWidget * widget,GtkDirectionType direction)8308 gtk_widget_real_focus (GtkWidget         *widget,
8309                        GtkDirectionType   direction)
8310 {
8311   if (!gtk_widget_get_can_focus (widget))
8312     return FALSE;
8313 
8314   if (!gtk_widget_is_focus (widget))
8315     {
8316       gtk_widget_grab_focus (widget);
8317       return TRUE;
8318     }
8319   else
8320     return FALSE;
8321 }
8322 
8323 static void
gtk_widget_real_move_focus(GtkWidget * widget,GtkDirectionType direction)8324 gtk_widget_real_move_focus (GtkWidget         *widget,
8325                             GtkDirectionType   direction)
8326 {
8327   GtkWidget *toplevel = _gtk_widget_get_toplevel (widget);
8328 
8329   if (widget != toplevel && GTK_IS_WINDOW (toplevel))
8330     {
8331       g_signal_emit (toplevel, widget_signals[MOVE_FOCUS], 0,
8332                      direction);
8333     }
8334 }
8335 
8336 static gboolean
gtk_widget_real_keynav_failed(GtkWidget * widget,GtkDirectionType direction)8337 gtk_widget_real_keynav_failed (GtkWidget        *widget,
8338                                GtkDirectionType  direction)
8339 {
8340   switch (direction)
8341     {
8342     case GTK_DIR_TAB_FORWARD:
8343     case GTK_DIR_TAB_BACKWARD:
8344       return FALSE;
8345 
8346     case GTK_DIR_UP:
8347     case GTK_DIR_DOWN:
8348     case GTK_DIR_LEFT:
8349     case GTK_DIR_RIGHT:
8350       break;
8351     }
8352 
8353   gtk_widget_error_bell (widget);
8354 
8355   return TRUE;
8356 }
8357 
8358 /**
8359  * gtk_widget_set_can_focus:
8360  * @widget: a #GtkWidget
8361  * @can_focus: whether or not @widget can own the input focus.
8362  *
8363  * Specifies whether @widget can own the input focus. See
8364  * gtk_widget_grab_focus() for actually setting the input focus on a
8365  * widget.
8366  *
8367  * Since: 2.18
8368  **/
8369 void
gtk_widget_set_can_focus(GtkWidget * widget,gboolean can_focus)8370 gtk_widget_set_can_focus (GtkWidget *widget,
8371                           gboolean   can_focus)
8372 {
8373   g_return_if_fail (GTK_IS_WIDGET (widget));
8374 
8375   if (widget->priv->can_focus != can_focus)
8376     {
8377       widget->priv->can_focus = can_focus;
8378 
8379       gtk_widget_queue_resize (widget);
8380       g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_CAN_FOCUS]);
8381     }
8382 }
8383 
8384 /**
8385  * gtk_widget_get_can_focus:
8386  * @widget: a #GtkWidget
8387  *
8388  * Determines whether @widget can own the input focus. See
8389  * gtk_widget_set_can_focus().
8390  *
8391  * Returns: %TRUE if @widget can own the input focus, %FALSE otherwise
8392  *
8393  * Since: 2.18
8394  **/
8395 gboolean
gtk_widget_get_can_focus(GtkWidget * widget)8396 gtk_widget_get_can_focus (GtkWidget *widget)
8397 {
8398   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
8399 
8400   return widget->priv->can_focus;
8401 }
8402 
8403 /**
8404  * gtk_widget_has_focus:
8405  * @widget: a #GtkWidget
8406  *
8407  * Determines if the widget has the global input focus. See
8408  * gtk_widget_is_focus() for the difference between having the global
8409  * input focus, and only having the focus within a toplevel.
8410  *
8411  * Returns: %TRUE if the widget has the global input focus.
8412  *
8413  * Since: 2.18
8414  **/
8415 gboolean
gtk_widget_has_focus(GtkWidget * widget)8416 gtk_widget_has_focus (GtkWidget *widget)
8417 {
8418   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
8419 
8420   return widget->priv->has_focus;
8421 }
8422 
8423 /**
8424  * gtk_widget_has_visible_focus:
8425  * @widget: a #GtkWidget
8426  *
8427  * Determines if the widget should show a visible indication that
8428  * it has the global input focus. This is a convenience function for
8429  * use in ::draw handlers that takes into account whether focus
8430  * indication should currently be shown in the toplevel window of
8431  * @widget. See gtk_window_get_focus_visible() for more information
8432  * about focus indication.
8433  *
8434  * To find out if the widget has the global input focus, use
8435  * gtk_widget_has_focus().
8436  *
8437  * Returns: %TRUE if the widget should display a “focus rectangle”
8438  *
8439  * Since: 3.2
8440  */
8441 gboolean
gtk_widget_has_visible_focus(GtkWidget * widget)8442 gtk_widget_has_visible_focus (GtkWidget *widget)
8443 {
8444   gboolean draw_focus;
8445 
8446   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
8447 
8448   if (widget->priv->has_focus)
8449     {
8450       GtkWidget *toplevel;
8451 
8452       toplevel = _gtk_widget_get_toplevel (widget);
8453 
8454       if (GTK_IS_WINDOW (toplevel))
8455         draw_focus = gtk_window_get_focus_visible (GTK_WINDOW (toplevel));
8456       else
8457         draw_focus = TRUE;
8458     }
8459   else
8460     draw_focus = FALSE;
8461 
8462   return draw_focus;
8463 }
8464 
8465 /**
8466  * gtk_widget_is_focus:
8467  * @widget: a #GtkWidget
8468  *
8469  * Determines if the widget is the focus widget within its
8470  * toplevel. (This does not mean that the #GtkWidget:has-focus property is
8471  * necessarily set; #GtkWidget:has-focus will only be set if the
8472  * toplevel widget additionally has the global input focus.)
8473  *
8474  * Returns: %TRUE if the widget is the focus widget.
8475  **/
8476 gboolean
gtk_widget_is_focus(GtkWidget * widget)8477 gtk_widget_is_focus (GtkWidget *widget)
8478 {
8479   GtkWidget *toplevel;
8480 
8481   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
8482 
8483   toplevel = _gtk_widget_get_toplevel (widget);
8484 
8485   if (GTK_IS_WINDOW (toplevel))
8486     return widget == gtk_window_get_focus (GTK_WINDOW (toplevel));
8487   else
8488     return FALSE;
8489 }
8490 
8491 /**
8492  * gtk_widget_set_focus_on_click:
8493  * @widget: a #GtkWidget
8494  * @focus_on_click: whether the widget should grab focus when clicked with the mouse
8495  *
8496  * Sets whether the widget should grab focus when it is clicked with the mouse.
8497  * Making mouse clicks not grab focus is useful in places like toolbars where
8498  * you don’t want the keyboard focus removed from the main area of the
8499  * application.
8500  *
8501  * Since: 3.20
8502  **/
8503 void
gtk_widget_set_focus_on_click(GtkWidget * widget,gboolean focus_on_click)8504 gtk_widget_set_focus_on_click (GtkWidget *widget,
8505 			       gboolean   focus_on_click)
8506 {
8507   GtkWidgetPrivate *priv;
8508 
8509   g_return_if_fail (GTK_IS_WIDGET (widget));
8510 
8511   priv = widget->priv;
8512 
8513   focus_on_click = focus_on_click != FALSE;
8514 
8515   if (priv->focus_on_click != focus_on_click)
8516     {
8517       priv->focus_on_click = focus_on_click;
8518 
8519       g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_FOCUS_ON_CLICK]);
8520     }
8521 }
8522 
8523 /**
8524  * gtk_widget_get_focus_on_click:
8525  * @widget: a #GtkWidget
8526  *
8527  * Returns whether the widget should grab focus when it is clicked with the mouse.
8528  * See gtk_widget_set_focus_on_click().
8529  *
8530  * Returns: %TRUE if the widget should grab focus when it is clicked with
8531  *               the mouse.
8532  *
8533  * Since: 3.20
8534  **/
8535 gboolean
gtk_widget_get_focus_on_click(GtkWidget * widget)8536 gtk_widget_get_focus_on_click (GtkWidget *widget)
8537 {
8538   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
8539 
8540   return widget->priv->focus_on_click;
8541 }
8542 
8543 
8544 /**
8545  * gtk_widget_set_can_default:
8546  * @widget: a #GtkWidget
8547  * @can_default: whether or not @widget can be a default widget.
8548  *
8549  * Specifies whether @widget can be a default widget. See
8550  * gtk_widget_grab_default() for details about the meaning of
8551  * “default”.
8552  *
8553  * Since: 2.18
8554  **/
8555 void
gtk_widget_set_can_default(GtkWidget * widget,gboolean can_default)8556 gtk_widget_set_can_default (GtkWidget *widget,
8557                             gboolean   can_default)
8558 {
8559   g_return_if_fail (GTK_IS_WIDGET (widget));
8560 
8561   if (widget->priv->can_default != can_default)
8562     {
8563       widget->priv->can_default = can_default;
8564 
8565       gtk_widget_queue_resize (widget);
8566       g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_CAN_DEFAULT]);
8567     }
8568 }
8569 
8570 /**
8571  * gtk_widget_get_can_default:
8572  * @widget: a #GtkWidget
8573  *
8574  * Determines whether @widget can be a default widget. See
8575  * gtk_widget_set_can_default().
8576  *
8577  * Returns: %TRUE if @widget can be a default widget, %FALSE otherwise
8578  *
8579  * Since: 2.18
8580  **/
8581 gboolean
gtk_widget_get_can_default(GtkWidget * widget)8582 gtk_widget_get_can_default (GtkWidget *widget)
8583 {
8584   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
8585 
8586   return widget->priv->can_default;
8587 }
8588 
8589 /**
8590  * gtk_widget_has_default:
8591  * @widget: a #GtkWidget
8592  *
8593  * Determines whether @widget is the current default widget within its
8594  * toplevel. See gtk_widget_set_can_default().
8595  *
8596  * Returns: %TRUE if @widget is the current default widget within
8597  *     its toplevel, %FALSE otherwise
8598  *
8599  * Since: 2.18
8600  */
8601 gboolean
gtk_widget_has_default(GtkWidget * widget)8602 gtk_widget_has_default (GtkWidget *widget)
8603 {
8604   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
8605 
8606   return widget->priv->has_default;
8607 }
8608 
8609 void
_gtk_widget_set_has_default(GtkWidget * widget,gboolean has_default)8610 _gtk_widget_set_has_default (GtkWidget *widget,
8611                              gboolean   has_default)
8612 {
8613   GtkStyleContext *context;
8614 
8615   widget->priv->has_default = has_default;
8616 
8617   context = _gtk_widget_get_style_context (widget);
8618 
8619   if (has_default)
8620     gtk_style_context_add_class (context, GTK_STYLE_CLASS_DEFAULT);
8621   else
8622     gtk_style_context_remove_class (context, GTK_STYLE_CLASS_DEFAULT);
8623 }
8624 
8625 /**
8626  * gtk_widget_grab_default:
8627  * @widget: a #GtkWidget
8628  *
8629  * Causes @widget to become the default widget. @widget must be able to be
8630  * a default widget; typically you would ensure this yourself
8631  * by calling gtk_widget_set_can_default() with a %TRUE value.
8632  * The default widget is activated when
8633  * the user presses Enter in a window. Default widgets must be
8634  * activatable, that is, gtk_widget_activate() should affect them. Note
8635  * that #GtkEntry widgets require the “activates-default” property
8636  * set to %TRUE before they activate the default widget when Enter
8637  * is pressed and the #GtkEntry is focused.
8638  **/
8639 void
gtk_widget_grab_default(GtkWidget * widget)8640 gtk_widget_grab_default (GtkWidget *widget)
8641 {
8642   GtkWidget *window;
8643 
8644   g_return_if_fail (GTK_IS_WIDGET (widget));
8645   g_return_if_fail (gtk_widget_get_can_default (widget));
8646 
8647   window = _gtk_widget_get_toplevel (widget);
8648 
8649   if (window && _gtk_widget_is_toplevel (window))
8650     gtk_window_set_default (GTK_WINDOW (window), widget);
8651   else
8652     g_warning (G_STRLOC ": widget not within a GtkWindow");
8653 }
8654 
8655 /**
8656  * gtk_widget_set_receives_default:
8657  * @widget: a #GtkWidget
8658  * @receives_default: whether or not @widget can be a default widget.
8659  *
8660  * Specifies whether @widget will be treated as the default widget
8661  * within its toplevel when it has the focus, even if another widget
8662  * is the default.
8663  *
8664  * See gtk_widget_grab_default() for details about the meaning of
8665  * “default”.
8666  *
8667  * Since: 2.18
8668  **/
8669 void
gtk_widget_set_receives_default(GtkWidget * widget,gboolean receives_default)8670 gtk_widget_set_receives_default (GtkWidget *widget,
8671                                  gboolean   receives_default)
8672 {
8673   g_return_if_fail (GTK_IS_WIDGET (widget));
8674 
8675   if (widget->priv->receives_default != receives_default)
8676     {
8677       widget->priv->receives_default = receives_default;
8678 
8679       g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_RECEIVES_DEFAULT]);
8680     }
8681 }
8682 
8683 /**
8684  * gtk_widget_get_receives_default:
8685  * @widget: a #GtkWidget
8686  *
8687  * Determines whether @widget is always treated as the default widget
8688  * within its toplevel when it has the focus, even if another widget
8689  * is the default.
8690  *
8691  * See gtk_widget_set_receives_default().
8692  *
8693  * Returns: %TRUE if @widget acts as the default widget when focused,
8694  *               %FALSE otherwise
8695  *
8696  * Since: 2.18
8697  **/
8698 gboolean
gtk_widget_get_receives_default(GtkWidget * widget)8699 gtk_widget_get_receives_default (GtkWidget *widget)
8700 {
8701   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
8702 
8703   return widget->priv->receives_default;
8704 }
8705 
8706 /**
8707  * gtk_widget_has_grab:
8708  * @widget: a #GtkWidget
8709  *
8710  * Determines whether the widget is currently grabbing events, so it
8711  * is the only widget receiving input events (keyboard and mouse).
8712  *
8713  * See also gtk_grab_add().
8714  *
8715  * Returns: %TRUE if the widget is in the grab_widgets stack
8716  *
8717  * Since: 2.18
8718  **/
8719 gboolean
gtk_widget_has_grab(GtkWidget * widget)8720 gtk_widget_has_grab (GtkWidget *widget)
8721 {
8722   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
8723 
8724   return widget->priv->has_grab;
8725 }
8726 
8727 void
_gtk_widget_set_has_grab(GtkWidget * widget,gboolean has_grab)8728 _gtk_widget_set_has_grab (GtkWidget *widget,
8729                           gboolean   has_grab)
8730 {
8731   widget->priv->has_grab = has_grab;
8732 }
8733 
8734 /**
8735  * gtk_widget_device_is_shadowed:
8736  * @widget: a #GtkWidget
8737  * @device: a #GdkDevice
8738  *
8739  * Returns %TRUE if @device has been shadowed by a GTK+
8740  * device grab on another widget, so it would stop sending
8741  * events to @widget. This may be used in the
8742  * #GtkWidget::grab-notify signal to check for specific
8743  * devices. See gtk_device_grab_add().
8744  *
8745  * Returns: %TRUE if there is an ongoing grab on @device
8746  *          by another #GtkWidget than @widget.
8747  *
8748  * Since: 3.0
8749  **/
8750 gboolean
gtk_widget_device_is_shadowed(GtkWidget * widget,GdkDevice * device)8751 gtk_widget_device_is_shadowed (GtkWidget *widget,
8752                                GdkDevice *device)
8753 {
8754   GtkWindowGroup *group;
8755   GtkWidget *grab_widget, *toplevel;
8756 
8757   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
8758   g_return_val_if_fail (GDK_IS_DEVICE (device), FALSE);
8759 
8760   if (!_gtk_widget_get_realized (widget))
8761     return TRUE;
8762 
8763   toplevel = _gtk_widget_get_toplevel (widget);
8764 
8765   if (GTK_IS_WINDOW (toplevel))
8766     group = gtk_window_get_group (GTK_WINDOW (toplevel));
8767   else
8768     group = gtk_window_get_group (NULL);
8769 
8770   grab_widget = gtk_window_group_get_current_device_grab (group, device);
8771 
8772   /* Widget not inside the hierarchy of grab_widget */
8773   if (grab_widget &&
8774       widget != grab_widget &&
8775       !gtk_widget_is_ancestor (widget, grab_widget))
8776     return TRUE;
8777 
8778   grab_widget = gtk_window_group_get_current_grab (group);
8779   if (grab_widget && widget != grab_widget &&
8780       !gtk_widget_is_ancestor (widget, grab_widget))
8781     return TRUE;
8782 
8783   return FALSE;
8784 }
8785 
8786 /**
8787  * gtk_widget_set_name:
8788  * @widget: a #GtkWidget
8789  * @name: name for the widget
8790  *
8791  * Widgets can be named, which allows you to refer to them from a
8792  * CSS file. You can apply a style to widgets with a particular name
8793  * in the CSS file. See the documentation for the CSS syntax (on the
8794  * same page as the docs for #GtkStyleContext).
8795  *
8796  * Note that the CSS syntax has certain special characters to delimit
8797  * and represent elements in a selector (period, #, >, *...), so using
8798  * these will make your widget impossible to match by name. Any combination
8799  * of alphanumeric symbols, dashes and underscores will suffice.
8800  */
8801 void
gtk_widget_set_name(GtkWidget * widget,const gchar * name)8802 gtk_widget_set_name (GtkWidget	 *widget,
8803 		     const gchar *name)
8804 {
8805   GtkWidgetPrivate *priv;
8806   gchar *new_name;
8807 
8808   g_return_if_fail (GTK_IS_WIDGET (widget));
8809 
8810   priv = widget->priv;
8811 
8812   new_name = g_strdup (name);
8813   g_free (priv->name);
8814   priv->name = new_name;
8815 
8816   if (priv->context)
8817     gtk_style_context_set_id (priv->context, priv->name);
8818 
8819   gtk_css_node_set_id (priv->cssnode, priv->name);
8820 
8821   g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_NAME]);
8822 }
8823 
8824 /**
8825  * gtk_widget_get_name:
8826  * @widget: a #GtkWidget
8827  *
8828  * Retrieves the name of a widget. See gtk_widget_set_name() for the
8829  * significance of widget names.
8830  *
8831  * Returns: name of the widget. This string is owned by GTK+ and
8832  * should not be modified or freed
8833  **/
8834 const gchar*
gtk_widget_get_name(GtkWidget * widget)8835 gtk_widget_get_name (GtkWidget *widget)
8836 {
8837   GtkWidgetPrivate *priv;
8838 
8839   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
8840 
8841   priv = widget->priv;
8842 
8843   if (priv->name)
8844     return priv->name;
8845   return G_OBJECT_TYPE_NAME (widget);
8846 }
8847 
8848 static void
gtk_widget_update_state_flags(GtkWidget * widget,GtkStateFlags flags_to_set,GtkStateFlags flags_to_unset)8849 gtk_widget_update_state_flags (GtkWidget     *widget,
8850                                GtkStateFlags  flags_to_set,
8851                                GtkStateFlags  flags_to_unset)
8852 {
8853   GtkWidgetPrivate *priv;
8854 
8855   priv = widget->priv;
8856 
8857   /* Handle insensitive first, since it is propagated
8858    * differently throughout the widget hierarchy.
8859    */
8860   if ((priv->state_flags & GTK_STATE_FLAG_INSENSITIVE) && (flags_to_unset & GTK_STATE_FLAG_INSENSITIVE))
8861     gtk_widget_set_sensitive (widget, TRUE);
8862   else if (!(priv->state_flags & GTK_STATE_FLAG_INSENSITIVE) && (flags_to_set & GTK_STATE_FLAG_INSENSITIVE))
8863     gtk_widget_set_sensitive (widget, FALSE);
8864 
8865   flags_to_set &= ~(GTK_STATE_FLAG_INSENSITIVE);
8866   flags_to_unset &= ~(GTK_STATE_FLAG_INSENSITIVE);
8867 
8868   if (flags_to_set != 0 || flags_to_unset != 0)
8869     {
8870       GtkStateData data;
8871 
8872       data.old_scale_factor = gtk_widget_get_scale_factor (widget);
8873       data.flags_to_set = flags_to_set;
8874       data.flags_to_unset = flags_to_unset;
8875 
8876       gtk_widget_propagate_state (widget, &data);
8877     }
8878 }
8879 
8880 /**
8881  * gtk_widget_set_state_flags:
8882  * @widget: a #GtkWidget
8883  * @flags: State flags to turn on
8884  * @clear: Whether to clear state before turning on @flags
8885  *
8886  * This function is for use in widget implementations. Turns on flag
8887  * values in the current widget state (insensitive, prelighted, etc.).
8888  *
8889  * This function accepts the values %GTK_STATE_FLAG_DIR_LTR and
8890  * %GTK_STATE_FLAG_DIR_RTL but ignores them. If you want to set the widget's
8891  * direction, use gtk_widget_set_direction().
8892  *
8893  * It is worth mentioning that any other state than %GTK_STATE_FLAG_INSENSITIVE,
8894  * will be propagated down to all non-internal children if @widget is a
8895  * #GtkContainer, while %GTK_STATE_FLAG_INSENSITIVE itself will be propagated
8896  * down to all #GtkContainer children by different means than turning on the
8897  * state flag down the hierarchy, both gtk_widget_get_state_flags() and
8898  * gtk_widget_is_sensitive() will make use of these.
8899  *
8900  * Since: 3.0
8901  **/
8902 void
gtk_widget_set_state_flags(GtkWidget * widget,GtkStateFlags flags,gboolean clear)8903 gtk_widget_set_state_flags (GtkWidget     *widget,
8904                             GtkStateFlags  flags,
8905                             gboolean       clear)
8906 {
8907 #define ALLOWED_FLAGS (~(GTK_STATE_FLAG_DIR_LTR | GTK_STATE_FLAG_DIR_RTL))
8908 
8909   g_return_if_fail (GTK_IS_WIDGET (widget));
8910   g_return_if_fail (flags < (1 << GTK_STATE_FLAGS_BITS));
8911 
8912   if ((!clear && (widget->priv->state_flags & flags) == flags) ||
8913       (clear && widget->priv->state_flags == flags))
8914     return;
8915 
8916   if (clear)
8917     gtk_widget_update_state_flags (widget, flags & ALLOWED_FLAGS, ~flags & ALLOWED_FLAGS);
8918   else
8919     gtk_widget_update_state_flags (widget, flags & ALLOWED_FLAGS, 0);
8920 
8921 #undef ALLOWED_FLAGS
8922 }
8923 
8924 /**
8925  * gtk_widget_unset_state_flags:
8926  * @widget: a #GtkWidget
8927  * @flags: State flags to turn off
8928  *
8929  * This function is for use in widget implementations. Turns off flag
8930  * values for the current widget state (insensitive, prelighted, etc.).
8931  * See gtk_widget_set_state_flags().
8932  *
8933  * Since: 3.0
8934  **/
8935 void
gtk_widget_unset_state_flags(GtkWidget * widget,GtkStateFlags flags)8936 gtk_widget_unset_state_flags (GtkWidget     *widget,
8937                               GtkStateFlags  flags)
8938 {
8939   g_return_if_fail (GTK_IS_WIDGET (widget));
8940   g_return_if_fail (flags < (1 << GTK_STATE_FLAGS_BITS));
8941 
8942   if ((widget->priv->state_flags & flags) == 0)
8943     return;
8944 
8945   gtk_widget_update_state_flags (widget, 0, flags);
8946 }
8947 
8948 /**
8949  * gtk_widget_get_state_flags:
8950  * @widget: a #GtkWidget
8951  *
8952  * Returns the widget state as a flag set. It is worth mentioning
8953  * that the effective %GTK_STATE_FLAG_INSENSITIVE state will be
8954  * returned, that is, also based on parent insensitivity, even if
8955  * @widget itself is sensitive.
8956  *
8957  * Also note that if you are looking for a way to obtain the
8958  * #GtkStateFlags to pass to a #GtkStyleContext method, you
8959  * should look at gtk_style_context_get_state().
8960  *
8961  * Returns: The state flags for widget
8962  *
8963  * Since: 3.0
8964  **/
8965 GtkStateFlags
gtk_widget_get_state_flags(GtkWidget * widget)8966 gtk_widget_get_state_flags (GtkWidget *widget)
8967 {
8968   g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
8969 
8970   return widget->priv->state_flags;
8971 }
8972 
8973 /**
8974  * gtk_widget_set_state:
8975  * @widget: a #GtkWidget
8976  * @state: new state for @widget
8977  *
8978  * This function is for use in widget implementations. Sets the state
8979  * of a widget (insensitive, prelighted, etc.) Usually you should set
8980  * the state using wrapper functions such as gtk_widget_set_sensitive().
8981  *
8982  * Deprecated: 3.0: Use gtk_widget_set_state_flags() instead.
8983  **/
8984 void
gtk_widget_set_state(GtkWidget * widget,GtkStateType state)8985 gtk_widget_set_state (GtkWidget           *widget,
8986 		      GtkStateType         state)
8987 {
8988   GtkStateFlags flags;
8989 
8990   G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
8991   if (state == gtk_widget_get_state (widget))
8992     return;
8993   G_GNUC_END_IGNORE_DEPRECATIONS;
8994 
8995   switch (state)
8996     {
8997     case GTK_STATE_ACTIVE:
8998       flags = GTK_STATE_FLAG_ACTIVE;
8999       break;
9000     case GTK_STATE_PRELIGHT:
9001       flags = GTK_STATE_FLAG_PRELIGHT;
9002       break;
9003     case GTK_STATE_SELECTED:
9004       flags = GTK_STATE_FLAG_SELECTED;
9005       break;
9006     case GTK_STATE_INSENSITIVE:
9007       flags = GTK_STATE_FLAG_INSENSITIVE;
9008       break;
9009     case GTK_STATE_INCONSISTENT:
9010       flags = GTK_STATE_FLAG_INCONSISTENT;
9011       break;
9012     case GTK_STATE_FOCUSED:
9013       flags = GTK_STATE_FLAG_FOCUSED;
9014       break;
9015     case GTK_STATE_NORMAL:
9016     default:
9017       flags = 0;
9018       break;
9019     }
9020 
9021   gtk_widget_update_state_flags (widget,
9022                                  flags,
9023                                  (GTK_STATE_FLAG_ACTIVE | GTK_STATE_FLAG_PRELIGHT | GTK_STATE_FLAG_SELECTED
9024                                  | GTK_STATE_FLAG_INSENSITIVE | GTK_STATE_FLAG_INCONSISTENT | GTK_STATE_FLAG_FOCUSED) ^ flags);
9025 }
9026 
9027 /**
9028  * gtk_widget_get_state:
9029  * @widget: a #GtkWidget
9030  *
9031  * Returns the widget’s state. See gtk_widget_set_state().
9032  *
9033  * Returns: the state of @widget.
9034  *
9035  * Since: 2.18
9036  *
9037  * Deprecated: 3.0: Use gtk_widget_get_state_flags() instead.
9038  */
9039 GtkStateType
gtk_widget_get_state(GtkWidget * widget)9040 gtk_widget_get_state (GtkWidget *widget)
9041 {
9042   GtkStateFlags flags;
9043 
9044   g_return_val_if_fail (GTK_IS_WIDGET (widget), GTK_STATE_NORMAL);
9045 
9046   flags = _gtk_widget_get_state_flags (widget);
9047 
9048   if (flags & GTK_STATE_FLAG_INSENSITIVE)
9049     return GTK_STATE_INSENSITIVE;
9050   else if (flags & GTK_STATE_FLAG_ACTIVE)
9051     return GTK_STATE_ACTIVE;
9052   else if (flags & GTK_STATE_FLAG_SELECTED)
9053     return GTK_STATE_SELECTED;
9054   else if (flags & GTK_STATE_FLAG_PRELIGHT)
9055     return GTK_STATE_PRELIGHT;
9056   else
9057     return GTK_STATE_NORMAL;
9058 }
9059 
9060 /**
9061  * gtk_widget_set_visible:
9062  * @widget: a #GtkWidget
9063  * @visible: whether the widget should be shown or not
9064  *
9065  * Sets the visibility state of @widget. Note that setting this to
9066  * %TRUE doesn’t mean the widget is actually viewable, see
9067  * gtk_widget_get_visible().
9068  *
9069  * This function simply calls gtk_widget_show() or gtk_widget_hide()
9070  * but is nicer to use when the visibility of the widget depends on
9071  * some condition.
9072  *
9073  * Since: 2.18
9074  **/
9075 void
gtk_widget_set_visible(GtkWidget * widget,gboolean visible)9076 gtk_widget_set_visible (GtkWidget *widget,
9077                         gboolean   visible)
9078 {
9079   g_return_if_fail (GTK_IS_WIDGET (widget));
9080 
9081   if (visible)
9082     gtk_widget_show (widget);
9083   else
9084     gtk_widget_hide (widget);
9085 }
9086 
9087 void
_gtk_widget_set_visible_flag(GtkWidget * widget,gboolean visible)9088 _gtk_widget_set_visible_flag (GtkWidget *widget,
9089                               gboolean   visible)
9090 {
9091   GtkWidgetPrivate *priv = widget->priv;
9092 
9093   priv->visible = visible;
9094 
9095   if (!visible)
9096     {
9097       priv->allocation.x = -1;
9098       priv->allocation.y = -1;
9099       priv->allocation.width = 1;
9100       priv->allocation.height = 1;
9101       memset (&priv->clip, 0, sizeof (priv->clip));
9102       memset (&priv->allocated_size, 0, sizeof (priv->allocated_size));
9103       priv->allocated_size_baseline = 0;
9104     }
9105 }
9106 
9107 /**
9108  * gtk_widget_get_visible:
9109  * @widget: a #GtkWidget
9110  *
9111  * Determines whether the widget is visible. If you want to
9112  * take into account whether the widget’s parent is also marked as
9113  * visible, use gtk_widget_is_visible() instead.
9114  *
9115  * This function does not check if the widget is obscured in any way.
9116  *
9117  * See gtk_widget_set_visible().
9118  *
9119  * Returns: %TRUE if the widget is visible
9120  *
9121  * Since: 2.18
9122  **/
9123 gboolean
gtk_widget_get_visible(GtkWidget * widget)9124 gtk_widget_get_visible (GtkWidget *widget)
9125 {
9126   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
9127 
9128   return widget->priv->visible;
9129 }
9130 
9131 /**
9132  * gtk_widget_is_visible:
9133  * @widget: a #GtkWidget
9134  *
9135  * Determines whether the widget and all its parents are marked as
9136  * visible.
9137  *
9138  * This function does not check if the widget is obscured in any way.
9139  *
9140  * See also gtk_widget_get_visible() and gtk_widget_set_visible()
9141  *
9142  * Returns: %TRUE if the widget and all its parents are visible
9143  *
9144  * Since: 3.8
9145  **/
9146 gboolean
gtk_widget_is_visible(GtkWidget * widget)9147 gtk_widget_is_visible (GtkWidget *widget)
9148 {
9149   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
9150 
9151   while (widget)
9152     {
9153       GtkWidgetPrivate *priv = widget->priv;
9154 
9155       if (!priv->visible)
9156         return FALSE;
9157 
9158       widget = priv->parent;
9159     }
9160 
9161   return TRUE;
9162 }
9163 
9164 /**
9165  * gtk_widget_set_has_window:
9166  * @widget: a #GtkWidget
9167  * @has_window: whether or not @widget has a window.
9168  *
9169  * Specifies whether @widget has a #GdkWindow of its own. Note that
9170  * all realized widgets have a non-%NULL “window” pointer
9171  * (gtk_widget_get_window() never returns a %NULL window when a widget
9172  * is realized), but for many of them it’s actually the #GdkWindow of
9173  * one of its parent widgets. Widgets that do not create a %window for
9174  * themselves in #GtkWidget::realize must announce this by
9175  * calling this function with @has_window = %FALSE.
9176  *
9177  * This function should only be called by widget implementations,
9178  * and they should call it in their init() function.
9179  *
9180  * Since: 2.18
9181  **/
9182 void
gtk_widget_set_has_window(GtkWidget * widget,gboolean has_window)9183 gtk_widget_set_has_window (GtkWidget *widget,
9184                            gboolean   has_window)
9185 {
9186   g_return_if_fail (GTK_IS_WIDGET (widget));
9187 
9188   widget->priv->no_window = !has_window;
9189 }
9190 
9191 /**
9192  * gtk_widget_get_has_window:
9193  * @widget: a #GtkWidget
9194  *
9195  * Determines whether @widget has a #GdkWindow of its own. See
9196  * gtk_widget_set_has_window().
9197  *
9198  * Returns: %TRUE if @widget has a window, %FALSE otherwise
9199  *
9200  * Since: 2.18
9201  **/
9202 gboolean
gtk_widget_get_has_window(GtkWidget * widget)9203 gtk_widget_get_has_window (GtkWidget *widget)
9204 {
9205   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
9206 
9207   return ! widget->priv->no_window;
9208 }
9209 
9210 /**
9211  * gtk_widget_is_toplevel:
9212  * @widget: a #GtkWidget
9213  *
9214  * Determines whether @widget is a toplevel widget.
9215  *
9216  * Currently only #GtkWindow and #GtkInvisible (and out-of-process
9217  * #GtkPlugs) are toplevel widgets. Toplevel widgets have no parent
9218  * widget.
9219  *
9220  * Returns: %TRUE if @widget is a toplevel, %FALSE otherwise
9221  *
9222  * Since: 2.18
9223  **/
9224 gboolean
gtk_widget_is_toplevel(GtkWidget * widget)9225 gtk_widget_is_toplevel (GtkWidget *widget)
9226 {
9227   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
9228 
9229   return widget->priv->toplevel;
9230 }
9231 
9232 void
_gtk_widget_set_is_toplevel(GtkWidget * widget,gboolean is_toplevel)9233 _gtk_widget_set_is_toplevel (GtkWidget *widget,
9234                              gboolean   is_toplevel)
9235 {
9236   widget->priv->toplevel = is_toplevel;
9237 }
9238 
9239 /**
9240  * gtk_widget_is_drawable:
9241  * @widget: a #GtkWidget
9242  *
9243  * Determines whether @widget can be drawn to. A widget can be drawn
9244  * to if it is mapped and visible.
9245  *
9246  * Returns: %TRUE if @widget is drawable, %FALSE otherwise
9247  *
9248  * Since: 2.18
9249  **/
9250 gboolean
gtk_widget_is_drawable(GtkWidget * widget)9251 gtk_widget_is_drawable (GtkWidget *widget)
9252 {
9253   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
9254 
9255   return (_gtk_widget_get_visible (widget) &&
9256           _gtk_widget_get_mapped (widget));
9257 }
9258 
9259 /**
9260  * gtk_widget_get_realized:
9261  * @widget: a #GtkWidget
9262  *
9263  * Determines whether @widget is realized.
9264  *
9265  * Returns: %TRUE if @widget is realized, %FALSE otherwise
9266  *
9267  * Since: 2.20
9268  **/
9269 gboolean
gtk_widget_get_realized(GtkWidget * widget)9270 gtk_widget_get_realized (GtkWidget *widget)
9271 {
9272   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
9273 
9274   return widget->priv->realized;
9275 }
9276 
9277 /**
9278  * gtk_widget_set_realized:
9279  * @widget: a #GtkWidget
9280  * @realized: %TRUE to mark the widget as realized
9281  *
9282  * Marks the widget as being realized. This function must only be
9283  * called after all #GdkWindows for the @widget have been created
9284  * and registered.
9285  *
9286  * This function should only ever be called in a derived widget's
9287  * “realize” or “unrealize” implementation.
9288  *
9289  * Since: 2.20
9290  */
9291 void
gtk_widget_set_realized(GtkWidget * widget,gboolean realized)9292 gtk_widget_set_realized (GtkWidget *widget,
9293                          gboolean   realized)
9294 {
9295   g_return_if_fail (GTK_IS_WIDGET (widget));
9296 
9297   widget->priv->realized = realized;
9298 }
9299 
9300 /**
9301  * gtk_widget_get_mapped:
9302  * @widget: a #GtkWidget
9303  *
9304  * Whether the widget is mapped.
9305  *
9306  * Returns: %TRUE if the widget is mapped, %FALSE otherwise.
9307  *
9308  * Since: 2.20
9309  */
9310 gboolean
gtk_widget_get_mapped(GtkWidget * widget)9311 gtk_widget_get_mapped (GtkWidget *widget)
9312 {
9313   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
9314 
9315   return widget->priv->mapped;
9316 }
9317 
9318 /**
9319  * gtk_widget_set_mapped:
9320  * @widget: a #GtkWidget
9321  * @mapped: %TRUE to mark the widget as mapped
9322  *
9323  * Marks the widget as being mapped.
9324  *
9325  * This function should only ever be called in a derived widget's
9326  * “map” or “unmap” implementation.
9327  *
9328  * Since: 2.20
9329  */
9330 void
gtk_widget_set_mapped(GtkWidget * widget,gboolean mapped)9331 gtk_widget_set_mapped (GtkWidget *widget,
9332                        gboolean   mapped)
9333 {
9334   g_return_if_fail (GTK_IS_WIDGET (widget));
9335 
9336   widget->priv->mapped = mapped;
9337 }
9338 
9339 /**
9340  * gtk_widget_set_app_paintable:
9341  * @widget: a #GtkWidget
9342  * @app_paintable: %TRUE if the application will paint on the widget
9343  *
9344  * Sets whether the application intends to draw on the widget in
9345  * an #GtkWidget::draw handler.
9346  *
9347  * This is a hint to the widget and does not affect the behavior of
9348  * the GTK+ core; many widgets ignore this flag entirely. For widgets
9349  * that do pay attention to the flag, such as #GtkEventBox and #GtkWindow,
9350  * the effect is to suppress default themed drawing of the widget's
9351  * background. (Children of the widget will still be drawn.) The application
9352  * is then entirely responsible for drawing the widget background.
9353  *
9354  * Note that the background is still drawn when the widget is mapped.
9355  **/
9356 void
gtk_widget_set_app_paintable(GtkWidget * widget,gboolean app_paintable)9357 gtk_widget_set_app_paintable (GtkWidget *widget,
9358 			      gboolean   app_paintable)
9359 {
9360   g_return_if_fail (GTK_IS_WIDGET (widget));
9361 
9362   app_paintable = (app_paintable != FALSE);
9363 
9364   if (widget->priv->app_paintable != app_paintable)
9365     {
9366       widget->priv->app_paintable = app_paintable;
9367 
9368       if (_gtk_widget_is_drawable (widget))
9369 	gtk_widget_queue_draw (widget);
9370 
9371       g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_APP_PAINTABLE]);
9372     }
9373 }
9374 
9375 /**
9376  * gtk_widget_get_app_paintable:
9377  * @widget: a #GtkWidget
9378  *
9379  * Determines whether the application intends to draw on the widget in
9380  * an #GtkWidget::draw handler.
9381  *
9382  * See gtk_widget_set_app_paintable()
9383  *
9384  * Returns: %TRUE if the widget is app paintable
9385  *
9386  * Since: 2.18
9387  **/
9388 gboolean
gtk_widget_get_app_paintable(GtkWidget * widget)9389 gtk_widget_get_app_paintable (GtkWidget *widget)
9390 {
9391   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
9392 
9393   return widget->priv->app_paintable;
9394 }
9395 
9396 /**
9397  * gtk_widget_set_double_buffered:
9398  * @widget: a #GtkWidget
9399  * @double_buffered: %TRUE to double-buffer a widget
9400  *
9401  * Widgets are double buffered by default; you can use this function
9402  * to turn off the buffering. “Double buffered” simply means that
9403  * gdk_window_begin_draw_frame() and gdk_window_end_draw_frame() are called
9404  * automatically around expose events sent to the
9405  * widget. gdk_window_begin_draw_frame() diverts all drawing to a widget's
9406  * window to an offscreen buffer, and gdk_window_end_draw_frame() draws the
9407  * buffer to the screen. The result is that users see the window
9408  * update in one smooth step, and don’t see individual graphics
9409  * primitives being rendered.
9410  *
9411  * In very simple terms, double buffered widgets don’t flicker,
9412  * so you would only use this function to turn off double buffering
9413  * if you had special needs and really knew what you were doing.
9414  *
9415  * Note: if you turn off double-buffering, you have to handle
9416  * expose events, since even the clearing to the background color or
9417  * pixmap will not happen automatically (as it is done in
9418  * gdk_window_begin_draw_frame()).
9419  *
9420  * In 3.10 GTK and GDK have been restructured for translucent drawing. Since
9421  * then expose events for double-buffered widgets are culled into a single
9422  * event to the toplevel GDK window. If you now unset double buffering, you
9423  * will cause a separate rendering pass for every widget. This will likely
9424  * cause rendering problems - in particular related to stacking - and usually
9425  * increases rendering times significantly.
9426  *
9427  * Deprecated: 3.14: This function does not work under non-X11 backends or with
9428  * non-native windows.
9429  * It should not be used in newly written code.
9430  **/
9431 void
gtk_widget_set_double_buffered(GtkWidget * widget,gboolean double_buffered)9432 gtk_widget_set_double_buffered (GtkWidget *widget,
9433 				gboolean   double_buffered)
9434 {
9435   g_return_if_fail (GTK_IS_WIDGET (widget));
9436 
9437   double_buffered = (double_buffered != FALSE);
9438 
9439   if (widget->priv->double_buffered != double_buffered)
9440     {
9441       widget->priv->double_buffered = double_buffered;
9442 
9443       g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_DOUBLE_BUFFERED]);
9444     }
9445 }
9446 
9447 /**
9448  * gtk_widget_get_double_buffered:
9449  * @widget: a #GtkWidget
9450  *
9451  * Determines whether the widget is double buffered.
9452  *
9453  * See gtk_widget_set_double_buffered()
9454  *
9455  * Returns: %TRUE if the widget is double buffered
9456  *
9457  * Since: 2.18
9458  **/
9459 gboolean
gtk_widget_get_double_buffered(GtkWidget * widget)9460 gtk_widget_get_double_buffered (GtkWidget *widget)
9461 {
9462   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
9463 
9464   return widget->priv->double_buffered;
9465 }
9466 
9467 /**
9468  * gtk_widget_set_redraw_on_allocate:
9469  * @widget: a #GtkWidget
9470  * @redraw_on_allocate: if %TRUE, the entire widget will be redrawn
9471  *   when it is allocated to a new size. Otherwise, only the
9472  *   new portion of the widget will be redrawn.
9473  *
9474  * Sets whether the entire widget is queued for drawing when its size
9475  * allocation changes. By default, this setting is %TRUE and
9476  * the entire widget is redrawn on every size change. If your widget
9477  * leaves the upper left unchanged when made bigger, turning this
9478  * setting off will improve performance.
9479 
9480  * Note that for widgets where gtk_widget_get_has_window() is %FALSE
9481  * setting this flag to %FALSE turns off all allocation on resizing:
9482  * the widget will not even redraw if its position changes; this is to
9483  * allow containers that don’t draw anything to avoid excess
9484  * invalidations. If you set this flag on a widget with no window that
9485  * does draw on @widget->window, you are
9486  * responsible for invalidating both the old and new allocation of the
9487  * widget when the widget is moved and responsible for invalidating
9488  * regions newly when the widget increases size.
9489  **/
9490 void
gtk_widget_set_redraw_on_allocate(GtkWidget * widget,gboolean redraw_on_allocate)9491 gtk_widget_set_redraw_on_allocate (GtkWidget *widget,
9492 				   gboolean   redraw_on_allocate)
9493 {
9494   g_return_if_fail (GTK_IS_WIDGET (widget));
9495 
9496   widget->priv->redraw_on_alloc = redraw_on_allocate;
9497 }
9498 
9499 /**
9500  * gtk_widget_set_sensitive:
9501  * @widget: a #GtkWidget
9502  * @sensitive: %TRUE to make the widget sensitive
9503  *
9504  * Sets the sensitivity of a widget. A widget is sensitive if the user
9505  * can interact with it. Insensitive widgets are “grayed out” and the
9506  * user can’t interact with them. Insensitive widgets are known as
9507  * “inactive”, “disabled”, or “ghosted” in some other toolkits.
9508  **/
9509 void
gtk_widget_set_sensitive(GtkWidget * widget,gboolean sensitive)9510 gtk_widget_set_sensitive (GtkWidget *widget,
9511 			  gboolean   sensitive)
9512 {
9513   GtkWidgetPrivate *priv;
9514 
9515   g_return_if_fail (GTK_IS_WIDGET (widget));
9516 
9517   priv = widget->priv;
9518 
9519   sensitive = (sensitive != FALSE);
9520 
9521   if (priv->sensitive == sensitive)
9522     return;
9523 
9524   priv->sensitive = sensitive;
9525 
9526   if (priv->parent == NULL
9527       || gtk_widget_is_sensitive (priv->parent))
9528     {
9529       GtkStateData data;
9530 
9531       data.old_scale_factor = gtk_widget_get_scale_factor (widget);
9532 
9533       if (sensitive)
9534         {
9535           data.flags_to_set = 0;
9536           data.flags_to_unset = GTK_STATE_FLAG_INSENSITIVE;
9537         }
9538       else
9539         {
9540           data.flags_to_set = GTK_STATE_FLAG_INSENSITIVE;
9541           data.flags_to_unset = 0;
9542         }
9543 
9544       gtk_widget_propagate_state (widget, &data);
9545     }
9546 
9547   g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_SENSITIVE]);
9548 }
9549 
9550 /**
9551  * gtk_widget_get_sensitive:
9552  * @widget: a #GtkWidget
9553  *
9554  * Returns the widget’s sensitivity (in the sense of returning
9555  * the value that has been set using gtk_widget_set_sensitive()).
9556  *
9557  * The effective sensitivity of a widget is however determined by both its
9558  * own and its parent widget’s sensitivity. See gtk_widget_is_sensitive().
9559  *
9560  * Returns: %TRUE if the widget is sensitive
9561  *
9562  * Since: 2.18
9563  */
9564 gboolean
gtk_widget_get_sensitive(GtkWidget * widget)9565 gtk_widget_get_sensitive (GtkWidget *widget)
9566 {
9567   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
9568 
9569   return widget->priv->sensitive;
9570 }
9571 
9572 /**
9573  * gtk_widget_is_sensitive:
9574  * @widget: a #GtkWidget
9575  *
9576  * Returns the widget’s effective sensitivity, which means
9577  * it is sensitive itself and also its parent widget is sensitive
9578  *
9579  * Returns: %TRUE if the widget is effectively sensitive
9580  *
9581  * Since: 2.18
9582  */
9583 gboolean
gtk_widget_is_sensitive(GtkWidget * widget)9584 gtk_widget_is_sensitive (GtkWidget *widget)
9585 {
9586   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
9587 
9588   return !(widget->priv->state_flags & GTK_STATE_FLAG_INSENSITIVE);
9589 }
9590 
9591 /**
9592  * gtk_widget_set_parent:
9593  * @widget: a #GtkWidget
9594  * @parent: parent container
9595  *
9596  * This function is useful only when implementing subclasses of
9597  * #GtkContainer.
9598  * Sets the container as the parent of @widget, and takes care of
9599  * some details such as updating the state and style of the child
9600  * to reflect its new location. The opposite function is
9601  * gtk_widget_unparent().
9602  **/
9603 void
gtk_widget_set_parent(GtkWidget * widget,GtkWidget * parent)9604 gtk_widget_set_parent (GtkWidget *widget,
9605 		       GtkWidget *parent)
9606 {
9607   GtkStateFlags parent_flags;
9608   GtkWidgetPrivate *priv;
9609   GtkStateData data;
9610 
9611   g_return_if_fail (GTK_IS_WIDGET (widget));
9612   g_return_if_fail (GTK_IS_WIDGET (parent));
9613   g_return_if_fail (widget != parent);
9614 
9615   priv = widget->priv;
9616 
9617   if (priv->parent != NULL)
9618     {
9619       g_warning ("Can't set a parent on widget which has a parent");
9620       return;
9621     }
9622   if (_gtk_widget_is_toplevel (widget))
9623     {
9624       g_warning ("Can't set a parent on a toplevel widget");
9625       return;
9626     }
9627 
9628   data.old_scale_factor = gtk_widget_get_scale_factor (widget);
9629 
9630   /* keep this function in sync with gtk_menu_attach_to_widget()
9631    */
9632 
9633   g_object_ref_sink (widget);
9634 
9635   gtk_widget_push_verify_invariants (widget);
9636 
9637   priv->parent = parent;
9638 
9639   parent_flags = _gtk_widget_get_state_flags (parent);
9640 
9641   /* Merge both old state and current parent state,
9642    * making sure to only propagate the right states */
9643   data.flags_to_set = parent_flags & GTK_STATE_FLAGS_DO_PROPAGATE;
9644   data.flags_to_unset = 0;
9645   gtk_widget_propagate_state (widget, &data);
9646 
9647   if (gtk_css_node_get_parent (widget->priv->cssnode) == NULL)
9648     gtk_css_node_set_parent (widget->priv->cssnode, parent->priv->cssnode);
9649   if (priv->context)
9650     gtk_style_context_set_parent (priv->context,
9651                                   _gtk_widget_get_style_context (parent));
9652 
9653   _gtk_widget_update_parent_muxer (widget);
9654 
9655   g_signal_emit (widget, widget_signals[PARENT_SET], 0, NULL);
9656   if (priv->parent->priv->anchored)
9657     _gtk_widget_propagate_hierarchy_changed (widget, NULL);
9658   g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_PARENT]);
9659 
9660   /* Enforce realized/mapped invariants
9661    */
9662   if (_gtk_widget_get_realized (priv->parent))
9663     gtk_widget_realize (widget);
9664 
9665   if (_gtk_widget_get_visible (priv->parent) &&
9666       _gtk_widget_get_visible (widget))
9667     {
9668       if (_gtk_widget_get_child_visible (widget) &&
9669 	  _gtk_widget_get_mapped (priv->parent))
9670 	gtk_widget_map (widget);
9671 
9672       gtk_widget_queue_resize (priv->parent);
9673     }
9674 
9675   /* child may cause parent's expand to change, if the child is
9676    * expanded. If child is not expanded, then it can't modify the
9677    * parent's expand. If the child becomes expanded later then it will
9678    * queue compute_expand then. This optimization plus defaulting
9679    * newly-constructed widgets to need_compute_expand=FALSE should
9680    * mean that initially building a widget tree doesn't have to keep
9681    * walking up setting need_compute_expand on parents over and over.
9682    *
9683    * We can't change a parent to need to expand unless we're visible.
9684    */
9685   if (_gtk_widget_get_visible (widget) &&
9686       (priv->need_compute_expand ||
9687        priv->computed_hexpand ||
9688        priv->computed_vexpand))
9689     {
9690       gtk_widget_queue_compute_expand (parent);
9691     }
9692 
9693   gtk_widget_pop_verify_invariants (widget);
9694 }
9695 
9696 /**
9697  * gtk_widget_get_parent:
9698  * @widget: a #GtkWidget
9699  *
9700  * Returns the parent container of @widget.
9701  *
9702  * Returns: (transfer none) (nullable): the parent container of @widget, or %NULL
9703  **/
9704 GtkWidget *
gtk_widget_get_parent(GtkWidget * widget)9705 gtk_widget_get_parent (GtkWidget *widget)
9706 {
9707   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
9708 
9709   return widget->priv->parent;
9710 }
9711 
9712 static GtkModifierStyle *
_gtk_widget_get_modifier_properties(GtkWidget * widget)9713 _gtk_widget_get_modifier_properties (GtkWidget *widget)
9714 {
9715   GtkModifierStyle *style;
9716 
9717   style = g_object_get_qdata (G_OBJECT (widget), quark_modifier_style);
9718 
9719   if (G_UNLIKELY (!style))
9720     {
9721       GtkStyleContext *context;
9722 
9723       style = _gtk_modifier_style_new ();
9724       g_object_set_qdata_full (G_OBJECT (widget),
9725                                quark_modifier_style,
9726                                style,
9727                                (GDestroyNotify) g_object_unref);
9728 
9729       context = _gtk_widget_get_style_context (widget);
9730 
9731       gtk_style_context_add_provider (context,
9732                                       GTK_STYLE_PROVIDER (style),
9733                                       GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
9734     }
9735 
9736   return style;
9737 }
9738 
9739 /**
9740  * gtk_widget_override_color:
9741  * @widget: a #GtkWidget
9742  * @state: the state for which to set the color
9743  * @color: (allow-none): the color to assign, or %NULL to undo the effect
9744  *     of previous calls to gtk_widget_override_color()
9745  *
9746  * Sets the color to use for a widget.
9747  *
9748  * All other style values are left untouched.
9749  *
9750  * This function does not act recursively. Setting the color of a
9751  * container does not affect its children. Note that some widgets that
9752  * you may not think of as containers, for instance #GtkButtons,
9753  * are actually containers.
9754  *
9755  * This API is mostly meant as a quick way for applications to
9756  * change a widget appearance. If you are developing a widgets
9757  * library and intend this change to be themeable, it is better
9758  * done by setting meaningful CSS classes in your
9759  * widget/container implementation through gtk_style_context_add_class().
9760  *
9761  * This way, your widget library can install a #GtkCssProvider
9762  * with the %GTK_STYLE_PROVIDER_PRIORITY_FALLBACK priority in order
9763  * to provide a default styling for those widgets that need so, and
9764  * this theming may fully overridden by the user’s theme.
9765  *
9766  * Note that for complex widgets this may bring in undesired
9767  * results (such as uniform background color everywhere), in
9768  * these cases it is better to fully style such widgets through a
9769  * #GtkCssProvider with the %GTK_STYLE_PROVIDER_PRIORITY_APPLICATION
9770  * priority.
9771  *
9772  * Since: 3.0
9773  *
9774  * Deprecated:3.16: Use a custom style provider and style classes instead
9775  */
9776 void
gtk_widget_override_color(GtkWidget * widget,GtkStateFlags state,const GdkRGBA * color)9777 gtk_widget_override_color (GtkWidget     *widget,
9778                            GtkStateFlags  state,
9779                            const GdkRGBA *color)
9780 {
9781   GtkModifierStyle *style;
9782 
9783   g_return_if_fail (GTK_IS_WIDGET (widget));
9784 
9785   style = _gtk_widget_get_modifier_properties (widget);
9786   _gtk_modifier_style_set_color (style, state, color);
9787 }
9788 
9789 /**
9790  * gtk_widget_override_background_color:
9791  * @widget: a #GtkWidget
9792  * @state: the state for which to set the background color
9793  * @color: (allow-none): the color to assign, or %NULL to undo the effect
9794  *     of previous calls to gtk_widget_override_background_color()
9795  *
9796  * Sets the background color to use for a widget.
9797  *
9798  * All other style values are left untouched.
9799  * See gtk_widget_override_color().
9800  *
9801  * Since: 3.0
9802  *
9803  * Deprecated: 3.16: This function is not useful in the context of CSS-based
9804  *   rendering. If you wish to change the way a widget renders its background
9805  *   you should use a custom CSS style, through an application-specific
9806  *   #GtkStyleProvider and a CSS style class. You can also override the default
9807  *   drawing of a widget through the #GtkWidget::draw signal, and use Cairo to
9808  *   draw a specific color, regardless of the CSS style.
9809  */
9810 void
gtk_widget_override_background_color(GtkWidget * widget,GtkStateFlags state,const GdkRGBA * color)9811 gtk_widget_override_background_color (GtkWidget     *widget,
9812                                       GtkStateFlags  state,
9813                                       const GdkRGBA *color)
9814 {
9815   GtkModifierStyle *style;
9816 
9817   g_return_if_fail (GTK_IS_WIDGET (widget));
9818 
9819   style = _gtk_widget_get_modifier_properties (widget);
9820   _gtk_modifier_style_set_background_color (style, state, color);
9821 }
9822 
9823 /**
9824  * gtk_widget_override_font:
9825  * @widget: a #GtkWidget
9826  * @font_desc: (allow-none): the font description to use, or %NULL to undo
9827  *     the effect of previous calls to gtk_widget_override_font()
9828  *
9829  * Sets the font to use for a widget. All other style values are
9830  * left untouched. See gtk_widget_override_color().
9831  *
9832  * Since: 3.0
9833  *
9834  * Deprecated: 3.16: This function is not useful in the context of CSS-based
9835  *   rendering. If you wish to change the font a widget uses to render its text
9836  *   you should use a custom CSS style, through an application-specific
9837  *   #GtkStyleProvider and a CSS style class.
9838  */
9839 void
gtk_widget_override_font(GtkWidget * widget,const PangoFontDescription * font_desc)9840 gtk_widget_override_font (GtkWidget                  *widget,
9841                           const PangoFontDescription *font_desc)
9842 {
9843   GtkModifierStyle *style;
9844 
9845   g_return_if_fail (GTK_IS_WIDGET (widget));
9846 
9847   style = _gtk_widget_get_modifier_properties (widget);
9848   _gtk_modifier_style_set_font (style, font_desc);
9849 }
9850 
9851 /**
9852  * gtk_widget_override_symbolic_color:
9853  * @widget: a #GtkWidget
9854  * @name: the name of the symbolic color to modify
9855  * @color: (allow-none): the color to assign (does not need
9856  *     to be allocated), or %NULL to undo the effect of previous
9857  *     calls to gtk_widget_override_symbolic_color()
9858  *
9859  * Sets a symbolic color for a widget.
9860  *
9861  * All other style values are left untouched.
9862  * See gtk_widget_override_color() for overriding the foreground
9863  * or background color.
9864  *
9865  * Since: 3.0
9866  *
9867  * Deprecated: 3.16: This function is not useful in the context of CSS-based
9868  *   rendering. If you wish to change the color used to render symbolic icons
9869  *   you should use a custom CSS style, through an application-specific
9870  *   #GtkStyleProvider and a CSS style class.
9871  */
9872 void
gtk_widget_override_symbolic_color(GtkWidget * widget,const gchar * name,const GdkRGBA * color)9873 gtk_widget_override_symbolic_color (GtkWidget     *widget,
9874                                     const gchar   *name,
9875                                     const GdkRGBA *color)
9876 {
9877   GtkModifierStyle *style;
9878 
9879   g_return_if_fail (GTK_IS_WIDGET (widget));
9880 
9881   style = _gtk_widget_get_modifier_properties (widget);
9882   _gtk_modifier_style_map_color (style, name, color);
9883 }
9884 
9885 /**
9886  * gtk_widget_override_cursor:
9887  * @widget: a #GtkWidget
9888  * @cursor: (allow-none): the color to use for primary cursor (does not need to be
9889  *     allocated), or %NULL to undo the effect of previous calls to
9890  *     of gtk_widget_override_cursor().
9891  * @secondary_cursor: (allow-none): the color to use for secondary cursor (does not
9892  *     need to be allocated), or %NULL to undo the effect of previous
9893  *     calls to of gtk_widget_override_cursor().
9894  *
9895  * Sets the cursor color to use in a widget, overriding the
9896  * cursor-color and secondary-cursor-color
9897  * style properties. All other style values are left untouched.
9898  * See also gtk_widget_modify_style().
9899  *
9900  * Note that the underlying properties have the #GdkColor type,
9901  * so the alpha value in @primary and @secondary will be ignored.
9902  *
9903  * Since: 3.0
9904  *
9905  * Deprecated: 3.16: This function is not useful in the context of CSS-based
9906  *   rendering. If you wish to change the color used to render the primary
9907  *   and secondary cursors you should use a custom CSS style, through an
9908  *   application-specific #GtkStyleProvider and a CSS style class.
9909  */
9910 void
gtk_widget_override_cursor(GtkWidget * widget,const GdkRGBA * cursor,const GdkRGBA * secondary_cursor)9911 gtk_widget_override_cursor (GtkWidget     *widget,
9912                             const GdkRGBA *cursor,
9913                             const GdkRGBA *secondary_cursor)
9914 {
9915   GtkModifierStyle *style;
9916 
9917   g_return_if_fail (GTK_IS_WIDGET (widget));
9918 
9919   style = _gtk_widget_get_modifier_properties (widget);
9920   _gtk_modifier_style_set_color_property (style,
9921                                           GTK_TYPE_WIDGET,
9922                                           "cursor-color", cursor);
9923   _gtk_modifier_style_set_color_property (style,
9924                                           GTK_TYPE_WIDGET,
9925                                           "secondary-cursor-color",
9926                                           secondary_cursor);
9927 }
9928 
9929 static void
gtk_widget_real_direction_changed(GtkWidget * widget,GtkTextDirection previous_direction)9930 gtk_widget_real_direction_changed (GtkWidget        *widget,
9931                                    GtkTextDirection  previous_direction)
9932 {
9933   gtk_widget_queue_resize (widget);
9934 }
9935 
9936 static void
gtk_widget_real_style_set(GtkWidget * widget,GtkStyle * previous_style)9937 gtk_widget_real_style_set (GtkWidget *widget,
9938                            GtkStyle  *previous_style)
9939 {
9940 }
9941 
9942 typedef struct {
9943   GtkWidget *previous_toplevel;
9944   GdkScreen *previous_screen;
9945   GdkScreen *new_screen;
9946 } HierarchyChangedInfo;
9947 
9948 static void
do_screen_change(GtkWidget * widget,GdkScreen * old_screen,GdkScreen * new_screen)9949 do_screen_change (GtkWidget *widget,
9950 		  GdkScreen *old_screen,
9951 		  GdkScreen *new_screen)
9952 {
9953   if (old_screen != new_screen)
9954     {
9955       GtkWidgetPrivate *priv = widget->priv;
9956 
9957       if (old_screen)
9958 	{
9959 	  PangoContext *context = g_object_get_qdata (G_OBJECT (widget), quark_pango_context);
9960 	  if (context)
9961 	    g_object_set_qdata (G_OBJECT (widget), quark_pango_context, NULL);
9962 	}
9963 
9964       _gtk_tooltip_hide (widget);
9965 
9966       if (new_screen && priv->context)
9967         gtk_style_context_set_screen (priv->context, new_screen);
9968 
9969       g_signal_emit (widget, widget_signals[SCREEN_CHANGED], 0, old_screen);
9970     }
9971 }
9972 
9973 static void
gtk_widget_propagate_hierarchy_changed_recurse(GtkWidget * widget,gpointer client_data)9974 gtk_widget_propagate_hierarchy_changed_recurse (GtkWidget *widget,
9975 						gpointer   client_data)
9976 {
9977   GtkWidgetPrivate *priv = widget->priv;
9978   HierarchyChangedInfo *info = client_data;
9979   gboolean new_anchored = _gtk_widget_is_toplevel (widget) ||
9980                  (priv->parent && priv->parent->priv->anchored);
9981 
9982   if (priv->anchored != new_anchored)
9983     {
9984       g_object_ref (widget);
9985 
9986       priv->anchored = new_anchored;
9987 
9988       /* This can only happen with gtk_widget_reparent() */
9989       if (priv->realized)
9990         {
9991           if (new_anchored)
9992             gtk_widget_connect_frame_clock (widget,
9993                                             gtk_widget_get_frame_clock (widget));
9994           else
9995             gtk_widget_disconnect_frame_clock (widget,
9996                                                gtk_widget_get_frame_clock (info->previous_toplevel));
9997         }
9998 
9999       g_signal_emit (widget, widget_signals[HIERARCHY_CHANGED], 0, info->previous_toplevel);
10000       do_screen_change (widget, info->previous_screen, info->new_screen);
10001 
10002       if (GTK_IS_CONTAINER (widget))
10003 	gtk_container_forall (GTK_CONTAINER (widget),
10004 			      gtk_widget_propagate_hierarchy_changed_recurse,
10005 			      client_data);
10006 
10007       g_object_unref (widget);
10008     }
10009 }
10010 
10011 /**
10012  * _gtk_widget_propagate_hierarchy_changed:
10013  * @widget: a #GtkWidget
10014  * @previous_toplevel: Previous toplevel
10015  *
10016  * Propagates changes in the anchored state to a widget and all
10017  * children, unsetting or setting the %ANCHORED flag, and
10018  * emitting #GtkWidget::hierarchy-changed.
10019  **/
10020 void
_gtk_widget_propagate_hierarchy_changed(GtkWidget * widget,GtkWidget * previous_toplevel)10021 _gtk_widget_propagate_hierarchy_changed (GtkWidget *widget,
10022 					 GtkWidget *previous_toplevel)
10023 {
10024   GtkWidgetPrivate *priv = widget->priv;
10025   HierarchyChangedInfo info;
10026 
10027   info.previous_toplevel = previous_toplevel;
10028   info.previous_screen = previous_toplevel ? gtk_widget_get_screen (previous_toplevel) : NULL;
10029 
10030   if (_gtk_widget_is_toplevel (widget) ||
10031       (priv->parent && priv->parent->priv->anchored))
10032     info.new_screen = gtk_widget_get_screen (widget);
10033   else
10034     info.new_screen = NULL;
10035 
10036   if (info.previous_screen)
10037     g_object_ref (info.previous_screen);
10038   if (previous_toplevel)
10039     g_object_ref (previous_toplevel);
10040 
10041   gtk_widget_propagate_hierarchy_changed_recurse (widget, &info);
10042 
10043   if (previous_toplevel)
10044     g_object_unref (previous_toplevel);
10045   if (info.previous_screen)
10046     g_object_unref (info.previous_screen);
10047 }
10048 
10049 static void
gtk_widget_propagate_screen_changed_recurse(GtkWidget * widget,gpointer client_data)10050 gtk_widget_propagate_screen_changed_recurse (GtkWidget *widget,
10051 					     gpointer   client_data)
10052 {
10053   HierarchyChangedInfo *info = client_data;
10054 
10055   g_object_ref (widget);
10056 
10057   do_screen_change (widget, info->previous_screen, info->new_screen);
10058 
10059   if (GTK_IS_CONTAINER (widget))
10060     gtk_container_forall (GTK_CONTAINER (widget),
10061 			  gtk_widget_propagate_screen_changed_recurse,
10062 			  client_data);
10063 
10064   g_object_unref (widget);
10065 }
10066 
10067 /**
10068  * gtk_widget_is_composited:
10069  * @widget: a #GtkWidget
10070  *
10071  * Whether @widget can rely on having its alpha channel
10072  * drawn correctly. On X11 this function returns whether a
10073  * compositing manager is running for @widget’s screen.
10074  *
10075  * Please note that the semantics of this call will change
10076  * in the future if used on a widget that has a composited
10077  * window in its hierarchy (as set by gdk_window_set_composited()).
10078  *
10079  * Returns: %TRUE if the widget can rely on its alpha
10080  * channel being drawn correctly.
10081  *
10082  * Since: 2.10
10083  *
10084  * Deprecated: 3.22: Use gdk_screen_is_composited() instead.
10085  */
10086 gboolean
gtk_widget_is_composited(GtkWidget * widget)10087 gtk_widget_is_composited (GtkWidget *widget)
10088 {
10089   GdkScreen *screen;
10090 
10091   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
10092 
10093   screen = gtk_widget_get_screen (widget);
10094 
10095   return gdk_screen_is_composited (screen);
10096 }
10097 
10098 static void
propagate_composited_changed(GtkWidget * widget,gpointer dummy)10099 propagate_composited_changed (GtkWidget *widget,
10100 			      gpointer dummy)
10101 {
10102   if (GTK_IS_CONTAINER (widget))
10103     {
10104       gtk_container_forall (GTK_CONTAINER (widget),
10105 			    propagate_composited_changed,
10106 			    NULL);
10107     }
10108 
10109   g_signal_emit (widget, widget_signals[COMPOSITED_CHANGED], 0);
10110 }
10111 
10112 void
_gtk_widget_propagate_composited_changed(GtkWidget * widget)10113 _gtk_widget_propagate_composited_changed (GtkWidget *widget)
10114 {
10115   propagate_composited_changed (widget, NULL);
10116 }
10117 
10118 /**
10119  * _gtk_widget_propagate_screen_changed:
10120  * @widget: a #GtkWidget
10121  * @previous_screen: Previous screen
10122  *
10123  * Propagates changes in the screen for a widget to all
10124  * children, emitting #GtkWidget::screen-changed.
10125  **/
10126 void
_gtk_widget_propagate_screen_changed(GtkWidget * widget,GdkScreen * previous_screen)10127 _gtk_widget_propagate_screen_changed (GtkWidget    *widget,
10128 				      GdkScreen    *previous_screen)
10129 {
10130   HierarchyChangedInfo info;
10131 
10132   info.previous_screen = previous_screen;
10133   info.new_screen = gtk_widget_get_screen (widget);
10134 
10135   if (previous_screen)
10136     g_object_ref (previous_screen);
10137 
10138   gtk_widget_propagate_screen_changed_recurse (widget, &info);
10139 
10140   if (previous_screen)
10141     g_object_unref (previous_screen);
10142 }
10143 
10144 static void
reset_style_recurse(GtkWidget * widget,gpointer data)10145 reset_style_recurse (GtkWidget *widget, gpointer data)
10146 {
10147   _gtk_widget_invalidate_style_context (widget, GTK_CSS_CHANGE_ANY);
10148 
10149   if (GTK_IS_CONTAINER (widget))
10150     gtk_container_forall (GTK_CONTAINER (widget),
10151 			  reset_style_recurse,
10152 			  NULL);
10153 }
10154 
10155 /**
10156  * gtk_widget_reset_style:
10157  * @widget: a #GtkWidget
10158  *
10159  * Updates the style context of @widget and all descendants
10160  * by updating its widget path. #GtkContainers may want
10161  * to use this on a child when reordering it in a way that a different
10162  * style might apply to it. See also gtk_container_get_path_for_child().
10163  *
10164  * Since: 3.0
10165  */
10166 void
gtk_widget_reset_style(GtkWidget * widget)10167 gtk_widget_reset_style (GtkWidget *widget)
10168 {
10169   g_return_if_fail (GTK_IS_WIDGET (widget));
10170 
10171   reset_style_recurse (widget, NULL);
10172 
10173   g_list_foreach (widget->priv->attached_windows,
10174                   (GFunc) reset_style_recurse, NULL);
10175 }
10176 
10177 #ifdef G_ENABLE_CONSISTENCY_CHECKS
10178 
10179 /* Verify invariants, see docs/widget_system.txt for notes on much of
10180  * this.  Invariants may be temporarily broken while we’re in the
10181  * process of updating state, of course, so you can only
10182  * verify_invariants() after a given operation is complete.
10183  * Use push/pop_verify_invariants to help with that.
10184  */
10185 static void
gtk_widget_verify_invariants(GtkWidget * widget)10186 gtk_widget_verify_invariants (GtkWidget *widget)
10187 {
10188   GtkWidget *parent;
10189 
10190   if (widget->priv->verifying_invariants_count > 0)
10191     return;
10192 
10193   parent = widget->priv->parent;
10194 
10195   if (widget->priv->mapped)
10196     {
10197       /* Mapped implies ... */
10198 
10199       if (!widget->priv->realized)
10200         g_warning ("%s %p is mapped but not realized",
10201                    G_OBJECT_TYPE_NAME (widget), widget);
10202 
10203       if (!widget->priv->visible)
10204         g_warning ("%s %p is mapped but not visible",
10205                    G_OBJECT_TYPE_NAME (widget), widget);
10206 
10207       if (!widget->priv->toplevel)
10208         {
10209           if (!widget->priv->child_visible)
10210             g_warning ("%s %p is mapped but not child_visible",
10211                        G_OBJECT_TYPE_NAME (widget), widget);
10212         }
10213     }
10214   else
10215     {
10216       /* Not mapped implies... */
10217 
10218 #if 0
10219   /* This check makes sense for normal toplevels, but for
10220    * something like a toplevel that is embedded within a clutter
10221    * state, mapping may depend on external factors.
10222    */
10223       if (widget->priv->toplevel)
10224         {
10225           if (widget->priv->visible)
10226             g_warning ("%s %p toplevel is visible but not mapped",
10227                        G_OBJECT_TYPE_NAME (widget), widget);
10228         }
10229 #endif
10230     }
10231 
10232   /* Parent related checks aren't possible if parent has
10233    * verifying_invariants_count > 0 because parent needs to recurse
10234    * children first before the invariants will hold.
10235    */
10236   if (parent == NULL || parent->priv->verifying_invariants_count == 0)
10237     {
10238       if (parent &&
10239           parent->priv->realized)
10240         {
10241           /* Parent realized implies... */
10242 
10243 #if 0
10244           /* This is in widget_system.txt but appears to fail
10245            * because there's no gtk_container_realize() that
10246            * realizes all children... instead we just lazily
10247            * wait for map to fix things up.
10248            */
10249           if (!widget->priv->realized)
10250             g_warning ("%s %p is realized but child %s %p is not realized",
10251                        G_OBJECT_TYPE_NAME (parent), parent,
10252                        G_OBJECT_TYPE_NAME (widget), widget);
10253 #endif
10254         }
10255       else if (!widget->priv->toplevel)
10256         {
10257           /* No parent or parent not realized on non-toplevel implies... */
10258 
10259           if (widget->priv->realized && !widget->priv->in_reparent)
10260             g_warning ("%s %p is not realized but child %s %p is realized",
10261                        parent ? G_OBJECT_TYPE_NAME (parent) : "no parent", parent,
10262                        G_OBJECT_TYPE_NAME (widget), widget);
10263         }
10264 
10265       if (parent &&
10266           parent->priv->mapped &&
10267           widget->priv->visible &&
10268           widget->priv->child_visible)
10269         {
10270           /* Parent mapped and we are visible implies... */
10271 
10272           if (!widget->priv->mapped)
10273             g_warning ("%s %p is mapped but visible child %s %p is not mapped",
10274                        G_OBJECT_TYPE_NAME (parent), parent,
10275                        G_OBJECT_TYPE_NAME (widget), widget);
10276         }
10277       else if (!widget->priv->toplevel)
10278         {
10279           /* No parent or parent not mapped on non-toplevel implies... */
10280 
10281           if (widget->priv->mapped && !widget->priv->in_reparent)
10282             g_warning ("%s %p is mapped but visible=%d child_visible=%d parent %s %p mapped=%d",
10283                        G_OBJECT_TYPE_NAME (widget), widget,
10284                        widget->priv->visible,
10285                        widget->priv->child_visible,
10286                        parent ? G_OBJECT_TYPE_NAME (parent) : "no parent", parent,
10287                        parent ? parent->priv->mapped : FALSE);
10288         }
10289     }
10290 
10291   if (!widget->priv->realized)
10292     {
10293       /* Not realized implies... */
10294 
10295 #if 0
10296       /* widget_system.txt says these hold, but they don't. */
10297       if (widget->priv->alloc_needed)
10298         g_warning ("%s %p alloc needed but not realized",
10299                    G_OBJECT_TYPE_NAME (widget), widget);
10300 
10301       if (widget->priv->width_request_needed)
10302         g_warning ("%s %p width request needed but not realized",
10303                    G_OBJECT_TYPE_NAME (widget), widget);
10304 
10305       if (widget->priv->height_request_needed)
10306         g_warning ("%s %p height request needed but not realized",
10307                    G_OBJECT_TYPE_NAME (widget), widget);
10308 #endif
10309     }
10310 }
10311 
10312 /* The point of this push/pop is that invariants may not hold while
10313  * we’re busy making changes. So we only check at the outermost call
10314  * on the call stack, after we finish updating everything.
10315  */
10316 static void
gtk_widget_push_verify_invariants(GtkWidget * widget)10317 gtk_widget_push_verify_invariants (GtkWidget *widget)
10318 {
10319   widget->priv->verifying_invariants_count += 1;
10320 }
10321 
10322 static void
gtk_widget_verify_child_invariants(GtkWidget * widget,gpointer client_data)10323 gtk_widget_verify_child_invariants (GtkWidget *widget,
10324                                     gpointer   client_data)
10325 {
10326   /* We don't recurse further; this is a one-level check. */
10327   gtk_widget_verify_invariants (widget);
10328 }
10329 
10330 static void
gtk_widget_pop_verify_invariants(GtkWidget * widget)10331 gtk_widget_pop_verify_invariants (GtkWidget *widget)
10332 {
10333   g_assert (widget->priv->verifying_invariants_count > 0);
10334 
10335   widget->priv->verifying_invariants_count -= 1;
10336 
10337   if (widget->priv->verifying_invariants_count == 0)
10338     {
10339       gtk_widget_verify_invariants (widget);
10340 
10341       if (GTK_IS_CONTAINER (widget))
10342         {
10343           /* Check one level of children, because our
10344            * push_verify_invariants() will have prevented some of the
10345            * checks. This does not recurse because if recursion is
10346            * needed, it will happen naturally as each child has a
10347            * push/pop on that child. For example if we're recursively
10348            * mapping children, we'll push/pop on each child as we map
10349            * it.
10350            */
10351           gtk_container_forall (GTK_CONTAINER (widget),
10352                                 gtk_widget_verify_child_invariants,
10353                                 NULL);
10354         }
10355     }
10356 }
10357 #endif /* G_ENABLE_CONSISTENCY_CHECKS */
10358 
10359 static PangoContext *
gtk_widget_peek_pango_context(GtkWidget * widget)10360 gtk_widget_peek_pango_context (GtkWidget *widget)
10361 {
10362   return g_object_get_qdata (G_OBJECT (widget), quark_pango_context);
10363 }
10364 
10365 /**
10366  * gtk_widget_get_pango_context:
10367  * @widget: a #GtkWidget
10368  *
10369  * Gets a #PangoContext with the appropriate font map, font description,
10370  * and base direction for this widget. Unlike the context returned
10371  * by gtk_widget_create_pango_context(), this context is owned by
10372  * the widget (it can be used until the screen for the widget changes
10373  * or the widget is removed from its toplevel), and will be updated to
10374  * match any changes to the widget’s attributes. This can be tracked
10375  * by using the #GtkWidget::screen-changed signal on the widget.
10376  *
10377  * Returns: (transfer none): the #PangoContext for the widget.
10378  **/
10379 PangoContext *
gtk_widget_get_pango_context(GtkWidget * widget)10380 gtk_widget_get_pango_context (GtkWidget *widget)
10381 {
10382   PangoContext *context;
10383 
10384   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
10385 
10386   context = g_object_get_qdata (G_OBJECT (widget), quark_pango_context);
10387   if (!context)
10388     {
10389       context = gtk_widget_create_pango_context (GTK_WIDGET (widget));
10390       g_object_set_qdata_full (G_OBJECT (widget),
10391 			       quark_pango_context,
10392 			       context,
10393 			       g_object_unref);
10394     }
10395 
10396   return context;
10397 }
10398 
10399 static PangoFontMap *
gtk_widget_get_effective_font_map(GtkWidget * widget)10400 gtk_widget_get_effective_font_map (GtkWidget *widget)
10401 {
10402   PangoFontMap *font_map;
10403 
10404   font_map = PANGO_FONT_MAP (g_object_get_qdata (G_OBJECT (widget), quark_font_map));
10405   if (font_map)
10406     return font_map;
10407   else if (widget->priv->parent)
10408     return gtk_widget_get_effective_font_map (widget->priv->parent);
10409   else
10410     return pango_cairo_font_map_get_default ();
10411 }
10412 
10413 static void
update_pango_context(GtkWidget * widget,PangoContext * context)10414 update_pango_context (GtkWidget    *widget,
10415                       PangoContext *context)
10416 {
10417   PangoFontDescription *font_desc;
10418   GtkStyleContext *style_context;
10419   GdkScreen *screen;
10420   cairo_font_options_t *font_options;
10421 
10422   style_context = _gtk_widget_get_style_context (widget);
10423   gtk_style_context_get (style_context,
10424                          gtk_style_context_get_state (style_context),
10425                          "font", &font_desc,
10426                          NULL);
10427 
10428   pango_context_set_font_description (context, font_desc);
10429 
10430   pango_font_description_free (font_desc);
10431 
10432   pango_context_set_base_dir (context,
10433 			      _gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR ?
10434 			      PANGO_DIRECTION_LTR : PANGO_DIRECTION_RTL);
10435 
10436   pango_cairo_context_set_resolution (context,
10437                                       _gtk_css_number_value_get (
10438                                           _gtk_style_context_peek_property (style_context,
10439                                                                             GTK_CSS_PROPERTY_DPI),
10440                                           100));
10441 
10442   screen = gtk_widget_get_screen_unchecked (widget);
10443   font_options = (cairo_font_options_t*)g_object_get_qdata (G_OBJECT (widget), quark_font_options);
10444   if (screen && font_options)
10445     {
10446       cairo_font_options_t *options;
10447 
10448       options = cairo_font_options_copy (gdk_screen_get_font_options (screen));
10449       cairo_font_options_merge (options, font_options);
10450       pango_cairo_context_set_font_options (context, options);
10451       cairo_font_options_destroy (options);
10452     }
10453   else if (screen)
10454     {
10455       pango_cairo_context_set_font_options (context,
10456                                             gdk_screen_get_font_options (screen));
10457     }
10458 
10459   pango_context_set_font_map (context, gtk_widget_get_effective_font_map (widget));
10460 }
10461 
10462 static void
gtk_widget_update_pango_context(GtkWidget * widget)10463 gtk_widget_update_pango_context (GtkWidget *widget)
10464 {
10465   PangoContext *context = gtk_widget_peek_pango_context (widget);
10466 
10467   if (context)
10468     update_pango_context (widget, context);
10469 }
10470 
10471 /**
10472  * gtk_widget_set_font_options:
10473  * @widget: a #GtkWidget
10474  * @options: (allow-none): a #cairo_font_options_t, or %NULL to unset any
10475  *   previously set default font options.
10476  *
10477  * Sets the #cairo_font_options_t used for Pango rendering in this widget.
10478  * When not set, the default font options for the #GdkScreen will be used.
10479  *
10480  * Since: 3.18
10481  **/
10482 void
gtk_widget_set_font_options(GtkWidget * widget,const cairo_font_options_t * options)10483 gtk_widget_set_font_options (GtkWidget                  *widget,
10484                              const cairo_font_options_t *options)
10485 {
10486   cairo_font_options_t *font_options;
10487 
10488   g_return_if_fail (GTK_IS_WIDGET (widget));
10489 
10490   font_options = (cairo_font_options_t *)g_object_get_qdata (G_OBJECT (widget), quark_font_options);
10491   if (font_options != options)
10492     {
10493       g_object_set_qdata_full (G_OBJECT (widget),
10494                                quark_font_options,
10495                                options ? cairo_font_options_copy (options) : NULL,
10496                                (GDestroyNotify)cairo_font_options_destroy);
10497 
10498       gtk_widget_update_pango_context (widget);
10499     }
10500 }
10501 
10502 /**
10503  * gtk_widget_get_font_options:
10504  * @widget: a #GtkWidget
10505  *
10506  * Returns the #cairo_font_options_t used for Pango rendering. When not set,
10507  * the defaults font options for the #GdkScreen will be used.
10508  *
10509  * Returns: (transfer none) (nullable): the #cairo_font_options_t or %NULL if not set
10510  *
10511  * Since: 3.18
10512  **/
10513 const cairo_font_options_t *
gtk_widget_get_font_options(GtkWidget * widget)10514 gtk_widget_get_font_options (GtkWidget *widget)
10515 {
10516   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
10517 
10518   return (cairo_font_options_t *)g_object_get_qdata (G_OBJECT (widget), quark_font_options);
10519 }
10520 
10521 static void
gtk_widget_set_font_map_recurse(GtkWidget * widget,gpointer data)10522 gtk_widget_set_font_map_recurse (GtkWidget *widget, gpointer data)
10523 {
10524   if (g_object_get_qdata (G_OBJECT (widget), quark_font_map))
10525     return;
10526 
10527   gtk_widget_update_pango_context (widget);
10528 
10529   if (GTK_IS_CONTAINER (widget))
10530     gtk_container_forall (GTK_CONTAINER (widget),
10531                           gtk_widget_set_font_map_recurse,
10532                           data);
10533 }
10534 
10535 /**
10536  * gtk_widget_set_font_map:
10537  * @widget: a #GtkWidget
10538  * @font_map: (allow-none): a #PangoFontMap, or %NULL to unset any previously
10539  *     set font map
10540  *
10541  * Sets the font map to use for Pango rendering. When not set, the widget
10542  * will inherit the font map from its parent.
10543  *
10544  * Since: 3.18
10545  */
10546 void
gtk_widget_set_font_map(GtkWidget * widget,PangoFontMap * font_map)10547 gtk_widget_set_font_map (GtkWidget    *widget,
10548                          PangoFontMap *font_map)
10549 {
10550   PangoFontMap *map;
10551 
10552   g_return_if_fail (GTK_IS_WIDGET (widget));
10553 
10554   map = PANGO_FONT_MAP (g_object_get_qdata (G_OBJECT (widget), quark_font_map));
10555   if (map == font_map)
10556     return;
10557 
10558   g_object_set_qdata_full (G_OBJECT (widget),
10559                            quark_font_map,
10560                            g_object_ref (font_map),
10561                            g_object_unref);
10562 
10563   gtk_widget_update_pango_context (widget);
10564   if (GTK_IS_CONTAINER (widget))
10565     gtk_container_forall (GTK_CONTAINER (widget),
10566                           gtk_widget_set_font_map_recurse,
10567                           NULL);
10568 }
10569 
10570 /**
10571  * gtk_widget_get_font_map:
10572  * @widget: a #GtkWidget
10573  *
10574  * Gets the font map that has been set with gtk_widget_set_font_map().
10575  *
10576  * Returns: (transfer none) (nullable): A #PangoFontMap, or %NULL
10577  *
10578  * Since: 3.18
10579  */
10580 PangoFontMap *
gtk_widget_get_font_map(GtkWidget * widget)10581 gtk_widget_get_font_map (GtkWidget *widget)
10582 {
10583   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
10584 
10585   return PANGO_FONT_MAP (g_object_get_qdata (G_OBJECT (widget), quark_font_map));
10586 }
10587 
10588 /**
10589  * gtk_widget_create_pango_context:
10590  * @widget: a #GtkWidget
10591  *
10592  * Creates a new #PangoContext with the appropriate font map,
10593  * font options, font description, and base direction for drawing
10594  * text for this widget. See also gtk_widget_get_pango_context().
10595  *
10596  * Returns: (transfer full): the new #PangoContext
10597  **/
10598 PangoContext *
gtk_widget_create_pango_context(GtkWidget * widget)10599 gtk_widget_create_pango_context (GtkWidget *widget)
10600 {
10601   GdkDisplay *display;
10602   PangoContext *context;
10603 
10604   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
10605 
10606   display = gtk_widget_get_display (widget);
10607   context = gdk_pango_context_get_for_display (display);
10608   update_pango_context (widget, context);
10609   pango_context_set_language (context, gtk_get_default_language ());
10610 
10611   return context;
10612 }
10613 
10614 /**
10615  * gtk_widget_create_pango_layout:
10616  * @widget: a #GtkWidget
10617  * @text: (nullable): text to set on the layout (can be %NULL)
10618  *
10619  * Creates a new #PangoLayout with the appropriate font map,
10620  * font description, and base direction for drawing text for
10621  * this widget.
10622  *
10623  * If you keep a #PangoLayout created in this way around, you need
10624  * to re-create it when the widget #PangoContext is replaced.
10625  * This can be tracked by using the #GtkWidget::screen-changed signal
10626  * on the widget.
10627  *
10628  * Returns: (transfer full): the new #PangoLayout
10629  **/
10630 PangoLayout *
gtk_widget_create_pango_layout(GtkWidget * widget,const gchar * text)10631 gtk_widget_create_pango_layout (GtkWidget   *widget,
10632 				const gchar *text)
10633 {
10634   PangoLayout *layout;
10635   PangoContext *context;
10636 
10637   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
10638 
10639   context = gtk_widget_get_pango_context (widget);
10640   layout = pango_layout_new (context);
10641 
10642   if (text)
10643     pango_layout_set_text (layout, text, -1);
10644 
10645   return layout;
10646 }
10647 
10648 /**
10649  * gtk_widget_render_icon_pixbuf:
10650  * @widget: a #GtkWidget
10651  * @stock_id: a stock ID
10652  * @size: (type int): a stock size (#GtkIconSize). A size of `(GtkIconSize)-1`
10653  *     means render at the size of the source and don’t scale (if there are
10654  *     multiple source sizes, GTK+ picks one of the available sizes).
10655  *
10656  * A convenience function that uses the theme engine and style
10657  * settings for @widget to look up @stock_id and render it to
10658  * a pixbuf. @stock_id should be a stock icon ID such as
10659  * #GTK_STOCK_OPEN or #GTK_STOCK_OK. @size should be a size
10660  * such as #GTK_ICON_SIZE_MENU.
10661  *
10662  * The pixels in the returned #GdkPixbuf are shared with the rest of
10663  * the application and should not be modified. The pixbuf should be freed
10664  * after use with g_object_unref().
10665  *
10666  * Returns: (transfer full) (nullable): a new pixbuf, or %NULL if the
10667  *     stock ID wasn’t known
10668  *
10669  * Since: 3.0
10670  *
10671  * Deprecated: 3.10: Use gtk_icon_theme_load_icon() instead.
10672  **/
10673 GdkPixbuf*
gtk_widget_render_icon_pixbuf(GtkWidget * widget,const gchar * stock_id,GtkIconSize size)10674 gtk_widget_render_icon_pixbuf (GtkWidget   *widget,
10675                                const gchar *stock_id,
10676                                GtkIconSize  size)
10677 {
10678   GtkStyleContext *context;
10679   GtkIconSet *icon_set;
10680 
10681   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
10682   g_return_val_if_fail (stock_id != NULL, NULL);
10683   g_return_val_if_fail (size > GTK_ICON_SIZE_INVALID || size == -1, NULL);
10684 
10685   context = _gtk_widget_get_style_context (widget);
10686   G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
10687   icon_set = gtk_style_context_lookup_icon_set (context, stock_id);
10688 
10689   if (icon_set == NULL)
10690     return NULL;
10691 
10692   return gtk_icon_set_render_icon_pixbuf (icon_set, context, size);
10693   G_GNUC_END_IGNORE_DEPRECATIONS;
10694 }
10695 
10696 /**
10697  * gtk_widget_set_parent_window:
10698  * @widget: a #GtkWidget.
10699  * @parent_window: the new parent window.
10700  *
10701  * Sets a non default parent window for @widget.
10702  *
10703  * For #GtkWindow classes, setting a @parent_window effects whether
10704  * the window is a toplevel window or can be embedded into other
10705  * widgets.
10706  *
10707  * For #GtkWindow classes, this needs to be called before the
10708  * window is realized.
10709  */
10710 void
gtk_widget_set_parent_window(GtkWidget * widget,GdkWindow * parent_window)10711 gtk_widget_set_parent_window (GtkWidget *widget,
10712                               GdkWindow *parent_window)
10713 {
10714   GdkWindow *old_parent_window;
10715 
10716   g_return_if_fail (GTK_IS_WIDGET (widget));
10717 
10718   old_parent_window = g_object_get_qdata (G_OBJECT (widget),
10719 					  quark_parent_window);
10720 
10721   if (parent_window != old_parent_window)
10722     {
10723       gboolean is_plug;
10724 
10725       g_object_set_qdata (G_OBJECT (widget), quark_parent_window,
10726 			  parent_window);
10727       if (old_parent_window)
10728 	g_object_unref (old_parent_window);
10729       if (parent_window)
10730 	g_object_ref (parent_window);
10731 
10732       /* Unset toplevel flag when adding a parent window to a widget,
10733        * this is the primary entry point to allow toplevels to be
10734        * embeddable.
10735        */
10736 #ifdef GDK_WINDOWING_X11
10737       is_plug = GTK_IS_PLUG (widget);
10738 #else
10739       is_plug = FALSE;
10740 #endif
10741       if (GTK_IS_WINDOW (widget) && !is_plug)
10742 	_gtk_window_set_is_toplevel (GTK_WINDOW (widget), parent_window == NULL);
10743     }
10744 }
10745 
10746 /**
10747  * gtk_widget_get_parent_window:
10748  * @widget: a #GtkWidget.
10749  *
10750  * Gets @widget’s parent window, or %NULL if it does not have one.
10751  *
10752  * Returns: (transfer none) (nullable): the parent window of @widget, or %NULL
10753  * if it does not have a parent window.
10754  **/
10755 GdkWindow *
gtk_widget_get_parent_window(GtkWidget * widget)10756 gtk_widget_get_parent_window (GtkWidget *widget)
10757 {
10758   GtkWidgetPrivate *priv;
10759   GdkWindow *parent_window;
10760 
10761   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
10762 
10763   priv = widget->priv;
10764 
10765   parent_window = g_object_get_qdata (G_OBJECT (widget), quark_parent_window);
10766 
10767   return (parent_window != NULL) ? parent_window :
10768 	 (priv->parent != NULL) ? priv->parent->priv->window : NULL;
10769 }
10770 
10771 
10772 /**
10773  * gtk_widget_set_child_visible:
10774  * @widget: a #GtkWidget
10775  * @is_visible: if %TRUE, @widget should be mapped along with its parent.
10776  *
10777  * Sets whether @widget should be mapped along with its when its parent
10778  * is mapped and @widget has been shown with gtk_widget_show().
10779  *
10780  * The child visibility can be set for widget before it is added to
10781  * a container with gtk_widget_set_parent(), to avoid mapping
10782  * children unnecessary before immediately unmapping them. However
10783  * it will be reset to its default state of %TRUE when the widget
10784  * is removed from a container.
10785  *
10786  * Note that changing the child visibility of a widget does not
10787  * queue a resize on the widget. Most of the time, the size of
10788  * a widget is computed from all visible children, whether or
10789  * not they are mapped. If this is not the case, the container
10790  * can queue a resize itself.
10791  *
10792  * This function is only useful for container implementations and
10793  * never should be called by an application.
10794  **/
10795 void
gtk_widget_set_child_visible(GtkWidget * widget,gboolean is_visible)10796 gtk_widget_set_child_visible (GtkWidget *widget,
10797 			      gboolean   is_visible)
10798 {
10799   GtkWidgetPrivate *priv;
10800 
10801   g_return_if_fail (GTK_IS_WIDGET (widget));
10802   g_return_if_fail (!_gtk_widget_is_toplevel (widget));
10803 
10804   priv = widget->priv;
10805 
10806   g_object_ref (widget);
10807   gtk_widget_verify_invariants (widget);
10808 
10809   if (is_visible)
10810     priv->child_visible = TRUE;
10811   else
10812     {
10813       GtkWidget *toplevel;
10814 
10815       priv->child_visible = FALSE;
10816 
10817       toplevel = _gtk_widget_get_toplevel (widget);
10818       if (toplevel != widget && _gtk_widget_is_toplevel (toplevel))
10819 	_gtk_window_unset_focus_and_default (GTK_WINDOW (toplevel), widget);
10820     }
10821 
10822   if (priv->parent && _gtk_widget_get_realized (priv->parent))
10823     {
10824       if (_gtk_widget_get_mapped (priv->parent) &&
10825 	  priv->child_visible &&
10826 	  _gtk_widget_get_visible (widget))
10827 	gtk_widget_map (widget);
10828       else
10829 	gtk_widget_unmap (widget);
10830     }
10831 
10832   gtk_widget_verify_invariants (widget);
10833   g_object_unref (widget);
10834 }
10835 
10836 /**
10837  * gtk_widget_get_child_visible:
10838  * @widget: a #GtkWidget
10839  *
10840  * Gets the value set with gtk_widget_set_child_visible().
10841  * If you feel a need to use this function, your code probably
10842  * needs reorganization.
10843  *
10844  * This function is only useful for container implementations and
10845  * never should be called by an application.
10846  *
10847  * Returns: %TRUE if the widget is mapped with the parent.
10848  **/
10849 gboolean
gtk_widget_get_child_visible(GtkWidget * widget)10850 gtk_widget_get_child_visible (GtkWidget *widget)
10851 {
10852   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
10853 
10854   return widget->priv->child_visible;
10855 }
10856 
10857 static GdkScreen *
gtk_widget_get_screen_unchecked(GtkWidget * widget)10858 gtk_widget_get_screen_unchecked (GtkWidget *widget)
10859 {
10860   GtkWidget *toplevel;
10861 
10862   toplevel = _gtk_widget_get_toplevel (widget);
10863 
10864   if (_gtk_widget_is_toplevel (toplevel))
10865     {
10866       if (GTK_IS_WINDOW (toplevel))
10867 	return _gtk_window_get_screen (GTK_WINDOW (toplevel));
10868       else if (GTK_IS_INVISIBLE (toplevel))
10869 	return gtk_invisible_get_screen (GTK_INVISIBLE (widget));
10870     }
10871 
10872   return NULL;
10873 }
10874 
10875 /**
10876  * gtk_widget_get_screen:
10877  * @widget: a #GtkWidget
10878  *
10879  * Get the #GdkScreen from the toplevel window associated with
10880  * this widget. This function can only be called after the widget
10881  * has been added to a widget hierarchy with a #GtkWindow
10882  * at the top.
10883  *
10884  * In general, you should only create screen specific
10885  * resources when a widget has been realized, and you should
10886  * free those resources when the widget is unrealized.
10887  *
10888  * Returns: (transfer none): the #GdkScreen for the toplevel for this widget.
10889  *
10890  * Since: 2.2
10891  **/
10892 GdkScreen*
gtk_widget_get_screen(GtkWidget * widget)10893 gtk_widget_get_screen (GtkWidget *widget)
10894 {
10895   GdkScreen *screen;
10896 
10897   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
10898 
10899   screen = gtk_widget_get_screen_unchecked (widget);
10900 
10901   if (screen)
10902     return screen;
10903   else
10904     return gdk_screen_get_default ();
10905 }
10906 
10907 /**
10908  * gtk_widget_has_screen:
10909  * @widget: a #GtkWidget
10910  *
10911  * Checks whether there is a #GdkScreen is associated with
10912  * this widget. All toplevel widgets have an associated
10913  * screen, and all widgets added into a hierarchy with a toplevel
10914  * window at the top.
10915  *
10916  * Returns: %TRUE if there is a #GdkScreen associated
10917  *   with the widget.
10918  *
10919  * Since: 2.2
10920  **/
10921 gboolean
gtk_widget_has_screen(GtkWidget * widget)10922 gtk_widget_has_screen (GtkWidget *widget)
10923 {
10924   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
10925 
10926   return (gtk_widget_get_screen_unchecked (widget) != NULL);
10927 }
10928 
10929 void
_gtk_widget_scale_changed(GtkWidget * widget)10930 _gtk_widget_scale_changed (GtkWidget *widget)
10931 {
10932   GtkWidgetPrivate *priv;
10933 
10934   g_return_if_fail (GTK_IS_WIDGET (widget));
10935 
10936   priv = widget->priv;
10937 
10938   if (priv->context)
10939     gtk_style_context_set_scale (priv->context, gtk_widget_get_scale_factor (widget));
10940 
10941   g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_SCALE_FACTOR]);
10942 
10943   gtk_widget_queue_draw (widget);
10944 
10945   if (GTK_IS_CONTAINER (widget))
10946     gtk_container_forall (GTK_CONTAINER (widget),
10947                           (GtkCallback) _gtk_widget_scale_changed,
10948                           NULL);
10949 }
10950 
10951 /**
10952  * gtk_widget_get_scale_factor:
10953  * @widget: a #GtkWidget
10954  *
10955  * Retrieves the internal scale factor that maps from window coordinates
10956  * to the actual device pixels. On traditional systems this is 1, on
10957  * high density outputs, it can be a higher value (typically 2).
10958  *
10959  * See gdk_window_get_scale_factor().
10960  *
10961  * Returns: the scale factor for @widget
10962  *
10963  * Since: 3.10
10964  */
10965 gint
gtk_widget_get_scale_factor(GtkWidget * widget)10966 gtk_widget_get_scale_factor (GtkWidget *widget)
10967 {
10968   GtkWidget *toplevel;
10969   GdkDisplay *display;
10970   GdkMonitor *monitor;
10971 
10972   g_return_val_if_fail (GTK_IS_WIDGET (widget), 1);
10973 
10974   if (_gtk_widget_get_realized (widget))
10975     return gdk_window_get_scale_factor (_gtk_widget_get_window (widget));
10976 
10977   toplevel = _gtk_widget_get_toplevel (widget);
10978   if (toplevel && toplevel != widget)
10979     return gtk_widget_get_scale_factor (toplevel);
10980 
10981   /* else fall back to something that is more likely to be right than
10982    * just returning 1:
10983    */
10984   display = gtk_widget_get_display (widget);
10985   monitor = gdk_display_get_monitor (display, 0);
10986 
10987   return gdk_monitor_get_scale_factor (monitor);
10988 }
10989 
10990 /**
10991  * gtk_widget_get_display:
10992  * @widget: a #GtkWidget
10993  *
10994  * Get the #GdkDisplay for the toplevel window associated with
10995  * this widget. This function can only be called after the widget
10996  * has been added to a widget hierarchy with a #GtkWindow at the top.
10997  *
10998  * In general, you should only create display specific
10999  * resources when a widget has been realized, and you should
11000  * free those resources when the widget is unrealized.
11001  *
11002  * Returns: (transfer none): the #GdkDisplay for the toplevel for this widget.
11003  *
11004  * Since: 2.2
11005  **/
11006 GdkDisplay*
gtk_widget_get_display(GtkWidget * widget)11007 gtk_widget_get_display (GtkWidget *widget)
11008 {
11009   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
11010 
11011   return gdk_screen_get_display (gtk_widget_get_screen (widget));
11012 }
11013 
11014 /**
11015  * gtk_widget_get_root_window:
11016  * @widget: a #GtkWidget
11017  *
11018  * Get the root window where this widget is located. This function can
11019  * only be called after the widget has been added to a widget
11020  * hierarchy with #GtkWindow at the top.
11021  *
11022  * The root window is useful for such purposes as creating a popup
11023  * #GdkWindow associated with the window. In general, you should only
11024  * create display specific resources when a widget has been realized,
11025  * and you should free those resources when the widget is unrealized.
11026  *
11027  * Returns: (transfer none): the #GdkWindow root window for the toplevel for this widget.
11028  *
11029  * Since: 2.2
11030  *
11031  * Deprecated: 3.12: Use gdk_screen_get_root_window() instead
11032  */
11033 GdkWindow*
gtk_widget_get_root_window(GtkWidget * widget)11034 gtk_widget_get_root_window (GtkWidget *widget)
11035 {
11036   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
11037 
11038   return gdk_screen_get_root_window (gtk_widget_get_screen (widget));
11039 }
11040 
11041 /**
11042  * gtk_widget_child_focus:
11043  * @widget: a #GtkWidget
11044  * @direction: direction of focus movement
11045  *
11046  * This function is used by custom widget implementations; if you're
11047  * writing an app, you’d use gtk_widget_grab_focus() to move the focus
11048  * to a particular widget, and gtk_container_set_focus_chain() to
11049  * change the focus tab order. So you may want to investigate those
11050  * functions instead.
11051  *
11052  * gtk_widget_child_focus() is called by containers as the user moves
11053  * around the window using keyboard shortcuts. @direction indicates
11054  * what kind of motion is taking place (up, down, left, right, tab
11055  * forward, tab backward). gtk_widget_child_focus() emits the
11056  * #GtkWidget::focus signal; widgets override the default handler
11057  * for this signal in order to implement appropriate focus behavior.
11058  *
11059  * The default ::focus handler for a widget should return %TRUE if
11060  * moving in @direction left the focus on a focusable location inside
11061  * that widget, and %FALSE if moving in @direction moved the focus
11062  * outside the widget. If returning %TRUE, widgets normally
11063  * call gtk_widget_grab_focus() to place the focus accordingly;
11064  * if returning %FALSE, they don’t modify the current focus location.
11065  *
11066  * Returns: %TRUE if focus ended up inside @widget
11067  **/
11068 gboolean
gtk_widget_child_focus(GtkWidget * widget,GtkDirectionType direction)11069 gtk_widget_child_focus (GtkWidget       *widget,
11070                         GtkDirectionType direction)
11071 {
11072   gboolean return_val;
11073 
11074   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
11075 
11076   if (!_gtk_widget_get_visible (widget) ||
11077       !gtk_widget_is_sensitive (widget))
11078     return FALSE;
11079 
11080   /* child widgets must set CAN_FOCUS, containers
11081    * don't have to though.
11082    */
11083   if (!GTK_IS_CONTAINER (widget) &&
11084       !gtk_widget_get_can_focus (widget))
11085     return FALSE;
11086 
11087   g_signal_emit (widget,
11088 		 widget_signals[FOCUS],
11089 		 0,
11090 		 direction, &return_val);
11091 
11092   return return_val;
11093 }
11094 
11095 /**
11096  * gtk_widget_keynav_failed:
11097  * @widget: a #GtkWidget
11098  * @direction: direction of focus movement
11099  *
11100  * This function should be called whenever keyboard navigation within
11101  * a single widget hits a boundary. The function emits the
11102  * #GtkWidget::keynav-failed signal on the widget and its return
11103  * value should be interpreted in a way similar to the return value of
11104  * gtk_widget_child_focus():
11105  *
11106  * When %TRUE is returned, stay in the widget, the failed keyboard
11107  * navigation is OK and/or there is nowhere we can/should move the
11108  * focus to.
11109  *
11110  * When %FALSE is returned, the caller should continue with keyboard
11111  * navigation outside the widget, e.g. by calling
11112  * gtk_widget_child_focus() on the widget’s toplevel.
11113  *
11114  * The default ::keynav-failed handler returns %FALSE for
11115  * %GTK_DIR_TAB_FORWARD and %GTK_DIR_TAB_BACKWARD. For the other
11116  * values of #GtkDirectionType it returns %TRUE.
11117  *
11118  * Whenever the default handler returns %TRUE, it also calls
11119  * gtk_widget_error_bell() to notify the user of the failed keyboard
11120  * navigation.
11121  *
11122  * A use case for providing an own implementation of ::keynav-failed
11123  * (either by connecting to it or by overriding it) would be a row of
11124  * #GtkEntry widgets where the user should be able to navigate the
11125  * entire row with the cursor keys, as e.g. known from user interfaces
11126  * that require entering license keys.
11127  *
11128  * Returns: %TRUE if stopping keyboard navigation is fine, %FALSE
11129  *               if the emitting widget should try to handle the keyboard
11130  *               navigation attempt in its parent container(s).
11131  *
11132  * Since: 2.12
11133  **/
11134 gboolean
gtk_widget_keynav_failed(GtkWidget * widget,GtkDirectionType direction)11135 gtk_widget_keynav_failed (GtkWidget        *widget,
11136                           GtkDirectionType  direction)
11137 {
11138   gboolean return_val;
11139 
11140   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
11141 
11142   g_signal_emit (widget, widget_signals[KEYNAV_FAILED], 0,
11143 		 direction, &return_val);
11144 
11145   return return_val;
11146 }
11147 
11148 /**
11149  * gtk_widget_error_bell:
11150  * @widget: a #GtkWidget
11151  *
11152  * Notifies the user about an input-related error on this widget.
11153  * If the #GtkSettings:gtk-error-bell setting is %TRUE, it calls
11154  * gdk_window_beep(), otherwise it does nothing.
11155  *
11156  * Note that the effect of gdk_window_beep() can be configured in many
11157  * ways, depending on the windowing backend and the desktop environment
11158  * or window manager that is used.
11159  *
11160  * Since: 2.12
11161  **/
11162 void
gtk_widget_error_bell(GtkWidget * widget)11163 gtk_widget_error_bell (GtkWidget *widget)
11164 {
11165   GtkWidgetPrivate *priv;
11166   GtkSettings* settings;
11167   gboolean beep;
11168 
11169   g_return_if_fail (GTK_IS_WIDGET (widget));
11170 
11171   priv = widget->priv;
11172 
11173   settings = gtk_widget_get_settings (widget);
11174   if (!settings)
11175     return;
11176 
11177   g_object_get (settings,
11178                 "gtk-error-bell", &beep,
11179                 NULL);
11180 
11181   if (beep && priv->window)
11182     gdk_window_beep (priv->window);
11183 }
11184 
11185 static void
gtk_widget_set_usize_internal(GtkWidget * widget,gint width,gint height)11186 gtk_widget_set_usize_internal (GtkWidget          *widget,
11187 			       gint                width,
11188 			       gint                height)
11189 {
11190   GtkWidgetPrivate *priv = widget->priv;
11191   gboolean changed = FALSE;
11192 
11193   g_object_freeze_notify (G_OBJECT (widget));
11194 
11195   if (width > -2 && priv->width != width)
11196     {
11197       g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_WIDTH_REQUEST]);
11198       priv->width = width;
11199       changed = TRUE;
11200     }
11201   if (height > -2 && priv->height != height)
11202     {
11203       g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_HEIGHT_REQUEST]);
11204       priv->height = height;
11205       changed = TRUE;
11206     }
11207 
11208   if (_gtk_widget_get_visible (widget) && changed)
11209     {
11210       gtk_widget_queue_resize (widget);
11211     }
11212 
11213   g_object_thaw_notify (G_OBJECT (widget));
11214 }
11215 
11216 /**
11217  * gtk_widget_set_size_request:
11218  * @widget: a #GtkWidget
11219  * @width: width @widget should request, or -1 to unset
11220  * @height: height @widget should request, or -1 to unset
11221  *
11222  * Sets the minimum size of a widget; that is, the widget’s size
11223  * request will be at least @width by @height. You can use this
11224  * function to force a widget to be larger than it normally would be.
11225  *
11226  * In most cases, gtk_window_set_default_size() is a better choice for
11227  * toplevel windows than this function; setting the default size will
11228  * still allow users to shrink the window. Setting the size request
11229  * will force them to leave the window at least as large as the size
11230  * request. When dealing with window sizes,
11231  * gtk_window_set_geometry_hints() can be a useful function as well.
11232  *
11233  * Note the inherent danger of setting any fixed size - themes,
11234  * translations into other languages, different fonts, and user action
11235  * can all change the appropriate size for a given widget. So, it's
11236  * basically impossible to hardcode a size that will always be
11237  * correct.
11238  *
11239  * The size request of a widget is the smallest size a widget can
11240  * accept while still functioning well and drawing itself correctly.
11241  * However in some strange cases a widget may be allocated less than
11242  * its requested size, and in many cases a widget may be allocated more
11243  * space than it requested.
11244  *
11245  * If the size request in a given direction is -1 (unset), then
11246  * the “natural” size request of the widget will be used instead.
11247  *
11248  * The size request set here does not include any margin from the
11249  * #GtkWidget properties margin-left, margin-right, margin-top, and
11250  * margin-bottom, but it does include pretty much all other padding
11251  * or border properties set by any subclass of #GtkWidget.
11252  **/
11253 void
gtk_widget_set_size_request(GtkWidget * widget,gint width,gint height)11254 gtk_widget_set_size_request (GtkWidget *widget,
11255                              gint       width,
11256                              gint       height)
11257 {
11258   g_return_if_fail (GTK_IS_WIDGET (widget));
11259   g_return_if_fail (width >= -1);
11260   g_return_if_fail (height >= -1);
11261 
11262   if (width == 0)
11263     width = 1;
11264   if (height == 0)
11265     height = 1;
11266 
11267   gtk_widget_set_usize_internal (widget, width, height);
11268 }
11269 
11270 
11271 /**
11272  * gtk_widget_get_size_request:
11273  * @widget: a #GtkWidget
11274  * @width: (out) (allow-none): return location for width, or %NULL
11275  * @height: (out) (allow-none): return location for height, or %NULL
11276  *
11277  * Gets the size request that was explicitly set for the widget using
11278  * gtk_widget_set_size_request(). A value of -1 stored in @width or
11279  * @height indicates that that dimension has not been set explicitly
11280  * and the natural requisition of the widget will be used instead. See
11281  * gtk_widget_set_size_request(). To get the size a widget will
11282  * actually request, call gtk_widget_get_preferred_size() instead of
11283  * this function.
11284  **/
11285 void
gtk_widget_get_size_request(GtkWidget * widget,gint * width,gint * height)11286 gtk_widget_get_size_request (GtkWidget *widget,
11287                              gint      *width,
11288                              gint      *height)
11289 {
11290   g_return_if_fail (GTK_IS_WIDGET (widget));
11291 
11292   if (width)
11293     *width = widget->priv->width;
11294 
11295   if (height)
11296     *height = widget->priv->height;
11297 }
11298 
11299 /*< private >
11300  * gtk_widget_has_size_request:
11301  * @widget: a #GtkWidget
11302  *
11303  * Returns if the widget has a size request set (anything besides -1 for height
11304  * or width)
11305  */
11306 gboolean
gtk_widget_has_size_request(GtkWidget * widget)11307 gtk_widget_has_size_request (GtkWidget *widget)
11308 {
11309   return !(widget->priv->width == -1 && widget->priv->height == -1);
11310 }
11311 
11312 /**
11313  * gtk_widget_set_events:
11314  * @widget: a #GtkWidget
11315  * @events: event mask
11316  *
11317  * Sets the event mask (see #GdkEventMask) for a widget. The event
11318  * mask determines which events a widget will receive. Keep in mind
11319  * that different widgets have different default event masks, and by
11320  * changing the event mask you may disrupt a widget’s functionality,
11321  * so be careful. This function must be called while a widget is
11322  * unrealized. Consider gtk_widget_add_events() for widgets that are
11323  * already realized, or if you want to preserve the existing event
11324  * mask. This function can’t be used with widgets that have no window.
11325  * (See gtk_widget_get_has_window()).  To get events on those widgets,
11326  * place them inside a #GtkEventBox and receive events on the event
11327  * box.
11328  **/
11329 void
gtk_widget_set_events(GtkWidget * widget,gint events)11330 gtk_widget_set_events (GtkWidget *widget,
11331 		       gint	  events)
11332 {
11333   gint e;
11334 
11335   g_return_if_fail (GTK_IS_WIDGET (widget));
11336   g_return_if_fail (!_gtk_widget_get_realized (widget));
11337 
11338   e = GPOINTER_TO_INT (g_object_get_qdata (G_OBJECT (widget), quark_event_mask));
11339   if (e != events)
11340     {
11341       g_object_set_qdata (G_OBJECT (widget), quark_event_mask,
11342                           GINT_TO_POINTER (events));
11343       g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_EVENTS]);
11344     }
11345 }
11346 
11347 /**
11348  * gtk_widget_set_device_events:
11349  * @widget: a #GtkWidget
11350  * @device: a #GdkDevice
11351  * @events: event mask
11352  *
11353  * Sets the device event mask (see #GdkEventMask) for a widget. The event
11354  * mask determines which events a widget will receive from @device. Keep
11355  * in mind that different widgets have different default event masks, and by
11356  * changing the event mask you may disrupt a widget’s functionality,
11357  * so be careful. This function must be called while a widget is
11358  * unrealized. Consider gtk_widget_add_device_events() for widgets that are
11359  * already realized, or if you want to preserve the existing event
11360  * mask. This function can’t be used with windowless widgets (which return
11361  * %FALSE from gtk_widget_get_has_window());
11362  * to get events on those widgets, place them inside a #GtkEventBox
11363  * and receive events on the event box.
11364  *
11365  * Since: 3.0
11366  **/
11367 void
gtk_widget_set_device_events(GtkWidget * widget,GdkDevice * device,GdkEventMask events)11368 gtk_widget_set_device_events (GtkWidget    *widget,
11369                               GdkDevice    *device,
11370                               GdkEventMask  events)
11371 {
11372   GHashTable *device_events;
11373 
11374   g_return_if_fail (GTK_IS_WIDGET (widget));
11375   g_return_if_fail (GDK_IS_DEVICE (device));
11376   g_return_if_fail (!_gtk_widget_get_realized (widget));
11377 
11378   device_events = g_object_get_qdata (G_OBJECT (widget), quark_device_event_mask);
11379 
11380   if (G_UNLIKELY (!device_events))
11381     {
11382       device_events = g_hash_table_new (NULL, NULL);
11383       g_object_set_qdata_full (G_OBJECT (widget), quark_device_event_mask, device_events,
11384                                (GDestroyNotify) g_hash_table_unref);
11385     }
11386 
11387   g_hash_table_insert (device_events, device, GUINT_TO_POINTER (events));
11388 }
11389 
11390 /**
11391  * gtk_widget_set_device_enabled:
11392  * @widget: a #GtkWidget
11393  * @device: a #GdkDevice
11394  * @enabled: whether to enable the device
11395  *
11396  * Enables or disables a #GdkDevice to interact with @widget
11397  * and all its children.
11398  *
11399  * It does so by descending through the #GdkWindow hierarchy
11400  * and enabling the same mask that is has for core events
11401  * (i.e. the one that gdk_window_get_events() returns).
11402  *
11403  * Since: 3.0
11404  */
11405 void
gtk_widget_set_device_enabled(GtkWidget * widget,GdkDevice * device,gboolean enabled)11406 gtk_widget_set_device_enabled (GtkWidget *widget,
11407                                GdkDevice *device,
11408                                gboolean   enabled)
11409 {
11410   GList *enabled_devices;
11411 
11412   g_return_if_fail (GTK_IS_WIDGET (widget));
11413   g_return_if_fail (GDK_IS_DEVICE (device));
11414 
11415   enabled_devices = g_object_get_qdata (G_OBJECT (widget), quark_enabled_devices);
11416   enabled_devices = g_list_append (enabled_devices, device);
11417 
11418   g_object_set_qdata_full (G_OBJECT (widget), quark_enabled_devices,
11419                            enabled_devices, (GDestroyNotify) g_list_free);;
11420 
11421   if (_gtk_widget_get_realized (widget))
11422     gtk_widget_set_device_enabled_internal (widget, device, TRUE, enabled);
11423 }
11424 
11425 /**
11426  * gtk_widget_get_device_enabled:
11427  * @widget: a #GtkWidget
11428  * @device: a #GdkDevice
11429  *
11430  * Returns whether @device can interact with @widget and its
11431  * children. See gtk_widget_set_device_enabled().
11432  *
11433  * Returns: %TRUE is @device is enabled for @widget
11434  *
11435  * Since: 3.0
11436  */
11437 gboolean
gtk_widget_get_device_enabled(GtkWidget * widget,GdkDevice * device)11438 gtk_widget_get_device_enabled (GtkWidget *widget,
11439                                GdkDevice *device)
11440 {
11441   GList *enabled_devices;
11442 
11443   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
11444   g_return_val_if_fail (GDK_IS_DEVICE (device), FALSE);
11445 
11446   enabled_devices = g_object_get_qdata (G_OBJECT (widget), quark_enabled_devices);
11447 
11448   return g_list_find (enabled_devices, device) != NULL;
11449 }
11450 
11451 static void
gtk_widget_add_events_internal_list(GtkWidget * widget,GdkDevice * device,GdkEventMask events,GList * window_list)11452 gtk_widget_add_events_internal_list (GtkWidget    *widget,
11453                                      GdkDevice    *device,
11454                                      GdkEventMask  events,
11455                                      GList        *window_list)
11456 {
11457   GdkEventMask controllers_mask;
11458   GList *l;
11459 
11460   controllers_mask = _gtk_widget_get_controllers_evmask (widget);
11461 
11462   for (l = window_list; l != NULL; l = l->next)
11463     {
11464       GdkWindow *window = l->data;
11465       GtkWidget *window_widget;
11466 
11467       gdk_window_get_user_data (window, (gpointer *)&window_widget);
11468       if (window_widget == widget)
11469         {
11470           GList *children;
11471 
11472           if (device)
11473             gdk_window_set_device_events (window, device,
11474                                           gdk_window_get_events (window)
11475                                           | events
11476                                           | controllers_mask);
11477           else
11478             gdk_window_set_events (window,
11479                                    gdk_window_get_events (window)
11480                                    | events
11481                                    | controllers_mask);
11482 
11483           children = gdk_window_peek_children (window);
11484           gtk_widget_add_events_internal_list (widget, device, events, children);
11485         }
11486     }
11487 }
11488 
11489 static void
gtk_widget_add_events_internal(GtkWidget * widget,GdkDevice * device,gint events)11490 gtk_widget_add_events_internal (GtkWidget *widget,
11491                                 GdkDevice *device,
11492                                 gint       events)
11493 {
11494   GtkWidgetPrivate *priv = widget->priv;
11495   GList *window_list;
11496   GList win;
11497 
11498   if (!_gtk_widget_get_has_window (widget))
11499     window_list = gdk_window_peek_children (priv->window);
11500   else
11501     {
11502       win.data = priv->window;
11503       win.prev = win.next = NULL;
11504       window_list = &win;
11505     }
11506 
11507   gtk_widget_add_events_internal_list (widget, device, events, window_list);
11508 }
11509 
11510 /**
11511  * gtk_widget_add_events:
11512  * @widget: a #GtkWidget
11513  * @events: an event mask, see #GdkEventMask
11514  *
11515  * Adds the events in the bitfield @events to the event mask for
11516  * @widget. See gtk_widget_set_events() and the
11517  * [input handling overview][event-masks] for details.
11518  **/
11519 void
gtk_widget_add_events(GtkWidget * widget,gint events)11520 gtk_widget_add_events (GtkWidget *widget,
11521 		       gint	  events)
11522 {
11523   gint old_events;
11524 
11525   g_return_if_fail (GTK_IS_WIDGET (widget));
11526 
11527   old_events = GPOINTER_TO_INT (g_object_get_qdata (G_OBJECT (widget), quark_event_mask));
11528   g_object_set_qdata (G_OBJECT (widget), quark_event_mask,
11529                       GINT_TO_POINTER (old_events | events));
11530 
11531   if (_gtk_widget_get_realized (widget))
11532     {
11533       gtk_widget_add_events_internal (widget, NULL, events);
11534       gtk_widget_update_devices_mask (widget, FALSE);
11535     }
11536 
11537   g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_EVENTS]);
11538 }
11539 
11540 /**
11541  * gtk_widget_add_device_events:
11542  * @widget: a #GtkWidget
11543  * @device: a #GdkDevice
11544  * @events: an event mask, see #GdkEventMask
11545  *
11546  * Adds the device events in the bitfield @events to the event mask for
11547  * @widget. See gtk_widget_set_device_events() for details.
11548  *
11549  * Since: 3.0
11550  **/
11551 void
gtk_widget_add_device_events(GtkWidget * widget,GdkDevice * device,GdkEventMask events)11552 gtk_widget_add_device_events (GtkWidget    *widget,
11553                               GdkDevice    *device,
11554                               GdkEventMask  events)
11555 {
11556   GdkEventMask old_events;
11557   GHashTable *device_events;
11558 
11559   g_return_if_fail (GTK_IS_WIDGET (widget));
11560   g_return_if_fail (GDK_IS_DEVICE (device));
11561 
11562   old_events = gtk_widget_get_device_events (widget, device);
11563 
11564   device_events = g_object_get_qdata (G_OBJECT (widget), quark_device_event_mask);
11565 
11566   if (G_UNLIKELY (!device_events))
11567     {
11568       device_events = g_hash_table_new (NULL, NULL);
11569       g_object_set_qdata_full (G_OBJECT (widget), quark_device_event_mask, device_events,
11570                                (GDestroyNotify) g_hash_table_unref);
11571     }
11572 
11573   g_hash_table_insert (device_events, device,
11574                        GUINT_TO_POINTER (old_events | events));
11575 
11576   if (_gtk_widget_get_realized (widget))
11577     gtk_widget_add_events_internal (widget, device, events);
11578 
11579   g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_EVENTS]);
11580 }
11581 
11582 /**
11583  * gtk_widget_get_toplevel:
11584  * @widget: a #GtkWidget
11585  *
11586  * This function returns the topmost widget in the container hierarchy
11587  * @widget is a part of. If @widget has no parent widgets, it will be
11588  * returned as the topmost widget. No reference will be added to the
11589  * returned widget; it should not be unreferenced.
11590  *
11591  * Note the difference in behavior vs. gtk_widget_get_ancestor();
11592  * `gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW)`
11593  * would return
11594  * %NULL if @widget wasn’t inside a toplevel window, and if the
11595  * window was inside a #GtkWindow-derived widget which was in turn
11596  * inside the toplevel #GtkWindow. While the second case may
11597  * seem unlikely, it actually happens when a #GtkPlug is embedded
11598  * inside a #GtkSocket within the same application.
11599  *
11600  * To reliably find the toplevel #GtkWindow, use
11601  * gtk_widget_get_toplevel() and call GTK_IS_WINDOW()
11602  * on the result. For instance, to get the title of a widget's toplevel
11603  * window, one might use:
11604  * |[<!-- language="C" -->
11605  * static const char *
11606  * get_widget_toplevel_title (GtkWidget *widget)
11607  * {
11608  *   GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
11609  *   if (GTK_IS_WINDOW (toplevel))
11610  *     {
11611  *       return gtk_window_get_title (GTK_WINDOW (toplevel));
11612  *     }
11613  *
11614  *   return NULL;
11615  * }
11616  * ]|
11617  *
11618  * Returns: (transfer none): the topmost ancestor of @widget, or @widget itself
11619  *    if there’s no ancestor.
11620  **/
11621 GtkWidget*
gtk_widget_get_toplevel(GtkWidget * widget)11622 gtk_widget_get_toplevel (GtkWidget *widget)
11623 {
11624   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
11625 
11626   while (widget->priv->parent)
11627     widget = widget->priv->parent;
11628 
11629   return widget;
11630 }
11631 
11632 /**
11633  * gtk_widget_get_ancestor:
11634  * @widget: a #GtkWidget
11635  * @widget_type: ancestor type
11636  *
11637  * Gets the first ancestor of @widget with type @widget_type. For example,
11638  * `gtk_widget_get_ancestor (widget, GTK_TYPE_BOX)` gets
11639  * the first #GtkBox that’s an ancestor of @widget. No reference will be
11640  * added to the returned widget; it should not be unreferenced. See note
11641  * about checking for a toplevel #GtkWindow in the docs for
11642  * gtk_widget_get_toplevel().
11643  *
11644  * Note that unlike gtk_widget_is_ancestor(), gtk_widget_get_ancestor()
11645  * considers @widget to be an ancestor of itself.
11646  *
11647  * Returns: (transfer none) (nullable): the ancestor widget, or %NULL if not found
11648  **/
11649 GtkWidget*
gtk_widget_get_ancestor(GtkWidget * widget,GType widget_type)11650 gtk_widget_get_ancestor (GtkWidget *widget,
11651 			 GType      widget_type)
11652 {
11653   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
11654 
11655   while (widget && !g_type_is_a (G_OBJECT_TYPE (widget), widget_type))
11656     widget = widget->priv->parent;
11657 
11658   if (!(widget && g_type_is_a (G_OBJECT_TYPE (widget), widget_type)))
11659     return NULL;
11660 
11661   return widget;
11662 }
11663 
11664 /**
11665  * gtk_widget_set_visual:
11666  * @widget: a #GtkWidget
11667  * @visual: (allow-none): visual to be used or %NULL to unset a previous one
11668  *
11669  * Sets the visual that should be used for by widget and its children for
11670  * creating #GdkWindows. The visual must be on the same #GdkScreen as
11671  * returned by gtk_widget_get_screen(), so handling the
11672  * #GtkWidget::screen-changed signal is necessary.
11673  *
11674  * Setting a new @visual will not cause @widget to recreate its windows,
11675  * so you should call this function before @widget is realized.
11676  **/
11677 void
gtk_widget_set_visual(GtkWidget * widget,GdkVisual * visual)11678 gtk_widget_set_visual (GtkWidget *widget,
11679                        GdkVisual *visual)
11680 {
11681   g_return_if_fail (GTK_IS_WIDGET (widget));
11682   g_return_if_fail (visual == NULL || GDK_IS_VISUAL (visual));
11683 
11684   if (visual)
11685     g_return_if_fail (gtk_widget_get_screen (widget) == gdk_visual_get_screen (visual));
11686 
11687   g_object_set_qdata_full (G_OBJECT (widget),
11688                            quark_visual,
11689                            visual ? g_object_ref (visual) : NULL,
11690                            g_object_unref);
11691 }
11692 
11693 /**
11694  * gtk_widget_get_visual:
11695  * @widget: a #GtkWidget
11696  *
11697  * Gets the visual that will be used to render @widget.
11698  *
11699  * Returns: (transfer none): the visual for @widget
11700  **/
11701 GdkVisual*
gtk_widget_get_visual(GtkWidget * widget)11702 gtk_widget_get_visual (GtkWidget *widget)
11703 {
11704   GtkWidget *w;
11705   GdkVisual *visual;
11706   GdkScreen *screen;
11707 
11708   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
11709 
11710   if (!_gtk_widget_get_has_window (widget) &&
11711       widget->priv->window)
11712     return gdk_window_get_visual (widget->priv->window);
11713 
11714   screen = gtk_widget_get_screen (widget);
11715 
11716   for (w = widget; w != NULL; w = w->priv->parent)
11717     {
11718       visual = g_object_get_qdata (G_OBJECT (w), quark_visual);
11719       if (visual)
11720         {
11721           if (gdk_visual_get_screen (visual) == screen)
11722             return visual;
11723 
11724           g_warning ("Ignoring visual set on widget '%s' that is not on the correct screen.",
11725                      gtk_widget_get_name (widget));
11726         }
11727     }
11728 
11729   return gdk_screen_get_system_visual (screen);
11730 }
11731 
11732 /**
11733  * gtk_widget_get_settings:
11734  * @widget: a #GtkWidget
11735  *
11736  * Gets the settings object holding the settings used for this widget.
11737  *
11738  * Note that this function can only be called when the #GtkWidget
11739  * is attached to a toplevel, since the settings object is specific
11740  * to a particular #GdkScreen.
11741  *
11742  * Returns: (transfer none): the relevant #GtkSettings object
11743  */
11744 GtkSettings*
gtk_widget_get_settings(GtkWidget * widget)11745 gtk_widget_get_settings (GtkWidget *widget)
11746 {
11747   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
11748 
11749   return gtk_settings_get_for_screen (gtk_widget_get_screen (widget));
11750 }
11751 
11752 /**
11753  * gtk_widget_get_events:
11754  * @widget: a #GtkWidget
11755  *
11756  * Returns the event mask (see #GdkEventMask) for the widget. These are the
11757  * events that the widget will receive.
11758  *
11759  * Note: Internally, the widget event mask will be the logical OR of the event
11760  * mask set through gtk_widget_set_events() or gtk_widget_add_events(), and the
11761  * event mask necessary to cater for every #GtkEventController created for the
11762  * widget.
11763  *
11764  * Returns: event mask for @widget
11765  **/
11766 gint
gtk_widget_get_events(GtkWidget * widget)11767 gtk_widget_get_events (GtkWidget *widget)
11768 {
11769   g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
11770 
11771   return GPOINTER_TO_INT (g_object_get_qdata (G_OBJECT (widget), quark_event_mask)) |
11772     _gtk_widget_get_controllers_evmask (widget);
11773 }
11774 
11775 /**
11776  * gtk_widget_get_device_events:
11777  * @widget: a #GtkWidget
11778  * @device: a #GdkDevice
11779  *
11780  * Returns the events mask for the widget corresponding to an specific device. These
11781  * are the events that the widget will receive when @device operates on it.
11782  *
11783  * Returns: device event mask for @widget
11784  *
11785  * Since: 3.0
11786  **/
11787 GdkEventMask
gtk_widget_get_device_events(GtkWidget * widget,GdkDevice * device)11788 gtk_widget_get_device_events (GtkWidget *widget,
11789                               GdkDevice *device)
11790 {
11791   GHashTable *device_events;
11792 
11793   g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
11794   g_return_val_if_fail (GDK_IS_DEVICE (device), 0);
11795 
11796   device_events = g_object_get_qdata (G_OBJECT (widget), quark_device_event_mask);
11797 
11798   if (!device_events)
11799     return 0;
11800 
11801   return GPOINTER_TO_UINT (g_hash_table_lookup (device_events, device));
11802 }
11803 
11804 /**
11805  * gtk_widget_get_pointer:
11806  * @widget: a #GtkWidget
11807  * @x: (out) (allow-none): return location for the X coordinate, or %NULL
11808  * @y: (out) (allow-none): return location for the Y coordinate, or %NULL
11809  *
11810  * Obtains the location of the mouse pointer in widget coordinates.
11811  * Widget coordinates are a bit odd; for historical reasons, they are
11812  * defined as @widget->window coordinates for widgets that return %TRUE for
11813  * gtk_widget_get_has_window(); and are relative to @widget->allocation.x,
11814  * @widget->allocation.y otherwise.
11815  *
11816  * Deprecated: 3.4: Use gdk_window_get_device_position() instead.
11817  **/
11818 void
gtk_widget_get_pointer(GtkWidget * widget,gint * x,gint * y)11819 gtk_widget_get_pointer (GtkWidget *widget,
11820 			gint	  *x,
11821 			gint	  *y)
11822 {
11823   GtkWidgetPrivate *priv;
11824 
11825   g_return_if_fail (GTK_IS_WIDGET (widget));
11826 
11827   priv = widget->priv;
11828 
11829   if (x)
11830     *x = -1;
11831   if (y)
11832     *y = -1;
11833 
11834   if (_gtk_widget_get_realized (widget))
11835     {
11836       GdkSeat *seat;
11837 
11838       seat = gdk_display_get_default_seat (gtk_widget_get_display (widget));
11839       gdk_window_get_device_position (priv->window,
11840                                       gdk_seat_get_pointer (seat),
11841                                       x, y, NULL);
11842 
11843       if (!_gtk_widget_get_has_window (widget))
11844 	{
11845 	  if (x)
11846 	    *x -= priv->allocation.x;
11847 	  if (y)
11848 	    *y -= priv->allocation.y;
11849 	}
11850     }
11851 }
11852 
11853 /**
11854  * gtk_widget_is_ancestor:
11855  * @widget: a #GtkWidget
11856  * @ancestor: another #GtkWidget
11857  *
11858  * Determines whether @widget is somewhere inside @ancestor, possibly with
11859  * intermediate containers.
11860  *
11861  * Returns: %TRUE if @ancestor contains @widget as a child,
11862  *    grandchild, great grandchild, etc.
11863  **/
11864 gboolean
gtk_widget_is_ancestor(GtkWidget * widget,GtkWidget * ancestor)11865 gtk_widget_is_ancestor (GtkWidget *widget,
11866 			GtkWidget *ancestor)
11867 {
11868   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
11869   g_return_val_if_fail (ancestor != NULL, FALSE);
11870 
11871   while (widget)
11872     {
11873       if (widget->priv->parent == ancestor)
11874 	return TRUE;
11875       widget = widget->priv->parent;
11876     }
11877 
11878   return FALSE;
11879 }
11880 
11881 static GQuark quark_composite_name = 0;
11882 
11883 /**
11884  * gtk_widget_set_composite_name:
11885  * @widget: a #GtkWidget.
11886  * @name: the name to set
11887  *
11888  * Sets a widgets composite name. The widget must be
11889  * a composite child of its parent; see gtk_widget_push_composite_child().
11890  *
11891  * Deprecated: 3.10: Use gtk_widget_class_set_template(), or don’t use this API at all.
11892  **/
11893 void
gtk_widget_set_composite_name(GtkWidget * widget,const gchar * name)11894 gtk_widget_set_composite_name (GtkWidget   *widget,
11895 			       const gchar *name)
11896 {
11897   g_return_if_fail (GTK_IS_WIDGET (widget));
11898   g_return_if_fail (widget->priv->composite_child);
11899   g_return_if_fail (name != NULL);
11900 
11901   if (!quark_composite_name)
11902     quark_composite_name = g_quark_from_static_string ("gtk-composite-name");
11903 
11904   g_object_set_qdata_full (G_OBJECT (widget),
11905 			   quark_composite_name,
11906 			   g_strdup (name),
11907 			   g_free);
11908 }
11909 
11910 /**
11911  * gtk_widget_get_composite_name:
11912  * @widget: a #GtkWidget
11913  *
11914  * Obtains the composite name of a widget.
11915  *
11916  * Returns: the composite name of @widget, or %NULL if @widget is not
11917  *   a composite child. The string should be freed when it is no
11918  *   longer needed.
11919  *
11920  * Deprecated: 3.10: Use gtk_widget_class_set_template(), or don’t use this API at all.
11921  **/
11922 gchar*
gtk_widget_get_composite_name(GtkWidget * widget)11923 gtk_widget_get_composite_name (GtkWidget *widget)
11924 {
11925   GtkWidgetPrivate *priv;
11926 
11927   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
11928 
11929   priv = widget->priv;
11930 
11931   if (widget->priv->composite_child && priv->parent)
11932     return _gtk_container_child_composite_name (GTK_CONTAINER (priv->parent),
11933 					       widget);
11934   else
11935     return NULL;
11936 }
11937 
11938 /**
11939  * gtk_widget_push_composite_child:
11940  *
11941  * Makes all newly-created widgets as composite children until
11942  * the corresponding gtk_widget_pop_composite_child() call.
11943  *
11944  * A composite child is a child that’s an implementation detail of the
11945  * container it’s inside and should not be visible to people using the
11946  * container. Composite children aren’t treated differently by GTK+ (but
11947  * see gtk_container_foreach() vs. gtk_container_forall()), but e.g. GUI
11948  * builders might want to treat them in a different way.
11949  *
11950  * Deprecated: 3.10: This API never really worked well and was mostly unused, now
11951  * we have a more complete mechanism for composite children, see gtk_widget_class_set_template().
11952  **/
11953 void
gtk_widget_push_composite_child(void)11954 gtk_widget_push_composite_child (void)
11955 {
11956   composite_child_stack++;
11957 }
11958 
11959 /**
11960  * gtk_widget_pop_composite_child:
11961  *
11962  * Cancels the effect of a previous call to gtk_widget_push_composite_child().
11963  *
11964  * Deprecated: 3.10: Use gtk_widget_class_set_template(), or don’t use this API at all.
11965  **/
11966 void
gtk_widget_pop_composite_child(void)11967 gtk_widget_pop_composite_child (void)
11968 {
11969   if (composite_child_stack)
11970     composite_child_stack--;
11971 }
11972 
11973 static void
gtk_widget_emit_direction_changed(GtkWidget * widget,GtkTextDirection old_dir)11974 gtk_widget_emit_direction_changed (GtkWidget        *widget,
11975                                    GtkTextDirection  old_dir)
11976 {
11977   GtkTextDirection direction;
11978   GtkStateFlags state;
11979 
11980   gtk_widget_update_pango_context (widget);
11981 
11982   direction = _gtk_widget_get_direction (widget);
11983 
11984   switch (direction)
11985     {
11986     case GTK_TEXT_DIR_LTR:
11987       state = GTK_STATE_FLAG_DIR_LTR;
11988       break;
11989 
11990     case GTK_TEXT_DIR_RTL:
11991       state = GTK_STATE_FLAG_DIR_RTL;
11992       break;
11993 
11994     case GTK_TEXT_DIR_NONE:
11995     default:
11996       g_assert_not_reached ();
11997       break;
11998     }
11999 
12000   gtk_widget_update_state_flags (widget,
12001                                  state,
12002                                  state ^ (GTK_STATE_FLAG_DIR_LTR | GTK_STATE_FLAG_DIR_RTL));
12003 
12004   g_signal_emit (widget, widget_signals[DIRECTION_CHANGED], 0, old_dir);
12005 }
12006 
12007 /**
12008  * gtk_widget_set_direction:
12009  * @widget: a #GtkWidget
12010  * @dir:    the new direction
12011  *
12012  * Sets the reading direction on a particular widget. This direction
12013  * controls the primary direction for widgets containing text,
12014  * and also the direction in which the children of a container are
12015  * packed. The ability to set the direction is present in order
12016  * so that correct localization into languages with right-to-left
12017  * reading directions can be done. Generally, applications will
12018  * let the default reading direction present, except for containers
12019  * where the containers are arranged in an order that is explicitly
12020  * visual rather than logical (such as buttons for text justification).
12021  *
12022  * If the direction is set to %GTK_TEXT_DIR_NONE, then the value
12023  * set by gtk_widget_set_default_direction() will be used.
12024  **/
12025 void
gtk_widget_set_direction(GtkWidget * widget,GtkTextDirection dir)12026 gtk_widget_set_direction (GtkWidget        *widget,
12027                           GtkTextDirection  dir)
12028 {
12029   GtkTextDirection old_dir;
12030 
12031   g_return_if_fail (GTK_IS_WIDGET (widget));
12032   g_return_if_fail (dir >= GTK_TEXT_DIR_NONE && dir <= GTK_TEXT_DIR_RTL);
12033 
12034   old_dir = _gtk_widget_get_direction (widget);
12035 
12036   widget->priv->direction = dir;
12037 
12038   if (old_dir != _gtk_widget_get_direction (widget))
12039     gtk_widget_emit_direction_changed (widget, old_dir);
12040 }
12041 
12042 /**
12043  * gtk_widget_get_direction:
12044  * @widget: a #GtkWidget
12045  *
12046  * Gets the reading direction for a particular widget. See
12047  * gtk_widget_set_direction().
12048  *
12049  * Returns: the reading direction for the widget.
12050  **/
12051 GtkTextDirection
gtk_widget_get_direction(GtkWidget * widget)12052 gtk_widget_get_direction (GtkWidget *widget)
12053 {
12054   g_return_val_if_fail (GTK_IS_WIDGET (widget), GTK_TEXT_DIR_LTR);
12055 
12056   if (widget->priv->direction == GTK_TEXT_DIR_NONE)
12057     return gtk_default_direction;
12058   else
12059     return widget->priv->direction;
12060 }
12061 
12062 static void
gtk_widget_set_default_direction_recurse(GtkWidget * widget,gpointer data)12063 gtk_widget_set_default_direction_recurse (GtkWidget *widget, gpointer data)
12064 {
12065   GtkTextDirection old_dir = GPOINTER_TO_UINT (data);
12066 
12067   g_object_ref (widget);
12068 
12069   if (widget->priv->direction == GTK_TEXT_DIR_NONE)
12070     gtk_widget_emit_direction_changed (widget, old_dir);
12071 
12072   if (GTK_IS_CONTAINER (widget))
12073     gtk_container_forall (GTK_CONTAINER (widget),
12074 			  gtk_widget_set_default_direction_recurse,
12075 			  data);
12076 
12077   g_object_unref (widget);
12078 }
12079 
12080 /**
12081  * gtk_widget_set_default_direction:
12082  * @dir: the new default direction. This cannot be
12083  *        %GTK_TEXT_DIR_NONE.
12084  *
12085  * Sets the default reading direction for widgets where the
12086  * direction has not been explicitly set by gtk_widget_set_direction().
12087  **/
12088 void
gtk_widget_set_default_direction(GtkTextDirection dir)12089 gtk_widget_set_default_direction (GtkTextDirection dir)
12090 {
12091   g_return_if_fail (dir == GTK_TEXT_DIR_RTL || dir == GTK_TEXT_DIR_LTR);
12092 
12093   if (dir != gtk_default_direction)
12094     {
12095       GList *toplevels, *tmp_list;
12096       GtkTextDirection old_dir = gtk_default_direction;
12097 
12098       gtk_default_direction = dir;
12099 
12100       tmp_list = toplevels = gtk_window_list_toplevels ();
12101       g_list_foreach (toplevels, (GFunc)g_object_ref, NULL);
12102 
12103       while (tmp_list)
12104 	{
12105 	  gtk_widget_set_default_direction_recurse (tmp_list->data,
12106 						    GUINT_TO_POINTER (old_dir));
12107 	  g_object_unref (tmp_list->data);
12108 	  tmp_list = tmp_list->next;
12109 	}
12110 
12111       g_list_free (toplevels);
12112     }
12113 }
12114 
12115 /**
12116  * gtk_widget_get_default_direction:
12117  *
12118  * Obtains the current default reading direction. See
12119  * gtk_widget_set_default_direction().
12120  *
12121  * Returns: the current default direction.
12122  **/
12123 GtkTextDirection
gtk_widget_get_default_direction(void)12124 gtk_widget_get_default_direction (void)
12125 {
12126   return gtk_default_direction;
12127 }
12128 
12129 static void
gtk_widget_constructed(GObject * object)12130 gtk_widget_constructed (GObject *object)
12131 {
12132   GtkWidget *widget = GTK_WIDGET (object);
12133   GtkWidgetPath *path;
12134 
12135   /* As strange as it may seem, this may happen on object construction.
12136    * init() implementations of parent types may eventually call this function,
12137    * each with its corresponding GType, which could leave a child
12138    * implementation with a wrong widget type in the widget path
12139    */
12140   path = (GtkWidgetPath*)g_object_get_qdata (object, quark_widget_path);
12141   if (path && G_OBJECT_TYPE (widget) != gtk_widget_path_get_object_type (path))
12142     g_object_set_qdata (object, quark_widget_path, NULL);
12143 
12144   G_OBJECT_CLASS (gtk_widget_parent_class)->constructed (object);
12145 }
12146 
12147 static void
gtk_widget_dispose(GObject * object)12148 gtk_widget_dispose (GObject *object)
12149 {
12150   GtkWidget *widget = GTK_WIDGET (object);
12151   GtkWidgetPrivate *priv = widget->priv;
12152   GSList *sizegroups;
12153 
12154   if (priv->parent)
12155     gtk_container_remove (GTK_CONTAINER (priv->parent), widget);
12156   else if (_gtk_widget_get_visible (widget))
12157     gtk_widget_hide (widget);
12158 
12159   priv->visible = FALSE;
12160   if (_gtk_widget_get_realized (widget))
12161     gtk_widget_unrealize (widget);
12162 
12163   if (!priv->in_destruction)
12164     {
12165       priv->in_destruction = TRUE;
12166       g_signal_emit (object, widget_signals[DESTROY], 0);
12167       priv->in_destruction = FALSE;
12168     }
12169 
12170   sizegroups = _gtk_widget_get_sizegroups (widget);
12171   while (sizegroups)
12172     {
12173       GtkSizeGroup *size_group;
12174 
12175       size_group = sizegroups->data;
12176       sizegroups = sizegroups->next;
12177       gtk_size_group_remove_widget (size_group, widget);
12178     }
12179 
12180   g_object_set_qdata (object, quark_action_muxer, NULL);
12181 
12182   while (priv->attached_windows)
12183     gtk_window_set_attached_to (priv->attached_windows->data, NULL);
12184 
12185   G_OBJECT_CLASS (gtk_widget_parent_class)->dispose (object);
12186 }
12187 
12188 #ifdef G_ENABLE_CONSISTENCY_CHECKS
12189 typedef struct {
12190   AutomaticChildClass *child_class;
12191   GType                widget_type;
12192   GObject             *object;
12193   gboolean             did_finalize;
12194 } FinalizeAssertion;
12195 
12196 static void
finalize_assertion_weak_ref(gpointer data,GObject * where_the_object_was)12197 finalize_assertion_weak_ref (gpointer data,
12198 			     GObject *where_the_object_was)
12199 {
12200   FinalizeAssertion *assertion = (FinalizeAssertion *)data;
12201   assertion->did_finalize = TRUE;
12202 }
12203 
12204 static FinalizeAssertion *
finalize_assertion_new(GtkWidget * widget,GType widget_type,AutomaticChildClass * child_class)12205 finalize_assertion_new (GtkWidget           *widget,
12206 			GType                widget_type,
12207 			AutomaticChildClass *child_class)
12208 {
12209   FinalizeAssertion *assertion = NULL;
12210   GObject           *object;
12211 
12212   object = gtk_widget_get_template_child (widget, widget_type, child_class->name);
12213 
12214   /* We control the hash table entry, the object should never be NULL
12215    */
12216   g_assert (object);
12217   if (!G_IS_OBJECT (object))
12218     g_critical ("Automated component '%s' of class '%s' seems to have been prematurely finalized",
12219 		child_class->name, g_type_name (widget_type));
12220   else
12221     {
12222       assertion = g_slice_new0 (FinalizeAssertion);
12223       assertion->child_class = child_class;
12224       assertion->widget_type = widget_type;
12225       assertion->object = object;
12226 
12227       g_object_weak_ref (object, finalize_assertion_weak_ref, assertion);
12228     }
12229 
12230   return assertion;
12231 }
12232 
12233 static GSList *
build_finalize_assertion_list(GtkWidget * widget)12234 build_finalize_assertion_list (GtkWidget *widget)
12235 {
12236   GType class_type;
12237   GtkWidgetClass *class;
12238   GSList *l, *list = NULL;
12239 
12240   for (class = GTK_WIDGET_GET_CLASS (widget);
12241        GTK_IS_WIDGET_CLASS (class);
12242        class = g_type_class_peek_parent (class))
12243     {
12244       if (!class->priv->template)
12245 	continue;
12246 
12247       class_type = G_OBJECT_CLASS_TYPE (class);
12248 
12249       for (l = class->priv->template->children; l; l = l->next)
12250 	{
12251 	  AutomaticChildClass *child_class = l->data;
12252 	  FinalizeAssertion *assertion;
12253 
12254 	  assertion = finalize_assertion_new (widget, class_type, child_class);
12255 	  list = g_slist_prepend (list, assertion);
12256 	}
12257     }
12258 
12259   return list;
12260 }
12261 #endif /* G_ENABLE_CONSISTENCY_CHECKS */
12262 
12263 static void
gtk_widget_real_destroy(GtkWidget * object)12264 gtk_widget_real_destroy (GtkWidget *object)
12265 {
12266   /* gtk_object_destroy() will already hold a refcount on object */
12267   GtkWidget *widget = GTK_WIDGET (object);
12268   GtkWidgetPrivate *priv = widget->priv;
12269 
12270   if (g_object_get_qdata (G_OBJECT (widget), quark_auto_children))
12271     {
12272       GtkWidgetClass *class;
12273       GSList *l;
12274 
12275 #ifdef G_ENABLE_CONSISTENCY_CHECKS
12276       GSList *assertions = NULL;
12277 
12278       /* Note, GTK_WIDGET_ASSERT_COMPONENTS is very useful
12279        * to catch ref counting bugs, but can only be used in
12280        * test cases which simply create and destroy a composite
12281        * widget.
12282        *
12283        * This is because some API can expose components explicitly,
12284        * and so we cannot assert that a component is expected to finalize
12285        * in a full application ecosystem.
12286        */
12287       if (g_getenv ("GTK_WIDGET_ASSERT_COMPONENTS") != NULL)
12288 	assertions = build_finalize_assertion_list (widget);
12289 #endif /* G_ENABLE_CONSISTENCY_CHECKS */
12290 
12291       /* Release references to all automated children */
12292       g_object_set_qdata (G_OBJECT (widget), quark_auto_children, NULL);
12293 
12294 #ifdef G_ENABLE_CONSISTENCY_CHECKS
12295       for (l = assertions; l; l = l->next)
12296 	{
12297 	  FinalizeAssertion *assertion = l->data;
12298 
12299 	  if (!assertion->did_finalize)
12300 	    g_critical ("Automated component '%s' of class '%s' did not finalize in gtk_widget_destroy(). "
12301 			"Current reference count is %d",
12302 			assertion->child_class->name,
12303 			g_type_name (assertion->widget_type),
12304 			assertion->object->ref_count);
12305 
12306 	  g_slice_free (FinalizeAssertion, assertion);
12307 	}
12308       g_slist_free (assertions);
12309 #endif /* G_ENABLE_CONSISTENCY_CHECKS */
12310 
12311       /* Set any automatic private data pointers to NULL */
12312       for (class = GTK_WIDGET_GET_CLASS (widget);
12313 	   GTK_IS_WIDGET_CLASS (class);
12314 	   class = g_type_class_peek_parent (class))
12315 	{
12316 	  if (!class->priv->template)
12317 	    continue;
12318 
12319 	  for (l = class->priv->template->children; l; l = l->next)
12320 	    {
12321 	      AutomaticChildClass *child_class = l->data;
12322 
12323 	      if (child_class->offset != 0)
12324 		{
12325 		  gpointer field_p;
12326 
12327 		  /* Nullify instance private data for internal children */
12328 		  field_p = G_STRUCT_MEMBER_P (widget, child_class->offset);
12329 		  (* (gpointer *) field_p) = NULL;
12330 		}
12331 	    }
12332 	}
12333     }
12334 
12335   if (priv->accessible)
12336     {
12337       gtk_accessible_set_widget (GTK_ACCESSIBLE (priv->accessible), NULL);
12338       g_object_unref (priv->accessible);
12339       priv->accessible = NULL;
12340     }
12341 
12342   /* wipe accelerator closures (keep order) */
12343   g_object_set_qdata (G_OBJECT (widget), quark_accel_path, NULL);
12344   g_object_set_qdata (G_OBJECT (widget), quark_accel_closures, NULL);
12345 
12346   /* Callers of add_mnemonic_label() should disconnect on ::destroy */
12347   g_object_set_qdata (G_OBJECT (widget), quark_mnemonic_labels, NULL);
12348 
12349   gtk_grab_remove (widget);
12350 
12351   destroy_tick_callbacks (widget);
12352 
12353   G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
12354   if (priv->style)
12355     g_object_unref (priv->style);
12356   priv->style = gtk_widget_get_default_style ();
12357   g_object_ref (priv->style);
12358   G_GNUC_END_IGNORE_DEPRECATIONS;
12359 }
12360 
12361 static void
gtk_widget_finalize(GObject * object)12362 gtk_widget_finalize (GObject *object)
12363 {
12364   GtkWidget *widget = GTK_WIDGET (object);
12365   GtkWidgetPrivate *priv = widget->priv;
12366   GList *l;
12367 
12368   gtk_grab_remove (widget);
12369 
12370   g_clear_object (&priv->style);
12371 
12372   g_free (priv->name);
12373 
12374   g_clear_object (&priv->accessible);
12375 
12376   gtk_widget_clear_path (widget);
12377 
12378   gtk_css_widget_node_widget_destroyed (GTK_CSS_WIDGET_NODE (priv->cssnode));
12379   g_object_unref (priv->cssnode);
12380 
12381   g_clear_object (&priv->context);
12382 
12383   _gtk_size_request_cache_free (&priv->requests);
12384 
12385   for (l = priv->event_controllers; l; l = l->next)
12386     {
12387       EventControllerData *data = l->data;
12388       if (data->controller)
12389         _gtk_widget_remove_controller (widget, data->controller);
12390     }
12391   g_list_free_full (priv->event_controllers, g_free);
12392   priv->event_controllers = NULL;
12393 
12394   if (g_object_is_floating (object))
12395     g_warning ("A floating object was finalized. This means that someone\n"
12396                "called g_object_unref() on an object that had only a floating\n"
12397                "reference; the initial floating reference is not owned by anyone\n"
12398                "and must be removed with g_object_ref_sink().");
12399 
12400   G_OBJECT_CLASS (gtk_widget_parent_class)->finalize (object);
12401 }
12402 
12403 /*****************************************
12404  * gtk_widget_real_map:
12405  *
12406  *   arguments:
12407  *
12408  *   results:
12409  *****************************************/
12410 
12411 static void
gtk_widget_real_map(GtkWidget * widget)12412 gtk_widget_real_map (GtkWidget *widget)
12413 {
12414   GtkWidgetPrivate *priv = widget->priv;
12415 
12416   g_assert (_gtk_widget_get_realized (widget));
12417 
12418   if (!_gtk_widget_get_mapped (widget))
12419     {
12420       gtk_widget_set_mapped (widget, TRUE);
12421 
12422       if (_gtk_widget_get_has_window (widget))
12423 	gdk_window_show (priv->window);
12424     }
12425 }
12426 
12427 /*****************************************
12428  * gtk_widget_real_unmap:
12429  *
12430  *   arguments:
12431  *
12432  *   results:
12433  *****************************************/
12434 
12435 static void
gtk_widget_real_unmap(GtkWidget * widget)12436 gtk_widget_real_unmap (GtkWidget *widget)
12437 {
12438   GtkWidgetPrivate *priv = widget->priv;
12439 
12440   if (_gtk_widget_get_mapped (widget))
12441     {
12442       gtk_widget_set_mapped (widget, FALSE);
12443 
12444       if (_gtk_widget_get_has_window (widget))
12445 	gdk_window_hide (priv->window);
12446     }
12447 }
12448 
12449 /*****************************************
12450  * gtk_widget_real_realize:
12451  *
12452  *   arguments:
12453  *
12454  *   results:
12455  *****************************************/
12456 
12457 static void
gtk_widget_real_realize(GtkWidget * widget)12458 gtk_widget_real_realize (GtkWidget *widget)
12459 {
12460   GtkWidgetPrivate *priv = widget->priv;
12461 
12462   g_assert (!_gtk_widget_get_has_window (widget));
12463 
12464   gtk_widget_set_realized (widget, TRUE);
12465   if (priv->parent)
12466     {
12467       priv->window = gtk_widget_get_parent_window (widget);
12468       g_object_ref (priv->window);
12469     }
12470 }
12471 
12472 /*****************************************
12473  * gtk_widget_real_unrealize:
12474  *
12475  *   arguments:
12476  *
12477  *   results:
12478  *****************************************/
12479 
12480 static void
gtk_widget_real_unrealize(GtkWidget * widget)12481 gtk_widget_real_unrealize (GtkWidget *widget)
12482 {
12483   GtkWidgetPrivate *priv = widget->priv;
12484 
12485   g_assert (!widget->priv->mapped);
12486 
12487    /* We must do unrealize child widget BEFORE container widget.
12488     * gdk_window_destroy() destroys specified xwindow and its sub-xwindows.
12489     * So, unrealizing container widget before its children causes the problem
12490     * (for example, gdk_ic_destroy () with destroyed window causes crash.)
12491     */
12492 
12493   if (GTK_IS_CONTAINER (widget))
12494     gtk_container_forall (GTK_CONTAINER (widget),
12495 			  (GtkCallback) gtk_widget_unrealize,
12496 			  NULL);
12497 
12498   if (_gtk_widget_get_has_window (widget))
12499     {
12500       gtk_widget_unregister_window (widget, priv->window);
12501       gdk_window_destroy (priv->window);
12502       priv->window = NULL;
12503     }
12504   else
12505     {
12506       g_object_unref (priv->window);
12507       priv->window = NULL;
12508     }
12509 
12510   gtk_selection_remove_all (widget);
12511 
12512   gtk_widget_set_realized (widget, FALSE);
12513 }
12514 
12515 static void
gtk_widget_real_adjust_size_request(GtkWidget * widget,GtkOrientation orientation,gint * minimum_size,gint * natural_size)12516 gtk_widget_real_adjust_size_request (GtkWidget      *widget,
12517                                      GtkOrientation  orientation,
12518                                      gint           *minimum_size,
12519                                      gint           *natural_size)
12520 {
12521   GtkWidgetPrivate *priv = widget->priv;
12522 
12523   if (orientation == GTK_ORIENTATION_HORIZONTAL && priv->width > 0)
12524     *minimum_size = MAX (*minimum_size, priv->width);
12525   else if (orientation == GTK_ORIENTATION_VERTICAL && priv->height > 0)
12526     *minimum_size = MAX (*minimum_size, priv->height);
12527 
12528   /* Fix it if set_size_request made natural size smaller than min size.
12529    * This would also silently fix broken widgets, but we warn about them
12530    * in gtksizerequest.c when calling their size request vfuncs.
12531    */
12532   *natural_size = MAX (*natural_size, *minimum_size);
12533 
12534   if (orientation == GTK_ORIENTATION_HORIZONTAL)
12535     {
12536       *minimum_size += priv->margin.left + priv->margin.right;
12537       *natural_size += priv->margin.left + priv->margin.right;
12538     }
12539   else
12540     {
12541       *minimum_size += priv->margin.top + priv->margin.bottom;
12542       *natural_size += priv->margin.top + priv->margin.bottom;
12543     }
12544 }
12545 
12546 static void
gtk_widget_real_adjust_baseline_request(GtkWidget * widget,gint * minimum_baseline,gint * natural_baseline)12547 gtk_widget_real_adjust_baseline_request (GtkWidget *widget,
12548 					 gint      *minimum_baseline,
12549 					 gint      *natural_baseline)
12550 {
12551   GtkWidgetPrivate *priv = widget->priv;
12552 
12553   if (priv->height >= 0)
12554     {
12555       /* No baseline support for explicitly set height */
12556       *minimum_baseline = -1;
12557       *natural_baseline = -1;
12558     }
12559   else
12560     {
12561       *minimum_baseline += priv->margin.top;
12562       *natural_baseline += priv->margin.top;
12563     }
12564 }
12565 
12566 static gboolean
is_my_window(GtkWidget * widget,GdkWindow * window)12567 is_my_window (GtkWidget *widget,
12568               GdkWindow *window)
12569 {
12570   gpointer user_data;
12571 
12572   gdk_window_get_user_data (window, &user_data);
12573   return (user_data == widget);
12574 }
12575 
12576 /*
12577  * _gtk_widget_get_device_window:
12578  * @widget: a #GtkWidget
12579  * @device: a #GdkDevice
12580  *
12581  * Returns: (nullable): the window of @widget that @device is in, or %NULL
12582  */
12583 GdkWindow *
_gtk_widget_get_device_window(GtkWidget * widget,GdkDevice * device)12584 _gtk_widget_get_device_window (GtkWidget *widget,
12585                                GdkDevice *device)
12586 {
12587   GdkWindow *window;
12588 
12589   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
12590   g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
12591 
12592   if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
12593     return NULL;
12594 
12595   window = gdk_device_get_last_event_window (device);
12596   if (window && is_my_window (widget, window))
12597     return window;
12598   else
12599     return NULL;
12600 }
12601 
12602 static void
list_devices(GtkWidget * widget,GdkDeviceManager * device_manager,GdkDeviceType device_type,GList ** result)12603 list_devices (GtkWidget        *widget,
12604               GdkDeviceManager *device_manager,
12605               GdkDeviceType     device_type,
12606               GList           **result)
12607 {
12608   GList *devices;
12609   GList *l;
12610 
12611   G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
12612   devices = gdk_device_manager_list_devices (device_manager, device_type);
12613   G_GNUC_END_IGNORE_DEPRECATIONS;
12614 
12615   for (l = devices; l; l = l->next)
12616     {
12617       GdkDevice *device = l->data;
12618       if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
12619         {
12620           GdkWindow *window = gdk_device_get_last_event_window (device);
12621           if (window && is_my_window (widget, window))
12622             *result = g_list_prepend (*result, device);
12623         }
12624     }
12625   g_list_free (devices);
12626 }
12627 
12628 /*
12629  * _gtk_widget_list_devices:
12630  * @widget: a #GtkWidget
12631  *
12632  * Returns the list of #GdkDevices that is currently on top
12633  * of any window belonging to @widget.
12634  * Free the list with g_list_free(), the elements are owned
12635  * by GTK+ and must not be freed.
12636  */
12637 GList *
_gtk_widget_list_devices(GtkWidget * widget)12638 _gtk_widget_list_devices (GtkWidget *widget)
12639 {
12640   GdkDisplay *display;
12641   GdkDeviceManager *device_manager;
12642   GList *result = NULL;
12643 
12644   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
12645 
12646   if (!_gtk_widget_get_mapped (widget))
12647     return NULL;
12648 
12649   G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
12650   display = gtk_widget_get_display (widget);
12651   device_manager = gdk_display_get_device_manager (display);
12652   G_GNUC_END_IGNORE_DEPRECATIONS;
12653 
12654   list_devices (widget, device_manager, GDK_DEVICE_TYPE_MASTER, &result);
12655   /* Rare, but we can get events for grabbed slave devices */
12656   list_devices (widget, device_manager, GDK_DEVICE_TYPE_SLAVE, &result);
12657 
12658   return result;
12659 }
12660 
12661 static void
synth_crossing(GtkWidget * widget,GdkEventType type,GdkWindow * window,GdkDevice * device,GdkCrossingMode mode,GdkNotifyType detail)12662 synth_crossing (GtkWidget       *widget,
12663                 GdkEventType     type,
12664                 GdkWindow       *window,
12665                 GdkDevice       *device,
12666                 GdkCrossingMode  mode,
12667                 GdkNotifyType    detail)
12668 {
12669   GdkEvent *event;
12670 
12671   event = gdk_event_new (type);
12672 
12673   event->crossing.window = g_object_ref (window);
12674   event->crossing.send_event = TRUE;
12675   event->crossing.subwindow = g_object_ref (window);
12676   event->crossing.time = GDK_CURRENT_TIME;
12677   gdk_device_get_position_double (device,
12678                                   NULL,
12679                                   &event->crossing.x_root,
12680                                   &event->crossing.y_root);
12681   gdk_window_get_device_position_double (window,
12682                                          device,
12683                                          &event->crossing.x,
12684                                          &event->crossing.y,
12685                                          NULL);
12686   event->crossing.mode = mode;
12687   event->crossing.detail = detail;
12688   event->crossing.focus = FALSE;
12689   event->crossing.state = 0;
12690   gdk_event_set_device (event, device);
12691 
12692   if (!widget)
12693     widget = gtk_get_event_widget (event);
12694 
12695   if (widget)
12696     gtk_widget_event_internal (widget, event);
12697 
12698   gdk_event_free (event);
12699 }
12700 
12701 /*
12702  * _gtk_widget_synthesize_crossing:
12703  * @from: the #GtkWidget the virtual pointer is leaving.
12704  * @to: the #GtkWidget the virtual pointer is moving to.
12705  * @mode: the #GdkCrossingMode to place on the synthesized events.
12706  *
12707  * Generate crossing event(s) on widget state (sensitivity) or GTK+ grab change.
12708  *
12709  * The real pointer window is the window that most recently received an enter notify
12710  * event.  Windows that don’t select for crossing events can’t become the real
12711  * pointer window.  The real pointer widget that owns the real pointer window.  The
12712  * effective pointer window is the same as the real pointer window unless the real
12713  * pointer widget is either insensitive or there is a grab on a widget that is not
12714  * an ancestor of the real pointer widget (in which case the effective pointer
12715  * window should be the root window).
12716  *
12717  * When the effective pointer window is the same as the real pointer window, we
12718  * receive crossing events from the windowing system.  When the effective pointer
12719  * window changes to become different from the real pointer window we synthesize
12720  * crossing events, attempting to follow X protocol rules:
12721  *
12722  * When the root window becomes the effective pointer window:
12723  *   - leave notify on real pointer window, detail Ancestor
12724  *   - leave notify on all of its ancestors, detail Virtual
12725  *   - enter notify on root window, detail Inferior
12726  *
12727  * When the root window ceases to be the effective pointer window:
12728  *   - leave notify on root window, detail Inferior
12729  *   - enter notify on all ancestors of real pointer window, detail Virtual
12730  *   - enter notify on real pointer window, detail Ancestor
12731  */
12732 void
_gtk_widget_synthesize_crossing(GtkWidget * from,GtkWidget * to,GdkDevice * device,GdkCrossingMode mode)12733 _gtk_widget_synthesize_crossing (GtkWidget       *from,
12734 				 GtkWidget       *to,
12735                                  GdkDevice       *device,
12736 				 GdkCrossingMode  mode)
12737 {
12738   GdkWindow *from_window = NULL, *to_window = NULL;
12739 
12740   g_return_if_fail (from != NULL || to != NULL);
12741 
12742   if (from != NULL)
12743     {
12744       from_window = _gtk_widget_get_device_window (from, device);
12745 
12746       if (!from_window)
12747         from_window = from->priv->window;
12748     }
12749 
12750   if (to != NULL)
12751     {
12752       to_window = _gtk_widget_get_device_window (to, device);
12753 
12754       if (!to_window)
12755         to_window = to->priv->window;
12756     }
12757 
12758   if (from_window == NULL && to_window == NULL)
12759     ;
12760   else if (from_window != NULL && to_window == NULL)
12761     {
12762       GList *from_ancestors = NULL, *list;
12763       GdkWindow *from_ancestor = from_window;
12764 
12765       while (from_ancestor != NULL)
12766 	{
12767 	  from_ancestor = gdk_window_get_effective_parent (from_ancestor);
12768           if (from_ancestor == NULL)
12769             break;
12770           from_ancestors = g_list_prepend (from_ancestors, from_ancestor);
12771 	}
12772 
12773       synth_crossing (from, GDK_LEAVE_NOTIFY, from_window,
12774 		      device, mode, GDK_NOTIFY_ANCESTOR);
12775       for (list = g_list_last (from_ancestors); list; list = list->prev)
12776 	{
12777 	  synth_crossing (NULL, GDK_LEAVE_NOTIFY, (GdkWindow *) list->data,
12778 			  device, mode, GDK_NOTIFY_VIRTUAL);
12779 	}
12780 
12781       /* XXX: enter/inferior on root window? */
12782 
12783       g_list_free (from_ancestors);
12784     }
12785   else if (from_window == NULL && to_window != NULL)
12786     {
12787       GList *to_ancestors = NULL, *list;
12788       GdkWindow *to_ancestor = to_window;
12789 
12790       while (to_ancestor != NULL)
12791 	{
12792 	  to_ancestor = gdk_window_get_effective_parent (to_ancestor);
12793 	  if (to_ancestor == NULL)
12794             break;
12795           to_ancestors = g_list_prepend (to_ancestors, to_ancestor);
12796         }
12797 
12798       /* XXX: leave/inferior on root window? */
12799 
12800       for (list = to_ancestors; list; list = list->next)
12801 	{
12802 	  synth_crossing (NULL, GDK_ENTER_NOTIFY, (GdkWindow *) list->data,
12803 			  device, mode, GDK_NOTIFY_VIRTUAL);
12804 	}
12805       synth_crossing (to, GDK_ENTER_NOTIFY, to_window,
12806 		      device, mode, GDK_NOTIFY_ANCESTOR);
12807 
12808       g_list_free (to_ancestors);
12809     }
12810   else if (from_window == to_window)
12811     ;
12812   else
12813     {
12814       GList *from_ancestors = NULL, *to_ancestors = NULL, *list;
12815       GdkWindow *from_ancestor = from_window, *to_ancestor = to_window;
12816 
12817       while (from_ancestor != NULL || to_ancestor != NULL)
12818 	{
12819 	  if (from_ancestor != NULL)
12820 	    {
12821 	      from_ancestor = gdk_window_get_effective_parent (from_ancestor);
12822 	      if (from_ancestor == to_window)
12823 		break;
12824               if (from_ancestor)
12825 	        from_ancestors = g_list_prepend (from_ancestors, from_ancestor);
12826 	    }
12827 	  if (to_ancestor != NULL)
12828 	    {
12829 	      to_ancestor = gdk_window_get_effective_parent (to_ancestor);
12830 	      if (to_ancestor == from_window)
12831 		break;
12832               if (to_ancestor)
12833 	        to_ancestors = g_list_prepend (to_ancestors, to_ancestor);
12834 	    }
12835 	}
12836       if (to_ancestor == from_window)
12837 	{
12838 	  if (mode != GDK_CROSSING_GTK_UNGRAB)
12839 	    synth_crossing (from, GDK_LEAVE_NOTIFY, from_window,
12840 			    device, mode, GDK_NOTIFY_INFERIOR);
12841 	  for (list = to_ancestors; list; list = list->next)
12842 	    synth_crossing (NULL, GDK_ENTER_NOTIFY, (GdkWindow *) list->data,
12843 			    device, mode, GDK_NOTIFY_VIRTUAL);
12844 	  synth_crossing (to, GDK_ENTER_NOTIFY, to_window,
12845 			  device, mode, GDK_NOTIFY_ANCESTOR);
12846 	}
12847       else if (from_ancestor == to_window)
12848 	{
12849 	  synth_crossing (from, GDK_LEAVE_NOTIFY, from_window,
12850 			  device, mode, GDK_NOTIFY_ANCESTOR);
12851 	  for (list = g_list_last (from_ancestors); list; list = list->prev)
12852 	    {
12853 	      synth_crossing (NULL, GDK_LEAVE_NOTIFY, (GdkWindow *) list->data,
12854 			      device, mode, GDK_NOTIFY_VIRTUAL);
12855 	    }
12856 	  if (mode != GDK_CROSSING_GTK_GRAB)
12857 	    synth_crossing (to, GDK_ENTER_NOTIFY, to_window,
12858 			    device, mode, GDK_NOTIFY_INFERIOR);
12859 	}
12860       else
12861 	{
12862 	  while (from_ancestors != NULL && to_ancestors != NULL
12863 		 && from_ancestors->data == to_ancestors->data)
12864 	    {
12865 	      from_ancestors = g_list_delete_link (from_ancestors,
12866 						   from_ancestors);
12867 	      to_ancestors = g_list_delete_link (to_ancestors, to_ancestors);
12868 	    }
12869 
12870 	  synth_crossing (from, GDK_LEAVE_NOTIFY, from_window,
12871 			  device, mode, GDK_NOTIFY_NONLINEAR);
12872 
12873 	  for (list = g_list_last (from_ancestors); list; list = list->prev)
12874 	    {
12875 	      synth_crossing (NULL, GDK_LEAVE_NOTIFY, (GdkWindow *) list->data,
12876 			      device, mode, GDK_NOTIFY_NONLINEAR_VIRTUAL);
12877 	    }
12878 	  for (list = to_ancestors; list; list = list->next)
12879 	    {
12880 	      synth_crossing (NULL, GDK_ENTER_NOTIFY, (GdkWindow *) list->data,
12881 			      device, mode, GDK_NOTIFY_NONLINEAR_VIRTUAL);
12882 	    }
12883 	  synth_crossing (to, GDK_ENTER_NOTIFY, to_window,
12884 			  device, mode, GDK_NOTIFY_NONLINEAR);
12885 	}
12886       g_list_free (from_ancestors);
12887       g_list_free (to_ancestors);
12888     }
12889 }
12890 
12891 static void
gtk_widget_propagate_state(GtkWidget * widget,GtkStateData * data)12892 gtk_widget_propagate_state (GtkWidget    *widget,
12893                             GtkStateData *data)
12894 {
12895   GtkWidgetPrivate *priv = widget->priv;
12896   GtkStateFlags new_flags, old_flags = priv->state_flags;
12897   GtkStateType old_state;
12898   gint new_scale_factor = gtk_widget_get_scale_factor (widget);
12899 
12900   G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
12901   old_state = gtk_widget_get_state (widget);
12902   G_GNUC_END_IGNORE_DEPRECATIONS;
12903 
12904   priv->state_flags |= data->flags_to_set;
12905   priv->state_flags &= ~(data->flags_to_unset);
12906 
12907   /* make insensitivity unoverridable */
12908   if (!priv->sensitive)
12909     priv->state_flags |= GTK_STATE_FLAG_INSENSITIVE;
12910 
12911   if (gtk_widget_is_focus (widget) && !gtk_widget_is_sensitive (widget))
12912     {
12913       GtkWidget *window;
12914 
12915       window = _gtk_widget_get_toplevel (widget);
12916 
12917       if (window && _gtk_widget_is_toplevel (window))
12918         gtk_window_set_focus (GTK_WINDOW (window), NULL);
12919     }
12920 
12921   new_flags = priv->state_flags;
12922 
12923   if (data->old_scale_factor != new_scale_factor)
12924     _gtk_widget_scale_changed (widget);
12925 
12926   if (old_flags != new_flags)
12927     {
12928       g_object_ref (widget);
12929 
12930       if (!gtk_widget_is_sensitive (widget) && gtk_widget_has_grab (widget))
12931         gtk_grab_remove (widget);
12932 
12933       gtk_style_context_set_state (_gtk_widget_get_style_context (widget), new_flags);
12934 
12935       g_signal_emit (widget, widget_signals[STATE_CHANGED], 0, old_state);
12936       g_signal_emit (widget, widget_signals[STATE_FLAGS_CHANGED], 0, old_flags);
12937 
12938       if (!priv->shadowed &&
12939           (new_flags & GTK_STATE_FLAG_INSENSITIVE) != (old_flags & GTK_STATE_FLAG_INSENSITIVE))
12940         {
12941           GList *event_windows = NULL;
12942           GList *devices, *d;
12943 
12944           devices = _gtk_widget_list_devices (widget);
12945 
12946           for (d = devices; d; d = d->next)
12947             {
12948               GdkWindow *window;
12949               GdkDevice *device;
12950 
12951               device = d->data;
12952               window = _gtk_widget_get_device_window (widget, device);
12953 
12954               /* Do not propagate more than once to the
12955                * same window if non-multidevice aware.
12956                */
12957               if (!gdk_window_get_support_multidevice (window) &&
12958                   g_list_find (event_windows, window))
12959                 continue;
12960 
12961               if (!gtk_widget_is_sensitive (widget))
12962                 _gtk_widget_synthesize_crossing (widget, NULL, d->data,
12963                                                  GDK_CROSSING_STATE_CHANGED);
12964               else
12965                 _gtk_widget_synthesize_crossing (NULL, widget, d->data,
12966                                                  GDK_CROSSING_STATE_CHANGED);
12967 
12968               event_windows = g_list_prepend (event_windows, window);
12969             }
12970 
12971           g_list_free (event_windows);
12972           g_list_free (devices);
12973         }
12974 
12975       if (!gtk_widget_is_sensitive (widget))
12976         gtk_widget_reset_controllers (widget);
12977 
12978       if (GTK_IS_CONTAINER (widget))
12979         {
12980           GtkStateData child_data;
12981 
12982           /* Make sure to only propagate the right states further */
12983           child_data.old_scale_factor = new_scale_factor;
12984           child_data.flags_to_set = data->flags_to_set & GTK_STATE_FLAGS_DO_PROPAGATE;
12985           child_data.flags_to_unset = data->flags_to_unset & GTK_STATE_FLAGS_DO_PROPAGATE;
12986 
12987           gtk_container_forall (GTK_CONTAINER (widget),
12988                                 (GtkCallback) gtk_widget_propagate_state,
12989                                 &child_data);
12990         }
12991 
12992       g_object_unref (widget);
12993     }
12994 }
12995 
12996 /**
12997  * gtk_widget_shape_combine_region:
12998  * @widget: a #GtkWidget
12999  * @region: (allow-none): shape to be added, or %NULL to remove an existing shape
13000  *
13001  * Sets a shape for this widget’s GDK window. This allows for
13002  * transparent windows etc., see gdk_window_shape_combine_region()
13003  * for more information.
13004  *
13005  * Since: 3.0
13006  **/
13007 void
gtk_widget_shape_combine_region(GtkWidget * widget,cairo_region_t * region)13008 gtk_widget_shape_combine_region (GtkWidget *widget,
13009                                  cairo_region_t *region)
13010 {
13011   GtkWidgetPrivate *priv;
13012 
13013   g_return_if_fail (GTK_IS_WIDGET (widget));
13014   /*  set_shape doesn't work on widgets without GDK window */
13015   g_return_if_fail (_gtk_widget_get_has_window (widget));
13016 
13017   priv = widget->priv;
13018 
13019   if (region == NULL)
13020     {
13021       priv->has_shape_mask = FALSE;
13022 
13023       if (priv->window)
13024 	gdk_window_shape_combine_region (priv->window, NULL, 0, 0);
13025 
13026       g_object_set_qdata (G_OBJECT (widget), quark_shape_info, NULL);
13027     }
13028   else
13029     {
13030       priv->has_shape_mask = TRUE;
13031 
13032       g_object_set_qdata_full (G_OBJECT (widget), quark_shape_info,
13033                                cairo_region_copy (region),
13034 			       (GDestroyNotify) cairo_region_destroy);
13035 
13036       /* set shape if widget has a GDK window already.
13037        * otherwise the shape is scheduled to be set by gtk_widget_realize().
13038        */
13039       if (priv->window)
13040 	gdk_window_shape_combine_region (priv->window, region, 0, 0);
13041     }
13042 }
13043 
13044 static void
gtk_widget_update_input_shape(GtkWidget * widget)13045 gtk_widget_update_input_shape (GtkWidget *widget)
13046 {
13047   GtkWidgetPrivate *priv = widget->priv;
13048 
13049   /* set shape if widget has a GDK window already.
13050    * otherwise the shape is scheduled to be set by gtk_widget_realize().
13051    */
13052   if (priv->window)
13053     {
13054       cairo_region_t *region;
13055       cairo_region_t *csd_region;
13056       cairo_region_t *app_region;
13057       gboolean free_region;
13058 
13059       app_region = g_object_get_qdata (G_OBJECT (widget), quark_input_shape_info);
13060       csd_region = g_object_get_data (G_OBJECT (widget), "csd-region");
13061 
13062       free_region = FALSE;
13063 
13064       if (app_region && csd_region)
13065         {
13066           free_region = TRUE;
13067           region = cairo_region_copy (app_region);
13068           cairo_region_intersect (region, csd_region);
13069         }
13070       else if (app_region)
13071         region = app_region;
13072       else if (csd_region)
13073         region = csd_region;
13074       else
13075         region = NULL;
13076 
13077       gdk_window_input_shape_combine_region (priv->window, region, 0, 0);
13078 
13079       if (free_region)
13080         cairo_region_destroy (region);
13081     }
13082 }
13083 
13084 void
gtk_widget_set_csd_input_shape(GtkWidget * widget,const cairo_region_t * region)13085 gtk_widget_set_csd_input_shape (GtkWidget            *widget,
13086                                 const cairo_region_t *region)
13087 {
13088   if (region == NULL)
13089     g_object_set_data (G_OBJECT (widget), "csd-region", NULL);
13090   else
13091     g_object_set_data_full (G_OBJECT (widget), "csd-region",
13092                             cairo_region_copy (region),
13093                             (GDestroyNotify) cairo_region_destroy);
13094   gtk_widget_update_input_shape (widget);
13095 }
13096 
13097 /**
13098  * gtk_widget_input_shape_combine_region:
13099  * @widget: a #GtkWidget
13100  * @region: (allow-none): shape to be added, or %NULL to remove an existing shape
13101  *
13102  * Sets an input shape for this widget’s GDK window. This allows for
13103  * windows which react to mouse click in a nonrectangular region, see
13104  * gdk_window_input_shape_combine_region() for more information.
13105  *
13106  * Since: 3.0
13107  **/
13108 void
gtk_widget_input_shape_combine_region(GtkWidget * widget,cairo_region_t * region)13109 gtk_widget_input_shape_combine_region (GtkWidget      *widget,
13110                                        cairo_region_t *region)
13111 {
13112   g_return_if_fail (GTK_IS_WIDGET (widget));
13113   /*  set_shape doesn't work on widgets without GDK window */
13114   g_return_if_fail (_gtk_widget_get_has_window (widget));
13115 
13116   if (region == NULL)
13117     g_object_set_qdata (G_OBJECT (widget), quark_input_shape_info, NULL);
13118   else
13119     g_object_set_qdata_full (G_OBJECT (widget), quark_input_shape_info,
13120                              cairo_region_copy (region),
13121                              (GDestroyNotify) cairo_region_destroy);
13122   gtk_widget_update_input_shape (widget);
13123 }
13124 
13125 
13126 /* style properties
13127  */
13128 
13129 /**
13130  * gtk_widget_class_install_style_property_parser: (skip)
13131  * @klass: a #GtkWidgetClass
13132  * @pspec: the #GParamSpec for the style property
13133  * @parser: the parser for the style property
13134  *
13135  * Installs a style property on a widget class.
13136  **/
13137 void
gtk_widget_class_install_style_property_parser(GtkWidgetClass * klass,GParamSpec * pspec,GtkRcPropertyParser parser)13138 gtk_widget_class_install_style_property_parser (GtkWidgetClass     *klass,
13139 						GParamSpec         *pspec,
13140 						GtkRcPropertyParser parser)
13141 {
13142   g_return_if_fail (GTK_IS_WIDGET_CLASS (klass));
13143   g_return_if_fail (G_IS_PARAM_SPEC (pspec));
13144   g_return_if_fail (pspec->flags & G_PARAM_READABLE);
13145   g_return_if_fail (!(pspec->flags & (G_PARAM_CONSTRUCT_ONLY | G_PARAM_CONSTRUCT)));
13146 
13147   if (g_param_spec_pool_lookup (style_property_spec_pool, pspec->name, G_OBJECT_CLASS_TYPE (klass), FALSE))
13148     {
13149       g_warning (G_STRLOC ": class '%s' already contains a style property named '%s'",
13150 		 G_OBJECT_CLASS_NAME (klass),
13151 		 pspec->name);
13152       return;
13153     }
13154 
13155   g_param_spec_ref_sink (pspec);
13156   g_param_spec_set_qdata (pspec, quark_property_parser, (gpointer) parser);
13157   g_param_spec_pool_insert (style_property_spec_pool, pspec, G_OBJECT_CLASS_TYPE (klass));
13158 }
13159 
13160 /**
13161  * gtk_widget_class_install_style_property:
13162  * @klass: a #GtkWidgetClass
13163  * @pspec: the #GParamSpec for the property
13164  *
13165  * Installs a style property on a widget class. The parser for the
13166  * style property is determined by the value type of @pspec.
13167  **/
13168 void
gtk_widget_class_install_style_property(GtkWidgetClass * klass,GParamSpec * pspec)13169 gtk_widget_class_install_style_property (GtkWidgetClass *klass,
13170 					 GParamSpec     *pspec)
13171 {
13172   GtkRcPropertyParser parser;
13173 
13174   g_return_if_fail (GTK_IS_WIDGET_CLASS (klass));
13175   g_return_if_fail (G_IS_PARAM_SPEC (pspec));
13176 
13177   parser = _gtk_rc_property_parser_from_type (G_PARAM_SPEC_VALUE_TYPE (pspec));
13178 
13179   gtk_widget_class_install_style_property_parser (klass, pspec, parser);
13180 }
13181 
13182 /**
13183  * gtk_widget_class_find_style_property:
13184  * @klass: a #GtkWidgetClass
13185  * @property_name: the name of the style property to find
13186  *
13187  * Finds a style property of a widget class by name.
13188  *
13189  * Returns: (transfer none): the #GParamSpec of the style property or
13190  *   %NULL if @class has no style property with that name.
13191  *
13192  * Since: 2.2
13193  */
13194 GParamSpec*
gtk_widget_class_find_style_property(GtkWidgetClass * klass,const gchar * property_name)13195 gtk_widget_class_find_style_property (GtkWidgetClass *klass,
13196 				      const gchar    *property_name)
13197 {
13198   g_return_val_if_fail (property_name != NULL, NULL);
13199 
13200   return g_param_spec_pool_lookup (style_property_spec_pool,
13201 				   property_name,
13202 				   G_OBJECT_CLASS_TYPE (klass),
13203 				   TRUE);
13204 }
13205 
13206 /**
13207  * gtk_widget_class_list_style_properties:
13208  * @klass: a #GtkWidgetClass
13209  * @n_properties: (out): location to return the number of style properties found
13210  *
13211  * Returns all style properties of a widget class.
13212  *
13213  * Returns: (array length=n_properties) (transfer container): a
13214  *     newly allocated array of #GParamSpec*. The array must be
13215  *     freed with g_free().
13216  *
13217  * Since: 2.2
13218  */
13219 GParamSpec**
gtk_widget_class_list_style_properties(GtkWidgetClass * klass,guint * n_properties)13220 gtk_widget_class_list_style_properties (GtkWidgetClass *klass,
13221 					guint          *n_properties)
13222 {
13223   GParamSpec **pspecs;
13224   guint n;
13225 
13226   pspecs = g_param_spec_pool_list (style_property_spec_pool,
13227 				   G_OBJECT_CLASS_TYPE (klass),
13228 				   &n);
13229   if (n_properties)
13230     *n_properties = n;
13231 
13232   return pspecs;
13233 }
13234 
13235 /**
13236  * gtk_widget_style_get_property:
13237  * @widget: a #GtkWidget
13238  * @property_name: the name of a style property
13239  * @value: location to return the property value
13240  *
13241  * Gets the value of a style property of @widget.
13242  */
13243 void
gtk_widget_style_get_property(GtkWidget * widget,const gchar * property_name,GValue * value)13244 gtk_widget_style_get_property (GtkWidget   *widget,
13245 			       const gchar *property_name,
13246 			       GValue      *value)
13247 {
13248   GParamSpec *pspec;
13249 
13250   g_return_if_fail (GTK_IS_WIDGET (widget));
13251   g_return_if_fail (property_name != NULL);
13252   g_return_if_fail (G_IS_VALUE (value));
13253 
13254   g_object_ref (widget);
13255   pspec = g_param_spec_pool_lookup (style_property_spec_pool,
13256 				    property_name,
13257 				    G_OBJECT_TYPE (widget),
13258 				    TRUE);
13259   if (!pspec)
13260     g_warning ("%s: widget class '%s' has no property named '%s'",
13261 	       G_STRLOC,
13262 	       G_OBJECT_TYPE_NAME (widget),
13263 	       property_name);
13264   else
13265     {
13266       GtkStyleContext *context;
13267       const GValue *peek_value;
13268 
13269       context = _gtk_widget_get_style_context (widget);
13270 
13271       peek_value = _gtk_style_context_peek_style_property (context,
13272                                                            G_OBJECT_TYPE (widget),
13273                                                            pspec);
13274 
13275       /* auto-conversion of the caller's value type
13276        */
13277       if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec))
13278 	g_value_copy (peek_value, value);
13279       else if (g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec), G_VALUE_TYPE (value)))
13280 	g_value_transform (peek_value, value);
13281       else
13282 	g_warning ("can't retrieve style property '%s' of type '%s' as value of type '%s'",
13283 		   pspec->name,
13284 		   g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
13285 		   G_VALUE_TYPE_NAME (value));
13286     }
13287   g_object_unref (widget);
13288 }
13289 
13290 /**
13291  * gtk_widget_style_get_valist:
13292  * @widget: a #GtkWidget
13293  * @first_property_name: the name of the first property to get
13294  * @var_args: a va_list of pairs of property names and
13295  *     locations to return the property values, starting with the location
13296  *     for @first_property_name.
13297  *
13298  * Non-vararg variant of gtk_widget_style_get(). Used primarily by language
13299  * bindings.
13300  */
13301 void
gtk_widget_style_get_valist(GtkWidget * widget,const gchar * first_property_name,va_list var_args)13302 gtk_widget_style_get_valist (GtkWidget   *widget,
13303 			     const gchar *first_property_name,
13304 			     va_list      var_args)
13305 {
13306   GtkStyleContext *context;
13307   const gchar *name;
13308 
13309   g_return_if_fail (GTK_IS_WIDGET (widget));
13310 
13311   g_object_ref (widget);
13312   context = _gtk_widget_get_style_context (widget);
13313 
13314   name = first_property_name;
13315   while (name)
13316     {
13317       const GValue *peek_value;
13318       GParamSpec *pspec;
13319       gchar *error;
13320 
13321       pspec = g_param_spec_pool_lookup (style_property_spec_pool,
13322 					name,
13323 					G_OBJECT_TYPE (widget),
13324 					TRUE);
13325       if (!pspec)
13326 	{
13327 	  g_warning ("%s: widget class '%s' has no property named '%s'",
13328 		     G_STRLOC,
13329 		     G_OBJECT_TYPE_NAME (widget),
13330 		     name);
13331 	  break;
13332 	}
13333       /* style pspecs are always readable so we can spare that check here */
13334 
13335       peek_value = _gtk_style_context_peek_style_property (context,
13336                                                            G_OBJECT_TYPE (widget),
13337                                                            pspec);
13338 
13339       G_VALUE_LCOPY (peek_value, var_args, 0, &error);
13340       if (error)
13341 	{
13342 	  g_warning ("%s: %s", G_STRLOC, error);
13343 	  g_free (error);
13344 	  break;
13345 	}
13346 
13347       name = va_arg (var_args, gchar*);
13348     }
13349 
13350   g_object_unref (widget);
13351 }
13352 
13353 /**
13354  * gtk_widget_style_get:
13355  * @widget: a #GtkWidget
13356  * @first_property_name: the name of the first property to get
13357  * @...: pairs of property names and locations to return the
13358  *     property values, starting with the location for
13359  *     @first_property_name, terminated by %NULL.
13360  *
13361  * Gets the values of a multiple style properties of @widget.
13362  */
13363 void
gtk_widget_style_get(GtkWidget * widget,const gchar * first_property_name,...)13364 gtk_widget_style_get (GtkWidget   *widget,
13365 		      const gchar *first_property_name,
13366 		      ...)
13367 {
13368   va_list var_args;
13369 
13370   g_return_if_fail (GTK_IS_WIDGET (widget));
13371 
13372   va_start (var_args, first_property_name);
13373   gtk_widget_style_get_valist (widget, first_property_name, var_args);
13374   va_end (var_args);
13375 }
13376 
13377 /**
13378  * gtk_requisition_new:
13379  *
13380  * Allocates a new #GtkRequisition-struct and initializes its elements to zero.
13381  *
13382  * Returns: a new empty #GtkRequisition. The newly allocated #GtkRequisition should
13383  *   be freed with gtk_requisition_free().
13384  *
13385  * Since: 3.0
13386  */
13387 GtkRequisition *
gtk_requisition_new(void)13388 gtk_requisition_new (void)
13389 {
13390   return g_slice_new0 (GtkRequisition);
13391 }
13392 
13393 /**
13394  * gtk_requisition_copy:
13395  * @requisition: a #GtkRequisition
13396  *
13397  * Copies a #GtkRequisition.
13398  *
13399  * Returns: a copy of @requisition
13400  **/
13401 GtkRequisition *
gtk_requisition_copy(const GtkRequisition * requisition)13402 gtk_requisition_copy (const GtkRequisition *requisition)
13403 {
13404   return g_slice_dup (GtkRequisition, requisition);
13405 }
13406 
13407 /**
13408  * gtk_requisition_free:
13409  * @requisition: a #GtkRequisition
13410  *
13411  * Frees a #GtkRequisition.
13412  **/
13413 void
gtk_requisition_free(GtkRequisition * requisition)13414 gtk_requisition_free (GtkRequisition *requisition)
13415 {
13416   g_slice_free (GtkRequisition, requisition);
13417 }
13418 
G_DEFINE_BOXED_TYPE(GtkRequisition,gtk_requisition,gtk_requisition_copy,gtk_requisition_free)13419 G_DEFINE_BOXED_TYPE (GtkRequisition, gtk_requisition,
13420                      gtk_requisition_copy,
13421                      gtk_requisition_free)
13422 
13423 /**
13424  * gtk_widget_class_set_accessible_type:
13425  * @widget_class: class to set the accessible type for
13426  * @type: The object type that implements the accessible for @widget_class
13427  *
13428  * Sets the type to be used for creating accessibles for widgets of
13429  * @widget_class. The given @type must be a subtype of the type used for
13430  * accessibles of the parent class.
13431  *
13432  * This function should only be called from class init functions of widgets.
13433  *
13434  * Since: 3.2
13435  **/
13436 void
13437 gtk_widget_class_set_accessible_type (GtkWidgetClass *widget_class,
13438                                       GType           type)
13439 {
13440   GtkWidgetClassPrivate *priv;
13441 
13442   g_return_if_fail (GTK_IS_WIDGET_CLASS (widget_class));
13443   g_return_if_fail (g_type_is_a (type, widget_class->priv->accessible_type));
13444 
13445   priv = widget_class->priv;
13446 
13447   priv->accessible_type = type;
13448   /* reset this - honoring the type's role is better. */
13449   priv->accessible_role = ATK_ROLE_INVALID;
13450 }
13451 
13452 /**
13453  * gtk_widget_class_set_accessible_role:
13454  * @widget_class: class to set the accessible role for
13455  * @role: The role to use for accessibles created for @widget_class
13456  *
13457  * Sets the default #AtkRole to be set on accessibles created for
13458  * widgets of @widget_class. Accessibles may decide to not honor this
13459  * setting if their role reporting is more refined. Calls to
13460  * gtk_widget_class_set_accessible_type() will reset this value.
13461  *
13462  * In cases where you want more fine-grained control over the role of
13463  * accessibles created for @widget_class, you should provide your own
13464  * accessible type and use gtk_widget_class_set_accessible_type()
13465  * instead.
13466  *
13467  * If @role is #ATK_ROLE_INVALID, the default role will not be changed
13468  * and the accessible’s default role will be used instead.
13469  *
13470  * This function should only be called from class init functions of widgets.
13471  *
13472  * Since: 3.2
13473  **/
13474 void
gtk_widget_class_set_accessible_role(GtkWidgetClass * widget_class,AtkRole role)13475 gtk_widget_class_set_accessible_role (GtkWidgetClass *widget_class,
13476                                       AtkRole         role)
13477 {
13478   GtkWidgetClassPrivate *priv;
13479 
13480   g_return_if_fail (GTK_IS_WIDGET_CLASS (widget_class));
13481 
13482   priv = widget_class->priv;
13483 
13484   priv->accessible_role = role;
13485 }
13486 
13487 /**
13488  * _gtk_widget_peek_accessible:
13489  * @widget: a #GtkWidget
13490  *
13491  * Gets the accessible for @widget, if it has been created yet.
13492  * Otherwise, this function returns %NULL. If the @widget’s implementation
13493  * does not use the default way to create accessibles, %NULL will always be
13494  * returned.
13495  *
13496  * Returns: (nullable): the accessible for @widget or %NULL if none has been
13497  *     created yet.
13498  **/
13499 AtkObject *
_gtk_widget_peek_accessible(GtkWidget * widget)13500 _gtk_widget_peek_accessible (GtkWidget *widget)
13501 {
13502   return widget->priv->accessible;
13503 }
13504 
13505 /**
13506  * gtk_widget_get_accessible:
13507  * @widget: a #GtkWidget
13508  *
13509  * Returns the accessible object that describes the widget to an
13510  * assistive technology.
13511  *
13512  * If accessibility support is not available, this #AtkObject
13513  * instance may be a no-op. Likewise, if no class-specific #AtkObject
13514  * implementation is available for the widget instance in question,
13515  * it will inherit an #AtkObject implementation from the first ancestor
13516  * class for which such an implementation is defined.
13517  *
13518  * The documentation of the
13519  * [ATK](http://developer.gnome.org/atk/stable/)
13520  * library contains more information about accessible objects and their uses.
13521  *
13522  * Returns: (transfer none): the #AtkObject associated with @widget
13523  */
13524 AtkObject*
gtk_widget_get_accessible(GtkWidget * widget)13525 gtk_widget_get_accessible (GtkWidget *widget)
13526 {
13527   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
13528 
13529   return GTK_WIDGET_GET_CLASS (widget)->get_accessible (widget);
13530 }
13531 
13532 static AtkObject*
gtk_widget_real_get_accessible(GtkWidget * widget)13533 gtk_widget_real_get_accessible (GtkWidget *widget)
13534 {
13535   AtkObject* accessible;
13536 
13537   accessible = widget->priv->accessible;
13538 
13539   if (!accessible)
13540     {
13541       GtkWidgetClass *widget_class;
13542       GtkWidgetClassPrivate *priv;
13543       AtkObjectFactory *factory;
13544       AtkRegistry *default_registry;
13545 
13546       widget_class = GTK_WIDGET_GET_CLASS (widget);
13547       priv = widget_class->priv;
13548 
13549       if (priv->accessible_type == GTK_TYPE_ACCESSIBLE)
13550         {
13551           default_registry = atk_get_default_registry ();
13552           factory = atk_registry_get_factory (default_registry,
13553                                               G_TYPE_FROM_INSTANCE (widget));
13554           accessible = atk_object_factory_create_accessible (factory, G_OBJECT (widget));
13555 
13556           if (priv->accessible_role != ATK_ROLE_INVALID)
13557             atk_object_set_role (accessible, priv->accessible_role);
13558 
13559           widget->priv->accessible = accessible;
13560         }
13561       else
13562         {
13563           accessible = g_object_new (priv->accessible_type,
13564                                      "widget", widget,
13565                                      NULL);
13566           if (priv->accessible_role != ATK_ROLE_INVALID)
13567             atk_object_set_role (accessible, priv->accessible_role);
13568 
13569           widget->priv->accessible = accessible;
13570 
13571           atk_object_initialize (accessible, widget);
13572 
13573           /* Set the role again, since we don't want a role set
13574            * in some parent initialize() function to override
13575            * our own.
13576            */
13577           if (priv->accessible_role != ATK_ROLE_INVALID)
13578             atk_object_set_role (accessible, priv->accessible_role);
13579         }
13580 
13581     }
13582 
13583   return accessible;
13584 }
13585 
13586 /*
13587  * Initialize a AtkImplementorIface instance’s virtual pointers as
13588  * appropriate to this implementor’s class (GtkWidget).
13589  */
13590 static void
gtk_widget_accessible_interface_init(AtkImplementorIface * iface)13591 gtk_widget_accessible_interface_init (AtkImplementorIface *iface)
13592 {
13593   iface->ref_accessible = gtk_widget_ref_accessible;
13594 }
13595 
13596 static AtkObject*
gtk_widget_ref_accessible(AtkImplementor * implementor)13597 gtk_widget_ref_accessible (AtkImplementor *implementor)
13598 {
13599   AtkObject *accessible;
13600 
13601   accessible = gtk_widget_get_accessible (GTK_WIDGET (implementor));
13602   if (accessible)
13603     g_object_ref (accessible);
13604   return accessible;
13605 }
13606 
13607 /*
13608  * Expand flag management
13609  */
13610 
13611 static void
gtk_widget_update_computed_expand(GtkWidget * widget)13612 gtk_widget_update_computed_expand (GtkWidget *widget)
13613 {
13614   GtkWidgetPrivate *priv;
13615 
13616   priv = widget->priv;
13617 
13618   if (priv->need_compute_expand)
13619     {
13620       gboolean h, v;
13621 
13622       if (priv->hexpand_set)
13623         h = priv->hexpand;
13624       else
13625         h = FALSE;
13626 
13627       if (priv->vexpand_set)
13628         v = priv->vexpand;
13629       else
13630         v = FALSE;
13631 
13632       /* we don't need to use compute_expand if both expands are
13633        * forced by the app
13634        */
13635       if (!(priv->hexpand_set && priv->vexpand_set))
13636         {
13637           if (GTK_WIDGET_GET_CLASS (widget)->compute_expand != NULL)
13638             {
13639               gboolean ignored;
13640 
13641               GTK_WIDGET_GET_CLASS (widget)->compute_expand (widget,
13642                                                              priv->hexpand_set ? &ignored : &h,
13643                                                              priv->vexpand_set ? &ignored : &v);
13644             }
13645         }
13646 
13647       priv->need_compute_expand = FALSE;
13648       priv->computed_hexpand = h != FALSE;
13649       priv->computed_vexpand = v != FALSE;
13650     }
13651 }
13652 
13653 /**
13654  * gtk_widget_queue_compute_expand:
13655  * @widget: a #GtkWidget
13656  *
13657  * Mark @widget as needing to recompute its expand flags. Call
13658  * this function when setting legacy expand child properties
13659  * on the child of a container.
13660  *
13661  * See gtk_widget_compute_expand().
13662  */
13663 void
gtk_widget_queue_compute_expand(GtkWidget * widget)13664 gtk_widget_queue_compute_expand (GtkWidget *widget)
13665 {
13666   GtkWidget *parent;
13667   gboolean changed_anything;
13668 
13669   if (widget->priv->need_compute_expand)
13670     return;
13671 
13672   changed_anything = FALSE;
13673   parent = widget;
13674   while (parent != NULL)
13675     {
13676       if (!parent->priv->need_compute_expand)
13677         {
13678           parent->priv->need_compute_expand = TRUE;
13679           changed_anything = TRUE;
13680         }
13681 
13682       /* Note: if we had an invariant that "if a child needs to
13683        * compute expand, its parents also do" then we could stop going
13684        * up when we got to a parent that already needed to
13685        * compute. However, in general we compute expand lazily (as
13686        * soon as we see something in a subtree that is expand, we know
13687        * we're expanding) and so this invariant does not hold and we
13688        * have to always walk all the way up in case some ancestor
13689        * is not currently need_compute_expand.
13690        */
13691 
13692       parent = parent->priv->parent;
13693     }
13694 
13695   /* recomputing expand always requires
13696    * a relayout as well
13697    */
13698   if (changed_anything)
13699     gtk_widget_queue_resize (widget);
13700 }
13701 
13702 /**
13703  * gtk_widget_compute_expand:
13704  * @widget: the widget
13705  * @orientation: expand direction
13706  *
13707  * Computes whether a container should give this widget extra space
13708  * when possible. Containers should check this, rather than
13709  * looking at gtk_widget_get_hexpand() or gtk_widget_get_vexpand().
13710  *
13711  * This function already checks whether the widget is visible, so
13712  * visibility does not need to be checked separately. Non-visible
13713  * widgets are not expanded.
13714  *
13715  * The computed expand value uses either the expand setting explicitly
13716  * set on the widget itself, or, if none has been explicitly set,
13717  * the widget may expand if some of its children do.
13718  *
13719  * Returns: whether widget tree rooted here should be expanded
13720  */
13721 gboolean
gtk_widget_compute_expand(GtkWidget * widget,GtkOrientation orientation)13722 gtk_widget_compute_expand (GtkWidget      *widget,
13723                            GtkOrientation  orientation)
13724 {
13725   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
13726 
13727   /* We never make a widget expand if not even showing. */
13728   if (!_gtk_widget_get_visible (widget))
13729     return FALSE;
13730 
13731   gtk_widget_update_computed_expand (widget);
13732 
13733   if (orientation == GTK_ORIENTATION_HORIZONTAL)
13734     return widget->priv->computed_hexpand;
13735   else
13736     return widget->priv->computed_vexpand;
13737 }
13738 
13739 static void
gtk_widget_set_expand(GtkWidget * widget,GtkOrientation orientation,gboolean expand)13740 gtk_widget_set_expand (GtkWidget     *widget,
13741                        GtkOrientation orientation,
13742                        gboolean       expand)
13743 {
13744   gint expand_prop;
13745   gint expand_set_prop;
13746   gboolean was_both;
13747   GtkWidgetPrivate *priv;
13748 
13749   g_return_if_fail (GTK_IS_WIDGET (widget));
13750 
13751   priv = widget->priv;
13752 
13753   expand = expand != FALSE;
13754 
13755   was_both = priv->hexpand && priv->vexpand;
13756 
13757   if (orientation == GTK_ORIENTATION_HORIZONTAL)
13758     {
13759       if (priv->hexpand_set &&
13760           priv->hexpand == expand)
13761         return;
13762 
13763       priv->hexpand_set = TRUE;
13764       priv->hexpand = expand;
13765 
13766       expand_prop = PROP_HEXPAND;
13767       expand_set_prop = PROP_HEXPAND_SET;
13768     }
13769   else
13770     {
13771       if (priv->vexpand_set &&
13772           priv->vexpand == expand)
13773         return;
13774 
13775       priv->vexpand_set = TRUE;
13776       priv->vexpand = expand;
13777 
13778       expand_prop = PROP_VEXPAND;
13779       expand_set_prop = PROP_VEXPAND_SET;
13780     }
13781 
13782   gtk_widget_queue_compute_expand (widget);
13783 
13784   g_object_freeze_notify (G_OBJECT (widget));
13785   g_object_notify_by_pspec (G_OBJECT (widget), widget_props[expand_prop]);
13786   g_object_notify_by_pspec (G_OBJECT (widget), widget_props[expand_set_prop]);
13787   if (was_both != (priv->hexpand && priv->vexpand))
13788     g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_EXPAND]);
13789   g_object_thaw_notify (G_OBJECT (widget));
13790 }
13791 
13792 static void
gtk_widget_set_expand_set(GtkWidget * widget,GtkOrientation orientation,gboolean set)13793 gtk_widget_set_expand_set (GtkWidget      *widget,
13794                            GtkOrientation  orientation,
13795                            gboolean        set)
13796 {
13797   GtkWidgetPrivate *priv;
13798   gint prop;
13799 
13800   priv = widget->priv;
13801 
13802   set = set != FALSE;
13803 
13804   if (orientation == GTK_ORIENTATION_HORIZONTAL)
13805     {
13806       if (set == priv->hexpand_set)
13807         return;
13808 
13809       priv->hexpand_set = set;
13810       prop = PROP_HEXPAND_SET;
13811     }
13812   else
13813     {
13814       if (set == priv->vexpand_set)
13815         return;
13816 
13817       priv->vexpand_set = set;
13818       prop = PROP_VEXPAND_SET;
13819     }
13820 
13821   gtk_widget_queue_compute_expand (widget);
13822 
13823   g_object_notify_by_pspec (G_OBJECT (widget), widget_props[prop]);
13824 }
13825 
13826 /**
13827  * gtk_widget_get_hexpand:
13828  * @widget: the widget
13829  *
13830  * Gets whether the widget would like any available extra horizontal
13831  * space. When a user resizes a #GtkWindow, widgets with expand=TRUE
13832  * generally receive the extra space. For example, a list or
13833  * scrollable area or document in your window would often be set to
13834  * expand.
13835  *
13836  * Containers should use gtk_widget_compute_expand() rather than
13837  * this function, to see whether a widget, or any of its children,
13838  * has the expand flag set. If any child of a widget wants to
13839  * expand, the parent may ask to expand also.
13840  *
13841  * This function only looks at the widget’s own hexpand flag, rather
13842  * than computing whether the entire widget tree rooted at this widget
13843  * wants to expand.
13844  *
13845  * Returns: whether hexpand flag is set
13846  */
13847 gboolean
gtk_widget_get_hexpand(GtkWidget * widget)13848 gtk_widget_get_hexpand (GtkWidget *widget)
13849 {
13850   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
13851 
13852   return widget->priv->hexpand;
13853 }
13854 
13855 /**
13856  * gtk_widget_set_hexpand:
13857  * @widget: the widget
13858  * @expand: whether to expand
13859  *
13860  * Sets whether the widget would like any available extra horizontal
13861  * space. When a user resizes a #GtkWindow, widgets with expand=TRUE
13862  * generally receive the extra space. For example, a list or
13863  * scrollable area or document in your window would often be set to
13864  * expand.
13865  *
13866  * Call this function to set the expand flag if you would like your
13867  * widget to become larger horizontally when the window has extra
13868  * room.
13869  *
13870  * By default, widgets automatically expand if any of their children
13871  * want to expand. (To see if a widget will automatically expand given
13872  * its current children and state, call gtk_widget_compute_expand(). A
13873  * container can decide how the expandability of children affects the
13874  * expansion of the container by overriding the compute_expand virtual
13875  * method on #GtkWidget.).
13876  *
13877  * Setting hexpand explicitly with this function will override the
13878  * automatic expand behavior.
13879  *
13880  * This function forces the widget to expand or not to expand,
13881  * regardless of children.  The override occurs because
13882  * gtk_widget_set_hexpand() sets the hexpand-set property (see
13883  * gtk_widget_set_hexpand_set()) which causes the widget’s hexpand
13884  * value to be used, rather than looking at children and widget state.
13885  */
13886 void
gtk_widget_set_hexpand(GtkWidget * widget,gboolean expand)13887 gtk_widget_set_hexpand (GtkWidget      *widget,
13888                         gboolean        expand)
13889 {
13890   g_return_if_fail (GTK_IS_WIDGET (widget));
13891 
13892   gtk_widget_set_expand (widget, GTK_ORIENTATION_HORIZONTAL, expand);
13893 }
13894 
13895 /**
13896  * gtk_widget_get_hexpand_set:
13897  * @widget: the widget
13898  *
13899  * Gets whether gtk_widget_set_hexpand() has been used to
13900  * explicitly set the expand flag on this widget.
13901  *
13902  * If hexpand is set, then it overrides any computed
13903  * expand value based on child widgets. If hexpand is not
13904  * set, then the expand value depends on whether any
13905  * children of the widget would like to expand.
13906  *
13907  * There are few reasons to use this function, but it’s here
13908  * for completeness and consistency.
13909  *
13910  * Returns: whether hexpand has been explicitly set
13911  */
13912 gboolean
gtk_widget_get_hexpand_set(GtkWidget * widget)13913 gtk_widget_get_hexpand_set (GtkWidget      *widget)
13914 {
13915   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
13916 
13917   return widget->priv->hexpand_set;
13918 }
13919 
13920 /**
13921  * gtk_widget_set_hexpand_set:
13922  * @widget: the widget
13923  * @set: value for hexpand-set property
13924  *
13925  * Sets whether the hexpand flag (see gtk_widget_get_hexpand()) will
13926  * be used.
13927  *
13928  * The hexpand-set property will be set automatically when you call
13929  * gtk_widget_set_hexpand() to set hexpand, so the most likely
13930  * reason to use this function would be to unset an explicit expand
13931  * flag.
13932  *
13933  * If hexpand is set, then it overrides any computed
13934  * expand value based on child widgets. If hexpand is not
13935  * set, then the expand value depends on whether any
13936  * children of the widget would like to expand.
13937  *
13938  * There are few reasons to use this function, but it’s here
13939  * for completeness and consistency.
13940  */
13941 void
gtk_widget_set_hexpand_set(GtkWidget * widget,gboolean set)13942 gtk_widget_set_hexpand_set (GtkWidget      *widget,
13943                             gboolean        set)
13944 {
13945   g_return_if_fail (GTK_IS_WIDGET (widget));
13946 
13947   gtk_widget_set_expand_set (widget, GTK_ORIENTATION_HORIZONTAL, set);
13948 }
13949 
13950 
13951 /**
13952  * gtk_widget_get_vexpand:
13953  * @widget: the widget
13954  *
13955  * Gets whether the widget would like any available extra vertical
13956  * space.
13957  *
13958  * See gtk_widget_get_hexpand() for more detail.
13959  *
13960  * Returns: whether vexpand flag is set
13961  */
13962 gboolean
gtk_widget_get_vexpand(GtkWidget * widget)13963 gtk_widget_get_vexpand (GtkWidget *widget)
13964 {
13965   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
13966 
13967   return widget->priv->vexpand;
13968 }
13969 
13970 /**
13971  * gtk_widget_set_vexpand:
13972  * @widget: the widget
13973  * @expand: whether to expand
13974  *
13975  * Sets whether the widget would like any available extra vertical
13976  * space.
13977  *
13978  * See gtk_widget_set_hexpand() for more detail.
13979  */
13980 void
gtk_widget_set_vexpand(GtkWidget * widget,gboolean expand)13981 gtk_widget_set_vexpand (GtkWidget      *widget,
13982                         gboolean        expand)
13983 {
13984   g_return_if_fail (GTK_IS_WIDGET (widget));
13985 
13986   gtk_widget_set_expand (widget, GTK_ORIENTATION_VERTICAL, expand);
13987 }
13988 
13989 /**
13990  * gtk_widget_get_vexpand_set:
13991  * @widget: the widget
13992  *
13993  * Gets whether gtk_widget_set_vexpand() has been used to
13994  * explicitly set the expand flag on this widget.
13995  *
13996  * See gtk_widget_get_hexpand_set() for more detail.
13997  *
13998  * Returns: whether vexpand has been explicitly set
13999  */
14000 gboolean
gtk_widget_get_vexpand_set(GtkWidget * widget)14001 gtk_widget_get_vexpand_set (GtkWidget      *widget)
14002 {
14003   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
14004 
14005   return widget->priv->vexpand_set;
14006 }
14007 
14008 /**
14009  * gtk_widget_set_vexpand_set:
14010  * @widget: the widget
14011  * @set: value for vexpand-set property
14012  *
14013  * Sets whether the vexpand flag (see gtk_widget_get_vexpand()) will
14014  * be used.
14015  *
14016  * See gtk_widget_set_hexpand_set() for more detail.
14017  */
14018 void
gtk_widget_set_vexpand_set(GtkWidget * widget,gboolean set)14019 gtk_widget_set_vexpand_set (GtkWidget      *widget,
14020                             gboolean        set)
14021 {
14022   g_return_if_fail (GTK_IS_WIDGET (widget));
14023 
14024   gtk_widget_set_expand_set (widget, GTK_ORIENTATION_VERTICAL, set);
14025 }
14026 
14027 /*
14028  * GtkBuildable implementation
14029  */
14030 static GQuark		 quark_builder_has_default = 0;
14031 static GQuark		 quark_builder_has_focus = 0;
14032 static GQuark		 quark_builder_atk_relations = 0;
14033 static GQuark            quark_builder_set_name = 0;
14034 
14035 static void
gtk_widget_buildable_interface_init(GtkBuildableIface * iface)14036 gtk_widget_buildable_interface_init (GtkBuildableIface *iface)
14037 {
14038   quark_builder_has_default = g_quark_from_static_string ("gtk-builder-has-default");
14039   quark_builder_has_focus = g_quark_from_static_string ("gtk-builder-has-focus");
14040   quark_builder_atk_relations = g_quark_from_static_string ("gtk-builder-atk-relations");
14041   quark_builder_set_name = g_quark_from_static_string ("gtk-builder-set-name");
14042 
14043   iface->set_name = gtk_widget_buildable_set_name;
14044   iface->get_name = gtk_widget_buildable_get_name;
14045   iface->get_internal_child = gtk_widget_buildable_get_internal_child;
14046   iface->set_buildable_property = gtk_widget_buildable_set_buildable_property;
14047   iface->parser_finished = gtk_widget_buildable_parser_finished;
14048   iface->custom_tag_start = gtk_widget_buildable_custom_tag_start;
14049   iface->custom_finished = gtk_widget_buildable_custom_finished;
14050 }
14051 
14052 static void
gtk_widget_buildable_set_name(GtkBuildable * buildable,const gchar * name)14053 gtk_widget_buildable_set_name (GtkBuildable *buildable,
14054 			       const gchar  *name)
14055 {
14056   g_object_set_qdata_full (G_OBJECT (buildable), quark_builder_set_name,
14057                            g_strdup (name), g_free);
14058 }
14059 
14060 static const gchar *
gtk_widget_buildable_get_name(GtkBuildable * buildable)14061 gtk_widget_buildable_get_name (GtkBuildable *buildable)
14062 {
14063   return g_object_get_qdata (G_OBJECT (buildable), quark_builder_set_name);
14064 }
14065 
14066 static GObject *
gtk_widget_buildable_get_internal_child(GtkBuildable * buildable,GtkBuilder * builder,const gchar * childname)14067 gtk_widget_buildable_get_internal_child (GtkBuildable *buildable,
14068 					 GtkBuilder   *builder,
14069 					 const gchar  *childname)
14070 {
14071   GtkWidgetClass *class;
14072   GSList *l;
14073   GType internal_child_type = 0;
14074 
14075   if (strcmp (childname, "accessible") == 0)
14076     return G_OBJECT (gtk_widget_get_accessible (GTK_WIDGET (buildable)));
14077 
14078   /* Find a widget type which has declared an automated child as internal by
14079    * the name 'childname', if any.
14080    */
14081   for (class = GTK_WIDGET_GET_CLASS (buildable);
14082        GTK_IS_WIDGET_CLASS (class);
14083        class = g_type_class_peek_parent (class))
14084     {
14085       GtkWidgetTemplate *template = class->priv->template;
14086 
14087       if (!template)
14088 	continue;
14089 
14090       for (l = template->children; l && internal_child_type == 0; l = l->next)
14091 	{
14092 	  AutomaticChildClass *child_class = l->data;
14093 
14094 	  if (child_class->internal_child && strcmp (childname, child_class->name) == 0)
14095 	    internal_child_type = G_OBJECT_CLASS_TYPE (class);
14096 	}
14097     }
14098 
14099   /* Now return the 'internal-child' from the class which declared it, note
14100    * that gtk_widget_get_template_child() an API used to access objects
14101    * which are in the private scope of a given class.
14102    */
14103   if (internal_child_type != 0)
14104     return gtk_widget_get_template_child (GTK_WIDGET (buildable), internal_child_type, childname);
14105 
14106   return NULL;
14107 }
14108 
14109 static void
gtk_widget_buildable_set_buildable_property(GtkBuildable * buildable,GtkBuilder * builder,const gchar * name,const GValue * value)14110 gtk_widget_buildable_set_buildable_property (GtkBuildable *buildable,
14111 					     GtkBuilder   *builder,
14112 					     const gchar  *name,
14113 					     const GValue *value)
14114 {
14115   if (strcmp (name, "has-default") == 0 && g_value_get_boolean (value))
14116       g_object_set_qdata (G_OBJECT (buildable), quark_builder_has_default,
14117 			  GINT_TO_POINTER (TRUE));
14118   else if (strcmp (name, "has-focus") == 0 && g_value_get_boolean (value))
14119       g_object_set_qdata (G_OBJECT (buildable), quark_builder_has_focus,
14120 			  GINT_TO_POINTER (TRUE));
14121   else
14122     g_object_set_property (G_OBJECT (buildable), name, value);
14123 }
14124 
14125 typedef struct
14126 {
14127   gchar *action_name;
14128   GString *description;
14129   gchar *context;
14130   gboolean translatable;
14131 } AtkActionData;
14132 
14133 typedef struct
14134 {
14135   gchar *target;
14136   AtkRelationType type;
14137   gint line;
14138   gint col;
14139 } AtkRelationData;
14140 
14141 static void
free_action(AtkActionData * data,gpointer user_data)14142 free_action (AtkActionData *data, gpointer user_data)
14143 {
14144   g_free (data->action_name);
14145   g_string_free (data->description, TRUE);
14146   g_free (data->context);
14147   g_slice_free (AtkActionData, data);
14148 }
14149 
14150 static void
free_relation(AtkRelationData * data,gpointer user_data)14151 free_relation (AtkRelationData *data, gpointer user_data)
14152 {
14153   g_free (data->target);
14154   g_slice_free (AtkRelationData, data);
14155 }
14156 
14157 static void
gtk_widget_buildable_parser_finished(GtkBuildable * buildable,GtkBuilder * builder)14158 gtk_widget_buildable_parser_finished (GtkBuildable *buildable,
14159 				      GtkBuilder   *builder)
14160 {
14161   GSList *atk_relations;
14162 
14163   if (g_object_get_qdata (G_OBJECT (buildable), quark_builder_has_default))
14164     {
14165       gtk_widget_grab_default (GTK_WIDGET (buildable));
14166       g_object_steal_qdata (G_OBJECT (buildable), quark_builder_has_default);
14167     }
14168 
14169   if (g_object_get_qdata (G_OBJECT (buildable), quark_builder_has_focus))
14170     {
14171       gtk_widget_grab_focus (GTK_WIDGET (buildable));
14172       g_object_steal_qdata (G_OBJECT (buildable), quark_builder_has_focus);
14173     }
14174 
14175   atk_relations = g_object_get_qdata (G_OBJECT (buildable),
14176 				      quark_builder_atk_relations);
14177   if (atk_relations)
14178     {
14179       AtkObject *accessible;
14180       AtkRelationSet *relation_set;
14181       GSList *l;
14182       GObject *target;
14183       AtkObject *target_accessible;
14184 
14185       accessible = gtk_widget_get_accessible (GTK_WIDGET (buildable));
14186       relation_set = atk_object_ref_relation_set (accessible);
14187 
14188       for (l = atk_relations; l; l = l->next)
14189 	{
14190 	  AtkRelationData *relation = (AtkRelationData*)l->data;
14191 
14192 	  target = _gtk_builder_lookup_object (builder, relation->target, relation->line, relation->col);
14193 	  if (!target)
14194 	    continue;
14195 	  target_accessible = gtk_widget_get_accessible (GTK_WIDGET (target));
14196 	  g_assert (target_accessible != NULL);
14197 
14198 	  atk_relation_set_add_relation_by_type (relation_set, relation->type, target_accessible);
14199 	}
14200       g_object_unref (relation_set);
14201 
14202       g_slist_free_full (atk_relations, (GDestroyNotify) free_relation);
14203       g_object_steal_qdata (G_OBJECT (buildable), quark_builder_atk_relations);
14204     }
14205 }
14206 
14207 typedef struct
14208 {
14209   GtkBuilder *builder;
14210   GSList *actions;
14211   GSList *relations;
14212 } AccessibilitySubParserData;
14213 
14214 static void
accessibility_start_element(GMarkupParseContext * context,const gchar * element_name,const gchar ** names,const gchar ** values,gpointer user_data,GError ** error)14215 accessibility_start_element (GMarkupParseContext  *context,
14216                              const gchar          *element_name,
14217                              const gchar         **names,
14218                              const gchar         **values,
14219                              gpointer              user_data,
14220                              GError              **error)
14221 {
14222   AccessibilitySubParserData *data = (AccessibilitySubParserData*)user_data;
14223 
14224   if (strcmp (element_name, "relation") == 0)
14225     {
14226       gchar *target = NULL;
14227       gchar *type = NULL;
14228       AtkRelationData *relation;
14229       AtkRelationType relation_type;
14230 
14231       if (!_gtk_builder_check_parent (data->builder, context, "accessibility", error))
14232         return;
14233 
14234       if (!g_markup_collect_attributes (element_name, names, values, error,
14235                                         G_MARKUP_COLLECT_STRING, "target", &target,
14236                                         G_MARKUP_COLLECT_STRING, "type", &type,
14237                                         G_MARKUP_COLLECT_INVALID))
14238         {
14239           _gtk_builder_prefix_error (data->builder, context, error);
14240           return;
14241         }
14242 
14243       relation_type = atk_relation_type_for_name (type);
14244       if (relation_type == ATK_RELATION_NULL)
14245         {
14246           g_set_error (error,
14247                        GTK_BUILDER_ERROR,
14248                        GTK_BUILDER_ERROR_INVALID_VALUE,
14249                        "No such relation type: '%s'", type);
14250           _gtk_builder_prefix_error (data->builder, context, error);
14251           return;
14252         }
14253 
14254       relation = g_slice_new (AtkRelationData);
14255       relation->target = g_strdup (target);
14256       relation->type = relation_type;
14257 
14258       data->relations = g_slist_prepend (data->relations, relation);
14259     }
14260   else if (strcmp (element_name, "action") == 0)
14261     {
14262       const gchar *action_name;
14263       const gchar *description = NULL;
14264       const gchar *msg_context = NULL;
14265       gboolean translatable = FALSE;
14266       AtkActionData *action;
14267 
14268       if (!_gtk_builder_check_parent (data->builder, context, "accessibility", error))
14269         return;
14270 
14271       if (!g_markup_collect_attributes (element_name, names, values, error,
14272                                         G_MARKUP_COLLECT_STRING, "action_name", &action_name,
14273                                         G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "description", &description,
14274                                         G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "comments", NULL,
14275                                         G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "context", &msg_context,
14276                                         G_MARKUP_COLLECT_BOOLEAN|G_MARKUP_COLLECT_OPTIONAL, "translatable", &translatable,
14277                                         G_MARKUP_COLLECT_INVALID))
14278         {
14279           _gtk_builder_prefix_error (data->builder, context, error);
14280           return;
14281         }
14282 
14283       action = g_slice_new (AtkActionData);
14284       action->action_name = g_strdup (action_name);
14285       action->description = g_string_new (description);
14286       action->context = g_strdup (msg_context);
14287       action->translatable = translatable;
14288 
14289       data->actions = g_slist_prepend (data->actions, action);
14290     }
14291   else if (strcmp (element_name, "accessibility") == 0)
14292     {
14293       if (!_gtk_builder_check_parent (data->builder, context, "object", error))
14294         return;
14295 
14296       if (!g_markup_collect_attributes (element_name, names, values, error,
14297                                         G_MARKUP_COLLECT_INVALID, NULL, NULL,
14298                                         G_MARKUP_COLLECT_INVALID))
14299         _gtk_builder_prefix_error (data->builder, context, error);
14300     }
14301   else
14302     {
14303       _gtk_builder_error_unhandled_tag (data->builder, context,
14304                                         "GtkWidget", element_name,
14305                                         error);
14306     }
14307 }
14308 
14309 static void
accessibility_text(GMarkupParseContext * context,const gchar * text,gsize text_len,gpointer user_data,GError ** error)14310 accessibility_text (GMarkupParseContext  *context,
14311                     const gchar          *text,
14312                     gsize                 text_len,
14313                     gpointer              user_data,
14314                     GError              **error)
14315 {
14316   AccessibilitySubParserData *data = (AccessibilitySubParserData*)user_data;
14317 
14318   if (strcmp (g_markup_parse_context_get_element (context), "action") == 0)
14319     {
14320       AtkActionData *action = data->actions->data;
14321 
14322       g_string_append_len (action->description, text, text_len);
14323     }
14324 }
14325 
14326 static const GMarkupParser accessibility_parser =
14327   {
14328     accessibility_start_element,
14329     NULL,
14330     accessibility_text,
14331   };
14332 
14333 typedef struct
14334 {
14335   GObject *object;
14336   GtkBuilder *builder;
14337   guint    key;
14338   guint    modifiers;
14339   gchar   *signal;
14340 } AccelGroupParserData;
14341 
14342 static void
accel_group_start_element(GMarkupParseContext * context,const gchar * element_name,const gchar ** names,const gchar ** values,gpointer user_data,GError ** error)14343 accel_group_start_element (GMarkupParseContext  *context,
14344                            const gchar          *element_name,
14345                            const gchar         **names,
14346                            const gchar         **values,
14347                            gpointer              user_data,
14348                            GError              **error)
14349 {
14350   AccelGroupParserData *data = (AccelGroupParserData*)user_data;
14351 
14352   if (strcmp (element_name, "accelerator") == 0)
14353     {
14354       const gchar *key_str = NULL;
14355       const gchar *signal = NULL;
14356       const gchar *modifiers_str = NULL;
14357       guint key = 0;
14358       guint modifiers = 0;
14359 
14360       if (!_gtk_builder_check_parent (data->builder, context, "object", error))
14361         return;
14362 
14363       if (!g_markup_collect_attributes (element_name, names, values, error,
14364                                         G_MARKUP_COLLECT_STRING, "key", &key_str,
14365                                         G_MARKUP_COLLECT_STRING, "signal", &signal,
14366                                         G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "modifiers", &modifiers_str,
14367                                         G_MARKUP_COLLECT_INVALID))
14368         {
14369           _gtk_builder_prefix_error (data->builder, context, error);
14370           return;
14371         }
14372 
14373       key = gdk_keyval_from_name (key_str);
14374       if (key == 0)
14375         {
14376           g_set_error (error,
14377                        GTK_BUILDER_ERROR, GTK_BUILDER_ERROR_INVALID_VALUE,
14378                        "Could not parse key '%s'", key_str);
14379           _gtk_builder_prefix_error (data->builder, context, error);
14380           return;
14381         }
14382 
14383       if (modifiers_str != NULL)
14384         {
14385           GFlagsValue aliases[2] = {
14386             { 0, "primary", "primary" },
14387             { 0, NULL, NULL }
14388           };
14389 
14390           aliases[0].value = _gtk_get_primary_accel_mod ();
14391 
14392           if (!_gtk_builder_flags_from_string (GDK_TYPE_MODIFIER_TYPE, aliases,
14393                                                modifiers_str, &modifiers, error))
14394             {
14395               _gtk_builder_prefix_error (data->builder, context, error);
14396 	      return;
14397             }
14398         }
14399 
14400       data->key = key;
14401       data->modifiers = modifiers;
14402       data->signal = g_strdup (signal);
14403     }
14404   else
14405     {
14406       _gtk_builder_error_unhandled_tag (data->builder, context,
14407                                         "GtkWidget", element_name,
14408                                         error);
14409     }
14410 }
14411 
14412 static const GMarkupParser accel_group_parser =
14413   {
14414     accel_group_start_element,
14415   };
14416 
14417 typedef struct
14418 {
14419   GtkBuilder *builder;
14420   GSList *classes;
14421 } StyleParserData;
14422 
14423 static void
style_start_element(GMarkupParseContext * context,const gchar * element_name,const gchar ** names,const gchar ** values,gpointer user_data,GError ** error)14424 style_start_element (GMarkupParseContext  *context,
14425                      const gchar          *element_name,
14426                      const gchar         **names,
14427                      const gchar         **values,
14428                      gpointer              user_data,
14429                      GError              **error)
14430 {
14431   StyleParserData *data = (StyleParserData *)user_data;
14432 
14433   if (strcmp (element_name, "class") == 0)
14434     {
14435       const gchar *name;
14436 
14437       if (!_gtk_builder_check_parent (data->builder, context, "style", error))
14438         return;
14439 
14440       if (!g_markup_collect_attributes (element_name, names, values, error,
14441                                         G_MARKUP_COLLECT_STRING, "name", &name,
14442                                         G_MARKUP_COLLECT_INVALID))
14443         {
14444           _gtk_builder_prefix_error (data->builder, context, error);
14445           return;
14446         }
14447 
14448       data->classes = g_slist_prepend (data->classes, g_strdup (name));
14449     }
14450   else if (strcmp (element_name, "style") == 0)
14451     {
14452       if (!_gtk_builder_check_parent (data->builder, context, "object", error))
14453         return;
14454 
14455       if (!g_markup_collect_attributes (element_name, names, values, error,
14456                                         G_MARKUP_COLLECT_INVALID, NULL, NULL,
14457                                         G_MARKUP_COLLECT_INVALID))
14458         _gtk_builder_prefix_error (data->builder, context, error);
14459     }
14460   else
14461     {
14462       _gtk_builder_error_unhandled_tag (data->builder, context,
14463                                         "GtkWidget", element_name,
14464                                         error);
14465     }
14466 }
14467 
14468 static const GMarkupParser style_parser =
14469   {
14470     style_start_element,
14471   };
14472 
14473 static gboolean
gtk_widget_buildable_custom_tag_start(GtkBuildable * buildable,GtkBuilder * builder,GObject * child,const gchar * tagname,GMarkupParser * parser,gpointer * parser_data)14474 gtk_widget_buildable_custom_tag_start (GtkBuildable     *buildable,
14475                                        GtkBuilder       *builder,
14476                                        GObject          *child,
14477                                        const gchar      *tagname,
14478                                        GMarkupParser    *parser,
14479                                        gpointer         *parser_data)
14480 {
14481   if (strcmp (tagname, "accelerator") == 0)
14482     {
14483       AccelGroupParserData *data;
14484 
14485       data = g_slice_new0 (AccelGroupParserData);
14486       data->object = G_OBJECT (g_object_ref (buildable));
14487       data->builder = builder;
14488 
14489       *parser = accel_group_parser;
14490       *parser_data = data;
14491 
14492       return TRUE;
14493     }
14494 
14495   if (strcmp (tagname, "accessibility") == 0)
14496     {
14497       AccessibilitySubParserData *data;
14498 
14499       data = g_slice_new0 (AccessibilitySubParserData);
14500       data->builder = builder;
14501 
14502       *parser = accessibility_parser;
14503       *parser_data = data;
14504 
14505       return TRUE;
14506     }
14507 
14508   if (strcmp (tagname, "style") == 0)
14509     {
14510       StyleParserData *data;
14511 
14512       data = g_slice_new0 (StyleParserData);
14513       data->builder = builder;
14514 
14515       *parser = style_parser;
14516       *parser_data = data;
14517 
14518       return TRUE;
14519     }
14520 
14521   return FALSE;
14522 }
14523 
14524 void
_gtk_widget_buildable_finish_accelerator(GtkWidget * widget,GtkWidget * toplevel,gpointer user_data)14525 _gtk_widget_buildable_finish_accelerator (GtkWidget *widget,
14526                                           GtkWidget *toplevel,
14527                                           gpointer   user_data)
14528 {
14529   AccelGroupParserData *accel_data;
14530   GSList *accel_groups;
14531   GtkAccelGroup *accel_group;
14532 
14533   g_return_if_fail (GTK_IS_WIDGET (widget));
14534   g_return_if_fail (GTK_IS_WIDGET (toplevel));
14535   g_return_if_fail (user_data != NULL);
14536 
14537   accel_data = (AccelGroupParserData*)user_data;
14538   accel_groups = gtk_accel_groups_from_object (G_OBJECT (toplevel));
14539   if (g_slist_length (accel_groups) == 0)
14540     {
14541       accel_group = gtk_accel_group_new ();
14542       gtk_window_add_accel_group (GTK_WINDOW (toplevel), accel_group);
14543     }
14544   else
14545     {
14546       g_assert (g_slist_length (accel_groups) == 1);
14547       accel_group = g_slist_nth_data (accel_groups, 0);
14548     }
14549 
14550   gtk_widget_add_accelerator (GTK_WIDGET (accel_data->object),
14551 			      accel_data->signal,
14552 			      accel_group,
14553 			      accel_data->key,
14554 			      accel_data->modifiers,
14555 			      GTK_ACCEL_VISIBLE);
14556 
14557   g_object_unref (accel_data->object);
14558   g_free (accel_data->signal);
14559   g_slice_free (AccelGroupParserData, accel_data);
14560 }
14561 
14562 static void
gtk_widget_buildable_custom_finished(GtkBuildable * buildable,GtkBuilder * builder,GObject * child,const gchar * tagname,gpointer user_data)14563 gtk_widget_buildable_custom_finished (GtkBuildable *buildable,
14564                                       GtkBuilder   *builder,
14565                                       GObject      *child,
14566                                       const gchar  *tagname,
14567                                       gpointer      user_data)
14568 {
14569   if (strcmp (tagname, "accelerator") == 0)
14570     {
14571       AccelGroupParserData *accel_data;
14572       GtkWidget *toplevel;
14573 
14574       accel_data = (AccelGroupParserData*)user_data;
14575       g_assert (accel_data->object);
14576 
14577       toplevel = _gtk_widget_get_toplevel (GTK_WIDGET (accel_data->object));
14578 
14579       _gtk_widget_buildable_finish_accelerator (GTK_WIDGET (buildable), toplevel, user_data);
14580     }
14581   else if (strcmp (tagname, "accessibility") == 0)
14582     {
14583       AccessibilitySubParserData *a11y_data;
14584 
14585       a11y_data = (AccessibilitySubParserData*)user_data;
14586 
14587       if (a11y_data->actions)
14588 	{
14589 	  AtkObject *accessible;
14590 	  AtkAction *action;
14591 	  gint i, n_actions;
14592 	  GSList *l;
14593 
14594 	  accessible = gtk_widget_get_accessible (GTK_WIDGET (buildable));
14595 
14596           if (ATK_IS_ACTION (accessible))
14597             {
14598 	      action = ATK_ACTION (accessible);
14599 	      n_actions = atk_action_get_n_actions (action);
14600 
14601 	      for (l = a11y_data->actions; l; l = l->next)
14602 	        {
14603 	          AtkActionData *action_data = (AtkActionData*)l->data;
14604 
14605 	          for (i = 0; i < n_actions; i++)
14606 		    if (strcmp (atk_action_get_name (action, i),
14607 		  	        action_data->action_name) == 0)
14608 		      break;
14609 
14610 	          if (i < n_actions)
14611                     {
14612                       const gchar *description;
14613 
14614                       if (action_data->translatable && action_data->description->len)
14615                         description = _gtk_builder_parser_translate (gtk_builder_get_translation_domain (builder),
14616                                                                      action_data->context,
14617                                                                      action_data->description->str);
14618                       else
14619                         description = action_data->description->str;
14620 
14621 		      atk_action_set_description (action, i, description);
14622                     }
14623                 }
14624 	    }
14625           else
14626             g_warning ("accessibility action on a widget that does not implement AtkAction");
14627 
14628 	  g_slist_free_full (a11y_data->actions, (GDestroyNotify) free_action);
14629 	}
14630 
14631       if (a11y_data->relations)
14632 	g_object_set_qdata (G_OBJECT (buildable), quark_builder_atk_relations,
14633 			    a11y_data->relations);
14634 
14635       g_slice_free (AccessibilitySubParserData, a11y_data);
14636     }
14637   else if (strcmp (tagname, "style") == 0)
14638     {
14639       StyleParserData *style_data = (StyleParserData *)user_data;
14640       GtkStyleContext *context;
14641       GSList *l;
14642 
14643       context = _gtk_widget_get_style_context (GTK_WIDGET (buildable));
14644 
14645       for (l = style_data->classes; l; l = l->next)
14646         gtk_style_context_add_class (context, (const gchar *)l->data);
14647 
14648       gtk_widget_reset_style (GTK_WIDGET (buildable));
14649 
14650       g_slist_free_full (style_data->classes, g_free);
14651       g_slice_free (StyleParserData, style_data);
14652     }
14653 }
14654 
14655 static GtkSizeRequestMode
gtk_widget_real_get_request_mode(GtkWidget * widget)14656 gtk_widget_real_get_request_mode (GtkWidget *widget)
14657 {
14658   /* By default widgets don't trade size at all. */
14659   return GTK_SIZE_REQUEST_CONSTANT_SIZE;
14660 }
14661 
14662 static void
gtk_widget_real_get_width(GtkWidget * widget,gint * minimum_size,gint * natural_size)14663 gtk_widget_real_get_width (GtkWidget *widget,
14664 			   gint      *minimum_size,
14665 			   gint      *natural_size)
14666 {
14667   *minimum_size = 0;
14668   *natural_size = 0;
14669 }
14670 
14671 static void
gtk_widget_real_get_height(GtkWidget * widget,gint * minimum_size,gint * natural_size)14672 gtk_widget_real_get_height (GtkWidget *widget,
14673 			    gint      *minimum_size,
14674 			    gint      *natural_size)
14675 {
14676   *minimum_size = 0;
14677   *natural_size = 0;
14678 }
14679 
14680 static void
gtk_widget_real_get_height_for_width(GtkWidget * widget,gint width,gint * minimum_height,gint * natural_height)14681 gtk_widget_real_get_height_for_width (GtkWidget *widget,
14682                                       gint       width,
14683                                       gint      *minimum_height,
14684                                       gint      *natural_height)
14685 {
14686   GTK_WIDGET_GET_CLASS (widget)->get_preferred_height (widget, minimum_height, natural_height);
14687 }
14688 
14689 static void
gtk_widget_real_get_width_for_height(GtkWidget * widget,gint height,gint * minimum_width,gint * natural_width)14690 gtk_widget_real_get_width_for_height (GtkWidget *widget,
14691                                       gint       height,
14692                                       gint      *minimum_width,
14693                                       gint      *natural_width)
14694 {
14695   GTK_WIDGET_GET_CLASS (widget)->get_preferred_width (widget, minimum_width, natural_width);
14696 }
14697 
14698 /**
14699  * gtk_widget_get_halign:
14700  * @widget: a #GtkWidget
14701  *
14702  * Gets the value of the #GtkWidget:halign property.
14703  *
14704  * For backwards compatibility reasons this method will never return
14705  * %GTK_ALIGN_BASELINE, but instead it will convert it to
14706  * %GTK_ALIGN_FILL. Baselines are not supported for horizontal
14707  * alignment.
14708  *
14709  * Returns: the horizontal alignment of @widget
14710  */
14711 GtkAlign
gtk_widget_get_halign(GtkWidget * widget)14712 gtk_widget_get_halign (GtkWidget *widget)
14713 {
14714   GtkAlign align;
14715 
14716   g_return_val_if_fail (GTK_IS_WIDGET (widget), GTK_ALIGN_FILL);
14717 
14718   align = widget->priv->halign;
14719   if (align == GTK_ALIGN_BASELINE)
14720     return GTK_ALIGN_FILL;
14721   return align;
14722 }
14723 
14724 /**
14725  * gtk_widget_set_halign:
14726  * @widget: a #GtkWidget
14727  * @align: the horizontal alignment
14728  *
14729  * Sets the horizontal alignment of @widget.
14730  * See the #GtkWidget:halign property.
14731  */
14732 void
gtk_widget_set_halign(GtkWidget * widget,GtkAlign align)14733 gtk_widget_set_halign (GtkWidget *widget,
14734                        GtkAlign   align)
14735 {
14736   g_return_if_fail (GTK_IS_WIDGET (widget));
14737 
14738   if (widget->priv->halign == align)
14739     return;
14740 
14741   widget->priv->halign = align;
14742   gtk_widget_queue_allocate (widget);
14743   g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_HALIGN]);
14744 }
14745 
14746 /**
14747  * gtk_widget_get_valign_with_baseline:
14748  * @widget: a #GtkWidget
14749  *
14750  * Gets the value of the #GtkWidget:valign property, including
14751  * %GTK_ALIGN_BASELINE.
14752  *
14753  * Returns: the vertical alignment of @widget
14754  *
14755  * Since: 3.10
14756  */
14757 GtkAlign
gtk_widget_get_valign_with_baseline(GtkWidget * widget)14758 gtk_widget_get_valign_with_baseline (GtkWidget *widget)
14759 {
14760   g_return_val_if_fail (GTK_IS_WIDGET (widget), GTK_ALIGN_FILL);
14761   return widget->priv->valign;
14762 }
14763 
14764 /**
14765  * gtk_widget_get_valign:
14766  * @widget: a #GtkWidget
14767  *
14768  * Gets the value of the #GtkWidget:valign property.
14769  *
14770  * For backwards compatibility reasons this method will never return
14771  * %GTK_ALIGN_BASELINE, but instead it will convert it to
14772  * %GTK_ALIGN_FILL. If your widget want to support baseline aligned
14773  * children it must use gtk_widget_get_valign_with_baseline(), or
14774  * `g_object_get (widget, "valign", &value, NULL)`, which will
14775  * also report the true value.
14776  *
14777  * Returns: the vertical alignment of @widget, ignoring baseline alignment
14778  */
14779 GtkAlign
gtk_widget_get_valign(GtkWidget * widget)14780 gtk_widget_get_valign (GtkWidget *widget)
14781 {
14782   GtkAlign align;
14783 
14784   align = gtk_widget_get_valign_with_baseline (widget);
14785   if (align == GTK_ALIGN_BASELINE)
14786     return GTK_ALIGN_FILL;
14787   return align;
14788 }
14789 
14790 /**
14791  * gtk_widget_set_valign:
14792  * @widget: a #GtkWidget
14793  * @align: the vertical alignment
14794  *
14795  * Sets the vertical alignment of @widget.
14796  * See the #GtkWidget:valign property.
14797  */
14798 void
gtk_widget_set_valign(GtkWidget * widget,GtkAlign align)14799 gtk_widget_set_valign (GtkWidget *widget,
14800                        GtkAlign   align)
14801 {
14802   g_return_if_fail (GTK_IS_WIDGET (widget));
14803 
14804   if (widget->priv->valign == align)
14805     return;
14806 
14807   widget->priv->valign = align;
14808   gtk_widget_queue_allocate (widget);
14809   g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_VALIGN]);
14810 }
14811 
14812 /**
14813  * gtk_widget_get_margin_left:
14814  * @widget: a #GtkWidget
14815  *
14816  * Gets the value of the #GtkWidget:margin-left property.
14817  *
14818  * Returns: The left margin of @widget
14819  *
14820  * Deprecated: 3.12: Use gtk_widget_get_margin_start() instead.
14821  *
14822  * Since: 3.0
14823  */
14824 gint
gtk_widget_get_margin_left(GtkWidget * widget)14825 gtk_widget_get_margin_left (GtkWidget *widget)
14826 {
14827   g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
14828 
14829   return widget->priv->margin.left;
14830 }
14831 
14832 /**
14833  * gtk_widget_set_margin_left:
14834  * @widget: a #GtkWidget
14835  * @margin: the left margin
14836  *
14837  * Sets the left margin of @widget.
14838  * See the #GtkWidget:margin-left property.
14839  *
14840  * Deprecated: 3.12: Use gtk_widget_set_margin_start() instead.
14841  *
14842  * Since: 3.0
14843  */
14844 void
gtk_widget_set_margin_left(GtkWidget * widget,gint margin)14845 gtk_widget_set_margin_left (GtkWidget *widget,
14846                             gint       margin)
14847 {
14848   gboolean rtl;
14849 
14850   g_return_if_fail (GTK_IS_WIDGET (widget));
14851   g_return_if_fail (margin <= G_MAXINT16);
14852 
14853   rtl = _gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
14854 
14855   if (widget->priv->margin.left == margin)
14856     return;
14857 
14858   widget->priv->margin.left = margin;
14859   gtk_widget_queue_resize (widget);
14860   g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_MARGIN_LEFT]);
14861   g_object_notify_by_pspec (G_OBJECT (widget), widget_props[rtl ? PROP_MARGIN_END : PROP_MARGIN_START]);
14862 }
14863 
14864 /**
14865  * gtk_widget_get_margin_right:
14866  * @widget: a #GtkWidget
14867  *
14868  * Gets the value of the #GtkWidget:margin-right property.
14869  *
14870  * Returns: The right margin of @widget
14871  *
14872  * Deprecated: 3.12: Use gtk_widget_get_margin_end() instead.
14873  *
14874  * Since: 3.0
14875  */
14876 gint
gtk_widget_get_margin_right(GtkWidget * widget)14877 gtk_widget_get_margin_right (GtkWidget *widget)
14878 {
14879   g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
14880 
14881   return widget->priv->margin.right;
14882 }
14883 
14884 /**
14885  * gtk_widget_set_margin_right:
14886  * @widget: a #GtkWidget
14887  * @margin: the right margin
14888  *
14889  * Sets the right margin of @widget.
14890  * See the #GtkWidget:margin-right property.
14891  *
14892  * Deprecated: 3.12: Use gtk_widget_set_margin_end() instead.
14893  *
14894  * Since: 3.0
14895  */
14896 void
gtk_widget_set_margin_right(GtkWidget * widget,gint margin)14897 gtk_widget_set_margin_right (GtkWidget *widget,
14898                              gint       margin)
14899 {
14900   gboolean rtl;
14901 
14902   g_return_if_fail (GTK_IS_WIDGET (widget));
14903   g_return_if_fail (margin <= G_MAXINT16);
14904 
14905   rtl = _gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
14906 
14907   if (widget->priv->margin.right == margin)
14908     return;
14909 
14910   widget->priv->margin.right = margin;
14911   gtk_widget_queue_resize (widget);
14912   g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_MARGIN_RIGHT]);
14913   g_object_notify_by_pspec (G_OBJECT (widget), widget_props[rtl ? PROP_MARGIN_START : PROP_MARGIN_END]);
14914 }
14915 
14916 /**
14917  * gtk_widget_get_margin_start:
14918  * @widget: a #GtkWidget
14919  *
14920  * Gets the value of the #GtkWidget:margin-start property.
14921  *
14922  * Returns: The start margin of @widget
14923  *
14924  * Since: 3.12
14925  */
14926 gint
gtk_widget_get_margin_start(GtkWidget * widget)14927 gtk_widget_get_margin_start (GtkWidget *widget)
14928 {
14929   g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
14930 
14931   if (_gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
14932     return widget->priv->margin.right;
14933   else
14934     return widget->priv->margin.left;
14935 }
14936 
14937 /**
14938  * gtk_widget_set_margin_start:
14939  * @widget: a #GtkWidget
14940  * @margin: the start margin
14941  *
14942  * Sets the start margin of @widget.
14943  * See the #GtkWidget:margin-start property.
14944  *
14945  * Since: 3.12
14946  */
14947 void
gtk_widget_set_margin_start(GtkWidget * widget,gint margin)14948 gtk_widget_set_margin_start (GtkWidget *widget,
14949                              gint       margin)
14950 {
14951   gint16 *start;
14952   gboolean rtl;
14953 
14954   g_return_if_fail (GTK_IS_WIDGET (widget));
14955   g_return_if_fail (margin <= G_MAXINT16);
14956 
14957   rtl = _gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
14958 
14959   if (rtl)
14960     start = &widget->priv->margin.right;
14961   else
14962     start = &widget->priv->margin.left;
14963 
14964   if (*start == margin)
14965     return;
14966 
14967   *start = margin;
14968   gtk_widget_queue_resize (widget);
14969   g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_MARGIN_START]);
14970   g_object_notify_by_pspec (G_OBJECT (widget), widget_props[rtl ? PROP_MARGIN_RIGHT : PROP_MARGIN_LEFT]);
14971 }
14972 
14973 /**
14974  * gtk_widget_get_margin_end:
14975  * @widget: a #GtkWidget
14976  *
14977  * Gets the value of the #GtkWidget:margin-end property.
14978  *
14979  * Returns: The end margin of @widget
14980  *
14981  * Since: 3.12
14982  */
14983 gint
gtk_widget_get_margin_end(GtkWidget * widget)14984 gtk_widget_get_margin_end (GtkWidget *widget)
14985 {
14986   g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
14987 
14988   if (_gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
14989     return widget->priv->margin.left;
14990   else
14991     return widget->priv->margin.right;
14992 }
14993 
14994 /**
14995  * gtk_widget_set_margin_end:
14996  * @widget: a #GtkWidget
14997  * @margin: the end margin
14998  *
14999  * Sets the end margin of @widget.
15000  * See the #GtkWidget:margin-end property.
15001  *
15002  * Since: 3.12
15003  */
15004 void
gtk_widget_set_margin_end(GtkWidget * widget,gint margin)15005 gtk_widget_set_margin_end (GtkWidget *widget,
15006                            gint       margin)
15007 {
15008   gint16 *end;
15009   gboolean rtl;
15010 
15011   g_return_if_fail (GTK_IS_WIDGET (widget));
15012   g_return_if_fail (margin <= G_MAXINT16);
15013 
15014   rtl = _gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
15015 
15016   if (rtl)
15017     end = &widget->priv->margin.left;
15018   else
15019     end = &widget->priv->margin.right;
15020 
15021   if (*end == margin)
15022     return;
15023 
15024   *end = margin;
15025   gtk_widget_queue_resize (widget);
15026   g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_MARGIN_END]);
15027   g_object_notify_by_pspec (G_OBJECT (widget), widget_props[rtl ? PROP_MARGIN_LEFT : PROP_MARGIN_RIGHT]);
15028 }
15029 
15030 /**
15031  * gtk_widget_get_margin_top:
15032  * @widget: a #GtkWidget
15033  *
15034  * Gets the value of the #GtkWidget:margin-top property.
15035  *
15036  * Returns: The top margin of @widget
15037  *
15038  * Since: 3.0
15039  */
15040 gint
gtk_widget_get_margin_top(GtkWidget * widget)15041 gtk_widget_get_margin_top (GtkWidget *widget)
15042 {
15043   g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
15044 
15045   return widget->priv->margin.top;
15046 }
15047 
15048 /**
15049  * gtk_widget_set_margin_top:
15050  * @widget: a #GtkWidget
15051  * @margin: the top margin
15052  *
15053  * Sets the top margin of @widget.
15054  * See the #GtkWidget:margin-top property.
15055  *
15056  * Since: 3.0
15057  */
15058 void
gtk_widget_set_margin_top(GtkWidget * widget,gint margin)15059 gtk_widget_set_margin_top (GtkWidget *widget,
15060                            gint       margin)
15061 {
15062   g_return_if_fail (GTK_IS_WIDGET (widget));
15063   g_return_if_fail (margin <= G_MAXINT16);
15064 
15065   if (widget->priv->margin.top == margin)
15066     return;
15067 
15068   widget->priv->margin.top = margin;
15069   gtk_widget_queue_resize (widget);
15070   g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_MARGIN_TOP]);
15071 }
15072 
15073 /**
15074  * gtk_widget_get_margin_bottom:
15075  * @widget: a #GtkWidget
15076  *
15077  * Gets the value of the #GtkWidget:margin-bottom property.
15078  *
15079  * Returns: The bottom margin of @widget
15080  *
15081  * Since: 3.0
15082  */
15083 gint
gtk_widget_get_margin_bottom(GtkWidget * widget)15084 gtk_widget_get_margin_bottom (GtkWidget *widget)
15085 {
15086   g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
15087 
15088   return widget->priv->margin.bottom;
15089 }
15090 
15091 /**
15092  * gtk_widget_set_margin_bottom:
15093  * @widget: a #GtkWidget
15094  * @margin: the bottom margin
15095  *
15096  * Sets the bottom margin of @widget.
15097  * See the #GtkWidget:margin-bottom property.
15098  *
15099  * Since: 3.0
15100  */
15101 void
gtk_widget_set_margin_bottom(GtkWidget * widget,gint margin)15102 gtk_widget_set_margin_bottom (GtkWidget *widget,
15103                               gint       margin)
15104 {
15105   g_return_if_fail (GTK_IS_WIDGET (widget));
15106   g_return_if_fail (margin <= G_MAXINT16);
15107 
15108   if (widget->priv->margin.bottom == margin)
15109     return;
15110 
15111   widget->priv->margin.bottom = margin;
15112   gtk_widget_queue_resize (widget);
15113   g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_MARGIN_BOTTOM]);
15114 }
15115 
15116 /**
15117  * gtk_widget_get_clipboard:
15118  * @widget: a #GtkWidget
15119  * @selection: a #GdkAtom which identifies the clipboard
15120  *             to use. %GDK_SELECTION_CLIPBOARD gives the
15121  *             default clipboard. Another common value
15122  *             is %GDK_SELECTION_PRIMARY, which gives
15123  *             the primary X selection.
15124  *
15125  * Returns the clipboard object for the given selection to
15126  * be used with @widget. @widget must have a #GdkDisplay
15127  * associated with it, so must be attached to a toplevel
15128  * window.
15129  *
15130  * Returns: (transfer none): the appropriate clipboard object. If no
15131  *             clipboard already exists, a new one will
15132  *             be created. Once a clipboard object has
15133  *             been created, it is persistent for all time.
15134  *
15135  * Since: 2.2
15136  **/
15137 GtkClipboard *
gtk_widget_get_clipboard(GtkWidget * widget,GdkAtom selection)15138 gtk_widget_get_clipboard (GtkWidget *widget, GdkAtom selection)
15139 {
15140   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
15141   g_return_val_if_fail (gtk_widget_has_screen (widget), NULL);
15142 
15143   return gtk_clipboard_get_for_display (gtk_widget_get_display (widget),
15144 					selection);
15145 }
15146 
15147 /**
15148  * gtk_widget_list_mnemonic_labels:
15149  * @widget: a #GtkWidget
15150  *
15151  * Returns a newly allocated list of the widgets, normally labels, for
15152  * which this widget is the target of a mnemonic (see for example,
15153  * gtk_label_set_mnemonic_widget()).
15154 
15155  * The widgets in the list are not individually referenced. If you
15156  * want to iterate through the list and perform actions involving
15157  * callbacks that might destroy the widgets, you
15158  * must call `g_list_foreach (result,
15159  * (GFunc)g_object_ref, NULL)` first, and then unref all the
15160  * widgets afterwards.
15161 
15162  * Returns: (element-type GtkWidget) (transfer container): the list of
15163  *  mnemonic labels; free this list
15164  *  with g_list_free() when you are done with it.
15165  *
15166  * Since: 2.4
15167  **/
15168 GList *
gtk_widget_list_mnemonic_labels(GtkWidget * widget)15169 gtk_widget_list_mnemonic_labels (GtkWidget *widget)
15170 {
15171   GList *list = NULL;
15172   GSList *l;
15173 
15174   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
15175 
15176   for (l = g_object_get_qdata (G_OBJECT (widget), quark_mnemonic_labels); l; l = l->next)
15177     list = g_list_prepend (list, l->data);
15178 
15179   return list;
15180 }
15181 
15182 /**
15183  * gtk_widget_add_mnemonic_label:
15184  * @widget: a #GtkWidget
15185  * @label: a #GtkWidget that acts as a mnemonic label for @widget
15186  *
15187  * Adds a widget to the list of mnemonic labels for
15188  * this widget. (See gtk_widget_list_mnemonic_labels()). Note the
15189  * list of mnemonic labels for the widget is cleared when the
15190  * widget is destroyed, so the caller must make sure to update
15191  * its internal state at this point as well, by using a connection
15192  * to the #GtkWidget::destroy signal or a weak notifier.
15193  *
15194  * Since: 2.4
15195  **/
15196 void
gtk_widget_add_mnemonic_label(GtkWidget * widget,GtkWidget * label)15197 gtk_widget_add_mnemonic_label (GtkWidget *widget,
15198                                GtkWidget *label)
15199 {
15200   GSList *old_list, *new_list;
15201 
15202   g_return_if_fail (GTK_IS_WIDGET (widget));
15203   g_return_if_fail (GTK_IS_WIDGET (label));
15204 
15205   old_list = g_object_steal_qdata (G_OBJECT (widget), quark_mnemonic_labels);
15206   new_list = g_slist_prepend (old_list, label);
15207 
15208   g_object_set_qdata_full (G_OBJECT (widget), quark_mnemonic_labels,
15209 			   new_list, (GDestroyNotify) g_slist_free);
15210 }
15211 
15212 /**
15213  * gtk_widget_remove_mnemonic_label:
15214  * @widget: a #GtkWidget
15215  * @label: a #GtkWidget that was previously set as a mnemonic label for
15216  *         @widget with gtk_widget_add_mnemonic_label().
15217  *
15218  * Removes a widget from the list of mnemonic labels for
15219  * this widget. (See gtk_widget_list_mnemonic_labels()). The widget
15220  * must have previously been added to the list with
15221  * gtk_widget_add_mnemonic_label().
15222  *
15223  * Since: 2.4
15224  **/
15225 void
gtk_widget_remove_mnemonic_label(GtkWidget * widget,GtkWidget * label)15226 gtk_widget_remove_mnemonic_label (GtkWidget *widget,
15227                                   GtkWidget *label)
15228 {
15229   GSList *old_list, *new_list;
15230 
15231   g_return_if_fail (GTK_IS_WIDGET (widget));
15232   g_return_if_fail (GTK_IS_WIDGET (label));
15233 
15234   old_list = g_object_steal_qdata (G_OBJECT (widget), quark_mnemonic_labels);
15235   new_list = g_slist_remove (old_list, label);
15236 
15237   if (new_list)
15238     g_object_set_qdata_full (G_OBJECT (widget), quark_mnemonic_labels,
15239 			     new_list, (GDestroyNotify) g_slist_free);
15240 }
15241 
15242 /**
15243  * gtk_widget_get_no_show_all:
15244  * @widget: a #GtkWidget
15245  *
15246  * Returns the current value of the #GtkWidget:no-show-all property,
15247  * which determines whether calls to gtk_widget_show_all()
15248  * will affect this widget.
15249  *
15250  * Returns: the current value of the “no-show-all” property.
15251  *
15252  * Since: 2.4
15253  **/
15254 gboolean
gtk_widget_get_no_show_all(GtkWidget * widget)15255 gtk_widget_get_no_show_all (GtkWidget *widget)
15256 {
15257   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
15258 
15259   return widget->priv->no_show_all;
15260 }
15261 
15262 /**
15263  * gtk_widget_set_no_show_all:
15264  * @widget: a #GtkWidget
15265  * @no_show_all: the new value for the “no-show-all” property
15266  *
15267  * Sets the #GtkWidget:no-show-all property, which determines whether
15268  * calls to gtk_widget_show_all() will affect this widget.
15269  *
15270  * This is mostly for use in constructing widget hierarchies with externally
15271  * controlled visibility, see #GtkUIManager.
15272  *
15273  * Since: 2.4
15274  **/
15275 void
gtk_widget_set_no_show_all(GtkWidget * widget,gboolean no_show_all)15276 gtk_widget_set_no_show_all (GtkWidget *widget,
15277 			    gboolean   no_show_all)
15278 {
15279   g_return_if_fail (GTK_IS_WIDGET (widget));
15280 
15281   no_show_all = (no_show_all != FALSE);
15282 
15283   if (widget->priv->no_show_all != no_show_all)
15284     {
15285       widget->priv->no_show_all = no_show_all;
15286 
15287       g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_NO_SHOW_ALL]);
15288     }
15289 }
15290 
15291 
15292 static void
gtk_widget_real_set_has_tooltip(GtkWidget * widget,gboolean has_tooltip,gboolean force)15293 gtk_widget_real_set_has_tooltip (GtkWidget *widget,
15294 			         gboolean   has_tooltip,
15295 			         gboolean   force)
15296 {
15297   GtkWidgetPrivate *priv = widget->priv;
15298 
15299   if (priv->has_tooltip != has_tooltip || force)
15300     {
15301       priv->has_tooltip = has_tooltip;
15302 
15303       if (priv->has_tooltip)
15304         {
15305 	  if (_gtk_widget_get_realized (widget) && !_gtk_widget_get_has_window (widget))
15306 	    gdk_window_set_events (priv->window,
15307 				   gdk_window_get_events (priv->window) |
15308 				   GDK_LEAVE_NOTIFY_MASK |
15309 				   GDK_POINTER_MOTION_MASK);
15310 
15311 	  if (_gtk_widget_get_has_window (widget))
15312 	      gtk_widget_add_events (widget,
15313 				     GDK_LEAVE_NOTIFY_MASK |
15314 				     GDK_POINTER_MOTION_MASK);
15315 	}
15316 
15317       g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_HAS_TOOLTIP]);
15318     }
15319 }
15320 
15321 /**
15322  * gtk_widget_set_tooltip_window:
15323  * @widget: a #GtkWidget
15324  * @custom_window: (allow-none): a #GtkWindow, or %NULL
15325  *
15326  * Replaces the default window used for displaying
15327  * tooltips with @custom_window. GTK+ will take care of showing and
15328  * hiding @custom_window at the right moment, to behave likewise as
15329  * the default tooltip window. If @custom_window is %NULL, the default
15330  * tooltip window will be used.
15331  *
15332  * Since: 2.12
15333  */
15334 void
gtk_widget_set_tooltip_window(GtkWidget * widget,GtkWindow * custom_window)15335 gtk_widget_set_tooltip_window (GtkWidget *widget,
15336 			       GtkWindow *custom_window)
15337 {
15338   gboolean has_tooltip;
15339   gchar *tooltip_markup;
15340 
15341   g_return_if_fail (GTK_IS_WIDGET (widget));
15342   g_return_if_fail (custom_window == NULL || GTK_IS_WINDOW (custom_window));
15343 
15344   tooltip_markup = g_object_get_qdata (G_OBJECT (widget), quark_tooltip_markup);
15345 
15346   if (custom_window)
15347     g_object_ref (custom_window);
15348 
15349   g_object_set_qdata_full (G_OBJECT (widget), quark_tooltip_window,
15350 			   custom_window, g_object_unref);
15351 
15352   has_tooltip = (custom_window != NULL || tooltip_markup != NULL);
15353   gtk_widget_real_set_has_tooltip (widget, has_tooltip, FALSE);
15354 
15355   if (has_tooltip && _gtk_widget_get_visible (widget))
15356     gtk_widget_queue_tooltip_query (widget);
15357 }
15358 
15359 /**
15360  * gtk_widget_get_tooltip_window:
15361  * @widget: a #GtkWidget
15362  *
15363  * Returns the #GtkWindow of the current tooltip. This can be the
15364  * GtkWindow created by default, or the custom tooltip window set
15365  * using gtk_widget_set_tooltip_window().
15366  *
15367  * Returns: (transfer none): The #GtkWindow of the current tooltip.
15368  *
15369  * Since: 2.12
15370  */
15371 GtkWindow *
gtk_widget_get_tooltip_window(GtkWidget * widget)15372 gtk_widget_get_tooltip_window (GtkWidget *widget)
15373 {
15374   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
15375 
15376   return g_object_get_qdata (G_OBJECT (widget), quark_tooltip_window);
15377 }
15378 
15379 /**
15380  * gtk_widget_trigger_tooltip_query:
15381  * @widget: a #GtkWidget
15382  *
15383  * Triggers a tooltip query on the display where the toplevel of @widget
15384  * is located. See gtk_tooltip_trigger_tooltip_query() for more
15385  * information.
15386  *
15387  * Since: 2.12
15388  */
15389 void
gtk_widget_trigger_tooltip_query(GtkWidget * widget)15390 gtk_widget_trigger_tooltip_query (GtkWidget *widget)
15391 {
15392   gtk_tooltip_trigger_tooltip_query (gtk_widget_get_display (widget));
15393 }
15394 
15395 static guint tooltip_query_id;
15396 static GSList *tooltip_query_displays;
15397 
15398 static gboolean
tooltip_query_idle(gpointer data)15399 tooltip_query_idle (gpointer data)
15400 {
15401   g_slist_foreach (tooltip_query_displays, (GFunc)gtk_tooltip_trigger_tooltip_query, NULL);
15402   g_slist_free_full (tooltip_query_displays, g_object_unref);
15403 
15404   tooltip_query_displays = NULL;
15405   tooltip_query_id = 0;
15406 
15407   return FALSE;
15408 }
15409 
15410 static void
gtk_widget_queue_tooltip_query(GtkWidget * widget)15411 gtk_widget_queue_tooltip_query (GtkWidget *widget)
15412 {
15413   GdkDisplay *display;
15414 
15415   display = gtk_widget_get_display (widget);
15416 
15417   if (!g_slist_find (tooltip_query_displays, display))
15418     tooltip_query_displays = g_slist_prepend (tooltip_query_displays, g_object_ref (display));
15419 
15420   if (tooltip_query_id == 0)
15421     {
15422       tooltip_query_id = gdk_threads_add_idle (tooltip_query_idle, NULL);
15423       g_source_set_name_by_id (tooltip_query_id, "[gtk+] tooltip_query_idle");
15424     }
15425 }
15426 
15427 /**
15428  * gtk_widget_set_tooltip_text:
15429  * @widget: a #GtkWidget
15430  * @text: (allow-none): the contents of the tooltip for @widget
15431  *
15432  * Sets @text as the contents of the tooltip. This function will take
15433  * care of setting #GtkWidget:has-tooltip to %TRUE and of the default
15434  * handler for the #GtkWidget::query-tooltip signal.
15435  *
15436  * See also the #GtkWidget:tooltip-text property and gtk_tooltip_set_text().
15437  *
15438  * Since: 2.12
15439  */
15440 void
gtk_widget_set_tooltip_text(GtkWidget * widget,const gchar * text)15441 gtk_widget_set_tooltip_text (GtkWidget   *widget,
15442                              const gchar *text)
15443 {
15444   g_return_if_fail (GTK_IS_WIDGET (widget));
15445 
15446   g_object_set (G_OBJECT (widget), "tooltip-text", text, NULL);
15447 }
15448 
15449 /**
15450  * gtk_widget_get_tooltip_text:
15451  * @widget: a #GtkWidget
15452  *
15453  * Gets the contents of the tooltip for @widget.
15454  *
15455  * Returns: (nullable): the tooltip text, or %NULL. You should free the
15456  *   returned string with g_free() when done.
15457  *
15458  * Since: 2.12
15459  */
15460 gchar *
gtk_widget_get_tooltip_text(GtkWidget * widget)15461 gtk_widget_get_tooltip_text (GtkWidget *widget)
15462 {
15463   gchar *text = NULL;
15464 
15465   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
15466 
15467   g_object_get (G_OBJECT (widget), "tooltip-text", &text, NULL);
15468 
15469   return text;
15470 }
15471 
15472 /**
15473  * gtk_widget_set_tooltip_markup:
15474  * @widget: a #GtkWidget
15475  * @markup: (allow-none): the contents of the tooltip for @widget, or %NULL
15476  *
15477  * Sets @markup as the contents of the tooltip, which is marked up with
15478  *  the [Pango text markup language][PangoMarkupFormat].
15479  *
15480  * This function will take care of setting #GtkWidget:has-tooltip to %TRUE
15481  * and of the default handler for the #GtkWidget::query-tooltip signal.
15482  *
15483  * See also the #GtkWidget:tooltip-markup property and
15484  * gtk_tooltip_set_markup().
15485  *
15486  * Since: 2.12
15487  */
15488 void
gtk_widget_set_tooltip_markup(GtkWidget * widget,const gchar * markup)15489 gtk_widget_set_tooltip_markup (GtkWidget   *widget,
15490                                const gchar *markup)
15491 {
15492   g_return_if_fail (GTK_IS_WIDGET (widget));
15493 
15494   g_object_set (G_OBJECT (widget), "tooltip-markup", markup, NULL);
15495 }
15496 
15497 /**
15498  * gtk_widget_get_tooltip_markup:
15499  * @widget: a #GtkWidget
15500  *
15501  * Gets the contents of the tooltip for @widget.
15502  *
15503  * Returns: (nullable): the tooltip text, or %NULL. You should free the
15504  *   returned string with g_free() when done.
15505  *
15506  * Since: 2.12
15507  */
15508 gchar *
gtk_widget_get_tooltip_markup(GtkWidget * widget)15509 gtk_widget_get_tooltip_markup (GtkWidget *widget)
15510 {
15511   gchar *text = NULL;
15512 
15513   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
15514 
15515   g_object_get (G_OBJECT (widget), "tooltip-markup", &text, NULL);
15516 
15517   return text;
15518 }
15519 
15520 /**
15521  * gtk_widget_set_has_tooltip:
15522  * @widget: a #GtkWidget
15523  * @has_tooltip: whether or not @widget has a tooltip.
15524  *
15525  * Sets the has-tooltip property on @widget to @has_tooltip.  See
15526  * #GtkWidget:has-tooltip for more information.
15527  *
15528  * Since: 2.12
15529  */
15530 void
gtk_widget_set_has_tooltip(GtkWidget * widget,gboolean has_tooltip)15531 gtk_widget_set_has_tooltip (GtkWidget *widget,
15532 			    gboolean   has_tooltip)
15533 {
15534   g_return_if_fail (GTK_IS_WIDGET (widget));
15535 
15536   gtk_widget_real_set_has_tooltip (widget, has_tooltip, FALSE);
15537 }
15538 
15539 /**
15540  * gtk_widget_get_has_tooltip:
15541  * @widget: a #GtkWidget
15542  *
15543  * Returns the current value of the has-tooltip property.  See
15544  * #GtkWidget:has-tooltip for more information.
15545  *
15546  * Returns: current value of has-tooltip on @widget.
15547  *
15548  * Since: 2.12
15549  */
15550 gboolean
gtk_widget_get_has_tooltip(GtkWidget * widget)15551 gtk_widget_get_has_tooltip (GtkWidget *widget)
15552 {
15553   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
15554 
15555   return widget->priv->has_tooltip;
15556 }
15557 
15558 /**
15559  * gtk_widget_get_clip:
15560  * @widget: a #GtkWidget
15561  * @clip: (out): a pointer to a #GtkAllocation to copy to
15562  *
15563  * Retrieves the widget’s clip area.
15564  *
15565  * The clip area is the area in which all of @widget's drawing will
15566  * happen. Other toolkits call it the bounding box.
15567  *
15568  * Historically, in GTK+ the clip area has been equal to the allocation
15569  * retrieved via gtk_widget_get_allocation().
15570  *
15571  * Since: 3.14
15572  */
15573 void
gtk_widget_get_clip(GtkWidget * widget,GtkAllocation * clip)15574 gtk_widget_get_clip (GtkWidget     *widget,
15575                      GtkAllocation *clip)
15576 {
15577   GtkWidgetPrivate *priv;
15578 
15579   g_return_if_fail (GTK_IS_WIDGET (widget));
15580   g_return_if_fail (clip != NULL);
15581 
15582   priv = widget->priv;
15583 
15584   *clip = priv->clip;
15585 }
15586 
15587 /**
15588  * gtk_widget_set_clip:
15589  * @widget: a #GtkWidget
15590  * @clip: a pointer to a #GtkAllocation to copy from
15591  *
15592  * Sets the widget’s clip.  This must not be used directly,
15593  * but from within a widget’s size_allocate method.
15594  * It must be called after gtk_widget_set_allocation() (or after chaining up
15595  * to the parent class), because that function resets the clip.
15596  *
15597  * The clip set should be the area that @widget draws on. If @widget is a
15598  * #GtkContainer, the area must contain all children's clips.
15599  *
15600  * If this function is not called by @widget during a ::size-allocate handler,
15601  * the clip will be set to @widget's allocation.
15602  *
15603  * Since: 3.14
15604  */
15605 void
gtk_widget_set_clip(GtkWidget * widget,const GtkAllocation * clip)15606 gtk_widget_set_clip (GtkWidget           *widget,
15607                      const GtkAllocation *clip)
15608 {
15609   GtkWidgetPrivate *priv;
15610 
15611   g_return_if_fail (GTK_IS_WIDGET (widget));
15612   g_return_if_fail (_gtk_widget_get_visible (widget) || _gtk_widget_is_toplevel (widget));
15613   g_return_if_fail (clip != NULL);
15614 
15615   priv = widget->priv;
15616 
15617 #ifdef G_ENABLE_DEBUG
15618   if (GTK_DEBUG_CHECK (GEOMETRY))
15619     {
15620       gint depth;
15621       GtkWidget *parent;
15622       const gchar *name;
15623 
15624       depth = 0;
15625       parent = widget;
15626       while (parent)
15627 	{
15628 	  depth++;
15629 	  parent = _gtk_widget_get_parent (parent);
15630 	}
15631 
15632       name = g_type_name (G_OBJECT_TYPE (G_OBJECT (widget)));
15633       g_message ("gtk_widget_set_clip:      %*s%s %d %d %d %d",
15634 	         2 * depth, " ", name,
15635 	         clip->x, clip->y,
15636 	         clip->width, clip->height);
15637     }
15638 #endif /* G_ENABLE_DEBUG */
15639 
15640   priv->clip = *clip;
15641 
15642   while (priv->parent &&
15643          _gtk_widget_get_window (widget) == _gtk_widget_get_window (priv->parent))
15644     {
15645       GtkWidgetPrivate *parent_priv = priv->parent->priv;
15646       GdkRectangle union_rect;
15647 
15648       gdk_rectangle_union (&priv->clip,
15649                            &parent_priv->clip,
15650                            &union_rect);
15651 
15652       if (gdk_rectangle_equal (&parent_priv->clip, &union_rect))
15653         break;
15654 
15655       parent_priv->clip = union_rect;
15656       priv = parent_priv;
15657     }
15658 }
15659 
15660 /*
15661  * _gtk_widget_set_simple_clip:
15662  * @widget: a #GtkWidget
15663  * @content_clip: (nullable): Clipping area of the contents
15664  *     or %NULL, if the contents
15665  *     do not extent the allocation.
15666  *
15667  * This is a convenience function for gtk_widget_set_clip(), if you
15668  * just want to set the clip for @widget based on its allocation,
15669  * CSS properties and - if the widget is a #GtkContainer - its
15670  * children. gtk_widget_set_allocation() must have been called
15671  * and all children must have been allocated with
15672  * gtk_widget_size_allocate() before calling this function.
15673  * It is therefore a good idea to call this function last in
15674  * your implementation of GtkWidget::size_allocate().
15675  *
15676  * If your widget overdraws its contents, you cannot use this
15677  * function and must call gtk_widget_set_clip() yourself.
15678  **/
15679 void
_gtk_widget_set_simple_clip(GtkWidget * widget,GtkAllocation * content_clip)15680 _gtk_widget_set_simple_clip (GtkWidget     *widget,
15681                              GtkAllocation *content_clip)
15682 {
15683   GtkStyleContext *context;
15684   GtkAllocation clip, allocation;
15685   GtkBorder extents;
15686 
15687   context = _gtk_widget_get_style_context (widget);
15688 
15689   _gtk_widget_get_allocation (widget, &allocation);
15690 
15691   _gtk_css_shadows_value_get_extents (_gtk_style_context_peek_property (context,
15692                                                                         GTK_CSS_PROPERTY_BOX_SHADOW),
15693                                       &extents);
15694 
15695   clip = allocation;
15696   clip.x -= extents.left;
15697   clip.y -= extents.top;
15698   clip.width += extents.left + extents.right;
15699   clip.height += extents.top + extents.bottom;
15700 
15701   if (content_clip)
15702     gdk_rectangle_union (content_clip, &clip, &clip);
15703 
15704   if (GTK_IS_CONTAINER (widget))
15705     {
15706       GdkRectangle children_clip;
15707 
15708       gtk_container_get_children_clip (GTK_CONTAINER (widget), &children_clip);
15709 
15710       if (_gtk_widget_get_has_window (widget))
15711         {
15712           children_clip.x += allocation.x;
15713           children_clip.y += allocation.y;
15714         }
15715 
15716       gdk_rectangle_union (&children_clip, &clip, &clip);
15717     }
15718 
15719   gtk_widget_set_clip (widget, &clip);
15720 }
15721 
15722 /**
15723  * gtk_widget_get_allocated_size:
15724  * @widget: a #GtkWidget
15725  * @allocation: (out): a pointer to a #GtkAllocation to copy to
15726  * @baseline: (out) (allow-none): a pointer to an integer to copy to
15727  *
15728  * Retrieves the widget’s allocated size.
15729  *
15730  * This function returns the last values passed to
15731  * gtk_widget_size_allocate_with_baseline(). The value differs from
15732  * the size returned in gtk_widget_get_allocation() in that functions
15733  * like gtk_widget_set_halign() can adjust the allocation, but not
15734  * the value returned by this function.
15735  *
15736  * If a widget is not visible, its allocated size is 0.
15737  *
15738  * Since: 3.20
15739  */
15740 void
gtk_widget_get_allocated_size(GtkWidget * widget,GtkAllocation * allocation,int * baseline)15741 gtk_widget_get_allocated_size (GtkWidget     *widget,
15742                                GtkAllocation *allocation,
15743                                int           *baseline)
15744 {
15745   GtkWidgetPrivate *priv;
15746 
15747   g_return_if_fail (GTK_IS_WIDGET (widget));
15748   g_return_if_fail (allocation != NULL);
15749 
15750   priv = widget->priv;
15751 
15752   *allocation = priv->allocated_size;
15753 
15754   if (baseline)
15755     *baseline = priv->allocated_size_baseline;
15756 }
15757 
15758 /**
15759  * gtk_widget_get_allocation:
15760  * @widget: a #GtkWidget
15761  * @allocation: (out): a pointer to a #GtkAllocation to copy to
15762  *
15763  * Retrieves the widget’s allocation.
15764  *
15765  * Note, when implementing a #GtkContainer: a widget’s allocation will
15766  * be its “adjusted” allocation, that is, the widget’s parent
15767  * container typically calls gtk_widget_size_allocate() with an
15768  * allocation, and that allocation is then adjusted (to handle margin
15769  * and alignment for example) before assignment to the widget.
15770  * gtk_widget_get_allocation() returns the adjusted allocation that
15771  * was actually assigned to the widget. The adjusted allocation is
15772  * guaranteed to be completely contained within the
15773  * gtk_widget_size_allocate() allocation, however. So a #GtkContainer
15774  * is guaranteed that its children stay inside the assigned bounds,
15775  * but not that they have exactly the bounds the container assigned.
15776  * There is no way to get the original allocation assigned by
15777  * gtk_widget_size_allocate(), since it isn’t stored; if a container
15778  * implementation needs that information it will have to track it itself.
15779  *
15780  * Since: 2.18
15781  */
15782 void
gtk_widget_get_allocation(GtkWidget * widget,GtkAllocation * allocation)15783 gtk_widget_get_allocation (GtkWidget     *widget,
15784                            GtkAllocation *allocation)
15785 {
15786   GtkWidgetPrivate *priv;
15787 
15788   g_return_if_fail (GTK_IS_WIDGET (widget));
15789   g_return_if_fail (allocation != NULL);
15790 
15791   priv = widget->priv;
15792 
15793   *allocation = priv->allocation;
15794 }
15795 
15796 /**
15797  * gtk_widget_set_allocation:
15798  * @widget: a #GtkWidget
15799  * @allocation: a pointer to a #GtkAllocation to copy from
15800  *
15801  * Sets the widget’s allocation.  This should not be used
15802  * directly, but from within a widget’s size_allocate method.
15803  *
15804  * The allocation set should be the “adjusted” or actual
15805  * allocation. If you’re implementing a #GtkContainer, you want to use
15806  * gtk_widget_size_allocate() instead of gtk_widget_set_allocation().
15807  * The GtkWidgetClass::adjust_size_allocation virtual method adjusts the
15808  * allocation inside gtk_widget_size_allocate() to create an adjusted
15809  * allocation.
15810  *
15811  * Since: 2.18
15812  */
15813 void
gtk_widget_set_allocation(GtkWidget * widget,const GtkAllocation * allocation)15814 gtk_widget_set_allocation (GtkWidget           *widget,
15815                            const GtkAllocation *allocation)
15816 {
15817   GtkWidgetPrivate *priv;
15818 
15819   g_return_if_fail (GTK_IS_WIDGET (widget));
15820   g_return_if_fail (_gtk_widget_get_visible (widget) || _gtk_widget_is_toplevel (widget));
15821   g_return_if_fail (allocation != NULL);
15822 
15823   priv = widget->priv;
15824 
15825   priv->allocation = *allocation;
15826   priv->clip = *allocation;
15827 }
15828 
15829 /**
15830  * gtk_widget_get_allocated_width:
15831  * @widget: the widget to query
15832  *
15833  * Returns the width that has currently been allocated to @widget.
15834  * This function is intended to be used when implementing handlers
15835  * for the #GtkWidget::draw function.
15836  *
15837  * Returns: the width of the @widget
15838  **/
15839 int
gtk_widget_get_allocated_width(GtkWidget * widget)15840 gtk_widget_get_allocated_width (GtkWidget *widget)
15841 {
15842   g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
15843 
15844   return widget->priv->allocation.width;
15845 }
15846 
15847 /**
15848  * gtk_widget_get_allocated_height:
15849  * @widget: the widget to query
15850  *
15851  * Returns the height that has currently been allocated to @widget.
15852  * This function is intended to be used when implementing handlers
15853  * for the #GtkWidget::draw function.
15854  *
15855  * Returns: the height of the @widget
15856  **/
15857 int
gtk_widget_get_allocated_height(GtkWidget * widget)15858 gtk_widget_get_allocated_height (GtkWidget *widget)
15859 {
15860   g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
15861 
15862   return widget->priv->allocation.height;
15863 }
15864 
15865 /**
15866  * gtk_widget_get_allocated_baseline:
15867  * @widget: the widget to query
15868  *
15869  * Returns the baseline that has currently been allocated to @widget.
15870  * This function is intended to be used when implementing handlers
15871  * for the #GtkWidget::draw function, and when allocating child
15872  * widgets in #GtkWidget::size_allocate.
15873  *
15874  * Returns: the baseline of the @widget, or -1 if none
15875  *
15876  * Since: 3.10
15877  **/
15878 int
gtk_widget_get_allocated_baseline(GtkWidget * widget)15879 gtk_widget_get_allocated_baseline (GtkWidget *widget)
15880 {
15881   g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
15882 
15883   return widget->priv->allocated_baseline;
15884 }
15885 
15886 /**
15887  * gtk_widget_get_requisition:
15888  * @widget: a #GtkWidget
15889  * @requisition: (out): a pointer to a #GtkRequisition to copy to
15890  *
15891  * Retrieves the widget’s requisition.
15892  *
15893  * This function should only be used by widget implementations in
15894  * order to figure whether the widget’s requisition has actually
15895  * changed after some internal state change (so that they can call
15896  * gtk_widget_queue_resize() instead of gtk_widget_queue_draw()).
15897  *
15898  * Normally, gtk_widget_size_request() should be used.
15899  *
15900  * Since: 2.20
15901  *
15902  * Deprecated: 3.0: The #GtkRequisition cache on the widget was
15903  * removed, If you need to cache sizes across requests and allocations,
15904  * add an explicit cache to the widget in question instead.
15905  */
15906 void
gtk_widget_get_requisition(GtkWidget * widget,GtkRequisition * requisition)15907 gtk_widget_get_requisition (GtkWidget      *widget,
15908                             GtkRequisition *requisition)
15909 {
15910   g_return_if_fail (GTK_IS_WIDGET (widget));
15911   g_return_if_fail (requisition != NULL);
15912 
15913   gtk_widget_get_preferred_size (widget, requisition, NULL);
15914 }
15915 
15916 /**
15917  * gtk_widget_set_window:
15918  * @widget: a #GtkWidget
15919  * @window: (transfer full): a #GdkWindow
15920  *
15921  * Sets a widget’s window. This function should only be used in a
15922  * widget’s #GtkWidget::realize implementation. The %window passed is
15923  * usually either new window created with gdk_window_new(), or the
15924  * window of its parent widget as returned by
15925  * gtk_widget_get_parent_window().
15926  *
15927  * Widgets must indicate whether they will create their own #GdkWindow
15928  * by calling gtk_widget_set_has_window(). This is usually done in the
15929  * widget’s init() function.
15930  *
15931  * Note that this function does not add any reference to @window.
15932  *
15933  * Since: 2.18
15934  */
15935 void
gtk_widget_set_window(GtkWidget * widget,GdkWindow * window)15936 gtk_widget_set_window (GtkWidget *widget,
15937                        GdkWindow *window)
15938 {
15939   GtkWidgetPrivate *priv;
15940 
15941   g_return_if_fail (GTK_IS_WIDGET (widget));
15942   g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
15943 
15944   priv = widget->priv;
15945 
15946   if (priv->window != window)
15947     {
15948       priv->window = window;
15949 
15950       g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_WINDOW]);
15951     }
15952 }
15953 
15954 /**
15955  * gtk_widget_register_window:
15956  * @widget: a #GtkWidget
15957  * @window: a #GdkWindow
15958  *
15959  * Registers a #GdkWindow with the widget and sets it up so that
15960  * the widget receives events for it. Call gtk_widget_unregister_window()
15961  * when destroying the window.
15962  *
15963  * Before 3.8 you needed to call gdk_window_set_user_data() directly to set
15964  * this up. This is now deprecated and you should use gtk_widget_register_window()
15965  * instead. Old code will keep working as is, although some new features like
15966  * transparency might not work perfectly.
15967  *
15968  * Since: 3.8
15969  */
15970 void
gtk_widget_register_window(GtkWidget * widget,GdkWindow * window)15971 gtk_widget_register_window (GtkWidget    *widget,
15972 			    GdkWindow    *window)
15973 {
15974   GtkWidgetPrivate *priv;
15975   gpointer user_data;
15976 
15977   g_return_if_fail (GTK_IS_WIDGET (widget));
15978   g_return_if_fail (GDK_IS_WINDOW (window));
15979 
15980   gdk_window_get_user_data (window, &user_data);
15981   g_assert (user_data == NULL);
15982 
15983   priv = widget->priv;
15984 
15985   gdk_window_set_user_data (window, widget);
15986   priv->registered_windows = g_list_prepend (priv->registered_windows, window);
15987 }
15988 
15989 /**
15990  * gtk_widget_unregister_window:
15991  * @widget: a #GtkWidget
15992  * @window: a #GdkWindow
15993  *
15994  * Unregisters a #GdkWindow from the widget that was previously set up with
15995  * gtk_widget_register_window(). You need to call this when the window is
15996  * no longer used by the widget, such as when you destroy it.
15997  *
15998  * Since: 3.8
15999  */
16000 void
gtk_widget_unregister_window(GtkWidget * widget,GdkWindow * window)16001 gtk_widget_unregister_window (GtkWidget    *widget,
16002 			      GdkWindow    *window)
16003 {
16004   GtkWidgetPrivate *priv;
16005   gpointer user_data;
16006 
16007   g_return_if_fail (GTK_IS_WIDGET (widget));
16008   g_return_if_fail (GDK_IS_WINDOW (window));
16009 
16010   priv = widget->priv;
16011 
16012   gdk_window_get_user_data (window, &user_data);
16013   g_assert (user_data == widget);
16014   gdk_window_set_user_data (window, NULL);
16015   priv->registered_windows = g_list_remove (priv->registered_windows, window);
16016 }
16017 
16018 /**
16019  * gtk_widget_get_window:
16020  * @widget: a #GtkWidget
16021  *
16022  * Returns the widget’s window if it is realized, %NULL otherwise
16023  *
16024  * Returns: (transfer none) (nullable): @widget’s window.
16025  *
16026  * Since: 2.14
16027  */
16028 GdkWindow*
gtk_widget_get_window(GtkWidget * widget)16029 gtk_widget_get_window (GtkWidget *widget)
16030 {
16031   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
16032 
16033   return widget->priv->window;
16034 }
16035 
16036 /**
16037  * gtk_widget_get_support_multidevice:
16038  * @widget: a #GtkWidget
16039  *
16040  * Returns %TRUE if @widget is multiple pointer aware. See
16041  * gtk_widget_set_support_multidevice() for more information.
16042  *
16043  * Returns: %TRUE if @widget is multidevice aware.
16044  **/
16045 gboolean
gtk_widget_get_support_multidevice(GtkWidget * widget)16046 gtk_widget_get_support_multidevice (GtkWidget *widget)
16047 {
16048   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
16049 
16050   return widget->priv->multidevice;
16051 }
16052 
16053 /**
16054  * gtk_widget_set_support_multidevice:
16055  * @widget: a #GtkWidget
16056  * @support_multidevice: %TRUE to support input from multiple devices.
16057  *
16058  * Enables or disables multiple pointer awareness. If this setting is %TRUE,
16059  * @widget will start receiving multiple, per device enter/leave events. Note
16060  * that if custom #GdkWindows are created in #GtkWidget::realize,
16061  * gdk_window_set_support_multidevice() will have to be called manually on them.
16062  *
16063  * Since: 3.0
16064  **/
16065 void
gtk_widget_set_support_multidevice(GtkWidget * widget,gboolean support_multidevice)16066 gtk_widget_set_support_multidevice (GtkWidget *widget,
16067                                     gboolean   support_multidevice)
16068 {
16069   GtkWidgetPrivate *priv;
16070 
16071   g_return_if_fail (GTK_IS_WIDGET (widget));
16072 
16073   priv = widget->priv;
16074   priv->multidevice = (support_multidevice == TRUE);
16075 
16076   if (_gtk_widget_get_realized (widget))
16077     gdk_window_set_support_multidevice (priv->window, support_multidevice);
16078 }
16079 
16080 /* There are multiple alpha related sources. First of all the user can specify alpha
16081  * in gtk_widget_set_opacity, secondly we can get it from the CSS opacity. These two
16082  * are multiplied together to form the total alpha. Secondly, the user can specify
16083  * an opacity group for a widget, which means we must essentially handle it as having alpha.
16084  */
16085 
16086 static void
gtk_widget_update_alpha(GtkWidget * widget)16087 gtk_widget_update_alpha (GtkWidget *widget)
16088 {
16089   GtkWidgetPrivate *priv;
16090   GtkStyleContext *context;
16091   gdouble opacity;
16092   guint8 alpha;
16093 
16094   priv = widget->priv;
16095 
16096   context = _gtk_widget_get_style_context (widget);
16097   opacity =
16098     _gtk_css_number_value_get (_gtk_style_context_peek_property (context,
16099                                                                  GTK_CSS_PROPERTY_OPACITY),
16100                                100);
16101   opacity = CLAMP (opacity, 0.0, 1.0);
16102   alpha = round (priv->user_alpha * opacity);
16103 
16104   if (alpha == priv->alpha)
16105     return;
16106 
16107   priv->alpha = alpha;
16108 
16109   if (_gtk_widget_get_realized (widget))
16110     {
16111       if (_gtk_widget_is_toplevel (widget) &&
16112           gtk_widget_get_visual (widget) != gdk_screen_get_rgba_visual (gtk_widget_get_screen (widget)))
16113 	gdk_window_set_opacity (priv->window, priv->alpha / 255.0);
16114 
16115       gtk_widget_queue_draw (widget);
16116     }
16117 }
16118 
16119 /**
16120  * gtk_widget_set_opacity:
16121  * @widget: a #GtkWidget
16122  * @opacity: desired opacity, between 0 and 1
16123  *
16124  * Request the @widget to be rendered partially transparent,
16125  * with opacity 0 being fully transparent and 1 fully opaque. (Opacity values
16126  * are clamped to the [0,1] range.).
16127  * This works on both toplevel widget, and child widgets, although there
16128  * are some limitations:
16129  *
16130  * For toplevel widgets this depends on the capabilities of the windowing
16131  * system. On X11 this has any effect only on X screens with a compositing manager
16132  * running. See gtk_widget_is_composited(). On Windows it should work
16133  * always, although setting a window’s opacity after the window has been
16134  * shown causes it to flicker once on Windows.
16135  *
16136  * For child widgets it doesn’t work if any affected widget has a native window, or
16137  * disables double buffering.
16138  *
16139  * Since: 3.8
16140  **/
16141 void
gtk_widget_set_opacity(GtkWidget * widget,gdouble opacity)16142 gtk_widget_set_opacity (GtkWidget *widget,
16143                         gdouble    opacity)
16144 {
16145   GtkWidgetPrivate *priv;
16146   guint8 alpha;
16147 
16148   g_return_if_fail (GTK_IS_WIDGET (widget));
16149 
16150   priv = widget->priv;
16151 
16152   opacity = CLAMP (opacity, 0.0, 1.0);
16153 
16154   alpha = round (opacity * 255);
16155 
16156   if (alpha == priv->user_alpha)
16157     return;
16158 
16159   priv->user_alpha = alpha;
16160 
16161   gtk_widget_update_alpha (widget);
16162 
16163   g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_OPACITY]);
16164 }
16165 
16166 /**
16167  * gtk_widget_get_opacity:
16168  * @widget: a #GtkWidget
16169  *
16170  * Fetches the requested opacity for this widget.
16171  * See gtk_widget_set_opacity().
16172  *
16173  * Returns: the requested opacity for this widget.
16174  *
16175  * Since: 3.8
16176  **/
16177 gdouble
gtk_widget_get_opacity(GtkWidget * widget)16178 gtk_widget_get_opacity (GtkWidget *widget)
16179 {
16180   g_return_val_if_fail (GTK_IS_WIDGET (widget), 0.0);
16181 
16182   return widget->priv->user_alpha / 255.0;
16183 }
16184 
16185 static void
_gtk_widget_set_has_focus(GtkWidget * widget,gboolean has_focus)16186 _gtk_widget_set_has_focus (GtkWidget *widget,
16187                            gboolean   has_focus)
16188 {
16189   widget->priv->has_focus = has_focus;
16190 
16191   if (has_focus)
16192     gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_FOCUSED, FALSE);
16193   else
16194     gtk_widget_unset_state_flags (widget, GTK_STATE_FLAG_FOCUSED);
16195 }
16196 
16197 /**
16198  * gtk_widget_send_focus_change:
16199  * @widget: a #GtkWidget
16200  * @event: a #GdkEvent of type GDK_FOCUS_CHANGE
16201  *
16202  * Sends the focus change @event to @widget
16203  *
16204  * This function is not meant to be used by applications. The only time it
16205  * should be used is when it is necessary for a #GtkWidget to assign focus
16206  * to a widget that is semantically owned by the first widget even though
16207  * it’s not a direct child - for instance, a search entry in a floating
16208  * window similar to the quick search in #GtkTreeView.
16209  *
16210  * An example of its usage is:
16211  *
16212  * |[<!-- language="C" -->
16213  *   GdkEvent *fevent = gdk_event_new (GDK_FOCUS_CHANGE);
16214  *
16215  *   fevent->focus_change.type = GDK_FOCUS_CHANGE;
16216  *   fevent->focus_change.in = TRUE;
16217  *   fevent->focus_change.window = _gtk_widget_get_window (widget);
16218  *   if (fevent->focus_change.window != NULL)
16219  *     g_object_ref (fevent->focus_change.window);
16220  *
16221  *   gtk_widget_send_focus_change (widget, fevent);
16222  *
16223  *   gdk_event_free (event);
16224  * ]|
16225  *
16226  * Returns: the return value from the event signal emission: %TRUE
16227  *   if the event was handled, and %FALSE otherwise
16228  *
16229  * Since: 2.20
16230  */
16231 gboolean
gtk_widget_send_focus_change(GtkWidget * widget,GdkEvent * event)16232 gtk_widget_send_focus_change (GtkWidget *widget,
16233                               GdkEvent  *event)
16234 {
16235   gboolean res;
16236 
16237   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
16238   g_return_val_if_fail (event != NULL && event->type == GDK_FOCUS_CHANGE, FALSE);
16239 
16240   g_object_ref (widget);
16241 
16242   _gtk_widget_set_has_focus (widget, event->focus_change.in);
16243 
16244   res = gtk_widget_event (widget, event);
16245 
16246   g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_HAS_FOCUS]);
16247 
16248   g_object_unref (widget);
16249 
16250   return res;
16251 }
16252 
16253 /**
16254  * gtk_widget_in_destruction:
16255  * @widget: a #GtkWidget
16256  *
16257  * Returns whether the widget is currently being destroyed.
16258  * This information can sometimes be used to avoid doing
16259  * unnecessary work.
16260  *
16261  * Returns: %TRUE if @widget is being destroyed
16262  */
16263 gboolean
gtk_widget_in_destruction(GtkWidget * widget)16264 gtk_widget_in_destruction (GtkWidget *widget)
16265 {
16266   return widget->priv->in_destruction;
16267 }
16268 
16269 gboolean
_gtk_widget_get_in_reparent(GtkWidget * widget)16270 _gtk_widget_get_in_reparent (GtkWidget *widget)
16271 {
16272   return widget->priv->in_reparent;
16273 }
16274 
16275 void
_gtk_widget_set_in_reparent(GtkWidget * widget,gboolean in_reparent)16276 _gtk_widget_set_in_reparent (GtkWidget *widget,
16277                              gboolean   in_reparent)
16278 {
16279   widget->priv->in_reparent = in_reparent;
16280 }
16281 
16282 gboolean
_gtk_widget_get_anchored(GtkWidget * widget)16283 _gtk_widget_get_anchored (GtkWidget *widget)
16284 {
16285   return widget->priv->anchored;
16286 }
16287 
16288 void
_gtk_widget_set_anchored(GtkWidget * widget,gboolean anchored)16289 _gtk_widget_set_anchored (GtkWidget *widget,
16290                           gboolean   anchored)
16291 {
16292   widget->priv->anchored = anchored;
16293 }
16294 
16295 gboolean
_gtk_widget_get_shadowed(GtkWidget * widget)16296 _gtk_widget_get_shadowed (GtkWidget *widget)
16297 {
16298   return widget->priv->shadowed;
16299 }
16300 
16301 void
_gtk_widget_set_shadowed(GtkWidget * widget,gboolean shadowed)16302 _gtk_widget_set_shadowed (GtkWidget *widget,
16303                           gboolean   shadowed)
16304 {
16305   widget->priv->shadowed = shadowed;
16306 }
16307 
16308 gboolean
_gtk_widget_get_alloc_needed(GtkWidget * widget)16309 _gtk_widget_get_alloc_needed (GtkWidget *widget)
16310 {
16311   return widget->priv->alloc_needed;
16312 }
16313 
16314 static void
gtk_widget_set_alloc_needed(GtkWidget * widget)16315 gtk_widget_set_alloc_needed (GtkWidget *widget)
16316 {
16317   GtkWidgetPrivate *priv = widget->priv;
16318 
16319   priv->alloc_needed = TRUE;
16320 
16321   do
16322     {
16323       if (priv->alloc_needed_on_child)
16324         break;
16325 
16326       priv->alloc_needed_on_child = TRUE;
16327 
16328       if (!priv->visible)
16329         break;
16330 
16331 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
16332       if (GTK_IS_RESIZE_CONTAINER (widget))
16333         {
16334           gtk_container_queue_resize_handler (GTK_CONTAINER (widget));
16335           break;
16336         }
16337 G_GNUC_END_IGNORE_DEPRECATIONS;
16338 
16339       widget = priv->parent;
16340       if (widget == NULL)
16341         break;
16342 
16343       priv = widget->priv;
16344     }
16345   while (TRUE);
16346 }
16347 
16348 gboolean
gtk_widget_needs_allocate(GtkWidget * widget)16349 gtk_widget_needs_allocate (GtkWidget *widget)
16350 {
16351   GtkWidgetPrivate *priv = widget->priv;
16352 
16353   if (!priv->visible || !priv->child_visible)
16354     return FALSE;
16355 
16356   if (priv->resize_needed || priv->alloc_needed || priv->alloc_needed_on_child)
16357     return TRUE;
16358 
16359   return FALSE;
16360 }
16361 
16362 void
gtk_widget_ensure_allocate(GtkWidget * widget)16363 gtk_widget_ensure_allocate (GtkWidget *widget)
16364 {
16365   GtkWidgetPrivate *priv = widget->priv;
16366 
16367   if (!gtk_widget_needs_allocate (widget))
16368     return;
16369 
16370   gtk_widget_ensure_resize (widget);
16371 
16372   /*  This code assumes that we only reach here if the previous
16373    *  allocation is still valid (ie no resize was queued).
16374    *  If that wasn't true, the parent would have taken care of
16375    *  things.
16376    */
16377   if (priv->alloc_needed)
16378     {
16379       GtkAllocation allocation;
16380       int baseline;
16381 
16382       gtk_widget_get_allocated_size (widget, &allocation, &baseline);
16383       gtk_widget_size_allocate_with_baseline (widget, &allocation, baseline);
16384     }
16385   else if (priv->alloc_needed_on_child)
16386     {
16387       priv->alloc_needed_on_child = FALSE;
16388 
16389       if (GTK_IS_CONTAINER (widget))
16390         gtk_container_forall (GTK_CONTAINER (widget),
16391                               (GtkCallback) gtk_widget_ensure_allocate,
16392                               NULL);
16393     }
16394 }
16395 
16396 void
gtk_widget_queue_resize_on_widget(GtkWidget * widget)16397 gtk_widget_queue_resize_on_widget (GtkWidget *widget)
16398 {
16399   GtkWidgetPrivate *priv = widget->priv;
16400 
16401   priv->resize_needed = TRUE;
16402   gtk_widget_set_alloc_needed (widget);
16403 }
16404 
16405 void
gtk_widget_ensure_resize(GtkWidget * widget)16406 gtk_widget_ensure_resize (GtkWidget *widget)
16407 {
16408   GtkWidgetPrivate *priv = widget->priv;
16409 
16410   if (!priv->resize_needed)
16411     return;
16412 
16413   priv->resize_needed = FALSE;
16414   _gtk_size_request_cache_clear (&priv->requests);
16415 }
16416 
16417 void
_gtk_widget_add_sizegroup(GtkWidget * widget,gpointer group)16418 _gtk_widget_add_sizegroup (GtkWidget    *widget,
16419 			   gpointer      group)
16420 {
16421   GSList *groups;
16422 
16423   groups = g_object_get_qdata (G_OBJECT (widget), quark_size_groups);
16424   groups = g_slist_prepend (groups, group);
16425   g_object_set_qdata (G_OBJECT (widget), quark_size_groups, groups);
16426 
16427   widget->priv->have_size_groups = TRUE;
16428 }
16429 
16430 void
_gtk_widget_remove_sizegroup(GtkWidget * widget,gpointer group)16431 _gtk_widget_remove_sizegroup (GtkWidget    *widget,
16432 			      gpointer      group)
16433 {
16434   GSList *groups;
16435 
16436   groups = g_object_get_qdata (G_OBJECT (widget), quark_size_groups);
16437   groups = g_slist_remove (groups, group);
16438   g_object_set_qdata (G_OBJECT (widget), quark_size_groups, groups);
16439 
16440   widget->priv->have_size_groups = groups != NULL;
16441 }
16442 
16443 GSList *
_gtk_widget_get_sizegroups(GtkWidget * widget)16444 _gtk_widget_get_sizegroups (GtkWidget    *widget)
16445 {
16446   if (widget->priv->have_size_groups)
16447     return g_object_get_qdata (G_OBJECT (widget), quark_size_groups);
16448 
16449   return NULL;
16450 }
16451 
16452 void
_gtk_widget_add_attached_window(GtkWidget * widget,GtkWindow * window)16453 _gtk_widget_add_attached_window (GtkWidget    *widget,
16454                                  GtkWindow    *window)
16455 {
16456   widget->priv->attached_windows = g_list_prepend (widget->priv->attached_windows, window);
16457 }
16458 
16459 void
_gtk_widget_remove_attached_window(GtkWidget * widget,GtkWindow * window)16460 _gtk_widget_remove_attached_window (GtkWidget    *widget,
16461                                     GtkWindow    *window)
16462 {
16463   widget->priv->attached_windows = g_list_remove (widget->priv->attached_windows, window);
16464 }
16465 
16466 /**
16467  * gtk_widget_path_append_for_widget:
16468  * @path: a widget path
16469  * @widget: the widget to append to the widget path
16470  *
16471  * Appends the data from @widget to the widget hierarchy represented
16472  * by @path. This function is a shortcut for adding information from
16473  * @widget to the given @path. This includes setting the name or
16474  * adding the style classes from @widget.
16475  *
16476  * Returns: the position where the data was inserted
16477  *
16478  * Since: 3.2
16479  */
16480 gint
gtk_widget_path_append_for_widget(GtkWidgetPath * path,GtkWidget * widget)16481 gtk_widget_path_append_for_widget (GtkWidgetPath *path,
16482                                    GtkWidget     *widget)
16483 {
16484   const GQuark *classes;
16485   guint n_classes, i;
16486   gint pos;
16487 
16488   g_return_val_if_fail (path != NULL, 0);
16489   g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
16490 
16491   pos = gtk_widget_path_append_type (path, gtk_css_node_get_widget_type (widget->priv->cssnode));
16492   gtk_widget_path_iter_set_object_name (path, pos, gtk_css_node_get_name (widget->priv->cssnode));
16493 
16494   if (widget->priv->name)
16495     gtk_widget_path_iter_set_name (path, pos, widget->priv->name);
16496 
16497   gtk_widget_path_iter_set_state (path, pos, widget->priv->state_flags);
16498 
16499   classes = gtk_css_node_list_classes (widget->priv->cssnode, &n_classes);
16500 
16501   for (i = n_classes; i-- > 0;)
16502     gtk_widget_path_iter_add_qclass (path, pos, classes[i]);
16503 
16504   return pos;
16505 }
16506 
16507 GtkWidgetPath *
_gtk_widget_create_path(GtkWidget * widget)16508 _gtk_widget_create_path (GtkWidget *widget)
16509 {
16510   GtkWidget *parent;
16511 
16512   parent = widget->priv->parent;
16513 
16514   if (parent)
16515     return gtk_container_get_path_for_child (GTK_CONTAINER (parent), widget);
16516   else
16517     {
16518       /* Widget is either toplevel or unparented, treat both
16519        * as toplevels style wise, since there are situations
16520        * where style properties might be retrieved on that
16521        * situation.
16522        */
16523       GtkWidget *attach_widget = NULL;
16524       GtkWidgetPath *result;
16525 
16526       if (GTK_IS_WINDOW (widget))
16527         attach_widget = gtk_window_get_attached_to (GTK_WINDOW (widget));
16528 
16529       if (attach_widget != NULL)
16530         result = gtk_widget_path_copy (gtk_widget_get_path (attach_widget));
16531       else
16532         result = gtk_widget_path_new ();
16533 
16534       gtk_widget_path_append_for_widget (result, widget);
16535 
16536       return result;
16537     }
16538 }
16539 
16540 /**
16541  * gtk_widget_get_path:
16542  * @widget: a #GtkWidget
16543  *
16544  * Returns the #GtkWidgetPath representing @widget, if the widget
16545  * is not connected to a toplevel widget, a partial path will be
16546  * created.
16547  *
16548  * Returns: (transfer none): The #GtkWidgetPath representing @widget
16549  **/
16550 GtkWidgetPath *
gtk_widget_get_path(GtkWidget * widget)16551 gtk_widget_get_path (GtkWidget *widget)
16552 {
16553   GtkWidgetPath *path;
16554 
16555   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
16556 
16557   path = (GtkWidgetPath*)g_object_get_qdata (G_OBJECT (widget), quark_widget_path);
16558   if (!path)
16559     {
16560       path = _gtk_widget_create_path (widget);
16561       g_object_set_qdata_full (G_OBJECT (widget),
16562                                quark_widget_path,
16563                                path,
16564                                (GDestroyNotify)gtk_widget_path_free);
16565     }
16566 
16567   return path;
16568 }
16569 
16570 void
gtk_widget_clear_path(GtkWidget * widget)16571 gtk_widget_clear_path (GtkWidget *widget)
16572 {
16573   g_object_set_qdata (G_OBJECT (widget), quark_widget_path, NULL);
16574 }
16575 
16576 /**
16577  * gtk_widget_class_set_css_name:
16578  * @widget_class: class to set the name on
16579  * @name: name to use
16580  *
16581  * Sets the name to be used for CSS matching of widgets.
16582  *
16583  * If this function is not called for a given class, the name
16584  * of the parent class is used.
16585  *
16586  * Since: 3.20
16587  */
16588 void
gtk_widget_class_set_css_name(GtkWidgetClass * widget_class,const char * name)16589 gtk_widget_class_set_css_name (GtkWidgetClass *widget_class,
16590                                const char     *name)
16591 {
16592   GtkWidgetClassPrivate *priv;
16593 
16594   g_return_if_fail (GTK_IS_WIDGET_CLASS (widget_class));
16595   g_return_if_fail (name != NULL);
16596 
16597   priv = widget_class->priv;
16598 
16599   priv->css_name = g_intern_string (name);
16600 }
16601 
16602 /**
16603  * gtk_widget_class_get_css_name:
16604  * @widget_class: class to set the name on
16605  *
16606  * Gets the name used by this class for matching in CSS code. See
16607  * gtk_widget_class_set_css_name() for details.
16608  *
16609  * Returns: the CSS name of the given class
16610  *
16611  * Since: 3.20
16612  */
16613 const char *
gtk_widget_class_get_css_name(GtkWidgetClass * widget_class)16614 gtk_widget_class_get_css_name (GtkWidgetClass *widget_class)
16615 {
16616   g_return_val_if_fail (GTK_IS_WIDGET_CLASS (widget_class), NULL);
16617 
16618   return widget_class->priv->css_name;
16619 }
16620 
16621 void
_gtk_widget_style_context_invalidated(GtkWidget * widget)16622 _gtk_widget_style_context_invalidated (GtkWidget *widget)
16623 {
16624   g_signal_emit (widget, widget_signals[STYLE_UPDATED], 0);
16625 }
16626 
16627 GtkCssNode *
gtk_widget_get_css_node(GtkWidget * widget)16628 gtk_widget_get_css_node (GtkWidget *widget)
16629 {
16630   return widget->priv->cssnode;
16631 }
16632 
16633 GtkStyleContext *
_gtk_widget_peek_style_context(GtkWidget * widget)16634 _gtk_widget_peek_style_context (GtkWidget *widget)
16635 {
16636   return widget->priv->context;
16637 }
16638 
16639 
16640 /**
16641  * gtk_widget_get_style_context:
16642  * @widget: a #GtkWidget
16643  *
16644  * Returns the style context associated to @widget. The returned object is
16645  * guaranteed to be the same for the lifetime of @widget.
16646  *
16647  * Returns: (transfer none): a #GtkStyleContext. This memory is owned by @widget and
16648  *          must not be freed.
16649  **/
16650 GtkStyleContext *
gtk_widget_get_style_context(GtkWidget * widget)16651 gtk_widget_get_style_context (GtkWidget *widget)
16652 {
16653   GtkWidgetPrivate *priv;
16654 
16655   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
16656 
16657   priv = widget->priv;
16658 
16659   if (G_UNLIKELY (priv->context == NULL))
16660     {
16661       GdkScreen *screen;
16662       GdkFrameClock *frame_clock;
16663 
16664       priv->context = gtk_style_context_new_for_node (priv->cssnode);
16665 
16666       gtk_style_context_set_id (priv->context, priv->name);
16667       gtk_style_context_set_state (priv->context, priv->state_flags);
16668       gtk_style_context_set_scale (priv->context, gtk_widget_get_scale_factor (widget));
16669 
16670       screen = gtk_widget_get_screen (widget);
16671       if (screen)
16672         gtk_style_context_set_screen (priv->context, screen);
16673 
16674       frame_clock = gtk_widget_get_frame_clock (widget);
16675       if (frame_clock)
16676         gtk_style_context_set_frame_clock (priv->context, frame_clock);
16677 
16678       if (priv->parent)
16679         gtk_style_context_set_parent (priv->context,
16680                                       _gtk_widget_get_style_context (priv->parent));
16681     }
16682 
16683   return widget->priv->context;
16684 }
16685 
16686 void
_gtk_widget_invalidate_style_context(GtkWidget * widget,GtkCssChange change)16687 _gtk_widget_invalidate_style_context (GtkWidget    *widget,
16688                                       GtkCssChange  change)
16689 {
16690   gtk_css_node_invalidate (widget->priv->cssnode, change);
16691 }
16692 
16693 /**
16694  * gtk_widget_get_modifier_mask:
16695  * @widget: a #GtkWidget
16696  * @intent: the use case for the modifier mask
16697  *
16698  * Returns the modifier mask the @widget’s windowing system backend
16699  * uses for a particular purpose.
16700  *
16701  * See gdk_keymap_get_modifier_mask().
16702  *
16703  * Returns: the modifier mask used for @intent.
16704  *
16705  * Since: 3.4
16706  **/
16707 GdkModifierType
gtk_widget_get_modifier_mask(GtkWidget * widget,GdkModifierIntent intent)16708 gtk_widget_get_modifier_mask (GtkWidget         *widget,
16709                               GdkModifierIntent  intent)
16710 {
16711   GdkDisplay *display;
16712 
16713   g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
16714 
16715   display = gtk_widget_get_display (widget);
16716 
16717   return gdk_keymap_get_modifier_mask (gdk_keymap_get_for_display (display),
16718                                        intent);
16719 }
16720 
16721 GtkStyle *
_gtk_widget_get_style(GtkWidget * widget)16722 _gtk_widget_get_style (GtkWidget *widget)
16723 {
16724   return widget->priv->style;
16725 }
16726 
16727 void
_gtk_widget_set_style(GtkWidget * widget,GtkStyle * style)16728 _gtk_widget_set_style (GtkWidget *widget,
16729                        GtkStyle  *style)
16730 {
16731   widget->priv->style = style;
16732   g_signal_emit (widget, widget_signals[STYLE_SET], 0, widget->priv->style);
16733 }
16734 
16735 GtkActionMuxer *
_gtk_widget_get_parent_muxer(GtkWidget * widget,gboolean create)16736 _gtk_widget_get_parent_muxer (GtkWidget *widget,
16737                               gboolean   create)
16738 {
16739   GtkWidget *parent;
16740 
16741   if (GTK_IS_WINDOW (widget))
16742     return gtk_application_get_parent_muxer_for_window (GTK_WINDOW (widget));
16743 
16744   if (GTK_IS_MENU (widget))
16745     parent = gtk_menu_get_attach_widget (GTK_MENU (widget));
16746   else if (GTK_IS_POPOVER (widget))
16747     parent = gtk_popover_get_relative_to (GTK_POPOVER (widget));
16748   else
16749     parent = _gtk_widget_get_parent (widget);
16750 
16751   if (parent)
16752     return _gtk_widget_get_action_muxer (parent, create);
16753 
16754   return NULL;
16755 }
16756 
16757 void
_gtk_widget_update_parent_muxer(GtkWidget * widget)16758 _gtk_widget_update_parent_muxer (GtkWidget *widget)
16759 {
16760   GtkActionMuxer *muxer;
16761 
16762   muxer = (GtkActionMuxer*)g_object_get_qdata (G_OBJECT (widget), quark_action_muxer);
16763   if (muxer == NULL)
16764     return;
16765 
16766   gtk_action_muxer_set_parent (muxer,
16767                                _gtk_widget_get_parent_muxer (widget, TRUE));
16768 }
16769 
16770 GtkActionMuxer *
_gtk_widget_get_action_muxer(GtkWidget * widget,gboolean create)16771 _gtk_widget_get_action_muxer (GtkWidget *widget,
16772                               gboolean   create)
16773 {
16774   GtkActionMuxer *muxer;
16775 
16776   muxer = (GtkActionMuxer*)g_object_get_qdata (G_OBJECT (widget), quark_action_muxer);
16777   if (muxer)
16778     return muxer;
16779 
16780   if (create)
16781     {
16782       muxer = gtk_action_muxer_new ();
16783       g_object_set_qdata_full (G_OBJECT (widget),
16784                                quark_action_muxer,
16785                                muxer,
16786                                g_object_unref);
16787       _gtk_widget_update_parent_muxer (widget);
16788 
16789       return muxer;
16790     }
16791   else
16792     return _gtk_widget_get_parent_muxer (widget, FALSE);
16793 }
16794 
16795 /**
16796  * gtk_widget_insert_action_group:
16797  * @widget: a #GtkWidget
16798  * @name: the prefix for actions in @group
16799  * @group: (allow-none): a #GActionGroup, or %NULL
16800  *
16801  * Inserts @group into @widget. Children of @widget that implement
16802  * #GtkActionable can then be associated with actions in @group by
16803  * setting their “action-name” to
16804  * @prefix.`action-name`.
16805  *
16806  * If @group is %NULL, a previously inserted group for @name is removed
16807  * from @widget.
16808  *
16809  * Since: 3.6
16810  */
16811 void
gtk_widget_insert_action_group(GtkWidget * widget,const gchar * name,GActionGroup * group)16812 gtk_widget_insert_action_group (GtkWidget    *widget,
16813                                 const gchar  *name,
16814                                 GActionGroup *group)
16815 {
16816   GtkActionMuxer *muxer;
16817 
16818   g_return_if_fail (GTK_IS_WIDGET (widget));
16819   g_return_if_fail (name != NULL);
16820 
16821   muxer = _gtk_widget_get_action_muxer (widget, TRUE);
16822 
16823   if (group)
16824     gtk_action_muxer_insert (muxer, name, group);
16825   else
16826     gtk_action_muxer_remove (muxer, name);
16827 }
16828 
16829 /****************************************************************
16830  *                 GtkBuilder automated templates               *
16831  ****************************************************************/
16832 static AutomaticChildClass *
template_child_class_new(const gchar * name,gboolean internal_child,gssize offset)16833 template_child_class_new (const gchar *name,
16834                           gboolean     internal_child,
16835                           gssize       offset)
16836 {
16837   AutomaticChildClass *child_class = g_slice_new0 (AutomaticChildClass);
16838 
16839   child_class->name = g_strdup (name);
16840   child_class->internal_child = internal_child;
16841   child_class->offset = offset;
16842 
16843   return child_class;
16844 }
16845 
16846 static void
template_child_class_free(AutomaticChildClass * child_class)16847 template_child_class_free (AutomaticChildClass *child_class)
16848 {
16849   if (child_class)
16850     {
16851       g_free (child_class->name);
16852       g_slice_free (AutomaticChildClass, child_class);
16853     }
16854 }
16855 
16856 static CallbackSymbol *
callback_symbol_new(const gchar * name,GCallback callback)16857 callback_symbol_new (const gchar *name,
16858 		     GCallback    callback)
16859 {
16860   CallbackSymbol *cb = g_slice_new0 (CallbackSymbol);
16861 
16862   cb->callback_name = g_strdup (name);
16863   cb->callback_symbol = callback;
16864 
16865   return cb;
16866 }
16867 
16868 static void
callback_symbol_free(CallbackSymbol * callback)16869 callback_symbol_free (CallbackSymbol *callback)
16870 {
16871   if (callback)
16872     {
16873       g_free (callback->callback_name);
16874       g_slice_free (CallbackSymbol, callback);
16875     }
16876 }
16877 
16878 static void
template_data_free(GtkWidgetTemplate * template_data)16879 template_data_free (GtkWidgetTemplate *template_data)
16880 {
16881   if (template_data)
16882     {
16883       g_bytes_unref (template_data->data);
16884       g_slist_free_full (template_data->children, (GDestroyNotify)template_child_class_free);
16885       g_slist_free_full (template_data->callbacks, (GDestroyNotify)callback_symbol_free);
16886 
16887       if (template_data->connect_data &&
16888 	  template_data->destroy_notify)
16889 	template_data->destroy_notify (template_data->connect_data);
16890 
16891       g_slice_free (GtkWidgetTemplate, template_data);
16892     }
16893 }
16894 
16895 static GHashTable *
get_auto_child_hash(GtkWidget * widget,GType type,gboolean create)16896 get_auto_child_hash (GtkWidget *widget,
16897 		     GType      type,
16898 		     gboolean   create)
16899 {
16900   GHashTable *auto_children;
16901   GHashTable *auto_child_hash;
16902 
16903   auto_children = (GHashTable *)g_object_get_qdata (G_OBJECT (widget), quark_auto_children);
16904   if (auto_children == NULL)
16905     {
16906       if (!create)
16907         return NULL;
16908 
16909       auto_children = g_hash_table_new_full (g_direct_hash,
16910                                              NULL,
16911 			                     NULL, (GDestroyNotify)g_hash_table_destroy);
16912       g_object_set_qdata_full (G_OBJECT (widget),
16913                                quark_auto_children,
16914                                auto_children,
16915                                (GDestroyNotify)g_hash_table_destroy);
16916     }
16917 
16918   auto_child_hash =
16919     g_hash_table_lookup (auto_children, GSIZE_TO_POINTER (type));
16920 
16921   if (!auto_child_hash && create)
16922     {
16923       auto_child_hash = g_hash_table_new_full (g_str_hash,
16924 					       g_str_equal,
16925 					       NULL,
16926 					       (GDestroyNotify)g_object_unref);
16927 
16928       g_hash_table_insert (auto_children,
16929 			   GSIZE_TO_POINTER (type),
16930 			   auto_child_hash);
16931     }
16932 
16933   return auto_child_hash;
16934 }
16935 
16936 static gboolean
setup_template_child(GtkWidgetTemplate * template_data,GType class_type,AutomaticChildClass * child_class,GtkWidget * widget,GtkBuilder * builder)16937 setup_template_child (GtkWidgetTemplate   *template_data,
16938                       GType                class_type,
16939                       AutomaticChildClass *child_class,
16940                       GtkWidget           *widget,
16941                       GtkBuilder          *builder)
16942 {
16943   GHashTable *auto_child_hash;
16944   GObject    *object;
16945 
16946   object = gtk_builder_get_object (builder, child_class->name);
16947   if (!object)
16948     {
16949       g_critical ("Unable to retrieve object '%s' from class template for type '%s' while building a '%s'",
16950 		  child_class->name, g_type_name (class_type), G_OBJECT_TYPE_NAME (widget));
16951       return FALSE;
16952     }
16953 
16954   /* Insert into the hash so that it can be fetched with
16955    * gtk_widget_get_template_child() and also in automated
16956    * implementations of GtkBuildable.get_internal_child()
16957    */
16958   auto_child_hash = get_auto_child_hash (widget, class_type, TRUE);
16959   g_hash_table_insert (auto_child_hash, child_class->name, g_object_ref (object));
16960 
16961   if (child_class->offset != 0)
16962     {
16963       gpointer field_p;
16964 
16965       /* Assign 'object' to the specified offset in the instance (or private) data */
16966       field_p = G_STRUCT_MEMBER_P (widget, child_class->offset);
16967       (* (gpointer *) field_p) = object;
16968     }
16969 
16970   return TRUE;
16971 }
16972 
16973 /**
16974  * gtk_widget_init_template:
16975  * @widget: a #GtkWidget
16976  *
16977  * Creates and initializes child widgets defined in templates. This
16978  * function must be called in the instance initializer for any
16979  * class which assigned itself a template using gtk_widget_class_set_template()
16980  *
16981  * It is important to call this function in the instance initializer
16982  * of a #GtkWidget subclass and not in #GObject.constructed() or
16983  * #GObject.constructor() for two reasons.
16984  *
16985  * One reason is that generally derived widgets will assume that parent
16986  * class composite widgets have been created in their instance
16987  * initializers.
16988  *
16989  * Another reason is that when calling g_object_new() on a widget with
16990  * composite templates, it’s important to build the composite widgets
16991  * before the construct properties are set. Properties passed to g_object_new()
16992  * should take precedence over properties set in the private template XML.
16993  *
16994  * Since: 3.10
16995  */
16996 void
gtk_widget_init_template(GtkWidget * widget)16997 gtk_widget_init_template (GtkWidget *widget)
16998 {
16999   GtkWidgetTemplate *template;
17000   GtkBuilder *builder;
17001   GError *error = NULL;
17002   GObject *object;
17003   GSList *l;
17004   GType class_type;
17005 
17006   g_return_if_fail (GTK_IS_WIDGET (widget));
17007 
17008   object = G_OBJECT (widget);
17009   class_type = G_OBJECT_TYPE (widget);
17010 
17011   template = GTK_WIDGET_GET_CLASS (widget)->priv->template;
17012   g_return_if_fail (template != NULL);
17013 
17014   builder = gtk_builder_new ();
17015 
17016   /* Add any callback symbols declared for this GType to the GtkBuilder namespace */
17017   for (l = template->callbacks; l; l = l->next)
17018     {
17019       CallbackSymbol *callback = l->data;
17020 
17021       gtk_builder_add_callback_symbol (builder, callback->callback_name, callback->callback_symbol);
17022     }
17023 
17024   /* This will build the template XML as children to the widget instance, also it
17025    * will validate that the template is created for the correct GType and assert that
17026    * there is no infinite recursion.
17027    */
17028   if (!gtk_builder_extend_with_template  (builder, widget, class_type,
17029 					  (const gchar *)g_bytes_get_data (template->data, NULL),
17030 					  g_bytes_get_size (template->data),
17031 					  &error))
17032     {
17033       g_critical ("Error building template class '%s' for an instance of type '%s': %s",
17034 		  g_type_name (class_type), G_OBJECT_TYPE_NAME (object), error->message);
17035       g_error_free (error);
17036 
17037       /* This should never happen, if the template XML cannot be built
17038        * then it is a critical programming error.
17039        */
17040       g_object_unref (builder);
17041       return;
17042     }
17043 
17044   /* Build the automatic child data
17045    */
17046   for (l = template->children; l; l = l->next)
17047     {
17048       AutomaticChildClass *child_class = l->data;
17049 
17050       /* This will setup the pointer of an automated child, and cause
17051        * it to be available in any GtkBuildable.get_internal_child()
17052        * invocations which may follow by reference in child classes.
17053        */
17054       if (!setup_template_child (template,
17055 				  class_type,
17056 				  child_class,
17057 				  widget,
17058 				  builder))
17059 	{
17060 	  g_object_unref (builder);
17061 	  return;
17062 	}
17063     }
17064 
17065   /* Connect signals. All signal data from a template receive the
17066    * template instance as user data automatically.
17067    *
17068    * A GtkBuilderConnectFunc can be provided to gtk_widget_class_set_signal_connect_func()
17069    * in order for templates to be usable by bindings.
17070    */
17071   if (template->connect_func)
17072     gtk_builder_connect_signals_full (builder, template->connect_func, template->connect_data);
17073   else
17074     gtk_builder_connect_signals (builder, object);
17075 
17076   g_object_unref (builder);
17077 }
17078 
17079 /**
17080  * gtk_widget_class_set_template:
17081  * @widget_class: A #GtkWidgetClass
17082  * @template_bytes: A #GBytes holding the #GtkBuilder XML
17083  *
17084  * This should be called at class initialization time to specify
17085  * the GtkBuilder XML to be used to extend a widget.
17086  *
17087  * For convenience, gtk_widget_class_set_template_from_resource() is also provided.
17088  *
17089  * Note that any class that installs templates must call gtk_widget_init_template()
17090  * in the widget’s instance initializer.
17091  *
17092  * Since: 3.10
17093  */
17094 void
gtk_widget_class_set_template(GtkWidgetClass * widget_class,GBytes * template_bytes)17095 gtk_widget_class_set_template (GtkWidgetClass    *widget_class,
17096 			       GBytes            *template_bytes)
17097 {
17098   g_return_if_fail (GTK_IS_WIDGET_CLASS (widget_class));
17099   g_return_if_fail (widget_class->priv->template == NULL);
17100   g_return_if_fail (template_bytes != NULL);
17101 
17102   widget_class->priv->template = g_slice_new0 (GtkWidgetTemplate);
17103   widget_class->priv->template->data = g_bytes_ref (template_bytes);
17104 }
17105 
17106 /**
17107  * gtk_widget_class_set_template_from_resource:
17108  * @widget_class: A #GtkWidgetClass
17109  * @resource_name: The name of the resource to load the template from
17110  *
17111  * A convenience function to call gtk_widget_class_set_template().
17112  *
17113  * Note that any class that installs templates must call gtk_widget_init_template()
17114  * in the widget’s instance initializer.
17115  *
17116  * Since: 3.10
17117  */
17118 void
gtk_widget_class_set_template_from_resource(GtkWidgetClass * widget_class,const gchar * resource_name)17119 gtk_widget_class_set_template_from_resource (GtkWidgetClass    *widget_class,
17120 					     const gchar       *resource_name)
17121 {
17122   GError *error = NULL;
17123   GBytes *bytes = NULL;
17124 
17125   g_return_if_fail (GTK_IS_WIDGET_CLASS (widget_class));
17126   g_return_if_fail (widget_class->priv->template == NULL);
17127   g_return_if_fail (resource_name && resource_name[0]);
17128 
17129   /* This is a hack, because class initializers now access resources
17130    * and GIR/gtk-doc initializes classes without initializing GTK+,
17131    * we ensure that our base resources are registered here and
17132    * avoid warnings which building GIRs/documentation.
17133    */
17134   _gtk_ensure_resources ();
17135 
17136   bytes = g_resources_lookup_data (resource_name, 0, &error);
17137   if (!bytes)
17138     {
17139       g_critical ("Unable to load resource for composite template for type '%s': %s",
17140 		  G_OBJECT_CLASS_NAME (widget_class), error->message);
17141       g_error_free (error);
17142       return;
17143     }
17144 
17145   gtk_widget_class_set_template (widget_class, bytes);
17146   g_bytes_unref (bytes);
17147 }
17148 
17149 /**
17150  * gtk_widget_class_bind_template_callback_full:
17151  * @widget_class: A #GtkWidgetClass
17152  * @callback_name: The name of the callback as expected in the template XML
17153  * @callback_symbol: (scope async): The callback symbol
17154  *
17155  * Declares a @callback_symbol to handle @callback_name from the template XML
17156  * defined for @widget_type. See gtk_builder_add_callback_symbol().
17157  *
17158  * Note that this must be called from a composite widget classes class
17159  * initializer after calling gtk_widget_class_set_template().
17160  *
17161  * Since: 3.10
17162  */
17163 void
gtk_widget_class_bind_template_callback_full(GtkWidgetClass * widget_class,const gchar * callback_name,GCallback callback_symbol)17164 gtk_widget_class_bind_template_callback_full (GtkWidgetClass *widget_class,
17165                                               const gchar    *callback_name,
17166                                               GCallback       callback_symbol)
17167 {
17168   CallbackSymbol *cb;
17169 
17170   g_return_if_fail (GTK_IS_WIDGET_CLASS (widget_class));
17171   g_return_if_fail (widget_class->priv->template != NULL);
17172   g_return_if_fail (callback_name && callback_name[0]);
17173   g_return_if_fail (callback_symbol != NULL);
17174 
17175   cb = callback_symbol_new (callback_name, callback_symbol);
17176   widget_class->priv->template->callbacks = g_slist_prepend (widget_class->priv->template->callbacks, cb);
17177 }
17178 
17179 /**
17180  * gtk_widget_class_set_connect_func:
17181  * @widget_class: A #GtkWidgetClass
17182  * @connect_func: The #GtkBuilderConnectFunc to use when connecting signals in the class template
17183  * @connect_data: The data to pass to @connect_func
17184  * @connect_data_destroy: The #GDestroyNotify to free @connect_data, this will only be used at
17185  *                        class finalization time, when no classes of type @widget_type are in use anymore.
17186  *
17187  * For use in language bindings, this will override the default #GtkBuilderConnectFunc to be
17188  * used when parsing GtkBuilder XML from this class’s template data.
17189  *
17190  * Note that this must be called from a composite widget classes class
17191  * initializer after calling gtk_widget_class_set_template().
17192  *
17193  * Since: 3.10
17194  */
17195 void
gtk_widget_class_set_connect_func(GtkWidgetClass * widget_class,GtkBuilderConnectFunc connect_func,gpointer connect_data,GDestroyNotify connect_data_destroy)17196 gtk_widget_class_set_connect_func (GtkWidgetClass        *widget_class,
17197 				   GtkBuilderConnectFunc  connect_func,
17198 				   gpointer               connect_data,
17199 				   GDestroyNotify         connect_data_destroy)
17200 {
17201   g_return_if_fail (GTK_IS_WIDGET_CLASS (widget_class));
17202   g_return_if_fail (widget_class->priv->template != NULL);
17203 
17204   /* Defensive, destroy any previously set data */
17205   if (widget_class->priv->template->connect_data &&
17206       widget_class->priv->template->destroy_notify)
17207     widget_class->priv->template->destroy_notify (widget_class->priv->template->connect_data);
17208 
17209   widget_class->priv->template->connect_func   = connect_func;
17210   widget_class->priv->template->connect_data   = connect_data;
17211   widget_class->priv->template->destroy_notify = connect_data_destroy;
17212 }
17213 
17214 /**
17215  * gtk_widget_class_bind_template_child_full:
17216  * @widget_class: A #GtkWidgetClass
17217  * @name: The “id” of the child defined in the template XML
17218  * @internal_child: Whether the child should be accessible as an “internal-child”
17219  *                  when this class is used in GtkBuilder XML
17220  * @struct_offset: The structure offset into the composite widget’s instance public or private structure
17221  *                 where the automated child pointer should be set, or 0 to not assign the pointer.
17222  *
17223  * Automatically assign an object declared in the class template XML to be set to a location
17224  * on a freshly built instance’s private data, or alternatively accessible via gtk_widget_get_template_child().
17225  *
17226  * The struct can point either into the public instance, then you should use G_STRUCT_OFFSET(WidgetType, member)
17227  * for @struct_offset,  or in the private struct, then you should use G_PRIVATE_OFFSET(WidgetType, member).
17228  *
17229  * An explicit strong reference will be held automatically for the duration of your
17230  * instance’s life cycle, it will be released automatically when #GObjectClass.dispose() runs
17231  * on your instance and if a @struct_offset that is != 0 is specified, then the automatic location
17232  * in your instance public or private data will be set to %NULL. You can however access an automated child
17233  * pointer the first time your classes #GObjectClass.dispose() runs, or alternatively in
17234  * #GtkWidgetClass.destroy().
17235  *
17236  * If @internal_child is specified, #GtkBuildableIface.get_internal_child() will be automatically
17237  * implemented by the #GtkWidget class so there is no need to implement it manually.
17238  *
17239  * The wrapper macros gtk_widget_class_bind_template_child(), gtk_widget_class_bind_template_child_internal(),
17240  * gtk_widget_class_bind_template_child_private() and gtk_widget_class_bind_template_child_internal_private()
17241  * might be more convenient to use.
17242  *
17243  * Note that this must be called from a composite widget classes class
17244  * initializer after calling gtk_widget_class_set_template().
17245  *
17246  * Since: 3.10
17247  */
17248 void
gtk_widget_class_bind_template_child_full(GtkWidgetClass * widget_class,const gchar * name,gboolean internal_child,gssize struct_offset)17249 gtk_widget_class_bind_template_child_full (GtkWidgetClass *widget_class,
17250                                            const gchar    *name,
17251                                            gboolean        internal_child,
17252                                            gssize          struct_offset)
17253 {
17254   AutomaticChildClass *child_class;
17255 
17256   g_return_if_fail (GTK_IS_WIDGET_CLASS (widget_class));
17257   g_return_if_fail (widget_class->priv->template != NULL);
17258   g_return_if_fail (name && name[0]);
17259 
17260   child_class = template_child_class_new (name,
17261                                           internal_child,
17262                                           struct_offset);
17263   widget_class->priv->template->children =
17264     g_slist_prepend (widget_class->priv->template->children, child_class);
17265 }
17266 
17267 /**
17268  * gtk_widget_get_template_child:
17269  * @widget: A #GtkWidget
17270  * @widget_type: The #GType to get a template child for
17271  * @name: The “id” of the child defined in the template XML
17272  *
17273  * Fetch an object build from the template XML for @widget_type in this @widget instance.
17274  *
17275  * This will only report children which were previously declared with
17276  * gtk_widget_class_bind_template_child_full() or one of its
17277  * variants.
17278  *
17279  * This function is only meant to be called for code which is private to the @widget_type which
17280  * declared the child and is meant for language bindings which cannot easily make use
17281  * of the GObject structure offsets.
17282  *
17283  * Returns: (transfer none): The object built in the template XML with the id @name
17284  */
17285 GObject *
gtk_widget_get_template_child(GtkWidget * widget,GType widget_type,const gchar * name)17286 gtk_widget_get_template_child (GtkWidget   *widget,
17287                                GType        widget_type,
17288                                const gchar *name)
17289 {
17290   GHashTable *auto_child_hash;
17291   GObject *ret = NULL;
17292 
17293   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
17294   g_return_val_if_fail (g_type_name (widget_type) != NULL, NULL);
17295   g_return_val_if_fail (name && name[0], NULL);
17296 
17297   auto_child_hash = get_auto_child_hash (widget, widget_type, FALSE);
17298 
17299   if (auto_child_hash)
17300     ret = g_hash_table_lookup (auto_child_hash, name);
17301 
17302   return ret;
17303 }
17304 
17305 /**
17306  * gtk_widget_list_action_prefixes:
17307  * @widget: A #GtkWidget
17308  *
17309  * Retrieves a %NULL-terminated array of strings containing the prefixes of
17310  * #GActionGroup's available to @widget.
17311  *
17312  * Returns: (transfer container): a %NULL-terminated array of strings.
17313  *
17314  * Since: 3.16
17315  */
17316 const gchar **
gtk_widget_list_action_prefixes(GtkWidget * widget)17317 gtk_widget_list_action_prefixes (GtkWidget *widget)
17318 {
17319   GtkActionMuxer *muxer;
17320 
17321   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
17322 
17323   muxer = _gtk_widget_get_action_muxer (widget, FALSE);
17324   if (muxer)
17325     return gtk_action_muxer_list_prefixes (muxer);
17326 
17327   return g_new0 (const gchar *, 1);
17328 }
17329 
17330 /**
17331  * gtk_widget_get_action_group:
17332  * @widget: A #GtkWidget
17333  * @prefix: The “prefix” of the action group.
17334  *
17335  * Retrieves the #GActionGroup that was registered using @prefix. The resulting
17336  * #GActionGroup may have been registered to @widget or any #GtkWidget in its
17337  * ancestry.
17338  *
17339  * If no action group was found matching @prefix, then %NULL is returned.
17340  *
17341  * Returns: (transfer none) (nullable): A #GActionGroup or %NULL.
17342  *
17343  * Since: 3.16
17344  */
17345 GActionGroup *
gtk_widget_get_action_group(GtkWidget * widget,const gchar * prefix)17346 gtk_widget_get_action_group (GtkWidget   *widget,
17347                              const gchar *prefix)
17348 {
17349   GtkActionMuxer *muxer;
17350 
17351   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
17352   g_return_val_if_fail (prefix, NULL);
17353 
17354   muxer = _gtk_widget_get_action_muxer (widget, FALSE);
17355   if (muxer)
17356     return gtk_action_muxer_lookup (muxer, prefix);
17357 
17358   return NULL;
17359 }
17360 
17361 static void
event_controller_grab_notify(GtkWidget * widget,gboolean was_grabbed,EventControllerData * data)17362 event_controller_grab_notify (GtkWidget           *widget,
17363                               gboolean             was_grabbed,
17364                               EventControllerData *data)
17365 {
17366   GdkDevice *device = NULL;
17367 
17368   if (GTK_IS_GESTURE (data->controller))
17369     device = gtk_gesture_get_device (GTK_GESTURE (data->controller));
17370 
17371   if (!device || !gtk_widget_device_is_shadowed (widget, device))
17372     return;
17373 
17374   gtk_event_controller_reset (data->controller);
17375 }
17376 
17377 static void
_gtk_widget_update_evmask(GtkWidget * widget)17378 _gtk_widget_update_evmask (GtkWidget *widget)
17379 {
17380   if (_gtk_widget_get_realized (widget))
17381     {
17382       gint events = GPOINTER_TO_INT (g_object_get_qdata (G_OBJECT (widget),
17383                                                          quark_event_mask));
17384       gtk_widget_add_events_internal (widget, NULL, events);
17385     }
17386 }
17387 
17388 static void
event_controller_sequence_state_changed(GtkGesture * gesture,GdkEventSequence * sequence,GtkEventSequenceState state,GtkWidget * widget)17389 event_controller_sequence_state_changed (GtkGesture            *gesture,
17390                                          GdkEventSequence      *sequence,
17391                                          GtkEventSequenceState  state,
17392                                          GtkWidget             *widget)
17393 {
17394   gboolean handled = FALSE;
17395   GtkWidget *event_widget;
17396   const GdkEvent *event;
17397 
17398   handled = _gtk_widget_set_sequence_state_internal (widget, sequence,
17399                                                      state, gesture);
17400 
17401   if (!handled || state != GTK_EVENT_SEQUENCE_CLAIMED)
17402     return;
17403 
17404   event = _gtk_widget_get_last_event (widget, sequence);
17405 
17406   if (!event)
17407     return;
17408 
17409   event_widget = gtk_get_event_widget ((GdkEvent *) event);
17410   cancel_event_sequence_on_hierarchy (widget, event_widget, sequence);
17411 }
17412 
17413 static EventControllerData *
_gtk_widget_has_controller(GtkWidget * widget,GtkEventController * controller)17414 _gtk_widget_has_controller (GtkWidget          *widget,
17415                             GtkEventController *controller)
17416 {
17417   EventControllerData *data;
17418   GtkWidgetPrivate *priv;
17419   GList *l;
17420 
17421   priv = widget->priv;
17422 
17423   for (l = priv->event_controllers; l; l = l->next)
17424     {
17425       data = l->data;
17426 
17427       if (data->controller == controller)
17428         return data;
17429     }
17430 
17431   return NULL;
17432 }
17433 
17434 void
_gtk_widget_add_controller(GtkWidget * widget,GtkEventController * controller)17435 _gtk_widget_add_controller (GtkWidget          *widget,
17436                             GtkEventController *controller)
17437 {
17438   EventControllerData *data;
17439   GtkWidgetPrivate *priv;
17440 
17441   g_return_if_fail (GTK_IS_WIDGET (widget));
17442   g_return_if_fail (GTK_IS_EVENT_CONTROLLER (controller));
17443   g_return_if_fail (widget == gtk_event_controller_get_widget (controller));
17444 
17445   priv = widget->priv;
17446   data = _gtk_widget_has_controller (widget, controller);
17447 
17448   if (data)
17449     return;
17450 
17451   data = g_new0 (EventControllerData, 1);
17452   data->controller = controller;
17453   data->grab_notify_id =
17454     g_signal_connect (widget, "grab-notify",
17455                       G_CALLBACK (event_controller_grab_notify), data);
17456 
17457   g_object_add_weak_pointer (G_OBJECT (data->controller), (gpointer *) &data->controller);
17458 
17459   if (GTK_IS_GESTURE (controller))
17460     {
17461       data->sequence_state_changed_id =
17462         g_signal_connect (controller, "sequence-state-changed",
17463                           G_CALLBACK (event_controller_sequence_state_changed),
17464                           widget);
17465     }
17466 
17467   priv->event_controllers = g_list_prepend (priv->event_controllers, data);
17468   _gtk_widget_update_evmask (widget);
17469 }
17470 
17471 void
_gtk_widget_remove_controller(GtkWidget * widget,GtkEventController * controller)17472 _gtk_widget_remove_controller (GtkWidget          *widget,
17473                                GtkEventController *controller)
17474 {
17475   EventControllerData *data;
17476 
17477   g_return_if_fail (GTK_IS_WIDGET (widget));
17478   g_return_if_fail (GTK_IS_EVENT_CONTROLLER (controller));
17479 
17480   data = _gtk_widget_has_controller (widget, controller);
17481 
17482   if (!data)
17483     return;
17484 
17485   g_object_remove_weak_pointer (G_OBJECT (data->controller), (gpointer *) &data->controller);
17486 
17487   if (g_signal_handler_is_connected (widget, data->grab_notify_id))
17488     g_signal_handler_disconnect (widget, data->grab_notify_id);
17489 
17490   if (data->sequence_state_changed_id)
17491     g_signal_handler_disconnect (data->controller, data->sequence_state_changed_id);
17492 
17493   data->controller = NULL;
17494 }
17495 
17496 GList *
_gtk_widget_list_controllers(GtkWidget * widget,GtkPropagationPhase phase)17497 _gtk_widget_list_controllers (GtkWidget           *widget,
17498                               GtkPropagationPhase  phase)
17499 {
17500   EventControllerData *data;
17501   GtkWidgetPrivate *priv;
17502   GList *l, *retval = NULL;
17503 
17504   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
17505 
17506   priv = widget->priv;
17507 
17508   for (l = priv->event_controllers; l; l = l->next)
17509     {
17510       data = l->data;
17511 
17512       if (data->controller != NULL &&
17513           phase == gtk_event_controller_get_propagation_phase (data->controller))
17514         retval = g_list_prepend (retval, data->controller);
17515     }
17516 
17517   return retval;
17518 }
17519 
17520 gboolean
_gtk_widget_consumes_motion(GtkWidget * widget,GdkEventSequence * sequence)17521 _gtk_widget_consumes_motion (GtkWidget        *widget,
17522                              GdkEventSequence *sequence)
17523 {
17524   EventControllerData *data;
17525   GtkWidgetPrivate *priv;
17526   GList *l;
17527 
17528   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
17529 
17530   priv = widget->priv;
17531 
17532   for (l = priv->event_controllers; l; l = l->next)
17533     {
17534       data = l->data;
17535 
17536       if (data->controller == NULL)
17537         continue;
17538 
17539       if ((!GTK_IS_GESTURE_SINGLE (data->controller) ||
17540            GTK_IS_GESTURE_DRAG (data->controller) ||
17541            GTK_IS_GESTURE_SWIPE (data->controller)) &&
17542           gtk_gesture_handles_sequence (GTK_GESTURE (data->controller), sequence))
17543         return TRUE;
17544     }
17545 
17546   return FALSE;
17547 }
17548 
17549 void
gtk_widget_reset_controllers(GtkWidget * widget)17550 gtk_widget_reset_controllers (GtkWidget *widget)
17551 {
17552   EventControllerData *controller_data;
17553   GtkWidgetPrivate *priv = widget->priv;
17554   GList *l;
17555 
17556   /* Reset all controllers */
17557   for (l = priv->event_controllers; l; l = l->next)
17558     {
17559       controller_data = l->data;
17560 
17561       if (controller_data->controller == NULL)
17562         continue;
17563 
17564       gtk_event_controller_reset (controller_data->controller);
17565     }
17566 }
17567 
17568 void
gtk_widget_render(GtkWidget * widget,GdkWindow * window,const cairo_region_t * region)17569 gtk_widget_render (GtkWidget            *widget,
17570                    GdkWindow            *window,
17571                    const cairo_region_t *region)
17572 {
17573   GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
17574   GdkDrawingContext *context;
17575   gboolean do_clip;
17576   cairo_t *cr;
17577   int x, y;
17578   gboolean is_double_buffered;
17579 
17580   /* We take the value here, in case somebody manages to changes
17581    * the double_buffered value inside a ::draw call, and ends up
17582    * breaking everything.
17583    */
17584   is_double_buffered = priv->double_buffered;
17585   if (is_double_buffered)
17586     {
17587       /* We only render double buffered on native windows */
17588       if (!gdk_window_has_native (window))
17589         return;
17590 
17591       context = gdk_window_begin_draw_frame (window, region);
17592       cr = gdk_drawing_context_get_cairo_context (context);
17593     }
17594   else
17595     {
17596       /* This is annoying, but it has to stay because Firefox
17597        * disables double buffering on a top-level GdkWindow,
17598        * which breaks the drawing context.
17599        *
17600        * Candidate for deletion in the next major API bump.
17601        */
17602 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
17603       cr = gdk_cairo_create (window);
17604 G_GNUC_END_IGNORE_DEPRECATIONS
17605     }
17606 
17607   do_clip = _gtk_widget_get_translation_to_window (widget, window, &x, &y);
17608   cairo_translate (cr, -x, -y);
17609 
17610   gtk_widget_draw_internal (widget, cr, do_clip);
17611 
17612   if (is_double_buffered)
17613     gdk_window_end_draw_frame (window, context);
17614   else
17615     cairo_destroy (cr);
17616 }
17617