gtkwidget.c 529 KB
Newer Older
Cody Russell's avatar
Cody Russell committed
1
/* GTK - The GIMP Toolkit
Elliot Lee's avatar
Elliot Lee committed
2 3 4
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * This library is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Lesser General Public
Elliot Lee's avatar
Elliot Lee committed
6 7 8 9 10
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * 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.
Elliot Lee's avatar
Elliot Lee committed
13
 *
14
 * You should have received a copy of the GNU Lesser General Public
Javier Jardón's avatar
Javier Jardón committed
15
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
Elliot Lee's avatar
Elliot Lee committed
16
 */
17 18

/*
19
 * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
20 21
 * file for a list of people on the GTK+ Team.  See the ChangeLog
 * 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

Elliot Lee's avatar
Elliot Lee committed
27 28
#include <stdarg.h>
#include <string.h>
29
#include <locale.h>
30
#include <math.h>
31 32 33 34 35

#include <gobject/gvaluecollector.h>
#include <gobject/gobjectnotifyqueue.c>
#include <cairo-gobject.h>

Elliot Lee's avatar
Elliot Lee committed
36
#include "gtkcontainer.h"
37
#include "gtkaccelmapprivate.h"
Matthias Clasen's avatar
Matthias Clasen committed
38
#include "gtkaccelgroupprivate.h"
39
#include "gtkclipboard.h"
40
#include "gtkcssstylepropertyprivate.h"
Alexander Larsson's avatar
Alexander Larsson committed
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 "gtksizerequestcacheprivate.h"
Elliot Lee's avatar
Elliot Lee committed
49
#include "gtkwidget.h"
Emmanuele Bassi's avatar
Emmanuele Bassi committed
50
#include "gtkwidgetprivate.h"
Matthias Clasen's avatar
Matthias Clasen committed
51
#include "gtkwindowprivate.h"
52
#include "gtkcontainerprivate.h"
Tim Janik's avatar
Tim Janik committed
53
#include "gtkbindings.h"
54
#include "gtkprivate.h"
55
#include "gtkaccessible.h"
56
#include "gtktooltipprivate.h"
57
#include "gtkinvisible.h"
Johan Dahlin's avatar
Johan Dahlin committed
58
#include "gtkbuildable.h"
59
#include "gtkbuilderprivate.h"
60
#include "gtksizerequest.h"
61
#include "gtkstylecontextprivate.h"
62
#include "gtkcssprovider.h"
Benjamin Otte's avatar
Benjamin Otte committed
63
#include "gtkcsswidgetnodeprivate.h"
64
#include "gtkmodifierstyle.h"
65
#include "gtkversion.h"
Matthias Clasen's avatar
Matthias Clasen committed
66
#include "gtkdebug.h"
67
#include "gtkplug.h"
68
#include "gtktypebuiltins.h"
69
#include "a11y/gtkwidgetaccessible.h"
70
#include "gtkapplicationprivate.h"
71
#include "gtkgestureprivate.h"
Elliot Lee's avatar
Elliot Lee committed
72

73 74 75
/* for the use of round() */
#include "fallback-c89.c"

