[PATCH 2/2] window: Use probe area to position popup window so it always visible
Rob Bradford
robert.bradford at intel.com
Mon Jan 28 09:19:27 PST 2013
From: Rob Bradford <rob at linux.intel.com>
With this change the popup menu will not go beyond the borders of the output.
---
clients/window.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 50 insertions(+), 8 deletions(-)
diff --git a/clients/window.c b/clients/window.c
index 2baf4d9..28d0bd6 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -359,6 +359,8 @@ struct menu {
int count;
int release_count;
menu_func_t func;
+ int width;
+ int height;
};
struct tooltip {
@@ -3747,6 +3749,46 @@ menu_redraw_handler(struct widget *widget, void *data)
cairo_destroy(cr);
}
+static void
+probe_result_visible_area (void *data,
+ struct wl_probe_result *wl_probe_result,
+ int32_t x, int32_t y,
+ int32_t w, int32_t h)
+{
+ struct menu *menu = data;
+ struct window *window = menu->window;
+ struct input *input = menu->input;
+
+ /* 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 < menu->width)
+ window->x = window->x - (menu->width - w);
+
+ /* Clipped to the bottom */
+ if (y == window->y && h < menu->height)
+ window->y = y - (menu->height - h);
+
+ input_ungrab(input);
+ wl_shell_surface_set_popup(window->shell_surface, input->seat,
+ display_get_serial(window->display),
+ window->parent->surface,
+ window->x, window->y, 0);
+
+ input_grab(input, menu->widget, 0);
+ window_schedule_resize(window, menu->width, menu->height);
+}
+
+struct wl_probe_result_listener probe_result_listener = {
+ probe_result_visible_area,
+};
+
void
window_show_menu(struct display *display,
struct input *input, uint32_t time, struct window *parent,
@@ -3756,6 +3798,7 @@ window_show_menu(struct display *display,
struct window *window;
struct menu *menu;
const int32_t margin = 3;
+ struct wl_probe_result *result;
menu = malloc(sizeof *menu);
if (!menu)
@@ -3776,24 +3819,23 @@ window_show_menu(struct display *display,
menu->time = time;
menu->func = func;
menu->input = input;
+ menu->width = 200;
+ menu->height = menu->count * 20 + margin * 2;
window->type = TYPE_MENU;
window->x = x;
window->y = y;
- input_ungrab(input);
- wl_shell_surface_set_popup(window->shell_surface, input->seat,
- display_get_serial(window->display),
- window->parent->surface,
- window->x, window->y, 0);
-
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);
+ result = wl_shell_surface_probe_area(window->parent->shell_surface,
+ window->x, window->y,
+ menu->width, menu->height);
+
+ wl_probe_result_add_listener(result, &probe_result_listener, menu);
}
void
--
1.8.0.2
More information about the wayland-devel
mailing list