index.md - sites - public wiki contents of suckless.org | |
git clone git://git.suckless.org/sites | |
Log | |
Files | |
Refs | |
--- | |
index.md (10038B) | |
--- | |
1 # Dynamic, Command-Line Driven Window Swallowing for dwm | |
2 | |
3 This patch introduces "dynamic" window swallowing to dwm. In contrast to… | |
4 mechanisms of the existing ("static") [swallow | |
5 patch](https://dwm.suckless.org/patches/swallow/), dynamic window swallo… | |
6 run-time configurable and fully scriptable via `dwmswallow`, the command… | |
7 tool included with this patch. | |
8 | |
9 ## Download | |
10 | |
11 - [dwm-dynamicswallow-20210221-61bb8b2.diff](dwm-dynamicswallow-20210221… | |
12 - [dwm-dynamicswallow-6.4.diff](dwm-dynamicswallow-6.4.diff) | |
13 - [dwm-dynamicswallow-20240320-061e9fe.diff](dwm-dynamicswallow-20240320… | |
14 | |
15 ## 1. Usage | |
16 | |
17 Window swallowing is concerned with two scenarios: an existing window may | |
18 either swallow another existing window, or it may be registered to swall… | |
19 a future window. | |
20 | |
21 ### 1.1 Swallowing Future Windows | |
22 | |
23 Any window managed by dwm may be registered to swallow the next upcoming… | |
24 whose attributes match the class name, instance name and window title fi… | |
25 using the command-line tool `dwmswallow`. Quoting from `dwmswallow -h`: | |
26 | |
27 dwmswallow SWALLOWER [-c CLASS] [-i INSTANCE] [-t TITLE] | |
28 Register window SWALLOWER to swallow the next future window whose … | |
29 match the CLASS name, INSTANCE name and window TITLE filters using… | |
30 string-matching. An omitted filter will match anything. | |
31 | |
32 The next window whose filters match will be swallowed by SWALLOWER, taki… | |
33 place. See the following example in which a terminal launches the `surf` | |
34 browser and swallows its window, creating the impression of browsing the… | |
35 "inside" the terminal. Upon closing the browser the terminal reappears. … | |
36 the symbol in the status bar next to the layout symbol while the swallow… | |
37 active. | |
38 | |
39  | |
40 | |
41 This example uses the WINDOWID environment variable to retrieve the term… | |
42 window id. Some terminals such as `st` or `kitty` export the variable, w… | |
43 others such as `gnome-terminal` don't. | |
44 | |
45 Note that swallowing is not at all restricted to terminals. Any two wind… | |
46 managed by dwm may be involved. Also, window swallowing is agnostic towa… | |
47 layouts, respects your usage of size hints and can be nested to arbitrary | |
48 depths. | |
49 | |
50 ### 1.2 Swallowing Existing Windows | |
51 | |
52 Swallowing of existing windows may be performed either from the command-… | |
53 (see `dwmswallow -h`) or using drag-and-drop via pointer (*mod+shift+but… | |
54 by default). | |
55 | |
56 See the following example in which a terminal is used to launch an appli… | |
57 whose stdout is considered important during its startup sequence. Once t… | |
58 startup finishes without errors the stdout is of no interest anymore and… | |
59 terminal window is made to swallow the application window by drag-and-dr… | |
60 the latter onto the former. | |
61 | |
62  | |
63 | |
64 Afterwards, the terminal can be remapped at any time by stopping the swa… | |
65 a hotkey (*mod+u* by default), which is not shown in the example. | |
66 | |
67 ### 1.3 Shell Integration | |
68 | |
69 When working in a terminal a shell alias can be used to express whether | |
70 a graphical application shall open in a separate window or "inside" the | |
71 terminal. Given `alias s='dwmswallow $WINDOWID;'` the command `s myguipr… | |
72 will run the application and swallow its window. Note that this requires… | |
73 terminal to export the WINDOWID environment variable. | |
74 | |
75 Alternatively, a shell hotkey may be configured to preface the execution… | |
76 a command with `dwmswallow $WINDOWID`. For example, the following zsh | |
77 configuration will cause an application to be swallowed by the terminal … | |
78 its command is submitted by pressing *CTRL-x + Enter* as opposed to pres… | |
79 only *Enter*. | |
80 | |
81 # add to .zshrc | |
82 bindkey '^X^m' accept-line-swallow | |
83 zle -N accept-line-swallow acceptandswallow | |
84 acceptandswallow() { | |
85 dwmswallow $WINDOWID | |
86 zle accept-line | |
87 } | |
88 | |
89 ## 2. Patching Instructions | |
90 | |
91 Unless your fork of dwm is only slighly modified the adaptions to the pa… | |
92 listed here may be necessary or appropriate to better fit in with your e… | |
93 build. | |
94 | |
95 ### 2.1 Patch-Specific Geometry Parameters | |
96 | |
97 When swallowing a window the swallowee copies the swallower's geometry | |
98 parameters to reposition itself to where the swallower used to be, creat… | |
99 impression of one window incorporating another. There exist patches whic… | |
100 client-specific parameters that can modify a window's size or behavior. … | |
101 applying the dynamicswallow patch these parameters must be configured ma… | |
102 in two places: | |
103 | |
104 1. Inside `swal()`: during the swallowing of a window the swallowee shall | |
105 inherit a copy of the swallower's values of these parameters. | |
106 2. Inside `swalstop()`: when swallowing is stopped the swallower is rema… | |
107 and the parameters' defaults for its window have to be chosen. | |
108 | |
109 As a representative example consider the | |
110 [cfacts](https://dwm.suckless.org/patches/cfacts/) patch which allows to | |
111 configure the relative sizes of windows in tiling mode using the | |
112 client-specific parameter `cfact` of type float. The two changes necessa… | |
113 accommodate this parameter are: | |
114 | |
115 1. Inside `swal()`: `cfact` shall be copied from the swallower to the sw… | |
116 | |
117 /* Configure geometry params obtained from patches (e.g. cfacts)… | |
118 swee->cfact = swer->cfact; | |
119 | |
120 2. Inside `swalstop()`: the swallower's `cfact` shall be set to a sensib… | |
121 | |
122 /* Configure geometry params obtained from patches (e.g. cfacts)… | |
123 swer->cfact = 1.0; | |
124 | |
125 The specific places of where to configure the parameters are marked with | |
126 comments included in the patch. | |
127 | |
128 ### 2.2 Inter-Process Communication | |
129 | |
130 In order for `dwmswallow` to communicate with dwm some means of inter-pr… | |
131 communication is required which dwm does not provide by default. To this… | |
132 this patch includes an adaption of the | |
133 [fakesignal](https://dwm.suckless.org/patches/fsignal/) patch which allo… | |
134 sending commands to dwm by concatenating the command and its parameters … | |
135 a specifically formatted string and making it the name of the root windo… | |
136 | |
137 The fakesignal patch is lightweight, non-intrusive, easy to use and easy… | |
138 extend to other commands. If your build does not include any IPC mechani… | |
139 there's no reason to not use fakesignal as a starting point. Its only do… | |
140 is that the communication is unidirectional: one may send commands to dw… | |
141 dwm cannot send a reply in return. | |
142 | |
143 If your build of dwm does contain an IPC mechanism you may, of course, u… | |
144 existing communication pathways. While there's nothing wrong with using | |
145 fakesignal to try out the patch you will eventually want to seemlessly | |
146 integrate everything into your existing build. To achieve this you'll ha… | |
147 | |
148 1. relay the execution of `dwmswallow SWALLOWER SWALLOWEE` to a call to … | |
149 2. relay the execution of `dwmswallow -c CLASS -i INSTANCE -t TITLE` to … | |
150 3. relay the execution of `dwmswallow -s` to a call to `swalstop()`. | |
151 4. relay the execution of `dwmswallow -d` to a call to `swalunreg()`. | |
152 | |
153 using your IPC mechanism of choice. | |
154 | |
155 ## 3. Assorted Notes and Implementation Details | |
156 | |
157 Consult this section if you're interested in changing the default behavi… | |
158 if you're curious about the internals of the patch. The content herein is | |
159 presented in no particular order. | |
160 | |
161 ### 3.1 Swallow Indicator in Status Bar | |
162 | |
163 If the currently selected window on a monitor is being swallowed a | |
164 tongue-symbol 👅 (U+1F445) is drawn on the status bar next to the layo… | |
165 symbol. If this is undesired remove the relevant commented section from | |
166 `drawbar()` or change the symbol in your *config.h*. | |
167 | |
168 ### 3.2 Retroactive Swallowing | |
169 | |
170 When registering the swallow of a future window using the window title as | |
171 filter the swallowing may fail for some applications if retroactive swal… | |
172 is disabled (set by `swalretroactive`). This is due to the fact these | |
173 applications create their window using a default window title and only u… | |
174 it later to the proper, usage-specific value. When dwm checks whether any | |
175 registed swallows match the window's title it finds that none do due to … | |
176 usage of the default window title when the window is mapped. | |
177 | |
178 If retroactive swallowing is enabled each time a window changes its titl… | |
179 checks whether a registered swallow instance matches the window and exec… | |
180 accordingly. If you find yourself wanting to filter by window title keep | |
181 retroactive swallowing enabled. While things are small, as they usually … | |
182 the runtime costs are completely negligible. | |
183 | |
184 An example of this is the PDF viewer zathura. Zathura's window title ref… | |
185 the currently viewed file and may be used to register swallows of PDF pr… | |
186 filtered by filename. However, zathura's startup sequence exhibits the a… | |
187 behavior and the window title is set to reflect the filename only after a | |
188 default window title has been used. | |
189 | |
190 # This requires retroactive swallowing | |
191 dwmswallow $WINDOWID -c Zathura -t ~/books/xlib.pdf | |
192 zathura ~/books/xlib.pdf | |
193 | |
194 ### 3.3 Decaying of Registered Swallows | |
195 | |
196 It occasionally happens that swallows are registered but not consumed, e… | |
197 due to misspelling the filters, causing them to never match or because t… | |
198 user's intention has changed along the way. If `swaldecay` is set to a v… | |
199 greater than zero any registered swallow instance is deleted if it hasn'… | |
200 consumed after so many new windows are mapped, i.e. after *swaldecay* | |
201 unsuccessful matches. | |
202 | |
203 ### 3.4 `wintoclient()` vs `wintoclient2()` | |
204 | |
205 Regular clients, swallowees and swallowers each require different handli… | |
206 dwm with respect to X request and notify events (map, unmap, delete, con… | |
207 ...) for their respective windows. | |
208 | |
209 In order to distinguish between the three classes of clients during runt… | |
210 function `wintoclient2()` extends the functionality of the built-in | |
211 `wintoclient()`. In addition to retrieving the address of a window's cli… | |
212 from the window ID, it also returns the client type. It entails a change… | |
213 signature which is responsible for the majority of changes made by the p… | |
214 except for self-contained function definitions. | |
215 | |
216 ## Author | |
217 | |
218 - Stanislaw Hüll ([email protected]) | |
219 |