* src/hildon-app-menu-private.h * src/hildon-app-menu.c (hildon_app_menu_init, hildon...
authorAlberto Garcia <agarcia@igalia.com>
Wed, 11 Jun 2008 17:49:15 +0000 (17:49 +0000)
committerAlberto Garcia <agarcia@igalia.com>
Wed, 11 Jun 2008 17:49:15 +0000 (17:49 +0000)
ChangeLog
src/hildon-app-menu-private.h
src/hildon-app-menu.c

index 276549a..0ba7d64 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2008-06-11  Alberto Garcia  <agarcia@igalia.com>
 
+       * src/hildon-app-menu-private.h
+       * src/hildon-app-menu.c
+       (hildon_app_menu_init, hildon_app_menu_finalize)
+       (hildon_app_menu_map, hildon_app_menu_unmap)
+       (hildon_app_menu_button_release)
+       (grab_transfer_window_get):
+       Bring back the grab window
+       (hildon_app_menu_realize):
+       Decorate the window, set WM hint for Matchbox
+
        * src/hildon-note.c (hildon_note_realize):
        * src/hildon-banner.c (hildon_banner_realize):
        Add WM hints for Matchbox
index 96f5175..069766b 100644 (file)
@@ -33,6 +33,7 @@ struct                                          _HildonAppMenuPrivate
     GtkBox *vbox;
     GtkTable *table;
     GtkSizeGroup *sizegroup;
+    GdkWindow *transfer_window;
     int nitems;
 };
 
index f408e67..dc02fe0 100644 (file)
  *
  */
 
-#include "hildon-app-menu.h"
-#include "hildon-app-menu-private.h"
+#include                                        "hildon-app-menu.h"
+#include                                        "hildon-app-menu-private.h"
+
+#include                                        <gdk/gdkx.h>
+#include                                        <X11/X.h>
+#include                                        <X11/Xatom.h>
+#include                                        <string.h>
+
+static GdkWindow *
+grab_transfer_window_get                        (GtkWidget *widget);
 
 G_DEFINE_TYPE (HildonAppMenu, hildon_app_menu, GTK_TYPE_WINDOW);
 
@@ -221,13 +229,16 @@ hildon_app_menu_map                             (GtkWidget *widget)
     GTK_WIDGET_CLASS (hildon_app_menu_parent_class)->map (widget);
 
     /* Grab pointer and keyboard */
-    gdk_pointer_grab (
-        widget->window, TRUE,
-        GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
-        GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK |
-        GDK_POINTER_MOTION_MASK, NULL, NULL, GDK_CURRENT_TIME);
-    gdk_keyboard_grab (widget->window, TRUE, GDK_CURRENT_TIME);
-    gtk_grab_add (widget);
+    if (priv->transfer_window == NULL) {
+        priv->transfer_window = grab_transfer_window_get (widget);
+        gdk_pointer_grab (
+            priv->transfer_window, TRUE,
+            GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
+            GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK |
+            GDK_POINTER_MOTION_MASK, NULL, NULL, GDK_CURRENT_TIME);
+        gdk_keyboard_grab (priv->transfer_window, TRUE, GDK_CURRENT_TIME);
+        gtk_grab_add (widget);
+    }
 }
 
 static void
@@ -236,9 +247,14 @@ hildon_app_menu_unmap                           (GtkWidget *widget)
     HildonAppMenuPrivate *priv = HILDON_APP_MENU_GET_PRIVATE(widget);
 
     /* Remove the grab */
-    gdk_display_pointer_ungrab (gtk_widget_get_display (widget),
-                                GDK_CURRENT_TIME);
-    gtk_grab_remove (widget);
+    if (priv->transfer_window != NULL) {
+        gdk_display_pointer_ungrab (gtk_widget_get_display (widget),
+                                    GDK_CURRENT_TIME);
+        gtk_grab_remove (widget);
+
+        gdk_window_destroy (priv->transfer_window);
+        priv->transfer_window = NULL;
+    }
 
     GTK_WIDGET_CLASS (hildon_app_menu_parent_class)->unmap (widget);
 }
