From: Rob Bradford <r...@linux.intel.com>

---
 clients/window.c |   65 +++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 57 insertions(+), 8 deletions(-)

diff --git a/clients/window.c b/clients/window.c
index 04692c0..5fda221 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -141,6 +141,11 @@ struct window {
 
        void *user_data;
        struct wl_list link;
+
+       /* Used for probing */
+       int requested_w, requested_h;
+       struct window *popup_window;
+       uint32_t popup_time;
 };
 
 struct widget {
@@ -2146,9 +2151,49 @@ handle_popup_done(void *data, struct wl_shell_surface 
*shell_surface)
        menu_destroy(menu);
 }
 
+static void
+handle_visible_area(void *data, struct wl_shell_surface *shell_surface,
+                   int x, int y, int w, int h)
+{
+       /* The event gets called on the toplevel window not the child surface
+        * so we must store that on the toplevel and retrieve it. Yuk?
+        */
+       struct window *toplevel_window = data;
+       struct window *window = toplevel_window->popup_window;
+
+       struct menu *menu = window->widget->user_data;
+
+       fprintf (stderr, "Got area %d %d %d %d on %p for %p\n",
+                x, y, w, h, toplevel_window, window);
+
+       /* Clipped to the left */
+       if (x != window->x)
+               window->x = x;
+
+       /* Clipped to the top */
+       if (y != window->y)
+               window->y = y;
+
+       /* Clipped to the right */
+       if (x == window->x && w < window->requested_w)
+               window->x = window->x - (window->requested_w - w);
+
+       /* Clipped to the bottom */
+       if (y == window->y && h < window->requested_h)
+               window->y = y - (window->requested_h - h);
+
+       wl_shell_surface_set_popup(window->shell_surface,
+                                  menu->input->input_device, 
window->popup_time,
+                                  window->parent->shell_surface,
+                                  window->x, window->y, 0);
+       input_grab(menu->input, menu->widget, 0);
+       window_schedule_resize(window, window->requested_w, 
window->requested_h);
+}
+
 static const struct wl_shell_surface_listener shell_surface_listener = {
        handle_configure,
-       handle_popup_done
+       handle_popup_done,
+       handle_visible_area,
 };
 
 void
@@ -2543,19 +2588,23 @@ window_show_menu(struct display *display,
        window->x = x;
        window->y = y;
 
-       wl_shell_surface_set_popup(window->shell_surface,
-                                  input->input_device, time,
-                                  window->parent->shell_surface,
-                                  window->x, window->y, 0);
+
+       window->requested_w = 200;
+       window->requested_h = count * 20 + margin * 2;
+       window->parent->popup_window = window;
+       wl_shell_surface_probe_area (window->parent->shell_surface,
+                                    window->x, window->y,
+                                    window->requested_w, window->requested_h);
+       fprintf (stderr, "Probing %d %d %d %d for %p on %p\n",
+                window->x, window->y,
+                window->requested_w, window->requested_h,
+                window, window->parent);
 
        widget_set_redraw_handler(menu->widget, menu_redraw_handler);
        widget_set_enter_handler(menu->widget, menu_enter_handler);
        widget_set_leave_handler(menu->widget, menu_leave_handler);
        widget_set_motion_handler(menu->widget, menu_motion_handler);
        widget_set_button_handler(menu->widget, menu_button_handler);
-
-       input_grab(input, menu->widget, 0);
-       window_schedule_resize(window, 200, count * 20 + margin * 2);
 }
 
 void
-- 
1.7.7.6

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to