]> git.mdlowis.com Git - proto/labwc.git/commitdiff
view: add 'struct border margin'
authorJohan Malm <jgm323@gmail.com>
Tue, 15 Sep 2020 19:41:01 +0000 (20:41 +0100)
committerJohan Malm <jgm323@gmail.com>
Tue, 15 Sep 2020 19:41:01 +0000 (20:41 +0100)
Simplify various view interfaces as a result

include/labwc.h
src/cursor.c
src/deco.c
src/desktop.c
src/interactive.c
src/output.c
src/view.c
src/xdg.c
src/xwayland.c

index ebc669877e0d72b72fef466fb59522bbf1724415..c86deccd77f8e37e7844a0132dd7a2aa2d9a57b1 100644 (file)
@@ -112,6 +112,13 @@ struct view_impl {
        void (*unmap)(struct view *view);
 };
 
+struct border {
+       int top;
+       int right;
+       int bottom;
+       int left;
+};
+
 struct view {
        struct server *server;
        enum view_type type;
@@ -127,7 +134,19 @@ struct view {
        bool mapped;
        bool been_mapped;
        bool minimized;
+
+       /* geometry of the wlr_surface contained within the view */
        int x, y, w, h;
+
+       /*
+        * margin refers to the space between the extremities of the view and
+        * wlr_surface - typically made up of decoration.
+        * For xdg-shell views, the margin is typically negative.
+        */
+       struct border margin;
+
+       int xdg_grab_offset;
+
        bool show_server_side_deco;
 
        struct wl_listener map;
@@ -168,8 +187,6 @@ void xwayland_surface_new(struct wl_listener *listener, void *data);
 void xwayland_unmanaged_create(struct server *server,
                               struct wlr_xwayland_surface *xsurface);
 
-void view_init_position(struct view *view);
-
 /**
  * view_get_surface_geometry - geometry relative to view
  * @view: toplevel containing the surface to process
@@ -181,7 +198,6 @@ struct wlr_box view_geometry(struct view *view);
 void view_resize(struct view *view, struct wlr_box geo);
 void view_minimize(struct view *view);
 void view_unminimize(struct view *view);
-bool view_hasfocus(struct view *view);
 
 void desktop_focus_view(struct view *view);
 
@@ -218,7 +234,7 @@ void keyboard_new(struct server *server, struct wlr_input_device *device);
 void output_frame(struct wl_listener *listener, void *data);
 void output_new(struct wl_listener *listener, void *data);
 
-struct wlr_box deco_max_extents(struct view *view);
+struct border deco_max_extents(struct view *view);
 struct wlr_box deco_box(struct view *view, enum deco_part deco_part);
 enum deco_part deco_at(struct view *view, double lx, double ly);
 
index efcada271cca2de8f7a9b00e6e0a6f70bd70de45..faa75e10aa57a6abac28e4d69d06c16735499cc8 100644 (file)
@@ -30,7 +30,9 @@ static void process_cursor_resize(struct server *server, uint32_t time)
        double dy = server->cursor->y - server->grab_y;
 
        struct view *view = server->grabbed_view;
-       struct wlr_box new_view_geo = view_geometry(view);
+       struct wlr_box new_view_geo = {
+               .x = view->x, .y = view->y, .width = view->w, .height = view->h
+       };
 
        if (server->resize_edges & WLR_EDGE_TOP) {
                new_view_geo.y = server->grab_box.y + dy;
@@ -53,6 +55,8 @@ static void process_cursor_resize(struct server *server, uint32_t time)
        view->y = new_view_geo.y;
 
        /* Resize */
+       new_view_geo.width -= 2 * view->xdg_grab_offset;
+       new_view_geo.height -= 2 * view->xdg_grab_offset;
        view_resize(view, new_view_geo);
 }
 
@@ -74,8 +78,8 @@ static void process_cursor_motion(struct server *server, uint32_t time)
        struct wlr_surface *surface = NULL;
        int view_area;
        struct view *view = desktop_view_at(server, server->cursor->x,
-                                   server->cursor->y, &surface, &sx, &sy,
-                                   &view_area);
+                                           server->cursor->y, &surface, &sx,
+                                           &sy, &view_area);
        if (!view) {
                /* If there's no view under the cursor, set the cursor image to
                 * a default. This is what makes the cursor image appear when
@@ -83,6 +87,8 @@ static void process_cursor_motion(struct server *server, uint32_t time)
                wlr_xcursor_manager_set_cursor_image(
                        server->cursor_mgr, XCURSOR_DEFAULT, server->cursor);
        }
+
+       /* TODO: Could we use wlr_xcursor_get_resize_name() here?? */
        switch (view_area) {
        case LAB_DECO_PART_TITLE:
                wlr_xcursor_manager_set_cursor_image(
@@ -189,8 +195,8 @@ void cursor_button(struct wl_listener *listener, void *data)
        struct wlr_surface *surface;
        int view_area;
        struct view *view = desktop_view_at(server, server->cursor->x,
-                                   server->cursor->y, &surface, &sx, &sy,
-                                   &view_area);
+                                           server->cursor->y, &surface, &sx,
+                                           &sy, &view_area);
        if (event->state == WLR_BUTTON_RELEASED) {
                /* Exit interactive move/resize mode. */
                server->cursor_mode = LAB_CURSOR_PASSTHROUGH;
index 1366b2260fb82cee50e8d068dffbe5257ba44e8d..4b365c16661b12c26ecec72c1ab54f21e6ab4e0d 100644 (file)
 #include "common/bug-on.h"
 #include "common/log.h"
 
-#define BORDER_WIDTH (1)
+#define BORDER_WIDTH (2)
 
-struct wlr_box deco_max_extents(struct view *view)
+struct border deco_max_extents(struct view *view)
 {
-       struct wlr_box box = {
-               .x = view->x - BORDER_WIDTH,
-               .y = view->y - rc.title_height - BORDER_WIDTH,
-               .width = view->w + 2 * BORDER_WIDTH,
-               .height = view->h + rc.title_height + 2 * BORDER_WIDTH,
+       struct border border = {
+               .top = rc.title_height + BORDER_WIDTH,
+               .bottom = BORDER_WIDTH,
+               .left = BORDER_WIDTH,
+               .right = BORDER_WIDTH,
        };
-       return box;
+       return border;
 }
 
 struct wlr_box deco_box(struct view *view, enum deco_part deco_part)
index 19e8e5d65df295c750579b56bd6a4c50689a104b..268e8951fa244029cf33d964d11903e1ed897f67 100644 (file)
@@ -153,11 +153,8 @@ static bool _view_at(struct view *view, double lx, double ly,
                        view->xdg_surface, view_sx, view_sy, &_sx, &_sy);
                break;
        case LAB_XWAYLAND_VIEW:
-               if (!view->xwayland_surface->surface)
-                       return false;
-               _surface =
-                       wlr_surface_surface_at(view->xwayland_surface->surface,
-                                              view_sx, view_sy, &_sx, &_sy);
+               _surface = wlr_surface_surface_at(view->surface, view_sx,
+                                                 view_sy, &_sx, &_sy);
                break;
        }
 
index c702e4c92c5621e54fb8ca2a282a5e98d22815b9..bad7690fcbe61106391f4d0f0c25d140788bce86 100644 (file)
@@ -14,6 +14,9 @@ void interactive_begin(struct view *view, enum cursor_mode mode, uint32_t edges)
        /* Remember view and cursor positions at start of move/resize */
        server->grab_x = server->cursor->x;
        server->grab_y = server->cursor->y;
-       server->grab_box = view_geometry(view);
+       struct wlr_box box = {
+               .x = view->x, .y = view->y, .width = view->w, .height = view->h
+       };
+       memcpy(&server->grab_box, &box, sizeof(struct wlr_box));
        server->resize_edges = edges;
 }
index 44cf15e1486d93507018afb6a6e418aa0fb1b447..3cd37f84cc95d1e6b898966a5f43a9f57bd183db 100644 (file)
@@ -53,14 +53,10 @@ static void render_cycle_box(struct output *output)
        }
        return;
 render_it:
-       if ((view->type == LAB_XWAYLAND_VIEW) || !rc.client_side_decorations) {
-               box = deco_max_extents(view);
-       } else {
-               box.x = view->x;
-               box.y = view->y;
-               box.width = view->w;
-               box.height = view->h;
-       }
+       box.x = view->x - view->margin.left;
+       box.y = view->y - view->margin.top;
+       box.width = view->w + view->margin.left + view->margin.right;
+       box.height = view->h + view->margin.top + view->margin.bottom;
        struct draw_data dd = {
                .renderer = view->server->renderer,
                .transform_matrix = output->wlr_output->transform_matrix,
index d47a07b3180808a703a1c8726c2bc4e4c1f53696..ee7a4dcef78a66b6a2ffc8261471b72986d7cad8 100644 (file)
@@ -1,70 +1,13 @@
 #include "labwc.h"
 #include "common/bug-on.h"
 
-void view_init_position(struct view *view)
-{
-       /* If surface already has a 'desired' position, don't touch it */
-       if (view->x || view->y)
-               return;
-
-       /* Do not touch xwayland surfaces like menus and apps like dmenu */
-       if (view->type == LAB_XWAYLAND_VIEW && !view->show_server_side_deco)
-               return;
-
-       struct wlr_box box;
-       if (view->type == LAB_XDG_SHELL_VIEW && !view->show_server_side_deco)
-               /*
-                * We're here either because rc.xml says yes to CSD or
-                * because the XDG shell won't allow CSD to be turned off
-                */
-               wlr_xdg_surface_get_geometry(view->xdg_surface, &box);
-       else
-               box = deco_max_extents(view);
-       view->x -= box.x;
-       view->y -= box.y;
-       if (view->type != LAB_XWAYLAND_VIEW)
-               return;
-       wlr_xwayland_surface_configure(view->xwayland_surface, view->x, view->y,
-                                      view->xwayland_surface->width,
-                                      view->xwayland_surface->height);
-}
-
-struct wlr_box view_get_surface_geometry(struct view *view)
-{
-       struct wlr_box box = { 0 };
-       switch (view->type) {
-       case LAB_XDG_SHELL_VIEW:
-               wlr_xdg_surface_get_geometry(view->xdg_surface, &box);
-               break;
-       case LAB_XWAYLAND_VIEW:
-               box.width = view->w;
-               box.height = view->h;
-               break;
-       }
-       return box;
-}
-
-/* Get geometry relative to screen */
-struct wlr_box view_geometry(struct view *view)
-{
-       struct wlr_box b = view_get_surface_geometry(view);
-       /* Add XDG view invisible border if it exists */
-       b.width += 2 * b.x;
-       b.height += 2 * b.y;
-       /* Make co-ordinates relative to screen */
-       b.x = view->x;
-       b.y = view->y;
-       return b;
-}
-
 void view_resize(struct view *view, struct wlr_box geo)
 {
-       struct wlr_box border = view_get_surface_geometry(view);
        struct wlr_box box = {
                .x = view->x,
                .y = view->y,
-               .width = geo.width - 2 * border.x,
-               .height = geo.height - 2 * border.y,
+               .width = geo.width,
+               .height = geo.height,
        };
        view->impl->configure(view, box);
 }
index df9c71d9fba01cb27289db097479d424ea963b38..595613de57fc9b9b33e9fec2a2c6c5655908732c 100644 (file)
--- a/src/xdg.c
+++ b/src/xdg.c
@@ -129,18 +129,41 @@ static void xdg_toplevel_view_close(struct view *view)
        wlr_xdg_toplevel_send_close(view->xdg_surface);
 }
 
+static struct border xdg_shell_border(struct view *view)
+{
+       struct wlr_box box;
+       wlr_xdg_surface_get_geometry(view->xdg_surface, &box);
+       struct border border = {
+               .top = -box.y,
+               .bottom = -box.y,
+               .left = -box.x,
+               .right = -box.x,
+       };
+       return border;
+}
+
 static void xdg_toplevel_view_map(struct view *view)
 {
        view->mapped = true;
        view->surface = view->xdg_surface->surface;
        if (!view->been_mapped) {
                view->show_server_side_deco = has_ssd(view);
-               view_init_position(view);
+               if (view->show_server_side_deco) {
+                       view->margin = deco_max_extents(view);
+               } else {
+                       view->margin = xdg_shell_border(view);
+                       view->xdg_grab_offset = -view->margin.left;
+               }
+               /* align to edge of screen */
+               view->x += view->margin.left;
+               view->y += view->margin.top;
        }
        view->been_mapped = true;
+
        wl_signal_add(&view->xdg_surface->surface->events.commit,
                      &view->commit);
        view->commit.notify = handle_commit;
+
        desktop_focus_view(view);
 }
 
index ae10e26d141e90609723807b72b9ee01341fd289..c40976b406f142705593cfd4246c039202353646 100644 (file)
@@ -55,12 +55,10 @@ static void _close(struct view *view)
        wlr_xwayland_surface_close(view->xwayland_surface);
 }
 
