/*
- * This file is part of hildon-libs
+ * This file is a part of hildon
*
* Copyright (C) 2006 Nokia Corporation, all rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; version 2.1 of
- * the License.
+ * the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
*
*/
+/**
+ * SECTION:hildon-window
+ * @short_description: Widget representing a top-level window in the Hildon framework.
+ *
+ * The HildonWindow is a GTK widget which represents a top-level
+ * window in the Hildon framework. It is derived from the GtkWindow
+ * and provides additional commodities specific to the Hildon
+ * framework.
+
+ * Among these windows in the Hildon framework can have a single menu
+ * attached, which is toggled with a hardware key or by tapping
+ * a custom button in the window frame. This menu can be set
+ * by providing a GtkMenu to the hildon_window_set_menu() method.
+
+ * Similarly a window in the Hildon framework can have several toolbars
+ * attached. These can be added to the HildonWindow with
+ * hildon_window_add_toolbar()..
+ *
+ * <example>
+ * <title>Creating a HildonWindow</title>
+ * <programlisting>
+ * HildonWindow *window;
+ * GtkToolbar *toolbar;
+ * GtkMenu *menu;
+ * GdkPixbuf *icon_pixbuf;
+ * <!-- -->
+ * window = HILDON_WINDOW (hildon_window_new());
+ * <!-- -->
+ * toolbar = create_toolbar();
+ * <!-- -->
+ * menu = create_menu();
+ * <!-- -->
+ * icon_pixbuf = create_icon();
+ * <!-- -->
+ * hildon_window_set_menu (window, menu);
+ * <!-- -->
+ * hildon_window_add_toolbar (window, toolbar);
+ * <!-- -->
+ * // Can be used to set the window fullscreen
+ * gtk_window_fullscreen (GTK_WINDOW (window));
+ * <!-- -->
+ * // Used to trigger the blinking of the window's icon in the task navigator
+ * gtk_window_set_urgency_hint (GTK_WINDOW (window), TRUE);
+ * <!-- -->
+ * // Change the window's icon in the task navigator
+ * gtk_window_set_icon (GTK_WINDOW (window), icon_pixbuf);
+ * </programlisting>
+ * </example>
+ *
+ */
+
#include "hildon-window.h"
#include <memory.h>
#include <string.h>
#define TITLE_SEPARATOR " - "
-static GtkWindowClass *parent_class;
-
typedef void (*HildonWindowSignal) (HildonWindow *, gint, gpointer);
static void
static void
hildon_window_unrealize (GtkWidget *widget);
+static void
+hildon_window_map (GtkWidget *widget);
+
+static void
+hildon_window_unmap (GtkWidget *widget);
+
static gboolean
hildon_window_key_press_event (GtkWidget *widget,
GdkEventKey *event);
static gboolean
hildon_window_window_state_event (GtkWidget *widget,
GdkEventWindowState *event);
+static gboolean
+hildon_window_focus_out_event (GtkWidget *widget,
+ GdkEventFocus *event);
static void
hildon_window_notify (GObject *gobject,
hildon_window_is_topmost_notify (HildonWindow *window);
static gboolean
-hildon_window_toggle_menu (HildonWindow * self);
+hildon_window_toggle_menu (HildonWindow * self,
+ guint button,
+ guint32 time);
static gboolean
hildon_window_escape_timeout (gpointer data);
MAX_WIN_MESSAGES
};
-GType
-hildon_window_get_type (void)
-{
- static GType window_type = 0;
-
- if (!window_type) {
- static const GTypeInfo window_info = {
- sizeof(HildonWindowClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) hildon_window_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(HildonWindow),
- 0, /* n_preallocs */
- (GInstanceInitFunc) hildon_window_init,
- };
- window_type = g_type_register_static(GTK_TYPE_WINDOW,
- "HildonWindow",
- &window_info, 0);
- }
- return window_type;
-}
+G_DEFINE_TYPE (HildonWindow, hildon_window, GTK_TYPE_WINDOW);
static void
hildon_window_class_init (HildonWindowClass * window_class)
{
/* Get convenience variables */
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (window_class);
- GObjectClass *object_class = G_OBJECT_CLASS (window_class);
- GtkContainerClass *container_class = GTK_CONTAINER_CLASS (window_class);
-
- /* Set the global parent_class here */
- parent_class = g_type_class_peek_parent (window_class);
-
- object_class->get_property = hildon_window_get_property;
- object_class->notify = hildon_window_notify;
-
- /* Set the widgets virtual functions */
- widget_class->size_allocate = hildon_window_size_allocate;
- widget_class->size_request = hildon_window_size_request;
- widget_class->expose_event = hildon_window_expose;
- widget_class->show_all = hildon_window_show_all;
- widget_class->realize = hildon_window_realize;
- widget_class->unrealize = hildon_window_unrealize;
- widget_class->key_press_event = hildon_window_key_press_event;
- widget_class->key_release_event = hildon_window_key_release_event;
- widget_class->window_state_event = hildon_window_window_state_event;
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (window_class);
+ GObjectClass *object_class = G_OBJECT_CLASS (window_class);
+ GtkContainerClass *container_class = GTK_CONTAINER_CLASS (window_class);
+
+ object_class->get_property = hildon_window_get_property;
+ object_class->notify = hildon_window_notify;
+ widget_class->size_allocate = hildon_window_size_allocate;
+ widget_class->size_request = hildon_window_size_request;
+ widget_class->expose_event = hildon_window_expose;
+ widget_class->show_all = hildon_window_show_all;
+ widget_class->realize = hildon_window_realize;
+ widget_class->unrealize = hildon_window_unrealize;
+ widget_class->key_press_event = hildon_window_key_press_event;
+ widget_class->key_release_event = hildon_window_key_release_event;
+ widget_class->window_state_event = hildon_window_window_state_event;
+ widget_class->focus_out_event = hildon_window_focus_out_event;
+ widget_class->map = hildon_window_map;
+ widget_class->unmap = hildon_window_unmap;
/* now the object stuff */
- object_class->finalize = hildon_window_finalize;
+ object_class->finalize = hildon_window_finalize;
/* To the container */
- container_class->forall = hildon_window_forall;
+ container_class->forall = hildon_window_forall;
/* gtkobject stuff*/
GTK_OBJECT_CLASS (window_class)->destroy = hildon_window_destroy;
sizeof (struct _HildonWindowPrivate));
/* Install properties */
+
+ /**
+ * HildonWindow:is-topmost:
+ *
+ * Whether the window is currently activated by the window manager.
+ */
g_object_class_install_property (object_class, PROP_IS_TOPMOST,
g_param_spec_boolean ("is-topmost",
"Is top-most",
self = HILDON_WINDOW (obj_self);
- g_free (priv->borders);
- g_free (priv->toolbar_borders);
+ if (priv->escape_timeout) {
+ g_source_remove (priv->escape_timeout);
+ priv->escape_timeout = 0;
+ }
+
+ if (priv->borders)
+ gtk_border_free (priv->borders);
+
+ if (priv->toolbar_borders)
+ gtk_border_free (priv->toolbar_borders);
- if (G_OBJECT_CLASS (parent_class)->finalize)
- G_OBJECT_CLASS (parent_class)->finalize (obj_self);
+ if (G_OBJECT_CLASS (hildon_window_parent_class)->finalize)
+ G_OBJECT_CLASS (hildon_window_parent_class)->finalize (obj_self);
}
Window active_window;
HildonWindowPrivate *priv;
- GTK_WIDGET_CLASS (parent_class)->realize (widget);
+ GTK_WIDGET_CLASS (hildon_window_parent_class)->realize (widget);
priv = HILDON_WINDOW_GET_PRIVATE (widget);
g_assert (priv != NULL);
widget);
gtk_widget_unrealize (GTK_WIDGET (priv->vbox));
- GTK_WIDGET_CLASS(parent_class)->unrealize(widget);
+ GTK_WIDGET_CLASS(hildon_window_parent_class)->unrealize(widget);
+}
+
+static void
+hildon_window_map (GtkWidget *widget)
+{
+ HildonWindowPrivate *priv = HILDON_WINDOW_GET_PRIVATE (widget);
+ g_assert (priv != NULL);
+
+ if (GTK_WIDGET_CLASS (hildon_window_parent_class)->map)
+ GTK_WIDGET_CLASS (hildon_window_parent_class)->map (widget);
+
+ if (GTK_WIDGET_VISIBLE (priv->vbox))
+ gtk_widget_map (priv->vbox);
+}
+
+static void
+hildon_window_unmap (GtkWidget *widget)
+{
+ HildonWindowPrivate *priv = HILDON_WINDOW_GET_PRIVATE (widget);
+ g_assert (priv != NULL);
+
+ gtk_widget_unmap (priv->vbox);
+
+ if (GTK_WIDGET_CLASS (hildon_window_parent_class)->unmap)
+ GTK_WIDGET_CLASS (hildon_window_parent_class)->unmap (widget);
}
static void
static void
hildon_window_get_borders (HildonWindow *window)
{
+ GtkBorder zero = {0, 0, 0, 0};
HildonWindowPrivate *priv = HILDON_WINDOW_GET_PRIVATE (window);
g_assert (priv);
- g_free (priv->borders);
- g_free (priv->toolbar_borders);
+ GtkBorder *borders = NULL;
+ GtkBorder *toolbar_borders = NULL;
- gtk_widget_style_get (GTK_WIDGET (window), "borders",&priv->borders,
- "toolbar-borders", &priv->toolbar_borders,
- NULL);
+ if (priv->borders)
+ gtk_border_free (priv->borders);
+ if (priv->toolbar_borders)
+ gtk_border_free (priv->toolbar_borders);
- if (! priv->borders)
- priv->borders = (GtkBorder *) g_malloc0 (sizeof (GtkBorder));
+ priv->borders = NULL;
+ priv->toolbar_borders = NULL;
- if (! priv->toolbar_borders)
- priv->toolbar_borders = (GtkBorder *) g_malloc0 (sizeof (GtkBorder));
-}
+ gtk_widget_style_get (GTK_WIDGET (window), "borders",&borders,
+ "toolbar-borders", &toolbar_borders,
+ NULL);
-static void
-visible_toolbars (gpointer data,
- gpointer user_data)
-{
- if (GTK_WIDGET_VISIBLE (GTK_WIDGET (((GtkBoxChild *)data)->widget)))
- (*((gint *)user_data)) ++;
+ // We're doing a copy here instead of reusing the pointer,
+ // as we don't know where it comes from (has it been allocated using
+ // malloc or slices... and we want to free it sanely. Blowing on
+ // cold probbably.
+
+ if (borders) {
+ priv->borders = gtk_border_copy (borders);
+ gtk_border_free (borders);
+ } else
+ priv->borders = g_boxed_copy (GTK_TYPE_BORDER, &zero);
+
+ if (toolbar_borders) {
+ priv->toolbar_borders = gtk_border_copy (toolbar_borders);
+ gtk_border_free (toolbar_borders);
+ } else
+ priv->toolbar_borders = g_boxed_copy (GTK_TYPE_BORDER, &zero);
}
static gboolean
GtkBorder *b = priv->borders;
GtkBorder *tb = priv->toolbar_borders;
gint tb_height = 0;
- gint currently_visible_toolbars = 0;
if (! priv->borders) {
hildon_window_get_borders (HILDON_WINDOW (widget));
tb_height = bx->allocation.height + tb->top + tb->bottom;
- g_list_foreach (box->children, visible_toolbars,
- ¤tly_visible_toolbars);
-
paint_toolbar (widget, box,
event, priv->fullscreen);
/* Draw the left and right window border */
gint side_borders_height = widget->allocation.height - b->top;
- if (currently_visible_toolbars)
+ if (priv->visible_toolbars)
side_borders_height -= tb_height;
else
side_borders_height -= b->bottom;
}
/* If no toolbar, draw the bottom window border */
- if (!currently_visible_toolbars && b->bottom > 0)
+ if (! priv->visible_toolbars && b->bottom > 0)
{
gtk_paint_box (widget->style, widget->window,
GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
/* don't draw the window stuff as it overwrites our borders with a blank
* rectangle. Instead start with the drawing of the GtkBin */
- GTK_WIDGET_CLASS (g_type_class_peek_parent (parent_class))->expose_event (widget, event);
+ GTK_WIDGET_CLASS (g_type_class_peek_parent (hildon_window_parent_class))->expose_event (widget, event);
/* FIXME Not sure why this is commented out
- * GTK_WIDGET_CLASS (parent_class))->
+ * GTK_WIDGET_CLASS (hildon_window_parent_class))->
* expose_event (widget, event);
*/
g_return_if_fail (callback != NULL);
g_assert (priv);
- GTK_CONTAINER_CLASS (parent_class)->forall (container, include_internals,
+ GTK_CONTAINER_CLASS (hildon_window_parent_class)->forall (container, include_internals,
callback, callback_data);
if (include_internals && priv->vbox != NULL)
(* callback)(GTK_WIDGET (priv->vbox), callback_data);
g_assert (priv != NULL);
- GTK_WIDGET_CLASS (parent_class)->show_all (widget);
+ GTK_WIDGET_CLASS (hildon_window_parent_class)->show_all (widget);
gtk_widget_show_all (priv->vbox);
}
{
HildonWindow *self = HILDON_WINDOW (obj);
HildonWindowPrivate *priv = HILDON_WINDOW_GET_PRIVATE (obj);
- GList *menu_list;
-
+ GList *menu_list = NULL;
+ GList *menu_node = NULL;
+
g_assert (priv != NULL);
if (priv->vbox != NULL)
}
menu_list = g_list_copy (gtk_menu_get_for_attach_widget (GTK_WIDGET (obj)));
+ menu_node = menu_list;
- while (menu_list)
+ while (menu_node)
{
- if (GTK_IS_MENU(menu_list->data))
+ if (GTK_IS_MENU (menu_node->data))
{
- if (GTK_WIDGET_VISIBLE (GTK_WIDGET (menu_list->data)))
+ if (GTK_WIDGET_VISIBLE (GTK_WIDGET (menu_node->data)))
{
- gtk_menu_popdown (GTK_MENU (menu_list->data));
- gtk_menu_shell_deactivate (GTK_MENU_SHELL (menu_list->data));
+ gtk_menu_popdown (GTK_MENU (menu_node->data));
+ gtk_menu_shell_deactivate (GTK_MENU_SHELL (menu_node->data));
+ }
+ gtk_menu_detach (GTK_MENU (menu_node->data));
+
+ /* Destroy it, but only if it's not a common menu */
+ if (priv->program &&
+ hildon_program_get_common_menu (priv->program) != menu_node->data) {
+ gtk_object_destroy (GTK_OBJECT (menu_node->data));
+ g_object_unref (menu_node->data);
}
- gtk_menu_detach (GTK_MENU (menu_list->data));
}
- menu_list = menu_list->next;
+ menu_node = menu_node->next;
}
g_list_free (menu_list);
+ menu_list = NULL;
if (priv->program)
{
gtk_widget_set_events (GTK_WIDGET(obj), 0);
- GTK_OBJECT_CLASS (parent_class)->destroy (obj);
+ GTK_OBJECT_CLASS (hildon_window_parent_class)->destroy (obj);
}
-
static void
hildon_window_notify (GObject *gobject,
GParamSpec *param)
{
HildonWindow *window = HILDON_WINDOW (gobject);
- if (strcmp (param->name, "title") == 0)
+ if (g_str_equal (param->name, "title"))
{
hildon_window_update_title (window);
}
- else if (strcmp (param->name, "is-topmost"))
+ else if (g_str_equal (param->name, "is-topmost"))
{
hildon_window_is_topmost_notify (window);
}
- if (G_OBJECT_CLASS(parent_class)->notify)
- G_OBJECT_CLASS(parent_class)->notify (gobject, param);
+ if (G_OBJECT_CLASS(hildon_window_parent_class)->notify)
+ G_OBJECT_CLASS(hildon_window_parent_class)->notify (gobject, param);
}
hildon_window_get_active_window (void)
{
Atom realtype;
+ gint xerror;
int format;
int status;
Window ret;
win.win = NULL;
+ gdk_error_trap_push ();
status = XGetWindowProperty (GDK_DISPLAY(), GDK_ROOT_WINDOW(),
active_app_atom, 0L, 16L,
0, XA_WINDOW, &realtype, &format,
&n, &extra, &win.char_pointer);
- if (!(status == Success && realtype == XA_WINDOW && format == 32
+ xerror = gdk_error_trap_pop ();
+ if (xerror || !(status == Success && realtype == XA_WINDOW && format == 32
&& n == 1 && win.win != NULL))
{
if (win.win != NULL)
if (xclient_message_type_check (cm, "_MB_GRAB_TRANSFER"))
{
- hildon_window_toggle_menu (HILDON_WINDOW ( data ));
+ hildon_window_toggle_menu (HILDON_WINDOW ( data ), cm->data.l[2], cm->data.l[0]);
return GDK_FILTER_REMOVE;
}
/* opera hack clipboard client message */
switch (event->keyval)
{
case HILDON_HARDKEY_MENU:
- if (hildon_window_toggle_menu (HILDON_WINDOW (widget)))
+ if (hildon_window_toggle_menu (HILDON_WINDOW (widget), 0, GDK_CURRENT_TIME))
return TRUE;
break;
case HILDON_HARDKEY_ESC:
break;
}
- return GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event);
+ return GTK_WIDGET_CLASS (hildon_window_parent_class)->key_press_event (widget, event);
}
static gboolean
break;
}
- return GTK_WIDGET_CLASS (parent_class)->key_release_event (widget, event);
+ return GTK_WIDGET_CLASS (hildon_window_parent_class)->key_release_event (widget, event);
}
if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN)
priv->fullscreen = event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN;
- if (GTK_WIDGET_CLASS (parent_class)->window_state_event)
+ if (GTK_WIDGET_CLASS (hildon_window_parent_class)->window_state_event)
{
- return GTK_WIDGET_CLASS (parent_class)->window_state_event (
+ return GTK_WIDGET_CLASS (hildon_window_parent_class)->window_state_event (
widget,
event);
}
}
/*
- static void
- hildon_window_title_notify (GObject *gobject,
- GParamSpec *arg1,
- gpointer user_data)
- {
- HildonWindow *window = HILDON_WINDOW (gobject);
+ * If the window lost focus while the user started to press the ESC key, we
+ * won't get the release event. We need to stop the timeout.
+ */
+static gboolean
+hildon_window_focus_out_event (GtkWidget *widget,
+ GdkEventFocus *event)
+{
+ HildonWindowPrivate *priv = HILDON_WINDOW_GET_PRIVATE (widget);
- hildon_window_update_title (window);
+ if (priv->escape_timeout)
+ {
+ g_source_remove (priv->escape_timeout);
+ priv->escape_timeout = 0;
+ }
- }*/
+ return GTK_WIDGET_CLASS (hildon_window_parent_class)->focus_out_event (widget, event);
+}
/*
* The menu popuping needs a menu popup-function
{
hildon_window_take_common_toolbar (window);
}
-
- else
- {
- /* If the window lost focus while the user started to press
- * the ESC key, we won't get the release event. We need to
- * stop the timeout*/
- if (priv->escape_timeout)
- {
- g_source_remove (priv->escape_timeout);
- priv->escape_timeout = 0;
- }
- }
}
/*
{
const gchar *old_title = gtk_window_get_title (GTK_WINDOW (window));
- if (old_title && old_title[0])
+ if (old_title)
{
gchar *title = NULL;
-
- title = g_strjoin (TITLE_SEPARATOR, application_name,
- old_title, NULL);
+
+ if (strlen (old_title) == 0)
+ title = g_strdup (application_name);
+ else
+ title = g_strjoin (TITLE_SEPARATOR, application_name,
+ old_title, NULL);
gdk_window_set_title (GTK_WIDGET (window)->window, title);
* to toggle)
*/
static gboolean
-hildon_window_toggle_menu (HildonWindow * self)
+hildon_window_toggle_menu (HildonWindow * self,
+ guint button,
+ guint32 time)
{
GtkMenu *menu_to_use = NULL;
GList *menu_children = NULL;
gtk_menu_popup (menu_to_use, NULL, NULL,
(GtkMenuPositionFunc)
hildon_window_menu_popup_func_full,
- self, 0,
- gtk_get_current_event_time ());
+ self, button, time);
}
else
{
gtk_menu_popup (menu_to_use, NULL, NULL,
(GtkMenuPositionFunc)
hildon_window_menu_popup_func,
- self, 0,
- gtk_get_current_event_time ());
+ self, button, time);
}
gtk_menu_shell_select_first (GTK_MENU_SHELL (menu_to_use), TRUE);
return TRUE;
return FALSE;
}
-
/**
* hildon_window_new:
*
gtk_container_add (GTK_CONTAINER (self), GTK_WIDGET (scrolledw));
}
+static void
+calculate_visible_toolbars (gpointer data,
+ gpointer user_data)
+{
+ if (GTK_WIDGET_VISIBLE (GTK_WIDGET (((GtkBoxChild *)data)->widget)))
+ (*((gint *)user_data)) ++;
+}
+
+static void
+toolbar_visible_notify (GtkWidget *toolbar, GParamSpec *pspec,
+ HildonWindow *window)
+{
+ HildonWindowPrivate *priv = HILDON_WINDOW_GET_PRIVATE (window);
+
+ g_assert (priv);
+
+ /* Recalculate from scratch the value just in case */
+ priv->visible_toolbars = 0;
+
+ g_list_foreach (GTK_BOX (priv->vbox)->children, calculate_visible_toolbars,
+ &priv->visible_toolbars);
+
+ if (priv->visible_toolbars == 0)
+ gtk_widget_hide (priv->vbox);
+ else
+ gtk_widget_show (priv->vbox);
+}
+
/**
* hildon_window_add_toolbar:
* @self: A @HildonWindow
* @toolbar: A #GtkToolbar to add to the HildonWindow
*
- * Adds a toolbar to the window.
+ * Adds a toolbar to the window. Note that the toolbar is not automatically
+ * shown. You need to call #gtk_widget_show_all on it to make it visible.
+ * It's also possible to hide the toolbar (without removing it) by calling
+ * #gtk_widget_hide.
**/
void
hildon_window_add_toolbar (HildonWindow *self,
GtkToolbar *toolbar)
{
GtkBox *vbox;
- HildonWindowPrivate *priv = HILDON_WINDOW_GET_PRIVATE (self);
+ HildonWindowPrivate *priv;
g_return_if_fail (HILDON_IS_WINDOW (self));
g_return_if_fail (toolbar && GTK_IS_TOOLBAR (toolbar));
- g_assert (priv);
+
+ priv = HILDON_WINDOW_GET_PRIVATE (self);
vbox = GTK_BOX (priv->vbox);
- gtk_box_pack_start (vbox, GTK_WIDGET(toolbar), TRUE, TRUE, 0);
- gtk_box_reorder_child (vbox, GTK_WIDGET(toolbar), 0);
+ gtk_box_pack_start (vbox, GTK_WIDGET (toolbar), TRUE, TRUE, 0);
+ gtk_box_reorder_child (vbox, GTK_WIDGET (toolbar), 0);
gtk_widget_set_size_request (GTK_WIDGET (toolbar), -1, TOOLBAR_HEIGHT);
- gtk_widget_queue_resize (GTK_WIDGET(self));
+ g_signal_connect (G_OBJECT (toolbar), "notify::visible",
+ G_CALLBACK (toolbar_visible_notify), self);
+
+ if (GTK_WIDGET_VISIBLE (toolbar))
+ {
+ priv->visible_toolbars++;
+ gtk_widget_show (priv->vbox);
+ }
+
+ gtk_widget_queue_resize (GTK_WIDGET (self));
}
/**
* @self: A @HildonWindow
* @toolbar: A #GtkToolbar to remove from the HildonWindow
*
- * Removes a toolbar from the window.
+ * Removes a toolbar from the window. Note that this decreases the refference
+ * count on the widget. If you want to keep the toolbar alive call #g_object_ref
+ * before calling this function.
**/
void
hildon_window_remove_toolbar (HildonWindow *self,
GtkToolbar *toolbar)
{
- HildonWindowPrivate *priv = HILDON_WINDOW_GET_PRIVATE (self);
-
+ HildonWindowPrivate *priv;
+
g_return_if_fail (HILDON_IS_WINDOW (self));
- g_assert (priv);
- gtk_container_remove (GTK_CONTAINER (priv->vbox), GTK_WIDGET(toolbar));
+ priv = HILDON_WINDOW_GET_PRIVATE (self);
+
+ if (GTK_WIDGET_VISIBLE (toolbar))
+ {
+ if (--(priv->visible_toolbars) == 0)
+ gtk_widget_hide (priv->vbox);
+ }
+
+ g_signal_handlers_disconnect_by_func (toolbar, toolbar_visible_notify, self);
+
+ gtk_container_remove (GTK_CONTAINER (priv->vbox), GTK_WIDGET (toolbar));
}
/**
* hildon_window_get_menu:
* @self : #HildonWindow
*
- * Gets the #GtMenu assigned to the #HildonAppview.
+ * Gets the #GtMenu assigned to the #HildonAppview. Note that the
+ * window is still the owner of the menu.
*
- * Return value: The #GtkMenu assigned to this application view.
+ * Return value: The #GtkMenu assigned to this application view.
**/
GtkMenu*
hildon_window_get_menu (HildonWindow * self)
{
- HildonWindowPrivate *priv = HILDON_WINDOW_GET_PRIVATE (self);
-
+ HildonWindowPrivate *priv;
+
g_return_val_if_fail (HILDON_IS_WINDOW (self), NULL);
- g_assert (priv);
+
+ priv = HILDON_WINDOW_GET_PRIVATE (self);
return GTK_MENU (priv->menu);
}
+/* Since we've been asking developers to call gtk_window_add_accel_group()
+ * themselves, do not trigger criticals by trying it again.
+ */
+static void
+hildon_window_add_accel_group (HildonWindow *self,
+ GtkAccelGroup *accel_group)
+{
+ GSList *groups, *l;
+
+ groups = gtk_accel_groups_from_object (G_OBJECT (self));
+ for (l = groups; l != NULL; l = l->next)
+ if (l->data == (gpointer)accel_group)
+ /* Maybe print a warning here? */
+ return;
+
+ gtk_window_add_accel_group (GTK_WINDOW (self), accel_group);
+}
+
/**
- * hildon_window_set_menu:
+ * hildon_window_set_main_menu:
* @self: A #HildonWindow
* @menu: The #GtkMenu to be used for this #HildonWindow
*
* Sets the menu to be used for this window. This menu overrides
* a program-wide menu that may have been set with
- * hildon_program_set_common_menu. Pass NULL to remove the current
- * menu.
+ * hildon_program_set_common_menu(). Pass %NULL to remove the current
+ * menu. #HildonWindow takes ownership of the passed menu and you're
+ * not supposed to free it yourself anymore.
+ *
+ * Since: Hildon 2.2
**/
void
-hildon_window_set_menu (HildonWindow *self,
- GtkMenu *menu)
+hildon_window_set_main_menu (HildonWindow* self,
+ GtkMenu * menu)
{
- HildonWindowPrivate *priv = HILDON_WINDOW_GET_PRIVATE (self);
+ HildonWindowPrivate *priv;
+ GtkAccelGroup *accel_group;
g_return_if_fail (HILDON_IS_WINDOW (self));
- g_assert (priv);
- if (priv->menu != NULL) {
+ priv = HILDON_WINDOW_GET_PRIVATE (self);
+
+ if (priv->menu != NULL)
+ {
+ accel_group = gtk_menu_get_accel_group (GTK_MENU (priv->menu));
+ if (accel_group != NULL)
+ gtk_window_remove_accel_group (GTK_WINDOW (self), accel_group);
+
gtk_menu_detach (GTK_MENU (priv->menu));
g_object_unref (priv->menu);
}
priv->menu = (menu != NULL) ? GTK_WIDGET (menu) : NULL;
- if (priv->menu != NULL) {
+ if (priv->menu != NULL)
+ {
gtk_widget_set_name (priv->menu, "menu_force_with_corners");
gtk_menu_attach_to_widget (GTK_MENU (priv->menu), GTK_WIDGET (self), &detach_menu_func);
g_object_ref (GTK_MENU (priv->menu));
- gtk_widget_show_all (GTK_WIDGET (priv->menu));
+
+ accel_group = gtk_menu_get_accel_group (GTK_MENU (priv->menu));
+ if (accel_group != NULL)
+ hildon_window_add_accel_group (self, accel_group);
}
}
/**
+ * hildon_window_set_menu:
+ * @self: A #HildonWindow
+ * @menu: The #GtkMenu to be used for this #HildonWindow
+ *
+ * Sets the menu to be used for this window. This menu overrides
+ * a program-wide menu that may have been set with
+ * hildon_program_set_common_menu. Pass NULL to remove the current
+ * menu. HildonWindow takes ownership of the passed menu and you're
+ * not supposed to free it yourself anymore.
+ *
+ * Note: hildon_window_set_menu() calls gtk_widget_show_all() for the
+ * #GtkMenu. To pass control about visibility to the application
+ * developer, hildon_window_set_main_menu() was introduced, which
+ * doesn't do this.
+ *
+ * Deprecated: Hildon 2.2: use hildon_window_set_main_menu()
+ **/
+void
+hildon_window_set_menu (HildonWindow *self,
+ GtkMenu *menu)
+{
+ HildonWindowPrivate *priv;
+
+ g_return_if_fail (HILDON_IS_WINDOW (self));
+
+ hildon_window_set_main_menu (self, menu);
+
+ priv = HILDON_WINDOW_GET_PRIVATE (self);
+
+ if (priv->menu != NULL)
+ gtk_widget_show_all (GTK_WIDGET (priv->menu));
+}
+
+/**
* hildon_window_get_is_topmost:
* @self: A #HildonWindow
*
gboolean
hildon_window_get_is_topmost (HildonWindow *self)
{
- HildonWindowPrivate *priv = HILDON_WINDOW_GET_PRIVATE (self);
+ HildonWindowPrivate *priv;
g_return_val_if_fail (HILDON_IS_WINDOW (self), FALSE);
- g_assert (priv);
+ priv = HILDON_WINDOW_GET_PRIVATE (self);
return priv->is_topmost;
}