gtkwidget.c 530 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"
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"
Elliot Lee's avatar
Elliot Lee committed
48
#include "gtkwidget.h"
Emmanuele Bassi's avatar
Emmanuele Bassi committed
49
#include "gtkwidgetprivate.h"
50
#include "gtkwindowprivate.h"
51
#include "gtkcontainerprivate.h"
Tim Janik's avatar
Tim Janik committed
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"
Elliot Lee's avatar
Elliot Lee committed
71

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

75 76 77 78 79 80 81
/**
 * 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.
82
 *
83
 * # Height-for-width Geometry Management # {#geometry-management}
84
 *
85
 * GTK+ uses a height-for-width (and width-for-height) geometry management
86
 * system. Height-for-width means that a widget can change how much
87 88 89
 * 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
90
 * to fewer lines, and therefore needs less height.
91
 *
92
 * Height-for-width geometry management is implemented in GTK+ by way
93
 * of five virtual methods:
94
 *
95 96 97 98 99 100
 * - #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()
101 102 103 104 105
 *
 * 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
106
 * only one orientation at a time. When widgets are initially queried
107 108 109
 * for their minimum sizes it is generally done in two initial passes
 * in the #GtkSizeRequestMode chosen by the toplevel.
 *
110
 * For example, when queried in the normal
111 112
 * %GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH mode:
 * First, the default minimum and natural width for each widget
113
 * in the interface will be computed using gtk_widget_get_preferred_width().
114 115
 * Because the preferred widths for each container depend on the preferred
 * widths of their children, this information propagates up the hierarchy,
116
 * and finally a minimum and natural width is determined for the entire
117 118 119 120 121
 * 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
122 123
 * (unless gtk_window_set_geometry_hints() is explicitly used instead).
 *
124
 * After the toplevel window has initially requested its size in both
125 126
 * dimensions it can go on to allocate itself a reasonable size (or a size
 * previously specified with gtk_window_set_default_size()). During the
127
 * recursive allocation process it’s important to note that request cycles
128
 * will be recursively executed while container widgets allocate their children.
129
 * Each container widget, once allocated a size, will go on to first share the
130
 * space in one orientation among its children and then request each child's
131
 * height for its target allocated width or its width for allocated height,
132
 * depending. In this way a #GtkWidget will typically be requested its size
133 134 135
 * 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
136 137
 * to avoid re-querying for the same sizes in one allocation cycle.
 *
138
 * See
139
 * [GtkContainer’s geometry management section][container-geometry-management]
140
 * to learn more about how height-for-width allocations are performed
141
 * by container widgets.
142
 *
143 144
 * If a widget does move content around to intelligently use up the
 * allocated size then it must support the request in both
145
 * #GtkSizeRequestModes even if the widget in question only
146
 * trades sizes in a single orientation.
147
 *
148
 * For instance, a #GtkLabel that does height-for-width word wrapping
149 150
 * will not expect to have #GtkWidgetClass.get_preferred_height() called
 * because that call is specific to a width-for-height request. In this
151
 * case the label must return the height required for its own minimum
152 153
 * possible width. By following this rule any widget that handles
 * height-for-width or width-for-height requests will always be allocated
154 155 156 157 158
 * 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:
159
 *
160
 * |[<!-- language="C" -->
161
 * static void
162 163 164
 * foo_widget_get_preferred_height (GtkWidget *widget,
 *                                  gint *min_height,
 *                                  gint *nat_height)
165 166 167
 * {
 *    if (i_am_in_height_for_width_mode)
 *      {
168
 *        gint min_width, nat_width;
169
 *
170 171
 *        GTK_WIDGET_GET_CLASS (widget)->get_preferred_width (widget,
 *                                                            &min_width,
172
 *                                                            &nat_width);
173 174 175 176 177
 *        GTK_WIDGET_GET_CLASS (widget)->get_preferred_height_for_width
 *                                                           (widget,
 *                                                            min_width,
 *                                                            min_height,
 *                                                            nat_height);
178 179 180
 *      }
 *    else
 *      {
181 182 183
 *         ... 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.
184 185
 *      }
 * }
186
 * ]|
187
 *
188 189
 * And in #GtkWidgetClass.get_preferred_width_for_height() it will simply return
 * the minimum and natural width:
190
 * |[<!-- language="C" -->
191
 * static void
192 193 194 195
 * foo_widget_get_preferred_width_for_height (GtkWidget *widget,
 *                                            gint for_height,
 *                                            gint *min_width,
 *                                            gint *nat_width)
196 197 198
 * {
 *    if (i_am_in_height_for_width_mode)
 *      {
199 200 201
 *        GTK_WIDGET_GET_CLASS (widget)->get_preferred_width (widget,
 *                                                            min_width,
 *                                                            nat_width);
202 203 204
 *      }
 *    else
 *      {
205 206 207
 *         ... 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.
208 209
 *      }
 * }
210
 * ]|
211 212
 *
 * Often a widget needs to get its own request during size request or
213 214
 * allocation. For example, when computing height it may need to also
 * compute width. Or when deciding how to use an allocation, the widget
215
 * may need to know its natural size. In these cases, the widget should
216
 * be careful to call its virtual methods directly, like this:
217
 *
218
 * |[<!-- language="C" -->
219 220 221
 * GTK_WIDGET_GET_CLASS(widget)->get_preferred_width (widget,
 *                                                    &min,
 *                                                    &natural);
222
 * ]|
223 224
 *
 * It will not work to use the wrapper functions, such as
225
 * gtk_widget_get_preferred_width() inside your own size request
226
 * implementation. These return a request adjusted by #GtkSizeGroup
227
 * and by the #GtkWidgetClass.adjust_size_request() virtual method. If a
228 229 230 231 232 233
 * 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
234 235
 * another widget, such as a child of a
 * container, you must use the wrapper APIs.
236
 * Otherwise, you would not properly consider widget margins,
237
 * #GtkSizeGroup, and so forth.
238
 *
239
 * Since 3.10 GTK+ also supports baseline vertical alignment of widgets. This
240 241 242
 * 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
243
 * that supports baselines and has a natural “row” that it aligns to the baseline,
244 245 246 247 248 249 250
 * 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(),
251
 * so if baselines are not supported it doesn’t need to be implemented.
252 253 254 255 256 257
 *
 * 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.
 *
258
 * # Style Properties
259
 *
260 261
 * #GtkWidget introduces “style
 * properties” - these are basically object properties that are stored
262
 * not on the object, but in the style object associated to the widget. Style
263
 * properties are set in [resource files][gtk3-Resource-Files].
264 265 266
 * 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.
267
 *
268 269 270 271 272
 * 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.
273
 *
274
 * # GtkWidget as GtkBuildable
275
 *
276
 * The GtkWidget implementation of the GtkBuildable interface supports a
277 278
 * custom <accelerator> element, which has attributes named ”key”, ”modifiers”
 * and ”signal” and allows to specify accelerators.
279 280
 *
 * An example of a UI definition fragment specifying an accelerator:
281
 * |[
282 283 284
 * <object class="GtkButton">
 *   <accelerator key="q" modifiers="GDK_CONTROL_MASK" signal="clicked"/>
 * </object>
285
 * ]|
286
 *
287 288 289 290
 * 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.
291 292
 *
 * An example of a UI definition fragment specifying an accessible:
293
 * |[
294 295 296 297 298 299 300 301 302 303
 * <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">
304
 *       <property name="accessible-name">Clickable Button</property>
305 306 307
 *     </object>
 *   </child>
 * </object>
308
 * ]|
309
 *
310
 * Finally, GtkWidget allows style information such as style classes to
311
 * be associated with widgets, using the custom <style> element:
312
 * |[
313 314 315 316 317 318
 * <object class="GtkButton" id="button1">
 *   <style>
 *     <class name="my-special-button-class"/>
 *     <class name="dark-button"/>
 *   </style>
 * </object>
319
 * ]|
320
 *
321
 * # Building composite widgets from template XML ## {#composite-templates}
322
 *
323
 * GtkWidget exposes some facilities to automate the procedure
324 325
 * of creating composite widgets using #GtkBuilder interface description
 * language.
326
 *
327 328 329
 * 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().
330
 *
331
 * The interface description semantics expected in composite template descriptions
332
 * is slightly different from regular #GtkBuilder XML.
333
 *
334 335 336 337 338 339
 * 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
340 341
 * of properties and internal children exist for a given type when the actual
 * type does not exist.
342
 *
343 344 345 346 347
 * 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.
348
 *
349
 * Additionally, <object> tags can also be added before and after the initial
350
 * <template> tag in the normal way, allowing one to define auxiliary objects
351 352
 * which might be referenced by other widgets declared as children of the
 * <template> tag.
353 354
 *
 * An example of a GtkBuilder Template Definition:
355
 * |[
356 357 358 359 360 361 362
 * <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>
363
 *         <signal name="clicked" handler="hello_button_clicked" object="FooWidget" swapped="yes"/>
364 365 366 367 368 369 370 371 372
 *       </object>
 *     </child>
 *     <child>
 *       <object class="GtkButton" id="goodbye_button">
 *         <property name="label">Goodbye World</property>
 *       </object>
 *     </child>
 *   </template>
 * </interface>
373
 * ]|
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
 *
 * 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);
 * }
 * ]|
453 454
 */

455
#define GTK_STATE_FLAGS_DO_PROPAGATE (GTK_STATE_FLAG_INSENSITIVE|GTK_STATE_FLAG_BACKDROP)
456

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

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

479
typedef struct {
480
  GtkEventController *controller;
481
  guint evmask_notify_id;
482
  guint grab_notify_id;
483
  guint sequence_state_changed_id;
484 485
} EventControllerData;

486 487
struct _GtkWidgetClassPrivate
{
488
  GtkWidgetTemplate *template;
489
  GType accessible_type;
490
  AtkRole accessible_role;
491 492
};

Elliot Lee's avatar
Elliot Lee committed
493
enum {
494
  DESTROY,
Elliot Lee's avatar
Elliot Lee committed
495 496 497 498 499 500 501
  SHOW,
  HIDE,
  MAP,
  UNMAP,
  REALIZE,
  UNREALIZE,
  SIZE_ALLOCATE,
502
  STATE_FLAGS_CHANGED,
Elliot Lee's avatar
Elliot Lee committed
503
  STATE_CHANGED,
504
  PARENT_SET,
Owen Taylor's avatar
Owen Taylor committed
505
  HIERARCHY_CHANGED,
506
  STYLE_SET,
507
  DIRECTION_CHANGED,
508
  GRAB_NOTIFY,
Tim Janik's avatar
Tim Janik committed
509
  CHILD_NOTIFY,
Benjamin Otte's avatar
Benjamin Otte committed
510
  DRAW,
511
  MNEMONIC_ACTIVATE,
512
  GRAB_FOCUS,
513
  FOCUS,
514
  MOVE_FOCUS,
515
  KEYNAV_FAILED,
Elliot Lee's avatar
Elliot Lee committed
516
  EVENT,
517
  EVENT_AFTER,
Elliot Lee's avatar
Elliot Lee committed
518 519
  BUTTON_PRESS_EVENT,
  BUTTON_RELEASE_EVENT,
520
  SCROLL_EVENT,
Elliot Lee's avatar
Elliot Lee committed
521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536
  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,
537
  SELECTION_GET,
Elliot Lee's avatar
Elliot Lee committed
538 539 540
  SELECTION_RECEIVED,
  PROXIMITY_IN_EVENT,
  PROXIMITY_OUT_EVENT,
541 542 543 544
  VISIBILITY_NOTIFY_EVENT,
  WINDOW_STATE_EVENT,
  DAMAGE_EVENT,
  GRAB_BROKEN_EVENT,
545 546 547 548 549 550 551 552
  DRAG_BEGIN,
  DRAG_END,
  DRAG_DATA_DELETE,
  DRAG_LEAVE,
  DRAG_MOTION,
  DRAG_DROP,
  DRAG_DATA_GET,
  DRAG_DATA_RECEIVED,
553
  POPUP_MENU,
554
  SHOW_HELP,
555
  ACCEL_CLOSURES_CHANGED,
556
  SCREEN_CHANGED,
557
  CAN_ACTIVATE_ACCEL,
558
  COMPOSITED_CHANGED,
Kristian Rietveld's avatar
Kristian Rietveld committed
559
  QUERY_TOOLTIP,
560
  DRAG_FAILED,
561
  STYLE_UPDATED,
562
  TOUCH_EVENT,
Elliot Lee's avatar
Elliot Lee committed
563 564 565
  LAST_SIGNAL
};

566
enum {
Alexander Larsson's avatar
Alexander Larsson committed
567 568 569
  PROP_0,
  PROP_NAME,
  PROP_PARENT,
Havoc Pennington's avatar
Havoc Pennington committed
570 571
  PROP_WIDTH_REQUEST,
  PROP_HEIGHT_REQUEST,
Alexander Larsson's avatar
Alexander Larsson committed
572 573 574 575 576
  PROP_VISIBLE,
  PROP_SENSITIVE,
  PROP_APP_PAINTABLE,
  PROP_CAN_FOCUS,
  PROP_HAS_FOCUS,
577
  PROP_IS_FOCUS,
Alexander Larsson's avatar
Alexander Larsson committed
578 579 580 581 582 583
  PROP_CAN_DEFAULT,
  PROP_HAS_DEFAULT,
  PROP_RECEIVES_DEFAULT,
  PROP_COMPOSITE_CHILD,
  PROP_STYLE,
  PROP_EVENTS,
Kristian Rietveld's avatar
Kristian Rietveld committed
584 585
  PROP_NO_SHOW_ALL,
  PROP_HAS_TOOLTIP,
586
  PROP_TOOLTIP_MARKUP,
Tim Janik's avatar
Tim Janik committed
587
  PROP_TOOLTIP_TEXT,
588
  PROP_WINDOW,
589
  PROP_OPACITY,
590
  PROP_DOUBLE_BUFFERED,
591 592
  PROP_HALIGN,
  PROP_VALIGN,
593 594
  PROP_MARGIN_LEFT,
  PROP_MARGIN_RIGHT,
595 596
  PROP_MARGIN_START,
  PROP_MARGIN_END,
597 598
  PROP_MARGIN_TOP,
  PROP_MARGIN_BOTTOM,
599 600 601 602 603
  PROP_MARGIN,
  PROP_HEXPAND,
  PROP_VEXPAND,
  PROP_HEXPAND_SET,
  PROP_VEXPAND_SET,
604
  PROP_EXPAND,
605 606
  PROP_SCALE_FACTOR,
  NUM_PROPERTIES
607 608
};

609 610
static GParamSpec *widget_props[NUM_PROPERTIES] = { NULL, };

611 612 613 614
typedef	struct	_GtkStateData	 GtkStateData;

struct _GtkStateData
{
615 616
  guint         flags_to_set;
  guint         flags_to_unset;
617
};
Elliot Lee's avatar
Elliot Lee committed
618

Tim Janik's avatar
Tim Janik committed
619
/* --- prototypes --- */
620
static void	gtk_widget_base_class_init	(gpointer            g_class);
621 622
static void	gtk_widget_class_init		(GtkWidgetClass     *klass);
static void	gtk_widget_base_class_finalize	(GtkWidgetClass     *klass);
623 624
static void     gtk_widget_init                  (GTypeInstance     *instance,
                                                  gpointer           g_class);
Tim Janik's avatar
Tim Janik committed
625
static void	gtk_widget_set_property		 (GObject           *object,
Alexander Larsson's avatar
Alexander Larsson committed
626 627 628
						  guint              prop_id,
						  const GValue      *value,
						  GParamSpec        *pspec);
Tim Janik's avatar
Tim Janik committed
629
static void	gtk_widget_get_property		 (GObject           *object,
Alexander Larsson's avatar
Alexander Larsson committed
630 631 632
						  guint              prop_id,
						  GValue            *value,
						  GParamSpec        *pspec);
633
static void	gtk_widget_constructed           (GObject	    *object);
Tim Janik's avatar
Tim Janik committed
634
static void	gtk_widget_dispose		 (GObject	    *object);
635
static void	gtk_widget_real_destroy		 (GtkWidget	    *object);
Tim Janik's avatar
Tim Janik committed
636 637 638 639 640 641 642 643
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,
644
                                                  GtkAllocation	    *allocation);
645 646 647 648
static void	gtk_widget_real_style_set        (GtkWidget         *widget,
                                                  GtkStyle          *previous_style);
static void	gtk_widget_real_direction_changed(GtkWidget         *widget,
                                                  GtkTextDirection   previous_direction);
649

Tim Janik's avatar
Tim Janik committed
650
static void	gtk_widget_real_grab_focus	 (GtkWidget         *focus_widget);
Kristian Rietveld's avatar
Kristian Rietveld committed
651 652 653 654 655
static gboolean gtk_widget_real_query_tooltip    (GtkWidget         *widget,
						  gint               x,
						  gint               y,
						  gboolean           keyboard_tip,
						  GtkTooltip        *tooltip);
656
static void     gtk_widget_real_style_updated    (GtkWidget         *widget);
657
static gboolean gtk_widget_real_show_help        (GtkWidget         *widget,
658
                                                  GtkWidgetHelpType  help_type);
659 660 661
static gboolean _gtk_widget_run_controllers      (GtkWidget           *widget,
                                                  const GdkEvent      *event,
                                                  GtkPropagationPhase  phase);
662

Tim Janik's avatar
Tim Janik committed
663 664 665
static void	gtk_widget_dispatch_child_properties_changed	(GtkWidget        *object,
								 guint             n_pspecs,
								 GParamSpec      **pspecs);
666 667 668 669
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
670 671 672 673 674 675 676 677
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);
678 679
static gboolean         gtk_widget_real_touch_event             (GtkWidget        *widget,
                                                                 GdkEventTouch    *event);
