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 < [email protected]>: > 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 <[email protected]> > --- > 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*
_______________________________________________ wayland-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/wayland-devel
