Fix scratchpad_show Test if window is in scratchpad Test if function is called without criteria Updated testcase
Patch status: superseded
Patch by Philippe Virouleau
To apply this patch, use:
curl http://cr.i3wm.org/patch/115/raw.patch | git am
b/src/scratchpad.c
16 |
@@ -88,12 +88,23 @@ void scratchpad_show(Con *con) { |
17 |
con_toggle_fullscreen(focused, CF_OUTPUT); |
18 |
} |
19 |
|
20 |
+ /* If this was 'scratchpad show' without criteria, we check if the |
21 |
+ * currently focused window is a scratchpad window and should be hidden |
22 |
+ * again. */ |
23 |
+ if (!con && |
24 |
+ (floating = con_inside_floating(focused)) && |
25 |
+ floating->scratchpad_state != SCRATCHPAD_NONE) { |
26 |
+ DLOG("Focused window is a scratchpad window, hiding it.\n"); |
27 |
+ scratchpad_move(focused); |
28 |
+ return; |
29 |
+ } |
30 |
+ |
31 |
/* If this was 'scratchpad show' without criteria, we check if there is a |
32 |
* unfocused scratchpad on the current workspace and focus it */ |
33 |
Con *walk_con; |
34 |
Con *focused_ws = con_get_workspace(focused); |
35 |
TAILQ_FOREACH(walk_con, &(focused_ws->floating_head), floating_windows) { |
36 |
- if ((floating = con_inside_floating(walk_con)) && |
37 |
+ if (!con && (floating = con_inside_floating(walk_con)) && |
38 |
floating->scratchpad_state != SCRATCHPAD_NONE && |
39 |
floating != con_inside_floating(focused)) { |
40 |
DLOG("Found an unfocused scratchpad window on this workspace\n"); |
41 |
@@ -112,7 +123,7 @@ void scratchpad_show(Con *con) { |
42 |
focused_ws = con_get_workspace(focused); |
43 |
TAILQ_FOREACH(walk_con, &all_cons, all_cons) { |
44 |
Con *walk_ws = con_get_workspace(walk_con); |
45 |
- if (walk_ws && |
46 |
+ if (!con && walk_ws && |
47 |
!con_is_internal(walk_ws) && focused_ws != walk_ws && |
48 |
(floating = con_inside_floating(walk_con)) && |
49 |
floating->scratchpad_state != SCRATCHPAD_NONE) { |
50 |
@@ -123,14 +134,10 @@ void scratchpad_show(Con *con) { |
51 |
} |
52 |
} |
53 |
|
54 |
- /* If this was 'scratchpad show' without criteria, we check if the |
55 |
- * currently focused window is a scratchpad window and should be hidden |
56 |
- * again. */ |
57 |
- if (!con && |
58 |
- (floating = con_inside_floating(focused)) && |
59 |
- floating->scratchpad_state != SCRATCHPAD_NONE) { |
60 |
- DLOG("Focused window is a scratchpad window, hiding it.\n"); |
61 |
- scratchpad_move(focused); |
62 |
+ /* If this was 'scratchpad show' with criteria, we check if the window |
63 |
+ * is actually in the scratchpad */ |
64 |
+ if (con && con->parent->scratchpad_state == SCRATCHPAD_NONE) { |
65 |
+ DLOG("Window is not in the scratchpad, doing nothing.\n"); |
66 |
return; |
67 |
} |
68 |
|
b/testcases/t/202-scratchpad-criteria.t
73 |
@@ -17,26 +17,35 @@ |
74 |
# Verifies that using criteria to address scratchpad windows works. |
75 |
use i3test; |
76 |
|
77 |
-################################################################################ |
78 |
+##################################################################### |
79 |
# Verify that using scratchpad show with criteria works as expected: |
80 |
-# When matching a scratchpad window which is visible, it should hide it. |
81 |
-# When matching a scratchpad window which is on __i3_scratch, it should show it. |
82 |
-# When matching a non-scratchpad window, it should be a no-op. |
83 |
-################################################################################ |
84 |
+# - When matching a scratchpad window which is visible, |
85 |
+# it should hide it. |
86 |
+# - When matching a scratchpad window which is on __i3_scratch, |
87 |
+# it should show it. |
88 |
+# - When matching a non-scratchpad window, it should be a no-op. |
89 |
+# - When matching a scratchpad window, |
90 |
+# non-matching windows shouldn't appear |
91 |
+###################################################################### |
92 |
|
93 |
my $tmp = fresh_workspace; |
94 |
|
95 |
my $third_window = open_window(name => 'scratch-match'); |
96 |
cmd 'move scratchpad'; |
97 |
|
98 |
-# Verify that using 'scratchpad show' without any matching windows is a no-op. |
99 |
+##################################################################### |
100 |
+# Verify that using 'scratchpad show' without any matching windows is |
101 |
+# a no-op. |
102 |
+##################################################################### |
103 |
my $old_focus = get_focused($tmp); |
104 |
|
105 |
cmd '[title="nomatch"] scratchpad show'; |
106 |
|
107 |
is(get_focused($tmp), $old_focus, 'non-matching criteria have no effect'); |
108 |
|
109 |
+##################################################################### |
110 |
# Verify that we can use criteria to show a scratchpad window. |
111 |
+##################################################################### |
112 |
cmd '[title="scratch-match"] scratchpad show'; |
113 |
|
114 |
my $scratch_focus = get_focused($tmp); |
115 |
@@ -47,12 +56,102 @@ cmd '[title="scratch-match"] scratchpad show'; |
116 |
isnt(get_focused($tmp), $scratch_focus, 'matching criteria works'); |
117 |
is(get_focused($tmp), $old_focus, 'focus restored'); |
118 |
|
119 |
+ |
120 |
+##################################################################### |
121 |
# Verify that we cannot use criteria to show a non-scratchpad window. |
122 |
+##################################################################### |
123 |
my $tmp2 = fresh_workspace; |
124 |
my $non_scratch_window = open_window(name => 'non-scratch'); |
125 |
cmd "workspace $tmp"; |
126 |
is(get_focused($tmp), $old_focus, 'focus still ok'); |
127 |
-cmd '[title="non-match"] scratchpad show'; |
128 |
+cmd '[title="non-scratch"] scratchpad show'; |
129 |
is(get_focused($tmp), $old_focus, 'focus unchanged'); |
130 |
|
131 |
+##################################################################### |
132 |
+# Verify that non-matching windows doesn't appear |
133 |
+##################################################################### |
134 |
+# Subroutine to clear scratchpad |
135 |
+sub clear_scratchpad { |
136 |
+ while (scalar @{get_ws('__i3_scratch')->{floating_nodes}}) { |
137 |
+ cmd 'scratchpad show'; |
138 |
+ cmd 'kill'; |
139 |
+ } |
140 |
+} |
141 |
+ |
142 |
+#Start from an empty fresh workspace |
143 |
+my $empty_ws = fresh_workspace; |
144 |
+cmd "workspace $empty_ws"; |
145 |
+ |
146 |
+my $no_focused = get_focused($empty_ws); |
147 |
+cmd '[title="nothingmatchthistitle"] scratchpad show'; |
148 |
+#Check nothing match |
149 |
+is(get_focused($empty_ws), $no_focused, "no window to focus on"); |
150 |
+ |
151 |
+clear_scratchpad; |
152 |
+ |
153 |
+open_window(name => "my-scratch-window"); |
154 |
+my $w1_focus = get_focused($empty_ws); |
155 |
+cmd 'move scratchpad'; |
156 |
+cmd '[title="my-scratch-window"] scratchpad show'; |
157 |
+#Check we created and shown a scratchpad window |
158 |
+is(get_focused($empty_ws), $w1_focus, "focus on scratchpad window"); |
159 |
+ |
160 |
+#Switching workspace |
161 |
+my $empty_ws2 = fresh_workspace; |
162 |
+cmd "workspace $empty_ws2"; |
163 |
+open_window(name => "my-second-scratch-window"); |
164 |
+ |
165 |
+my $w2_focus = get_focused($empty_ws2); |
166 |
+cmd 'move scratchpad'; |
167 |
+cmd '[title="my-second-scratch-window"] scratchpad show'; |
168 |
+ |
169 |
+#Check we got the correct window |
170 |
+is(get_focused($empty_ws2), $w2_focus, "focus is on second window"); |
171 |
+ |
172 |
+##################################################################### |
173 |
+# Verify that 'scratchpad show' correctly hide multiple scratchpad |
174 |
+# windows |
175 |
+##################################################################### |
176 |
+clear_scratchpad; |
177 |
+ |
178 |
+sub check_floating { |
179 |
+ my($rws, $n) = @_; |
180 |
+ my $ws = get_ws($rws); |
181 |
+ is(scalar @{$ws->{nodes}}, 0, 'no windows on ws'); |
182 |
+ is(scalar @{$ws->{floating_nodes}}, $n, "$n floating windows on ws"); |
183 |
+} |
184 |
+ |
185 |
+my $empty_ws3 = fresh_workspace; |
186 |
+cmd "workspace $empty_ws3"; |
187 |
+ |
188 |
+check_floating($empty_ws3, 0); |
189 |
+ |
190 |
+#Creating two scratchpad windows |
191 |
+open_window(name => "toggle-1"); |
192 |
+cmd 'move scratchpad'; |
193 |
+open_window(name => "toggle-2"); |
194 |
+cmd 'move scratchpad'; |
195 |
+check_floating($empty_ws3, 0); |
196 |
+#Showing both |
197 |
+cmd '[title="toggle-"] scratchpad show'; |
198 |
+ |
199 |
+check_floating($empty_ws3, 2); |
200 |
+ |
201 |
+#Hiding both |
202 |
+cmd '[title="toggle-"] scratchpad show'; |
203 |
+check_floating($empty_ws3, 0); |
204 |
+ |
205 |
+#Showing both again |
206 |
+cmd '[title="toggle-"] scratchpad show'; |
207 |
+check_floating($empty_ws3, 2); |
208 |
+ |
209 |
+ |
210 |
+#Hiding one |
211 |
+cmd 'scratchpad show'; |
212 |
+check_floating($empty_ws3, 1); |
213 |
+ |
214 |
+#Hiding the last |
215 |
+cmd 'scratchpad show'; |
216 |
+check_floating($empty_ws3, 0); |
217 |
+ |
218 |
done_testing; |