680 681
static gboolean         gtk_widget_real_grab_broken_event       (GtkWidget          *widget,
                                                                 GdkEventGrabBroken *event);
Tim Janik's avatar
Tim Janik committed
682 683
static gboolean		gtk_widget_real_focus			(GtkWidget        *widget,
								 GtkDirectionType  direction);
684 685
static void             gtk_widget_real_move_focus              (GtkWidget        *widget,
                                                                 GtkDirectionType  direction);
686 687
static gboolean		gtk_widget_real_keynav_failed		(GtkWidget        *widget,
								 GtkDirectionType  direction);
688
#ifdef G_ENABLE_CONSISTENCY_CHECKS
689 690 691 692 693 694 695 696
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
697
static PangoContext*	gtk_widget_peek_pango_context		(GtkWidget	  *widget);
698
static void     	gtk_widget_update_pango_context		(GtkWidget	  *widget);
Tim Janik's avatar
Tim Janik committed
699 700
static void		gtk_widget_propagate_state		(GtkWidget	  *widget,
								 GtkStateData 	  *data);
Alexander Larsson's avatar
Alexander Larsson committed
701 702
static void             gtk_widget_update_alpha                 (GtkWidget        *widget);

Tim Janik's avatar
Tim Janik committed
703 704 705 706
static gint		gtk_widget_event_internal		(GtkWidget	  *widget,
								 GdkEvent	  *event);
static gboolean		gtk_widget_real_mnemonic_activate	(GtkWidget	  *widget,
								 gboolean	   group_cycling);
707 708 709 710 711 712 713 714 715 716 717 718 719 720
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);
721 722
static void             gtk_widget_real_state_flags_changed     (GtkWidget        *widget,
                                                                 GtkStateFlags     old_state);
723 724
static void             gtk_widget_real_queue_draw_region       (GtkWidget         *widget,
								 const cairo_region_t *region);
725
static const GtkWidgetAuxInfo* _gtk_widget_get_aux_info_or_defaults (GtkWidget *widget);
726 727
static GtkWidgetAuxInfo* gtk_widget_get_aux_info                (GtkWidget        *widget,
                                                                 gboolean          create);
Tim Janik's avatar
Tim Janik committed
728 729 730 731
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);
732
static void             gtk_widget_invalidate_widget_windows    (GtkWidget        *widget,
733
								 cairo_region_t        *region);
734
static GdkScreen *      gtk_widget_get_screen_unchecked         (GtkWidget        *widget);
735 736
static gboolean         gtk_widget_real_can_activate_accel      (GtkWidget *widget,
                                                                 guint      signal_id);
Kristian Rietveld's avatar
Kristian Rietveld committed
737

738
static void             gtk_widget_real_set_has_tooltip         (GtkWidget *widget,
Kristian Rietveld's avatar
Kristian Rietveld committed
739 740
								 gboolean   has_tooltip,
								 gboolean   force);
741 742 743 744
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);
745 746 747
static GObject *        gtk_widget_buildable_get_internal_child (GtkBuildable *buildable,
								 GtkBuilder   *builder,
								 const gchar  *childname);
748 749 750 751
static void             gtk_widget_buildable_set_buildable_property (GtkBuildable     *buildable,
								     GtkBuilder       *builder,
								     const gchar      *name,
								     const GValue     *value);
752 753 754 755 756 757
static gboolean         gtk_widget_buildable_custom_tag_start   (GtkBuildable     *buildable,
                                                                 GtkBuilder       *builder,
                                                                 GObject          *child,
                                                                 const gchar      *tagname,
                                                                 GMarkupParser    *parser,
                                                                 gpointer         *data);
758
static void             gtk_widget_buildable_custom_finished    (GtkBuildable     *buildable,
759 760 761 762
                                                                 GtkBuilder       *builder,
                                                                 GObject          *child,
                                                                 const gchar      *tagname,
                                                                 gpointer          data);
763
static void             gtk_widget_buildable_parser_finished    (GtkBuildable     *buildable,
764 765
                                                                 GtkBuilder       *builder);

766
static GtkSizeRequestMode gtk_widget_real_get_request_mode      (GtkWidget         *widget);
767
static void             gtk_widget_real_get_width               (GtkWidget         *widget,
768 769
                                                                 gint              *minimum_size,
                                                                 gint              *natural_size);
770
static void             gtk_widget_real_get_height              (GtkWidget         *widget,
771 772
                                                                 gint              *minimum_size,
                                                                 gint              *natural_size);
773

Matthias Clasen's avatar
Matthias Clasen committed
774
static void             gtk_widget_queue_tooltip_query          (GtkWidget *widget);
775 776 777 778 779 780


static void             gtk_widget_real_adjust_size_request     (GtkWidget         *widget,
                                                                 GtkOrientation     orientation,
                                                                 gint              *minimum_size,
                                                                 gint              *natural_size);
781 782 783
static void             gtk_widget_real_adjust_baseline_request (GtkWidget         *widget,
								 gint              *minimum_baseline,
								 gint              *natural_baseline);
784
static void             gtk_widget_real_adjust_size_allocation  (GtkWidget         *widget,
785
                                                                 GtkOrientation     orientation,
786
                                                                 gint              *minimum_size,
787 788 789
                                                                 gint              *natural_size,
                                                                 gint              *allocated_pos,
                                                                 gint              *allocated_size);
790 791
static void             gtk_widget_real_adjust_baseline_allocation (GtkWidget         *widget,
								    gint              *baseline);
792

793
/* --- functions dealing with template data structures --- */
794 795 796 797
static AutomaticChildClass  *template_child_class_new          (const gchar          *name,
                                                                gboolean              internal_child,
                                                                gssize                offset);
static void                  template_child_class_free         (AutomaticChildClass  *child_class);
798 799 800 801 802 803 804
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);
805 806 807 808 809
static gboolean              setup_template_child              (GtkWidgetTemplate    *template_data,
                                                                GType                 class_type,
                                                                AutomaticChildClass  *child_class,
                                                                GtkWidget            *widget,
                                                                GtkBuilder           *builder);
