commit 28ab10b

wf  ·  2026-04-17 11:13:39 +0000 UTC
parent 98633bd
Add window IDs, clean up howlc manpage
8 files changed,  +68, -82
M howl.c
M ipc.c
+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 -------
+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