]> git.mdlowis.com Git - proto/labwc.git/commitdiff
Create a linked list of SSD for each view
authorJohan Malm <jgm323@gmail.com>
Sun, 21 Mar 2021 21:46:16 +0000 (21:46 +0000)
committerJohan Malm <jgm323@gmail.com>
Sun, 21 Mar 2021 21:46:16 +0000 (21:46 +0000)
include/labwc.h
include/ssd.h
src/desktop.c
src/output.c
src/ssd.c
src/view.c
src/xdg.c
src/xwayland.c

index eb6e0c4e6391ec96c74b0d6eed9bfaf46657d5ea..fa0bac02f377a4ae5cd3ab60737b4f90f8fe0fec 100644 (file)
@@ -213,7 +213,11 @@ struct view {
                uint32_t configure_serial;
        } pending_move_resize;
 
-       bool server_side_deco;
+       struct {
+               bool enabled;
+               struct wl_list parts;
+               struct wlr_box box; /* remember geo so we know when to update */
+       } ssd;
 
        struct wl_listener map;
        struct wl_listener unmap;
index 76544cf3328f7dda9e5bba8054cf5929a0831490..734f290184152b28388e0a2fec5880cef479feb9 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef __LABWC_SSD_H
 #define __LABWC_SSD_H
 
