]> git.mdlowis.com Git - proto/labwc.git/commitdiff
Added basic maximize support for xdg and xwayland
authorAlex Bryan <abryancs@gmail.com>
Sat, 27 Feb 2021 22:10:53 +0000 (17:10 -0500)
committerAlex Bryan <abryancs@gmail.com>
Sat, 27 Feb 2021 22:10:53 +0000 (17:10 -0500)
include/labwc.h
src/cursor.c
src/view.c
src/xdg.c
src/xwayland.c

index 26754a21ec94ba07bd534e17dd1f936f24e8460e..fe6f55495f4f2deb84f59dec4c213001c9a56948 100644 (file)
@@ -162,6 +162,7 @@ struct view_impl {
        void (*map)(struct view *view);
        void (*move)(struct view *view, double x, double y);
        void (*unmap)(struct view *view);
+       void (*maximize)(struct view *view, bool maximize);
 };
 
 struct border {
@@ -188,6 +189,7 @@ struct view {
        bool mapped;
        bool been_mapped;
        bool minimized;
+       bool maximized;
 
        /* geometry of the wlr_surface contained within the view */
        int x, y, w, h;
@@ -217,6 +219,7 @@ struct view {
        struct wl_listener request_move;
        struct wl_listener request_resize;
        struct wl_listener request_configure;
+       struct wl_listener request_maximize;
        struct wl_listener new_popup; /* xdg-shell only */
 };
 
@@ -259,6 +262,7 @@ void view_move_resize(struct view *view, struct wlr_box geo);
 void view_move(struct view *view, double x, double y);
 void view_minimize(struct view *view);
 void view_unminimize(struct view *view);
+void view_maximize(struct view *view, bool maximize);
 void view_for_each_surface(struct view *view,
        wlr_surface_iterator_func_t iterator, void *user_data);
 void view_for_each_popup(struct view *view,
@@ -274,8 +278,8 @@ void desktop_focus_view(struct seat *seat, struct view *view);
 struct view *desktop_cycle_view(struct server *server, struct view *current);
 void desktop_focus_topmost_mapped_view(struct server *server);
 struct view *desktop_view_at(struct server *server, double lx, double ly,
-                            struct wlr_surface **surface, double *sx,
-                            double *sy, int *view_area);
+                           struct wlr_surface **surface, double *sx,
+                           double *sy, int *view_area);
 
 void cursor_init(struct seat *seat);
 
@@ -287,7 +291,7 @@ void seat_focus_surface(struct seat *seat, struct wlr_surface *surface);
 void seat_set_focus_layer(struct seat *seat, struct wlr_layer_surface_v1 *layer);
 
 void interactive_begin(struct view *view, enum input_mode mode,
-                      uint32_t edges);
+                     uint32_t edges);
 
 void output_init(struct server *server);
 void output_damage_surface(struct output *output, struct wlr_surface *surface,
index 899a13b75e3db53a9aebc1f60fe1fe70e061f240..9d1e9b492d88fd6e823e92d9fe8688836f821d05 100644 (file)
@@ -323,6 +323,9 @@ cursor_button(struct wl_listener *listener, void *data)
        case LAB_DECO_PART_TITLE:
                interactive_begin(view, LAB_INPUT_STATE_MOVE, 0);
                break;
+       case LAB_DECO_BUTTON_MAXIMIZE:
+               view_maximize(view, !view->maximized);
+               break;
        }
 }
 
index c1e456bf261975141a783007ec0fb44bcec2f908..9621b2049172a32291cb9d61946c870eff452fcb 100644 (file)
@@ -1,5 +1,7 @@
 #include "labwc.h"
 
+#include <stdio.h>
+#include <assert.h>
 void
 view_move_resize(struct view *view, struct wlr_box geo)
 {
@@ -32,6 +34,71 @@ view_unminimize(struct view *view)
        view->impl->map(view);
 }
 
+void
+view_maximize(struct view *view, bool maximize)
+{
+       if(maximize == true)
+       {
+               struct wlr_output_layout *layout = view->server->output_layout;
+               struct wlr_output* output =
+                       wlr_output_layout_output_at(layout, view->x, view->y);
+               struct wlr_output_layout_output* ol_output =
+                       wlr_output_layout_get(layout, output);
+
+               assert(layout);
+               if(output == NULL)
+               {
+                       die("output NULL w/ x and y of: %d, %d", view->x, view->y);
+               }
+               assert(output);
+               assert(ol_output);
+
+               int x = ol_output->x;
+               int y = ol_output->y;
+               int width = output->width;
+               int height = output->height;
+
+               if(view->server_side_deco)
+               {
+                       struct border border = deco_thickness(view);
+                       x += border.right;
+                       x += border.left;
+                       y += border.top;
+                       y += border.bottom;
+
+                       width -= border.right;
+                       width -= border.left;
+                       height -= border.top;
+                       height -= border.bottom;
+               }
+
+               struct wlr_box box = {
+                       .x = x * output->scale,
+                       .y = y * output->scale,
+                       .width = width * output->scale,
+                       .height = height * output->scale
+               };
+
+               view_move_resize(view, box);
+               view_move(view, box.x * output->scale, box.y * output->scale);
+
+               view->maximized = true;
+       }
+       else
+       {
+               struct wlr_box box = {
+                       .x = 20,
+                       .y = 50,
+                       .width = 640,
+                       .height = 480
+               };
+
+               view_move_resize(view, box);
+               view->maximized = false;
+       }
+       view->impl->maximize(view, maximize);
+}
+
 void
 view_for_each_surface(struct view *view, wlr_surface_iterator_func_t iterator,
                void *user_data)