76 77 78 79 80 81 82
/**
 * SECTION:gtkwidget
 * @Short_description: Base class for all widgets
 * @Title: GtkWidget
 *
 * GtkWidget is the base class all widgets in GTK+ derive from. It manages the
 * widget lifecycle, states and style.
83
 *
84
 * # Height-for-width Geometry Management # {#geometry-management}
Matthias Clasen's avatar
Matthias Clasen committed
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 89 90
 * vertical space it needs, depending on the amount of horizontal space
 * that it is given (and similar for width-for-height). The most common
 * 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
 *
Matthias Clasen's avatar
Matthias Clasen committed
96 97 98 99 100 101
 * - #GtkWidgetClass.get_request_mode()
 * - #GtkWidgetClass.get_preferred_width()
 * - #GtkWidgetClass.get_preferred_height()
 * - #GtkWidgetClass.get_preferred_height_for_width()
 * - #GtkWidgetClass.get_preferred_width_for_height()
 * - #GtkWidgetClass.get_preferred_height_and_baseline_for_width()
102 103 104 105 106
 *
 * There are some important things to keep in mind when implementing
 * height-for-width and when using it in container implementations.
 *
 * The geometry management system will query a widget hierarchy in
107
 * only one orientation at a time. When widgets are initially queried
108 109 110
 * for their minimum sizes it is generally done in two initial passes
 * in the #GtkSizeRequestMode chosen by the toplevel.
 *
111
 * For example, when queried in the normal
112 113
 * %GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH mode:
 * First, the default minimum and natural width for each widget
114
 * in the interface will be computed using gtk_widget_get_preferred_width().
115 116
 * Because the preferred widths for each container depend on the preferred
 * widths of their children, this information propagates up the hierarchy,
117
 * and finally a minimum and natural width is determined for the entire
118 119 120 121 122
 * toplevel. Next, the toplevel will use the minimum width to query for the
 * minimum height contextual to that width using
 * gtk_widget_get_preferred_height_for_width(), which will also be a highly
 * recursive operation. The minimum height for the minimum width is normally
 * used to set the minimum size constraint on the toplevel
123 124
 * (unless gtk_window_set_geometry_hints() is explicitly used instead).
 *
125
 * After the toplevel window has initially requested its size in both
126 127
 * dimensions it can go on to allocate itself a reasonable size (or a size
 * 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 135 136
 * a number of times before actually being allocated a size. The size a
 * widget is finally allocated can of course differ from the size it has
 * requested. For this reason, #GtkWidget caches a  small number of results
137 138
 * to avoid re-querying for the same sizes in one allocation cycle.
 *
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 145
 * If a widget does move content around to intelligently use up the
 * 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 151
 * will not expect to have #GtkWidgetClass.get_preferred_height() called
 * 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 154
 * possible width. By following this rule any widget that handles
 * height-for-width or width-for-height requests will always be allocated
155 156 157 158 159
 * at least enough space to fit its own content.
 *
 * Here are some examples of how a %GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH widget
 * generally deals with width-for-height requests, for #GtkWidgetClass.get_preferred_height()
 * it will do:
160
 *
161
 * |[<!-- language="C" -->
162
 * static void
163 164 165
 * foo_widget_get_preferred_height (GtkWidget *widget,
 *                                  gint *min_height,
 *                                  gint *nat_height)
166 167 168
 * {
 *    if (i_am_in_height_for_width_mode)
 *      {
Matthias Clasen's avatar
Matthias Clasen committed
169
 *        gint min_width, nat_width;
170
 *
171 172
 *        GTK_WIDGET_GET_CLASS (widget)->get_preferred_width (widget,
 *                                                            &min_width,
Matthias Clasen's avatar
Matthias Clasen committed
173
 *                                                            &nat_width);
174 175 176 177 178
 *        GTK_WIDGET_GET_CLASS (widget)->get_preferred_height_for_width
 *                                                           (widget,
 *                                                            min_width,
 *                                                            min_height,
 *                                                            nat_height);
179 180 181
 *      }
 *    else
 *      {
182 183 184
 *         ... some widgets do both. For instance, if a GtkLabel is
 *         rotated to 90 degrees it will return the minimum and
 *         natural height for the rotated label here.
185 186
 *      }
 * }
187
 * ]|
188
 *
189 190
 * And in #GtkWidgetClass.get_preferred_width_for_height() it will simply return
 * the minimum and natural width:
191
 * |[<!-- language="C" -->
192
 * static void
193 194 195 196
 * foo_widget_get_preferred_width_for_height (GtkWidget *widget,
 *                                            gint for_height,
 *                                            gint *min_width,
 *                                            gint *nat_width)
197 198 199
 * {
 *    if (i_am_in_height_for_width_mode)
 *      {
200 201 202
 *        GTK_WIDGET_GET_CLASS (widget)->get_preferred_width (widget,
 *                                                            min_width,
 *                                                            nat_width);
203 204 205
 *      }
 *    else
 *      {
206 207 208
 *         ... again if a widget is sometimes operating in
 *         width-for-height mode (like a rotated GtkLabel) it can go
 *         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 215
 * allocation. For example, when computing height it may need to also
 * 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
 *
Matthias Clasen's avatar
Matthias Clasen committed
219
 * |[<!-- language="C" -->
220 221 222
 * GTK_WIDGET_GET_CLASS(widget)->get_preferred_width (widget,
 *                                                    &min,
 *                                                    &natural);
Matthias Clasen's avatar
Matthias Clasen committed
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 230 231 232 233 234
 * widget used the wrappers inside its virtual method implementations,
 * then the adjustments (such as widget margins) would be applied
 * twice. GTK+ therefore does not allow this and will warn if you try
 * to do it.
 *
 * Of course if you are getting the size request for
235 236
 * another widget, such as a child of a
 * container, you must use the wrapper APIs.
237
 * Otherwise, you would not properly consider widget margins,
238
 * #GtkSizeGroup, and so forth.
239 240 241 242 243
 *
 * Since 3.10 Gtk+ also supports baseline vertical alignment of widgets. This
 * means that widgets are positioned such that the typographical baseline of
 * widgets in the same row are aligned. This happens if a widget supports baselines,
 * has a vertical alignment of %GTK_ALIGN_BASELINE, and is inside a container
William Jon McCann's avatar
William Jon McCann committed
244
 * that supports baselines and has a natural “row” that it aligns to the baseline,
245 246 247 248 249 250 251
 * or a baseline assigned to it by the grandparent.
 *
 * Baseline alignment support for a widget is done by the #GtkWidgetClass.get_preferred_height_and_baseline_for_width()
 * virtual function. It allows you to report a baseline in combination with the
 * minimum and natural height. If there is no baseline you can return -1 to indicate
 * this. The default implementation of this virtual function calls into the
 * #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 255 256 257 258
 *
 * If a widget ends up baseline aligned it will be allocated all the space in the parent
 * as if it was %GTK_ALIGN_FILL, but the selected baseline can be found via gtk_widget_get_allocated_baseline().
 * If this has a value other than -1 you need to align the widget such that the baseline
 * appears at the position.
 *
259
 * # Style Properties
Matthias Clasen's avatar
Matthias Clasen committed
260
 *
261 262
 * #GtkWidget introduces “style
 * 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 266 267
 * This mechanism is used for configuring such things as the location of the
 * scrollbar arrows through the theme, giving theme authors more control over the
 * look of applications without the need to write a theme engine in C.
Matthias Clasen's avatar
Matthias Clasen committed
268
 *
269 270 271 272 273
 * Use gtk_widget_class_install_style_property() to install style properties for
 * a widget class, gtk_widget_class_find_style_property() or
 * gtk_widget_class_list_style_properties() to get information about existing
 * style properties and gtk_widget_style_get_property(), gtk_widget_style_get() or
 * gtk_widget_style_get_valist() to obtain the value of a style property.
Matthias Clasen's avatar
Matthias Clasen committed
274
 *
275
 * # GtkWidget as GtkBuildable
Matthias Clasen's avatar
Matthias Clasen committed
276
 *
277
 * The GtkWidget implementation of the GtkBuildable interface supports a
278 279
 * custom <accelerator> element, which has attributes named ”key”, ”modifiers”
 * and ”signal” and allows to specify accelerators.
Matthias Clasen's avatar
Matthias Clasen committed
280 281
 *
 * An example of a UI definition fragment specifying an accelerator:
282
 * |[
283 284 285
 * <object class="GtkButton">
 *   <accelerator key="q" modifiers="GDK_CONTROL_MASK" signal="clicked"/>
 * </object>
286
 * ]|
Matthias Clasen's avatar
Matthias Clasen committed
287
 *
288 289 290 291
 * In addition to accelerators, GtkWidget also support a custom <accessible>
 * element, which supports actions and relations. Properties on the accessible
 * implementation of an object can be set by accessing the internal child
 * “accessible” of a #GtkWidget.
Matthias Clasen's avatar
Matthias Clasen committed
292 293
 *
 * An example of a UI definition fragment specifying an accessible:
294
 * |[
295 296 297 298 299 300 301 302 303 304
 * <object class="GtkButton" id="label1"/>
 *   <property name="label">I am a Label for a Button</property>
 * </object>
 * <object class="GtkButton" id="button1">
 *   <accessibility>
 *     <action action_name="click" translatable="yes">Click the button.</action>
 *     <relation target="label1" type="labelled-by"/>
 *   </accessibility>
 *   <child internal-child="accessible">
 *     <object class="AtkObject" id="a11y-button1">
305
 *       <property name="accessible-name">Clickable Button</property>
306 307 308
 *     </object>
 *   </child>
 * </object>
309
 * ]|
Matthias Clasen's avatar
Matthias Clasen committed
310
 *
311
 * Finally, GtkWidget allows style information such as style classes to
312
 * be associated with widgets, using the custom <style> element:
313
 * |[
314 315 316 317 318 319
 * <object class="GtkButton" id="button1">
 *   <style>
 *     <class name="my-special-button-class"/>
 *     <class name="dark-button"/>
 *   </style>
 * </object>
320
 * ]|
Matthias Clasen's avatar
Matthias Clasen committed
321
 *
322
 * # Building composite widgets from template XML
Matthias Clasen's avatar
Matthias Clasen committed
323
 *
324 325 326
 * GtkWidget exposes some facilities to automate the proceedure
 * of creating composite widgets using #GtkBuilder interface description
 * language.
Matthias Clasen's avatar
Matthias Clasen committed
327
 *
328 329 330
 * To create composite widgets with #GtkBuilder XML, one must associate
 * the interface description with the widget class at class initialization
 * time using gtk_widget_class_set_template().
Matthias Clasen's avatar
Matthias Clasen committed
331
 *
332 333
 * The interface description semantics expected in composite template descriptions
 * is slightly different from regulare #GtkBuilder XML.
Matthias Clasen's avatar
Matthias Clasen committed
334
 *
335 336 337 338 339 340
 * Unlike regular interface descriptions, gtk_widget_class_set_template() will
 * expect a <template> tag as a direct child of the toplevel <interface>
 * tag. The <template> tag must specify the “class” attribute which must be
 * the type name of the widget. Optionally, the “parent” attribute may be
 * specified to specify the direct parent type of the widget type, this is
 * ignored by the GtkBuilder but required for Glade to introspect what kind
341 342
 * of properties and internal children exist for a given type when the actual
 * type does not exist.
Matthias Clasen's avatar
Matthias Clasen committed
343
 *
344 345 346 347 348
 * The XML which is contained inside the <template> tag behaves as if it were
 * added to the <object> tag defining @widget itself. You may set properties
 * on @widget by inserting <property> tags into the <template> tag, and also
 * add <child> tags to add children and extend @widget in the normal way you
 * would with <object> tags.
Matthias Clasen's avatar
Matthias Clasen committed
349
 *
350 351 352 353
 * Additionally, <object> tags can also be added before and after the initial
 * <template> tag in the normal way, allowing one to define auxilary objects
 * which might be referenced by other widgets declared as children of the
 * <template> tag.
Matthias Clasen's avatar
Matthias Clasen committed
354 355
 *
 * An example of a GtkBuilder Template Definition:
356
 * |[
357 358 359 360 361 362 363
 * <interface>
 *   <template class="FooWidget" parent="GtkBox">
 *     <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
 *     <property name="spacing">4</property>
 *     <child>
 *       <object class="GtkButton" id="hello_button">
 *         <property name="label">Hello World</property>
364
 *         <signal name="clicked" handler="hello_button_clicked" object="FooWidget" swapped="yes"/>
365 366 367 368 369 370 371 372 373
 *       </object>
 *     </child>
 *     <child>
 *       <object class="GtkButton" id="goodbye_button">
 *         <property name="label">Goodbye World</property>
 *       </object>
 *     </child>
 *   </template>
 * </interface>
374
 * ]|
375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453
 *
 * Typically, you'll place the template fragment into a file that is
 * bundled with your project, using #GResource. In order to load the
 * template, you need to call gtk_widget_class_set_template_from_resource()
 * from the class initialization of your #GtkWidget type:
 *
 * |[<!-- language="C" -->
 * static void
 * foo_widget_class_init (FooWidgetClass *klass)
 * {
 *   // ...
 *
 *   gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass),
 *                                                "/com/example/ui/foowidget.ui");
 * }
 * ]|
 *
 * You will also need to call gtk_widget_init_template() from the instance
 * initialization function:
 *
 * |[<!-- language="C" -->
 * static void
 * foo_widget_init (FooWidget *self)
 * {
 *   // ...
 *   gtk_widget_init_template (GTK_WIDGET (self));
 * }
 * ]|
 *
 * You can access widgets defined in the template using the
 * gtk_widget_get_template_child() function, but you will typically declare
 * a pointer in the instance private data structure of your type using the same
 * name as the widget in the template definition, and call
 * gtk_widget_class_bind_template_child_private() with that name, e.g.
 *
 * |[<!-- language="C" -->
 * typedef struct {
 *   GtkWidget *hello_button;
 *   GtkWidget *goodbye_button;
 * } FooWidgetPrivate;
 *
 * G_DEFINE_TYPE_WITH_PRIVATE (FooWidget, foo_widget, GTK_TYPE_BOX)
 *
 * static void
 * foo_widget_class_init (FooWidgetClass *klass)
 * {
 *   // ...
 *   gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass),
 *                                                "/com/example/ui/foowidget.ui");
 *   gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass),
 *                                                 FooWidget, hello_button);
 *   gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass),
 *                                                 FooWidget, goodbye_button);
 * }
 * ]|
 *
 * You can also use gtk_widget_class_bind_template_callback() to connect a signal
 * callback defined in the template with a function visible in the scope of the
 * class, e.g.
 *
 * |[<!-- language="C" -->
 * // the signal handler has the instance and user data swapped
 * // because of the swapped="yes" attribute in the template XML
 * static void
 * hello_button_clicked (FooWidget *self,
 *                       GtkButton *button)
 * {
 *   g_print ("Hello, world!\n");
 * }
 *
 * static void
 * foo_widget_class_init (FooWidgetClass *klass)
 * {
 *   // ...
 *   gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass),
 *                                                "/com/example/ui/foowidget.ui");
 *   gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (klass), hello_button_clicked);
 * }
 * ]|
454 455
 */

