/**
* SECTION:hildon-window
- * @short_description: Widget representing a top-level window in the Hildon framework.
+ * @short_description: Top-level window in the Hildon framework.
* @see_also: #HildonProgram, #HildonStackableWindow
*
- * #HildonWindow is a GTK widget which represents a top-level
+ * #HildonWindow is a top-level
* window in the Hildon framework. It is derived from #GtkWindow
* and provides additional commodities specific to the Hildon
* framework.
#include "hildon-app-menu-private.h"
#include "hildon-find-toolbar.h"
#include "hildon-defines.h"
+#include "hildon-private.h"
#define _(String) gettext(String)
#define CAN_HIBERNATE_PROPERTY "_HILDON_ABLE_TO_HIBERNATE"
+#define LEGACY_MENU_PROPERTY_NAME "_HILDON_WM_WINDOW_TYPE"
+#define LEGACY_MENU_PROPERTY_VALUE "_HILDON_WM_WINDOW_TYPE_LEGACY_MENU"
+
#define TITLE_SEPARATOR " - "
typedef void (*HildonWindowSignal) (HildonWindow *, gint, gpointer);
case HILDON_HARDKEY_ESC:
if (!priv->escape_timeout)
{
- priv->escape_timeout = g_timeout_add
+ priv->escape_timeout = gdk_threads_add_timeout
(HILDON_WINDOW_LONG_PRESS_TIME,
hildon_window_escape_timeout, widget);
}
return GTK_WIDGET_CLASS (hildon_window_parent_class)->focus_out_event (widget, event);
}
+static void
+set_legacy_menu_type (GtkMenu *menu,
+ gboolean set)
+{
+ GdkWindow *gdkwin = GTK_WIDGET (menu->toplevel)->window;
+ GdkAtom property = gdk_atom_intern_static_string (LEGACY_MENU_PROPERTY_NAME);
+ if (set) {
+ GdkAtom type = gdk_x11_xatom_to_atom (XA_ATOM);
+ GdkAtom value = gdk_atom_intern_static_string (LEGACY_MENU_PROPERTY_VALUE);
+ gdk_property_change (gdkwin, property, type, 32,
+ GDK_PROP_MODE_REPLACE, (const guchar *) &value, 1);
+ } else {
+ gdk_property_delete (gdkwin, property);
+ }
+}
+
+static void
+legacy_menu_realized (GtkMenu *menu)
+{
+ set_legacy_menu_type (menu, TRUE);
+ g_signal_handlers_disconnect_by_func (menu, legacy_menu_realized, NULL);
+}
+
+static void
+legacy_menu_unmapped (GtkMenu *menu)
+{
+ set_legacy_menu_type (menu, FALSE);
+ g_signal_handlers_disconnect_by_func (menu, legacy_menu_unmapped, NULL);
+}
+
/*
* The menu popuping needs a menu popup-function
*/
}
}
+static void
+hildon_window_update_menu_flag (HildonWindow *self,
+ gboolean is_app_menu)
+{
+ HildonWindowPrivate *priv;
+
+ priv = HILDON_WINDOW_GET_PRIVATE (self);
+
+ if (is_app_menu)
+ {
+ /* Change the menu flag only if there is no program or common
+ application menu. */
+ if (!priv->program ||
+ !hildon_program_get_common_app_menu (priv->program))
+ {
+ hildon_window_set_menu_flag (self, priv->app_menu != NULL &&
+ hildon_app_menu_has_visible_children (priv->app_menu));
+ }
+ } else {
+ if (!priv->program || !hildon_program_get_common_menu (priv->program))
+ {
+ GList *menu_children = gtk_container_get_children (GTK_CONTAINER (priv->menu));
+ hildon_window_set_menu_flag (self, priv->menu != NULL && menu_children != NULL);
+ g_free (menu_children);
+ }
+ }
+}
+
+static void
+on_menu_changed (HildonAppMenu *menu,
+ HildonWindow *window)
+{
+ hildon_window_update_menu_flag (window, TRUE);
+}
+
/*
* Sets the program to which the window belongs. This should only be called
* by hildon_program_add_window
HildonWindowPrivate *priv = HILDON_WINDOW_GET_PRIVATE (self);
g_list_free (menu_children);
+ /* Set the 'legacy app menu' property when the widget is realized */
+ if (GTK_WIDGET_REALIZED (menu)) {
+ set_legacy_menu_type (menu, TRUE);
+ } else {
+ g_signal_connect (menu, "realize",
+ G_CALLBACK (legacy_menu_realized), NULL);
+ }
+
+ /* Remove it when it's unmapped */
+ g_signal_connect (menu, "unmap",
+ G_CALLBACK (legacy_menu_unmapped), NULL);
+
/* Apply right theming */
gtk_widget_set_name (GTK_WIDGET (menu), "menu_force_with_corners");
g_assert (priv);
- GDK_THREADS_ENTER ();
-
/* Send fake event, simulation a situation that user
pressed 'x' from the corner */
event = gdk_event_new(GDK_DELETE);
priv->escape_timeout = 0;
- GDK_THREADS_LEAVE ();
-
return FALSE;
}
* hildon_window_get_main_menu:
* @self: a #HildonWindow
*
- * Gets the #GtkMenu assigned to the #HildonAppview. Note that the
+ * Gets the #GtkMenu assigned to the #HildonWindow. Note that the
* window is still the owner of the menu.
*
* Note that if you're using a #HildonAppMenu rather than a #GtkMenu
* hildon_window_get_menu:
* @self: a #HildonWindow
*
+ * Gets the #GtkMenu assigned to @self
+ *
* Return value: a #GtkMenu
*
* Deprecated: In Hildon 2.2 this function has been renamed to
gtk_window_add_accel_group (GTK_WINDOW (self), accel_group);
}
+static void
+do_set_has_menu (GtkWindow *window,
+ gpointer boolptr)
+{
+ gboolean has_menu = GPOINTER_TO_INT (boolptr);
+ hildon_gtk_window_set_clear_window_flag (window, "_HILDON_WM_WINDOW_MENU_INDICATOR",
+ XA_INTEGER, has_menu);
+ g_signal_handlers_disconnect_matched (window, G_SIGNAL_MATCH_FUNC,
+ 0, 0, NULL, do_set_has_menu, NULL);
+}
+
+void
+hildon_window_set_menu_flag (HildonWindow *window,
+ gboolean has_menu)
+{
+ hildon_gtk_window_set_flag (GTK_WINDOW (window), (HildonFlagFunc) do_set_has_menu,
+ GUINT_TO_POINTER (has_menu));
+}
+
/**
* hildon_window_set_main_menu:
* @self: A #HildonWindow
if (accel_group != NULL)
hildon_window_add_accel_group (self, accel_group);
}
+
+ hildon_window_update_menu_flag (self, FALSE);
}
/**
/* Add new menu */
priv->app_menu = menu;
if (menu)
+ {
g_object_ref_sink (menu);
+ g_signal_connect (menu, "changed", G_CALLBACK (on_menu_changed), self);
+ }
/* Unref old menu */
if (old_menu)
+ {
+ g_signal_handlers_disconnect_by_func (old_menu, on_menu_changed, self);
g_object_unref (old_menu);
+ }
+
+ hildon_window_update_menu_flag (self, TRUE);
}
/**