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 (managed_surface->surface == shsurf->surface) { + managed_surface_send_removed (managed_surface->resource); + wl_list_remove(&managed_surface->link); + } + } + } + if (shsurf->fullscreen.type == WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER && shell_surface_is_top_fullscreen(shsurf)) restore_output_mode (shsurf->fullscreen_output); @@ -3941,6 +3959,27 @@ static const struct desktop_shell_interface desktop_shell_implementation = { desktop_shell_desktop_ready }; +static void +managed_surface_set_state(struct wl_client *client, + struct wl_resource *resource, + uint32_t state) +{ + /* receive desktop-shell taskbar signal to show/hide */ + struct managed_surface *managed_surface = wl_resource_get_user_data(resource); + struct weston_surface *surface = managed_surface->surface; + + if (state) + /* compositor hides surface on its own ; will follow in next patch */ + weston_log ("minimize stub\n"); + else + /* compositor unhides surface on its own ; will follow in next patch */ + weston_log ("unminimize stub\n"); +} + +static const struct managed_surface_interface managed_surface_implementation = { + managed_surface_set_state +}; + static enum shell_surface_type get_shell_surface_type(struct weston_surface *surface) { @@ -4849,6 +4888,28 @@ map(struct desktop_shell *shell, struct shell_surface *shsurf, break; } + if (shsurf->type == SHELL_SURFACE_TOPLEVEL) { + struct managed_surface *surface; + surface = calloc(1, sizeof *surface); + + if (surface) { + struct wl_client *client; + client = wl_resource_get_client(shsurf->shell->child.desktop_shell); + surface->surface = shsurf->surface; + surface->resource = wl_resource_create(client, + &managed_surface_interface, 1, 0); + wl_resource_set_implementation(surface->resource, + &managed_surface_implementation, + surface, NULL); + + desktop_shell_send_add_managed_surface(shsurf->shell->child.desktop_shell, + surface->resource); + wl_list_insert(shsurf->shell->managed_surfaces_list.prev, &surface->link); + } else { + weston_log("Could not create managed surface\n"); + } + } + if (shsurf->type == SHELL_SURFACE_TOPLEVEL && !shsurf->state.maximized && !shsurf->state.fullscreen) { @@ -5957,6 +6018,8 @@ module_init(struct weston_compositor *ec, } activate_workspace(shell, 0); + wl_list_init(&shell->managed_surfaces_list); + wl_list_init(&shell->workspaces.anim_sticky_list); wl_list_init(&shell->workspaces.animation.link); shell->workspaces.animation.frame = animate_workspace_change_frame; diff --git a/desktop-shell/shell.h b/desktop-shell/shell.h index 104e621..ed563b9 100644 --- a/desktop-shell/shell.h +++ b/desktop-shell/shell.h @@ -93,6 +93,12 @@ struct focus_surface { struct weston_transform workspace_transform; }; +struct managed_surface { + struct wl_resource *resource; + struct weston_surface *surface; + struct wl_list link; +}; + struct workspace { struct weston_layer layer; @@ -198,6 +204,8 @@ struct desktop_shell { enum animation_type startup_animation_type; enum animation_type focus_animation_type; + struct wl_list managed_surfaces_list; + struct wl_listener output_create_listener; struct wl_listener output_move_listener; struct wl_list output_list; 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> + <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. + </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> + + <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. -- 1.7.10.4 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel