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

Reply via email to