]> git.mdlowis.com Git - proto/labwc.git/commitdiff
Support fullscreen mode (issue #53)
authorJohan Malm <jgm323@gmail.com>
Mon, 23 Aug 2021 21:05:30 +0000 (22:05 +0100)
committerJohan Malm <jgm323@gmail.com>
Mon, 23 Aug 2021 21:05:30 +0000 (22:05 +0100)
include/labwc.h
src/foreign.c
src/output.c
src/view.c
src/xdg.c
src/xwayland.c

index 367838c889b4a079169396926468fe6e2fae5bce..68b15ad9bec37bb60f98e9665db39b7d76430c3b 100644 (file)
@@ -160,6 +160,8 @@ struct view_impl {
        const char *(*get_string_prop)(struct view *view, const char *prop);
        void (*map)(struct view *view);
        void (*move)(struct view *view, double x, double y);
+       void (*set_fullscreen)(struct view *view, bool fullscreen,
+               struct wlr_output *wlr_output);
        void (*unmap)(struct view *view);
        void (*maximize)(struct view *view, bool maximize);
 };
@@ -189,6 +191,7 @@ struct view {
        bool been_mapped;
        bool minimized;
        bool maximized;
+       struct wlr_output *fullscreen;
 
        /* geometry of the wlr_surface contained within the view */
        int x, y, w, h;
@@ -229,6 +232,7 @@ struct view {
        struct wlr_foreign_toplevel_handle_v1 *toplevel_handle;
        struct wl_listener toplevel_handle_request_maximize;
        struct wl_listener toplevel_handle_request_minimize;
+       struct wl_listener toplevel_handle_request_fullscreen;
 
        struct wl_listener map;
        struct wl_listener unmap;
@@ -238,6 +242,7 @@ struct view {
        struct wl_listener request_resize;
        struct wl_listener request_configure;   /* xwayland only */
        struct wl_listener request_maximize;
+       struct wl_listener request_fullscreen;
        struct wl_listener set_title;
        struct wl_listener new_popup;           /* xdg-shell only */
        struct wl_listener new_subsurface;      /* xdg-shell only */
@@ -305,6 +310,8 @@ void view_minimize(struct view *view, bool minimized);
 struct wlr_output *view_wlr_output(struct view *view);
 void view_center(struct view *view);
 void view_maximize(struct view *view, bool maximize);
+void view_set_fullscreen(struct view *view, bool fullscreen,
+       struct wlr_output *wlr_output);
 void view_toggle_maximize(struct view *view);
 void view_for_each_surface(struct view *view,
        wlr_surface_iterator_func_t iterator, void *user_data);
index 46d7448602f9244f191a426f1e5dfc099e9f99c7..73644944cad8ac38c3579e4eb124e3c0aed361c0 100644 (file)
@@ -18,6 +18,15 @@ handle_toplevel_handle_request_maximize(struct wl_listener *listener, void *data
        view_maximize(view, event->maximized);
 }
 
+static void
+handle_toplevel_handle_request_fullscreen(struct wl_listener *listener, void *data)
+{
+       struct view *view = wl_container_of(listener, view,
+               toplevel_handle_request_fullscreen);
+       struct wlr_foreign_toplevel_handle_v1_fullscreen_event *event = data;
+       view_set_fullscreen(view, event->fullscreen, NULL);
+}
+
 void
 foreign_toplevel_handle_create(struct view *view)
 {
@@ -47,5 +56,9 @@ foreign_toplevel_handle_create(struct view *view)
                handle_toplevel_handle_request_minimize;
        wl_signal_add(&view->toplevel_handle->events.request_minimize,
                &view->toplevel_handle_request_minimize);
-       // TODO: hook up remaining signals
+       view->toplevel_handle_request_fullscreen.notify =
+               handle_toplevel_handle_request_fullscreen;
+       wl_signal_add(&view->toplevel_handle->events.request_fullscreen,
+               &view->toplevel_handle_request_fullscreen);
+       // TODO: hook up remaining signals (close)
 }
index cf8d1507eb57ff12d767d56093cd32aa1bac7a00..34cba5deba9bd5051d69455f18ec328d3dd708f9 100644 (file)
@@ -494,7 +494,7 @@ static void
 render_deco(struct view *view, struct output *output,
                pixman_region32_t *output_damage)
 {
-       if (!view->ssd.enabled) {
+       if (!view->ssd.enabled || view->fullscreen) {
                return;
        }
 
index 8af7777805b411995b5617b7143334b701b2afe6..81228a7d3d80b4c9f6e5a61e20cee4b69c9061f4 100644 (file)
@@ -107,6 +107,48 @@ view_toggle_maximize(struct view *view)
        view_maximize(view, !view->maximized);
 }
 
+void
+view_set_fullscreen(struct view *view, bool fullscreen,
+               struct wlr_output *wlr_output)
+{
+       if (fullscreen == (view->fullscreen != NULL)) {
+               return;
+       }
+       if (view->impl->set_fullscreen) {
+               view->impl->set_fullscreen(view, fullscreen, wlr_output);
+       }
+       if (view->toplevel_handle) {
+               wlr_foreign_toplevel_handle_v1_set_fullscreen(
+                       view->toplevel_handle, fullscreen);
+       }
+       if (fullscreen) {
+               view->unmaximized_geometry.x = view->x;
+               view->unmaximized_geometry.y = view->y;
+               view->unmaximized_geometry.width = view->w;
+               view->unmaximized_geometry.height = view->h;
+
+               if (!wlr_output) {
+                       wlr_output = view_wlr_output(view);
+               }
+               view->fullscreen = wlr_output;
+               struct output *output =
+                       output_from_wlr_output(view->server, wlr_output);
+               struct wlr_box box = { 0 };
+               wlr_output_effective_resolution(wlr_output, &box.width,
+                                               &box.height);
+               double ox = 0, oy = 0;
+               wlr_output_layout_output_coords(output->server->output_layout,
+                       output->wlr_output, &ox, &oy);
+               box.x -= ox;
+               box.y -= oy;
+               view_move_resize(view, box);
+       } else {
+               /* restore to normal */
+               view_move_resize(view, view->unmaximized_geometry);
+               view->fullscreen = false;
+       }
+}
+
 void
 view_for_each_surface(struct view *view, wlr_surface_iterator_func_t iterator,
                void *user_data)
index 8b33350789960f00ecf31248a0e2c1fb2633934e..71a4df4457221bfe57cee929dc7d67ef5283d095 100644 (file)
--- a/src/xdg.c
+++ b/src/xdg.c
@@ -139,6 +139,14 @@ handle_request_maximize(struct wl_listener *listener, void *data)
 
 }
 
+static void
+handle_request_fullscreen(struct wl_listener *listener, void *data)
+{
+       struct view *view = wl_container_of(listener, view, request_fullscreen);
+       struct wlr_xdg_toplevel_set_fullscreen_event *e = data;
+       view_set_fullscreen(view, e->fullscreen, e->output);
+}
+
 static void
 handle_set_title(struct wl_listener *listener, void *data)
 {
@@ -213,6 +221,12 @@ xdg_toplevel_view_maximize(struct view *view, bool maximized)
        wlr_xdg_toplevel_set_maximized(view->xdg_surface, maximized);
 }
 
+static void
+xdg_toplevel_view_set_fullscreen(struct view *view, bool fullscreen)
+{
+       wlr_xdg_toplevel_set_fullscreen(view->xdg_surface, fullscreen);
+}
+
 static bool
 istopmost(struct view *view)
 {
@@ -336,6 +350,7 @@ static const struct view_impl xdg_toplevel_view_impl = {
        .get_string_prop = xdg_toplevel_view_get_string_prop,
        .map = xdg_toplevel_view_map,
        .move = xdg_toplevel_view_move,
+       .set_fullscreen = xdg_toplevel_view_set_fullscreen,
        .unmap = xdg_toplevel_view_unmap,
        .maximize = xdg_toplevel_view_maximize,
 };
@@ -375,6 +390,9 @@ xdg_surface_new(struct wl_listener *listener, void *data)
        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);
+       view->request_fullscreen.notify = handle_request_fullscreen;
+       wl_signal_add(&toplevel->events.request_fullscreen,
+               &view->request_fullscreen);
        view->set_title.notify = handle_set_title;
        wl_signal_add(&toplevel->events.set_title, &view->set_title);
 
index ed2f989c05611ad4a9311a4624849217d2af4187..4f3555e8a500a535b980e2818ff846d508997c84 100644 (file)
@@ -53,6 +53,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);
+       wl_list_remove(&view->request_fullscreen.link);
        ssd_destroy(view);
        free(view);
 }
@@ -71,11 +72,18 @@ static void
 handle_request_maximize(struct wl_listener *listener, void *data)
 {
        struct view *view = wl_container_of(listener, view, request_maximize);
-
        assert(view);
        view_toggle_maximize(view);
 }
 
+static void
+handle_request_fullscreen(struct wl_listener *listener, void *data)
+{
+       struct view *view = wl_container_of(listener, view, request_fullscreen);
+       bool fullscreen = view->xwayland_surface->fullscreen;
+       view_set_fullscreen(view, fullscreen, NULL);
+}
+
 static void
 handle_set_title(struct wl_listener *listener, void *data)
 {
@@ -217,6 +225,13 @@ maximize(struct view *view, bool maximized)
        wlr_xwayland_surface_set_maximized(view->xwayland_surface, maximized);
 }
 
+static void
+set_fullscreen(struct view *view, bool fullscreen,
+               struct wlr_output *wlr_output)
+{
+       wlr_xwayland_surface_set_fullscreen(view->xwayland_surface, fullscreen);
+}
+
 static const struct view_impl xwl_view_impl = {
        .configure = configure,
        .close = _close,
@@ -224,6 +239,7 @@ static const struct view_impl xwl_view_impl = {
        .get_string_prop = get_string_prop,
        .map = map,
        .move = move,
+       .set_fullscreen = set_fullscreen,
        .unmap = unmap,
        .maximize = maximize
 };
@@ -263,6 +279,9 @@ xwayland_surface_new(struct wl_listener *listener, void *data)
                      &view->request_configure);
        view->request_maximize.notify = handle_request_maximize;
        wl_signal_add(&xsurface->events.request_maximize, &view->request_maximize);
+       view->request_fullscreen.notify = handle_request_fullscreen;
+       wl_signal_add(&xsurface->events.request_fullscreen,
+               &view->request_fullscreen);
        view->set_title.notify = handle_set_title;
        wl_signal_add(&xsurface->events.set_title, &view->set_title);