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