Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: b359113b40
Fetching contributors…

Cannot retrieve contributors at this time

14495 lines (12803 sloc) 444.493 kb
/* GTK - The GIMP Toolkit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* 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
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "config.h"
#include <stdarg.h>
#include <string.h>
#include <locale.h>
#include <gobject/gvaluecollector.h>
#include <gobject/gobjectnotifyqueue.c>
#include <cairo-gobject.h>
#include "gtkcontainer.h"
#include "gtkaccelmap.h"
#include "gtkclipboard.h"
#include "gtkiconfactory.h"
#include "gtkintl.h"
#include "gtkmainprivate.h"
#include "gtkmarshalers.h"
#include "gtkselectionprivate.h"
#include "gtksettingsprivate.h"
#include "gtksizegroup-private.h"
#include "gtkwidget.h"
#include "gtkwidgetprivate.h"
#include "gtkwindowprivate.h"
#include "gtkcontainerprivate.h"
#include "gtkbindings.h"
#include "gtkprivate.h"
#include "gtkaccessible.h"
#include "gtktooltip.h"
#include "gtkinvisible.h"
#include "gtkbuildable.h"
#include "gtkbuilderprivate.h"
#include "gtksizerequest.h"
#include "gtkstylecontextprivate.h"
#include "gtksymboliccolor.h"
#include "gtkcssprovider.h"
#include "gtkanimationdescription.h"
#include "gtkmodifierstyle.h"
#include "gtkversion.h"
#include "gtkdebug.h"
#include "gtkplug.h"
#include "gtktypebuiltins.h"
#include "a11y/gtkwidgetaccessible.h"
/**
* 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.
*
* <refsect2 id="geometry-management">
* <title>Height-for-width Geometry Management</title>
* <para>
* GTK+ uses a height-for-width (and width-for-height) geometry management
* system. Height-for-width means that a widget can change how much
* 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
* to fewer lines, and therefore needs less height.
*
* Height-for-width geometry management is implemented in GTK+ by way
* of five virtual methods:
* <itemizedlist>
* <listitem>#GtkWidgetClass.get_request_mode()</listitem>
* <listitem>#GtkWidgetClass.get_preferred_width()</listitem>
* <listitem>#GtkWidgetClass.get_preferred_height()</listitem>
* <listitem>#GtkWidgetClass.get_preferred_height_for_width()</listitem>
* <listitem>#GtkWidgetClass.get_preferred_width_for_height()</listitem>
* </itemizedlist>
*
* 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
* only one orientation at a time. When widgets are initially queried
* for their minimum sizes it is generally done in two initial passes
* in the #GtkSizeRequestMode chosen by the toplevel.
*
* For example, when queried in the normal
* %GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH mode:
* First, the default minimum and natural width for each widget
* in the interface will be computed using gtk_widget_get_preferred_width().
* Because the preferred widths for each container depend on the preferred
* widths of their children, this information propagates up the hierarchy,
* and finally a minimum and natural width is determined for the entire
* 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
* (unless gtk_window_set_geometry_hints() is explicitly used instead).
*
* After the toplevel window has initially requested its size in both
* dimensions it can go on to allocate itself a reasonable size (or a size
* previously specified with gtk_window_set_default_size()). During the
* recursive allocation process it's important to note that request cycles
* will be recursively executed while container widgets allocate their children.
* Each container widget, once allocated a size, will go on to first share the
* space in one orientation among its children and then request each child's
* height for its target allocated width or its width for allocated height,
* depending. In this way a #GtkWidget will typically be requested its size
* 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
* to avoid re-querying for the same sizes in one allocation cycle.
*
* See <link linkend="container-geometry-management">GtkContainer's
* geometry management section</link>
* to learn more about how height-for-width allocations are performed
* by container widgets.
*
* If a widget does move content around to intelligently use up the
* allocated size then it must support the request in both
* #GtkSizeRequestModes even if the widget in question only
* trades sizes in a single orientation.
*
* For instance, a #GtkLabel that does height-for-width word wrapping
* will not expect to have #GtkWidgetClass.get_preferred_height() called
* because that call is specific to a width-for-height request. In this
* case the label must return the height required for its own minimum
* possible width. By following this rule any widget that handles
* height-for-width or width-for-height requests will always be allocated
* 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:
* <programlisting><![CDATA[
* static void
* foo_widget_get_preferred_height (GtkWidget *widget, gint *min_height, gint *nat_height)
* {
* if (i_am_in_height_for_width_mode)
* {
* gint min_width;
*
* GTK_WIDGET_GET_CLASS (widget)->get_preferred_width (widget, &min_width, NULL);
* GTK_WIDGET_GET_CLASS (widget)->get_preferred_height_for_width (widget, min_width,
* min_height, nat_height);
* }
* else
* {
* ... 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.
* }
* }
* ]]></programlisting>
*
* And in #GtkWidgetClass.get_preferred_width_for_height() it will simply return
* the minimum and natural width:
*
* <programlisting><![CDATA[
* static void
* foo_widget_get_preferred_width_for_height (GtkWidget *widget, gint for_height,
* gint *min_width, gint *nat_width)
* {
* if (i_am_in_height_for_width_mode)
* {
* GTK_WIDGET_GET_CLASS (widget)->get_preferred_width (widget, min_width, nat_width);
* }
* else
* {
* ... 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.
* }
* }
* ]]></programlisting>
*
* Often a widget needs to get its own request during size request or
* allocation. For example, when computing height it may need to also
* compute width. Or when deciding how to use an allocation, the widget
* may need to know its natural size. In these cases, the widget should
* be careful to call its virtual methods directly, like this:
* <example>
* <title>Widget calling its own size request method.</title>
* <programlisting>
* GTK_WIDGET_GET_CLASS(widget)-&gt;get_preferred_width (widget),
* &min, &natural);
* </programlisting>
* </example>
*
* It will not work to use the wrapper functions, such as
* gtk_widget_get_preferred_width() inside your own size request
* implementation. These return a request adjusted by #GtkSizeGroup
* and by the #GtkWidgetClass.adjust_size_request() virtual method. If a
* 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
* <emphasis>another</emphasis> widget, such as a child of a
* container, you <emphasis>must</emphasis> use the wrapper APIs.
* Otherwise, you would not properly consider widget margins,
* #GtkSizeGroup, and so forth.
* </para>
* </refsect2>
* <refsect2 id="style-properties">
* <title>Style Properties</title>
* <para>
* <structname>GtkWidget</structname> introduces <firstterm>style
* properties</firstterm> - these are basically object properties that are stored
* not on the object, but in the style object associated to the widget. Style
* properties are set in <link linkend="gtk-Resource-Files">resource files</link>.
* 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.
* </para>
* <para>
* 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.
* </para>
* </refsect2>
* <refsect2 id="GtkWidget-BUILDER-UI">
* <title>GtkWidget as GtkBuildable</title>
* <para>
* The GtkWidget implementation of the GtkBuildable interface supports a
* custom &lt;accelerator&gt; element, which has attributes named key,
* modifiers and signal and allows to specify accelerators.
* </para>
* <example>
* <title>A UI definition fragment specifying an accelerator</title>
* <programlisting><![CDATA[
* <object class="GtkButton">
* <accelerator key="q" modifiers="GDK_CONTROL_MASK" signal="clicked"/>
* </object>
* ]]></programlisting>
* </example>
* <para>
* In addition to accelerators, <structname>GtkWidget</structname> also support a
* custom &lt;accessible&gt; 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 <structname>GtkWidget</structname>.
* </para>
* <example>
* <title>A UI definition fragment specifying an accessible</title>
* <programlisting><![CDATA[
* <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">
* <property name="AtkObject::name">Clickable Button</property>
* </object>
* </child>
* </object>
* ]]></programlisting>
* </example>
* <para>
* Finally, GtkWidget allows style information such as style classes to
* be associated with widgets, using the custom &lt;style&gt; element:
* <example>
* <title>A UI definition fragment specifying an style class</title>
* <programlisting><![CDATA[
* <object class="GtkButton" id="button1">
* <style>
* <class name="my-special-button-class"/>
* <class name="dark-button"/>
* </style>
* </object>
* ]]></programlisting>
* </example>
* </para>
* </refsect2>
*/
/* Add flags here that should not be propagated to children. By default,
* all flags will be set on children (think prelight or active), but we
* might want to not do this for some.
*/
#define GTK_STATE_FLAGS_DONT_PROPAGATE (GTK_STATE_FLAG_FOCUSED)
#define GTK_STATE_FLAGS_DO_PROPAGATE (~GTK_STATE_FLAGS_DONT_PROPAGATE)
#define WIDGET_CLASS(w) GTK_WIDGET_GET_CLASS (w)
#define INIT_PATH_SIZE (512)
struct _GtkWidgetPrivate
{
/* The state of the widget. There are actually only
* 5 widget states (defined in "gtkenums.h")
* so 3 bits.
*/
guint state_flags : 6;
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;
guint rc_style : 1;
guint style_update_pending : 1;
guint app_paintable : 1;
guint double_buffered : 1;
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;
/* Queue-resize related flags */
guint resize_pending : 1;
guint alloc_needed : 1;
guint width_request_needed : 1;
guint height_request_needed : 1;
/* 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 */
/* SizeGroup related flags */
guint sizegroup_visited : 1;
guint sizegroup_bumping : 1;
guint have_size_groups : 1;
/* The widget's name. If the widget does not have a name
* (the name is NULL), then its name (as returned by
* "gtk_widget_get_name") is its class's name.
* Among other things, the widget name is used to determine
* the style to use for a widget.
*/
gchar *name;
/* The style for the widget. The style contains the
* 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.
*/
GtkStyle *style;
GtkStyleContext *context;
/* Widget's path for styling */
GtkWidgetPath *path;
/* The widget's allocated size */
GtkAllocation allocation;
/* The widget's requested sizes */
SizeRequestCache requests;
/* The widget's window or its parent window if it does
* not have a window. (Which will be indicated by the
* GTK_NO_WINDOW flag being set).
*/
GdkWindow *window;
/* The widget's parent */
GtkWidget *parent;
#ifdef G_ENABLE_DEBUG
/* Number of gtk_widget_push_verify_invariants () */
guint verifying_invariants_count;
#endif /* G_ENABLE_DEBUG */
};
struct _GtkWidgetClassPrivate
{
GType accessible_type;
AtkRole accessible_role;
};
enum {
DESTROY,
SHOW,
HIDE,
MAP,
UNMAP,
REALIZE,
UNREALIZE,
SIZE_ALLOCATE,
STATE_FLAGS_CHANGED,
STATE_CHANGED,
PARENT_SET,
HIERARCHY_CHANGED,
STYLE_SET,
DIRECTION_CHANGED,
GRAB_NOTIFY,
CHILD_NOTIFY,
DRAW,
MNEMONIC_ACTIVATE,
GRAB_FOCUS,
FOCUS,
MOVE_FOCUS,
KEYNAV_FAILED,
EVENT,
EVENT_AFTER,
BUTTON_PRESS_EVENT,
BUTTON_RELEASE_EVENT,
SCROLL_EVENT,
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,
SELECTION_GET,
SELECTION_RECEIVED,
PROXIMITY_IN_EVENT,
PROXIMITY_OUT_EVENT,
VISIBILITY_NOTIFY_EVENT,
WINDOW_STATE_EVENT,
DAMAGE_EVENT,
GRAB_BROKEN_EVENT,
DRAG_BEGIN,
DRAG_END,
DRAG_DATA_DELETE,
DRAG_LEAVE,
DRAG_MOTION,
DRAG_DROP,
DRAG_DATA_GET,
DRAG_DATA_RECEIVED,
POPUP_MENU,
SHOW_HELP,
ACCEL_CLOSURES_CHANGED,
SCREEN_CHANGED,
CAN_ACTIVATE_ACCEL,
COMPOSITED_CHANGED,
QUERY_TOOLTIP,
DRAG_FAILED,
STYLE_UPDATED,
LAST_SIGNAL
};
enum {
PROP_0,
PROP_NAME,
PROP_PARENT,
PROP_WIDTH_REQUEST,
PROP_HEIGHT_REQUEST,
PROP_VISIBLE,
PROP_SENSITIVE,
PROP_APP_PAINTABLE,
PROP_CAN_FOCUS,
PROP_HAS_FOCUS,
PROP_IS_FOCUS,
PROP_CAN_DEFAULT,
PROP_HAS_DEFAULT,
PROP_RECEIVES_DEFAULT,
PROP_COMPOSITE_CHILD,
PROP_STYLE,
PROP_EVENTS,
PROP_NO_SHOW_ALL,
PROP_HAS_TOOLTIP,
PROP_TOOLTIP_MARKUP,
PROP_TOOLTIP_TEXT,
PROP_WINDOW,
PROP_DOUBLE_BUFFERED,
PROP_HALIGN,
PROP_VALIGN,
PROP_MARGIN_LEFT,
PROP_MARGIN_RIGHT,
PROP_MARGIN_TOP,
PROP_MARGIN_BOTTOM,
PROP_MARGIN,
PROP_HEXPAND,
PROP_VEXPAND,
PROP_HEXPAND_SET,
PROP_VEXPAND_SET,
PROP_EXPAND
};
typedef struct _GtkStateData GtkStateData;
enum {
STATE_CHANGE_REPLACE,
STATE_CHANGE_SET,
STATE_CHANGE_UNSET
};
struct _GtkStateData
{
guint flags : 6;
guint operation : 2;
guint use_forall : 1;
};
/* --- prototypes --- */
static void gtk_widget_base_class_init (gpointer g_class);
static void gtk_widget_class_init (GtkWidgetClass *klass);
static void gtk_widget_base_class_finalize (GtkWidgetClass *klass);
static void gtk_widget_init (GtkWidget *widget);
static void gtk_widget_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec);
static void gtk_widget_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
static void gtk_widget_dispose (GObject *object);
static void gtk_widget_real_destroy (GtkWidget *object);
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,
GtkAllocation *allocation);
static void gtk_widget_real_style_set (GtkWidget *widget,
GtkStyle *previous_style);
static void gtk_widget_real_direction_changed(GtkWidget *widget,
GtkTextDirection previous_direction);
static void gtk_widget_real_grab_focus (GtkWidget *focus_widget);
static gboolean gtk_widget_real_query_tooltip (GtkWidget *widget,
gint x,
gint y,
gboolean keyboard_tip,
GtkTooltip *tooltip);
static void gtk_widget_real_style_updated (GtkWidget *widget);
static gboolean gtk_widget_real_show_help (GtkWidget *widget,
GtkWidgetHelpType help_type);
static void gtk_widget_dispatch_child_properties_changed (GtkWidget *object,
guint n_pspecs,
GParamSpec **pspecs);
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);
static gboolean gtk_widget_real_focus (GtkWidget *widget,
GtkDirectionType direction);
static void gtk_widget_real_move_focus (GtkWidget *widget,
GtkDirectionType direction);
static gboolean gtk_widget_real_keynav_failed (GtkWidget *widget,
GtkDirectionType direction);
#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
static PangoContext* gtk_widget_peek_pango_context (GtkWidget *widget);
static void gtk_widget_update_pango_context (GtkWidget *widget);
static void gtk_widget_propagate_state (GtkWidget *widget,
GtkStateData *data);
;
static gint gtk_widget_event_internal (GtkWidget *widget,
GdkEvent *event);
static gboolean gtk_widget_real_mnemonic_activate (GtkWidget *widget,
gboolean group_cycling);
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);
static const GtkWidgetAuxInfo* _gtk_widget_get_aux_info_or_defaults (GtkWidget *widget);
static GtkWidgetAuxInfo* gtk_widget_get_aux_info (GtkWidget *widget,
gboolean create);
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);
static void gtk_widget_invalidate_widget_windows (GtkWidget *widget,
cairo_region_t *region);
static GdkScreen * gtk_widget_get_screen_unchecked (GtkWidget *widget);
static void gtk_widget_queue_shallow_draw (GtkWidget *widget);
static gboolean gtk_widget_real_can_activate_accel (GtkWidget *widget,
guint signal_id);
static void gtk_widget_real_set_has_tooltip (GtkWidget *widget,
gboolean has_tooltip,
gboolean force);
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);
static GObject * gtk_widget_buildable_get_internal_child (GtkBuildable *buildable,
GtkBuilder *builder,
const gchar *childname);
static void gtk_widget_buildable_set_buildable_property (GtkBuildable *buildable,
GtkBuilder *builder,
const gchar *name,
const GValue *value);
static gboolean gtk_widget_buildable_custom_tag_start (GtkBuildable *buildable,
GtkBuilder *builder,
GObject *child,
const gchar *tagname,
GMarkupParser *parser,
gpointer *data);
static void gtk_widget_buildable_custom_finished (GtkBuildable *buildable,
GtkBuilder *builder,
GObject *child,
const gchar *tagname,
gpointer data);
static void gtk_widget_buildable_parser_finished (GtkBuildable *buildable,
GtkBuilder *builder);
static GtkSizeRequestMode gtk_widget_real_get_request_mode (GtkWidget *widget);
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_queue_tooltip_query (GtkWidget *widget);
static void gtk_widget_real_adjust_size_request (GtkWidget *widget,
GtkOrientation orientation,
gint *minimum_size,
gint *natural_size);
static void gtk_widget_real_adjust_size_allocation (GtkWidget *widget,
GtkOrientation orientation,
gint *minimum_size,
gint *natural_size,
gint *allocated_pos,
gint *allocated_size);
static void gtk_widget_set_usize_internal (GtkWidget *widget,
gint width,
gint height,
GtkQueueResizeFlags flags);
static void gtk_widget_add_events_internal (GtkWidget *widget,
GdkDevice *device,
gint events);
static void gtk_widget_set_device_enabled_internal (GtkWidget *widget,
GdkDevice *device,
gboolean recurse,
gboolean enabled);
/* --- variables --- */
static gpointer gtk_widget_parent_class = NULL;
static guint widget_signals[LAST_SIGNAL] = { 0 };
static GtkStyle *gtk_default_style = NULL;
static guint composite_child_stack = 0;
static GtkTextDirection gtk_default_direction = GTK_TEXT_DIR_LTR;
static GParamSpecPool *style_property_spec_pool = NULL;
static GQuark quark_property_parser = 0;
static GQuark quark_aux_info = 0;
static GQuark quark_accel_path = 0;
static GQuark quark_accel_closures = 0;
static GQuark quark_event_mask = 0;
static GQuark quark_device_event_mask = 0;
static GQuark quark_parent_window = 0;
static GQuark quark_pointer_window = 0;
static GQuark quark_shape_info = 0;
static GQuark quark_input_shape_info = 0;
static GQuark quark_pango_context = 0;
static GQuark quark_rc_style = 0;
static GQuark quark_accessible_object = 0;
static GQuark quark_mnemonic_labels = 0;
static GQuark quark_tooltip_markup = 0;
static GQuark quark_has_tooltip = 0;
static GQuark quark_tooltip_window = 0;
static GQuark quark_visual = 0;
static GQuark quark_modifier_style = 0;
static GQuark quark_enabled_devices = 0;
static GQuark quark_size_groups = 0;
GParamSpecPool *_gtk_widget_child_property_pool = NULL;
GObjectNotifyContext *_gtk_widget_child_property_notify_context = NULL;
/* --- functions --- */
GType
gtk_widget_get_type (void)
{
static GType widget_type = 0;
if (G_UNLIKELY (widget_type == 0))
{
const GTypeInfo widget_info =
{
sizeof (GtkWidgetClass),
gtk_widget_base_class_init,
(GBaseFinalizeFunc) gtk_widget_base_class_finalize,
(GClassInitFunc) gtk_widget_class_init,
NULL, /* class_finalize */
NULL, /* class_init */
sizeof (GtkWidget),
0, /* n_preallocs */
(GInstanceInitFunc) gtk_widget_init,
NULL, /* value_table */
};
const GInterfaceInfo accessibility_info =
{
(GInterfaceInitFunc) gtk_widget_accessible_interface_init,
(GInterfaceFinalizeFunc) NULL,
NULL /* interface data */
};
const GInterfaceInfo buildable_info =
{
(GInterfaceInitFunc) gtk_widget_buildable_interface_init,
(GInterfaceFinalizeFunc) NULL,
NULL /* interface data */
};
widget_type = g_type_register_static (G_TYPE_INITIALLY_UNOWNED, "GtkWidget",
&widget_info, G_TYPE_FLAG_ABSTRACT);
g_type_add_class_private (widget_type, sizeof (GtkWidgetClassPrivate));
g_type_add_interface_static (widget_type, ATK_TYPE_IMPLEMENTOR,
&accessibility_info) ;
g_type_add_interface_static (widget_type, GTK_TYPE_BUILDABLE,
&buildable_info) ;
}
return widget_type;
}
static void
gtk_widget_base_class_init (gpointer g_class)
{
GtkWidgetClass *klass = g_class;
klass->priv = G_TYPE_CLASS_GET_PRIVATE (g_class, GTK_TYPE_WIDGET, GtkWidgetClassPrivate);
}
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);
}
/* We guard against the draw signal callbacks modifying the state of the
* cairo context by surounding it with save/restore.
* 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_class_init (GtkWidgetClass *klass)
{
static GObjectNotifyContext cpn_context = { 0, NULL, NULL };
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GtkBindingSet *binding_set;
gtk_widget_parent_class = g_type_class_peek_parent (klass);
quark_property_parser = g_quark_from_static_string ("gtk-rc-property-parser");
quark_aux_info = g_quark_from_static_string ("gtk-aux-info");
quark_accel_path = g_quark_from_static_string ("gtk-accel-path");
quark_accel_closures = g_quark_from_static_string ("gtk-accel-closures");
quark_event_mask = g_quark_from_static_string ("gtk-event-mask");
quark_device_event_mask = g_quark_from_static_string ("gtk-device-event-mask");
quark_parent_window = g_quark_from_static_string ("gtk-parent-window");
quark_pointer_window = g_quark_from_static_string ("gtk-pointer-window");
quark_shape_info = g_quark_from_static_string ("gtk-shape-info");
quark_input_shape_info = g_quark_from_static_string ("gtk-input-shape-info");
quark_pango_context = g_quark_from_static_string ("gtk-pango-context");
quark_rc_style = g_quark_from_static_string ("gtk-rc-style");
quark_accessible_object = g_quark_from_static_string ("gtk-accessible-object");
quark_mnemonic_labels = g_quark_from_static_string ("gtk-mnemonic-labels");
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");
quark_visual = g_quark_from_static_string ("gtk-widget-visual");
quark_modifier_style = g_quark_from_static_string ("gtk-widget-modifier-style");
quark_enabled_devices = g_quark_from_static_string ("gtk-widget-enabled-devices");
quark_size_groups = g_quark_from_static_string ("gtk-widget-size-groups");
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;
gobject_class->dispose = gtk_widget_dispose;
gobject_class->finalize = gtk_widget_finalize;
gobject_class->set_property = gtk_widget_set_property;
gobject_class->get_property = gtk_widget_get_property;
klass->destroy = gtk_widget_real_destroy;
klass->activate_signal = 0;
klass->dispatch_child_properties_changed = gtk_widget_dispatch_child_properties_changed;
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;
klass->get_request_mode = gtk_widget_real_get_request_mode;
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;
klass->get_preferred_height_for_width = gtk_widget_real_get_height_for_width;
klass->state_changed = NULL;
klass->parent_set = NULL;
klass->hierarchy_changed = NULL;
klass->style_set = gtk_widget_real_style_set;
klass->direction_changed = gtk_widget_real_direction_changed;
klass->grab_notify = NULL;
klass->child_notify = NULL;
klass->draw = NULL;
klass->mnemonic_activate = gtk_widget_real_mnemonic_activate;
klass->grab_focus = gtk_widget_real_grab_focus;
klass->focus = gtk_widget_real_focus;
klass->move_focus = gtk_widget_real_move_focus;
klass->keynav_failed = gtk_widget_real_keynav_failed;
klass->event = NULL;
klass->button_press_event = NULL;
klass->button_release_event = NULL;
klass->motion_notify_event = NULL;
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;
klass->focus_in_event = gtk_widget_real_focus_in_event;
klass->focus_out_event = gtk_widget_real_focus_out_event;
klass->map_event = NULL;
klass->unmap_event = NULL;
klass->window_state_event = NULL;
klass->property_notify_event = _gtk_selection_property_notify;
klass->selection_clear_event = _gtk_selection_clear;
klass->selection_request_event = _gtk_selection_request;
klass->selection_notify_event = _gtk_selection_notify;
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;
klass->screen_changed = NULL;
klass->can_activate_accel = gtk_widget_real_can_activate_accel;
klass->grab_broken_event = NULL;
klass->query_tooltip = gtk_widget_real_query_tooltip;
klass->style_updated = gtk_widget_real_style_updated;
klass->show_help = gtk_widget_real_show_help;
/* Accessibility support */
klass->priv->accessible_type = GTK_TYPE_ACCESSIBLE;
klass->priv->accessible_role = ATK_ROLE_INVALID;
klass->get_accessible = gtk_widget_real_get_accessible;
klass->adjust_size_request = gtk_widget_real_adjust_size_request;
klass->adjust_size_allocation = gtk_widget_real_adjust_size_allocation;
g_object_class_install_property (gobject_class,
PROP_NAME,
g_param_spec_string ("name",
P_("Widget name"),
P_("The name of the widget"),
NULL,
GTK_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
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));
g_object_class_install_property (gobject_class,
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_object_class_install_property (gobject_class,
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_object_class_install_property (gobject_class,
PROP_VISIBLE,
g_param_spec_boolean ("visible",
P_("Visible"),
P_("Whether the widget is visible"),
FALSE,
GTK_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
PROP_SENSITIVE,
g_param_spec_boolean ("sensitive",
P_("Sensitive"),
P_("Whether the widget responds to input"),
TRUE,
GTK_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
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_object_class_install_property (gobject_class,
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_object_class_install_property (gobject_class,
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_object_class_install_property (gobject_class,
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));
g_object_class_install_property (gobject_class,
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_object_class_install_property (gobject_class,
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_object_class_install_property (gobject_class,
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_object_class_install_property (gobject_class,
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));
g_object_class_install_property (gobject_class,
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_object_class_install_property (gobject_class,
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_object_class_install_property (gobject_class,
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));
/**
* GtkWidget:has-tooltip:
*
* Enables or disables the emission of #GtkWidget::query-tooltip on @widget.
* 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
* whether it will provide a tooltip or not.
*
* 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.
*
* Since: 2.12
*/
g_object_class_install_property (gobject_class,
PROP_HAS_TOOLTIP,
g_param_spec_boolean ("has-tooltip",
P_("Has tooltip"),
P_("Whether this widget has a tooltip"),
FALSE,
GTK_PARAM_READWRITE));
/**
* 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.
*
* Since: 2.12
*/
g_object_class_install_property (gobject_class,
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));
/**
* GtkWidget:tooltip-markup:
*
* Sets the text of tooltip to be the given string, which is marked up
* with the <link linkend="PangoMarkupFormat">Pango text markup language</link>.
* 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.
*
* Since: 2.12
*/
g_object_class_install_property (gobject_class,
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));
/**
* GtkWidget:window:
*
* The widget's window if it is realized, %NULL otherwise.
*
* Since: 2.14
*/
g_object_class_install_property (gobject_class,
PROP_WINDOW,
g_param_spec_object ("window",
P_("Window"),
P_("The widget's window if it is realized"),
GDK_TYPE_WINDOW,
GTK_PARAM_READABLE));
/**
* GtkWidget:double-buffered
*
* Whether the widget is double buffered.
*
* Since: 2.18
*/
g_object_class_install_property (gobject_class,
PROP_DOUBLE_BUFFERED,
g_param_spec_boolean ("double-buffered",
P_("Double Buffered"),
P_("Whether the widget is double buffered"),
TRUE,
GTK_PARAM_READWRITE));
/**
* GtkWidget:halign:
*
* How to distribute horizontal space if widget gets extra space, see #GtkAlign
*
* Since: 3.0
*/
g_object_class_install_property (gobject_class,
PROP_HALIGN,
g_param_spec_enum ("halign",
P_("Horizontal Alignment"),
P_("How to position in extra horizontal space"),
GTK_TYPE_ALIGN,
GTK_ALIGN_FILL,
GTK_PARAM_READWRITE));
/**
* GtkWidget:valign:
*
* How to distribute vertical space if widget gets extra space, see #GtkAlign
*
* Since: 3.0
*/
g_object_class_install_property (gobject_class,
PROP_VALIGN,
g_param_spec_enum ("valign",
P_("Vertical Alignment"),
P_("How to position in extra vertical space"),
GTK_TYPE_ALIGN,
GTK_ALIGN_FILL,
GTK_PARAM_READWRITE));
/**
* GtkWidget:margin-left
*
* Margin on left side of widget.
*
* This property adds margin outside of the widget's normal size
* request, the margin will be added in addition to the size from
* gtk_widget_set_size_request() for example.
*
* Since: 3.0
*/
g_object_class_install_property (gobject_class,
PROP_MARGIN_LEFT,
g_param_spec_int ("margin-left",
P_("Margin on Left"),
P_("Pixels of extra space on the left side"),
0,
G_MAXINT16,
0,
GTK_PARAM_READWRITE));
/**
* GtkWidget:margin-right
*
* Margin on right side of widget.
*
* This property adds margin outside of the widget's normal size
* request, the margin will be added in addition to the size from
* gtk_widget_set_size_request() for example.
*
* Since: 3.0
*/
g_object_class_install_property (gobject_class,
PROP_MARGIN_RIGHT,
g_param_spec_int ("margin-right",
P_("Margin on Right"),
P_("Pixels of extra space on the right side"),
0,
G_MAXINT16,
0,
GTK_PARAM_READWRITE));
/**
* GtkWidget:margin-top
*
* Margin on top side of widget.
*
* This property adds margin outside of the widget's normal size
* request, the margin will be added in addition to the size from
* gtk_widget_set_size_request() for example.
*
* Since: 3.0
*/
g_object_class_install_property (gobject_class,
PROP_MARGIN_TOP,
g_param_spec_int ("margin-top",
P_("Margin on Top"),
P_("Pixels of extra space on the top side"),
0,
G_MAXINT16,
0,
GTK_PARAM_READWRITE));
/**
* GtkWidget:margin-bottom
*
* Margin on bottom side of widget.
*
* This property adds margin outside of the widget's normal size
* request, the margin will be added in addition to the size from
* gtk_widget_set_size_request() for example.
*
* Since: 3.0
*/
g_object_class_install_property (gobject_class,
PROP_MARGIN_BOTTOM,
g_param_spec_int ("margin-bottom",
P_("Margin on Bottom"),
P_("Pixels of extra space on the bottom side"),
0,
G_MAXINT16,
0,
GTK_PARAM_READWRITE));
/**
* GtkWidget:margin
*
* Sets all four sides' margin at once. If read, returns max
* margin on any side.
*
* Since: 3.0
*/
g_object_class_install_property (gobject_class,
PROP_MARGIN,
g_param_spec_int ("margin",
P_("All Margins"),
P_("Pixels of extra space on all four sides"),
0,
G_MAXINT16,
0,
GTK_PARAM_READWRITE));
/**
* GtkWidget::destroy:
* @object: the object which received the signal
*
* Signals that all holders of a reference to the widget should release
* the reference that they hold. May result in finalization of the widget
* if all references are released.
*/
widget_signals[DESTROY] =
g_signal_new (I_("destroy"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_CLEANUP | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
G_STRUCT_OFFSET (GtkWidgetClass, destroy),
NULL, NULL,
_gtk_marshal_VOID__VOID,
G_TYPE_NONE, 0);
/**
* GtkWidget:hexpand
*
* Whether to expand horizontally. See gtk_widget_set_hexpand().
*
* Since: 3.0
*/
g_object_class_install_property (gobject_class,
PROP_HEXPAND,
g_param_spec_boolean ("hexpand",
P_("Horizontal Expand"),
P_("Whether widget wants more horizontal space"),
FALSE,
GTK_PARAM_READWRITE));
/**
* GtkWidget:hexpand-set
*
* Whether to use the #GtkWidget:hexpand property. See gtk_widget_get_hexpand_set().
*
* Since: 3.0
*/
g_object_class_install_property (gobject_class,
PROP_HEXPAND_SET,
g_param_spec_boolean ("hexpand-set",
P_("Horizontal Expand Set"),
P_("Whether to use the hexpand property"),
FALSE,
GTK_PARAM_READWRITE));
/**
* GtkWidget:vexpand
*
* Whether to expand vertically. See gtk_widget_set_vexpand().
*
* Since: 3.0
*/
g_object_class_install_property (gobject_class,
PROP_VEXPAND,
g_param_spec_boolean ("vexpand",
P_("Vertical Expand"),
P_("Whether widget wants more vertical space"),
FALSE,
GTK_PARAM_READWRITE));
/**
* GtkWidget:vexpand-set
*
* Whether to use the #GtkWidget:vexpand property. See gtk_widget_get_vexpand_set().
*
* Since: 3.0
*/
g_object_class_install_property (gobject_class,
PROP_VEXPAND_SET,
g_param_spec_boolean ("vexpand-set",
P_("Vertical Expand Set"),
P_("Whether to use the vexpand property"),
FALSE,
GTK_PARAM_READWRITE));
/**
* GtkWidget:expand
*
* Whether to expand in both directions. Setting this sets both #GtkWidget:hexpand and #GtkWidget:vexpand
*
* Since: 3.0
*/
g_object_class_install_property (gobject_class,
PROP_EXPAND,
g_param_spec_boolean ("expand",
P_("Expand Both"),
P_("Whether widget wants to expand in both directions"),
FALSE,
GTK_PARAM_READWRITE));
/**
* GtkWidget::show:
* @widget: the object which received the signal.
*/
widget_signals[SHOW] =
g_signal_new (I_("show"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GtkWidgetClass, show),
NULL, NULL,
_gtk_marshal_VOID__VOID,
G_TYPE_NONE, 0);
/**
* GtkWidget::hide:
* @widget: the object which received the signal.
*/
widget_signals[HIDE] =
g_signal_new (I_("hide"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GtkWidgetClass, hide),
NULL, NULL,
_gtk_marshal_VOID__VOID,
G_TYPE_NONE, 0);
/**
* GtkWidget::map:
* @widget: the object which received the signal.
*/
widget_signals[MAP] =
g_signal_new (I_("map"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GtkWidgetClass, map),
NULL, NULL,
_gtk_marshal_VOID__VOID,
G_TYPE_NONE, 0);
/**
* GtkWidget::unmap:
* @widget: the object which received the signal.
*/
widget_signals[UNMAP] =
g_signal_new (I_("unmap"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GtkWidgetClass, unmap),
NULL, NULL,
_gtk_marshal_VOID__VOID,
G_TYPE_NONE, 0);
/**
* GtkWidget::realize:
* @widget: the object which received the signal.
*/
widget_signals[REALIZE] =
g_signal_new (I_("realize"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GtkWidgetClass, realize),
NULL, NULL,
_gtk_marshal_VOID__VOID,
G_TYPE_NONE, 0);
/**
* GtkWidget::unrealize:
* @widget: the object which received the signal.
*/
widget_signals[UNREALIZE] =
g_signal_new (I_("unrealize"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, unrealize),
NULL, NULL,
_gtk_marshal_VOID__VOID,
G_TYPE_NONE, 0);
/**
* GtkWidget::size-allocate:
* @widget: the object which received the signal.
* @allocation:
*/
widget_signals[SIZE_ALLOCATE] =
g_signal_new (I_("size-allocate"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GtkWidgetClass, size_allocate),
NULL, NULL,
_gtk_marshal_VOID__BOXED,
G_TYPE_NONE, 1,
GDK_TYPE_RECTANGLE | G_SIGNAL_TYPE_STATIC_SCOPE);
/**
* GtkWidget::state-changed:
* @widget: the object which received the signal.
* @state: the previous state
*
* The ::state-changed signal is emitted when the widget state changes.
* See gtk_widget_get_state().
*
* Deprecated: 3.0. Use #GtkWidget::state-flags-changed instead.
*/
widget_signals[STATE_CHANGED] =
g_signal_new (I_("state-changed"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GtkWidgetClass, state_changed),
NULL, NULL,
_gtk_marshal_VOID__ENUM,
G_TYPE_NONE, 1,
GTK_TYPE_STATE_TYPE);
/**
* GtkWidget::state-flags-changed:
* @widget: the object which received the signal.
* @flags: The previous state flags.
*
* The ::state-flags-changed signal is emitted when the widget state
* changes, see gtk_widget_get_state_flags().
*
* Since: 3.0
*/
widget_signals[STATE_FLAGS_CHANGED] =
g_signal_new (I_("state-flags-changed"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GtkWidgetClass, state_flags_changed),
NULL, NULL,
_gtk_marshal_VOID__FLAGS,
G_TYPE_NONE, 1,
GTK_TYPE_STATE_FLAGS);
/**
* GtkWidget::parent-set:
* @widget: the object on which the signal is emitted
* @old_parent: (allow-none): the previous parent, or %NULL if the widget
* just got its initial parent.
*
* The ::parent-set signal is emitted when a new parent
* has been set on a widget.
*/
widget_signals[PARENT_SET] =
g_signal_new (I_("parent-set"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GtkWidgetClass, parent_set),
NULL, NULL,
_gtk_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
GTK_TYPE_WIDGET);
/**
* GtkWidget::hierarchy-changed:
* @widget: the object on which the signal is emitted
* @previous_toplevel: (allow-none): the previous toplevel ancestor, or %NULL
* if the widget was previously unanchored
*
* The ::hierarchy-changed signal is emitted when the
* anchored state of a widget changes. A widget is
* <firstterm>anchored</firstterm> when its toplevel
* ancestor is a #GtkWindow. This signal is emitted when
* a widget changes from un-anchored to anchored or vice-versa.
*/
widget_signals[HIERARCHY_CHANGED] =
g_signal_new (I_("hierarchy-changed"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, hierarchy_changed),
NULL, NULL,
_gtk_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
GTK_TYPE_WIDGET);
/**
* GtkWidget::style-set:
* @widget: the object on which the signal is emitted
* @previous_style: (allow-none): the previous style, or %NULL if the widget
* just got its initial style
*
* The ::style-set signal is emitted when a new style has been set
* on a widget. Note that style-modifying functions like
* gtk_widget_modify_base() also cause this signal to be emitted.
*
* Note that this signal is emitted for changes to the deprecated
* #GtkStyle. To track changes to the #GtkStyleContext associated
* with a widget, use the #GtkWidget::style-updated signal.
*
* Deprecated:3.0: Use the #GtkWidget::style-updated signal
*/
widget_signals[STYLE_SET] =
g_signal_new (I_("style-set"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GtkWidgetClass, style_set),
NULL, NULL,
_gtk_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
GTK_TYPE_STYLE);
/**
* GtkWidget::style-updated:
* @widget: the object on which the signal is emitted
*
* The ::style-updated signal is emitted when the #GtkStyleContext
* of a widget is changed. Note that style-modifying functions like
* gtk_widget_override_color() also cause this signal to be emitted.
*
* Since: 3.0
*/
widget_signals[STYLE_UPDATED] =
g_signal_new (I_("style-updated"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GtkWidgetClass, style_updated),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
/**
* GtkWidget::direction-changed:
* @widget: the object on which the signal is emitted
* @previous_direction: the previous text direction of @widget
*
* The ::direction-changed signal is emitted when the text direction
* of a widget changes.
*/
widget_signals[DIRECTION_CHANGED] =
g_signal_new (I_("direction-changed"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GtkWidgetClass, direction_changed),
NULL, NULL,
_gtk_marshal_VOID__ENUM,
G_TYPE_NONE, 1,
GTK_TYPE_TEXT_DIRECTION);
/**
* GtkWidget::grab-notify:
* @widget: the object which received the signal
* @was_grabbed: %FALSE if the widget becomes shadowed, %TRUE
* if it becomes unshadowed
*
* The ::grab-notify signal is emitted when a widget becomes
* shadowed by a GTK+ grab (not a pointer or keyboard grab) on
* another widget, or when it becomes unshadowed due to a grab
* being removed.
*
* A widget is shadowed by a gtk_grab_add() when the topmost
* grab widget in the grab stack of its window group is not
* its ancestor.
*/
widget_signals[GRAB_NOTIFY] =
g_signal_new (I_("grab-notify"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GtkWidgetClass, grab_notify),
NULL, NULL,
_gtk_marshal_VOID__BOOLEAN,
G_TYPE_NONE, 1,
G_TYPE_BOOLEAN);
/**
* GtkWidget::child-notify:
* @widget: the object which received the signal
* @pspec: the #GParamSpec of the changed child property
*
* The ::child-notify signal is emitted for each
* <link linkend="child-properties">child property</link> that has
* changed on an object. The signal's detail holds the property name.
*/
widget_signals[CHILD_NOTIFY] =
g_signal_new (I_("child-notify"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED | G_SIGNAL_NO_HOOKS,
G_STRUCT_OFFSET (GtkWidgetClass, child_notify),
NULL, NULL,
g_cclosure_marshal_VOID__PARAM,
G_TYPE_NONE, 1,
G_TYPE_PARAM);
/**
* GtkWidget::draw:
* @widget: the object which received the signal
* @cr: the cairo context to draw to
*
* This signal is emitted when a widget is supposed to render itself.
* The @widget's top left corner must be painted at the origin of
* the passed in context and be sized to the values returned by
* gtk_widget_get_allocated_width() and
* gtk_widget_get_allocated_height().
*
* Signal handlers connected to this signal can modify the cairo
* context passed as @cr in any way they like and don't need to
* restore it. The signal emission takes care of calling cairo_save()
* before and cairo_restore() after invoking the handler.
*
* Since: 3.0
*/
widget_signals[DRAW] =
g_signal_new (I_("draw"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, draw),
_gtk_boolean_handled_accumulator, NULL,
gtk_widget_draw_marshaller,
G_TYPE_BOOLEAN, 1,
CAIRO_GOBJECT_TYPE_CONTEXT);
/**
* GtkWidget::mnemonic-activate:
* @widget: the object which received the signal.
* @arg1:
*/
widget_signals[MNEMONIC_ACTIVATE] =
g_signal_new (I_("mnemonic-activate"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, mnemonic_activate),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__BOOLEAN,
G_TYPE_BOOLEAN, 1,
G_TYPE_BOOLEAN);
/**
* GtkWidget::grab-focus:
* @widget: the object which received the signal.
*/
widget_signals[GRAB_FOCUS] =
g_signal_new (I_("grab-focus"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (GtkWidgetClass, grab_focus),
NULL, NULL,
_gtk_marshal_VOID__VOID,
G_TYPE_NONE, 0);
/**
* GtkWidget::focus:
* @widget: the object which received the signal.
* @direction:
*
* Returns: %TRUE to stop other handlers from being invoked for the event. %FALSE to propagate the event further.
*/
widget_signals[FOCUS] =
g_signal_new (I_("focus"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, focus),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__ENUM,
G_TYPE_BOOLEAN, 1,
GTK_TYPE_DIRECTION_TYPE);
/**
* GtkWidget::move-focus:
* @widget: the object which received the signal.
* @direction:
*/
widget_signals[MOVE_FOCUS] =
g_signal_new (I_("move-focus"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (GtkWidgetClass, move_focus),
NULL, NULL,
_gtk_marshal_VOID__ENUM,
G_TYPE_NONE,
1,
GTK_TYPE_DIRECTION_TYPE);
/**
* GtkWidget::keynav-failed:
* @widget: the object which received the signal
* @direction: the direction of movement
*
* Gets emitted if keyboard navigation fails.
* See gtk_widget_keynav_failed() for details.
*
* Returns: %TRUE if stopping keyboard navigation is fine, %FALSE
* if the emitting widget should try to handle the keyboard
* navigation attempt in its parent container(s).
*
* Since: 2.12
**/
widget_signals[KEYNAV_FAILED] =
g_signal_new (I_("keynav-failed"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, keynav_failed),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__ENUM,
G_TYPE_BOOLEAN, 1,
GTK_TYPE_DIRECTION_TYPE);
/**
* GtkWidget::event:
* @widget: the object which received the signal.
* @event: the #GdkEvent which triggered this signal
*
* The GTK+ main loop will emit three signals for each GDK event delivered
* to a widget: one generic ::event signal, another, more specific,
* signal that matches the type of event delivered (e.g.
* #GtkWidget::key-press-event) and finally a generic
* #GtkWidget::event-after signal.
*
* Returns: %TRUE to stop other handlers from being invoked for the event
* and to cancel the emission of the second specific ::event signal.
* %FALSE to propagate the event further and to allow the emission of
* the second signal. The ::event-after signal is emitted regardless of
* the return value.
*/
widget_signals[EVENT] =
g_signal_new (I_("event"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, event),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__BOXED,
G_TYPE_BOOLEAN, 1,
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
/**
* GtkWidget::event-after:
* @widget: the object which received the signal.
* @event: the #GdkEvent which triggered this signal
*
* After the emission of the #GtkWidget::event signal and (optionally)
* the second more specific signal, ::event-after will be emitted
* regardless of the previous two signals handlers return values.
*
*/
widget_signals[EVENT_AFTER] =
g_signal_new (I_("event-after"),
G_TYPE_FROM_CLASS (klass),
0,
0,
NULL, NULL,
_gtk_marshal_VOID__BOXED,
G_TYPE_NONE, 1,
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
/**
* GtkWidget::button-press-event:
* @widget: the object which received the signal.
* @event: (type Gdk.EventButton): the #GdkEventButton which triggered
* this signal.
*
* The ::button-press-event signal will be emitted when a button
* (typically from a mouse) is pressed.
*
* To receive this signal, the #GdkWindow associated to the
* widget needs to enable the #GDK_BUTTON_PRESS_MASK mask.
*
* This signal will be sent to the grab widget if there is one.
*
* Returns: %TRUE to stop other handlers from being invoked for the event.
* %FALSE to propagate the event further.
*/
widget_signals[BUTTON_PRESS_EVENT] =
g_signal_new (I_("button-press-event"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, button_press_event),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__BOXED,
G_TYPE_BOOLEAN, 1,
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
/**
* GtkWidget::button-release-event:
* @widget: the object which received the signal.
* @event: (type Gdk.EventButton): the #GdkEventButton which triggered
* this signal.
*
* The ::button-release-event signal will be emitted when a button
* (typically from a mouse) is released.
*
* To receive this signal, the #GdkWindow associated to the
* widget needs to enable the #GDK_BUTTON_RELEASE_MASK mask.
*
* This signal will be sent to the grab widget if there is one.
*
* Returns: %TRUE to stop other handlers from being invoked for the event.
* %FALSE to propagate the event further.
*/
widget_signals[BUTTON_RELEASE_EVENT] =
g_signal_new (I_("button-release-event"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, button_release_event),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__BOXED,
G_TYPE_BOOLEAN, 1,
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
/**
* GtkWidget::scroll-event:
* @widget: the object which received the signal.
* @event: (type Gdk.EventScroll): the #GdkEventScroll which triggered
* this signal.
*
* The ::scroll-event signal is emitted when a button in the 4 to 7
* range is pressed. Wheel mice are usually configured to generate
* button press events for buttons 4 and 5 when the wheel is turned.
*
* To receive this signal, the #GdkWindow associated to the widget needs
* to enable the #GDK_BUTTON_PRESS_MASK mask.
*
* This signal will be sent to the grab widget if there is one.
*
* Returns: %TRUE to stop other handlers from being invoked for the event.
* %FALSE to propagate the event further.
*/
widget_signals[SCROLL_EVENT] =
g_signal_new (I_("scroll-event"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, scroll_event),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__BOXED,
G_TYPE_BOOLEAN, 1,
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
/**
* GtkWidget::motion-notify-event:
* @widget: the object which received the signal.
* @event: (type Gdk.EventMotion): the #GdkEventMotion which triggered
* this signal.
*
* The ::motion-notify-event signal is emitted when the pointer moves
* over the widget's #GdkWindow.
*
* To receive this signal, the #GdkWindow associated to the widget
* needs to enable the #GDK_POINTER_MOTION_MASK mask.
*
* This signal will be sent to the grab widget if there is one.
*
* Returns: %TRUE to stop other handlers from being invoked for the event.
* %FALSE to propagate the event further.
*/
widget_signals[MOTION_NOTIFY_EVENT] =
g_signal_new (I_("motion-notify-event"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, motion_notify_event),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__BOXED,
G_TYPE_BOOLEAN, 1,
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
/**
* GtkWidget::composited-changed:
* @widget: the object on which the signal is emitted
*
* The ::composited-changed signal is emitted when the composited
* status of @widget<!-- -->s screen changes.
* See gdk_screen_is_composited().
*/
widget_signals[COMPOSITED_CHANGED] =
g_signal_new (I_("composited-changed"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (GtkWidgetClass, composited_changed),
NULL, NULL,
_gtk_marshal_VOID__VOID,
G_TYPE_NONE, 0);
/**
* GtkWidget::delete-event:
* @widget: the object which received the signal
* @event: the event which triggered this signal
*
* The ::delete-event signal is emitted if a user requests that
* a toplevel window is closed. The default handler for this signal
* destroys the window. Connecting gtk_widget_hide_on_delete() to
* this signal will cause the window to be hidden instead, so that
* it can later be shown again without reconstructing it.
*
* Returns: %TRUE to stop other handlers from being invoked for the event.
* %FALSE to propagate the event further.
*/
widget_signals[DELETE_EVENT] =
g_signal_new (I_("delete-event"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, delete_event),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__BOXED,
G_TYPE_BOOLEAN, 1,
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
/**
* GtkWidget::destroy-event:
* @widget: the object which received the signal.
* @event: the event which triggered this signal
*
* The ::destroy-event signal is emitted when a #GdkWindow is destroyed.
* You rarely get this signal, because most widgets disconnect themselves
* from their window before they destroy it, so no widget owns the
* window at destroy time.
*
* To receive this signal, the #GdkWindow associated to the widget needs
* to enable the #GDK_STRUCTURE_MASK mask. GDK will enable this mask
* automatically for all new windows.
*
* Returns: %TRUE to stop other handlers from being invoked for the event.
* %FALSE to propagate the event further.
*/
widget_signals[DESTROY_EVENT] =
g_signal_new (I_("destroy-event"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, destroy_event),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__BOXED,
G_TYPE_BOOLEAN, 1,
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
/**
* GtkWidget::key-press-event:
* @widget: the object which received the signal
* @event: (type Gdk.EventKey): the #GdkEventKey which triggered this signal.
*
* The ::key-press-event signal is emitted when a key is pressed. The signal
* emission will reoccur at the key-repeat rate when the key is kept pressed.
*
* To receive this signal, the #GdkWindow associated to the widget needs
* to enable the #GDK_KEY_PRESS_MASK mask.
*
* This signal will be sent to the grab widget if there is one.
*
* Returns: %TRUE to stop other handlers from being invoked for the event.
* %FALSE to propagate the event further.
*/
widget_signals[KEY_PRESS_EVENT] =
g_signal_new (I_("key-press-event"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, key_press_event),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__BOXED,
G_TYPE_BOOLEAN, 1,
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
/**
* GtkWidget::key-release-event:
* @widget: the object which received the signal
* @event: (type Gdk.EventKey): the #GdkEventKey which triggered this signal.
*
* The ::key-release-event signal is emitted when a key is released.
*
* To receive this signal, the #GdkWindow associated to the widget needs
* to enable the #GDK_KEY_RELEASE_MASK mask.
*
* This signal will be sent to the grab widget if there is one.
*
* Returns: %TRUE to stop other handlers from being invoked for the event.
* %FALSE to propagate the event further.
*/
widget_signals[KEY_RELEASE_EVENT] =
g_signal_new (I_("key-release-event"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, key_release_event),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__BOXED,
G_TYPE_BOOLEAN, 1,
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
/**
* GtkWidget::enter-notify-event:
* @widget: the object which received the signal
* @event: (type Gdk.EventCrossing): the #GdkEventCrossing which triggered
* this signal.
*
* The ::enter-notify-event will be emitted when the pointer enters
* the @widget's window.
*
* To receive this signal, the #GdkWindow associated to the widget needs
* to enable the #GDK_ENTER_NOTIFY_MASK mask.
*
* This signal will be sent to the grab widget if there is one.
*
* Returns: %TRUE to stop other handlers from being invoked for the event.
* %FALSE to propagate the event further.
*/
widget_signals[ENTER_NOTIFY_EVENT] =
g_signal_new (I_("enter-notify-event"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, enter_notify_event),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__BOXED,
G_TYPE_BOOLEAN, 1,
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
/**
* GtkWidget::leave-notify-event:
* @widget: the object which received the signal
* @event: (type Gdk.EventCrossing): the #GdkEventCrossing which triggered
* this signal.
*
* The ::leave-notify-event will be emitted when the pointer leaves
* the @widget's window.
*
* To receive this signal, the #GdkWindow associated to the widget needs
* to enable the #GDK_LEAVE_NOTIFY_MASK mask.
*
* This signal will be sent to the grab widget if there is one.
*
* Returns: %TRUE to stop other handlers from being invoked for the event.
* %FALSE to propagate the event further.
*/
widget_signals[LEAVE_NOTIFY_EVENT] =
g_signal_new (I_("leave-notify-event"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, leave_notify_event),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__BOXED,
G_TYPE_BOOLEAN, 1,
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
/**
* GtkWidget::configure-event:
* @widget: the object which received the signal
* @event: (type Gdk.EventConfigure): the #GdkEventConfigure which triggered
* this signal.
*
* The ::configure-event signal will be emitted when the size, position or
* stacking of the @widget's window has changed.
*
* To receive this signal, the #GdkWindow associated to the widget needs
* to enable the #GDK_STRUCTURE_MASK mask. GDK will enable this mask
* automatically for all new windows.
*
* Returns: %TRUE to stop other handlers from being invoked for the event.
* %FALSE to propagate the event further.
*/
widget_signals[CONFIGURE_EVENT] =
g_signal_new (I_("configure-event"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, configure_event),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__BOXED,
G_TYPE_BOOLEAN, 1,
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
/**
* GtkWidget::focus-in-event:
* @widget: the object which received the signal
* @event: (type Gdk.EventFocus): the #GdkEventFocus which triggered
* this signal.
*
* The ::focus-in-event signal will be emitted when the keyboard focus
* enters the @widget's window.
*
* To receive this signal, the #GdkWindow associated to the widget needs
* to enable the #GDK_FOCUS_CHANGE_MASK mask.
*
* Returns: %TRUE to stop other handlers from being invoked for the event.
* %FALSE to propagate the event further.
*/
widget_signals[FOCUS_IN_EVENT] =
g_signal_new (I_("focus-in-event"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, focus_in_event),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__BOXED,
G_TYPE_BOOLEAN, 1,
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
/**
* GtkWidget::focus-out-event:
* @widget: the object which received the signal
* @event: (type Gdk.EventFocus): the #GdkEventFocus which triggered this
* signal.
*
* The ::focus-out-event signal will be emitted when the keyboard focus
* leaves the @widget's window.
*
* To receive this signal, the #GdkWindow associated to the widget needs
* to enable the #GDK_FOCUS_CHANGE_MASK mask.
*
* Returns: %TRUE to stop other handlers from being invoked for the event.
* %FALSE to propagate the event further.
*/
widget_signals[FOCUS_OUT_EVENT] =
g_signal_new (I_("focus-out-event"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, focus_out_event),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__BOXED,
G_TYPE_BOOLEAN, 1,
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
/**
* GtkWidget::map-event:
* @widget: the object which received the signal
* @event: (type Gdk.EventAny): the #GdkEventAny which triggered this signal.
*
* The ::map-event signal will be emitted when the @widget's window is
* mapped. A window is mapped when it becomes visible on the screen.
*
* To receive this signal, the #GdkWindow associated to the widget needs
* to enable the #GDK_STRUCTURE_MASK mask. GDK will enable this mask
* automatically for all new windows.
*
* Returns: %TRUE to stop other handlers from being invoked for the event.
* %FALSE to propagate the event further.
*/
widget_signals[MAP_EVENT] =
g_signal_new (I_("map-event"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, map_event),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__BOXED,
G_TYPE_BOOLEAN, 1,
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
/**
* GtkWidget::unmap-event:
* @widget: the object which received the signal
* @event: (type Gdk.EventAny): the #GdkEventAny which triggered this signal
*
* The ::unmap-event signal will be emitted when the @widget's window is
* unmapped. A window is unmapped when it becomes invisible on the screen.
*
* To receive this signal, the #GdkWindow associated to the widget needs
* to enable the #GDK_STRUCTURE_MASK mask. GDK will enable this mask
* automatically for all new windows.
*
* Returns: %TRUE to stop other handlers from being invoked for the event.
* %FALSE to propagate the event further.
*/
widget_signals[UNMAP_EVENT] =
g_signal_new (I_("unmap-event"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, unmap_event),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__BOXED,
G_TYPE_BOOLEAN, 1,
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
/**
* GtkWidget::property-notify-event:
* @widget: the object which received the signal
* @event: (type Gdk.EventProperty): the #GdkEventProperty which triggered
* this signal.
*
* The ::property-notify-event signal will be emitted when a property on
* the @widget's window has been changed or deleted.
*
* To receive this signal, the #GdkWindow associated to the widget needs
* to enable the #GDK_PROPERTY_CHANGE_MASK mask.
*
* Returns: %TRUE to stop other handlers from being invoked for the event.
* %FALSE to propagate the event further.
*/
widget_signals[PROPERTY_NOTIFY_EVENT] =
g_signal_new (I_("property-notify-event"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, property_notify_event),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__BOXED,
G_TYPE_BOOLEAN, 1,
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
/**
* GtkWidget::selection-clear-event:
* @widget: the object which received the signal
* @event: (type Gdk.EventSelection): the #GdkEventSelection which triggered
* this signal.
*
* The ::selection-clear-event signal will be emitted when the
* the @widget's window has lost ownership of a selection.
*
* Returns: %TRUE to stop other handlers from being invoked for the event.
* %FALSE to propagate the event further.
*/
widget_signals[SELECTION_CLEAR_EVENT] =
g_signal_new (I_("selection-clear-event"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, selection_clear_event),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__BOXED,
G_TYPE_BOOLEAN, 1,
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
/**
* GtkWidget::selection-request-event:
* @widget: the object which received the signal
* @event: (type Gdk.EventSelection): the #GdkEventSelection which triggered
* this signal.
*
* The ::selection-request-event signal will be emitted when
* another client requests ownership of the selection owned by
* the @widget's window.
*
* Returns: %TRUE to stop other handlers from being invoked for the event.
* %FALSE to propagate the event further.
*/
widget_signals[SELECTION_REQUEST_EVENT] =
g_signal_new (I_("selection-request-event"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, selection_request_event),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__BOXED,
G_TYPE_BOOLEAN, 1,
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
/**
* GtkWidget::selection-notify-event:
* @widget: the object which received the signal.
* @event: (type Gdk.EventSelection):
*
* Returns: %TRUE to stop other handlers from being invoked for the event. %FALSE to propagate the event further.
*/
widget_signals[SELECTION_NOTIFY_EVENT] =
g_signal_new (I_("selection-notify-event"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, selection_notify_event),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__BOXED,
G_TYPE_BOOLEAN, 1,
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
/**
* GtkWidget::selection-received:
* @widget: the object which received the signal.
* @data:
* @time:
*/
widget_signals[SELECTION_RECEIVED] =
g_signal_new (I_("selection-received"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, selection_received),
NULL, NULL,
_gtk_marshal_VOID__BOXED_UINT,
G_TYPE_NONE, 2,
GTK_TYPE_SELECTION_DATA | G_SIGNAL_TYPE_STATIC_SCOPE,
G_TYPE_UINT);
/**
* GtkWidget::selection-get:
* @widget: the object which received the signal.
* @data:
* @info:
* @time:
*/
widget_signals[SELECTION_GET] =
g_signal_new (I_("selection-get"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, selection_get),
NULL, NULL,
_gtk_marshal_VOID__BOXED_UINT_UINT,
G_TYPE_NONE, 3,
GTK_TYPE_SELECTION_DATA | G_SIGNAL_TYPE_STATIC_SCOPE,
G_TYPE_UINT,
G_TYPE_UINT);
/**
* GtkWidget::proximity-in-event:
* @widget: the object which received the signal
* @event: (type Gdk.EventProximity): the #GdkEventProximity which triggered
* this signal.
*
* To receive this signal the #GdkWindow associated to the widget needs
* to enable the #GDK_PROXIMITY_IN_MASK mask.
*
* This signal will be sent to the grab widget if there is one.
*
* Returns: %TRUE to stop other handlers from being invoked for the event.
* %FALSE to propagate the event further.
*/
widget_signals[PROXIMITY_IN_EVENT] =
g_signal_new (I_("proximity-in-event"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, proximity_in_event),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__BOXED,
G_TYPE_BOOLEAN, 1,
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
/**
* GtkWidget::proximity-out-event:
* @widget: the object which received the signal
* @event: (type Gdk.EventProximity): the #GdkEventProximity which triggered
* this signal.
*
* To receive this signal the #GdkWindow associated to the widget needs
* to enable the #GDK_PROXIMITY_OUT_MASK mask.
*
* This signal will be sent to the grab widget if there is one.
*
* Returns: %TRUE to stop other handlers from being invoked for the event.
* %FALSE to propagate the event further.
*/
widget_signals[PROXIMITY_OUT_EVENT] =
g_signal_new (I_("proximity-out-event"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, proximity_out_event),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__BOXED,
G_TYPE_BOOLEAN, 1,
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
/**
* GtkWidget::drag-leave:
* @widget: the object which received the signal.
* @drag_context: the drag context
* @time: the timestamp of the motion event
*
* The ::drag-leave signal is emitted on the drop site when the cursor
* leaves the widget. A typical reason to connect to this signal is to
* undo things done in #GtkWidget::drag-motion, e.g. undo highlighting
* with gtk_drag_unhighlight()
*/
widget_signals[DRAG_LEAVE] =
g_signal_new (I_("drag-leave"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, drag_leave),
NULL, NULL,
_gtk_marshal_VOID__OBJECT_UINT,
G_TYPE_NONE, 2,
GDK_TYPE_DRAG_CONTEXT,
G_TYPE_UINT);
/**
* GtkWidget::drag-begin:
* @widget: the object which received the signal
* @drag_context: the drag context
*
* The ::drag-begin signal is emitted on the drag source when a drag is
* started. A typical reason to connect to this signal is to set up a
* custom drag icon with gtk_drag_source_set_icon().
*
* Note that some widgets set up a drag icon in the default handler of
* this signal, so you may have to use g_signal_connect_after() to
* override what the default handler did.
*/
widget_signals[DRAG_BEGIN] =
g_signal_new (I_("drag-begin"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, drag_begin),
NULL, NULL,
_gtk_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
GDK_TYPE_DRAG_CONTEXT);
/**
* GtkWidget::drag-end:
* @widget: the object which received the signal
* @drag_context: the drag context
*
* The ::drag-end signal is emitted on the drag source when a drag is
* finished. A typical reason to connect to this signal is to undo
* things done in #GtkWidget::drag-begin.
*/
widget_signals[DRAG_END] =
g_signal_new (I_("drag-end"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, drag_end),
NULL, NULL,
_gtk_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
GDK_TYPE_DRAG_CONTEXT);
/**
* GtkWidget::drag-data-delete:
* @widget: the object which received the signal
* @drag_context: the drag context
*
* The ::drag-data-delete signal is emitted on the drag source when a drag
* with the action %GDK_ACTION_MOVE is successfully completed. The signal
* handler is responsible for deleting the data that has been dropped. What
* "delete" means depends on the context of the drag operation.
*/
widget_signals[DRAG_DATA_DELETE] =
g_signal_new (I_("drag-data-delete"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, drag_data_delete),
NULL, NULL,
_gtk_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
GDK_TYPE_DRAG_CONTEXT);
/**
* GtkWidget::drag-failed:
* @widget: the object which received the signal
* @drag_context: the drag context
* @result: the result of the drag operation
*
* The ::drag-failed signal is emitted on the drag source when a drag has
* failed. The signal handler may hook custom code to handle a failed DND
* operation based on the type of error, it returns %TRUE is the failure has
* been already handled (not showing the default "drag operation failed"
* animation), otherwise it returns %FALSE.
*
* Return value: %TRUE if the failed drag operation has been already handled.
*
* Since: 2.12
*/
widget_signals[DRAG_FAILED] =
g_signal_new (I_("drag-failed"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, drag_failed),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__OBJECT_ENUM,
G_TYPE_BOOLEAN, 2,
GDK_TYPE_DRAG_CONTEXT,
GTK_TYPE_DRAG_RESULT);
/**
* GtkWidget::drag-motion:
* @widget: the object which received the signal
* @drag_context: the drag context
* @x: the x coordinate of the current cursor position
* @y: the y coordinate of the current cursor position
* @time: the timestamp of the motion event
* @returns: whether the cursor position is in a drop zone
*
* The drag-motion signal is emitted on the drop site when the user
* moves the cursor over the widget during a drag. The signal handler
* must determine whether the cursor position is in a drop zone or not.
* If it is not in a drop zone, it returns %FALSE and no further processing
* is necessary. Otherwise, the handler returns %TRUE. In this case, the
* handler is responsible for providing the necessary information for
* displaying feedback to the user, by calling gdk_drag_status().
*
* If the decision whether the drop will be accepted or rejected can't be
* made based solely on the cursor position and the type of the data, the
* handler may inspect the dragged data by calling gtk_drag_get_data() and
* defer the gdk_drag_status() call to the #GtkWidget::drag-data-received
* handler. Note that you cannot not pass #GTK_DEST_DEFAULT_DROP,
* #GTK_DEST_DEFAULT_MOTION or #GTK_DEST_DEFAULT_ALL to gtk_drag_dest_set()
* when using the drag-motion signal that way.
*
* Also note that there is no drag-enter signal. The drag receiver has to
* keep track of whether he has received any drag-motion signals since the
* last #GtkWidget::drag-leave and if not, treat the drag-motion signal as
* an "enter" signal. Upon an "enter", the handler will typically highlight
* the drop site with gtk_drag_highlight().
* |[
* static void
* drag_motion (GtkWidget *widget,
* GdkDragContext *context,
* gint x,
* gint y,
* guint time)
* {
* GdkAtom target;
*
* PrivateData *private_data = GET_PRIVATE_DATA (widget);
*
* if (!private_data->drag_highlight)
* {
* private_data->drag_highlight = 1;
* gtk_drag_highlight (widget);
* }
*
* target = gtk_drag_dest_find_target (widget, context, NULL);
* if (target == GDK_NONE)
* gdk_drag_status (context, 0, time);
* else
* {
* private_data->pending_status = context->suggested_action;
* gtk_drag_get_data (widget, context, target, time);
* }
*
* return TRUE;
* }
*
* static void
* drag_data_received (GtkWidget *widget,
* GdkDragContext *context,
* gint x,
* gint y,
* GtkSelectionData *selection_data,
* guint info,
* guint time)
* {
* PrivateData *private_data = GET_PRIVATE_DATA (widget);
*
* if (private_data->suggested_action)
* {
* private_data->suggested_action = 0;
*
* /&ast; We are getting this data due to a request in drag_motion,
* * rather than due to a request in drag_drop, so we are just
* * supposed to call gdk_drag_status (), not actually paste in
* * the data.
* &ast;/
* str = gtk_selection_data_get_text (selection_data);
* if (!data_is_acceptable (str))
* gdk_drag_status (context, 0, time);
* else
* gdk_drag_status (context, private_data->suggested_action, time);
* }
* else
* {
* /&ast; accept the drop &ast;/
* }
* }
* ]|
*/
widget_signals[DRAG_MOTION] =
g_signal_new (I_("drag-motion"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, drag_motion),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__OBJECT_INT_INT_UINT,
G_TYPE_BOOLEAN, 4,
GDK_TYPE_DRAG_CONTEXT,
G_TYPE_INT,
G_TYPE_INT,
G_TYPE_UINT);
/**
* GtkWidget::drag-drop:
* @widget: the object which received the signal
* @drag_context: the drag context
* @x: the x coordinate of the current cursor position
* @y: the y coordinate of the current cursor position
* @time: the timestamp of the motion event
* @returns: whether the cursor position is in a drop zone
*
* The ::drag-drop signal is emitted on the drop site when the user drops
* the data onto the widget. The signal handler must determine whether
* the cursor position is in a drop zone or not. If it is not in a drop
* zone, it returns %FALSE and no further processing is necessary.
* Otherwise, the handler returns %TRUE. In this case, the handler must
* ensure that gtk_drag_finish() is called to let the source know that
* the drop is done. The call to gtk_drag_finish() can be done either
* directly or in a #GtkWidget::drag-data-received handler which gets
* triggered by calling gtk_drag_get_data() to receive the data for one
* or more of the supported targets.
*/
widget_signals[DRAG_DROP] =
g_signal_new (I_("drag-drop"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, drag_drop),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__OBJECT_INT_INT_UINT,
G_TYPE_BOOLEAN, 4,
GDK_TYPE_DRAG_CONTEXT,
G_TYPE_INT,
G_TYPE_INT,
G_TYPE_UINT);
/**
* GtkWidget::drag-data-get:
* @widget: the object which received the signal
* @drag_context: the drag context
* @data: the #GtkSelectionData to be filled with the dragged data
* @info: the info that has been registered with the target in the
* #GtkTargetList
* @time: the timestamp at which the data was requested
*
* The ::drag-data-get signal is emitted on the drag source when the drop
* site requests the data which is dragged. It is the responsibility of
* the signal handler to fill @data with the data in the format which
* is indicated by @info. See gtk_selection_data_set() and
* gtk_selection_data_set_text().
*/
widget_signals[DRAG_DATA_GET] =
g_signal_new (I_("drag-data-get"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, drag_data_get),
NULL, NULL,
_gtk_marshal_VOID__OBJECT_BOXED_UINT_UINT,
G_TYPE_NONE, 4,
GDK_TYPE_DRAG_CONTEXT,
GTK_TYPE_SELECTION_DATA | G_SIGNAL_TYPE_STATIC_SCOPE,
G_TYPE_UINT,
G_TYPE_UINT);
/**
* GtkWidget::drag-data-received:
* @widget: the object which received the signal
* @drag_context: the drag context
* @x: where the drop happened
* @y: where the drop happened
* @data: the received data
* @info: the info that has been registered with the target in the
* #GtkTargetList
* @time: the timestamp at which the data was received
*
* The ::drag-data-received signal is emitted on the drop site when the
* dragged data has been received. If the data was received in order to
* determine whether the drop will be accepted, the handler is expected
* to call gdk_drag_status() and <emphasis>not</emphasis> finish the drag.
* If the data was received in response to a #GtkWidget::drag-drop signal
* (and this is the last target to be received), the handler for this
* signal is expected to process the received data and then call
* gtk_drag_finish(), setting the @success parameter depending on whether
* the data was processed successfully.
*
* The handler may inspect and modify @drag_context->action before calling
* gtk_drag_finish(), e.g. to implement %GDK_ACTION_ASK as shown in the
* following example:
* |[
* void
* drag_data_received (GtkWidget *widget,
* GdkDragContext *drag_context,
* gint x,
* gint y,
* GtkSelectionData *data,
* guint info,
* guint time)
* {
* if ((data->length >= 0) && (data->format == 8))
* {
* if (drag_context->action == GDK_ACTION_ASK)
* {
* GtkWidget *dialog;
* gint response;
*
* dialog = gtk_message_dialog_new (NULL,
* GTK_DIALOG_MODAL |
* GTK_DIALOG_DESTROY_WITH_PARENT,
* GTK_MESSAGE_INFO,
* GTK_BUTTONS_YES_NO,
* "Move the data ?\n");
* response = gtk_dialog_run (GTK_DIALOG (dialog));
* gtk_widget_destroy (dialog);
*
* if (response == GTK_RESPONSE_YES)
* drag_context->action = GDK_ACTION_MOVE;
* else
* drag_context->action = GDK_ACTION_COPY;
* }
*
* gtk_drag_finish (drag_context, TRUE, FALSE, time);
* return;
* }
*
* gtk_drag_finish (drag_context, FALSE, FALSE, time);
* }
* ]|
*/
widget_signals[DRAG_DATA_RECEIVED] =
g_signal_new (I_("drag-data-received"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, drag_data_received),
NULL, NULL,
_gtk_marshal_VOID__OBJECT_INT_INT_BOXED_UINT_UINT,
G_TYPE_NONE, 6,
GDK_TYPE_DRAG_CONTEXT,
G_TYPE_INT,
G_TYPE_INT,
GTK_TYPE_SELECTION_DATA | G_SIGNAL_TYPE_STATIC_SCOPE,
G_TYPE_UINT,
G_TYPE_UINT);
/**
* GtkWidget::visibility-notify-event:
* @widget: the object which received the signal
* @event: (type Gdk.EventVisibility): the #GdkEventVisibility which
* triggered this signal.
*
* The ::visibility-notify-event will be emitted when the @widget's window
* is obscured or unobscured.
*
* To receive this signal the #GdkWindow associated to the widget needs
* to enable the #GDK_VISIBILITY_NOTIFY_MASK mask.
*
* Returns: %TRUE to stop other handlers from being invoked for the event.
* %FALSE to propagate the event further.
*/
widget_signals[VISIBILITY_NOTIFY_EVENT] =
g_signal_new (I_("visibility-notify-event"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, visibility_notify_event),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__BOXED,
G_TYPE_BOOLEAN, 1,
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
/**
* GtkWidget::window-state-event:
* @widget: the object which received the signal
* @event: (type Gdk.EventWindowState): the #GdkEventWindowState which
* triggered this signal.
*
* The ::window-state-event will be emitted when the state of the
* toplevel window associated to the @widget changes.
*
* To receive this signal the #GdkWindow associated to the widget
* needs to enable the #GDK_STRUCTURE_MASK mask. GDK will enable
* this mask automatically for all new windows.
*
* Returns: %TRUE to stop other handlers from being invoked for the
* event. %FALSE to propagate the event further.
*/
widget_signals[WINDOW_STATE_EVENT] =
g_signal_new (I_("window-state-event"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, window_state_event),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__BOXED,
G_TYPE_BOOLEAN, 1,
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
/**
* GtkWidget::damage-event:
* @widget: the object which received the signal
* @event: (type Gdk.EventExpose): the #GdkEventExpose event
*
* Emitted when a redirected window belonging to @widget gets drawn into.
* The region/area members of the event shows what area of the redirected
* drawable was drawn into.
*
* Returns: %TRUE to stop other handlers from being invoked for the event.
* %FALSE to propagate the event further.
*
* Since: 2.14
*/
widget_signals[DAMAGE_EVENT] =
g_signal_new (I_("damage-event"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, damage_event),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__BOXED,
G_TYPE_BOOLEAN, 1,
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
/**
* GtkWidget::grab-broken-event:
* @widget: the object which received the signal
* @event: (type Gdk.EventGrabBroken): the #GdkEventGrabBroken event
*
* Emitted when a pointer or keyboard grab on a window belonging
* to @widget gets broken.
*
* On X11, this happens when the grab window becomes unviewable
* (i.e. it or one of its ancestors is unmapped), or if the same
* application grabs the pointer or keyboard again.
*
* Returns: %TRUE to stop other handlers from being invoked for
* the event. %FALSE to propagate the event further.
*
* Since: 2.8
*/
widget_signals[GRAB_BROKEN_EVENT] =
g_signal_new (I_("grab-broken-event"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, grab_broken_event),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__BOXED,
G_TYPE_BOOLEAN, 1,
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
/**
* GtkWidget::query-tooltip:
* @widget: the object which received the signal
* @x: the x coordinate of the cursor position where the request has
* been emitted, relative to @widget's left side
* @y: the y coordinate of the cursor position where the request has
* been emitted, relative to @widget's top
* @keyboard_mode: %TRUE if the tooltip was trigged using the keyboard
* @tooltip: a #GtkTooltip
*
* Emitted when #GtkWidget:has-tooltip is %TRUE and the #GtkSettings:gtk-tooltip-timeout
* has expired with the cursor hovering "above" @widget; or emitted when @widget got
* focus in keyboard mode.
*
* Using the given coordinates, the signal handler should determine
* whether a tooltip should be shown for @widget. If this is the case
* %TRUE should be returned, %FALSE otherwise. Note that if
* @keyboard_mode is %TRUE, the values of @x and @y are undefined and
* should not be used.
*
* The signal handler is free to manipulate @tooltip with the therefore
* destined function calls.
*
* Returns: %TRUE if @tooltip should be shown right now, %FALSE otherwise.
*
* Since: 2.12
*/
widget_signals[QUERY_TOOLTIP] =
g_signal_new (I_("query-tooltip"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, query_tooltip),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__INT_INT_BOOLEAN_OBJECT,
G_TYPE_BOOLEAN, 4,
G_TYPE_INT,
G_TYPE_INT,
G_TYPE_BOOLEAN,
GTK_TYPE_TOOLTIP);
/**
* GtkWidget::popup-menu
* @widget: the object which received the signal
*
* This signal gets emitted whenever a widget should pop up a context
* menu. This usually happens through the standard key binding mechanism;
* by pressing a certain key while a widget is focused, the user can cause
* the widget to pop up a menu. For example, the #GtkEntry widget creates
* a menu with clipboard commands. See <xref linkend="checklist-popup-menu"/>
* for an example of how to use this signal.
*
* Returns: %TRUE if a menu was activated
*/
widget_signals[POPUP_MENU] =
g_signal_new (I_("popup-menu"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (GtkWidgetClass, popup_menu),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__VOID,
G_TYPE_BOOLEAN, 0);
/**
* GtkWidget::show-help:
* @widget: the object which received the signal.
* @help_type:
*/
widget_signals[SHOW_HELP] =
g_signal_new (I_("show-help"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (GtkWidgetClass, show_help),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__ENUM,
G_TYPE_BOOLEAN, 1,
GTK_TYPE_WIDGET_HELP_TYPE);
/**
* GtkWidget::accel-closures-changed:
* @widget: the object which received the signal.
*/
widget_signals[ACCEL_CLOSURES_CHANGED] =
g_signal_new (I_("accel-closures-changed"),
G_TYPE_FROM_CLASS (klass),
0,
0,
NULL, NULL,
_gtk_marshal_VOID__VOID,
G_TYPE_NONE, 0);
/**
* GtkWidget::screen-changed:
* @widget: the object on which the signal is emitted
* @previous_screen: (allow-none): the previous screen, or %NULL if the
* widget was not associated with a screen before
*
* The ::screen-changed signal gets emitted when the
* screen of a widget has changed.
*/
widget_signals[SCREEN_CHANGED] =
g_signal_new (I_("screen-changed"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, screen_changed),
NULL, NULL,
_gtk_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
GDK_TYPE_SCREEN);
/**
* GtkWidget::can-activate-accel:
* @widget: the object which received the signal
* @signal_id: the ID of a signal installed on @widget
*
* Determines whether an accelerator that activates the signal
* identified by @signal_id can currently be activated.
* This signal is present to allow applications and derived
* widgets to override the default #GtkWidget handling
* for determining whether an accelerator can be activated.
*
* Returns: %TRUE if the signal can be activated.
*/
widget_signals[CAN_ACTIVATE_ACCEL] =
g_signal_new (I_("can-activate-accel"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWidgetClass, can_activate_accel),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__UINT,
G_TYPE_BOOLEAN, 1, G_TYPE_UINT);
binding_set = gtk_binding_set_by_class (klass);
gtk_binding_entry_add_signal (binding_set, GDK_KEY_F10, GDK_SHIFT_MASK,
"popup-menu", 0);
gtk_binding_entry_add_signal (binding_set, GDK_KEY_Menu, 0,
"popup-menu", 0);
gtk_binding_entry_add_signal (binding_set, GDK_KEY_F1, GDK_CONTROL_MASK,
"show-help", 1,
GTK_TYPE_WIDGET_HELP_TYPE,
GTK_WIDGET_HELP_TOOLTIP);
gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_F1, GDK_CONTROL_MASK,
"show-help", 1,
GTK_TYPE_WIDGET_HELP_TYPE,
GTK_WIDGET_HELP_TOOLTIP);
gtk_binding_entry_add_signal (binding_set, GDK_KEY_F1, GDK_SHIFT_MASK,
"show-help", 1,
GTK_TYPE_WIDGET_HELP_TYPE,
GTK_WIDGET_HELP_WHATS_THIS);
gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_F1, GDK_SHIFT_MASK,
"show-help", 1,
GTK_TYPE_WIDGET_HELP_TYPE,
GTK_WIDGET_HELP_WHATS_THIS);
gtk_widget_class_install_style_property (klass,
g_param_spec_boolean ("interior-focus",
P_("Interior Focus"),
P_("Whether to draw the focus indicator inside widgets"),
TRUE,
GTK_PARAM_READABLE));
gtk_widget_class_install_style_property (klass,
g_param_spec_int ("focus-line-width",
P_("Focus linewidth"),
P_("Width, in pixels, of the focus indicator line"),
0, G_MAXINT, 1,
GTK_PARAM_READABLE));
gtk_widget_class_install_style_property (klass,
g_param_spec_string ("focus-line-pattern",
P_("Focus line dash pattern"),
P_("Dash pattern used to draw the focus indicator"),
"\1\1",
GTK_PARAM_READABLE));
gtk_widget_class_install_style_property (klass,
g_param_spec_int ("focus-padding",
P_("Focus padding"),
P_("Width, in pixels, between focus indicator and the widget 'box'"),
0, G_MAXINT, 1,
GTK_PARAM_READABLE));
gtk_widget_class_install_style_property (klass,
g_param_spec_boxed ("cursor-color",
P_("Cursor color"),
P_("Color with which to draw insertion cursor"),
GDK_TYPE_COLOR,
GTK_PARAM_READABLE));
gtk_widget_class_install_style_property (klass,
g_param_spec_boxed ("secondary-cursor-color",
P_("Secondary cursor color"),
P_("Color with which to draw the secondary insertion cursor when editing mixed right-to-left and left-to-right text"),
GDK_TYPE_COLOR,
GTK_PARAM_READABLE));
gtk_widget_class_install_style_property (klass,
g_param_spec_float ("cursor-aspect-ratio",
P_("Cursor line aspect ratio"),
P_("Aspect ratio with which to draw insertion cursor"),
0.0, 1.0, 0.04,
GTK_PARAM_READABLE));
gtk_widget_class_install_style_property (klass,
g_param_spec_boolean ("window-dragging",
P_("Window dragging"),
P_("Whether windows can be dragged by clicking on empty areas"),
FALSE,
GTK_PARAM_READABLE));
/**
* GtkWidget:link-color:
*
* The "link-color" style property defines the color of unvisited links.
*
* Since: 2.10
*/
gtk_widget_class_install_style_property (klass,
g_param_spec_boxed ("link-color",
P_("Unvisited Link Color"),
P_("Color of unvisited links"),
GDK_TYPE_COLOR,
GTK_PARAM_READABLE));
/**
* GtkWidget:visited-link-color:
*
* The "visited-link-color" style property defines the color of visited links.
*
* Since: 2.10
*/
gtk_widget_class_install_style_property (klass,
g_param_spec_boxed ("visited-link-color",
P_("Visited Link Color"),
P_("Color of visited links"),
GDK_TYPE_COLOR,
GTK_PARAM_READABLE));
/**
* GtkWidget:wide-separators:
*
* The "wide-separators" style property defines whether separators have
* configurable width and should be drawn using a box instead of a line.
*
* Since: 2.10
*/
gtk_widget_class_install_style_property (klass,
g_param_spec_boolean ("wide-separators",
P_("Wide Separators"),
P_("Whether separators have configurable width and should be drawn using a box instead of a line"),
FALSE,
GTK_PARAM_READABLE));
/**
* GtkWidget:separator-width:
*
* The "separator-width" style property defines the width of separators.
* This property only takes effect if #GtkWidget:wide-separators is %TRUE.
*
* Since: 2.10
*/
gtk_widget_class_install_style_property (klass,
g_param_spec_int ("separator-width",
P_("Separator Width"),
P_("The width of separators if wide-separators is TRUE"),
0, G_MAXINT, 0,
GTK_PARAM_READABLE));
/**
* GtkWidget:separator-height:
*
* The "separator-height" style property defines the height of separators.
* This property only takes effect if #GtkWidget:wide-separators is %TRUE.
*
* Since: 2.10
*/
gtk_widget_class_install_style_property (klass,
g_param_spec_int ("separator-height",
P_("Separator Height"),
P_("The height of separators if \"wide-separators\" is TRUE"),
0, G_MAXINT, 0,
GTK_PARAM_READABLE));
/**
* GtkWidget:scroll-arrow-hlength:
*
* The "scroll-arrow-hlength" style property defines the length of
* horizontal scroll arrows.
*
* Since: 2.10
*/
gtk_widget_class_install_style_property (klass,
g_param_spec_int ("scroll-arrow-hlength",
P_("Horizontal Scroll Arrow Length"),
P_("The length of horizontal scroll arrows"),
1, G_MAXINT, 16,
GTK_PARAM_READABLE));
/**
* GtkWidget:scroll-arrow-vlength:
*
* The "scroll-arrow-vlength" style property defines the length of
* vertical scroll arrows.
*
* Since: 2.10
*/
gtk_widget_class_install_style_property (klass,
g_param_spec_int ("scroll-arrow-vlength",
P_("Vertical Scroll Arrow Length"),
P_("The length of vertical scroll arrows"),
1, G_MAXINT, 16,
GTK_PARAM_READABLE));
g_type_class_add_private (klass, sizeof (GtkWidgetPrivate));
gtk_widget_class_set_accessible_type (klass, GTK_TYPE_WIDGET_ACCESSIBLE);
}
static void
gtk_widget_base_class_finalize (GtkWidgetClass *klass)
{
GList *list, *node;
list = g_param_spec_pool_list_owned (style_property_spec_pool, G_OBJECT_CLASS_TYPE (klass));
for (node = list; node; node = node->next)
{
GParamSpec *pspec = node->data;
g_param_spec_pool_remove (style_property_spec_pool, pspec);
g_param_spec_unref (pspec);
}
g_list_free (list);
}
static void
gtk_widget_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkWidget *widget = GTK_WIDGET (object);
switch (prop_id)
{
gboolean tmp;
gchar *tooltip_markup;
const gchar *tooltip_text;
GtkWindow *tooltip_window;
case PROP_NAME:
gtk_widget_set_name (widget, g_value_get_string (value));
break;
case PROP_PARENT:
gtk_container_add (GTK_CONTAINER (g_value_get_object (value)), widget);
break;
case PROP_WIDTH_REQUEST:
gtk_widget_set_usize_internal (widget, g_value_get_int (value), -2, 0);
break;
case PROP_HEIGHT_REQUEST:
gtk_widget_set_usize_internal (widget, -2, g_value_get_int (value), 0);
break;
case PROP_VISIBLE:
gtk_widget_set_visible (widget, g_value_get_boolean (value));
break;
case PROP_SENSITIVE:
gtk_widget_set_sensitive (widget, g_value_get_boolean (value));
break;
case PROP_APP_PAINTABLE:
gtk_widget_set_app_paintable (widget, g_value_get_boolean (value));
break;
case PROP_CAN_FOCUS:
gtk_widget_set_can_focus (widget, g_value_get_boolean (value));
break;
case PROP_HAS_FOCUS:
if (g_value_get_boolean (value))
gtk_widget_grab_focus (widget);
break;
case PROP_IS_FOCUS:
if (g_value_get_boolean (value))
gtk_widget_grab_focus (widget);
break;
case PROP_CAN_DEFAULT:
gtk_widget_set_can_default (widget, g_value_get_boolean (value));
break;
case PROP_HAS_DEFAULT:
if (g_value_get_boolean (value))
gtk_widget_grab_default (widget);
break;
case PROP_RECEIVES_DEFAULT:
gtk_widget_set_receives_default (widget, g_value_get_boolean (value));
break;
case PROP_STYLE:
gtk_widget_set_style (widget, g_value_get_object (value));
break;
case PROP_EVENTS:
if (!gtk_widget_get_realized (widget) && gtk_widget_get_has_window (widget))
gtk_widget_set_events (widget, g_value_get_flags (value));
break;
case PROP_NO_SHOW_ALL:
gtk_widget_set_no_show_all (widget, g_value_get_boolean (value));
break;
case PROP_HAS_TOOLTIP:
gtk_widget_real_set_has_tooltip (widget,
g_value_get_boolean (value), FALSE);
break;
case PROP_TOOLTIP_MARKUP:
tooltip_window = g_object_get_qdata (object, quark_tooltip_window);
tooltip_markup = g_value_dup_string (value);
/* Treat an empty string as a NULL string,
* because an empty string would be useless for a tooltip:
*/
if (tooltip_markup && (strlen (tooltip_markup) == 0))
{
g_free (tooltip_markup);
tooltip_markup = NULL;
}
g_object_set_qdata_full (object, quark_tooltip_markup,
tooltip_markup, g_free);
tmp = (tooltip_window != NULL || tooltip_markup != NULL);
gtk_widget_real_set_has_tooltip (widget, tmp, FALSE);
if (gtk_widget_get_visible (widget))
gtk_widget_queue_tooltip_query (widget);
break;
case PROP_TOOLTIP_TEXT:
tooltip_window = g_object_get_qdata (object, quark_tooltip_window);
tooltip_text = g_value_get_string (value);
/* Treat an empty string as a NULL string,
* because an empty string would be useless for a tooltip:
*/
if (tooltip_text && (strlen (tooltip_text) == 0))
tooltip_text = NULL;
tooltip_markup = tooltip_text ? g_markup_escape_text (tooltip_text, -1) : NULL;
g_object_set_qdata_full (object, quark_tooltip_markup,
tooltip_markup, g_free);
tmp = (tooltip_window != NULL || tooltip_markup != NULL);
gtk_widget_real_set_has_tooltip (widget, tmp, FALSE);
if (gtk_widget_get_visible (widget))
gtk_widget_queue_tooltip_query (widget);
break;
case PROP_DOUBLE_BUFFERED:
gtk_widget_set_double_buffered (widget, g_value_get_boolean (value));
break;
case PROP_HALIGN:
gtk_widget_set_halign (widget, g_value_get_enum (value));
break;
case PROP_VALIGN:
gtk_widget_set_valign (widget, g_value_get_enum (value));
break;
case PROP_MARGIN_LEFT:
gtk_widget_set_margin_left (widget, g_value_get_int (value));
break;
case PROP_MARGIN_RIGHT:
gtk_widget_set_margin_right (widget, g_value_get_int (value));
break;
case PROP_MARGIN_TOP:
gtk_widget_set_margin_top (widget, g_value_get_int (value));
break;
case PROP_MARGIN_BOTTOM:
gtk_widget_set_margin_bottom (widget, g_value_get_int (value));
break;
case PROP_MARGIN:
g_object_freeze_notify (G_OBJECT (widget));
gtk_widget_set_margin_left (widget, g_value_get_int (value));
gtk_widget_set_margin_right (widget, g_value_get_int (value));
gtk_widget_set_margin_top (widget, g_value_get_int (value));
gtk_widget_set_margin_bottom (widget, g_value_get_int (value));
g_object_thaw_notify (G_OBJECT (widget));
break;
case PROP_HEXPAND:
gtk_widget_set_hexpand (widget, g_value_get_boolean (value));
break;
case PROP_HEXPAND_SET:
gtk_widget_set_hexpand_set (widget, g_value_get_boolean (value));
break;
case PROP_VEXPAND:
gtk_widget_set_vexpand (widget, g_value_get_boolean (value));
break;
case PROP_VEXPAND_SET:
gtk_widget_set_vexpand_set (widget, g_value_get_boolean (value));
break;
case PROP_EXPAND:
g_object_freeze_notify (G_OBJECT (widget));
gtk_widget_set_hexpand (widget, g_value_get_boolean (value));
gtk_widget_set_vexpand (widget, g_value_get_boolean (value));
g_object_thaw_notify (G_OBJECT (widget));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_widget_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkWidget *widget = GTK_WIDGET (object);
GtkWidgetPrivate *priv = widget->priv;
switch (prop_id)
{
gpointer *eventp;
case PROP_NAME:
if (priv->name)
g_value_set_string (value, priv->name);
else
g_value_set_static_string (value, "");
break;
case PROP_PARENT:
g_value_set_object (value, priv->parent);
break;
case PROP_WIDTH_REQUEST:
{
int w;
gtk_widget_get_size_request (widget, &w, NULL);
g_value_set_int (value, w);
}
break;
case PROP_HEIGHT_REQUEST:
{
int h;
gtk_widget_get_size_request (widget, NULL, &h);
g_value_set_int (value, h);
}
break;
case PROP_VISIBLE:
g_value_set_boolean (value, (gtk_widget_get_visible (widget) != FALSE));
break;
case PROP_SENSITIVE:
g_value_set_boolean (value, (gtk_widget_get_sensitive (widget) != FALSE));
break;
case PROP_APP_PAINTABLE:
g_value_set_boolean (value, (gtk_widget_get_app_paintable (widget) != FALSE));
break;
case PROP_CAN_FOCUS:
g_value_set_boolean (value, (gtk_widget_get_can_focus (widget) != FALSE));
break;
case PROP_HAS_FOCUS:
g_value_set_boolean (value, (gtk_widget_has_focus (widget) != FALSE));
break;
case PROP_IS_FOCUS:
g_value_set_boolean (value, (gtk_widget_is_focus (widget)));
break;
case PROP_CAN_DEFAULT:
g_value_set_boolean (value, (gtk_widget_get_can_default (widget) != FALSE));
break;
case PROP_HAS_DEFAULT:
g_value_set_boolean (value, (gtk_widget_has_default (widget) != FALSE));
break;
case PROP_RECEIVES_DEFAULT:
g_value_set_boolean (value, (gtk_widget_get_receives_default (widget) != FALSE));
break;
case PROP_COMPOSITE_CHILD:
g_value_set_boolean (value, widget->priv->composite_child);
break;
case PROP_STYLE:
g_value_set_object (value, gtk_widget_get_style (widget));
break;
case PROP_EVENTS:
eventp = g_object_get_qdata (G_OBJECT (widget), quark_event_mask);
g_value_set_flags (value, GPOINTER_TO_INT (eventp));
break;
case PROP_NO_SHOW_ALL:
g_value_set_boolean (value, gtk_widget_get_no_show_all (widget));
break;
case PROP_HAS_TOOLTIP:
g_value_set_boolean (value, GPOINTER_TO_UINT (g_object_get_qdata (object, quark_has_tooltip)));
break;
case PROP_TOOLTIP_TEXT:
{
gchar *escaped = g_object_get_qdata (object, quark_tooltip_markup);
gchar *text = NULL;
if (escaped && !pango_parse_markup (escaped, -1, 0, NULL, &text, NULL, NULL))
g_assert (NULL == text); /* text should still be NULL in case of markup errors */
g_value_take_string (value, text);
}
break;
case PROP_TOOLTIP_MARKUP:
g_value_set_string (value, g_object_get_qdata (object, quark_tooltip_markup));
break;
case PROP_WINDOW:
g_value_set_object (value, gtk_widget_get_window (widget));
break;
case PROP_DOUBLE_BUFFERED:
g_value_set_boolean (value, gtk_widget_get_double_buffered (widget));
break;
case PROP_HALIGN:
g_value_set_enum (value, gtk_widget_get_halign (widget));
break;
case PROP_VALIGN:
g_value_set_enum (value, gtk_widget_get_valign (widget));
break;
case PROP_MARGIN_LEFT:
g_value_set_int (value, gtk_widget_get_margin_left (widget));
break;
case PROP_MARGIN_RIGHT:
g_value_set_int (value, gtk_widget_get_margin_right (widget));
break;
case PROP_MARGIN_TOP:
g_value_set_int (value, gtk_widget_get_margin_top (widget));
break;
case PROP_MARGIN_BOTTOM:
g_value_set_int (value, gtk_widget_get_margin_bottom (widget));
break;
case PROP_MARGIN:
{
GtkWidgetAuxInfo *aux_info = gtk_widget_get_aux_info (widget, FALSE);
if (aux_info == NULL)
{
g_value_set_int (value, 0);
}
else
{
g_value_set_int (value, MAX (MAX (aux_info->margin.left,
aux_info->margin.right),
MAX (aux_info->margin.top,
aux_info->margin.bottom)));
}
}
break;
case PROP_HEXPAND:
g_value_set_boolean (value, gtk_widget_get_hexpand (widget));
break;
case PROP_HEXPAND_SET:
g_value_set_boolean (value, gtk_widget_get_hexpand_set (widget));
break;
case PROP_VEXPAND:
g_value_set_boolean (value, gtk_widget_get_vexpand (widget));
break;
case PROP_VEXPAND_SET:
g_value_set_boolean (value, gtk_widget_get_vexpand_set (widget));
break;
case PROP_EXPAND:
g_value_set_boolean (value,
gtk_widget_get_hexpand (widget) &&
gtk_widget_get_vexpand (widget));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_widget_init (GtkWidget *widget)
{
GtkWidgetPrivate *priv;
widget->priv = G_TYPE_INSTANCE_GET_PRIVATE (widget,
GTK_TYPE_WIDGET,
GtkWidgetPrivate);
priv = widget->priv;
priv->child_visible = TRUE;
priv->name = NULL;
priv->allocation.x = -1;
priv->allocation.y = -1;
priv->allocation.width = 1;
priv->allocation.height = 1;
priv->window = NULL;
priv->parent = NULL;
priv->sensitive = TRUE;
priv->composite_child = composite_child_stack != 0;
priv->double_buffered = TRUE;
priv->redraw_on_alloc = TRUE;
priv->width_request_needed = TRUE;
priv->height_request_needed = TRUE;
priv->alloc_needed = TRUE;
/* this will be set to TRUE if the widget gets a child or if the
* expand flag is set on the widget, but until one of those happen
* we know the expand is already properly FALSE.
*
* We really want to default FALSE here to avoid computing expand
* all over the place while initially building a widget tree.
*/
priv->need_compute_expand = FALSE;
priv->style = gtk_widget_get_default_style ();
g_object_ref (priv->style);
}
static void
gtk_widget_dispatch_child_properties_changed (GtkWidget *widget,
guint n_pspecs,
GParamSpec **pspecs)
{
GtkWidgetPrivate *priv = widget->priv;
GtkWidget *container = priv->parent;
guint i;
for (i = 0; widget->priv->parent == container && i < n_pspecs; i++)
g_signal_emit (widget, widget_signals[CHILD_NOTIFY], g_quark_from_string (pspecs[i]->name), pspecs[i]);
}
/**
* gtk_widget_freeze_child_notify:
* @widget: a #GtkWidget
*
* Stops emission of #GtkWidget::child-notify signals on @widget. The
* signals are queued until gtk_widget_thaw_child_notify() is called
* on @widget.
*
* This is the analogue of g_object_freeze_notify() for child properties.
**/
void
gtk_widget_freeze_child_notify (GtkWidget *widget)
{
g_return_if_fail (GTK_IS_WIDGET (widget));
if (!G_OBJECT (widget)->ref_count)
return;
g_object_ref (widget);
g_object_notify_queue_freeze (G_OBJECT (widget), _gtk_widget_child_property_notify_context);
g_object_unref (widget);
}
/**
* gtk_widget_child_notify:
* @widget: a #GtkWidget
* @child_property: the name of a child property installed on the
* class of @widget<!-- -->'s parent
*
* Emits a #GtkWidget::child-notify signal for the
* <link linkend="child-properties">child property</link> @child_property
* on @widget.
*
* This is the analogue of g_object_notify() for child properties.
*
* Also see gtk_container_child_notify().
*/
void
gtk_widget_child_notify (GtkWidget *widget,
const gchar *child_property)
{
if (widget->priv->parent == NULL)
return;
gtk_container_child_notify (GTK_CONTAINER (widget->priv->parent), widget, child_property);
}
/**
* gtk_widget_thaw_child_notify:
* @widget: a #GtkWidget
*
* Reverts the effect of a previous call to gtk_widget_freeze_child_notify().
* This causes all queued #GtkWidget::child-notify signals on @widget to be
* emitted.
*/
void
gtk_widget_thaw_child_notify (GtkWidget *widget)
{
GObjectNotifyQueue *nqueue;
g_return_if_fail (GTK_IS_WIDGET (widget));
if (!G_OBJECT (widget)->ref_count)
return;
g_object_ref (widget);
nqueue = g_object_notify_queue_from_object (G_OBJECT (widget), _gtk_widget_child_property_notify_context);
if (!nqueue || !nqueue->freeze_count)
g_warning (G_STRLOC ": child-property-changed notification for %s(%p) is not frozen",
G_OBJECT_TYPE_NAME (widget), widget);
else
g_object_notify_queue_thaw (G_OBJECT (widget), nqueue);
g_object_unref (widget);
}
/**
* gtk_widget_new:
* @type: type ID of the widget to create
* @first_property_name: name of first property to set
* @Varargs: value of first property, followed by more properties,
* %NULL-terminated
*
* This is a convenience function for creating a widget and setting
* its properties in one go. For example you might write:
* <literal>gtk_widget_new (GTK_TYPE_LABEL, "label", "Hello World", "xalign",
* 0.0, NULL)</literal> to create a left-aligned label. Equivalent to
* g_object_new(), but returns a widget so you don't have to
* cast the object yourself.
*
* Return value: a new #GtkWidget of type @widget_type
**/
GtkWidget*
gtk_widget_new (GType type,
const gchar *first_property_name,
...)
{
GtkWidget *widget;
va_list var_args;
g_return_val_if_fail (g_type_is_a (type, GTK_TYPE_WIDGET), NULL);
va_start (var_args, first_property_name);
widget = (GtkWidget *)g_object_new_valist (type, first_property_name, var_args);
va_end (var_args);
return widget;
}
static inline void
gtk_widget_queue_draw_child (GtkWidget *widget)
{
GtkWidgetPrivate *priv = widget->priv;
GtkWidget *parent;
parent = priv->parent;
if (parent && gtk_widget_is_drawable (parent))
gtk_widget_queue_draw_area (parent,
priv->allocation.x,
priv->allocation.y,
priv->allocation.width,
priv->allocation.height);
}
/**
* gtk_widget_unparent:
* @widget: a #GtkWidget
*
* This function is only for use in widget implementations.
* Should be called by implementations of the remove method
* on #GtkContainer, to dissociate a child from the container.
**/
void
gtk_widget_unparent (GtkWidget *widget)
{
GtkWidgetPrivate *priv;
GObjectNotifyQueue *nqueue;
GtkWidget *toplevel;
GtkWidget *old_parent;
g_return_if_fail (GTK_IS_WIDGET (widget));
priv = widget->priv;
if (priv->parent == NULL)
return;
/* keep this function in sync with gtk_menu_detach() */
gtk_widget_push_verify_invariants (widget);
g_object_freeze_notify (G_OBJECT (widget));
nqueue = g_object_notify_queue_freeze (G_OBJECT (widget), _gtk_widget_child_property_notify_context);
toplevel = gtk_widget_get_toplevel (widget);
if (gtk_widget_is_toplevel (toplevel))
_gtk_window_unset_focus_and_default (GTK_WINDOW (toplevel), widget);
if (gtk_container_get_focus_child (GTK_CONTAINER (priv->parent)) == widget)
gtk_container_set_focus_child (GTK_CONTAINER (priv->parent), NULL);
gtk_widget_queue_draw_child (widget);
/* Reset the width and height here, to force reallocation if we
* get added back to a new parent. This won't work if our new
* allocation is smaller than 1x1 and we actually want a size of 1x1...
* (would 0x0 be OK here?)
*/
priv->allocation.width = 1;
priv->allocation.height = 1;
if (gtk_widget_get_realized (widget))
{
if (priv->in_reparent)
gtk_widget_unmap (widget);
else
gtk_widget_unrealize (widget);
}
/* If we are unanchoring the child, we save around the toplevel
* to emit hierarchy changed
*/
if (priv->parent->priv->anchored)
g_object_ref (toplevel);
else
toplevel = NULL;
/* Removing a widget from a container restores the child visible
* flag to the default state, so it doesn't affect the child
* in the next parent.
*/
priv->child_visible = TRUE;
old_parent = priv->parent;
priv->parent = NULL;
/* parent may no longer expand if the removed
* child was expand=TRUE and could therefore
* be forcing it to.
*/
if (gtk_widget_get_visible (widget) &&
(priv->need_compute_expand ||
priv->computed_hexpand ||
priv->computed_vexpand))
{
gtk_widget_queue_compute_expand (old_parent);
}
g_signal_emit (widget, widget_signals[PARENT_SET], 0, old_parent);
if (toplevel)
{
_gtk_widget_propagate_hierarchy_changed (widget, toplevel);
g_object_unref (toplevel);
}
/* Now that the parent pointer is nullified and the hierarchy-changed
* already passed, go ahead and unset the parent window, if we are unparenting
* an embeded GtkWindow the window will become toplevel again and hierarchy-changed
* will fire again for the new subhierarchy.
*/
gtk_widget_set_parent_window (widget, NULL);
g_object_notify (G_OBJECT (widget), "parent");
g_object_thaw_notify (G_OBJECT (widget));
if (!priv->parent)
g_object_notify_queue_clear (G_OBJECT (widget), nqueue);
g_object_notify_queue_thaw (G_OBJECT (widget), nqueue);
gtk_widget_pop_verify_invariants (widget);
g_object_unref (widget);
}
/**
* gtk_widget_destroy:
* @widget: a #GtkWidget
*
* Destroys a widget.
*
* When a widget is
* destroyed, it will break any references it holds to other objects.
* If the widget is inside a container, the widget will be removed
* from the container. If the widget is a toplevel (derived from
* #GtkWindow), it will be removed from the list of toplevels, and the
* reference GTK+ holds to it will be removed. Removing a
* widget from its container or the list of toplevels results in the
* widget being finalized, unless you've added additional references
* to the widget with g_object_ref().
*
* In most cases, only toplevel widgets (windows) require explicit
* destruction, because when you destroy a toplevel its children will
* be destroyed as well.
**/
void
gtk_widget_destroy (GtkWidget *widget)
{
g_return_if_fail (GTK_IS_WIDGET (widget));
if (!widget->priv->in_destruction)
g_object_run_dispose (G_OBJECT (widget));
}
/**
* gtk_widget_destroyed:
* @widget: a #GtkWidget
* @widget_pointer: (inout) (transfer none): address of a variable that contains @widget
*
* This function sets *@widget_pointer to %NULL if @widget_pointer !=
* %NULL. It's intended to be used as a callback connected to the
* "destroy" signal of a widget. You connect gtk_widget_destroyed()
* as a signal handler, and pass the address of your widget variable
* as user data. Then when the widget is destroyed, the variable will
* be set to %NULL. Useful for example to avoid multiple copies
* of the same dialog.
**/
void
gtk_widget_destroyed (GtkWidget *widget,
GtkWidget **widget_pointer)
{
/* Don't make any assumptions about the
* value of widget!
* Even check widget_pointer.
*/
if (widget_pointer)
*widget_pointer = NULL;
}
/**
* gtk_widget_show:
* @widget: a #GtkWidget
*
* Flags a widget to be displayed. Any widget that isn't shown will
* not appear on the screen. If you want to show all the widgets in a
* container, it's easier to call gtk_widget_show_all() on the
* container, instead of individually showing the widgets.
*
* Remember that you have to show the containers containing a widget,
* in addition to the widget itself, before it will appear onscreen.
*
* When a toplevel container is shown, it is immediately realized and
* mapped; other shown widgets are realized and mapped when their
* toplevel container is realized and mapped.
**/
void
gtk_widget_show (GtkWidget *widget)
{
g_return_if_fail (GTK_IS_WIDGET (widget));
if (!gtk_widget_get_visible (widget))
{
g_object_ref (widget);
gtk_widget_push_verify_invariants (widget);
if (!gtk_widget_is_toplevel (widget))
gtk_widget_queue_resize (widget);
/* see comment in set_parent() for why this should and can be
* conditional
*/
if (widget->priv->need_compute_expand ||
widget->priv->computed_hexpand ||
widget->priv->computed_vexpand)
{
if (widget->priv->parent != NULL)
gtk_widget_queue_compute_expand (widget->priv->parent);
}
g_signal_emit (widget, widget_signals[SHOW], 0);
g_object_notify (G_OBJECT (widget), "visible");
gtk_widget_pop_verify_invariants (widget);
g_object_unref (widget);
}
}
static void
gtk_widget_real_show (GtkWidget *widget)
{
GtkWidgetPrivate *priv = widget->priv;
if (!gtk_widget_get_visible (widget))
{
priv->visible = TRUE;
if (priv->parent &&
gtk_widget_get_mapped (priv->parent) &&
gtk_widget_get_child_visible (widget) &&
!gtk_widget_get_mapped (widget))
gtk_widget_map (widget);
}
}
static void
gtk_widget_show_map_callback (GtkWidget *widget, GdkEvent *event, gint *flag)
{
*flag = TRUE;
g_signal_handlers_disconnect_by_func (widget,
gtk_widget_show_map_callback,
flag);
}
/**
* gtk_widget_show_now:
* @widget: a #GtkWidget
*
* Shows a widget. If the widget is an unmapped toplevel widget
* (i.e. a #GtkWindow that has not yet been shown), enter the main
* loop and wait for the window to actually be mapped. Be careful;
* because the main loop is running, anything can happen during
* this function.
**/
void
gtk_widget_show_now (GtkWidget *widget)
{
gint flag = FALSE;
g_return_if_fail (GTK_IS_WIDGET (widget));
/* make sure we will get event */
if (!gtk_widget_get_mapped (widget) &&
gtk_widget_is_toplevel (widget))
{
gtk_widget_show (widget);
g_signal_connect (widget, "map-event",
G_CALLBACK (gtk_widget_show_map_callback),
&flag);
while (!flag)
gtk_main_iteration ();
}
else
gtk_widget_show (widget);
}
/**
* gtk_widget_hide:
* @widget: a #GtkWidget
*
* Reverses the effects of gtk_widget_show(), causing the widget to be
* hidden (invisible to the user).
**/
void
gtk_widget_hide (GtkWidget *widget)
{
g_return_if_fail (GTK_IS_WIDGET (widget));
if (gtk_widget_get_visible (widget))
{
GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
g_object_ref (widget);
gtk_widget_push_verify_invariants (widget);
if (toplevel != widget && gtk_widget_is_toplevel (toplevel))
_gtk_window_unset_focus_and_default (GTK_WINDOW (toplevel), widget);
/* a parent may now be expand=FALSE since we're hidden. */
if (widget->priv->need_compute_expand ||
widget->priv->computed_hexpand ||
widget->priv->computed_vexpand)
{
gtk_widget_queue_compute_expand (widget);
}
g_signal_emit (widget, widget_signals[HIDE], 0);
if (!gtk_widget_is_toplevel (widget))
gtk_widget_queue_resize (widget);
g_object_notify (G_OBJECT (widget), "visible");
gtk_widget_pop_verify_invariants (widget);
g_object_unref (widget);
}
}
static void
gtk_widget_real_hide (GtkWidget *widget)
{
if (gtk_widget_get_visible (widget))
{
widget->priv->visible = FALSE;
if (gtk_widget_get_mapped (widget))
gtk_widget_unmap (widget);
}
}
/**
* gtk_widget_hide_on_delete:
* @widget: a #GtkWidget
*
* Utility function; intended to be connected to the #GtkWidget::delete-event
* signal on a #GtkWindow. The function calls gtk_widget_hide() on its
* argument, then returns %TRUE. If connected to ::delete-event, the
* result is that clicking the close button for a window (on the
* window frame, top right corner usually) will hide but not destroy
* the window. By default, GTK+ destroys windows when ::delete-event
* is received.
*
* Return value: %TRUE
**/
gboolean
gtk_widget_hide_on_delete (GtkWidget *widget)
{
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
gtk_widget_hide (widget);
return TRUE;
}
/**
* gtk_widget_show_all:
* @widget: a #GtkWidget
*
* Recursively shows a widget, and any child widgets (if the widget is
* a container).
**/
void
gtk_widget_show_all (GtkWidget *widget)
{
GtkWidgetClass *class;
g_return_if_fail (GTK_IS_WIDGET (widget));
if (gtk_widget_get_no_show_all (widget))
return;
class = GTK_WIDGET_GET_CLASS (widget);
if (class->show_all)
class->show_all (widget);
}
static void
_gtk_widget_notify_state_change (GtkWidget *widget,
GtkStateFlags flag,
gboolean target)
{
GtkStateType state;
switch (flag)
{
case GTK_STATE_FLAG_ACTIVE:
state = GTK_STATE_ACTIVE;
break;
case GTK_STATE_FLAG_PRELIGHT:
state = GTK_STATE_PRELIGHT;
break;
case GTK_STATE_FLAG_SELECTED:
state = GTK_STATE_SELECTED;
break;
case GTK_STATE_FLAG_INSENSITIVE:
state = GTK_STATE_INSENSITIVE;
break;
case GTK_STATE_FLAG_INCONSISTENT:
state = GTK_STATE_INCONSISTENT;
break;
case GTK_STATE_FLAG_FOCUSED:
state = GTK_STATE_FOCUSED;
break;
default:
return;
}
gtk_style_context_notify_state_change (widget->priv->context,
gtk_widget_get_window (widget),
NULL, state, target);
}
/* Initializes state transitions for those states that
* were enabled before mapping and have a looping animation.
*/
static void
_gtk_widget_start_state_transitions (GtkWidget *widget)
{
GtkStateFlags state, flag;
if (!widget->priv->context)