[PATCH weston 6/6] stacking: manage stacking lists, implement present()
Manuel Bachmann
manuel.bachmann at open.eurogiciel.org
Thu Apr 9 09:49:12 PDT 2015
For reference, here is a video of the "weston-stacking" client with
vanilla Weston, latest master branch, and this series of patches applied :
https://www.youtube.com/watch?v=IZj72kWLY2w
(if a parent window creates a new child window, and we use the "n" button
from the parent again, then xdg_surface_present() will be called on the
child window surface. desktop-shell will issue a small GUI notification
-which the user can ignore. If the user clicks, the corresponding surface
will be raised to moved to the current workspace)
2015-04-09 18:25 GMT+02:00 Manuel Bachmann <
manuel.bachmann at open.eurogiciel.org>:
> Due to the absence of a clever close handler, closing one
> window among multiple ones used to quit the application.
> We now keep track of our children windows, and close only
> these ones.
>
> If the user tries to create a new window and we already
> have a child, present() the child instead. The user will
> then be able to raise and find the child by interacting
> with the notification.
>
> Signed-off-by: Manuel Bachmann <manuel.bachmann at open.eurogiciel.org>
> ---
> clients/stacking.c | 81
> ++++++++++++++++++++++++++++++++++++++++++++++--------
> 1 file changed, 70 insertions(+), 11 deletions(-)
>
> diff --git a/clients/stacking.c b/clients/stacking.c
> index ea6101d..c9e38d3 100644
> --- a/clients/stacking.c
> +++ b/clients/stacking.c
> @@ -33,9 +33,15 @@
>
> #include "window.h"
>
> +struct stacked_window {
> + struct window *window;
> + struct stacked_window *child_window;
> + struct stacking *stacking;
> +};
> +
> struct stacking {
> struct display *display;
> - struct window *root_window;
> + struct stacked_window *root_window;
> };
>
> static void
> @@ -55,17 +61,33 @@ static void
> fullscreen_handler(struct window *window, void *data);
> static void
> redraw_handler(struct widget *widget, void *data);
> +static void
> +close_handler(void *data);
>
> /* Iff parent_window is set, the new window will be transient. */
> static struct window *
> new_window(struct stacking *stacking, struct window *parent_window)
> {
> + struct stacked_window *current_window;
> struct window *new_window;
> struct widget *new_widget;
>
> new_window = window_create(stacking->display);
> window_set_parent(new_window, parent_window);
>
> + /* iterate through stackings, and stop once we find
> + * the last window */
> + current_window = stacking->root_window;
> + while (current_window->child_window) {
> + current_window = current_window->child_window;
> + }
> + /* we create the new child */
> + current_window->child_window = xzalloc(sizeof *current_window);
> + current_window = current_window->child_window;
> + current_window->stacking = stacking;
> + current_window->window = new_window;
> + current_window->child_window = NULL;
> +
> new_widget = window_frame_create(new_window, new_window);
>
> window_set_title(new_window, "Stacking Test");
> @@ -74,7 +96,8 @@ new_window(struct stacking *stacking, struct window
> *parent_window)
> window_set_fullscreen_handler(new_window, fullscreen_handler);
> widget_set_button_handler(new_widget, button_handler);
> widget_set_redraw_handler(new_widget, redraw_handler);
> - window_set_user_data(new_window, stacking);
> + window_set_close_handler(new_window, close_handler);
> + window_set_user_data(new_window, current_window);
>
> window_schedule_resize(new_window, 300, 300);
>
> @@ -108,12 +131,12 @@ button_handler(struct widget *widget,
> uint32_t button,
> enum wl_pointer_button_state state, void *data)
> {
> - struct stacking *stacking = data;
> + struct stacked_window *current_window = data;
>
> switch (button) {
> case BTN_RIGHT:
> if (state == WL_POINTER_BUTTON_STATE_PRESSED)
> - show_popup(stacking, input, time,
> + show_popup(current_window->stacking, input, time,
> widget_get_user_data(widget));
> break;
>
> @@ -129,7 +152,7 @@ key_handler(struct window *window,
> uint32_t key, uint32_t sym, enum wl_keyboard_key_state state,
> void *data)
> {
> - struct stacking *stacking = data;
> + struct stacked_window *current_window = data;
>
> if (state != WL_KEYBOARD_KEY_STATE_PRESSED)
> return;
> @@ -144,12 +167,16 @@ key_handler(struct window *window,
> break;
>
> case XKB_KEY_n:
> - /* New top-level window. */
> - new_window(stacking, NULL);
> + /* If this window has no child, create a new top-level one.
> + * Otherwise, present the existing child to the user. */
> + if (!current_window->child_window)
> + new_window(current_window->stacking, NULL);
> + else
> +
> window_present(current_window->child_window->window);
> break;
>
> case XKB_KEY_p:
> - show_popup(stacking, input, time, window);
> + show_popup(current_window->stacking, input, time, window);
> break;
>
> case XKB_KEY_q:
> @@ -158,7 +185,7 @@ key_handler(struct window *window,
>
> case XKB_KEY_t:
> /* New transient window. */
> - new_window(stacking, window);
> + new_window(current_window->stacking, window);
> break;
>
> default:
> @@ -281,6 +308,34 @@ redraw_handler(struct widget *widget, void *data)
> cairo_destroy(cr);
> }
>
> +static void
> +close_handler(void *data)
> +{
> + struct stacked_window *current_window = data;
> + struct stacked_window *parent_window;
> +
> + /* we first re-iterate from the root window to the current
> + * one to find the direct parent, and unreference it */
> + parent_window = current_window->stacking->root_window;
> + while (parent_window) {
> + if (parent_window->child_window == current_window) {
> + parent_window->child_window = NULL;
> + break;
> + }
> + parent_window = parent_window->child_window;
> + }
> +
> + /* we can now unreference and free all the children */
> + while (current_window) {
> + window_destroy(current_window->window);
> + free(current_window);
> +
> + parent_window = current_window;
> + current_window = current_window->child_window;
> + parent_window->child_window = NULL;
> + }
> +}
> +
> int
> main(int argc, char *argv[])
> {
> @@ -288,6 +343,10 @@ main(int argc, char *argv[])
>
> memset(&stacking, 0, sizeof stacking);
>
> + stacking.root_window = xzalloc(sizeof stacking.root_window);
> + stacking.root_window->stacking = &stacking;
> + stacking.root_window->child_window = NULL;
> +
> #ifdef HAVE_PANGO
> g_type_init();
> #endif
> @@ -300,11 +359,11 @@ main(int argc, char *argv[])
>
> display_set_user_data(stacking.display, &stacking);
>
> - stacking.root_window = new_window(&stacking, NULL);
> + stacking.root_window->window = new_window(&stacking, NULL);
>
> display_run(stacking.display);
>
> - window_destroy(stacking.root_window);
> + window_destroy(stacking.root_window->window);
> display_destroy(stacking.display);
>
> return 0;
> --
> 1.8.3.1
>
>
--
Regards,
*Manuel BACHMANN Tizen Project VANNES-FR*
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20150409/950b8c98/attachment-0001.html>
More information about the wayland-devel
mailing list