-/* GTK - The GIMP Toolkit
+/* GTK - The GTK+ Toolkit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
*/
#define GTK_MENU_INTERNALS
-#include <config.h>
+#include "config.h"
#include <string.h> /* memset */
#include "gdk/gdkkeysyms.h"
#include "gtkaccellabel.h"
enum {
PROP_0,
+ PROP_ACTIVE,
+ PROP_ACCEL_GROUP,
+ PROP_ACCEL_PATH,
+ PROP_ATTACH_WIDGET,
PROP_TEAROFF_STATE,
- PROP_TEAROFF_TITLE
+ PROP_TEAROFF_TITLE,
+ PROP_MONITOR
};
enum {
GValue *value,
GParamSpec *pspec);
static void gtk_menu_destroy (GtkObject *object);
-static void gtk_menu_finalize (GObject *object);
static void gtk_menu_realize (GtkWidget *widget);
static void gtk_menu_unrealize (GtkWidget *widget);
static void gtk_menu_size_request (GtkWidget *widget,
gtk_widget_queue_resize (GTK_WIDGET (menu));
}
+static void
+attach_info_free (AttachInfo *info)
+{
+ g_slice_free (AttachInfo, info);
+}
+
static AttachInfo *
get_attach_info (GtkWidget *child)
{
if (!ai)
{
- ai = g_new0 (AttachInfo, 1);
- g_object_set_data_full (object, I_(ATTACH_INFO_KEY), ai, g_free);
+ ai = g_slice_new0 (AttachInfo);
+ g_object_set_data_full (object, I_(ATTACH_INFO_KEY), ai,
+ (GDestroyNotify) attach_info_free);
}
return ai;
GtkMenuShellClass *menu_shell_class = GTK_MENU_SHELL_CLASS (class);
GtkBindingSet *binding_set;
- gobject_class->finalize = gtk_menu_finalize;
gobject_class->set_property = gtk_menu_set_property;
gobject_class->get_property = gtk_menu_get_property;
_gtk_marshal_VOID__ENUM,
G_TYPE_NONE, 1,
GTK_TYPE_SCROLL_TYPE);
-
+
+ /**
+ * GtkMenu:active:
+ *
+ * The currently selected menu item.
+ *
+ * Since: 2.14
+ **/
+ g_object_class_install_property (gobject_class,
+ PROP_ACTIVE,
+ g_param_spec_uint ("active",
+ P_("Active"),
+ P_("The currently selected menu item"),
+ 0, G_MAXUINT, 0,
+ GTK_PARAM_READWRITE));
+
+ /**
+ * GtkMenu:accel-group:
+ *
+ * The accel group holding accelerators for the menu.
+ *
+ * Since: 2.14
+ **/
+ g_object_class_install_property (gobject_class,
+ PROP_ACCEL_GROUP,
+ g_param_spec_object ("accel-group",
+ P_("Accel Group"),
+ P_("The accel group holding accelerators for the menu"),
+ GTK_TYPE_ACCEL_GROUP,
+ GTK_PARAM_READWRITE));
+
+ /**
+ * GtkMenu:accel-path:
+ *
+ * An accel path used to conveniently construct accel paths of child items.
+ *
+ * Since: 2.14
+ **/
+ g_object_class_install_property (gobject_class,
+ PROP_ACCEL_PATH,
+ g_param_spec_string ("accel-path",
+ P_("Accel Path"),
+ P_("An accel path used to conveniently construct accel paths of child items"),
+ NULL,
+ GTK_PARAM_READWRITE));
+
+ /**
+ * GtkMenu:attach-widget:
+ *
+ * The widget the menu is attached to.
+ *
+ * Since: 2.14
+ **/
+ g_object_class_install_property (gobject_class,
+ PROP_ACCEL_PATH,
+ g_param_spec_string ("attach-widget",
+ P_("Attach Widget"),
+ P_("The widget the menu is attached to"),
+ NULL,
+ GTK_PARAM_READWRITE));
+
g_object_class_install_property (gobject_class,
PROP_TEAROFF_TITLE,
g_param_spec_string ("tearoff-title",
P_("Tearoff Title"),
P_("A title that may be displayed by the window manager when this menu is torn-off"),
- "",
+ NULL,
GTK_PARAM_READWRITE));
/**
FALSE,
GTK_PARAM_READWRITE));
+ /**
+ * GtkMenu:monitor:
+ *
+ * The monitor the menu will be popped up on.
+ *
+ * Since: 2.14
+ **/
+ g_object_class_install_property (gobject_class,
+ PROP_MONITOR,
+ g_param_spec_int ("monitor",
+ P_("Monitor"),
+ P_("The monitor the menu will be popped up on"),
+ -1, G_MAXINT, -1,
+ GTK_PARAM_READWRITE));
+
gtk_widget_class_install_style_property (widget_class,
g_param_spec_int ("vertical-padding",
P_("Vertical Padding"),
switch (prop_id)
{
+ case PROP_ACTIVE:
+ gtk_menu_set_active (menu, g_value_get_uint (value));
+ break;
+ case PROP_ACCEL_GROUP:
+ gtk_menu_set_accel_group (menu, g_value_get_object (value));
+ break;
+ case PROP_ACCEL_PATH:
+ gtk_menu_set_accel_path (menu, g_value_get_string (value));
+ break;
+ case PROP_ATTACH_WIDGET:
+ gtk_menu_attach (menu, g_value_get_object (value), 0, 0, 0, 0);
+ break;
case PROP_TEAROFF_STATE:
gtk_menu_set_tearoff_state (menu, g_value_get_boolean (value));
break;
case PROP_TEAROFF_TITLE:
gtk_menu_set_title (menu, g_value_get_string (value));
- break;
+ break;
+ case PROP_MONITOR:
+ gtk_menu_set_monitor (menu, g_value_get_int (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
switch (prop_id)
{
+ case PROP_ACTIVE:
+ g_value_set_uint (value, g_list_index (GTK_MENU_SHELL (menu)->children, gtk_menu_get_active (menu)));
+ break;
+ case PROP_ACCEL_GROUP:
+ g_value_set_object (value, gtk_menu_get_accel_group (menu));
+ break;
+ case PROP_ACCEL_PATH:
+ g_value_set_string (value, gtk_menu_get_accel_path (menu));
+ break;
+ case PROP_ATTACH_WIDGET:
+ g_value_set_object (value, gtk_menu_get_attach_widget (menu));
+ break;
case PROP_TEAROFF_STATE:
g_value_set_boolean (value, gtk_menu_get_tearoff_state (menu));
break;
case PROP_TEAROFF_TITLE:
g_value_set_string (value, gtk_menu_get_title (menu));
break;
+ case PROP_MONITOR:
+ g_value_set_int (value, gtk_menu_get_monitor (menu));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
static void
gtk_menu_destroy (GtkObject *object)
{
- GtkMenu *menu;
+ GtkMenu *menu = GTK_MENU (object);
GtkMenuAttachData *data;
GtkMenuPrivate *priv;
- g_return_if_fail (GTK_IS_MENU (object));
-
- menu = GTK_MENU (object);
-
gtk_menu_remove_scroll_timeout (menu);
data = g_object_get_data (G_OBJECT (object), attach_data_key);
GTK_OBJECT_CLASS (gtk_menu_parent_class)->destroy (object);
}
-static void
-gtk_menu_finalize (GObject *object)
-{
- GtkMenu *menu = GTK_MENU (object);
-
- g_free (menu->accel_path);
-
- G_OBJECT_CLASS (gtk_menu_parent_class)->finalize (object);
-}
-
static void
menu_change_screen (GtkMenu *menu,
GdkScreen *new_screen)
g_object_ref_sink (menu);
- data = g_new (GtkMenuAttachData, 1);
+ data = g_slice_new (GtkMenuAttachData);
data->attach_widget = attach_widget;
g_signal_connect (attach_widget, "screen_changed",
{
list = g_list_prepend (list, menu);
}
- g_object_set_data_full (G_OBJECT (attach_widget), I_(ATTACHED_MENUS), list, (GtkDestroyNotify) g_list_free);
-
+ g_object_set_data_full (G_OBJECT (attach_widget), I_(ATTACHED_MENUS), list,
+ (GDestroyNotify) g_list_free);
+
if (GTK_WIDGET_STATE (menu) != GTK_STATE_NORMAL)
gtk_widget_set_state (GTK_WIDGET (menu), GTK_STATE_NORMAL);
list = g_object_steal_data (G_OBJECT (data->attach_widget), ATTACHED_MENUS);
list = g_list_remove (list, menu);
if (list)
- g_object_set_data_full (G_OBJECT (data->attach_widget), I_(ATTACHED_MENUS), list, (GtkDestroyNotify) g_list_free);
+ g_object_set_data_full (G_OBJECT (data->attach_widget), I_(ATTACHED_MENUS), list,
+ (GDestroyNotify) g_list_free);
else
g_object_set_data (G_OBJECT (data->attach_widget), I_(ATTACHED_MENUS), NULL);
if (GTK_WIDGET_REALIZED (menu))
gtk_widget_unrealize (GTK_WIDGET (menu));
- g_free (data);
+ g_slice_free (GtkMenuAttachData, data);
/* Fallback title for menu comes from attach widget */
gtk_menu_update_title (menu);
gtk_menu_remove (GtkContainer *container,
GtkWidget *widget)
{
- GtkMenu *menu;
+ GtkMenu *menu = GTK_MENU (container);
- g_return_if_fail (GTK_IS_MENU (container));
g_return_if_fail (GTK_IS_MENU_ITEM (widget));
- menu = GTK_MENU (container);
-
/* Clear out old_active_menu_item if it matches the item we are removing
*/
if (menu->old_active_menu_item == widget)
}
/* Set transient for to get the right window group and parent relationship */
- if (parent_toplevel && GTK_IS_WINDOW (parent_toplevel))
+ if (GTK_IS_WINDOW (parent_toplevel))
gtk_window_set_transient_for (GTK_WINDOW (menu->toplevel),
GTK_WINDOW (parent_toplevel));
*/
gtk_widget_show (menu->toplevel);
- /* flush the X event queue for the popup to become realized and
- * mapped, since grabbing requires a mapped window. (this only works
- * for popups, regular windows need gtk_widget_show_now() to sync
- * with window manager interaction).
- */
- gdk_flush ();
-
if (xgrab_shell == widget)
popup_grab_on_window (widget->window, activate_time, grab_keyboard); /* Should always succeed */
gtk_grab_add (GTK_WIDGET (menu));
* Assigning accel paths to menu items then enables the user to change
* their accelerators at runtime. More details about accelerator paths
* and their default setups can be found at gtk_accel_map_add_entry().
+ *
+ * Note that @accel_path string will be stored in a #GQuark. Therefore, if you
+ * pass a static string, you can save some memory by interning it first with
+ * g_intern_static_string().
*/
void
gtk_menu_set_accel_path (GtkMenu *menu,
if (accel_path)
g_return_if_fail (accel_path[0] == '<' && strchr (accel_path, '/')); /* simplistic check */
- g_free (menu->accel_path);
- menu->accel_path = g_strdup (accel_path);
+ /* FIXME: accel_path should be defined as const gchar* */
+ menu->accel_path = (gchar*)g_intern_string (accel_path);
if (menu->accel_path)
_gtk_menu_refresh_accel_paths (menu, FALSE);
}
+/**
+ * gtk_menu_get_accel_path
+ * @menu: a valid #GtkMenu
+ *
+ * Retrieves the accelerator path set on the menu.
+ *
+ * Since: 2.14
+ */
+const gchar*
+gtk_menu_get_accel_path (GtkMenu *menu)
+{
+ g_return_val_if_fail (GTK_IS_MENU (menu), NULL);
+
+ return menu->accel_path;
+}
+
typedef struct {
GtkMenu *menu;
gboolean group_changed;
{
GtkWidget *toplevel;
- menu->tearoff_window = gtk_widget_new (GTK_TYPE_WINDOW,
+ menu->tearoff_window = g_object_new (GTK_TYPE_WINDOW,
"type", GTK_WINDOW_TOPLEVEL,
"screen", gtk_widget_get_screen (menu->toplevel),
"app-paintable", TRUE,
static void
gtk_menu_unrealize (GtkWidget *widget)
{
- GtkMenu *menu;
-
- g_return_if_fail (GTK_IS_MENU (widget));
-
- menu = GTK_MENU (widget);
+ GtkMenu *menu = GTK_MENU (widget);
menu_grab_transfer_window_destroy (menu);
widget->window,
priv->upper_arrow_state,
GTK_SHADOW_OUT,
- &event->area, widget, "menu",
+ &event->area, widget, "menu_scroll_arrow_up",
upper.x,
upper.y,
upper.width,
widget->window,
priv->lower_arrow_state,
GTK_SHADOW_OUT,
- &event->area, widget, "menu",
+ &event->area, widget, "menu_scroll_arrow_down",
lower.x,
lower.y,
lower.width,
priv->monitor_num = monitor_num;
}
+/**
+ * gtk_menu_get_monitor:
+ * @menu: a #GtkMenu
+ *
+ * Retrieves the number of the monitor on which to show the menu.
+ *
+ * Returns: the number of the monitor on which the menu should
+ * be popped up or -1
+ *
+ * Since: 2.14
+ **/
+gint
+gtk_menu_get_monitor (GtkMenu *menu)
+{
+ GtkMenuPrivate *priv;
+ g_return_val_if_fail (GTK_IS_MENU (menu), -1);
+
+ priv = gtk_menu_get_private (menu);
+
+ return priv->monitor_num;
+}
+
/**
* gtk_menu_get_for_attach_widget:
* @widget: a #GtkWidget