[PATCH weston] shell: Implement wl_notification_daemon

Pier Luigi pierluigi.fiorini at gmail.com
Sun Mar 17 15:38:42 PDT 2013


Wouldn't be better to use struct wl_notification_daemon pointers
instead of struct desktop_shell?

2013/3/14 Quentin Glidic <sardemff7+wayland at sardemff7.net>:
> From: Quentin Glidic <sardemff7+git at sardemff7.net>
>
> Implement the "bubbles list" style notifications.
> Corner anchor, margin and order can be changed in the configuration.
>
> Signed-off-by: Quentin Glidic <sardemff7+git at sardemff7.net>
> ---
>
> Rebase on top of current master
>
>  src/shell.c | 196 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
>  weston.ini  |   5 ++
>  2 files changed, 193 insertions(+), 8 deletions(-)
>
> diff --git a/src/shell.c b/src/shell.c
> index 3da5321..a066dc3 100644
> --- a/src/shell.c
> +++ b/src/shell.c
> @@ -42,6 +42,8 @@
>  #define DEFAULT_NUM_WORKSPACES 1
>  #define DEFAULT_WORKSPACE_CHANGE_ANIMATION_LENGTH 200
>
> +#define DEFAULT_NOTIFICATIONS_MARGIN 20
> +
>  enum animation_type {
>         ANIMATION_NONE,
>
> @@ -54,6 +56,25 @@ enum fade_type {
>         FADE_OUT
>  };
>
> +enum edge_anchor {
> +       EDGE_TOP    = 1<<0,
> +       EDGE_BOTTOM = 1<<1,
> +       EDGE_LEFT   = 1<<2,
> +       EDGE_RIGHT  = 1<<3
> +};
> +
> +enum corner_anchor {
> +       CORNER_TOP_RIGHT    = EDGE_TOP | EDGE_RIGHT,
> +       CORNER_TOP_LEFT     = EDGE_TOP | EDGE_LEFT,
> +       CORNER_BOTTOM_RIGHT = EDGE_BOTTOM | EDGE_RIGHT,
> +       CORNER_BOTTOM_LEFT  = EDGE_BOTTOM | EDGE_LEFT,
> +};
> +
> +enum notifications_order {
> +       ORDER_NEWEST_FIRST,
> +       ORDER_OLDEST_FIRST
> +};
> +
>  struct focus_state {
>         struct weston_seat *seat;
>         struct workspace *ws;
> @@ -89,6 +110,7 @@ struct desktop_shell {
>         struct wl_listener show_input_panel_listener;
>         struct wl_listener hide_input_panel_listener;
>
> +       struct weston_layer notification_layer;
>         struct weston_layer fullscreen_layer;
>         struct weston_layer panel_layer;
>         struct weston_layer background_layer;
> @@ -144,6 +166,14 @@ struct desktop_shell {
>         } input_panel;
>
>         struct {
> +               enum corner_anchor corner;
> +               enum notifications_order order;
> +               int32_t margin;
> +               struct weston_output *output;
> +               struct wl_resource *binding;
> +       } notification_daemon;
> +
> +       struct {
>                 struct weston_surface *surface;
>                 struct weston_surface_animation *animation;
>                 enum fade_type type;
> @@ -356,6 +386,43 @@ get_animation_type(char *animation)
>                 return ANIMATION_NONE;
>  }
>
> +static enum corner_anchor
> +get_corner_anchor(char *placement, enum corner_anchor default_anchor)
> +{
> +       if (placement == NULL)
> +               return default_anchor;
> +
> +       if (strcmp("top-left", placement) == 0)
> +               return CORNER_TOP_LEFT;
> +       if (strcmp("top-right", placement) == 0)
> +               return CORNER_TOP_RIGHT;
> +       if (strcmp("bottom-right", placement) == 0)
> +               return CORNER_BOTTOM_RIGHT;
> +       if (strcmp("bottom-left", placement) == 0)
> +               return CORNER_BOTTOM_LEFT;
> +
> +       return default_anchor;
> +}
> +
> +static enum notifications_order
> +get_notification_order(char *order)
> +{
> +       if (order == NULL)
> +               return ORDER_NEWEST_FIRST;
> +
> +       if (strcmp("oldest-first", order) == 0)
> +               return ORDER_OLDEST_FIRST;
> +
> +       return ORDER_NEWEST_FIRST;
> +}
> +
> +static struct weston_output *
> +get_default_output(struct weston_compositor *compositor)
> +{
> +       return container_of(compositor->output_list.next,
> +                           struct weston_output, link);
> +}
> +
>  static void
>  shell_configuration(struct desktop_shell *shell, const char *config_file)
>  {
> @@ -364,6 +431,9 @@ shell_configuration(struct desktop_shell *shell, const char *config_file)
>         unsigned int num_workspaces = DEFAULT_NUM_WORKSPACES;
>         char *modifier = NULL;
>         char *win_animation = NULL;
> +       char *notifications_corner = NULL;
> +       char *notifications_order = NULL;
> +       int notifications_margin = DEFAULT_NOTIFICATIONS_MARGIN;
>
>         struct config_key shell_keys[] = {
>                 { "binding-modifier",   CONFIG_KEY_STRING, &modifier },
> @@ -377,9 +447,16 @@ shell_configuration(struct desktop_shell *shell, const char *config_file)
>                 { "duration",   CONFIG_KEY_INTEGER, &duration },
>         };
>
> +       struct config_key notifications_keys[] = {
> +               { "corner", CONFIG_KEY_STRING,  &notifications_corner },
> +               { "order",     CONFIG_KEY_STRING,  &notifications_order },
> +               { "margin",    CONFIG_KEY_INTEGER, &notifications_margin },
> +       };
> +
>         struct config_section cs[] = {
>                 { "shell", shell_keys, ARRAY_LENGTH(shell_keys), NULL },
>                 { "screensaver", saver_keys, ARRAY_LENGTH(saver_keys), NULL },
> +               { "notifications", notifications_keys, ARRAY_LENGTH(notifications_keys), NULL },
>         };
>
>         parse_config_file(config_file, cs, ARRAY_LENGTH(cs), shell);
> @@ -389,6 +466,13 @@ shell_configuration(struct desktop_shell *shell, const char *config_file)
>         shell->binding_modifier = get_modifier(modifier);
>         shell->win_animation_type = get_animation_type(win_animation);
>         shell->workspaces.num = num_workspaces > 0 ? num_workspaces : 1;
> +       shell->notification_daemon.corner = get_corner_anchor(notifications_corner, CORNER_TOP_RIGHT);
> +       shell->notification_daemon.order = get_notification_order(notifications_order);
> +       shell->notification_daemon.margin = notifications_margin;
> +       shell->notification_daemon.output = get_default_output(shell->compositor);
> +
> +       free(notifications_order);
> +       free(notifications_corner);
>  }
>
>  static void
> @@ -1434,13 +1518,6 @@ shell_surface_set_class(struct wl_client *client,
>         shsurf->class = strdup(class);
>  }
>
> -static struct weston_output *
> -get_default_output(struct weston_compositor *compositor)
> -{
> -       return container_of(compositor->output_list.next,
> -                           struct weston_output, link);
> -}
> -
>  static void
>  shell_unset_fullscreen(struct shell_surface *shsurf)
>  {
> @@ -2137,6 +2214,73 @@ static const struct wl_shell_interface shell_implementation = {
>  };
>
>  static void
> +notification_daemon_map_surfaces(struct desktop_shell *shell)
> +{
> +       bool right;
> +       bool bottom;
> +       int32_t x, y;
> +       struct weston_surface *ws;
> +
> +       right = shell->notification_daemon.corner & EDGE_RIGHT;
> +       bottom = shell->notification_daemon.corner & EDGE_BOTTOM;
> +
> +       if (right)
> +               x = shell->notification_daemon.output->width - shell->notification_daemon.margin;
> +       else
> +               x = shell->notification_daemon.margin;
> +       if (bottom)
> +               y = shell->notification_daemon.output->height - shell->notification_daemon.margin;
> +       else
> +               y = shell->notification_daemon.margin;
> +
> +       wl_list_for_each(ws, &shell->notification_layer.surface_list, layer_link) {
> +               if (bottom)
> +                       y -= ws->geometry.height;
> +               if (right)
> +                       x -= ws->geometry.width;
> +               weston_surface_set_position(ws, x, y);
> +               if (right)
> +                       x += ws->geometry.width;
> +               if (bottom)
> +                       y -= shell->notification_daemon.margin;
> +               else
> +                       y += ws->geometry.height + shell->notification_daemon.margin;
> +       }
> +}
> +
> +static void
> +notification_daemon_add_surface(struct wl_client *client, struct wl_resource *resource,
> +                               struct wl_resource *surface_resource)
> +{
> +       struct desktop_shell *shell = resource->data;
> +       struct weston_surface *surface = surface_resource->data;
> +
> +       if (surface->configure != NULL) {
> +               wl_resource_post_error(surface_resource,
> +                                      WL_DISPLAY_ERROR_INVALID_OBJECT,
> +                                      "surface role already assigned");
> +               return;
> +       }
> +
> +       surface->geometry.width = weston_surface_buffer_width(surface);
> +       surface->geometry.height = weston_surface_buffer_height(surface);
> +
> +       surface->output = shell->notification_daemon.output;
> +
> +       if (shell->notification_daemon.order == ORDER_NEWEST_FIRST)
> +               wl_list_insert(&shell->notification_layer.surface_list, &surface->layer_link);
> +       else
> +               wl_list_insert(shell->notification_layer.surface_list.prev, &surface->layer_link);
> +       notification_daemon_map_surfaces(shell);
> +
> +       weston_compositor_schedule_repaint(shell->compositor);
> +}
> +
> +static const struct wl_notification_daemon_interface notification_daemon_implementation = {
> +       notification_daemon_add_surface
> +};
> +
> +static void
>  shell_fade(struct desktop_shell *shell, enum fade_type type);
>
>  static int
> @@ -3269,6 +3413,37 @@ bind_shell(struct wl_client *client, void *data, uint32_t version, uint32_t id)
>  }
>
>  static void
> +unbind_notification_daemon(struct wl_resource *resource)
> +{
> +       struct desktop_shell *shell = resource->data;
> +
> +       shell->notification_daemon.binding = NULL;
> +       free(resource);
> +}
> +
> +static void
> +bind_notification_daemon(struct wl_client *client,
> +                        void *data, uint32_t version, uint32_t id)
> +{
> +       struct desktop_shell *shell = data;
> +       struct wl_resource *resource;
> +
> +       resource = wl_client_add_object(client, &wl_notification_daemon_interface,
> +                                       &notification_daemon_implementation,
> +                                       id, shell);
> +
> +       if (shell->notification_daemon.binding == NULL) {
> +               resource->destroy = unbind_notification_daemon;
> +               shell->notification_daemon.binding = resource;
> +               return;
> +       }
> +
> +       wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
> +                              "interface object already bound");
> +       wl_resource_destroy(resource);
> +}
> +
> +static void
>  unbind_desktop_shell(struct wl_resource *resource)
>  {
>         struct desktop_shell *shell = resource->data;
> @@ -4098,7 +4273,8 @@ module_init(struct weston_compositor *ec,
>
>         wl_list_init(&shell->input_panel.surfaces);
>
> -       weston_layer_init(&shell->fullscreen_layer, &ec->cursor_layer.link);
> +       weston_layer_init(&shell->notification_layer, &ec->cursor_layer.link);
> +       weston_layer_init(&shell->fullscreen_layer, &shell->notification_layer.link);
>         weston_layer_init(&shell->panel_layer, &shell->fullscreen_layer.link);
>         weston_layer_init(&shell->background_layer, &shell->panel_layer.link);
>         weston_layer_init(&shell->lock_layer, NULL);
> @@ -4128,6 +4304,10 @@ module_init(struct weston_compositor *ec,
>                                   shell, bind_shell) == NULL)
>                 return -1;
>
> +       if (wl_display_add_global(ec->wl_display, &wl_notification_daemon_interface,
> +                                 shell, bind_notification_daemon) == NULL)
> +               return -1;
> +
>         if (wl_display_add_global(ec->wl_display,
>                                   &desktop_shell_interface,
>                                   shell, bind_desktop_shell) == NULL)
> diff --git a/weston.ini b/weston.ini
> index 98092a1..07aaa5a 100644
> --- a/weston.ini
> +++ b/weston.ini
> @@ -36,6 +36,11 @@ path=./clients/flower
>  path=/usr/libexec/weston-screensaver
>  duration=600
>
> +[notifications]
> +#corner=top-right
> +#order=newest-first
> +#margin=20
> +
>  [input-method]
>  path=/usr/libexec/weston-keyboard
>
> --
> 1.8.1.5
>
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel



--
Out of the box experience
http://www.maui-project.org/


More information about the wayland-devel mailing list