-static bool want_ssd(struct view *view)
+static bool want_deco(struct view *view)
 {
-       if (view->xwayland_surface->decorations !=
-           WLR_XWAYLAND_SURFACE_DECORATIONS_ALL)
-               return false;
-       return true;
+       return view->xwayland_surface->decorations ==
+              WLR_XWAYLAND_SURFACE_DECORATIONS_ALL;
 }
 
 static void map(struct view *view)
@@ -68,12 +66,20 @@ static void map(struct view *view)
        view->mapped = true;
        view->x = view->xwayland_surface->x;
        view->y = view->xwayland_surface->y;
+       view->w = view->xwayland_surface->width;
+       view->h = view->xwayland_surface->height;
        view->surface = view->xwayland_surface->surface;
-       if (!view->been_mapped) {
-               view->show_server_side_deco = want_ssd(view);
-               view_init_position(view);
-       }
-       view->been_mapped = true;
+       view->show_server_side_deco = want_deco(view);
+
+       view->margin = deco_max_extents(view);
+
+       /* ensure we're inside screen */
+       view->x += view->margin.left;
+       view->y += view->margin.top;
+       struct wlr_box box = {
+               .x = view->x, .y = view->y, .width = view->w, .height = view->h
+       };
+       view->impl->configure(view, box);
 
        /* Add commit here, as xwayland map/unmap can change the wlr_surface */
        wl_signal_add(&view->xwayland_surface->surface->events.commit,