810

811 812 813 814
static void gtk_widget_set_usize_internal (GtkWidget          *widget,
					   gint                width,
					   gint                height,
					   GtkQueueResizeFlags flags);
815

816 817 818
static void gtk_widget_add_events_internal (GtkWidget *widget,
                                            GdkDevice *device,
                                            gint       events);
819 820 821 822
static void gtk_widget_set_device_enabled_internal (GtkWidget *widget,
                                                    GdkDevice *device,
                                                    gboolean   recurse,
                                                    gboolean   enabled);
823 824 825 826

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

827
static gboolean event_window_is_still_viewable (GdkEvent *event);
828 829
static void gtk_cairo_set_event_window (cairo_t        *cr,
					GdkWindow *window);
830 831
static void gtk_cairo_set_event (cairo_t        *cr,
				 GdkEventExpose *event);
Tim Janik's avatar
Tim Janik committed
832

833 834
static void gtk_widget_update_input_shape (GtkWidget *widget);

Tim Janik's avatar
Tim Janik committed
835
/* --- variables --- */
836
static gint             GtkWidget_private_offset = 0;
837
static gpointer         gtk_widget_parent_class = NULL;
838 839
static guint            widget_signals[LAST_SIGNAL] = { 0 };
static guint            composite_child_stack = 0;
840
GtkTextDirection gtk_default_direction = GTK_TEXT_DIR_LTR;
841
static GParamSpecPool  *style_property_spec_pool = NULL;
842

Tim Janik's avatar
Tim Janik committed
843 844
static GQuark		quark_property_parser = 0;
static GQuark		quark_aux_info = 0;
845 846
static GQuark		quark_accel_path = 0;
static GQuark		quark_accel_closures = 0;
Tim Janik's avatar
Tim Janik committed
847
static GQuark		quark_event_mask = 0;
848
static GQuark           quark_device_event_mask = 0;
Tim Janik's avatar
Tim Janik committed
849 850
static GQuark		quark_parent_window = 0;
static GQuark		quark_shape_info = 0;
851
static GQuark		quark_input_shape_info = 0;
Tim Janik's avatar
Tim Janik committed
852 853
static GQuark		quark_pango_context = 0;
static GQuark		quark_accessible_object = 0;
854
static GQuark		quark_mnemonic_labels = 0;
Kristian Rietveld's avatar
Kristian Rietveld committed
855 856 857
static GQuark		quark_tooltip_markup = 0;
static GQuark		quark_has_tooltip = 0;
static GQuark		quark_tooltip_window = 0;
858
static GQuark		quark_visual = 0;
859
static GQuark           quark_modifier_style = 0;
860
static GQuark           quark_enabled_devices = 0;
861
static GQuark           quark_size_groups = 0;
Tim Janik's avatar
Tim Janik committed
862 863 864 865
GParamSpecPool         *_gtk_widget_child_property_pool = NULL;
GObjectNotifyContext   *_gtk_widget_child_property_notify_context = NULL;

/* --- functions --- */
866 867 868 869 870 871 872 873 874 875
GType
gtk_widget_get_type (void)
{
  static GType widget_type = 0;

  if (G_UNLIKELY (widget_type == 0))
    {
      const GTypeInfo widget_info =
      {
	sizeof (GtkWidgetClass),
876
	gtk_widget_base_class_init,
877 878 879 880 881 882
	(GBaseFinalizeFunc) gtk_widget_base_class_finalize,
	(GClassInitFunc) gtk_widget_class_init,
	NULL,		/* class_finalize */
	NULL,		/* class_init */
	sizeof (GtkWidget),
	0,		/* n_preallocs */
883
	gtk_widget_init,
884 885 886 887 888 889 890 891 892 893
	NULL,		/* value_table */
      };

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

894 895 896 897 898 899 900
      const GInterfaceInfo buildable_info =
      {
	(GInterfaceInitFunc) gtk_widget_buildable_interface_init,
	(GInterfaceFinalizeFunc) NULL,
	NULL /* interface data */
      };

901 902
      widget_type = g_type_register_static (G_TYPE_INITIALLY_UNOWNED, "GtkWidget",
                                            &widget_info, G_TYPE_FLAG_ABSTRACT);
903

904 905
      g_type_add_class_private (widget_type, sizeof (GtkWidgetClassPrivate));

906 907 908
      GtkWidget_private_offset =
        g_type_add_instance_private (widget_type, sizeof (GtkWidgetPrivate));

909 910
      g_type_add_interface_static (widget_type, ATK_TYPE_IMPLEMENTOR,
                                   &accessibility_info) ;
911 912
      g_type_add_interface_static (widget_type, GTK_TYPE_BUILDABLE,
                                   &buildable_info) ;
913 914 915 916
    }

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

918 919 920 921 922 923
static inline gpointer
gtk_widget_get_instance_private (GtkWidget *self)
{
  return (G_STRUCT_MEMBER_P (self, GtkWidget_private_offset));
}

924 925 926 927 928
static void
gtk_widget_base_class_init (gpointer g_class)
{
  GtkWidgetClass *klass = g_class;

929
  klass->priv = G_TYPE_CLASS_GET_PRIVATE (g_class, GTK_TYPE_WIDGET, GtkWidgetClassPrivate);
930
  klass->priv->template = NULL;
931 932
}

Tim Janik's avatar
Tim Janik committed
933 934 935 936 937 938 939 940
static void
child_property_notify_dispatcher (GObject     *object,
				  guint        n_pspecs,
				  GParamSpec **pspecs)
{
  GTK_WIDGET_GET_CLASS (object)->dispatch_child_properties_changed (GTK_WIDGET (object), n_pspecs, pspecs);
}

941
/* We guard against the draw signal callbacks modifying the state of the
942
 * cairo context by surrounding it with save/restore.
943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998
 * Maybe we should also cairo_new_path() just to be sure?
 */
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)
{
  cairo_t *cr = g_value_get_boxed (&param_values[1]);

  cairo_save (cr);

  _gtk_marshal_BOOLEAN__BOXED (closure,
                               return_value,
                               n_param_values,
                               param_values,
                               invocation_hint,
                               marshal_data);


  cairo_restore (cr);
}

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)
{
  cairo_t *cr;
  va_list args_copy;

  G_VA_COPY (args_copy, args);
  cr = va_arg (args_copy, gpointer);

  cairo_save (cr);

  _gtk_marshal_BOOLEAN__BOXEDv (closure,
				return_value,
				instance,
				args,
				marshal_data,
				n_params,
				param_types);


  cairo_restore (cr);

  va_end (args_copy);
}

