From e9708bb978d755fe039ee71f0b9c1bf941592e29 Mon Sep 17 00:00:00 2001 From: migueldeoleiros Date: Thu, 31 Oct 2024 15:09:11 +0100 Subject: [PATCH] feat: implement window kill command it works for both the active window (no id specified) and to kill a specific window --- src/commands.c | 32 ++++++++++++++++++++++++++++++++ src/toplevel.c | 21 +++++++++++++++++++++ src/toplevel.h | 3 +++ 3 files changed, 56 insertions(+) diff --git a/src/commands.c b/src/commands.c index c9ba3a4..8bdaaa5 100644 --- a/src/commands.c +++ b/src/commands.c @@ -42,6 +42,8 @@ void window_switch_command(char *tokens[], int ntokens, char *response, struct turtile_context *context); void window_cycle_command(char *tokens[], int ntokens, char *response, struct turtile_context *context); +void window_kill_command(char *tokens[], int ntokens, char *response, + struct turtile_context *context); void workspace_command(char *tokens[], int ntokens, char *response, struct turtile_context *context); void workspace_list_command(char *tokens[], int ntokens, char *response, @@ -61,6 +63,7 @@ static command_t commands[] = { {"window", "list", window_list_command}, {"window", "switch", window_switch_command}, {"window", "cycle", window_cycle_command}, + {"window", "kill", window_kill_command}, {"window", NULL, window_command}, {"workspace", "list", workspace_list_command}, {"workspace", "switch", workspace_switch_command}, @@ -227,6 +230,35 @@ void window_cycle_command(char *tokens[], int ntokens, char *response, next_toplevel->xdg_toplevel->title); } +void window_kill_command(char *tokens[], int ntokens, char *response, + struct turtile_context *context){ + // kill designated toplevel + struct turtile_server *server = context->server; + struct turtile_toplevel *toplevel; + + if(ntokens >= 1){ + char *new_toplevel_id = tokens[0]; + + wl_list_for_each(toplevel, &server->focus_toplevels, flink) { + if(strcmp(toplevel->id, new_toplevel_id) == 0){ + kill_toplevel(toplevel); + snprintf(response, MAX_MSG_SIZE, + "{\"success\": \"kill: %s\"}", + toplevel->xdg_toplevel->title); + return; + } + } + snprintf(response, MAX_MSG_SIZE, + "{\"error\": \"window %s not found\"}", new_toplevel_id); + + } else{ + toplevel = get_first_toplevel(server); + kill_toplevel(toplevel); + snprintf(response, MAX_MSG_SIZE, + "{\"success\": \"kill: %s\"}", toplevel->xdg_toplevel->title); + } +} + void workspace_command(char *tokens[], int ntokens, char *response, struct turtile_context *context){ // TODO: use this function as a help for the other workspace subcommands diff --git a/src/toplevel.c b/src/toplevel.c index 530c801..4990359 100644 --- a/src/toplevel.c +++ b/src/toplevel.c @@ -76,6 +76,27 @@ void focus_toplevel(struct turtile_toplevel *toplevel, struct wlr_surface *surfa server_redraw_windows(server); } +void kill_toplevel(struct turtile_toplevel *toplevel) { + struct turtile_server *server = toplevel->server; + + struct wl_list workspace_toplevels; + get_workspace_toplevels(server->active_workspace, &workspace_toplevels); + + if (wl_list_empty(&workspace_toplevels)){ + wlr_xdg_toplevel_send_close(toplevel->xdg_toplevel); + return; + } else if (wl_list_length(&workspace_toplevels) < 2) { + wlr_xdg_toplevel_send_close(toplevel->xdg_toplevel); + return; + } + + struct turtile_toplevel *next_toplevel = + wl_container_of(workspace_toplevels.next, next_toplevel, auxlink); + focus_toplevel(next_toplevel, next_toplevel->xdg_toplevel->base->surface); + + wlr_xdg_toplevel_send_close(toplevel->xdg_toplevel); +} + struct turtile_toplevel *get_first_toplevel(struct turtile_server *server) { struct turtile_toplevel *toplevel; wl_list_for_each(toplevel, &server->focus_toplevels, flink) diff --git a/src/toplevel.h b/src/toplevel.h index a9b8e7b..05c2a83 100644 --- a/src/toplevel.h +++ b/src/toplevel.h @@ -60,6 +60,9 @@ struct turtile_toplevel { */ void focus_toplevel(struct turtile_toplevel *toplevel, struct wlr_surface *surface); + +void kill_toplevel(struct turtile_toplevel *toplevel); + /** * Retrieves the first toplevel on the active workspace of the given server. * If no such toplevel is found, NULL is returned.