aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sway/desktop/launcher.h2
-rw-r--r--sway/commands/rename.c2
-rw-r--r--sway/desktop/launcher.c130
3 files changed, 77 insertions, 57 deletions
diff --git a/include/sway/desktop/launcher.h b/include/sway/desktop/launcher.h
index cb22eb98..bbc4a2c3 100644
--- a/include/sway/desktop/launcher.h
+++ b/include/sway/desktop/launcher.h
@@ -9,6 +9,4 @@ void root_record_workspace_pid(pid_t pid);
9 9
10void root_remove_workspace_pid(pid_t pid); 10void root_remove_workspace_pid(pid_t pid);
11 11
12void root_rename_pid_workspaces(const char *old_name, const char *new_name);
13
14#endif 12#endif
diff --git a/sway/commands/rename.c b/sway/commands/rename.c
index 4656a410..60a66d58 100644
--- a/sway/commands/rename.c
+++ b/sway/commands/rename.c
@@ -92,8 +92,6 @@ struct cmd_results *cmd_rename(int argc, char **argv) {
92 92
93 sway_log(SWAY_DEBUG, "renaming workspace '%s' to '%s'", workspace->name, new_name); 93 sway_log(SWAY_DEBUG, "renaming workspace '%s' to '%s'", workspace->name, new_name);
94 94
95 root_rename_pid_workspaces(workspace->name, new_name);
96
97 free(workspace->name); 95 free(workspace->name);
98 workspace->name = new_name; 96 workspace->name = new_name;
99 97
diff --git a/sway/desktop/launcher.c b/sway/desktop/launcher.c
index 4e0d9dc1..dd81e23d 100644
--- a/sway/desktop/launcher.c
+++ b/sway/desktop/launcher.c
@@ -4,19 +4,21 @@
4#include "sway/input/seat.h" 4#include "sway/input/seat.h"
5#include "sway/output.h" 5#include "sway/output.h"
6#include "sway/desktop/launcher.h" 6#include "sway/desktop/launcher.h"
7#include "sway/tree/node.h"
7#include "sway/tree/container.h" 8#include "sway/tree/container.h"
8#include "sway/tree/workspace.h" 9#include "sway/tree/workspace.h"
10#include "sway/tree/root.h"
9#include "log.h" 11#include "log.h"
10 12
11static struct wl_list pid_workspaces; 13static struct wl_list pid_workspaces;
12 14
13struct pid_workspace { 15struct pid_workspace {
14 pid_t pid; 16 pid_t pid;
15 char *workspace; 17 char *name;
16 struct timespec time_added; 18 struct timespec time_added;
17 19
18 struct sway_output *output; 20 struct sway_node *node;
19 struct wl_listener output_destroy; 21 struct wl_listener node_destroy;
20 22
21 struct wl_list link; 23 struct wl_list link;
22}; 24};
@@ -56,9 +58,9 @@ static pid_t get_parent_pid(pid_t child) {
56} 58}
57 59
58static void pid_workspace_destroy(struct pid_workspace *pw) { 60static void pid_workspace_destroy(struct pid_workspace *pw) {
59 wl_list_remove(&pw->output_destroy.link); 61 wl_list_remove(&pw->node_destroy.link);
60 wl_list_remove(&pw->link); 62 wl_list_remove(&pw->link);
61 free(pw->workspace); 63 free(pw->name);
62 free(pw); 64 free(pw);
63} 65}
64 66
@@ -69,6 +71,7 @@ struct sway_workspace *root_workspace_for_pid(pid_t pid) {
69 } 71 }
70 72
71 struct sway_workspace *ws = NULL; 73 struct sway_workspace *ws = NULL;
74 struct sway_output *output = NULL;
72 struct pid_workspace *pw = NULL; 75 struct pid_workspace *pw = NULL;
73 76
74 sway_log(SWAY_DEBUG, "Looking up workspace for pid %d", pid); 77 sway_log(SWAY_DEBUG, "Looking up workspace for pid %d", pid);
@@ -79,45 +82,84 @@ struct sway_workspace *root_workspace_for_pid(pid_t pid) {
79 if (pid == _pw->pid) { 82 if (pid == _pw->pid) {
80 pw = _pw; 83 pw = _pw;
81 sway_log(SWAY_DEBUG, 84 sway_log(SWAY_DEBUG,
82 "found pid_workspace for pid %d, workspace %s", 85 "found %s match for pid %d: %s",
83 pid, pw->workspace); 86 node_type_to_str(pw->node->type), pid, node_get_name(pw->node));
84 goto found; 87 break;
85 } 88 }
86 } 89 }
87 pid = get_parent_pid(pid); 90 pid = get_parent_pid(pid);
88 } while (pid > 1); 91 } while (pid > 1);
89 92
90found: 93 if (pw) {
91 if (pw && pw->workspace) { 94 switch (pw->node->type) {
92 ws = workspace_by_name(pw->workspace); 95 case N_CONTAINER:
93 96 // Unimplemented
94 if (!ws) { 97 // TODO: add container matching?
95 sway_log(SWAY_DEBUG, 98 ws = pw->node->sway_container->pending.workspace;
96 "Creating workspace %s for pid %d because it disappeared", 99 break;
97 pw->workspace, pid); 100 case N_WORKSPACE:
98 101 ws = pw->node->sway_workspace;
99 struct sway_output *output = pw->output; 102 break;
100 if (pw->output && !pw->output->enabled) { 103 case N_OUTPUT:
104 output = pw->node->sway_output;
105 ws = workspace_by_name(pw->name);
106 if (!ws) {
101 sway_log(SWAY_DEBUG, 107 sway_log(SWAY_DEBUG,
102 "Workspace output %s is disabled, trying another one", 108 "Creating workspace %s for pid %d because it disappeared",
103 pw->output->wlr_output->name); 109 pw->name, pid);
104 output = NULL; 110 if (!output->enabled) {
111 sway_log(SWAY_DEBUG,
112 "Workspace output %s is disabled, trying another one",
113 output->wlr_output->name);
114 output = NULL;
115 }
116 ws = workspace_create(output, pw->name);
105 } 117 }
106 118 break;
107 ws = workspace_create(output, pw->workspace); 119 case N_ROOT:
120 ws = workspace_create(NULL, pw->name);
121 break;
108 } 122 }
109
110 pid_workspace_destroy(pw); 123 pid_workspace_destroy(pw);
111 } 124 }
112 125
113 return ws; 126 return ws;
114} 127}
115 128
116static void pw_handle_output_destroy(struct wl_listener *listener, void *data) { 129static void pw_handle_node_destroy(struct wl_listener *listener, void *data) {
117 struct pid_workspace *pw = wl_container_of(listener, pw, output_destroy); 130 struct pid_workspace *pw = wl_container_of(listener, pw, node_destroy);
118 pw->output = NULL; 131 switch (pw->node->type) {
119 wl_list_remove(&pw->output_destroy.link); 132 case N_CONTAINER:
120 wl_list_init(&pw->output_destroy.link); 133 // Unimplemented
134 break;
135 case N_WORKSPACE:;
136 struct sway_workspace *ws = pw->node->sway_workspace;
137 wl_list_remove(&pw->node_destroy.link);
138 wl_list_init(&pw->node_destroy.link);
139 // We want to save this ws name to recreate later, hopefully on the
140 // same output
141 free(pw->name);
142 pw->name = strdup(ws->name);
143 if (!ws->output || ws->output->node.destroying) {
144 // If the output is being destroyed it would be pointless to track
145 // If the output is being disabled, we'll find out if it's still
146 // disabled when we try to match it.
147 pw->node = &root->node;
148 break;
149 }
150 pw->node = &ws->output->node;
151 wl_signal_add(&pw->node->events.destroy, &pw->node_destroy);
152 break;
153 case N_OUTPUT:
154 wl_list_remove(&pw->node_destroy.link);
155 wl_list_init(&pw->node_destroy.link);
156 // We'll make the ws pw->name somewhere else
157 pw->node = &root->node;
158 break;
159 case N_ROOT:
160 // Unreachable
161 break;
162 }
121} 163}
122 164
123void root_record_workspace_pid(pid_t pid) { 165void root_record_workspace_pid(pid_t pid) {
@@ -132,11 +174,6 @@ void root_record_workspace_pid(pid_t pid) {
132 sway_log(SWAY_DEBUG, "Bailing out, no workspace"); 174 sway_log(SWAY_DEBUG, "Bailing out, no workspace");
133 return; 175 return;
134 } 176 }
135 struct sway_output *output = ws->output;
136 if (!output) {
137 sway_log(SWAY_DEBUG, "Bailing out, no output");
138 return;
139 }
140 177
141 struct timespec now; 178 struct timespec now;
142 clock_gettime(CLOCK_MONOTONIC, &now); 179 clock_gettime(CLOCK_MONOTONIC, &now);
@@ -151,12 +188,13 @@ void root_record_workspace_pid(pid_t pid) {
151 } 188 }
152 189
153 struct pid_workspace *pw = calloc(1, sizeof(struct pid_workspace)); 190 struct pid_workspace *pw = calloc(1, sizeof(struct pid_workspace));
154 pw->workspace = strdup(ws->name); 191 pw->name = strdup(ws->name);
155 pw->output = output; 192 pw->node = &ws->node;
156 pw->pid = pid; 193 pw->pid = pid;
194
157 memcpy(&pw->time_added, &now, sizeof(struct timespec)); 195 memcpy(&pw->time_added, &now, sizeof(struct timespec));
158 pw->output_destroy.notify = pw_handle_output_destroy; 196 pw->node_destroy.notify = pw_handle_node_destroy;
159 wl_signal_add(&output->wlr_output->events.destroy, &pw->output_destroy); 197 wl_signal_add(&pw->node->events.destroy, &pw->node_destroy);
160 wl_list_insert(&pid_workspaces, &pw->link); 198 wl_list_insert(&pid_workspaces, &pw->link);
161} 199}
162 200
@@ -173,17 +211,3 @@ void root_remove_workspace_pid(pid_t pid) {
173 } 211 }
174 } 212 }
175} 213}
176
177void root_rename_pid_workspaces(const char *old_name, const char *new_name) {
178 if (!pid_workspaces.prev && !pid_workspaces.next) {
179 wl_list_init(&pid_workspaces);
180 }
181
182 struct pid_workspace *pw = NULL;
183 wl_list_for_each(pw, &pid_workspaces, link) {
184 if (strcmp(pw->workspace, old_name) == 0) {
185 free(pw->workspace);
186 pw->workspace = strdup(new_name);
187 }
188 }
189}