Elliot Lee's avatar
Elliot Lee committed
999 1000 1001
static void
gtk_widget_class_init (GtkWidgetClass *klass)
{
Tim Janik's avatar
Tim Janik committed
1002
  static GObjectNotifyContext cpn_context = { 0, NULL, NULL };
1003
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
1004
  GtkBindingSet *binding_set;
1005

1006
  g_type_class_adjust_private_offset (klass, &GtkWidget_private_offset);
1007 1008
  gtk_widget_parent_class = g_type_class_peek_parent (klass);

Tim Janik's avatar
Tim Janik committed
1009 1010
  quark_property_parser = g_quark_from_static_string ("gtk-rc-property-parser");
  quark_aux_info = g_quark_from_static_string ("gtk-aux-info");
1011 1012
  quark_accel_path = g_quark_from_static_string ("gtk-accel-path");
  quark_accel_closures = g_quark_from_static_string ("gtk-accel-closures");
Tim Janik's avatar
Tim Janik committed
1013
  quark_event_mask = g_quark_from_static_string ("gtk-event-mask");
1014
  quark_device_event_mask = g_quark_from_static_string ("gtk-device-event-mask");
Tim Janik's avatar
Tim Janik committed
1015 1016
  quark_parent_window = g_quark_from_static_string ("gtk-parent-window");
  quark_shape_info = g_quark_from_static_string ("gtk-shape-info");
1017
  quark_input_shape_info = g_quark_from_static_string ("gtk-input-shape-info");
Tim Janik's avatar
Tim Janik committed
1018 1019
  quark_pango_context = g_quark_from_static_string ("gtk-pango-context");
  quark_accessible_object = g_quark_from_static_string ("gtk-accessible-object");
1020
  quark_mnemonic_labels = g_quark_from_static_string ("gtk-mnemonic-labels");
Kristian Rietveld's avatar
Kristian Rietveld committed
1021 1022 1023
  quark_tooltip_markup = g_quark_from_static_string ("gtk-tooltip-markup");
  quark_has_tooltip = g_quark_from_static_string ("gtk-has-tooltip");
  quark_tooltip_window = g_quark_from_static_string ("gtk-tooltip-window");
1024
  quark_visual = g_quark_from_static_string ("gtk-widget-visual");
1025
  quark_modifier_style = g_quark_from_static_string ("gtk-widget-modifier-style");
1026
  quark_enabled_devices = g_quark_from_static_string ("gtk-widget-enabled-devices");
1027
  quark_size_groups = g_quark_from_static_string ("gtk-widget-size-groups");
Tim Janik's avatar
Tim Janik committed
1028 1029 1030 1031 1032 1033

  style_property_spec_pool = g_param_spec_pool_new (FALSE);
  _gtk_widget_child_property_pool = g_param_spec_pool_new (TRUE);
  cpn_context.quark_notify_queue = g_quark_from_static_string ("GtkWidget-child-property-notify-queue");
  cpn_context.dispatcher = child_property_notify_dispatcher;
  _gtk_widget_child_property_notify_context = &cpn_context;
1034

1035
  gobject_class->constructed = gtk_widget_constructed;
Tim Janik's avatar
Tim Janik committed
1036
  gobject_class->dispose = gtk_widget_dispose;
1037
  gobject_class->finalize = gtk_widget_finalize;
Alexander Larsson's avatar
Alexander Larsson committed
1038 1039
  gobject_class->set_property = gtk_widget_set_property;
  gobject_class->get_property = gtk_widget_get_property;
1040

1041 1042
  klass->destroy = gtk_widget_real_destroy;

1043
  klass->activate_signal = 0;
Tim Janik's avatar
Tim Janik committed
1044
  klass->dispatch_child_properties_changed = gtk_widget_dispatch_child_properties_changed;
1045 1046 1047 1048 1049 1050 1051 1052
  klass->show = gtk_widget_real_show;
  klass->show_all = gtk_widget_show;
  klass->hide = gtk_widget_real_hide;
  klass->map = gtk_widget_real_map;
  klass->unmap = gtk_widget_real_unmap;
  klass->realize = gtk_widget_real_realize;
  klass->unrealize = gtk_widget_real_unrealize;
  klass->size_allocate = gtk_widget_real_size_allocate;
1053
  klass->get_request_mode = gtk_widget_real_get_request_mode;
1054 1055 1056
  klass->get_preferred_width = gtk_widget_real_get_width;
  klass->get_preferred_height = gtk_widget_real_get_height;
  klass->get_preferred_width_for_height = gtk_widget_real_get_width_for_height;
1057
  klass->get_preferred_height_for_width = gtk_widget_real_get_height_for_width;
1058
  klass->get_preferred_height_and_baseline_for_width = NULL;
1059
  klass->state_changed = NULL;
1060
  klass->state_flags_changed = gtk_widget_real_state_flags_changed;
1061
  klass->parent_set = NULL;
Owen Taylor's avatar
Owen Taylor committed
1062
  klass->hierarchy_changed = NULL;
1063 1064
  klass->style_set = gtk_widget_real_style_set;
  klass->direction_changed = gtk_widget_real_direction_changed;
Tim Janik's avatar
Tim Janik committed
1065 1066
  klass->grab_notify = NULL;
  klass->child_notify = NULL;
Benjamin Otte's avatar
Benjamin Otte committed
1067
  klass->draw = NULL;
1068
  klass->mnemonic_activate = gtk_widget_real_mnemonic_activate;
1069
  klass->grab_focus = gtk_widget_real_grab_focus;
1070
  klass->focus = gtk_widget_real_focus;
1071 1072
  klass->move_focus = gtk_widget_real_move_focus;
  klass->keynav_failed = gtk_widget_real_keynav_failed;
1073
  klass->event = NULL;
1074 1075 1076
  klass->button_press_event = gtk_widget_real_button_event;
  klass->button_release_event = gtk_widget_real_button_event;
  klass->motion_notify_event = gtk_widget_real_motion_event;
1077
  klass->touch_event = gtk_widget_real_touch_event;
1078 1079 1080 1081 1082 1083 1084
  klass->delete_event = NULL;
  klass->destroy_event = NULL;
  klass->key_press_event = gtk_widget_real_key_press_event;
  klass->key_release_event = gtk_widget_real_key_release_event;
  klass->enter_notify_event = NULL;
  klass->leave_notify_event = NULL;
  klass->configure_event = NULL;
1085 1086
  klass->focus_in_event = gtk_widget_real_focus_in_event;
  klass->focus_out_event = gtk_widget_real_focus_out_event;
1087 1088
  klass->map_event = NULL;
  klass->unmap_event = NULL;
1089
  klass->window_state_event = NULL;
1090
  klass->property_notify_event = _gtk_selection_property_notify;
1091
  klass->selection_clear_event = _gtk_selection_clear;
1092 1093
  klass->selection_request_event = _gtk_selection_request;
  klass->selection_notify_event = _gtk_selection_notify;
1094 1095 1096 1097 1098 1099 1100 1101 1102 1103
  klass->selection_received = NULL;
  klass->proximity_in_event = NULL;
  klass->proximity_out_event = NULL;
  klass->drag_begin = NULL;
  klass->drag_end = NULL;
  klass->drag_data_delete = NULL;
  klass->drag_leave = NULL;
  klass->drag_motion = NULL;
  klass->drag_drop = NULL;
  klass->drag_data_received = NULL;
1104
  klass->screen_changed = NULL;
1105
  klass->can_activate_accel = gtk_widget_real_can_activate_accel;
1106
  klass->grab_broken_event = gtk_widget_real_grab_broken_event;
Kristian Rietveld's avatar
Kristian Rietveld committed
1107
  klass->query_tooltip = gtk_widget_real_query_tooltip;
1108
  klass->style_updated = gtk_widget_real_style_updated;
1109 1110

  klass->show_help = gtk_widget_real_show_help;
1111

1112
  /* Accessibility support */
1113
  klass->priv->accessible_type = GTK_TYPE_ACCESSIBLE;
1114
  klass->priv->accessible_role = ATK_ROLE_INVALID;
1115 1116
  klass->get_accessible = gtk_widget_real_get_accessible;

1117
  klass->adjust_size_request = gtk_widget_real_adjust_size_request;
1118
  klass->adjust_baseline_request = gtk_widget_real_adjust_baseline_request;
1119
  klass->adjust_size_allocation = gtk_widget_real_adjust_size_allocation;
1120
  klass->adjust_baseline_allocation = gtk_widget_real_adjust_baseline_allocation;
1121
  klass->queue_draw_region = gtk_widget_real_queue_draw_region;
1122

1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221
  widget_props[PROP_NAME] =
      g_param_spec_string ("name",
                           P_("Widget name"),
                           P_("The name of the widget"),
                           NULL,
                           GTK_PARAM_READWRITE);

  widget_props[PROP_PARENT] =
      g_param_spec_object ("parent",
                           P_("Parent widget"),
                           P_("The parent widget of this widget. Must be a Container widget"),
                           GTK_TYPE_CONTAINER,
                           GTK_PARAM_READWRITE);

  widget_props[PROP_WIDTH_REQUEST] =
      g_param_spec_int ("width-request",
                        P_("Width request"),
                        P_("Override for width request of the widget, or -1 if natural request should be used"),
                        -1, G_MAXINT,
                        -1,
                        GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);

  widget_props[PROP_HEIGHT_REQUEST] =
      g_param_spec_int ("height-request",
                        P_("Height request"),
                        P_("Override for height request of the widget, or -1 if natural request should be used"),
                        -1, G_MAXINT,
                        -1,
                        GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);

  widget_props[PROP_VISIBLE] =
      g_param_spec_boolean ("visible",
                            P_("Visible"),
                            P_("Whether the widget is visible"),
                            FALSE,
                            GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);

  widget_props[PROP_SENSITIVE] =
      g_param_spec_boolean ("sensitive",
                            P_("Sensitive"),
                            P_("Whether the widget responds to input"),
                            TRUE,
                            GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);

  widget_props[PROP_APP_PAINTABLE] =
      g_param_spec_boolean ("app-paintable",
                            P_("Application paintable"),
                            P_("Whether the application will paint directly on the widget"),
                            FALSE,
                            GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);

  widget_props[PROP_CAN_FOCUS] =
      g_param_spec_boolean ("can-focus",
                            P_("Can focus"),
                            P_("Whether the widget can accept the input focus"),
                            FALSE,
                            GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);

  widget_props[PROP_HAS_FOCUS] =
      g_param_spec_boolean ("has-focus",
                            P_("Has focus"),
                            P_("Whether the widget has the input focus"),
                            FALSE,
                            GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);

  widget_props[PROP_IS_FOCUS] =
      g_param_spec_boolean ("is-focus",
                            P_("Is focus"),
                            P_("Whether the widget is the focus widget within the toplevel"),
                            FALSE,
                            GTK_PARAM_READWRITE);

  widget_props[PROP_CAN_DEFAULT] =
      g_param_spec_boolean ("can-default",
                            P_("Can default"),
                            P_("Whether the widget can be the default widget"),
                            FALSE,
                            GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);

  widget_props[PROP_HAS_DEFAULT] =
      g_param_spec_boolean ("has-default",
                            P_("Has default"),
                            P_("Whether the widget is the default widget"),
                            FALSE,
                            GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);

  widget_props[PROP_RECEIVES_DEFAULT] =
      g_param_spec_boolean ("receives-default",
                            P_("Receives default"),
                            P_("If TRUE, the widget will receive the default action when it is focused"),
                            FALSE,
                            GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);

  widget_props[PROP_COMPOSITE_CHILD] =
      g_param_spec_boolean ("composite-child",
                            P_("Composite child"),
                            P_("Whether the widget is part of a composite widget"),
                            FALSE,
                            GTK_PARAM_READABLE);
1222 1223 1224

G_GNUC_BEGIN_IGNORE_DEPRECATIONS

1225 1226 1227 1228 1229 1230
  widget_props[PROP_STYLE] =
      g_param_spec_object ("style",
                           P_("Style"),
                           P_("The style of the widget, which contains information about how it will look (colors etc)"),
                           GTK_TYPE_STYLE,
                           GTK_PARAM_READWRITE|G_PARAM_DEPRECATED);
1231 1232 1233

G_GNUC_END_IGNORE_DEPRECATIONS

1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247
  widget_props[PROP_EVENTS] =
      g_param_spec_flags ("events",
                          P_("Events"),
                          P_("The event mask that decides what kind of GdkEvents this widget gets"),
                          GDK_TYPE_EVENT_MASK,
                          GDK_STRUCTURE_MASK,
                          GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);

  widget_props[PROP_NO_SHOW_ALL] =
      g_param_spec_boolean ("no-show-all",
                            P_("No show all"),
                            P_("Whether gtk_widget_show_all() should not affect this widget"),
                            FALSE,
                            GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
Kristian Rietveld's avatar
Kristian Rietveld committed
1248 1249 1250 1251

/**
 * GtkWidget:has-tooltip:
 *
1252
 * Enables or disables the emission of #GtkWidget::query-tooltip on @widget.
1253 1254
 * A value of %TRUE indicates that @widget can have a tooltip, in this case
 * the widget will be queried using #GtkWidget::query-tooltip to determine
Kristian Rietveld's avatar
Kristian Rietveld committed
1255 1256
 * whether it will provide a tooltip or not.
 *
1257 1258 1259 1260 1261
 * Note that setting this property to %TRUE for the first time will change
 * the event masks of the GdkWindows of this widget to include leave-notify
 * and motion-notify events.  This cannot and will not be undone when the
 * property is set to %FALSE again.
 *
Kristian Rietveld's avatar
Kristian Rietveld committed
1262 1263
 * Since: 2.12
 */
1264 1265 1266 1267 1268 1269 1270
  widget_props[PROP_HAS_TOOLTIP] =
      g_param_spec_boolean ("has-tooltip",
                            P_("Has tooltip"),
                            P_("Whether this widget has a tooltip"),
                            FALSE,
                            GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);

1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282
  /**
   * GtkWidget:tooltip-text:
   *
   * Sets the text of tooltip to be the given string.
   *
   * Also see gtk_tooltip_set_text().
   *
   * This is a convenience property which will take care of getting the
   * tooltip shown if the given string is not %NULL: #GtkWidget:has-tooltip
   * will automatically be set to %TRUE and there will be taken care of
   * #GtkWidget::query-tooltip in the default signal handler.
   *
1283 1284 1285
   * Note that if both #GtkWidget:tooltip-text and #GtkWidget:tooltip-markup
   * are set, the last one wins.
   *
1286 1287
   * Since: 2.12
   */
1288 1289 1290 1291 1292 1293 1294
  widget_props[PROP_TOOLTIP_TEXT] =
      g_param_spec_string ("tooltip-text",
                           P_("Tooltip Text"),
                           P_("The contents of the tooltip for this widget"),
                           NULL,
                           GTK_PARAM_READWRITE);

1295 1296 1297 1298
  /**
   * GtkWidget:tooltip-markup:
   *
   * Sets the text of tooltip to be the given string, which is marked up
1299
   * with the [Pango text markup language][PangoMarkupFormat].
1300 1301 1302 1303 1304 1305 1306
   * Also see gtk_tooltip_set_markup().
   *
   * This is a convenience property which will take care of getting the
   * tooltip shown if the given string is not %NULL: #GtkWidget:has-tooltip
   * will automatically be set to %TRUE and there will be taken care of
   * #GtkWidget::query-tooltip in the default signal handler.
   *
1307 1308 1309
   * Note that if both #GtkWidget:tooltip-text and #GtkWidget:tooltip-markup
   * are set, the last one wins.
   *
1310 1311
   * Since: 2.12
   */
1312 1313 1314 1315 1316 1317
  widget_props[PROP_TOOLTIP_MARKUP] =
      g_param_spec_string ("tooltip-markup",
                           P_("Tooltip markup"),
                           P_("The contents of the tooltip for this widget"),
                           NULL,
                           GTK_PARAM_READWRITE);
Kristian Rietveld's avatar
Kristian Rietveld committed
1318

Tim Janik's avatar
Tim Janik committed
1319 1320 1321
  /**
   * GtkWidget:window:
   *
1322
   * The widget's window if it is realized, %NULL otherwise.
Tim Janik's avatar
Tim Janik committed
1323
   *
1324
   * Since: 2.14
Tim Janik's avatar
Tim Janik committed
1325
   */
1326 1327 1328 1329 1330 1331
  widget_props[PROP_WINDOW] =
      g_param_spec_object ("window",
                           P_("Window"),
                           P_("The widget's window if it is realized"),
                           GDK_TYPE_WINDOW,
                           GTK_PARAM_READABLE);
Tim Janik's avatar
Tim Janik committed
1332

1333
  /**
1334
   * GtkWidget:double-buffered:
1335
   *
1336
   * Whether the widget is double buffered.
1337 1338
   *
   * Since: 2.18
1339
   *
1340
   * Deprecated: 3.14: Widgets should not use this property.
1341
   */
1342 1343 1344 1345 1346 1347
  widget_props[PROP_DOUBLE_BUFFERED] =
      g_param_spec_boolean ("double-buffered",
                            P_("Double Buffered"),
                            P_("Whether the widget is double buffered"),
                            TRUE,
                            GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY|G_PARAM_DEPRECATED);
1348

1349
  /**