diff options
-rw-r--r-- | include/workspace.h | 8 | ||||
-rw-r--r-- | sway/commands.c | 8 | ||||
-rw-r--r-- | sway/workspace.c | 122 |
3 files changed, 74 insertions, 64 deletions
diff --git a/include/workspace.h b/include/workspace.h index d447ac2d..a731068d 100644 --- a/include/workspace.h +++ b/include/workspace.h | |||
@@ -9,9 +9,9 @@ char *workspace_next_name(void); | |||
9 | swayc_t *workspace_create(const char*); | 9 | swayc_t *workspace_create(const char*); |
10 | swayc_t *workspace_by_name(const char*); | 10 | swayc_t *workspace_by_name(const char*); |
11 | void workspace_switch(swayc_t*); | 11 | void workspace_switch(swayc_t*); |
12 | void workspace_output_next(); | 12 | swayc_t *workspace_output_next(); |
13 | void workspace_next(); | 13 | swayc_t *workspace_next(); |
14 | void workspace_output_prev(); | 14 | swayc_t *workspace_output_prev(); |
15 | void workspace_prev(); | 15 | swayc_t *workspace_prev(); |
16 | 16 | ||
17 | #endif | 17 | #endif |
diff --git a/sway/commands.c b/sway/commands.c index 23339b9d..74c19b5b 100644 --- a/sway/commands.c +++ b/sway/commands.c | |||
@@ -668,23 +668,23 @@ static bool cmd_workspace(struct sway_config *config, int argc, char **argv) { | |||
668 | if (argc == 1) { | 668 | if (argc == 1) { |
669 | // Handle workspace next/prev | 669 | // Handle workspace next/prev |
670 | if (strcmp(argv[0], "next") == 0) { | 670 | if (strcmp(argv[0], "next") == 0) { |
671 | workspace_next(); | 671 | workspace_switch(workspace_next()); |
672 | return true; | 672 | return true; |
673 | } | 673 | } |
674 | 674 | ||
675 | if (strcmp(argv[0], "prev") == 0) { | 675 | if (strcmp(argv[0], "prev") == 0) { |
676 | workspace_next(); | 676 | workspace_switch(workspace_prev()); |
677 | return true; | 677 | return true; |
678 | } | 678 | } |
679 | 679 | ||
680 | // Handle workspace output_next/prev | 680 | // Handle workspace output_next/prev |
681 | if (strcmp(argv[0], "next_on_output") == 0) { | 681 | if (strcmp(argv[0], "next_on_output") == 0) { |
682 | workspace_output_next(); | 682 | workspace_switch(workspace_output_next()); |
683 | return true; | 683 | return true; |
684 | } | 684 | } |
685 | 685 | ||
686 | if (strcmp(argv[0], "prev_on_output") == 0) { | 686 | if (strcmp(argv[0], "prev_on_output") == 0) { |
687 | workspace_output_prev(); | 687 | workspace_switch(workspace_output_prev()); |
688 | return true; | 688 | return true; |
689 | } | 689 | } |
690 | 690 | ||
diff --git a/sway/workspace.c b/sway/workspace.c index ca9f5ef0..252526ce 100644 --- a/sway/workspace.c +++ b/sway/workspace.c | |||
@@ -85,85 +85,95 @@ static bool _workspace_by_name(swayc_t *view, void *data) { | |||
85 | } | 85 | } |
86 | 86 | ||
87 | swayc_t *workspace_by_name(const char* name) { | 87 | swayc_t *workspace_by_name(const char* name) { |
88 | return swayc_by_test(&root_container, _workspace_by_name, (void *) name); | 88 | if (strcmp(name, "prev") == 0) { |
89 | return workspace_prev(); | ||
90 | } | ||
91 | else if (strcmp(name, "prev_on_output") == 0) { | ||
92 | return workspace_output_prev(); | ||
93 | } | ||
94 | else if (strcmp(name, "next") == 0) { | ||
95 | return workspace_next(); | ||
96 | } | ||
97 | else if (strcmp(name, "next_on_output") == 0) { | ||
98 | return workspace_output_next(); | ||
99 | } | ||
100 | else if (strcmp(name, "current") == 0) { | ||
101 | return swayc_active_workspace(); | ||
102 | } | ||
103 | else { | ||
104 | return swayc_by_test(&root_container, _workspace_by_name, (void *) name); | ||
105 | } | ||
89 | } | 106 | } |
90 | 107 | ||
91 | void workspace_output_next() { | 108 | /** |
92 | // Get the index of the workspace in the current output, and change the view to index+1 workspace. | 109 | * Get the previous or next workspace on the specified output. |
93 | // if we're currently focused on the last workspace in the output, switch to the first | 110 | * Wraps around at the end and beginning. |
94 | swayc_t *current_output = swayc_active_workspace()->parent; | 111 | * If next is false, the previous workspace is returned, otherwise the next one is returned. |
112 | */ | ||
113 | swayc_t *workspace_output_prev_next_impl(swayc_t *output, bool next) { | ||
114 | if (!sway_assert(output->type == C_OUTPUT, "Argument must be an output, is %d", output->type)) { | ||
115 | return NULL; | ||
116 | } | ||
117 | |||
95 | int i; | 118 | int i; |
96 | for (i = 0; i < current_output->children->length - 1; i++) { | 119 | for (i = 0; i < output->children->length; i++) { |
97 | if (strcmp((((swayc_t *)current_output->children->items[i])->name), swayc_active_workspace()->name) == 0) { | 120 | if (output->children->items[i] == output->focused) { |
98 | workspace_switch(current_output->children->items[i + 1]); | 121 | return output->children->items[wrap(i + (next ? 1 : -1), output->children->length)]; |
99 | return; | ||
100 | } | 122 | } |
101 | } | 123 | } |
102 | workspace_switch(current_output->children->items[0]); | 124 | |
125 | // Doesn't happen, at worst the for loop returns the previously active workspace | ||
126 | return NULL; | ||
103 | } | 127 | } |
104 | 128 | ||
105 | void workspace_next() { | 129 | /** |
106 | // Get the index of the workspace in the current output, and change the focus to index+1 workspace. | 130 | * Get the previous or next workspace. If the first/last workspace on an output is active, |
107 | // if we're currently focused on the last workspace in the output, change focus to the next output | 131 | * proceed to the previous/next output's previous/next workspace. |
108 | // and call workspace_output_next() | 132 | * If next is false, the previous workspace is returned, otherwise the next one is returned. |
133 | */ | ||
134 | swayc_t *workspace_prev_next_impl(swayc_t *workspace, bool next) { | ||
135 | if (!sway_assert(workspace->type == C_WORKSPACE, "Argument must be a workspace, is %d", workspace->type)) { | ||
136 | return NULL; | ||
137 | } | ||
109 | 138 | ||
110 | swayc_t *current_output = swayc_active_workspace()->parent; | 139 | swayc_t *current_output = workspace->parent; |
140 | int offset = next ? 1 : -1; | ||
141 | int start = next ? 0 : 1; | ||
142 | int end = next ? (current_output->children->length) - 1 : current_output->children->length; | ||
111 | int i; | 143 | int i; |
112 | for (i = 0; i < current_output->children->length - 1; i++) { | 144 | for (i = start; i < end; i++) { |
113 | if (current_output->children->items[i] == swayc_active_workspace()) { | 145 | if (current_output->children->items[i] == workspace) { |
114 | workspace_switch(current_output->children->items[i + 1]); | 146 | return current_output->children->items[i + offset]; |
115 | return; | ||
116 | } | 147 | } |
117 | } | 148 | } |
118 | 149 | ||
150 | // Given workspace is the first/last on the output, jump to the previous/next output | ||
119 | int num_outputs = root_container.children->length; | 151 | int num_outputs = root_container.children->length; |
120 | for (i = 0; i < num_outputs; i++) { | 152 | for (i = 0; i < num_outputs; i++) { |
121 | if (root_container.children->items[i] == current_output) { | 153 | if (root_container.children->items[i] == current_output) { |
122 | swayc_t *next_output = root_container.children->items[wrap(++i, num_outputs)]; | 154 | swayc_t *next_output = root_container.children->items[wrap(i + offset, num_outputs)]; |
123 | workspace_switch(next_output->focused); | 155 | return workspace_output_prev_next_impl(next_output, next); |
124 | workspace_output_next(); | ||
125 | return; | ||
126 | } | 156 | } |
127 | } | 157 | } |
158 | |||
159 | // Doesn't happen, at worst the for loop returns the previously active workspace on the active output | ||
160 | return NULL; | ||
128 | } | 161 | } |
129 | 162 | ||
130 | void workspace_output_prev() { | 163 | swayc_t *workspace_output_next() { |
131 | // Get the index of the workspace in the current output, and change the view to index+1 workspace | 164 | return workspace_output_prev_next_impl(swayc_active_output(), true); |
132 | // if we're currently focused on the first workspace in the output, do nothing and return false | ||
133 | swayc_t *current_output = swayc_active_workspace()->parent; | ||
134 | int i; | ||
135 | for (i = 1; i < current_output->children->length; i++) { | ||
136 | if (strcmp((((swayc_t *)current_output->children->items[i])->name), swayc_active_workspace()->name) == 0) { | ||
137 | workspace_switch(current_output->children->items[i - 1]); | ||
138 | return; | ||
139 | } | ||
140 | } | ||
141 | workspace_switch(current_output->children->items[current_output->children->length - 1]); | ||
142 | } | 165 | } |
143 | 166 | ||
144 | void workspace_prev() { | 167 | swayc_t *workspace_next() { |
145 | // Get the index of the workspace in the current output, and change the focus to index-1 workspace. | 168 | return workspace_prev_next_impl(swayc_active_workspace(), true); |
146 | // if we're currently focused on the first workspace in the output, change focus to the previous output | 169 | } |
147 | // and call workspace_output_prev() | ||
148 | 170 | ||
149 | swayc_t *current_output = swayc_active_workspace()->parent; | 171 | swayc_t *workspace_output_prev() { |
150 | int i; | 172 | return workspace_output_prev_next_impl(swayc_active_output(), false); |
151 | for (i = 1; i < current_output->children->length; i++) { | 173 | } |
152 | if (current_output->children->items[i] == swayc_active_workspace()) { | ||
153 | workspace_switch(current_output->children->items[i - 1]); | ||
154 | return; | ||
155 | } | ||
156 | } | ||
157 | 174 | ||
158 | int num_outputs = root_container.children->length; | 175 | swayc_t *workspace_prev() { |
159 | for (i = 0; i < num_outputs; i++) { | 176 | return workspace_prev_next_impl(swayc_active_workspace(), false); |
160 | if (root_container.children->items[i] == current_output) { | ||
161 | swayc_t *prev_output = root_container.children->items[wrap(--i, num_outputs)]; | ||
162 | workspace_switch(prev_output->focused); | ||
163 | workspace_output_prev(); | ||
164 | return; | ||
165 | } | ||
166 | } | ||
167 | } | 177 | } |
168 | 178 | ||
169 | void workspace_switch(swayc_t *workspace) { | 179 | void workspace_switch(swayc_t *workspace) { |