* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
-#include <config.h>
+#include "config.h"
#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
#include <limits.h>
#include "gdk/gdk.h"
#include "gdk/gdkkeysyms.h"
#include "gtkkeyhash.h"
#include "gtkmain.h"
#include "gtkmnemonichash.h"
+#include "gtkmenubar.h"
#include "gtkiconfactory.h"
#include "gtkicontheme.h"
#include "gtkmarshalers.h"
#include "gtkplug.h"
+#include "gtkbuildable.h"
#include "gtkalias.h"
#ifdef GDK_WINDOWING_X11
FRAME_EVENT,
ACTIVATE_FOCUS,
ACTIVATE_DEFAULT,
- MOVE_FOCUS,
KEYS_CHANGED,
LAST_SIGNAL
};
PROP_DECORATED,
PROP_DELETABLE,
PROP_GRAVITY,
+ PROP_TRANSIENT_FOR,
+ PROP_OPACITY,
/* Readonly properties */
PROP_IS_ACTIVE,
PROP_HAS_TOPLEVEL_FOCUS,
+ /* Writeonly properties */
+ PROP_STARTUP_ID,
+
+ PROP_MNEMONICS_VISIBLE,
+
LAST_ARG
};
guint accept_focus : 1;
guint focus_on_map : 1;
guint deletable : 1;
+ guint transient_parent_group : 1;
+
+ guint reset_type_hint : 1;
+ guint opacity_set : 1;
+ guint builder_visible : 1;
+
+ guint mnemonics_visible : 1;
+ guint mnemonics_visible_set : 1;
+
+ GdkWindowTypeHint type_hint;
+
+ gdouble opacity;
+
+ gchar *startup_id;
};
-static void gtk_window_class_init (GtkWindowClass *klass);
-static void gtk_window_init (GtkWindow *window);
static void gtk_window_dispose (GObject *object);
static void gtk_window_destroy (GtkObject *object);
static void gtk_window_finalize (GObject *object);
GtkAllocation *allocation);
static gint gtk_window_event (GtkWidget *widget,
GdkEvent *event);
+static gboolean gtk_window_map_event (GtkWidget *widget,
+ GdkEventAny *event);
static gboolean gtk_window_frame_event (GtkWindow *window,
GdkEvent *event);
static gint gtk_window_configure_event (GtkWidget *widget,
static void gtk_window_notify_keys_changed (GtkWindow *window);
static GtkKeyHash *gtk_window_get_key_hash (GtkWindow *window);
static void gtk_window_free_key_hash (GtkWindow *window);
+static void gtk_window_on_composited_changed (GdkScreen *screen,
+ GtkWindow *window);
static GSList *toplevel_list = NULL;
-static GtkBinClass *parent_class = NULL;
static guint window_signals[LAST_SIGNAL] = { 0 };
static GList *default_icon_list = NULL;
static gchar *default_icon_name = NULL;
static gboolean disable_startup_notification = FALSE;
static gboolean sent_startup_notification = FALSE;
+static GQuark quark_gtk_embedded = 0;
+static GQuark quark_gtk_window_key_hash = 0;
+static GQuark quark_gtk_window_default_icon_pixmap = 0;
+static GQuark quark_gtk_window_icon_info = 0;
+static GQuark quark_gtk_buildable_accels = 0;
+
+static GtkBuildableIface *parent_buildable_iface;
+
static void gtk_window_set_property (GObject *object,
guint prop_id,
const GValue *value,
GValue *value,
GParamSpec *pspec);
-
-GType
-gtk_window_get_type (void)
-{
- static GType window_type = 0;
-
- if (!window_type)
- {
- static const GTypeInfo window_info =
- {
- sizeof (GtkWindowClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) gtk_window_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (GtkWindow),
- 0, /* n_preallocs */
- (GInstanceInitFunc) gtk_window_init,
- };
-
- window_type = g_type_register_static (GTK_TYPE_BIN, I_("GtkWindow"),
- &window_info, 0);
- }
-
- return window_type;
-}
+/* GtkBuildable */
+static void gtk_window_buildable_interface_init (GtkBuildableIface *iface);
+static void gtk_window_buildable_set_buildable_property (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ const gchar *name,
+ const GValue *value);
+static void gtk_window_buildable_parser_finished (GtkBuildable *buildable,
+ GtkBuilder *builder);
+static gboolean gtk_window_buildable_custom_tag_start (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ GObject *child,
+ const gchar *tagname,
+ GMarkupParser *parser,
+ gpointer *data);
+static void gtk_window_buildable_custom_finished (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ GObject *child,
+ const gchar *tagname,
+ gpointer user_data);
+
+
+G_DEFINE_TYPE_WITH_CODE (GtkWindow, gtk_window, GTK_TYPE_BIN,
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
+ gtk_window_buildable_interface_init))
static void
add_tab_bindings (GtkBindingSet *binding_set,
GtkDirectionType direction)
{
gtk_binding_entry_add_signal (binding_set, GDK_Tab, modifiers,
- "move_focus", 1,
+ "move-focus", 1,
GTK_TYPE_DIRECTION_TYPE, direction);
gtk_binding_entry_add_signal (binding_set, GDK_KP_Tab, modifiers,
- "move_focus", 1,
+ "move-focus", 1,
GTK_TYPE_DIRECTION_TYPE, direction);
}
guint keypad_keysym = keysym - GDK_Left + GDK_KP_Left;
gtk_binding_entry_add_signal (binding_set, keysym, 0,
- "move_focus", 1,
+ "move-focus", 1,
GTK_TYPE_DIRECTION_TYPE, direction);
gtk_binding_entry_add_signal (binding_set, keysym, GDK_CONTROL_MASK,
- "move_focus", 1,
+ "move-focus", 1,
GTK_TYPE_DIRECTION_TYPE, direction);
gtk_binding_entry_add_signal (binding_set, keypad_keysym, 0,
- "move_focus", 1,
+ "move-focus", 1,
GTK_TYPE_DIRECTION_TYPE, direction);
gtk_binding_entry_add_signal (binding_set, keypad_keysym, GDK_CONTROL_MASK,
- "move_focus", 1,
+ "move-focus", 1,
GTK_TYPE_DIRECTION_TYPE, direction);
}
+static guint32
+extract_time_from_startup_id (const gchar* startup_id)
+{
+ gchar *timestr = g_strrstr (startup_id, "_TIME");
+ guint32 retval = GDK_CURRENT_TIME;
+
+ if (timestr)
+ {
+ gchar *end;
+ guint32 timestamp;
+
+ /* Skip past the "_TIME" part */
+ timestr += 5;
+
+ errno = 0;
+ timestamp = strtoul (timestr, &end, 0);
+ if (end != timestr && errno == 0)
+ retval = timestamp;
+ }
+
+ return retval;
+}
+
+static gboolean
+startup_id_is_fake (const gchar* startup_id)
+{
+ return strncmp (startup_id, "_TIME", 5) == 0;
+}
static void
gtk_window_class_init (GtkWindowClass *klass)
widget_class = (GtkWidgetClass*) klass;
container_class = (GtkContainerClass*) klass;
- parent_class = g_type_class_peek_parent (klass);
+ quark_gtk_embedded = g_quark_from_static_string ("gtk-embedded");
+ quark_gtk_window_key_hash = g_quark_from_static_string ("gtk-window-key-hash");
+ quark_gtk_window_default_icon_pixmap = g_quark_from_static_string ("gtk-window-default-icon-pixmap");
+ quark_gtk_window_icon_info = g_quark_from_static_string ("gtk-window-icon-info");
+ quark_gtk_buildable_accels = g_quark_from_static_string ("gtk-window-buildable-accels");
gobject_class->dispose = gtk_window_dispose;
gobject_class->finalize = gtk_window_finalize;
widget_class->show = gtk_window_show;
widget_class->hide = gtk_window_hide;
widget_class->map = gtk_window_map;
+ widget_class->map_event = gtk_window_map_event;
widget_class->unmap = gtk_window_unmap;
widget_class->realize = gtk_window_realize;
widget_class->unrealize = gtk_window_unrealize;
widget_class->focus_out_event = gtk_window_focus_out_event;
widget_class->client_event = gtk_window_client_event;
widget_class->focus = gtk_window_focus;
-
widget_class->expose_event = gtk_window_expose;
-
+
container_class->check_resize = gtk_window_check_resize;
klass->set_focus = gtk_window_real_set_focus;
NULL,
GTK_PARAM_READWRITE));
+ /**
+ * GtkWindow:startup-id:
+ *
+ * The :startup-id is a write-only property for setting window's
+ * startup notification identifier. See gtk_window_set_startup_id()
+ * for more details.
+ *
+ * Since: 2.12
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_STARTUP_ID,
+ g_param_spec_string ("startup-id",
+ P_("Startup ID"),
+ P_("Unique startup identifier for the window used by startup-notification"),
+ NULL,
+ GTK_PARAM_WRITABLE));
+
g_object_class_install_property (gobject_class,
PROP_ALLOW_SHRINK,
g_param_spec_boolean ("allow-shrink",
P_("Icon for this window"),
GDK_TYPE_PIXBUF,
GTK_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class,
+ PROP_MNEMONICS_VISIBLE,
+ g_param_spec_boolean ("mnemonics-visible",
+ P_("Mnemonics Visible"),
+ P_("Whether mnemonics are currently visible in this window"),
+ TRUE,
+ GTK_PARAM_READWRITE));
/**
* GtkWindow:icon-name:
GTK_PARAM_READWRITE));
/**
- * GtkWindow:accept-focus-hint:
+ * GtkWindow:accept-focus:
*
* Whether the window should receive the input focus.
*
GTK_PARAM_READWRITE));
/**
- * GtkWindow:focus-on-map-hint:
+ * GtkWindow:focus-on-map:
*
* Whether the window should receive the input focus when mapped.
*
GDK_GRAVITY_NORTH_WEST,
GTK_PARAM_READWRITE));
+
+ /**
+ * GtkWindow:transient-for:
+ *
+ * The transient parent of the window. See gtk_window_set_transient_for() for
+ * more details about transient windows.
+ *
+ * Since: 2.10
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_TRANSIENT_FOR,
+ g_param_spec_object ("transient-for",
+ P_("Transient for Window"),
+ P_("The transient parent of the dialog"),
+ GTK_TYPE_WINDOW,
+ GTK_PARAM_READWRITE| G_PARAM_CONSTRUCT));
+
+ /**
+ * GtkWindow:opacity:
+ *
+ * The requested opacity of the window. See gtk_window_set_opacity() for
+ * more details about window opacity.
+ *
+ * Since: 2.12
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_OPACITY,
+ g_param_spec_double ("opacity",
+ P_("Opacity for Window"),
+ P_("The opacity of the window, from 0 to 1"),
+ 0.0,
+ 1.0,
+ 1.0,
+ GTK_PARAM_READWRITE));
+
window_signals[SET_FOCUS] =
- g_signal_new (I_("set_focus"),
+ g_signal_new (I_("set-focus"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkWindowClass, set_focus),
GTK_TYPE_WIDGET);
window_signals[FRAME_EVENT] =
- g_signal_new (I_("frame_event"),
+ g_signal_new (I_("frame-event"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(GtkWindowClass, frame_event),
G_TYPE_BOOLEAN, 1,
GDK_TYPE_EVENT);
+ /**
+ * GtkWindow::activate-focus:
+ * @window: the window which received the signal
+ *
+ * The ::activate-default signal is a
+ * <link linkend="keybinding-signals">keybinding signal</link>
+ * which gets emitted when the user activates the currently
+ * focused widget of @window.
+ */
window_signals[ACTIVATE_FOCUS] =
- g_signal_new (I_("activate_focus"),
+ g_signal_new (I_("activate-focus"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (GtkWindowClass, activate_focus),
G_TYPE_NONE,
0);
+ /**
+ * GtkWindow::activate-default:
+ * @window: the window which received the signal
+ *
+ * The ::activate-default signal is a
+ * <link linkend="keybinding-signals">keybinding signal</link>
+ * which gets emitted when the user activates the default widget
+ * of @window.
+ */
window_signals[ACTIVATE_DEFAULT] =
- g_signal_new (I_("activate_default"),
+ g_signal_new (I_("activate-default"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (GtkWindowClass, activate_default),
G_TYPE_NONE,
0);
- window_signals[MOVE_FOCUS] =
- g_signal_new (I_("move_focus"),
- G_TYPE_FROM_CLASS (gobject_class),
- G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
- G_STRUCT_OFFSET (GtkWindowClass, move_focus),
- NULL, NULL,
- _gtk_marshal_VOID__ENUM,
- G_TYPE_NONE,
- 1,
- GTK_TYPE_DIRECTION_TYPE);
-
+ /**
+ * GtkWindow::keys-changed:
+ * @window: the window which received the signal
+ *
+ * The ::keys-changed signal gets emitted when the set of accelerators
+ * or mnemonics that are associated with @window changes.
+ */
window_signals[KEYS_CHANGED] =
- g_signal_new (I_("keys_changed"),
+ g_signal_new (I_("keys-changed"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GtkWindowClass, keys_changed),
binding_set = gtk_binding_set_by_class (klass);
gtk_binding_entry_add_signal (binding_set, GDK_space, 0,
- "activate_focus", 0);
+ "activate-focus", 0);
gtk_binding_entry_add_signal (binding_set, GDK_KP_Space, 0,
- "activate_focus", 0);
+ "activate-focus", 0);
gtk_binding_entry_add_signal (binding_set, GDK_Return, 0,
- "activate_default", 0);
-
+ "activate-default", 0);
+ gtk_binding_entry_add_signal (binding_set, GDK_ISO_Enter, 0,
+ "activate-default", 0);
gtk_binding_entry_add_signal (binding_set, GDK_KP_Enter, 0,
- "activate_default", 0);
+ "activate-default", 0);
add_arrow_bindings (binding_set, GDK_Up, GTK_DIR_UP);
add_arrow_bindings (binding_set, GDK_Down, GTK_DIR_DOWN);
priv->accept_focus = TRUE;
priv->focus_on_map = TRUE;
priv->deletable = TRUE;
+ priv->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
+ priv->opacity = 1.0;
+ priv->startup_id = NULL;
+ priv->mnemonics_visible = TRUE;
colormap = _gtk_widget_peek_colormap ();
if (colormap)
gtk_widget_set_colormap (GTK_WIDGET (window), colormap);
- g_object_ref (window);
- gtk_object_sink (GTK_OBJECT (window));
+ g_object_ref_sink (window);
window->has_user_ref_count = TRUE;
toplevel_list = g_slist_prepend (toplevel_list, window);
gtk_decorated_window_init (window);
- g_signal_connect (window,
- "event",
- G_CALLBACK (gtk_window_event),
- NULL);
+ g_signal_connect (window->screen, "composited-changed",
+ G_CALLBACK (gtk_window_on_composited_changed), window);
}
static void
GParamSpec *pspec)
{
GtkWindow *window;
+ GtkWindowPrivate *priv;
window = GTK_WINDOW (object);
+ priv = GTK_WINDOW_GET_PRIVATE (window);
+
switch (prop_id)
{
case PROP_TYPE:
case PROP_ROLE:
gtk_window_set_role (window, g_value_get_string (value));
break;
+ case PROP_STARTUP_ID:
+ gtk_window_set_startup_id (window, g_value_get_string (value));
+ break;
case PROP_ALLOW_SHRINK:
window->allow_shrink = g_value_get_boolean (value);
gtk_widget_queue_resize (GTK_WIDGET (window));
case PROP_GRAVITY:
gtk_window_set_gravity (window, g_value_get_enum (value));
break;
+ case PROP_TRANSIENT_FOR:
+ gtk_window_set_transient_for (window, g_value_get_object (value));
+ break;
+ case PROP_OPACITY:
+ gtk_window_set_opacity (window, g_value_get_double (value));
+ break;
+ case PROP_MNEMONICS_VISIBLE:
+ gtk_window_set_mnemonics_visible (window, g_value_get_boolean (value));
+ break;
default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
GParamSpec *pspec)
{
GtkWindow *window;
+ GtkWindowPrivate *priv;
window = GTK_WINDOW (object);
-
+ priv = GTK_WINDOW_GET_PRIVATE (window);
+
switch (prop_id)
{
GtkWindowGeometryInfo *info;
g_value_set_boolean (value, window->has_toplevel_focus);
break;
case PROP_TYPE_HINT:
- g_value_set_enum (value,
- window->type_hint);
+ g_value_set_enum (value, priv->type_hint);
break;
case PROP_SKIP_TASKBAR_HINT:
g_value_set_boolean (value,
case PROP_GRAVITY:
g_value_set_enum (value, gtk_window_get_gravity (window));
break;
+ case PROP_TRANSIENT_FOR:
+ g_value_set_object (value, gtk_window_get_transient_for (window));
+ break;
+ case PROP_OPACITY:
+ g_value_set_double (value, gtk_window_get_opacity (window));
+ break;
+ case PROP_MNEMONICS_VISIBLE:
+ g_value_set_boolean (value, priv->mnemonics_visible);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
+static void
+gtk_window_buildable_interface_init (GtkBuildableIface *iface)
+{
+ parent_buildable_iface = g_type_interface_peek_parent (iface);
+ iface->set_buildable_property = gtk_window_buildable_set_buildable_property;
+ iface->parser_finished = gtk_window_buildable_parser_finished;
+ iface->custom_tag_start = gtk_window_buildable_custom_tag_start;
+ iface->custom_finished = gtk_window_buildable_custom_finished;
+}
+
+static void
+gtk_window_buildable_set_buildable_property (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ const gchar *name,
+ const GValue *value)
+{
+ GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (buildable);
+
+ if (strcmp (name, "visible") == 0 && g_value_get_boolean (value))
+ priv->builder_visible = TRUE;
+ else
+ parent_buildable_iface->set_buildable_property (buildable, builder, name, value);
+}
+
+static void
+gtk_window_buildable_parser_finished (GtkBuildable *buildable,
+ GtkBuilder *builder)
+{
+ GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (buildable);
+ GObject *object;
+ GSList *accels, *l;
+
+ if (priv->builder_visible)
+ gtk_widget_show (GTK_WIDGET (buildable));
+
+ accels = g_object_get_qdata (G_OBJECT (buildable), quark_gtk_buildable_accels);
+ for (l = accels; l; l = l->next)
+ {
+ object = gtk_builder_get_object (builder, l->data);
+ if (!object)
+ {
+ g_warning ("Unknown accel group %s specified in window %s",
+ (const gchar*)l->data, gtk_buildable_get_name (buildable));
+ continue;
+ }
+ gtk_window_add_accel_group (GTK_WINDOW (buildable),
+ GTK_ACCEL_GROUP (object));
+ g_free (l->data);
+ }
+
+ g_object_set_qdata (G_OBJECT (buildable), quark_gtk_buildable_accels, NULL);
+
+ parent_buildable_iface->parser_finished (buildable, builder);
+}
+
+typedef struct {
+ GObject *object;
+ GSList *items;
+} GSListSubParserData;
+
+static void
+window_start_element (GMarkupParseContext *context,
+ const gchar *element_name,
+ const gchar **names,
+ const gchar **values,
+ gpointer user_data,
+ GError **error)
+{
+ guint i;
+ GSListSubParserData *data = (GSListSubParserData*)user_data;
+
+ if (strcmp (element_name, "group") == 0)
+ {
+ for (i = 0; names[i]; i++)
+ {
+ if (strcmp (names[i], "name") == 0)
+ data->items = g_slist_prepend (data->items, g_strdup (values[i]));
+ }
+ }
+ else if (strcmp (element_name, "accel-groups") == 0)
+ return;
+ else
+ g_warning ("Unsupported tag type for GtkWindow: %s\n",
+ element_name);
+
+}
+
+static const GMarkupParser window_parser =
+ {
+ window_start_element
+ };
+
+static gboolean
+gtk_window_buildable_custom_tag_start (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ GObject *child,
+ const gchar *tagname,
+ GMarkupParser *parser,
+ gpointer *data)
+{
+ GSListSubParserData *parser_data;
+
+ if (parent_buildable_iface->custom_tag_start (buildable, builder, child,
+ tagname, parser, data))
+ return TRUE;
+
+ if (strcmp (tagname, "accel-groups") == 0)
+ {
+ parser_data = g_slice_new0 (GSListSubParserData);
+ parser_data->items = NULL;
+ parser_data->object = G_OBJECT (buildable);
+
+ *parser = window_parser;
+ *data = parser_data;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+gtk_window_buildable_custom_finished (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ GObject *child,
+ const gchar *tagname,
+ gpointer user_data)
+{
+ GSListSubParserData *data;
+
+ parent_buildable_iface->custom_finished (buildable, builder, child,
+ tagname, user_data);
+
+ if (strcmp (tagname, "accel-groups") != 0)
+ return;
+
+ data = (GSListSubParserData*)user_data;
+
+ g_object_set_qdata_full (G_OBJECT (buildable), quark_gtk_buildable_accels,
+ data->items, (GDestroyNotify) g_slist_free);
+
+ g_slice_free (GSListSubParserData, data);
+}
+
/**
* gtk_window_new:
* @type: type of window
g_object_notify (G_OBJECT (window), "role");
}
+/**
+ * gtk_window_set_startup_id:
+ * @window: a #GtkWindow
+ * @startup_id: a string with startup-notification identifier
+ *
+ * Startup notification identifiers are used by desktop environment to
+ * track application startup, to provide user feedback and other
+ * features. This function changes the corresponding property on the
+ * underlying GdkWindow. Normally, startup identifier is managed
+ * automatically and you should only use this function in special cases
+ * like transferring focus from other processes. You should use this
+ * function before calling gtk_window_present() or any equivalent
+ * function generating a window map event.
+ *
+ * This function is only useful on X11, not with other GTK+ targets.
+ *
+ * Since: 2.12
+ **/
+void
+gtk_window_set_startup_id (GtkWindow *window,
+ const gchar *startup_id)
+{
+ GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
+
+ g_return_if_fail (GTK_IS_WINDOW (window));
+
+ g_free (priv->startup_id);
+ priv->startup_id = g_strdup (startup_id);
+
+ if (GTK_WIDGET_REALIZED (window))
+ {
+ guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
+
+#ifdef GDK_WINDOWING_X11
+ if (timestamp != GDK_CURRENT_TIME)
+ gdk_x11_window_set_user_time (GTK_WIDGET (window)->window, timestamp);
+#endif
+
+ /* Here we differentiate real and "fake" startup notification IDs,
+ * constructed on purpose just to pass interaction timestamp
+ */
+ if (startup_id_is_fake (priv->startup_id))
+ gtk_window_present_with_time (window, timestamp);
+ else
+ {
+ gdk_window_set_startup_id (GTK_WIDGET (window)->window,
+ priv->startup_id);
+
+ /* If window is mapped, terminate the startup-notification too */
+ if (GTK_WIDGET_MAPPED (window) && !disable_startup_notification)
+ gdk_notify_startup_complete_with_id (priv->startup_id);
+ }
+ }
+
+ g_object_notify (G_OBJECT (window), "startup-id");
+}
+
/**
* gtk_window_get_role:
* @window: a #GtkWindow
/**
* gtk_window_set_focus:
* @window: a #GtkWindow
- * @focus: widget to be the new focus widget, or %NULL to unset
+ * @focus: (allow-none): widget to be the new focus widget, or %NULL to unset
* any focus widget for the toplevel window.
*
* If @focus is not the current focus widget, and is focusable, sets
/**
* gtk_window_set_default:
* @window: a #GtkWindow
- * @default_widget: widget to be the default, or %NULL to unset the
+ * @default_widget: (allow-none): widget to be the default, or %NULL to unset the
* default widget for the toplevel.
*
* The default widget is the widget that's activated when the user
}
}
-void
-gtk_window_set_policy (GtkWindow *window,
- gboolean allow_shrink,
- gboolean allow_grow,
- gboolean auto_shrink)
+/**
+ * gtk_window_get_default_widget:
+ * @window: a #GtkWindow
+ *
+ * Returns the default widget for @window. See gtk_window_set_default()
+ * for more details.
+ *
+ * Returns: the default widget, or %NULL if there is none.
+ *
+ * Since: 2.14
+ **/
+GtkWidget *
+gtk_window_get_default_widget (GtkWindow *window)
{
- g_return_if_fail (GTK_IS_WINDOW (window));
+ g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
+ return window->default_widget;
+}
+
+static void
+gtk_window_set_policy_internal (GtkWindow *window,
+ gboolean allow_shrink,
+ gboolean allow_grow,
+ gboolean auto_shrink)
+{
window->allow_shrink = (allow_shrink != FALSE);
window->allow_grow = (allow_grow != FALSE);
g_object_notify (G_OBJECT (window), "allow-grow");
g_object_notify (G_OBJECT (window), "resizable");
g_object_thaw_notify (G_OBJECT (window));
-
- gtk_widget_queue_resize (GTK_WIDGET (window));
+
+ gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
+}
+
+void
+gtk_window_set_policy (GtkWindow *window,
+ gboolean allow_shrink,
+ gboolean allow_grow,
+ gboolean auto_shrink)
+{
+ g_return_if_fail (GTK_IS_WINDOW (window));
+
+ gtk_window_set_policy_internal (window, allow_shrink, allow_grow, auto_shrink);
}
static gboolean
{
GtkWindow *window;
- GDK_THREADS_ENTER ();
window = GTK_WINDOW (data);
if (window->keys_changed_handler)
}
g_signal_emit (window, window_signals[KEYS_CHANGED], 0);
- GDK_THREADS_LEAVE ();
return FALSE;
}
gtk_window_notify_keys_changed (GtkWindow *window)
{
if (!window->keys_changed_handler)
- window->keys_changed_handler = g_idle_add (handle_keys_changed, window);
+ window->keys_changed_handler = gdk_threads_add_idle (handle_keys_changed, window);
}
/**
g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
_gtk_accel_group_attach (accel_group, G_OBJECT (window));
- g_signal_connect_object (accel_group, "accel_changed",
+ g_signal_connect_object (accel_group, "accel-changed",
G_CALLBACK (gtk_window_notify_keys_changed),
window, G_CONNECT_SWAPPED);
+ gtk_window_notify_keys_changed (window);
}
/**
gtk_window_notify_keys_changed,
window);
_gtk_accel_group_detach (accel_group, G_OBJECT (window));
+ gtk_window_notify_keys_changed (window);
}
static GtkMnemonicHash *
*/
info->position_constraints_changed = TRUE;
- gtk_widget_queue_resize (GTK_WIDGET (window));
+ gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
}
window->position = position;
* Note that this is the widget that would have the focus
* if the toplevel window focused; if the toplevel window
* is not focused then <literal>GTK_WIDGET_HAS_FOCUS (widget)</literal> will
- * not be %TRUE for the widget.
- *
- * Return value: the currently focused widget, or %NULL if there is none.
+ * not be %TRUE for the widget.
+ *
+ * Return value: (transfer none): the currently focused widget, or %NULL if there is none.
**/
GtkWidget *
gtk_window_get_focus (GtkWindow *window)
* 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: list of toplevel widgets
+ *
+ * Return value: (element-type GtkWidget) (transfer container): list of toplevel widgets
**/
GList*
gtk_window_list_toplevels (void)
}
void
-gtk_window_add_embedded_xid (GtkWindow *window, guint xid)
+gtk_window_add_embedded_xid (GtkWindow *window, GdkNativeWindow xid)
{
GList *embedded_windows;
g_return_if_fail (GTK_IS_WINDOW (window));
- embedded_windows = g_object_get_data (G_OBJECT (window), "gtk-embedded");
+ embedded_windows = g_object_get_qdata (G_OBJECT (window), quark_gtk_embedded);
if (embedded_windows)
- g_object_steal_qdata (G_OBJECT (window),
- g_quark_from_static_string ("gtk-embedded"));
+ g_object_steal_qdata (G_OBJECT (window), quark_gtk_embedded);
embedded_windows = g_list_prepend (embedded_windows,
GUINT_TO_POINTER (xid));
- g_object_set_data_full (G_OBJECT (window), I_("gtk-embedded"),
- embedded_windows,
- embedded_windows ?
- (GDestroyNotify) g_list_free : NULL);
+ g_object_set_qdata_full (G_OBJECT (window), quark_gtk_embedded,
+ embedded_windows,
+ embedded_windows ?
+ (GDestroyNotify) g_list_free : NULL);
}
void
-gtk_window_remove_embedded_xid (GtkWindow *window, guint xid)
+gtk_window_remove_embedded_xid (GtkWindow *window, GdkNativeWindow xid)
{
GList *embedded_windows;
GList *node;
g_return_if_fail (GTK_IS_WINDOW (window));
- embedded_windows = g_object_get_data (G_OBJECT (window), "gtk-embedded");
+ embedded_windows = g_object_get_qdata (G_OBJECT (window), quark_gtk_embedded);
if (embedded_windows)
- g_object_steal_qdata (G_OBJECT (window),
- g_quark_from_static_string ("gtk-embedded"));
+ g_object_steal_qdata (G_OBJECT (window), quark_gtk_embedded);
node = g_list_find (embedded_windows, GUINT_TO_POINTER (xid));
if (node)
g_list_free_1 (node);
}
- g_object_set_data_full (G_OBJECT (window), I_("gtk-embedded"),
- embedded_windows,
- embedded_windows ?
- (GDestroyNotify) g_list_free : NULL);
+ g_object_set_qdata_full (G_OBJECT (window), quark_gtk_embedded,
+ embedded_windows,
+ embedded_windows ?
+ (GDestroyNotify) g_list_free : NULL);
}
void
gtk_window_set_focus (window, NULL);
gtk_window_set_default (window, NULL);
- G_OBJECT_CLASS (parent_class)->dispose (object);
+ G_OBJECT_CLASS (gtk_window_parent_class)->dispose (object);
}
static void
static void
gtk_window_unset_transient_for (GtkWindow *window)
{
+ GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
+
if (window->transient_parent)
{
- if (window->transient_parent->group)
- gtk_window_group_remove_window (window->transient_parent->group,
- window);
-
g_signal_handlers_disconnect_by_func (window->transient_parent,
gtk_window_transient_parent_realized,
window);
disconnect_parent_destroyed (window);
window->transient_parent = NULL;
+
+ if (priv->transient_parent_group)
+ {
+ priv->transient_parent_group = FALSE;
+ gtk_window_group_remove_window (window->group,
+ window);
+ }
}
}
/**
* gtk_window_set_transient_for:
* @window: a #GtkWindow
- * @parent: parent window
+ * @parent: (allow-none): parent window
*
* Dialog windows should be set transient for the main application
* window they were spawned from. This allows <link
* functions in GTK+ will sometimes call
* gtk_window_set_transient_for() on your behalf.
*
- * On Windows, this function will and put the child window
- * on top of the parent, much as the window manager would have
- * done on X.
+ * On Windows, this function puts the child window on top of the parent,
+ * much as the window manager would have done on X.
*
**/
void
gtk_window_set_transient_for (GtkWindow *window,
GtkWindow *parent)
{
+ GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
+
g_return_if_fail (GTK_IS_WINDOW (window));
g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent));
g_return_if_fail (window != parent);
-
if (window->transient_parent)
{
if (GTK_WIDGET_REALIZED (window) &&
}
window->transient_parent = parent;
-
+
if (parent)
{
g_signal_connect (parent, "destroy",
GTK_WIDGET (window));
if (parent->group)
- gtk_window_group_add_window (parent->group, window);
+ {
+ gtk_window_group_add_window (parent->group, window);
+ priv->transient_parent_group = TRUE;
+ }
}
}
* Fetches the transient parent for this window. See
* gtk_window_set_transient_for().
*
- * Return value: the transient parent for this window, or %NULL
+ * Return value: (transfer none): the transient parent for this window, or %NULL
* if no transient parent has been set.
**/
GtkWindow *
return window->transient_parent;
}
+/**
+ * gtk_window_set_opacity:
+ * @window: a #GtkWindow
+ * @opacity: desired opacity, between 0 and 1
+ *
+ * Request the windowing system to make @window partially transparent,
+ * with opacity 0 being fully transparent and 1 fully opaque. (Values
+ * of the opacity parameter are clamped to the [0,1] range.) On X11
+ * this has any effect only on X screens with a compositing manager
+ * running. See gtk_widget_is_composited(). On Windows it should work
+ * always.
+ *
+ * Note that setting a window's opacity after the window has been
+ * shown causes it to flicker once on Windows.
+ *
+ * Since: 2.12
+ **/
+void
+gtk_window_set_opacity (GtkWindow *window,
+ gdouble opacity)
+{
+ GtkWindowPrivate *priv;
+
+ g_return_if_fail (GTK_IS_WINDOW (window));
+
+ priv = GTK_WINDOW_GET_PRIVATE (window);
+
+ if (opacity < 0.0)
+ opacity = 0.0;
+ else if (opacity > 1.0)
+ opacity = 1.0;
+
+ priv->opacity_set = TRUE;
+ priv->opacity = opacity;
+
+ if (GTK_WIDGET_REALIZED (window))
+ gdk_window_set_opacity (GTK_WIDGET (window)->window, priv->opacity);
+}
+
+/**
+ * gtk_window_get_opacity:
+ * @window: a #GtkWindow
+ *
+ * Fetches the requested opacity for this window. See
+ * gtk_window_set_opacity().
+ *
+ * Return value: the requested opacity for this window.
+ *
+ * Since: 2.12
+ **/
+gdouble
+gtk_window_get_opacity (GtkWindow *window)
+{
+ GtkWindowPrivate *priv;
+
+ g_return_val_if_fail (GTK_IS_WINDOW (window), 0.0);
+
+ priv = GTK_WINDOW_GET_PRIVATE (window);
+
+ return priv->opacity;
+}
+
/**
* gtk_window_set_type_hint:
* @window: a #GtkWindow
gtk_window_set_type_hint (GtkWindow *window,
GdkWindowTypeHint hint)
{
+ GtkWindowPrivate *priv;
+
g_return_if_fail (GTK_IS_WINDOW (window));
- g_return_if_fail (!GTK_WIDGET_VISIBLE (window));
- window->type_hint = hint;
+ g_return_if_fail (!GTK_WIDGET_MAPPED (window));
+
+ priv = GTK_WINDOW_GET_PRIVATE (window);
+
+ if (hint < GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU)
+ window->type_hint = hint;
+ else
+ window->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
+
+ priv->reset_type_hint = TRUE;
+ priv->type_hint = hint;
}
/**
GdkWindowTypeHint
gtk_window_get_type_hint (GtkWindow *window)
{
+ GtkWindowPrivate *priv;
+
g_return_val_if_fail (GTK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
- return window->type_hint;
+ priv = GTK_WINDOW_GET_PRIVATE (window);
+
+ return priv->type_hint;
}
/**
gtk_window_set_gravity (window, geometry->win_gravity);
}
- gtk_widget_queue_resize (GTK_WIDGET (window));
+ gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
}
/**
}
/**
+ * gtk_window_set_deletable:
* @window: a #GtkWindow
* @setting: %TRUE to decorate the window as deletable
*
* via gtk_window_set_deletable().
*
* Return value: %TRUE if the window has been set to have a close button
+ *
+ * Since: 2.10
**/
gboolean
gtk_window_get_deletable (GtkWindow *window)
static GtkWindowIconInfo*
get_icon_info (GtkWindow *window)
{
- return g_object_get_data (G_OBJECT (window),
- "gtk-window-icon-info");
+ return g_object_get_qdata (G_OBJECT (window), quark_gtk_window_icon_info);
}
static void
free_icon_info (GtkWindowIconInfo *info)
{
g_free (info->icon_name);
- g_free (info);
+ g_slice_free (GtkWindowIconInfo, info);
}
if (info == NULL)
{
- info = g_new0 (GtkWindowIconInfo, 1);
- g_object_set_data_full (G_OBJECT (window),
- I_("gtk-window-icon-info"),
+ info = g_slice_new0 (GtkWindowIconInfo);
+ g_object_set_qdata_full (G_OBJECT (window),
+ quark_gtk_window_icon_info,
info,
(GDestroyNotify)free_icon_info);
}
static ScreenIconInfo *
get_screen_icon_info (GdkScreen *screen)
{
- ScreenIconInfo *info = g_object_get_data (G_OBJECT (screen),
- "gtk-window-default-icon-pixmap");
+ ScreenIconInfo *info = g_object_get_qdata (G_OBJECT (screen),
+ quark_gtk_window_default_icon_pixmap);
if (!info)
{
- info = g_new0 (ScreenIconInfo, 1);
- g_object_set_data (G_OBJECT (screen), I_("gtk-window-default-icon-pixmap"), info);
+ info = g_slice_new0 (ScreenIconInfo);
+ g_object_set_qdata (G_OBJECT (screen),
+ quark_gtk_window_default_icon_pixmap, info);
}
if (info->serial != default_icon_serial)
* Retrieves the list of icons set by gtk_window_set_icon_list().
* The list is copied, but the reference count on each
* member won't be incremented.
- *
- * Return value: copy of window's icon list
+ *
+ * Return value: (element-type GdkPixbuf) (transfer container): copy of window's icon list
**/
GList*
gtk_window_get_icon_list (GtkWindow *window)
/**
* gtk_window_set_icon:
* @window: a #GtkWindow
- * @icon: icon image, or %NULL
- *
+ * @icon: (allow-none): icon image, or %NULL
+ *
* Sets up the icon representing a #GtkWindow. This icon is used when
* the window is minimized (also known as iconified). Some window
* managers or desktop environments may also place it in the window
/**
* gtk_window_set_icon_name:
* @window: a #GtkWindow
- * @name: the name of the themed icon
+ * @name: (allow-none): the name of the themed icon
*
* Sets the icon for the window from a named themed icon. See
- * the docs for #GtkIconTheme for more details.
- *
+ * the docs for #GtkIconTheme for more details.
+ *
* Note that this has nothing to do with the WM_ICON_NAME
* property which is mentioned in the ICCCM.
*
info = ensure_icon_info (window);
+ if (g_strcmp0 (info->icon_name, name) == 0)
+ return;
+
tmp = info->icon_name;
info->icon_name = g_strdup (name);
g_free (tmp);
* Gets the value set by gtk_window_set_icon() (or if you've
* called gtk_window_set_icon_list(), gets the first icon in
* the icon list).
- *
- * Return value: icon for window
+ *
+ * Return value: (transfer none): icon for window
**/
GdkPixbuf*
gtk_window_get_icon (GtkWindow *window)
/**
* gtk_window_set_default_icon_name:
* @name: the name of the themed icon
- *
+ *
* Sets an icon to be used as fallback for windows that haven't
* had gtk_window_set_icon_list() called on them from a named
* themed icon, see gtk_window_set_icon_name().
g_list_free (toplevels);
}
+/**
+ * gtk_window_get_default_icon_name:
+ *
+ * Returns the fallback icon name for windows that has been set
+ * with gtk_window_set_default_icon_name(). The returned
+ * string is owned by GTK+ and should not be modified. It
+ * is only valid until the next call to
+ * gtk_window_set_default_icon_name().
+ *
+ * Returns: the fallback icon name for windows
+ *
+ * Since: 2.16
+ */
+const gchar *
+gtk_window_get_default_icon_name (void)
+{
+ return default_icon_name;
+}
+
/**
* gtk_window_set_default_icon_from_file:
* @filename: location of icon file
g_object_thaw_notify (G_OBJECT (window));
- gtk_widget_queue_resize (GTK_WIDGET (window));
+ gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
}
/**
info->resize_width = width;
info->resize_height = height;
- gtk_widget_queue_resize (GTK_WIDGET (window));
+ gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
}
/**
* gtk_window_get_size:
* @window: a #GtkWindow
- * @width: return location for width, or %NULL
- * @height: return location for height, or %NULL
+ * @width: (out): return location for width, or %NULL
+ * @height: (out): return location for height, or %NULL
*
* Obtains the current size of @window. If @window is not onscreen,
* it returns the size GTK+ will suggest to the <link
* because the size of the window may change between the time that you
* get the size and the time that you perform some action assuming
* that size is the current size. To avoid race conditions, connect to
- * "configure_event" on the window and adjust your size-dependent
+ * "configure-event" on the window and adjust your size-dependent
* state to match the size delivered in the #GdkEventConfigure.
*
* Note 2: The returned size does <emphasis>not</emphasis> include the
* reference point. So, to place a window in the bottom right corner
* you would first set gravity to south east, then write:
* <literal>gtk_window_move (window, gdk_screen_width () - window_width,
- * gdk_screen_height () - window_height)</literal>.
+ * gdk_screen_height () - window_height)</literal> (note that this
+ * example does not take multi-head scenarios into account).
*
* The Extended Window Manager Hints specification at <ulink
* url="http://www.freedesktop.org/Standards/wm-spec">
* nice table of gravities in the "implementation notes" section.
*
* The gtk_window_get_position() documentation may also be relevant.
- *
- **/
+ */
void
gtk_window_move (GtkWindow *window,
gint x,
/**
* gtk_window_get_position:
* @window: a #GtkWindow
- * @root_x: return location for X coordinate of gravity-determined reference p\oint
- * @root_y: return location for Y coordinate of gravity-determined reference p\oint
+ * @root_x: return location for X coordinate of gravity-determined reference point
+ * @root_y: return location for Y coordinate of gravity-determined reference point
*
* This function returns the position you need to pass to
* gtk_window_move() to keep @window in its current position. This
gtk_window_free_key_hash (window);
- GTK_OBJECT_CLASS (parent_class)->destroy (object);
+ GTK_OBJECT_CLASS (gtk_window_parent_class)->destroy (object);
}
static void
gtk_window_finalize (GObject *object)
{
GtkWindow *window = GTK_WINDOW (object);
+ GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
GtkMnemonicHash *mnemonic_hash;
g_free (window->title);
window->keys_changed_handler = 0;
}
- G_OBJECT_CLASS (parent_class)->finalize (object);
+ if (window->screen)
+ g_signal_handlers_disconnect_by_func (window->screen,
+ gtk_window_on_composited_changed, window);
+
+ g_free (priv->startup_id);
+
+ G_OBJECT_CLASS (gtk_window_parent_class)->finalize (object);
}
static void
GtkWindow *window = GTK_WINDOW (widget);
GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
GdkWindow *toplevel;
+ gboolean auto_mnemonics;
GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
window->need_default_size = FALSE;
window->need_default_position = FALSE;
+ if (priv->reset_type_hint)
+ {
+ /* We should only reset the type hint when the application
+ * used gtk_window_set_type_hint() to change the hint.
+ * Some applications use X directly to change the properties;
+ * in that case, we shouldn't overwrite what they did.
+ */
+ gdk_window_set_type_hint (widget->window, priv->type_hint);
+ priv->reset_type_hint = FALSE;
+ }
+
gdk_window_show (widget->window);
if (window->frame)
gdk_window_show (window->frame);
- if (!disable_startup_notification &&
- !sent_startup_notification)
+ if (!disable_startup_notification)
+ {
+ /* Do we have a custom startup-notification id? */
+ if (priv->startup_id != NULL)
+ {
+ /* Make sure we have a "real" id */
+ if (!startup_id_is_fake (priv->startup_id))
+ gdk_notify_startup_complete_with_id (priv->startup_id);
+
+ g_free (priv->startup_id);
+ priv->startup_id = NULL;
+ }
+ else if (!sent_startup_notification)
+ {
+ sent_startup_notification = TRUE;
+ gdk_notify_startup_complete ();
+ }
+ }
+
+ /* if auto-mnemonics is enabled and mnemonics visible is not already set
+ * (as in the case of popup menus), then hide mnemonics initially
+ */
+ g_object_get (gtk_widget_get_settings (widget), "gtk-auto-mnemonics",
+ &auto_mnemonics, NULL);
+ if (auto_mnemonics && !priv->mnemonics_visible_set)
+ gtk_window_set_mnemonics_visible (window, FALSE);
+}
+
+static gboolean
+gtk_window_map_event (GtkWidget *widget,
+ GdkEventAny *event)
+{
+ if (!GTK_WIDGET_MAPPED (widget))
{
- sent_startup_notification = TRUE;
- gdk_notify_startup_complete ();
+ /* we should be be unmapped, but are getting a MapEvent, this may happen
+ * to toplevel XWindows if mapping was intercepted by a window manager
+ * and an unmap request occoured while the MapRequestEvent was still
+ * being handled. we work around this situaiton here by re-requesting
+ * the window being unmapped. more details can be found in:
+ * http://bugzilla.gnome.org/show_bug.cgi?id=316180
+ */
+ gdk_window_hide (widget->window);
}
+ return FALSE;
}
static void
}
state = gdk_window_get_state (widget->window);
- window->iconify_initially = state & GDK_WINDOW_STATE_ICONIFIED;
- window->maximize_initially = state & GDK_WINDOW_STATE_MAXIMIZED;
- window->stick_initially = state & GDK_WINDOW_STATE_STICKY;
- priv->above_initially = state & GDK_WINDOW_STATE_ABOVE;
- priv->below_initially = state & GDK_WINDOW_STATE_BELOW;
+ window->iconify_initially = (state & GDK_WINDOW_STATE_ICONIFIED) != 0;
+ window->maximize_initially = (state & GDK_WINDOW_STATE_MAXIMIZED) != 0;
+ window->stick_initially = (state & GDK_WINDOW_STATE_STICKY) != 0;
+ priv->above_initially = (state & GDK_WINDOW_STATE_ABOVE) != 0;
+ priv->below_initially = (state & GDK_WINDOW_STATE_BELOW) != 0;
}
static void
GtkWindowPrivate *priv;
window = GTK_WINDOW (widget);
-
priv = GTK_WINDOW_GET_PRIVATE (window);
/* ensure widget tree is properly size allocated */
window->frame = gdk_window_new (gtk_widget_get_root_window (widget),
&attributes, attributes_mask);
+ if (priv->opacity_set)
+ gdk_window_set_opacity (window->frame, priv->opacity);
+
gdk_window_set_user_data (window->frame, widget);
attributes.window_type = GDK_WINDOW_CHILD;
attributes_mask = GDK_WA_X | GDK_WA_Y;
parent_window = window->frame;
+
+ g_signal_connect (window,
+ "event",
+ G_CALLBACK (gtk_window_event),
+ NULL);
}
else
{
GDK_LEAVE_NOTIFY_MASK |
GDK_FOCUS_CHANGE_MASK |
GDK_STRUCTURE_MASK);
+ attributes.type_hint = priv->type_hint;
- attributes_mask |= GDK_WA_VISUAL | GDK_WA_COLORMAP;
+ attributes_mask |= GDK_WA_VISUAL | GDK_WA_COLORMAP | GDK_WA_TYPE_HINT;
attributes_mask |= (window->title ? GDK_WA_TITLE : 0);
attributes_mask |= (window->wmclass_name ? GDK_WA_WMCLASS : 0);
widget->window = gdk_window_new (parent_window, &attributes, attributes_mask);
+ if (!window->has_frame && priv->opacity_set)
+ gdk_window_set_opacity (widget->window, priv->opacity);
+
gdk_window_enable_synchronized_configure (widget->window);
gdk_window_set_user_data (widget->window, window);
if (!priv->deletable)
gdk_window_set_functions (widget->window, GDK_FUNC_ALL | GDK_FUNC_CLOSE);
- gdk_window_set_type_hint (widget->window, window->type_hint);
-
if (gtk_window_get_skip_pager_hint (window))
gdk_window_set_skip_pager_hint (widget->window, TRUE);
gdk_window_set_modal_hint (widget->window, TRUE);
else
gdk_window_set_modal_hint (widget->window, FALSE);
+
+ if (priv->startup_id)
+ {
+#ifdef GDK_WINDOWING_X11
+ guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
+ if (timestamp != GDK_CURRENT_TIME)
+ gdk_x11_window_set_user_time (widget->window, timestamp);
+#endif
+ if (!startup_id_is_fake (priv->startup_id))
+ gdk_window_set_startup_id (widget->window, priv->startup_id);
+ }
/* Icons */
gtk_window_realize_icon (window);
/* Icons */
gtk_window_unrealize_icon (window);
-
- (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
+
+ GTK_WIDGET_CLASS (gtk_window_parent_class)->unrealize (widget);
}
static void
*/
if (window->configure_request_count > 0)
- window->configure_request_count -= 1;
+ {
+ window->configure_request_count -= 1;
+ gdk_window_thaw_toplevel_updates_libgtk_only (widget->window);
+ }
/* As an optimization, we avoid a resize when possible.
*
if (!accel_mods)
{
static const guint bindings[] = {
- GDK_space, GDK_KP_Space, GDK_Return, GDK_KP_Enter, GDK_Up, GDK_KP_Up, GDK_Down, GDK_KP_Down,
+ GDK_space, GDK_KP_Space, GDK_Return, GDK_ISO_Enter, GDK_KP_Enter, GDK_Up, GDK_KP_Up, GDK_Down, GDK_KP_Down,
GDK_Left, GDK_KP_Left, GDK_Right, GDK_KP_Right, GDK_Tab, GDK_KP_Tab, GDK_ISO_Left_Tab,
};
guint i;
* overriding the standard key handling for a toplevel window.
*
* Return value: %TRUE if a widget in the focus chain handled the event.
- **/
+ *
+ * Since: 2.4
+ */
gboolean
gtk_window_propagate_key_event (GtkWindow *window,
GdkEventKey *event)
/* Chain up, invokes binding set */
if (!handled)
- handled = GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event);
+ handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_press_event (widget, event);
return handled;
}
/* Chain up, invokes binding set */
if (!handled)
- handled = GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event);
+ handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_release_event (widget, event);
return handled;
}
GdkEventFocus *event)
{
GtkWindow *window = GTK_WINDOW (widget);
+ gboolean auto_mnemonics;
_gtk_window_set_has_toplevel_focus (window, FALSE);
_gtk_window_set_is_active (window, FALSE);
+ /* set the mnemonic-visible property to false */
+ g_object_get (gtk_widget_get_settings (widget),
+ "gtk-auto-mnemonics", &auto_mnemonics, NULL);
+ if (auto_mnemonics)
+ gtk_window_set_mnemonics_visible (window, FALSE);
+
return FALSE;
}
{
GList *embedded_windows;
- embedded_windows = g_object_get_data (G_OBJECT (widget), "gtk-embedded");
+ embedded_windows = g_object_get_qdata (G_OBJECT (widget), quark_gtk_embedded);
if (embedded_windows)
{
GdkEvent *send_event = gdk_event_new (GDK_CLIENT_EVENT);
while (embedded_windows)
{
- guint xid = GPOINTER_TO_UINT (embedded_windows->data);
+ GdkNativeWindow xid = GDK_GPOINTER_TO_NATIVE_WINDOW(embedded_windows->data);
gdk_event_send_client_message_for_display (gtk_widget_get_display (widget), send_event, xid);
embedded_windows = embedded_windows->next;
}
{
gint base_width = 0;
gint base_height = 0;
+ gint min_width = 0;
+ gint min_height = 0;
gint width_inc = 1;
gint height_inc = 1;
base_width = geometry.base_width;
base_height = geometry.base_height;
}
- else if (flags & GDK_HINT_MIN_SIZE)
+ if (flags & GDK_HINT_MIN_SIZE)
{
- base_width = geometry.min_width;
- base_height = geometry.min_height;
+ min_width = geometry.min_width;
+ min_height = geometry.min_height;
}
if (flags & GDK_HINT_RESIZE_INC)
{
}
if (info->default_width > 0)
- *width = info->default_width * width_inc + base_width;
+ *width = MAX (info->default_width * width_inc + base_width, min_width);
if (info->default_height > 0)
- *height = info->default_height * height_inc + base_height;
+ *height = MAX (info->default_height * height_inc + base_height, min_height);
}
}
else
if (info->resize_height > 0)
*height = info->resize_height;
}
+
+ /* Don't ever request zero width or height, its not supported by
+ gdk. The size allocation code will round it to 1 anyway but if
+ we do it then the value returned from this function will is
+ not comparable to the size allocation read from the GtkWindow. */
+ *width = MAX (*width, 1);
+ *height = MAX (*height, 1);
}
static GtkWindowPosition
*y = monitor.y;
}
+static void
+clamp (gint *base,
+ gint extent,
+ gint clamp_base,
+ gint clamp_extent)
+{
+ if (extent > clamp_extent)
+ /* Center */
+ *base = clamp_base + clamp_extent/2 - extent/2;
+ else if (*base < clamp_base)
+ *base = clamp_base;
+ else if (*base + extent > clamp_base + clamp_extent)
+ *base = clamp_base + clamp_extent - extent;
+}
+
static void
clamp_window_to_rectangle (gint *x,
gint *y,
gint h,
const GdkRectangle *rect)
{
- gint outside_w, outside_h;
-
- outside_w = (*x + w) - (rect->x + rect->width);
- if (outside_w > 0)
- *x -= outside_w;
-
- outside_h = (*y + h) - (rect->y + rect->height);
- if (outside_h > 0)
- *y -= outside_h;
+#ifdef DEBUGGING_OUTPUT
+ g_print ("%s: %+d%+d %dx%d: %+d%+d: %dx%d", G_STRFUNC, rect->x, rect->y, rect->width, rect->height, *x, *y, w, h);
+#endif
- /* if larger than the screen, center on the screen. */
- if (*x < rect->x)
- *x += (rect->x - *x) / 2;
- if (*y < rect->y)
- *y += (rect->y - *y) / 2;
+ /* If it is too large, center it. If it fits on the monitor but is
+ * partially outside, move it to the closest edge. Do this
+ * separately in x and y directions.
+ */
+ clamp (x, w, rect->x, rect->width);
+ clamp (y, h, rect->y, rect->height);
+#ifdef DEBUGGING_OUTPUT
+ g_print (" ==> %+d%+d: %dx%d\n", *x, *y, w, h);
+#endif
}
parent_widget = (GtkWidget*) window->transient_parent;
pos = get_effective_position (window);
- info = gtk_window_get_geometry_info (window, TRUE);
-
- /* by default, don't change position requested */
- x = info->last.configure_request.x;
- y = info->last.configure_request.y;
+ info = gtk_window_get_geometry_info (window, FALSE);
+ /* by default, don't change position requested */
+ if (info)
+ {
+ x = info->last.configure_request.x;
+ y = info->last.configure_request.y;
+ }
+ else
+ {
+ x = 0;
+ y = 0;
+ }
+
+
if (window->need_default_position)
{
}
} /* if (window->need_default_position) */
- if (window->need_default_position &&
+ if (window->need_default_position && info &&
info->initial_pos_set)
{
x = info->initial_x;
allocation = widget->allocation;
gtk_widget_size_allocate (widget, &allocation);
- gdk_window_process_all_updates ();
+ gdk_window_process_updates (widget->window, TRUE);
gdk_window_configure_finished (widget->window);
*/
info->last = saved_last_info;
- gtk_widget_queue_resize (widget); /* migth recurse for GTK_RESIZE_IMMEDIATE */
+ gtk_widget_queue_resize_no_redraw (widget); /* migth recurse for GTK_RESIZE_IMMEDIATE */
}
return; /* Bail out, we didn't really process the move/resize */
new_request.width, new_request.height);
}
- /* Increment the number of have-not-yet-received-notify requests */
- window->configure_request_count += 1;
-
- /* for GTK_RESIZE_QUEUE toplevels, we are now awaiting a new
- * configure event in response to our resizing request.
- * the configure event will cause a new resize with
- * ->configure_notify_received=TRUE.
- * until then, we want to
- * - discard expose events
- * - coalesce resizes for our children
- * - defer any window resizes until the configure event arrived
- * to achieve this, we queue a resize for the window, but remove its
- * resizing handler, so resizing will not be handled from the next
- * idle handler but when the configure event arrives.
- *
- * FIXME: we should also dequeue the pending redraws here, since
- * we handle those ourselves upon ->configure_notify_received==TRUE.
- */
- if (container->resize_mode == GTK_RESIZE_QUEUE)
- {
- gtk_widget_queue_resize (widget);
- _gtk_container_dequeue_resize_handler (container);
+ if (window->type == GTK_WINDOW_POPUP)
+ {
+ GtkAllocation allocation;
+
+ /* Directly size allocate for override redirect (popup) windows. */
+ allocation.x = 0;
+ allocation.y = 0;
+ allocation.width = new_request.width;
+ allocation.height = new_request.height;
+
+ gtk_widget_size_allocate (widget, &allocation);
+
+ gdk_window_process_updates (widget->window, TRUE);
+
+ if (container->resize_mode == GTK_RESIZE_QUEUE)
+ gtk_widget_queue_draw (widget);
+ }
+ else
+ {
+ /* Increment the number of have-not-yet-received-notify requests */
+ window->configure_request_count += 1;
+ gdk_window_freeze_toplevel_updates_libgtk_only (widget->window);
+
+ /* for GTK_RESIZE_QUEUE toplevels, we are now awaiting a new
+ * configure event in response to our resizing request.
+ * the configure event will cause a new resize with
+ * ->configure_notify_received=TRUE.
+ * until then, we want to
+ * - discard expose events
+ * - coalesce resizes for our children
+ * - defer any window resizes until the configure event arrived
+ * to achieve this, we queue a resize for the window, but remove its
+ * resizing handler, so resizing will not be handled from the next
+ * idle handler but when the configure event arrives.
+ *
+ * FIXME: we should also dequeue the pending redraws here, since
+ * we handle those ourselves upon ->configure_notify_received==TRUE.
+ */
+ if (container->resize_mode == GTK_RESIZE_QUEUE)
+ {
+ gtk_widget_queue_resize_no_redraw (widget);
+ _gtk_container_dequeue_resize_handler (container);
+ }
}
}
else
if (!GTK_WIDGET_APP_PAINTABLE (widget))
gtk_window_paint (widget, &event->area);
- if (GTK_WIDGET_CLASS (parent_class)->expose_event)
- return GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event);
+ if (GTK_WIDGET_CLASS (gtk_window_parent_class)->expose_event)
+ return GTK_WIDGET_CLASS (gtk_window_parent_class)->expose_event (widget, event);
return FALSE;
}
* frame_event you can receive all events targeted at the frame.
*
* This function is used by the linux-fb port to implement managed
- * windows, but it could concievably be used by X-programs that
+ * windows, but it could conceivably be used by X-programs that
* want to do their own window decorations.
*
**/
* where the user can see it.
*
* If you are calling this function in response to a user interaction,
- * it is preferable to use gdk_window_present_with_time().
+ * it is preferable to use gtk_window_present_with_time().
*
**/
void
* in which case the window will be iconified before it ever appears
* onscreen.
*
- * You can track iconification via the "window_state_event" signal
+ * You can track iconification via the "window-state-event" signal
* on #GtkWidget.
*
**/
* linkend="gtk-X11-arch">window manager</link>) could iconify it
* again before your code which assumes deiconification gets to run.
*
- * You can track iconification via the "window_state_event" signal
+ * You can track iconification via the "window-state-event" signal
* on #GtkWidget.
**/
void
*
* It's permitted to call this function before showing a window.
*
- * You can track stickiness via the "window_state_event" signal
+ * You can track stickiness via the "window-state-event" signal
* on #GtkWidget.
*
**/
* manager</link>) could stick it again. But normally the window will
* end up stuck. Just don't write code that crashes if not.
*
- * You can track stickiness via the "window_state_event" signal
+ * You can track stickiness via the "window-state-event" signal
* on #GtkWidget.
*
**/
* in which case the window will be maximized when it appears onscreen
* initially.
*
- * You can track maximization via the "window_state_event" signal
+ * You can track maximization via the "window-state-event" signal
* on #GtkWidget.
*
**/
* managers honor requests to unmaximize. But normally the window will
* end up unmaximized. Just don't write code that crashes if not.
*
- * You can track maximization via the "window_state_event" signal
+ * You can track maximization via the "window-state-event" signal
* on #GtkWidget.
*
**/
* windows. But normally the window will end up fullscreen. Just
* don't write code that crashes if not.
*
- * You can track the fullscreen state via the "window_state_event" signal
+ * You can track the fullscreen state via the "window-state-event" signal
* on #GtkWidget.
*
* Since: 2.2
* windows. But normally the window will end up restored to its normal
* state. Just don't write code that crashes if not.
*
- * You can track the fullscreen state via the "window_state_event" signal
+ * You can track the fullscreen state via the "window-state-event" signal
* on #GtkWidget.
*
* Since: 2.2
* in which case the window will be kept above when it appears onscreen
* initially.
*
- * You can track the above state via the "window_state_event" signal
+ * You can track the above state via the "window-state-event" signal
* on #GtkWidget.
*
* Note that, according to the <ulink
widget = GTK_WIDGET (window);
priv = GTK_WINDOW_GET_PRIVATE (window);
- priv->above_initially = setting;
+ priv->above_initially = setting != FALSE;
if (setting)
priv->below_initially = FALSE;
* in which case the window will be kept below when it appears onscreen
* initially.
*
- * You can track the below state via the "window_state_event" signal
+ * You can track the below state via the "window-state-event" signal
* on #GtkWidget.
*
* Note that, according to the <ulink
widget = GTK_WIDGET (window);
priv = GTK_WINDOW_GET_PRIVATE (window);
- priv->below_initially = setting;
+ priv->below_initially = setting != FALSE;
if (setting)
priv->above_initially = FALSE;
{
g_return_if_fail (GTK_IS_WINDOW (window));
- gtk_window_set_policy (window, FALSE, resizable, FALSE);
+ gtk_window_set_policy_internal (window, FALSE, resizable, FALSE);
}
/**
/* gtk_window_move_resize() will adapt gravity
*/
- gtk_widget_queue_resize (GTK_WIDGET (window));
+ gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
g_object_notify (G_OBJECT (window), "gravity");
}
*
* Gets the value set by gtk_window_set_gravity().
*
- * Return value: window gravity
+ * Return value: (transfer none): window gravity
**/
GdkGravity
gtk_window_get_gravity (GtkWindow *window)
window->screen = screen;
gtk_widget_reset_rc_styles (widget);
if (screen != previous_screen)
- _gtk_widget_propagate_screen_changed (widget, previous_screen);
+ {
+ g_signal_handlers_disconnect_by_func (previous_screen,
+ gtk_window_on_composited_changed, window);
+ g_signal_connect (screen, "composited-changed",
+ G_CALLBACK (gtk_window_on_composited_changed), window);
+
+ _gtk_widget_propagate_screen_changed (widget, previous_screen);
+ _gtk_widget_propagate_composited_changed (widget);
+ }
g_object_notify (G_OBJECT (window), "screen");
if (was_mapped)
gtk_widget_map (widget);
}
+static void
+gtk_window_on_composited_changed (GdkScreen *screen,
+ GtkWindow *window)
+{
+ gtk_widget_queue_draw (GTK_WIDGET (window));
+
+ _gtk_widget_propagate_composited_changed (GTK_WIDGET (window));
+}
+
static GdkScreen *
gtk_window_check_screen (GtkWindow *window)
{
*
* Returns the #GdkScreen associated with @window.
*
- * Return value: a #GdkScreen.
+ * Return value: (transfer none): a #GdkScreen.
*
* Since: 2.2
*/
if (!window_group_type)
{
- static const GTypeInfo window_group_info =
+ const GTypeInfo window_group_info =
{
sizeof (GtkWindowGroupClass),
NULL, /* base_init */
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GtkWindowGroup),
- 16, /* n_preallocs */
+ 0, /* n_preallocs */
(GInstanceInitFunc) NULL,
};
if (window->group)
gtk_window_group_remove_window (window->group, window);
else
- window_group_cleanup_grabs (_gtk_window_get_group (NULL), window);
+ window_group_cleanup_grabs (gtk_window_get_group (NULL), window);
window->group = window_group;
GtkWindow *window)
{
g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
- g_return_if_fail (GTK_IS_WIDGET (window));
+ g_return_if_fail (GTK_IS_WINDOW (window));
g_return_if_fail (window->group == window_group);
g_object_ref (window);
g_object_unref (window);
}
-/* Return the group for the window or the default group
+/**
+ * gtk_window_group_list_windows:
+ * @window_group: a #GtkWindowGroup
+ *
+ * Returns a list of the #GtkWindows that belong to @window_group.
+ *
+ * Returns: (element-type GtkWidget) (transfer container): A newly-allocated list of
+ * windows inside the group.
+ *
+ * Since: 2.14
+ **/
+GList *
+gtk_window_group_list_windows (GtkWindowGroup *window_group)
+{
+ GList *toplevels, *toplevel, *group_windows;
+
+ g_return_val_if_fail (GTK_IS_WINDOW_GROUP (window_group), NULL);
+
+ group_windows = NULL;
+ toplevels = gtk_window_list_toplevels ();
+
+ for (toplevel = toplevels; toplevel; toplevel = toplevel->next)
+ {
+ GtkWindow *window = toplevel->data;
+
+ if (window_group == window->group)
+ group_windows = g_list_prepend (group_windows, window);
+ }
+
+ return g_list_reverse (group_windows);
+}
+
+/**
+ * gtk_window_get_group:
+ * @window: a #GtkWindow, or %NULL
+ *
+ * Returns the group for @window or the default group, if
+ * @window is %NULL or if @window does not have an explicit
+ * window group.
+ *
+ * Returns: (transfer none): the #GtkWindowGroup for a window or the default group
+ *
+ * Since: 2.10
*/
GtkWindowGroup *
-_gtk_window_get_group (GtkWindow *window)
+gtk_window_get_group (GtkWindow *window)
{
if (window && window->group)
return window->group;
* to be called when the window has its "final" size, i.e. after calling
* gtk_widget_show_all() on the contents and gtk_window_set_geometry_hints()
* on the window.
- *
- * <informalexample><programlisting>
- * #include <gtk/gtk.h>
+ * |[
+ * #include <gtk/gtk.h>
*
* static void
* fill_with_content (GtkWidget *vbox)
* {
- * /<!-- -->* fill with content... *<!-- -->/
+ * /* fill with content... */
* }
*
* int
* 100, 50, 0, 0, 100, 50, 10, 10, 0.0, 0.0, GDK_GRAVITY_NORTH_WEST
* };
*
- * gtk_init (&argc, &argv);
+ * gtk_init (&argc, &argv);
*
* window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
* vbox = gtk_vbox_new (FALSE, 0);
*
* gtk_window_set_geometry_hints (GTK_WINDOW (window),
* window,
- * &size_hints,
+ * &size_hints,
* GDK_HINT_MIN_SIZE |
* GDK_HINT_BASE_SIZE |
* GDK_HINT_RESIZE_INC);
* if (argc > 1)
* {
* if (!gtk_window_parse_geometry (GTK_WINDOW (window), argv[1]))
- * fprintf (stderr, "Failed to parse '%s'\n", argv[1]);
+ * fprintf (stderr, "Failed to parse '%s'\n", argv[1]);
* }
*
* gtk_widget_show_all (window);
*
* return 0;
* }
- * </programlisting></informalexample>
+ * ]|
*
* Return value: %TRUE if string was parsed successfully
**/
{
guint keyval;
guint modifiers;
- gboolean is_mnemonic;
+ guint is_mnemonic : 1;
};
+static void
+window_key_entry_destroy (gpointer data)
+{
+ g_slice_free (GtkWindowKeyEntry, data);
+}
+
static void
add_to_key_hash (GtkWindow *window,
guint keyval,
{
GtkKeyHash *key_hash = data;
- GtkWindowKeyEntry *entry = g_new (GtkWindowKeyEntry, 1);
+ GtkWindowKeyEntry *entry = g_slice_new (GtkWindowKeyEntry);
entry->keyval = keyval;
entry->modifiers = modifiers;
gtk_window_get_key_hash (GtkWindow *window)
{
GdkScreen *screen = gtk_window_check_screen (window);
- GtkKeyHash *key_hash = g_object_get_data (G_OBJECT (window), "gtk-window-key-hash");
+ GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
if (key_hash)
return key_hash;
key_hash = _gtk_key_hash_new (gdk_keymap_get_for_display (gdk_screen_get_display (screen)),
- (GDestroyNotify)g_free);
+ (GDestroyNotify)window_key_entry_destroy);
_gtk_window_keys_foreach (window, add_to_key_hash, key_hash);
- g_object_set_data (G_OBJECT (window), I_("gtk-window-key-hash"), key_hash);
+ g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, key_hash);
return key_hash;
}
static void
gtk_window_free_key_hash (GtkWindow *window)
{
- GtkKeyHash *key_hash = g_object_get_data (G_OBJECT (window), "gtk-window-key-hash");
+ GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
if (key_hash)
{
_gtk_key_hash_free (key_hash);
- g_object_set_data (G_OBJECT (window), "gtk-window-key-hash", NULL);
+ g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, NULL);
}
}
* called by the default ::key_press_event handler for toplevel windows,
* however in some cases it may be useful to call this directly when
* overriding the standard key handling for a toplevel window.
- *
+ *
* Return value: %TRUE if a mnemonic or accelerator was found and activated.
- **/
+ *
+ * Since: 2.4
+ */
gboolean
gtk_window_activate_key (GtkWindow *window,
GdkEventKey *event)
{
- GtkKeyHash *key_hash = g_object_get_data (G_OBJECT (window), "gtk-window-key-hash");
+ GtkKeyHash *key_hash;
GtkWindowKeyEntry *found_entry = NULL;
+ gboolean enable_mnemonics;
+ gboolean enable_accels;
+
+ g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
+ g_return_val_if_fail (event != NULL, FALSE);
+
+ key_hash = gtk_window_get_key_hash (window);
- if (!key_hash)
- {
- gtk_window_keys_changed (window);
- key_hash = g_object_get_data (G_OBJECT (window), "gtk-window-key-hash");
- }
-
if (key_hash)
{
+ GSList *tmp_list;
GSList *entries = _gtk_key_hash_lookup (key_hash,
event->hardware_keycode,
event->state,
gtk_accelerator_get_default_mod_mask (),
event->group);
- GSList *tmp_list;
+
+ g_object_get (gtk_widget_get_settings (GTK_WIDGET (window)),
+ "gtk-enable-mnemonics", &enable_mnemonics,
+ "gtk-enable-accels", &enable_accels,
+ NULL);
for (tmp_list = entries; tmp_list; tmp_list = tmp_list->next)
{
GtkWindowKeyEntry *entry = tmp_list->data;
if (entry->is_mnemonic)
- {
- found_entry = entry;
- break;
- }
+ {
+ if (enable_mnemonics)
+ {
+ found_entry = entry;
+ break;
+ }
+ }
+ else
+ {
+ if (enable_accels && !found_entry)
+ {
+ found_entry = entry;
+ }
+ }
}
-
- if (!found_entry && entries)
- found_entry = entries->data;
g_slist_free (entries);
}
if (found_entry)
{
if (found_entry->is_mnemonic)
- return gtk_window_mnemonic_activate (window, found_entry->keyval, found_entry->modifiers);
+ {
+ if (enable_mnemonics)
+ return gtk_window_mnemonic_activate (window, found_entry->keyval,
+ found_entry->modifiers);
+ }
else
- return gtk_accel_groups_activate (G_OBJECT (window), found_entry->keyval, found_entry->modifiers);
+ {
+ if (enable_accels)
+ return gtk_accel_groups_activate (G_OBJECT (window), found_entry->keyval,
+ found_entry->modifiers);
+ }
}
- else
- return FALSE;
+
+ return FALSE;
}
static void
}
}
+/**
+ * _gtk_window_set_is_toplevel:
+ * @window: a #GtkWindow
+ * @is_toplevel: %TRUE if the window is still a real toplevel (nominally a
+ * parent of the root window); %FALSE if it is not (for example, for an
+ * in-process, parented GtkPlug)
+ *
+ * Internal function used by #GtkPlug when it gets parented/unparented by a
+ * #GtkSocket. This keeps the @window's #GTK_TOPLEVEL flag in sync with the
+ * global list of toplevel windows.
+ */
+void
+_gtk_window_set_is_toplevel (GtkWindow *window,
+ gboolean is_toplevel)
+{
+ if (gtk_widget_is_toplevel (GTK_WIDGET (window)))
+ g_assert (g_slist_find (toplevel_list, window) != NULL);
+ else
+ g_assert (g_slist_find (toplevel_list, window) == NULL);
+
+ if (is_toplevel == gtk_widget_is_toplevel (GTK_WIDGET (window)))
+ return;
+
+ if (is_toplevel)
+ {
+ GTK_WIDGET_SET_FLAGS (window, GTK_TOPLEVEL);
+ toplevel_list = g_slist_prepend (toplevel_list, window);
+ }
+ else
+ {
+ GTK_WIDGET_UNSET_FLAGS (window, GTK_TOPLEVEL);
+ toplevel_list = g_slist_remove (toplevel_list, window);
+ }
+}
+
/**
* _gtk_window_set_has_toplevel_focus:
* @window: a #GtkWindow
* gtk_window_set_auto_startup_notification:
* @setting: %TRUE to automatically do startup notification
*
- * By default, after showing the first #GtkWindow for each #GdkScreen,
- * GTK+ calls gdk_screen_notify_startup_complete(). Call this
- * function to disable the automatic startup notification. You might
- * do this if your first window is a splash screen, and you want to
- * delay notification until after your real main window has been
- * shown, for example.
+ * By default, after showing the first #GtkWindow, GTK+ calls
+ * gdk_notify_startup_complete(). Call this function to disable
+ * the automatic startup notification. You might do this if your
+ * first window is a splash screen, and you want to delay notification
+ * until after your real main window has been shown, for example.
*
* In that example, you would disable startup notification
* temporarily, show your splash screen, then re-enable it so that
disable_startup_notification = !setting;
}
-#ifdef G_OS_WIN32
+/**
+ * gtk_window_get_window_type:
+ * @window: a #GtkWindow
+ *
+ * Gets the type of the window. See #GtkWindowType.
+ *
+ * Return value: the type of the window
+ *
+ * Since: 2.20
+ **/
+GtkWindowType
+gtk_window_get_window_type (GtkWindow *window)
+{
+ g_return_val_if_fail (GTK_IS_WINDOW (window), GTK_WINDOW_TOPLEVEL);
+
+ return window->type;
+}
+
+gboolean
+gtk_window_get_mnemonics_visible (GtkWindow *window)
+{
+ GtkWindowPrivate *priv;
+
+ g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
+
+ priv = GTK_WINDOW_GET_PRIVATE (window);
+
+ return priv->mnemonics_visible;
+}
+
+void
+gtk_window_set_mnemonics_visible (GtkWindow *window,
+ gboolean setting)
+{
+ GtkWindowPrivate *priv;
+
+ g_return_if_fail (GTK_IS_WINDOW (window));
+
+ priv = GTK_WINDOW_GET_PRIVATE (window);
+
+ setting = setting != FALSE;
+
+ if (priv->mnemonics_visible != setting)
+ {
+ priv->mnemonics_visible = setting;
+ g_object_notify (G_OBJECT (window), "mnemonics-visible");
+ }
+
+ priv->mnemonics_visible_set = TRUE;
+}
+
+#if defined (G_OS_WIN32) && !defined (_WIN64)
#undef gtk_window_set_icon_from_file