From 4f7dcd6eb18ea708f172a9e0239992f49c6860d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Fri, 6 Jan 2012 21:59:05 -0500 Subject: [PATCH] window: Add a window menu At least this gives us a way to close the toy toolkit clients. --- clients/desktop-shell.c | 2 +- clients/resizor.c | 9 ++++- clients/window.c | 88 +++++++++++++++++++++++++++++++++++------ clients/window.h | 12 +++++- 4 files changed, 95 insertions(+), 16 deletions(-) diff --git a/clients/desktop-shell.c b/clients/desktop-shell.c index 25fcee60..9ea09673 100644 --- a/clients/desktop-shell.c +++ b/clients/desktop-shell.c @@ -138,7 +138,7 @@ show_menu(struct panel *panel, struct input *input, uint32_t time) input_get_position(input, &x, &y); panel->menu = window_create_menu(window_get_display(panel->window), input, time, panel->window, - x - 10, y - 10, entries, 4); + x - 10, y - 10, NULL, entries, 4); window_schedule_redraw(panel->menu); } diff --git a/clients/resizor.c b/clients/resizor.c index 867ceb90..10378241 100644 --- a/clients/resizor.c +++ b/clients/resizor.c @@ -166,6 +166,12 @@ key_handler(struct window *window, struct input *input, uint32_t time, } } +static void +menu_func(struct window *window, int index, void *user_data) +{ + fprintf(stderr, "picked entry %d\n", index); +} + static void show_menu(struct resizor *resizor, struct input *input, uint32_t time) { @@ -177,7 +183,8 @@ show_menu(struct resizor *resizor, struct input *input, uint32_t time) input_get_position(input, &x, &y); resizor->menu = window_create_menu(resizor->display, input, time, resizor->window, - x - 10, y - 10, entries, 4); + x - 10, y - 10, + menu_func, entries, 4); window_schedule_redraw(resizor->menu); } diff --git a/clients/window.c b/clients/window.c index 3be93b9c..a1012045 100644 --- a/clients/window.c +++ b/clients/window.c @@ -137,11 +137,14 @@ struct window { window_item_focus_handler_t item_focus_handler; window_data_handler_t data_handler; window_drop_handler_t drop_handler; + window_close_handler_t close_handler; struct wl_list item_list; struct item *focus_item; uint32_t item_grab_button; + struct window *menu; + void *user_data; struct wl_list link; }; @@ -177,6 +180,15 @@ struct output { void *user_data; }; +struct menu { + struct window *window; + const char **entries; + uint32_t time; + int current; + int count; + menu_func_t func; +}; + enum { POINTER_DEFAULT = 100, POINTER_UNSET @@ -1253,6 +1265,28 @@ input_handle_motion(void *data, struct wl_input_device *input_device, input_set_pointer_image(input, time, pointer); } +static void +window_menu_func(struct window *window, int index, void *data) +{ + switch (index) { + case 0: /* close */ + if (window->close_handler) + window->close_handler(window->parent, + window->user_data); + else + exit(0); + break; + case 1: /* fullscreen */ + /* we don't have a way to get out of fullscreen for now */ + window_set_fullscreen(window, 1); + break; + case 2: /* rotate */ + case 3: /* scale */ + break; + } +} + + static void input_handle_button(void *data, struct wl_input_device *input_device, @@ -1262,14 +1296,17 @@ input_handle_button(void *data, struct window *window = input->pointer_focus; struct item *item; int location; + int32_t x, y; + static const char *entries[] = { + "Close", "Fullscreen", "Rotate", "Scale" + }; if (window->focus_item && window->item_grab_button == 0 && state) window->item_grab_button = button; location = get_pointer_location(window, input->sx, input->sy); - if (window->display->shell && - button == BTN_LEFT && state == 1) { + if (window->display->shell && button == BTN_LEFT && state == 1) { switch (location) { case WINDOW_TITLEBAR: if (!window->shell_surface) @@ -1300,6 +1337,26 @@ input_handle_button(void *data, window->user_data); break; } + } else if (button == BTN_RIGHT && state == 1) { + switch (location) { + default: + input_get_position(input, &x, &y); + window->menu = window_create_menu(window->display, + input, time, + window, + x - 10, y - 10, + window_menu_func, + entries, 4); + window_schedule_redraw(window->menu); + break; + case WINDOW_CLIENT_AREA: + if (window->button_handler) + (*window->button_handler)(window, + input, time, + button, state, + window->user_data); + break; + } } else { if (window->button_handler) (*window->button_handler)(window, @@ -1803,10 +1860,11 @@ static void handle_popup_done(void *data, struct wl_shell_surface *shell_surface) { struct window *window = data; - + struct menu *menu = window_get_user_data(window); /* FIXME: Need more context in this event, at least the input * device. Or just use wl_callback. */ + menu->func(window->parent, menu->current, window->parent->user_data); window_destroy(window); } @@ -1999,6 +2057,13 @@ window_set_drop_handler(struct window *window, window_drop_handler_t handler) window->drop_handler = handler; } +void +window_set_close_handler(struct window *window, + window_close_handler_t handler) +{ + window->close_handler = handler; +} + void window_set_transparent(struct window *window, int transparent) { @@ -2117,14 +2182,6 @@ window_create_transient(struct display *display, struct window *parent, return window; } -struct menu { - struct window *window; - const char **entries; - uint32_t time; - int current; - int count; -}; - static int menu_set_item(struct window *window, struct menu *menu, int sy) { @@ -2172,8 +2229,11 @@ menu_button_handler(struct window *window, struct menu *menu = data; /* Either relase after press-drag-release or click-motion-click. */ - if (state == 0 && time - menu->time > 500) + if (state == 0 && time - menu->time > 500) { + menu->func(window->parent, + menu->current, window->parent->user_data); window_destroy(window); + } } static void @@ -2224,7 +2284,8 @@ menu_redraw_handler(struct window *window, void *data) struct window * window_create_menu(struct display *display, struct input *input, uint32_t time, struct window *parent, - int32_t x, int32_t y, const char **entries, int count) + int32_t x, int32_t y, + menu_func_t func, const char **entries, int count) { struct window *window; struct menu *menu; @@ -2241,6 +2302,7 @@ window_create_menu(struct display *display, menu->entries = entries; menu->count = count; menu->time = time; + menu->func = func; window->decoration = 0; window->type = TYPE_MENU; window->x = x; diff --git a/clients/window.h b/clients/window.h index f1bad3fd..30311df8 100644 --- a/clients/window.h +++ b/clients/window.h @@ -197,15 +197,21 @@ typedef void (*window_drop_handler_t)(struct window *window, typedef void (*window_item_focus_handler_t)(struct window *window, struct item *focus, void *data); +typedef void (*window_close_handler_t)(struct window *window, void *data); + struct window * window_create(struct display *display, int32_t width, int32_t height); struct window * window_create_transient(struct display *display, struct window *parent, int32_t x, int32_t y, int32_t width, int32_t height); + +typedef void (*menu_func_t)(struct window *window, int index, void *data); + struct window * window_create_menu(struct display *display, struct input *input, uint32_t time, struct window *parent, - int32_t x, int32_t y, const char **entries, int count); + int32_t x, int32_t y, + menu_func_t func, const char **entries, int count); void window_destroy(struct window *window); @@ -340,6 +346,10 @@ void window_set_drop_handler(struct window *window, window_drop_handler_t handler); +void +window_set_close_handler(struct window *window, + window_close_handler_t handler); + void window_set_title(struct window *window, const char *title);