-enum ssd_part {
+enum ssd_part_type {
        LAB_SSD_NONE = 0,
        LAB_SSD_BUTTON_CLOSE,
        LAB_SSD_BUTTON_MAXIMIZE,
@@ -14,11 +14,22 @@ enum ssd_part {
        LAB_SSD_END_MARKER
 };
 
+struct ssd_part {
+       struct wlr_box box;
+       enum ssd_part_type type;
+       struct wlr_texture *texture;
+       float *color;
+       struct wl_list link;
+};
+
 struct view;
 
 struct border ssd_thickness(struct view *view);
 struct wlr_box ssd_max_extents(struct view *view);
-struct wlr_box ssd_box(struct view *view, enum ssd_part ssd_part);
-enum ssd_part ssd_at(struct view *view, double lx, double ly);
+struct wlr_box ssd_box(struct view *view, enum ssd_part_type type);
+enum ssd_part_type ssd_at(struct view *view, double lx, double ly);
+void ssd_create(struct view *view);
+void ssd_destroy(struct view *view);
+void ssd_update_geometry(struct view *view);
 
 #endif /* __LABWC_SSD_H */
index bb1a8c89087119724e7bfb81806ed3504c307391..21521423c3b3ff203a0608de950294c45571c72d 100644 (file)
@@ -244,7 +244,7 @@ desktop_view_at(struct server *server, double lx, double ly,
                if (_view_at(view, lx, ly, surface, sx, sy)) {
                        return view;
                }
-               if (!view->server_side_deco) {
+               if (!view->ssd.enabled) {
                        continue;
                }
                *view_area = ssd_at(view, lx, ly);
index b9377fb9cf65ae5c6cd9a07b8ee0d94268bf36f0..d00951378ca5c90c15c50b5b5f240640ae7a73af 100644 (file)
@@ -321,6 +321,7 @@ render_rect(struct output *output, pixman_region32_t *output_damage,
                output->wlr_output, &ox, &oy);
        box.x += ox;
        box.y += oy;
+       scale_box(&box, wlr_output->scale);
 
        pixman_region32_t damage;
        pixman_region32_init(&damage);
@@ -424,6 +425,7 @@ render_icon(struct output *output, pixman_region32_t *output_damage,
                output->wlr_output, &ox, &oy);
        button.x += ox;
        button.y += oy;
+       scale_box(&button, output->wlr_output->scale);
 
        float matrix[9];
        wlr_matrix_project_box(matrix, &button, WL_OUTPUT_TRANSFORM_NORMAL, 0,
@@ -433,54 +435,48 @@ render_icon(struct output *output, pixman_region32_t *output_damage,
 }
 
 static bool
-isbutton(enum ssd_part ssd_part)
+isbutton(enum ssd_part_type type)
 {
-       return ssd_part == LAB_SSD_BUTTON_CLOSE ||
-              ssd_part == LAB_SSD_BUTTON_MAXIMIZE ||
-              ssd_part == LAB_SSD_BUTTON_ICONIFY;
+       return type == LAB_SSD_BUTTON_CLOSE ||
+              type == LAB_SSD_BUTTON_MAXIMIZE ||
+              type == LAB_SSD_BUTTON_ICONIFY;
 }
 
 static void
 render_deco(struct view *view, struct output *output,
                pixman_region32_t *output_damage)
 {
-       if (!view->server_side_deco) {
+       if (!view->ssd.enabled) {
                return;
        }
 
-       struct theme *theme = view->server->theme;
-
-       /* render border */
-       float *color = theme->window_active_handle_bg_color;
-       enum ssd_part border[4] = {
-               LAB_SSD_PART_TOP,
-               LAB_SSD_PART_RIGHT,
-               LAB_SSD_PART_BOTTOM,
-               LAB_SSD_PART_LEFT,
-       };
-       for (int i = 0; i < 4; i++) {
-               struct wlr_box box = ssd_box(view, border[i]);
-               scale_box(&box, output->wlr_output->scale);
-               render_rect(output, output_damage, &box, color);
+       struct ssd_part *part;
+       wl_list_for_each_reverse(part, &view->ssd.parts, link) {
+               if (part->texture) {
+                       ; // render_texture()
+               } else {
+                       render_rect(output, output_damage, &part->box,
+                                   part->color);
+               }
        }
 
        /* render title */
        struct wlr_seat *seat = view->server->seat.seat;
+       float *color;
+       struct theme *theme = view->server->theme;
        if (view->surface == seat->keyboard_state.focused_surface) {
                color = theme->window_active_title_bg_color;
        } else {
                color = theme->window_inactive_title_bg_color;
        }
        struct wlr_box box = ssd_box(view, LAB_SSD_PART_TITLE);
-       scale_box(&box, output->wlr_output->scale);
        render_rect(output, output_damage, &box, color);
 
        /* button background */
        struct wlr_cursor *cur = view->server->seat.cursor;
-       enum ssd_part ssd_part = ssd_at(view, cur->x, cur->y);
-       box = ssd_box(view, ssd_part);
-       scale_box(&box, output->wlr_output->scale);
-       if (isbutton(ssd_part) &&
+       enum ssd_part_type type = ssd_at(view, cur->x, cur->y);
+       box = ssd_box(view, type);
+       if (isbutton(type) &&
                        wlr_box_contains_point(&box, cur->x, cur->y)) {
                color = (float[4]){ 0.5, 0.5, 0.5, 0.5 };
                render_rect(output, output_damage, &box, color);
@@ -489,28 +485,22 @@ render_deco(struct view *view, struct output *output,
        /* buttons */
        if (view->surface == seat->keyboard_state.focused_surface) {
                box = ssd_box(view, LAB_SSD_BUTTON_CLOSE);
-               scale_box(&box, output->wlr_output->scale);
                render_icon(output, output_damage, &box,
                        theme->xbm_close_active_unpressed);
                box = ssd_box(view, LAB_SSD_BUTTON_MAXIMIZE);
-               scale_box(&box, output->wlr_output->scale);
                render_icon(output, output_damage, &box,
                        theme->xbm_maximize_active_unpressed);
                box = ssd_box(view, LAB_SSD_BUTTON_ICONIFY);
-               scale_box(&box, output->wlr_output->scale);
                render_icon(output, output_damage, &box,
                        theme->xbm_iconify_active_unpressed);
        } else {
                box = ssd_box(view, LAB_SSD_BUTTON_CLOSE);
-               scale_box(&box, output->wlr_output->scale);
                render_icon(output, output_damage, &box,
                        theme->xbm_close_inactive_unpressed);
                box = ssd_box(view, LAB_SSD_BUTTON_MAXIMIZE);
-               scale_box(&box, output->wlr_output->scale);
                render_icon(output, output_damage, &box,
                        theme->xbm_maximize_inactive_unpressed);
                box = ssd_box(view, LAB_SSD_BUTTON_ICONIFY);
-               scale_box(&box, output->wlr_output->scale);
                render_icon(output, output_damage, &box,
                        theme->xbm_iconify_inactive_unpressed);
        }
index 0d89cebe50a4282025640a3ef0d710bdf10b13b0..c7748a2074e5e3a7a11daa04b8d4dcd5a6c1df17 100644 (file)
--- a/src/ssd.c
+++ b/src/ssd.c
@@ -7,6 +7,7 @@
 #include <assert.h>
 #include "config/rcxml.h"
 #include "labwc.h"
+#include "theme.h"
 #include "ssd.h"
 
 #define BORDER_WIDTH (2)
@@ -37,11 +38,11 @@ ssd_max_extents(struct view *view)
 }
 
 struct wlr_box
-ssd_box(struct view *view, enum ssd_part ssd_part)
+ssd_box(struct view *view, enum ssd_part_type type)
 {
        struct wlr_box box = { 0 };
        assert(view);
-       switch (ssd_part) {
+       switch (type) {
        case LAB_SSD_BUTTON_CLOSE:
                box.width = rc.title_height;
                box.height = rc.title_height;
@@ -96,17 +97,85 @@ ssd_box(struct view *view, enum ssd_part ssd_part)
        return box;
 }
 
-enum ssd_part
+enum ssd_part_type
 ssd_at(struct view *view, double lx, double ly)
 {
-       enum ssd_part ssd_part;
-       for (ssd_part = 0; ssd_part < LAB_SSD_END_MARKER; ++ssd_part) {
-               struct wlr_box box = ssd_box(view, ssd_part);
+       enum ssd_part_type type;
+       for (type = 0; type < LAB_SSD_END_MARKER; ++type) {
+               struct wlr_box box = ssd_box(view, type);
                if (wlr_box_contains_point(&box, lx, ly)) {
-                       return ssd_part;
+                       return type;
                }
        }
        return LAB_SSD_NONE;
 }
 
+static struct ssd_part *
+add_part(struct view *view, enum ssd_part_type type)
+{
+       struct ssd_part *part = calloc(1, sizeof(struct ssd_part));
+       part->type = type;
+       wl_list_insert(&view->ssd.parts, &part->link);
+       return part;
+}
+
+void
+ssd_create(struct view *view)
+{
+       struct theme *theme = view->server->theme;
+       struct ssd_part *part;
+
+       view->ssd.box.x = view->x;
+       view->ssd.box.y = view->y;
+       view->ssd.box.width = view->w;
+       view->ssd.box.height = view->h;
+
+       /* border */
+       float *color = theme->window_active_handle_bg_color;
+       enum ssd_part_type border[4] = {
+               LAB_SSD_PART_TOP,
+               LAB_SSD_PART_RIGHT,
+               LAB_SSD_PART_BOTTOM,
+               LAB_SSD_PART_LEFT,
+       };
+       for (int i = 0; i < 4; i++) {
+               part = add_part(view, border[i]);
+               part->box = ssd_box(view, border[i]);
+               part->color = color;
+       }
+}
+
+void
+ssd_destroy(struct view *view)
+{
+       struct ssd_part *part, *next;
+       wl_list_for_each_safe(part, next, &view->ssd.parts, link) {
+               wl_list_remove(&part->link);
+               free(part);
+       }
+}
+
+static bool
+geometry_changed(struct view *view)
+{
+       return view->x != view->ssd.box.x || view->y != view->ssd.box.y ||
+               view->w != view->ssd.box.width ||
+               view->h != view->ssd.box.height;
+}
 
+void
+ssd_update_geometry(struct view *view)
+{
+       if (!geometry_changed(view)) {
+               return;
+       }
+       struct ssd_part *part;
+       wl_list_for_each(part, &view->ssd.parts, link) {
+               part->box = ssd_box(view, part->type);
+       }
+       view->ssd.box.x = view->x;
+       view->ssd.box.y = view->y;
+       view->ssd.box.width = view->w;
+       view->ssd.box.height = view->h;
+       damage_all_outputs(view->server);
+}
index 9aeae4d5c7d8fd54e47593a85d93e97a68068523..2a463232d8bdc94aafededb4c3d93af262ea5652 100644 (file)
@@ -77,7 +77,7 @@ view_maximize(struct view *view, bool maximize)
                        .width = output->width,
                        .height = output->height,
                };
-               if (view->server_side_deco) {
+               if (view->ssd.enabled) {
                        struct border border = ssd_thickness(view);
                        box.x += border.left;
                        box.y += border.top;
index 2ac771cd5dfe8b33232003bd907dab00c39a8a70..1e0dc828c33cb3d962dc92ffe22df00f4d0c2d42 100644 (file)
--- a/src/xdg.c
+++ b/src/xdg.c
@@ -69,6 +69,7 @@ handle_commit(struct wl_listener *listener, void *data)
                        view->pending_move_resize.configure_serial = 0;
                }
        }
+       ssd_update_geometry(view);
        damage_view_part(view);
 }
 
@@ -91,6 +92,7 @@ handle_destroy(struct wl_listener *listener, void *data)
 {
        struct view *view = wl_container_of(listener, view, destroy);
        wl_list_remove(&view->link);
+       ssd_destroy(view);
        free(view);
 }
 
@@ -151,6 +153,7 @@ xdg_toplevel_view_configure(struct view *view, struct wlr_box geo)
        } else if (view->pending_move_resize.configure_serial == 0) {
                view->x = geo.x;
                view->y = geo.y;
+               ssd_update_geometry(view);
                damage_all_outputs(view->server);
        }
 }
@@ -160,6 +163,7 @@ xdg_toplevel_view_move(struct view *view, double x, double y)
 {
        view->x = x;
        view->y = y;
+       ssd_update_geometry(view);
        damage_all_outputs(view->server);
 }
 
@@ -253,9 +257,10 @@ xdg_toplevel_view_map(struct view *view)
                 */
                view_maximize(view, false);
 
-               view->server_side_deco = has_ssd(view);
-               if (view->server_side_deco) {
+               view->ssd.enabled = has_ssd(view);
+               if (view->ssd.enabled) {
                        view->margin = ssd_thickness(view);
+                       ssd_create(view);
                }
                update_padding(view);
                position_xdg_toplevel_view(view);
@@ -310,6 +315,7 @@ xdg_surface_new(struct wl_listener *listener, void *data)
        view->type = LAB_XDG_SHELL_VIEW;
        view->impl = &xdg_toplevel_view_impl;
        view->xdg_surface = xdg_surface;
+       wl_list_init(&view->ssd.parts);
 
        view->map.notify = handle_map;
        wl_signal_add(&xdg_surface->events.map, &view->map);
index 1a8b4061a9695a7c68ec2ac330f5311ccb4097d6..185208727fef54f8005b6addd75d28cfb4c4a7fe 100644 (file)
@@ -22,6 +22,7 @@ handle_commit(struct wl_listener *listener, void *data)
                        view->pending_move_resize.height - view->h;
                view->pending_move_resize.update_y = false;
        }
+       ssd_update_geometry(view);
        damage_view_whole(view);
 }
 
@@ -49,6 +50,7 @@ handle_destroy(struct wl_listener *listener, void *data)
        wl_list_remove(&view->destroy.link);
        wl_list_remove(&view->request_configure.link);
        wl_list_remove(&view->request_maximize.link);
+       ssd_destroy(view);
        free(view);
 }
 
@@ -95,6 +97,7 @@ move(struct view *view, double x, double y)
        struct wlr_xwayland_surface *s = view->xwayland_surface;
        wlr_xwayland_surface_configure(s, (int16_t)x, (int16_t)y,
                (uint16_t)s->width, (uint16_t)s->height);
+       ssd_update_geometry(view);
        damage_all_outputs(view->server);
 }
 
@@ -147,9 +150,12 @@ map(struct view *view)
        view->w = view->xwayland_surface->width;
        view->h = view->xwayland_surface->height;
        view->surface = view->xwayland_surface->surface;
-       view->server_side_deco = want_deco(view);
+       view->ssd.enabled = want_deco(view);
 
-       view->margin = ssd_thickness(view);
+       if (view->ssd.enabled) {
+               view->margin = ssd_thickness(view);
+               ssd_create(view);
+       }
 
        top_left_edge_boundary_check(view);
 
@@ -209,6 +215,7 @@ xwayland_surface_new(struct wl_listener *listener, void *data)
        view->type = LAB_XWAYLAND_VIEW;
        view->impl = &xwl_view_impl;
        view->xwayland_surface = xsurface;
+       wl_list_init(&view->ssd.parts);
 
        view->map.notify = handle_map;
        wl_signal_add(&xsurface->events.map, &view->map);