From 7e54722940b7c9df08b652ee763d634bb87d5d50 Mon Sep 17 00:00:00 2001 From: rozodru Date: Sun, 20 Jul 2025 08:51:25 -0400 Subject: [PATCH] added in gap feature for windows that can be configured via the config file --- examples/config | 3 +++ keybinding.c | 30 ++++++++++++++++++++++++++++++ keybinding.h | 6 +++++- parse.c | 7 +++++++ server.h | 1 + view.c | 18 +++++++++++++++--- 6 files changed, 61 insertions(+), 4 deletions(-) diff --git a/examples/config b/examples/config index ca1430b..136b63a 100644 --- a/examples/config +++ b/examples/config @@ -7,6 +7,9 @@ exec foot workspaces 6 background 0.25 0.21 0.2 +# Gap between windows (in pixels) +gap 10 + escape A-space bind s hsplit diff --git a/keybinding.c b/keybinding.c index 87b1e4d..32800da 100644 --- a/keybinding.c +++ b/keybinding.c @@ -1602,6 +1602,33 @@ keybinding_set_nws(struct nedm_server *server, int nws) { old_nws, server->nws); } +void +keybinding_set_gap(struct nedm_server *server, int gap_size) { + uint32_t old_gap = server->gap_size; + server->gap_size = gap_size >= 0 ? gap_size : 0; + + // Re-position all windows with new gap settings + struct nedm_output *output; + wl_list_for_each(output, &server->outputs, link) { + for(unsigned int i = 0; i < server->nws; ++i) { + struct nedm_tile *tile = output->workspaces[i]->focused_tile; + if(tile) { + struct nedm_tile *curr_tile = tile; + do { + if(curr_tile->view) { + view_maximize(curr_tile->view, curr_tile); + } + curr_tile = curr_tile->next; + } while(curr_tile != tile); + } + } + } + + ipc_send_event(server, + "{\"event_name\":\"set_gap\",\"old_gap\":%d,\"new_gap\":%d}", + old_gap, server->gap_size); +} + void keybinding_definemode(struct nedm_server *server, char *mode) { int length = 0; @@ -2172,6 +2199,9 @@ run_action(enum keybinding_action action, struct nedm_server *server, case KEYBINDING_WORKSPACES: keybinding_set_nws(server, data.i); break; + case KEYBINDING_GAP: + keybinding_set_gap(server, data.i); + break; case KEYBINDING_CONFIGURE_OUTPUT: keybinding_configure_output(server, data.o_cfg); break; diff --git a/keybinding.h b/keybinding.h index 1a4e038..c72f8e5 100644 --- a/keybinding.h +++ b/keybinding.h @@ -114,7 +114,9 @@ struct nedm_server; KEYBINDING(KEYBINDING_DEFINEMODE, \ definemode) /* data.c is the mode name */ \ KEYBINDING(KEYBINDING_WORKSPACES, \ - workspaces) /* data.i is the number of workspaces */ + workspaces) /* data.i is the number of workspaces */ \ + KEYBINDING(KEYBINDING_GAP, \ + gap) /* data.i is the gap size in pixels */ #define GENERATE_ENUM(ENUM, NAME) ENUM, #define GENERATE_STRING(STRING, NAME) #NAME, @@ -176,5 +178,7 @@ run_action(enum keybinding_action action, struct nedm_server *server, union keybinding_params data); void keybinding_free(struct keybinding *keybinding, bool recursive); +void +keybinding_set_gap(struct nedm_server *server, int gap_size); #endif /* end of include guard NEDM_KEYBINDING_H */ diff --git a/parse.c b/parse.c index b63fe36..c21ae98 100644 --- a/parse.c +++ b/parse.c @@ -1748,6 +1748,13 @@ parse_command(struct nedm_server *server, struct keybinding *keybinding, if(keybinding->data.i < 0) { return -1; } + } else if(strcmp(action, "gap") == 0) { + keybinding->action = KEYBINDING_GAP; + keybinding->data.i = parse_uint(&saveptr, " "); + if(keybinding->data.i < 0) { + *errstr = log_error("Error parsing gap size, expected positive integer"); + return -1; + } } else if(strcmp(action, "output") == 0) { keybinding->action = KEYBINDING_CONFIGURE_OUTPUT; keybinding->data.o_cfg = parse_output_config(&saveptr, errstr); diff --git a/server.h b/server.h index a5b4d36..20bbcad 100644 --- a/server.h +++ b/server.h @@ -81,6 +81,7 @@ struct nedm_server { uint32_t views_curr_id; uint32_t tiles_curr_id; uint32_t xcursor_size; + uint32_t gap_size; }; void diff --git a/view.c b/view.c index 1c52a3f..0617d1d 100644 --- a/view.c +++ b/view.c @@ -78,13 +78,25 @@ view_activate(struct nedm_view *view, bool activate) { void view_maximize(struct nedm_view *view, struct nedm_tile *tile) { - view->ox = tile->tile.x; - view->oy = tile->tile.y; + uint32_t gap = view->workspace->output->server->gap_size; + + // Apply gap offset to position + view->ox = tile->tile.x + gap; + view->oy = tile->tile.y + gap; + + // Reduce window size by gap amount (gap on all sides) + int32_t width = tile->tile.width - (2 * gap); + int32_t height = tile->tile.height - (2 * gap); + + // Ensure minimum window size + if (width < 1) width = 1; + if (height < 1) height = 1; + wlr_scene_node_set_position( &view->scene_tree->node, view->ox + output_get_layout_box(view->workspace->output).x, view->oy + output_get_layout_box(view->workspace->output).y); - view->impl->maximize(view, tile->tile.width, tile->tile.height); + view->impl->maximize(view, width, height); view->tile = tile; wlr_scene_node_raise_to_top(&view->scene_tree->node); }