sway

i3-compatible Wayland compositor
git clone https://git.awy.one/sway
Log | Files | Refs | README | LICENSE

commit 9da295c11f90dcfbf254ccf23b9124c87ccd8ddf
parent 09e11dabb203513c038b723e50de2fd836e7edb3
Author: Alexander Orzechowski <alex@ozal.ski>
Date:   Wed, 22 Nov 2023 15:11:12 -0500

scene_graph: Implement toplevel clipping

Diffstat:
Minclude/sway/tree/view.h | 2+-
Msway/desktop/transaction.c | 2+-
Msway/desktop/xdg_shell.c | 4++--
Msway/desktop/xwayland.c | 4++--
Msway/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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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) {