]> Pileus Git - ~andy/gtk/commitdiff
wayland: Categorise menus, popups and combo boxes as Wayland popup windows
authorRob Bradford <rob@linux.intel.com>
Mon, 27 Feb 2012 14:30:58 +0000 (14:30 +0000)
committerRob Bradford <rob@linux.intel.com>
Mon, 27 Feb 2012 17:15:12 +0000 (17:15 +0000)
Once we've made them popup windows we must also implement the popup_done event
handler on the shell surface listener. The best we can currently do is to hide
the window. This will then signal up to GTK which could then deactivate the
appropriate menu (see https://bugzilla.gnome.org/show_bug.cgi?id=670881)

gdk/wayland/gdkwindow-wayland.c

index cdadd47bcfe01c37a09c5df2fd31eb85de6bf587..24a2e93ddc10e435713ee35a4c499356a082274a 100644 (file)
@@ -478,19 +478,30 @@ gdk_wayland_window_map (GdkWindow *window)
   if (!impl->mapped)
     {
       if (impl->transient_for)
-       {
-         fprintf(stderr, "parent surface: %d, %d, transient surface %d, %d\n",
-                 impl->transient_for->x,
-                 impl->transient_for->y,
-                 window->x,
-                 window->y);
-
-         parent = GDK_WINDOW_IMPL_WAYLAND (impl->transient_for->impl);
-          wl_shell_surface_set_transient (impl->shell_surface, parent->shell_surface,
+        {
+          parent = GDK_WINDOW_IMPL_WAYLAND (impl->transient_for->impl);
+
+          if (impl->hint & GDK_WINDOW_TYPE_HINT_POPUP_MENU ||
+              impl->hint & GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU ||
+              impl->hint & GDK_WINDOW_TYPE_HINT_COMBO)
+            {
+              /* Use the device that was used for the grab as the device for
+               * the popup window setup - so this relies on GTK+ taking the
+               * grab before showing the popup window.
+               */
+              wl_shell_surface_set_popup (impl->shell_surface,
+                                          parent->grab_input_device, parent->grab_time,
+                                          parent->shell_surface,
                                           window->x, window->y, 0);
-       }
+            } else {
+                wl_shell_surface_set_transient (impl->shell_surface, parent->shell_surface,
+                                                window->x, window->y, 0);
+            }
+        }
       else
-        wl_shell_surface_set_toplevel (impl->shell_surface);
+        {
+          wl_shell_surface_set_toplevel (impl->shell_surface);
+        }
       impl->mapped = TRUE;
     }
 }
@@ -516,8 +527,22 @@ shell_surface_handle_configure(void *data,
   gdk_wayland_window_configure (window, width, height, edges);
 }
 
+static void
+shell_surface_popup_done (void                    *data,
+                          struct wl_shell_surface *shell_surface)
+{
+  GdkWindow *window = GDK_WINDOW (data);
+
+  /* When the popup is complete hide the window - this really relies on the
+   * fix in https://bugzilla.gnome.org/show_bug.cgi?id=670881 to work
+   * effectively.
+   */
+  gdk_window_hide (window);
+}
+
 static const struct wl_shell_surface_listener shell_surface_listener = {
   shell_surface_handle_configure,
+  shell_surface_popup_done
 };
 
 static void