diff --git a/include/types.h b/include/types.h index 18474de..941a0be 100644 --- a/include/types.h +++ b/include/types.h @@ -22,10 +22,7 @@ #define ABSINTHE_CURSOR_MOVE_BUTTON BTN_LEFT #define ABSINTHE_CURSOR_RESIZE_BUTTON BTN_RIGHT -#define ABSINTHE_BORDER_WIDTH 1 - -#define ABSINTHE_WINDOW_MIN_WIDTH 200 -#define ABSINTHE_WINDOW_MIN_HEIGHT 200 +#define ABSINTHE_WINDOW_BORDER_WIDTH 2 static const float bordercolor[4] = {0.88, 0.18, 0.18, 1.0}; diff --git a/src/absinthe-toplevel.c b/src/absinthe-toplevel.c index 893cfc6..09b9c2f 100644 --- a/src/absinthe-toplevel.c +++ b/src/absinthe-toplevel.c @@ -32,14 +32,11 @@ void absinthe_toplevel_set_position(struct absinthe_toplevel *toplevel, int32_t void absinthe_toplevel_set_size(struct absinthe_toplevel *toplevel, int32_t width, int32_t height) { - int bw = ABSINTHE_BORDER_WIDTH; + int bw = ABSINTHE_WINDOW_BORDER_WIDTH; if (width < 0 || height < 0) return; - toplevel->geometry.width = width; - toplevel->geometry.height = height; - wlr_xdg_toplevel_set_size(toplevel->xdg_toplevel, width, height); wlr_xdg_surface_schedule_configure(toplevel->xdg_toplevel->base); } @@ -53,7 +50,7 @@ void absinthe_toplevel_set_border_color(struct absinthe_toplevel *toplevel, cons void absinthe_toplevel_update_borders_geometry(struct absinthe_toplevel *toplevel) { - int bw = ABSINTHE_BORDER_WIDTH; + int bw = ABSINTHE_WINDOW_BORDER_WIDTH; if (toplevel->geometry.width - 2 * bw < 0 || toplevel->geometry.height - 2 * bw < 0) return; diff --git a/src/cursor.c b/src/cursor.c index 8adf095..d8f7899 100644 --- a/src/cursor.c +++ b/src/cursor.c @@ -7,7 +7,11 @@ void reset_cursor_mode(struct absinthe_server *server) { server->cursor_mode = ABSINTHE_CURSOR_PASSTHROUGH; - server->grabbed_toplevel = NULL; + + if (server->grabbed_toplevel) { + wlr_xdg_toplevel_set_resizing(server->grabbed_toplevel->xdg_toplevel, false); + server->grabbed_toplevel = NULL; + } } static void process_cursor_move(struct absinthe_server *server) { @@ -24,16 +28,46 @@ static void process_cursor_move(struct absinthe_server *server) { absinthe_toplevel_set_position(toplevel, new_x, new_y); } +static void apply_resize(struct absinthe_toplevel *toplevel, struct wlr_box *new_geometry) +{ + int32_t bw = ABSINTHE_WINDOW_BORDER_WIDTH; + + int32_t min_width = toplevel->xdg_toplevel->current.min_width; + int32_t min_height = toplevel->xdg_toplevel->current.min_height; + + int32_t max_width = toplevel->xdg_toplevel->current.max_width; + int32_t max_height = toplevel->xdg_toplevel->current.max_height; + + if (max_width == 0) + max_width = 10000; + + if (max_height == 0) + max_height = 10000; + + if (new_geometry->width - 2 * bw >= min_width && new_geometry->width - 2 * bw <= max_width) { + toplevel->geometry.x = new_geometry->x; + toplevel->geometry.width = new_geometry->width; + toplevel->performing_resize = true; + } + + if (new_geometry->height - 2 * bw >= min_height && new_geometry->height - 2 * bw <= max_height) { + toplevel->geometry.y = new_geometry->y; + toplevel->geometry.height = new_geometry->height; + toplevel->performing_resize = true; + } + + if (toplevel->performing_resize) + absinthe_toplevel_set_size(toplevel, toplevel->geometry.width - 2 * bw, toplevel->geometry.height - 2 * bw); +} + static void process_cursor_resize(struct absinthe_server *server) { struct absinthe_toplevel *toplevel = server->grabbed_toplevel; - if (toplevel->performing_resize == true) - return; - if (!toplevel) return; - int bw = ABSINTHE_BORDER_WIDTH; + if (toplevel->performing_resize == true) + return; int32_t new_x, new_y, new_width, new_height; new_x = server->grabbed_geometry.x; @@ -73,12 +107,14 @@ static void process_cursor_resize(struct absinthe_server *server) { } if (new_width > 0 && new_height > 0) { - toplevel->geometry.x = new_x; - toplevel->geometry.y = new_y; + struct wlr_box new_geometry = { + .x = new_x, + .y = new_y, + .width = new_width, + .height = new_height, + }; - absinthe_toplevel_set_size(toplevel, new_width, new_height); - - toplevel->performing_resize = true; + apply_resize(server->grabbed_toplevel, &new_geometry); } } diff --git a/src/output.c b/src/output.c index fee4b7b..f43ecba 100644 --- a/src/output.c +++ b/src/output.c @@ -1,5 +1,7 @@ #include +#include + #include "types.h" void output_frame(struct wl_listener *listener, void *data) diff --git a/src/server.c b/src/server.c index ea2fb36..58faf6a 100644 --- a/src/server.c +++ b/src/server.c @@ -48,6 +48,7 @@ void server_new_output(struct wl_listener *listener, void *data) struct wlr_output_layout_output *l_layout = wlr_output_layout_add_auto(server->output_layout, output->wlr_output); struct wlr_scene_output *scene_output = wlr_scene_output_create(server->scene, wlr_output); wlr_scene_output_layout_add_output(server->scene_layout, l_layout, scene_output); + wlr_output_layout_get_box(server->output_layout, output->wlr_output, &output->geometry); } void server_new_xdg_toplevel(struct wl_listener *listener, void *data) @@ -166,8 +167,8 @@ void server_cursor_button(struct wl_listener *listener, void *data) wlr_scene_node_coords(&toplevel->scene_tree->node, &lx, &ly); server->grabbed_geometry.x = lx; server->grabbed_geometry.y = ly; - server->grabbed_geometry.width = toplevel->xdg_toplevel->base->geometry.width; - server->grabbed_geometry.height = toplevel->xdg_toplevel->base->geometry.height; + server->grabbed_geometry.width = toplevel->geometry.width; + server->grabbed_geometry.height = toplevel->geometry.height; server->grabbed_toplevel = toplevel; int width = toplevel->xdg_toplevel->base->geometry.width; @@ -182,6 +183,8 @@ void server_cursor_button(struct wl_listener *listener, void *data) } else { server->cursor_resize_corner = ABSINTHE_CURSOR_RESIZE_CORNER_TOP_LEFT; } + + wlr_xdg_toplevel_set_resizing(toplevel->xdg_toplevel, true); } } diff --git a/src/xdg-decoration.c b/src/xdg-decoration.c index 577ead6..556e15d 100644 --- a/src/xdg-decoration.c +++ b/src/xdg-decoration.c @@ -5,19 +5,14 @@ void xdg_decoration_request_mode(struct wl_listener *listener, void *data) { struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, decoration_request_mode); - if (toplevel->xdg_toplevel->base->initialized) { + if (toplevel->xdg_toplevel->base->initialized) wlr_xdg_toplevel_decoration_v1_set_mode(toplevel->decoration, WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); - } } void xdg_decoration_destroy(struct wl_listener *listener, void *data) { struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, decoration_destroy); - for (int i = 0; i < 4; ++i) { - wlr_scene_node_destroy(&toplevel->border[i]->node); - } - wl_list_remove(&toplevel->decoration_request_mode.link); wl_list_remove(&toplevel->decoration_destroy.link); } diff --git a/src/xdg-toplevel.c b/src/xdg-toplevel.c index da0de04..39afee8 100644 --- a/src/xdg-toplevel.c +++ b/src/xdg-toplevel.c @@ -12,17 +12,17 @@ void xdg_toplevel_commit(struct wl_listener *listener, void *data) struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, commit); if (toplevel->xdg_toplevel->base->initial_commit) { - int32_t cw = toplevel->xdg_toplevel->current.min_width; - int32_t ch = toplevel->xdg_toplevel->current.min_height; - - int32_t w = MAX(cw, ABSINTHE_WINDOW_MIN_WIDTH); - int32_t h = MAX(ch, ABSINTHE_WINDOW_MIN_HEIGHT); - - absinthe_toplevel_set_size(toplevel, w, h); + wlr_xdg_toplevel_set_size(toplevel->xdg_toplevel, 0, 0); if (toplevel->decoration) xdg_decoration_request_mode(&toplevel->decoration_request_mode, toplevel->decoration); } else { + if (toplevel->geometry.width == 0 || toplevel->geometry.height == 0) { + int bw = ABSINTHE_WINDOW_BORDER_WIDTH; + toplevel->geometry.width = toplevel->xdg_toplevel->base->geometry.width + 2 * bw; + toplevel->geometry.height = toplevel->xdg_toplevel->base->geometry.height + 2 * bw; + } + absinthe_toplevel_set_position(toplevel, toplevel->geometry.x, toplevel->geometry.y); absinthe_toplevel_update_borders_geometry(toplevel); toplevel->performing_resize = false; @@ -48,6 +48,8 @@ void xdg_toplevel_unmap(struct wl_listener *listener, void *data) { struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, unmap); + wlr_scene_node_destroy(&toplevel->scene_tree->node); + wl_list_remove(&toplevel->link); }