index 91fb7b2296c0d977cb9e37d8910c5be8369d49ab..e7b6bcf9d5418921f21c47760888a927db2cc49b 100644 (file)
--- a/src/xdg.c
+++ b/src/xdg.c
@@ -230,6 +230,26 @@ handle_request_resize(struct wl_listener *listener, void *data)
        interactive_begin(view, LAB_INPUT_STATE_RESIZE, event->edges);
 }
 
+static void
+handle_request_maximize(struct wl_listener *listener, void *data)
+{
+       /* This event is raised when a client would like to begin an interactive
+        * resize, typically because the user clicked on their client-side
+        * decorations. Note that a more sophisticated compositor should check
+        * the provied serial against a list of button press serials sent to
+        * this
+        * client, to prevent the client from requesting this whenever they want.
+        */
+
+       struct view *view = wl_container_of(listener, view, request_maximize);
+
+       struct wlr_xdg_surface *surface = data;
+       if(view != NULL) {
+               view_maximize(view, surface->toplevel->client_pending.maximized);
+       }
+
+}
+
 static void
 xdg_toplevel_view_configure(struct view *view, struct wlr_box geo)
 {
@@ -279,6 +299,12 @@ xdg_toplevel_view_for_each_surface(struct view *view,
        wlr_xdg_surface_for_each_surface(view->xdg_surface, iterator, data);
 }
 
+static void
+xdg_toplevel_view_maximize(struct view *view, bool maximized)
+{
+       wlr_xdg_toplevel_set_maximized(view->xdg_surface, maximized);
+}
+
 static struct border
 xdg_shell_border(struct view *view)
 {
@@ -345,6 +371,7 @@ static const struct view_impl xdg_toplevel_view_impl = {
        .map = xdg_toplevel_view_map,
        .move = xdg_toplevel_view_move,
        .unmap = xdg_toplevel_view_unmap,
+       .maximize = xdg_toplevel_view_maximize
 };
 
 void
@@ -363,6 +390,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;
+       view->maximized = false;
 
        view->map.notify = handle_map;
        wl_signal_add(&xdg_surface->events.map, &view->map);
@@ -379,6 +407,13 @@ xdg_surface_new(struct wl_listener *listener, void *data)
        wl_signal_add(&toplevel->events.request_move, &view->request_move);
        view->request_resize.notify = handle_request_resize;
        wl_signal_add(&toplevel->events.request_resize, &view->request_resize);
+       view->request_maximize.notify = handle_request_maximize;
+       wl_signal_add(&toplevel->events.request_maximize, &view->request_maximize);
+
+       // hacky workaround to bug where sometimes a window starts maximized and
+       // when we hit the maximize button, labwc crashes. instead we unmaximize
+       // it from the start to avoid this situation
+       view_maximize(view, false);
 
        wl_list_insert(&server->views, &view->link);
 }
index 6697580d58332dc83cf15d489850fcb927a6caa2..2485361ee24df4d708f7a550c90bb9713f257aa8 100644 (file)
@@ -47,6 +47,7 @@ handle_destroy(struct wl_listener *listener, void *data)
        wl_list_remove(&view->unmap.link);
        wl_list_remove(&view->destroy.link);
        wl_list_remove(&view->request_configure.link);
+       wl_list_remove(&view->request_maximize.link);
        free(view);
 }
 
@@ -60,6 +61,16 @@ handle_request_configure(struct wl_listener *listener, void *data)
        damage_all_outputs(view->server);
 }
 
+static void handle_request_maximize(struct wl_listener *listener, void *data)
+{
+       struct view *view = wl_container_of(listener, view, request_maximize);
+
+       if(view != NULL) {
+               view_maximize(view, !view->maximized);
+       }
+
+}
+
 static void
 configure(struct view *view, struct wlr_box geo)
 {
@@ -159,6 +170,12 @@ unmap(struct view *view)
        desktop_focus_topmost_mapped_view(view->server);
 }
 
+static void
+maximize(struct view *view, bool maximized)
+{
+       wlr_xwayland_surface_set_maximized(view->xwayland_surface, maximized);
+}
+
 static const struct view_impl xwl_view_impl = {
        .configure = configure,
        .close = _close,
@@ -166,6 +183,7 @@ static const struct view_impl xwl_view_impl = {
        .map = map,
        .move = move,
        .unmap = unmap,
+       .maximize = maximize
 };
 
 void
@@ -200,6 +218,8 @@ xwayland_surface_new(struct wl_listener *listener, void *data)
        view->request_configure.notify = handle_request_configure;
        wl_signal_add(&xsurface->events.request_configure,
                      &view->request_configure);
+       view->request_maximize.notify = handle_request_maximize;
+       wl_signal_add(&xsurface->events.request_maximize, &view->request_maximize);
 
        wl_list_insert(&view->server->views, &view->link);
 }