456
#define GTK_STATE_FLAGS_DO_PROPAGATE (GTK_STATE_FLAG_INSENSITIVE|GTK_STATE_FLAG_BACKDROP)
457

458
#define WIDGET_CLASS(w)	 GTK_WIDGET_GET_CLASS (w)
Elliot Lee's avatar
Elliot Lee committed
459

460
#define GTK_STATE_FLAGS_BITS 12
461

462 463 464
typedef struct {
  gchar               *name;           /* Name of the template automatic child */
  gboolean             internal_child; /* Whether the automatic widget should be exported as an <internal-child> */
465
  gssize               offset;         /* Instance private data offset where to set the automatic child (or 0) */
466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481
} AutomaticChildClass;

typedef struct {
  gchar     *callback_name;
  GCallback  callback_symbol;
} CallbackSymbol;

typedef struct {
  GBytes               *data;
  GSList               *children;
  GSList               *callbacks;
  GtkBuilderConnectFunc connect_func;
  gpointer              connect_data;
  GDestroyNotify        destroy_notify;
} GtkWidgetTemplate;

482
typedef struct {
483
  GtkEventController *controller;
484
  guint evmask_notify_id;
485
  guint grab_notify_id;
486
  guint sequence_state_changed_id;
487 488
} EventControllerData;

