diff options
author | Luminarys <kizunanohikari@gmail.com> | 2015-08-17 00:38:34 -0500 |
---|---|---|
committer | Luminarys <kizunanohikari@gmail.com> | 2015-08-17 00:38:34 -0500 |
commit | 05f969074e39c5adeb5d7390d8255b83cf351866 (patch) | |
tree | 3f31fc1f7f4d7c31620f012adfcb2e629b2d2042 | |
parent | Fix format warnings (diff) | |
download | sway-05f969074e39c5adeb5d7390d8255b83cf351866.tar.gz sway-05f969074e39c5adeb5d7390d8255b83cf351866.tar.zst sway-05f969074e39c5adeb5d7390d8255b83cf351866.zip |
Added in basic floating toggling
-rw-r--r-- | include/container.h | 5 | ||||
-rw-r--r-- | sway/children | 26 | ||||
-rw-r--r-- | sway/commands.c | 68 | ||||
-rw-r--r-- | sway/container.c | 21 | ||||
-rw-r--r-- | sway/layout.c | 47 | ||||
-rw-r--r-- | sway/workspace.c | 13 |
6 files changed, 176 insertions, 4 deletions
diff --git a/include/container.h b/include/container.h index dd934be6..7560ddb8 100644 --- a/include/container.h +++ b/include/container.h | |||
@@ -40,12 +40,17 @@ struct sway_container { | |||
40 | 40 | ||
41 | bool visible; | 41 | bool visible; |
42 | 42 | ||
43 | bool is_floating; | ||
44 | |||
43 | int weight; | 45 | int weight; |
44 | 46 | ||
45 | char *name; | 47 | char *name; |
46 | 48 | ||
47 | list_t *children; | 49 | list_t *children; |
48 | 50 | ||
51 | // Special list for floating windows in workspaces | ||
52 | list_t *floating; | ||
53 | |||
49 | struct sway_container *parent; | 54 | struct sway_container *parent; |
50 | struct sway_container *focused; | 55 | struct sway_container *focused; |
51 | }; | 56 | }; |
diff --git a/sway/children b/sway/children new file mode 100644 index 00000000..55ef43c9 --- /dev/null +++ b/sway/children | |||
@@ -0,0 +1,26 @@ | |||
1 | workspace.c:90:35: swayc_t *current_output = active_workspace->parent; | ||
2 | workspace.c:93:78: if (strcmp((((swayc_t *)current_output->children->items[i])->name), active_workspace->name) == 0) { | ||
3 | workspace.c:105:35: swayc_t *current_output = active_workspace->parent; | ||
4 | workspace.c:108:78: if (strcmp((((swayc_t *)current_output->children->items[i])->name), active_workspace->name) == 0) { | ||
5 | workspace.c:133:35: swayc_t *current_output = active_workspace->parent; | ||
6 | workspace.c:136:78: if (strcmp((((swayc_t *)current_output->children->items[i])->name), active_workspace->name) == 0) { | ||
7 | workspace.c:149:35: swayc_t *current_output = active_workspace->parent; | ||
8 | workspace.c:152:78: if (strcmp((((swayc_t *)current_output->children->items[i])->name), active_workspace->name) == 0) { | ||
9 | workspace.c:176:23: swayc_t *ws_output = workspace->parent; | ||
10 | workspace.c:183:70: sway_log(L_DEBUG, "workspace: changing from '%s' to '%s'", focused_workspace->name, workspace->name); | ||
11 | workspace.c:199:20: swayc_t *output = workspace->parent; | ||
12 | |||
13 | container.c:79:2: workspace->layout = L_HORIZ; // TODO:default layout | ||
14 | container.c:80:2: workspace->width = output->width; | ||
15 | container.c:81:2: workspace->height = output->height; | ||
16 | container.c:82:2: workspace->name = strdup(name); | ||
17 | container.c:83:2: workspace->visible = true; | ||
18 | container.c:105:19: cont->focused = workspace->focused; | ||
19 | container.c:106:3: workspace->focused = cont; | ||
20 | container.c:108:24: list_t *tmp_list = workspace->children; | ||
21 | container.c:109:3: workspace->children = cont->children; | ||
22 | container.c:114:18: cont->layout = workspace->layout; | ||
23 | container.c:115:3: workspace->layout = layout; | ||
24 | container.c:162:6: if (workspace->children->length == 0) { | ||
25 | container.c:163:61: sway_log(L_DEBUG, "Workspace: Destroying workspace '%s'", workspace->name); | ||
26 | container.c:164:21: swayc_t *parent = workspace->parent; | ||
diff --git a/sway/commands.c b/sway/commands.c index f0db4ed2..91dfa2b2 100644 --- a/sway/commands.c +++ b/sway/commands.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include "workspace.h" | 13 | #include "workspace.h" |
14 | #include "commands.h" | 14 | #include "commands.h" |
15 | #include "container.h" | 15 | #include "container.h" |
16 | #include "handlers.h" | ||
16 | 17 | ||
17 | struct modifier_key { | 18 | struct modifier_key { |
18 | char *name; | 19 | char *name; |
@@ -169,6 +170,72 @@ static bool cmd_exit(struct sway_config *config, int argc, char **argv) { | |||
169 | return true; | 170 | return true; |
170 | } | 171 | } |
171 | 172 | ||
173 | static bool cmd_floating(struct sway_config *config, int argc, char **argv) { | ||
174 | if (strcasecmp(argv[0], "toggle") == 0) { | ||
175 | swayc_t *view = get_focused_container(&root_container); | ||
176 | // Prevent running floating commands on things like workspaces | ||
177 | if (view->type != C_VIEW) { | ||
178 | return true; | ||
179 | } | ||
180 | int i; | ||
181 | // Change from nonfloating to floating | ||
182 | if (!view->is_floating) { | ||
183 | view->is_floating = true; | ||
184 | for (i = 0; i < view->parent->children->length; i++) { | ||
185 | if (view->parent->children->items[i] == view) { | ||
186 | // Cut down on width/height so it's obvious that you've gone floating | ||
187 | // if this is the only view | ||
188 | view->width = view->width - 30; | ||
189 | view->height = view->height - 30; | ||
190 | |||
191 | // Swap from the list of whatever container the view was in | ||
192 | // to the workspace->floating list | ||
193 | // TODO: Destroy any remaining empty containers | ||
194 | list_del(view->parent->children, i); | ||
195 | list_add(active_workspace->floating, view); | ||
196 | |||
197 | // Set the new position of the container and arrange windows | ||
198 | view->x = (active_workspace->width - view->width)/2; | ||
199 | view->y = (active_workspace->height - view->height)/2; | ||
200 | sway_log(L_INFO, "Setting container %p to floating at coordinates X:%d Y:%d, W:%d, H:%d", view, view->x, view->y, view->width, view->height); | ||
201 | // Change parent to active_workspace | ||
202 | view->parent = active_workspace; | ||
203 | arrange_windows(active_workspace, -1, -1); | ||
204 | return true; | ||
205 | } | ||
206 | } | ||
207 | } else { | ||
208 | // Delete the view from the floating list and unset its is_floating flag | ||
209 | // Using length-1 as the index is safe because the view must be the currently | ||
210 | // focused floating output | ||
211 | list_del(active_workspace->floating, active_workspace->floating->length - 1); | ||
212 | view->is_floating = false; | ||
213 | active_workspace->focused = NULL; | ||
214 | // Get the properly focused container, and add in the view there | ||
215 | swayc_t *focused = focus_pointer(); | ||
216 | // If focused is null, it's because the currently focused container is a workspace | ||
217 | if (focused == NULL) { | ||
218 | focused = active_workspace; | ||
219 | } | ||
220 | |||
221 | sway_log(L_DEBUG, "Non-floating focused container is %p", focused); | ||
222 | |||
223 | //Case of focused workspace, just create as child of it | ||
224 | if (focused->type == C_WORKSPACE) { | ||
225 | add_child(focused, view); | ||
226 | } | ||
227 | //Regular case, create as sibling of current container | ||
228 | else { | ||
229 | add_sibling(focused, view); | ||
230 | } | ||
231 | arrange_windows(active_workspace, -1, -1); | ||
232 | return true; | ||
233 | } | ||
234 | } | ||
235 | |||
236 | return true; | ||
237 | } | ||
238 | |||
172 | static bool cmd_focus(struct sway_config *config, int argc, char **argv) { | 239 | static bool cmd_focus(struct sway_config *config, int argc, char **argv) { |
173 | if (!checkarg(argc, "focus", EXPECTED_EQUAL_TO, 1)) { | 240 | if (!checkarg(argc, "focus", EXPECTED_EQUAL_TO, 1)) { |
174 | return false; | 241 | return false; |
@@ -378,6 +445,7 @@ static struct cmd_handler handlers[] = { | |||
378 | { "exec", cmd_exec }, | 445 | { "exec", cmd_exec }, |
379 | { "exec_always", cmd_exec_always }, | 446 | { "exec_always", cmd_exec_always }, |
380 | { "exit", cmd_exit }, | 447 | { "exit", cmd_exit }, |
448 | { "floating", cmd_floating }, | ||
381 | { "focus", cmd_focus }, | 449 | { "focus", cmd_focus }, |
382 | { "focus_follows_mouse", cmd_focus_follows_mouse }, | 450 | { "focus_follows_mouse", cmd_focus_follows_mouse }, |
383 | { "fullscreen", cmd_fullscreen }, | 451 | { "fullscreen", cmd_fullscreen }, |
diff --git a/sway/container.c b/sway/container.c index 4321b6ce..87e48e91 100644 --- a/sway/container.c +++ b/sway/container.c | |||
@@ -81,6 +81,7 @@ swayc_t *new_workspace(swayc_t * output, const char *name) { | |||
81 | workspace->height = output->height; | 81 | workspace->height = output->height; |
82 | workspace->name = strdup(name); | 82 | workspace->name = strdup(name); |
83 | workspace->visible = true; | 83 | workspace->visible = true; |
84 | workspace->floating = create_list(); | ||
84 | 85 | ||
85 | add_child(output, workspace); | 86 | add_child(output, workspace); |
86 | return workspace; | 87 | return workspace; |
@@ -134,6 +135,9 @@ swayc_t *new_view(swayc_t *sibling, wlc_handle handle) { | |||
134 | view->name = strdup(title); | 135 | view->name = strdup(title); |
135 | view->visible = true; | 136 | view->visible = true; |
136 | 137 | ||
138 | // TODO: properly set this | ||
139 | view->is_floating = false; | ||
140 | |||
137 | //Case of focused workspace, just create as child of it | 141 | //Case of focused workspace, just create as child of it |
138 | if (sibling->type == C_WORKSPACE) { | 142 | if (sibling->type == C_WORKSPACE) { |
139 | add_child(sibling, view); | 143 | add_child(sibling, view); |
@@ -192,23 +196,32 @@ swayc_t *destroy_view(swayc_t *view) { | |||
192 | if (parent->type == C_CONTAINER) { | 196 | if (parent->type == C_CONTAINER) { |
193 | return destroy_container(parent); | 197 | return destroy_container(parent); |
194 | } | 198 | } |
199 | |||
195 | return parent; | 200 | return parent; |
196 | } | 201 | } |
197 | 202 | ||
198 | |||
199 | swayc_t *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data) { | 203 | swayc_t *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data) { |
200 | if (!container->children) { | 204 | if (!container->children) { |
201 | return NULL; | 205 | return NULL; |
202 | } | 206 | } |
207 | // Special case for checking floating stuff | ||
203 | int i; | 208 | int i; |
209 | if (container->type == C_WORKSPACE) { | ||
210 | for (i = 0; i < container->floating->length; ++i) { | ||
211 | swayc_t *child = container->floating->items[i]; | ||
212 | if (test(child, data)) { | ||
213 | return child; | ||
214 | } | ||
215 | } | ||
216 | } | ||
204 | for (i = 0; i < container->children->length; ++i) { | 217 | for (i = 0; i < container->children->length; ++i) { |
205 | swayc_t *child = container->children->items[i]; | 218 | swayc_t *child = container->children->items[i]; |
206 | if (test(child, data)) { | 219 | if (test(child, data)) { |
207 | return child; | 220 | return child; |
208 | } else { | 221 | } else { |
209 | swayc_t *_ = find_container(child, test, data); | 222 | swayc_t *res = find_container(child, test, data); |
210 | if (_) { | 223 | if (res) { |
211 | return _; | 224 | return res; |
212 | } | 225 | } |
213 | } | 226 | } |
214 | } | 227 | } |
diff --git a/sway/layout.c b/sway/layout.c index 4407742a..c53b9dad 100644 --- a/sway/layout.c +++ b/sway/layout.c | |||
@@ -65,6 +65,15 @@ swayc_t *replace_child(swayc_t *child, swayc_t *new_child) { | |||
65 | 65 | ||
66 | swayc_t *remove_child(swayc_t *parent, swayc_t *child) { | 66 | swayc_t *remove_child(swayc_t *parent, swayc_t *child) { |
67 | int i; | 67 | int i; |
68 | // Special case for floating views | ||
69 | if (child->is_floating) { | ||
70 | for (i = 0; i < parent->floating->length; ++i) { | ||
71 | if (parent->floating->items[i] == child) { | ||
72 | list_del(parent->floating, i); | ||
73 | break; | ||
74 | } | ||
75 | } | ||
76 | } | ||
68 | for (i = 0; i < parent->children->length; ++i) { | 77 | for (i = 0; i < parent->children->length; ++i) { |
69 | if (parent->children->items[i] == child) { | 78 | if (parent->children->items[i] == child) { |
70 | list_del(parent->children, i); | 79 | list_del(parent->children, i); |
@@ -192,6 +201,33 @@ void arrange_windows(swayc_t *container, int width, int height) { | |||
192 | } | 201 | } |
193 | break; | 202 | break; |
194 | } | 203 | } |
204 | |||
205 | // Arrage floating layouts for workspaces last | ||
206 | if (container->type == C_WORKSPACE) { | ||
207 | for (i = 0; i < container->floating->length; ++i) { | ||
208 | swayc_t *view = ((swayc_t *)container->floating->items[i]); | ||
209 | // Set the geometry | ||
210 | struct wlc_geometry geometry = { | ||
211 | .origin = { | ||
212 | .x = view->x, | ||
213 | .y = view->y | ||
214 | }, | ||
215 | .size = { | ||
216 | .w = view->width, | ||
217 | .h = view->height | ||
218 | } | ||
219 | }; | ||
220 | wlc_view_set_geometry(view->handle, &geometry); | ||
221 | |||
222 | // Bring the views to the front in order of the list, the list | ||
223 | // will be kept up to date so that more recently focused views | ||
224 | // have higher indexes | ||
225 | // This is conditional on there not being a fullscreen view in the workspace | ||
226 | if (!(wlc_view_get_state(container->focused->handle) & WLC_BIT_FULLSCREEN)) { | ||
227 | wlc_view_bring_to_front(view->handle); | ||
228 | } | ||
229 | } | ||
230 | } | ||
195 | layout_log(&root_container, 0); | 231 | layout_log(&root_container, 0); |
196 | } | 232 | } |
197 | 233 | ||
@@ -199,7 +235,18 @@ swayc_t *get_swayc_for_handle(wlc_handle handle, swayc_t *parent) { | |||
199 | if (parent->children == NULL) { | 235 | if (parent->children == NULL) { |
200 | return NULL; | 236 | return NULL; |
201 | } | 237 | } |
238 | |||
239 | // Search for floating workspaces | ||
202 | int i; | 240 | int i; |
241 | if (parent->type == C_WORKSPACE) { | ||
242 | for (i = 0; i < parent->floating->length; ++i) { | ||
243 | swayc_t *child = parent->floating->items[i]; | ||
244 | if (child->handle == handle) { | ||
245 | return child; | ||
246 | } | ||
247 | } | ||
248 | } | ||
249 | |||
203 | for (i = 0; i < parent->children->length; ++i) { | 250 | for (i = 0; i < parent->children->length; ++i) { |
204 | swayc_t *child = parent->children->items[i]; | 251 | swayc_t *child = parent->children->items[i]; |
205 | if (child->handle == handle) { | 252 | if (child->handle == handle) { |
diff --git a/sway/workspace.c b/sway/workspace.c index 4db75f48..df646445 100644 --- a/sway/workspace.c +++ b/sway/workspace.c | |||
@@ -255,5 +255,18 @@ void layout_log(const swayc_t *c, int depth) { | |||
255 | for (i = 0; i < depth; ++i) fputc(' ', stderr); | 255 | for (i = 0; i < depth; ++i) fputc(' ', stderr); |
256 | fprintf(stderr,")\n"); | 256 | fprintf(stderr,")\n"); |
257 | } | 257 | } |
258 | if (c->type == C_WORKSPACE) { | ||
259 | e = c->floating?c->floating->length:0; | ||
260 | for (i = 0; i < depth; ++i) fputc(' ', stderr); | ||
261 | if (e) { | ||
262 | for (i = 0; i < depth; ++i) fputc(' ', stderr); | ||
263 | fprintf(stderr,"(\n"); | ||
264 | for (i = 0; i < e; ++i) { | ||
265 | layout_log(c->floating->items[i], depth + 1); | ||
266 | } | ||
267 | for (i = 0; i < depth; ++i) fputc(' ', stderr); | ||
268 | fprintf(stderr,")\n"); | ||
269 | } | ||
270 | } | ||
258 | } | 271 | } |
259 | /* XXX:DEBUG:XXX */ | 272 | /* XXX:DEBUG:XXX */ |