[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