* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
+#include <config.h>
#include <stdarg.h>
#include <string.h>
#include <locale.h>
+#include "gtkalias.h"
#include "gtkcontainer.h"
#include "gtkaccelmap.h"
#include "gtkclipboard.h"
SHOW_HELP,
ACCEL_CLOSURES_CHANGED,
SCREEN_CHANGED,
+ CAN_ACTIVATE_ACCEL,
LAST_SIGNAL
};
PROP_COMPOSITE_CHILD,
PROP_STYLE,
PROP_EVENTS,
- PROP_EXTENSION_EVENTS
+ PROP_EXTENSION_EVENTS,
+ PROP_NO_SHOW_ALL
};
typedef struct _GtkStateData GtkStateData;
GdkRegion *region);
static GdkScreen * gtk_widget_get_screen_unchecked (GtkWidget *widget);
static void gtk_widget_queue_shallow_draw (GtkWidget *widget);
-
+static gboolean gtk_widget_real_can_activate_accel (GtkWidget *widget,
+ guint signal_id);
+
static void gtk_widget_set_usize_internal (GtkWidget *widget,
gint width,
gint height);
static GQuark quark_pango_context = 0;
static GQuark quark_rc_style = 0;
static GQuark quark_accessible_object = 0;
+static GQuark quark_mnemonic_labels = 0;
GParamSpecPool *_gtk_widget_child_property_pool = NULL;
GObjectNotifyContext *_gtk_widget_child_property_notify_context = NULL;
quark_pango_context = g_quark_from_static_string ("gtk-pango-context");
quark_rc_style = g_quark_from_static_string ("gtk-rc-style");
quark_accessible_object = g_quark_from_static_string ("gtk-accessible-object");
+ quark_mnemonic_labels = g_quark_from_static_string ("gtk-mnemonic-labels");
style_property_spec_pool = g_param_spec_pool_new (FALSE);
_gtk_widget_child_property_pool = g_param_spec_pool_new (TRUE);
klass->drag_drop = NULL;
klass->drag_data_received = NULL;
klass->screen_changed = NULL;
+ klass->can_activate_accel = gtk_widget_real_can_activate_accel;
klass->show_help = gtk_widget_real_show_help;
g_object_class_install_property (gobject_class,
PROP_NAME,
g_param_spec_string ("name",
- _("Widget name"),
- _("The name of the widget"),
+ P_("Widget name"),
+ P_("The name of the widget"),
NULL,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
PROP_PARENT,
g_param_spec_object ("parent",
- _("Parent widget"),
- _("The parent widget of this widget. Must be a Container widget"),
+ P_("Parent widget"),
+ P_("The parent widget of this widget. Must be a Container widget"),
GTK_TYPE_CONTAINER,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
PROP_WIDTH_REQUEST,
g_param_spec_int ("width_request",
- _("Width request"),
- _("Override for width request of the widget, or -1 if natural request should be used"),
+ P_("Width request"),
+ P_("Override for width request of the widget, or -1 if natural request should be used"),
-1,
G_MAXINT,
-1,
g_object_class_install_property (gobject_class,
PROP_HEIGHT_REQUEST,
g_param_spec_int ("height_request",
- _("Height request"),
- _("Override for height request of the widget, or -1 if natural request should be used"),
+ P_("Height request"),
+ P_("Override for height request of the widget, or -1 if natural request should be used"),
-1,
G_MAXINT,
-1,
g_object_class_install_property (gobject_class,
PROP_VISIBLE,
g_param_spec_boolean ("visible",
- _("Visible"),
- _("Whether the widget is visible"),
+ P_("Visible"),
+ P_("Whether the widget is visible"),
FALSE,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
PROP_SENSITIVE,
g_param_spec_boolean ("sensitive",
- _("Sensitive"),
- _("Whether the widget responds to input"),
+ P_("Sensitive"),
+ P_("Whether the widget responds to input"),
TRUE,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
PROP_APP_PAINTABLE,
g_param_spec_boolean ("app_paintable",
- _("Application paintable"),
- _("Whether the application will paint directly on the widget"),
+ P_("Application paintable"),
+ P_("Whether the application will paint directly on the widget"),
FALSE,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
PROP_CAN_FOCUS,
g_param_spec_boolean ("can_focus",
- _("Can focus"),
- _("Whether the widget can accept the input focus"),
+ P_("Can focus"),
+ P_("Whether the widget can accept the input focus"),
FALSE,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
PROP_HAS_FOCUS,
g_param_spec_boolean ("has_focus",
- _("Has focus"),
- _("Whether the widget has the input focus"),
+ P_("Has focus"),
+ P_("Whether the widget has the input focus"),
FALSE,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
PROP_IS_FOCUS,
g_param_spec_boolean ("is_focus",
- _("Is focus"),
- _("Whether the widget is the focus widget within the toplevel"),
+ P_("Is focus"),
+ P_("Whether the widget is the focus widget within the toplevel"),
FALSE,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
PROP_CAN_DEFAULT,
g_param_spec_boolean ("can_default",
- _("Can default"),
- _("Whether the widget can be the default widget"),
+ P_("Can default"),
+ P_("Whether the widget can be the default widget"),
FALSE,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
PROP_HAS_DEFAULT,
g_param_spec_boolean ("has_default",
- _("Has default"),
- _("Whether the widget is the default widget"),
+ P_("Has default"),
+ P_("Whether the widget is the default widget"),
FALSE,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
PROP_RECEIVES_DEFAULT,
g_param_spec_boolean ("receives_default",
- _("Receives default"),
- _("If TRUE, the widget will receive the default action when it is focused"),
+ P_("Receives default"),
+ P_("If TRUE, the widget will receive the default action when it is focused"),
FALSE,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
PROP_COMPOSITE_CHILD,
g_param_spec_boolean ("composite_child",
- _("Composite child"),
- _("Whether the widget is part of a composite widget"),
+ P_("Composite child"),
+ P_("Whether the widget is part of a composite widget"),
FALSE,
G_PARAM_READABLE));
g_object_class_install_property (gobject_class,
PROP_STYLE,
g_param_spec_object ("style",
- _("Style"),
- _("The style of the widget, which contains information about how it will look (colors etc)"),
+ P_("Style"),
+ P_("The style of the widget, which contains information about how it will look (colors etc)"),
GTK_TYPE_STYLE,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
PROP_EVENTS,
g_param_spec_flags ("events",
- _("Events"),
- _("The event mask that decides what kind of GdkEvents this widget gets"),
+ P_("Events"),
+ P_("The event mask that decides what kind of GdkEvents this widget gets"),
GDK_TYPE_EVENT_MASK,
GDK_STRUCTURE_MASK,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
PROP_EXTENSION_EVENTS,
g_param_spec_enum ("extension_events",
- _("Extension events"),
- _("The mask that decides what kind of extension events this widget gets"),
+ P_("Extension events"),
+ P_("The mask that decides what kind of extension events this widget gets"),
GDK_TYPE_EXTENSION_MODE,
GDK_EXTENSION_EVENTS_NONE,
G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class,
+ PROP_NO_SHOW_ALL,
+ g_param_spec_boolean ("no_show_all",
+ P_("No show all"),
+ P_("Whether gtk_widget_show_all() should not affect this widget"),
+ FALSE,
+ G_PARAM_READWRITE));
widget_signals[SHOW] =
g_signal_new ("show",
G_TYPE_FROM_CLASS (gobject_class),
_gtk_marshal_BOOLEAN__BOXED,
G_TYPE_BOOLEAN, 1,
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
+
+ /**
+ * GtkWidget::drag-leave:
+ * @widget: the object which received the signal.
+ * @drag_context: the drag context
+ * @time: the timestamp of the motion event
+ *
+ * The ::drag-leave signal is emitted on the drop site when the cursor leaves the widget.
+ * A typical reason to connect to this signal is to undo things done in ::drag-motion, e.g.
+ * undo highlighting with gtk_drag_unhighlight()
+ */
widget_signals[DRAG_LEAVE] =
g_signal_new ("drag_leave",
G_TYPE_FROM_CLASS (gobject_class),
G_TYPE_NONE, 2,
GDK_TYPE_DRAG_CONTEXT,
G_TYPE_UINT);
+
+ /**
+ * GtkWidget::drag-begin:
+ * @widget: the object which received the signal.
+ * @drag_context: the drag context
+ *
+ * The ::drag-begin signal is emitted on the drag source when a drag is started.
+ * A typical reason to connect to this signal is to set up a custom drag icon with
+ * gtk_drag_source_set_icon().
+ */
widget_signals[DRAG_BEGIN] =
g_signal_new ("drag_begin",
G_TYPE_FROM_CLASS (gobject_class),
_gtk_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
GDK_TYPE_DRAG_CONTEXT);
+
+ /**
+ * GtkWidget::drag-end:
+ * @widget: the object which received the signal.
+ * @drag_context: the drag context
+ *
+ * The ::drag-end signal is emitted on the drag source when a drag is finished.
+ * A typical reason to connect to this signal is to undo things done in ::drag-begin.
+ */
widget_signals[DRAG_END] =
g_signal_new ("drag_end",
G_TYPE_FROM_CLASS (gobject_class),
_gtk_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
GDK_TYPE_DRAG_CONTEXT);
+
+ /**
+ * GtkWidget::drag-data-delete:
+ * @widget: the object which received the signal.
+ * @drag_context: the drag context
+ *
+ * The ::drag-data-delete signal is emitted on the drag source when a drag with the action
+ * %GDK_ACTION_MOVE is successfully completed. The signal handler is responsible for deleting
+ * the data that has been dropped. What "delete" means, depends on the context of the drag
+ * operation.
+ */
widget_signals[DRAG_DATA_DELETE] =
g_signal_new ("drag_data_delete",
G_TYPE_FROM_CLASS (gobject_class),
_gtk_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
GDK_TYPE_DRAG_CONTEXT);
+
+ /**
+ * GtkWidget::drag-motion:
+ * @widget: the object which received the signal.
+ * @drag_context: the drag context
+ * @x: the x coordinate of the current cursor position
+ * @y: the y coordinate of the current cursor position
+ * @time: the timestamp of the motion event
+ * @returns: whether the cursor position is in a drop zone
+ *
+ * The ::drag-motion signal is emitted on the drop site when the user moves the cursor over
+ * the widget during a drag. The signal handler must determine whether the cursor position is in
+ * a drop zone or not. If it is not in a drop zone, it returns %FALSE and no further processing is
+ * necessary. Otherwise, the handler returns %TRUE. In this case, the handler is responsible for
+ * providing the necessary information for displaying feedback to the user, by calling
+ * gdk_drag_status(). If the decision whether the drop will be accepted or rejected can't be made
+ * based solely on the cursor position and the type of the data, the handler may inspect the dragged
+ * data by calling gtk_drag_get_data() and defer the gdk_drag_status() call to the ::drag-data-received
+ * handler.
+ *
+ * Note that there is no ::drag-enter signal. The drag receiver has to keep track of whether
+ * he has received any ::drag-motion signals since the last ::drag-leave and if not, treat the
+ * ::drag-motion signal as an "enter" signal. Upon an "enter", the handler will typically highlight
+ * the drop site with gtk_drag_highlight().
+ *
+ * <informalexample><programlisting>
+ * static void
+ * drag_motion (GtkWidget *widget,
+ * GdkDragContext *context,
+ * gint x,
+ * gint y,
+ * guint time)
+ * {
+ * GdkAtom target;
+ *
+ * PrivateData *private_data = GET_PRIVATE_DATA (widget);
+ *
+ * if (!private_data->drag_highlight)
+ * {
+ * private_data->drag_highlight = 1;
+ * gtk_drag_highlight (widget);
+ * }
+ *
+ * target = gtk_drag_dest_find_target (widget, context, NULL);
+ * if (target == GDK_NONE)
+ * gdk_drag_status (context, 0, time);
+ * else
+ * {
+ * private_data->pending_status = context->suggested_action;
+ * gtk_drag_get_data (widget, context, target, time);
+ * }
+ *
+ * return TRUE;
+ * }
+ *
+ * static void
+ * drag_data_received (GtkWidget *widget,
+ * GdkDragContext *context,
+ * gint x,
+ * gint y,
+ * GtkSelectionData *selection_data,
+ * guint info,
+ * guint time)
+ * {
+ * PrivateData *private_data = GET_PRIVATE_DATA (widget);
+ *
+ * if (private_data->suggested_action)
+ * {
+ * private_data->suggested_action = 0;
+ *
+ * /<!-- -->* We are getting this data due to a request in drag_motion,
+ * * rather than due to a request in drag_drop, so we are just
+ * * supposed to call gdk_drag_status(<!-- -->), not actually paste in the data.
+ * *<!-- -->/
+ * str = gtk_selection_data_get_text (selection_data);
+ * if (!data_is_acceptable (str))
+ * gdk_drag_status (context, 0, time);
+ * else
+ * gdk_drag_status (context, private_data->suggested_action, time);
+ * }
+ * else
+ * {
+ * /<!-- -->* accept the drop *<!-- -->/
+ * }
+ * }
+ * </programlisting></informalexample>
+ */
widget_signals[DRAG_MOTION] =
g_signal_new ("drag_motion",
G_TYPE_FROM_CLASS (gobject_class),
G_TYPE_INT,
G_TYPE_INT,
G_TYPE_UINT);
+
+ /**
+ * GtkWidget::drag-drop:
+ * @widget: the object which received the signal.
+ * @drag_context: the drag context
+ * @x: the x coordinate of the current cursor position
+ * @y: the y coordinate of the current cursor position
+ * @time: the timestamp of the motion event
+ * @returns: whether the cursor position is in a drop zone
+ *
+ * The ::drag-drop signal is emitted on the drop site when the user drops the data
+ * onto the widget. The signal handler must determine whether the cursor position is in
+ * a drop zone or not. If it is not in a drop zone, it returns %FALSE and no further
+ * processing is necessary. Otherwise, the handler returns %TRUE. In this case, the handler
+ * must ensure that gtk_drag_finish() is called to let the source know that the drop is done.
+ * The call to gtk_drag_finish() can be done either directly or in a ::drag-data-received handler
+ * which gets triggered by calling gtk_drop_get_data() to receive the data for one or more of the
+ * supported targets.
+ */
widget_signals[DRAG_DROP] =
g_signal_new ("drag_drop",
G_TYPE_FROM_CLASS (gobject_class),
G_TYPE_INT,
G_TYPE_INT,
G_TYPE_UINT);
+
+ /**
+ * GtkWidget::drag-data-get:
+ * @widget: the object which received the signal.
+ * @drag_context: the drag context
+ * @data: the #GtkSelectionData to be filled with the dragged data
+ * @info: the info that has been registered with the target in the #GtkTargetList.
+ * @time: the timestamp at which the data was requested
+ *
+ * The ::drag-data-get signal is emitted on the drag source when the drop site requests
+ * the data which is dragged. It is the responsibility of the signal handler to fill @data
+ * with the data in the format which is indicated by @info. See gtk_selection_data_set() and
+ * gtk_selection_data_set_text().
+ */
widget_signals[DRAG_DATA_GET] =
g_signal_new ("drag_data_get",
G_TYPE_FROM_CLASS (gobject_class),
* @x: where the drop happened
* @y: where the drop happened
* @data: the received data
- * @info: the info that has been registered with the target in the
- * #GtkTargetList.
+ * @info: the info that has been registered with the target in the #GtkTargetList.
* @time: the timestamp at which the data was received
- * @user_data: user data set when the signal handler was connected.
*
- * The ::drag-data-received signal is emitted on the drop site when the drop
- * happens and the data has been received. A handler for this signal is
- * expected to process the received data and then call gtk_drag_finish(),
- * setting the <literal>success</literal> parameter depending on whether the
- * data was processed successfully.
- *
- * The handler may inspect and modify @drag_context->action
- * before calling gtk_drag_finish(), e.g. to implement %GTK_ACTION_ASK as
- * shown in the following example:
+ * The ::drag-data-received signal is emitted on the drop site when the dragged data has been
+ * received. If the data was received in order to determine whether the drop will be accepted,
+ * the handler is expected to call gdk_drag_status() and <emphasis>not</emphasis> finish the drag.
+ * If the data was received in response to a ::drag-drop signal (and this is the last target to be
+ * received), the handler for this signal is expected to process the received data and then call
+ * gtk_drag_finish(), setting the @success parameter depending on whether the data was processed
+ * successfully.
+ *
+ * The handler may inspect and modify @drag_context->action before calling gtk_drag_finish(),
+ * e.g. to implement %GDK_ACTION_ASK as shown in the following example:
* <informalexample><programlisting>
* void
* drag_data_received (GtkWidget *widget,
_gtk_marshal_BOOLEAN__BOXED,
G_TYPE_BOOLEAN, 1,
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
+/**
+ * GtkWidget::popup-menu
+ * @widget: the object which received the signal
+ * @returns: TRUE if a menu was activated
+ *
+ * This signal gets emitted whenever a widget should pop up a context-sensitive
+ * menu. This usually happens through the standard key binding mechanism; by
+ * pressing a certain key while a widget is focused, the user can cause the
+ * widget to pop up a menu. For example, the #GtkEntry widget creates a menu
+ * with clipboard commands. See <xref linkend="checklist-popup-menu"/> for an
+ * example of how to use this signal.
+ */
widget_signals[POPUP_MENU] =
g_signal_new ("popup_menu",
G_TYPE_FROM_CLASS (gobject_class),
_gtk_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
GDK_TYPE_SCREEN);
-
+/**
+ * GtkWidget::can-activate-accel:
+ * @widget: the object which received the signal
+ * @signal_id: the ID of a signal installed on @widget
+ * @returns: %TRUE if the signal can be activated.
+ *
+ * Determines whether an accelerator that activates the signal
+ * identified by @signal_id can currently be activated.
+ * This signal is present to allow applications and derived
+ * widgets to override the default #GtkWidget handling
+ * for determining whether an accelerator can be activated.
+ */
+ widget_signals[CAN_ACTIVATE_ACCEL] =
+ g_signal_new ("can_activate_accel",
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GtkWidgetClass, can_activate_accel),
+ _gtk_boolean_handled_accumulator, NULL,
+ _gtk_marshal_BOOLEAN__UINT,
+ G_TYPE_BOOLEAN, 1, G_TYPE_UINT);
+
binding_set = gtk_binding_set_by_class (klass);
gtk_binding_entry_add_signal (binding_set, GDK_F10, GDK_SHIFT_MASK,
"popup_menu", 0);
gtk_widget_class_install_style_property (klass,
g_param_spec_boolean ("interior_focus",
- _("Interior Focus"),
- _("Whether to draw the focus indicator inside widgets"),
+ P_("Interior Focus"),
+ P_("Whether to draw the focus indicator inside widgets"),
TRUE,
G_PARAM_READABLE));
gtk_widget_class_install_style_property (klass,
g_param_spec_int ("focus-line-width",
- _("Focus linewidth"),
- _("Width, in pixels, of the focus indicator line"),
+ P_("Focus linewidth"),
+ P_("Width, in pixels, of the focus indicator line"),
0, G_MAXINT, 1,
- G_PARAM_READWRITE));
+ G_PARAM_READABLE));
gtk_widget_class_install_style_property (klass,
g_param_spec_string ("focus-line-pattern",
- _("Focus line dash pattern"),
- _("Dash pattern used to draw the focus indicator"),
+ P_("Focus line dash pattern"),
+ P_("Dash pattern used to draw the focus indicator"),
"\1\1",
- G_PARAM_READWRITE));
+ G_PARAM_READABLE));
gtk_widget_class_install_style_property (klass,
g_param_spec_int ("focus-padding",
- _("Focus padding"),
- _("Width, in pixels, between focus indicator and the widget 'box'"),
+ P_("Focus padding"),
+ P_("Width, in pixels, between focus indicator and the widget 'box'"),
0, G_MAXINT, 1,
- G_PARAM_READWRITE));
+ G_PARAM_READABLE));
gtk_widget_class_install_style_property (klass,
g_param_spec_boxed ("cursor-color",
- _("Cursor color"),
- _("Color with which to draw insertion cursor"),
+ P_("Cursor color"),
+ P_("Color with which to draw insertion cursor"),
GDK_TYPE_COLOR,
G_PARAM_READABLE));
gtk_widget_class_install_style_property (klass,
g_param_spec_boxed ("secondary-cursor-color",
- _("Secondary cursor color"),
- _("Color with which to draw the secondary insertion cursor when editing mixed right-to-left and left-to-right text"),
+ P_("Secondary cursor color"),
+ P_("Color with which to draw the secondary insertion cursor when editing mixed right-to-left and left-to-right text"),
GDK_TYPE_COLOR,
G_PARAM_READABLE));
gtk_widget_class_install_style_property (klass,
g_param_spec_float ("cursor-aspect-ratio",
- _("Cursor line aspect ratio"),
- _("Aspect ratio with which to draw insertion cursor"),
+ P_("Cursor line aspect ratio"),
+ P_("Aspect ratio with which to draw insertion cursor"),
0.0, 1.0, 0.04,
G_PARAM_READABLE));
}
case PROP_EXTENSION_EVENTS:
gtk_widget_set_extension_events (widget, g_value_get_enum (value));
break;
+ case PROP_NO_SHOW_ALL:
+ gtk_widget_set_no_show_all (widget, g_value_get_boolean (value));
+ break;
default:
break;
}
else
g_value_set_enum (value, (GdkExtensionMode) *modep);
break;
+ case PROP_NO_SHOW_ALL:
+ g_value_set_boolean (value, gtk_widget_get_no_show_all (widget));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
if (GTK_WIDGET_VISIBLE (widget))
{
GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
+
+ g_object_ref (widget);
if (toplevel != widget && GTK_WIDGET_TOPLEVEL (toplevel))
_gtk_window_unset_focus_and_default (GTK_WINDOW (toplevel), widget);
- g_object_ref (widget);
g_signal_emit (widget, widget_signals[HIDE], 0);
if (!GTK_WIDGET_TOPLEVEL (widget))
gtk_widget_queue_resize (widget);
g_return_if_fail (GTK_IS_WIDGET (widget));
+ if ((GTK_WIDGET_FLAGS (widget) & GTK_NO_SHOW_ALL) != 0)
+ return;
+
class = GTK_WIDGET_GET_CLASS (widget);
if (class->show_all)
g_return_if_fail (GTK_IS_WIDGET (widget));
+ if ((GTK_WIDGET_FLAGS (widget) & GTK_NO_SHOW_ALL) != 0)
+ return;
+
class = GTK_WIDGET_GET_CLASS (widget);
if (class->hide_all)
gtk_widget_invalidate_widget_windows (GtkWidget *widget,
GdkRegion *region)
{
- if (!GTK_WIDGET_NO_WINDOW (widget))
+ if (!GTK_WIDGET_REALIZED (widget))
+ return;
+
+ if (!GTK_WIDGET_NO_WINDOW (widget) && widget->parent)
{
int x, y;
}
}
+static gboolean
+gtk_widget_real_can_activate_accel (GtkWidget *widget,
+ guint signal_id)
+{
+ /* widgets must be onscreen for accels to take effect */
+ return GTK_WIDGET_IS_SENSITIVE (widget) && GTK_WIDGET_DRAWABLE (widget) && gdk_window_is_viewable (widget->window);
+}
+
+/**
+ * gtk_widget_can_activate_accel:
+ * @widget: a #GtkWidget
+ * @signal_id: the ID of a signal installed on @widget
+ *
+ * Determines whether an accelerator that activates the signal
+ * identified by @signal_id can currently be activated.
+ * This is done by emitting the GtkWidget::can-activate-accel
+ * signal on @widget; if the signal isn't overridden by a
+ * handler or in a derived widget, then the default check is
+ * that the widget must be sensitive, and the widget and all
+ * its ancestors mapped.
+ *
+ * Return value: %TRUE if the accelerator can be activated.
+ *
+ * Since: 2.4
+ **/
+gboolean
+gtk_widget_can_activate_accel (GtkWidget *widget,
+ guint signal_id)
+{
+ gboolean can_activate = FALSE;
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
+ g_signal_emit (widget, widget_signals[CAN_ACTIVATE_ACCEL], 0, signal_id, &can_activate);
+ return can_activate;
+}
+
typedef struct {
GClosure closure;
guint signal_id;
gpointer marshal_data)
{
AccelClosure *aclosure = (AccelClosure*) closure;
+ gboolean can_activate = gtk_widget_can_activate_accel (closure->data, aclosure->signal_id);
- if (GTK_WIDGET_IS_SENSITIVE (closure->data))
+ if (can_activate)
g_signal_emit (closure->data, aclosure->signal_id, 0);
- /* we handled the accelerator */
- g_value_set_boolean (return_value, TRUE);
+ /* whether accelerator was handled */
+ g_value_set_boolean (return_value, can_activate);
}
static void
gtk_widget_real_key_press_event (GtkWidget *widget,
GdkEventKey *event)
{
- return _gtk_bindings_activate_event (GTK_OBJECT (widget), event);
+ return gtk_bindings_activate_event (GTK_OBJECT (widget), event);
}
static gboolean
gtk_widget_real_key_release_event (GtkWidget *widget,
GdkEventKey *event)
{
- return _gtk_bindings_activate_event (GTK_OBJECT (widget), event);
+ return gtk_bindings_activate_event (GTK_OBJECT (widget), event);
}
static gboolean
*
* For widgets that can be "activated" (buttons, menu items, etc.)
* this function activates them. Activation is what happens when you
- * press Enter on a widget during key navigation; clicking a button,
- * selecting a menu item, etc. If @widget isn't activatable,
- * the function returns %FALSE.
+ * press Enter on a widget during key navigation. If @widget isn't
+ * activatable, the function returns %FALSE.
*
* Return value: %TRUE if the widget was activatable
**/
return dest;
}
+/**
+ * _gtk_widget_grab_notify:
+ * @widget: a #GtkWidget
+ * @was_grabbed: whether a grab is now in effect
+ *
+ * Emits the signal "grab_notify" on @widget.
+ *
+ * Since: 2.6
+ **/
+void
+_gtk_widget_grab_notify (GtkWidget *widget,
+ gboolean was_grabbed)
+{
+ g_signal_emit (widget, widget_signals[GRAB_NOTIFY], 0, was_grabbed);
+}
+
/**
* gtk_widget_grab_focus:
* @widget: a #GtkWidget
gtk_widget_set_name (GtkWidget *widget,
const gchar *name)
{
- g_return_if_fail (GTK_IS_WIDGET (widget));
+ gchar *new_name;
- if (widget->name)
- g_free (widget->name);
- widget->name = g_strdup (name);
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+
+ new_name = g_strdup (name);
+ g_free (widget->name);
+ widget->name = new_name;
if (GTK_WIDGET_RC_STYLE (widget))
gtk_widget_reset_rc_style (widget);
GtkStateData data;
g_return_if_fail (GTK_IS_WIDGET (widget));
- g_return_if_fail (widget->parent == NULL);
- g_return_if_fail (!GTK_WIDGET_TOPLEVEL (widget));
g_return_if_fail (GTK_IS_WIDGET (parent));
g_return_if_fail (widget != parent);
+ if (widget->parent != NULL)
+ {
+ g_warning ("Can't set a parent on widget which has a parent\n");
+ return;
+ }
+ if (GTK_WIDGET_TOPLEVEL (widget))
+ {
+ g_warning ("Can't set a parent on a toplevel widget\n");
+ return;
+ }
/* keep this function in sync with gtk_menu_attach_to_widget()
*/
}
static void
-gtk_widget_modify_color_component (GtkWidget *widget,
- GtkRcFlags component,
- GtkStateType state,
- GdkColor *color)
+gtk_widget_modify_color_component (GtkWidget *widget,
+ GtkRcFlags component,
+ GtkStateType state,
+ const GdkColor *color)
{
GtkRcStyle *rc_style = gtk_widget_get_modifier_style (widget);
* gtk_widget_modify_style().
**/
void
-gtk_widget_modify_fg (GtkWidget *widget,
- GtkStateType state,
- GdkColor *color)
+gtk_widget_modify_fg (GtkWidget *widget,
+ GtkStateType state,
+ const GdkColor *color)
{
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (state >= GTK_STATE_NORMAL && state <= GTK_STATE_INSENSITIVE);
* gtk_widget_modify_style().
**/
void
-gtk_widget_modify_bg (GtkWidget *widget,
- GtkStateType state,
- GdkColor *color)
+gtk_widget_modify_bg (GtkWidget *widget,
+ GtkStateType state,
+ const GdkColor *color)
{
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (state >= GTK_STATE_NORMAL && state <= GTK_STATE_INSENSITIVE);
* gtk_widget_modify_style().
**/
void
-gtk_widget_modify_text (GtkWidget *widget,
- GtkStateType state,
- GdkColor *color)
+gtk_widget_modify_text (GtkWidget *widget,
+ GtkStateType state,
+ const GdkColor *color)
{
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (state >= GTK_STATE_NORMAL && state <= GTK_STATE_INSENSITIVE);
* and #GtkTextView. See also gtk_widget_modify_style().
**/
void
-gtk_widget_modify_base (GtkWidget *widget,
- GtkStateType state,
- GdkColor *color)
+gtk_widget_modify_base (GtkWidget *widget,
+ GtkStateType state,
+ const GdkColor *color)
{
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (state >= GTK_STATE_NORMAL && state <= GTK_STATE_INSENSITIVE);
initial_emission ? NULL : previous_style);
g_object_unref (previous_style);
- if (widget->parent && !initial_emission)
+ if (GTK_WIDGET_ANCHORED (widget) && !initial_emission)
gtk_widget_queue_resize (widget);
}
else if (initial_emission)
* gtk_widget_render_icon:
* @widget: a #GtkWidget
* @stock_id: a stock ID
- * @size: a stock size
+ * @size: 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: render detail to pass to theme engine
*
* A convenience function that uses the theme engine and RC file
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, NULL);
+ g_return_val_if_fail (size > GTK_ICON_SIZE_INVALID || size == -1, NULL);
gtk_widget_ensure_style (widget);
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (!GTK_WIDGET_TOPLEVEL (widget));
+ g_object_ref (widget);
+
if (is_visible)
GTK_PRIVATE_SET_FLAG (widget, GTK_CHILD_VISIBLE);
else
else
gtk_widget_unmap (widget);
}
+
+ g_object_unref (widget);
}
/**
if (widget->parent)
gtk_container_remove (GTK_CONTAINER (widget->parent), widget);
+ else if (GTK_WIDGET_VISIBLE (widget))
+ gtk_widget_hide (widget);
GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
if (GTK_WIDGET_REALIZED (widget))
g_object_set_qdata (G_OBJECT (widget), quark_accel_path, NULL);
g_object_set_qdata (G_OBJECT (widget), quark_accel_closures, NULL);
+ /* Callers of add_mnemonic_label() should disconnect on ::destroy */
+ g_object_set_qdata (G_OBJECT (widget), quark_mnemonic_labels, NULL);
+
gtk_grab_remove (widget);
g_object_unref (widget->style);
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,
+ * gtk_label_set_mnemonic_widget()).
+
+ * The widgets in the list are not individually referenced. If you
+ * want to iterate through the list and perform actions involving
+ * callbacks that might destroy the widgets, you
+ * <emphasis>must</emphasis> call <literal>g_list_foreach (result,
+ * (GFunc)g_object_ref, NULL)</literal> first, and then unref all the
+ * widgets afterwards.
+
+ * Return value: the list of mnemonic labels; free this list
+ * with g_list_free() when you are done with it.
+ *
+ * Since: 2.4
+ **/
+GList *
+gtk_widget_list_mnemonic_labels (GtkWidget *widget)
+{
+ GList *list = NULL;
+ GSList *l;
+
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
+
+ for (l = g_object_get_qdata (G_OBJECT (widget), quark_mnemonic_labels); l; l = l->next)
+ list = g_list_prepend (list, l->data);
+
+ return list;
+}
+
+/**
+ * gtk_widget_add_mnemonic_label:
+ * @widget: a #GtkWidget
+ * @label: a #GtkWidget that acts as a mnemonic label for @widget.
+ *
+ * Adds a widget to the list of mnemonic labels for
+ * this widget. (See gtk_widget_list_mnemonic_labels()). Note the
+ * list of mnemonic labels for the widget is cleared when the
+ * widget is destroyed, so the caller must make sure to update
+ * it's internal state at this point as well, by using a connection
+ * to the ::destroy signal or a weak notifier.
+ *
+ * Since: 2.4
+ **/
+void
+gtk_widget_add_mnemonic_label (GtkWidget *widget,
+ GtkWidget *label)
+{
+ GSList *old_list, *new_list;
+
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+ g_return_if_fail (GTK_IS_WIDGET (label));
+
+ old_list = g_object_steal_qdata (G_OBJECT (widget), quark_mnemonic_labels);
+ new_list = g_slist_prepend (old_list, label);
+
+ g_object_set_qdata_full (G_OBJECT (widget), quark_mnemonic_labels,
+ new_list, (GDestroyNotify) g_slist_free);
+}
+
+/**
+ * gtk_widget_remove_mnemonic_label:
+ * @widget: a #GtkWidget
+ * @label: a #GtkWidget that was previously set as a mnemnic label for
+ * @widget with gtk_widget_add_mnemonic_label().
+ *
+ * Removes a widget from the list of mnemonic labels for
+ * this widget. (See gtk_widget_list_mnemonic_labels()). The widget
+ * must have previously been added to the list with
+ * gtk_widget_add_mnemonic_label().
+ *
+ * Since: 2.4
+ **/
+void
+gtk_widget_remove_mnemonic_label (GtkWidget *widget,
+ GtkWidget *label)
+{
+ GSList *old_list, *new_list;
+
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+ g_return_if_fail (GTK_IS_WIDGET (label));
+
+ old_list = g_object_steal_qdata (G_OBJECT (widget), quark_mnemonic_labels);
+ new_list = g_slist_remove (old_list, label);
+
+ if (new_list)
+ g_object_set_qdata_full (G_OBJECT (widget), quark_mnemonic_labels,
+ new_list, (GDestroyNotify) g_slist_free);
+}
+
+/**
+ * gtk_widget_get_no_show_all:
+ * @widget: a #GtkWidget
+ *
+ * Returns the current value of the "no_show_all" property, which determines
+ * whether calls to gtk_widget_show_all() and gtk_widget_hide_all()
+ * will affect this widget.
+ *
+ * Return value: the current value of the "no_show_all" property.
+ *
+ * Since: 2.4
+ **/
+gboolean
+gtk_widget_get_no_show_all (GtkWidget *widget)
+{
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
+
+ return (GTK_WIDGET_FLAGS (widget) & GTK_NO_SHOW_ALL) != 0;
+}
+
+/**
+ * gtk_widget_set_no_show_all:
+ * @widget: a #GtkWidget
+ * @no_show_all: the new value for the "no_show_all" property
+ *
+ * Sets the "no_show_all" property, which determines whether calls to
+ * gtk_widget_show_all() and gtk_widget_hide_all() will affect this widget.
+ *
+ * This is mostly for use in constructing widget hierarchies with externally
+ * controlled visibility, see #GtkUIManager.
+ *
+ * Since: 2.4
+ **/
+void
+gtk_widget_set_no_show_all (GtkWidget *widget,
+ gboolean no_show_all)
+{
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+
+ no_show_all = (no_show_all != FALSE);
+
+ if (no_show_all == ((GTK_WIDGET_FLAGS (widget) & GTK_NO_SHOW_ALL) != 0))
+ return;
+
+ if (no_show_all)
+ GTK_WIDGET_SET_FLAGS (widget, GTK_NO_SHOW_ALL);
+ else
+ GTK_WIDGET_UNSET_FLAGS (widget, GTK_NO_SHOW_ALL);
+
+ g_object_notify (G_OBJECT (widget), "no_show_all");
+}