From 9da295c11f90dcfbf254ccf23b9124c87ccd8ddf Mon Sep 17 00:00:00 2001 From: Alexander Orzechowski Date: Wed, 22 Nov 2023 15:11:12 -0500 Subject: [PATCH] scene_graph: Implement toplevel clipping --- include/sway/tree/view.h | 2 +- sway/desktop/transaction.c | 2 +- sway/desktop/xdg_shell.c | 4 ++-- sway/desktop/xwayland.c | 4 ++-- sway/tree/view.c | 27 +++++++++++++++++++++------ 5 files changed, 27 insertions(+), 12 deletions(-) diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h index 80097dd3e..3e5a9bfe3 100644 --- a/include/sway/tree/view.h +++ b/include/sway/tree/view.h @@ -274,7 +274,7 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface, void view_unmap(struct sway_view *view); void view_update_size(struct sway_view *view); -void view_center_surface(struct sway_view *view); +void view_center_and_clip_surface(struct sway_view *view); struct sway_view *view_from_wlr_xdg_surface( struct wlr_xdg_surface *xdg_surface); diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c index 0755c8a00..980e839ee 100644 --- a/sway/desktop/transaction.c +++ b/sway/desktop/transaction.c @@ -248,7 +248,7 @@ static void apply_container_state(struct sway_container *container, // the container. This is important for fullscreen views which // refuse to resize to the size of the output. if (view->surface) { - view_center_surface(view); + view_center_and_clip_surface(view); } } } diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index 48b7b4c7e..7cdd97c83 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c @@ -306,9 +306,9 @@ static void handle_commit(struct wl_listener *listener, void *data) { view->geometry.height); } transaction_commit_dirty_client(); - } else { - view_center_surface(view); } + + view_center_and_clip_surface(view); } if (view->container->node.instruction) { diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index e0c80c074..9f3f4d5f2 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c @@ -436,9 +436,9 @@ static void handle_commit(struct wl_listener *listener, void *data) { if (container_is_floating(view->container)) { view_update_size(view); transaction_commit_dirty_client(); - } else { - view_center_surface(view); } + + view_center_and_clip_surface(view); } if (view->container->node.instruction) { diff --git a/sway/tree/view.c b/sway/tree/view.c index 3bc0855bc..d69841783 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -893,14 +893,29 @@ void view_update_size(struct sway_view *view) { container_set_geometry_from_content(con); } -void view_center_surface(struct sway_view *view) { +void view_center_and_clip_surface(struct sway_view *view) { struct sway_container *con = view->container; - // We always center the current coordinates rather than the next, as the - // geometry immediately affects the currently active rendering. - int x = (int) fmax(0, (con->current.content_width - view->geometry.width) / 2); - int y = (int) fmax(0, (con->current.content_height - view->geometry.height) / 2); - wlr_scene_node_set_position(&view->content_tree->node, x, y); + if (container_is_floating(con)) { + // We always center the current coordinates rather than the next, as the + // geometry immediately affects the currently active rendering. + int x = (int) fmax(0, (con->current.content_width - view->geometry.width) / 2); + int y = (int) fmax(0, (con->current.content_height - view->geometry.height) / 2); + + wlr_scene_node_set_position(&view->content_tree->node, x, y); + } else { + wlr_scene_node_set_position(&view->content_tree->node, 0, 0); + } + + // only make sure to clip the content if there is content to clip + if (!wl_list_empty(&con->view->content_tree->children)) { + wlr_scene_subsurface_tree_set_clip(&con->view->content_tree->node, &(struct wlr_box){ + .x = con->view->geometry.x, + .y = con->view->geometry.y, + .width = con->current.content_width, + .height = con->current.content_height, + }); + } } struct sway_view *view_from_wlr_surface(struct wlr_surface *wlr_surface) {