489 490
struct _GtkWidgetPrivate
{
491 492
  /* The state of the widget. Needs to be able to hold all GtkStateFlags bits
   * (defined in "gtkenums.h").
493
   */
494
  guint state_flags : GTK_STATE_FLAGS_BITS;
495

Matthias Clasen's avatar
Matthias Clasen committed
496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513
  guint direction             : 2;

  guint in_destruction        : 1;
  guint toplevel              : 1;
  guint anchored              : 1;
  guint composite_child       : 1;
  guint no_window             : 1;
  guint realized              : 1;
  guint mapped                : 1;
  guint visible               : 1;
  guint sensitive             : 1;
  guint can_focus             : 1;
  guint has_focus             : 1;
  guint can_default           : 1;
  guint has_default           : 1;
  guint receives_default      : 1;
  guint has_grab              : 1;
  guint shadowed              : 1;
514
  guint style_update_pending  : 1;
Matthias Clasen's avatar
Matthias Clasen committed
515
  guint app_paintable         : 1;
516
  guint double_buffered       : 1;
Matthias Clasen's avatar
Matthias Clasen committed
517 518 519 520 521 522
  guint redraw_on_alloc       : 1;
  guint no_show_all           : 1;
  guint child_visible         : 1;
  guint multidevice           : 1;
  guint has_shape_mask        : 1;
  guint in_reparent           : 1;
523 524

  /* Queue-resize related flags */
Matthias Clasen's avatar
Matthias Clasen committed
525
  guint alloc_needed          : 1;
526

527 528 529 530 531 532 533 534 535
  /* Expand-related flags */
  guint need_compute_expand   : 1; /* Need to recompute computed_[hv]_expand */
  guint computed_hexpand      : 1; /* computed results (composite of child flags) */
  guint computed_vexpand      : 1;
  guint hexpand               : 1; /* application-forced expand */
  guint vexpand               : 1;
  guint hexpand_set           : 1; /* whether to use application-forced  */
  guint vexpand_set           : 1; /* instead of computing from children */

536 537 538
  /* SizeGroup related flags */
  guint have_size_groups      : 1;

539
  guint8 alpha;
Alexander Larsson's avatar
Alexander Larsson committed
540
  guint8 user_alpha;
541

542
  /* The widget's name. If the widget does not have a name
543 544
   * (the name is NULL), then its name (as returned by
   * "gtk_widget_get_name") is its class's name.
545
   * Among other things, the widget name is used to determine
546
   * the style to use for a widget.
547 548 549
   */
  gchar *name;

550 551 552 553 554
  /* The list of attached windows to this widget.
   * We keep a list in order to call reset_style to all of them,
   * recursively. */
  GList *attached_windows; 

555
  /* The style for the widget. The style contains the
556 557 558
   * colors the widget should be drawn in for each state
   * along with graphics contexts used to draw with and
   * the font to use for text.
559 560
   */
  GtkStyle *style;
Benjamin Otte's avatar
Benjamin Otte committed
561
  GtkCssNode *cssnode;
562
  GtkStyleContext *context;
563

564 565 566 567
  /* Widget's path for styling */
  GtkWidgetPath *path;

  /* The widget's allocated size */
568
  GtkAllocation allocation;
569
  gint allocated_baseline;
570
  GtkAllocation clip;
571

572 573 574
  /* The widget's requested sizes */
  SizeRequestCache requests;

575
  /* actions attached to this or any parent widget */
576
  GtkActionMuxer *muxer;
577

578
  /* The widget's window or its parent window if it does
579
   * not have a window. (Which will be indicated by the
580
   * no_window field being set).
581 582
   */
  GdkWindow *window;
583
  GList *registered_windows;
584

585
  /* The widget's parent */
586
  GtkWidget *parent;
587

588
  /* Animations and other things to update on clock ticks */
589
  GList *tick_callbacks;
590
  guint clock_tick_id;
591

592 593 594 595
  /* A hash by GType key, containing hash tables by widget name
   */
  GHashTable *auto_children;

596 597 598 599
#ifdef G_ENABLE_DEBUG
  /* Number of gtk_widget_push_verify_invariants () */
  guint verifying_invariants_count;
#endif /* G_ENABLE_DEBUG */
600 601

  GList *event_controllers;
602
};
Elliot Lee's avatar
Elliot Lee committed
603

604 605
struct _GtkWidgetClassPrivate
{
606
  GtkWidgetTemplate *template;
607
  GType accessible_type;
608
  AtkRole accessible_role;
609 610
};

