aboutsummaryrefslogtreecommitdiff
path: root/sway/desktop
diff options
context:
space:
mode:
Diffstat (limited to 'sway/desktop')
-rw-r--r--sway/desktop/output.c35
-rw-r--r--sway/desktop/wl_shell.c35
-rw-r--r--sway/desktop/xdg_shell_v6.c32
-rw-r--r--sway/desktop/xwayland.c26
4 files changed, 119 insertions, 9 deletions
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index 1b3143d0..1ab9324d 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -22,6 +22,7 @@
#include "sway/tree/container.h"
#include "sway/tree/layout.h"
#include "sway/tree/view.h"
+#include "sway/tree/workspace.h"
struct sway_container *output_by_name(const char *name) {
for (int i = 0; i < root_container.children->length; ++i) {
@@ -228,7 +229,11 @@ static void render_container_iterator(struct sway_container *con,
static void render_container(struct sway_output *output,
struct sway_container *con) {
- container_descendants(con, C_VIEW, render_container_iterator, output);
+ if (con->type == C_VIEW) { // Happens if a view is fullscreened
+ render_container_iterator(con, output);
+ } else {
+ container_descendants(con, C_VIEW, render_container_iterator, output);
+ }
}
static struct sway_container *output_get_active_workspace(
@@ -270,18 +275,24 @@ static void render_output(struct sway_output *output, struct timespec *when,
wlr_output_transformed_resolution(wlr_output, &width, &height);
pixman_region32_union_rect(damage, damage, 0, 0, width, height);
- float clear_color[] = {0.25f, 0.25f, 0.25f, 1.0f};
- wlr_renderer_clear(renderer, clear_color);
+ struct sway_container *workspace = output_get_active_workspace(output);
- render_layer(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]);
- render_layer(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]);
+ if (workspace->sway_workspace->fullscreen) {
+ float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f};
+ wlr_renderer_clear(renderer, clear_color);
+ render_container(output, workspace->sway_workspace->fullscreen->swayc);
+ } else {
+ float clear_color[] = {0.25f, 0.25f, 0.25f, 1.0f};
+ wlr_renderer_clear(renderer, clear_color);
- struct sway_container *workspace = output_get_active_workspace(output);
- render_container(output, workspace);
+ render_layer(output,
+ &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]);
+ render_layer(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]);
- render_unmanaged(output, &root_container.sway_root->xwayland_unmanaged);
+ render_container(output, workspace);
- // TODO: consider revising this when fullscreen windows are supported
+ render_unmanaged(output, &root_container.sway_root->xwayland_unmanaged);
+ }
render_layer(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]);
render_layer(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]);
@@ -462,6 +473,12 @@ void output_damage_view(struct sway_output *output, struct sway_view *view,
return;
}
+ struct sway_container *workspace = container_parent(view->swayc,
+ C_WORKSPACE);
+ if (workspace->sway_workspace->fullscreen && !view->is_fullscreen) {
+ return;
+ }
+
struct damage_data data = {
.output = output,
.whole = whole,
diff --git a/sway/desktop/wl_shell.c b/sway/desktop/wl_shell.c
index b63c220c..2d666d95 100644
--- a/sway/desktop/wl_shell.c
+++ b/sway/desktop/wl_shell.c
@@ -61,14 +61,21 @@ static void destroy(struct sway_view *view) {
}
wl_list_remove(&wl_shell_view->commit.link);
wl_list_remove(&wl_shell_view->destroy.link);
+ wl_list_remove(&wl_shell_view->request_fullscreen.link);
+ wl_list_remove(&wl_shell_view->set_state.link);
free(wl_shell_view);
}
+static void set_fullscreen(struct sway_view *view, bool fullscreen) {
+ // TODO
+}
+
static const struct sway_view_impl view_impl = {
.get_prop = get_prop,
.configure = configure,
.close = _close,
.destroy = destroy,
+ .set_fullscreen = set_fullscreen,
};
static void handle_commit(struct wl_listener *listener, void *data) {
@@ -88,6 +95,23 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
view_destroy(&wl_shell_view->view);
}
+static void handle_request_fullscreen(struct wl_listener *listener, void *data) {
+ struct sway_wl_shell_view *wl_shell_view =
+ wl_container_of(listener, wl_shell_view, request_fullscreen);
+ view_set_fullscreen(&wl_shell_view->view, true);
+}
+
+static void handle_set_state(struct wl_listener *listener, void *data) {
+ struct sway_wl_shell_view *wl_shell_view =
+ wl_container_of(listener, wl_shell_view, set_state);
+ struct sway_view *view = &wl_shell_view->view;
+ struct wlr_wl_shell_surface *surface = view->wlr_wl_shell_surface;
+ if (view->is_fullscreen &&
+ surface->state != WLR_WL_SHELL_SURFACE_STATE_FULLSCREEN) {
+ view_set_fullscreen(view, false);
+ }
+}
+
void handle_wl_shell_surface(struct wl_listener *listener, void *data) {
struct sway_server *server = wl_container_of(listener, server,
wl_shell_surface);
@@ -127,5 +151,16 @@ void handle_wl_shell_surface(struct wl_listener *listener, void *data) {
wl_shell_view->destroy.notify = handle_destroy;
wl_signal_add(&shell_surface->events.destroy, &wl_shell_view->destroy);
+ wl_shell_view->request_fullscreen.notify = handle_request_fullscreen;
+ wl_signal_add(&shell_surface->events.request_fullscreen,
+ &wl_shell_view->request_fullscreen);
+
+ wl_shell_view->set_state.notify = handle_set_state;
+ wl_signal_add(&shell_surface->events.set_state, &wl_shell_view->set_state);
+
view_map(&wl_shell_view->view, shell_surface->surface);
+
+ if (shell_surface->state == WLR_WL_SHELL_SURFACE_STATE_FULLSCREEN) {
+ view_set_fullscreen(&wl_shell_view->view, true);
+ }
}
diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c
index e4703040..87e34666 100644
--- a/sway/desktop/xdg_shell_v6.c
+++ b/sway/desktop/xdg_shell_v6.c
@@ -118,6 +118,14 @@ static void set_activated(struct sway_view *view, bool activated) {
}
}
+static void set_fullscreen(struct sway_view *view, bool fullscreen) {
+ if (xdg_shell_v6_view_from_view(view) == NULL) {
+ return;
+ }
+ struct wlr_xdg_surface_v6 *surface = view->wlr_xdg_surface_v6;
+ wlr_xdg_toplevel_v6_set_fullscreen(surface, fullscreen);
+}
+
static void for_each_surface(struct sway_view *view,
wlr_surface_iterator_func_t iterator, void *user_data) {
if (xdg_shell_v6_view_from_view(view) == NULL) {
@@ -146,6 +154,7 @@ static void destroy(struct sway_view *view) {
wl_list_remove(&xdg_shell_v6_view->destroy.link);
wl_list_remove(&xdg_shell_v6_view->map.link);
wl_list_remove(&xdg_shell_v6_view->unmap.link);
+ wl_list_remove(&xdg_shell_v6_view->request_fullscreen.link);
free(xdg_shell_v6_view);
}
@@ -153,6 +162,7 @@ static const struct sway_view_impl view_impl = {
.get_prop = get_prop,
.configure = configure,
.set_activated = set_activated,
+ .set_fullscreen = set_fullscreen,
.for_each_surface = for_each_surface,
.close = _close,
.destroy = destroy,
@@ -202,6 +212,10 @@ static void handle_map(struct wl_listener *listener, void *data) {
xdg_shell_v6_view->new_popup.notify = handle_new_popup;
wl_signal_add(&xdg_surface->events.new_popup,
&xdg_shell_v6_view->new_popup);
+
+ if (xdg_surface->toplevel->client_pending.fullscreen) {
+ view_set_fullscreen(view, true);
+ }
}
static void handle_destroy(struct wl_listener *listener, void *data) {
@@ -210,6 +224,20 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
view_destroy(&xdg_shell_v6_view->view);
}
+static void handle_request_fullscreen(struct wl_listener *listener, void *data) {
+ struct sway_xdg_shell_v6_view *xdg_shell_v6_view =
+ wl_container_of(listener, xdg_shell_v6_view, request_fullscreen);
+ struct wlr_xdg_toplevel_v6_set_fullscreen_event *e = data;
+
+ if (!sway_assert(xdg_shell_v6_view->view.wlr_xdg_surface_v6->role == WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL,
+ "xdg_shell_v6 requested fullscreen of surface with role %i",
+ xdg_shell_v6_view->view.wlr_xdg_surface_v6->role)) {
+ return;
+ }
+
+ view_set_fullscreen(&xdg_shell_v6_view->view, e->fullscreen);
+}
+
void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) {
struct sway_server *server = wl_container_of(listener, server,
xdg_shell_v6_surface);
@@ -246,4 +274,8 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) {
xdg_shell_v6_view->destroy.notify = handle_destroy;
wl_signal_add(&xdg_surface->events.destroy, &xdg_shell_v6_view->destroy);
+
+ xdg_shell_v6_view->request_fullscreen.notify = handle_request_fullscreen;
+ wl_signal_add(&xdg_surface->toplevel->events.request_fullscreen,
+ &xdg_shell_v6_view->request_fullscreen);
}
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c
index 69166af0..46eaa84c 100644
--- a/sway/desktop/xwayland.c
+++ b/sway/desktop/xwayland.c
@@ -179,6 +179,14 @@ static void set_activated(struct sway_view *view, bool activated) {
wlr_xwayland_surface_activate(surface, activated);
}
+static void set_fullscreen(struct sway_view *view, bool fullscreen) {
+ if (xwayland_view_from_view(view) == NULL) {
+ return;
+ }
+ struct wlr_xwayland_surface *surface = view->wlr_xwayland_surface;
+ wlr_xwayland_surface_set_fullscreen(surface, fullscreen);
+}
+
static void _close(struct sway_view *view) {
if (xwayland_view_from_view(view) == NULL) {
return;
@@ -193,6 +201,7 @@ static void destroy(struct sway_view *view) {
}
wl_list_remove(&xwayland_view->destroy.link);
wl_list_remove(&xwayland_view->request_configure.link);
+ wl_list_remove(&xwayland_view->request_fullscreen.link);
wl_list_remove(&xwayland_view->map.link);
wl_list_remove(&xwayland_view->unmap.link);
free(xwayland_view);
@@ -202,6 +211,7 @@ static const struct sway_view_impl view_impl = {
.get_prop = get_prop,
.configure = configure,
.set_activated = set_activated,
+ .set_fullscreen = set_fullscreen,
.close = _close,
.destroy = destroy,
};
@@ -238,6 +248,10 @@ static void handle_map(struct wl_listener *listener, void *data) {
// Put it back into the tree
wlr_xwayland_surface_set_maximized(xsurface, true);
view_map(view, xsurface->surface);
+
+ if (xsurface->fullscreen) {
+ view_set_fullscreen(view, true);
+ }
}
static void handle_destroy(struct wl_listener *listener, void *data) {
@@ -263,6 +277,14 @@ static void handle_request_configure(struct wl_listener *listener, void *data) {
ev->width, ev->height);
}
+static void handle_request_fullscreen(struct wl_listener *listener, void *data) {
+ struct sway_xwayland_view *xwayland_view =
+ wl_container_of(listener, xwayland_view, request_fullscreen);
+ struct sway_view *view = &xwayland_view->view;
+ struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
+ view_set_fullscreen(view, xsurface->fullscreen);
+}
+
void handle_xwayland_surface(struct wl_listener *listener, void *data) {
struct sway_server *server = wl_container_of(listener, server,
xwayland_surface);
@@ -298,6 +320,10 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) {
&xwayland_view->request_configure);
xwayland_view->request_configure.notify = handle_request_configure;
+ wl_signal_add(&xsurface->events.request_fullscreen,
+ &xwayland_view->request_fullscreen);
+ xwayland_view->request_fullscreen.notify = handle_request_fullscreen;
+
wl_signal_add(&xsurface->events.unmap, &xwayland_view->unmap);
xwayland_view->unmap.notify = handle_unmap;