@@ -254,7 +270,7 @@ hildon_app_menu_button_release                  (GtkWidget *widget,
     gdk_window_get_position (widget->window, &x, &y);
 
     /* Whether the button has been released outside the widget */
-    released_outside = (event->window != widget->window ||
+    released_outside = (event->window != priv->transfer_window ||
                         event->x_root < x || event->x_root > x + widget->allocation.width ||
                         event->y_root < y || event->y_root > y + widget->allocation.height);
 
@@ -269,11 +285,50 @@ hildon_app_menu_button_release                  (GtkWidget *widget,
     }
 }
 
+/* Grab transfer window (based on the one from GtkMenu) */
+static GdkWindow *
+grab_transfer_window_get                        (GtkWidget *widget)
+{
+    GdkWindow *window;
+    GdkWindowAttr attributes;
+    gint attributes_mask;
+
+    attributes.x = 0;
+    attributes.y = 0;
+    attributes.width = 10;
+    attributes.height = 10;
+    attributes.window_type = GDK_WINDOW_TEMP;
+    attributes.wclass = GDK_INPUT_ONLY;
+    attributes.override_redirect = TRUE;
+    attributes.event_mask = 0;
+
+    attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_NOREDIR;
+
+    window = gdk_window_new (gtk_widget_get_root_window (widget),
+                                 &attributes, attributes_mask);
+    gdk_window_set_user_data (window, widget);
+
+    gdk_window_show (window);
+
+    return window;
+}
+
 static void
 hildon_app_menu_realize                         (GtkWidget *widget)
 {
+    GdkDisplay *display;
+    Atom atom;
+    const gchar *notification_type = "_HILDON_WM_WINDOW_TYPE_APP_MENU";
+
     GTK_WIDGET_CLASS (hildon_app_menu_parent_class)->realize (widget);
-    gdk_window_set_override_redirect(widget->window, TRUE);
+
+    gdk_window_set_decorations (widget->window, GDK_DECOR_BORDER);
+
+    display = gdk_drawable_get_display (widget->window);
+    atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE");
+    XChangeProperty (GDK_WINDOW_XDISPLAY (widget->window), GDK_WINDOW_XID (widget->window),
+                     atom, XA_STRING, 8, PropModeReplace, (guchar *) notification_type,
+                     strlen (notification_type));
 }
 
 static void
@@ -299,6 +354,7 @@ hildon_app_menu_init                            (HildonAppMenu *menu)
     priv->table = GTK_TABLE (gtk_table_new (1, 2, TRUE));
     priv->sizegroup = GTK_SIZE_GROUP (gtk_size_group_new (GTK_SIZE_GROUP_BOTH));
     priv->nitems = 0;
+    priv->transfer_window = NULL;
 
     /* Set spacing between table elements */
     gtk_table_set_row_spacings (priv->table, vertical_spacing);
@@ -319,8 +375,6 @@ hildon_app_menu_init                            (HildonAppMenu *menu)
     gtk_window_set_default_size (GTK_WINDOW (menu), width, -1);
 
     gtk_widget_show_all (GTK_WIDGET (priv->vbox));
-
-    gtk_window_set_type_hint (GTK_WINDOW (menu), GDK_WINDOW_TYPE_HINT_POPUP_MENU);
 }
 
 static void
@@ -329,6 +383,8 @@ hildon_app_menu_finalize                        (GObject *object)
     HildonAppMenuPrivate *priv = HILDON_APP_MENU_GET_PRIVATE(object);
 
     g_object_unref (priv->sizegroup);
+    if (priv->transfer_window)
+        gdk_window_destroy (priv->transfer_window);
 
     g_signal_handlers_destroy (object);
     G_OBJECT_CLASS (hildon_app_menu_parent_class)->finalize (object);