From 5d567e9a66d6ad83224918904dbe093a4e52a4a8 Mon Sep 17 00:00:00 2001 From: migueldeoleiros Date: Thu, 31 Oct 2024 12:37:11 +0100 Subject: [PATCH 1/8] feat: implement window cycle command on workspace --- src/commands.c | 34 ++++++++++++++++++++++++++++++++-- src/toplevel.h | 1 + src/workspace.c | 11 +++++++++++ src/workspace.h | 9 +++++++++ 4 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/commands.c b/src/commands.c index 3cd6688..f5e04db 100644 --- a/src/commands.c +++ b/src/commands.c @@ -24,8 +24,10 @@ #include "src/server.h" #include "src/toplevel.h" #include "src/workspace.h" +#include "wlr/util/log.h" #include #include +#include #include #include @@ -38,6 +40,8 @@ void window_list_command(char *tokens[], int ntokens, char *response, struct turtile_context *context); 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 workspace_command(char *tokens[], int ntokens, char *response, struct turtile_context *context); void workspace_list_command(char *tokens[], int ntokens, char *response, @@ -56,6 +60,7 @@ static command_t commands[] = { {"exit", NULL, exit_command}, {"window", "list", window_list_command}, {"window", "switch", window_switch_command}, + {"window", "cycle", window_cycle_command}, {"window", NULL, window_command}, {"workspace", "list", workspace_list_command}, {"workspace", "switch", workspace_switch_command}, @@ -170,12 +175,37 @@ void window_switch_command(char *tokens[], int ntokens, char *response, // TODO: add option to switch window by name struct turtile_server *server = context->server; - if (wl_list_length(&server->toplevels) < 2) { + if (wl_list_length(&server->focus_toplevels) < 2) { response = strdup("{\"error\": \"Only one current window open\"}"); return; } struct turtile_toplevel *next_toplevel = - wl_container_of(server->toplevels.prev, next_toplevel, link); + wl_container_of(server->focus_toplevels.prev, next_toplevel, flink); + focus_toplevel(next_toplevel, next_toplevel->xdg_toplevel->base->surface); + snprintf(response, MAX_MSG_SIZE, "{\"success\": \"switching focus to: %s\"}", + next_toplevel->xdg_toplevel->title); +} + +void window_cycle_command(char *tokens[], int ntokens, char *response, + struct turtile_context *context){ + // Cycle to the next toplevel in the same workspace + struct turtile_server *server = context->server; + + struct wl_list workspace_toplevels; + get_workspace_toplevels(server->active_workspace, &workspace_toplevels); + + if (wl_list_empty(&workspace_toplevels)){ + snprintf(response, MAX_MSG_SIZE, + "{\"error\": \"Workspace is empty\"}"); + return; + } else if (wl_list_length(&workspace_toplevels) < 2) { + snprintf(response, MAX_MSG_SIZE, + "{\"error\": \"Only one current window open\"}"); + 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); snprintf(response, MAX_MSG_SIZE, "{\"success\": \"switching focus to: %s\"}", next_toplevel->xdg_toplevel->title); diff --git a/src/toplevel.h b/src/toplevel.h index 9fdd4d9..7312fd2 100644 --- a/src/toplevel.h +++ b/src/toplevel.h @@ -31,6 +31,7 @@ struct turtile_toplevel { struct wl_list link; struct wl_list flink; + struct wl_list auxlink; struct turtile_server *server; struct wlr_xdg_toplevel *xdg_toplevel; struct wlr_scene_tree *scene_tree; diff --git a/src/workspace.c b/src/workspace.c index 0682f15..789c7b5 100644 --- a/src/workspace.c +++ b/src/workspace.c @@ -65,3 +65,14 @@ struct turtile_workspace* create_workspaces_from_config(struct turtile_server *s } return active_workspace; } + +void get_workspace_toplevels(struct turtile_workspace *workspace, + struct wl_list *toplevels) { + struct turtile_server *server = workspace->server; + wl_list_init(toplevels); + + struct turtile_toplevel *toplevel; + wl_list_for_each(toplevel, &server->focus_toplevels, flink) + if (toplevel->workspace == workspace) + wl_list_insert(toplevels, &toplevel->auxlink); +} diff --git a/src/workspace.h b/src/workspace.h index a2145fe..44f87aa 100644 --- a/src/workspace.h +++ b/src/workspace.h @@ -61,4 +61,13 @@ void switch_workspace(struct turtile_workspace *workspace); */ struct turtile_workspace* create_workspaces_from_config(struct turtile_server *server); +/** + * Retrieves the list of toplevel windows in the specified workspace. + * + * @param workspace The workspace to retrieve toplevel windows from. + * @param toplevels The list to store the toplevel windows in, making use of + * auxlink +*/ +void get_workspace_toplevels(struct turtile_workspace *workspace, + struct wl_list *toplevels); #endif // WORKSPACE_H From 3b045d3c2cc86c0ec9eed862db870b0897240d1e Mon Sep 17 00:00:00 2001 From: migueldeoleiros Date: Thu, 31 Oct 2024 13:24:20 +0100 Subject: [PATCH 2/8] feat: add unique id and app to window information --- meson.build | 3 ++- src/commands.c | 4 ++++ src/toplevel.c | 8 ++++++++ src/toplevel.h | 7 +++++-- 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/meson.build b/meson.build index 9c5739e..9a05d44 100644 --- a/meson.build +++ b/meson.build @@ -32,7 +32,8 @@ deps = [ dependency('wayland-server'), dependency('xkbcommon'), dependency('libconfig'), - dependency('json-c') + dependency('json-c'), + dependency('uuid') ] executable( diff --git a/src/commands.c b/src/commands.c index f5e04db..94f76aa 100644 --- a/src/commands.c +++ b/src/commands.c @@ -156,6 +156,10 @@ void window_list_command(char *tokens[], int ntokens, char *response, // Create a JSON object for each window and populate its fields struct json_object *json_window = json_object_new_object(); + json_object_object_add(json_window, "id", + json_object_new_string(toplevel->id)); + json_object_object_add(json_window, "app", + json_object_new_string(toplevel->xdg_toplevel->app_id)); json_object_object_add(json_window, "title", json_object_new_string(title)); json_object_object_add(json_window, "workspace", diff --git a/src/toplevel.c b/src/toplevel.c index 38047e1..530c801 100644 --- a/src/toplevel.c +++ b/src/toplevel.c @@ -29,6 +29,7 @@ #include #include #include +#include void focus_toplevel(struct turtile_toplevel *toplevel, struct wlr_surface *surface) { /* Note: this function only deals with keyboard focus. */ @@ -131,6 +132,13 @@ void xdg_toplevel_map(struct wl_listener *listener, void *data) { /* Called when the surface is mapped, or ready to display on-screen. */ struct turtile_toplevel *toplevel = wl_container_of(listener, toplevel, map); + uuid_t uuid; + uuid_generate(uuid); + // Convert first 4 bytes of UUID to a short 8-character hexadecimal string + char short_uuid_str[9]; // 8 characters + null terminator + snprintf(short_uuid_str, sizeof(short_uuid_str), "%08x", *(uint32_t*)uuid); + strncpy(toplevel->id, short_uuid_str, sizeof(toplevel->id)); + toplevel->workspace = toplevel->server->active_workspace; wl_list_insert(&toplevel->server->toplevels, &toplevel->link); wl_list_insert(&toplevel->server->focus_toplevels, &toplevel->flink); diff --git a/src/toplevel.h b/src/toplevel.h index 7312fd2..a9b8e7b 100644 --- a/src/toplevel.h +++ b/src/toplevel.h @@ -27,15 +27,20 @@ #include "src/output.h" #include #include +#include struct turtile_toplevel { struct wl_list link; struct wl_list flink; struct wl_list auxlink; + + char id[9]; // 8 characters + null terminator struct turtile_server *server; struct wlr_xdg_toplevel *xdg_toplevel; struct wlr_scene_tree *scene_tree; + struct turtile_workspace *workspace; struct wlr_box geometry; + struct wl_listener map; struct wl_listener unmap; struct wl_listener commit; @@ -44,8 +49,6 @@ struct turtile_toplevel { struct wl_listener request_resize; struct wl_listener request_maximize; struct wl_listener request_fullscreen; - - struct turtile_workspace *workspace; }; /** From 7259dd908f5292a8f90a6e73379c49fdd413e5a2 Mon Sep 17 00:00:00 2001 From: migueldeoleiros Date: Thu, 31 Oct 2024 13:25:02 +0100 Subject: [PATCH 3/8] ci: update ci to parse json properly this avoids problems with unique ids for windows --- tests/test.py | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/tests/test.py b/tests/test.py index 3ade31c..3ec230f 100644 --- a/tests/test.py +++ b/tests/test.py @@ -1,4 +1,5 @@ import subprocess +import json TTCLI = "./build/ttcli --json " @@ -7,14 +8,22 @@ def run_ttcli(command): return subprocess.run([TTCLI + command], capture_output=True, text=True, shell=True) def test_workspace_list(expected_output): - """Check list of workspaces.""" + """Check list of workspaces, ignoring irrelevant fields.""" result = run_ttcli('workspace list') - assert expected_output in result.stdout, f"Expected '{expected_output}' in output, but got:\n{result.stdout}" + workspaces = json.loads(result.stdout) -def test_window_list(expected_output): - """Check list of windows.""" + # Extract only 'name' and 'active' fields for comparison + actual_output = [{ "name": w["name"], "active": w["active"] } for w in workspaces] + assert actual_output == expected_output, f"Expected {expected_output} but got {actual_output}" + +def test_window_list(expected_titles): + """Check list of windows, ignoring IDs.""" result = run_ttcli('window list') - assert expected_output in result.stdout, f"Expected '{expected_output}' in output, but got:\n{result.stdout}" + windows = json.loads(result.stdout) + + # Extract 'title' and 'workspace' fields only + actual_titles = [{ "title": w["title"], "workspace": w["workspace"] } for w in windows] + assert actual_titles == expected_titles, f"Expected {expected_titles} but got {actual_titles}" def test_workspace_switch(destination_workspace): """Check workspace switch.""" @@ -23,8 +32,17 @@ def test_workspace_switch(destination_workspace): assert expected_success_message in result.stdout, f"Expected 'switch to workspace {destination_workspace}' in output, but got:\n{result.stdout}" if __name__ == '__main__': - test_workspace_list('[ { "name": "main", "active": true }, { "name": "test", "active": false } ]') - test_window_list('[ { "title": "simple-egl", "workspace": "main" }, { "title": "simple-damage", "workspace": "main" } ]') + test_workspace_list([ + { "name": "main", "active": True }, + { "name": "test", "active": False } + ]) + test_window_list([ + { "title": "simple-egl", "workspace": "main" }, + { "title": "simple-damage", "workspace": "main" } + ]) test_workspace_switch('test') - test_workspace_list('[ { "name": "main", "active": false }, { "name": "test", "active": true } ]') + test_workspace_list([ + { "name": "main", "active": False }, + { "name": "test", "active": True } + ]) run_ttcli('exit') From 6ec5aec08410aec90dd2e9262a66779cc00a7c40 Mon Sep 17 00:00:00 2001 From: migueldeoleiros Date: Thu, 31 Oct 2024 14:34:51 +0100 Subject: [PATCH 4/8] fix: check null for app_id --- src/commands.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/commands.c b/src/commands.c index 94f76aa..104b620 100644 --- a/src/commands.c +++ b/src/commands.c @@ -153,13 +153,15 @@ void window_list_command(char *tokens[], int ntokens, char *response, if (toplevel->xdg_toplevel) { const char *title = toplevel->xdg_toplevel->title ? toplevel->xdg_toplevel->title : "Unnamed"; + const char *app = toplevel->xdg_toplevel->app_id ? + toplevel->xdg_toplevel->title : "null"; // Create a JSON object for each window and populate its fields struct json_object *json_window = json_object_new_object(); json_object_object_add(json_window, "id", json_object_new_string(toplevel->id)); json_object_object_add(json_window, "app", - json_object_new_string(toplevel->xdg_toplevel->app_id)); + json_object_new_string(app)); json_object_object_add(json_window, "title", json_object_new_string(title)); json_object_object_add(json_window, "workspace", From 34d36a9ae6f35e5708b1506ea5ef754c123c232e Mon Sep 17 00:00:00 2001 From: migueldeoleiros Date: Thu, 31 Oct 2024 14:48:38 +0100 Subject: [PATCH 5/8] feat: implement window switch by id --- src/commands.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/commands.c b/src/commands.c index 104b620..c9ba3a4 100644 --- a/src/commands.c +++ b/src/commands.c @@ -177,19 +177,29 @@ void window_list_command(char *tokens[], int ntokens, char *response, void window_switch_command(char *tokens[], int ntokens, char *response, struct turtile_context *context){ - // Cycle to the next toplevel - // TODO: add option to switch window by name + // Switch focus to designated toplevel struct turtile_server *server = context->server; - if (wl_list_length(&server->focus_toplevels) < 2) { - response = strdup("{\"error\": \"Only one current window open\"}"); - return; + if(ntokens >= 1){ + char *new_toplevel_id = tokens[0]; + struct turtile_toplevel *toplevel; + + wl_list_for_each(toplevel, &server->focus_toplevels, flink) { + if(strcmp(toplevel->id, new_toplevel_id) == 0){ + focus_toplevel(toplevel, toplevel->xdg_toplevel->base->surface); + snprintf(response, MAX_MSG_SIZE, + "{\"success\": \"switching focus to: %s\"}", + toplevel->xdg_toplevel->title); + return; + } + } + snprintf(response, MAX_MSG_SIZE, + "{\"error\": \"window %s not found\"}", new_toplevel_id); + + } else{ + snprintf(response, MAX_MSG_SIZE, + "{\"error\": \"missing argument: window id\"}"); } - struct turtile_toplevel *next_toplevel = - wl_container_of(server->focus_toplevels.prev, next_toplevel, flink); - focus_toplevel(next_toplevel, next_toplevel->xdg_toplevel->base->surface); - snprintf(response, MAX_MSG_SIZE, "{\"success\": \"switching focus to: %s\"}", - next_toplevel->xdg_toplevel->title); } void window_cycle_command(char *tokens[], int ntokens, char *response, From e9708bb978d755fe039ee71f0b9c1bf941592e29 Mon Sep 17 00:00:00 2001 From: migueldeoleiros Date: Thu, 31 Oct 2024 15:09:11 +0100 Subject: [PATCH 6/8] 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. From 09168e7494bafa69ce2ed808aa42e281a2772f5a Mon Sep 17 00:00:00 2001 From: migueldeoleiros Date: Thu, 31 Oct 2024 18:00:44 +0100 Subject: [PATCH 7/8] feat: implement window move to workspace command - Add getters for both toplevel and workspace --- src/commands.c | 59 +++++++++++++++++++++++++++++++++++++++++++++---- src/toplevel.c | 10 +++++++++ src/toplevel.h | 2 ++ src/workspace.c | 11 +++++++++ src/workspace.h | 3 +++ 5 files changed, 81 insertions(+), 4 deletions(-) diff --git a/src/commands.c b/src/commands.c index 8bdaaa5..d2bbb91 100644 --- a/src/commands.c +++ b/src/commands.c @@ -39,17 +39,19 @@ void window_command(char *tokens[], int ntokens, char *response, void window_list_command(char *tokens[], int ntokens, char *response, struct turtile_context *context); void window_switch_command(char *tokens[], int ntokens, char *response, - struct turtile_context *context); + struct turtile_context *context); void window_cycle_command(char *tokens[], int ntokens, char *response, - struct turtile_context *context); + struct turtile_context *context); void window_kill_command(char *tokens[], int ntokens, char *response, struct turtile_context *context); +void window_move_to_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, - struct turtile_context *context); + struct turtile_context *context); void workspace_switch_command(char *tokens[], int ntokens, char *response, - struct turtile_context *context); + struct turtile_context *conntext); typedef struct { char *cmd_name; char *subcmd_name; @@ -64,6 +66,7 @@ static command_t commands[] = { {"window", "switch", window_switch_command}, {"window", "cycle", window_cycle_command}, {"window", "kill", window_kill_command}, + {"window", "move-to", window_move_to_command}, {"window", NULL, window_command}, {"workspace", "list", workspace_list_command}, {"workspace", "switch", workspace_switch_command}, @@ -259,6 +262,54 @@ void window_kill_command(char *tokens[], int ntokens, char *response, } } +void window_move_to_command(char *tokens[], int ntokens, char *response, + struct turtile_context *context){ + struct turtile_server *server = context->server; + + if (ntokens >= 1) { + char *target_workspace_name = tokens[0]; + struct turtile_workspace *target_workspace = + get_workspace(server, target_workspace_name); + + if (!target_workspace) { + snprintf(response, MAX_MSG_SIZE, + "{\"error\": \"workspace not found\"}"); + return; + } + + struct turtile_toplevel *toplevel_to_move; + if (ntokens >= 2) { + char *toplevel_id = tokens[1]; + + toplevel_to_move = get_toplevel(server, toplevel_id); + + if (!toplevel_to_move) { + snprintf(response, MAX_MSG_SIZE, + "{\"error\": \"window %s not found\"}", toplevel_id); + return; + } + } else { + toplevel_to_move = get_first_toplevel(server); + if (!toplevel_to_move) { + snprintf(response, MAX_MSG_SIZE, + "{\"error\": \"no focused window to move\"}"); + return; + } + } + + toplevel_to_move->workspace = target_workspace; + server_redraw_windows(server); + + snprintf(response, MAX_MSG_SIZE, + "{\"success\": \"moved window %s to workspace %s\"}", + toplevel_to_move->xdg_toplevel->title, target_workspace->name); + + } else { + snprintf(response, MAX_MSG_SIZE, + "{\"error\": \"missing argument: workspace name\"}"); + } +} + 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 4990359..fe159fa 100644 --- a/src/toplevel.c +++ b/src/toplevel.c @@ -97,6 +97,16 @@ void kill_toplevel(struct turtile_toplevel *toplevel) { wlr_xdg_toplevel_send_close(toplevel->xdg_toplevel); } +struct turtile_toplevel *get_toplevel(struct turtile_server *server, char *id) { + struct turtile_toplevel *toplevel; + wl_list_for_each(toplevel, &server->toplevels, link) { + if (strcmp(toplevel->id, id) == 0) { + return toplevel; + } + } + return NULL; +} + 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 05c2a83..aed5205 100644 --- a/src/toplevel.h +++ b/src/toplevel.h @@ -63,6 +63,8 @@ void focus_toplevel(struct turtile_toplevel *toplevel, void kill_toplevel(struct turtile_toplevel *toplevel); +struct turtile_toplevel *get_toplevel(struct turtile_server *server, char *id); + /** * Retrieves the first toplevel on the active workspace of the given server. * If no such toplevel is found, NULL is returned. diff --git a/src/workspace.c b/src/workspace.c index 789c7b5..b287041 100644 --- a/src/workspace.c +++ b/src/workspace.c @@ -41,6 +41,17 @@ struct turtile_workspace* create_workspace(struct turtile_server *server, return new_workspace; } +struct turtile_workspace *get_workspace(struct turtile_server *server, + char *name) { + struct turtile_workspace *workspace; + wl_list_for_each(workspace, &server->workspaces, link) { + if (strcmp(workspace->name, name) == 0) { + return workspace; + } + } + return NULL; +} + void switch_workspace(struct turtile_workspace *workspace){ if(workspace == NULL){ return; diff --git a/src/workspace.h b/src/workspace.h index 44f87aa..53c06fb 100644 --- a/src/workspace.h +++ b/src/workspace.h @@ -43,6 +43,9 @@ struct turtile_workspace { */ struct turtile_workspace* create_workspace(struct turtile_server *server, char *name); + +struct turtile_workspace *get_workspace(struct turtile_server *server, + char *name); /** * Switches the active workspace to the specified workspace. * From 972dc93d1705758186998ee268e019db8f68293d Mon Sep 17 00:00:00 2001 From: migueldeoleiros Date: Thu, 31 Oct 2024 18:07:54 +0100 Subject: [PATCH 8/8] docs: add docstrings to new functions --- src/toplevel.h | 13 ++++++++++++- src/workspace.h | 7 +++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/toplevel.h b/src/toplevel.h index aed5205..0f81bef 100644 --- a/src/toplevel.h +++ b/src/toplevel.h @@ -60,9 +60,20 @@ struct turtile_toplevel { */ void focus_toplevel(struct turtile_toplevel *toplevel, struct wlr_surface *surface); - +/** + * Send close request to toplevel, and focus next window + * + * @param toplevel The turtile toplevel to kill. + */ void kill_toplevel(struct turtile_toplevel *toplevel); +/** + * Retrieves the toplevel with the given ID from the given server. + * + * @param server The turtile server to search for the toplevel on. + * @param id The ID of the toplevel to retrieve. + * @return A pointer to the toplevel with the given ID, or NULL + */ struct turtile_toplevel *get_toplevel(struct turtile_server *server, char *id); /** diff --git a/src/workspace.h b/src/workspace.h index 53c06fb..c1d301d 100644 --- a/src/workspace.h +++ b/src/workspace.h @@ -44,6 +44,13 @@ struct turtile_workspace { struct turtile_workspace* create_workspace(struct turtile_server *server, char *name); +/** + * Retrieves the workspace with the given name from the given server. + * + * @param server The turtile server to search for the workspace on. + * @param name The name of the workspace to retrieve. + * @return A pointer to the workspace with the given name, or NULL + */ struct turtile_workspace *get_workspace(struct turtile_server *server, char *name); /**