[PATCH 3/5] shell: add managed_surface interface, request and events
Manuel Bachmann
manuel.bachmann at open.eurogiciel.org
Tue Feb 18 21:18:18 PST 2014
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.bachmann at 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
More information about the wayland-devel
mailing list