Elliot Lee's avatar
Elliot Lee committed
611
enum {
612
  DESTROY,
Elliot Lee's avatar
Elliot Lee committed
613 614 615 616 617 618 619
  SHOW,
  HIDE,
  MAP,
  UNMAP,
  REALIZE,
  UNREALIZE,
  SIZE_ALLOCATE,
620
  STATE_FLAGS_CHANGED,
Elliot Lee's avatar
Elliot Lee committed
621
  STATE_CHANGED,
622
  PARENT_SET,
Owen Taylor's avatar
Owen Taylor committed
623
  HIERARCHY_CHANGED,
624
  STYLE_SET,
625
  DIRECTION_CHANGED,
626
  GRAB_NOTIFY,
Tim Janik's avatar
Tim Janik committed
627
  CHILD_NOTIFY,
Benjamin Otte's avatar
Benjamin Otte committed
628
  DRAW,
629
  MNEMONIC_ACTIVATE,
630
  GRAB_FOCUS,
631
  FOCUS,
632
  MOVE_FOCUS,
633
  KEYNAV_FAILED,
Elliot Lee's avatar
Elliot Lee committed
634
  EVENT,
635
  EVENT_AFTER,
Elliot Lee's avatar
Elliot Lee committed
636 637
  BUTTON_PRESS_EVENT,
  BUTTON_RELEASE_EVENT,
638
  SCROLL_EVENT,
Elliot Lee's avatar
Elliot Lee committed
639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654
  MOTION_NOTIFY_EVENT,
  DELETE_EVENT,
  DESTROY_EVENT,
  KEY_PRESS_EVENT,
  KEY_RELEASE_EVENT,
  ENTER_NOTIFY_EVENT,
  LEAVE_NOTIFY_EVENT,
  CONFIGURE_EVENT,
  FOCUS_IN_EVENT,
  FOCUS_OUT_EVENT,
  MAP_EVENT,
  UNMAP_EVENT,
  PROPERTY_NOTIFY_EVENT,
  SELECTION_CLEAR_EVENT,
  SELECTION_REQUEST_EVENT,
  SELECTION_NOTIFY_EVENT,
655
  SELECTION_GET,
Elliot Lee's avatar
Elliot Lee committed
656 657 658
  SELECTION_RECEIVED,
  PROXIMITY_IN_EVENT,
  PROXIMITY_OUT_EVENT,
659 660 661 662
  VISIBILITY_NOTIFY_EVENT,
  WINDOW_STATE_EVENT,
  DAMAGE_EVENT,
  GRAB_BROKEN_EVENT,
663 664 665 666 667 668 669 670
  DRAG_BEGIN,
  DRAG_END,
  DRAG_DATA_DELETE,
  DRAG_LEAVE,
  DRAG_MOTION,
  DRAG_DROP,
  DRAG_DATA_GET,
  DRAG_DATA_RECEIVED,
Owen Taylor's avatar
Owen Taylor committed
671
  POPUP_MENU,
672
  SHOW_HELP,
673
  ACCEL_CLOSURES_CHANGED,
Owen Taylor's avatar
Owen Taylor committed
674
  SCREEN_CHANGED,
675
  CAN_ACTIVATE_ACCEL,
Søren Sandmann's avatar
Søren Sandmann committed
676
  COMPOSITED_CHANGED,
Kristian Rietveld's avatar
Kristian Rietveld committed
677
  QUERY_TOOLTIP,
678
  DRAG_FAILED,
679
  STYLE_UPDATED,
680
  TOUCH_EVENT,
Elliot Lee's avatar
Elliot Lee committed
681 682 683
  LAST_SIGNAL
};

684
enum {
Alexander Larsson's avatar
Alexander Larsson committed
685 686 687
  PROP_0,
  PROP_NAME,
  PROP_PARENT,
Havoc Pennington's avatar
Havoc Pennington committed
688 689
  PROP_WIDTH_REQUEST,
  PROP_HEIGHT_REQUEST,
Alexander Larsson's avatar
Alexander Larsson committed
690 691 692 693 694
  PROP_VISIBLE,
  PROP_SENSITIVE,
  PROP_APP_PAINTABLE,
  PROP_CAN_FOCUS,
  PROP_HAS_FOCUS,
695
  PROP_IS_FOCUS,
Alexander Larsson's avatar
Alexander Larsson committed
696 697 698 699 700 701
  PROP_CAN_DEFAULT,
  PROP_HAS_DEFAULT,
  PROP_RECEIVES_DEFAULT,
  PROP_COMPOSITE_CHILD,
  PROP_STYLE,
  PROP_EVENTS,
Kristian Rietveld's avatar
Kristian Rietveld committed
702 703
  PROP_NO_SHOW_ALL,
  PROP_HAS_TOOLTIP,
704
  PROP_TOOLTIP_MARKUP,
Tim Janik's avatar
Tim Janik committed
705
  PROP_TOOLTIP_TEXT,
706
  PROP_WINDOW,
707
  PROP_OPACITY,
708
  PROP_DOUBLE_BUFFERED,
Matthias Clasen's avatar
Matthias Clasen committed
709 710
  PROP_HALIGN,
  PROP_VALIGN,
711 712
  PROP_MARGIN_LEFT,
  PROP_MARGIN_RIGHT,
713 714
  PROP_MARGIN_START,
  PROP_MARGIN_END,
715 716
  PROP_MARGIN_TOP,
  PROP_MARGIN_BOTTOM,
717 718 719 720 721
  PROP_MARGIN,
  PROP_HEXPAND,
  PROP_VEXPAND,
  PROP_HEXPAND_SET,
  PROP_VEXPAND_SET,
722 723
  PROP_EXPAND,
  PROP_SCALE_FACTOR
724 725
};

726 727 728 729
typedef	struct	_GtkStateData	 GtkStateData;

struct _GtkStateData
{
730 731
  guint         flags_to_set;
  guint         flags_to_unset;
732
};
Elliot Lee's avatar
Elliot Lee committed
733

Tim Janik's avatar
Tim Janik committed
734
/* --- prototypes --- */
735
static void	gtk_widget_base_class_init	(gpointer            g_class);
736 737
static void	gtk_widget_class_init		(GtkWidgetClass     *klass);
static void	gtk_widget_base_class_finalize	(GtkWidgetClass     *klass);
Benjamin Otte's avatar
Benjamin Otte committed
738 739
static void     gtk_widget_init                  (GTypeInstance     *instance,
                                                  gpointer           g_class);
Tim Janik's avatar
Tim Janik committed
740
static void	gtk_widget_set_property		 (GObject           *object,
Alexander Larsson's avatar
Alexander Larsson committed
741 742 743
						  guint              prop_id,
						  const GValue      *value,
						  GParamSpec        *pspec);
Tim Janik's avatar
Tim Janik committed
744
static void	gtk_widget_get_property		 (GObject           *object,
Alexander Larsson's avatar
Alexander Larsson committed
745 746 747
						  guint              prop_id,
						  GValue            *value,
						  GParamSpec        *pspec);
748
static void	gtk_widget_constructed           (GObject	    *object);
Tim Janik's avatar
Tim Janik committed
749
static void	gtk_widget_dispose		 (GObject	    *object);
Matthias Clasen's avatar
Matthias Clasen committed
750
static void	gtk_widget_real_destroy		 (GtkWidget	    *object);
Tim Janik's avatar
Tim Janik committed
751 752 753 754 755 756 757 758
static void	gtk_widget_finalize		 (GObject	    *object);
static void	gtk_widget_real_show		 (GtkWidget	    *widget);
static void	gtk_widget_real_hide		 (GtkWidget	    *widget);
static void	gtk_widget_real_map		 (GtkWidget	    *widget);
static void	gtk_widget_real_unmap		 (GtkWidget	    *widget);
static void	gtk_widget_real_realize		 (GtkWidget	    *widget);
static void	gtk_widget_real_unrealize	 (GtkWidget	    *widget);
static void	gtk_widget_real_size_allocate	 (GtkWidget	    *widget,
759
                                                  GtkAllocation	    *allocation);
760 761 762 763
static void	gtk_widget_real_style_set        (GtkWidget         *widget,
                                                  GtkStyle          *previous_style);
static void	gtk_widget_real_direction_changed(GtkWidget         *widget,
                                                  GtkTextDirection   previous_direction);
764

Tim Janik's avatar
Tim Janik committed
765
static void	gtk_widget_real_grab_focus	 (GtkWidget         *focus_widget);
Kristian Rietveld's avatar
Kristian Rietveld committed
766 767 768 769 770
static gboolean gtk_widget_real_query_tooltip    (GtkWidget         *widget,
						  gint               x,
						  gint               y,
						  gboolean           keyboard_tip,
						  GtkTooltip        *tooltip);
771
static void     gtk_widget_real_style_updated    (GtkWidget         *widget);
772
static gboolean gtk_widget_real_show_help        (GtkWidget         *widget,
773
                                                  GtkWidgetHelpType  help_type);
774 775 776
static gboolean _gtk_widget_run_controllers      (GtkWidget           *widget,
                                                  const GdkEvent      *event,
                                                  GtkPropagationPhase  phase);
777

Tim Janik's avatar
Tim Janik committed
778 779 780
static void	gtk_widget_dispatch_child_properties_changed	(GtkWidget        *object,
								 guint             n_pspecs,
								 GParamSpec      **pspecs);
781 782 783 784
static gboolean         gtk_widget_real_button_event            (GtkWidget        *widget,
                                                                 GdkEventButton   *event);
static gboolean         gtk_widget_real_motion_event            (GtkWidget        *widget,
                                                                 GdkEventMotion   *event);
Tim Janik's avatar
Tim Janik committed
785 786 787 788 789 790 791 792
static gboolean		gtk_widget_real_key_press_event   	(GtkWidget        *widget,
								 GdkEventKey      *event);
static gboolean		gtk_widget_real_key_release_event 	(GtkWidget        *widget,
								 GdkEventKey      *event);
static gboolean		gtk_widget_real_focus_in_event   	 (GtkWidget       *widget,
								  GdkEventFocus   *event);
static gboolean		gtk_widget_real_focus_out_event   	(GtkWidget        *widget,
								 GdkEventFocus    *event);
793 794
static gboolean         gtk_widget_real_touch_event             (GtkWidget        *widget,
                                                                 GdkEventTouch    *event);
795 796
static gboolean         gtk_widget_real_grab_broken_event       (GtkWidget          *widget,
                                                                 GdkEventGrabBroken *event);
Tim Janik's avatar
Tim Janik committed
797 798
static gboolean		gtk_widget_real_focus			(GtkWidget        *widget,
								 GtkDirectionType  direction);
799 800
static void             gtk_widget_real_move_focus              (GtkWidget        *widget,
                                                                 GtkDirectionType  direction);
801 802
static gboolean		gtk_widget_real_keynav_failed		(GtkWidget        *widget,
								 GtkDirectionType  direction);
803 804 805 806 807 808 809 810 811
#ifdef G_ENABLE_DEBUG
static void             gtk_widget_verify_invariants            (GtkWidget        *widget);
static void             gtk_widget_push_verify_invariants       (GtkWidget        *widget);
static void             gtk_widget_pop_verify_invariants        (GtkWidget        *widget);
#else
#define                 gtk_widget_verify_invariants(widget)
#define                 gtk_widget_push_verify_invariants(widget)
#define                 gtk_widget_pop_verify_invariants(widget)
#endif
Tim Janik's avatar
Tim Janik committed
812
static PangoContext*	gtk_widget_peek_pango_context		(GtkWidget	  *widget);
813
static void     	gtk_widget_update_pango_context		(GtkWidget	  *widget);
Tim Janik's avatar
Tim Janik committed
814 815
static void		gtk_widget_propagate_state		(GtkWidget	  *widget,
								 GtkStateData 	  *data);
Alexander Larsson's avatar
Alexander Larsson committed
816 817
static void             gtk_widget_update_alpha                 (GtkWidget        *widget);

