* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
+#undef GDK_DISABLE_DEPRECATED /* gdk_input_set_extension_events() */
+
#include "config.h"
#include <stdarg.h>
#include <string.h>
#include "gdk/gdkprivate.h" /* Used in gtk_reset_shapes_recurse to avoid copy */
#include <gobject/gvaluecollector.h>
#include <gobject/gobjectnotifyqueue.c>
+#include <cairo-gobject.h>
#include "gdk/gdkkeysyms.h"
#include "gtkaccessible.h"
#include "gtktooltip.h"
#include "gtkinvisible.h"
#include "gtkbuildable.h"
#include "gtkbuilderprivate.h"
-#include "gtkalias.h"
+#include "gtksizerequest.h"
+
/**
* SECTION:gtkwidget
#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 : 3;
+
+ /* The saved state of the widget. When a widget's state
+ * is changed to GTK_STATE_INSENSITIVE via
+ * "gtk_widget_set_state" or "gtk_widget_set_sensitive"
+ * the old state is kept around in this field. The state
+ * will be restored once the widget gets sensitive again.
+ */
+ guint saved_state : 3;
+
+ /* unused bits in our 32-bit block */
+ guint reserved : 10;
+
+ /* 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;
+
+ /* 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;
+};
enum {
SHOW,
DIRECTION_CHANGED,
GRAB_NOTIFY,
CHILD_NOTIFY,
+ DRAW,
MNEMONIC_ACTIVATE,
GRAB_FOCUS,
FOCUS,
PROP_TOOLTIP_MARKUP,
PROP_TOOLTIP_TEXT,
PROP_WINDOW,
- PROP_DOUBLE_BUFFERED
+ PROP_DOUBLE_BUFFERED,
+ PROP_HALIGN,
+ PROP_VALIGN,
+ PROP_MARGIN_LEFT,
+ PROP_MARGIN_RIGHT,
+ PROP_MARGIN_TOP,
+ PROP_MARGIN_BOTTOM,
+ PROP_MARGIN
};
typedef struct _GtkStateData GtkStateData;
static void gtk_widget_real_size_request (GtkWidget *widget,
GtkRequisition *requisition);
static void gtk_widget_real_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation);
+ GtkAllocation *allocation);
static void gtk_widget_real_style_set (GtkWidget *widget,
GtkStyle *previous_style);
static void gtk_widget_real_direction_changed(GtkWidget *widget,
static void gtk_widget_dispatch_child_properties_changed (GtkWidget *object,
guint n_pspecs,
GParamSpec **pspecs);
+static gboolean gtk_widget_real_expose_event (GtkWidget *widget,
+ GdkEventExpose *event);
static gboolean gtk_widget_real_key_press_event (GtkWidget *widget,
GdkEventKey *event);
static gboolean gtk_widget_real_key_release_event (GtkWidget *widget,
GdkEvent *event);
static gboolean gtk_widget_real_mnemonic_activate (GtkWidget *widget,
gboolean group_cycling);
+static const GtkWidgetAuxInfo* _gtk_widget_get_aux_info_or_defaults (GtkWidget *widget);
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,
- GdkRegion *region);
+ 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,
static void gtk_widget_buildable_parser_finished (GtkBuildable *buildable,
GtkBuilder *builder);
+static void gtk_widget_size_request_init (GtkSizeRequestIface *iface);
+static void gtk_widget_real_get_width (GtkSizeRequest *widget,
+ gint *minimum_size,
+ gint *natural_size);
+static void gtk_widget_real_get_height (GtkSizeRequest *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 for_size,
+ gint *minimum_size,
+ gint *natural_size);
+static void gtk_widget_real_adjust_size_allocation (GtkWidget *widget,
+ GtkAllocation *allocation);
+
static void gtk_widget_set_usize_internal (GtkWidget *widget,
gint width,
gint height);
-static void gtk_widget_get_draw_rectangle (GtkWidget *widget,
- GdkRectangle *rect);
+static void gtk_widget_add_events_internal (GtkWidget *widget,
+ GdkDevice *device,
+ gint events);
/* --- variables --- */
static gpointer gtk_widget_parent_class = NULL;
static guint widget_signals[LAST_SIGNAL] = { 0 };
static GtkStyle *gtk_default_style = NULL;
-static GSList *colormap_stack = 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_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_extension_event_mode = 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_colormap = 0;
static GQuark quark_pango_context = 0;
static GQuark quark_rc_style = 0;
static GQuark quark_accessible_object = 0;
NULL /* interface data */
};
+ const GInterfaceInfo layout_info =
+ {
+ (GInterfaceInitFunc) gtk_widget_size_request_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL /* interface data */
+ };
+
widget_type = g_type_register_static (GTK_TYPE_OBJECT, "GtkWidget",
&widget_info, G_TYPE_FLAG_ABSTRACT);
&accessibility_info) ;
g_type_add_interface_static (widget_type, GTK_TYPE_BUILDABLE,
&buildable_info) ;
-
+ g_type_add_interface_static (widget_type, GTK_TYPE_SIZE_REQUEST,
+ &layout_info) ;
}
return widget_type;
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 (¶m_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)
{
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_extension_event_mode = g_quark_from_static_string ("gtk-extension-event-mode");
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_colormap = g_quark_from_static_string ("gtk-colormap");
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");
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->motion_notify_event = NULL;
klass->delete_event = NULL;
klass->destroy_event = NULL;
- klass->expose_event = NULL;
+ klass->expose_event = gtk_widget_real_expose_event;
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->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_clear_event = _gtk_selection_clear;
klass->selection_request_event = _gtk_selection_request;
klass->selection_notify_event = _gtk_selection_notify;
klass->selection_received = NULL;
klass->no_expose_event = NULL;
+ 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",
/**
* GtkWidget:double-buffered
*
- * Whether or not the widget is double buffered.
+ * Whether the widget is double buffered.
*
* Since: 2.18
*/
PROP_DOUBLE_BUFFERED,
g_param_spec_boolean ("double-buffered",
P_("Double Buffered"),
- P_("Whether or not the widget is 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::show:
* @widget: the object which received the signal.
G_TYPE_NONE, 1,
G_TYPE_PARAM);
+ /**
+ * GtkWidget::draw:
+ * @widget: the object which received the signal
+ * @cr: the cairo context to draw to
+ * @width: width of the widget
+ * @height: height of the widget
+ *
+ * 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 in the given @width and @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.
+ */
+ 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.
/**
* GtkWidget::button-press-event:
* @widget: the object which received the signal.
- * @event: the #GdkEventButton which triggered this 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.
/**
* GtkWidget::button-release-event:
* @widget: the object which received the signal.
- * @event: the #GdkEventButton which triggered this 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.
/**
* GtkWidget::scroll-event:
* @widget: the object which received the signal.
- * @event: the #GdkEventScroll which triggered this 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
/**
* GtkWidget::motion-notify-event:
* @widget: the object which received the signal.
- * @event: the #GdkEventMotion which triggered this 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.
/**
* GtkWidget::expose-event:
* @widget: the object which received the signal.
- * @event: the #GdkEventExpose which triggered this signal
+ * @event: (type Gdk.EventExpose): the #GdkEventExpose which triggered
+ * this signal.
*
* The ::expose-event signal is emitted when an area of a previously
* obscured #GdkWindow is made visible and needs to be redrawn.
/**
* GtkWidget::key-press-event:
* @widget: the object which received the signal
- * @event: the #GdkEventKey which triggered this signal
+ * @event: (type Gdk.EventKey): the #GdkEventKey which triggered this signal.
*
* The ::key-press-event signal is emitted when a key is pressed.
*
/**
* GtkWidget::key-release-event:
* @widget: the object which received the signal
- * @event: the #GdkEventKey which triggered this signal
+ * @event: (type Gdk.EventKey): the #GdkEventKey which triggered this signal.
*
* The ::key-release-event signal is emitted when a key is pressed.
*
/**
* GtkWidget::enter-notify-event:
* @widget: the object which received the signal
- * @event: the #GdkEventCrossing which triggered this 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.
/**
* GtkWidget::leave-notify-event:
* @widget: the object which received the signal
- * @event: the #GdkEventCrossing which triggered this 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.
/**
* GtkWidget::configure-event
* @widget: the object which received the signal
- * @event: the #GdkEventConfigure which triggered this 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.
/**
* GtkWidget::focus-in-event
* @widget: the object which received the signal
- * @event: the #GdkEventFocus which triggered this 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.
/**
* GtkWidget::focus-out-event
* @widget: the object which received the signal
- * @event: the #GdkEventFocus which triggered this 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.
/**
* GtkWidget::map-event
* @widget: the object which received the signal
- * @event: the #GdkEventAny which triggered this 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.
/**
* GtkWidget::unmap-event
* @widget: the object which received the signal
- * @event: the #GdkEventAny which triggered this signal
+ * @event: (type Gdk.EventAny): the #GdkEventAny which triggered this signal
*
- * The ::unmap-event signal will be emitted when the @widget's window is
+ * The ::unmap-event signal may be emitted when the @widget's window is
* unmapped. A window is unmapped when it becomes invisible on the screen.
*
+ * For performance reasons GTK+ may not emit ::unmap-event, so one
+ * should always also implement ::unrealize in order to release
+ * resources and disconnect signal handlers.
+ *
* 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.
/**
* GtkWidget::property-notify-event
* @widget: the object which received the signal
- * @event: the #GdkEventProperty which triggered this 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.
/**
* GtkWidget::selection-clear-event
* @widget: the object which received the signal
- * @event: the #GdkEventSelection which triggered this 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.
/**
* GtkWidget::selection-request-event
* @widget: the object which received the signal
- * @event: the #GdkEventSelection which triggered this 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
/**
* GtkWidget::proximity-in-event
* @widget: the object which received the signal
- * @event: the #GdkEventProximity which triggered this 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.
/**
* GtkWidget::proximity-out-event
* @widget: the object which received the signal
- * @event: the #GdkEventProximity which triggered this 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.
/**
* GtkWidget::visibility-notify-event:
* @widget: the object which received the signal
- * @event: the #GdkEventVisibility which triggered this 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.
/**
* GtkWidget::client-event:
* @widget: the object which received the signal
- * @event: the #GdkEventClient which triggered this signal
+ * @event: (type Gdk.EventClient): the #GdkEventClient which triggered
+ * this signal.
*
* The ::client-event will be emitted when the @widget's window
* receives a message (via a ClientMessage event) from another
/**
* GtkWidget::no-expose-event:
* @widget: the object which received the signal
- * @event: the #GdkEventNoExpose which triggered this signal
+ * @event: (type Gdk.EventNoExpose): the #GdkEventNoExpose which triggered
+ * this signal.
*
* The ::no-expose-event will be emitted when the @widget's window is
- * drawn as a copy of another #GdkDrawable (with gdk_draw_drawable() or
- * gdk_window_copy_area()) which was completely unobscured. If the source
- * window was partially obscured #GdkEventExpose events will be generated
- * for those areas.
+ * drawn as a copy of another #GdkDrawable which was completely unobscured.
+ * If the source window was partially obscured #GdkEventExpose events will
+ * be generated for those areas.
*
* Returns: %TRUE to stop other handlers from being invoked for the event.
* %FALSE to propagate the event further.
/**
* GtkWidget::window-state-event:
* @widget: the object which received the signal
- * @event: the #GdkEventWindowState which triggered this 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.
G_TYPE_BOOLEAN, 1, G_TYPE_UINT);
binding_set = gtk_binding_set_by_class (klass);
- gtk_binding_entry_add_signal (binding_set, GDK_F10, GDK_SHIFT_MASK,
+ gtk_binding_entry_add_signal (binding_set, GDK_KEY_F10, GDK_SHIFT_MASK,
"popup-menu", 0);
- gtk_binding_entry_add_signal (binding_set, GDK_Menu, 0,
+ gtk_binding_entry_add_signal (binding_set, GDK_KEY_Menu, 0,
"popup-menu", 0);
- gtk_binding_entry_add_signal (binding_set, GDK_F1, GDK_CONTROL_MASK,
+ 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_KP_F1, GDK_CONTROL_MASK,
+ 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_F1, GDK_SHIFT_MASK,
+ 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_KP_F1, GDK_SHIFT_MASK,
+ 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);
0.0, 1.0, 0.04,
GTK_PARAM_READABLE));
- /**
- * GtkWidget:draw-border:
- *
- * The "draw-border" style property defines the size of areas outside
- * the widget's allocation to draw.
- *
- * Since: 2.8
- */
gtk_widget_class_install_style_property (klass,
- g_param_spec_boxed ("draw-border",
- P_("Draw Border"),
- P_("Size of areas outside the widget's allocation to draw"),
- GTK_TYPE_BORDER,
- GTK_PARAM_READABLE));
+ 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:
P_("The length of vertical scroll arrows"),
1, G_MAXINT, 16,
GTK_PARAM_READABLE));
+
+ g_type_class_add_private (klass, sizeof (GtkWidgetPrivate));
}
static void
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;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
GParamSpec *pspec)
{
GtkWidget *widget = GTK_WIDGET (object);
-
+ GtkWidgetPrivate *priv = widget->priv;
+
switch (prop_id)
{
gpointer *eventp;
gpointer *modep;
case PROP_NAME:
- if (widget->name)
- g_value_set_string (value, widget->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, widget->parent);
+ g_value_set_object (value, priv->parent);
break;
case PROP_WIDTH_REQUEST:
{
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;
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;
+
GTK_PRIVATE_FLAGS (widget) = PRIVATE_GTK_CHILD_VISIBLE;
- widget->state = GTK_STATE_NORMAL;
- widget->saved_state = GTK_STATE_NORMAL;
- widget->name = NULL;
- widget->requisition.width = 0;
- widget->requisition.height = 0;
- widget->allocation.x = -1;
- widget->allocation.y = -1;
- widget->allocation.width = 1;
- widget->allocation.height = 1;
- widget->window = NULL;
- widget->parent = NULL;
+ priv->state = GTK_STATE_NORMAL;
+ priv->saved_state = GTK_STATE_NORMAL;
+ 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;
GTK_OBJECT_FLAGS (widget) |= GTK_SENSITIVE;
GTK_OBJECT_FLAGS (widget) |= GTK_PARENT_SENSITIVE;
gtk_widget_set_double_buffered (widget, TRUE);
GTK_PRIVATE_SET_FLAG (widget, GTK_REDRAW_ON_ALLOC);
- GTK_PRIVATE_SET_FLAG (widget, GTK_REQUEST_NEEDED);
+ GTK_PRIVATE_SET_FLAG (widget, GTK_WIDTH_REQUEST_NEEDED);
+ GTK_PRIVATE_SET_FLAG (widget, GTK_HEIGHT_REQUEST_NEEDED);
GTK_PRIVATE_SET_FLAG (widget, GTK_ALLOC_NEEDED);
- widget->style = gtk_widget_get_default_style ();
- g_object_ref (widget->style);
+ priv->style = gtk_widget_get_default_style ();
+ g_object_ref (priv->style);
}
guint n_pspecs,
GParamSpec **pspecs)
{
- GtkWidget *container = widget->parent;
+ GtkWidgetPrivate *priv = widget->priv;
+ GtkWidget *container = priv->parent;
guint i;
- for (i = 0; widget->parent == container && i < n_pspecs; 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_child_notify (GtkWidget *widget,
const gchar *child_property)
{
+ GtkWidgetPrivate *priv = widget->priv;
GParamSpec *pspec;
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (child_property != NULL);
- if (!G_OBJECT (widget)->ref_count || !widget->parent)
+ if (!G_OBJECT (widget)->ref_count || !priv->parent)
return;
g_object_ref (widget);
pspec = g_param_spec_pool_lookup (_gtk_widget_child_property_pool,
child_property,
- G_OBJECT_TYPE (widget->parent),
+ G_OBJECT_TYPE (priv->parent),
TRUE);
if (!pspec)
g_warning ("%s: container class `%s' has no child property named `%s'",
G_STRLOC,
- G_OBJECT_TYPE_NAME (widget->parent),
+ G_OBJECT_TYPE_NAME (priv->parent),
child_property);
else
{
return widget;
}
-/**
- * gtk_widget_set:
- * @widget: a #GtkWidget
- * @first_property_name: name of first property to set
- * @Varargs: value of first property, followed by more properties,
- * %NULL-terminated
- *
- * Precursor of g_object_set().
- *
- * Deprecated: 2.0: Use g_object_set() instead.
- **/
-void
-gtk_widget_set (GtkWidget *widget,
- const gchar *first_property_name,
- ...)
-{
- va_list var_args;
-
- g_return_if_fail (GTK_IS_WIDGET (widget));
-
- va_start (var_args, first_property_name);
- g_object_set_valist (G_OBJECT (widget), first_property_name, var_args);
- va_end (var_args);
-}
-
static inline void
gtk_widget_queue_draw_child (GtkWidget *widget)
{
+ GtkWidgetPrivate *priv = widget->priv;
GtkWidget *parent;
- parent = widget->parent;
+ parent = priv->parent;
if (parent && gtk_widget_is_drawable (parent))
gtk_widget_queue_draw_area (parent,
- widget->allocation.x,
- widget->allocation.y,
- widget->allocation.width,
- widget->allocation.height);
+ priv->allocation.x,
+ priv->allocation.y,
+ priv->allocation.width,
+ priv->allocation.height);
}
/**
void
gtk_widget_unparent (GtkWidget *widget)
{
+ GtkWidgetPrivate *priv;
GObjectNotifyQueue *nqueue;
GtkWidget *toplevel;
GtkWidget *old_parent;
g_return_if_fail (GTK_IS_WIDGET (widget));
- if (widget->parent == NULL)
+
+ priv = widget->priv;
+
+ if (priv->parent == NULL)
return;
/* keep this function in sync with gtk_menu_detach()
if (gtk_widget_is_toplevel (toplevel))
_gtk_window_unset_focus_and_default (GTK_WINDOW (toplevel), widget);
- if (GTK_CONTAINER (widget->parent)->focus_child == widget)
- gtk_container_set_focus_child (GTK_CONTAINER (widget->parent), NULL);
+ if (gtk_container_get_focus_child (GTK_CONTAINER (priv->parent)) == widget)
+ gtk_container_set_focus_child (GTK_CONTAINER (priv->parent), NULL);
/* If we are unanchoring the child, we save around the toplevel
* to emit hierarchy changed
*/
- if (GTK_WIDGET_ANCHORED (widget->parent))
+ if (GTK_WIDGET_ANCHORED (priv->parent))
g_object_ref (toplevel);
else
toplevel = NULL;
* allocation is smaller than 1x1 and we actually want a size of 1x1...
* (would 0x0 be OK here?)
*/
- widget->allocation.width = 1;
- widget->allocation.height = 1;
+ priv->allocation.width = 1;
+ priv->allocation.height = 1;
if (gtk_widget_get_realized (widget))
{
*/
GTK_PRIVATE_SET_FLAG (widget, GTK_CHILD_VISIBLE);
- old_parent = widget->parent;
- widget->parent = NULL;
+ old_parent = priv->parent;
+ priv->parent = NULL;
gtk_widget_set_parent_window (widget, NULL);
g_signal_emit (widget, widget_signals[PARENT_SET], 0, old_parent);
if (toplevel)
g_object_notify (G_OBJECT (widget), "parent");
g_object_thaw_notify (G_OBJECT (widget));
- if (!widget->parent)
+ if (!priv->parent)
g_object_notify_queue_clear (G_OBJECT (widget), nqueue);
g_object_notify_queue_thaw (G_OBJECT (widget), nqueue);
g_object_unref (widget);
static void
gtk_widget_real_show (GtkWidget *widget)
{
+ GtkWidgetPrivate *priv = widget->priv;
+
if (!gtk_widget_get_visible (widget))
{
GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
- if (widget->parent &&
- gtk_widget_get_mapped (widget->parent) &&
+ if (priv->parent &&
+ gtk_widget_get_mapped (priv->parent) &&
GTK_WIDGET_CHILD_VISIBLE (widget) &&
!gtk_widget_get_mapped (widget))
gtk_widget_map (widget);
void
gtk_widget_map (GtkWidget *widget)
{
+ GtkWidgetPrivate *priv;
+
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (gtk_widget_get_visible (widget));
g_return_if_fail (GTK_WIDGET_CHILD_VISIBLE (widget));
-
+
+ priv = widget->priv;
+
if (!gtk_widget_get_mapped (widget))
{
if (!gtk_widget_get_realized (widget))
g_signal_emit (widget, widget_signals[MAP], 0);
if (!gtk_widget_get_has_window (widget))
- gdk_window_invalidate_rect (widget->window, &widget->allocation, FALSE);
+ gdk_window_invalidate_rect (priv->window, &priv->allocation, FALSE);
}
}
void
gtk_widget_unmap (GtkWidget *widget)
{
+ GtkWidgetPrivate *priv;
+
g_return_if_fail (GTK_IS_WIDGET (widget));
-
+
+ priv = widget->priv;
+
if (gtk_widget_get_mapped (widget))
{
if (!gtk_widget_get_has_window (widget))
- gdk_window_invalidate_rect (widget->window, &widget->allocation, FALSE);
+ gdk_window_invalidate_rect (priv->window, &priv->allocation, FALSE);
_gtk_tooltip_hide (widget);
g_signal_emit (widget, widget_signals[UNMAP], 0);
}
GdkExtensionMode mode,
GList *window_list)
{
+ GtkWidgetPrivate *priv = widget->priv;
GList *free_list = NULL;
GList *l;
if (window_list == NULL)
{
if (gtk_widget_get_has_window (widget))
- window_list = g_list_prepend (NULL, widget->window);
+ window_list = g_list_prepend (NULL, priv->window);
else
- window_list = gdk_window_get_children (widget->window);
+ window_list = gdk_window_get_children (priv->window);
free_list = window_list;
}
g_list_free (free_list);
}
+static void
+_gtk_widget_enable_device_events (GtkWidget *widget)
+{
+ GHashTable *device_events;
+ GHashTableIter iter;
+ gpointer key, value;
+
+ device_events = g_object_get_qdata (G_OBJECT (widget), quark_device_event_mask);
+
+ if (!device_events)
+ return;
+
+ g_hash_table_iter_init (&iter, device_events);
+
+ while (g_hash_table_iter_next (&iter, &key, &value))
+ {
+ GdkDevice *device;
+ GdkEventMask event_mask;
+
+ device = key;
+ event_mask = GPOINTER_TO_UINT (value);
+ gtk_widget_add_events_internal (widget, device, event_mask);
+ }
+}
+
/**
* gtk_widget_realize:
* @widget: a #GtkWidget
void
gtk_widget_realize (GtkWidget *widget)
{
+ GtkWidgetPrivate *priv;
GdkExtensionMode mode;
- GtkWidgetShapeInfo *shape_info;
+ cairo_region_t *region;
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (GTK_WIDGET_ANCHORED (widget) ||
GTK_IS_INVISIBLE (widget));
-
+
+ priv = widget->priv;
+
if (!gtk_widget_get_realized (widget))
{
/*
g_message ("gtk_widget_realize(%s)", G_OBJECT_TYPE_NAME (widget));
*/
- if (widget->parent == NULL &&
+ if (priv->parent == NULL &&
!gtk_widget_is_toplevel (widget))
g_warning ("Calling gtk_widget_realize() on a widget that isn't "
"inside a toplevel window is not going to work very well. "
"Widgets must be inside a toplevel container before realizing them.");
- if (widget->parent && !gtk_widget_get_realized (widget->parent))
- gtk_widget_realize (widget->parent);
+ if (priv->parent && !gtk_widget_get_realized (priv->parent))
+ gtk_widget_realize (priv->parent);
gtk_widget_ensure_style (widget);
if (GTK_WIDGET_HAS_SHAPE_MASK (widget))
{
- shape_info = g_object_get_qdata (G_OBJECT (widget), quark_shape_info);
- gdk_window_shape_combine_mask (widget->window,
- shape_info->shape_mask,
- shape_info->offset_x,
- shape_info->offset_y);
+ region = g_object_get_qdata (G_OBJECT (widget), quark_shape_info);
+ gdk_window_shape_combine_region (priv->window, region, 0, 0);
}
- shape_info = g_object_get_qdata (G_OBJECT (widget), quark_input_shape_info);
- if (shape_info)
- gdk_window_input_shape_combine_mask (widget->window,
- shape_info->shape_mask,
- shape_info->offset_x,
- shape_info->offset_y);
+ region = g_object_get_qdata (G_OBJECT (widget), quark_input_shape_info);
+ if (region)
+ gdk_window_input_shape_combine_region (priv->window, region, 0, 0);
mode = gtk_widget_get_extension_events (widget);
if (mode != GDK_EXTENSION_EVENTS_NONE)
gtk_widget_set_extension_events_internal (widget, mode, NULL);
+
+ if ((GTK_WIDGET_FLAGS (widget) & GTK_MULTIDEVICE) != 0)
+ gdk_window_set_support_multidevice (priv->window, TRUE);
+
+ _gtk_widget_enable_device_events (widget);
}
}
g_return_if_fail (GTK_IS_WIDGET (widget));
if (GTK_WIDGET_HAS_SHAPE_MASK (widget))
- gtk_widget_shape_combine_mask (widget, NULL, 0, 0);
+ gtk_widget_shape_combine_region (widget, NULL);
if (g_object_get_qdata (G_OBJECT (widget), quark_input_shape_info))
- gtk_widget_input_shape_combine_mask (widget, NULL, 0, 0);
+ gtk_widget_input_shape_combine_region (widget, NULL);
if (gtk_widget_get_realized (widget))
{
gint width,
gint height)
{
+ GtkWidgetPrivate *priv;
GdkRectangle invalid_rect;
GtkWidget *w;
g_return_if_fail (GTK_IS_WIDGET (widget));
+ priv = widget->priv;
+
if (!gtk_widget_get_realized (widget))
return;
/* Just return if the widget or one of its ancestors isn't mapped */
- for (w = widget; w != NULL; w = w->parent)
+ for (w = widget; w != NULL; w = w->priv->parent)
if (!gtk_widget_get_mapped (w))
return;
if (gtk_widget_get_has_window (widget))
{
- if (widget->parent)
+ if (priv->parent)
{
/* Translate widget relative to window-relative */
gint wx, wy, wwidth, wheight;
-
- gdk_window_get_position (widget->window, &wx, &wy);
- x -= wx - widget->allocation.x;
- y -= wy - widget->allocation.y;
-
- gdk_drawable_get_size (widget->window, &wwidth, &wheight);
+
+ gdk_window_get_position (priv->window, &wx, &wy);
+ x -= wx - priv->allocation.x;
+ y -= wy - priv->allocation.y;
+
+ gdk_drawable_get_size (priv->window, &wwidth, &wheight);
if (x + width <= 0 || y + height <= 0 ||
x >= wwidth || y >= wheight)
invalid_rect.width = width;
invalid_rect.height = height;
- gdk_window_invalidate_rect (widget->window, &invalid_rect, TRUE);
-}
-
-static void
-widget_add_child_draw_rectangle (GtkWidget *widget,
- GdkRectangle *rect)
-{
- GdkRectangle child_rect;
-
- if (!gtk_widget_get_mapped (widget) ||
- widget->window != widget->parent->window)
- return;
-
- gtk_widget_get_draw_rectangle (widget, &child_rect);
- gdk_rectangle_union (rect, &child_rect, rect);
-}
-
-static void
-gtk_widget_get_draw_rectangle (GtkWidget *widget,
- GdkRectangle *rect)
-{
- if (!gtk_widget_get_has_window (widget))
- {
- GtkBorder *draw_border = NULL;
-
- *rect = widget->allocation;
-
- gtk_widget_style_get (widget,
- "draw-border", &draw_border,
- NULL);
- if (draw_border)
- {
- rect->x -= draw_border->left;
- rect->y -= draw_border->top;
- rect->width += draw_border->left + draw_border->right;
- rect->height += draw_border->top + draw_border->bottom;
-
- gtk_border_free (draw_border);
- }
-
- if (GTK_IS_CONTAINER (widget))
- gtk_container_forall (GTK_CONTAINER (widget),
- (GtkCallback)widget_add_child_draw_rectangle,
- rect);
- }
- else
- {
- rect->x = 0;
- rect->y = 0;
- rect->width = widget->allocation.width;
- rect->height = widget->allocation.height;
- }
+ gdk_window_invalidate_rect (priv->window, &invalid_rect, TRUE);
}
/**
g_return_if_fail (GTK_IS_WIDGET (widget));
- gtk_widget_get_draw_rectangle (widget, &rect);
-
- gtk_widget_queue_draw_area (widget,
- rect.x, rect.y,
- rect.width, rect.height);
-}
-
-/* Invalidates the given area (allocation-relative-coordinates)
- * in all of the widget's windows
- */
-/**
- * gtk_widget_queue_clear_area:
- * @widget: a #GtkWidget
- * @x: x coordinate of upper-left corner of rectangle to redraw
- * @y: y coordinate of upper-left corner of rectangle to redraw
- * @width: width of region to draw
- * @height: height of region to draw
- *
- * This function is no longer different from
- * gtk_widget_queue_draw_area(), though it once was. Now it just calls
- * gtk_widget_queue_draw_area(). Originally
- * gtk_widget_queue_clear_area() would force a redraw of the
- * background for %GTK_NO_WINDOW widgets, and
- * gtk_widget_queue_draw_area() would not. Now both functions ensure
- * the background will be redrawn.
- *
- * Deprecated: 2.2: Use gtk_widget_queue_draw_area() instead.
- **/
-void
-gtk_widget_queue_clear_area (GtkWidget *widget,
- gint x,
- gint y,
- gint width,
- gint height)
-{
- g_return_if_fail (GTK_IS_WIDGET (widget));
-
- gtk_widget_queue_draw_area (widget, x, y, width, height);
-}
-
-/**
- * gtk_widget_queue_clear:
- * @widget: a #GtkWidget
- *
- * This function does the same as gtk_widget_queue_draw().
- *
- * Deprecated: 2.2: Use gtk_widget_queue_draw() instead.
- **/
-void
-gtk_widget_queue_clear (GtkWidget *widget)
-{
- g_return_if_fail (GTK_IS_WIDGET (widget));
+ gtk_widget_get_allocation (widget, &rect);
- gtk_widget_queue_draw (widget);
+ if (!gtk_widget_get_has_window (widget))
+ gtk_widget_queue_draw_area (widget,
+ rect.x, rect.y, rect.width, rect.height);
+ else
+ gtk_widget_queue_draw_area (widget,
+ 0, 0, rect.width, rect.height);
}
/**
_gtk_size_group_queue_resize (widget);
}
-/**
- * gtk_widget_draw:
- * @widget: a #GtkWidget
- * @area: area to draw
- *
- * In GTK+ 1.2, this function would immediately render the
- * region @area of a widget, by invoking the virtual draw method of a
- * widget. In GTK+ 2.0, the draw method is gone, and instead
- * gtk_widget_draw() simply invalidates the specified region of the
- * widget, then updates the invalid region of the widget immediately.
- * Usually you don't want to update the region immediately for
- * performance reasons, so in general gtk_widget_queue_draw_area() is
- * a better choice if you want to draw a region of a widget.
- **/
-void
-gtk_widget_draw (GtkWidget *widget,
- const GdkRectangle *area)
-{
- g_return_if_fail (GTK_IS_WIDGET (widget));
-
- if (gtk_widget_is_drawable (widget))
- {
- if (area)
- gtk_widget_queue_draw_area (widget,
- area->x, area->y,
- area->width, area->height);
- else
- gtk_widget_queue_draw (widget);
-
- gdk_window_process_updates (widget->window, TRUE);
- }
-}
-
/**
* gtk_widget_size_request:
* @widget: a #GtkWidget
- * @requisition: a #GtkRequisition to be filled in
+ * @requisition: (out): a #GtkRequisition to be filled in
*
* This function is typically used when implementing a #GtkContainer
* subclass. Obtains the preferred size of a widget. The container
* Also remember that the size request is not necessarily the size
* a widget will actually be allocated.
*
- * See also gtk_widget_get_child_requisition().
+ * Deprecated: 3.0: Use gtk_size_request_get_size() instead.
**/
void
gtk_widget_size_request (GtkWidget *widget,
{
g_return_if_fail (GTK_IS_WIDGET (widget));
-#ifdef G_ENABLE_DEBUG
- if (requisition == &widget->requisition)
- g_warning ("gtk_widget_size_request() called on child widget with request equal\n to widget->requisition. gtk_widget_set_usize() may not work properly.");
-#endif /* G_ENABLE_DEBUG */
-
- _gtk_size_group_compute_requisition (widget, requisition);
+ gtk_size_request_get_size (GTK_SIZE_REQUEST (widget), requisition, NULL);
}
/**
* gtk_widget_get_child_requisition:
* @widget: a #GtkWidget
- * @requisition: a #GtkRequisition to be filled in
+ * @requisition: (out): a #GtkRequisition to be filled in
*
* This function is only for use in widget implementations. Obtains
* @widget->requisition, unless someone has forced a particular
* since the last time a resize was queued. In general, only container
* implementations have this information; applications should use
* gtk_widget_size_request().
+ *
+ *
+ * Deprecated: 3.0: Use gtk_size_request_get_size() instead.
**/
void
gtk_widget_get_child_requisition (GtkWidget *widget,
GtkRequisition *requisition)
{
- _gtk_size_group_get_child_requisition (widget, requisition);
+ gtk_size_request_get_size (GTK_SIZE_REQUEST (widget), requisition, NULL);
}
static gboolean
*/
static void
gtk_widget_invalidate_widget_windows (GtkWidget *widget,
- GdkRegion *region)
+ cairo_region_t *region)
{
+ GtkWidgetPrivate *priv = widget->priv;
+
if (!gtk_widget_get_realized (widget))
return;
- if (gtk_widget_get_has_window (widget) && widget->parent)
+ if (gtk_widget_get_has_window (widget) && priv->parent)
{
int x, y;
-
- gdk_window_get_position (widget->window, &x, &y);
- gdk_region_offset (region, -x, -y);
+
+ gdk_window_get_position (priv->window, &x, &y);
+ cairo_region_translate (region, -x, -y);
}
- gdk_window_invalidate_maybe_recurse (widget->window, region,
+ gdk_window_invalidate_maybe_recurse (priv->window, region,
invalidate_predicate, widget);
}
gtk_widget_queue_shallow_draw (GtkWidget *widget)
{
GdkRectangle rect;
- GdkRegion *region;
-
+ cairo_region_t *region;
+
if (!gtk_widget_get_realized (widget))
return;
- gtk_widget_get_draw_rectangle (widget, &rect);
+ gtk_widget_get_allocation (widget, &rect);
- /* get_draw_rectangle() gives us window coordinates, we
- * need to convert to the coordinates that widget->allocation
- * is in.
- */
- if (gtk_widget_get_has_window (widget) && widget->parent)
- {
- int wx, wy;
-
- gdk_window_get_position (widget->window, &wx, &wy);
-
- rect.x += wx;
- rect.y += wy;
- }
-
- region = gdk_region_rectangle (&rect);
+ region = cairo_region_create_rectangle (&rect);
gtk_widget_invalidate_widget_windows (widget, region);
- gdk_region_destroy (region);
+ cairo_region_destroy (region);
}
/**
* gtk_widget_size_allocate:
* @widget: a #GtkWidget
- * @allocation: position and size to be allocated to @widget
+ * @allocation: (inout): position and size to be allocated to @widget
*
* This function is only used by #GtkContainer subclasses, to assign a size
- * and position to their child widgets.
+ * and position to their child widgets.
+ *
+ * In this function, the allocation may be adjusted. It will be forced
+ * to a 1x1 minimum size, and the adjust_size_allocation virtual
+ * method on the child will be used to adjust the allocation. Standard
+ * adjustments include removing the widget's margins, and applying the
+ * widget's #GtkWidget:halign and #GtkWidget:valign properties.
**/
void
gtk_widget_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
- GtkWidgetAuxInfo *aux_info;
+ GtkWidgetPrivate *priv;
GdkRectangle real_allocation;
GdkRectangle old_allocation;
+ GdkRectangle adjusted_allocation;
gboolean alloc_needed;
gboolean size_changed;
gboolean position_changed;
-
+
+ priv = widget->priv;
+
g_return_if_fail (GTK_IS_WIDGET (widget));
#ifdef G_ENABLE_DEBUG
- if (gtk_debug_flags & GTK_DEBUG_GEOMETRY)
+ if (gtk_get_debug_flags () & GTK_DEBUG_GEOMETRY)
{
gint depth;
GtkWidget *parent;
#endif /* G_ENABLE_DEBUG */
alloc_needed = GTK_WIDGET_ALLOC_NEEDED (widget);
- if (!GTK_WIDGET_REQUEST_NEEDED (widget)) /* Preserve request/allocate ordering */
+ if (!GTK_WIDGET_WIDTH_REQUEST_NEEDED (widget) &&
+ !GTK_WIDGET_HEIGHT_REQUEST_NEEDED (widget)) /* Preserve request/allocate ordering */
GTK_PRIVATE_UNSET_FLAG (widget, GTK_ALLOC_NEEDED);
- old_allocation = widget->allocation;
+ old_allocation = priv->allocation;
real_allocation = *allocation;
- aux_info =_gtk_widget_get_aux_info (widget, FALSE);
-
- if (aux_info)
+
+ adjusted_allocation = real_allocation;
+ GTK_WIDGET_GET_CLASS (widget)->adjust_size_allocation (widget, &adjusted_allocation);
+
+ if (adjusted_allocation.x < real_allocation.x ||
+ adjusted_allocation.y < real_allocation.y ||
+ (adjusted_allocation.x + adjusted_allocation.width) >
+ (real_allocation.x + real_allocation.width) ||
+ (adjusted_allocation.y + adjusted_allocation.height >
+ real_allocation.y + real_allocation.height))
+ {
+ g_warning ("%s %p attempted to adjust its size allocation from %d,%d %dx%d to %d,%d %dx%d. adjust_size_allocation must keep allocation inside original bounds",
+ G_OBJECT_TYPE_NAME (widget), widget,
+ real_allocation.x, real_allocation.y, real_allocation.width, real_allocation.height,
+ adjusted_allocation.x, adjusted_allocation.y, adjusted_allocation.width, adjusted_allocation.height);
+ adjusted_allocation = real_allocation; /* veto it */
+ }
+ else
{
- if (aux_info->x_set)
- real_allocation.x = aux_info->x;
- if (aux_info->y_set)
- real_allocation.y = aux_info->y;
+ real_allocation = adjusted_allocation;
}
if (real_allocation.width < 0 || real_allocation.height < 0)
{
if (!gtk_widget_get_has_window (widget) && GTK_WIDGET_REDRAW_ON_ALLOC (widget) && position_changed)
{
- /* Invalidate union(old_allaction,widget->allocation) in widget->window
+ /* Invalidate union(old_allaction,priv->allocation) in priv->window
*/
- GdkRegion *invalidate = gdk_region_rectangle (&widget->allocation);
- gdk_region_union_with_rect (invalidate, &old_allocation);
+ cairo_region_t *invalidate = cairo_region_create_rectangle (&priv->allocation);
+ cairo_region_union_rectangle (invalidate, &old_allocation);
- gdk_window_invalidate_region (widget->window, invalidate, FALSE);
- gdk_region_destroy (invalidate);
+ gdk_window_invalidate_region (priv->window, invalidate, FALSE);
+ cairo_region_destroy (invalidate);
}
if (size_changed)
{
if (GTK_WIDGET_REDRAW_ON_ALLOC (widget))
{
- /* Invalidate union(old_allaction,widget->allocation) in widget->window and descendents owned by widget
+ /* Invalidate union(old_allaction,priv->allocation) in priv->window and descendents owned by widget
*/
- GdkRegion *invalidate = gdk_region_rectangle (&widget->allocation);
- gdk_region_union_with_rect (invalidate, &old_allocation);
+ cairo_region_t *invalidate = cairo_region_create_rectangle (&priv->allocation);
+ cairo_region_union_rectangle (invalidate, &old_allocation);
gtk_widget_invalidate_widget_windows (widget, invalidate);
- gdk_region_destroy (invalidate);
+ cairo_region_destroy (invalidate);
}
}
}
- if ((size_changed || position_changed) && widget->parent &&
- gtk_widget_get_realized (widget->parent) && GTK_CONTAINER (widget->parent)->reallocate_redraws)
+ if ((size_changed || position_changed) && priv->parent &&
+ gtk_widget_get_realized (priv->parent) && _gtk_container_get_reallocate_redraws (GTK_CONTAINER (priv->parent)))
{
- GdkRegion *invalidate = gdk_region_rectangle (&widget->parent->allocation);
- gtk_widget_invalidate_widget_windows (widget->parent, invalidate);
- gdk_region_destroy (invalidate);
+ cairo_region_t *invalidate = cairo_region_create_rectangle (&priv->parent->priv->allocation);
+ gtk_widget_invalidate_widget_windows (priv->parent, invalidate);
+ cairo_region_destroy (invalidate);
}
}
gint depth_b = 0;
parent_a = widget_a;
- while (parent_a->parent)
+ while (parent_a->priv->parent)
{
- parent_a = parent_a->parent;
+ parent_a = parent_a->priv->parent;
depth_a++;
}
parent_b = widget_b;
- while (parent_b->parent)
+ while (parent_b->priv->parent)
{
- parent_b = parent_b->parent;
+ parent_b = parent_b->priv->parent;
depth_b++;
}
while (depth_a > depth_b)
{
- widget_a = widget_a->parent;
+ widget_a = widget_a->priv->parent;
depth_a--;
}
while (depth_b > depth_a)
{
- widget_b = widget_b->parent;
+ widget_b = widget_b->priv->parent;
depth_b--;
}
while (widget_a != widget_b)
{
- widget_a = widget_a->parent;
- widget_b = widget_b->parent;
+ widget_a = widget_a->priv->parent;
+ widget_b = widget_b->priv->parent;
}
return widget_a;
gint *dest_x,
gint *dest_y)
{
+ GtkWidgetPrivate *src_priv = src_widget->priv;
+ GtkWidgetPrivate *dest_priv = dest_widget->priv;
GtkWidget *ancestor;
GdkWindow *window;
GList *dest_list = NULL;
return FALSE;
/* Translate from allocation relative to window relative */
- if (gtk_widget_get_has_window (src_widget) && src_widget->parent)
+ if (gtk_widget_get_has_window (src_widget) && src_priv->parent)
{
gint wx, wy;
- gdk_window_get_position (src_widget->window, &wx, &wy);
+ gdk_window_get_position (src_priv->window, &wx, &wy);
- src_x -= wx - src_widget->allocation.x;
- src_y -= wy - src_widget->allocation.y;
+ src_x -= wx - src_priv->allocation.x;
+ src_y -= wy - src_priv->allocation.y;
}
else
{
- src_x += src_widget->allocation.x;
- src_y += src_widget->allocation.y;
+ src_x += src_priv->allocation.x;
+ src_y += src_priv->allocation.y;
}
/* Translate to the common ancestor */
- window = src_widget->window;
- while (window != ancestor->window)
+ window = src_priv->window;
+ while (window != ancestor->priv->window)
{
gdouble dx, dy;
}
/* And back */
- window = dest_widget->window;
- while (window != ancestor->window)
+ window = dest_priv->window;
+ while (window != ancestor->priv->window)
{
dest_list = g_list_prepend (dest_list, window);
}
/* Translate from window relative to allocation relative */
- if (gtk_widget_get_has_window (dest_widget) && dest_widget->parent)
+ if (gtk_widget_get_has_window (dest_widget) && dest_priv->parent)
{
gint wx, wy;
- gdk_window_get_position (dest_widget->window, &wx, &wy);
+ gdk_window_get_position (dest_priv->window, &wx, &wy);
- src_x += wx - dest_widget->allocation.x;
- src_y += wy - dest_widget->allocation.y;
+ src_x += wx - dest_priv->allocation.x;
+ src_y += wy - dest_priv->allocation.y;
}
else
{
- src_x -= dest_widget->allocation.x;
- src_y -= dest_widget->allocation.y;
+ src_x -= dest_priv->allocation.x;
+ src_y -= dest_priv->allocation.y;
}
if (dest_x)
gtk_widget_real_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
- widget->allocation = *allocation;
-
+ GtkWidgetPrivate *priv = widget->priv;
+
+ priv->allocation = *allocation;
+
if (gtk_widget_get_realized (widget) &&
gtk_widget_get_has_window (widget))
{
- gdk_window_move_resize (widget->window,
+ gdk_window_move_resize (priv->window,
allocation->x, allocation->y,
allocation->width, allocation->height);
}
}
+static void
+get_span_inside_border (GtkWidget *widget,
+ GtkAlign align,
+ int start_pad,
+ int end_pad,
+ int allocated_outside_size,
+ int natural_inside_size,
+ int *coord_inside_p,
+ int *size_inside_p)
+{
+ int inside_allocated;
+ int content_size;
+ int coord, size;
+
+ inside_allocated = allocated_outside_size - start_pad - end_pad;
+
+ content_size = natural_inside_size;
+ if (content_size > inside_allocated)
+ {
+ /* didn't get full natural size */
+ content_size = inside_allocated;
+ }
+
+ coord = size = 0; /* silence compiler */
+ switch (align)
+ {
+ case GTK_ALIGN_FILL:
+ coord = start_pad;
+ size = inside_allocated;
+ break;
+ case GTK_ALIGN_START:
+ coord = start_pad;
+ size = content_size;
+ break;
+ case GTK_ALIGN_END:
+ coord = allocated_outside_size - end_pad - content_size;
+ size = content_size;
+ break;
+ case GTK_ALIGN_CENTER:
+ coord = start_pad + (inside_allocated - content_size) / 2;
+ size = content_size;
+ break;
+ }
+
+ if (coord_inside_p)
+ *coord_inside_p = coord;
+
+ if (size_inside_p)
+ *size_inside_p = size;
+}
+
+static void
+get_span_inside_border_horizontal (GtkWidget *widget,
+ const GtkWidgetAuxInfo *aux_info,
+ int allocated_outside_width,
+ int natural_inside_width,
+ int *x_inside_p,
+ int *width_inside_p)
+{
+ get_span_inside_border (widget,
+ aux_info->halign,
+ aux_info->margin.left,
+ aux_info->margin.right,
+ allocated_outside_width,
+ natural_inside_width,
+ x_inside_p,
+ width_inside_p);
+}
+
+static void
+get_span_inside_border_vertical (GtkWidget *widget,
+ const GtkWidgetAuxInfo *aux_info,
+ int allocated_outside_height,
+ int natural_inside_height,
+ int *y_inside_p,
+ int *height_inside_p)
+{
+ get_span_inside_border (widget,
+ aux_info->valign,
+ aux_info->margin.top,
+ aux_info->margin.bottom,
+ allocated_outside_height,
+ natural_inside_height,
+ y_inside_p,
+ height_inside_p);
+}
+
+static void
+gtk_widget_real_adjust_size_allocation (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ const GtkWidgetAuxInfo *aux_info;
+ GtkRequisition min, natural;
+ int x, y, w, h;
+
+ aux_info = _gtk_widget_get_aux_info_or_defaults (widget);
+
+ gtk_size_request_get_size (GTK_SIZE_REQUEST (widget), &min, &natural);
+
+ get_span_inside_border_horizontal (widget,
+ aux_info,
+ allocation->width,
+ natural.width,
+ &x, &w);
+ get_span_inside_border_vertical (widget,
+ aux_info,
+ allocation->height,
+ natural.height,
+ &y, &h);
+
+ allocation->x += x;
+ allocation->y += y;
+ allocation->width = w;
+ allocation->height = h;
+}
+
static gboolean
gtk_widget_real_can_activate_accel (GtkWidget *widget,
guint signal_id)
{
+ GtkWidgetPrivate *priv = widget->priv;
+
/* widgets must be onscreen for accels to take effect */
return gtk_widget_is_sensitive (widget) &&
gtk_widget_is_drawable (widget) &&
- gdk_window_is_viewable (widget->window);
+ gdk_window_is_viewable (priv->window);
}
/**
}
/**
- * gtk_widget_list_accel_closures
+ * gtk_widget_list_accel_closures:
* @widget: widget to list accelerator closures for
- * @returns: a newly allocated #GList of closures
*
* Lists the closures used by @widget for accelerator group connections
* with gtk_accel_group_connect_by_path() or gtk_accel_group_connect().
* The closures can be used to monitor accelerator changes on @widget,
- * by connecting to the @GtkAccelGroup::accel-changed signal of the
- * #GtkAccelGroup of a closure which can be found out with
+ * by connecting to the @GtkAccelGroup::accel-changed signal of the
+ * #GtkAccelGroup of a closure which can be found out with
* gtk_accel_group_from_accel_closure().
+ *
+ * Return value: (transfer container) (element-type GClosure):
+ * a newly allocated #GList of closures
*/
GList*
gtk_widget_list_accel_closures (GtkWidget *widget)
apath = g_object_get_qdata (G_OBJECT (widget), quark_accel_path);
if (locked)
- *locked = apath ? apath->accel_group->lock_count > 0 : TRUE;
+ *locked = apath ? gtk_accel_group_get_is_locked (apath->accel_group) : TRUE;
return apath ? g_quark_to_string (apath->path_quark) : NULL;
}
return TRUE;
}
+static const cairo_user_data_key_t window_key;
+
+static GdkWindow *
+gtk_cairo_get_window (cairo_t *cr)
+{
+ g_return_val_if_fail (cr != NULL, NULL);
+
+ return cairo_get_user_data (cr, &window_key);
+}
+
+/**
+ * gtk_cairo_should_draw_window:
+ * @cr: a cairo context
+ * @window: the window to check
+ *
+ * This function is supposed to be called in GtkWidget::draw
+ * implementations for widgets that support multiple windows.
+ * @cr must be untransformed from invoking of the draw function.
+ * This function will return %TRUE if the contents of the given
+ * @window are supposed to be drawn and %FALSE otherwise. Note
+ * that when the drawing was not initiated by the windowing
+ * system this function will return %TRUE for all windows, so
+ * you need to draw the bottommost window first. Also, do not
+ * use "else if" statements to check which window should be drawn.
+ *
+ * Returns: %TRUE if @window should be drawn
+ **/
+gboolean
+gtk_cairo_should_draw_window (cairo_t *cr,
+ GdkWindow *window)
+{
+ GdkWindow *cairo_window;
+
+ g_return_val_if_fail (cr != NULL, FALSE);
+ g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
+
+ cairo_window = gtk_cairo_get_window (cr);
+
+ return cairo_window == NULL ||
+ cairo_window == window;
+}
+
+static void
+gtk_cairo_set_window (cairo_t *cr,
+ GdkWindow *window)
+{
+ cairo_set_user_data (cr, &window_key, window, NULL);
+}
+static gboolean
+gtk_widget_real_expose_event (GtkWidget *widget,
+ GdkEventExpose *expose)
+{
+ GdkWindow *window;
+ gboolean result = FALSE;
+ cairo_t *cr;
+
+ if (!gtk_widget_is_drawable (widget))
+ return FALSE;
+
+ cr = gdk_cairo_create (expose->window);
+ gtk_cairo_set_window (cr, expose->window);
+
+ gdk_cairo_region (cr, expose->region);
+ cairo_clip (cr);
+
+ /* translate cairo context properly */
+ window = gtk_widget_get_window (widget);
+ if (window != expose->window)
+ {
+ int x, y;
+
+ if (gdk_window_get_parent (expose->window) == window)
+ {
+ gdk_window_get_position (expose->window, &x, &y);
+ }
+ else
+ {
+ int ex, ey;
+ gdk_window_get_origin (expose->window, &ex, &ey);
+ gdk_window_get_origin (window, &x, &y);
+ x = ex - x;
+ y = ey - y;
+ }
+
+ cairo_translate (cr, -x, -y);
+ }
+
+
+ if (!gtk_widget_get_has_window (widget))
+ {
+ cairo_translate (cr,
+ widget->priv->allocation.x,
+ widget->priv->allocation.y);
+ }
+
+ g_signal_emit (widget, widget_signals[DRAW],
+ 0, cr,
+ &result);
+
+ /* unset here, so if someone keeps a reference to cr we
+ * don't leak the window. */
+ gtk_cairo_set_window (cr, NULL);
+ cairo_destroy (cr);
+
+ return result;
+}
+
static gboolean
gtk_widget_real_key_press_event (GtkWidget *widget,
GdkEventKey *event)
static gboolean
event_window_is_still_viewable (GdkEvent *event)
{
- /* Some programs, such as gnome-theme-manager, fake widgets
- * into exposing onto a pixmap by sending expose events with
- * event->window pointing to a pixmap
- */
- if (GDK_IS_PIXMAP (event->any.window))
- return event->type == GDK_EXPOSE;
-
/* Check that we think the event's window is viewable before
* delivering the event, to prevent suprises. We do this here
* at the last moment, since the event may have been queued
gtk_widget_reparent_subwindows (GtkWidget *widget,
GdkWindow *new_window)
{
+ GtkWidgetPrivate *priv = widget->priv;
+
if (!gtk_widget_get_has_window (widget))
{
- GList *children = gdk_window_get_children (widget->window);
+ GList *children = gdk_window_get_children (priv->window);
GList *tmp_list;
for (tmp_list = children; tmp_list; tmp_list = tmp_list->next)
gdk_window_get_user_data (window, &child);
while (child && child != widget)
- child = ((GtkWidget*) child)->parent;
+ child = ((GtkWidget*) child)->priv->parent;
if (child)
gdk_window_reparent (window, new_window, 0, 0);
GdkWindow *parent;
GList *tmp_list, *children;
- parent = gdk_window_get_parent (widget->window);
+ parent = gdk_window_get_parent (priv->window);
if (parent == NULL)
- gdk_window_reparent (widget->window, new_window, 0, 0);
+ gdk_window_reparent (priv->window, new_window, 0, 0);
else
{
children = gdk_window_get_children (parent);
gtk_widget_reparent_fixup_child (GtkWidget *widget,
gpointer client_data)
{
+ GtkWidgetPrivate *priv = widget->priv;
+
g_assert (client_data != NULL);
if (!gtk_widget_get_has_window (widget))
{
- if (widget->window)
- g_object_unref (widget->window);
- widget->window = (GdkWindow*) client_data;
- if (widget->window)
- g_object_ref (widget->window);
+ if (priv->window)
+ g_object_unref (priv->window);
+ priv->window = (GdkWindow*) client_data;
+ if (priv->window)
+ g_object_ref (priv->window);
if (GTK_IS_CONTAINER (widget))
gtk_container_forall (GTK_CONTAINER (widget),
gtk_widget_reparent (GtkWidget *widget,
GtkWidget *new_parent)
{
+ GtkWidgetPrivate *priv;
+
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (GTK_IS_CONTAINER (new_parent));
- g_return_if_fail (widget->parent != NULL);
-
- if (widget->parent != new_parent)
+ priv = widget->priv;
+ g_return_if_fail (priv->parent != NULL);
+
+ if (priv->parent != new_parent)
{
/* First try to see if we can get away without unrealizing
* the widget as we reparent it. if so we set a flag so
GTK_PRIVATE_SET_FLAG (widget, GTK_IN_REPARENT);
g_object_ref (widget);
- gtk_container_remove (GTK_CONTAINER (widget->parent), widget);
+ gtk_container_remove (GTK_CONTAINER (priv->parent), widget);
gtk_container_add (GTK_CONTAINER (new_parent), widget);
g_object_unref (widget);
const GdkRectangle *area,
GdkRectangle *intersection)
{
+ GtkWidgetPrivate *priv;
GdkRectangle *dest;
GdkRectangle tmp;
gint return_val;
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
g_return_val_if_fail (area != NULL, FALSE);
-
+
+ priv = widget->priv;
+
if (intersection)
dest = intersection;
else
dest = &tmp;
- return_val = gdk_rectangle_intersect (&widget->allocation, area, dest);
+ return_val = gdk_rectangle_intersect (&priv->allocation, area, dest);
if (return_val && intersection && gtk_widget_get_has_window (widget))
{
- intersection->x -= widget->allocation.x;
- intersection->y -= widget->allocation.y;
+ intersection->x -= priv->allocation.x;
+ intersection->y -= priv->allocation.y;
}
return return_val;
/**
* gtk_widget_region_intersect:
* @widget: a #GtkWidget
- * @region: a #GdkRegion, in the same coordinate system as
+ * @region: a #cairo_region_t, in the same coordinate system as
* @widget->allocation. That is, relative to @widget->window
* for %NO_WINDOW widgets; relative to the parent window
* of @widget->window for widgets with their own window.
* widgets with their own window.
*
* Computes the intersection of a @widget's area and @region, returning
- * the intersection. The result may be empty, use gdk_region_empty() to
+ * the intersection. The result may be empty, use cairo_region_is_empty() to
* check.
**/
-GdkRegion *
+cairo_region_t *
gtk_widget_region_intersect (GtkWidget *widget,
- const GdkRegion *region)
+ const cairo_region_t *region)
{
GdkRectangle rect;
- GdkRegion *dest;
+ cairo_region_t *dest;
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
g_return_val_if_fail (region != NULL, NULL);
- gtk_widget_get_draw_rectangle (widget, &rect);
+ gtk_widget_get_allocation (widget, &rect);
- dest = gdk_region_rectangle (&rect);
+ dest = cairo_region_create_rectangle (&rect);
- gdk_region_intersect (dest, region);
+ cairo_region_intersect (dest, region);
return dest;
}
*
* More precisely, it must have the %GTK_CAN_FOCUS flag set. Use
* gtk_widget_set_can_focus() to modify that flag.
+ *
+ * The widget also needs to be realized and mapped. This is indicated by the
+ * related signals. Grabbing the focus immediately after creating the widget
+ * will likely fail and cause critical warnings.
**/
void
gtk_widget_grab_focus (GtkWidget *widget)
toplevel = gtk_widget_get_toplevel (focus_widget);
if (gtk_widget_is_toplevel (toplevel) && GTK_IS_WINDOW (toplevel))
{
- widget = GTK_WINDOW (toplevel)->focus_widget;
-
+ widget = gtk_window_get_focus (GTK_WINDOW (toplevel));
+
if (widget == focus_widget)
{
/* We call _gtk_window_internal_set_focus() here so that the
if (widget)
{
- while (widget->parent && widget->parent != focus_widget->parent)
+ while (widget->priv->parent && widget->priv->parent != focus_widget->priv->parent)
{
- widget = widget->parent;
+ widget = widget->priv->parent;
gtk_container_set_focus_child (GTK_CONTAINER (widget), NULL);
}
}
* set it on the window
*/
widget = focus_widget;
- while (widget->parent)
+ while (widget->priv->parent)
{
- gtk_container_set_focus_child (GTK_CONTAINER (widget->parent), widget);
- widget = widget->parent;
+ gtk_container_set_focus_child (GTK_CONTAINER (widget->priv->parent), widget);
+ widget = widget->priv->parent;
}
if (GTK_IS_WINDOW (widget))
_gtk_window_internal_set_focus (GTK_WINDOW (widget), focus_widget);
toplevel = gtk_widget_get_toplevel (widget);
if (GTK_IS_WINDOW (toplevel))
- return widget == GTK_WINDOW (toplevel)->focus_widget;
+ return widget == gtk_window_get_focus (GTK_WINDOW (toplevel));
else
return FALSE;
}
* yourself by calling <literal>gtk_widget_set_can_default (@widget,
* %TRUE)</literal>. The default widget is activated when
* the user presses Enter in a window. Default widgets must be
- * activatable, that is, gtk_widget_activate() should affect them.
+ * activatable, that is, gtk_widget_activate() should affect them. Note
+ * that #GtkEntry widgets require the "activates-default" property
+ * set to %TRUE before they activate the default widget when Enter
+ * is pressed and the #GtkEntry is focused.
**/
void
gtk_widget_grab_default (GtkWidget *widget)
GTK_OBJECT_FLAGS (widget) &= ~(GTK_HAS_GRAB);
}
+/**
+ * gtk_widget_device_is_shadowed:
+ * @widget: a #GtkWidget
+ * @device: a #GdkDevice
+ *
+ * Returns %TRUE if @device has been shadowed by a GTK+
+ * device grab on another widget, so it would stop sending
+ * events to @widget. This may be used in the
+ * #GtkWidget::grab-notify signal to check for specific
+ * devices. See gtk_device_grab_add().
+ *
+ * Returns: %TRUE if there is an ongoing grab on @device
+ * by another #GtkWidget than @widget.
+ *
+ * Since: 3.0
+ **/
+gboolean
+gtk_widget_device_is_shadowed (GtkWidget *widget,
+ GdkDevice *device)
+{
+ GtkWindowGroup *group;
+ GtkWidget *grab_widget, *toplevel;
+
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
+ g_return_val_if_fail (GDK_IS_DEVICE (device), FALSE);
+
+ if (!gtk_widget_get_realized (widget))
+ return TRUE;
+
+ toplevel = gtk_widget_get_toplevel (widget);
+
+ if (GTK_IS_WINDOW (toplevel))
+ group = gtk_window_get_group (GTK_WINDOW (toplevel));
+ else
+ group = gtk_window_get_group (NULL);
+
+ grab_widget = gtk_window_group_get_current_device_grab (group, device);
+
+ /* Widget not inside the hierarchy of grab_widget */
+ if (grab_widget &&
+ widget != grab_widget &&
+ !gtk_widget_is_ancestor (widget, grab_widget))
+ return TRUE;
+
+ grab_widget = gtk_window_group_get_current_grab (group);
+ if (grab_widget && widget != grab_widget &&
+ !gtk_widget_is_ancestor (widget, grab_widget))
+ return TRUE;
+
+ return FALSE;
+}
+
/**
* gtk_widget_set_name:
* @widget: a #GtkWidget
gtk_widget_set_name (GtkWidget *widget,
const gchar *name)
{
+ GtkWidgetPrivate *priv;
gchar *new_name;
g_return_if_fail (GTK_IS_WIDGET (widget));
+ priv = widget->priv;
+
new_name = g_strdup (name);
- g_free (widget->name);
- widget->name = new_name;
+ g_free (priv->name);
+ priv->name = new_name;
if (gtk_widget_has_rc_style (widget))
gtk_widget_reset_rc_style (widget);
G_CONST_RETURN gchar*
gtk_widget_get_name (GtkWidget *widget)
{
+ GtkWidgetPrivate *priv;
+
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
-
- if (widget->name)
- return widget->name;
+
+ priv = widget->priv;
+
+ if (priv->name)
+ return priv->name;
return G_OBJECT_TYPE_NAME (widget);
}
gtk_widget_set_state (GtkWidget *widget,
GtkStateType state)
{
+ GtkWidgetPrivate *priv;
+
g_return_if_fail (GTK_IS_WIDGET (widget));
+ priv = widget->priv;
+
if (state == gtk_widget_get_state (widget))
return;
data.state = state;
data.state_restoration = FALSE;
data.use_forall = FALSE;
- if (widget->parent)
- data.parent_sensitive = (gtk_widget_is_sensitive (widget->parent) != FALSE);
+ if (priv->parent)
+ data.parent_sensitive = (gtk_widget_is_sensitive (priv->parent) != FALSE);
else
data.parent_sensitive = TRUE;
{
g_return_val_if_fail (GTK_IS_WIDGET (widget), GTK_STATE_NORMAL);
- return widget->state;
+ return widget->priv->state;
}
/**
* all realized widgets have a non-%NULL "window" pointer
* (gtk_widget_get_window() never returns a %NULL window when a widget
* is realized), but for many of them it's actually the #GdkWindow of
- * one of its parent widgets. Widgets that create a %window for
- * themselves in GtkWidget::realize() however must announce this by
- * calling this function with @has_window = %TRUE.
+ * one of its parent widgets. Widgets that do not create a %window for
+ * themselves in GtkWidget::realize() must announce this by
+ * calling this function with @has_window = %FALSE.
*
* This function should only be called by widget implementations,
* and they should call it in their init() function.
* is then entirely responsible for drawing the widget background.
*
* Note that the background is still drawn when the widget is mapped.
- * If this is not suitable (e.g. because you want to make a transparent
- * window using an RGBA visual), you can work around this by doing:
- * |[
- * gtk_widget_realize (window);
- * gdk_window_set_back_pixmap (window->window, NULL, FALSE);
- * gtk_widget_show (window);
- * ]|
**/
void
gtk_widget_set_app_paintable (GtkWidget *widget,
gtk_widget_set_sensitive (GtkWidget *widget,
gboolean sensitive)
{
+ GtkWidgetPrivate *priv;
GtkStateData data;
g_return_if_fail (GTK_IS_WIDGET (widget));
+ priv = widget->priv;
+
sensitive = (sensitive != FALSE);
if (sensitive == (gtk_widget_get_sensitive (widget) != FALSE))
if (sensitive)
{
GTK_OBJECT_FLAGS (widget) |= GTK_SENSITIVE;
- data.state = widget->saved_state;
+ data.state = priv->saved_state;
}
else
{
data.state_restoration = TRUE;
data.use_forall = TRUE;
- if (widget->parent)
- data.parent_sensitive = (gtk_widget_is_sensitive (widget->parent) != FALSE);
+ if (priv->parent)
+ data.parent_sensitive = (gtk_widget_is_sensitive (priv->parent) != FALSE);
else
data.parent_sensitive = TRUE;
gtk_widget_set_parent (GtkWidget *widget,
GtkWidget *parent)
{
+ GtkWidgetPrivate *priv;
GtkStateData data;
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (GTK_IS_WIDGET (parent));
g_return_if_fail (widget != parent);
- if (widget->parent != NULL)
+
+ priv = widget->priv;
+
+ if (priv->parent != NULL)
{
g_warning ("Can't set a parent on widget which has a parent\n");
return;
*/
g_object_ref_sink (widget);
- widget->parent = parent;
+ priv->parent = parent;
if (gtk_widget_get_state (parent) != GTK_STATE_NORMAL)
data.state = gtk_widget_get_state (parent);
gtk_widget_reset_rc_styles (widget);
g_signal_emit (widget, widget_signals[PARENT_SET], 0, NULL);
- if (GTK_WIDGET_ANCHORED (widget->parent))
+ if (GTK_WIDGET_ANCHORED (priv->parent))
_gtk_widget_propagate_hierarchy_changed (widget, NULL);
g_object_notify (G_OBJECT (widget), "parent");
/* Enforce realized/mapped invariants
*/
- if (gtk_widget_get_realized (widget->parent))
+ if (gtk_widget_get_realized (priv->parent))
gtk_widget_realize (widget);
- if (gtk_widget_get_visible (widget->parent) &&
+ if (gtk_widget_get_visible (priv->parent) &&
gtk_widget_get_visible (widget))
{
if (GTK_WIDGET_CHILD_VISIBLE (widget) &&
- gtk_widget_get_mapped (widget->parent))
+ gtk_widget_get_mapped (priv->parent))
gtk_widget_map (widget);
gtk_widget_queue_resize (widget);
{
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
- return widget->parent;
+ return widget->priv->parent;
}
/*****************************************
void
gtk_widget_style_attach (GtkWidget *widget)
{
+ GtkWidgetPrivate *priv;
+
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (gtk_widget_get_realized (widget));
- widget->style = gtk_style_attach (widget->style, widget->window);
+ priv = widget->priv;
+
+ priv->style = gtk_style_attach (priv->style, priv->window);
}
/**
static void
gtk_widget_reset_rc_style (GtkWidget *widget)
{
+ GtkWidgetPrivate *priv = widget->priv;
GtkStyle *new_style = NULL;
gboolean initial_emission;
if (!new_style)
new_style = gtk_widget_get_default_style ();
- if (initial_emission || new_style != widget->style)
+ if (initial_emission || new_style != priv->style)
gtk_widget_set_style_internal (widget, new_style, initial_emission);
}
gtk_widget_get_style (GtkWidget *widget)
{
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
-
- return widget->style;
+
+ return widget->priv->style;
}
/**
* All other style values are left untouched. See also
* gtk_widget_modify_style().
*
- * Since: 2.22
+ * Since: 3.0
**/
void
gtk_widget_modify_symbolic_color (GtkWidget *widget,
gtk_widget_real_style_set (GtkWidget *widget,
GtkStyle *previous_style)
{
+ GtkWidgetPrivate *priv = widget->priv;
+
if (gtk_widget_get_realized (widget) &&
gtk_widget_get_has_window (widget))
- gtk_style_set_background (widget->style, widget->window, widget->state);
+ gtk_style_set_background (priv->style, priv->window, priv->state);
}
static void
GtkStyle *style,
gboolean initial_emission)
{
+ GtkWidgetPrivate *priv = widget->priv;
+
g_object_ref (widget);
g_object_freeze_notify (G_OBJECT (widget));
- if (widget->style != style)
+ if (priv->style != style)
{
GtkStyle *previous_style;
if (gtk_widget_get_realized (widget))
{
gtk_widget_reset_shapes (widget);
- gtk_style_detach (widget->style);
+ gtk_style_detach (priv->style);
}
-
- previous_style = widget->style;
- widget->style = style;
- g_object_ref (widget->style);
-
+
+ previous_style = priv->style;
+ priv->style = style;
+ g_object_ref (priv->style);
+
if (gtk_widget_get_realized (widget))
- widget->style = gtk_style_attach (widget->style, widget->window);
+ priv->style = gtk_style_attach (priv->style, priv->window);
gtk_widget_update_pango_context (widget);
g_signal_emit (widget,
gtk_widget_propagate_hierarchy_changed_recurse (GtkWidget *widget,
gpointer client_data)
{
+ GtkWidgetPrivate *priv = widget->priv;
HierarchyChangedInfo *info = client_data;
gboolean new_anchored = gtk_widget_is_toplevel (widget) ||
- (widget->parent && GTK_WIDGET_ANCHORED (widget->parent));
+ (priv->parent && GTK_WIDGET_ANCHORED (priv->parent));
if (GTK_WIDGET_ANCHORED (widget) != new_anchored)
{
_gtk_widget_propagate_hierarchy_changed (GtkWidget *widget,
GtkWidget *previous_toplevel)
{
+ GtkWidgetPrivate *priv = widget->priv;
HierarchyChangedInfo info;
info.previous_toplevel = previous_toplevel;
info.previous_screen = previous_toplevel ? gtk_widget_get_screen (previous_toplevel) : NULL;
if (gtk_widget_is_toplevel (widget) ||
- (widget->parent && GTK_WIDGET_ANCHORED (widget->parent)))
+ (priv->parent && GTK_WIDGET_ANCHORED (priv->parent)))
info.new_screen = gtk_widget_get_screen (widget);
else
info.new_screen = NULL;
update_pango_context (GtkWidget *widget,
PangoContext *context)
{
- pango_context_set_font_description (context, widget->style->font_desc);
+ GtkWidgetPrivate *priv = widget->priv;
+
+ pango_context_set_font_description (context, priv->style->font_desc);
pango_context_set_base_dir (context,
gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR ?
PANGO_DIRECTION_LTR : PANGO_DIRECTION_RTL);
/**
* gtk_widget_create_pango_context:
* @widget: a #GtkWidget
- *
+ *
* Creates a new #PangoContext with the appropriate font map,
* font description, and base direction for drawing text for
* this widget. See also gtk_widget_get_pango_context().
- *
- * Return value: the new #PangoContext
+ *
+ * Return value: (transfer full): the new #PangoContext
**/
PangoContext *
gtk_widget_create_pango_context (GtkWidget *widget)
* gtk_widget_create_pango_layout:
* @widget: a #GtkWidget
* @text: text to set on the layout (can be %NULL)
- *
+ *
* Creates a new #PangoLayout with the appropriate font map,
* font description, and base direction for drawing text for
* this widget.
* If you keep a #PangoLayout created in this way around, in order to
* notify the layout of changes to the base direction or font of this
* widget, you must call pango_layout_context_changed() in response to
- * the #GtkWidget::style-set and #GtkWidget::direction-changed signals
+ * the #GtkWidget::style-set and #GtkWidget::direction-changed signals
* for the widget.
- *
- * Return value: the new #PangoLayout
+ *
+ * Return value: (transfer full): the new #PangoLayout
**/
PangoLayout *
gtk_widget_create_pango_layout (GtkWidget *widget,
* gtk_widget_render_icon:
* @widget: a #GtkWidget
* @stock_id: a stock ID
- * @size: (type int) a stock size. A size of (GtkIconSize)-1 means
+ * @size: (type int): a stock size. A size of (GtkIconSize)-1 means
* render at the size of the source and don't scale (if there are
* multiple source sizes, GTK+ picks one of the available sizes).
* @detail: (allow-none): render detail to pass to theme engine
* the application and should not be modified. The pixbuf should be freed
* after use with g_object_unref().
*
- * Return value: a new pixbuf, or %NULL if the stock ID wasn't known
+ * Return value: (transfer full): a new pixbuf, or %NULL if the
+ * stock ID wasn't known
**/
GdkPixbuf*
gtk_widget_render_icon (GtkWidget *widget,
GtkIconSize size,
const gchar *detail)
{
+ GtkWidgetPrivate *priv;
GtkIconSet *icon_set;
GdkPixbuf *retval;
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
g_return_val_if_fail (stock_id != NULL, NULL);
g_return_val_if_fail (size > GTK_ICON_SIZE_INVALID || size == -1, NULL);
-
+
+ priv = widget->priv;
+
gtk_widget_ensure_style (widget);
- icon_set = gtk_style_lookup_icon_set (widget->style, stock_id);
+ icon_set = gtk_style_lookup_icon_set (priv->style, stock_id);
if (icon_set == NULL)
return NULL;
retval = gtk_icon_set_render_icon (icon_set,
- widget->style,
+ priv->style,
gtk_widget_get_direction (widget),
gtk_widget_get_state (widget),
size,
GdkWindow *
gtk_widget_get_parent_window (GtkWidget *widget)
{
+ GtkWidgetPrivate *priv;
GdkWindow *parent_window;
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
+ priv = widget->priv;
+
parent_window = g_object_get_qdata (G_OBJECT (widget), quark_parent_window);
return (parent_window != NULL) ? parent_window :
- (widget->parent != NULL) ? widget->parent->window : NULL;
+ (priv->parent != NULL) ? priv->parent->priv->window : NULL;
}
gtk_widget_set_child_visible (GtkWidget *widget,
gboolean is_visible)
{
+ GtkWidgetPrivate *priv;
+
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (!gtk_widget_is_toplevel (widget));
+ priv = widget->priv;
+
g_object_ref (widget);
if (is_visible)
_gtk_window_unset_focus_and_default (GTK_WINDOW (toplevel), widget);
}
- if (widget->parent && gtk_widget_get_realized (widget->parent))
+ if (priv->parent && gtk_widget_get_realized (priv->parent))
{
- if (gtk_widget_get_mapped (widget->parent) &&
+ if (gtk_widget_get_mapped (priv->parent) &&
GTK_WIDGET_CHILD_VISIBLE (widget) &&
gtk_widget_get_visible (widget))
gtk_widget_map (widget);
if (gtk_widget_is_toplevel (toplevel))
{
if (GTK_IS_WINDOW (toplevel))
- return GTK_WINDOW (toplevel)->screen;
+ return gtk_window_get_screen (GTK_WINDOW (toplevel));
else if (GTK_IS_INVISIBLE (toplevel))
- return GTK_INVISIBLE (widget)->screen;
+ return gtk_invisible_get_screen (GTK_INVISIBLE (widget));
}
return NULL;
* outside the widget. If returning %TRUE, widgets normally
* call gtk_widget_grab_focus() to place the focus accordingly;
* if returning %FALSE, they don't modify the current focus location.
- *
- * This function replaces gtk_container_focus() from GTK+ 1.2.
- * It was necessary to check that the child was visible, sensitive,
- * and focusable before calling gtk_container_focus().
- * gtk_widget_child_focus() returns %FALSE if the widget is not
- * currently in a focusable state, so there's no need for those checks.
- *
+ *
* Return value: %TRUE if focus ended up inside @widget
**/
gboolean
void
gtk_widget_error_bell (GtkWidget *widget)
{
+ GtkWidgetPrivate *priv;
GtkSettings* settings;
gboolean beep;
g_return_if_fail (GTK_IS_WIDGET (widget));
+ priv = widget->priv;
+
settings = gtk_widget_get_settings (widget);
if (!settings)
return;
"gtk-error-bell", &beep,
NULL);
- if (beep && widget->window)
- gdk_window_beep (widget->window);
-}
-
-/**
- * gtk_widget_set_uposition:
- * @widget: a #GtkWidget
- * @x: x position; -1 to unset x; -2 to leave x unchanged
- * @y: y position; -1 to unset y; -2 to leave y unchanged
- *
- *
- * Sets the position of a widget. The funny "u" in the name comes from
- * the "user position" hint specified by the X Window System, and
- * exists for legacy reasons. This function doesn't work if a widget
- * is inside a container; it's only really useful on #GtkWindow.
- *
- * Don't use this function to center dialogs over the main application
- * window; most window managers will do the centering on your behalf
- * if you call gtk_window_set_transient_for(), and it's really not
- * possible to get the centering to work correctly in all cases from
- * application code. But if you insist, use gtk_window_set_position()
- * to set #GTK_WIN_POS_CENTER_ON_PARENT, don't do the centering
- * manually.
- *
- * Note that although @x and @y can be individually unset, the position
- * is not honoured unless both @x and @y are set.
- **/
-void
-gtk_widget_set_uposition (GtkWidget *widget,
- gint x,
- gint y)
-{
- /* FIXME this function is the only place that aux_info->x and
- * aux_info->y are even used I believe, and this function is
- * deprecated. Should be cleaned up.
- *
- * (Actually, size_allocate uses them) -Yosh
- */
-
- GtkWidgetAuxInfo *aux_info;
-
- g_return_if_fail (GTK_IS_WIDGET (widget));
-
- aux_info =_gtk_widget_get_aux_info (widget, TRUE);
-
- if (x > -2)
- {
- if (x == -1)
- aux_info->x_set = FALSE;
- else
- {
- aux_info->x_set = TRUE;
- aux_info->x = x;
- }
- }
-
- if (y > -2)
- {
- if (y == -1)
- aux_info->y_set = FALSE;
- else
- {
- aux_info->y_set = TRUE;
- aux_info->y = y;
- }
- }
-
- if (GTK_IS_WINDOW (widget) && aux_info->x_set && aux_info->y_set)
- _gtk_window_reposition (GTK_WINDOW (widget), aux_info->x, aux_info->y);
-
- if (gtk_widget_get_visible (widget) && widget->parent)
- gtk_widget_size_allocate (widget, &widget->allocation);
+ if (beep && priv->window)
+ gdk_window_beep (priv->window);
}
static void
g_object_thaw_notify (G_OBJECT (widget));
}
-/**
- * gtk_widget_set_usize:
- * @widget: a #GtkWidget
- * @width: minimum width, or -1 to unset
- * @height: minimum height, or -1 to unset
- *
- * Sets the minimum size of a widget; that is, the widget's size
- * request will be @width by @height. You can use this function to
- * force a widget to be either larger or smaller than it is. The
- * strange "usize" name dates from the early days of GTK+, and derives
- * from X Window System terminology. In many cases,
- * gtk_window_set_default_size() is a better choice for toplevel
- * windows than this function; setting the default size will still
- * allow users to shrink the window. Setting the usize will force them
- * to leave the window at least as large as the usize. When dealing
- * with window sizes, gtk_window_set_geometry_hints() can be a useful
- * function as well.
- *
- * Note the inherent danger of setting any fixed size - themes,
- * translations into other languages, different fonts, and user action
- * can all change the appropriate size for a given widget. So, it's
- * basically impossible to hardcode a size that will always be
- * correct.
- *
- * Deprecated: 2.2: Use gtk_widget_set_size_request() instead.
- **/
-void
-gtk_widget_set_usize (GtkWidget *widget,
- gint width,
- gint height)
-{
- g_return_if_fail (GTK_IS_WIDGET (widget));
-
- gtk_widget_set_usize_internal (widget, width, height);
-}
-
/**
* gtk_widget_set_size_request:
* @widget: a #GtkWidget
*
* Widgets can't actually be allocated a size less than 1 by 1, but
* you can pass 0,0 to this function to mean "as small as possible."
+ *
+ * The size request set here does not include any margin from the
+ * #GtkWidget properties margin-left, margin-right, margin-top, and
+ * margin-bottom, but it does include pretty much all other padding
+ * or border properties set by any subclass of #GtkWidget.
**/
void
gtk_widget_set_size_request (GtkWidget *widget,
/**
* gtk_widget_get_size_request:
* @widget: a #GtkWidget
- * @width: (allow-none): (out): return location for width, or %NULL
- * @height: (allow-none): (out): return location for height, or %NULL
+ * @width: (out) (allow-none): return location for width, or %NULL
+ * @height: (out) (allow-none): return location for height, or %NULL
*
* Gets the size request that was explicitly set for the widget using
* gtk_widget_set_size_request(). A value of -1 stored in @width or
* @height indicates that that dimension has not been set explicitly
* and the natural requisition of the widget will be used intead. See
* gtk_widget_set_size_request(). To get the size a widget will
- * actually use, call gtk_widget_size_request() instead of
+ * actually request, call gtk_size_request_get_size() instead of
* this function.
**/
void
gint *width,
gint *height)
{
- GtkWidgetAuxInfo *aux_info;
+ const GtkWidgetAuxInfo *aux_info;
g_return_if_fail (GTK_IS_WIDGET (widget));
- aux_info = _gtk_widget_get_aux_info (widget, FALSE);
+ aux_info = _gtk_widget_get_aux_info_or_defaults (widget);
if (width)
- *width = aux_info ? aux_info->width : -1;
+ *width = aux_info->width;
if (height)
- *height = aux_info ? aux_info->height : -1;
+ *height = aux_info->height;
}
/**
g_object_notify (G_OBJECT (widget), "events");
}
-static void
-gtk_widget_add_events_internal (GtkWidget *widget,
- gint events,
- GList *window_list)
-{
- GList *l;
-
- for (l = window_list; l != NULL; l = l->next)
- {
- GdkWindow *window = l->data;
- gpointer user_data;
-
- gdk_window_get_user_data (window, &user_data);
- if (user_data == widget)
- {
- GList *children;
-
- gdk_window_set_events (window, gdk_window_get_events (window) | events);
-
- children = gdk_window_get_children (window);
- gtk_widget_add_events_internal (widget, events, children);
- g_list_free (children);
- }
- }
-}
-
/**
- * gtk_widget_add_events:
+ * gtk_widget_set_device_events:
+ * @widget: a #GtkWidget
+ * @device: a #GdkDevice
+ * @events: event mask
+ *
+ * Sets the device event mask (see #GdkEventMask) for a widget. The event
+ * mask determines which events a widget will receive from @device. Keep
+ * in mind that different widgets have different default event masks, and by
+ * changing the event mask you may disrupt a widget's functionality,
+ * so be careful. This function must be called while a widget is
+ * unrealized. Consider gtk_widget_add_device_events() for widgets that are
+ * already realized, or if you want to preserve the existing event
+ * mask. This function can't be used with #GTK_NO_WINDOW widgets;
+ * to get events on those widgets, place them inside a #GtkEventBox
+ * and receive events on the event box.
+ *
+ * Since: 3.0
+ **/
+void
+gtk_widget_set_device_events (GtkWidget *widget,
+ GdkDevice *device,
+ GdkEventMask events)
+{
+ GHashTable *device_events;
+
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+ g_return_if_fail (GDK_IS_DEVICE (device));
+ g_return_if_fail (!gtk_widget_get_realized (widget));
+
+ device_events = g_object_get_qdata (G_OBJECT (widget), quark_device_event_mask);
+
+ if (G_UNLIKELY (!device_events))
+ {
+ device_events = g_hash_table_new (NULL, NULL);
+ g_object_set_qdata_full (G_OBJECT (widget), quark_device_event_mask, device_events,
+ (GDestroyNotify) g_hash_table_unref);
+ }
+
+ g_hash_table_insert (device_events, device, GUINT_TO_POINTER (events));
+}
+
+static void
+gtk_widget_add_events_internal_list (GtkWidget *widget,
+ GdkDevice *device,
+ gint events,
+ GList *window_list)
+{
+ GList *l;
+
+ for (l = window_list; l != NULL; l = l->next)
+ {
+ GdkWindow *window = l->data;
+ gpointer user_data;
+
+ gdk_window_get_user_data (window, &user_data);
+ if (user_data == widget)
+ {
+ GList *children;
+
+ if (device)
+ gdk_window_set_device_events (window, device, gdk_window_get_events (window) | events);
+ else
+ gdk_window_set_events (window, gdk_window_get_events (window) | events);
+
+ children = gdk_window_get_children (window);
+ gtk_widget_add_events_internal_list (widget, device, events, children);
+ g_list_free (children);
+ }
+ }
+}
+
+static void
+gtk_widget_add_events_internal (GtkWidget *widget,
+ GdkDevice *device,
+ gint events)
+{
+ GtkWidgetPrivate *priv = widget->priv;
+ GList *window_list;
+
+ if (!gtk_widget_get_has_window (widget))
+ window_list = gdk_window_get_children (priv->window);
+ else
+ window_list = g_list_prepend (NULL, priv->window);
+
+ gtk_widget_add_events_internal_list (widget, device, events, window_list);
+
+ g_list_free (window_list);
+}
+
+/**
+ * gtk_widget_add_events:
* @widget: a #GtkWidget
* @events: an event mask, see #GdkEventMask
*
GINT_TO_POINTER (old_events | events));
if (gtk_widget_get_realized (widget))
- {
- GList *window_list;
+ gtk_widget_add_events_internal (widget, NULL, events);
- if (!gtk_widget_get_has_window (widget))
- window_list = gdk_window_get_children (widget->window);
- else
- window_list = g_list_prepend (NULL, widget->window);
+ g_object_notify (G_OBJECT (widget), "events");
+}
- gtk_widget_add_events_internal (widget, events, window_list);
+/**
+ * gtk_widget_add_device_events:
+ * @widget: a #GtkWidget
+ * @device: a #GdkDevice
+ * @events: an event mask, see #GdkEventMask
+ *
+ * Adds the device events in the bitfield @events to the event mask for
+ * @widget. See gtk_widget_set_device_events() for details.
+ *
+ * Since: 3.0
+ **/
+void
+gtk_widget_add_device_events (GtkWidget *widget,
+ GdkDevice *device,
+ GdkEventMask events)
+{
+ GdkEventMask old_events;
+ GHashTable *device_events;
- g_list_free (window_list);
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+ g_return_if_fail (GDK_IS_DEVICE (device));
+
+ old_events = gtk_widget_get_device_events (widget, device);
+
+ device_events = g_object_get_qdata (G_OBJECT (widget), quark_device_event_mask);
+
+ if (G_UNLIKELY (!device_events))
+ {
+ device_events = g_hash_table_new (NULL, NULL);
+ g_object_set_qdata_full (G_OBJECT (widget), quark_device_event_mask, device_events,
+ (GDestroyNotify) g_hash_table_unref);
}
+ g_hash_table_insert (device_events, device,
+ GUINT_TO_POINTER (old_events | events));
+
+ if (gtk_widget_get_realized (widget))
+ gtk_widget_add_events_internal (widget, device, events);
+
g_object_notify (G_OBJECT (widget), "events");
}
gtk_widget_get_toplevel (GtkWidget *widget)
{
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
-
- while (widget->parent)
- widget = widget->parent;
-
+
+ while (widget->priv->parent)
+ widget = widget->priv->parent;
+
return widget;
}
GType widget_type)
{
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
-
+
while (widget && !g_type_is_a (G_OBJECT_TYPE (widget), widget_type))
- widget = widget->parent;
-
+ widget = widget->priv->parent;
+
if (!(widget && g_type_is_a (G_OBJECT_TYPE (widget), widget_type)))
return NULL;
return widget;
}
-/**
- * gtk_widget_get_colormap:
- * @widget: a #GtkWidget
- *
- * Gets the colormap that will be used to render @widget. No reference will
- * be added to the returned colormap; it should not be unreferenced.
- *
- * Return value: (transfer none): the colormap used by @widget
- **/
-GdkColormap*
-gtk_widget_get_colormap (GtkWidget *widget)
-{
- GdkColormap *colormap;
- GtkWidget *tmp_widget;
-
- g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
-
- if (widget->window)
- {
- colormap = gdk_drawable_get_colormap (widget->window);
- /* If window was destroyed previously, we'll get NULL here */
- if (colormap)
- return colormap;
- }
-
- tmp_widget = widget;
- while (tmp_widget)
- {
- colormap = g_object_get_qdata (G_OBJECT (tmp_widget), quark_colormap);
- if (colormap)
- return colormap;
-
- tmp_widget= tmp_widget->parent;
- }
-
- return gdk_screen_get_default_colormap (gtk_widget_get_screen (widget));
-}
-
/**
* gtk_widget_get_visual:
* @widget: a #GtkWidget
GdkVisual*
gtk_widget_get_visual (GtkWidget *widget)
{
+ GtkWidget *w;
+
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
- return gdk_colormap_get_visual (gtk_widget_get_colormap (widget));
+ for (w = widget; w != NULL; w = w->priv->parent)
+ {
+ if (gtk_widget_get_has_window (w) &&
+ w->priv->window)
+ return gdk_window_get_visual (w->priv->window);
+
+ if (GTK_IS_WINDOW (w))
+ return _gtk_window_get_visual (GTK_WINDOW (w));
+ }
+
+ return gdk_screen_get_system_visual (gdk_screen_get_default ());
}
/**
return gtk_settings_get_for_screen (gtk_widget_get_screen (widget));
}
-/**
- * gtk_widget_set_colormap:
- * @widget: a #GtkWidget
- * @colormap: a colormap
- *
- * Sets the colormap for the widget to the given value. Widget must not
- * have been previously realized. This probably should only be used
- * from an <function>init()</function> function (i.e. from the constructor
- * for the widget).
- **/
-void
-gtk_widget_set_colormap (GtkWidget *widget,
- GdkColormap *colormap)
-{
- g_return_if_fail (GTK_IS_WIDGET (widget));
- g_return_if_fail (!gtk_widget_get_realized (widget));
- g_return_if_fail (GDK_IS_COLORMAP (colormap));
-
- g_object_ref (colormap);
-
- g_object_set_qdata_full (G_OBJECT (widget),
- quark_colormap,
- colormap,
- g_object_unref);
-}
-
/**
* gtk_widget_get_events:
* @widget: a #GtkWidget
return GPOINTER_TO_INT (g_object_get_qdata (G_OBJECT (widget), quark_event_mask));
}
+/**
+ * gtk_widget_get_device_events:
+ * @widget: a #GtkWidget
+ * @device: a #GdkDevice
+ *
+ * Returns the events mask for the widget corresponding to an specific device. These
+ * are the events that the widget will receive when @device operates on it.
+ *
+ * Returns: device event mask for @widget
+ *
+ * Since: 3.0
+ **/
+GdkEventMask
+gtk_widget_get_device_events (GtkWidget *widget,
+ GdkDevice *device)
+{
+ GHashTable *device_events;
+
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
+ g_return_val_if_fail (GDK_IS_DEVICE (device), 0);
+
+ device_events = g_object_get_qdata (G_OBJECT (widget), quark_device_event_mask);
+
+ if (!device_events)
+ return 0;
+
+ return GPOINTER_TO_UINT (g_hash_table_lookup (device_events, device));
+}
+
/**
* gtk_widget_get_extension_events:
* @widget: a #GtkWidget
gint *x,
gint *y)
{
+ GtkWidgetPrivate *priv;
+
g_return_if_fail (GTK_IS_WIDGET (widget));
-
+
+ priv = widget->priv;
+
if (x)
*x = -1;
if (y)
if (gtk_widget_get_realized (widget))
{
- gdk_window_get_pointer (widget->window, x, y, NULL);
-
+ gdk_window_get_pointer (priv->window, x, y, NULL);
+
if (!gtk_widget_get_has_window (widget))
{
if (x)
- *x -= widget->allocation.x;
+ *x -= priv->allocation.x;
if (y)
- *y -= widget->allocation.y;
+ *y -= priv->allocation.y;
}
}
}
{
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
g_return_val_if_fail (ancestor != NULL, FALSE);
-
+
while (widget)
{
- if (widget->parent == ancestor)
+ if (widget->priv->parent == ancestor)
return TRUE;
- widget = widget->parent;
+ widget = widget->priv->parent;
}
return FALSE;
gchar*
gtk_widget_get_composite_name (GtkWidget *widget)
{
+ GtkWidgetPrivate *priv;
+
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
- if (((GTK_OBJECT_FLAGS (widget) & GTK_COMPOSITE_CHILD) != 0) && widget->parent)
- return _gtk_container_child_composite_name (GTK_CONTAINER (widget->parent),
+ priv = widget->priv;
+
+ if (((GTK_OBJECT_FLAGS (widget) & GTK_COMPOSITE_CHILD) != 0) && priv->parent)
+ return _gtk_container_child_composite_name (GTK_CONTAINER (priv->parent),
widget);
else
return NULL;
composite_child_stack--;
}
-/**
- * gtk_widget_push_colormap:
- * @cmap: a #GdkColormap
- *
- * Pushes @cmap onto a global stack of colormaps; the topmost
- * colormap on the stack will be used to create all widgets.
- * Remove @cmap with gtk_widget_pop_colormap(). There's little
- * reason to use this function.
- **/
-void
-gtk_widget_push_colormap (GdkColormap *cmap)
-{
- g_return_if_fail (!cmap || GDK_IS_COLORMAP (cmap));
-
- colormap_stack = g_slist_prepend (colormap_stack, cmap);
-}
-
-/**
- * gtk_widget_pop_colormap:
- *
- * Removes a colormap pushed with gtk_widget_push_colormap().
- **/
-void
-gtk_widget_pop_colormap (void)
-{
- if (colormap_stack)
- colormap_stack = g_slist_delete_link (colormap_stack, colormap_stack);
-}
-
-/**
- * gtk_widget_set_default_colormap:
- * @colormap: a #GdkColormap
- *
- * Sets the default colormap to use when creating widgets.
- * gtk_widget_push_colormap() is a better function to use if
- * you only want to affect a few widgets, rather than all widgets.
- **/
-void
-gtk_widget_set_default_colormap (GdkColormap *colormap)
-{
- g_return_if_fail (GDK_IS_COLORMAP (colormap));
-
- gdk_screen_set_default_colormap (gdk_colormap_get_screen (colormap),
- colormap);
-}
-
-/**
- * gtk_widget_get_default_colormap:
- *
- * Obtains the default colormap used to create widgets.
- *
- * Return value: (transfer none): default widget colormap
- **/
-GdkColormap*
-gtk_widget_get_default_colormap (void)
-{
- return gdk_screen_get_default_colormap (gdk_screen_get_default ());
-}
-
-/**
- * gtk_widget_get_default_visual:
- *
- * Obtains the visual of the default colormap. Not really useful;
- * used to be useful before gdk_colormap_get_visual() existed.
- *
- * Return value: (transfer none): visual of the default colormap
- **/
-GdkVisual*
-gtk_widget_get_default_visual (void)
-{
- return gdk_colormap_get_visual (gtk_widget_get_default_colormap ());
-}
-
static void
gtk_widget_emit_direction_changed (GtkWidget *widget,
GtkTextDirection old_dir)
gtk_widget_dispose (GObject *object)
{
GtkWidget *widget = GTK_WIDGET (object);
+ GtkWidgetPrivate *priv = widget->priv;
- if (widget->parent)
- gtk_container_remove (GTK_CONTAINER (widget->parent), widget);
+ if (priv->parent)
+ gtk_container_remove (GTK_CONTAINER (priv->parent), widget);
else if (gtk_widget_get_visible (widget))
gtk_widget_hide (widget);
{
/* gtk_object_destroy() will already hold a refcount on object */
GtkWidget *widget = GTK_WIDGET (object);
+ GtkWidgetPrivate *priv = widget->priv;
/* wipe accelerator closures (keep order) */
g_object_set_qdata (G_OBJECT (widget), quark_accel_path, NULL);
g_object_set_qdata (G_OBJECT (widget), quark_mnemonic_labels, NULL);
gtk_grab_remove (widget);
-
- g_object_unref (widget->style);
- widget->style = gtk_widget_get_default_style ();
- g_object_ref (widget->style);
+
+ g_object_unref (priv->style);
+ priv->style = gtk_widget_get_default_style ();
+ g_object_ref (priv->style);
GTK_OBJECT_CLASS (gtk_widget_parent_class)->destroy (object);
}
gtk_widget_finalize (GObject *object)
{
GtkWidget *widget = GTK_WIDGET (object);
+ GtkWidgetPrivate *priv = widget->priv;
GtkWidgetAuxInfo *aux_info;
GtkAccessible *accessible;
gtk_grab_remove (widget);
- g_object_unref (widget->style);
- widget->style = NULL;
+ g_object_unref (priv->style);
+ priv->style = NULL;
- g_free (widget->name);
+ g_free (priv->name);
aux_info =_gtk_widget_get_aux_info (widget, FALSE);
if (aux_info)
static void
gtk_widget_real_map (GtkWidget *widget)
{
+ GtkWidgetPrivate *priv = widget->priv;
+
g_assert (gtk_widget_get_realized (widget));
if (!gtk_widget_get_mapped (widget))
gtk_widget_set_mapped (widget, TRUE);
if (gtk_widget_get_has_window (widget))
- gdk_window_show (widget->window);
+ gdk_window_show (priv->window);
}
}
static void
gtk_widget_real_unmap (GtkWidget *widget)
{
+ GtkWidgetPrivate *priv = widget->priv;
+
if (gtk_widget_get_mapped (widget))
{
gtk_widget_set_mapped (widget, FALSE);
if (gtk_widget_get_has_window (widget))
- gdk_window_hide (widget->window);
+ gdk_window_hide (priv->window);
}
}
static void
gtk_widget_real_realize (GtkWidget *widget)
{
+ GtkWidgetPrivate *priv = widget->priv;
+
g_assert (!gtk_widget_get_has_window (widget));
gtk_widget_set_realized (widget, TRUE);
- if (widget->parent)
+ if (priv->parent)
{
- widget->window = gtk_widget_get_parent_window (widget);
- g_object_ref (widget->window);
+ priv->window = gtk_widget_get_parent_window (widget);
+ g_object_ref (priv->window);
}
- widget->style = gtk_style_attach (widget->style, widget->window);
+ priv->style = gtk_style_attach (priv->style, priv->window);
}
/*****************************************
static void
gtk_widget_real_unrealize (GtkWidget *widget)
{
+ GtkWidgetPrivate *priv = widget->priv;
+
if (gtk_widget_get_mapped (widget))
gtk_widget_real_unmap (widget);
(GtkCallback) gtk_widget_unrealize,
NULL);
- gtk_style_detach (widget->style);
+ gtk_style_detach (priv->style);
if (gtk_widget_get_has_window (widget))
{
- gdk_window_set_user_data (widget->window, NULL);
- gdk_window_destroy (widget->window);
- widget->window = NULL;
+ gdk_window_set_user_data (priv->window, NULL);
+ gdk_window_destroy (priv->window);
+ priv->window = NULL;
}
else
{
- g_object_unref (widget->window);
- widget->window = NULL;
+ g_object_unref (priv->window);
+ priv->window = NULL;
}
gtk_selection_remove_all (widget);
gtk_widget_real_size_request (GtkWidget *widget,
GtkRequisition *requisition)
{
- requisition->width = widget->requisition.width;
- requisition->height = widget->requisition.height;
+ requisition->width = 0;
+ requisition->height = 0;
+}
+
+static void
+gtk_widget_real_adjust_size_request (GtkWidget *widget,
+ GtkOrientation orientation,
+ gint for_size,
+ gint *minimum_size,
+ gint *natural_size)
+{
+ const GtkWidgetAuxInfo *aux_info;
+
+ aux_info =_gtk_widget_get_aux_info_or_defaults (widget);
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL &&
+ aux_info->width > 0)
+ {
+ *minimum_size = MAX (*minimum_size, aux_info->width);
+ }
+ else if (orientation == GTK_ORIENTATION_VERTICAL &&
+ aux_info->height > 0)
+ {
+ *minimum_size = MAX (*minimum_size, aux_info->height);
+ }
+
+ /* Fix it if set_size_request made natural size smaller than min size.
+ * This would also silently fix broken widgets, but we warn about them
+ * in gtksizerequest.c when calling their size request vfuncs.
+ */
+ *natural_size = MAX (*natural_size, *minimum_size);
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ *minimum_size += (aux_info->margin.left + aux_info->margin.right);
+ *natural_size += (aux_info->margin.left + aux_info->margin.right);
+ }
+ else
+ {
+ *minimum_size += (aux_info->margin.top + aux_info->margin.bottom);
+ *natural_size += (aux_info->margin.top + aux_info->margin.bottom);
+ }
}
/**
- * _gtk_widget_peek_colormap:
+ * _gtk_widget_peek_request_cache:
*
- * Returns colormap currently pushed by gtk_widget_push_colormap, if any.
+ * Returns the address of the widget's request cache (strictly for
+ * internal use in gtksizerequest.c)
*
- * Return value: the currently pushed colormap, or %NULL if there is none.
+ * Return value: the address of @widget's size request cache.
**/
-GdkColormap*
-_gtk_widget_peek_colormap (void)
+gpointer
+_gtk_widget_peek_request_cache (GtkWidget *widget)
{
- if (colormap_stack)
- return (GdkColormap*) colormap_stack->data;
- return NULL;
+ /* Don't bother slowing things down with the return_if_fail guards here */
+ return &widget->priv->requests;
}
/*
- * _gtk_widget_set_pointer_window:
+ * _gtk_widget_set_device_window:
* @widget: a #GtkWidget.
- * @pointer_window: the new pointer window.
+ * @device: a #GdkDevice.
+ * @window: the new device window.
*
- * Sets pointer window for @widget. Does not ref @pointer_window.
+ * Sets pointer window for @widget and @device. Does not ref @window.
* Actually stores it on the #GdkScreen, but you don't need to know that.
*/
void
-_gtk_widget_set_pointer_window (GtkWidget *widget,
- GdkWindow *pointer_window)
+_gtk_widget_set_device_window (GtkWidget *widget,
+ GdkDevice *device,
+ GdkWindow *window)
{
+ GtkWidgetPrivate *priv;
+ GdkScreen *screen;
+ GHashTable *device_window;
+
g_return_if_fail (GTK_IS_WIDGET (widget));
+ g_return_if_fail (GDK_IS_DEVICE (device));
+ g_return_if_fail (!window || GDK_IS_WINDOW (window));
- if (gtk_widget_get_realized (widget))
- {
- GdkScreen *screen = gdk_drawable_get_screen (widget->window);
+ priv = widget->priv;
+
+ if (!gtk_widget_get_realized (widget))
+ return;
+
+ screen = gdk_window_get_screen (priv->window);
+ device_window = g_object_get_qdata (G_OBJECT (screen), quark_pointer_window);
- g_object_set_qdata (G_OBJECT (screen), quark_pointer_window,
- pointer_window);
+ if (G_UNLIKELY (!device_window))
+ {
+ device_window = g_hash_table_new (NULL, NULL);
+ g_object_set_qdata_full (G_OBJECT (screen),
+ quark_pointer_window,
+ device_window,
+ (GDestroyNotify) g_hash_table_destroy);
}
+
+ if (window)
+ g_hash_table_insert (device_window, device, window);
+ else
+ g_hash_table_remove (device_window, device);
}
/*
- * _gtk_widget_get_pointer_window:
+ * _gtk_widget_get_device_window:
* @widget: a #GtkWidget.
+ * @device: a #GdkDevice.
*
- * Return value: the pointer window set on the #GdkScreen @widget is attached
+ * Return value: the device window set on the #GdkScreen @widget is attached
* to, or %NULL.
*/
GdkWindow *
-_gtk_widget_get_pointer_window (GtkWidget *widget)
+_gtk_widget_get_device_window (GtkWidget *widget,
+ GdkDevice *device)
{
+ GtkWidgetPrivate *priv;
+ GdkScreen *screen;
+ GHashTable *device_window;
+ GdkWindow *window;
+ GtkWidget *w;
+
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
+ g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
- if (gtk_widget_get_realized (widget))
+ priv = widget->priv;
+
+ if (!gtk_widget_get_realized (widget))
+ return NULL;
+
+ screen = gdk_window_get_screen (priv->window);
+ device_window = g_object_get_qdata (G_OBJECT (screen), quark_pointer_window);
+
+ if (G_UNLIKELY (!device_window))
+ return NULL;
+
+ window = g_hash_table_lookup (device_window, device);
+
+ if (!window)
+ return NULL;
+
+ gdk_window_get_user_data (window, (gpointer *) &w);
+
+ if (widget != w)
+ return NULL;
+
+ return window;
+}
+
+/*
+ * _gtk_widget_list_devices:
+ * @widget: a #GtkWidget.
+ *
+ * Returns the list of #GdkDevices that is currently on top of any widget #GdkWindow.
+ * Free the list with g_list_free(), the elements are owned by GTK+ and must not
+ * be freed.
+ */
+GList *
+_gtk_widget_list_devices (GtkWidget *widget)
+{
+ GtkWidgetPrivate *priv;
+ GdkScreen *screen;
+ GHashTableIter iter;
+ GHashTable *device_window;
+ GList *devices = NULL;
+ gpointer key, value;
+
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
+
+ priv = widget->priv;
+
+ if (!gtk_widget_get_realized (widget))
+ return NULL;
+
+ screen = gdk_window_get_screen (priv->window);
+ device_window = g_object_get_qdata (G_OBJECT (screen), quark_pointer_window);
+
+ if (G_UNLIKELY (!device_window))
+ return NULL;
+
+ g_hash_table_iter_init (&iter, device_window);
+
+ while (g_hash_table_iter_next (&iter, &key, &value))
{
- GdkScreen *screen = gdk_drawable_get_screen (widget->window);
+ GdkDevice *device = key;
+ GdkWindow *window = value;
+ GtkWidget *w;
- return g_object_get_qdata (G_OBJECT (screen), quark_pointer_window);
+ if (window)
+ {
+ gdk_window_get_user_data (window, (gpointer *) &w);
+
+ if (widget == w)
+ devices = g_list_prepend (devices, device);
+ }
}
- return NULL;
+ return devices;
}
static void
-synth_crossing (GtkWidget *widget,
- GdkEventType type,
- GdkWindow *window,
- GdkCrossingMode mode,
- GdkNotifyType detail)
+synth_crossing (GtkWidget *widget,
+ GdkEventType type,
+ GdkWindow *window,
+ GdkDevice *device,
+ GdkCrossingMode mode,
+ GdkNotifyType detail)
{
GdkEvent *event;
-
+
event = gdk_event_new (type);
event->crossing.window = g_object_ref (window);
event->crossing.detail = detail;
event->crossing.focus = FALSE;
event->crossing.state = 0;
+ gdk_event_set_device (event, device);
if (!widget)
widget = gtk_get_event_widget (event);
gdk_event_free (event);
}
-/*
- * _gtk_widget_is_pointer_widget:
- * @widget: a #GtkWidget
- *
- * Returns %TRUE if the pointer window belongs to @widget.
- */
-gboolean
-_gtk_widget_is_pointer_widget (GtkWidget *widget)
-{
- if (GTK_WIDGET_HAS_POINTER (widget))
- {
- GdkWindow *win;
- GtkWidget *wid;
-
- win = _gtk_widget_get_pointer_window (widget);
- if (win)
- {
- gdk_window_get_user_data (win, (gpointer *)&wid);
- if (wid == widget)
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
/*
* _gtk_widget_synthesize_crossing:
* @from: the #GtkWidget the virtual pointer is leaving.
* - enter notify on real pointer window, detail Ancestor
*/
void
-_gtk_widget_synthesize_crossing (GtkWidget *from,
- GtkWidget *to,
- GdkCrossingMode mode)
+_gtk_widget_synthesize_crossing (GtkWidget *from,
+ GtkWidget *to,
+ GdkDevice *device,
+ GdkCrossingMode mode)
{
GdkWindow *from_window = NULL, *to_window = NULL;
g_return_if_fail (from != NULL || to != NULL);
if (from != NULL)
- from_window = GTK_WIDGET_HAS_POINTER (from)
- ? _gtk_widget_get_pointer_window (from) : from->window;
+ {
+ from_window = _gtk_widget_get_device_window (from, device);
+
+ if (!from_window)
+ from_window = from->priv->window;
+ }
+
if (to != NULL)
- to_window = GTK_WIDGET_HAS_POINTER (to)
- ? _gtk_widget_get_pointer_window (to) : to->window;
+ {
+ to_window = _gtk_widget_get_device_window (to, device);
+
+ if (!to_window)
+ to_window = to->priv->window;
+ }
if (from_window == NULL && to_window == NULL)
;
}
synth_crossing (from, GDK_LEAVE_NOTIFY, from_window,
- mode, GDK_NOTIFY_ANCESTOR);
+ device, mode, GDK_NOTIFY_ANCESTOR);
for (list = g_list_last (from_ancestors); list; list = list->prev)
{
synth_crossing (NULL, GDK_LEAVE_NOTIFY, (GdkWindow *) list->data,
- mode, GDK_NOTIFY_VIRTUAL);
+ device, mode, GDK_NOTIFY_VIRTUAL);
}
/* XXX: enter/inferior on root window? */
for (list = to_ancestors; list; list = list->next)
{
synth_crossing (NULL, GDK_ENTER_NOTIFY, (GdkWindow *) list->data,
- mode, GDK_NOTIFY_VIRTUAL);
+ device, mode, GDK_NOTIFY_VIRTUAL);
}
synth_crossing (to, GDK_ENTER_NOTIFY, to_window,
- mode, GDK_NOTIFY_ANCESTOR);
+ device, mode, GDK_NOTIFY_ANCESTOR);
g_list_free (to_ancestors);
}
{
if (mode != GDK_CROSSING_GTK_UNGRAB)
synth_crossing (from, GDK_LEAVE_NOTIFY, from_window,
- mode, GDK_NOTIFY_INFERIOR);
+ device, mode, GDK_NOTIFY_INFERIOR);
for (list = to_ancestors; list; list = list->next)
synth_crossing (NULL, GDK_ENTER_NOTIFY, (GdkWindow *) list->data,
- mode, GDK_NOTIFY_VIRTUAL);
+ device, mode, GDK_NOTIFY_VIRTUAL);
synth_crossing (to, GDK_ENTER_NOTIFY, to_window,
- mode, GDK_NOTIFY_ANCESTOR);
+ device, mode, GDK_NOTIFY_ANCESTOR);
}
else if (from_ancestor == to_window)
{
synth_crossing (from, GDK_LEAVE_NOTIFY, from_window,
- mode, GDK_NOTIFY_ANCESTOR);
+ device, mode, GDK_NOTIFY_ANCESTOR);
for (list = g_list_last (from_ancestors); list; list = list->prev)
{
synth_crossing (NULL, GDK_LEAVE_NOTIFY, (GdkWindow *) list->data,
- mode, GDK_NOTIFY_VIRTUAL);
+ device, mode, GDK_NOTIFY_VIRTUAL);
}
if (mode != GDK_CROSSING_GTK_GRAB)
synth_crossing (to, GDK_ENTER_NOTIFY, to_window,
- mode, GDK_NOTIFY_INFERIOR);
+ device, mode, GDK_NOTIFY_INFERIOR);
}
else
{
}
synth_crossing (from, GDK_LEAVE_NOTIFY, from_window,
- mode, GDK_NOTIFY_NONLINEAR);
+ device, mode, GDK_NOTIFY_NONLINEAR);
for (list = g_list_last (from_ancestors); list; list = list->prev)
{
synth_crossing (NULL, GDK_LEAVE_NOTIFY, (GdkWindow *) list->data,
- mode, GDK_NOTIFY_NONLINEAR_VIRTUAL);
+ device, mode, GDK_NOTIFY_NONLINEAR_VIRTUAL);
}
for (list = to_ancestors; list; list = list->next)
{
synth_crossing (NULL, GDK_ENTER_NOTIFY, (GdkWindow *) list->data,
- mode, GDK_NOTIFY_NONLINEAR_VIRTUAL);
+ device, mode, GDK_NOTIFY_NONLINEAR_VIRTUAL);
}
synth_crossing (to, GDK_ENTER_NOTIFY, to_window,
- mode, GDK_NOTIFY_NONLINEAR);
+ device, mode, GDK_NOTIFY_NONLINEAR);
}
g_list_free (from_ancestors);
g_list_free (to_ancestors);
gtk_widget_propagate_state (GtkWidget *widget,
GtkStateData *data)
{
+ GtkWidgetPrivate *priv = widget->priv;
guint8 old_state = gtk_widget_get_state (widget);
- guint8 old_saved_state = widget->saved_state;
+ guint8 old_saved_state = priv->saved_state;
/* don't call this function with state==GTK_STATE_INSENSITIVE,
* parent_sensitive==TRUE on a sensitive widget
if (gtk_widget_is_sensitive (widget))
{
if (data->state_restoration)
- widget->state = widget->saved_state;
+ priv->state = priv->saved_state;
else
- widget->state = data->state;
+ priv->state = data->state;
}
else
{
if (!data->state_restoration)
{
if (data->state != GTK_STATE_INSENSITIVE)
- widget->saved_state = data->state;
+ priv->saved_state = data->state;
}
else if (gtk_widget_get_state (widget) != GTK_STATE_INSENSITIVE)
- widget->saved_state = gtk_widget_get_state (widget);
- widget->state = GTK_STATE_INSENSITIVE;
+ priv->saved_state = gtk_widget_get_state (widget);
+ priv->state = GTK_STATE_INSENSITIVE;
}
if (gtk_widget_is_focus (widget) && !gtk_widget_is_sensitive (widget))
}
if (old_state != gtk_widget_get_state (widget) ||
- old_saved_state != widget->saved_state)
+ old_saved_state != priv->saved_state)
{
g_object_ref (widget);
g_signal_emit (widget, widget_signals[STATE_CHANGED], 0, old_state);
- if (GTK_WIDGET_HAS_POINTER (widget) && !GTK_WIDGET_SHADOWED (widget))
- {
- if (!gtk_widget_is_sensitive (widget))
- _gtk_widget_synthesize_crossing (widget, NULL,
- GDK_CROSSING_STATE_CHANGED);
- else if (old_state == GTK_STATE_INSENSITIVE)
- _gtk_widget_synthesize_crossing (NULL, widget,
- GDK_CROSSING_STATE_CHANGED);
- }
+ if (!GTK_WIDGET_SHADOWED (widget))
+ {
+ GList *event_windows = NULL;
+ GList *devices, *d;
+
+ devices = _gtk_widget_list_devices (widget);
+
+ for (d = devices; d; d = d->next)
+ {
+ GdkWindow *window;
+ GdkDevice *device;
+
+ device = d->data;
+ window = _gtk_widget_get_device_window (widget, device);
+
+ /* Do not propagate more than once to the
+ * same window if non-multidevice aware.
+ */
+ if (!gdk_window_get_support_multidevice (window) &&
+ g_list_find (event_windows, window))
+ continue;
+
+ if (!gtk_widget_is_sensitive (widget))
+ _gtk_widget_synthesize_crossing (widget, NULL, d->data,
+ GDK_CROSSING_STATE_CHANGED);
+ else if (old_state == GTK_STATE_INSENSITIVE)
+ _gtk_widget_synthesize_crossing (NULL, widget, d->data,
+ GDK_CROSSING_STATE_CHANGED);
+
+ event_windows = g_list_prepend (event_windows, window);
+ }
+
+ g_list_free (event_windows);
+ g_list_free (devices);
+ }
if (GTK_IS_CONTAINER (widget))
{
}
}
+static const GtkWidgetAuxInfo default_aux_info = {
+ -1, -1,
+ GTK_ALIGN_FILL,
+ GTK_ALIGN_FILL,
+ { 0, 0, 0, 0 }
+};
+
/*
* _gtk_widget_get_aux_info:
* @widget: a #GtkWidget
aux_info = g_object_get_qdata (G_OBJECT (widget), quark_aux_info);
if (!aux_info && create)
{
- aux_info = g_slice_new (GtkWidgetAuxInfo);
+ aux_info = g_slice_new0 (GtkWidgetAuxInfo);
+
+ *aux_info = default_aux_info;
- aux_info->width = -1;
- aux_info->height = -1;
- aux_info->x = 0;
- aux_info->y = 0;
- aux_info->x_set = FALSE;
- aux_info->y_set = FALSE;
g_object_set_qdata (G_OBJECT (widget), quark_aux_info, aux_info);
}
return aux_info;
}
+static const GtkWidgetAuxInfo*
+_gtk_widget_get_aux_info_or_defaults (GtkWidget *widget)
+{
+ GtkWidgetAuxInfo *aux_info;
+
+ aux_info = _gtk_widget_get_aux_info (widget, FALSE);
+ if (aux_info == NULL)
+ {
+ return &default_aux_info;
+ }
+ else
+ {
+ return aux_info;
+ }
+}
+
/*****************************************
* gtk_widget_aux_info_destroy:
*
g_slice_free (GtkWidgetAuxInfo, aux_info);
}
-static void
-gtk_widget_shape_info_destroy (GtkWidgetShapeInfo *info)
-{
- g_object_unref (info->shape_mask);
- g_slice_free (GtkWidgetShapeInfo, info);
-}
-
/**
- * gtk_widget_shape_combine_mask:
+ * gtk_widget_shape_combine_region:
* @widget: a #GtkWidget
- * @shape_mask: (allow-none): shape to be added, or %NULL to remove an existing shape
- * @offset_x: X position of shape mask with respect to @window
- * @offset_y: Y position of shape mask with respect to @window
+ * @region: (allow-none): shape to be added, or %NULL to remove an existing shape
*
* Sets a shape for this widget's GDK window. This allows for
- * transparent windows etc., see gdk_window_shape_combine_mask()
+ * transparent windows etc., see gdk_window_shape_combine_region()
* for more information.
+ *
+ * Since: 3.0
**/
void
-gtk_widget_shape_combine_mask (GtkWidget *widget,
- GdkBitmap *shape_mask,
- gint offset_x,
- gint offset_y)
+gtk_widget_shape_combine_region (GtkWidget *widget,
+ cairo_region_t *region)
{
- GtkWidgetShapeInfo* shape_info;
+ GtkWidgetPrivate *priv;
g_return_if_fail (GTK_IS_WIDGET (widget));
/* set_shape doesn't work on widgets without gdk window */
g_return_if_fail (gtk_widget_get_has_window (widget));
- if (!shape_mask)
+ priv = widget->priv;
+
+ if (region == NULL)
{
GTK_PRIVATE_UNSET_FLAG (widget, GTK_HAS_SHAPE_MASK);
- if (widget->window)
- gdk_window_shape_combine_mask (widget->window, NULL, 0, 0);
+ if (priv->window)
+ gdk_window_shape_combine_region (priv->window, NULL, 0, 0);
g_object_set_qdata (G_OBJECT (widget), quark_shape_info, NULL);
}
{
GTK_PRIVATE_SET_FLAG (widget, GTK_HAS_SHAPE_MASK);
- shape_info = g_slice_new (GtkWidgetShapeInfo);
- g_object_set_qdata_full (G_OBJECT (widget), quark_shape_info, shape_info,
- (GDestroyNotify) gtk_widget_shape_info_destroy);
-
- shape_info->shape_mask = g_object_ref (shape_mask);
- shape_info->offset_x = offset_x;
- shape_info->offset_y = offset_y;
+ g_object_set_qdata_full (G_OBJECT (widget), quark_shape_info,
+ cairo_region_copy (region),
+ (GDestroyNotify) cairo_region_destroy);
/* set shape if widget has a gdk window already.
* otherwise the shape is scheduled to be set by gtk_widget_realize().
*/
- if (widget->window)
- gdk_window_shape_combine_mask (widget->window, shape_mask,
- offset_x, offset_y);
+ if (priv->window)
+ gdk_window_shape_combine_region (priv->window, region, 0, 0);
}
}
/**
- * gtk_widget_input_shape_combine_mask:
+ * gtk_widget_input_shape_combine_region:
* @widget: a #GtkWidget
- * @shape_mask: (allow-none): shape to be added, or %NULL to remove an existing shape
- * @offset_x: X position of shape mask with respect to @window
- * @offset_y: Y position of shape mask with respect to @window
+ * @region: (allow-none): shape to be added, or %NULL to remove an existing shape
*
* Sets an input shape for this widget's GDK window. This allows for
* windows which react to mouse click in a nonrectangular region, see
- * gdk_window_input_shape_combine_mask() for more information.
+ * gdk_window_input_shape_combine_region() for more information.
*
- * Since: 2.10
+ * Since: 3.0
**/
void
-gtk_widget_input_shape_combine_mask (GtkWidget *widget,
- GdkBitmap *shape_mask,
- gint offset_x,
- gint offset_y)
+gtk_widget_input_shape_combine_region (GtkWidget *widget,
+ cairo_region_t *region)
{
- GtkWidgetShapeInfo* shape_info;
+ GtkWidgetPrivate *priv;
g_return_if_fail (GTK_IS_WIDGET (widget));
/* set_shape doesn't work on widgets without gdk window */
g_return_if_fail (gtk_widget_get_has_window (widget));
- if (!shape_mask)
+ priv = widget->priv;
+
+ if (region == NULL)
{
- if (widget->window)
- gdk_window_input_shape_combine_mask (widget->window, NULL, 0, 0);
+ if (priv->window)
+ gdk_window_input_shape_combine_region (priv->window, NULL, 0, 0);
g_object_set_qdata (G_OBJECT (widget), quark_input_shape_info, NULL);
}
else
{
- shape_info = g_slice_new (GtkWidgetShapeInfo);
g_object_set_qdata_full (G_OBJECT (widget), quark_input_shape_info,
- shape_info,
- (GDestroyNotify) gtk_widget_shape_info_destroy);
-
- shape_info->shape_mask = g_object_ref (shape_mask);
- shape_info->offset_x = offset_x;
- shape_info->offset_y = offset_y;
+ cairo_region_copy (region),
+ (GDestroyNotify) cairo_region_destroy);
/* set shape if widget has a gdk window already.
* otherwise the shape is scheduled to be set by gtk_widget_realize().
*/
- if (widget->window)
- gdk_window_input_shape_combine_mask (widget->window, shape_mask,
- offset_x, offset_y);
+ if (priv->window)
+ gdk_window_input_shape_combine_region (priv->window, region, 0, 0);
}
}
if (data != widget)
return;
- gdk_window_shape_combine_mask (window, NULL, 0, 0);
+ gdk_window_shape_combine_region (window, NULL, 0, 0);
for (list = gdk_window_peek_children (window); list; list = list->next)
gtk_reset_shapes_recurse (widget, list->data);
}
void
gtk_widget_reset_shapes (GtkWidget *widget)
{
- g_return_if_fail (GTK_IS_WIDGET (widget));
- g_return_if_fail (gtk_widget_get_realized (widget));
-
- if (!GTK_WIDGET_HAS_SHAPE_MASK (widget))
- gtk_reset_shapes_recurse (widget, widget->window);
-}
+ GtkWidgetPrivate *priv;
-/**
- * gtk_widget_ref:
- * @widget: a #GtkWidget
- *
- * Adds a reference to a widget. This function is exactly the same
- * as calling g_object_ref(), and exists mostly for historical
- * reasons. It can still be convenient to avoid casting a widget
- * to a #GObject, it saves a small amount of typing.
- *
- * Return value: the widget that was referenced
- *
- * Deprecated: 2.12: Use g_object_ref() instead.
- **/
-GtkWidget*
-gtk_widget_ref (GtkWidget *widget)
-{
- g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
-
- return (GtkWidget*) g_object_ref ((GObject*) widget);
-}
-
-/**
- * gtk_widget_unref:
- * @widget: a #GtkWidget
- *
- * Inverse of gtk_widget_ref(). Equivalent to g_object_unref().
- *
- * Deprecated: 2.12: Use g_object_unref() instead.
- **/
-void
-gtk_widget_unref (GtkWidget *widget)
-{
g_return_if_fail (GTK_IS_WIDGET (widget));
+ g_return_if_fail (gtk_widget_get_realized (widget));
- g_object_unref ((GObject*) widget);
-}
-
-static void
-expose_window (GdkWindow *window)
-{
- GdkEvent event;
- GList *l, *children;
- gpointer user_data;
- gboolean is_double_buffered;
-
- gdk_window_get_user_data (window, &user_data);
-
- if (user_data)
- is_double_buffered = gtk_widget_get_double_buffered (GTK_WIDGET (user_data));
- else
- is_double_buffered = FALSE;
-
- event.expose.type = GDK_EXPOSE;
- event.expose.window = g_object_ref (window);
- event.expose.send_event = FALSE;
- event.expose.count = 0;
- event.expose.area.x = 0;
- event.expose.area.y = 0;
- gdk_drawable_get_size (GDK_DRAWABLE (window),
- &event.expose.area.width,
- &event.expose.area.height);
- event.expose.region = gdk_region_rectangle (&event.expose.area);
-
- /* If this is not double buffered, force a double buffer so that
- redirection works. */
- if (!is_double_buffered)
- gdk_window_begin_paint_region (window, event.expose.region);
-
- gtk_main_do_event (&event);
-
- if (!is_double_buffered)
- gdk_window_end_paint (window);
-
- children = gdk_window_peek_children (window);
- for (l = children; l != NULL; l = l->next)
- {
- GdkWindow *child = l->data;
-
- /* Don't expose input-only windows */
- if (gdk_drawable_get_depth (GDK_DRAWABLE (child)) != 0)
- expose_window (l->data);
- }
-
- g_object_unref (window);
-}
-
-/**
- * gtk_widget_get_snapshot:
- * @widget: a #GtkWidget
- * @clip_rect: (allow-none): a #GdkRectangle or %NULL
- *
- * Create a #GdkPixmap of the contents of the widget and its children.
- *
- * Works even if the widget is obscured. The depth and visual of the
- * resulting pixmap is dependent on the widget being snapshot and likely
- * differs from those of a target widget displaying the pixmap.
- * The function gdk_pixbuf_get_from_drawable() can be used to convert
- * the pixmap to a visual independant representation.
- *
- * The snapshot area used by this function is the @widget's allocation plus
- * any extra space occupied by additional windows belonging to this widget
- * (such as the arrows of a spin button).
- * Thus, the resulting snapshot pixmap is possibly larger than the allocation.
- *
- * If @clip_rect is non-%NULL, the resulting pixmap is shrunken to
- * match the specified clip_rect. The (x,y) coordinates of @clip_rect are
- * interpreted widget relative. If width or height of @clip_rect are 0 or
- * negative, the width or height of the resulting pixmap will be shrunken
- * by the respective amount.
- * For instance a @clip_rect <literal>{ +5, +5, -10, -10 }</literal> will
- * chop off 5 pixels at each side of the snapshot pixmap.
- * If non-%NULL, @clip_rect will contain the exact widget-relative snapshot
- * coordinates upon return. A @clip_rect of <literal>{ -1, -1, 0, 0 }</literal>
- * can be used to preserve the auto-grown snapshot area and use @clip_rect
- * as a pure output parameter.
- *
- * The returned pixmap can be %NULL, if the resulting @clip_area was empty.
- *
- * Return value: #GdkPixmap snapshot of the widget
- *
- * Since: 2.14
- **/
-GdkPixmap*
-gtk_widget_get_snapshot (GtkWidget *widget,
- GdkRectangle *clip_rect)
-{
- int x, y, width, height;
- GdkWindow *parent_window = NULL;
- GdkPixmap *pixmap;
- GList *windows = NULL, *list;
-
- g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
- if (!gtk_widget_get_visible (widget))
- return NULL;
-
- /* the widget (and parent_window) must be realized to be drawable */
- if (widget->parent && !gtk_widget_get_realized (widget->parent))
- gtk_widget_realize (widget->parent);
- if (!gtk_widget_get_realized (widget))
- gtk_widget_realize (widget);
-
- /* determine snapshot rectangle */
- x = widget->allocation.x;
- y = widget->allocation.y;
- width = widget->allocation.width;
- height = widget->allocation.height;
-
- if (widget->parent && gtk_widget_get_has_window (widget))
- {
- /* grow snapshot rectangle to cover all widget windows */
- parent_window = gtk_widget_get_parent_window (widget);
- for (list = gdk_window_peek_children (parent_window); list; list = list->next)
- {
- GdkWindow *subwin = list->data;
- gpointer windata;
- int wx, wy, ww, wh;
- gdk_window_get_user_data (subwin, &windata);
- if (windata != widget)
- continue;
- windows = g_list_prepend (windows, subwin);
- gdk_window_get_position (subwin, &wx, &wy);
- gdk_drawable_get_size (subwin, &ww, &wh);
- /* grow snapshot rectangle by extra widget sub window */
- if (wx < x)
- {
- width += x - wx;
- x = wx;
- }
- if (wy < y)
- {
- height += y - wy;
- y = wy;
- }
- if (x + width < wx + ww)
- width += wx + ww - (x + width);
- if (y + height < wy + wh)
- height += wy + wh - (y + height);
- }
- }
- else if (!widget->parent)
- x = y = 0; /* toplevel */
-
- /* at this point, (x,y,width,height) is the parent_window relative
- * snapshot area covering all of widget's windows.
- */
-
- /* shrink snapshot size by clip_rectangle */
- if (clip_rect)
- {
- GdkRectangle snap = { x, y, width, height }, clip = *clip_rect;
- clip.x = clip.x < 0 ? x : clip.x;
- clip.y = clip.y < 0 ? y : clip.y;
- clip.width = clip.width <= 0 ? MAX (0, width + clip.width) : clip.width;
- clip.height = clip.height <= 0 ? MAX (0, height + clip.height) : clip.height;
- if (widget->parent)
- {
- /* offset clip_rect, so it's parent_window relative */
- if (clip_rect->x >= 0)
- clip.x += widget->allocation.x;
- if (clip_rect->y >= 0)
- clip.y += widget->allocation.y;
- }
- if (!gdk_rectangle_intersect (&snap, &clip, &snap))
- {
- g_list_free (windows);
- clip_rect->width = clip_rect->height = 0;
- return NULL; /* empty snapshot area */
- }
- x = snap.x;
- y = snap.y;
- width = snap.width;
- height = snap.height;
- }
-
- /* render snapshot */
- pixmap = gdk_pixmap_new (widget->window, width, height, gdk_drawable_get_depth (widget->window));
- for (list = windows; list; list = list->next) /* !NO_WINDOW widgets */
- {
- GdkWindow *subwin = list->data;
- int wx, wy;
- if (gdk_drawable_get_depth (GDK_DRAWABLE (subwin)) == 0)
- continue; /* Input only window */
- gdk_window_get_position (subwin, &wx, &wy);
- gdk_window_redirect_to_drawable (subwin, pixmap, MAX (0, x - wx), MAX (0, y - wy),
- MAX (0, wx - x), MAX (0, wy - y), width, height);
-
- expose_window (subwin);
- }
- if (!windows) /* NO_WINDOW || toplevel => parent_window == NULL || parent_window == widget->window */
- {
- gdk_window_redirect_to_drawable (widget->window, pixmap, x, y, 0, 0, width, height);
- expose_window (widget->window);
- }
- for (list = windows; list; list = list->next)
- gdk_window_remove_redirection (list->data);
- if (!windows) /* NO_WINDOW || toplevel */
- gdk_window_remove_redirection (widget->window);
- g_list_free (windows);
+ priv = widget->priv;
- /* return pixmap and snapshot rectangle coordinates */
- if (clip_rect)
- {
- clip_rect->x = x;
- clip_rect->y = y;
- clip_rect->width = width;
- clip_rect->height = height;
- if (widget->parent)
- {
- /* offset clip_rect from parent_window so it's widget relative */
- clip_rect->x -= widget->allocation.x;
- clip_rect->y -= widget->allocation.y;
- }
- if (0)
- g_printerr ("gtk_widget_get_snapshot: %s (%d,%d, %dx%d)\n",
- G_OBJECT_TYPE_NAME (widget),
- clip_rect->x, clip_rect->y, clip_rect->width, clip_rect->height);
- }
- return pixmap;
+ if (!GTK_WIDGET_HAS_SHAPE_MASK (widget))
+ gtk_reset_shapes_recurse (widget, priv->window);
}
/* style properties
const gchar *property_name,
GValue *value)
{
+ GtkWidgetPrivate *priv;
GParamSpec *pspec;
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (property_name != NULL);
g_return_if_fail (G_IS_VALUE (value));
+ priv = widget->priv;
+
g_object_ref (widget);
pspec = g_param_spec_pool_lookup (style_property_spec_pool,
property_name,
{
const GValue *peek_value;
- peek_value = _gtk_style_peek_property_value (widget->style,
+ peek_value = _gtk_style_peek_property_value (priv->style,
G_OBJECT_TYPE (widget),
pspec,
(GtkRcPropertyParser) g_param_spec_get_qdata (pspec, quark_property_parser));
const gchar *first_property_name,
va_list var_args)
{
+ GtkWidgetPrivate *priv;
const gchar *name;
g_return_if_fail (GTK_IS_WIDGET (widget));
+ priv = widget->priv;
+
g_object_ref (widget);
name = first_property_name;
}
/* style pspecs are always readable so we can spare that check here */
- peek_value = _gtk_style_peek_property_value (widget->style,
+ peek_value = _gtk_style_peek_property_value (priv->style,
G_OBJECT_TYPE (widget),
pspec,
(GtkRcPropertyParser) g_param_spec_get_qdata (pspec, quark_property_parser));
guint len;
g_return_if_fail (GTK_IS_WIDGET (widget));
-
+
len = 0;
do
{
while (s >= string)
*(d++) = *(s--);
len += l;
-
- widget = widget->parent;
-
+
+ widget = widget->priv->parent;
+
if (widget)
rev_path[len++] = '.';
else
* gtk_widget_class_path:
* @widget: a #GtkWidget
* @path_length: (out) (allow-none): location to store the length of the class path, or %NULL
- * @path: (out) (allow-none) location to store the class path as an allocated string, or %NULL
- * @path_reversed: (out) (allow-none) location to store the reverse class path as an allocated
+ * @path: (out) (allow-none): location to store the class path as an allocated string, or %NULL
+ * @path_reversed: (out) (allow-none): location to store the reverse class path as an allocated
* string, or %NULL
*
* Same as gtk_widget_path(), but always uses the name of a widget's type,
guint len;
g_return_if_fail (GTK_IS_WIDGET (widget));
-
+
len = 0;
do
{
while (s >= string)
*(d++) = *(s--);
len += l;
-
- widget = widget->parent;
-
+
+ widget = widget->priv->parent;
+
if (widget)
rev_path[len++] = '.';
else
}
}
+/**
+ * gtk_requisition_new:
+ *
+ * Allocates a new #GtkRequisition structure and initializes its elements to zero.
+ *
+ * Returns: a new empty #GtkRequisition. The newly allocated #GtkRequisition should
+ * be freed with gtk_requisition_free().
+ *
+ * Since: 3.0
+ */
+GtkRequisition *
+gtk_requisition_new (void)
+{
+ return g_slice_new0 (GtkRequisition);
+}
+
/**
* gtk_requisition_copy:
* @requisition: a #GtkRequisition
GtkRequisition *
gtk_requisition_copy (const GtkRequisition *requisition)
{
- return (GtkRequisition *)g_memdup (requisition, sizeof (GtkRequisition));
+ return g_slice_dup (GtkRequisition, requisition);
}
/**
void
gtk_requisition_free (GtkRequisition *requisition)
{
- g_free (requisition);
+ g_slice_free (GtkRequisition, requisition);
}
-GType
-gtk_requisition_get_type (void)
-{
- static GType our_type = 0;
-
- if (our_type == 0)
- our_type = g_boxed_type_register_static (I_("GtkRequisition"),
- (GBoxedCopyFunc) gtk_requisition_copy,
- (GBoxedFreeFunc) gtk_requisition_free);
-
- return our_type;
-}
+G_DEFINE_BOXED_TYPE (GtkRequisition, gtk_requisition,
+ gtk_requisition_copy,
+ gtk_requisition_free)
/**
* gtk_widget_get_accessible:
* @widget: a #GtkWidget
*
* Returns the accessible object that describes the widget to an
- * assistive technology.
- *
- * If no accessibility library is loaded (i.e. no ATK implementation library is
- * loaded via <envar>GTK_MODULES</envar> or via another application library,
- * such as libgnome), then this #AtkObject instance may be a no-op. Likewise,
- * if no class-specific #AtkObject implementation is available for the widget
- * instance in question, it will inherit an #AtkObject implementation from the
+ * assistive technology.
+ *
+ * If no accessibility library is loaded (i.e. no ATK implementation library is
+ * loaded via <envar>GTK_MODULES</envar> or via another application library,
+ * such as libgnome), then this #AtkObject instance may be a no-op. Likewise,
+ * if no class-specific #AtkObject implementation is available for the widget
+ * instance in question, it will inherit an #AtkObject implementation from the
* first ancestor class for which such an implementation is defined.
*
* The documentation of the <ulink url="http://developer.gnome.org/doc/API/2.0/atk/index.html">ATK</ulink>
}
}
+/*
+ * GtkSizeRequest implementation
+ */
+static void
+gtk_widget_real_get_width (GtkSizeRequest *widget,
+ gint *minimum_size,
+ gint *natural_size)
+{
+ if (minimum_size)
+ *minimum_size = 0;
+
+ if (natural_size)
+ *natural_size = 0;
+}
+
+static void
+gtk_widget_real_get_height (GtkSizeRequest *widget,
+ gint *minimum_size,
+ gint *natural_size)
+{
+ if (minimum_size)
+ *minimum_size = 0;
+
+ if (natural_size)
+ *natural_size = 0;
+}
+
+static void
+gtk_widget_real_get_height_for_width (GtkSizeRequest *layout,
+ gint width,
+ gint *minimum_height,
+ gint *natural_height)
+{
+ GTK_SIZE_REQUEST_GET_IFACE (layout)->get_height(layout, minimum_height, natural_height);
+}
+
+static void
+gtk_widget_real_get_width_for_height (GtkSizeRequest *layout,
+ gint height,
+ gint *minimum_width,
+ gint *natural_width)
+{
+ GTK_SIZE_REQUEST_GET_IFACE (layout)->get_width(layout, minimum_width, natural_width);
+}
+
+static void
+gtk_widget_size_request_init (GtkSizeRequestIface *iface)
+{
+ iface->get_width = gtk_widget_real_get_width;
+ iface->get_height = gtk_widget_real_get_height;
+ iface->get_width_for_height = gtk_widget_real_get_width_for_height;
+ iface->get_height_for_width = gtk_widget_real_get_height_for_width;
+}
+
+/**
+ * gtk_widget_get_halign:
+ * @widget: a #GtkWidget
+ *
+ * Gets the value of the #GtkWidget:halign property.
+ *
+ * Returns: the horizontal alignment of @widget
+ */
+GtkAlign
+gtk_widget_get_halign (GtkWidget *widget)
+{
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), GTK_ALIGN_FILL);
+ return _gtk_widget_get_aux_info_or_defaults (widget)->halign;
+}
+
+/**
+ * gtk_widget_set_halign:
+ * @widget: a #GtkWidget
+ * @align: the horizontal alignment
+ *
+ * Sets the horizontal alignment of @widget.
+ * See the #GtkWidget:halign property.
+ */
+void
+gtk_widget_set_halign (GtkWidget *widget,
+ GtkAlign align)
+{
+ GtkWidgetAuxInfo *aux_info;
+
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+
+ aux_info = _gtk_widget_get_aux_info (widget, TRUE);
+
+ if (aux_info->halign == align)
+ return;
+
+ aux_info->halign = align;
+ gtk_widget_queue_resize (widget);
+ g_object_notify (G_OBJECT (widget), "halign");
+}
+
+/**
+ * gtk_widget_get_valign:
+ * @widget: a #GtkWidget
+ *
+ * Gets the value of the #GtkWidget:valign property.
+ *
+ * Returns: the vertical alignment of @widget
+ */
+GtkAlign
+gtk_widget_get_valign (GtkWidget *widget)
+{
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), GTK_ALIGN_FILL);
+ return _gtk_widget_get_aux_info_or_defaults (widget)->valign;
+}
+
+/**
+ * gtk_widget_set_valign:
+ * @widget: a #GtkWidget
+ * @align: the vertical alignment
+ *
+ * Sets the vertical alignment of @widget.
+ * See the #GtkWidget:valign property.
+ */
+void
+gtk_widget_set_valign (GtkWidget *widget,
+ GtkAlign align)
+{
+ GtkWidgetAuxInfo *aux_info;
+
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+
+ aux_info = _gtk_widget_get_aux_info (widget, TRUE);
+
+ if (aux_info->valign == align)
+ return;
+
+ aux_info->valign = align;
+ gtk_widget_queue_resize (widget);
+ g_object_notify (G_OBJECT (widget), "valign");
+}
+
+/**
+ * gtk_widget_get_margin_left:
+ * @widget: a #GtkWidget
+ *
+ * Gets the value of the #GtkWidget:margin-left property.
+ *
+ * Returns: The left margin of @widget
+ */
+gint
+gtk_widget_get_margin_left (GtkWidget *widget)
+{
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
+
+ return _gtk_widget_get_aux_info_or_defaults (widget)->margin.left;
+}
+
+/**
+ * gtk_widget_set_margin_left:
+ * @widget: a #GtkWidget
+ * @margin: the left margin
+ *
+ * Sets the left margin of @widget.
+ * See the #GtkWidget:margin-left property.
+ */
+void
+gtk_widget_set_margin_left (GtkWidget *widget,
+ gint margin)
+{
+ GtkWidgetAuxInfo *aux_info;
+
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+ g_return_if_fail (margin <= G_MAXINT16);
+
+ aux_info = _gtk_widget_get_aux_info (widget, TRUE);
+
+ if (aux_info->margin.left == margin)
+ return;
+
+ aux_info->margin.left = margin;
+ gtk_widget_queue_resize (widget);
+ g_object_notify (G_OBJECT (widget), "margin-left");
+}
+
+/**
+ * gtk_widget_get_margin_right:
+ * @widget: a #GtkWidget
+ *
+ * Gets the value of the #GtkWidget:margin-right property.
+ *
+ * Returns: The left margin of @widget
+ */
+gint
+gtk_widget_get_margin_right (GtkWidget *widget)
+{
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
+
+ return _gtk_widget_get_aux_info_or_defaults (widget)->margin.right;
+}
+
+/**
+ * gtk_widget_set_margin_right:
+ * @widget: a #GtkWidget
+ * @margin: the right margin
+ *
+ * Sets the right margin of @widget.
+ * See the #GtkWidget:margin-right property.
+ */
+void
+gtk_widget_set_margin_right (GtkWidget *widget,
+ gint margin)
+{
+ GtkWidgetAuxInfo *aux_info;
+
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+ g_return_if_fail (margin <= G_MAXINT16);
+
+ aux_info = _gtk_widget_get_aux_info (widget, TRUE);
+
+ if (aux_info->margin.right == margin)
+ return;
+
+ aux_info->margin.right = margin;
+ gtk_widget_queue_resize (widget);
+ g_object_notify (G_OBJECT (widget), "margin-right");
+}
+
+/**
+ * gtk_widget_get_margin_top:
+ * @widget: a #GtkWidget
+ *
+ * Gets the value of the #GtkWidget:margin-top property.
+ *
+ * Returns: The top margin of @widget
+ */
+gint
+gtk_widget_get_margin_top (GtkWidget *widget)
+{
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
+
+ return _gtk_widget_get_aux_info_or_defaults (widget)->margin.top;
+}
+
+/**
+ * gtk_widget_set_margin_top:
+ * @widget: a #GtkWidget
+ * @margin: the top margin
+ *
+ * Sets the top margin of @widget.
+ * See the #GtkWidget:margin-top property.
+ */
+void
+gtk_widget_set_margin_top (GtkWidget *widget,
+ gint margin)
+{
+ GtkWidgetAuxInfo *aux_info;
+
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+ g_return_if_fail (margin <= G_MAXINT16);
+
+ aux_info = _gtk_widget_get_aux_info (widget, TRUE);
+
+ if (aux_info->margin.top == margin)
+ return;
+
+ aux_info->margin.top = margin;
+ gtk_widget_queue_resize (widget);
+ g_object_notify (G_OBJECT (widget), "margin-top");
+}
+
+/**
+ * gtk_widget_get_margin_bottom:
+ * @widget: a #GtkWidget
+ *
+ * Gets the value of the #GtkWidget:margin-bottom property.
+ *
+ * Returns: The bottom margin of @widget
+ */
+gint
+gtk_widget_get_margin_bottom (GtkWidget *widget)
+{
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
+
+ return _gtk_widget_get_aux_info_or_defaults (widget)->margin.bottom;
+}
+
+/**
+ * gtk_widget_set_margin_bottom:
+ * @widget: a #GtkWidget
+ * @margin: the bottom margin
+ *
+ * Sets the bottom margin of @widget.
+ * See the #GtkWidget:margin-bottom property.
+ */
+void
+gtk_widget_set_margin_bottom (GtkWidget *widget,
+ gint margin)
+{
+ GtkWidgetAuxInfo *aux_info;
+
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+ g_return_if_fail (margin <= G_MAXINT16);
+
+ aux_info = _gtk_widget_get_aux_info (widget, TRUE);
+
+ if (aux_info->margin.bottom == margin)
+ return;
+
+ aux_info->margin.bottom = margin;
+ gtk_widget_queue_resize (widget);
+ g_object_notify (G_OBJECT (widget), "margin-bottom");
+}
/**
* gtk_widget_get_clipboard:
{
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
g_return_val_if_fail (gtk_widget_has_screen (widget), NULL);
-
+
return gtk_clipboard_get_for_display (gtk_widget_get_display (widget),
selection);
}
/**
* gtk_widget_list_mnemonic_labels:
* @widget: a #GtkWidget
- *
- * Returns a newly allocated list of the widgets, normally labels, for
- * which this widget is a the target of a mnemonic (see for example,
+ *
+ * Returns a newly allocated list of the widgets, normally labels, for
+ * which this widget is the target of a mnemonic (see for example,
* gtk_label_set_mnemonic_widget()).
* The widgets in the list are not individually referenced. If you
gboolean has_tooltip,
gboolean force)
{
+ GtkWidgetPrivate *priv = widget->priv;
gboolean priv_has_tooltip;
priv_has_tooltip = GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (widget),
if (priv_has_tooltip)
{
if (gtk_widget_get_realized (widget) && !gtk_widget_get_has_window (widget))
- gdk_window_set_events (widget->window,
- gdk_window_get_events (widget->window) |
+ gdk_window_set_events (priv->window,
+ gdk_window_get_events (priv->window) |
GDK_LEAVE_NOTIFY_MASK |
GDK_POINTER_MOTION_MASK |
GDK_POINTER_MOTION_HINT_MASK);
*
* Retrieves the widget's allocation.
*
+ * Note, when implementing a #GtkContainer: a widget's allocation will
+ * be its "adjusted" allocation, that is, the widget's parent
+ * container typically calls gtk_widget_size_allocate() with an
+ * allocation, and that allocation is then adjusted (to handle margin
+ * and alignment for example) before assignment to the widget.
+ * gtk_widget_get_allocation() returns the adjusted allocation that
+ * was actually assigned to the widget. The adjusted allocation is
+ * guaranteed to be completely contained within the
+ * gtk_widget_size_allocate() allocation, however. So a #GtkContainer
+ * is guaranteed that its children stay inside the assigned bounds,
+ * but not that they have exactly the bounds the container assigned.
+ * There is no way to get the original allocation assigned by
+ * gtk_widget_size_allocate(), since it isn't stored; if a container
+ * implementation needs that information it will have to track it itself.
+ *
* Since: 2.18
*/
void
gtk_widget_get_allocation (GtkWidget *widget,
GtkAllocation *allocation)
{
+ GtkWidgetPrivate *priv;
+
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (allocation != NULL);
- *allocation = widget->allocation;
+ priv = widget->priv;
+
+ *allocation = priv->allocation;
}
/**
* Sets the widget's allocation. This should not be used
* directly, but from within a widget's size_allocate method.
*
+ * The allocation set should be the "adjusted" or actual
+ * allocation. If you're implementing a #GtkContainer, you want to use
+ * gtk_widget_size_allocate() instead of gtk_widget_set_allocation().
+ * The GtkWidgetClass::adjust_size_allocation virtual method adjusts the
+ * allocation inside gtk_widget_size_allocate() to create an adjusted
+ * allocation.
+ *
* Since: 2.18
*/
void
gtk_widget_set_allocation (GtkWidget *widget,
const GtkAllocation *allocation)
{
+ GtkWidgetPrivate *priv;
+
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (allocation != NULL);
- widget->allocation = *allocation;
+ priv = widget->priv;
+
+ priv->allocation = *allocation;
+}
+
+/**
+ * gtk_widget_get_allocated_width:
+ * @widget: the widget to query
+ *
+ * Returns the width that has currently been allocated to @widget.
+ * This function is intended to be used when implementing handlers
+ * for the GtkWidget::draw function.
+ *
+ * Returns: the width of the @widget
+ **/
+int
+gtk_widget_get_allocated_width (GtkWidget *widget)
+{
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
+
+ return widget->priv->allocation.width;
+}
+
+/**
+ * gtk_widget_get_allocated_height:
+ * @widget: the widget to query
+ *
+ * Returns the height that has currently been allocated to @widget.
+ * This function is intended to be used when implementing handlers
+ * for the GtkWidget::draw function.
+ *
+ * Returns: the height of the @widget
+ **/
+int
+gtk_widget_get_allocated_height (GtkWidget *widget)
+{
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
+
+ return widget->priv->allocation.height;
}
/**
* Normally, gtk_widget_size_request() should be used.
*
* Since: 2.20
+ *
+ * Deprecated: 3.0: The #GtkRequisition cache on the widget was
+ * removed, If you need to cache sizes across requests and allocations,
+ * add an explicit cache to the widget in question instead.
*/
void
gtk_widget_get_requisition (GtkWidget *widget,
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (requisition != NULL);
- *requisition = widget->requisition;
+ gtk_size_request_get_size (GTK_SIZE_REQUEST (widget), requisition, NULL);
}
/**
* by calling gtk_widget_set_has_window(). This is usually done in the
* widget's init() function.
*
+ * <note><para>This function does not add any reference to @window.</para></note>
+ *
* Since: 2.18
*/
void
gtk_widget_set_window (GtkWidget *widget,
GdkWindow *window)
{
+ GtkWidgetPrivate *priv;
+
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
- if (widget->window != window)
+ priv = widget->priv;
+
+ if (priv->window != window)
{
- widget->window = window;
+ priv->window = window;
g_object_notify (G_OBJECT (widget), "window");
}
}
*
* Returns the widget's window if it is realized, %NULL otherwise
*
- * Return value: @widget's window.
+ * Return value: (transfer none): @widget's window.
*
* Since: 2.14
*/
{
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
- return widget->window;
+ return widget->priv->window;
+}
+
+/**
+ * gtk_widget_get_support_multidevice:
+ * @widget: a #GtkWidget
+ *
+ * Returns %TRUE if @widget is multiple pointer aware. See
+ * gtk_widget_set_support_multidevice() for more information.
+ *
+ * Returns: %TRUE is @widget is multidevice aware.
+ **/
+gboolean
+gtk_widget_get_support_multidevice (GtkWidget *widget)
+{
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
+
+ return GTK_WIDGET_FLAGS (widget) & GTK_MULTIDEVICE;
+}
+
+/**
+ * gtk_widget_set_support_multidevice:
+ * @widget: a #GtkWidget
+ * @support_multidevice: %TRUE to support input from multiple devices.
+ *
+ * Enables or disables multiple pointer awareness. If this setting is %TRUE,
+ * @widget will start receiving multiple, per device enter/leave events. Note
+ * that if custom #GdkWindow<!-- -->s are created in #GtkWidget::realize,
+ * gdk_window_set_support_multidevice() will have to be called manually on them.
+ *
+ * Since: 3.0
+ **/
+void
+gtk_widget_set_support_multidevice (GtkWidget *widget,
+ gboolean support_multidevice)
+{
+ GtkWidgetPrivate *priv;
+
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+
+ priv = widget->priv;
+
+ if (support_multidevice)
+ {
+ GTK_WIDGET_SET_FLAGS (widget, GTK_MULTIDEVICE);
+ gtk_widget_set_extension_events (widget, GDK_EXTENSION_EVENTS_ALL);
+ }
+ else
+ {
+ GTK_WIDGET_UNSET_FLAGS (widget, GTK_MULTIDEVICE);
+ gtk_widget_set_extension_events (widget, GDK_EXTENSION_EVENTS_NONE);
+ }
+
+ if (gtk_widget_get_realized (widget))
+ gdk_window_set_support_multidevice (priv->window, support_multidevice);
}
static void
return res;
}
-
-#define __GTK_WIDGET_C__
-#include "gtkaliasdef.c"