diff --git a/GNUmakefile b/GNUmakefile new file mode 100644 index 0000000..9fae4c0 --- /dev/null +++ b/GNUmakefile @@ -0,0 +1,33 @@ +include config.mk + +TARGET = absinthe + +SRC_FILES != find src/ -type f +OBJ_FILES = $(SRC_FILES:src/%.c=build/%.o) + +all: proto $(TARGET) + +xdg-shell-protocol.h: + $(WAYLAND_SCANNER) server-header $(WAYLAND_PROTOCOLS)/stable/xdg-shell/xdg-shell.xml xdg-shell-protocol.h + +wlr-layer-shell-unstable-v1-protocol.h: + $(WAYLAND_SCANNER) server-header ./protocols/wlr-layer-shell-unstable-v1.xml wlr-layer-shell-unstable-v1-protocol.h + +proto: xdg-shell-protocol.h wlr-layer-shell-unstable-v1-protocol.h + +build/%.o: src/%.c + @mkdir -p build + $(CC) $(CFLAGS) -o $@ -c $< + +$(TARGET): $(OBJ_FILES) + $(CC) -o absinthe $(OBJ_FILES) $(LDFLAGS) + +clean: + rm -rf build/ + rm absinthe + rm xdg-shell-protocol.h + rm wlr-layer-shell-unstable-v1-protocol.h + +format: + find src/ -type f | xargs $(CLANG_FORMAT) -i + find include/ -type f | xargs $(CLANG_FORMAT) -i diff --git a/Makefile b/Makefile index bbad683..5cb71ce 100644 --- a/Makefile +++ b/Makefile @@ -5,17 +5,23 @@ TARGET = absinthe SRC_FILES != find src/ -type f OBJ_FILES = $(SRC_FILES:src/%.c=build/%.o) -all: $(TARGET) +all: proto $(TARGET) -proto: +xdg-shell-protocol.h: $(WAYLAND_SCANNER) server-header $(WAYLAND_PROTOCOLS)/stable/xdg-shell/xdg-shell.xml xdg-shell-protocol.h + +wlr-layer-shell-unstable-v1-protocol.h: $(WAYLAND_SCANNER) server-header ./protocols/wlr-layer-shell-unstable-v1.xml wlr-layer-shell-unstable-v1-protocol.h -$(OBJ_FILES): - mkdir -p $(@D) - $(CC) $(CFLAGS) -o $@ -c $(@:build/%.o=src/%.c) +proto: xdg-shell-protocol.h wlr-layer-shell-unstable-v1-protocol.h -$(TARGET): proto $(OBJ_FILES) +.for _src in ${SRC_FILES} +build/${_src:T:R}.o: ${_src} + @mkdir -p build + $(CC) $(CFLAGS) -c ${.ALLSRC} -o ${.TARGET} +.endfor + +$(TARGET): $(OBJ_FILES) $(CC) -o absinthe $(OBJ_FILES) $(LDFLAGS) clean: diff --git a/config.mk b/config.mk index c966052..caa9125 100644 --- a/config.mk +++ b/config.mk @@ -4,7 +4,7 @@ XLIBS = xcb xcb-icccm # tools PKG_CONFIG ?= pkg-config CC ?= clang -CLANG_FORMAT=clang-format22 +CLANG_FORMAT ?= clang-format22 PKGS = wayland-server xkbcommon libinput $(XLIBS) diff --git a/include/config.h b/include/config.h index db663dc..43b0a1b 100644 --- a/include/config.h +++ b/include/config.h @@ -1,14 +1,16 @@ #ifndef __CONFIG_H_ #define __CONFIG_H_ -#include "callbacks.h" +#include "keybinds.h" #include "types.h" #define CURSOR_MOD WLR_MODIFIER_ALT #define CURSOR_MOVE_BUTTON BTN_LEFT #define CURSOR_RESIZE_BUTTON BTN_RIGHT -#define TOPLEVEL_BW 1 +#define TOPLEVEL_BW 2 + +static const float bgcolor[4] = { 0.0, 0.0, 0.0, 1.0 }; static const float focused_bc[4] = { 0.0, 0.0, 1.0, 1.0 }; static const float urgent_bc[4] = { 1.0, 0.0, 0.0, 1.0 }; @@ -17,8 +19,8 @@ static const float unfocused_bc[4] = { 0.28, 0.28, 0.28, 1.0 }; #define MSTACK_SIZE 1 #define MSTACK_WIDTH 0.5 -#define OUTPUT_GAP 0 -#define LAYOUT_GAP 0 +#define OUTPUT_GAP 10 +#define LAYOUT_GAP 5 #define ALT WLR_MODIFIER_ALT #define CTRL WLR_MODIFIER_CTRL diff --git a/include/callbacks.h b/include/keybinds.h similarity index 100% rename from include/callbacks.h rename to include/keybinds.h diff --git a/include/layer-surface.h b/include/layer-surface.h index 076c7c2..7aca707 100644 --- a/include/layer-surface.h +++ b/include/layer-surface.h @@ -6,6 +6,7 @@ void layer_surface_map(struct wl_listener *listener, void *data); void layer_surface_unmap(struct wl_listener *listener, void *data); void layer_surface_commit(struct wl_listener *listener, void *data); +void layer_surface_new_popup(struct wl_listener *listener, void *data); void layer_surface_destroy(struct wl_listener *listener, void *data); #endif diff --git a/include/toplevel.h b/include/toplevel.h index ce356d4..fbede7b 100644 --- a/include/toplevel.h +++ b/include/toplevel.h @@ -13,6 +13,7 @@ void toplevel_get_geom(absn_toplevel *toplevel); void toplevel_set_pos(absn_toplevel *toplevel, int32_t x, int32_t y); void toplevel_set_size(absn_toplevel *toplevel, int32_t width, int32_t height); void toplevel_set_geom(absn_toplevel *toplevel, struct wlr_box *geom); +void toplevel_set_floating(absn_toplevel *toplevel, bool floating); void toplevel_set_fullscreen(absn_toplevel *toplevel, bool fullscreen); void toplevel_set_border_color(absn_toplevel *toplevel, const float color[4]); diff --git a/include/types.h b/include/types.h index d126440..548a3d0 100644 --- a/include/types.h +++ b/include/types.h @@ -55,6 +55,7 @@ enum { enum { TOPLEVEL_XDG, TOPLEVEL_X11, + LAYER_SURFACE, }; /* layers for wlr layer shell */ @@ -63,11 +64,30 @@ enum { LAYER_BOTTOM, LAYER_TILE, LAYER_FLOAT, + LAYER_FULLSCREEN, + LAYER_TOP, + LAYER_OVERLAY, + LAYERS_COUNT, +}; + +static const int layermap[] = { + LAYER_BACKGROUND, + LAYER_BOTTOM, LAYER_TOP, LAYER_FULLSCREEN, - LAYER_OVERLAY, - LAYER_LOCK, - LAYERS_COUNT, +}; + +enum { + LAYOUT_FLOAT, + LAYOUT_TILE, + LAYOUT_TILELEFT, + LAYOUT_TILETOP, + LAYOUT_TILEBOTTOM, + LAYOUT_SPIRAL, + LAYOUT_DWINDLE, + LAYOUT_MAX, + LAYOUT_VGRID, + LAYOUT_HGRID, }; typedef struct absn_output absn_output; @@ -81,6 +101,7 @@ typedef struct { struct wlr_compositor *compositor; struct wlr_scene *scene; struct wlr_scene_output_layout *scene_layout; + struct wlr_scene_rect *bg; struct wlr_xdg_shell *xdg_shell; struct wl_listener new_xdg_toplevel; @@ -88,7 +109,7 @@ typedef struct { struct wlr_xdg_decoration_manager_v1 *xdg_deco_mgr; struct wl_listener new_xdg_deco; - struct wlr_layer_shell *layer_shell; + struct wlr_layer_shell_v1 *layer_shell; struct wl_listener new_layer_surface; struct wlr_scene_tree *layers[LAYERS_COUNT]; @@ -132,6 +153,11 @@ typedef struct { struct wl_listener mgr_test; } absn_server; +typedef struct { + int layout; + uint32_t id; +} absn_tag; + struct absn_output { struct wl_list link; absn_server *server; @@ -146,20 +172,28 @@ struct absn_output { float mstack_width; int mstack_count; + + absn_tag *tags; + uint32_t active_tags; + + struct wl_list layers[4]; }; typedef struct { + struct wl_list link; + absn_server *server; absn_output *output; + int type; /* LAYER_SURFACE */ struct wlr_scene_tree *scene_tree; - struct wlr_scene_tree *scene_layer; - struct wlr_scene_tree *popups; + struct wlr_scene_layer_surface_v1 *scene_layer; struct wlr_layer_surface_v1 *wlr; struct wl_listener map; struct wl_listener unmap; struct wl_listener commit; + struct wl_listener new_popup; struct wl_listener destroy; } absn_layer_surface; @@ -176,7 +210,8 @@ struct absn_toplevel { struct wlr_scene_rect *border[4]; struct wlr_xdg_toplevel_decoration_v1 *deco; - bool tiled, floating, fullscreen, maximized; + bool floating; + bool fullscreen; bool urgent; uint32_t resizing; diff --git a/src/absinthe.c b/src/absinthe.c index 02461c4..f358d5c 100644 --- a/src/absinthe.c +++ b/src/absinthe.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -17,6 +18,7 @@ #include #include +#include "config.h" #include "output.h" #include "seat.h" #include "server.h" @@ -56,6 +58,7 @@ setup(absn_server *server) wlr_linux_dmabuf_v1_create_with_renderer(server->display, 5, server->renderer)); } + server->bg = wlr_scene_rect_create(&server->scene->tree, 0, 0, bgcolor); server->allocator = wlr_allocator_autocreate(server->backend, server->renderer); @@ -87,6 +90,10 @@ setup(absn_server *server) LISTEN(server->new_xdg_deco, new_xdg_decoration, server->xdg_deco_mgr->events.new_toplevel_decoration); + /* toplevels lists */ + wl_list_init(&server->toplevels); + wl_list_init(&server->focus_stack); + /* output */ wl_list_init(&server->outputs); LISTEN(server->new_output, new_output, @@ -104,10 +111,6 @@ setup(absn_server *server) server->scene_layout = wlr_scene_attach_output_layout(server->scene, server->output_layout); - /* toplevels lists */ - wl_list_init(&server->toplevels); - wl_list_init(&server->focus_stack); - /* xdg_shell */ server->xdg_shell = wlr_xdg_shell_create(server->display, 6); LISTEN(server->new_xdg_toplevel, new_xdg_toplevel, @@ -143,6 +146,10 @@ setup(absn_server *server) LISTEN(server->request_set_selection, request_cursor, server->seat->events.request_set_selection); + server->layer_shell = wlr_layer_shell_v1_create(server->display, 1); + for (int i = 0; i < LAYERS_COUNT; ++i) + server->layers[i] = wlr_scene_tree_create(&server->scene->tree); + unsetenv("DISPLAY"); #ifdef XWAYLAND if ((server->xwayland = wlr_xwayland_create(server->display, @@ -203,6 +210,8 @@ cleanup(absn_server *server) wl_list_remove(&server->new_output.link); + wl_list_remove(&server->new_layer_surface.link); + wlr_scene_node_destroy(&server->scene->tree.node); wlr_xcursor_manager_destroy(server->cursor_mgr); wlr_cursor_destroy(server->cursor); diff --git a/src/cursor.c b/src/cursor.c index f928cfd..47fe003 100644 --- a/src/cursor.c +++ b/src/cursor.c @@ -34,10 +34,8 @@ process_cursor_move(absn_server *server) new_y = server->cursor->y - server->grab_y + server->grab_geom.y; toplevel_set_pos(toplevel, new_x, new_y); - if (toplevel->tiled) { - toplevel->tiled = false; - layout_arrange(toplevel->output); - } + if (!toplevel->floating) + toplevel_set_floating(toplevel, true); } static void @@ -86,10 +84,8 @@ process_cursor_resize(absn_server *server) if (toplevel->fullscreen) toplevel_set_fullscreen(toplevel, false); - if (toplevel->tiled) { - toplevel->tiled = false; - layout_arrange(toplevel->output); - } + if (!toplevel->floating) + toplevel_set_floating(toplevel, true); int32_t new_x, new_y, new_width, new_height; new_x = server->grab_geom.x; diff --git a/src/callbacks.c b/src/keybinds.c similarity index 70% rename from src/callbacks.c rename to src/keybinds.c index e9e5091..2e0c54c 100644 --- a/src/callbacks.c +++ b/src/keybinds.c @@ -25,13 +25,15 @@ kill_focus(absn_server *server, const absn_arg *arg) if (!server->focused_output) return; + absn_toplevel *focus = server->focused_toplevel; + #ifdef XWAYLAND - if (server->focused_toplevel->type == TOPLEVEL_X11) { - wlr_xwayland_surface_close(server->focused_toplevel->xw); + if (focus->type == TOPLEVEL_X11) { + wlr_xwayland_surface_close(focus->xw); } else #endif { - wlr_xdg_toplevel_send_close(server->focused_toplevel->xdg); + wlr_xdg_toplevel_send_close(focus->xdg); } } @@ -39,7 +41,7 @@ void cycle_focus(absn_server *server, const absn_arg *arg) { absn_toplevel *toplevel = focus_get_topmost(server); - if (!toplevel) + if (!toplevel || toplevel->fullscreen) return; absn_toplevel *new_focus; @@ -67,8 +69,9 @@ toggle_fullscreen(absn_server *server, const absn_arg *arg) UNUSED(arg); if (!server->focused_toplevel) return; - toplevel_set_fullscreen(server->focused_toplevel, - !server->focused_toplevel->fullscreen); + + absn_toplevel *focus = server->focused_toplevel; + toplevel_set_fullscreen(focus, !focus->fullscreen); } void @@ -77,12 +80,14 @@ increase_master_width(absn_server *server, const absn_arg *arg) if (!server->focused_output) return; - if (server->focused_output->mstack_width + arg->f >= 1.0 || - server->focused_output->mstack_width + arg->f <= 0.0) + absn_output *focus = server->focused_output; + + if (focus->mstack_width + arg->f >= 1.0 || + focus->mstack_width + arg->f <= 0.0) return; - server->focused_output->mstack_width += arg->f; - layout_arrange(server->focused_output); + focus->mstack_width += arg->f; + layout_arrange(focus); } void @@ -91,11 +96,13 @@ increase_master_count(absn_server *server, const absn_arg *arg) if (!server->focused_output) return; - if (server->focused_output->mstack_count + arg->i <= 0) + absn_output *focus = server->focused_output; + + if (focus->mstack_count + arg->i <= 0) return; - server->focused_output->mstack_count += arg->i; - layout_arrange(server->focused_output); + focus->mstack_count += arg->i; + layout_arrange(focus); } noreturn void diff --git a/src/layer-surface.c b/src/layer-surface.c index d3ca7ca..c2b6595 100644 --- a/src/layer-surface.c +++ b/src/layer-surface.c @@ -22,8 +22,26 @@ layer_surface_commit(struct wl_listener *listener, void *data) } void -layer_surface_destroy(struct wl_listener *listener, void *data) +layer_surface_new_popup(struct wl_listener *listener, void *data) { UNUSED(listener); UNUSED(data); } + +void +layer_surface_destroy(struct wl_listener *listener, void *data) +{ + UNUSED(data); + absn_layer_surface *layer_surface = wl_container_of(listener, + layer_surface, destroy); + + wl_list_remove(&layer_surface->link); + wl_list_remove(&layer_surface->map.link); + wl_list_remove(&layer_surface->unmap.link); + wl_list_remove(&layer_surface->commit.link); + wl_list_remove(&layer_surface->new_popup.link); + wl_list_remove(&layer_surface->destroy.link); + wlr_scene_node_destroy(&layer_surface->scene_tree->node); + + free(layer_surface); +} diff --git a/src/layout.c b/src/layout.c index 9565e47..291eece 100644 --- a/src/layout.c +++ b/src/layout.c @@ -12,7 +12,8 @@ layout_arrange(struct absn_output *output) int toplevels_count = 0; wl_list_for_each(toplevel, &output->server->toplevels, link) { - if (toplevel->output == output && toplevel->tiled) { + if (toplevel->output == output && !toplevel->floating && + !toplevel->fullscreen) { toplevels_count++; wlr_scene_node_set_enabled(&toplevel->scene_tree->node, true); @@ -28,7 +29,8 @@ layout_arrange(struct absn_output *output) if (toplevels_count == 1) { wl_list_for_each(toplevel, &output->server->toplevels, link) { - if (toplevel->output == output && toplevel->tiled) + if (toplevel->output == output && !toplevel->floating && + !toplevel->fullscreen) break; } new_geom.x = output->geom.x + og, @@ -41,31 +43,43 @@ layout_arrange(struct absn_output *output) } int32_t lg = LAYOUT_GAP; + int32_t total_lg; + int32_t main_stack_width = (toplevels_count <= output->mstack_count) ? output->geom.width - 2 * og : output->mstack_width * (output->geom.width - 2 * og); int32_t w = output->geom.width - main_stack_width - 2 * og - lg; + + int32_t pure_h; int32_t h; + int32_t cur_h; + int32_t r; + int32_t dy = og; int i = 0; if (toplevels_count <= output->mstack_count) { + total_lg = (toplevels_count - 1) * lg; + pure_h = output->geom.height - 2 * og - total_lg; + h = pure_h / toplevels_count; + r = pure_h % toplevels_count; + wl_list_for_each(toplevel, &output->server->toplevels, link) { - if (toplevel->output != output || !toplevel->tiled) + if (toplevel->output != output || toplevel->floating || + toplevel->fullscreen) continue; - h = (output->geom.height - dy - og) / - (toplevels_count - i); + cur_h = h + (i < r ? 1 : 0); new_geom.x = output->geom.x + og; new_geom.y = output->geom.y + dy; new_geom.width = main_stack_width; - new_geom.height = h; + new_geom.height = cur_h; toplevel_set_geom(toplevel, &new_geom); - dy += h + lg; + dy += cur_h + lg; i++; } @@ -74,27 +88,38 @@ layout_arrange(struct absn_output *output) wl_list_for_each(toplevel, &output->server->toplevels, link) { - if (toplevel->output != output || !toplevel->tiled) + if (toplevel->output != output || toplevel->floating || + toplevel->fullscreen) continue; if (i < output->mstack_count) { - h = (output->geom.height - dy - og) / - (output->mstack_count - i); + total_lg = (output->mstack_count - 1) * lg; + pure_h = output->geom.height - 2 * og - total_lg; + h = pure_h / output->mstack_count; + r = pure_h % output->mstack_count; + + cur_h = h + (i < r ? 1 : 0); new_geom.x = output->geom.x + og; new_geom.y = output->geom.y + dy; new_geom.width = main_stack_width; - new_geom.height = h; + new_geom.height = cur_h; toplevel_set_geom(toplevel, &new_geom); - dy += h + lg; + dy += cur_h + lg; } else { if (i == output->mstack_count) dy = og; - h = (output->geom.height - dy - og) / - (toplevels_count - i); + int32_t stack_count = toplevels_count - + output->mstack_count; + total_lg = (stack_count - 1) * lg; + pure_h = output->geom.height - 2 * og - total_lg; + h = pure_h / stack_count; + r = pure_h % stack_count; + + cur_h = h + (i - output->mstack_count < r ? 1 : 0); new_geom.x = output->geom.x + main_stack_width + lg + og; @@ -104,7 +129,7 @@ layout_arrange(struct absn_output *output) toplevel_set_geom(toplevel, &new_geom); - dy += h + lg; + dy += cur_h + lg; } i++; diff --git a/src/output.c b/src/output.c index 0d5fb5a..cd17353 100644 --- a/src/output.c +++ b/src/output.c @@ -12,6 +12,7 @@ output_frame(struct wl_listener *listener, void *data) UNUSED(data); struct timespec now; absn_output *output = wl_container_of(listener, output, frame); + struct wlr_scene *scene = output->server->scene; struct wlr_scene_output *scene_output = wlr_scene_get_scene_output(scene, output->wlr); @@ -86,6 +87,14 @@ output_layout_change(struct wl_listener *listener, void *data) toplevel->output->wlr); } + struct wlr_box layout_geom; + wlr_output_layout_get_box(server->output_layout, NULL, &layout_geom); + + wlr_scene_node_set_position(&server->bg->node, layout_geom.x, + layout_geom.y); + wlr_scene_rect_set_size(server->bg, layout_geom.width, + layout_geom.height); + wl_list_for_each(output, &server->outputs, link) { if (!output->wlr->enabled) diff --git a/src/server.c b/src/server.c index 27ab7b8..199934e 100644 --- a/src/server.c +++ b/src/server.c @@ -53,6 +53,9 @@ new_output(struct wl_listener *listener, void *data) wl_list_insert(&server->outputs, &output->link); + for (int i = 0; i < 4; ++i) + wl_list_init(&output->layers[i]); + struct wlr_output_layout_output *l_layout = wlr_output_layout_add_auto(server->output_layout, output->wlr); struct wlr_scene_output *scene_output = @@ -142,21 +145,39 @@ new_layer_surface(struct wl_listener *listener, void *data) { absn_server *server = wl_container_of(listener, server, new_layer_surface); - struct wlr_layer_surface_v1 *layer_surface = data; + struct wlr_layer_surface_v1 *surface = data; - if (!layer_surface->output && - !(layer_surface->output = server->focused_output->wlr)) { - wlr_layer_surface_v1_destroy(layer_surface); + if (!surface->output && + !(surface->output = server->focused_output->wlr)) { + wlr_layer_surface_v1_destroy(surface); return; } - absn_layer_surface *layer = calloc(1, sizeof(*layer)); - LISTEN(layer->commit, layer_surface_commit, - layer_surface->surface->events.commit); - LISTEN(layer->unmap, layer_surface_unmap, - layer_surface->surface->events.unmap); - LISTEN(layer->destroy, layer_surface_destroy, - layer_surface->surface->events.destroy); + absn_layer_surface *layer_surface = calloc(1, sizeof(*layer_surface)); + + LISTEN(layer_surface->map, layer_surface_map, + surface->surface->events.map); + LISTEN(layer_surface->unmap, layer_surface_unmap, + surface->surface->events.unmap); + LISTEN(layer_surface->commit, layer_surface_commit, + surface->surface->events.commit); + LISTEN(layer_surface->new_popup, layer_surface_new_popup, + surface->events.new_popup); + LISTEN(layer_surface->destroy, layer_surface_destroy, + surface->surface->events.destroy); + + layer_surface->wlr = surface; + layer_surface->output = surface->output->data; + + struct wlr_scene_tree *scene_layer = + server->layers[layermap[surface->pending.layer]]; + layer_surface->scene_layer = + wlr_scene_layer_surface_v1_create(scene_layer, surface); + layer_surface->scene_tree = layer_surface->scene_layer->tree; + + wl_list_insert(&layer_surface->output->layers[surface->pending.layer], + &layer_surface->link); + wlr_surface_send_enter(surface->surface, surface->output); } #ifdef XWAYLAND diff --git a/src/toplevel-handlers.c b/src/toplevel-handlers.c index 79a7bf2..eba8e1d 100644 --- a/src/toplevel-handlers.c +++ b/src/toplevel-handlers.c @@ -12,15 +12,14 @@ toplevel_map(struct wl_listener *listener, void *data) { UNUSED(data); absn_toplevel *toplevel = wl_container_of(listener, toplevel, map); + absn_server *server = toplevel->server; toplevel->scene_tree = wlr_scene_tree_create( - &toplevel->server->scene->tree); + server->layers[LAYER_TILE]); toplevel->scene_tree->node.data = toplevel; wlr_scene_node_set_enabled(&toplevel->scene_tree->node, toplevel_is_unmanaged(toplevel)); - toplevel->tiled = true; - if (toplevel->type != TOPLEVEL_X11 && wl_resource_get_version(toplevel->xdg->resource) >= XDG_TOPLEVEL_STATE_TILED_RIGHT_SINCE_VERSION) { diff --git a/src/toplevel.c b/src/toplevel.c index cc97d7e..52db2ea 100644 --- a/src/toplevel.c +++ b/src/toplevel.c @@ -2,6 +2,7 @@ #include #include "config.h" +#include "layout.h" #include "toplevel.h" #include "types.h" #include "xdg-shell-protocol.h" @@ -162,6 +163,24 @@ toplevel_set_geom(absn_toplevel *toplevel, struct wlr_box *geom) toplevel_set_size(toplevel, geom->width, geom->height); } +void +toplevel_set_floating(absn_toplevel *toplevel, bool floating) +{ + if (!toplevel || toplevel->floating == floating) + return; + + toplevel->floating = floating; + + if (floating) + wlr_scene_node_reparent(&toplevel->scene_tree->node, + toplevel->server->layers[LAYER_FLOAT]); + else + wlr_scene_node_reparent(&toplevel->scene_tree->node, + toplevel->server->layers[LAYER_TILE]); + + layout_arrange(toplevel->output); +} + void toplevel_set_fullscreen(absn_toplevel *toplevel, bool fullscreen) { @@ -176,10 +195,19 @@ toplevel_set_fullscreen(absn_toplevel *toplevel, bool fullscreen) toplevel->prev_geom = toplevel->geom; toplevel->bw = 0; toplevel_set_geom(toplevel, &output->geom); + + wlr_scene_node_reparent(&toplevel->scene_tree->node, + toplevel->server->layers[LAYER_FULLSCREEN]); } else { toplevel->bw = toplevel_is_unmanaged(toplevel) ? 0 : TOPLEVEL_BW; toplevel_set_geom(toplevel, &toplevel->prev_geom); + if (toplevel->floating) + wlr_scene_node_reparent(&toplevel->scene_tree->node, + toplevel->server->layers[LAYER_FLOAT]); + else + wlr_scene_node_reparent(&toplevel->scene_tree->node, + toplevel->server->layers[LAYER_TILE]); } toplevel_update_borders_geom(toplevel);