Tim Janik's avatar
Tim Janik committed
818 819 820 821
static gint		gtk_widget_event_internal		(GtkWidget	  *widget,
								 GdkEvent	  *event);
static gboolean		gtk_widget_real_mnemonic_activate	(GtkWidget	  *widget,
								 gboolean	   group_cycling);
822 823 824 825 826 827 828 829 830 831 832 833 834 835
static void             gtk_widget_real_get_width               (GtkWidget        *widget,
                                                                 gint             *minimum_size,
                                                                 gint             *natural_size);
static void             gtk_widget_real_get_height              (GtkWidget        *widget,
                                                                 gint             *minimum_size,
                                                                 gint             *natural_size);
static void             gtk_widget_real_get_height_for_width    (GtkWidget        *widget,
                                                                 gint              width,
                                                                 gint             *minimum_height,
                                                                 gint             *natural_height);
static void             gtk_widget_real_get_width_for_height    (GtkWidget        *widget,
                                                                 gint              height,
                                                                 gint             *minimum_width,
                                                                 gint             *natural_width);
836 837
static void             gtk_widget_real_state_flags_changed     (GtkWidget        *widget,
                                                                 GtkStateFlags     old_state);
838 839
static void             gtk_widget_real_queue_draw_region       (GtkWidget         *widget,
								 const cairo_region_t *region);
840
static const GtkWidgetAuxInfo* _gtk_widget_get_aux_info_or_defaults (GtkWidget *widget);
841 842
static GtkWidgetAuxInfo* gtk_widget_get_aux_info                (GtkWidget        *widget,
                                                                 gboolean          create);
Tim Janik's avatar
Tim Janik committed
843 844 845 846
static void		gtk_widget_aux_info_destroy		(GtkWidgetAuxInfo *aux_info);
static AtkObject*	gtk_widget_real_get_accessible		(GtkWidget	  *widget);
static void		gtk_widget_accessible_interface_init	(AtkImplementorIface *iface);
static AtkObject*	gtk_widget_ref_accessible		(AtkImplementor *implementor);
847
static void             gtk_widget_invalidate_widget_windows    (GtkWidget        *widget,
848
								 cairo_region_t        *region);
849
static GdkScreen *      gtk_widget_get_screen_unchecked         (GtkWidget        *widget);
850 851
static gboolean         gtk_widget_real_can_activate_accel      (GtkWidget *widget,
                                                                 guint      signal_id);
Kristian Rietveld's avatar
Kristian Rietveld committed
852

853
static void             gtk_widget_real_set_has_tooltip         (GtkWidget *widget,
Kristian Rietveld's avatar
Kristian Rietveld committed
854 855
								 gboolean   has_tooltip,
								 gboolean   force);
Johan Dahlin's avatar
Johan Dahlin committed
856 857 858 859
static void             gtk_widget_buildable_interface_init     (GtkBuildableIface *iface);
static void             gtk_widget_buildable_set_name           (GtkBuildable     *buildable,
                                                                 const gchar      *name);
static const gchar *    gtk_widget_buildable_get_name           (GtkBuildable     *buildable);
860 861 862
static GObject *        gtk_widget_buildable_get_internal_child (GtkBuildable *buildable,
								 GtkBuilder   *builder,
								 const gchar  *childname);
863 864 865 866
static void             gtk_widget_buildable_set_buildable_property (GtkBuildable     *buildable,
								     GtkBuilder       *builder,
								     const gchar      *name,
								     const GValue     *value);
Johan Dahlin's avatar
Johan Dahlin committed
867 868 869 870 871 872
static gboolean         gtk_widget_buildable_custom_tag_start   (GtkBuildable     *buildable,
                                                                 GtkBuilder       *builder,
                                                                 GObject          *child,
                                                                 const gchar      *tagname,
                                                                 GMarkupParser    *parser,
                                                                 gpointer         *data);
873
static void             gtk_widget_buildable_custom_finished    (GtkBuildable     *buildable,
Johan Dahlin's avatar
Johan Dahlin committed
874 875 876 877
                                                                 GtkBuilder       *builder,
                                                                 GObject          *child,
                                                                 const gchar      *tagname,
                                                                 gpointer          data);
878
static void             gtk_widget_buildable_parser_finished    (GtkBuildable     *buildable,
Johan Dahlin's avatar
Johan Dahlin committed
879 880
                                                                 GtkBuilder       *builder);

881
static GtkSizeRequestMode gtk_widget_real_get_request_mode      (GtkWidget         *widget);
882
static void             gtk_widget_real_get_width               (GtkWidget         *widget,
883 884
                                                                 gint              *minimum_size,
                                                                 gint              *natural_size);
885
static void             gtk_widget_real_get_height              (GtkWidget         *widget,
886 887
                                                                 gint              *minimum_size,
                                                                 gint              *natural_size);
888

Matthias Clasen's avatar
Matthias Clasen committed
889
static void             gtk_widget_queue_tooltip_query          (GtkWidget *widget);
890 891 892 893 894 895


static void             gtk_widget_real_adjust_size_request     (GtkWidget         *widget,
                                                                 GtkOrientation     orientation,
                                                                 gint              *minimum_size,
                                                                 gint              *natural_size);
896 897 898
static void             gtk_widget_real_adjust_baseline_request (GtkWidget         *widget,
								 gint              *minimum_baseline,
								 gint              *natural_baseline);
899
static void             gtk_widget_real_adjust_size_allocation  (GtkWidget         *widget,
900
                                                                 GtkOrientation     orientation,
901
                                                                 gint              *minimum_size,
902 903 904
                                                                 gint              *natural_size,
                                                                 gint              *allocated_pos,
                                                                 gint              *allocated_size);
905 906
static void             gtk_widget_real_adjust_baseline_allocation (GtkWidget         *widget,
								    gint              *baseline);
907

908
/* --- functions dealing with template data structures --- */
909 910 911 912
static AutomaticChildClass  *template_child_class_new          (const gchar          *name,
                                                                gboolean              internal_child,
                                                                gssize                offset);
