Skip to content

Commit 90fbc71

Browse files
committed
Don't skip identically numbered workspaces when moving to next/prev
eg if you have workspaces: { 1, 2:a, 2:b, 3 } and are on workspace 1, then 'workspace next' should traverse 1 -> 2:a -> 2:b -> 3 -> 1 instead of 1 -> 2:a -> 3 -> 1.
1 parent eada44b commit 90fbc71

File tree

4 files changed

+142
-8
lines changed

4 files changed

+142
-8
lines changed

src/workspace.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,7 @@ Con *workspace_next(void) {
588588
}
589589
} else {
590590
/* If currently a numbered workspace, find next numbered workspace. */
591+
bool found_current = false;
591592
TAILQ_FOREACH (output, &(croot->nodes_head), nodes) {
592593
/* Skip outputs starting with __, they are internal. */
593594
if (con_is_internal(output))
@@ -606,6 +607,14 @@ Con *workspace_next(void) {
606607
* relative order between the list of workspaces. */
607608
if (current->num < child->num && (!next || child->num < next->num))
608609
next = child;
610+
611+
/* If two workspaces have the same number, but different names
612+
* (eg '5:a', '5:b') then just take the next one. */
613+
if (child == current) {
614+
found_current = true;
615+
} else if (found_current && current->num == child->num) {
616+
return child;
617+
}
609618
}
610619
}
611620
}
@@ -654,6 +663,7 @@ Con *workspace_prev(void) {
654663
}
655664
} else {
656665
/* If numbered workspace, find previous numbered workspace. */
666+
bool found_current = false;
657667
TAILQ_FOREACH_REVERSE (output, &(croot->nodes_head), nodes_head, nodes) {
658668
/* Skip outputs starting with __, they are internal. */
659669
if (con_is_internal(output))
@@ -672,6 +682,14 @@ Con *workspace_prev(void) {
672682
* the relative order between the list of workspaces. */
673683
if (current->num > child->num && (!prev || child->num > prev->num))
674684
prev = child;
685+
686+
/* If two workspaces have the same number, but different names
687+
* (eg '5:a', '5:b') then just take the previous one. */
688+
if (child == current) {
689+
found_current = true;
690+
} else if (found_current && current->num == child->num) {
691+
return child;
692+
}
675693
}
676694
}
677695
}
@@ -696,6 +714,7 @@ Con *workspace_next_on_output(void) {
696714
next = TAILQ_NEXT(current, nodes);
697715
} else {
698716
/* If currently a numbered workspace, find next numbered workspace. */
717+
bool found_current = false;
699718
NODES_FOREACH (output_get_content(output)) {
700719
if (child->type != CT_WORKSPACE)
701720
continue;
@@ -706,6 +725,14 @@ Con *workspace_next_on_output(void) {
706725
* relative order between the list of workspaces. */
707726
if (current->num < child->num && (!next || child->num < next->num))
708727
next = child;
728+
729+
/* If two workspaces have the same number, but different names
730+
* (eg '5:a', '5:b') then just take the next one. */
731+
if (child == current) {
732+
found_current = true;
733+
} else if (found_current && current->num == child->num) {
734+
return child;
735+
}
709736
}
710737
}
711738

@@ -754,6 +781,7 @@ Con *workspace_prev_on_output(void) {
754781
prev = NULL;
755782
} else {
756783
/* If numbered workspace, find previous numbered workspace. */
784+
bool found_current = false;
757785
NODES_FOREACH_REVERSE (output_get_content(output)) {
758786
if (child->type != CT_WORKSPACE || child->num == -1)
759787
continue;
@@ -762,6 +790,14 @@ Con *workspace_prev_on_output(void) {
762790
* the relative order between the list of workspaces. */
763791
if (current->num > child->num && (!prev || child->num > prev->num))
764792
prev = child;
793+
794+
/* If two workspaces have the same number, but different names
795+
* (eg '5:a', '5:b') then just take the previous one. */
796+
if (child == current) {
797+
found_current = true;
798+
} else if (found_current && current->num == child->num) {
799+
return child;
800+
}
765801
}
766802
}
767803

testcases/t/503-workspace.t

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ is(focused_ws, '2', 'workspace 2 on second output');
4141
# ensure workspace 2 stays open
4242
open_window;
4343

44+
cmd 'workspace 6:c';
45+
# ensure workspace 6:c stays open
46+
open_window;
47+
4448
cmd 'focus output right';
4549
is(focused_ws, '1', 'back on workspace 1');
4650

@@ -50,13 +54,25 @@ cmd 'workspace 5';
5054
# ensure workspace 5 stays open
5155
open_window;
5256

57+
# numbered w/ name workspaces must be created in reverse order compared to
58+
# other workspace types (because a new numbered w/ name workspace is prepended
59+
# to the list of similarly numbered workspaces).
60+
61+
cmd 'workspace 6:b';
62+
# ensure workspace 5 stays open
63+
open_window;
64+
65+
cmd 'workspace 6:a';
66+
# ensure workspace 5 stays open
67+
open_window;
68+
5369
################################################################################
5470
# Use workspace next and verify the correct order.
5571
################################################################################
5672

5773
# The current order should be:
58-
# output 1: 1, 5
59-
# output 2: 2
74+
# output 1: 1, 5, 6:a, 6:b
75+
# output 2: 2, 6:c
6076
cmd 'workspace 1';
6177
cmd 'workspace next';
6278
# We need to sync after changing focus to a different output to wait for the
@@ -72,6 +88,27 @@ cmd 'workspace next';
7288
sync_with_i3;
7389

7490
is(focused_ws, '5', 'workspace 5 focused');
91+
cmd 'workspace next';
92+
# We need to sync after changing focus to a different output to wait for the
93+
# EnterNotify to be processed, otherwise it will be processed at some point
94+
# later in time and mess up our subsequent tests.
95+
sync_with_i3;
96+
97+
is(focused_ws, '6:a', 'workspace 6:a focused');
98+
cmd 'workspace next';
99+
# We need to sync after changing focus to a different output to wait for the
100+
# EnterNotify to be processed, otherwise it will be processed at some point
101+
# later in time and mess up our subsequent tests.
102+
sync_with_i3;
103+
104+
is(focused_ws, '6:b', 'workspace 6:b focused');
105+
cmd 'workspace next';
106+
# We need to sync after changing focus to a different output to wait for the
107+
# EnterNotify to be processed, otherwise it will be processed at some point
108+
# later in time and mess up our subsequent tests.
109+
sync_with_i3;
110+
111+
is(focused_ws, '6:c', 'workspace 6:b focused');
75112

76113
################################################################################
77114
# Now try the same with workspace next_on_output.
@@ -81,8 +118,16 @@ cmd 'workspace 1';
81118
cmd 'workspace next_on_output';
82119
is(focused_ws, '5', 'workspace 5 focused');
83120
cmd 'workspace next_on_output';
121+
is(focused_ws, '6:a', 'workspace 6:a focused');
122+
cmd 'workspace next_on_output';
123+
is(focused_ws, '6:b', 'workspace 6:b focused');
124+
cmd 'workspace next_on_output';
84125
is(focused_ws, '1', 'workspace 1 focused');
85126

127+
cmd 'workspace prev_on_output';
128+
is(focused_ws, '6:b', 'workspace 6:b focused');
129+
cmd 'workspace prev_on_output';
130+
is(focused_ws, '6:a', 'workspace 6:a focused');
86131
cmd 'workspace prev_on_output';
87132
is(focused_ws, '5', 'workspace 5 focused');
88133
cmd 'workspace prev_on_output';
@@ -94,6 +139,9 @@ cmd 'workspace 2';
94139
# later in time and mess up our subsequent tests.
95140
sync_with_i3;
96141

142+
cmd 'workspace prev_on_output';
143+
is(focused_ws, '6:c', 'workspace 6:c focused');
144+
97145
cmd 'workspace prev_on_output';
98146
is(focused_ws, '2', 'workspace 2 focused');
99147

testcases/t/528-workspace-next-prev-reversed.t

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@ sync_with_i3;
5656
# Setup workspaces so that they stay open (with an empty container).
5757
# open_window ensures, this
5858
#
59-
# numbered named
60-
# output 1 (left) : 1, 2, 3, 6, 7, B, F, C
61-
# output 2 (right): 4, 5, A, D, E
59+
# numbered numbered w/ names named
60+
# output 1 (left): 4, 5, 8:d, 8:e, A, D, E
61+
# output 2 (right): 1, 2, 3, 6, 7, 8:a, 8:b, 8:c B, F, C
6262
#
6363
################################################################################
6464

@@ -68,6 +68,11 @@ cmd 'workspace D'; open_window;
6868
cmd 'workspace 4'; open_window;
6969
cmd 'workspace 5'; open_window;
7070
cmd 'workspace E'; open_window;
71+
# numbered w/ name workspaces must be created in reverse order compared to
72+
# other workspace types (because a new numbered w/ name workspace is prepended
73+
# to the list of similarly numbered workspaces).
74+
cmd 'workspace 8:e'; open_window;
75+
cmd 'workspace 8:d'; open_window;
7176

7277
cmd 'focus output right';
7378
cmd 'workspace 1'; open_window;
@@ -78,10 +83,18 @@ cmd 'workspace F'; open_window;
7883
cmd 'workspace 6'; open_window;
7984
cmd 'workspace C'; open_window;
8085
cmd 'workspace 7'; open_window;
86+
# numbered w/ name workspaces must be created in reverse order compared to
87+
# other workspace types (because a new numbered w/ name workspace is prepended
88+
# to the list of similarly numbered workspaces).
89+
cmd 'workspace 8:c'; open_window;
90+
cmd 'workspace 8:b'; open_window;
91+
cmd 'workspace 8:a'; open_window;
8192

8293
################################################################################
8394
# Use workspace next and verify the correct order.
8495
# numbered -> numerical sort
96+
# numbered w/ names -> numerical sort. Workspaces with the same number but
97+
# different names sort by output, followed by creation time on each output.
8598
# named -> sort by creation time
8699
################################################################################
87100
cmd 'workspace 1';
@@ -94,6 +107,12 @@ assert_next('5');
94107
assert_next('6');
95108
assert_next('7');
96109

110+
assert_next('8:a');
111+
assert_next('8:b');
112+
assert_next('8:c');
113+
assert_next('8:d');
114+
assert_next('8:e');
115+
97116
assert_next('B');
98117
assert_next('F');
99118
assert_next('C');
@@ -112,6 +131,12 @@ assert_prev('C');
112131
assert_prev('F');
113132
assert_prev('B');
114133

134+
assert_prev('8:e');
135+
assert_prev('8:d');
136+
assert_prev('8:c');
137+
assert_prev('8:b');
138+
assert_prev('8:a');
139+
115140
assert_prev('7');
116141
assert_prev('6');
117142
assert_prev('5');

testcases/t/535-workspace-next-prev.t

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@ sync_with_i3;
5656
# Setup workspaces so that they stay open (with an empty container).
5757
# open_window ensures, this
5858
#
59-
# numbered named
60-
# output 1 (left) : 1, 2, 3, 6, 7, B, F, C
61-
# output 2 (right): 4, 5, A, D, E
59+
# numbered numbered w/ names named
60+
# output 1 (left) : 1, 2, 3, 6, 7, 8:a, 8:b, 8:c B, F, C
61+
# output 2 (right): 4, 5, 8:d, 8:e, A, D, E
6262
#
6363
################################################################################
6464

@@ -68,6 +68,11 @@ cmd 'workspace D'; open_window;
6868
cmd 'workspace 4'; open_window;
6969
cmd 'workspace 5'; open_window;
7070
cmd 'workspace E'; open_window;
71+
# numbered w/ name workspaces must be created in reverse order compared to
72+
# other workspace types (because a new numbered w/ name workspace is prepended
73+
# to the list of similarly numbered workspaces).
74+
cmd 'workspace 8:e'; open_window;
75+
cmd 'workspace 8:d'; open_window;
7176

7277
cmd 'focus output left';
7378
cmd 'workspace 1'; open_window;
@@ -78,10 +83,18 @@ cmd 'workspace F'; open_window;
7883
cmd 'workspace 6'; open_window;
7984
cmd 'workspace C'; open_window;
8085
cmd 'workspace 7'; open_window;
86+
# numbered w/ name workspaces must be created in reverse order compared to
87+
# other workspace types (because a new numbered w/ name workspace is prepended
88+
# to the list of similarly numbered workspaces).
89+
cmd 'workspace 8:c'; open_window;
90+
cmd 'workspace 8:b'; open_window;
91+
cmd 'workspace 8:a'; open_window;
8192

8293
################################################################################
8394
# Use workspace next and verify the correct order.
8495
# numbered -> numerical sort
96+
# numbered w/ names -> numerical sort. Workspaces with the same number but
97+
# different names sort by output, followed by creation time on each output.
8598
# named -> sort by creation time
8699
################################################################################
87100
cmd 'workspace 1';
@@ -94,6 +107,12 @@ assert_next('5');
94107
assert_next('6');
95108
assert_next('7');
96109

110+
assert_next('8:a');
111+
assert_next('8:b');
112+
assert_next('8:c');
113+
assert_next('8:d');
114+
assert_next('8:e');
115+
97116
assert_next('B');
98117
assert_next('F');
99118
assert_next('C');
@@ -112,6 +131,12 @@ assert_prev('C');
112131
assert_prev('F');
113132
assert_prev('B');
114133

134+
assert_prev('8:e');
135+
assert_prev('8:d');
136+
assert_prev('8:c');
137+
assert_prev('8:b');
138+
assert_prev('8:a');
139+
115140
assert_prev('7');
116141
assert_prev('6');
117142
assert_prev('5');

0 commit comments

Comments
 (0)