commit 28ab10b
wf
·
2026-04-17 11:13:39 +0000 UTC
parent 98633bd
Add window IDs, clean up howlc manpage
+3,
-1
1@@ -10,7 +10,9 @@ See the `howl` and `howlc` manual pages for more information on usage.
2 TODO
3 ----
4
5- * Eyecandy: titlebars and double borders
6+ * Sort window list output by window stack order
7+ * Add optional window ID flags to `get_*` commands
8+ * Titlebars
9
10 CREDITS
11 -------
M
client.c
+2,
-0
1@@ -37,7 +37,9 @@ static const struct command commands[] = {
2 { "get_pid", cmd_get_pid, 0, false },
3 { "get_title", cmd_get_title, 0, false },
4 { "get_app_id", cmd_get_app_id, 0, false },
5+ { "get_focus", cmd_get_focus, 0, false },
6 { "get_workspace", cmd_get_workspace, 0, false },
7+ { "list_windows", cmd_list_windows, 0, false },
8 { "bind", cmd_bind, 2, false },
9 { "modkey", cmd_modkey, 1, true },
10 { "inner_focus_color", cmd_inner_focus_color, 1, true },
+13,
-54
1@@ -14,12 +14,8 @@ Will move the window relative to either its current position or to the top left
2 .IP
3 Example:
4 .IP
5-# Shift the window 20px forward and 40px up
6-.br
7 $ howlc move 20 \-40
8 .IP
9-# Move the window to absolute coordinates [300, 300]
10-.br
11 $ howlc move_absolute 300 300
12 .TP
13 \fBresize\fR, \fBresize_absolute\fR
14@@ -27,12 +23,8 @@ Will resize the window relative to either its current position or the top left c
15 .IP
16 Example:
17 .IP
18-# Grow the window 20px forward and shrink it 40px up
19-.br
20 $ howlc resize 20 \-40
21 .IP
22-# Resize the window to the absolute size [300, 300]
23-.br
24 $ howlc resize_absolute 300 300
25 .TP
26 \fBteleport\fR
27@@ -40,8 +32,6 @@ Will "teleport" (move and resize) the window to the coordinates specified, in th
28 .IP
29 Example:
30 .IP
31-# Move the window to [50, 25] and resize it to [200, 250]
32-.br
33 $ howlc teleport 50 25 200 250
34 .TP
35 \fBcenter\fR
36@@ -49,8 +39,6 @@ Will position the window in the center of the screen\.
37 .IP
38 Example:
39 .IP
40-# Move the window to the center of the screen
41-.br
42 $ howlc center
43 .TP
44 \fBfullscreen\fR
45@@ -58,8 +46,6 @@ Will resize the window to the screen size\.
46 .IP
47 Example:
48 .IP
49-# Put the window in fullscreen mode
50-.br
51 $ howlc fullscreen
52 .TP
53 \fBhide\fR, \fBshow\fR
54@@ -67,12 +53,8 @@ Hide/show the current window\. Currently these don't have much use\.
55 .IP
56 Example:
57 .IP
58-# Hide (unmap) the current window
59-.br
60 $ howlc hide
61 .IP
62-# And now show (map) it
63-.br
64 $ howlc show
65 .TP
66 \fBfocus_prev\fR, \fBfocus_next\fR
67@@ -80,12 +62,8 @@ Focus the previous/next window\.
68 .IP
69 Example:
70 .IP
71-# Focus the previous window
72-.br
73 $ howlc focus_prev
74 .IP
75-# And the next
76-.br
77 $ howlc focus_next
78 .TP
79 \fBlower\fR, \fBraise\fR
80@@ -93,12 +71,8 @@ Lower/raise the window's stack order\.
81 .IP
82 Example:
83 .IP
84-# Lower the current window
85-.br
86 $ howlc lower
87 .IP
88-# And then raise it
89-.br
90 $ howlc raise
91 .TP
92 \fBclose\fR
93@@ -106,8 +80,6 @@ Closes the window\.
94 .IP
95 Example:
96 .IP
97-# Close the current window
98-.br
99 $ howlc close
100 .TP
101 \fBworkspace\fR, \fBmove_workspace\fR
102@@ -115,12 +87,8 @@ Switch, or move the current window, to the specified workspace\. Argument is a s
103 .IP
104 Example:
105 .IP
106-# Switch to the 3rd workspace
107-.br
108 $ howlc workspace 3
109 .IP
110-# Move the current window to the 6th workspace
111-.br
112 $ howlc move_workspace 6
113 .TP
114 \fBget_geometry\fR, \fBget_pid\fR, \fBget_title\fR, \fBget_app_id\fR
115@@ -128,30 +96,35 @@ Print the current window's geometry (in x, y, w and h), process ID, title or app
116 .IP
117 Example:
118 .IP
119-# Get the current window's geometry
120-.br
121 $ howlc get_geometry
122 .br
123 327 148 620 620
124 .IP
125-# Get the current window's process ID
126-.br
127 $ howlc get_pid
128 .br
129 12345
130 .IP
131-# Get the current window's title
132-.br
133 $ howlc get_title
134 .br
135 Example
136 .IP
137-# Get the current window's app ID
138-.br
139 $ howlc get_app_id
140 .br
141 example
142 .TP
143+\fBlist_windows\fR
144+Print a list of currently open windows (both visible and invisible)\.
145+.IP
146+Example:
147+.IP
148+$ howlc list_windows
149+.br
150+0
151+.br
152+21
153+.br
154+25
155+.TP
156 \fBbind\fR
157 Create a key binding\. Arguments are in the form of a list of keys and the command to execute, see the \fIBINDINGS\fR section for more info\.
158 .IP
159@@ -170,12 +143,8 @@ Configure the modifier key\. This can be then used as an alias in keybindings, l
160 .IP
161 Example:
162 .IP
163-# Configure the modifier key to Alt
164-.br
165 $ howlc modkey alt
166 .IP
167-# Configure the modifier key to Win+Ctrl
168-.br
169 $ howlc modkey win+ctrl
170 .TP
171 \fBfocus_color\fR, \fBunfocus_color\fR
172@@ -183,12 +152,8 @@ Set the focused and unfocused colors of the window borders\. Arguments are in th
173 .IP
174 Example:
175 .IP
176-# Set the focused color to a shade of red
177-.br
178 $ howlc focus_color "#f03937"
179 .IP
180-# Set the unfocused color to a bright white
181-.br
182 $ howlc unfocus_color eeeeee
183 .TP
184 \fBborder_width\fR
185@@ -196,12 +161,8 @@ Set the window's border width\. Argument is a single integer representing the ne
186 .IP
187 Example:
188 .IP
189-# Set the border width to 4px
190-.br
191 $ howlc border_width 4
192 .IP
193-# Set the border width to 0px, essentially disabling borders
194-.br
195 $ howlc border_width 0
196 .TP
197 \fBquit\fR
198@@ -209,8 +170,6 @@ Quit the compositor\.
199 .IP
200 Example:
201 .IP
202-# Terminate the Wayland display, cleanup and exit
203-.br
204 $ howlc quit
205 .SH "BINDINGS"
206 The format for keybindings is the following:
+10,
-27
1@@ -18,10 +18,8 @@ howlc(1) -- client to control the howl compositor
2
3 Example:
4
5- \# Shift the window 20px forward and 40px up<br>
6 $ howlc move 20 -40
7
8- \# Move the window to absolute coordinates [300, 300]<br>
9 $ howlc move_absolute 300 300
10
11 * `resize`, `resize_absolute`:
12@@ -31,10 +29,8 @@ howlc(1) -- client to control the howl compositor
13
14 Example:
15
16- \# Grow the window 20px forward and shrink it 40px up<br>
17 $ howlc resize 20 -40
18
19- \# Resize the window to the absolute size [300, 300]<br>
20 $ howlc resize_absolute 300 300
21
22 * `teleport`:
23@@ -43,7 +39,6 @@ howlc(1) -- client to control the howl compositor
24
25 Example:
26
27- \# Move the window to [50, 25] and resize it to [200, 250]<br>
28 $ howlc teleport 50 25 200 250
29
30 * `center`:
31@@ -51,7 +46,6 @@ howlc(1) -- client to control the howl compositor
32
33 Example:
34
35- \# Move the window to the center of the screen<br>
36 $ howlc center
37
38 * `fullscreen`:
39@@ -59,7 +53,6 @@ howlc(1) -- client to control the howl compositor
40
41 Example:
42
43- \# Put the window in fullscreen mode<br>
44 $ howlc fullscreen
45
46 * `hide`, `show`:
47@@ -67,10 +60,8 @@ howlc(1) -- client to control the howl compositor
48
49 Example:
50
51- \# Hide (unmap) the current window<br>
52 $ howlc hide
53
54- \# And now show (map) it<br>
55 $ howlc show
56
57 * `focus_prev`, `focus_next`:
58@@ -78,10 +69,8 @@ howlc(1) -- client to control the howl compositor
59
60 Example:
61
62- \# Focus the previous window<br>
63 $ howlc focus_prev
64
65- \# And the next<br>
66 $ howlc focus_next
67
68 * `lower`, `raise`:
69@@ -89,10 +78,8 @@ howlc(1) -- client to control the howl compositor
70
71 Example:
72
73- \# Lower the current window<br>
74 $ howlc lower
75
76- \# And then raise it<br>
77 $ howlc raise
78
79 * `close`:
80@@ -100,7 +87,6 @@ howlc(1) -- client to control the howl compositor
81
82 Example:
83
84- \# Close the current window<br>
85 $ howlc close
86
87 * `workspace`, `move_workspace`:
88@@ -109,10 +95,8 @@ howlc(1) -- client to control the howl compositor
89
90 Example:
91
92- \# Switch to the 3rd workspace<br>
93 $ howlc workspace 3
94
95- \# Move the current window to the 6th workspace<br>
96 $ howlc move_workspace 6
97
98 * `get_geometry`, `get_pid`, `get_title`, `get_app_id`:
99@@ -120,22 +104,28 @@ howlc(1) -- client to control the howl compositor
100
101 Example:
102
103- \# Get the current window's geometry<br>
104 $ howlc get_geometry<br>
105 327 148 620 620
106
107- \# Get the current window's process ID<br>
108 $ howlc get_pid<br>
109 12345
110
111- \# Get the current window's title<br>
112 $ howlc get_title<br>
113 Example
114
115- \# Get the current window's app ID<br>
116 $ howlc get_app_id<br>
117 example
118
119+ * `list_windows`:
120+ Print a list of currently open windows (both visible and invisible).
121+
122+ Example:
123+
124+ $ howlc list_windows<br>
125+ 0<br>
126+ 21<br>
127+ 25
128+
129 * `bind`:
130 Create a key binding. Arguments are in the form of a list of keys and the command to execute,
131 see the [BINDINGS][] section for more info.
132@@ -154,10 +144,8 @@ howlc(1) -- client to control the howl compositor
133
134 Example:
135
136- \# Configure the modifier key to Alt<br>
137 $ howlc modkey alt
138
139- \# Configure the modifier key to Win+Ctrl<br>
140 $ howlc modkey win+ctrl
141
142 * `focus_color`, `unfocus_color`:
143@@ -167,10 +155,8 @@ howlc(1) -- client to control the howl compositor
144
145 Example:
146
147- \# Set the focused color to a shade of red<br>
148 $ howlc focus_color "#f03937"
149
150- \# Set the unfocused color to a bright white<br>
151 $ howlc unfocus_color eeeeee
152
153 * `border_width`:
154@@ -178,10 +164,8 @@ howlc(1) -- client to control the howl compositor
155
156 Example:
157
158- \# Set the border width to 4px<br>
159 $ howlc border_width 4
160
161- \# Set the border width to 0px, essentially disabling borders<br>
162 $ howlc border_width 0
163
164 * `quit`:
165@@ -189,7 +173,6 @@ howlc(1) -- client to control the howl compositor
166
167 Example:
168
169- \# Terminate the Wayland display, cleanup and exit<br>
170 $ howlc quit
171
172 ## BINDINGS
M
howl.c
+6,
-0
1@@ -42,7 +42,9 @@ extern status ipc_get_geometry(char **);
2 extern status ipc_get_pid(char **);
3 extern status ipc_get_title(char **);
4 extern status ipc_get_app_id(char **);
5+extern status ipc_get_focus(char **);
6 extern status ipc_get_workspace(char **);
7+extern status ipc_list_windows(char **);
8 extern status ipc_bind(char **);
9 extern status ipc_quit(char **);
10 extern status ipc_config(char **);
11@@ -86,7 +88,9 @@ static const cmd_handler_t cmd_handler [cmd_last] = {
12 [cmd_get_pid] = ipc_get_pid,
13 [cmd_get_title] = ipc_get_title,
14 [cmd_get_app_id] = ipc_get_app_id,
15+ [cmd_get_focus] = ipc_get_focus,
16 [cmd_get_workspace] = ipc_get_workspace,
17+ [cmd_list_windows] = ipc_list_windows,
18 [cmd_bind] = ipc_bind,
19 [cmd_quit] = ipc_quit,
20 [cmd_config] = ipc_config
21@@ -224,6 +228,7 @@ setup(void) {
22 wm.grab.resize = false;
23 wm.grab.client = NULL;
24 wm.ws = 1;
25+ wm.last_id = 0;
26
27 config.mod = SWC_MOD_LOGO;
28 config.if_color = 0xFF8777E5;
29@@ -479,6 +484,7 @@ new_window(struct swc_window *win) {
30 c->y = 0;
31 c->width = 0;
32 c->height = 0;
33+ c->id = wm.last_id++;
34
35 wl_list_insert(&wm.clients, &c->link);
36 swc_window_set_handler(win, &win_handler, c);
+2,
-0
1@@ -19,9 +19,11 @@ enum cmd {
2 cmd_workspace,
3 cmd_send_workspace,
4 cmd_get_geometry,
5+ cmd_list_windows,
6 cmd_get_pid,
7 cmd_get_title,
8 cmd_get_app_id,
9+ cmd_get_focus,
10 cmd_get_workspace,
11 cmd_bind,
12 cmd_modkey,
+1,
-0
1@@ -30,6 +30,7 @@ struct client {
2 int32_t x, y;
3 uint32_t width, height;
4 uint8_t ws;
5+ uint32_t id;
6 };
7
8 struct grab {
M
ipc.c
+31,
-0
1@@ -2,6 +2,7 @@
2 #include <string.h>
3 #include <stdlib.h>
4
5+#include <wayland-server.h>
6 #include <swc.h>
7 #include <xkbcommon/xkbcommon.h>
8
9@@ -359,6 +360,20 @@ ipc_get_app_id(char **arg) {
10 return s;
11 }
12
13+status
14+ipc_get_focus(char **arg) {
15+ status s = {0};
16+
17+ UNUSED(arg);
18+ if (!wm.cur)
19+ return (status){ false, "" };
20+
21+ snprintf(s.msg, MAXSIZE * sizeof(char), "%u\n", wm.cur->id);
22+
23+ s.ok = true;
24+ return s;
25+}
26+
27 status
28 ipc_get_workspace(char **arg) {
29 status s = {0};
30@@ -370,6 +385,22 @@ ipc_get_workspace(char **arg) {
31 return s;
32 }
33
34+status
35+ipc_list_windows(char **arg) {
36+ status s = {0};
37+
38+ UNUSED(arg);
39+ if (!wl_list_empty(&wm.clients)) {
40+ size_t o = 0;
41+ struct client *c;
42+ wl_list_for_each(c, &wm.clients, link)
43+ o += snprintf(s.msg + o, sizeof(s.msg) - o, "%u\n", c->id);
44+ }
45+
46+ s.ok = true;
47+ return s;
48+}
49+
50 /*********/
51
52 status