static void                  template_child_class_free         (AutomaticChildClass  *child_class);
913 914 915 916 917 918 919
static CallbackSymbol       *callback_symbol_new                (const gchar          *name,
								 GCallback             callback);
static void                  callback_symbol_free               (CallbackSymbol       *callback);
static void                  template_data_free                 (GtkWidgetTemplate    *template_data);
static GHashTable           *get_auto_child_hash                (GtkWidget            *widget,
								 GType                 type,
								 gboolean              create);
920 921 922 923 924
static gboolean              setup_template_child              (GtkWidgetTemplate    *template_data,
                                                                GType                 class_type,
                                                                AutomaticChildClass  *child_class,
                                                                GtkWidget            *widget,
                                                                GtkBuilder           *builder);
925

926 927 928 929
static void gtk_widget_set_usize_internal (GtkWidget          *widget,
					   gint                width,
					   gint                height,
					   GtkQueueResizeFlags flags);
930

931 932 933
static void gtk_widget_add_events_internal (GtkWidget *widget,
                                            GdkDevice *device,
                                            gint       events);
934 935 936 937
static void gtk_widget_set_device_enabled_internal (GtkWidget *widget,
                                                    GdkDevice *device,
                                                    gboolean   recurse,
                                                    gboolean   enabled);
938 939 940 941

static void gtk_widget_on_frame_clock_update (GdkFrameClock *frame_clock,
                                              GtkWidget     *widget);

942
static gboolean event_window_is_still_viewable (GdkEvent *event);
943 944
static void gtk_cairo_set_event_window (cairo_t        *cr,
					GdkWindow *window);
945 946
static void gtk_cairo_set_event (cairo_t        *cr,
				 GdkEventExpose *event);
Tim Janik's avatar
Tim Janik committed
947

948 949
static void gtk_widget_update_input_shape (GtkWidget *widget);

Tim Janik's avatar
Tim Janik committed
950
/* --- variables --- */
951
static gint             GtkWidget_private_offset = 0;
952
static gpointer         gtk_widget_parent_class = NULL;
953 954 955 956
static guint            widget_signals[LAST_SIGNAL] = { 0 };
static guint            composite_child_stack = 0;
static GtkTextDirection gtk_default_direction = GTK_TEXT_DIR_LTR;
static GParamSpecPool  *style_property_spec_pool = NULL;
957

Tim Janik's avatar
Tim Janik committed
958 959
static GQuark		quark_property_parser = 0;
static GQuark		quark_aux_info = 0;
960 961
static GQuark		quark_accel_path = 0;
static GQuark		quark_accel_closures = 0;
Tim Janik's avatar
Tim Janik committed
962
static GQuark		quark_event_mask = 0;
963
static GQuark           quark_device_event_mask = 0;
Tim Janik's avatar
Tim Janik committed
964 965
static GQuark		quark_parent_window = 0;
static GQuark		quark_shape_info = 0;
966
static GQuark		quark_input_shape_info = 0;
Tim Janik's avatar
Tim Janik committed
967 968
static GQuark		quark_pango_context = 0;
static GQuark		quark_accessible_object = 0;
969
static GQuark		quark_mnemonic_labels = 0;
Kristian Rietveld's avatar
Kristian Rietveld committed
970 971 972
static GQuark		quark_tooltip_markup = 0;
static GQuark		quark_has_tooltip = 0;
static GQuark		quark_tooltip_window = 0;
973
static GQuark		quark_visual = 0;
974
static GQuark           quark_modifier_style = 0;
975
static GQuark           quark_enabled_devices = 0;
976
static GQuark           quark_size_groups = 0;
Tim Janik's avatar
Tim Janik committed
977 978 979 980
GParamSpecPool         *_gtk_widget_child_property_pool = NULL;
GObjectNotifyContext   *_gtk_widget_child_property_notify_context = NULL;

/* --- functions --- */
981 982 983 984 985 986 987 988 989 990
GType
gtk_widget_get_type (void)
{
  static GType widget_type = 0;

  if (G_UNLIKELY (widget_type == 0))
    {
      const GTypeInfo widget_info =
      {
	sizeof (GtkWidgetClass),
991
	gtk_widget_base_class_init,
992 993 994 995 996 997
	(GBaseFinalizeFunc) gtk_widget_base_class_finalize,
	(GClassInitFunc) gtk_widget_class_init,
	NULL,		/* class_finalize */
	NULL,		/* class_init */
	sizeof (GtkWidget),
	0,		/* n_preallocs */
Benjamin Otte's avatar
Benjamin Otte committed
998
	gtk_widget_init,
999 1000 1001 1002 1003 1004 1005 1006 1007 1008
	NULL,		/* value_table */
      };

      const GInterfaceInfo accessibility_info =
      {
	(GInterfaceInitFunc) gtk_widget_accessible_interface_init,
	(GInterfaceFinalizeFunc) NULL,
	NULL /* interface data */
      };

Johan Dahlin's avatar
Johan Dahlin committed
1009 1010 1011 1012 1013 1014 1015
      const GInterfaceInfo buildable_info =
      {
	(GInterfaceInitFunc) gtk_widget_buildable_interface_init,
	(GInterfaceFinalizeFunc) NULL,
	NULL /* interface data */
      };

1016 1017
      widget_type = g_type_register_static (G_TYPE_INITIALLY_UNOWNED, "GtkWidget",
                                            &widget_info, G_TYPE_FLAG_ABSTRACT);
1018

1019 1020
      g_type_add_class_private (widget_type, sizeof (GtkWidgetClassPrivate));

1021 1022 1023
      GtkWidget_private_offset =
        g_type_add_instance_private (widget_type, sizeof (GtkWidgetPrivate));

1024 1025
      g_type_add_interface_static (widget_type, ATK_TYPE_IMPLEMENTOR,
                                   &accessibility_info) ;
Johan Dahlin's avatar
Johan Dahlin committed
1026 1027
      g_type_add_interface_static (widget_type, GTK_TYPE_BUILDABLE,
                                   &buildable_info) ;
1028 1029 1030 1031
    }

  return widget_type;
}
Elliot Lee's avatar
Elliot Lee committed
1032