Re: [PATCH 3/5] shell: add managed_surface interface, request and events
Just some info regarding these taskbar patches ; I have some more patches fixing bugs experienced on certain cases (multiples outputs, DRM backend...). They are all available on GitHub, https://github.com/Tarnyko/weston-taskbar/commits/HEAD-taskbar. I could refactor and repost the whole set here. However, I also realized that having an UI is maybe too early. I have sized down a smaller set (2 patches) that only handles xdg_surface_set_minimized() and allows to unminimize by doing Mod-Tab. So no modification of desktop-shell is needed. Will post them in a few minutes. Regards, Manuel 2014-02-19 14:04 GMT+01:00 Manuel Bachmann manuel.bachm...@open.eurogiciel.org: Hi Pekka, and thanks a lot for your review ! I changed my code, taking your comments into consideration. Here are the details : New events should be added last, so they do not change the opcodes of existing events. Ouch. You are right. I just reversed the order, so add_managed_surface is now the last event : --- a/clients/desktop-shell.c +++ b/clients/desktop-shell.c @@ -1239,21 +1239,6 @@ desktop_shell_prepare_lock_surface(void *data, } static void -desktop_shell_add_managed_surface(void *data, - struct desktop_shell *desktop_shell, - struct managed_surface *managed_surface) -{ -struct desktop *desktop = data; -struct output *output; - -wl_list_for_each(output, desktop-outputs, link) { -/* add a handler with default title */ -taskbar_add_handler(output-taskbar, managed_surface, Default); -update_window(output-taskbar-window); -} -} - -static void desktop_shell_grab_cursor(void *data, struct desktop_shell *desktop_shell, uint32_t cursor) @@ -1300,11 +1285,26 @@ desktop_shell_grab_cursor(void *data, } } +static void +desktop_shell_add_managed_surface(void *data, + struct desktop_shell *desktop_shell, + struct managed_surface *managed_surface) +{ +struct desktop *desktop = data; +struct output *output; + +wl_list_for_each(output, desktop-outputs, link) { +/* add a handler with default title */ +taskbar_add_handler(output-taskbar, managed_surface, Default); +update_window(output-taskbar-window); +} +} + static const struct desktop_shell_listener listener = { desktop_shell_configure, desktop_shell_prepare_lock_surface, -desktop_shell_add_managed_surface, -desktop_shell_grab_cursor +desktop_shell_grab_cursor, +desktop_shell_add_managed_surface }; Copy-pasta? This is not a global interface, is it? Correct. The description is now : @@ -108,9 +108,16 @@ interface name=managed_surface version=1 description summary=interface for handling managed surfaces - Only one client can bind this interface at a time. + Managed surfaces are abstractions for specific shell surfaces. /description You need protocol for destroying managed_surface objects Nice to have spotted that. More generally, I never called wl_resource_destroy(), which was bad. Here is the additional request and code : +request name=destroy type=destructor + description summary=remove managed_surface interface +The managed_surface interface is removed and ceases to refer +to anything. + /description +/request + --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -4020,6 +4020,13 @@ static const struct desktop_shell_interface desktop_shell_implementation = { }; static void +managed_surface_destroy(struct wl_client *client, +struct wl_resource *resource) +{ +wl_resource_destroy(resource); +} + +static void managed_surface_set_state(struct wl_client *client, struct wl_resource *resource, uint32_t state) @@ -4033,6 +4040,7 @@ managed_surface_set_state(struct wl_client *client, } --- a/clients/desktop-shell.c +++ b/clients/desktop-shell.c static const struct managed_surface_interface managed_surface_implementation = { +managed_surface_destroy, managed_surface_set_state }; @@ -1344,6 +1344,8 @@ managed_surface_removed(void *data, /* destroy the handler */ taskbar_destroy_handler(handler); update_window(handler-taskbar-window); + +managed_surface_destroy(managed_surface); I'm not sure if I need to do anything else. managed_surface only contains a reference to an object which is destroyed somewhere else, so I just destroy the wl_resource itself here. Thanks again. I'll be aware of any other suggestions , and will eventually repost a set of corrected modifications. Regards, Manuel 2014-02-19 11:56 GMT+01:00 Pekka Paalanen ppaala...@gmail.com: On Wed, 19 Feb 2014 06:18:18 +0100 Manuel Bachmann manuel.bachm...@open.eurogiciel.org wrote: We create a new managed_surface object which will track a
Re: [PATCH 3/5] shell: add managed_surface interface, request and events
On Wed, 19 Feb 2014 06:18:18 +0100 Manuel Bachmann manuel.bachm...@open.eurogiciel.org wrote: We create a new managed_surface object which will track a surface compositor-side, and receive events shell-side to handle 3 cases : - a toplevel surface has been created ; - a toplevel surface has been destroyed ; - a toplevel surface has a new title ; Signed-off-by: Manuel Bachmann manuel.bachm...@open.eurogiciel.org --- clients/desktop-shell.c| 69 desktop-shell/shell.c | 63 desktop-shell/shell.h |8 + protocol/desktop-shell.xml | 49 +++ 4 files changed, 189 insertions(+) Hi, I'll comment only on the protocol bits, I didn't check the code. diff --git a/protocol/desktop-shell.xml b/protocol/desktop-shell.xml index 3ae5d33..2262ade 100644 --- a/protocol/desktop-shell.xml +++ b/protocol/desktop-shell.xml @@ -68,6 +68,14 @@ /description /event +event name=add_managed_surface + description summary=tell client to manage a new surface + Tell the shell there is a new surface to manage, informing some + GUI components such as the taskbar. + /description + arg name=id type=new_id interface=managed_surface/ +/event + New events should be added last, so they do not change the opcodes of existing events. Same goes for requests. But this is only if we are concerned about backwards compatibility, and if we are, you need to bump the interface version. Since desktop-shell is already at version 2, I think we are concerned about backwards compatibility. Of course then the code will need to handle interface versions lower than what it was written for. event name=grab_cursor description summary=tell client what cursor to show during a grab This event will be sent immediately before a fake enter event on the @@ -98,6 +106,47 @@ /enum /interface + interface name=managed_surface version=1 +description summary=interface for handling managed surfaces + Only one client can bind this interface at a time. Copy-pasta? This is not a global interface, is it? +/description + + request name=set_state + description summary=set managed surface state + The client can ask the state of the shell surface linked to a managed + surface to be changed. It currently supports minimization. + /description + arg name=state type=uint/ + /request + + event name=state_changed + description summary=tell client managed surface state was changed + This event will be sent immediately after the shell suface linked to a + managed surface had its state changed. It currently supports minimization. + /description + arg name=state type=uint/ + /event + + event name=title_changed + description summary=tell client managed surface title was changed + This event will be sent immediately after the title of the shell surface + linked to a managed surface has been changed. + /description + arg name=title type=string/ + /event + + event name=removed + description summary=remove a managed surface + This event will be sent when a managed surface is removed. + /description + /event You need protocol for destroying managed_surface objects, IOW you need to add a request that is a destructor. Otherwise, the server can never destroy these objects (it essentially leaks them as the related windows are destroyed), or if you thought that sending removed event means the server itself destroys this protocol object, then you have a race. The client may send set_state request before it sees the removed event, which means the compositor will kill it for using an invalid object. + + enum name=state + entry name=normal value=0/ + entry name=minimized value=1/ + /enum + /interface + interface name=screensaver version=1 description summary=interface for implementing screensavers Only one client can bind this interface at a time. Thanks, pq ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: [PATCH 3/5] shell: add managed_surface interface, request and events
Hi Pekka, and thanks a lot for your review ! I changed my code, taking your comments into consideration. Here are the details : New events should be added last, so they do not change the opcodes of existing events. Ouch. You are right. I just reversed the order, so add_managed_surface is now the last event : --- a/clients/desktop-shell.c +++ b/clients/desktop-shell.c @@ -1239,21 +1239,6 @@ desktop_shell_prepare_lock_surface(void *data, } static void -desktop_shell_add_managed_surface(void *data, - struct desktop_shell *desktop_shell, - struct managed_surface *managed_surface) -{ -struct desktop *desktop = data; -struct output *output; - -wl_list_for_each(output, desktop-outputs, link) { -/* add a handler with default title */ -taskbar_add_handler(output-taskbar, managed_surface, Default); -update_window(output-taskbar-window); -} -} - -static void desktop_shell_grab_cursor(void *data, struct desktop_shell *desktop_shell, uint32_t cursor) @@ -1300,11 +1285,26 @@ desktop_shell_grab_cursor(void *data, } } +static void +desktop_shell_add_managed_surface(void *data, + struct desktop_shell *desktop_shell, + struct managed_surface *managed_surface) +{ +struct desktop *desktop = data; +struct output *output; + +wl_list_for_each(output, desktop-outputs, link) { +/* add a handler with default title */ +taskbar_add_handler(output-taskbar, managed_surface, Default); +update_window(output-taskbar-window); +} +} + static const struct desktop_shell_listener listener = { desktop_shell_configure, desktop_shell_prepare_lock_surface, -desktop_shell_add_managed_surface, -desktop_shell_grab_cursor +desktop_shell_grab_cursor, +desktop_shell_add_managed_surface }; Copy-pasta? This is not a global interface, is it? Correct. The description is now : @@ -108,9 +108,16 @@ interface name=managed_surface version=1 description summary=interface for handling managed surfaces - Only one client can bind this interface at a time. + Managed surfaces are abstractions for specific shell surfaces. /description You need protocol for destroying managed_surface objects Nice to have spotted that. More generally, I never called wl_resource_destroy(), which was bad. Here is the additional request and code : +request name=destroy type=destructor + description summary=remove managed_surface interface +The managed_surface interface is removed and ceases to refer +to anything. + /description +/request + --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -4020,6 +4020,13 @@ static const struct desktop_shell_interface desktop_shell_implementation = { }; static void +managed_surface_destroy(struct wl_client *client, +struct wl_resource *resource) +{ +wl_resource_destroy(resource); +} + +static void managed_surface_set_state(struct wl_client *client, struct wl_resource *resource, uint32_t state) @@ -4033,6 +4040,7 @@ managed_surface_set_state(struct wl_client *client, } --- a/clients/desktop-shell.c +++ b/clients/desktop-shell.c static const struct managed_surface_interface managed_surface_implementation = { +managed_surface_destroy, managed_surface_set_state }; @@ -1344,6 +1344,8 @@ managed_surface_removed(void *data, /* destroy the handler */ taskbar_destroy_handler(handler); update_window(handler-taskbar-window); + +managed_surface_destroy(managed_surface); I'm not sure if I need to do anything else. managed_surface only contains a reference to an object which is destroyed somewhere else, so I just destroy the wl_resource itself here. Thanks again. I'll be aware of any other suggestions , and will eventually repost a set of corrected modifications. Regards, Manuel 2014-02-19 11:56 GMT+01:00 Pekka Paalanen ppaala...@gmail.com: On Wed, 19 Feb 2014 06:18:18 +0100 Manuel Bachmann manuel.bachm...@open.eurogiciel.org wrote: We create a new managed_surface object which will track a surface compositor-side, and receive events shell-side to handle 3 cases : - a toplevel surface has been created ; - a toplevel surface has been destroyed ; - a toplevel surface has a new title ; Signed-off-by: Manuel Bachmann manuel.bachm...@open.eurogiciel.org --- clients/desktop-shell.c| 69 desktop-shell/shell.c | 63 desktop-shell/shell.h |8 + protocol/desktop-shell.xml | 49 +++ 4 files changed, 189 insertions(+) Hi, I'll comment only on the protocol bits, I didn't check the code. diff --git a/protocol/desktop-shell.xml b/protocol/desktop-shell.xml index 3ae5d33..2262ade 100644 ---
[PATCH 3/5] shell: add managed_surface interface, request and events
We create a new managed_surface object which will track a surface compositor-side, and receive events shell-side to handle 3 cases : - a toplevel surface has been created ; - a toplevel surface has been destroyed ; - a toplevel surface has a new title ; Signed-off-by: Manuel Bachmann manuel.bachm...@open.eurogiciel.org --- clients/desktop-shell.c| 69 desktop-shell/shell.c | 63 desktop-shell/shell.h |8 + protocol/desktop-shell.xml | 49 +++ 4 files changed, 189 insertions(+) diff --git a/clients/desktop-shell.c b/clients/desktop-shell.c index c341a91..5f861b2 100644 --- a/clients/desktop-shell.c +++ b/clients/desktop-shell.c @@ -139,6 +139,7 @@ struct taskbar_handler { struct taskbar *taskbar; cairo_surface_t *icon; int focused, pressed; + struct managed_surface *surface; char *title; int state; struct wl_list link; @@ -186,6 +187,14 @@ show_menu(struct panel *panel, struct input *input, uint32_t time) x - 10, y - 10, menu_func, entries, 4); } +static void +update_window(struct window *window) +{ + struct rectangle allocation; + window_get_allocation(window, allocation); + window_schedule_resize(window, allocation.width, allocation.height); +} + static int is_desktop_painted(struct desktop *desktop) { @@ -1113,6 +1122,20 @@ desktop_shell_prepare_lock_surface(void *data, } static void +desktop_shell_add_managed_surface(void *data, + struct desktop_shell *desktop_shell, + struct managed_surface *managed_surface) +{ + struct desktop *desktop = data; + struct output *output; + + wl_list_for_each(output, desktop-outputs, link) { + /* will follow in next patch : add the actual handler here */ + update_window(output-taskbar-window); + } +} + +static void desktop_shell_grab_cursor(void *data, struct desktop_shell *desktop_shell, uint32_t cursor) @@ -1162,10 +1185,56 @@ desktop_shell_grab_cursor(void *data, static const struct desktop_shell_listener listener = { desktop_shell_configure, desktop_shell_prepare_lock_surface, + desktop_shell_add_managed_surface, desktop_shell_grab_cursor }; static void +managed_surface_state_changed(void *data, + struct managed_surface *managed_surface, + uint32_t state) +{ + struct taskbar_handler *handler = data; + + if (handler-surface == managed_surface) { + /* set the handler state */ + handler-state = state; + } +} + +static void +managed_surface_title_changed(void *data, + struct managed_surface *managed_surface, + const char *title) +{ + struct taskbar_handler *handler = data; + + if (handler-surface == managed_surface) { + /* change the handler title text */ + handler-title = strdup(title); + update_window(handler-taskbar-window); + } +} + +static void +managed_surface_removed(void *data, + struct managed_surface *managed_surface) +{ + struct taskbar_handler *handler = data; + + if (handler-surface == managed_surface) { + /* will follow in next patch : destroy the actual handler here */ + update_window(handler-taskbar-window); + } +} + +static const struct managed_surface_listener managed_surface_listener = { + managed_surface_state_changed, + managed_surface_title_changed, + managed_surface_removed +}; + +static void background_destroy(struct background *background) { widget_destroy(background-widget); diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c index b9b4ad9..57afe5b 100644 --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -2023,6 +2023,14 @@ set_title(struct shell_surface *shsurf, const char *title) { free(shsurf-title); shsurf-title = strdup(title); + + if (shsurf-type == SHELL_SURFACE_TOPLEVEL) { + struct managed_surface *managed_surface; + wl_list_for_each(managed_surface, shsurf-shell-managed_surfaces_list, link) { + if (managed_surface-surface == shsurf-surface) + managed_surface_send_title_changed (managed_surface-resource, shsurf-title); + } + } } static void @@ -2991,6 +2999,16 @@ destroy_shell_surface(struct shell_surface *shsurf) remove_popup_grab(shsurf); } + if (shsurf-type == SHELL_SURFACE_TOPLEVEL) { + struct managed_surface *managed_surface; + wl_list_for_each(managed_surface, shsurf-shell-managed_surfaces_list, link) { + if