diff options
-rw-r--r-- | include/sway/desktop/launcher.h | 2 | ||||
-rw-r--r-- | sway/commands/rename.c | 2 | ||||
-rw-r--r-- | sway/desktop/launcher.c | 130 |
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 | ||
10 | void root_remove_workspace_pid(pid_t pid); | 10 | void root_remove_workspace_pid(pid_t pid); |
11 | 11 | ||
12 | void 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 | ||
11 | static struct wl_list pid_workspaces; | 13 | static struct wl_list pid_workspaces; |
12 | 14 | ||
13 | struct pid_workspace { | 15 | struct 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 | ||
58 | static void pid_workspace_destroy(struct pid_workspace *pw) { | 60 | static 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 | ||
90 | found: | 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 | ||
116 | static void pw_handle_output_destroy(struct wl_listener *listener, void *data) { | 129 | static 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 | ||
123 | void root_record_workspace_pid(pid_t pid) { | 165 | void 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 | |||
177 | void 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 | } | ||