diff --git a/include/layout.h b/include/layout.h new file mode 100644 index 0000000..f4c4445 --- /dev/null +++ b/include/layout.h @@ -0,0 +1,5 @@ +#pragma once + +#include "types.h" + +void layout_arrange(struct absinthe_output *output); diff --git a/include/types.h b/include/types.h index 65f2246..1cdea36 100644 --- a/include/types.h +++ b/include/types.h @@ -16,7 +16,7 @@ #include #include -// Configuration, later will be moved +// Configuration, will be moved later #define ABSINTHE_CURSOR_MOD WLR_MODIFIER_ALT #define ABSINTHE_CURSOR_MOVE_BUTTON BTN_LEFT @@ -27,6 +27,13 @@ static const float focused_border_color[4] = {0.88, 0.18, 0.18, 1.0}; static const float unfocused_border_color[4] = {0.18, 0.18, 0.18, 1.0}; +#define ABSINTHE_MAIN_TOPLEVEL_WIDTH 0.5 + +#define ABSINTHE_OUTPUT_GAP 10 +#define ABSINTHE_LAYOUT_GAP 10 + +// Configuration end + enum absinthe_cursor_mode { ABSINTHE_CURSOR_PASSTHROUGH, ABSINTHE_CURSOR_MOVE, @@ -40,6 +47,23 @@ enum absinthe_cursor_resize_corner { ABSINTHE_CURSOR_RESIZE_CORNER_BOTTOM_RIGHT, }; +enum absinthe_toplevel_type { + ABSINTHE_TOPLEVEL_XDG_SHELL, + ABSINTHE_TOPLEVEL_LAYER_SHELL, + ABSINTHE_TOPLEVEL_X11, +}; + +enum absinthe_layers { + ABSINTHE_LAYER_BACKGROUND, + ABSINTHE_LAYER_TILE, + ABSINTHE_LAYER_FLOAT, + ABSINTHE_LAYER_FULLSCREEN, + ABSINTHE_LAYER_POPUP, + ABSINTHE_LAYER_OVERLAY, + ABSINTHE_LAYER_LOCK, + ABSINTHE_LAYERS_COUNT, +}; + struct absinthe_output; struct absinthe_server { @@ -71,14 +95,15 @@ struct absinthe_server { struct wl_listener pointer_focus_change; struct wl_listener request_set_selection; struct wl_list keyboards; + enum absinthe_cursor_mode cursor_mode; struct wlr_box grabbed_geometry; uint32_t grab_x, grab_y; enum absinthe_cursor_resize_corner cursor_resize_corner; struct wl_list toplevels; - struct absinthe_toplevel *focused_toplevel; struct wl_list focus_stack; + struct absinthe_toplevel *focused_toplevel; struct absinthe_output *focused_output; struct wl_list outputs; @@ -107,12 +132,15 @@ struct absinthe_toplevel { struct absinthe_output *output; struct wlr_scene_tree *scene_tree; struct wlr_scene_tree *scene_surface; + int32_t border_width; struct wlr_scene_rect *border[4]; bool fullscreen; bool performing_resize; + struct wlr_box geometry; struct wlr_box prev_geometry; + struct wlr_xdg_toplevel *xdg_toplevel; struct wl_listener map; struct wl_listener unmap; diff --git a/src/layout.c b/src/layout.c new file mode 100644 index 0000000..3497940 --- /dev/null +++ b/src/layout.c @@ -0,0 +1,61 @@ +#include "types.h" + +void layout_arrange(struct absinthe_output *output) +{ + if (!output) + return; + + struct absinthe_toplevel *toplevel; + size_t toplevels_count = 0; + wl_list_for_each(toplevel, &output->server->toplevels, link) { + if (toplevel->output == output) + toplevels_count++; + } + + + if (toplevels_count < 1) + return; + + int32_t bw = ABSINTHE_WINDOW_BORDER_WIDTH; + int32_t og = ABSINTHE_OUTPUT_GAP; + + if (toplevels_count == 1) { + wl_list_for_each(toplevel, &output->server->toplevels, link) { + if (toplevel->output == output) + break; + } + + wlr_xdg_toplevel_set_size(toplevel->xdg_toplevel, + output->geometry.width - 2 * bw - 2 * og, + output->geometry.height - 2 * bw - 2 * og); + toplevel->geometry.x = output->geometry.x + og; + toplevel->geometry.y = output->geometry.y + og; + return; + } + + int32_t w, h; + int32_t lg = ABSINTHE_LAYOUT_GAP; + int32_t mw = ABSINTHE_MAIN_TOPLEVEL_WIDTH * (output->geometry.width - 2 * og); + int32_t ty = og; + size_t i = 0; + wl_list_for_each(toplevel, &output->server->toplevels, link) { + if (toplevel->output != output) + continue; + + if (i == 0) { + h = output->geometry.height - 2 * bw - 2 * og; + wlr_xdg_toplevel_set_size(toplevel->xdg_toplevel, mw, h); + toplevel->geometry.x = output->geometry.x + og; + toplevel->geometry.y = output->geometry.y + og; + } else { + w = output->geometry.width - mw - 2 * bw - 2 * lg - 2 * og; + h = (output->geometry.height - ty - og) / (toplevels_count - i) - 2 * bw; + wlr_xdg_toplevel_set_size(toplevel->xdg_toplevel, w, h); + toplevel->geometry.x = output->geometry.x + mw + lg + og; + toplevel->geometry.y = output->geometry.y + ty; + ty += h + 2 * bw + lg; + } + + i++; + } +} diff --git a/src/server.c b/src/server.c index 2b9eb26..b76e245 100644 --- a/src/server.c +++ b/src/server.c @@ -172,7 +172,7 @@ void server_cursor_button(struct wl_listener *listener, void *data) int32_t lx, ly; wlr_scene_node_coords(&toplevel->scene_tree->node, &lx, &ly); server->grabbed_geometry.x = lx; - server->grabbed_geometry.y = ly; + server->grabbed_geometry.y = ly; server->grabbed_geometry.width = toplevel->geometry.width; server->grabbed_geometry.height = toplevel->geometry.height; diff --git a/src/xdg-toplevel.c b/src/xdg-toplevel.c index da411b9..af54c42 100644 --- a/src/xdg-toplevel.c +++ b/src/xdg-toplevel.c @@ -5,8 +5,10 @@ #include #include "types.h" -#include "xdg-decoration.h" #include "absinthe-toplevel.h" +#include "layout.h" +#include "output.h" +#include "xdg-decoration.h" void xdg_toplevel_commit(struct wl_listener *listener, void *data) { @@ -18,7 +20,7 @@ void xdg_toplevel_commit(struct wl_listener *listener, void *data) xdg_decoration_request_mode(&toplevel->decoration_request_mode, toplevel->decoration); // Let toplevel set preferred size - wlr_xdg_toplevel_set_size(toplevel->xdg_toplevel, 0, 0); + // wlr_xdg_toplevel_set_size(toplevel->xdg_toplevel, 0, 0); } else { // Check for size because we did't set it on initial commit int32_t bw = toplevel->border_width; @@ -42,11 +44,14 @@ void xdg_toplevel_map(struct wl_listener *listener, void *data) toplevel->border_width = ABSINTHE_WINDOW_BORDER_WIDTH; + update_focused_output(toplevel->server); toplevel->output = toplevel->server->focused_output; toplevel->fullscreen = false; wl_list_insert(&toplevel->server->toplevels, &toplevel->link); wl_list_insert(&toplevel->server->focus_stack, &toplevel->flink); + + layout_arrange(toplevel->output); } void xdg_toplevel_unmap(struct wl_listener *listener, void *data) @@ -57,6 +62,8 @@ void xdg_toplevel_unmap(struct wl_listener *listener, void *data) wl_list_remove(&toplevel->link); wl_list_remove(&toplevel->flink); + + layout_arrange(toplevel->output); } void xdg_toplevel_destroy(struct wl_listener *listener, void *data)