Codebase list i3-gaps / e6d2486
Initial Debian packaging Joseph O'Gorman 4 years ago
43 changed file(s) with 18165 addition(s) and 863 deletion(s). Raw diff Collapse all Expand all
0 i3-wm (4.18.1-1) unstable; urgency=medium
0 i3-gaps (4.18.1-0kali1) kali-dev; urgency=medium
11
2 * New upstream release.
2 * Initial release
33
4 -- Michael Stapelberg <[email protected]> Mon, 17 Feb 2020 18:25:47 +0100
5
6 i3-wm (4.18-1) unstable; urgency=medium
7
8 * New upstream release.
9
10 -- Michael Stapelberg <[email protected]> Mon, 17 Feb 2020 18:25:47 +0100
11
12 i3-wm (4.17.1-1) unstable; urgency=medium
13
14 * New upstream release.
15
16 -- Michael Stapelberg <[email protected]> Fri, 30 Aug 2019 23:06:40 +0200
17
18 i3-wm (4.17-1) unstable; urgency=medium
19
20 * New upstream release.
21
22 -- Michael Stapelberg <[email protected]> Sat, 03 Aug 2019 15:14:28 +0200
23
24 i3-wm (4.16.1-1) unstable; urgency=medium
25
26 * New upstream release.
27
28 -- Michael Stapelberg <[email protected]> Sun, 27 Jan 2019 16:45:11 +0100
29
30 i3-wm (4.16-1) unstable; urgency=medium
31
32 * UNRELEASED
33
34 -- Michael Stapelberg <[email protected]> Sun, 04 Nov 2018 14:47:25 +0100
35
36 i3-wm (4.15-1) unstable; urgency=medium
37
38 * New upstream release.
39
40 -- Michael Stapelberg <[email protected]> Sat, 10 Mar 2018 17:27:26 +0100
41
42 i3-wm (4.14.1-1) unstable; urgency=medium
43
44 * New upstream release.
45
46 -- Michael Stapelberg <[email protected]> Sun, 24 Sep 2017 19:21:15 +0200
47
48 i3-wm (4.14-1) unstable; urgency=medium
49
50 * New upstream release.
51
52 -- Michael Stapelberg <[email protected]> Mon, 04 Sep 2017 07:53:16 +0200
53
54 i3-wm (4.13-1) unstable; urgency=medium
55
56 * New upstream release.
57
58 -- Michael Stapelberg <[email protected]> Tue, 08 Nov 2016 19:02:16 +0100
59
60 i3-wm (4.12-2) unstable; urgency=medium
61
62 * Override lintian warning desktop-entry-contains-unknown-key for
63 DesktopNames, gdm needs that key.
64 * Remove i3-wm.menu to conform to the tech-ctte decision on #741573.
65
66 -- Michael Stapelberg <[email protected]> Fri, 01 Apr 2016 15:51:23 +0200
67
68 i3-wm (4.12-1) unstable; urgency=medium
69
70 * New upstream release.
71 * Move to debhelper 9
72 * Bump Standards-Version to 3.9.7 (no changes necessary)
73 * debian/watch: verify signature, use https
74
75 -- Michael Stapelberg <[email protected]> Sun, 06 Mar 2016 14:20:38 +0100
76
77 i3-wm (4.11-1) unstable; urgency=medium
78
79 * New upstream release.
80
81 -- Michael Stapelberg <[email protected]> Wed, 30 Sep 2015 08:50:13 +0200
82
83 i3-wm (4.10.4-1) unstable; urgency=medium
84
85 * New upstream release.
86
87 -- Michael Stapelberg <[email protected]> Tue, 08 Sep 2015 09:15:45 +0200
88
89 i3-wm (4.10.3-1) unstable; urgency=medium
90
91 * New upstream release.
92
93 -- Michael Stapelberg <[email protected]> Thu, 30 Jul 2015 21:51:27 +0200
94
95 i3-wm (4.10.2-2) unstable; urgency=medium
96
97 * New upstream release.
98 * experimental to unstable because i3-wm 4.10.2-1 was only in experimental
99 due to the freeze.
100
101 -- Michael Stapelberg <[email protected]> Fri, 01 May 2015 20:21:18 +0200
102
103 i3-wm (4.10.2-1) experimental; urgency=medium
104
105 * New upstream release.
106
107 -- Michael Stapelberg <[email protected]> Thu, 16 Apr 2015 09:02:53 +0200
108
109 i3-wm (4.10.1-1) experimental; urgency=medium
110
111 * New upstream release.
112
113 -- Michael Stapelberg <[email protected]> Sun, 29 Mar 2015 18:54:07 +0200
114
115 i3-wm (4.10-1) experimental; urgency=medium
116
117 * New upstream release.
118
119 -- Michael Stapelberg <[email protected]> Sun, 29 Mar 2015 17:46:09 +0200
120
121 i3-wm (4.9.1-1) experimental; urgency=medium
122
123 * New upstream release.
124
125 -- Michael Stapelberg <[email protected]> Sat, 07 Mar 2015 20:01:46 +0100
126
127 i3-wm (4.9-1) experimental; urgency=medium
128
129 * New upstream release.
130
131 -- Michael Stapelberg <[email protected]> Sat, 28 Feb 2015 14:53:34 +0100
132
133 i3-wm (4.8-2) unstable; urgency=medium
134
135 * Backport two bugfixes:
136 - backport-dpi-fix.patch (Closes: #778460)
137 - backport-i3bar-tray-fix.patch (Closes: #778461)
138
139 -- Michael Stapelberg <[email protected]> Sun, 15 Feb 2015 13:24:42 +0100
140
141 i3-wm (4.8-1) unstable; urgency=medium
142
143 * New upstream release.
144 * Bump standards-version to 3.9.5 (no changes necessary)
145
146 -- Michael Stapelberg <[email protected]> Sun, 15 Jun 2014 19:15:29 +0200
147
148 i3-wm (4.7.2-1) unstable; urgency=low
149
150 * New upstream release. (Closes: #736396)
151
152 -- Michael Stapelberg <[email protected]> Thu, 23 Jan 2014 23:03:03 +0100
153
154 i3-wm (4.7.1-1) unstable; urgency=low
155
156 * New upstream release.
157
158 -- Michael Stapelberg <[email protected]> Tue, 21 Jan 2014 19:29:34 +0100
159
160 i3-wm (4.7-1) unstable; urgency=low
161
162 * New upstream release.
163
164 -- Michael Stapelberg <[email protected]> Sun, 22 Dec 2013 21:19:02 +0100
165
166 i3-wm (4.6-1) unstable; urgency=low
167
168 * New upstream release.
169
170 -- Michael Stapelberg <[email protected]> Wed, 07 Aug 2013 20:53:26 +0200
171
172 i3-wm (4.5.1-2) unstable; urgency=low
173
174 * experimental to unstable because i3-wm 4.5.1 was only in experimental due
175 to the freeze.
176 * bump standards-version to 3.9.4 (no changes necessary)
177
178 -- Michael Stapelberg <[email protected]> Tue, 14 May 2013 20:48:16 +0200
179
180 i3-wm (4.5.1-1) experimental; urgency=low
181
182 * New upstream release
183
184 -- Michael Stapelberg <[email protected]> Mon, 18 Mar 2013 22:50:12 +0100
185
186 i3-wm (4.5-1) experimental; urgency=low
187
188 * New upstream release
189
190 -- Michael Stapelberg <[email protected]> Tue, 12 Mar 2013 13:51:04 +0100
191
192 i3-wm (4.4-1) experimental; urgency=low
193
194 * New upstream release
195
196 -- Michael Stapelberg <[email protected]> Tue, 11 Dec 2012 22:52:56 +0100
197
198 i3-wm (4.3-1) experimental; urgency=low
199
200 * New upstream release
201
202 -- Michael Stapelberg <[email protected]> Wed, 19 Sep 2012 18:13:40 +0200
203
204 i3-wm (4.2-1) unstable; urgency=low
205
206 * New upstream release
207
208 -- Michael Stapelberg <[email protected]> Wed, 25 Apr 2012 23:19:44 +0200
209
210 i3-wm (4.1.2-3) unstable; urgency=low
211
212 * Disable generation of docs/refcard.pdf (Closes: #666363)
213 * Add debian/i3-wm.menu (Closes: #664697)
214 * Bump standards-version to 3.9.3 (no changes needed)
215 * Fix 'section' field of the i3-wm source package to 'x11'
216 * Email change: Michael Stapelberg -> [email protected]
217
218 -- Michael Stapelberg <[email protected]> Thu, 12 Apr 2012 16:09:58 +0200
219
220 i3-wm (4.1.2-2) unstable; urgency=low
221
222 * Rebuild against libyajl and libxcb from unstable
223
224 -- Michael Stapelberg <[email protected]> Fri, 27 Jan 2012 19:50:29 +0000
225
226 i3-wm (4.1.2-1) unstable; urgency=low
227
228 * Bugfix: Don’t lose focus on fullscreen windows when another window gets
229 moved to that workspace
230 * Bugfix: Open new windows in the correct place when assignments match
231 * Bugfix: Fix assignments of floating windows to (yet) unused workspaces
232 * Bugfix: Either use SetInputFocus *or* send WM_TAKE_FOCUS, not both
233 * Bugfix: Respect WM_HINTS.input for WM_TAKE_FOCUS clients
234 * Bugfix: Setup the _NET_SUPPORTING_WM_CHECK atom in a standards-compliant
235 way
236 * Bugfix: Only ignore EnterNotify events after UnmapNotifies from managed
237 windows
238 * Bugfix: Force a new sequence number after UnmapNotify
239 * Bugfix: Position floating windows exactly where their geometry specified
240 * Bugfix: Fix coordinates when the rect of an output changes
241
242 -- Michael Stapelberg <[email protected]> Fri, 27 Jan 2012 19:04:28 +0000
243
244 i3-wm (4.1.1-1) unstable; urgency=low
245
246 * Re-add build-arch/build-indep targets to debian/rules (Closes: #648613)
247 * Create a secure temp path instead of a predictable one
248 * ipc: set CLOEXEC on client file descriptors
249 * Fix prototype in include/xcursor.h
250 * Bugfix: Skip dock clients when handling FocusIn events
251 * Bugfix: Fix fullscreen with floating windows
252 * Bugfix: Fix startup when RandR is not present
253 * Bugfix: Retain window position and size when changing floating border
254 * Bugfix: Disallow focusing dock clients via criteria
255 * Bugfix: Don’t create a workspace named 'back_and_forth' on startup
256 * Bugfix: Fix wrong focus in complex tabbed/stacked layouts
257 * Bugfix: Fix resizing for (e.g.) v-split containers in h-split containers
258 * Bugfix: Fix 'resize' command in nested containers
259 * Bugfix: Don’t set the _NET_WM_WORKAREA hint at all
260 * Bugfix: Skip leading whitespace in variable assignments
261 * Bugfix: Make resizing of tiling windows with floating_modifier use absolute
262 coordinates
263 * Bugfix: Make resizing work when pressing floating_modifier + right mouse
264 button on window decorations
265 * Bugfix: Fix setting the same mark repeatedly on different windows
266 * Bugfix: Disallow focusing other windows when in fullscreen mode
267 * Bugfix: Ignore ConfigureRequests with out-of-bound coordinates
268 * Bugfix: Correctly check boundaries and reassign floating windows when
269 moving
270 * Bugfix: Don’t close workspace when there are still floating windows on it
271
272 -- Michael Stapelberg <[email protected]> Sat, 24 Dec 2011 16:23:55 +0100
273
274 i3-wm (4.1-1) unstable; urgency=low
275
276 * Switch to dpkg-source 3.0 (quilt) and compat level 7
277 * Implement system tray support in i3bar (for NetworkManager, Skype, …)
278 * i3bar is now configurable in the i3 configfile
279 * Implement support for PCRE regular expressions in criteria
280 * Implement a new assign syntax which uses criteria
281 * Sort named workspaces whose name starts with a number accordingly
282 * Warn on duplicate bindings for the same key
283 * Restrict 'resize' command to left/right for horizontal containers, up/down
284 for vertical containers
285 * Implement support for startup notifications (cursor will change to 'watch',
286 started applications show up on the workspace they have been launched on)
287 * Implement the GET_MARKS IPC request to get all marks
288 * Implement the new_float config option (border style for floating windows)
289 * Implement passing IPC sockets to i3 (systemd-style socket activation)
290 * Implement the 'move output' command to move containers to a specific output
291 * Implement focus switching for floating windows
292 * Implement the window_role criterion (for matching multi-window apps)
293 * Implement a force_xinerama configuration directive
294 * Implement the --get-socketpath, useful for scripts using the IPC interface
295 * Implement the 'move workspace next' and 'move workspace prev' commands
296 * Implement the 'workspace back_and_forth' command and related configuration
297 option
298 * Implement the move command for floating windows
299 * i3 will now handle arbitrary text arguments by sending them as an IPC
300 command, like i3-msg: 'i3 reload' or 'i3 move workspace 3'
301 * Introduce the i3-sensible-{pager,editor,terminal} scripts to execute
302 $PAGER, $EDITOR or an available terminal emulator
303 * i3-input: implement -F (format) option
304 * Bugfix: Preserve marks when restarting
305 * Bugfix: Correctly free old assignments when reloading
306 * Bugfix: Fix flickering when moving floating windows between monitors
307 * Bugfix: Correctly handle ConfigureRequests for floating windows in a
308 multi-monitor environment.
309 * Bugfix: Fix size of floating windows with X11 borders
310 * Bugfix: Always adjust floating window position when moving to another
311 output
312 * Bugfix: Avoid out-of-bounds coordinates when moving floating windows
313 * Bugfix: Don’t steal focus when a window gets destroyed
314 * Bugfix: Correctly split key/value when parsing variables
315 * Bugfix: Correctly revert focus to other floating windows when closing a
316 floating window
317 * Bugfix: Don’t leak the error logfile file descriptor
318 * Bugfix: Don’t steal focus when a window opens on an invisible workspace due
319 to assignments
320 * Bugfix: Fix handling of Mode_switch in i3-input
321 * Bugfix: Close invisible workspaces when they become empty
322 * Bugfix: Don’t invoke interactive resizing when clicking on the decoration
323 of a split container with more than one child (switch focus instead)
324 * Bugfix: Make named workspace assignments work again
325 * Bugfix: RandR: Correctly keep focus on the focused workspace when an output
326 disappears
327 * Bugfix: Insert container at the correct position on workspace level when
328 workspace_layout == default
329
330 -- Michael Stapelberg <[email protected]> Fri, 11 Nov 2011 21:28:15 +0000
331
332 i3-wm (4.0.2-1) unstable; urgency=low
333
334 * i3-config-wizard: handle mouse button clicks on <win> and <alt> texts
335 * i3-config-wizard: check the modifier mapping to decide whether to use Mod1
336 or Mod4
337 * migrate-config: use \s, be a bit more whitespace tolerant
338 * userguide: s/mod+h/mod+s for stacking
339 * userguide: provide the default colors in the colors example
340 * userguide: document force_focus_wrapping directive
341 * userguide: properly document the resize command
342 * userguide: properly document command chaining and criteria
343 * Bugfix: Correctly bind on multiple keycodes if a symbol has more than one
344 * Bugfix: Allow multiple criteria in 'for_window'
345 * Bugfix: Ensure a minimum size when using the 'resize' command
346 * Bugfix: Start on the first named workspace, not always on '1'
347 * Bugfix: Fix resize command with direction != up for floating windows
348 * Bugfix: Correctly set the _NET_CLIENT_LIST_STACKING hint (chromium tabbar)
349 * Bugfix: 'workspace <next|prev>' now takes all outputs into account
350 * Bugfix: i3-wsbar: make workspace names clickable again
351 * Bugfix: i3-wsbar: correctly handle EOF on stdin
352 * Bugfix: i3-wsbar: display a separator between workspaces of each output
353 * Bugfix: Correctly handle the 'instance' criterion (WM_CLASS)
354 * Bugfix: Use correct format string in load_layout (fixes crash in restart)
355 * Bugfix: Fix border rendering (border lines were "cutting" through)
356 * Bugfix: Raise floating windows immediately when dragging/resizing
357 * Bugfix: Make focus switching work across outputs again
358 * Bugfix: migration-script: handle resize top/bottom correctly
359 * Bugfix: Fix focus issue when moving containers to workspaces
360 * Bugfix: Warp cursor when changing outputs again
361 * Bugfix: i3bar: fix switching to workspaces with extremely long names
362 * Bugfix: i3bar: fix switching to workspaces "next" and "prev"
363 * Bugfix: i3bar: Correctly allocate pixmap for statuslines which are longer
364 than the screen
365 * Bugfix: i3bar: set statusline = NULL on EOF / SIGCHLD
366 * Bugfix: Correctly initialize the verbose flag
367 * Bugfix: Don’t start with workspace 'next' when the command 'workspace next'
368 is bound in the config file
369 * Bugfix: Set focus to where the mouse pointer is when starting
370 * Bugfix: Don’t change focus when assigned windows start on invisible
371 workspaces
372 * Bugfix: Don’t use absolute paths for exec in the config file
373 * Bugfix: Fix crash when using 'focus mode_toggle' on an empty workspace
374 * Bugfix: Make the 'resize' command work inside tabbed/stacked cons
375 * Bugfix: Correctly place floating windows on their appropriate output
376 * Bugfix: Fix coordinates when moving a floating window to a different output
377 * Bugfix: Correctly keep focus when moving non-leaf windows
378 * Bugfix: Accept '\t' in the set command
379 * Bugfix: Only consider tiling windows when attaching tiling windows to a
380 workspace
381 * Bugfix: Correctly render containers when a split container is focused
382 * Bugfix: Correctly recognize duplicate workspace assignments
383 * Bugfix: Re-enable X11 Eventmask *after* pushing all the X11 changes
384 * Bugfix: Fix focus stealing with assignments of floating windows
385 * Bugfix: Re-implement reconfiguring height of dock windows
386 * Bugfix: IPC: return name_json if available
387 * Bugfix: Make 'floating enable' check for dock windows
388
389 -- Michael Stapelberg <[email protected]> Sun, 28 Aug 2011 19:07:43 +0200
390
391 i3-wm (4.0.1-1) unstable; urgency=low
392
393 * Fix the build process of i3bar (Closes: #636274)
394 * Fix the build process on Mac OS X
395 * i3-config-wizard: also start i3bar in the keycode config template
396 * userguide: Remove the obsolete bar.* colors
397 * userguide: Use i3bar instead of dzen2 in the 'exec' example
398
399 -- Michael Stapelberg <[email protected]> Mon, 01 Aug 2011 23:31:06 +0200
400
401 i3-wm (4.0-1) unstable; urgency=low
402
403 * In addition to the proper flex/bison based parser for the config file
404 introduced in 3.δ, we now also have a flex/bison parser for commands. What
405 this means is that we can have more human-readable, beautiful command names
406 instead of cryptic commands like 'f' for fullscreen or 'mh' for move left.
407 In fact, the commands for the aforementioned functions *are* 'fullscreen'
408 and 'move left'!
409 * You can now chain commands using ';' (a semicolon). One example for that is
410 'workspace 3 ; exec /usr/bin/urxvt' to switch to a new workspace and open a
411 terminal.
412 * You can specify which windows should be affected by your command by using
413 different criteria. A good example is '[class="Firefox"] kill' to get rid
414 of all Firefox windows.
415 * As the configuration file needs new commands (and a few options are
416 obsolete), you need to change it. To make this process a little bit easier
417 for you, this release comes with the script i3-migrate-config-to-v4. Just
418 run it on your current config file and it will spit out a v4 config file to
419 stdout. To make things even better, i3 automatically detects v3 config files
420 and calls that script, so you never end up with a non-working config :).
421 * Similarly to the criteria when using commands, we now have a 'for_window'
422 configuration directive, which lets you automatically apply certain commands
423 to certain windows. Use it to set border styles per window, for example with
424 'for_window [class="XTerm"] border 1pixel'.
425 * Since dock clients (like dzen2) are now part of the layout tree (as opposed
426 to a custom data structure as before), it was easy to implement top and
427 bottom dock areas. Programs which properly specify the dock hint get placed
428 on the edge of the screen they request. i3bar has the -dtop and -dbottom
429 parameters, for example.
430 * The internal workspace bar is obsolete. Use i3bar instead.
431 * Resizing now works between all windows!
432 * Fullscreen now works for everything!
433 * Floating now works for everything!
434 * Your layout is now preserved when doing an inplace restart.
435 * When you have an error in your config file, a new program called i3-nagbar
436 will tell you so. It offers you two buttons: One to view the error in your
437 $PAGER and one to edit your config in your $EDITOR.
438 * The default config used key symbols (like 'bind Mod1+f fullscreen') instead
439 of key codes. If you use a non-qwerty layout, the program i3-config-wizard
440 can create a key symbol based config file based on your current layout. You
441 can also chose between Windows (Mod4) and Alt (Mod1) as your default
442 modifier. i3-config-wizard will automatically be started as long as you
443 don’t have a configuration file for i3.
444 * Custom X cursor themes are now supported.
445 * The RandR backend now respects the primary output.
446 * A wrong 'font' configuration in your config file will no longer make i3
447 exit. Instead, it will fall back to a different font and tell you about the
448 error in its log.
449 * The default split direction (whether a new window gets placed right next to
450 the current one or below the current one) is now automatically set to
451 horizontal if you have a monitor that is wider than high or vertical if you
452 a monitor which is higher than wide. This works great with rotated monitors.
453 * Sockets and temporary files are now placed in XDG_RUNTIME_DIR, if set (this
454 is used on systemd based systems).
455 * Tools like i3bar, i3-msg etc. use the I3_SOCKET_PATH property which is set
456 to the X11 root window, so you don’t have to configure your socket path
457 anywhere.
458 * The kill command kills single windows by default now. To kill a whole
459 application, use 'kill client'.
460 * IPC: Commands can now have custom replies. When the parser encounters an
461 error, a proper error reply is sent.
462 * There is now an 'exec_always' configuration directive which works like
463 'exec' but will also be run when restarting.
464
465 -- Michael Stapelberg <[email protected]> Sun, 31 Jul 2011 22:34:26 +0200
466
467 i3-wm (3.e-bf1-3) unstable; urgency=low
468
469 * include keyboard-layer{1,2}.png in docs (Closes: #595295)
470
471 -- Michael Stapelberg <[email protected]> Wed, 03 Nov 2010 20:32:42 +0100
472
473 i3-wm (3.e-bf1-2) unstable; urgency=low
474
475 * debian: call dh_installwm to register as alternative for x-window-manager
476
477 -- Michael Stapelberg <[email protected]> Wed, 23 Jun 2010 18:23:10 +0200
478
479 i3-wm (3.e-bf1-1) unstable; urgency=low
480
481 * Bugfix: Correctly initialize workspaces if RandR is not available
482 * Bugfix: Correctly handle asprintf() return value
483 * Bugfix: Update _NET_WM_STATE when clients request changes via ClientMessage
484 * Bugfix: Don’t invert directions when resizing floating clients (top/left)
485 * Bugfix: Don’t leak file descriptors
486
487 -- Michael Stapelberg <[email protected]> Wed, 09 Jun 2010 09:51:10 +0200
488
489 i3-wm (3.e-3) unstable; urgency=low
490
491 * Bump debian policy version
492 * Add Recommends: libanyevent-i3-perl, libanyevent-perl, libipc-run-perl
493 which are necessary to use i3-wsbar (which is not core functionality,
494 thus no Depends:) (Closes: #577287)
495
496 -- Michael Stapelberg <[email protected]> Sat, 24 Apr 2010 11:20:19 +0200
497
498 i3-wm (3.e-2) unstable; urgency=low
499
500 * Use x-terminal-emulator instead of hard-coded urxvt
501
502 -- Michael Stapelberg <[email protected]> Sun, 04 Apr 2010 19:30:46 +0200
503
504 i3-wm (3.e-1) unstable; urgency=low
505
506 * Implement RandR instead of Xinerama
507 * Obey the XDG Base Directory Specification for config file paths
508 * lexer/parser: proper error messages
509 * Add new options -V for verbose mode and -d <loglevel> for debug log levels
510 * Implement resize command for floating clients
511 * Include date of the last commit in version string
512 * Fixed cursor orientation when resizing
513 * Added focus_follows_mouse config option
514 * Feature: Cycle through workspaces
515 * Fix bindings using the cursor keys in default config
516 * added popup for handling SIGSEGV or SIGFPE
517 * Correctly exit when another window manager is already running
518 * Take into account the window’s base_{width,height} when resizing
519 * Disable XKB instead of quitting with an error
520 * Make containers containing exactly one window behave like default containers
521 * Also warp the pointer when moving a window to a another visible workspace
522 * work around clients setting 0xFFFF as resize increments
523 * Move autostart after creating the IPC socket in start process
524 * Restore geometry of all windows before exiting/restarting
525 * When in fullscreen mode, focus whole screens instead of denying to focus
526 * draw consistent borders for each frame in a tabbed/stacked container
527 * Update fullscreen client position/size when an output changes
528 * i3-input: Bugfix: repeatedly grab the keyboard if it does not succeed
529 * put windows with WM_CLIENT_LEADER on the workspace of their leader
530 * use real functions instead of nested functions (enables compilation with
531 llvm-clang)
532 * implement screen-spanning fullscreen mode
533 * floating resize now uses arbitrary corners
534 * floating resize now works proportionally when pressing shift
535 * Don’t use SYNC key bindings for mode_switch but re-grab keys
536 * support PREFIX and SYSCONFDIR in Makefile
537 * make pointer follow the focus when moving to a different screen also for
538 floating clients
539 * start dock clients on the output they request to be started on according
540 to their geometry
541 * handle destroy notify events like unmap notify events
542 * ewmh: correctly set _NET_CURRENT_DESKTOP to the number of the active
543 workspace
544 * ewmh: correctly set _NET_ACTIVE_WINDOW
545 * ewmh: implement support for _NET_WORKAREA (rdesktop can use that)
546 * default ipc-socket path is now ~/.i3/ipc.sock, enabled in the default config
547 * Bugfix: Containers could lose their snap state
548 * Bugfix: Use ev_loop_new to not block SIGCHLD
549 * Bugfix: if a font provides no per-char info for width, fall back to default
550 * Bugfix: lexer: return to INITIAL state after floating_modifier
551 * Bugfix: Don’t leak IPC socket to launched processes
552 * Bugfix: Use both parts of WM_CLASS (it contains instance and class)
553 * Bugfix: Correctly do boundary checking/moving to other workspaces when
554 moving floating clients via keyboard
555 * Bugfix: checked for wrong flag in size hints
556 * Bugfix: Correctly render workspace names containing some non-ascii chars
557 * Bugfix: Correctly position floating windows sending configure requests
558 * Bugfix: Don’t remap stack windows errnously when changing workspaces
559 * Bugfix: configure floating windows above tiling windows when moving them
560 to another workspace
561 * Bugfix: Take window out of fullscreen mode before entering floating mode
562 * Bugfix: Don’t enter BIND_A2WS_COND state too early
563 * Bugfix: only restore focus if the workspace is focused, not if it is visible
564 * Bugfix: numlock state will now be filtered in i3-input and signal handler
565 * Bugfix: Don’t unmap windows when current workspace gets reassigned
566 * Bugfix: correctly translate coordinates for floating windows when outputs
567 change
568 * Bugfix: Correctly switch workspace when using the "jump" command
569 * Bugfix: Fix rendering of workspace names after "reload"
570 * Bugfix: Correctly ignore clicks when in fullscreen mode
571 * Bugfix: Don’t allow fullscreen floating windows to be moved
572 * Bugfix: Don’t render containers which are not visible on hint changes
573 * Some memory leaks/invalid accesses have been fixed
574
575 -- Michael Stapelberg <[email protected]> Tue, 30 Mar 2010 13:11:50 +0200
576
577 i3-wm (3.d-bf1-1) unstable; urgency=low
578
579 * Bugfix: Don’t draw window title when titlebar is disabled
580 * Bugfix: Correctly switch border types for floating windows
581 * Bugfix: Correctly replay pointer if the click handler does not trigger
582 * Bugfix: Also allow WORDs as workspace names
583 * Bugfix: Correctly clear the urgency hint if a window gets unmapped without
584 clearing it
585 * Bugfix: Fix resizing of floating windows in borderless/1-px-border mode
586 * Bugfix: Accept underscores in bindsym
587 * Bugfix: Don’t set the urgency flag if the window is focused
588 * Bugfix: Handle stack-limit cols on tabbed containers
589 * Bugfix: Resize client after updating base_width/base_height
590 * Bugfix: Force render containers after setting the client active
591 * Bugfix: Fix two problems in resizing floating windows with right mouse
592 * Bugfix: Use more precise floating point arithmetics
593 * Bugfix: Correctly place new windows below fullscreen windows
594
595 -- Michael Stapelberg <[email protected]> Mon, 21 Dec 2009 22:33:02 +0100
596
597 i3-wm (3.d-2) unstable; urgency=low
598
599 * debian: register in doc-base
600 * debian: add watchfile
601 * debian: remove unnecessary priority-field from binary packages
602 * debian: add missing images to documentation
603
604 -- Michael Stapelberg <[email protected]> Mon, 23 Nov 2009 21:56:04 +0100
605
606 i3-wm (3.d-1) unstable; urgency=low
607
608 * Implement tabbing (command "T")
609 * Implement horizontal resize of containers (containers! not windows)
610 * Implement the urgency hint for windows/workspaces
611 * Implement vim-like marks (mark/goto command)
612 * Implement stack-limit for further defining how stack windows should look
613 * Implement modes which allow you to use a different set of keybindings
614 when inside a specific mode
615 * Implement changing the default mode of containers
616 * Implement long options (--version, --no-autostart, --help, --config)
617 * Implement 'bt' to toggle between the different border styles
618 * Implement an option to specify the default border style
619 * Use a yacc/lex parser/lexer for the configuration file
620 * The number of workspaces is now dynamic instead of limited to 10
621 * Floating windows (and tiled containers) can now be resized using
622 floating_modifier and right mouse button
623 * Dock windows can now reconfigure their height
624 * Bugfix: Correctly handle multiple messages on the IPC socket
625 * Bugfix: Correctly use base_width, base_height and size increment hints
626 * Bugfix: Correctly send fake configure_notify events
627 * Bugfix: Don’t crash if the numlock symbol cannot be found
628 * Bugfix: Don’t display a colon after unnamed workspaces
629 * Bugfix: If the pointer is outside of the screen when starting, fall back to
630 the first screen.
631 * Bugfix: Initialize screens correctly when not using Xinerama
632 * Bugfix: Correctly handle unmap_notify events when resizing
633 * Bugfix: Correctly warp pointer after rendering the layout
634 * Bugfix: Fix NULL pointer dereference when reconfiguring screens
635 * Explicitly specify -lxcb when linking (Closes: #554860)
636
637 -- Michael Stapelberg <[email protected]> Mon, 09 Nov 2009 20:53:43 +0100
638
639 i3-wm (3.c-2) unstable; urgency=low
640
641 * Fix FTBFS on GNU/kFreeBSD and possibly GNU/Hurd (Closes: #542877)
642 * Add manpage for i3-msg
643
644 -- Michael Stapelberg <[email protected]> Mon, 24 Aug 2009 12:23:18 +0200
645
646 i3-wm (3.c-1) unstable; urgency=low
647
648 * Implement a reload command
649 * Implement keysymbols in configuration file
650 * Implement assignments of workspaces to screens
651 * Implement named workspaces
652 * Implement borderless/1-px-border windows
653 * Implement command to focus screens
654 * Implement IPC via unix sockets
655 * Correctly render decoration of floating windows
656 * Map floating windows requesting (0x0) to center of their leader/workspace
657 * Optimization: Render stack windows on pixmaps to reduce flickering
658 * Optimization: Directly position new windows to their final position
659 * Bugfix: Repeatedly try to find screens if none are available
660 * Bugfix: Correctly redecorate clients when changing focus
661 * Bugfix: Don’t crash when clients reconfigure themselves
662 * Bugfix: Fix screen wrapping
663 * Bugfix: Fix selecting a different screen with your mouse when not having
664 any windows on the current workspace
665 * Bugfix: Correctly unmap stack windows and don’t re-map them too early
666 * Bugfix: Allow switching layout if there are no clients in the this container
667 * Bugfix: Set WM_STATE_WITHDRAWN when unmapping, unmap windows when
668 destroying
669 * Bugfix: Don’t hide assigned clients to inactive but visible workspaces
670
671 -- Michael Stapelberg <[email protected]> Wed, 19 Aug 2009 13:07:58 +0200
672
673 i3-wm (3.b-1) unstable; urgency=low
674
675 * Bugfix: Correctly handle col-/rowspanned containers when setting focus.
676 * Bugfix: Correctly handle col-/rowspanned containers when snapping.
677 * Bugfix: Force reconfiguration of all windows on workspaces which are
678 re-assigned because a screen was detached.
679 * Bugfix: Several bugs in resizing table columns fixed.
680 * Bugfix: Resizing should now work correctly in all cases.
681 * Bugfix: Correctly re-assign dock windows when workspace is destroyed.
682 * Bugfix: Correctly handle Mode_switch modifier.
683 * Bugfix: Don't raise clients in fullscreen mode.
684 * Bugfix: Re-assign dock windows to different workspaces when a workspace
685 is detached.
686 * Bugfix: Fix crash because of workspace-pointer which did not get updated
687 * Bugfix: Correctly initialize screen when Xinerama is disabled.
688 * Bugfix: Fullscreen window movement and focus problems fixed
689 * Implement jumping to other windows by specifying their position or
690 window class/title.
691 * Implement jumping back by using the focus stack.
692 * Implement autostart (exec-command in configuration file).
693 * Implement floating.
694 * Implement automatically assigning clients on specific workspaces.
695 * Implement variables in configfile.
696 * Colors are now configurable.
697
698 -- Michael Stapelberg <[email protected]> Fri, 26 Jun 2009 04:42:23 +0200
699
700 i3-wm (3.a-bf2-1) unstable; urgency=low
701
702 * Bugfix: Don't crash when setting focus
703 * Bugfix: Reconfigure bar window when changing resolutions
704
705 -- Michael Stapelberg <[email protected]> Sun, 03 May 2009 23:02:24 +0200
706
707 i3-wm (3.a-bf1-1) unstable; urgency=low
708
709 * Bugfix: When entering a stack window with the mouse, set focus to the
710 active client in the container the stack window belongs to.
711 * Bugfix: Correctly filter out the numlock bit. This fixes i3 not reacting
712 to any keybindings after pressing numlock once.
713 * Bugfix: Don't crash when Xinerama is disabled.
714 * Bugfix: Correctly remove client from container when moving to another
715 workspace.
716 * Bugfix: Set focus to the client which was previously focused instead of
717 the next client in container when moving windows out of a container.
718 * Bugfix: Correctly set focus when switching between screens.
719 * Bugfix: Don't crash anymore moving focus to another screen under the
720 following conditions: The screen you switch to has a lower number of cells
721 and/or rows than the current one, you switch focus using your mouse, you
722 previously were in a column/row which is not available on the destination
723 screen.
724 * Bugfix: When switching screens, warp the pointer to the correct
725 destination window.
726 * Bugfix: Store dock clients per screen, not per workspace.
727 * Bugfix: Perform bounds checking for snapped containers.
728 * Bugfix: Send clients their absolute position/size (on the root window) in
729 generated configure events. This fixes problems with xfontsel, xmaple,
730 etc.
731 * Bugfix: Correctly update state when moving fullscreen windows across
732 workspaces.
733 * Bugfix: Correctly restart i3 when not using its absolute path
734 * Bugfix: Drag & Drop in GTK applications works now
735 * Bugfix: Don't hide non-managed windows (libnotify-popups for example)
736 when raising clients in stacked containers.
737 * Bugfix: Correctly restore focus when leaving fullscreen mode
738 * Bugfix: Re-distribute free space when closing customly resized containers,
739 re-evaluate for other containers
740 * Bugfix: When moving windows into different containers, insert them at the
741 correct position.
742 * Bugfix: Correctly set focus when moving windows into other containers
743 * Implement scrolling on stack windows and on the bottom bar.
744 * Create i3-wm-dbg with debug symbols
745 * Don't rely on libxcb-wm any longer, as it got removed in libxcb 0.3.4.
746
747 -- Michael Stapelberg <[email protected]> Sat, 02 May 2009 20:55:46 +0200
748
749 i3-wm (3.a-1) unstable; urgency=low
750
751 * First release (Closes: #521709)
752
753 -- Michael Stapelberg <[email protected]> Sun, 29 Mar 2009 18:21:30 +0200
4 -- Joseph O'Gorman <[email protected]> Thu, 16 Apr 2020 16:41:23 -0400
0 Source: i3-wm
0 Source: i3-gaps
11 Section: x11
22 Priority: extra
3 Maintainer: Michael Stapelberg <[email protected]>
3 Maintainer: Kali Developers <[email protected]>
4 Uploaders: Joseph O'Gorman <[email protected]>
45 Build-Depends: debhelper (>= 9),
56 dh-autoreconf,
67 libx11-dev,
2526 libstartup-notification0-dev (>= 0.10),
2627 libcairo2-dev (>= 1.14.4),
2728 libpango1.0-dev,
28 libpod-simple-perl
29 Standards-Version: 3.9.8
30 Homepage: https://i3wm.org/
29 libpod-simple-perl,
30 xcb,
31 libxcb1-dev,
32 libxcb-xrm0,
33 libxcb-shape0,
34 Standards-Version: 4.5.0
35 Homepage: https://github.com/Airblader/i3
36 Vcs-Browser: https://gitlab.com/kalilinux/packages/i3-gaps
37 Vcs-Git: https://gitlab.com/kalilinux/packages/i3-gaps.git
3138
32 Package: i3
39 Package: i3-gaps
3340 Architecture: any
34 Depends: i3-wm (=${binary:Version}), ${misc:Depends}
35 Recommends: i3lock (>= 2.2), suckless-tools, i3status (>= 2.3), dunst
36 Description: metapackage (i3 window manager, screen locker, menu, statusbar)
37 This metapackage installs the i3 window manager (i3-wm), the i3lock screen
41 Depends: i3-gaps-wm (=${binary:Version}), ${misc:Depends}, sensible-utils, libc6, libxcb-cursor0,
42 dh-autoreconf,
43 gcc,
44 libev-dev,
45 libpango1.0-dev,
46 libstartup-notification0-dev,
47 libxcb-cursor-dev,
48 libxcb-icccm4-dev,
49 libxcb-keysyms1-dev,
50 libxcb-randr0-dev,
51 libxcb-shape0,
52 libxcb-shape0-dev,
53 libxcb-util0-dev,
54 libxcb-xinerama0-dev,
55 libxcb-xkb-dev,
56 libxcb-xrm-dev,
57 libxcb-xrm0,
58 libxcb1-dev,
59 libxkbcommon-dev,
60 libxkbcommon-x11-dev,
61 libyajl-dev,
62 make,
63 xcb
64 Recommends: i3lock-color, suckless-tools, i3status (>= 2.3), dunst
65 Conflicts: i3
66 Description: metapackage (i3-gaps window manager, screen locker, menu, statusbar)
67 This metapackage installs the i3-gaps window manager (i3-gaps-wm), the i3lock-color screen
3868 locker, i3status (for system information) and suckless-tools (for dmenu).
39 These are all the tools you need to use the i3 window manager efficiently.
69 These are all the tools you need to use the i3-gaps window manager efficiently.
4070
41 Package: i3-wm
71 Package: i3-gaps-wm
4272 Architecture: any
4373 Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}
4474 Provides: x-window-manager
4575 Recommends: xfonts-base, fonts-dejavu-core, libanyevent-i3-perl (>= 0.12), libjson-xs-perl, rxvt-unicode | x-terminal-emulator
4676 Description: improved dynamic tiling window manager
47 Key features of i3 are good documentation, reasonable defaults (changeable in
77 Key features of i3-gaps are good documentation, reasonable defaults (changeable in
4878 a simple configuration file) and good multi-monitor support. The user
49 interface is designed for power users and emphasizes keyboard usage. i3 uses
79 interface is designed for power users and emphasizes keyboard usage. i3-gaps uses
5080 XCB for asynchronous communication with X11 and aims to be fast and
5181 light-weight.
5282 .
53 Please be aware i3 is primarily targeted at advanced users and developers.
83 Please be aware i3-gaps is primarily targeted at advanced users and developers.
5484
55 Package: i3-wm-dbg
85 Package: i3-gaps-wm-dbg
5686 Architecture: any
5787 Section: debug
58 Depends: i3-wm (=${binary:Version}), ${misc:Depends}
59 Description: Debugging symbols for the i3 window manager
60 Debugging symbols for the i3 window manager. Please install this to produce
88 Depends: i3-gaps-wm (=${binary:Version}), ${misc:Depends}
89 Description: Debugging symbols for the i3-gaps window manager
90 Debugging symbols for the i3-gaps window manager. Please install this to produce
6191 useful backtraces before creating new tickets.
00 Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
1 Upstream-Name: i3
2 Upstream-Contact: Michael Stapelberg <[email protected]>
3 Source: https://i3wm.org/
1 Upstream-Name: i3-wm
2 Upstream-Contact: Ingo Bürk <[email protected]>
3 Source: https://github.com/Airblader/i3
44
55 Files: *
66 Copyright: 2009 Michael Stapelberg
77 License: BSD-3-clause
88
99 Files: debian/*
10 Copyright: 2009 Michael Stapelberg
10 Copyright: 2020 Joseph O'Gorman <[email protected]>
1111 License: BSD-3-clause
1212
1313 License: BSD-3-clause
14 Copyright: © 2009 Michael Stapelberg <michael at i3wm dot org>
1514 All rights reserved.
1615 .
1716 Redistribution and use in source and binary forms, with or without
1817 modification, are permitted provided that the following conditions are met:
1918 .
20 * Redistributions of source code must retain the above copyright notice, this
21 list of conditions and the following disclaimer.
19 * Redistributions of source code must retain the above copyright
20 notice, this list of conditions and the following disclaimer.
2221 .
23 * Redistributions in binary form must reproduce the above copyright notice,
24 this list of conditions and the following disclaimer in the documentation
25 and/or other materials provided with the distribution.
22 * Redistributions in binary form must reproduce the above copyright
23 notice, this list of conditions and the following disclaimer in the
24 documentation and/or other materials provided with the distribution.
2625 .
27 * Neither the name of Michael Stapelberg, i3 nor the names of its contributors
28 may be used to endorse or promote products derived from this software
29 without specific prior written permission.
26 * Neither the name of Michael Stapelberg nor the
27 names of contributors may be used to endorse or promote products
28 derived from this software without specific prior written permission.
3029 .
31 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
32 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
34 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
35 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
37 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
39 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
40 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 THIS SOFTWARE IS PROVIDED BY Michael Stapelberg ''AS IS'' AND ANY
31 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
32 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
33 DISCLAIMED. IN NO EVENT SHALL Michael Stapelberg BE LIABLE FOR ANY
34 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
35 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
36 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
37 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
39 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0 [DEFAULT]
1 debian-branch = kali/master
2 debian-tag = kali/%(version)s
3 pristine-tar = True
4
5 [pq]
6 patch-numbers = False
7
8 [dch]
9 multimaint-merge = True
0 Document: i3-gaps
1 Title: i3 documentation
2 Author: Michael Stapelberg
3 Abstract: The documentation explains how to use and modify the i3 window
4 manager.
5 Section: Window Managers
6
7 Format: HTML
8 Files: /usr/share/doc/i3-gaps/*.html
9 Index: /usr/share/doc/i3-gaps/userguide.html
0 docs/debugging.html
1 docs/hacking-howto.html
2 docs/i3bar-protocol.html
3 docs/userguide.html
4 docs/bigpicture.png
5 docs/single_terminal.png
6 docs/snapping.png
7 docs/two_columns.png
8 docs/two_terminals.png
9 docs/modes.png
10 docs/ipc.html
11 docs/multi-monitor.html
12 docs/wsbar.html
13 docs/wsbar.png
14 docs/keyboard-layer1.png
15 docs/keyboard-layer2.png
16 docs/testsuite.html
17 docs/i3-sync-working.png
18 docs/i3-sync.png
19 docs/tree-layout1.png
20 docs/tree-layout2.png
21 docs/tree-shot1.png
22 docs/tree-shot2.png
23 docs/tree-shot3.png
24 docs/tree-shot4.png
25 docs/refcard.html
26 docs/refcard_style.css
27 docs/logo-30.png
28 docs/lib-i3test.html
29 docs/lib-i3test-test.html
30 docs/layout-saving.html
31 docs/layout-saving-1.png
0 debian/tmp/etc
1 debian/tmp/usr
2 contrib/dump-asy.pl usr/share/doc/i3-gaps/examples/
3 contrib/gtk-tree-watch.pl usr/share/doc/i3-gaps/examples/
4 contrib/i3-wsbar usr/share/doc/i3-gaps/examples/
5 contrib/per-workspace-layout.pl usr/share/doc/i3-gaps/examples/
6 contrib/trivial-bar-script.sh usr/share/doc/i3-gaps/examples/
0 usr/share/man/man1/i3.1.gz usr/share/man/man1/i3-with-shmlog.1.gz
0 man/i3.1
1 man/i3-msg.1
2 man/i3-input.1
3 man/i3-nagbar.1
4 man/i3-config-wizard.1
5 man/i3-dump-log.1
6 man/i3-migrate-config-to-v4.1
7 man/i3-sensible-pager.1
8 man/i3-sensible-editor.1
9 man/i3-sensible-terminal.1
10 man/i3-dmenu-desktop.1
11 man/i3-save-tree.1
12 man/i3bar.1
0 /usr/bin/i3
+0
-10
debian/i3-wm.doc-base less more
0 Document: i3-wm
1 Title: i3 documentation
2 Author: Michael Stapelberg
3 Abstract: The documentation explains how to use and modify the i3 window
4 manager.
5 Section: Window Managers
6
7 Format: HTML
8 Files: /usr/share/doc/i3-wm/*.html
9 Index: /usr/share/doc/i3-wm/userguide.html
+0
-32
debian/i3-wm.docs less more
0 docs/debugging.html
1 docs/hacking-howto.html
2 docs/i3bar-protocol.html
3 docs/userguide.html
4 docs/bigpicture.png
5 docs/single_terminal.png
6 docs/snapping.png
7 docs/two_columns.png
8 docs/two_terminals.png
9 docs/modes.png
10 docs/ipc.html
11 docs/multi-monitor.html
12 docs/wsbar.html
13 docs/wsbar.png
14 docs/keyboard-layer1.png
15 docs/keyboard-layer2.png
16 docs/testsuite.html
17 docs/i3-sync-working.png
18 docs/i3-sync.png
19 docs/tree-layout1.png
20 docs/tree-layout2.png
21 docs/tree-shot1.png
22 docs/tree-shot2.png
23 docs/tree-shot3.png
24 docs/tree-shot4.png
25 docs/refcard.html
26 docs/refcard_style.css
27 docs/logo-30.png
28 docs/lib-i3test.html
29 docs/lib-i3test-test.html
30 docs/layout-saving.html
31 docs/layout-saving-1.png
+0
-7
debian/i3-wm.install less more
0 debian/tmp/etc
1 debian/tmp/usr
2 contrib/dump-asy.pl usr/share/doc/i3-wm/examples/
3 contrib/gtk-tree-watch.pl usr/share/doc/i3-wm/examples/
4 contrib/i3-wsbar usr/share/doc/i3-wm/examples/
5 contrib/per-workspace-layout.pl usr/share/doc/i3-wm/examples/
6 contrib/trivial-bar-script.sh usr/share/doc/i3-wm/examples/
+0
-1
debian/i3-wm.links less more
0 usr/share/man/man1/i3.1.gz usr/share/man/man1/i3-with-shmlog.1.gz
+0
-13
debian/i3-wm.manpages less more
0 man/i3.1
1 man/i3-msg.1
2 man/i3-input.1
3 man/i3-nagbar.1
4 man/i3-config-wizard.1
5 man/i3-dump-log.1
6 man/i3-migrate-config-to-v4.1
7 man/i3-sensible-pager.1
8 man/i3-sensible-editor.1
9 man/i3-sensible-terminal.1
10 man/i3-dmenu-desktop.1
11 man/i3-save-tree.1
12 man/i3bar.1
+0
-1
debian/i3-wm.wm less more
0 /usr/bin/i3
0 include:
1 - https://gitlab.com/kalilinux/tools/kali-ci-pipeline/raw/master/recipes/kali.yml
77 dh_installchangelogs RELEASE-NOTES-*
88
99 override_dh_strip:
10 dh_strip --dbg-package=i3-wm-dbg
10 dh_strip --dbg-package=i3-gaps-wm-dbg
1111
1212 override_dh_auto_test:
1313 # TODO: enable tests
1414
1515 override_dh_auto_configure:
1616 # The default is /usr/share/doc/i3
17 dh_auto_configure -- --docdir=/usr/share/doc/i3-wm
17 dh_auto_configure -- --docdir=/usr/share/doc/i3-gaps
1818
1919 override_dh_builddeb:
2020 # bintray does not support xz currently.
0 version=3
1 opts=pgpsigurlmangle=s/$/.asc/ \
2 https://i3wm.org/downloads/ /downloads/i3-(.*)\.tar\.bz2
0 version=4
1 https://github.com/Airblader/i3/tags \
2 (?:.*?/)?i3-(\d[\d.]*)\.tar\.gz debian uupdate
0 <?xml version="1.0" encoding="UTF-8"?>
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
2 "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
4 <head>
5 <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
6 <meta name="generator" content="AsciiDoc 8.6.10" />
7 <title>Debugging i3: How To</title>
8 <style type="text/css">
9 /* Shared CSS for AsciiDoc xhtml11 and html5 backends */
10
11 /* Default font. */
12 body {
13 font-family: Georgia,serif;
14 }
15
16 /* Title font. */
17 h1, h2, h3, h4, h5, h6,
18 div.title, caption.title,
19 thead, p.table.header,
20 #toctitle,
21 #author, #revnumber, #revdate, #revremark,
22 #footer {
23 font-family: Arial,Helvetica,sans-serif;
24 }
25
26 body {
27 margin: 1em 5% 1em 5%;
28 }
29
30 a {
31 color: blue;
32 text-decoration: underline;
33 }
34 a:visited {
35 color: fuchsia;
36 }
37
38 em {
39 font-style: italic;
40 color: navy;
41 }
42
43 strong {
44 font-weight: bold;
45 color: #083194;
46 }
47
48 h1, h2, h3, h4, h5, h6 {
49 color: #527bbd;
50 margin-top: 1.2em;
51 margin-bottom: 0.5em;
52 line-height: 1.3;
53 }
54
55 h1, h2, h3 {
56 border-bottom: 2px solid silver;
57 }
58 h2 {
59 padding-top: 0.5em;
60 }
61 h3 {
62 float: left;
63 }
64 h3 + * {
65 clear: left;
66 }
67 h5 {
68 font-size: 1.0em;
69 }
70
71 div.sectionbody {
72 margin-left: 0;
73 }
74
75 hr {
76 border: 1px solid silver;
77 }
78
79 p {
80 margin-top: 0.5em;
81 margin-bottom: 0.5em;
82 }
83
84 ul, ol, li > p {
85 margin-top: 0;
86 }
87 ul > li { color: #aaa; }
88 ul > li > * { color: black; }
89
90 .monospaced, code, pre {
91 font-family: "Courier New", Courier, monospace;
92 font-size: inherit;
93 color: navy;
94 padding: 0;
95 margin: 0;
96 }
97 pre {
98 white-space: pre-wrap;
99 }
100
101 #author {
102 color: #527bbd;
103 font-weight: bold;
104 font-size: 1.1em;
105 }
106 #email {
107 }
108 #revnumber, #revdate, #revremark {
109 }
110
111 #footer {
112 font-size: small;
113 border-top: 2px solid silver;
114 padding-top: 0.5em;
115 margin-top: 4.0em;
116 }
117 #footer-text {
118 float: left;
119 padding-bottom: 0.5em;
120 }
121 #footer-badges {
122 float: right;
123 padding-bottom: 0.5em;
124 }
125
126 #preamble {
127 margin-top: 1.5em;
128 margin-bottom: 1.5em;
129 }
130 div.imageblock, div.exampleblock, div.verseblock,
131 div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
132 div.admonitionblock {
133 margin-top: 1.0em;
134 margin-bottom: 1.5em;
135 }
136 div.admonitionblock {
137 margin-top: 2.0em;
138 margin-bottom: 2.0em;
139 margin-right: 10%;
140 color: #606060;
141 }
142
143 div.content { /* Block element content. */
144 padding: 0;
145 }
146
147 /* Block element titles. */
148 div.title, caption.title {
149 color: #527bbd;
150 font-weight: bold;
151 text-align: left;
152 margin-top: 1.0em;
153 margin-bottom: 0.5em;
154 }
155 div.title + * {
156 margin-top: 0;
157 }
158
159 td div.title:first-child {
160 margin-top: 0.0em;
161 }
162 div.content div.title:first-child {
163 margin-top: 0.0em;
164 }
165 div.content + div.title {
166 margin-top: 0.0em;
167 }
168
169 div.sidebarblock > div.content {
170 background: #ffffee;
171 border: 1px solid #dddddd;
172 border-left: 4px solid #f0f0f0;
173 padding: 0.5em;
174 }
175
176 div.listingblock > div.content {
177 border: 1px solid #dddddd;
178 border-left: 5px solid #f0f0f0;
179 background: #f8f8f8;
180 padding: 0.5em;
181 }
182
183 div.quoteblock, div.verseblock {
184 padding-left: 1.0em;
185 margin-left: 1.0em;
186 margin-right: 10%;
187 border-left: 5px solid #f0f0f0;
188 color: #888;
189 }
190
191 div.quoteblock > div.attribution {
192 padding-top: 0.5em;
193 text-align: right;
194 }
195
196 div.verseblock > pre.content {
197 font-family: inherit;
198 font-size: inherit;
199 }
200 div.verseblock > div.attribution {
201 padding-top: 0.75em;
202 text-align: left;
203 }
204 /* DEPRECATED: Pre version 8.2.7 verse style literal block. */
205 div.verseblock + div.attribution {
206 text-align: left;
207 }
208
209 div.admonitionblock .icon {
210 vertical-align: top;
211 font-size: 1.1em;
212 font-weight: bold;
213 text-decoration: underline;
214 color: #527bbd;
215 padding-right: 0.5em;
216 }
217 div.admonitionblock td.content {
218 padding-left: 0.5em;
219 border-left: 3px solid #dddddd;
220 }
221
222 div.exampleblock > div.content {
223 border-left: 3px solid #dddddd;
224 padding-left: 0.5em;
225 }
226
227 div.imageblock div.content { padding-left: 0; }
228 span.image img { border-style: none; vertical-align: text-bottom; }
229 a.image:visited { color: white; }
230
231 dl {
232 margin-top: 0.8em;
233 margin-bottom: 0.8em;
234 }
235 dt {
236 margin-top: 0.5em;
237 margin-bottom: 0;
238 font-style: normal;
239 color: navy;
240 }
241 dd > *:first-child {
242 margin-top: 0.1em;
243 }
244
245 ul, ol {
246 list-style-position: outside;
247 }
248 ol.arabic {
249 list-style-type: decimal;
250 }
251 ol.loweralpha {
252 list-style-type: lower-alpha;
253 }
254 ol.upperalpha {
255 list-style-type: upper-alpha;
256 }
257 ol.lowerroman {
258 list-style-type: lower-roman;
259 }
260 ol.upperroman {
261 list-style-type: upper-roman;
262 }
263
264 div.compact ul, div.compact ol,
265 div.compact p, div.compact p,
266 div.compact div, div.compact div {
267 margin-top: 0.1em;
268 margin-bottom: 0.1em;
269 }
270
271 tfoot {
272 font-weight: bold;
273 }
274 td > div.verse {
275 white-space: pre;
276 }
277
278 div.hdlist {
279 margin-top: 0.8em;
280 margin-bottom: 0.8em;
281 }
282 div.hdlist tr {
283 padding-bottom: 15px;
284 }
285 dt.hdlist1.strong, td.hdlist1.strong {
286 font-weight: bold;
287 }
288 td.hdlist1 {
289 vertical-align: top;
290 font-style: normal;
291 padding-right: 0.8em;
292 color: navy;
293 }
294 td.hdlist2 {
295 vertical-align: top;
296 }
297 div.hdlist.compact tr {
298 margin: 0;
299 padding-bottom: 0;
300 }
301
302 .comment {
303 background: yellow;
304 }
305
306 .footnote, .footnoteref {
307 font-size: 0.8em;
308 }
309
310 span.footnote, span.footnoteref {
311 vertical-align: super;
312 }
313
314 #footnotes {
315 margin: 20px 0 20px 0;
316 padding: 7px 0 0 0;
317 }
318
319 #footnotes div.footnote {
320 margin: 0 0 5px 0;
321 }
322
323 #footnotes hr {
324 border: none;
325 border-top: 1px solid silver;
326 height: 1px;
327 text-align: left;
328 margin-left: 0;
329 width: 20%;
330 min-width: 100px;
331 }
332
333 div.colist td {
334 padding-right: 0.5em;
335 padding-bottom: 0.3em;
336 vertical-align: top;
337 }
338 div.colist td img {
339 margin-top: 0.3em;
340 }
341
342 @media print {
343 #footer-badges { display: none; }
344 }
345
346 #toc {
347 margin-bottom: 2.5em;
348 }
349
350 #toctitle {
351 color: #527bbd;
352 font-size: 1.1em;
353 font-weight: bold;
354 margin-top: 1.0em;
355 margin-bottom: 0.1em;
356 }
357
358 div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
359 margin-top: 0;
360 margin-bottom: 0;
361 }
362 div.toclevel2 {
363 margin-left: 2em;
364 font-size: 0.9em;
365 }
366 div.toclevel3 {
367 margin-left: 4em;
368 font-size: 0.9em;
369 }
370 div.toclevel4 {
371 margin-left: 6em;
372 font-size: 0.9em;
373 }
374
375 span.aqua { color: aqua; }
376 span.black { color: black; }
377 span.blue { color: blue; }
378 span.fuchsia { color: fuchsia; }
379 span.gray { color: gray; }
380 span.green { color: green; }
381 span.lime { color: lime; }
382 span.maroon { color: maroon; }
383 span.navy { color: navy; }
384 span.olive { color: olive; }
385 span.purple { color: purple; }
386 span.red { color: red; }
387 span.silver { color: silver; }
388 span.teal { color: teal; }
389 span.white { color: white; }
390 span.yellow { color: yellow; }
391
392 span.aqua-background { background: aqua; }
393 span.black-background { background: black; }
394 span.blue-background { background: blue; }
395 span.fuchsia-background { background: fuchsia; }
396 span.gray-background { background: gray; }
397 span.green-background { background: green; }
398 span.lime-background { background: lime; }
399 span.maroon-background { background: maroon; }
400 span.navy-background { background: navy; }
401 span.olive-background { background: olive; }
402 span.purple-background { background: purple; }
403 span.red-background { background: red; }
404 span.silver-background { background: silver; }
405 span.teal-background { background: teal; }
406 span.white-background { background: white; }
407 span.yellow-background { background: yellow; }
408
409 span.big { font-size: 2em; }
410 span.small { font-size: 0.6em; }
411
412 span.underline { text-decoration: underline; }
413 span.overline { text-decoration: overline; }
414 span.line-through { text-decoration: line-through; }
415
416 div.unbreakable { page-break-inside: avoid; }
417
418
419 /*
420 * xhtml11 specific
421 *
422 * */
423
424 div.tableblock {
425 margin-top: 1.0em;
426 margin-bottom: 1.5em;
427 }
428 div.tableblock > table {
429 border: 3px solid #527bbd;
430 }
431 thead, p.table.header {
432 font-weight: bold;
433 color: #527bbd;
434 }
435 p.table {
436 margin-top: 0;
437 }
438 /* Because the table frame attribute is overriden by CSS in most browsers. */
439 div.tableblock > table[frame="void"] {
440 border-style: none;
441 }
442 div.tableblock > table[frame="hsides"] {
443 border-left-style: none;
444 border-right-style: none;
445 }
446 div.tableblock > table[frame="vsides"] {
447 border-top-style: none;
448 border-bottom-style: none;
449 }
450
451
452 /*
453 * html5 specific
454 *
455 * */
456
457 table.tableblock {
458 margin-top: 1.0em;
459 margin-bottom: 1.5em;
460 }
461 thead, p.tableblock.header {
462 font-weight: bold;
463 color: #527bbd;
464 }
465 p.tableblock {
466 margin-top: 0;
467 }
468 table.tableblock {
469 border-width: 3px;
470 border-spacing: 0px;
471 border-style: solid;
472 border-color: #527bbd;
473 border-collapse: collapse;
474 }
475 th.tableblock, td.tableblock {
476 border-width: 1px;
477 padding: 4px;
478 border-style: solid;
479 border-color: #527bbd;
480 }
481
482 table.tableblock.frame-topbot {
483 border-left-style: hidden;
484 border-right-style: hidden;
485 }
486 table.tableblock.frame-sides {
487 border-top-style: hidden;
488 border-bottom-style: hidden;
489 }
490 table.tableblock.frame-none {
491 border-style: hidden;
492 }
493
494 th.tableblock.halign-left, td.tableblock.halign-left {
495 text-align: left;
496 }
497 th.tableblock.halign-center, td.tableblock.halign-center {
498 text-align: center;
499 }
500 th.tableblock.halign-right, td.tableblock.halign-right {
501 text-align: right;
502 }
503
504 th.tableblock.valign-top, td.tableblock.valign-top {
505 vertical-align: top;
506 }
507 th.tableblock.valign-middle, td.tableblock.valign-middle {
508 vertical-align: middle;
509 }
510 th.tableblock.valign-bottom, td.tableblock.valign-bottom {
511 vertical-align: bottom;
512 }
513
514
515 /*
516 * manpage specific
517 *
518 * */
519
520 body.manpage h1 {
521 padding-top: 0.5em;
522 padding-bottom: 0.5em;
523 border-top: 2px solid silver;
524 border-bottom: 2px solid silver;
525 }
526 body.manpage h2 {
527 border-style: none;
528 }
529 body.manpage div.sectionbody {
530 margin-left: 3em;
531 }
532
533 @media print {
534 body.manpage div#toc { display: none; }
535 }
536
537
538 </style>
539 <script type="text/javascript">
540 /*<![CDATA[*/
541 var asciidoc = { // Namespace.
542
543 /////////////////////////////////////////////////////////////////////
544 // Table Of Contents generator
545 /////////////////////////////////////////////////////////////////////
546
547 /* Author: Mihai Bazon, September 2002
548 * http://students.infoiasi.ro/~mishoo
549 *
550 * Table Of Content generator
551 * Version: 0.4
552 *
553 * Feel free to use this script under the terms of the GNU General Public
554 * License, as long as you do not remove or alter this notice.
555 */
556
557 /* modified by Troy D. Hanson, September 2006. License: GPL */
558 /* modified by Stuart Rackham, 2006, 2009. License: GPL */
559
560 // toclevels = 1..4.
561 toc: function (toclevels) {
562
563 function getText(el) {
564 var text = "";
565 for (var i = el.firstChild; i != null; i = i.nextSibling) {
566 if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
567 text += i.data;
568 else if (i.firstChild != null)
569 text += getText(i);
570 }
571 return text;
572 }
573
574 function TocEntry(el, text, toclevel) {
575 this.element = el;
576 this.text = text;
577 this.toclevel = toclevel;
578 }
579
580 function tocEntries(el, toclevels) {
581 var result = new Array;
582 var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
583 // Function that scans the DOM tree for header elements (the DOM2
584 // nodeIterator API would be a better technique but not supported by all
585 // browsers).
586 var iterate = function (el) {
587 for (var i = el.firstChild; i != null; i = i.nextSibling) {
588 if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
589 var mo = re.exec(i.tagName);
590 if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
591 result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
592 }
593 iterate(i);
594 }
595 }
596 }
597 iterate(el);
598 return result;
599 }
600
601 var toc = document.getElementById("toc");
602 if (!toc) {
603 return;
604 }
605
606 // Delete existing TOC entries in case we're reloading the TOC.
607 var tocEntriesToRemove = [];
608 var i;
609 for (i = 0; i < toc.childNodes.length; i++) {
610 var entry = toc.childNodes[i];
611 if (entry.nodeName.toLowerCase() == 'div'
612 && entry.getAttribute("class")
613 && entry.getAttribute("class").match(/^toclevel/))
614 tocEntriesToRemove.push(entry);
615 }
616 for (i = 0; i < tocEntriesToRemove.length; i++) {
617 toc.removeChild(tocEntriesToRemove[i]);
618 }
619
620 // Rebuild TOC entries.
621 var entries = tocEntries(document.getElementById("content"), toclevels);
622 for (var i = 0; i < entries.length; ++i) {
623 var entry = entries[i];
624 if (entry.element.id == "")
625 entry.element.id = "_toc_" + i;
626 var a = document.createElement("a");
627 a.href = "#" + entry.element.id;
628 a.appendChild(document.createTextNode(entry.text));
629 var div = document.createElement("div");
630 div.appendChild(a);
631 div.className = "toclevel" + entry.toclevel;
632 toc.appendChild(div);
633 }
634 if (entries.length == 0)
635 toc.parentNode.removeChild(toc);
636 },
637
638
639 /////////////////////////////////////////////////////////////////////
640 // Footnotes generator
641 /////////////////////////////////////////////////////////////////////
642
643 /* Based on footnote generation code from:
644 * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
645 */
646
647 footnotes: function () {
648 // Delete existing footnote entries in case we're reloading the footnodes.
649 var i;
650 var noteholder = document.getElementById("footnotes");
651 if (!noteholder) {
652 return;
653 }
654 var entriesToRemove = [];
655 for (i = 0; i < noteholder.childNodes.length; i++) {
656 var entry = noteholder.childNodes[i];
657 if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
658 entriesToRemove.push(entry);
659 }
660 for (i = 0; i < entriesToRemove.length; i++) {
661 noteholder.removeChild(entriesToRemove[i]);
662 }
663
664 // Rebuild footnote entries.
665 var cont = document.getElementById("content");
666 var spans = cont.getElementsByTagName("span");
667 var refs = {};
668 var n = 0;
669 for (i=0; i<spans.length; i++) {
670 if (spans[i].className == "footnote") {
671 n++;
672 var note = spans[i].getAttribute("data-note");
673 if (!note) {
674 // Use [\s\S] in place of . so multi-line matches work.
675 // Because JavaScript has no s (dotall) regex flag.
676 note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
677 spans[i].innerHTML =
678 "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
679 "' title='View footnote' class='footnote'>" + n + "</a>]";
680 spans[i].setAttribute("data-note", note);
681 }
682 noteholder.innerHTML +=
683 "<div class='footnote' id='_footnote_" + n + "'>" +
684 "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
685 n + "</a>. " + note + "</div>";
686 var id =spans[i].getAttribute("id");
687 if (id != null) refs["#"+id] = n;
688 }
689 }
690 if (n == 0)
691 noteholder.parentNode.removeChild(noteholder);
692 else {
693 // Process footnoterefs.
694 for (i=0; i<spans.length; i++) {
695 if (spans[i].className == "footnoteref") {
696 var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
697 href = href.match(/#.*/)[0]; // Because IE return full URL.
698 n = refs[href];
699 spans[i].innerHTML =
700 "[<a href='#_footnote_" + n +
701 "' title='View footnote' class='footnote'>" + n + "</a>]";
702 }
703 }
704 }
705 },
706
707 install: function(toclevels) {
708 var timerId;
709
710 function reinstall() {
711 asciidoc.footnotes();
712 if (toclevels) {
713 asciidoc.toc(toclevels);
714 }
715 }
716
717 function reinstallAndRemoveTimer() {
718 clearInterval(timerId);
719 reinstall();
720 }
721
722 timerId = setInterval(reinstall, 500);
723 if (document.addEventListener)
724 document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
725 else
726 window.onload = reinstallAndRemoveTimer;
727 }
728
729 }
730 asciidoc.install();
731 /*]]>*/
732 </script>
733 </head>
734 <body class="article">
735 <div id="header">
736 <h1>Debugging i3: How To</h1>
737 <span id="author">Michael Stapelberg</span><br />
738 <span id="email"><code>&lt;<a href="mailto:[email protected]">[email protected]</a>&gt;</code></span><br />
739 <span id="revdate">January 2014</span>
740 </div>
741 <div id="content">
742 <div id="preamble">
743 <div class="sectionbody">
744 <div class="paragraph"><p>This document describes how to debug i3 to send us useful bug
745 reports, even if you have no knowledge of C programming.</p></div>
746 <div class="paragraph"><p>Thank you for being interested in debugging i3. It really means
747 something to us to get your bug fixed. If you have any questions about the
748 process and/or need further help, do not hesitate to contact us!</p></div>
749 </div>
750 </div>
751 <div class="sect1">
752 <h2 id="_verify_you_are_using_i3_4_10">1. Verify you are using i3 ≥ 4.10</h2>
753 <div class="sectionbody">
754 <div class="paragraph"><p>Only the latest major version of i3 is supported. To verify which version
755 you are running, use:</p></div>
756 <div class="listingblock">
757 <div class="content">
758 <pre><code>$ i3 --moreversion 2&gt;&amp;- || i3 --version
759 Binary i3 version: 4.7 (2013-12-22, branch "tags/4.7")
760 Running i3 version: 4.7-84-gac74a63 (2014-01-01, branch "next") (pid 1995)</code></pre>
761 </div></div>
762 <div class="paragraph"><p>Your version can look like this:</p></div>
763 <div class="dlist"><dl>
764 <dt class="hdlist1">
765 4.7 (release version)
766 </dt>
767 <dd>
768 <p>
769 You are using a release version. In many cases, bugs are already
770 fixed in the development version of i3. Even if the bug is not a known fixed
771 one, we will still ask you to reproduce your error with the most recent
772 development version of i3. Therefore, please upgrade to a development version
773 if you can.
774 </p>
775 </dd>
776 <dt class="hdlist1">
777 4.7-85-g9c15b95 (development version)
778 </dt>
779 <dd>
780 <p>
781 Your version is 85 commits newer than 4.7, and the git revision of your
782 version is <code>9c15b95</code>. Go to <a href="https://github.com/i3/i3/commits/next">https://github.com/i3/i3/commits/next</a> and see if
783 the most recent commit starts with the same revision. If so, you are using the
784 latest version.
785 </p>
786 </dd>
787 </dl></div>
788 <div class="paragraph"><p>Development versions of i3 have logging enabled by default and are compiled
789 with debug symbols.</p></div>
790 </div>
791 </div>
792 <div class="sect1">
793 <h2 id="_enabling_logging">2. Enabling logging</h2>
794 <div class="sectionbody">
795 <div class="paragraph"><p>If you are using a development version (see previous section), you don’t need
796 to do anything&#8201;&#8212;&#8201;skip to section 3.</p></div>
797 <div class="paragraph"><p>If you are using a release version with a custom <code>~/.xsession</code> (or xinitrc)
798 file, execute i3 with a line like this:</p></div>
799 <div class="listingblock">
800 <div class="content">
801 <pre><code># Use 25 MiB of RAM for debug logs
802 exec i3 --shmlog-size=26214400</code></pre>
803 </div></div>
804 <div class="paragraph"><p>If you are <strong>NOT</strong> using an <code>~/.xsession</code> file but you just chose "i3" from the
805 list of sessions in your desktop manager (gdm, lxdm, …), edit
806 <code>/usr/share/xsessions/i3.desktop</code> and replace the <code>Exec=i3</code> line with:</p></div>
807 <div class="listingblock">
808 <div class="content">
809 <pre><code>Exec=i3 --shmlog-size=26214400</code></pre>
810 </div></div>
811 <div class="paragraph"><p>If you cannot restart i3 for some reason, you can enable debug logging on the
812 fly:</p></div>
813 <div class="listingblock">
814 <div class="content">
815 <pre><code>i3-msg 'debuglog on; shmlog on; reload'</code></pre>
816 </div></div>
817 </div>
818 </div>
819 <div class="sect1">
820 <h2 id="_reproducing_the_problem">3. Reproducing the problem</h2>
821 <div class="sectionbody">
822 <div class="paragraph"><p>Before submitting an issue, please make sure to close down on the problem as
823 much as you can yourself. Here are some steps you should consider:</p></div>
824 <div class="ulist"><ul>
825 <li>
826 <p>
827 Find a deterministic, reliable way to reproduce the problem and provide it
828 with your bug report.
829 </p>
830 </li>
831 <li>
832 <p>
833 Try using the default i3 config to reproduce the problem. If the issue does
834 not appear with the default config, gradually adapt it to track down what
835 change(s) to the config introduce the problem.
836 </p>
837 </li>
838 <li>
839 <p>
840 Reproduce the problem with a minimal setup, i.e., only use as few applications,
841 windows and steps as necessary.
842 </p>
843 </li>
844 <li>
845 <p>
846 In addition, try to stick to applications that are common and, even more
847 importantly, free / open source.
848 </p>
849 </li>
850 <li>
851 <p>
852 Before obtaining the log file, restart i3 in-place, execute the steps to
853 reproduce the problem and then save the logs. This keeps the log file as
854 small as possible and necessary.
855 </p>
856 </li>
857 </ul></div>
858 <div class="paragraph"><p>Please be aware that we cannot support compatibility issues with closed-source
859 software, as digging into compatibility problems without having access to the
860 source code is too time-consuming. Additionally, experience has shown that
861 often, the software in question is responsible for the issue. Please raise an
862 issue with the software in question, not i3.</p></div>
863 </div>
864 </div>
865 <div class="sect1">
866 <h2 id="_obtaining_the_debug_logfile">4. Obtaining the debug logfile</h2>
867 <div class="sectionbody">
868 <div class="admonitionblock">
869 <table><tr>
870 <td class="icon">
871 <div class="title">Caution</div>
872 </td>
873 <td class="content">
874 <div class="paragraph"><p>Logs may contain sensitive information, so please inspect the log before
875 submitting it. Logs may be viewed by anyone, once posted. If you choose to
876 redact the log, make an effort not to discard information which may be relevant
877 to the issue you are reporting.</p></div>
878 <div class="paragraph"><p>The best way to avoid submitting such information is to only run the necessary
879 steps to reproduce the behavior when saving the log file. This will also make
880 analyzing the log file easier.</p></div>
881 </td>
882 </tr></table>
883 </div>
884 <div class="paragraph"><p>No matter whether i3 misbehaved in some way without crashing or whether it just
885 crashed, the logfile provides all information necessary to debug the problem.</p></div>
886 <div class="paragraph"><p>To upload a compressed version of the logfile (for a bugreport), use:</p></div>
887 <div class="listingblock">
888 <div class="content">
889 <pre><code>DISPLAY=:0 i3-dump-log | bzip2 -c | curl --data-binary @- https://logs.i3wm.org</code></pre>
890 </div></div>
891 <div class="paragraph"><p>This command does not depend on i3 (it also works while i3 displays
892 the crash dialog), but it requires a working X11 connection.</p></div>
893 <div class="paragraph"><p>After running it, you will get a URL to the logfile. Please include that URL in
894 your bug report.</p></div>
895 </div>
896 </div>
897 <div class="sect1">
898 <h2 id="_on_crashes_obtaining_a_backtrace">5. On crashes: Obtaining a backtrace</h2>
899 <div class="sectionbody">
900 <div class="paragraph"><p>When i3 crashes, it will display a dialog stating “i3 just crashed”, offering
901 you to save a backtrace to a text file.</p></div>
902 <div class="paragraph"><p>To actually get useful backtraces, you should make sure that your version of i3
903 is compiled with debug symbols:</p></div>
904 <div class="listingblock">
905 <div class="content">
906 <pre><code>$ file `which i3`
907 /usr/bin/i3: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically
908 linked (uses shared libs), for GNU/Linux 2.6.18, not stripped</code></pre>
909 </div></div>
910 <div class="paragraph"><p>Notice the <code>not stripped</code>, which is the important part. If you have a version
911 which is stripped, please check whether your distribution provides debug
912 symbols (package <code>i3-wm-dbg</code> on Debian for example) or if you can turn off
913 stripping. If nothing helps, please build i3 from source.</p></div>
914 <div class="paragraph"><p>Once you have made sure that your i3 is compiled with debug symbols and the C
915 debugger <code>gdb</code> is installed on your machine, you can let i3 generate a
916 backtrace in the crash dialog.</p></div>
917 <div class="paragraph"><p>After pressing "b" in the crash dialog, you will get a file called
918 <code>/tmp/i3-backtrace.%d.%d.txt</code> where the first <code>%d</code> is replaced by i3’s process
919 id (PID) and the second one is incremented each time you generate a backtrace,
920 starting at 0.</p></div>
921 </div>
922 </div>
923 <div class="sect1">
924 <h2 id="_sending_bug_reports_debugging_on_irc">6. Sending bug reports/debugging on IRC</h2>
925 <div class="sectionbody">
926 <div class="paragraph"><p>When sending bug reports, please attach the <strong>whole</strong> log file. Even if you think
927 you found the section which clearly highlights the problem, additional
928 information might be necessary to completely diagnose the problem.</p></div>
929 <div class="paragraph"><p>When debugging with us in IRC, be prepared to use a so-called nopaste service
930 such as <a href="https://pastebin.com">https://pastebin.com</a> because pasting large amounts of text in IRC
931 sometimes leads to incomplete lines (servers have line length limitations) or
932 flood kicks.</p></div>
933 </div>
934 </div>
935 <div class="sect1">
936 <h2 id="_debugging_i3bar">7. Debugging i3bar</h2>
937 <div class="sectionbody">
938 <div class="paragraph"><p>To debug i3bar problems, use the <code>--verbose</code> commandline parameter,
939 or add <code>verbose yes</code> to all <code>bar {}</code> blocks in your i3
940 config, reload your config and then restart all i3bar instances like this:</p></div>
941 <div class="listingblock">
942 <div class="content">
943 <pre><code>$ i3 reload
944 $ killall i3bar
945 $ for c in $(i3-msg -t get_bar_config | python -c \
946 'import json,sys;print("\n".join(json.load(sys.stdin)))'); do \
947 (i3bar --bar_id=$c &gt;i3bar.$c.log 2&gt;&amp;1) &amp; \
948 done;</code></pre>
949 </div></div>
950 <div class="paragraph"><p>There will now be <code>i3bar.*.log</code> files in your current directory that you can provide
951 in your bug report.</p></div>
952 </div>
953 </div>
954 </div>
955 <div id="footnotes"><hr /></div>
956 <div id="footer">
957 <div id="footer-text">
958 Last updated
959 2019-08-30 23:06:47 CEST
960 </div>
961 </div>
962 </body>
963 </html>
0 <?xml version="1.0" encoding="UTF-8"?>
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
2 "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
4 <head>
5 <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
6 <meta name="generator" content="AsciiDoc 8.6.10" />
7 <title>Hacking i3: How To</title>
8 <style type="text/css">
9 /* Shared CSS for AsciiDoc xhtml11 and html5 backends */
10
11 /* Default font. */
12 body {
13 font-family: Georgia,serif;
14 }
15
16 /* Title font. */
17 h1, h2, h3, h4, h5, h6,
18 div.title, caption.title,
19 thead, p.table.header,
20 #toctitle,
21 #author, #revnumber, #revdate, #revremark,
22 #footer {
23 font-family: Arial,Helvetica,sans-serif;
24 }
25
26 body {
27 margin: 1em 5% 1em 5%;
28 }
29
30 a {
31 color: blue;
32 text-decoration: underline;
33 }
34 a:visited {
35 color: fuchsia;
36 }
37
38 em {
39 font-style: italic;
40 color: navy;
41 }
42
43 strong {
44 font-weight: bold;
45 color: #083194;
46 }
47
48 h1, h2, h3, h4, h5, h6 {
49 color: #527bbd;
50 margin-top: 1.2em;
51 margin-bottom: 0.5em;
52 line-height: 1.3;
53 }
54
55 h1, h2, h3 {
56 border-bottom: 2px solid silver;
57 }
58 h2 {
59 padding-top: 0.5em;
60 }
61 h3 {
62 float: left;
63 }
64 h3 + * {
65 clear: left;
66 }
67 h5 {
68 font-size: 1.0em;
69 }
70
71 div.sectionbody {
72 margin-left: 0;
73 }
74
75 hr {
76 border: 1px solid silver;
77 }
78
79 p {
80 margin-top: 0.5em;
81 margin-bottom: 0.5em;
82 }
83
84 ul, ol, li > p {
85 margin-top: 0;
86 }
87 ul > li { color: #aaa; }
88 ul > li > * { color: black; }
89
90 .monospaced, code, pre {
91 font-family: "Courier New", Courier, monospace;
92 font-size: inherit;
93 color: navy;
94 padding: 0;
95 margin: 0;
96 }
97 pre {
98 white-space: pre-wrap;
99 }
100
101 #author {
102 color: #527bbd;
103 font-weight: bold;
104 font-size: 1.1em;
105 }
106 #email {
107 }
108 #revnumber, #revdate, #revremark {
109 }
110
111 #footer {
112 font-size: small;
113 border-top: 2px solid silver;
114 padding-top: 0.5em;
115 margin-top: 4.0em;
116 }
117 #footer-text {
118 float: left;
119 padding-bottom: 0.5em;
120 }
121 #footer-badges {
122 float: right;
123 padding-bottom: 0.5em;
124 }
125
126 #preamble {
127 margin-top: 1.5em;
128 margin-bottom: 1.5em;
129 }
130 div.imageblock, div.exampleblock, div.verseblock,
131 div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
132 div.admonitionblock {
133 margin-top: 1.0em;
134 margin-bottom: 1.5em;
135 }
136 div.admonitionblock {
137 margin-top: 2.0em;
138 margin-bottom: 2.0em;
139 margin-right: 10%;
140 color: #606060;
141 }
142
143 div.content { /* Block element content. */
144 padding: 0;
145 }
146
147 /* Block element titles. */
148 div.title, caption.title {
149 color: #527bbd;
150 font-weight: bold;
151 text-align: left;
152 margin-top: 1.0em;
153 margin-bottom: 0.5em;
154 }
155 div.title + * {
156 margin-top: 0;
157 }
158
159 td div.title:first-child {
160 margin-top: 0.0em;
161 }
162 div.content div.title:first-child {
163 margin-top: 0.0em;
164 }
165 div.content + div.title {
166 margin-top: 0.0em;
167 }
168
169 div.sidebarblock > div.content {
170 background: #ffffee;
171 border: 1px solid #dddddd;
172 border-left: 4px solid #f0f0f0;
173 padding: 0.5em;
174 }
175
176 div.listingblock > div.content {
177 border: 1px solid #dddddd;
178 border-left: 5px solid #f0f0f0;
179 background: #f8f8f8;
180 padding: 0.5em;
181 }
182
183 div.quoteblock, div.verseblock {
184 padding-left: 1.0em;
185 margin-left: 1.0em;
186 margin-right: 10%;
187 border-left: 5px solid #f0f0f0;
188 color: #888;
189 }
190
191 div.quoteblock > div.attribution {
192 padding-top: 0.5em;
193 text-align: right;
194 }
195
196 div.verseblock > pre.content {
197 font-family: inherit;
198 font-size: inherit;
199 }
200 div.verseblock > div.attribution {
201 padding-top: 0.75em;
202 text-align: left;
203 }
204 /* DEPRECATED: Pre version 8.2.7 verse style literal block. */
205 div.verseblock + div.attribution {
206 text-align: left;
207 }
208
209 div.admonitionblock .icon {
210 vertical-align: top;
211 font-size: 1.1em;
212 font-weight: bold;
213 text-decoration: underline;
214 color: #527bbd;
215 padding-right: 0.5em;
216 }
217 div.admonitionblock td.content {
218 padding-left: 0.5em;
219 border-left: 3px solid #dddddd;
220 }
221
222 div.exampleblock > div.content {
223 border-left: 3px solid #dddddd;
224 padding-left: 0.5em;
225 }
226
227 div.imageblock div.content { padding-left: 0; }
228 span.image img { border-style: none; vertical-align: text-bottom; }
229 a.image:visited { color: white; }
230
231 dl {
232 margin-top: 0.8em;
233 margin-bottom: 0.8em;
234 }
235 dt {
236 margin-top: 0.5em;
237 margin-bottom: 0;
238 font-style: normal;
239 color: navy;
240 }
241 dd > *:first-child {
242 margin-top: 0.1em;
243 }
244
245 ul, ol {
246 list-style-position: outside;
247 }
248 ol.arabic {
249 list-style-type: decimal;
250 }
251 ol.loweralpha {
252 list-style-type: lower-alpha;
253 }
254 ol.upperalpha {
255 list-style-type: upper-alpha;
256 }
257 ol.lowerroman {
258 list-style-type: lower-roman;
259 }
260 ol.upperroman {
261 list-style-type: upper-roman;
262 }
263
264 div.compact ul, div.compact ol,
265 div.compact p, div.compact p,
266 div.compact div, div.compact div {
267 margin-top: 0.1em;
268 margin-bottom: 0.1em;
269 }
270
271 tfoot {
272 font-weight: bold;
273 }
274 td > div.verse {
275 white-space: pre;
276 }
277
278 div.hdlist {
279 margin-top: 0.8em;
280 margin-bottom: 0.8em;
281 }
282 div.hdlist tr {
283 padding-bottom: 15px;
284 }
285 dt.hdlist1.strong, td.hdlist1.strong {
286 font-weight: bold;
287 }
288 td.hdlist1 {
289 vertical-align: top;
290 font-style: normal;
291 padding-right: 0.8em;
292 color: navy;
293 }
294 td.hdlist2 {
295 vertical-align: top;
296 }
297 div.hdlist.compact tr {
298 margin: 0;
299 padding-bottom: 0;
300 }
301
302 .comment {
303 background: yellow;
304 }
305
306 .footnote, .footnoteref {
307 font-size: 0.8em;
308 }
309
310 span.footnote, span.footnoteref {
311 vertical-align: super;
312 }
313
314 #footnotes {
315 margin: 20px 0 20px 0;
316 padding: 7px 0 0 0;
317 }
318
319 #footnotes div.footnote {
320 margin: 0 0 5px 0;
321 }
322
323 #footnotes hr {
324 border: none;
325 border-top: 1px solid silver;
326 height: 1px;
327 text-align: left;
328 margin-left: 0;
329 width: 20%;
330 min-width: 100px;
331 }
332
333 div.colist td {
334 padding-right: 0.5em;
335 padding-bottom: 0.3em;
336 vertical-align: top;
337 }
338 div.colist td img {
339 margin-top: 0.3em;
340 }
341
342 @media print {
343 #footer-badges { display: none; }
344 }
345
346 #toc {
347 margin-bottom: 2.5em;
348 }
349
350 #toctitle {
351 color: #527bbd;
352 font-size: 1.1em;
353 font-weight: bold;
354 margin-top: 1.0em;
355 margin-bottom: 0.1em;
356 }
357
358 div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
359 margin-top: 0;
360 margin-bottom: 0;
361 }
362 div.toclevel2 {
363 margin-left: 2em;
364 font-size: 0.9em;
365 }
366 div.toclevel3 {
367 margin-left: 4em;
368 font-size: 0.9em;
369 }
370 div.toclevel4 {
371 margin-left: 6em;
372 font-size: 0.9em;
373 }
374
375 span.aqua { color: aqua; }
376 span.black { color: black; }
377 span.blue { color: blue; }
378 span.fuchsia { color: fuchsia; }
379 span.gray { color: gray; }
380 span.green { color: green; }
381 span.lime { color: lime; }
382 span.maroon { color: maroon; }
383 span.navy { color: navy; }
384 span.olive { color: olive; }
385 span.purple { color: purple; }
386 span.red { color: red; }
387 span.silver { color: silver; }
388 span.teal { color: teal; }
389 span.white { color: white; }
390 span.yellow { color: yellow; }
391
392 span.aqua-background { background: aqua; }
393 span.black-background { background: black; }
394 span.blue-background { background: blue; }
395 span.fuchsia-background { background: fuchsia; }
396 span.gray-background { background: gray; }
397 span.green-background { background: green; }
398 span.lime-background { background: lime; }
399 span.maroon-background { background: maroon; }
400 span.navy-background { background: navy; }
401 span.olive-background { background: olive; }
402 span.purple-background { background: purple; }
403 span.red-background { background: red; }
404 span.silver-background { background: silver; }
405 span.teal-background { background: teal; }
406 span.white-background { background: white; }
407 span.yellow-background { background: yellow; }
408
409 span.big { font-size: 2em; }
410 span.small { font-size: 0.6em; }
411
412 span.underline { text-decoration: underline; }
413 span.overline { text-decoration: overline; }
414 span.line-through { text-decoration: line-through; }
415
416 div.unbreakable { page-break-inside: avoid; }
417
418
419 /*
420 * xhtml11 specific
421 *
422 * */
423
424 div.tableblock {
425 margin-top: 1.0em;
426 margin-bottom: 1.5em;
427 }
428 div.tableblock > table {
429 border: 3px solid #527bbd;
430 }
431 thead, p.table.header {
432 font-weight: bold;
433 color: #527bbd;
434 }
435 p.table {
436 margin-top: 0;
437 }
438 /* Because the table frame attribute is overriden by CSS in most browsers. */
439 div.tableblock > table[frame="void"] {
440 border-style: none;
441 }
442 div.tableblock > table[frame="hsides"] {
443 border-left-style: none;
444 border-right-style: none;
445 }
446 div.tableblock > table[frame="vsides"] {
447 border-top-style: none;
448 border-bottom-style: none;
449 }
450
451
452 /*
453 * html5 specific
454 *
455 * */
456
457 table.tableblock {
458 margin-top: 1.0em;
459 margin-bottom: 1.5em;
460 }
461 thead, p.tableblock.header {
462 font-weight: bold;
463 color: #527bbd;
464 }
465 p.tableblock {
466 margin-top: 0;
467 }
468 table.tableblock {
469 border-width: 3px;
470 border-spacing: 0px;
471 border-style: solid;
472 border-color: #527bbd;
473 border-collapse: collapse;
474 }
475 th.tableblock, td.tableblock {
476 border-width: 1px;
477 padding: 4px;
478 border-style: solid;
479 border-color: #527bbd;
480 }
481
482 table.tableblock.frame-topbot {
483 border-left-style: hidden;
484 border-right-style: hidden;
485 }
486 table.tableblock.frame-sides {
487 border-top-style: hidden;
488 border-bottom-style: hidden;
489 }
490 table.tableblock.frame-none {
491 border-style: hidden;
492 }
493
494 th.tableblock.halign-left, td.tableblock.halign-left {
495 text-align: left;
496 }
497 th.tableblock.halign-center, td.tableblock.halign-center {
498 text-align: center;
499 }
500 th.tableblock.halign-right, td.tableblock.halign-right {
501 text-align: right;
502 }
503
504 th.tableblock.valign-top, td.tableblock.valign-top {
505 vertical-align: top;
506 }
507 th.tableblock.valign-middle, td.tableblock.valign-middle {
508 vertical-align: middle;
509 }
510 th.tableblock.valign-bottom, td.tableblock.valign-bottom {
511 vertical-align: bottom;
512 }
513
514
515 /*
516 * manpage specific
517 *
518 * */
519
520 body.manpage h1 {
521 padding-top: 0.5em;
522 padding-bottom: 0.5em;
523 border-top: 2px solid silver;
524 border-bottom: 2px solid silver;
525 }
526 body.manpage h2 {
527 border-style: none;
528 }
529 body.manpage div.sectionbody {
530 margin-left: 3em;
531 }
532
533 @media print {
534 body.manpage div#toc { display: none; }
535 }
536
537
538 </style>
539 <script type="text/javascript">
540 /*<![CDATA[*/
541 var asciidoc = { // Namespace.
542
543 /////////////////////////////////////////////////////////////////////
544 // Table Of Contents generator
545 /////////////////////////////////////////////////////////////////////
546
547 /* Author: Mihai Bazon, September 2002
548 * http://students.infoiasi.ro/~mishoo
549 *
550 * Table Of Content generator
551 * Version: 0.4
552 *
553 * Feel free to use this script under the terms of the GNU General Public
554 * License, as long as you do not remove or alter this notice.
555 */
556
557 /* modified by Troy D. Hanson, September 2006. License: GPL */
558 /* modified by Stuart Rackham, 2006, 2009. License: GPL */
559
560 // toclevels = 1..4.
561 toc: function (toclevels) {
562
563 function getText(el) {
564 var text = "";
565 for (var i = el.firstChild; i != null; i = i.nextSibling) {
566 if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
567 text += i.data;
568 else if (i.firstChild != null)
569 text += getText(i);
570 }
571 return text;
572 }
573
574 function TocEntry(el, text, toclevel) {
575 this.element = el;
576 this.text = text;
577 this.toclevel = toclevel;
578 }
579
580 function tocEntries(el, toclevels) {
581 var result = new Array;
582 var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
583 // Function that scans the DOM tree for header elements (the DOM2
584 // nodeIterator API would be a better technique but not supported by all
585 // browsers).
586 var iterate = function (el) {
587 for (var i = el.firstChild; i != null; i = i.nextSibling) {
588 if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
589 var mo = re.exec(i.tagName);
590 if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
591 result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
592 }
593 iterate(i);
594 }
595 }
596 }
597 iterate(el);
598 return result;
599 }
600
601 var toc = document.getElementById("toc");
602 if (!toc) {
603 return;
604 }
605
606 // Delete existing TOC entries in case we're reloading the TOC.
607 var tocEntriesToRemove = [];
608 var i;
609 for (i = 0; i < toc.childNodes.length; i++) {
610 var entry = toc.childNodes[i];
611 if (entry.nodeName.toLowerCase() == 'div'
612 && entry.getAttribute("class")
613 && entry.getAttribute("class").match(/^toclevel/))
614 tocEntriesToRemove.push(entry);
615 }
616 for (i = 0; i < tocEntriesToRemove.length; i++) {
617 toc.removeChild(tocEntriesToRemove[i]);
618 }
619
620 // Rebuild TOC entries.
621 var entries = tocEntries(document.getElementById("content"), toclevels);
622 for (var i = 0; i < entries.length; ++i) {
623 var entry = entries[i];
624 if (entry.element.id == "")
625 entry.element.id = "_toc_" + i;
626 var a = document.createElement("a");
627 a.href = "#" + entry.element.id;
628 a.appendChild(document.createTextNode(entry.text));
629 var div = document.createElement("div");
630 div.appendChild(a);
631 div.className = "toclevel" + entry.toclevel;
632 toc.appendChild(div);
633 }
634 if (entries.length == 0)
635 toc.parentNode.removeChild(toc);
636 },
637
638
639 /////////////////////////////////////////////////////////////////////
640 // Footnotes generator
641 /////////////////////////////////////////////////////////////////////
642
643 /* Based on footnote generation code from:
644 * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
645 */
646
647 footnotes: function () {
648 // Delete existing footnote entries in case we're reloading the footnodes.
649 var i;
650 var noteholder = document.getElementById("footnotes");
651 if (!noteholder) {
652 return;
653 }
654 var entriesToRemove = [];
655 for (i = 0; i < noteholder.childNodes.length; i++) {
656 var entry = noteholder.childNodes[i];
657 if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
658 entriesToRemove.push(entry);
659 }
660 for (i = 0; i < entriesToRemove.length; i++) {
661 noteholder.removeChild(entriesToRemove[i]);
662 }
663
664 // Rebuild footnote entries.
665 var cont = document.getElementById("content");
666 var spans = cont.getElementsByTagName("span");
667 var refs = {};
668 var n = 0;
669 for (i=0; i<spans.length; i++) {
670 if (spans[i].className == "footnote") {
671 n++;
672 var note = spans[i].getAttribute("data-note");
673 if (!note) {
674 // Use [\s\S] in place of . so multi-line matches work.
675 // Because JavaScript has no s (dotall) regex flag.
676 note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
677 spans[i].innerHTML =
678 "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
679 "' title='View footnote' class='footnote'>" + n + "</a>]";
680 spans[i].setAttribute("data-note", note);
681 }
682 noteholder.innerHTML +=
683 "<div class='footnote' id='_footnote_" + n + "'>" +
684 "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
685 n + "</a>. " + note + "</div>";
686 var id =spans[i].getAttribute("id");
687 if (id != null) refs["#"+id] = n;
688 }
689 }
690 if (n == 0)
691 noteholder.parentNode.removeChild(noteholder);
692 else {
693 // Process footnoterefs.
694 for (i=0; i<spans.length; i++) {
695 if (spans[i].className == "footnoteref") {
696 var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
697 href = href.match(/#.*/)[0]; // Because IE return full URL.
698 n = refs[href];
699 spans[i].innerHTML =
700 "[<a href='#_footnote_" + n +
701 "' title='View footnote' class='footnote'>" + n + "</a>]";
702 }
703 }
704 }
705 },
706
707 install: function(toclevels) {
708 var timerId;
709
710 function reinstall() {
711 asciidoc.footnotes();
712 if (toclevels) {
713 asciidoc.toc(toclevels);
714 }
715 }
716
717 function reinstallAndRemoveTimer() {
718 clearInterval(timerId);
719 reinstall();
720 }
721
722 timerId = setInterval(reinstall, 500);
723 if (document.addEventListener)
724 document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
725 else
726 window.onload = reinstallAndRemoveTimer;
727 }
728
729 }
730 asciidoc.install(2);
731 /*]]>*/
732 </script>
733 </head>
734 <body class="article">
735 <div id="header">
736 <h1>Hacking i3: How To</h1>
737 <span id="author">Michael Stapelberg</span><br />
738 <span id="email"><code>&lt;<a href="mailto:[email protected]">[email protected]</a>&gt;</code></span><br />
739 <span id="revdate">February 2013</span>
740 <div id="toc">
741 <div id="toctitle">Table of Contents</div>
742 <noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
743 </div>
744 </div>
745 <div id="content">
746 <div id="preamble">
747 <div class="sectionbody">
748 <div class="paragraph"><p>This document is intended to be the first thing you read before looking and/or
749 touching i3’s source code. It should contain all important information to help
750 you understand why things are like they are. If it does not mention something
751 you find necessary, please do not hesitate to contact me.</p></div>
752 </div>
753 </div>
754 <div class="sect1">
755 <h2 id="_building_i3">1. Building i3</h2>
756 <div class="sectionbody">
757 <div class="paragraph"><p>You can build i3 like you build any other software package which uses autotools.
758 Here’s a memory refresher:</p></div>
759 <div class="literalblock">
760 <div class="content">
761 <pre><code>$ autoreconf -fi
762 $ mkdir -p build &amp;&amp; cd build
763 $ ../configure
764 $ make -j8</code></pre>
765 </div></div>
766 <div class="paragraph"><p>(The autoreconf -fi step is unnecessary if you are building from a release tarball,
767 but shouldn’t hurt either.)</p></div>
768 <div class="sect2">
769 <h3 id="_build_system_features">1.1. Build system features</h3>
770 <div class="ulist"><ul>
771 <li>
772 <p>
773 We use the AX_ENABLE_BUILDDIR macro to enforce builds happening in a separate
774 directory. This is a prerequisite for the AX_EXTEND_SRCDIR macro and building
775 in a separate directory is common practice anyway. In case this causes any
776 trouble when packaging i3 for your distribution, please open an issue.
777 </p>
778 </li>
779 <li>
780 <p>
781 “make check” runs the i3 testsuite. See docs/testsuite for details.
782 </p>
783 </li>
784 <li>
785 <p>
786 “make distcheck” (runs testsuite on “make dist” result, tiny bit quicker
787 feedback cycle than waiting for the travis build to catch the issue).
788 </p>
789 </li>
790 <li>
791 <p>
792 “make uninstall” (occasionally requested by users who compile from source)
793 </p>
794 </li>
795 <li>
796 <p>
797 “make” will build manpages/docs by default if the tools are installed.
798 Conversely, manpages/docs are not tried to be built for users who don’t want
799 to install all these dependencies to get started hacking on i3.
800 </p>
801 </li>
802 <li>
803 <p>
804 non-release builds will enable address sanitizer by default. Use the
805 --disable-sanitizers configure option to turn off all sanitizers, and see
806 --help for available sanitizers.
807 </p>
808 </li>
809 <li>
810 <p>
811 Support for pre-compiled headers (PCH) has been dropped for now in the
812 interest of simplicity. If you need support for PCH, please open an issue.
813 </p>
814 </li>
815 <li>
816 <p>
817 Coverage reports are now generated using “make check-code-coverage”, which
818 requires specifying --enable-code-coverage when calling configure.
819 </p>
820 </li>
821 </ul></div>
822 </div>
823 </div>
824 </div>
825 <div class="sect1">
826 <h2 id="_using_git_sending_patches">2. Using git / sending patches</h2>
827 <div class="sectionbody">
828 <div class="paragraph"><p>For a short introduction into using git, see
829 <a href="https://web.archive.org/web/20121024222556/http://www.spheredev.org/wiki/Git_for_the_lazy">https://web.archive.org/web/20121024222556/http://www.spheredev.org/wiki/Git_for_the_lazy</a>
830 or, for more documentation, see <a href="https://git-scm.com/documentation">https://git-scm.com/documentation</a></p></div>
831 <div class="paragraph"><p>Please talk to us before working on new features to see whether they will be
832 accepted. A good way for this is to open an issue and asking for opinions on it.
833 Even for accepted features, this can be a good way to refine an idea upfront. However,
834 we don&#8217;t want to see certain features in i3, e.g., switching window focus in an
835 Alt+Tab like way.</p></div>
836 <div class="paragraph"><p>When working on bugfixes, please make sure you mention that you are working on
837 it in the corresponding bug report at <a href="https://github.com/i3/i3/issues">https://github.com/i3/i3/issues</a>. In case
838 there is no bug report yet, please create one.</p></div>
839 <div class="paragraph"><p>After you are done, please submit your work for review as a pull request at
840 <a href="https://github.com/i3/i3">https://github.com/i3/i3</a>.</p></div>
841 <div class="paragraph"><p>Do not send emails to the mailing list or any author directly, and don’t submit
842 them in the bugtracker, since all reviews should be done in public at
843 <a href="https://github.com/i3/i3">https://github.com/i3/i3</a>. In order to make your review go as fast as possible, you
844 could have a look at previous reviews and see what the common mistakes are.</p></div>
845 <div class="sect2">
846 <h3 id="_which_branch_to_use">2.1. Which branch to use?</h3>
847 <div class="paragraph"><p>Work on i3 generally happens in two branches: “master” and “next” (the latter
848 being the default branch, the one that people get when they check out the git
849 repository).</p></div>
850 <div class="paragraph"><p>The contents of “master” are always stable. That is, it contains the source code
851 of the latest release, plus any bugfixes that were applied since that release.</p></div>
852 <div class="paragraph"><p>New features are only found in the “next” branch. Therefore, if you are working
853 on a new feature, use the “next” branch. If you are working on a bugfix, use the
854 “next” branch, too, but make sure your code also works on “master”.</p></div>
855 </div>
856 </div>
857 </div>
858 <div class="sect1">
859 <h2 id="_window_managers">3. Window Managers</h2>
860 <div class="sectionbody">
861 <div class="paragraph"><p>A window manager is not necessarily needed to run X, but it is usually used in
862 combination with X to facilitate some things. The window manager&#8217;s job is to
863 take care of the placement of windows, to provide the user with some mechanisms
864 to change the position/size of windows and to communicate with clients to a
865 certain extent (for example handle fullscreen requests of clients such as
866 MPlayer).</p></div>
867 <div class="paragraph"><p>There are no different contexts in which X11 clients run, so a window manager
868 is just another client, like all other X11 applications. However, it handles
869 some events which normal clients usually don’t handle.</p></div>
870 <div class="paragraph"><p>In the case of i3, the tasks (and order of them) are the following:</p></div>
871 <div class="olist arabic"><ol class="arabic">
872 <li>
873 <p>
874 Grab the key bindings (events will be sent upon keypress/keyrelease)
875 </p>
876 </li>
877 <li>
878 <p>
879 Iterate through all existing windows (if the window manager is not started as
880 the first client of X) and manage them (reparent them, create window
881 decorations, etc.)
882 </p>
883 </li>
884 <li>
885 <p>
886 When new windows are created, manage them
887 </p>
888 </li>
889 <li>
890 <p>
891 Handle the client’s <code>_WM_STATE</code> property, but only <code>_WM_STATE_FULLSCREEN</code> and
892 <code>_NET_WM_STATE_DEMANDS_ATTENTION</code>
893 </p>
894 </li>
895 <li>
896 <p>
897 Handle the client’s <code>WM_NAME</code> property
898 </p>
899 </li>
900 <li>
901 <p>
902 Handle the client’s size hints to display them proportionally
903 </p>
904 </li>
905 <li>
906 <p>
907 Handle the client’s urgency hint
908 </p>
909 </li>
910 <li>
911 <p>
912 Handle enter notifications (focus follows mouse)
913 </p>
914 </li>
915 <li>
916 <p>
917 Handle button (as in mouse buttons) presses for focus/raise on click
918 </p>
919 </li>
920 <li>
921 <p>
922 Handle expose events to re-draw own windows such as decorations
923 </p>
924 </li>
925 <li>
926 <p>
927 React to the user’s commands: Change focus, Move windows, Switch workspaces,
928 Change the layout mode of a container (default/stacking/tabbed), start a new
929 application, restart the window manager
930 </p>
931 </li>
932 </ol></div>
933 <div class="paragraph"><p>In the following chapters, each of these tasks and their implementation details
934 will be discussed.</p></div>
935 <div class="sect2">
936 <h3 id="_tiling_window_managers">3.1. Tiling window managers</h3>
937 <div class="paragraph"><p>Traditionally, there are two approaches to managing windows: The most common
938 one nowadays is floating, which means the user can freely move/resize the
939 windows. The other approach is called tiling, which means that your window
940 manager distributes windows to use as much space as possible while not
941 overlapping each other.</p></div>
942 <div class="paragraph"><p>The idea behind tiling is that you should not need to waste your time
943 moving/resizing windows while you usually want to get some work done. After
944 all, most users sooner or later tend to lay out their windows in a way which
945 corresponds to tiling or stacking mode in i3. Therefore, why not let i3 do this
946 for you? Certainly, it’s faster than you could ever do it.</p></div>
947 <div class="paragraph"><p>The problem with most tiling window managers is that they are too inflexible.
948 In my opinion, a window manager is just another tool, and similar to vim which
949 can edit all kinds of text files (like source code, HTML, …) and is not limited
950 to a specific file type, a window manager should not limit itself to a certain
951 layout (like dwm, awesome, …) but provide mechanisms for you to easily create
952 the layout you need at the moment.</p></div>
953 </div>
954 <div class="sect2">
955 <h3 id="_the_layout_tree">3.2. The layout tree</h3>
956 <div class="paragraph"><p>The data structure which i3 uses to keep track of your windows is a tree. Every
957 node in the tree is a container (type <code>Con</code>). Some containers represent actual
958 windows (every container with a <code>window != NULL</code>), some represent split
959 containers and a few have special purposes: they represent workspaces, outputs
960 (like VGA1, LVDS1, …) or the X11 root window.</p></div>
961 <div class="paragraph"><p>So, when you open a terminal and immediately open another one, they reside in
962 the same split container, which uses the default layout. In case of an empty
963 workspace, the split container we are talking about is the workspace.</p></div>
964 <div class="paragraph"><p>To get an impression of how different layouts are represented, just play around
965 and look at the data structures&#8201;&#8212;&#8201;they are exposed as a JSON hash. See
966 <a href="https://i3wm.org/docs/ipc.html#_tree_reply">https://i3wm.org/docs/ipc.html#_tree_reply</a> for documentation on that and an
967 example.</p></div>
968 </div>
969 </div>
970 </div>
971 <div class="sect1">
972 <h2 id="_files">4. Files</h2>
973 <div class="sectionbody">
974 <div class="dlist"><dl>
975 <dt class="hdlist1">
976 include/atoms.xmacro
977 </dt>
978 <dd>
979 <p>
980 A file containing all X11 atoms which i3 uses. This file will be included
981 various times (for defining, requesting and receiving the atoms), each time
982 with a different definition of xmacro().
983 </p>
984 </dd>
985 <dt class="hdlist1">
986 include/data.h
987 </dt>
988 <dd>
989 <p>
990 Contains data definitions used by nearly all files. You really need to read
991 this first.
992 </p>
993 </dd>
994 <dt class="hdlist1">
995 include/*.h
996 </dt>
997 <dd>
998 <p>
999 Contains forward definitions for all public functions, as well as
1000 doxygen-compatible comments (so if you want to get a bit more of the big
1001 picture, either browse all header files or use doxygen if you prefer that).
1002 </p>
1003 </dd>
1004 <dt class="hdlist1">
1005 src/config_parser.c
1006 </dt>
1007 <dd>
1008 <p>
1009 Contains a custom configuration parser. See src/command_parser.c for rationale
1010 on why we use a custom parser.
1011 </p>
1012 </dd>
1013 <dt class="hdlist1">
1014 src/click.c
1015 </dt>
1016 <dd>
1017 <p>
1018 Contains all functions which handle mouse button clicks (right mouse button
1019 clicks initiate resizing and thus are relatively complex).
1020 </p>
1021 </dd>
1022 <dt class="hdlist1">
1023 src/command_parser.c
1024 </dt>
1025 <dd>
1026 <p>
1027 Contains a hand-written parser to parse commands (commands are what
1028 you bind on keys and what you can send to i3 using the IPC interface, like
1029 <em>move left</em> or <em>workspace 4</em>).
1030 </p>
1031 </dd>
1032 <dt class="hdlist1">
1033 src/con.c
1034 </dt>
1035 <dd>
1036 <p>
1037 Contains all functions which deal with containers directly (creating
1038 containers, searching containers, getting specific properties from containers,
1039 …).
1040 </p>
1041 </dd>
1042 <dt class="hdlist1">
1043 src/config.c
1044 </dt>
1045 <dd>
1046 <p>
1047 Contains all functions handling the configuration file (calling the parser
1048 src/config_parser.c) with the correct path, switching key bindings mode).
1049 </p>
1050 </dd>
1051 <dt class="hdlist1">
1052 src/ewmh.c
1053 </dt>
1054 <dd>
1055 <p>
1056 Functions to get/set certain EWMH properties easily.
1057 </p>
1058 </dd>
1059 <dt class="hdlist1">
1060 src/floating.c
1061 </dt>
1062 <dd>
1063 <p>
1064 Contains functions for floating mode (mostly resizing/dragging).
1065 </p>
1066 </dd>
1067 <dt class="hdlist1">
1068 src/handlers.c
1069 </dt>
1070 <dd>
1071 <p>
1072 Contains all handlers for all kinds of X events (new window title, new hints,
1073 unmapping, key presses, button presses, …).
1074 </p>
1075 </dd>
1076 <dt class="hdlist1">
1077 src/ipc.c
1078 </dt>
1079 <dd>
1080 <p>
1081 Contains code for the IPC interface.
1082 </p>
1083 </dd>
1084 <dt class="hdlist1">
1085 src/load_layout.c
1086 </dt>
1087 <dd>
1088 <p>
1089 Contains code for loading layouts from JSON files.
1090 </p>
1091 </dd>
1092 <dt class="hdlist1">
1093 src/log.c
1094 </dt>
1095 <dd>
1096 <p>
1097 Contains the logging functions.
1098 </p>
1099 </dd>
1100 <dt class="hdlist1">
1101 src/main.c
1102 </dt>
1103 <dd>
1104 <p>
1105 Initializes the window manager.
1106 </p>
1107 </dd>
1108 <dt class="hdlist1">
1109 src/manage.c
1110 </dt>
1111 <dd>
1112 <p>
1113 Looks at existing or new windows and decides whether to manage them. If so, it
1114 reparents the window and inserts it into our data structures.
1115 </p>
1116 </dd>
1117 <dt class="hdlist1">
1118 src/match.c
1119 </dt>
1120 <dd>
1121 <p>
1122 A "match" is a data structure which acts like a mask or expression to match
1123 certain windows or not. For example, when using commands, you can specify a
1124 command like this: [title="<strong>Firefox</strong>"] kill. The title member of the match
1125 data structure will then be filled and i3 will check each window using
1126 match_matches_window() to find the windows affected by this command.
1127 </p>
1128 </dd>
1129 <dt class="hdlist1">
1130 src/move.c
1131 </dt>
1132 <dd>
1133 <p>
1134 Contains code to move a container in a specific direction.
1135 </p>
1136 </dd>
1137 <dt class="hdlist1">
1138 src/output.c
1139 </dt>
1140 <dd>
1141 <p>
1142 Functions to handle CT_OUTPUT cons.
1143 </p>
1144 </dd>
1145 <dt class="hdlist1">
1146 src/randr.c
1147 </dt>
1148 <dd>
1149 <p>
1150 The RandR API is used to get (and re-query) the configured outputs (monitors,
1151 …).
1152 </p>
1153 </dd>
1154 <dt class="hdlist1">
1155 src/render.c
1156 </dt>
1157 <dd>
1158 <p>
1159 Renders the tree data structure by assigning coordinates to every node. These
1160 values will later be pushed to X11 in <code>src/x.c</code>.
1161 </p>
1162 </dd>
1163 <dt class="hdlist1">
1164 src/resize.c
1165 </dt>
1166 <dd>
1167 <p>
1168 Contains the functions to resize containers.
1169 </p>
1170 </dd>
1171 <dt class="hdlist1">
1172 src/restore_layout.c
1173 </dt>
1174 <dd>
1175 <p>
1176 Everything for restored containers that is not pure state parsing (which can be
1177 found in load_layout.c).
1178 </p>
1179 </dd>
1180 <dt class="hdlist1">
1181 src/sighandler.c
1182 </dt>
1183 <dd>
1184 <p>
1185 Handles <code>SIGSEGV</code>, <code>SIGABRT</code> and <code>SIGFPE</code> by showing a dialog that i3 crashed.
1186 You can chose to let it dump core, to restart it in-place or to restart it
1187 in-place but forget about the layout.
1188 </p>
1189 </dd>
1190 <dt class="hdlist1">
1191 src/tree.c
1192 </dt>
1193 <dd>
1194 <p>
1195 Contains functions which open or close containers in the tree, change focus or
1196 cleanup ("flatten") the tree. See also <code>src/move.c</code> for another similar
1197 function, which was moved into its own file because it is so long.
1198 </p>
1199 </dd>
1200 <dt class="hdlist1">
1201 src/util.c
1202 </dt>
1203 <dd>
1204 <p>
1205 Contains useful functions which are not really dependent on anything.
1206 </p>
1207 </dd>
1208 <dt class="hdlist1">
1209 src/window.c
1210 </dt>
1211 <dd>
1212 <p>
1213 Handlers to update X11 window properties like <code>WM_CLASS</code>, <code>_NET_WM_NAME</code>,
1214 <code>CLIENT_LEADER</code>, etc.
1215 </p>
1216 </dd>
1217 <dt class="hdlist1">
1218 src/workspace.c
1219 </dt>
1220 <dd>
1221 <p>
1222 Contains all functions related to workspaces (displaying, hiding, renaming…)
1223 </p>
1224 </dd>
1225 <dt class="hdlist1">
1226 src/x.c
1227 </dt>
1228 <dd>
1229 <p>
1230 Transfers our in-memory tree (see <code>src/render.c</code>) to X11.
1231 </p>
1232 </dd>
1233 <dt class="hdlist1">
1234 src/xcb.c
1235 </dt>
1236 <dd>
1237 <p>
1238 Contains wrappers to use xcb more easily.
1239 </p>
1240 </dd>
1241 <dt class="hdlist1">
1242 src/xcursor.c
1243 </dt>
1244 <dd>
1245 <p>
1246 XCursor functions (for cursor themes).
1247 </p>
1248 </dd>
1249 <dt class="hdlist1">
1250 src/xinerama.c
1251 </dt>
1252 <dd>
1253 <p>
1254 Legacy support for Xinerama. See <code>src/randr.c</code> for the preferred API.
1255 </p>
1256 </dd>
1257 </dl></div>
1258 </div>
1259 </div>
1260 <div class="sect1">
1261 <h2 id="_data_structures">5. Data structures</h2>
1262 <div class="sectionbody">
1263 <div class="paragraph"><p>See include/data.h for documented data structures. The most important ones are
1264 explained right here.</p></div>
1265 <div class="paragraph"><p>So, the hierarchy is:</p></div>
1266 <div class="olist arabic"><ol class="arabic">
1267 <li>
1268 <p>
1269 <strong>X11 root window</strong>, the root container
1270 </p>
1271 </li>
1272 <li>
1273 <p>
1274 <strong>Output container</strong> (LVDS1 in this example)
1275 </p>
1276 </li>
1277 <li>
1278 <p>
1279 <strong>Content container</strong> (there are also containers for dock windows)
1280 </p>
1281 </li>
1282 <li>
1283 <p>
1284 <strong>Workspaces</strong> (Workspace 1 in this example, with horizontal orientation)
1285 </p>
1286 </li>
1287 <li>
1288 <p>
1289 <strong>Split container</strong> (vertically split)
1290 </p>
1291 </li>
1292 <li>
1293 <p>
1294 <strong>X11 window containers</strong>
1295 </p>
1296 </li>
1297 </ol></div>
1298 <div class="paragraph"><p>The data type is <code>Con</code>, in all cases.</p></div>
1299 <div class="sect2">
1300 <h3 id="_x11_root_window">5.1. X11 root window</h3>
1301 <div class="paragraph"><p>The X11 root window is a single window per X11 display (a display is identified
1302 by <code>:0</code> or <code>:1</code> etc.). The root window is what you draw your background image
1303 on. It spans all the available outputs, e.g. <code>VGA1</code> is a specific part of the
1304 root window and <code>LVDS1</code> is a specific part of the root window.</p></div>
1305 </div>
1306 <div class="sect2">
1307 <h3 id="_output_container">5.2. Output container</h3>
1308 <div class="paragraph"><p>Every active output obtained through RandR is represented by one output
1309 container. Outputs are considered active when a mode is configured (meaning
1310 something is actually displayed on the output) and the output is not a clone.</p></div>
1311 <div class="paragraph"><p>For example, if your notebook has a screen resolution of 1280x800 px and you
1312 connect a video projector with a resolution of 1024x768 px, set it up in clone
1313 mode (<code>xrandr --output VGA1 --mode 1024x768 --same-as LVDS1</code>), i3 will
1314 reduce the resolution to the lowest common resolution and disable one of the
1315 cloned outputs afterwards.</p></div>
1316 <div class="paragraph"><p>However, if you configure it using <code>xrandr --output VGA1 --mode 1024x768
1317 --right-of LVDS1</code>, i3 will set both outputs active. For each output, a new
1318 workspace will be assigned. New workspaces are created on the output you are
1319 currently on.</p></div>
1320 </div>
1321 <div class="sect2">
1322 <h3 id="_content_container">5.3. Content container</h3>
1323 <div class="paragraph"><p>Each output has multiple children. Two of them are dock containers which hold
1324 dock clients. The other one is the content container, which holds the actual
1325 content (workspaces) of this output.</p></div>
1326 </div>
1327 <div class="sect2">
1328 <h3 id="_workspace">5.4. Workspace</h3>
1329 <div class="paragraph"><p>A workspace is identified by its name. Basically, you could think of
1330 workspaces as different desks in your office, if you like the desktop
1331 metaphor. They just contain different sets of windows and are completely
1332 separate of each other. Other window managers also call this &#8220;Virtual
1333 desktops&#8221;.</p></div>
1334 </div>
1335 <div class="sect2">
1336 <h3 id="_split_container">5.5. Split container</h3>
1337 <div class="paragraph"><p>A split container is a container which holds an arbitrary amount of split
1338 containers or X11 window containers. It has an orientation (horizontal or
1339 vertical) and a layout.</p></div>
1340 <div class="paragraph"><p>Split containers (and X11 window containers, which are a subtype of split
1341 containers) can have different border styles.</p></div>
1342 </div>
1343 <div class="sect2">
1344 <h3 id="_x11_window_container">5.6. X11 window container</h3>
1345 <div class="paragraph"><p>An X11 window container holds exactly one X11 window. These are the leaf nodes
1346 of the layout tree, they cannot have any children.</p></div>
1347 </div>
1348 </div>
1349 </div>
1350 <div class="sect1">
1351 <h2 id="_list_queue_macros">6. List/queue macros</h2>
1352 <div class="sectionbody">
1353 <div class="paragraph"><p>i3 makes heavy use of the list macros defined in BSD operating systems. To
1354 ensure that the operating system on which i3 is compiled has all the expected
1355 features, i3 comes with <code>include/queue.h</code>. On BSD systems, you can use man
1356 <code>queue(3)</code>. On Linux, you have to use google (or read the source).</p></div>
1357 <div class="paragraph"><p>The lists used are <code>SLIST</code> (single linked lists), <code>CIRCLEQ</code> (circular
1358 queues) and <code>TAILQ</code> (tail queues). Usually, only forward traversal is necessary,
1359 so an <code>SLIST</code> works fine. If inserting elements at arbitrary positions or at
1360 the end of a list is necessary, a <code>TAILQ</code> is used instead. However, for the
1361 windows inside a container, a <code>CIRCLEQ</code> is necessary to go from the currently
1362 selected window to the window above/below.</p></div>
1363 </div>
1364 </div>
1365 <div class="sect1">
1366 <h2 id="_naming_conventions">7. Naming conventions</h2>
1367 <div class="sectionbody">
1368 <div class="paragraph"><p>There is a row of standard variables used in many events. The following names
1369 should be chosen for those:</p></div>
1370 <div class="ulist"><ul>
1371 <li>
1372 <p>
1373 &#8220;conn&#8221; is the xcb_connection_t
1374 </p>
1375 </li>
1376 <li>
1377 <p>
1378 &#8220;event&#8221; is the event of the particular type
1379 </p>
1380 </li>
1381 <li>
1382 <p>
1383 &#8220;con&#8221; names a container
1384 </p>
1385 </li>
1386 <li>
1387 <p>
1388 &#8220;current&#8221; is a loop variable when using <code>TAILQ_FOREACH</code> etc.
1389 </p>
1390 </li>
1391 </ul></div>
1392 </div>
1393 </div>
1394 <div class="sect1">
1395 <h2 id="_startup_src_mainx_c_main">8. Startup (src/mainx.c, main())</h2>
1396 <div class="sectionbody">
1397 <div class="ulist"><ul>
1398 <li>
1399 <p>
1400 Establish the xcb connection
1401 </p>
1402 </li>
1403 <li>
1404 <p>
1405 Check for XKB extension on the separate X connection, load Xcursor
1406 </p>
1407 </li>
1408 <li>
1409 <p>
1410 Check for RandR screens (with a fall-back to Xinerama)
1411 </p>
1412 </li>
1413 <li>
1414 <p>
1415 Grab the keycodes for which bindings exist
1416 </p>
1417 </li>
1418 <li>
1419 <p>
1420 Manage all existing windows
1421 </p>
1422 </li>
1423 <li>
1424 <p>
1425 Enter the event loop
1426 </p>
1427 </li>
1428 </ul></div>
1429 </div>
1430 </div>
1431 <div class="sect1">
1432 <h2 id="_keybindings">9. Keybindings</h2>
1433 <div class="sectionbody">
1434 <div class="sect2">
1435 <h3 id="_grabbing_the_bindings">9.1. Grabbing the bindings</h3>
1436 <div class="paragraph"><p>Grabbing the bindings is quite straight-forward. You pass X your combination of
1437 modifiers and the keycode you want to grab and whether you want to grab them
1438 actively or passively. Most bindings (everything except for bindings using
1439 Mode_switch) are grabbed passively, that is, just the window manager gets the
1440 event and cannot replay it.</p></div>
1441 <div class="paragraph"><p>We need to grab bindings that use Mode_switch actively because of a bug in X.
1442 When the window manager receives the keypress/keyrelease event for an actively
1443 grabbed keycode, it has to decide what to do with this event: It can either
1444 replay it so that other applications get it or it can prevent other
1445 applications from receiving it.</p></div>
1446 <div class="paragraph"><p>So, why do we need to grab keycodes actively? Because X does not set the
1447 state-property of keypress/keyrelease events properly. The Mode_switch bit is
1448 not set and we need to get it using XkbGetState. This means we cannot pass X
1449 our combination of modifiers containing Mode_switch when grabbing the key and
1450 therefore need to grab the keycode itself without any modifiers. This means,
1451 if you bind Mode_switch + keycode 38 ("a"), i3 will grab keycode 38 ("a") and
1452 check on each press of "a" if the Mode_switch bit is set using XKB. If yes, it
1453 will handle the event, if not, it will replay the event.</p></div>
1454 </div>
1455 <div class="sect2">
1456 <h3 id="_handling_a_keypress">9.2. Handling a keypress</h3>
1457 <div class="paragraph"><p>As mentioned in "Grabbing the bindings", upon a keypress event, i3 first gets
1458 the correct state.</p></div>
1459 <div class="paragraph"><p>Then, it looks through all bindings and gets the one which matches the received
1460 event.</p></div>
1461 <div class="paragraph"><p>The bound command is parsed by the cmdparse lexer/parser, see <code>parse_cmd</code> in
1462 <code>src/cmdparse.y</code>.</p></div>
1463 </div>
1464 </div>
1465 </div>
1466 <div class="sect1">
1467 <h2 id="_manage_windows_src_main_c_manage_window_and_reparent_window">10. Manage windows (src/main.c, manage_window() and reparent_window())</h2>
1468 <div class="sectionbody">
1469 <div class="paragraph"><p><code>manage_window()</code> does some checks to decide whether the window should be
1470 managed at all:</p></div>
1471 <div class="ulist"><ul>
1472 <li>
1473 <p>
1474 Windows have to be mapped, that is, visible on screen
1475 </p>
1476 </li>
1477 <li>
1478 <p>
1479 The override_redirect must not be set. Windows with override_redirect shall
1480 not be managed by a window manager
1481 </p>
1482 </li>
1483 </ul></div>
1484 <div class="paragraph"><p>Afterwards, i3 gets the initial geometry and reparents the window (see
1485 <code>reparent_window()</code>) if it wasn’t already managed.</p></div>
1486 <div class="paragraph"><p>Reparenting means that for each window which is reparented, a new window,
1487 slightly larger than the original one, is created. The original window is then
1488 reparented to the bigger one (called "frame").</p></div>
1489 <div class="paragraph"><p>After reparenting, the window type (<code>_NET_WM_WINDOW_TYPE</code>) is checked to see
1490 whether this window is a dock (<code>_NET_WM_WINDOW_TYPE_DOCK</code>), like dzen2 for
1491 example. Docks are handled differently, they don’t have decorations and are not
1492 assigned to a specific container. Instead, they are positioned at the bottom
1493 or top of the screen (in the appropriate dock area containers). To get the
1494 height which needs to be reserved for the window, the <code>_NET_WM_STRUT_PARTIAL</code>
1495 property is used.</p></div>
1496 <div class="paragraph"><p>Furthermore, the list of assignments (to other workspaces, which may be on
1497 other screens) is checked. If the window matches one of the user’s criteria,
1498 it may either be put in floating mode or moved to a different workspace. If the
1499 target workspace is not visible, the window will not be mapped.</p></div>
1500 </div>
1501 </div>
1502 <div class="sect1">
1503 <h2 id="_what_happens_when_an_application_is_started">11. What happens when an application is started?</h2>
1504 <div class="sectionbody">
1505 <div class="paragraph"><p>i3 does not care about applications. All it notices is when new windows are
1506 mapped (see <code>src/handlers.c</code>, <code>handle_map_request()</code>). The window is then
1507 reparented (see section "Manage windows").</p></div>
1508 <div class="paragraph"><p>After reparenting the window, <code>render_tree()</code> is called which renders the
1509 internal layout table. The new window has been placed in the currently focused
1510 container and therefore the new window and the old windows (if any) need to be
1511 moved/resized so that the currently active layout (default/stacking/tabbed mode)
1512 is rendered correctly. To move/resize windows, a window is &#8220;configured&#8221; in
1513 X11-speak.</p></div>
1514 <div class="paragraph"><p>Some applications, such as MPlayer obviously assume the window manager is
1515 stupid and try to configure their windows by themselves. This generates an
1516 event called configurerequest. i3 handles these events and tells the window the
1517 size it had before the configurerequest (with the exception of not yet mapped
1518 windows, which get configured like they want to, and floating windows, which
1519 can reconfigure themselves).</p></div>
1520 </div>
1521 </div>
1522 <div class="sect1">
1523 <h2 id="_net_wm_state">12. _NET_WM_STATE</h2>
1524 <div class="sectionbody">
1525 <div class="paragraph"><p>Only the _NET_WM_STATE_FULLSCREEN and _NET_WM_STATE_DEMANDS_ATTENTION atoms
1526 are handled.</p></div>
1527 <div class="paragraph"><p>The former calls &#8220;toggle_fullscreen()&#8221; for the specific client which just
1528 configures the client to use the whole screen on which it currently is.
1529 Also, it is set as fullscreen_client for the i3Screen.</p></div>
1530 <div class="paragraph"><p>The latter is used to set, read and display urgency hints.</p></div>
1531 </div>
1532 </div>
1533 <div class="sect1">
1534 <h2 id="_wm_name">13. WM_NAME</h2>
1535 <div class="sectionbody">
1536 <div class="paragraph"><p>When the WM_NAME property of a window changes, its decoration (containing the
1537 title) is re-rendered. Note that WM_NAME is in COMPOUND_TEXT encoding which is
1538 totally uncommon and cumbersome. Therefore, the _NET_WM_NAME atom will be used
1539 if present.</p></div>
1540 </div>
1541 </div>
1542 <div class="sect1">
1543 <h2 id="_net_wm_name">14. _NET_WM_NAME</h2>
1544 <div class="sectionbody">
1545 <div class="paragraph"><p>Like WM_NAME, this atom contains the title of a window. However, _NET_WM_NAME
1546 is encoded in UTF-8. i3 will recode it to UCS-2 in order to be able to pass it
1547 to X. Using an appropriate font (ISO-10646), you can see most special
1548 characters (every special character contained in your font).</p></div>
1549 </div>
1550 </div>
1551 <div class="sect1">
1552 <h2 id="_size_hints">15. Size hints</h2>
1553 <div class="sectionbody">
1554 <div class="paragraph"><p>Size hints specify the minimum/maximum size for a given window as well as its
1555 aspect ratio. This is important for clients like mplayer, who only set the
1556 aspect ratio and resize their window to be as small as possible (but only with
1557 some video outputs, for example in Xv, while when using x11, mplayer does the
1558 necessary centering for itself).</p></div>
1559 <div class="paragraph"><p>So, when an aspect ratio was specified, i3 adjusts the height of the window
1560 until the size maintains the correct aspect ratio. For the code to do this, see
1561 src/layout.c, function resize_client().</p></div>
1562 </div>
1563 </div>
1564 <div class="sect1">
1565 <h2 id="_rendering_src_layout_c_render_layout_and_render_container">16. Rendering (src/layout.c, render_layout() and render_container())</h2>
1566 <div class="sectionbody">
1567 <div class="paragraph"><p>Rendering in i3 version 4 is the step which assigns the correct sizes for
1568 borders, decoration windows, child windows and the stacking order of all
1569 windows. In a separate step (<code>x_push_changes()</code>), these changes are pushed to
1570 X11.</p></div>
1571 <div class="paragraph"><p>Keep in mind that all these properties (<code>rect</code>, <code>window_rect</code> and <code>deco_rect</code>)
1572 are temporary, meaning they will be overwritten by calling <code>render_con</code>.
1573 Persistent position/size information is kept in <code>geometry</code>.</p></div>
1574 <div class="paragraph"><p>The entry point for every rendering operation (except for the case of moving
1575 floating windows around) currently is <code>tree_render()</code> which will re-render
1576 everything that’s necessary (for every output, only the currently displayed
1577 workspace is rendered). This behavior is expected to change in the future,
1578 since for a lot of updates, re-rendering everything is not actually necessary.
1579 Focus was on getting it working correct, not getting it work very fast.</p></div>
1580 <div class="paragraph"><p>What <code>tree_render()</code> actually does is calling <code>render_con()</code> on the root
1581 container and then pushing the changes to X11. The following sections talk
1582 about the different rendering steps, in the order of "top of the tree" (root
1583 container) to the bottom.</p></div>
1584 <div class="sect2">
1585 <h3 id="_rendering_the_root_container">16.1. Rendering the root container</h3>
1586 <div class="paragraph"><p>The i3 root container (<code>con-&gt;type == CT_ROOT</code>) represents the X11 root window.
1587 It contains one child container for every output (like LVDS1, VGA1, …), which
1588 is available on your computer.</p></div>
1589 <div class="paragraph"><p>Rendering the root will first render all tiling windows and then all floating
1590 windows. This is necessary because a floating window can be positioned in such
1591 a way that it is visible on two different outputs. Therefore, by first
1592 rendering all the tiling windows (of all outputs), we make sure that floating
1593 windows can never be obscured by tiling windows.</p></div>
1594 <div class="paragraph"><p>Essentially, though, this code path will just call <code>render_con()</code> for every
1595 output and <code>x_raise_con(); render_con()</code> for every floating window.</p></div>
1596 <div class="paragraph"><p>In the special case of having a "global fullscreen" window (fullscreen mode
1597 spanning all outputs), a shortcut is taken and <code>x_raise_con(); render_con()</code> is
1598 only called for the global fullscreen window.</p></div>
1599 </div>
1600 <div class="sect2">
1601 <h3 id="_rendering_an_output">16.2. Rendering an output</h3>
1602 <div class="paragraph"><p>Output containers (<code>con-&gt;layout == L_OUTPUT</code>) represent a hardware output like
1603 LVDS1, VGA1, etc. An output container has three children (at the moment): One
1604 content container (having workspaces as children) and the top/bottom dock area
1605 containers.</p></div>
1606 <div class="paragraph"><p>The rendering happens in the function <code>render_l_output()</code> in the following
1607 steps:</p></div>
1608 <div class="olist arabic"><ol class="arabic">
1609 <li>
1610 <p>
1611 Find the content container (<code>con-&gt;type == CT_CON</code>)
1612 </p>
1613 </li>
1614 <li>
1615 <p>
1616 Get the currently visible workspace (<code>con_get_fullscreen_con(content,
1617 CF_OUTPUT)</code>).
1618 </p>
1619 </li>
1620 <li>
1621 <p>
1622 If there is a fullscreened window on that workspace, directly render it and
1623 return, thus ignoring the dock areas.
1624 </p>
1625 </li>
1626 <li>
1627 <p>
1628 Sum up the space used by all the dock windows (they have a variable height
1629 only).
1630 </p>
1631 </li>
1632 <li>
1633 <p>
1634 Set the workspace rects (x/y/width/height) based on the position of the
1635 output (stored in <code>con-&gt;rect</code>) and the usable space
1636 (<code>con-&gt;rect.{width,height}</code> without the space used for dock windows).
1637 </p>
1638 </li>
1639 <li>
1640 <p>
1641 Recursively raise and render the output’s child containers (meaning dock
1642 area containers and the content container).
1643 </p>
1644 </li>
1645 </ol></div>
1646 </div>
1647 <div class="sect2">
1648 <h3 id="_rendering_a_workspace_or_split_container">16.3. Rendering a workspace or split container</h3>
1649 <div class="paragraph"><p>From here on, there really is no difference anymore. All containers are of
1650 <code>con-&gt;type == CT_CON</code> (whether workspace or split container) and some of them
1651 have a <code>con-&gt;window</code>, meaning they represent an actual window instead of a
1652 split container.</p></div>
1653 <div class="sect3">
1654 <h4 id="_default_layout">16.3.1. Default layout</h4>
1655 <div class="paragraph"><p>In default layout, containers are placed horizontally or vertically next to
1656 each other (depending on the <code>con-&gt;orientation</code>). If a child is a leaf node (as
1657 opposed to a split container) and has border style "normal", appropriate space
1658 will be reserved for its window decoration.</p></div>
1659 </div>
1660 <div class="sect3">
1661 <h4 id="_stacked_layout">16.3.2. Stacked layout</h4>
1662 <div class="paragraph"><p>In stacked layout, only the focused window is actually shown (this is achieved
1663 by calling <code>x_raise_con()</code> in reverse focus order at the end of <code>render_con()</code>).</p></div>
1664 <div class="paragraph"><p>The available space for the focused window is the size of the container minus
1665 the height of the window decoration for all windows inside this stacked
1666 container.</p></div>
1667 <div class="paragraph"><p>If border style is "1pixel" or "none", no window decoration height will be
1668 reserved (or displayed later on), unless there is more than one window inside
1669 the stacked container.</p></div>
1670 </div>
1671 <div class="sect3">
1672 <h4 id="_tabbed_layout">16.3.3. Tabbed layout</h4>
1673 <div class="paragraph"><p>Tabbed layout works precisely like stacked layout, but the window decoration
1674 position/size is different: They are placed next to each other on a single line
1675 (fixed height).</p></div>
1676 </div>
1677 <div class="sect3">
1678 <h4 id="_dock_area_layout">16.3.4. Dock area layout</h4>
1679 <div class="paragraph"><p>This is a special case. Users cannot choose the dock area layout, but it will be
1680 set for the dock area containers. In the dockarea layout (at the moment!),
1681 windows will be placed above each other.</p></div>
1682 </div>
1683 </div>
1684 <div class="sect2">
1685 <h3 id="_rendering_a_window">16.4. Rendering a window</h3>
1686 <div class="paragraph"><p>A window’s size and position will be determined in the following way:</p></div>
1687 <div class="olist arabic"><ol class="arabic">
1688 <li>
1689 <p>
1690 Subtract the border if border style is not "none" (but "normal" or "1pixel").
1691 </p>
1692 </li>
1693 <li>
1694 <p>
1695 Subtract the X11 border, if the window has an X11 border &gt; 0.
1696 </p>
1697 </li>
1698 <li>
1699 <p>
1700 Obey the aspect ratio of the window (think MPlayer).
1701 </p>
1702 </li>
1703 <li>
1704 <p>
1705 Obey the height- and width-increments of the window (think terminal emulator
1706 which can only be resized in one-line or one-character steps).
1707 </p>
1708 </li>
1709 </ol></div>
1710 </div>
1711 </div>
1712 </div>
1713 <div class="sect1">
1714 <h2 id="_pushing_updates_to_x11_drawing">17. Pushing updates to X11 / Drawing</h2>
1715 <div class="sectionbody">
1716 <div class="paragraph"><p>A big problem with i3 before version 4 was that we just sent requests to X11
1717 anywhere in the source code. This was bad because nobody could understand the
1718 entirety of our interaction with X11, it lead to subtle bugs and a lot of edge
1719 cases which we had to consider all over again.</p></div>
1720 <div class="paragraph"><p>Therefore, since version 4, we have a single file, <code>src/x.c</code>, which is
1721 responsible for repeatedly transferring parts of our tree datastructure to X11.</p></div>
1722 <div class="paragraph"><p><code>src/x.c</code> consists of multiple parts:</p></div>
1723 <div class="olist arabic"><ol class="arabic">
1724 <li>
1725 <p>
1726 The state pushing: <code>x_push_changes()</code>, which calls <code>x_push_node()</code>.
1727 </p>
1728 </li>
1729 <li>
1730 <p>
1731 State modification functions: <code>x_con_init</code>, <code>x_reinit</code>,
1732 <code>x_reparent_child</code>, <code>x_move_win</code>, <code>x_con_kill</code>, <code>x_raise_con</code>, <code>x_set_name</code>
1733 and <code>x_set_warp_to</code>.
1734 </p>
1735 </li>
1736 <li>
1737 <p>
1738 Expose event handling (drawing decorations): <code>x_deco_recurse()</code> and
1739 <code>x_draw_decoration()</code>.
1740 </p>
1741 </li>
1742 </ol></div>
1743 <div class="sect2">
1744 <h3 id="_pushing_state_to_x11">17.1. Pushing state to X11</h3>
1745 <div class="paragraph"><p>In general, the function <code>x_push_changes</code> should be called to push state
1746 changes. Only when the scope of the state change is clearly defined (for
1747 example only the title of a window) and its impact is known beforehand, one can
1748 optimize this and call <code>x_push_node</code> on the appropriate con directly.</p></div>
1749 <div class="paragraph"><p><code>x_push_changes</code> works in the following steps:</p></div>
1750 <div class="olist arabic"><ol class="arabic">
1751 <li>
1752 <p>
1753 Clear the eventmask for all mapped windows. This leads to not getting
1754 useless ConfigureNotify or EnterNotify events which are caused by our
1755 requests. In general, we only want to handle user input.
1756 </p>
1757 </li>
1758 <li>
1759 <p>
1760 Stack windows above each other, in reverse stack order (starting with the
1761 most obscured/bottom window). This is relevant for floating windows which
1762 can overlap each other, but also for tiling windows in stacked or tabbed
1763 containers. We also update the <code>_NET_CLIENT_LIST_STACKING</code> hint which is
1764 necessary for tab drag and drop in Chromium.
1765 </p>
1766 </li>
1767 <li>
1768 <p>
1769 <code>x_push_node</code> will be called for the root container, recursively calling
1770 itself for the container’s children. This function actually pushes the
1771 state, see the next paragraph.
1772 </p>
1773 </li>
1774 <li>
1775 <p>
1776 If the pointer needs to be warped to a different position (for example when
1777 changing focus to a different output), it will be warped now.
1778 </p>
1779 </li>
1780 <li>
1781 <p>
1782 The eventmask is restored for all mapped windows.
1783 </p>
1784 </li>
1785 <li>
1786 <p>
1787 Window decorations will be rendered by calling <code>x_deco_recurse</code> on the root
1788 container, which then recursively calls itself for the children.
1789 </p>
1790 </li>
1791 <li>
1792 <p>
1793 If the input focus needs to be changed (because the user focused a different
1794 window), it will be updated now.
1795 </p>
1796 </li>
1797 <li>
1798 <p>
1799 <code>x_push_node_unmaps</code> will be called for the root container. This function
1800 only pushes UnmapWindow requests. Separating the state pushing is necessary
1801 to handle fullscreen windows (and workspace switches) in a smooth fashion:
1802 The newly visible windows should be visible before the old windows are
1803 unmapped.
1804 </p>
1805 </li>
1806 </ol></div>
1807 <div class="paragraph"><p><code>x_push_node</code> works in the following steps:</p></div>
1808 <div class="olist arabic"><ol class="arabic">
1809 <li>
1810 <p>
1811 Update the window’s <code>WM_NAME</code>, if changed (the <code>WM_NAME</code> is set on i3
1812 containers mainly for debugging purposes).
1813 </p>
1814 </li>
1815 <li>
1816 <p>
1817 Reparents a child window into the i3 container if the container was created
1818 for a specific managed window.
1819 </p>
1820 </li>
1821 <li>
1822 <p>
1823 If the size/position of the i3 container changed (due to opening a new
1824 window or switching layouts for example), the window will be reconfigured.
1825 Also, the pixmap which is used to draw the window decoration/border on is
1826 reconfigured (pixmaps are size-dependent).
1827 </p>
1828 </li>
1829 <li>
1830 <p>
1831 Size/position for the child window is adjusted.
1832 </p>
1833 </li>
1834 <li>
1835 <p>
1836 The i3 container is mapped if it should be visible and was not yet mapped.
1837 When mapping, <code>WM_STATE</code> is set to <code>WM_STATE_NORMAL</code>. Also, the eventmask of
1838 the child window is updated and the i3 container’s contents are copied from
1839 the pixmap.
1840 </p>
1841 </li>
1842 <li>
1843 <p>
1844 <code>x_push_node</code> is called recursively for all children of the current
1845 container.
1846 </p>
1847 </li>
1848 </ol></div>
1849 <div class="paragraph"><p><code>x_push_node_unmaps</code> handles the remaining case of an i3 container being
1850 unmapped if it should not be visible anymore. <code>WM_STATE</code> will be set to
1851 <code>WM_STATE_WITHDRAWN</code>.</p></div>
1852 </div>
1853 <div class="sect2">
1854 <h3 id="_drawing_window_decorations_borders_backgrounds">17.2. Drawing window decorations/borders/backgrounds</h3>
1855 <div class="paragraph"><p><code>x_draw_decoration</code> draws window decorations. It is run for every leaf
1856 container (representing an actual X11 window) and for every non-leaf container
1857 which is in a stacked/tabbed container (because stacked/tabbed containers
1858 display a window decoration for split containers, which consists of a representation
1859 of the child container&#8217;s names.</p></div>
1860 <div class="paragraph"><p>Then, parameters are collected to be able to determine whether this decoration
1861 drawing is actually necessary or was already done. This saves a substantial
1862 number of redraws (depending on your workload, but far over 50%).</p></div>
1863 <div class="paragraph"><p>Assuming that we need to draw this decoration, we start by filling the empty
1864 space around the child window (think of MPlayer with a specific aspect ratio)
1865 in the user-configured client background color.</p></div>
1866 <div class="paragraph"><p>Afterwards, we draw the appropriate border (in case of border styles "normal"
1867 and "1pixel") and the top bar (in case of border style "normal").</p></div>
1868 <div class="paragraph"><p>The last step is drawing the window title on the top bar.</p></div>
1869 </div>
1870 </div>
1871 </div>
1872 <div class="sect1">
1873 <h2 id="_user_commands_parser_specs_commands_spec">18. User commands (parser-specs/commands.spec)</h2>
1874 <div class="sectionbody">
1875 <div class="paragraph"><p>In the configuration file and when using i3 interactively (with <code>i3-msg</code>, for
1876 example), you use commands to make i3 do things, like focus a different window,
1877 set a window to fullscreen, and so on. An example command is <code>floating enable</code>,
1878 which enables floating mode for the currently focused window. See the
1879 appropriate section in the <a href="userguide.html">User’s Guide</a> for a reference of
1880 all commands.</p></div>
1881 <div class="paragraph"><p>In earlier versions of i3, interpreting these commands was done using lex and
1882 yacc, but experience has shown that lex and yacc are not well suited for our
1883 command language. Therefore, starting from version 4.2, we use a custom parser
1884 for user commands and the configuration file.
1885 The input specification for this parser can be found in the file
1886 <code>parser-specs/*.spec</code>. Should you happen to use Vim as an editor, use
1887 :source parser-specs/highlighting.vim to get syntax highlighting for this file
1888 (highlighting files for other editors are welcome).</p></div>
1889 <div class="listingblock">
1890 <div class="title">Excerpt from commands.spec</div>
1891 <div class="content">
1892 <pre><code>state INITIAL:
1893 '[' -&gt; call cmd_criteria_init(); CRITERIA
1894 'move' -&gt; MOVE
1895 'exec' -&gt; EXEC
1896 'workspace' -&gt; WORKSPACE
1897 'exit' -&gt; call cmd_exit()
1898 'restart' -&gt; call cmd_restart()
1899 'reload' -&gt; call cmd_reload()</code></pre>
1900 </div></div>
1901 <div class="paragraph"><p>The input specification is written in an extremely simple format. The
1902 specification is then converted into C code by the Perl script
1903 generate-commands-parser.pl (the output file names begin with GENERATED and the
1904 files are stored in the <code>include</code> directory). The parser implementation
1905 <code>src/commands_parser.c</code> includes the generated C code at compile-time.</p></div>
1906 <div class="paragraph"><p>The above excerpt from commands.spec illustrates nearly all features of our
1907 specification format: You describe different states and what can happen within
1908 each state. State names are all-caps; the state in the above excerpt is called
1909 INITIAL. A list of tokens and their actions (separated by an ASCII arrow)
1910 follows. In the excerpt, all tokens are literals, that is, simple text strings
1911 which will be compared with the input. An action is either the name of a state
1912 in which the parser will transition into, or the keyword <em>call</em>, followed by
1913 the name of a function (and optionally a state).</p></div>
1914 <div class="sect2">
1915 <h3 id="_example_the_workspace_state">18.1. Example: The WORKSPACE state</h3>
1916 <div class="paragraph"><p>Let’s have a look at the WORKSPACE state, which is a good example of all
1917 features. This is its definition:</p></div>
1918 <div class="listingblock">
1919 <div class="title">WORKSPACE state (commands.spec)</div>
1920 <div class="content">
1921 <pre><code># workspace next|prev|next_on_output|prev_on_output
1922 # workspace back_and_forth
1923 # workspace &lt;name&gt;
1924 # workspace number &lt;number&gt;
1925 state WORKSPACE:
1926 direction = 'next_on_output', 'prev_on_output', 'next', 'prev'
1927 -&gt; call cmd_workspace($direction)
1928 'back_and_forth'
1929 -&gt; call cmd_workspace_back_and_forth()
1930 'number'
1931 -&gt; WORKSPACE_NUMBER
1932 workspace = string
1933 -&gt; call cmd_workspace_name($workspace)</code></pre>
1934 </div></div>
1935 <div class="paragraph"><p>As you can see from the commands, there are multiple different valid variants
1936 of the workspace command:</p></div>
1937 <div class="dlist"><dl>
1938 <dt class="hdlist1">
1939 workspace &lt;direction&gt;
1940 </dt>
1941 <dd>
1942 <p>
1943 The word <em>workspace</em> can be followed by any of the tokens <em>next</em>,
1944 <em>prev</em>, <em>next_on_output</em> or <em>prev_on_output</em>. This command will
1945 switch to the next or previous workspace (optionally on the same
1946 output).<br />
1947 There is one function called <code>cmd_workspace</code>, which is defined
1948 in <code>src/commands.c</code>. It will handle this kind of command. To know which
1949 direction was specified, the direction token is stored on the stack
1950 with the name "direction", which is what the "direction = " means in
1951 the beginning.<br />
1952 </p>
1953 </dd>
1954 </dl></div>
1955 <div class="admonitionblock">
1956 <table><tr>
1957 <td class="icon">
1958 <div class="title">Note</div>
1959 </td>
1960 <td class="content">Note that you can specify multiple literals in the same line. This has
1961 exactly the same effect as if you specified <code>direction =
1962 'next_on_output' -&gt; call cmd_workspace($direction)</code> and so forth.<br /></td>
1963 </tr></table>
1964 </div>
1965 <div class="admonitionblock">
1966 <table><tr>
1967 <td class="icon">
1968 <div class="title">Note</div>
1969 </td>
1970 <td class="content">Also note that the order of literals is important here: If <em>next</em> were
1971 ordered before <em>next_on_output</em>, then <em>next_on_output</em> would never
1972 match.</td>
1973 </tr></table>
1974 </div>
1975 <div class="dlist"><dl>
1976 <dt class="hdlist1">
1977 workspace back_and_forth
1978 </dt>
1979 <dd>
1980 <p>
1981 This is a very simple case: When the literal <em>back_and_forth</em> is found
1982 in the input, the function <code>cmd_workspace_back_and_forth</code> will be
1983 called without parameters and the parser will return to the INITIAL
1984 state (since no other state was specified).
1985 </p>
1986 </dd>
1987 <dt class="hdlist1">
1988 workspace &lt;name&gt;
1989 </dt>
1990 <dd>
1991 <p>
1992 In this case, the workspace command is followed by an arbitrary string,
1993 possibly in quotes, for example "workspace 3" or "workspace bleh".<br />
1994 This is the first time that the token is actually not a literal (not in
1995 single quotes), but just called string. Other possible tokens are word
1996 (the same as string, but stops matching at a whitespace) and end
1997 (matches the end of the input).
1998 </p>
1999 </dd>
2000 <dt class="hdlist1">
2001 workspace number &lt;number&gt;
2002 </dt>
2003 <dd>
2004 <p>
2005 The workspace command has to be followed by the keyword <code>number</code>. It
2006 then transitions into the state <code>WORKSPACE_NUMBER</code>, where the actual
2007 parameter will be read.
2008 </p>
2009 </dd>
2010 </dl></div>
2011 </div>
2012 <div class="sect2">
2013 <h3 id="_introducing_a_new_command">18.2. Introducing a new command</h3>
2014 <div class="paragraph"><p>The following steps have to be taken in order to properly introduce a new
2015 command (or possibly extend an existing command):</p></div>
2016 <div class="olist arabic"><ol class="arabic">
2017 <li>
2018 <p>
2019 Define a function beginning with <code>cmd_</code> in the file <code>src/commands.c</code>. Copy
2020 the prototype of an existing function.
2021 </p>
2022 </li>
2023 <li>
2024 <p>
2025 After adding a comment on what the function does, copy the comment and
2026 function definition to <code>include/commands.h</code>. Make the comment in the header
2027 file use double asterisks to make doxygen pick it up.
2028 </p>
2029 </li>
2030 <li>
2031 <p>
2032 Write a test case (or extend an existing test case) for your feature, see
2033 <a href="testsuite.html">i3 testsuite</a>. For now, it is sufficient to simply call
2034 your command in all the various possible ways.
2035 </p>
2036 </li>
2037 <li>
2038 <p>
2039 Extend the parser specification in <code>parser-specs/commands.spec</code>. Run the
2040 testsuite and see if your new function gets called with the appropriate
2041 arguments for the appropriate input.
2042 </p>
2043 </li>
2044 <li>
2045 <p>
2046 Actually implement the feature.
2047 </p>
2048 </li>
2049 <li>
2050 <p>
2051 Document the feature in the <a href="userguide.html">User’s Guide</a>.
2052 </p>
2053 </li>
2054 </ol></div>
2055 </div>
2056 </div>
2057 </div>
2058 <div class="sect1">
2059 <h2 id="_moving_containers">19. Moving containers</h2>
2060 <div class="sectionbody">
2061 <div class="paragraph"><p>The movement code is pretty delicate. You need to consider all cases before
2062 making any changes or before being able to fully understand how it works.</p></div>
2063 <div class="sect2">
2064 <h3 id="_case_1_moving_inside_the_same_container">19.1. Case 1: Moving inside the same container</h3>
2065 <div class="paragraph"><p>The reference layout for this case is a single workspace in horizontal
2066 orientation with two containers on it. Focus is on the left container (1).</p></div>
2067 <div class="tableblock">
2068 <table rules="all"
2069 width="15%"
2070 frame="border"
2071 cellspacing="0" cellpadding="4">
2072 <col width="50%" />
2073 <col width="50%" />
2074 <tbody>
2075 <tr>
2076 <td align="center" valign="top"><p class="table">1</p></td>
2077 <td align="center" valign="top"><p class="table">2</p></td>
2078 </tr>
2079 </tbody>
2080 </table>
2081 </div>
2082 <div class="paragraph"><p>When moving the left window to the right (command <code>move right</code>), tree_move will
2083 look for a container with horizontal orientation and finds the parent of the
2084 left container, that is, the workspace. Afterwards, it runs the code branch
2085 commented with "the easy case": it calls TAILQ_NEXT to get the container right
2086 of the current one and swaps both containers.</p></div>
2087 </div>
2088 <div class="sect2">
2089 <h3 id="_case_2_move_a_container_into_a_split_container">19.2. Case 2: Move a container into a split container</h3>
2090 <div class="paragraph"><p>The reference layout for this case is a horizontal workspace with two
2091 containers. The right container is a v-split with two containers. Focus is on
2092 the left container (1).</p></div>
2093 <div class="tableblock">
2094 <table rules="all"
2095 width="15%"
2096 frame="border"
2097 cellspacing="0" cellpadding="4">
2098 <col width="50%" />
2099 <col width="50%" />
2100 <tbody>
2101 <tr>
2102 <td rowspan="2" align="center" valign="middle"><p class="table">1</p></td>
2103 <td align="center" valign="top"><p class="table">2</p></td>
2104 </tr>
2105 <tr>
2106 <td align="center" valign="top"><p class="table">3</p></td>
2107 </tr>
2108 </tbody>
2109 </table>
2110 </div>
2111 <div class="paragraph"><p>When moving to the right (command <code>move right</code>), i3 will work like in case 1
2112 ("the easy case"). However, as the right container is not a leaf container, but
2113 a v-split, the left container (1) will be inserted at the right position (below
2114 2, assuming that 2 is focused inside the v-split) by calling <code>insert_con_into</code>.</p></div>
2115 <div class="paragraph"><p><code>insert_con_into</code> detaches the container from its parent and inserts it
2116 before/after the given target container. Afterwards, the on_remove_child
2117 callback is called on the old parent container which will then be closed, if
2118 empty.</p></div>
2119 <div class="paragraph"><p>Afterwards, <code>con_focus</code> will be called to fix the focus stack and the tree will
2120 be flattened.</p></div>
2121 </div>
2122 <div class="sect2">
2123 <h3 id="_case_3_moving_to_non_existent_top_bottom">19.3. Case 3: Moving to non-existent top/bottom</h3>
2124 <div class="paragraph"><p>Like in case 1, the reference layout for this case is a single workspace in
2125 horizontal orientation with two containers on it. Focus is on the left
2126 container:</p></div>
2127 <div class="tableblock">
2128 <table rules="all"
2129 width="15%"
2130 frame="border"
2131 cellspacing="0" cellpadding="4">
2132 <col width="50%" />
2133 <col width="50%" />
2134 <tbody>
2135 <tr>
2136 <td align="center" valign="top"><p class="table">1</p></td>
2137 <td align="center" valign="top"><p class="table">2</p></td>
2138 </tr>
2139 </tbody>
2140 </table>
2141 </div>
2142 <div class="paragraph"><p>This time however, the command is <code>move up</code> or <code>move down</code>. tree_move will look
2143 for a container with vertical orientation. As it will not find any,
2144 <code>same_orientation</code> is NULL and therefore i3 will perform a forced orientation
2145 change on the workspace by creating a new h-split container, moving the
2146 workspace contents into it and then changing the workspace orientation to
2147 vertical. Now it will again search for parent containers with vertical
2148 orientation and it will find the workspace.</p></div>
2149 <div class="paragraph"><p>This time, the easy case code path will not be run as we are not moving inside
2150 the same container. Instead, <code>insert_con_into</code> will be called with the focused
2151 container and the container above/below the current one (on the level of
2152 <code>same_orientation</code>).</p></div>
2153 <div class="paragraph"><p>Now, <code>con_focus</code> will be called to fix the focus stack and the tree will be
2154 flattened.</p></div>
2155 </div>
2156 <div class="sect2">
2157 <h3 id="_case_4_moving_to_existent_top_bottom">19.4. Case 4: Moving to existent top/bottom</h3>
2158 <div class="paragraph"><p>The reference layout for this case is a vertical workspace with two containers.
2159 The bottom one is a h-split containing two containers (1 and 2). Focus is on
2160 the bottom left container (1).</p></div>
2161 <div class="tableblock">
2162 <table rules="all"
2163 width="15%"
2164 frame="border"
2165 cellspacing="0" cellpadding="4">
2166 <col width="50%" />
2167 <col width="50%" />
2168 <tbody>
2169 <tr>
2170 <td colspan="2" align="center" valign="top"><p class="table">3</p></td>
2171 </tr>
2172 <tr>
2173 <td align="center" valign="top"><p class="table">1</p></td>
2174 <td align="center" valign="top"><p class="table">2</p></td>
2175 </tr>
2176 </tbody>
2177 </table>
2178 </div>
2179 <div class="paragraph"><p>This case is very much like case 3, only this time the forced workspace
2180 orientation change does not need to be performed because the workspace already
2181 is in vertical orientation.</p></div>
2182 </div>
2183 <div class="sect2">
2184 <h3 id="_case_5_moving_in_one_child_h_split">19.5. Case 5: Moving in one-child h-split</h3>
2185 <div class="paragraph"><p>The reference layout for this case is a horizontal workspace with two
2186 containers having a v-split on the left side with a one-child h-split on the
2187 bottom. Focus is on the bottom left container (2(h)):</p></div>
2188 <div class="tableblock">
2189 <table rules="all"
2190 width="15%"
2191 frame="border"
2192 cellspacing="0" cellpadding="4">
2193 <col width="50%" />
2194 <col width="50%" />
2195 <tbody>
2196 <tr>
2197 <td align="center" valign="top"><p class="table">1</p></td>
2198 <td rowspan="2" align="center" valign="middle"><p class="table">3</p></td>
2199 </tr>
2200 <tr>
2201 <td align="center" valign="top"><p class="table">2(h)</p></td>
2202 </tr>
2203 </tbody>
2204 </table>
2205 </div>
2206 <div class="paragraph"><p>In this case, <code>same_orientation</code> will be set to the h-split container around
2207 the focused container. However, when trying the easy case, the next/previous
2208 container <code>swap</code> will be NULL. Therefore, i3 will search again for a
2209 <code>same_orientation</code> container, this time starting from the parent of the h-split
2210 container.</p></div>
2211 <div class="paragraph"><p>After determining a new <code>same_orientation</code> container (if it is NULL, the
2212 orientation will be force-changed), this case is equivalent to case 2 or case
2213 4.</p></div>
2214 </div>
2215 <div class="sect2">
2216 <h3 id="_case_6_floating_containers">19.6. Case 6: Floating containers</h3>
2217 <div class="paragraph"><p>The reference layout for this case is a horizontal workspace with two
2218 containers plus one floating h-split container. Focus is on the floating
2219 container.</p></div>
2220 <div class="paragraph"><p>TODO: nice illustration. table not possible?</p></div>
2221 <div class="paragraph"><p>When moving up/down, the container needs to leave the floating container and it
2222 needs to be placed on the workspace (at workspace level). This is accomplished
2223 by calling the function <code>attach_to_workspace</code>.</p></div>
2224 </div>
2225 </div>
2226 </div>
2227 <div class="sect1">
2228 <h2 id="_click_handling">20. Click handling</h2>
2229 <div class="sectionbody">
2230 <div class="paragraph"><p>Without much ado, here is the list of cases which need to be considered:</p></div>
2231 <div class="ulist"><ul>
2232 <li>
2233 <p>
2234 click to focus (tiling + floating) and raise (floating)
2235 </p>
2236 </li>
2237 <li>
2238 <p>
2239 click to focus/raise when in stacked/tabbed mode
2240 </p>
2241 </li>
2242 <li>
2243 <p>
2244 floating_modifier + left mouse button to drag a floating con
2245 </p>
2246 </li>
2247 <li>
2248 <p>
2249 floating_modifier + right mouse button to resize a floating con
2250 </p>
2251 </li>
2252 <li>
2253 <p>
2254 click on decoration in a floating con to either initiate a resize (if there
2255 is more than one child in the floating con) or to drag the
2256 floating con (if it’s the one at the top).
2257 </p>
2258 </li>
2259 <li>
2260 <p>
2261 click on border in a floating con to resize the floating con
2262 </p>
2263 </li>
2264 <li>
2265 <p>
2266 floating_modifier + right mouse button to resize a tiling con
2267 </p>
2268 </li>
2269 <li>
2270 <p>
2271 click on border/decoration to resize a tiling con
2272 </p>
2273 </li>
2274 </ul></div>
2275 </div>
2276 </div>
2277 <div class="sect1">
2278 <h2 id="_gotchas">21. Gotchas</h2>
2279 <div class="sectionbody">
2280 <div class="ulist"><ul>
2281 <li>
2282 <p>
2283 Forgetting to call <code>xcb_flush(conn);</code> after sending a request. This usually
2284 leads to code which looks like it works fine but which does not work under
2285 certain conditions.
2286 </p>
2287 </li>
2288 <li>
2289 <p>
2290 Forgetting to call <code>floating_fix_coordinates(con, old_rect, new_rect)</code> after
2291 moving workspaces across outputs. Coordinates for floating containers are
2292 not relative to workspace boundaries, so you must correct their coordinates
2293 or those containers will show up in the wrong workspace or not at all.
2294 </p>
2295 </li>
2296 </ul></div>
2297 </div>
2298 </div>
2299 <div class="sect1">
2300 <h2 id="_thought_experiments">22. Thought experiments</h2>
2301 <div class="sectionbody">
2302 <div class="paragraph"><p>In this section, we collect thought experiments, so that we don’t forget our
2303 thoughts about specific topics. They are not necessary to get into hacking i3,
2304 but if you are interested in one of the topics they cover, you should read them
2305 before asking us why things are the way they are or why we don’t implement
2306 things.</p></div>
2307 <div class="sect2">
2308 <h3 id="_using_cgroups_per_workspace">22.1. Using cgroups per workspace</h3>
2309 <div class="paragraph"><p>cgroups (control groups) are a linux-only feature which provides the ability to
2310 group multiple processes. For each group, you can individually set resource
2311 limits, like allowed memory usage. Furthermore, and more importantly for our
2312 purposes, they serve as a namespace, a label which you can attach to processes
2313 and their children.</p></div>
2314 <div class="paragraph"><p>One interesting use for cgroups is having one cgroup per workspace (or
2315 container, doesn’t really matter). That way, you could set different priorities
2316 and have a workspace for important stuff (say, writing a LaTeX document or
2317 programming) and a workspace for unimportant background stuff (say,
2318 JDownloader). Both tasks can obviously consume a lot of I/O resources, but in
2319 this example it doesn’t really matter if JDownloader unpacks the download a
2320 minute earlier or not. However, your compiler should work as fast as possible.
2321 Having one cgroup per workspace, you would assign more resources to the
2322 programming workspace.</p></div>
2323 <div class="paragraph"><p>Another interesting feature is that an inherent problem of the workspace
2324 concept could be solved by using cgroups: When starting an application on
2325 workspace 1, then switching to workspace 2, you will get the application’s
2326 window(s) on workspace 2 instead of the one you started it on. This is because
2327 the window manager does not have any mapping between the process it starts (or
2328 gets started in any way) and the window(s) which appear.</p></div>
2329 <div class="paragraph"><p>Imagine for example using dmenu: The user starts dmenu by pressing Mod+d, dmenu
2330 gets started with PID 3390. The user then decides to launch Firefox, which
2331 takes a long time. So they enter firefox into dmenu and press enter. Firefox
2332 gets started with PID 4001. When it finally finishes loading, it creates an X11
2333 window and uses MapWindow to make it visible. This is the first time i3
2334 actually gets in touch with Firefox. It decides to map the window, but it has
2335 no way of knowing that this window (even though it has the _NET_WM_PID property
2336 set to 4001) belongs to the dmenu the user started before.</p></div>
2337 <div class="paragraph"><p>How do cgroups help with this? Well, when pressing Mod+d to launch dmenu, i3
2338 would create a new cgroup, let’s call it i3-3390-1. It launches dmenu in that
2339 cgroup, which gets PID 3390. As before, the user enters firefox and Firefox
2340 gets launched with PID 4001. This time, though, the Firefox process with PID
2341 4001 is <strong>also</strong> member of the cgroup i3-3390-1 (because fork()ing in a cgroup
2342 retains the cgroup property). Therefore, when mapping the window, i3 can look
2343 up in which cgroup the process is and can establish a mapping between the
2344 workspace and the window.</p></div>
2345 <div class="paragraph"><p>There are multiple problems with this approach:</p></div>
2346 <div class="olist arabic"><ol class="arabic">
2347 <li>
2348 <p>
2349 Every application has to properly set <code>_NET_WM_PID</code>. This is acceptable and
2350 patches can be written for the few applications which don’t set the hint yet.
2351 </p>
2352 </li>
2353 <li>
2354 <p>
2355 It does only work on Linux, since cgroups are a Linux-only feature. Again,
2356 this is acceptable.
2357 </p>
2358 </li>
2359 <li>
2360 <p>
2361 The main problem is that some applications create X11 windows completely
2362 independent of UNIX processes. An example for this is Chromium (or
2363 gnome-terminal), which, when being started a second time, communicates with
2364 the first process and lets the first process open a new window. Therefore, if
2365 you have a Chromium window on workspace 2 and you are currently working on
2366 workspace 3, starting <code>chromium</code> does not lead to the desired result (the
2367 window will open on workspace 2).
2368 </p>
2369 </li>
2370 </ol></div>
2371 <div class="paragraph"><p>Therefore, my conclusion is that the only proper way of fixing the "window gets
2372 opened on the wrong workspace" problem is in the application itself. Most
2373 modern applications support freedesktop startup-notifications which can be
2374 used for this.</p></div>
2375 </div>
2376 </div>
2377 </div>
2378 </div>
2379 <div id="footnotes"><hr /></div>
2380 <div id="footer">
2381 <div id="footer-text">
2382 Last updated
2383 2019-08-30 23:06:47 CEST
2384 </div>
2385 </div>
2386 </body>
2387 </html>
0 <?xml version="1.0" encoding="UTF-8"?>
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
2 "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
4 <head>
5 <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
6 <meta name="generator" content="AsciiDoc 8.6.10" />
7 <title>i3bar input protocol</title>
8 <style type="text/css">
9 /* Shared CSS for AsciiDoc xhtml11 and html5 backends */
10
11 /* Default font. */
12 body {
13 font-family: Georgia,serif;
14 }
15
16 /* Title font. */
17 h1, h2, h3, h4, h5, h6,
18 div.title, caption.title,
19 thead, p.table.header,
20 #toctitle,
21 #author, #revnumber, #revdate, #revremark,
22 #footer {
23 font-family: Arial,Helvetica,sans-serif;
24 }
25
26 body {
27 margin: 1em 5% 1em 5%;
28 }
29
30 a {
31 color: blue;
32 text-decoration: underline;
33 }
34 a:visited {
35 color: fuchsia;
36 }
37
38 em {
39 font-style: italic;
40 color: navy;
41 }
42
43 strong {
44 font-weight: bold;
45 color: #083194;
46 }
47
48 h1, h2, h3, h4, h5, h6 {
49 color: #527bbd;
50 margin-top: 1.2em;
51 margin-bottom: 0.5em;
52 line-height: 1.3;
53 }
54
55 h1, h2, h3 {
56 border-bottom: 2px solid silver;
57 }
58 h2 {
59 padding-top: 0.5em;
60 }
61 h3 {
62 float: left;
63 }
64 h3 + * {
65 clear: left;
66 }
67 h5 {
68 font-size: 1.0em;
69 }
70
71 div.sectionbody {
72 margin-left: 0;
73 }
74
75 hr {
76 border: 1px solid silver;
77 }
78
79 p {
80 margin-top: 0.5em;
81 margin-bottom: 0.5em;
82 }
83
84 ul, ol, li > p {
85 margin-top: 0;
86 }
87 ul > li { color: #aaa; }
88 ul > li > * { color: black; }
89
90 .monospaced, code, pre {
91 font-family: "Courier New", Courier, monospace;
92 font-size: inherit;
93 color: navy;
94 padding: 0;
95 margin: 0;
96 }
97 pre {
98 white-space: pre-wrap;
99 }
100
101 #author {
102 color: #527bbd;
103 font-weight: bold;
104 font-size: 1.1em;
105 }
106 #email {
107 }
108 #revnumber, #revdate, #revremark {
109 }
110
111 #footer {
112 font-size: small;
113 border-top: 2px solid silver;
114 padding-top: 0.5em;
115 margin-top: 4.0em;
116 }
117 #footer-text {
118 float: left;
119 padding-bottom: 0.5em;
120 }
121 #footer-badges {
122 float: right;
123 padding-bottom: 0.5em;
124 }
125
126 #preamble {
127 margin-top: 1.5em;
128 margin-bottom: 1.5em;
129 }
130 div.imageblock, div.exampleblock, div.verseblock,
131 div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
132 div.admonitionblock {
133 margin-top: 1.0em;
134 margin-bottom: 1.5em;
135 }
136 div.admonitionblock {
137 margin-top: 2.0em;
138 margin-bottom: 2.0em;
139 margin-right: 10%;
140 color: #606060;
141 }
142
143 div.content { /* Block element content. */
144 padding: 0;
145 }
146
147 /* Block element titles. */
148 div.title, caption.title {
149 color: #527bbd;
150 font-weight: bold;
151 text-align: left;
152 margin-top: 1.0em;
153 margin-bottom: 0.5em;
154 }
155 div.title + * {
156 margin-top: 0;
157 }
158
159 td div.title:first-child {
160 margin-top: 0.0em;
161 }
162 div.content div.title:first-child {
163 margin-top: 0.0em;
164 }
165 div.content + div.title {
166 margin-top: 0.0em;
167 }
168
169 div.sidebarblock > div.content {
170 background: #ffffee;
171 border: 1px solid #dddddd;
172 border-left: 4px solid #f0f0f0;
173 padding: 0.5em;
174 }
175
176 div.listingblock > div.content {
177 border: 1px solid #dddddd;
178 border-left: 5px solid #f0f0f0;
179 background: #f8f8f8;
180 padding: 0.5em;
181 }
182
183 div.quoteblock, div.verseblock {
184 padding-left: 1.0em;
185 margin-left: 1.0em;
186 margin-right: 10%;
187 border-left: 5px solid #f0f0f0;
188 color: #888;
189 }
190
191 div.quoteblock > div.attribution {
192 padding-top: 0.5em;
193 text-align: right;
194 }
195
196 div.verseblock > pre.content {
197 font-family: inherit;
198 font-size: inherit;
199 }
200 div.verseblock > div.attribution {
201 padding-top: 0.75em;
202 text-align: left;
203 }
204 /* DEPRECATED: Pre version 8.2.7 verse style literal block. */
205 div.verseblock + div.attribution {
206 text-align: left;
207 }
208
209 div.admonitionblock .icon {
210 vertical-align: top;
211 font-size: 1.1em;
212 font-weight: bold;
213 text-decoration: underline;
214 color: #527bbd;
215 padding-right: 0.5em;
216 }
217 div.admonitionblock td.content {
218 padding-left: 0.5em;
219 border-left: 3px solid #dddddd;
220 }
221
222 div.exampleblock > div.content {
223 border-left: 3px solid #dddddd;
224 padding-left: 0.5em;
225 }
226
227 div.imageblock div.content { padding-left: 0; }
228 span.image img { border-style: none; vertical-align: text-bottom; }
229 a.image:visited { color: white; }
230
231 dl {
232 margin-top: 0.8em;
233 margin-bottom: 0.8em;
234 }
235 dt {
236 margin-top: 0.5em;
237 margin-bottom: 0;
238 font-style: normal;
239 color: navy;
240 }
241 dd > *:first-child {
242 margin-top: 0.1em;
243 }
244
245 ul, ol {
246 list-style-position: outside;
247 }
248 ol.arabic {
249 list-style-type: decimal;
250 }
251 ol.loweralpha {
252 list-style-type: lower-alpha;
253 }
254 ol.upperalpha {
255 list-style-type: upper-alpha;
256 }
257 ol.lowerroman {
258 list-style-type: lower-roman;
259 }
260 ol.upperroman {
261 list-style-type: upper-roman;
262 }
263
264 div.compact ul, div.compact ol,
265 div.compact p, div.compact p,
266 div.compact div, div.compact div {
267 margin-top: 0.1em;
268 margin-bottom: 0.1em;
269 }
270
271 tfoot {
272 font-weight: bold;
273 }
274 td > div.verse {
275 white-space: pre;
276 }
277
278 div.hdlist {
279 margin-top: 0.8em;
280 margin-bottom: 0.8em;
281 }
282 div.hdlist tr {
283 padding-bottom: 15px;
284 }
285 dt.hdlist1.strong, td.hdlist1.strong {
286 font-weight: bold;
287 }
288 td.hdlist1 {
289 vertical-align: top;
290 font-style: normal;
291 padding-right: 0.8em;
292 color: navy;
293 }
294 td.hdlist2 {
295 vertical-align: top;
296 }
297 div.hdlist.compact tr {
298 margin: 0;
299 padding-bottom: 0;
300 }
301
302 .comment {
303 background: yellow;
304 }
305
306 .footnote, .footnoteref {
307 font-size: 0.8em;
308 }
309
310 span.footnote, span.footnoteref {
311 vertical-align: super;
312 }
313
314 #footnotes {
315 margin: 20px 0 20px 0;
316 padding: 7px 0 0 0;
317 }
318
319 #footnotes div.footnote {
320 margin: 0 0 5px 0;
321 }
322
323 #footnotes hr {
324 border: none;
325 border-top: 1px solid silver;
326 height: 1px;
327 text-align: left;
328 margin-left: 0;
329 width: 20%;
330 min-width: 100px;
331 }
332
333 div.colist td {
334 padding-right: 0.5em;
335 padding-bottom: 0.3em;
336 vertical-align: top;
337 }
338 div.colist td img {
339 margin-top: 0.3em;
340 }
341
342 @media print {
343 #footer-badges { display: none; }
344 }
345
346 #toc {
347 margin-bottom: 2.5em;
348 }
349
350 #toctitle {
351 color: #527bbd;
352 font-size: 1.1em;
353 font-weight: bold;
354 margin-top: 1.0em;
355 margin-bottom: 0.1em;
356 }
357
358 div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
359 margin-top: 0;
360 margin-bottom: 0;
361 }
362 div.toclevel2 {
363 margin-left: 2em;
364 font-size: 0.9em;
365 }
366 div.toclevel3 {
367 margin-left: 4em;
368 font-size: 0.9em;
369 }
370 div.toclevel4 {
371 margin-left: 6em;
372 font-size: 0.9em;
373 }
374
375 span.aqua { color: aqua; }
376 span.black { color: black; }
377 span.blue { color: blue; }
378 span.fuchsia { color: fuchsia; }
379 span.gray { color: gray; }
380 span.green { color: green; }
381 span.lime { color: lime; }
382 span.maroon { color: maroon; }
383 span.navy { color: navy; }
384 span.olive { color: olive; }
385 span.purple { color: purple; }
386 span.red { color: red; }
387 span.silver { color: silver; }
388 span.teal { color: teal; }
389 span.white { color: white; }
390 span.yellow { color: yellow; }
391
392 span.aqua-background { background: aqua; }
393 span.black-background { background: black; }
394 span.blue-background { background: blue; }
395 span.fuchsia-background { background: fuchsia; }
396 span.gray-background { background: gray; }
397 span.green-background { background: green; }
398 span.lime-background { background: lime; }
399 span.maroon-background { background: maroon; }
400 span.navy-background { background: navy; }
401 span.olive-background { background: olive; }
402 span.purple-background { background: purple; }
403 span.red-background { background: red; }
404 span.silver-background { background: silver; }
405 span.teal-background { background: teal; }
406 span.white-background { background: white; }
407 span.yellow-background { background: yellow; }
408
409 span.big { font-size: 2em; }
410 span.small { font-size: 0.6em; }
411
412 span.underline { text-decoration: underline; }
413 span.overline { text-decoration: overline; }
414 span.line-through { text-decoration: line-through; }
415
416 div.unbreakable { page-break-inside: avoid; }
417
418
419 /*
420 * xhtml11 specific
421 *
422 * */
423
424 div.tableblock {
425 margin-top: 1.0em;
426 margin-bottom: 1.5em;
427 }
428 div.tableblock > table {
429 border: 3px solid #527bbd;
430 }
431 thead, p.table.header {
432 font-weight: bold;
433 color: #527bbd;
434 }
435 p.table {
436 margin-top: 0;
437 }
438 /* Because the table frame attribute is overriden by CSS in most browsers. */
439 div.tableblock > table[frame="void"] {
440 border-style: none;
441 }
442 div.tableblock > table[frame="hsides"] {
443 border-left-style: none;
444 border-right-style: none;
445 }
446 div.tableblock > table[frame="vsides"] {
447 border-top-style: none;
448 border-bottom-style: none;
449 }
450
451
452 /*
453 * html5 specific
454 *
455 * */
456
457 table.tableblock {
458 margin-top: 1.0em;
459 margin-bottom: 1.5em;
460 }
461 thead, p.tableblock.header {
462 font-weight: bold;
463 color: #527bbd;
464 }
465 p.tableblock {
466 margin-top: 0;
467 }
468 table.tableblock {
469 border-width: 3px;
470 border-spacing: 0px;
471 border-style: solid;
472 border-color: #527bbd;
473 border-collapse: collapse;
474 }
475 th.tableblock, td.tableblock {
476 border-width: 1px;
477 padding: 4px;
478 border-style: solid;
479 border-color: #527bbd;
480 }
481
482 table.tableblock.frame-topbot {
483 border-left-style: hidden;
484 border-right-style: hidden;
485 }
486 table.tableblock.frame-sides {
487 border-top-style: hidden;
488 border-bottom-style: hidden;
489 }
490 table.tableblock.frame-none {
491 border-style: hidden;
492 }
493
494 th.tableblock.halign-left, td.tableblock.halign-left {
495 text-align: left;
496 }
497 th.tableblock.halign-center, td.tableblock.halign-center {
498 text-align: center;
499 }
500 th.tableblock.halign-right, td.tableblock.halign-right {
501 text-align: right;
502 }
503
504 th.tableblock.valign-top, td.tableblock.valign-top {
505 vertical-align: top;
506 }
507 th.tableblock.valign-middle, td.tableblock.valign-middle {
508 vertical-align: middle;
509 }
510 th.tableblock.valign-bottom, td.tableblock.valign-bottom {
511 vertical-align: bottom;
512 }
513
514
515 /*
516 * manpage specific
517 *
518 * */
519
520 body.manpage h1 {
521 padding-top: 0.5em;
522 padding-bottom: 0.5em;
523 border-top: 2px solid silver;
524 border-bottom: 2px solid silver;
525 }
526 body.manpage h2 {
527 border-style: none;
528 }
529 body.manpage div.sectionbody {
530 margin-left: 3em;
531 }
532
533 @media print {
534 body.manpage div#toc { display: none; }
535 }
536
537
538 </style>
539 <script type="text/javascript">
540 /*<![CDATA[*/
541 var asciidoc = { // Namespace.
542
543 /////////////////////////////////////////////////////////////////////
544 // Table Of Contents generator
545 /////////////////////////////////////////////////////////////////////
546
547 /* Author: Mihai Bazon, September 2002
548 * http://students.infoiasi.ro/~mishoo
549 *
550 * Table Of Content generator
551 * Version: 0.4
552 *
553 * Feel free to use this script under the terms of the GNU General Public
554 * License, as long as you do not remove or alter this notice.
555 */
556
557 /* modified by Troy D. Hanson, September 2006. License: GPL */
558 /* modified by Stuart Rackham, 2006, 2009. License: GPL */
559
560 // toclevels = 1..4.
561 toc: function (toclevels) {
562
563 function getText(el) {
564 var text = "";
565 for (var i = el.firstChild; i != null; i = i.nextSibling) {
566 if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
567 text += i.data;
568 else if (i.firstChild != null)
569 text += getText(i);
570 }
571 return text;
572 }
573
574 function TocEntry(el, text, toclevel) {
575 this.element = el;
576 this.text = text;
577 this.toclevel = toclevel;
578 }
579
580 function tocEntries(el, toclevels) {
581 var result = new Array;
582 var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
583 // Function that scans the DOM tree for header elements (the DOM2
584 // nodeIterator API would be a better technique but not supported by all
585 // browsers).
586 var iterate = function (el) {
587 for (var i = el.firstChild; i != null; i = i.nextSibling) {
588 if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
589 var mo = re.exec(i.tagName);
590 if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
591 result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
592 }
593 iterate(i);
594 }
595 }
596 }
597 iterate(el);
598 return result;
599 }
600
601 var toc = document.getElementById("toc");
602 if (!toc) {
603 return;
604 }
605
606 // Delete existing TOC entries in case we're reloading the TOC.
607 var tocEntriesToRemove = [];
608 var i;
609 for (i = 0; i < toc.childNodes.length; i++) {
610 var entry = toc.childNodes[i];
611 if (entry.nodeName.toLowerCase() == 'div'
612 && entry.getAttribute("class")
613 && entry.getAttribute("class").match(/^toclevel/))
614 tocEntriesToRemove.push(entry);
615 }
616 for (i = 0; i < tocEntriesToRemove.length; i++) {
617 toc.removeChild(tocEntriesToRemove[i]);
618 }
619
620 // Rebuild TOC entries.
621 var entries = tocEntries(document.getElementById("content"), toclevels);
622 for (var i = 0; i < entries.length; ++i) {
623 var entry = entries[i];
624 if (entry.element.id == "")
625 entry.element.id = "_toc_" + i;
626 var a = document.createElement("a");
627 a.href = "#" + entry.element.id;
628 a.appendChild(document.createTextNode(entry.text));
629 var div = document.createElement("div");
630 div.appendChild(a);
631 div.className = "toclevel" + entry.toclevel;
632 toc.appendChild(div);
633 }
634 if (entries.length == 0)
635 toc.parentNode.removeChild(toc);
636 },
637
638
639 /////////////////////////////////////////////////////////////////////
640 // Footnotes generator
641 /////////////////////////////////////////////////////////////////////
642
643 /* Based on footnote generation code from:
644 * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
645 */
646
647 footnotes: function () {
648 // Delete existing footnote entries in case we're reloading the footnodes.
649 var i;
650 var noteholder = document.getElementById("footnotes");
651 if (!noteholder) {
652 return;
653 }
654 var entriesToRemove = [];
655 for (i = 0; i < noteholder.childNodes.length; i++) {
656 var entry = noteholder.childNodes[i];
657 if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
658 entriesToRemove.push(entry);
659 }
660 for (i = 0; i < entriesToRemove.length; i++) {
661 noteholder.removeChild(entriesToRemove[i]);
662 }
663
664 // Rebuild footnote entries.
665 var cont = document.getElementById("content");
666 var spans = cont.getElementsByTagName("span");
667 var refs = {};
668 var n = 0;
669 for (i=0; i<spans.length; i++) {
670 if (spans[i].className == "footnote") {
671 n++;
672 var note = spans[i].getAttribute("data-note");
673 if (!note) {
674 // Use [\s\S] in place of . so multi-line matches work.
675 // Because JavaScript has no s (dotall) regex flag.
676 note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
677 spans[i].innerHTML =
678 "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
679 "' title='View footnote' class='footnote'>" + n + "</a>]";
680 spans[i].setAttribute("data-note", note);
681 }
682 noteholder.innerHTML +=
683 "<div class='footnote' id='_footnote_" + n + "'>" +
684 "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
685 n + "</a>. " + note + "</div>";
686 var id =spans[i].getAttribute("id");
687 if (id != null) refs["#"+id] = n;
688 }
689 }
690 if (n == 0)
691 noteholder.parentNode.removeChild(noteholder);
692 else {
693 // Process footnoterefs.
694 for (i=0; i<spans.length; i++) {
695 if (spans[i].className == "footnoteref") {
696 var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
697 href = href.match(/#.*/)[0]; // Because IE return full URL.
698 n = refs[href];
699 spans[i].innerHTML =
700 "[<a href='#_footnote_" + n +
701 "' title='View footnote' class='footnote'>" + n + "</a>]";
702 }
703 }
704 }
705 },
706
707 install: function(toclevels) {
708 var timerId;
709
710 function reinstall() {
711 asciidoc.footnotes();
712 if (toclevels) {
713 asciidoc.toc(toclevels);
714 }
715 }
716
717 function reinstallAndRemoveTimer() {
718 clearInterval(timerId);
719 reinstall();
720 }
721
722 timerId = setInterval(reinstall, 500);
723 if (document.addEventListener)
724 document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
725 else
726 window.onload = reinstallAndRemoveTimer;
727 }
728
729 }
730 asciidoc.install(2);
731 /*]]>*/
732 </script>
733 </head>
734 <body class="article">
735 <div id="header">
736 <h1>i3bar input protocol</h1>
737 <span id="author">Michael Stapelberg</span><br />
738 <span id="email"><code>&lt;<a href="mailto:[email protected]">[email protected]</a>&gt;</code></span><br />
739 <span id="revdate">August 2012</span>
740 <div id="toc">
741 <div id="toctitle">Table of Contents</div>
742 <noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
743 </div>
744 </div>
745 <div id="content">
746 <div id="preamble">
747 <div class="sectionbody">
748 <div class="paragraph"><p>This document explains the protocol in which i3bar expects its input. It
749 provides support for colors, urgency, shortening and easy manipulation.</p></div>
750 </div>
751 </div>
752 <div class="sect1">
753 <h2 id="_rationale_for_choosing_json">1. Rationale for choosing JSON</h2>
754 <div class="sectionbody">
755 <div class="paragraph"><p>Before describing the protocol, let’s cover why JSON is a building block of
756 this protocol.</p></div>
757 <div class="olist arabic"><ol class="arabic">
758 <li>
759 <p>
760 Other bar display programs such as dzen2 or xmobar are using in-band
761 signaling: they recognize certain sequences (like ^fg(#330000) in your input
762 text). We would like to avoid that and separate information from
763 meta-information. By information, we mean the actual output, like the IP
764 address of your ethernet adapter and by meta-information, we mean in which
765 color it should be displayed right now.
766 </p>
767 </li>
768 <li>
769 <p>
770 It is easy to write a simple script which manipulates part(s) of the input.
771 Each block of information (like a block for the disk space indicator, a block
772 for the current IP address, etc.) can be identified specifically and modified
773 in whichever way you like.
774 </p>
775 </li>
776 <li>
777 <p>
778 It remains easy to write a simple script which just suffixes (or prefixes) a
779 status line input, because tools like i3status will output their JSON in
780 such a way that each line array will be terminated by a newline. Therefore,
781 you are not required to use a streaming JSON parser, but you can use any
782 JSON parser and write your script in any programming language. In fact, you
783 can decide to not bother with the JSON parsing at all and just inject your
784 output at a specific position (beginning or end).
785 </p>
786 </li>
787 <li>
788 <p>
789 Relying on JSON does not introduce any new dependencies. In fact, the IPC
790 interface of i3 also uses JSON, therefore i3bar already depends on JSON.
791 </p>
792 </li>
793 </ol></div>
794 <div class="paragraph"><p>The only point against using JSON is computational complexity. If that really
795 bothers you, just use the plain text input format (which i3bar will continue to
796 support).</p></div>
797 </div>
798 </div>
799 <div class="sect1">
800 <h2 id="_the_protocol">2. The protocol</h2>
801 <div class="sectionbody">
802 <div class="paragraph"><p>The first message of the protocol is a header block, which contains (at least)
803 the version of the protocol to be used. In case there are significant changes
804 (not only additions), the version will be incremented. i3bar will still
805 understand the old protocol version, but in order to use the new one, you need
806 to provide the correct version. The header block is terminated by a newline and
807 consists of a single JSON hash:</p></div>
808 <div class="paragraph"><p><strong>Minimal example</strong>:</p></div>
809 <div class="listingblock">
810 <div class="content">
811 <pre><code>{ "version": 1 }</code></pre>
812 </div></div>
813 <div class="paragraph"><p><strong>All features example</strong>:</p></div>
814 <div class="listingblock">
815 <div class="content">
816 <pre><code>{ "version": 1, "stop_signal": 10, "cont_signal": 12, "click_events": true }</code></pre>
817 </div></div>
818 <div class="paragraph"><p>(Note that before i3 v4.3 the precise format had to be <code>{"version":1}</code>,
819 byte-for-byte.)</p></div>
820 <div class="paragraph"><p>What follows is an infinite array (so it should be parsed by a streaming JSON
821 parser, but as described above you can go for a simpler solution), whose
822 elements are one array per status line. A status line is one unit of
823 information which should be displayed at a time. i3bar will not display any
824 input until the status line is complete. In each status line, every block will
825 be represented by a JSON hash:</p></div>
826 <div class="paragraph"><p><strong>Example</strong>:</p></div>
827 <div class="listingblock">
828 <div class="content">
829 <pre><code>[
830
831 [
832 {
833 "full_text": "E: 10.0.0.1 (1000 Mbit/s)",
834 "color": "#00ff00"
835 },
836 {
837 "full_text": "2012-01-05 20:00:01"
838 }
839 ],
840
841 [
842 {
843 "full_text": "E: 10.0.0.1 (1000 Mbit/s)",
844 "color": "#00ff00"
845 },
846 {
847 "full_text": "2012-01-05 20:00:02"
848 }
849 ],
850 …</code></pre>
851 </div></div>
852 <div class="paragraph"><p>Please note that this example was pretty printed for human consumption.
853 i3status and others will output single statuslines in one line, separated by
854 \n.</p></div>
855 <div class="paragraph"><p>You can find an example of a shell script which can be used as your
856 <code>status_command</code> in the bar configuration at
857 <a href="https://github.com/i3/i3/blob/next/contrib/trivial-bar-script.sh">https://github.com/i3/i3/blob/next/contrib/trivial-bar-script.sh</a></p></div>
858 <div class="sect2">
859 <h3 id="_header_in_detail">2.1. Header in detail</h3>
860 <div class="dlist"><dl>
861 <dt class="hdlist1">
862 version
863 </dt>
864 <dd>
865 <p>
866 The version number (as an integer) of the i3bar protocol you will use.
867 </p>
868 </dd>
869 <dt class="hdlist1">
870 stop_signal
871 </dt>
872 <dd>
873 <p>
874 Specify to i3bar the signal (as an integer) to send to stop your
875 processing.
876 The default value (if none is specified) is SIGSTOP.
877 </p>
878 </dd>
879 <dt class="hdlist1">
880 cont_signal
881 </dt>
882 <dd>
883 <p>
884 Specify to i3bar the signal (as an integer) to send to continue your
885 processing.
886 The default value (if none is specified) is SIGCONT.
887 </p>
888 </dd>
889 <dt class="hdlist1">
890 click_events
891 </dt>
892 <dd>
893 <p>
894 If specified and true i3bar will write an infinite array (same as above)
895 to your stdin.
896 </p>
897 </dd>
898 </dl></div>
899 </div>
900 <div class="sect2">
901 <h3 id="_blocks_in_detail">2.2. Blocks in detail</h3>
902 <div class="dlist"><dl>
903 <dt class="hdlist1">
904 full_text
905 </dt>
906 <dd>
907 <p>
908 The <code>full_text</code> will be displayed by i3bar on the status line. This is the
909 only required key. If <code>full_text</code> is an empty string, the block will be
910 skipped.
911 </p>
912 </dd>
913 <dt class="hdlist1">
914 short_text
915 </dt>
916 <dd>
917 <p>
918 Where appropriate, the <code>short_text</code> (string) entry should also be
919 provided. It will be used in case the status line needs to be shortened
920 because it uses more space than your screen provides. For example, when
921 displaying an IPv6 address, the prefix is usually (!) more relevant
922 than the suffix, because the latter stays constant when using autoconf,
923 while the prefix changes. When displaying the date, the time is more
924 important than the date (it is more likely that you know which day it
925 is than what time it is).
926 </p>
927 </dd>
928 <dt class="hdlist1">
929 color
930 </dt>
931 <dd>
932 <p>
933 To make the current state of the information easy to spot, colors can
934 be used. For example, the wireless block could be displayed in red
935 (using the <code>color</code> (string) entry) if the card is not associated with
936 any network and in green or yellow (depending on the signal strength)
937 when it is associated.
938 Colors are specified in hex (like in HTML), starting with a leading
939 hash sign. For example, <code>#ff0000</code> means red.
940 </p>
941 </dd>
942 <dt class="hdlist1">
943 background
944 </dt>
945 <dd>
946 <p>
947 Overrides the background color for this particular block.
948 </p>
949 </dd>
950 <dt class="hdlist1">
951 border
952 </dt>
953 <dd>
954 <p>
955 Overrides the border color for this particular block.
956 </p>
957 </dd>
958 <dt class="hdlist1">
959 border_top
960 </dt>
961 <dd>
962 <p>
963 Defines the width (in pixels) of the top border of this block. Defaults
964 to 1.
965 </p>
966 </dd>
967 <dt class="hdlist1">
968 border_right
969 </dt>
970 <dd>
971 <p>
972 Defines the width (in pixels) of the right border of this block. Defaults
973 to 1.
974 </p>
975 </dd>
976 <dt class="hdlist1">
977 border_bottom
978 </dt>
979 <dd>
980 <p>
981 Defines the width (in pixels) of the bottom border of this block. Defaults
982 to 1.
983 </p>
984 </dd>
985 <dt class="hdlist1">
986 border_left
987 </dt>
988 <dd>
989 <p>
990 Defines the width (in pixels) of the left border of this block. Defaults
991 to 1.
992 </p>
993 </dd>
994 <dt class="hdlist1">
995 min_width
996 </dt>
997 <dd>
998 <p>
999 The minimum width (in pixels) of the block. If the content of the
1000 <code>full_text</code> key take less space than the specified min_width, the block
1001 will be padded to the left and/or the right side, according to the <code>align</code>
1002 key. This is useful when you want to prevent the whole status line to shift
1003 when value take more or less space between each iteration.
1004 The value can also be a string. In this case, the width of the text given
1005 by <code>min_width</code> determines the minimum width of the block. This is useful
1006 when you want to set a sensible minimum width regardless of which font you
1007 are using, and at what particular size.
1008 </p>
1009 </dd>
1010 <dt class="hdlist1">
1011 align
1012 </dt>
1013 <dd>
1014 <p>
1015 Align text on the <code>center</code>, <code>right</code> or <code>left</code> (default) of the block, when
1016 the minimum width of the latter, specified by the <code>min_width</code> key, is not
1017 reached.
1018 </p>
1019 </dd>
1020 <dt class="hdlist1">
1021 name and instance
1022 </dt>
1023 <dd>
1024 <p>
1025 Every block should have a unique <code>name</code> (string) entry so that it can
1026 be easily identified in scripts which process the output. i3bar
1027 completely ignores the name and instance fields. Make sure to also
1028 specify an <code>instance</code> (string) entry where appropriate. For example,
1029 the user can have multiple disk space blocks for multiple mount points.
1030 </p>
1031 </dd>
1032 <dt class="hdlist1">
1033 urgent
1034 </dt>
1035 <dd>
1036 <p>
1037 A boolean which specifies whether the current value is urgent. Examples
1038 are battery charge values below 1 percent or no more available disk
1039 space (for non-root users). The presentation of urgency is up to i3bar.
1040 </p>
1041 </dd>
1042 <dt class="hdlist1">
1043 separator
1044 </dt>
1045 <dd>
1046 <p>
1047 A boolean which specifies whether a separator line should be drawn
1048 after this block. The default is true, meaning the separator line will
1049 be drawn. Note that if you disable the separator line, there will still
1050 be a gap after the block, unless you also use <code>separator_block_width</code>.
1051 </p>
1052 </dd>
1053 <dt class="hdlist1">
1054 separator_block_width
1055 </dt>
1056 <dd>
1057 <p>
1058 The amount of pixels to leave blank after the block. In the middle of
1059 this gap, a separator line will be drawn unless <code>separator</code> is
1060 disabled. Normally, you want to set this to an odd value (the default
1061 is 9 pixels), since the separator line is drawn in the middle.
1062 </p>
1063 </dd>
1064 <dt class="hdlist1">
1065 markup
1066 </dt>
1067 <dd>
1068 <p>
1069 A string that indicates how the text of the block should be parsed. Set to
1070 <code>"pango"</code> to use <a href="https://developer.gnome.org/pango/stable/PangoMarkupFormat.html">Pango markup</a>.
1071 Set to <code>"none"</code> to not use any markup (default). Pango markup only works
1072 if you use a pango font.
1073 </p>
1074 </dd>
1075 </dl></div>
1076 <div class="paragraph"><p>If you want to put in your own entries into a block, prefix the key with an
1077 underscore (_). i3bar will ignore all keys it doesn’t understand, and prefixing
1078 them with an underscore makes it clear in every script that they are not part
1079 of the i3bar protocol.</p></div>
1080 <div class="paragraph"><p><strong>Example</strong>:</p></div>
1081 <div class="listingblock">
1082 <div class="content">
1083 <pre><code>{
1084 "full_text": "E: 10.0.0.1 (1000 Mbit/s)",
1085 "_ethernet_vendor": "Intel"
1086 }</code></pre>
1087 </div></div>
1088 <div class="paragraph"><p>In the following example, the longest (widest) possible value of the block is
1089 used to set the minimum width:</p></div>
1090 <div class="listingblock">
1091 <div class="content">
1092 <pre><code>{
1093 "full_text": "CPU 4%",
1094 "min_width": "CPU 100%",
1095 "align": "left"
1096 }</code></pre>
1097 </div></div>
1098 <div class="paragraph"><p>An example of a block which uses all possible entries follows:</p></div>
1099 <div class="paragraph"><p><strong>Example</strong>:</p></div>
1100 <div class="listingblock">
1101 <div class="content">
1102 <pre><code>{
1103 "full_text": "E: 10.0.0.1 (1000 Mbit/s)",
1104 "short_text": "10.0.0.1",
1105 "color": "#00ff00",
1106 "background": "#1c1c1c",
1107 "border": "#ee0000",
1108 "border_top": 1,
1109 "border_right": 0,
1110 "border_bottom": 3,
1111 "border_left": 1,
1112 "min_width": 300,
1113 "align": "right",
1114 "urgent": false,
1115 "name": "ethernet",
1116 "instance": "eth0",
1117 "separator": true,
1118 "separator_block_width": 9,
1119 "markup": "none"
1120 }</code></pre>
1121 </div></div>
1122 </div>
1123 <div class="sect2">
1124 <h3 id="_click_events">2.3. Click events</h3>
1125 <div class="paragraph"><p>If enabled i3bar will send you notifications if the user clicks on a block and
1126 looks like this:</p></div>
1127 <div class="dlist"><dl>
1128 <dt class="hdlist1">
1129 name
1130 </dt>
1131 <dd>
1132 <p>
1133 Name of the block, if set
1134 </p>
1135 </dd>
1136 <dt class="hdlist1">
1137 instance
1138 </dt>
1139 <dd>
1140 <p>
1141 Instance of the block, if set
1142 </p>
1143 </dd>
1144 <dt class="hdlist1">
1145 x, y
1146 </dt>
1147 <dd>
1148 <p>
1149 X11 root window coordinates where the click occurred
1150 </p>
1151 </dd>
1152 <dt class="hdlist1">
1153 button
1154 </dt>
1155 <dd>
1156 <p>
1157 X11 button ID (for example 1 to 3 for left/middle/right mouse button)
1158 </p>
1159 </dd>
1160 <dt class="hdlist1">
1161 relative_x, relative_y
1162 </dt>
1163 <dd>
1164 <p>
1165 Coordinates where the click occurred, with respect to the top left corner
1166 of the block
1167 </p>
1168 </dd>
1169 <dt class="hdlist1">
1170 width, height
1171 </dt>
1172 <dd>
1173 <p>
1174 Width and height (in px) of the block
1175 </p>
1176 </dd>
1177 <dt class="hdlist1">
1178 modifiers
1179 </dt>
1180 <dd>
1181 <p>
1182 An array of the modifiers active when the click occurred. The order in which
1183 modifiers are listed is not guaranteed.
1184 </p>
1185 </dd>
1186 </dl></div>
1187 <div class="paragraph"><p><strong>Example</strong>:</p></div>
1188 <div class="listingblock">
1189 <div class="content">
1190 <pre><code>{
1191 "name": "ethernet",
1192 "instance": "eth0",
1193 "button": 1,
1194 "modifiers": ["Shift", "Mod1"],
1195 "x": 1320,
1196 "y": 1400,
1197 "relative_x": 12,
1198 "relative_y": 8,
1199 "width": 50,
1200 "height": 22
1201 }</code></pre>
1202 </div></div>
1203 </div>
1204 </div>
1205 </div>
1206 </div>
1207 <div id="footnotes"><hr /></div>
1208 <div id="footer">
1209 <div id="footer-text">
1210 Last updated
1211 2019-08-30 23:06:47 CEST
1212 </div>
1213 </div>
1214 </body>
1215 </html>
0 <?xml version="1.0" encoding="UTF-8"?>
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
2 "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
4 <head>
5 <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
6 <meta name="generator" content="AsciiDoc 8.6.10" />
7 <title>IPC interface (interprocess communication)</title>
8 <style type="text/css">
9 /* Shared CSS for AsciiDoc xhtml11 and html5 backends */
10
11 /* Default font. */
12 body {
13 font-family: Georgia,serif;
14 }
15
16 /* Title font. */
17 h1, h2, h3, h4, h5, h6,
18 div.title, caption.title,
19 thead, p.table.header,
20 #toctitle,
21 #author, #revnumber, #revdate, #revremark,
22 #footer {
23 font-family: Arial,Helvetica,sans-serif;
24 }
25
26 body {
27 margin: 1em 5% 1em 5%;
28 }
29
30 a {
31 color: blue;
32 text-decoration: underline;
33 }
34 a:visited {
35 color: fuchsia;
36 }
37
38 em {
39 font-style: italic;
40 color: navy;
41 }
42
43 strong {
44 font-weight: bold;
45 color: #083194;
46 }
47
48 h1, h2, h3, h4, h5, h6 {
49 color: #527bbd;
50 margin-top: 1.2em;
51 margin-bottom: 0.5em;
52 line-height: 1.3;
53 }
54
55 h1, h2, h3 {
56 border-bottom: 2px solid silver;
57 }
58 h2 {
59 padding-top: 0.5em;
60 }
61 h3 {
62 float: left;
63 }
64 h3 + * {
65 clear: left;
66 }
67 h5 {
68 font-size: 1.0em;
69 }
70
71 div.sectionbody {
72 margin-left: 0;
73 }
74
75 hr {
76 border: 1px solid silver;
77 }
78
79 p {
80 margin-top: 0.5em;
81 margin-bottom: 0.5em;
82 }
83
84 ul, ol, li > p {
85 margin-top: 0;
86 }
87 ul > li { color: #aaa; }
88 ul > li > * { color: black; }
89
90 .monospaced, code, pre {
91 font-family: "Courier New", Courier, monospace;
92 font-size: inherit;
93 color: navy;
94 padding: 0;
95 margin: 0;
96 }
97 pre {
98 white-space: pre-wrap;
99 }
100
101 #author {
102 color: #527bbd;
103 font-weight: bold;
104 font-size: 1.1em;
105 }
106 #email {
107 }
108 #revnumber, #revdate, #revremark {
109 }
110
111 #footer {
112 font-size: small;
113 border-top: 2px solid silver;
114 padding-top: 0.5em;
115 margin-top: 4.0em;
116 }
117 #footer-text {
118 float: left;
119 padding-bottom: 0.5em;
120 }
121 #footer-badges {
122 float: right;
123 padding-bottom: 0.5em;
124 }
125
126 #preamble {
127 margin-top: 1.5em;
128 margin-bottom: 1.5em;
129 }
130 div.imageblock, div.exampleblock, div.verseblock,
131 div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
132 div.admonitionblock {
133 margin-top: 1.0em;
134 margin-bottom: 1.5em;
135 }
136 div.admonitionblock {
137 margin-top: 2.0em;
138 margin-bottom: 2.0em;
139 margin-right: 10%;
140 color: #606060;
141 }
142
143 div.content { /* Block element content. */
144 padding: 0;
145 }
146
147 /* Block element titles. */
148 div.title, caption.title {
149 color: #527bbd;
150 font-weight: bold;
151 text-align: left;
152 margin-top: 1.0em;
153 margin-bottom: 0.5em;
154 }
155 div.title + * {
156 margin-top: 0;
157 }
158
159 td div.title:first-child {
160 margin-top: 0.0em;
161 }
162 div.content div.title:first-child {
163 margin-top: 0.0em;
164 }
165 div.content + div.title {
166 margin-top: 0.0em;
167 }
168
169 div.sidebarblock > div.content {
170 background: #ffffee;
171 border: 1px solid #dddddd;
172 border-left: 4px solid #f0f0f0;
173 padding: 0.5em;
174 }
175
176 div.listingblock > div.content {
177 border: 1px solid #dddddd;
178 border-left: 5px solid #f0f0f0;
179 background: #f8f8f8;
180 padding: 0.5em;
181 }
182
183 div.quoteblock, div.verseblock {
184 padding-left: 1.0em;
185 margin-left: 1.0em;
186 margin-right: 10%;
187 border-left: 5px solid #f0f0f0;
188 color: #888;
189 }
190
191 div.quoteblock > div.attribution {
192 padding-top: 0.5em;
193 text-align: right;
194 }
195
196 div.verseblock > pre.content {
197 font-family: inherit;
198 font-size: inherit;
199 }
200 div.verseblock > div.attribution {
201 padding-top: 0.75em;
202 text-align: left;
203 }
204 /* DEPRECATED: Pre version 8.2.7 verse style literal block. */
205 div.verseblock + div.attribution {
206 text-align: left;
207 }
208
209 div.admonitionblock .icon {
210 vertical-align: top;
211 font-size: 1.1em;
212 font-weight: bold;
213 text-decoration: underline;
214 color: #527bbd;
215 padding-right: 0.5em;
216 }
217 div.admonitionblock td.content {
218 padding-left: 0.5em;
219 border-left: 3px solid #dddddd;
220 }
221
222 div.exampleblock > div.content {
223 border-left: 3px solid #dddddd;
224 padding-left: 0.5em;
225 }
226
227 div.imageblock div.content { padding-left: 0; }
228 span.image img { border-style: none; vertical-align: text-bottom; }
229 a.image:visited { color: white; }
230
231 dl {
232 margin-top: 0.8em;
233 margin-bottom: 0.8em;
234 }
235 dt {
236 margin-top: 0.5em;
237 margin-bottom: 0;
238 font-style: normal;
239 color: navy;
240 }
241 dd > *:first-child {
242 margin-top: 0.1em;
243 }
244
245 ul, ol {
246 list-style-position: outside;
247 }
248 ol.arabic {
249 list-style-type: decimal;
250 }
251 ol.loweralpha {
252 list-style-type: lower-alpha;
253 }
254 ol.upperalpha {
255 list-style-type: upper-alpha;
256 }
257 ol.lowerroman {
258 list-style-type: lower-roman;
259 }
260 ol.upperroman {
261 list-style-type: upper-roman;
262 }
263
264 div.compact ul, div.compact ol,
265 div.compact p, div.compact p,
266 div.compact div, div.compact div {
267 margin-top: 0.1em;
268 margin-bottom: 0.1em;
269 }
270
271 tfoot {
272 font-weight: bold;
273 }
274 td > div.verse {
275 white-space: pre;
276 }
277
278 div.hdlist {
279 margin-top: 0.8em;
280 margin-bottom: 0.8em;
281 }
282 div.hdlist tr {
283 padding-bottom: 15px;
284 }
285 dt.hdlist1.strong, td.hdlist1.strong {
286 font-weight: bold;
287 }
288 td.hdlist1 {
289 vertical-align: top;
290 font-style: normal;
291 padding-right: 0.8em;
292 color: navy;
293 }
294 td.hdlist2 {
295 vertical-align: top;
296 }
297 div.hdlist.compact tr {
298 margin: 0;
299 padding-bottom: 0;
300 }
301
302 .comment {
303 background: yellow;
304 }
305
306 .footnote, .footnoteref {
307 font-size: 0.8em;
308 }
309
310 span.footnote, span.footnoteref {
311 vertical-align: super;
312 }
313
314 #footnotes {
315 margin: 20px 0 20px 0;
316 padding: 7px 0 0 0;
317 }
318
319 #footnotes div.footnote {
320 margin: 0 0 5px 0;
321 }
322
323 #footnotes hr {
324 border: none;
325 border-top: 1px solid silver;
326 height: 1px;
327 text-align: left;
328 margin-left: 0;
329 width: 20%;
330 min-width: 100px;
331 }
332
333 div.colist td {
334 padding-right: 0.5em;
335 padding-bottom: 0.3em;
336 vertical-align: top;
337 }
338 div.colist td img {
339 margin-top: 0.3em;
340 }
341
342 @media print {
343 #footer-badges { display: none; }
344 }
345
346 #toc {
347 margin-bottom: 2.5em;
348 }
349
350 #toctitle {
351 color: #527bbd;
352 font-size: 1.1em;
353 font-weight: bold;
354 margin-top: 1.0em;
355 margin-bottom: 0.1em;
356 }
357
358 div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
359 margin-top: 0;
360 margin-bottom: 0;
361 }
362 div.toclevel2 {
363 margin-left: 2em;
364 font-size: 0.9em;
365 }
366 div.toclevel3 {
367 margin-left: 4em;
368 font-size: 0.9em;
369 }
370 div.toclevel4 {
371 margin-left: 6em;
372 font-size: 0.9em;
373 }
374
375 span.aqua { color: aqua; }
376 span.black { color: black; }
377 span.blue { color: blue; }
378 span.fuchsia { color: fuchsia; }
379 span.gray { color: gray; }
380 span.green { color: green; }
381 span.lime { color: lime; }
382 span.maroon { color: maroon; }
383 span.navy { color: navy; }
384 span.olive { color: olive; }
385 span.purple { color: purple; }
386 span.red { color: red; }
387 span.silver { color: silver; }
388 span.teal { color: teal; }
389 span.white { color: white; }
390 span.yellow { color: yellow; }
391
392 span.aqua-background { background: aqua; }
393 span.black-background { background: black; }
394 span.blue-background { background: blue; }
395 span.fuchsia-background { background: fuchsia; }
396 span.gray-background { background: gray; }
397 span.green-background { background: green; }
398 span.lime-background { background: lime; }
399 span.maroon-background { background: maroon; }
400 span.navy-background { background: navy; }
401 span.olive-background { background: olive; }
402 span.purple-background { background: purple; }
403 span.red-background { background: red; }
404 span.silver-background { background: silver; }
405 span.teal-background { background: teal; }
406 span.white-background { background: white; }
407 span.yellow-background { background: yellow; }
408
409 span.big { font-size: 2em; }
410 span.small { font-size: 0.6em; }
411
412 span.underline { text-decoration: underline; }
413 span.overline { text-decoration: overline; }
414 span.line-through { text-decoration: line-through; }
415
416 div.unbreakable { page-break-inside: avoid; }
417
418
419 /*
420 * xhtml11 specific
421 *
422 * */
423
424 div.tableblock {
425 margin-top: 1.0em;
426 margin-bottom: 1.5em;
427 }
428 div.tableblock > table {
429 border: 3px solid #527bbd;
430 }
431 thead, p.table.header {
432 font-weight: bold;
433 color: #527bbd;
434 }
435 p.table {
436 margin-top: 0;
437 }
438 /* Because the table frame attribute is overriden by CSS in most browsers. */
439 div.tableblock > table[frame="void"] {
440 border-style: none;
441 }
442 div.tableblock > table[frame="hsides"] {
443 border-left-style: none;
444 border-right-style: none;
445 }
446 div.tableblock > table[frame="vsides"] {
447 border-top-style: none;
448 border-bottom-style: none;
449 }
450
451
452 /*
453 * html5 specific
454 *
455 * */
456
457 table.tableblock {
458 margin-top: 1.0em;
459 margin-bottom: 1.5em;
460 }
461 thead, p.tableblock.header {
462 font-weight: bold;
463 color: #527bbd;
464 }
465 p.tableblock {
466 margin-top: 0;
467 }
468 table.tableblock {
469 border-width: 3px;
470 border-spacing: 0px;
471 border-style: solid;
472 border-color: #527bbd;
473 border-collapse: collapse;
474 }
475 th.tableblock, td.tableblock {
476 border-width: 1px;
477 padding: 4px;
478 border-style: solid;
479 border-color: #527bbd;
480 }
481
482 table.tableblock.frame-topbot {
483 border-left-style: hidden;
484 border-right-style: hidden;
485 }
486 table.tableblock.frame-sides {
487 border-top-style: hidden;
488 border-bottom-style: hidden;
489 }
490 table.tableblock.frame-none {
491 border-style: hidden;
492 }
493
494 th.tableblock.halign-left, td.tableblock.halign-left {
495 text-align: left;
496 }
497 th.tableblock.halign-center, td.tableblock.halign-center {
498 text-align: center;
499 }
500 th.tableblock.halign-right, td.tableblock.halign-right {
501 text-align: right;
502 }
503
504 th.tableblock.valign-top, td.tableblock.valign-top {
505 vertical-align: top;
506 }
507 th.tableblock.valign-middle, td.tableblock.valign-middle {
508 vertical-align: middle;
509 }
510 th.tableblock.valign-bottom, td.tableblock.valign-bottom {
511 vertical-align: bottom;
512 }
513
514
515 /*
516 * manpage specific
517 *
518 * */
519
520 body.manpage h1 {
521 padding-top: 0.5em;
522 padding-bottom: 0.5em;
523 border-top: 2px solid silver;
524 border-bottom: 2px solid silver;
525 }
526 body.manpage h2 {
527 border-style: none;
528 }
529 body.manpage div.sectionbody {
530 margin-left: 3em;
531 }
532
533 @media print {
534 body.manpage div#toc { display: none; }
535 }
536
537
538 </style>
539 <script type="text/javascript">
540 /*<![CDATA[*/
541 var asciidoc = { // Namespace.
542
543 /////////////////////////////////////////////////////////////////////
544 // Table Of Contents generator
545 /////////////////////////////////////////////////////////////////////
546
547 /* Author: Mihai Bazon, September 2002
548 * http://students.infoiasi.ro/~mishoo
549 *
550 * Table Of Content generator
551 * Version: 0.4
552 *
553 * Feel free to use this script under the terms of the GNU General Public
554 * License, as long as you do not remove or alter this notice.
555 */
556
557 /* modified by Troy D. Hanson, September 2006. License: GPL */
558 /* modified by Stuart Rackham, 2006, 2009. License: GPL */
559
560 // toclevels = 1..4.
561 toc: function (toclevels) {
562
563 function getText(el) {
564 var text = "";
565 for (var i = el.firstChild; i != null; i = i.nextSibling) {
566 if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
567 text += i.data;
568 else if (i.firstChild != null)
569 text += getText(i);
570 }
571 return text;
572 }
573
574 function TocEntry(el, text, toclevel) {
575 this.element = el;
576 this.text = text;
577 this.toclevel = toclevel;
578 }
579
580 function tocEntries(el, toclevels) {
581 var result = new Array;
582 var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
583 // Function that scans the DOM tree for header elements (the DOM2
584 // nodeIterator API would be a better technique but not supported by all
585 // browsers).
586 var iterate = function (el) {
587 for (var i = el.firstChild; i != null; i = i.nextSibling) {
588 if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
589 var mo = re.exec(i.tagName);
590 if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
591 result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
592 }
593 iterate(i);
594 }
595 }
596 }
597 iterate(el);
598 return result;
599 }
600
601 var toc = document.getElementById("toc");
602 if (!toc) {
603 return;
604 }
605
606 // Delete existing TOC entries in case we're reloading the TOC.
607 var tocEntriesToRemove = [];
608 var i;
609 for (i = 0; i < toc.childNodes.length; i++) {
610 var entry = toc.childNodes[i];
611 if (entry.nodeName.toLowerCase() == 'div'
612 && entry.getAttribute("class")
613 && entry.getAttribute("class").match(/^toclevel/))
614 tocEntriesToRemove.push(entry);
615 }
616 for (i = 0; i < tocEntriesToRemove.length; i++) {
617 toc.removeChild(tocEntriesToRemove[i]);
618 }
619
620 // Rebuild TOC entries.
621 var entries = tocEntries(document.getElementById("content"), toclevels);
622 for (var i = 0; i < entries.length; ++i) {
623 var entry = entries[i];
624 if (entry.element.id == "")
625 entry.element.id = "_toc_" + i;
626 var a = document.createElement("a");
627 a.href = "#" + entry.element.id;
628 a.appendChild(document.createTextNode(entry.text));
629 var div = document.createElement("div");
630 div.appendChild(a);
631 div.className = "toclevel" + entry.toclevel;
632 toc.appendChild(div);
633 }
634 if (entries.length == 0)
635 toc.parentNode.removeChild(toc);
636 },
637
638
639 /////////////////////////////////////////////////////////////////////
640 // Footnotes generator
641 /////////////////////////////////////////////////////////////////////
642
643 /* Based on footnote generation code from:
644 * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
645 */
646
647 footnotes: function () {
648 // Delete existing footnote entries in case we're reloading the footnodes.
649 var i;
650 var noteholder = document.getElementById("footnotes");
651 if (!noteholder) {
652 return;
653 }
654 var entriesToRemove = [];
655 for (i = 0; i < noteholder.childNodes.length; i++) {
656 var entry = noteholder.childNodes[i];
657 if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
658 entriesToRemove.push(entry);
659 }
660 for (i = 0; i < entriesToRemove.length; i++) {
661 noteholder.removeChild(entriesToRemove[i]);
662 }
663
664 // Rebuild footnote entries.
665 var cont = document.getElementById("content");
666 var spans = cont.getElementsByTagName("span");
667 var refs = {};
668 var n = 0;
669 for (i=0; i<spans.length; i++) {
670 if (spans[i].className == "footnote") {
671 n++;
672 var note = spans[i].getAttribute("data-note");
673 if (!note) {
674 // Use [\s\S] in place of . so multi-line matches work.
675 // Because JavaScript has no s (dotall) regex flag.
676 note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
677 spans[i].innerHTML =
678 "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
679 "' title='View footnote' class='footnote'>" + n + "</a>]";
680 spans[i].setAttribute("data-note", note);
681 }
682 noteholder.innerHTML +=
683 "<div class='footnote' id='_footnote_" + n + "'>" +
684 "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
685 n + "</a>. " + note + "</div>";
686 var id =spans[i].getAttribute("id");
687 if (id != null) refs["#"+id] = n;
688 }
689 }
690 if (n == 0)
691 noteholder.parentNode.removeChild(noteholder);
692 else {
693 // Process footnoterefs.
694 for (i=0; i<spans.length; i++) {
695 if (spans[i].className == "footnoteref") {
696 var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
697 href = href.match(/#.*/)[0]; // Because IE return full URL.
698 n = refs[href];
699 spans[i].innerHTML =
700 "[<a href='#_footnote_" + n +
701 "' title='View footnote' class='footnote'>" + n + "</a>]";
702 }
703 }
704 }
705 },
706
707 install: function(toclevels) {
708 var timerId;
709
710 function reinstall() {
711 asciidoc.footnotes();
712 if (toclevels) {
713 asciidoc.toc(toclevels);
714 }
715 }
716
717 function reinstallAndRemoveTimer() {
718 clearInterval(timerId);
719 reinstall();
720 }
721
722 timerId = setInterval(reinstall, 500);
723 if (document.addEventListener)
724 document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
725 else
726 window.onload = reinstallAndRemoveTimer;
727 }
728
729 }
730 asciidoc.install(2);
731 /*]]>*/
732 </script>
733 </head>
734 <body class="article">
735 <div id="header">
736 <h1>IPC interface (interprocess communication)</h1>
737 <span id="author">Michael Stapelberg</span><br />
738 <span id="email"><code>&lt;<a href="mailto:[email protected]">[email protected]</a>&gt;</code></span><br />
739 <span id="revdate">September 2017</span>
740 <div id="toc">
741 <div id="toctitle">Table of Contents</div>
742 <noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
743 </div>
744 </div>
745 <div id="content">
746 <div id="preamble">
747 <div class="sectionbody">
748 <div class="paragraph"><p>This document describes how to interface with i3 from a separate process. This
749 is useful for example to remote-control i3 (to write test cases for example) or
750 to get various information like the current workspaces to implement an external
751 workspace bar.</p></div>
752 <div class="paragraph"><p>The method of choice for IPC in our case is a unix socket because it has very
753 little overhead on both sides and is usually available without headaches in
754 most languages. In the default configuration file, the ipc-socket gets created
755 in <code>/tmp/i3-%u.XXXXXX/ipc-socket.%p</code> where <code>%u</code> is your UNIX username, <code>%p</code> is
756 the PID of i3 and XXXXXX is a string of random characters from the portable
757 filename character set (see mkdtemp(3)). You can get the socketpath from i3 by
758 calling <code>i3 --get-socketpath</code>.</p></div>
759 <div class="paragraph"><p>All i3 utilities, like <code>i3-msg</code> and <code>i3-input</code> will read the <code>I3_SOCKET_PATH</code>
760 X11 property, stored on the X11 root window.</p></div>
761 <div class="admonitionblock">
762 <table><tr>
763 <td class="icon">
764 <div class="title">Warning</div>
765 </td>
766 <td class="content">
767 <div class="title">Use an existing library!</div>There are existing libraries for many languages. You can have a look at
768 <a href="#libraries">[libraries]</a> or search the web if your language of choice is not mentioned.
769 Usually, it is not necessary to implement low-level communication with i3
770 directly.</td>
771 </tr></table>
772 </div>
773 </div>
774 </div>
775 <div class="sect1">
776 <h2 id="_establishing_a_connection">1. Establishing a connection</h2>
777 <div class="sectionbody">
778 <div class="paragraph"><p>To establish a connection, simply open the IPC socket. The following code
779 snippet illustrates this in Perl:</p></div>
780 <div class="listingblock">
781 <div class="content">
782 <pre><code>use IO::Socket::UNIX;
783 chomp(my $path = qx(i3 --get-socketpath));
784 my $sock = IO::Socket::UNIX-&gt;new(Peer =&gt; $path);</code></pre>
785 </div></div>
786 </div>
787 </div>
788 <div class="sect1">
789 <h2 id="_sending_messages_to_i3">2. Sending messages to i3</h2>
790 <div class="sectionbody">
791 <div class="paragraph"><p>To send a message to i3, you have to format in the binary message format which
792 i3 expects. This format specifies a magic string in the beginning to ensure
793 the integrity of messages (to prevent follow-up errors). Following the magic
794 string comes the length of the payload of the message as 32-bit integer, and
795 the type of the message as 32-bit integer (the integers are not converted, so
796 they are in native byte order).</p></div>
797 <div class="paragraph"><p>The magic string currently is "i3-ipc" and will only be changed when a change
798 in the IPC API is done which breaks compatibility (we hope that we don’t need
799 to do that).</p></div>
800 <div class="tableblock">
801 <table rules="all"
802 width="100%"
803 frame="border"
804 cellspacing="0" cellpadding="4">
805 <caption class="title">Table 1. Currently implemented message types</caption>
806 <col width="10%" />
807 <col width="20%" />
808 <col width="20%" />
809 <col width="50%" />
810 <thead>
811 <tr>
812 <th align="center" valign="top"> Type (numeric) </th>
813 <th align="center" valign="top"> Type (name) </th>
814 <th align="center" valign="top"> Reply type </th>
815 <th align="center" valign="top"> Purpose</th>
816 </tr>
817 </thead>
818 <tbody>
819 <tr>
820 <td align="center" valign="top"><p class="table">0</p></td>
821 <td align="center" valign="top"><p class="table"><code>RUN_COMMAND</code></p></td>
822 <td align="center" valign="top"><p class="table"><a href="#_command_reply">COMMAND</a></p></td>
823 <td align="center" valign="top"><p class="table">Run the payload as an i3 command (like the commands you can bind to keys).</p></td>
824 </tr>
825 <tr>
826 <td align="center" valign="top"><p class="table">1</p></td>
827 <td align="center" valign="top"><p class="table"><code>GET_WORKSPACES</code></p></td>
828 <td align="center" valign="top"><p class="table"><a href="#_workspaces_reply">WORKSPACES</a></p></td>
829 <td align="center" valign="top"><p class="table">Get the list of current workspaces.</p></td>
830 </tr>
831 <tr>
832 <td align="center" valign="top"><p class="table">2</p></td>
833 <td align="center" valign="top"><p class="table"><code>SUBSCRIBE</code></p></td>
834 <td align="center" valign="top"><p class="table"><a href="#_subscribe_reply">SUBSCRIBE</a></p></td>
835 <td align="center" valign="top"><p class="table">Subscribe this IPC connection to the event types specified in the message payload. See <a href="#events">[events]</a>.</p></td>
836 </tr>
837 <tr>
838 <td align="center" valign="top"><p class="table">3</p></td>
839 <td align="center" valign="top"><p class="table"><code>GET_OUTPUTS</code></p></td>
840 <td align="center" valign="top"><p class="table"><a href="#_outputs_reply">OUTPUTS</a></p></td>
841 <td align="center" valign="top"><p class="table">Get the list of current outputs.</p></td>
842 </tr>
843 <tr>
844 <td align="center" valign="top"><p class="table">4</p></td>
845 <td align="center" valign="top"><p class="table"><code>GET_TREE</code></p></td>
846 <td align="center" valign="top"><p class="table"><a href="#_tree_reply">TREE</a></p></td>
847 <td align="center" valign="top"><p class="table">Get the i3 layout tree.</p></td>
848 </tr>
849 <tr>
850 <td align="center" valign="top"><p class="table">5</p></td>
851 <td align="center" valign="top"><p class="table"><code>GET_MARKS</code></p></td>
852 <td align="center" valign="top"><p class="table"><a href="#_marks_reply">MARKS</a></p></td>
853 <td align="center" valign="top"><p class="table">Gets the names of all currently set marks.</p></td>
854 </tr>
855 <tr>
856 <td align="center" valign="top"><p class="table">6</p></td>
857 <td align="center" valign="top"><p class="table"><code>GET_BAR_CONFIG</code></p></td>
858 <td align="center" valign="top"><p class="table"><a href="#_bar_config_reply">BAR_CONFIG</a></p></td>
859 <td align="center" valign="top"><p class="table">Gets the specified bar configuration or the names of all bar configurations if payload is empty.</p></td>
860 </tr>
861 <tr>
862 <td align="center" valign="top"><p class="table">7</p></td>
863 <td align="center" valign="top"><p class="table"><code>GET_VERSION</code></p></td>
864 <td align="center" valign="top"><p class="table"><a href="#_version_reply">VERSION</a></p></td>
865 <td align="center" valign="top"><p class="table">Gets the i3 version.</p></td>
866 </tr>
867 <tr>
868 <td align="center" valign="top"><p class="table">8</p></td>
869 <td align="center" valign="top"><p class="table"><code>GET_BINDING_MODES</code></p></td>
870 <td align="center" valign="top"><p class="table"><a href="#_binding_modes_reply">BINDING_MODES</a></p></td>
871 <td align="center" valign="top"><p class="table">Gets the names of all currently configured binding modes.</p></td>
872 </tr>
873 <tr>
874 <td align="center" valign="top"><p class="table">9</p></td>
875 <td align="center" valign="top"><p class="table"><code>GET_CONFIG</code></p></td>
876 <td align="center" valign="top"><p class="table"><a href="#_config_reply">CONFIG</a></p></td>
877 <td align="center" valign="top"><p class="table">Returns the last loaded i3 config.</p></td>
878 </tr>
879 <tr>
880 <td align="center" valign="top"><p class="table">10</p></td>
881 <td align="center" valign="top"><p class="table"><code>SEND_TICK</code></p></td>
882 <td align="center" valign="top"><p class="table"><a href="#_tick_reply">TICK</a></p></td>
883 <td align="center" valign="top"><p class="table">Sends a tick event with the specified payload.</p></td>
884 </tr>
885 <tr>
886 <td align="center" valign="top"><p class="table">11</p></td>
887 <td align="center" valign="top"><p class="table"><code>SYNC</code></p></td>
888 <td align="center" valign="top"><p class="table"><a href="#_sync_reply">SYNC</a></p></td>
889 <td align="center" valign="top"><p class="table">Sends an i3 sync event with the specified random value to the specified window.</p></td>
890 </tr>
891 </tbody>
892 </table>
893 </div>
894 <div class="paragraph"><p>So, a typical message could look like this:</p></div>
895 <div class="listingblock">
896 <div class="content">
897 <pre><code>"i3-ipc" &lt;message length&gt; &lt;message type&gt; &lt;payload&gt;</code></pre>
898 </div></div>
899 <div class="paragraph"><p>Or, as a hexdump:</p></div>
900 <div class="listingblock">
901 <div class="content">
902 <pre><code>00000000 69 33 2d 69 70 63 04 00 00 00 00 00 00 00 65 78 |i3-ipc........ex|
903 00000010 69 74 |it|</code></pre>
904 </div></div>
905 <div class="paragraph"><p>To generate and send such a message, you could use the following code in Perl:</p></div>
906 <div class="listingblock">
907 <div class="content">
908 <pre><code>sub format_ipc_command {
909 my ($msg) = @_;
910 my $len;
911 # Get the real byte count (vs. amount of characters)
912 { use bytes; $len = length($msg); }
913 return "i3-ipc" . pack("LL", $len, 0) . $msg;
914 }
915
916 $sock-&gt;write(format_ipc_command("exit"));</code></pre>
917 </div></div>
918 </div>
919 </div>
920 <div class="sect1">
921 <h2 id="_receiving_replies_from_i3">3. Receiving replies from i3</h2>
922 <div class="sectionbody">
923 <div class="paragraph"><p>Replies from i3 usually consist of a simple string (the length of the string
924 is the message_length, so you can consider them length-prefixed) which in turn
925 contain the JSON serialization of a data structure. For example, the
926 GET_WORKSPACES message returns an array of workspaces (each workspace is a map
927 with certain attributes).</p></div>
928 <div class="sect2">
929 <h3 id="_reply_format">3.1. Reply format</h3>
930 <div class="paragraph"><p>The reply format is identical to the normal message format. There also is
931 the magic string, then the message length, then the message type and the
932 payload.</p></div>
933 <div class="paragraph"><p>The following reply types are implemented:</p></div>
934 <div class="dlist"><dl>
935 <dt class="hdlist1">
936 COMMAND (0)
937 </dt>
938 <dd>
939 <p>
940 Confirmation/Error code for the RUN_COMMAND message.
941 </p>
942 </dd>
943 <dt class="hdlist1">
944 WORKSPACES (1)
945 </dt>
946 <dd>
947 <p>
948 Reply to the GET_WORKSPACES message.
949 </p>
950 </dd>
951 <dt class="hdlist1">
952 SUBSCRIBE (2)
953 </dt>
954 <dd>
955 <p>
956 Confirmation/Error code for the SUBSCRIBE message.
957 </p>
958 </dd>
959 <dt class="hdlist1">
960 OUTPUTS (3)
961 </dt>
962 <dd>
963 <p>
964 Reply to the GET_OUTPUTS message.
965 </p>
966 </dd>
967 <dt class="hdlist1">
968 TREE (4)
969 </dt>
970 <dd>
971 <p>
972 Reply to the GET_TREE message.
973 </p>
974 </dd>
975 <dt class="hdlist1">
976 MARKS (5)
977 </dt>
978 <dd>
979 <p>
980 Reply to the GET_MARKS message.
981 </p>
982 </dd>
983 <dt class="hdlist1">
984 BAR_CONFIG (6)
985 </dt>
986 <dd>
987 <p>
988 Reply to the GET_BAR_CONFIG message.
989 </p>
990 </dd>
991 <dt class="hdlist1">
992 VERSION (7)
993 </dt>
994 <dd>
995 <p>
996 Reply to the GET_VERSION message.
997 </p>
998 </dd>
999 <dt class="hdlist1">
1000 BINDING_MODES (8)
1001 </dt>
1002 <dd>
1003 <p>
1004 Reply to the GET_BINDING_MODES message.
1005 </p>
1006 </dd>
1007 <dt class="hdlist1">
1008 GET_CONFIG (9)
1009 </dt>
1010 <dd>
1011 <p>
1012 Reply to the GET_CONFIG message.
1013 </p>
1014 </dd>
1015 <dt class="hdlist1">
1016 TICK (10)
1017 </dt>
1018 <dd>
1019 <p>
1020 Reply to the SEND_TICK message.
1021 </p>
1022 </dd>
1023 </dl></div>
1024 </div>
1025 <div class="sect2">
1026 <h3 id="_command_reply">3.2. COMMAND reply</h3>
1027 <div class="paragraph"><p>The reply consists of a list of serialized maps for each command that was
1028 parsed. Each has the property <code>success (bool)</code> and may also include a
1029 human-readable error message in the property <code>error (string)</code>.</p></div>
1030 <div class="admonitionblock">
1031 <table><tr>
1032 <td class="icon">
1033 <div class="title">Note</div>
1034 </td>
1035 <td class="content">When sending the <code>restart</code> command, you will get a singular reply once the
1036 restart completed. All IPC connection states (e.g. subscriptions) will reset and
1037 all but one socket will be closed. Libraries must be able to cope with this by
1038 aligning their internal states. It is also recommended that libraries close
1039 the last remaining socket(one which replied to <code>restart</code> command) to achieve
1040 the full reset.</td>
1041 </tr></table>
1042 </div>
1043 <div class="admonitionblock">
1044 <table><tr>
1045 <td class="icon">
1046 <div class="title">Note</div>
1047 </td>
1048 <td class="content">It is easiest to always send the <code>restart</code> command alone: due to i3’s
1049 state reset, the reply messages of preceding commands are lost, and following
1050 commands will not be executed.</td>
1051 </tr></table>
1052 </div>
1053 <div class="admonitionblock">
1054 <table><tr>
1055 <td class="icon">
1056 <div class="title">Note</div>
1057 </td>
1058 <td class="content">When processing the <code>exit</code> command, i3 will immediately exit without
1059 sending a reply. Expect the socket to be shut down.</td>
1060 </tr></table>
1061 </div>
1062 <div class="paragraph"><p><strong>Example:</strong></p></div>
1063 <div class="listingblock">
1064 <div class="content">
1065 <pre><code>[{ "success": true }]</code></pre>
1066 </div></div>
1067 </div>
1068 <div class="sect2">
1069 <h3 id="_workspaces_reply">3.3. WORKSPACES reply</h3>
1070 <div class="paragraph"><p>The reply consists of a serialized list of workspaces. Each workspace has the
1071 following properties:</p></div>
1072 <div class="dlist"><dl>
1073 <dt class="hdlist1">
1074 num (integer)
1075 </dt>
1076 <dd>
1077 <p>
1078 The logical number of the workspace. Corresponds to the command
1079 to switch to this workspace. For named workspaces, this will be -1.
1080 </p>
1081 </dd>
1082 <dt class="hdlist1">
1083 name (string)
1084 </dt>
1085 <dd>
1086 <p>
1087 The name of this workspace (by default num+1), as changed by the
1088 user. Encoded in UTF-8.
1089 </p>
1090 </dd>
1091 <dt class="hdlist1">
1092 visible (boolean)
1093 </dt>
1094 <dd>
1095 <p>
1096 Whether this workspace is currently visible on an output (multiple
1097 workspaces can be visible at the same time).
1098 </p>
1099 </dd>
1100 <dt class="hdlist1">
1101 focused (boolean)
1102 </dt>
1103 <dd>
1104 <p>
1105 Whether this workspace currently has the focus (only one workspace
1106 can have the focus at the same time).
1107 </p>
1108 </dd>
1109 <dt class="hdlist1">
1110 urgent (boolean)
1111 </dt>
1112 <dd>
1113 <p>
1114 Whether a window on this workspace has the "urgent" flag set.
1115 </p>
1116 </dd>
1117 <dt class="hdlist1">
1118 rect (map)
1119 </dt>
1120 <dd>
1121 <p>
1122 The rectangle of this workspace (equals the rect of the output it
1123 is on), consists of x, y, width, height.
1124 </p>
1125 </dd>
1126 <dt class="hdlist1">
1127 output (string)
1128 </dt>
1129 <dd>
1130 <p>
1131 The video output this workspace is on (LVDS1, VGA1, …).
1132 </p>
1133 </dd>
1134 </dl></div>
1135 <div class="paragraph"><p><strong>Example:</strong></p></div>
1136 <div class="listingblock">
1137 <div class="content">
1138 <pre><code>[
1139 {
1140 "num": 0,
1141 "name": "1",
1142 "visible": true,
1143 "focused": true,
1144 "urgent": false,
1145 "rect": {
1146 "x": 0,
1147 "y": 0,
1148 "width": 1280,
1149 "height": 800
1150 },
1151 "output": "LVDS1"
1152 },
1153 {
1154 "num": 1,
1155 "name": "2",
1156 "visible": false,
1157 "focused": false,
1158 "urgent": false,
1159 "rect": {
1160 "x": 0,
1161 "y": 0,
1162 "width": 1280,
1163 "height": 800
1164 },
1165 "output": "LVDS1"
1166 }
1167 ]</code></pre>
1168 </div></div>
1169 </div>
1170 <div class="sect2">
1171 <h3 id="_subscribe_reply">3.4. SUBSCRIBE reply</h3>
1172 <div class="paragraph"><p>The reply consists of a single serialized map. The only property is
1173 <code>success (bool)</code>, indicating whether the subscription was successful (the
1174 default) or whether a JSON parse error occurred.</p></div>
1175 <div class="paragraph"><p><strong>Example:</strong></p></div>
1176 <div class="listingblock">
1177 <div class="content">
1178 <pre><code>{ "success": true }</code></pre>
1179 </div></div>
1180 </div>
1181 <div class="sect2">
1182 <h3 id="_outputs_reply">3.5. OUTPUTS reply</h3>
1183 <div class="paragraph"><p>The reply consists of a serialized list of outputs. Each output has the
1184 following properties:</p></div>
1185 <div class="dlist"><dl>
1186 <dt class="hdlist1">
1187 name (string)
1188 </dt>
1189 <dd>
1190 <p>
1191 The name of this output (as seen in <code>xrandr(1)</code>). Encoded in UTF-8.
1192 </p>
1193 </dd>
1194 <dt class="hdlist1">
1195 active (boolean)
1196 </dt>
1197 <dd>
1198 <p>
1199 Whether this output is currently active (has a valid mode).
1200 </p>
1201 </dd>
1202 <dt class="hdlist1">
1203 primary (boolean)
1204 </dt>
1205 <dd>
1206 <p>
1207 Whether this output is currently the primary output.
1208 </p>
1209 </dd>
1210 <dt class="hdlist1">
1211 current_workspace (string)
1212 </dt>
1213 <dd>
1214 <p>
1215 The name of the current workspace that is visible on this output. <code>null</code> if
1216 the output is not active.
1217 </p>
1218 </dd>
1219 <dt class="hdlist1">
1220 rect (map)
1221 </dt>
1222 <dd>
1223 <p>
1224 The rectangle of this output (equals the rect of the output it
1225 is on), consists of x, y, width, height.
1226 </p>
1227 </dd>
1228 </dl></div>
1229 <div class="paragraph"><p><strong>Example:</strong></p></div>
1230 <div class="listingblock">
1231 <div class="content">
1232 <pre><code>[
1233 {
1234 "name": "LVDS1",
1235 "active": true,
1236 "current_workspace": "4",
1237 "rect": {
1238 "x": 0,
1239 "y": 0,
1240 "width": 1280,
1241 "height": 800
1242 }
1243 },
1244 {
1245 "name": "VGA1",
1246 "active": true,
1247 "current_workspace": "1",
1248 "rect": {
1249 "x": 1280,
1250 "y": 0,
1251 "width": 1280,
1252 "height": 1024
1253 }
1254 }
1255 ]</code></pre>
1256 </div></div>
1257 </div>
1258 <div class="sect2">
1259 <h3 id="_tree_reply">3.6. TREE reply</h3>
1260 <div class="paragraph"><p>The reply consists of a serialized tree. Each node in the tree (representing
1261 one container) has at least the properties listed below. While the nodes might
1262 have more properties, please do not use any properties which are not documented
1263 here. They are not yet finalized and will probably change!</p></div>
1264 <div class="dlist"><dl>
1265 <dt class="hdlist1">
1266 id (integer)
1267 </dt>
1268 <dd>
1269 <p>
1270 The internal ID (actually a C pointer value) of this container. Do not
1271 make any assumptions about it. You can use it to (re-)identify and
1272 address containers when talking to i3.
1273 </p>
1274 </dd>
1275 <dt class="hdlist1">
1276 name (string)
1277 </dt>
1278 <dd>
1279 <p>
1280 The internal name of this container. For all containers which are part
1281 of the tree structure down to the workspace contents, this is set to a
1282 nice human-readable name of the container.
1283 For containers that have an X11 window, the content is the title
1284 (_NET_WM_NAME property) of that window.
1285 For all other containers, the content is not defined (yet).
1286 </p>
1287 </dd>
1288 <dt class="hdlist1">
1289 type (string)
1290 </dt>
1291 <dd>
1292 <p>
1293 Type of this container. Can be one of "root", "output", "con",
1294 "floating_con", "workspace" or "dockarea".
1295 </p>
1296 </dd>
1297 <dt class="hdlist1">
1298 border (string)
1299 </dt>
1300 <dd>
1301 <p>
1302 Can be either "normal", "none" or "pixel", depending on the
1303 container’s border style.
1304 </p>
1305 </dd>
1306 <dt class="hdlist1">
1307 current_border_width (integer)
1308 </dt>
1309 <dd>
1310 <p>
1311 Number of pixels of the border width.
1312 </p>
1313 </dd>
1314 <dt class="hdlist1">
1315 layout (string)
1316 </dt>
1317 <dd>
1318 <p>
1319 Can be either "splith", "splitv", "stacked", "tabbed", "dockarea" or
1320 "output".
1321 Other values might be possible in the future, should we add new
1322 layouts.
1323 </p>
1324 </dd>
1325 <dt class="hdlist1">
1326 orientation (string)
1327 </dt>
1328 <dd>
1329 <p>
1330 Can be either "none" (for non-split containers), "horizontal" or
1331 "vertical".
1332 THIS FIELD IS OBSOLETE. It is still present, but your code should not
1333 use it. Instead, rely on the layout field.
1334 </p>
1335 </dd>
1336 <dt class="hdlist1">
1337 percent (float)
1338 </dt>
1339 <dd>
1340 <p>
1341 The percentage which this container takes in its parent. A value of
1342 <code>null</code> means that the percent property does not make sense for this
1343 container, for example for the root container.
1344 </p>
1345 </dd>
1346 <dt class="hdlist1">
1347 rect (map)
1348 </dt>
1349 <dd>
1350 <p>
1351 The absolute display coordinates for this container. Display
1352 coordinates means that when you have two 1600x1200 monitors on a single
1353 X11 Display (the standard way), the coordinates of the first window on
1354 the second monitor are <code>{ "x": 1600, "y": 0, "width": 1600, "height":
1355 1200 }</code>.
1356 </p>
1357 </dd>
1358 <dt class="hdlist1">
1359 window_rect (map)
1360 </dt>
1361 <dd>
1362 <p>
1363 The coordinates of the <strong>actual client window</strong> inside its container.
1364 These coordinates are relative to the container and do not include the
1365 window decoration (which is actually rendered on the parent container).
1366 So, when using the <code>default</code> layout, you will have a 2 pixel border on
1367 each side, making the window_rect <code>{ "x": 2, "y": 0, "width": 632,
1368 "height": 366 }</code> (for example).
1369 </p>
1370 </dd>
1371 <dt class="hdlist1">
1372 deco_rect (map)
1373 </dt>
1374 <dd>
1375 <p>
1376 The coordinates of the <strong>window decoration</strong> inside its container. These
1377 coordinates are relative to the container and do not include the actual
1378 client window.
1379 </p>
1380 </dd>
1381 <dt class="hdlist1">
1382 geometry (map)
1383 </dt>
1384 <dd>
1385 <p>
1386 The original geometry the window specified when i3 mapped it. Used when
1387 switching a window to floating mode, for example.
1388 </p>
1389 </dd>
1390 <dt class="hdlist1">
1391 window (integer)
1392 </dt>
1393 <dd>
1394 <p>
1395 The X11 window ID of the <strong>actual client window</strong> inside this container.
1396 This field is set to null for split containers or otherwise empty
1397 containers. This ID corresponds to what xwininfo(1) and other
1398 X11-related tools display (usually in hex).
1399 </p>
1400 </dd>
1401 <dt class="hdlist1">
1402 window_properties (map)
1403 </dt>
1404 <dd>
1405 <p>
1406 X11 window properties title, instance, class, window_role and transient_for.
1407 </p>
1408 </dd>
1409 <dt class="hdlist1">
1410 urgent (bool)
1411 </dt>
1412 <dd>
1413 <p>
1414 Whether this container (window, split container, floating container or
1415 workspace) has the urgency hint set, directly or indirectly. All parent
1416 containers up until the workspace container will be marked urgent if they
1417 have at least one urgent child.
1418 </p>
1419 </dd>
1420 <dt class="hdlist1">
1421 focused (bool)
1422 </dt>
1423 <dd>
1424 <p>
1425 Whether this container is currently focused.
1426 </p>
1427 </dd>
1428 <dt class="hdlist1">
1429 focus (array of integer)
1430 </dt>
1431 <dd>
1432 <p>
1433 List of child node IDs (see <code>nodes</code>, <code>floating_nodes</code> and <code>id</code>) in focus
1434 order. Traversing the tree by following the first entry in this array
1435 will result in eventually reaching the one node with <code>focused</code> set to
1436 true.
1437 </p>
1438 </dd>
1439 <dt class="hdlist1">
1440 nodes (array of node)
1441 </dt>
1442 <dd>
1443 <p>
1444 The tiling (i.e. non-floating) child containers of this node.
1445 </p>
1446 </dd>
1447 <dt class="hdlist1">
1448 floating_nodes (array of node)
1449 </dt>
1450 <dd>
1451 <p>
1452 The floating child containers of this node. Only non-empty on nodes with
1453 type <code>workspace</code>.
1454 </p>
1455 </dd>
1456 </dl></div>
1457 <div class="paragraph"><p>Please note that in the following example, I have left out some keys/values
1458 which are not relevant for the type of the node. Otherwise, the example would
1459 be by far too long (it already is quite long, despite showing only 1 window and
1460 one dock window).</p></div>
1461 <div class="paragraph"><p>It is useful to have an overview of the structure before taking a look at the
1462 JSON dump:</p></div>
1463 <div class="ulist"><ul>
1464 <li>
1465 <p>
1466 root
1467 </p>
1468 <div class="ulist"><ul>
1469 <li>
1470 <p>
1471 LVDS1
1472 </p>
1473 <div class="ulist"><ul>
1474 <li>
1475 <p>
1476 topdock
1477 </p>
1478 </li>
1479 <li>
1480 <p>
1481 content
1482 </p>
1483 <div class="ulist"><ul>
1484 <li>
1485 <p>
1486 workspace 1
1487 </p>
1488 <div class="ulist"><ul>
1489 <li>
1490 <p>
1491 window 1
1492 </p>
1493 </li>
1494 </ul></div>
1495 </li>
1496 </ul></div>
1497 </li>
1498 <li>
1499 <p>
1500 bottomdock
1501 </p>
1502 <div class="ulist"><ul>
1503 <li>
1504 <p>
1505 dock window 1
1506 </p>
1507 </li>
1508 </ul></div>
1509 </li>
1510 </ul></div>
1511 </li>
1512 <li>
1513 <p>
1514 VGA1
1515 </p>
1516 </li>
1517 </ul></div>
1518 </li>
1519 </ul></div>
1520 <div class="paragraph"><p><strong>Example:</strong></p></div>
1521 <div class="listingblock">
1522 <div class="content">
1523 <pre><code>{
1524 "id": 6875648,
1525 "name": "root",
1526 "rect": {
1527 "x": 0,
1528 "y": 0,
1529 "width": 1280,
1530 "height": 800
1531 },
1532 "nodes": [
1533
1534 {
1535 "id": 6878320,
1536 "name": "LVDS1",
1537 "layout": "output",
1538 "rect": {
1539 "x": 0,
1540 "y": 0,
1541 "width": 1280,
1542 "height": 800
1543 },
1544 "nodes": [
1545
1546 {
1547 "id": 6878784,
1548 "name": "topdock",
1549 "layout": "dockarea",
1550 "orientation": "vertical",
1551 "rect": {
1552 "x": 0,
1553 "y": 0,
1554 "width": 1280,
1555 "height": 0
1556 }
1557 },
1558
1559 {
1560 "id": 6879344,
1561 "name": "content",
1562 "rect": {
1563 "x": 0,
1564 "y": 0,
1565 "width": 1280,
1566 "height": 782
1567 },
1568 "nodes": [
1569
1570 {
1571 "id": 6880464,
1572 "name": "1",
1573 "orientation": "horizontal",
1574 "rect": {
1575 "x": 0,
1576 "y": 0,
1577 "width": 1280,
1578 "height": 782
1579 },
1580 "window_properties": {
1581 "class": "Evince",
1582 "instance": "evince",
1583 "title": "Properties",
1584 "transient_for": 52428808
1585 },
1586 "floating_nodes": [],
1587 "nodes": [
1588
1589 {
1590 "id": 6929968,
1591 "name": "#aa0000",
1592 "border": "normal",
1593 "percent": 1,
1594 "rect": {
1595 "x": 0,
1596 "y": 18,
1597 "width": 1280,
1598 "height": 782
1599 }
1600 }
1601
1602 ]
1603 }
1604
1605 ]
1606 },
1607
1608 {
1609 "id": 6880208,
1610 "name": "bottomdock",
1611 "layout": "dockarea",
1612 "orientation": "vertical",
1613 "rect": {
1614 "x": 0,
1615 "y": 782,
1616 "width": 1280,
1617 "height": 18
1618 },
1619 "nodes": [
1620
1621 {
1622 "id": 6931312,
1623 "name": "#00aa00",
1624 "percent": 1,
1625 "rect": {
1626 "x": 0,
1627 "y": 782,
1628 "width": 1280,
1629 "height": 18
1630 }
1631 }
1632
1633 ]
1634 }
1635 ]
1636 }
1637 ]
1638 }</code></pre>
1639 </div></div>
1640 </div>
1641 <div class="sect2">
1642 <h3 id="_marks_reply">3.7. MARKS reply</h3>
1643 <div class="paragraph"><p>The reply consists of a single array of strings for each container that has a
1644 mark. A mark can only be set on one container, so the array is unique.
1645 The order of that array is undefined.</p></div>
1646 <div class="paragraph"><p>If no window has a mark the response will be the empty array [].</p></div>
1647 </div>
1648 <div class="sect2">
1649 <h3 id="_bar_config_reply">3.8. BAR_CONFIG reply</h3>
1650 <div class="paragraph"><p>This can be used by third-party workspace bars (especially i3bar, but others
1651 are free to implement compatible alternatives) to get the <code>bar</code> block
1652 configuration from i3.</p></div>
1653 <div class="paragraph"><p>Depending on the input, the reply is either:</p></div>
1654 <div class="dlist"><dl>
1655 <dt class="hdlist1">
1656 empty input
1657 </dt>
1658 <dd>
1659 <p>
1660 An array of configured bar IDs
1661 </p>
1662 </dd>
1663 <dt class="hdlist1">
1664 Bar ID
1665 </dt>
1666 <dd>
1667 <p>
1668 A JSON map containing the configuration for the specified bar.
1669 </p>
1670 </dd>
1671 </dl></div>
1672 <div class="paragraph"><p>Each bar configuration has the following properties:</p></div>
1673 <div class="dlist"><dl>
1674 <dt class="hdlist1">
1675 id (string)
1676 </dt>
1677 <dd>
1678 <p>
1679 The ID for this bar. Included in case you request multiple
1680 configurations and want to differentiate the different replies.
1681 </p>
1682 </dd>
1683 <dt class="hdlist1">
1684 mode (string)
1685 </dt>
1686 <dd>
1687 <p>
1688 Either <code>dock</code> (the bar sets the dock window type) or <code>hide</code> (the bar
1689 does not show unless a specific key is pressed).
1690 </p>
1691 </dd>
1692 <dt class="hdlist1">
1693 position (string)
1694 </dt>
1695 <dd>
1696 <p>
1697 Either <code>bottom</code> or <code>top</code> at the moment.
1698 </p>
1699 </dd>
1700 <dt class="hdlist1">
1701 status_command (string)
1702 </dt>
1703 <dd>
1704 <p>
1705 Command which will be run to generate a statusline. Each line on stdout
1706 of this command will be displayed in the bar. At the moment, no
1707 formatting is supported.
1708 </p>
1709 </dd>
1710 <dt class="hdlist1">
1711 font (string)
1712 </dt>
1713 <dd>
1714 <p>
1715 The font to use for text on the bar.
1716 </p>
1717 </dd>
1718 <dt class="hdlist1">
1719 workspace_buttons (boolean)
1720 </dt>
1721 <dd>
1722 <p>
1723 Display workspace buttons or not? Defaults to true.
1724 </p>
1725 </dd>
1726 <dt class="hdlist1">
1727 binding_mode_indicator (boolean)
1728 </dt>
1729 <dd>
1730 <p>
1731 Display the mode indicator or not? Defaults to true.
1732 </p>
1733 </dd>
1734 <dt class="hdlist1">
1735 verbose (boolean)
1736 </dt>
1737 <dd>
1738 <p>
1739 Should the bar enable verbose output for debugging? Defaults to false.
1740 </p>
1741 </dd>
1742 <dt class="hdlist1">
1743 colors (map)
1744 </dt>
1745 <dd>
1746 <p>
1747 Contains key/value pairs of colors. Each value is a color code in hex,
1748 formatted #rrggbb (like in HTML).
1749 </p>
1750 </dd>
1751 </dl></div>
1752 <div class="paragraph"><p>The following colors can be configured at the moment:</p></div>
1753 <div class="dlist"><dl>
1754 <dt class="hdlist1">
1755 background
1756 </dt>
1757 <dd>
1758 <p>
1759 Background color of the bar.
1760 </p>
1761 </dd>
1762 <dt class="hdlist1">
1763 statusline
1764 </dt>
1765 <dd>
1766 <p>
1767 Text color to be used for the statusline.
1768 </p>
1769 </dd>
1770 <dt class="hdlist1">
1771 separator
1772 </dt>
1773 <dd>
1774 <p>
1775 Text color to be used for the separator.
1776 </p>
1777 </dd>
1778 <dt class="hdlist1">
1779 focused_background
1780 </dt>
1781 <dd>
1782 <p>
1783 Background color of the bar on the currently focused monitor output.
1784 </p>
1785 </dd>
1786 <dt class="hdlist1">
1787 focused_statusline
1788 </dt>
1789 <dd>
1790 <p>
1791 Text color to be used for the statusline on the currently focused
1792 monitor output.
1793 </p>
1794 </dd>
1795 <dt class="hdlist1">
1796 focused_separator
1797 </dt>
1798 <dd>
1799 <p>
1800 Text color to be used for the separator on the currently focused
1801 monitor output.
1802 </p>
1803 </dd>
1804 <dt class="hdlist1">
1805 focused_workspace_text/focused_workspace_bg/focused_workspace_border
1806 </dt>
1807 <dd>
1808 <p>
1809 Text/background/border color for a workspace button when the workspace
1810 has focus.
1811 </p>
1812 </dd>
1813 <dt class="hdlist1">
1814 active_workspace_text/active_workspace_bg/active_workspace_border
1815 </dt>
1816 <dd>
1817 <p>
1818 Text/background/border color for a workspace button when the workspace
1819 is active (visible) on some output, but the focus is on another one.
1820 You can only tell this apart from the focused workspace when you are
1821 using multiple monitors.
1822 </p>
1823 </dd>
1824 <dt class="hdlist1">
1825 inactive_workspace_text/inactive_workspace_bg/inactive_workspace_border
1826 </dt>
1827 <dd>
1828 <p>
1829 Text/background/border color for a workspace button when the workspace
1830 does not have focus and is not active (visible) on any output. This
1831 will be the case for most workspaces.
1832 </p>
1833 </dd>
1834 <dt class="hdlist1">
1835 urgent_workspace_text/urgent_workspace_bg/urgent_workspace_border
1836 </dt>
1837 <dd>
1838 <p>
1839 Text/background/border color for workspaces which contain at least one
1840 window with the urgency hint set.
1841 </p>
1842 </dd>
1843 <dt class="hdlist1">
1844 binding_mode_text/binding_mode_bg/binding_mode_border
1845 </dt>
1846 <dd>
1847 <p>
1848 Text/background/border color for the binding mode indicator.
1849 </p>
1850 </dd>
1851 </dl></div>
1852 <div class="paragraph"><p><strong>Example of configured bars:</strong></p></div>
1853 <div class="listingblock">
1854 <div class="content">
1855 <pre><code>["bar-bxuqzf"]</code></pre>
1856 </div></div>
1857 <div class="paragraph"><p><strong>Example of bar configuration:</strong></p></div>
1858 <div class="listingblock">
1859 <div class="content">
1860 <pre><code>{
1861 "id": "bar-bxuqzf",
1862 "mode": "dock",
1863 "position": "bottom",
1864 "status_command": "i3status",
1865 "font": "-misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1",
1866 "workspace_buttons": true,
1867 "binding_mode_indicator": true,
1868 "verbose": false,
1869 "colors": {
1870 "background": "#c0c0c0",
1871 "statusline": "#00ff00",
1872 "focused_workspace_text": "#ffffff",
1873 "focused_workspace_bg": "#000000"
1874 }
1875 }</code></pre>
1876 </div></div>
1877 </div>
1878 <div class="sect2">
1879 <h3 id="_version_reply">3.9. VERSION reply</h3>
1880 <div class="paragraph"><p>The reply consists of a single JSON dictionary with the following keys:</p></div>
1881 <div class="dlist"><dl>
1882 <dt class="hdlist1">
1883 major (integer)
1884 </dt>
1885 <dd>
1886 <p>
1887 The major version of i3, such as <code>4</code>.
1888 </p>
1889 </dd>
1890 <dt class="hdlist1">
1891 minor (integer)
1892 </dt>
1893 <dd>
1894 <p>
1895 The minor version of i3, such as <code>2</code>. Changes in the IPC interface (new
1896 features) will only occur with new minor (or major) releases. However,
1897 bugfixes might be introduced in patch releases, too.
1898 </p>
1899 </dd>
1900 <dt class="hdlist1">
1901 patch (integer)
1902 </dt>
1903 <dd>
1904 <p>
1905 The patch version of i3, such as <code>1</code> (when the complete version is
1906 <code>4.2.1</code>). For versions such as <code>4.2</code>, patch will be set to <code>0</code>.
1907 </p>
1908 </dd>
1909 <dt class="hdlist1">
1910 human_readable (string)
1911 </dt>
1912 <dd>
1913 <p>
1914 A human-readable version of i3 containing the precise git version,
1915 build date and branch name. When you need to display the i3 version to
1916 your users, use the human-readable version whenever possible (since
1917 this is what <code>i3 --version</code> displays, too).
1918 </p>
1919 </dd>
1920 <dt class="hdlist1">
1921 loaded_config_file_name (string)
1922 </dt>
1923 <dd>
1924 <p>
1925 The current config path.
1926 </p>
1927 </dd>
1928 </dl></div>
1929 <div class="paragraph"><p><strong>Example:</strong></p></div>
1930 <div class="listingblock">
1931 <div class="content">
1932 <pre><code>{
1933 "human_readable" : "4.2-169-gf80b877 (2012-08-05, branch \"next\")",
1934 "loaded_config_file_name" : "/home/hwangcc23/.i3/config",
1935 "minor" : 2,
1936 "patch" : 0,
1937 "major" : 4
1938 }</code></pre>
1939 </div></div>
1940 </div>
1941 <div class="sect2">
1942 <h3 id="_binding_modes_reply">3.10. BINDING_MODES reply</h3>
1943 <div class="paragraph"><p>The reply consists of an array of all currently configured binding modes.</p></div>
1944 <div class="paragraph"><p><strong>Example:</strong></p></div>
1945 <div class="listingblock">
1946 <div class="content">
1947 <pre><code>["default", "resize"]</code></pre>
1948 </div></div>
1949 </div>
1950 <div class="sect2">
1951 <h3 id="_config_reply">3.11. CONFIG reply</h3>
1952 <div class="paragraph"><p>The config reply is a map which currently only contains the "config" member,
1953 which is a string containing the config file as loaded by i3 most recently.</p></div>
1954 <div class="paragraph"><p><strong>Example:</strong></p></div>
1955 <div class="listingblock">
1956 <div class="content">
1957 <pre><code>{ "config": "font pango:monospace 8\nbindsym Mod4+q exit\n" }</code></pre>
1958 </div></div>
1959 </div>
1960 <div class="sect2">
1961 <h3 id="_tick_reply">3.12. TICK reply</h3>
1962 <div class="paragraph"><p>The reply is a map containing the "success" member. After the reply was
1963 received, the tick event has been written to all IPC connections which subscribe
1964 to tick events. UNIX sockets are usually buffered, but you can be certain that
1965 once you receive the tick event you just triggered, you must have received all
1966 events generated prior to the <code>SEND_TICK</code> message (happened-before relation).</p></div>
1967 <div class="paragraph"><p><strong>Example:</strong></p></div>
1968 <div class="listingblock">
1969 <div class="content">
1970 <pre><code>{ "success": true }</code></pre>
1971 </div></div>
1972 </div>
1973 <div class="sect2">
1974 <h3 id="_sync_reply">3.13. SYNC reply</h3>
1975 <div class="paragraph"><p>The reply is a map containing the "success" member. After the reply was
1976 received, the <a href="https://i3wm.org/docs/testsuite.html#i3_sync">i3 sync message</a> was
1977 responded to.</p></div>
1978 <div class="paragraph"><p><strong>Example:</strong></p></div>
1979 <div class="listingblock">
1980 <div class="content">
1981 <pre><code>{ "success": true }</code></pre>
1982 </div></div>
1983 </div>
1984 </div>
1985 </div>
1986 <div class="sect1">
1987 <h2 id="_events">4. Events</h2>
1988 <div class="sectionbody">
1989 <div class="paragraph" id="events"><p>To get informed when certain things happen in i3, clients can subscribe to
1990 events. Events consist of a name (like "workspace") and an event reply type
1991 (like I3_IPC_EVENT_WORKSPACE). Events sent by i3 follow a format similar to
1992 replies but with the highest bit of the message type set to 1 to indicate an
1993 event reply instead of a normal reply. Note that event types and reply types
1994 do not follow the same enumeration scheme (e.g. event type 0 corresponds to the
1995 workspace event however reply type 0 corresponds to the COMMAND reply).</p></div>
1996 <div class="paragraph"><p>Caveat: As soon as you subscribe to an event, it is not guaranteed any longer
1997 that the requests to i3 are processed in order. This means, the following
1998 situation can happen: You send a GET_WORKSPACES request but you receive a
1999 "workspace" event before receiving the reply to GET_WORKSPACES. If your
2000 program does not want to cope which such kinds of race conditions (an
2001 event based library may not have a problem here), I suggest you create a
2002 separate connection to receive events.</p></div>
2003 <div class="paragraph"><p>If an event message needs to be sent and the socket is not writeable (write
2004 returns EAGAIN, happens when the socket doesn&#8217;t have enough buffer space for
2005 writing new data) then i3 uses a queue system to store outgoing messages for
2006 each client. This is combined with a timer: if the message queue for a client is
2007 not empty and no data where successfully written in the past 10 seconds, the
2008 connection is killed. Practically, this means that your client should try to
2009 always read events from the socket to avoid having its connection closed.</p></div>
2010 <div class="sect2">
2011 <h3 id="_subscribing_to_events">4.1. Subscribing to events</h3>
2012 <div class="paragraph"><p>By sending a message of type SUBSCRIBE with a JSON-encoded array as payload
2013 you can register to an event.</p></div>
2014 <div class="paragraph"><p><strong>Example:</strong></p></div>
2015 <div class="listingblock">
2016 <div class="content">
2017 <pre><code>type: SUBSCRIBE
2018 payload: [ "workspace", "output" ]</code></pre>
2019 </div></div>
2020 </div>
2021 <div class="sect2">
2022 <h3 id="_available_events">4.2. Available events</h3>
2023 <div class="paragraph"><p>The numbers in parenthesis is the event type (keep in mind that you need to
2024 strip the highest bit first).</p></div>
2025 <div class="dlist"><dl>
2026 <dt class="hdlist1">
2027 workspace (0)
2028 </dt>
2029 <dd>
2030 <p>
2031 Sent when the user switches to a different workspace, when a new
2032 workspace is initialized or when a workspace is removed (because the
2033 last client vanished).
2034 </p>
2035 </dd>
2036 <dt class="hdlist1">
2037 output (1)
2038 </dt>
2039 <dd>
2040 <p>
2041 Sent when RandR issues a change notification (of either screens,
2042 outputs, CRTCs or output properties).
2043 </p>
2044 </dd>
2045 <dt class="hdlist1">
2046 mode (2)
2047 </dt>
2048 <dd>
2049 <p>
2050 Sent whenever i3 changes its binding mode.
2051 </p>
2052 </dd>
2053 <dt class="hdlist1">
2054 window (3)
2055 </dt>
2056 <dd>
2057 <p>
2058 Sent when a client&#8217;s window is successfully reparented (that is when i3
2059 has finished fitting it into a container), when a window received input
2060 focus or when certain properties of the window have changed.
2061 </p>
2062 </dd>
2063 <dt class="hdlist1">
2064 barconfig_update (4)
2065 </dt>
2066 <dd>
2067 <p>
2068 Sent when the hidden_state or mode field in the barconfig of any bar
2069 instance was updated and when the config is reloaded.
2070 </p>
2071 </dd>
2072 <dt class="hdlist1">
2073 binding (5)
2074 </dt>
2075 <dd>
2076 <p>
2077 Sent when a configured command binding is triggered with the keyboard or
2078 mouse
2079 </p>
2080 </dd>
2081 <dt class="hdlist1">
2082 shutdown (6)
2083 </dt>
2084 <dd>
2085 <p>
2086 Sent when the ipc shuts down because of a restart or exit by user command
2087 </p>
2088 </dd>
2089 <dt class="hdlist1">
2090 tick (7)
2091 </dt>
2092 <dd>
2093 <p>
2094 Sent when the ipc client subscribes to the tick event (with <code>"first":
2095 true</code>) or when any ipc client sends a SEND_TICK message (with <code>"first":
2096 false</code>).
2097 </p>
2098 </dd>
2099 </dl></div>
2100 <div class="paragraph"><p><strong>Example:</strong></p></div>
2101 <div class="listingblock">
2102 <div class="content">
2103 <pre><code># the appropriate 4 bytes read from the socket are stored in $input
2104
2105 # unpack a 32-bit unsigned integer
2106 my $message_type = unpack("L", $input);
2107
2108 # check if the highest bit is 1
2109 my $is_event = (($message_type &gt;&gt; 31) == 1);
2110
2111 # use the other bits
2112 my $event_type = ($message_type &amp; 0x7F);
2113
2114 if ($is_event) {
2115 say "Received event of type $event_type";
2116 }</code></pre>
2117 </div></div>
2118 </div>
2119 <div class="sect2">
2120 <h3 id="_workspace_event">4.3. workspace event</h3>
2121 <div class="paragraph"><p>This event consists of a single serialized map containing a property
2122 <code>change (string)</code> which indicates the type of the change ("focus", "init",
2123 "empty", "urgent", "reload", "rename", "restored", "move"). A
2124 <code>current (object)</code> property will be present with the affected workspace
2125 whenever the type of event affects a workspace (otherwise, it will be <code>null</code>).</p></div>
2126 <div class="paragraph"><p>When the change is "focus", an <code>old (object)</code> property will be present with the
2127 previous workspace. When the first switch occurs (when i3 focuses the
2128 workspace visible at the beginning) there is no previous workspace, and the
2129 <code>old</code> property will be set to <code>null</code>. Also note that if the previous is empty
2130 it will get destroyed when switching, but will still be present in the "old"
2131 property.</p></div>
2132 <div class="paragraph"><p><strong>Example:</strong></p></div>
2133 <div class="listingblock">
2134 <div class="content">
2135 <pre><code>{
2136 "change": "focus",
2137 "current": {
2138 "id": 28489712,
2139 "type": "workspace",
2140 ...
2141 }
2142 "old": {
2143 "id": 28489715,
2144 "type": "workspace",
2145 ...
2146 }
2147 }</code></pre>
2148 </div></div>
2149 </div>
2150 <div class="sect2">
2151 <h3 id="_output_event">4.4. output event</h3>
2152 <div class="paragraph"><p>This event consists of a single serialized map containing a property
2153 <code>change (string)</code> which indicates the type of the change (currently only
2154 "unspecified").</p></div>
2155 <div class="paragraph"><p><strong>Example:</strong></p></div>
2156 <div class="listingblock">
2157 <div class="content">
2158 <pre><code>{ "change": "unspecified" }</code></pre>
2159 </div></div>
2160 </div>
2161 <div class="sect2">
2162 <h3 id="_mode_event">4.5. mode event</h3>
2163 <div class="paragraph"><p>This event consists of a single serialized map containing a property
2164 <code>change (string)</code> which holds the name of current mode in use. The name
2165 is the same as specified in config when creating a mode. The default
2166 mode is simply named default. It contains a second property, <code>pango_markup</code>, which
2167 defines whether pango markup shall be used for displaying this mode.</p></div>
2168 <div class="paragraph"><p><strong>Example:</strong></p></div>
2169 <div class="listingblock">
2170 <div class="content">
2171 <pre><code>{
2172 "change": "default",
2173 "pango_markup": true
2174 }</code></pre>
2175 </div></div>
2176 </div>
2177 <div class="sect2">
2178 <h3 id="_window_event">4.6. window event</h3>
2179 <div class="paragraph"><p>This event consists of a single serialized map containing a property
2180 <code>change (string)</code> which indicates the type of the change</p></div>
2181 <div class="ulist"><ul>
2182 <li>
2183 <p>
2184 <code>new</code> – the window has become managed by i3
2185 </p>
2186 </li>
2187 <li>
2188 <p>
2189 <code>close</code> – the window has closed
2190 </p>
2191 </li>
2192 <li>
2193 <p>
2194 <code>focus</code> – the window has received input focus
2195 </p>
2196 </li>
2197 <li>
2198 <p>
2199 <code>title</code> – the window&#8217;s title has changed
2200 </p>
2201 </li>
2202 <li>
2203 <p>
2204 <code>fullscreen_mode</code> – the window has entered or exited fullscreen mode
2205 </p>
2206 </li>
2207 <li>
2208 <p>
2209 <code>move</code> – the window has changed its position in the tree
2210 </p>
2211 </li>
2212 <li>
2213 <p>
2214 <code>floating</code> – the window has transitioned to or from floating
2215 </p>
2216 </li>
2217 <li>
2218 <p>
2219 <code>urgent</code> – the window has become urgent or lost its urgent status
2220 </p>
2221 </li>
2222 <li>
2223 <p>
2224 <code>mark</code> – a mark has been added to or removed from the window
2225 </p>
2226 </li>
2227 </ul></div>
2228 <div class="paragraph"><p>Additionally a <code>container (object)</code> field will be present, which consists
2229 of the window&#8217;s parent container. Be aware that for the "new" event, the
2230 container will hold the initial name of the newly reparented window (e.g.
2231 if you run urxvt with a shell that changes the title, you will still at
2232 this point get the window title as "urxvt").</p></div>
2233 <div class="paragraph"><p><strong>Example:</strong></p></div>
2234 <div class="listingblock">
2235 <div class="content">
2236 <pre><code>{
2237 "change": "new",
2238 "container": {
2239 "id": 35569536,
2240 "type": "con",
2241 ...
2242 }
2243 }</code></pre>
2244 </div></div>
2245 </div>
2246 <div class="sect2">
2247 <h3 id="_barconfig_update_event">4.7. barconfig_update event</h3>
2248 <div class="paragraph"><p>This event consists of a single serialized map reporting on options from the
2249 barconfig of the specified bar_id that were updated in i3. This event is the
2250 same as a <code>GET_BAR_CONFIG</code> reply for the bar with the given id.</p></div>
2251 </div>
2252 <div class="sect2">
2253 <h3 id="_binding_event">4.8. binding event</h3>
2254 <div class="paragraph"><p>This event consists of a single serialized map reporting on the details of a
2255 binding that ran a command because of user input. The <code>change (string)</code> field
2256 indicates what sort of binding event was triggered (right now it will always be
2257 <code>"run"</code> but may be expanded in the future).</p></div>
2258 <div class="paragraph"><p>The <code>binding (object)</code> field contains details about the binding that was run:</p></div>
2259 <div class="dlist"><dl>
2260 <dt class="hdlist1">
2261 command (string)
2262 </dt>
2263 <dd>
2264 <p>
2265 The i3 command that is configured to run for this binding.
2266 </p>
2267 </dd>
2268 <dt class="hdlist1">
2269 event_state_mask (array of strings)
2270 </dt>
2271 <dd>
2272 <p>
2273 The group and modifier keys that were configured with this binding.
2274 </p>
2275 </dd>
2276 <dt class="hdlist1">
2277 input_code (integer)
2278 </dt>
2279 <dd>
2280 <p>
2281 If the binding was configured with <code>bindcode</code>, this will be the key code
2282 that was given for the binding. If the binding is a mouse binding, it will be
2283 the number of the mouse button that was pressed. Otherwise it will be 0.
2284 </p>
2285 </dd>
2286 <dt class="hdlist1">
2287 symbol (string or null)
2288 </dt>
2289 <dd>
2290 <p>
2291 If this is a keyboard binding that was configured with <code>bindsym</code>, this
2292 field will contain the given symbol. Otherwise it will be <code>null</code>.
2293 </p>
2294 </dd>
2295 <dt class="hdlist1">
2296 input_type (string)
2297 </dt>
2298 <dd>
2299 <p>
2300 This will be <code>"keyboard"</code> or <code>"mouse"</code> depending on whether or not this was
2301 a keyboard or a mouse binding.
2302 </p>
2303 </dd>
2304 </dl></div>
2305 <div class="paragraph"><p><strong>Example:</strong></p></div>
2306 <div class="listingblock">
2307 <div class="content">
2308 <pre><code>{
2309 "change": "run",
2310 "binding": {
2311 "command": "nop",
2312 "event_state_mask": [
2313 "shift",
2314 "ctrl"
2315 ],
2316 "input_code": 0,
2317 "symbol": "t",
2318 "input_type": "keyboard"
2319 }
2320 }</code></pre>
2321 </div></div>
2322 </div>
2323 <div class="sect2">
2324 <h3 id="_shutdown_event">4.9. shutdown event</h3>
2325 <div class="paragraph"><p>This event is triggered when the connection to the ipc is about to shutdown
2326 because of a user action such as a <code>restart</code> or <code>exit</code> command. The <code>change
2327 (string)</code> field indicates why the ipc is shutting down. It can be either
2328 <code>"restart"</code> or <code>"exit"</code>.</p></div>
2329 <div class="paragraph"><p><strong>Example:</strong></p></div>
2330 <div class="listingblock">
2331 <div class="content">
2332 <pre><code>{
2333 "change": "restart"
2334 }</code></pre>
2335 </div></div>
2336 </div>
2337 <div class="sect2">
2338 <h3 id="_tick_event">4.10. tick event</h3>
2339 <div class="paragraph"><p>This event is triggered by a subscription to tick events or by a <code>SEND_TICK</code>
2340 message.</p></div>
2341 <div class="paragraph"><p><strong>Example (upon subscription):</strong></p></div>
2342 <div class="listingblock">
2343 <div class="content">
2344 <pre><code>{
2345 "first": true,
2346 "payload": ""
2347 }</code></pre>
2348 </div></div>
2349 <div class="paragraph"><p><strong>Example (upon <code>SEND_TICK</code> with a payload of <code>arbitrary string</code>):</strong></p></div>
2350 <div class="listingblock">
2351 <div class="content">
2352 <pre><code>{
2353 "first": false,
2354 "payload": "arbitrary string"
2355 }</code></pre>
2356 </div></div>
2357 </div>
2358 </div>
2359 </div>
2360 <div class="sect1">
2361 <h2 id="_see_also_existing_libraries">5. See also (existing libraries)</h2>
2362 <div class="sectionbody">
2363 <div class="paragraph" id="libraries"><p>For some languages, libraries are available (so you don’t have to implement
2364 all this on your own). This list names some (if you wrote one, please let me
2365 know):</p></div>
2366 <div class="dlist"><dl>
2367 <dt class="hdlist1">
2368 C
2369 </dt>
2370 <dd>
2371 <div class="ulist"><ul>
2372 <li>
2373 <p>
2374 i3 includes a headerfile <code>i3/ipc.h</code> which provides you all constants.
2375 </p>
2376 </li>
2377 <li>
2378 <p>
2379 <a href="https://github.com/acrisci/i3ipc-glib">https://github.com/acrisci/i3ipc-glib</a>
2380 </p>
2381 </li>
2382 </ul></div>
2383 </dd>
2384 <dt class="hdlist1">
2385 C++
2386 </dt>
2387 <dd>
2388 <div class="ulist"><ul>
2389 <li>
2390 <p>
2391 <a href="https://github.com/Iskustvo/i3-ipcpp">i3-ipc++</a>
2392 </p>
2393 </li>
2394 <li>
2395 <p>
2396 <a href="https://github.com/drmgc/i3ipcpp">https://github.com/drmgc/i3ipcpp</a>
2397 </p>
2398 </li>
2399 </ul></div>
2400 </dd>
2401 <dt class="hdlist1">
2402 Go
2403 </dt>
2404 <dd>
2405 <div class="ulist"><ul>
2406 <li>
2407 <p>
2408 <a href="https://github.com/mdirkse/i3ipc-go">https://github.com/mdirkse/i3ipc-go</a>
2409 </p>
2410 </li>
2411 <li>
2412 <p>
2413 <a href="https://github.com/i3/go-i3">https://github.com/i3/go-i3</a>
2414 </p>
2415 </li>
2416 </ul></div>
2417 </dd>
2418 <dt class="hdlist1">
2419 JavaScript
2420 </dt>
2421 <dd>
2422 <div class="ulist"><ul>
2423 <li>
2424 <p>
2425 <a href="https://github.com/acrisci/i3ipc-gjs">https://github.com/acrisci/i3ipc-gjs</a>
2426 </p>
2427 </li>
2428 </ul></div>
2429 </dd>
2430 <dt class="hdlist1">
2431 Lua
2432 </dt>
2433 <dd>
2434 <div class="ulist"><ul>
2435 <li>
2436 <p>
2437 <a href="https://github.com/acrisci/i3ipc-lua">https://github.com/acrisci/i3ipc-lua</a>
2438 </p>
2439 </li>
2440 </ul></div>
2441 </dd>
2442 <dt class="hdlist1">
2443 Perl
2444 </dt>
2445 <dd>
2446 <div class="ulist"><ul>
2447 <li>
2448 <p>
2449 <a href="https://metacpan.org/module/AnyEvent::I3">https://metacpan.org/module/AnyEvent::I3</a>
2450 </p>
2451 </li>
2452 </ul></div>
2453 </dd>
2454 <dt class="hdlist1">
2455 Python
2456 </dt>
2457 <dd>
2458 <div class="ulist"><ul>
2459 <li>
2460 <p>
2461 <a href="https://github.com/acrisci/i3ipc-python">https://github.com/acrisci/i3ipc-python</a>
2462 </p>
2463 </li>
2464 <li>
2465 <p>
2466 <a href="https://github.com/whitelynx/i3ipc">https://github.com/whitelynx/i3ipc</a> (not maintained)
2467 </p>
2468 </li>
2469 <li>
2470 <p>
2471 <a href="https://github.com/ziberna/i3-py">https://github.com/ziberna/i3-py</a> (not maintained)
2472 </p>
2473 </li>
2474 </ul></div>
2475 </dd>
2476 <dt class="hdlist1">
2477 Ruby
2478 </dt>
2479 <dd>
2480 <div class="ulist"><ul>
2481 <li>
2482 <p>
2483 <a href="https://github.com/veelenga/i3ipc-ruby">https://github.com/veelenga/i3ipc-ruby</a>
2484 </p>
2485 </li>
2486 <li>
2487 <p>
2488 <a href="https://github.com/badboy/i3-ipc">https://github.com/badboy/i3-ipc</a> (not maintained)
2489 </p>
2490 </li>
2491 </ul></div>
2492 </dd>
2493 <dt class="hdlist1">
2494 Rust
2495 </dt>
2496 <dd>
2497 <div class="ulist"><ul>
2498 <li>
2499 <p>
2500 <a href="https://github.com/tmerr/i3ipc-rs">https://github.com/tmerr/i3ipc-rs</a>
2501 </p>
2502 </li>
2503 </ul></div>
2504 </dd>
2505 <dt class="hdlist1">
2506 OCaml
2507 </dt>
2508 <dd>
2509 <div class="ulist"><ul>
2510 <li>
2511 <p>
2512 <a href="https://github.com/Armael/ocaml-i3ipc">https://github.com/Armael/ocaml-i3ipc</a>
2513 </p>
2514 </li>
2515 </ul></div>
2516 </dd>
2517 </dl></div>
2518 </div>
2519 </div>
2520 <div class="sect1">
2521 <h2 id="_appendix_a_detecting_byte_order_in_memory_safe_languages">6. Appendix A: Detecting byte order in memory-safe languages</h2>
2522 <div class="sectionbody">
2523 <div class="paragraph"><p>Some programming languages such as Go don’t offer a way to serialize data in the
2524 native byte order of the machine they’re running on without resorting to tricks
2525 involving the <code>unsafe</code> package.</p></div>
2526 <div class="paragraph"><p>The following technique can be used (and will not be broken by changes to i3) to
2527 detect the byte order i3 is using:</p></div>
2528 <div class="olist arabic"><ol class="arabic">
2529 <li>
2530 <p>
2531 The byte order dependent fields of an IPC message are message type and
2532 payload length.
2533 </p>
2534 <div class="ulist"><ul>
2535 <li>
2536 <p>
2537 The message type <code>RUN_COMMAND</code> (0) is the same in big and little endian, so
2538 we can use it in either byte order to elicit a reply from i3.
2539 </p>
2540 </li>
2541 <li>
2542 <p>
2543 The payload length 65536 + 256 (<code>0x00 01 01 00</code>) is the same in big and
2544 little endian, and also small enough to not worry about memory allocations
2545 of that size. We must use payloads of length 65536 + 256 in every message
2546 we send, so that i3 will be able to read the entire message regardless of
2547 the byte order it uses.
2548 </p>
2549 </li>
2550 </ul></div>
2551 </li>
2552 <li>
2553 <p>
2554 Send a big endian encoded message of type <code>SUBSCRIBE</code> (2) with payload <code>[]</code>
2555 followed by 65536 + 256 - 2 <code>SPACE</code> (ASCII 0x20) bytes.
2556 </p>
2557 <div class="ulist"><ul>
2558 <li>
2559 <p>
2560 If i3 is running in big endian, this message is treated as a noop,
2561 resulting in a <code>SUBSCRIBE</code> reply with payload <code>{"success":true}</code>
2562 <span class="footnote"><br />[A small payload is important: that way, we circumvent dealing
2563 with UNIX domain socket buffer sizes, whose size depends on the
2564 implementation/operating system. Exhausting such a buffer results in an i3
2565 deadlock unless you concurrently read and write, which — depending on the
2566 programming language — makes the technique much more complicated.]<br /></span>.
2567 </p>
2568 </li>
2569 <li>
2570 <p>
2571 If i3 is running in little endian, this message is read in its entirety due
2572 to the byte order independent payload length, then
2573 <a href="https://github.com/i3/i3/blob/d726d09d496577d1c337a4b97486f2c9fbc914f1/src/ipc.c#L1188">silently
2574 discarded</a> due to the unknown message type.
2575 </p>
2576 </li>
2577 </ul></div>
2578 </li>
2579 <li>
2580 <p>
2581 Send a byte order independent message, i.e. type <code>RUN_COMMAND</code> (0) with
2582 payload <code>nop byte order detection. padding:</code>, padded to 65536 + 256 bytes
2583 with <code>a</code> (ASCII 0x61) bytes. i3 will reply to this message with a reply of
2584 type <code>COMMAND</code> (0).
2585 </p>
2586 <div class="ulist"><ul>
2587 <li>
2588 <p>
2589 The human-readable prefix is in there to not confuse readers of the i3 log.
2590 </p>
2591 </li>
2592 <li>
2593 <p>
2594 This messages serves as a synchronization primitive so that we know whether
2595 i3 discarded the <code>SUBSCRIBE</code> message or didn’t answer it yet.
2596 </p>
2597 </li>
2598 </ul></div>
2599 </li>
2600 <li>
2601 <p>
2602 Receive a message header from i3, decoding the message type as big endian.
2603 </p>
2604 <div class="ulist"><ul>
2605 <li>
2606 <p>
2607 If the message’s reply type is <code>COMMAND</code> (0), i3 is running in little
2608 endian (because the <code>SUBSCRIBE</code> message was discarded). Decode the message
2609 payload length as little endian, receive the message payload.
2610 </p>
2611 </li>
2612 <li>
2613 <p>
2614 If the message’s reply type is anything else, i3 is running in big endian
2615 (because our big endian encoded <code>SUBSCRIBE</code> message was answered). Decode
2616 the message payload length in big endian, receive the message
2617 payload. Then, receive the pending <code>COMMAND</code> message reply in big endian.
2618 </p>
2619 </li>
2620 </ul></div>
2621 </li>
2622 <li>
2623 <p>
2624 From here on out, send/receive all messages using the detected byte order.
2625 </p>
2626 </li>
2627 </ol></div>
2628 <div class="paragraph"><p>Find an example implementation of this technique in
2629 <a href="https://github.com/i3/go-i3/blob/master/byteorder.go">https://github.com/i3/go-i3/blob/master/byteorder.go</a></p></div>
2630 </div>
2631 </div>
2632 </div>
2633 <div id="footnotes"><hr /></div>
2634 <div id="footer">
2635 <div id="footer-text">
2636 Last updated
2637 2019-08-30 23:06:47 CEST
2638 </div>
2639 </div>
2640 </body>
2641 </html>
0 <?xml version="1.0" encoding="UTF-8"?>
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
2 "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
4 <head>
5 <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
6 <meta name="generator" content="AsciiDoc 8.6.10" />
7 <title>Layout saving in i3</title>
8 <style type="text/css">
9 /* Shared CSS for AsciiDoc xhtml11 and html5 backends */
10
11 /* Default font. */
12 body {
13 font-family: Georgia,serif;
14 }
15
16 /* Title font. */
17 h1, h2, h3, h4, h5, h6,
18 div.title, caption.title,
19 thead, p.table.header,
20 #toctitle,
21 #author, #revnumber, #revdate, #revremark,
22 #footer {
23 font-family: Arial,Helvetica,sans-serif;
24 }
25
26 body {
27 margin: 1em 5% 1em 5%;
28 }
29
30 a {
31 color: blue;
32 text-decoration: underline;
33 }
34 a:visited {
35 color: fuchsia;
36 }
37
38 em {
39 font-style: italic;
40 color: navy;
41 }
42
43 strong {
44 font-weight: bold;
45 color: #083194;
46 }
47
48 h1, h2, h3, h4, h5, h6 {
49 color: #527bbd;
50 margin-top: 1.2em;
51 margin-bottom: 0.5em;
52 line-height: 1.3;
53 }
54
55 h1, h2, h3 {
56 border-bottom: 2px solid silver;
57 }
58 h2 {
59 padding-top: 0.5em;
60 }
61 h3 {
62 float: left;
63 }
64 h3 + * {
65 clear: left;
66 }
67 h5 {
68 font-size: 1.0em;
69 }
70
71 div.sectionbody {
72 margin-left: 0;
73 }
74
75 hr {
76 border: 1px solid silver;
77 }
78
79 p {
80 margin-top: 0.5em;
81 margin-bottom: 0.5em;
82 }
83
84 ul, ol, li > p {
85 margin-top: 0;
86 }
87 ul > li { color: #aaa; }
88 ul > li > * { color: black; }
89
90 .monospaced, code, pre {
91 font-family: "Courier New", Courier, monospace;
92 font-size: inherit;
93 color: navy;
94 padding: 0;
95 margin: 0;
96 }
97 pre {
98 white-space: pre-wrap;
99 }
100
101 #author {
102 color: #527bbd;
103 font-weight: bold;
104 font-size: 1.1em;
105 }
106 #email {
107 }
108 #revnumber, #revdate, #revremark {
109 }
110
111 #footer {
112 font-size: small;
113 border-top: 2px solid silver;
114 padding-top: 0.5em;
115 margin-top: 4.0em;
116 }
117 #footer-text {
118 float: left;
119 padding-bottom: 0.5em;
120 }
121 #footer-badges {
122 float: right;
123 padding-bottom: 0.5em;
124 }
125
126 #preamble {
127 margin-top: 1.5em;
128 margin-bottom: 1.5em;
129 }
130 div.imageblock, div.exampleblock, div.verseblock,
131 div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
132 div.admonitionblock {
133 margin-top: 1.0em;
134 margin-bottom: 1.5em;
135 }
136 div.admonitionblock {
137 margin-top: 2.0em;
138 margin-bottom: 2.0em;
139 margin-right: 10%;
140 color: #606060;
141 }
142
143 div.content { /* Block element content. */
144 padding: 0;
145 }
146
147 /* Block element titles. */
148 div.title, caption.title {
149 color: #527bbd;
150 font-weight: bold;
151 text-align: left;
152 margin-top: 1.0em;
153 margin-bottom: 0.5em;
154 }
155 div.title + * {
156 margin-top: 0;
157 }
158
159 td div.title:first-child {
160 margin-top: 0.0em;
161 }
162 div.content div.title:first-child {
163 margin-top: 0.0em;
164 }
165 div.content + div.title {
166 margin-top: 0.0em;
167 }
168
169 div.sidebarblock > div.content {
170 background: #ffffee;
171 border: 1px solid #dddddd;
172 border-left: 4px solid #f0f0f0;
173 padding: 0.5em;
174 }
175
176 div.listingblock > div.content {
177 border: 1px solid #dddddd;
178 border-left: 5px solid #f0f0f0;
179 background: #f8f8f8;
180 padding: 0.5em;
181 }
182
183 div.quoteblock, div.verseblock {
184 padding-left: 1.0em;
185 margin-left: 1.0em;
186 margin-right: 10%;
187 border-left: 5px solid #f0f0f0;
188 color: #888;
189 }
190
191 div.quoteblock > div.attribution {
192 padding-top: 0.5em;
193 text-align: right;
194 }
195
196 div.verseblock > pre.content {
197 font-family: inherit;
198 font-size: inherit;
199 }
200 div.verseblock > div.attribution {
201 padding-top: 0.75em;
202 text-align: left;
203 }
204 /* DEPRECATED: Pre version 8.2.7 verse style literal block. */
205 div.verseblock + div.attribution {
206 text-align: left;
207 }
208
209 div.admonitionblock .icon {
210 vertical-align: top;
211 font-size: 1.1em;
212 font-weight: bold;
213 text-decoration: underline;
214 color: #527bbd;
215 padding-right: 0.5em;
216 }
217 div.admonitionblock td.content {
218 padding-left: 0.5em;
219 border-left: 3px solid #dddddd;
220 }
221
222 div.exampleblock > div.content {
223 border-left: 3px solid #dddddd;
224 padding-left: 0.5em;
225 }
226
227 div.imageblock div.content { padding-left: 0; }
228 span.image img { border-style: none; vertical-align: text-bottom; }
229 a.image:visited { color: white; }
230
231 dl {
232 margin-top: 0.8em;
233 margin-bottom: 0.8em;
234 }
235 dt {
236 margin-top: 0.5em;
237 margin-bottom: 0;
238 font-style: normal;
239 color: navy;
240 }
241 dd > *:first-child {
242 margin-top: 0.1em;
243 }
244
245 ul, ol {
246 list-style-position: outside;
247 }
248 ol.arabic {
249 list-style-type: decimal;
250 }
251 ol.loweralpha {
252 list-style-type: lower-alpha;
253 }
254 ol.upperalpha {
255 list-style-type: upper-alpha;
256 }
257 ol.lowerroman {
258 list-style-type: lower-roman;
259 }
260 ol.upperroman {
261 list-style-type: upper-roman;
262 }
263
264 div.compact ul, div.compact ol,
265 div.compact p, div.compact p,
266 div.compact div, div.compact div {
267 margin-top: 0.1em;
268 margin-bottom: 0.1em;
269 }
270
271 tfoot {
272 font-weight: bold;
273 }
274 td > div.verse {
275 white-space: pre;
276 }
277
278 div.hdlist {
279 margin-top: 0.8em;
280 margin-bottom: 0.8em;
281 }
282 div.hdlist tr {
283 padding-bottom: 15px;
284 }
285 dt.hdlist1.strong, td.hdlist1.strong {
286 font-weight: bold;
287 }
288 td.hdlist1 {
289 vertical-align: top;
290 font-style: normal;
291 padding-right: 0.8em;
292 color: navy;
293 }
294 td.hdlist2 {
295 vertical-align: top;
296 }
297 div.hdlist.compact tr {
298 margin: 0;
299 padding-bottom: 0;
300 }
301
302 .comment {
303 background: yellow;
304 }
305
306 .footnote, .footnoteref {
307 font-size: 0.8em;
308 }
309
310 span.footnote, span.footnoteref {
311 vertical-align: super;
312 }
313
314 #footnotes {
315 margin: 20px 0 20px 0;
316 padding: 7px 0 0 0;
317 }
318
319 #footnotes div.footnote {
320 margin: 0 0 5px 0;
321 }
322
323 #footnotes hr {
324 border: none;
325 border-top: 1px solid silver;
326 height: 1px;
327 text-align: left;
328 margin-left: 0;
329 width: 20%;
330 min-width: 100px;
331 }
332
333 div.colist td {
334 padding-right: 0.5em;
335 padding-bottom: 0.3em;
336 vertical-align: top;
337 }
338 div.colist td img {
339 margin-top: 0.3em;
340 }
341
342 @media print {
343 #footer-badges { display: none; }
344 }
345
346 #toc {
347 margin-bottom: 2.5em;
348 }
349
350 #toctitle {
351 color: #527bbd;
352 font-size: 1.1em;
353 font-weight: bold;
354 margin-top: 1.0em;
355 margin-bottom: 0.1em;
356 }
357
358 div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
359 margin-top: 0;
360 margin-bottom: 0;
361 }
362 div.toclevel2 {
363 margin-left: 2em;
364 font-size: 0.9em;
365 }
366 div.toclevel3 {
367 margin-left: 4em;
368 font-size: 0.9em;
369 }
370 div.toclevel4 {
371 margin-left: 6em;
372 font-size: 0.9em;
373 }
374
375 span.aqua { color: aqua; }
376 span.black { color: black; }
377 span.blue { color: blue; }
378 span.fuchsia { color: fuchsia; }
379 span.gray { color: gray; }
380 span.green { color: green; }
381 span.lime { color: lime; }
382 span.maroon { color: maroon; }
383 span.navy { color: navy; }
384 span.olive { color: olive; }
385 span.purple { color: purple; }
386 span.red { color: red; }
387 span.silver { color: silver; }
388 span.teal { color: teal; }
389 span.white { color: white; }
390 span.yellow { color: yellow; }
391
392 span.aqua-background { background: aqua; }
393 span.black-background { background: black; }
394 span.blue-background { background: blue; }
395 span.fuchsia-background { background: fuchsia; }
396 span.gray-background { background: gray; }
397 span.green-background { background: green; }
398 span.lime-background { background: lime; }
399 span.maroon-background { background: maroon; }
400 span.navy-background { background: navy; }
401 span.olive-background { background: olive; }
402 span.purple-background { background: purple; }
403 span.red-background { background: red; }
404 span.silver-background { background: silver; }
405 span.teal-background { background: teal; }
406 span.white-background { background: white; }
407 span.yellow-background { background: yellow; }
408
409 span.big { font-size: 2em; }
410 span.small { font-size: 0.6em; }
411
412 span.underline { text-decoration: underline; }
413 span.overline { text-decoration: overline; }
414 span.line-through { text-decoration: line-through; }
415
416 div.unbreakable { page-break-inside: avoid; }
417
418
419 /*
420 * xhtml11 specific
421 *
422 * */
423
424 div.tableblock {
425 margin-top: 1.0em;
426 margin-bottom: 1.5em;
427 }
428 div.tableblock > table {
429 border: 3px solid #527bbd;
430 }
431 thead, p.table.header {
432 font-weight: bold;
433 color: #527bbd;
434 }
435 p.table {
436 margin-top: 0;
437 }
438 /* Because the table frame attribute is overriden by CSS in most browsers. */
439 div.tableblock > table[frame="void"] {
440 border-style: none;
441 }
442 div.tableblock > table[frame="hsides"] {
443 border-left-style: none;
444 border-right-style: none;
445 }
446 div.tableblock > table[frame="vsides"] {
447 border-top-style: none;
448 border-bottom-style: none;
449 }
450
451
452 /*
453 * html5 specific
454 *
455 * */
456
457 table.tableblock {
458 margin-top: 1.0em;
459 margin-bottom: 1.5em;
460 }
461 thead, p.tableblock.header {
462 font-weight: bold;
463 color: #527bbd;
464 }
465 p.tableblock {
466 margin-top: 0;
467 }
468 table.tableblock {
469 border-width: 3px;
470 border-spacing: 0px;
471 border-style: solid;
472 border-color: #527bbd;
473 border-collapse: collapse;
474 }
475 th.tableblock, td.tableblock {
476 border-width: 1px;
477 padding: 4px;
478 border-style: solid;
479 border-color: #527bbd;
480 }
481
482 table.tableblock.frame-topbot {
483 border-left-style: hidden;
484 border-right-style: hidden;
485 }
486 table.tableblock.frame-sides {
487 border-top-style: hidden;
488 border-bottom-style: hidden;
489 }
490 table.tableblock.frame-none {
491 border-style: hidden;
492 }
493
494 th.tableblock.halign-left, td.tableblock.halign-left {
495 text-align: left;
496 }
497 th.tableblock.halign-center, td.tableblock.halign-center {
498 text-align: center;
499 }
500 th.tableblock.halign-right, td.tableblock.halign-right {
501 text-align: right;
502 }
503
504 th.tableblock.valign-top, td.tableblock.valign-top {
505 vertical-align: top;
506 }
507 th.tableblock.valign-middle, td.tableblock.valign-middle {
508 vertical-align: middle;
509 }
510 th.tableblock.valign-bottom, td.tableblock.valign-bottom {
511 vertical-align: bottom;
512 }
513
514
515 /*
516 * manpage specific
517 *
518 * */
519
520 body.manpage h1 {
521 padding-top: 0.5em;
522 padding-bottom: 0.5em;
523 border-top: 2px solid silver;
524 border-bottom: 2px solid silver;
525 }
526 body.manpage h2 {
527 border-style: none;
528 }
529 body.manpage div.sectionbody {
530 margin-left: 3em;
531 }
532
533 @media print {
534 body.manpage div#toc { display: none; }
535 }
536
537
538 </style>
539 <script type="text/javascript">
540 /*<![CDATA[*/
541 var asciidoc = { // Namespace.
542
543 /////////////////////////////////////////////////////////////////////
544 // Table Of Contents generator
545 /////////////////////////////////////////////////////////////////////
546
547 /* Author: Mihai Bazon, September 2002
548 * http://students.infoiasi.ro/~mishoo
549 *
550 * Table Of Content generator
551 * Version: 0.4
552 *
553 * Feel free to use this script under the terms of the GNU General Public
554 * License, as long as you do not remove or alter this notice.
555 */
556
557 /* modified by Troy D. Hanson, September 2006. License: GPL */
558 /* modified by Stuart Rackham, 2006, 2009. License: GPL */
559
560 // toclevels = 1..4.
561 toc: function (toclevels) {
562
563 function getText(el) {
564 var text = "";
565 for (var i = el.firstChild; i != null; i = i.nextSibling) {
566 if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
567 text += i.data;
568 else if (i.firstChild != null)
569 text += getText(i);
570 }
571 return text;
572 }
573
574 function TocEntry(el, text, toclevel) {
575 this.element = el;
576 this.text = text;
577 this.toclevel = toclevel;
578 }
579
580 function tocEntries(el, toclevels) {
581 var result = new Array;
582 var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
583 // Function that scans the DOM tree for header elements (the DOM2
584 // nodeIterator API would be a better technique but not supported by all
585 // browsers).
586 var iterate = function (el) {
587 for (var i = el.firstChild; i != null; i = i.nextSibling) {
588 if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
589 var mo = re.exec(i.tagName);
590 if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
591 result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
592 }
593 iterate(i);
594 }
595 }
596 }
597 iterate(el);
598 return result;
599 }
600
601 var toc = document.getElementById("toc");
602 if (!toc) {
603 return;
604 }
605
606 // Delete existing TOC entries in case we're reloading the TOC.
607 var tocEntriesToRemove = [];
608 var i;
609 for (i = 0; i < toc.childNodes.length; i++) {
610 var entry = toc.childNodes[i];
611 if (entry.nodeName.toLowerCase() == 'div'
612 && entry.getAttribute("class")
613 && entry.getAttribute("class").match(/^toclevel/))
614 tocEntriesToRemove.push(entry);
615 }
616 for (i = 0; i < tocEntriesToRemove.length; i++) {
617 toc.removeChild(tocEntriesToRemove[i]);
618 }
619
620 // Rebuild TOC entries.
621 var entries = tocEntries(document.getElementById("content"), toclevels);
622 for (var i = 0; i < entries.length; ++i) {
623 var entry = entries[i];
624 if (entry.element.id == "")
625 entry.element.id = "_toc_" + i;
626 var a = document.createElement("a");
627 a.href = "#" + entry.element.id;
628 a.appendChild(document.createTextNode(entry.text));
629 var div = document.createElement("div");
630 div.appendChild(a);
631 div.className = "toclevel" + entry.toclevel;
632 toc.appendChild(div);
633 }
634 if (entries.length == 0)
635 toc.parentNode.removeChild(toc);
636 },
637
638
639 /////////////////////////////////////////////////////////////////////
640 // Footnotes generator
641 /////////////////////////////////////////////////////////////////////
642
643 /* Based on footnote generation code from:
644 * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
645 */
646
647 footnotes: function () {
648 // Delete existing footnote entries in case we're reloading the footnodes.
649 var i;
650 var noteholder = document.getElementById("footnotes");
651 if (!noteholder) {
652 return;
653 }
654 var entriesToRemove = [];
655 for (i = 0; i < noteholder.childNodes.length; i++) {
656 var entry = noteholder.childNodes[i];
657 if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
658 entriesToRemove.push(entry);
659 }
660 for (i = 0; i < entriesToRemove.length; i++) {
661 noteholder.removeChild(entriesToRemove[i]);
662 }
663
664 // Rebuild footnote entries.
665 var cont = document.getElementById("content");
666 var spans = cont.getElementsByTagName("span");
667 var refs = {};
668 var n = 0;
669 for (i=0; i<spans.length; i++) {
670 if (spans[i].className == "footnote") {
671 n++;
672 var note = spans[i].getAttribute("data-note");
673 if (!note) {
674 // Use [\s\S] in place of . so multi-line matches work.
675 // Because JavaScript has no s (dotall) regex flag.
676 note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
677 spans[i].innerHTML =
678 "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
679 "' title='View footnote' class='footnote'>" + n + "</a>]";
680 spans[i].setAttribute("data-note", note);
681 }
682 noteholder.innerHTML +=
683 "<div class='footnote' id='_footnote_" + n + "'>" +
684 "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
685 n + "</a>. " + note + "</div>";
686 var id =spans[i].getAttribute("id");
687 if (id != null) refs["#"+id] = n;
688 }
689 }
690 if (n == 0)
691 noteholder.parentNode.removeChild(noteholder);
692 else {
693 // Process footnoterefs.
694 for (i=0; i<spans.length; i++) {
695 if (spans[i].className == "footnoteref") {
696 var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
697 href = href.match(/#.*/)[0]; // Because IE return full URL.
698 n = refs[href];
699 spans[i].innerHTML =
700 "[<a href='#_footnote_" + n +
701 "' title='View footnote' class='footnote'>" + n + "</a>]";
702 }
703 }
704 }
705 },
706
707 install: function(toclevels) {
708 var timerId;
709
710 function reinstall() {
711 asciidoc.footnotes();
712 if (toclevels) {
713 asciidoc.toc(toclevels);
714 }
715 }
716
717 function reinstallAndRemoveTimer() {
718 clearInterval(timerId);
719 reinstall();
720 }
721
722 timerId = setInterval(reinstall, 500);
723 if (document.addEventListener)
724 document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
725 else
726 window.onload = reinstallAndRemoveTimer;
727 }
728
729 }
730 asciidoc.install(2);
731 /*]]>*/
732 </script>
733 </head>
734 <body class="article">
735 <div id="header">
736 <h1>Layout saving in i3</h1>
737 <span id="author">Michael Stapelberg</span><br />
738 <span id="email"><code>&lt;<a href="mailto:[email protected]">[email protected]</a>&gt;</code></span><br />
739 <span id="revdate">April 2014</span>
740 <div id="toc">
741 <div id="toctitle">Table of Contents</div>
742 <noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
743 </div>
744 </div>
745 <div id="content">
746 <div id="preamble">
747 <div class="sectionbody">
748 <div class="paragraph"><p>Layout saving/restoring is a feature that was introduced in i3 v4.8.</p></div>
749 <div class="paragraph"><p>Layout saving/restoring allows you to load a JSON layout file so that you can
750 have a base layout to start working with after powering on your computer.
751 Dynamic use-cases also come to mind: if you frequently (but not always!) need a
752 grid layout of terminals with ping/traceroute commands to diagnose network
753 issues, you can easily automate opening these windows in just the right layout.</p></div>
754 </div>
755 </div>
756 <div class="sect1">
757 <h2 id="_saving_the_layout">1. Saving the layout</h2>
758 <div class="sectionbody">
759 <div class="paragraph"><p>You can save the layout of either a single workspace or an entire output (e.g.
760 LVDS1). Of course, you can repeat this step multiple times if you want to
761 save/restore multiple workspaces/outputs.</p></div>
762 <div class="paragraph"><p><code>i3-save-tree(1)</code> is a tool to save the layout. It will print a JSON
763 representation of i3’s internal layout data structures to stdout. Typically,
764 you may want to take a quick look at the output, then save it to a file and
765 tweak it a little bit:</p></div>
766 <div class="listingblock">
767 <div class="content">
768 <pre><code>i3-save-tree --workspace 1 &gt; ~/.i3/workspace-1.json</code></pre>
769 </div></div>
770 <div class="paragraph"><p>Please note that the output of <code>i3-save-tree(1)</code> is <strong>NOT useful</strong> until you
771 manually modify it — you need to tell i3 how to match/distinguish windows (for
772 example based on their WM_CLASS, title, etc.). By default, all the different
773 window properties are included in the output, but commented out. This is partly
774 to avoid relying on heuristics and partly to make you aware how i3 works so
775 that you can easily solve layout restoring problems.</p></div>
776 <div class="paragraph"><p>How to modify the file manually is described in <a href="#EditingLayoutFiles">[EditingLayoutFiles]</a>.</p></div>
777 </div>
778 </div>
779 <div class="sect1">
780 <h2 id="_restoring_the_layout">2. Restoring the layout</h2>
781 <div class="sectionbody">
782 <div class="paragraph"><p>After restoring the example layout from <a href="#EditingLayoutFiles">[EditingLayoutFiles]</a>, i3 will open
783 placeholder windows for all the windows that were specified in the layout file.
784 You can recognize the placeholder windows by the watch symbol
785 <span class="footnote"><br />[Depending on the font you are using, a placeholder symbol may show up
786 instead of the watch symbol.]<br /></span> in the center of the window, and by the swallow
787 criteria specification at the top of the window:</p></div>
788 <div class="paragraph"><p><span class="image">
789 <a class="image" href="layout-saving-1.png">
790 <img src="layout-saving-1.png" alt="Restored layout" width="400" />
791 </a>
792 </span></p></div>
793 <div class="paragraph"><p>When an application opens a window that matches the specified swallow criteria,
794 it will be placed in the corresponding placeholder window. We say it gets
795 <strong>swallowed</strong> by the placeholder container, hence the term.</p></div>
796 <div class="paragraph"><p>Note: Swallowing windows into unsatisfied placeholder windows takes precedence
797 over
798 <a href="https://i3wm.org/docs/userguide.html#_automatically_putting_clients_on_specific_workspaces">assignment
799 rules</a>. For example, if you assign all Emacs windows to workspace 1 in your i3
800 configuration file, but there is a placeholder window on workspace 2 which
801 matches Emacs as well, your newly started Emacs window will end up in the
802 placeholder window on workspace 2.</p></div>
803 <div class="paragraph"><p>The placeholder windows are just regular windows, so feel free to move them
804 around or close them, for example.</p></div>
805 <div class="sect2">
806 <h3 id="_append_layout_command">2.1. append_layout command</h3>
807 <div class="paragraph"><p>The <code>append_layout</code> command is used to load a layout file into i3. It accepts a
808 path (relative to i3’s current working directory or absolute) to a JSON file.</p></div>
809 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
810 <div class="listingblock">
811 <div class="content">
812 <pre><code>append_layout &lt;path&gt;</code></pre>
813 </div></div>
814 <div class="paragraph"><p><strong>Examples</strong>:</p></div>
815 <div class="listingblock">
816 <div class="content">
817 <pre><code># From a terminal or script:
818 i3-msg "workspace 1; append_layout /home/michael/.i3/workspace-1.json"
819
820 # In your i3 configuration file, you can autostart i3-msg like this:
821 # (Note that those lines will quickly become long, so typically you would store
822 # them in a script with proper indentation.)
823 exec --no-startup-id "i3-msg 'workspace 1; append_layout /home/michael/.i3/workspace-1.json'"</code></pre>
824 </div></div>
825 </div>
826 </div>
827 </div>
828 <div class="sect1">
829 <h2 id="_editing_layout_files">3. Editing layout files</h2>
830 <div class="sectionbody">
831 <div class="sect2">
832 <h3 id="EditingLayoutFiles">3.1. Anatomy of a layout file</h3>
833 <div class="paragraph"><p>Here is an example layout file that we’ll discuss:</p></div>
834 <div class="listingblock">
835 <div class="content">
836 <pre><code>{
837 // splitv split container with 2 children
838 "layout": "splitv",
839 "percent": 0.4,
840 "type": "con",
841 "nodes": [
842 {
843 "border": "none",
844 "name": "irssi",
845 "percent": 0.5,
846 "type": "con",
847 "swallows": [
848 {
849 "class": "^URxvt$",
850 "instance": "^irssi$"
851 }
852 ]
853 },
854 {
855 // stacked split container with 2 children
856 "layout": "stacked",
857 "percent": 0.5,
858 "type": "con",
859 "nodes": [
860 {
861 "name": "notmuch",
862 "percent": 0.5,
863 "type": "con",
864 "swallows": [
865 {
866 "class": "^Emacs$",
867 "instance": "^notmuch$"
868 }
869 ]
870 },
871 {
872 "name": "midna: ~",
873 "percent": 0.5,
874 "type": "con"
875 }
876 ]
877 }
878 ]
879 }
880
881 {
882 // stacked split container with 1 children
883 "layout": "stacked",
884 "percent": 0.6,
885 "type": "con",
886 "nodes": [
887 {
888 "name": "chrome",
889 "type": "con",
890 "swallows": [
891 {
892 "class": "^Google-chrome$"
893 }
894 ]
895 }
896 ]
897 }</code></pre>
898 </div></div>
899 <div class="paragraph"><p>In this layout, the screen is divided into two columns. In the left column,
900 which covers 40% of the screen, there is a terminal emulator running irssi on
901 the top, and a stacked split container with an Emacs window and a terminal
902 emulator on the bottom. In the right column, there is a stacked container with
903 a Chrome window:</p></div>
904 <div class="paragraph"><p><span class="image">
905 <a class="image" href="layout-saving-1.png">
906 <img src="layout-saving-1.png" alt="Restored layout" width="400" />
907 </a>
908 </span></p></div>
909 <div class="paragraph"><p>The structure of this JSON file looks a lot like the <code>TREE</code> reply, see
910 <a href="https://build.i3wm.org/docs/ipc.html#_tree_reply">https://build.i3wm.org/docs/ipc.html#_tree_reply</a> for documentation on that. Some
911 properties are excluded because they are not relevant when restoring a layout.</p></div>
912 <div class="paragraph"><p>Most importantly, look at the "swallows" section of each window. This is where
913 you need to be more or less specific. As an example, remember the section about
914 the Emacs window:</p></div>
915 <div class="listingblock">
916 <div class="content">
917 <pre><code>"swallows": [
918 {
919 "class": "^Emacs$",
920 "instance": "^notmuch$"
921 }
922 ]</code></pre>
923 </div></div>
924 <div class="paragraph"><p>Here you can see that i3 will require both the class and the instance to match.
925 Therefore, if you just start Emacs via dmenu, it will not get swallowed by that
926 container. Only if you start Emacs with the proper instance name (<code>emacs24
927 --name notmuch</code>), it will get swallowed.</p></div>
928 <div class="paragraph"><p>You can match on "class", "instance", "window_role" and "title". All values are
929 case-sensitive regular expressions (PCRE). Use <code>xprop(1)</code> and click into a
930 window to see its properties:</p></div>
931 <div class="listingblock">
932 <div class="content">
933 <pre><code>$ xprop
934 WM_WINDOW_ROLE(STRING) = "gimp-toolbox-color-dialog"
935 WM_CLASS(STRING) = "gimp-2.8", "Gimp-2.8"
936 _NET_WM_NAME(UTF8_STRING) = "Change Foreground Color"</code></pre>
937 </div></div>
938 <div class="paragraph"><p>The first part of <code>WM_CLASS</code> is the "instance" (gimp-2.8 in this case), the
939 second part is the "class" (Gimp-2.8 in this case). "title" matches against
940 <code>_NET_WM_NAME</code> and "window_role" matches against <code>WM_WINDOW_ROLE</code>.</p></div>
941 <div class="paragraph"><p>In general, you should try to be as specific as possible in your swallow
942 criteria. Try to use criteria that match one window and only one window, to
943 have a reliable startup procedure.</p></div>
944 <div class="paragraph"><p>If you specify multiple swallow criteria, the placeholder will be replaced by
945 the window which matches any of the criteria. As an example:</p></div>
946 <div class="listingblock">
947 <div class="content">
948 <pre><code>// Matches either Emacs or Gvim, whichever one is started first.
949 "swallows": [
950 {"class": "^Emacs$"},
951 {"class": "^Gvim$"}
952 ]</code></pre>
953 </div></div>
954 </div>
955 <div class="sect2">
956 <h3 id="_json_standard_non_compliance">3.2. JSON standard non-compliance</h3>
957 <div class="paragraph"><p>A layout file as generated by <code>i3-save-tree(1)</code> is not strictly valid JSON:</p></div>
958 <div class="olist arabic"><ol class="arabic">
959 <li>
960 <p>
961 Layout files contain multiple “JSON texts” at the top level. The JSON
962 standard doesn&#8217;t prohibit this, but in practice most JSON parsers only
963 allow precisely one “text” per document/file, and will mark multiple texts
964 as invalid JSON.
965 </p>
966 </li>
967 <li>
968 <p>
969 Layout files contain comments which are not allowed by the JSON standard,
970 but are understood by many parsers.
971 </p>
972 </li>
973 </ol></div>
974 <div class="paragraph"><p>Both of these deviations from the norm are to make manual editing by humans
975 easier. In case you are writing a more elaborate tool for manipulating these
976 layouts, you can either use a JSON parser that supports these deviations (for
977 example libyajl), transform the layout file to a JSON-conforming file, or
978 <a href="https://github.com/i3/i3/blob/next/.github/CONTRIBUTING.md">submit a patch</a>
979 to make <code>i3-save-tree(1)</code> optionally output standard-conforming JSON.</p></div>
980 </div>
981 </div>
982 </div>
983 <div class="sect1">
984 <h2 id="_troubleshooting">4. Troubleshooting</h2>
985 <div class="sectionbody">
986 <div class="sect2">
987 <h3 id="_restoring_a_vertically_split_workspace">4.1. Restoring a vertically split workspace</h3>
988 <div class="paragraph"><p>When using <code>i3-save-tree</code> with the <code>--workspace</code> switch, only the <strong>contents</strong> of
989 the workspace will be dumped. This means that properties of the workspace
990 itself will be lost.</p></div>
991 <div class="paragraph"><p>This is relevant for, e.g., a vertically split container as the base container of
992 a workspace. Since the split mode is a property of the workspace, it will not be
993 stored. In this case, you will have to manually wrap your layout in such a
994 container:</p></div>
995 <div class="listingblock">
996 <div class="content">
997 <pre><code>// vim:ts=4:sw=4:et
998 {
999 // this is a manually added container to restore the vertical split
1000 "layout": "splitv",
1001 "percent": 0.5,
1002 "type": "con",
1003 "nodes": [
1004
1005 // the dumped workspace layout goes here
1006
1007 ]
1008 }</code></pre>
1009 </div></div>
1010 </div>
1011 <div class="sect2">
1012 <h3 id="_placeholders_using_window_title_matches_don_8217_t_swallow_the_window">4.2. Placeholders using window title matches don&#8217;t swallow the window</h3>
1013 <div class="paragraph"><p>If you use the <code>title</code> attribute to match a window and find that it doesn&#8217;t
1014 work or only works sometimes, the reason might be that the application sets the
1015 title only after making the window visible. This will be especially true for
1016 programs running inside terminal emulators, e.g., <code>urxvt -e irssi</code> when
1017 matching on <code>title: "irssi"</code>.</p></div>
1018 <div class="paragraph"><p>One way to deal with this is to not rely on the title, but instead use, e.g.,
1019 the <code>instance</code> attribute and running the program to set this window instance to
1020 that value:</p></div>
1021 <div class="listingblock">
1022 <div class="content">
1023 <pre><code># Run irssi via
1024 # urxvt -name "irssi-container" -e irssi
1025
1026 "swallows": [
1027 {
1028 "class": "URxvt",
1029 "instance": "irssi-container"
1030 }
1031 ]</code></pre>
1032 </div></div>
1033 </div>
1034 </div>
1035 </div>
1036 </div>
1037 <div id="footnotes"><hr /></div>
1038 <div id="footer">
1039 <div id="footer-text">
1040 Last updated
1041 2019-08-30 23:06:47 CEST
1042 </div>
1043 </div>
1044 </body>
1045 </html>
0 <!doctype html>
1 <html lang="en">
2 <head>
3 <link rel="icon" type="image/png" href="/favicon.png">
4 <meta charset="utf-8">
5 <meta name="generator" content="Pod::Simple::HTML">
6 <meta name="description" content="i3 Perl documentation">
7 <link rel="stylesheet" href="https://i3wm.org/css/style.css" type="text/css" />
8 <style type="text/css">
9 .pod pre {
10 background: #333;
11 border: 1px solid #555;
12 border-left: 5px solid #555;
13 padding: 0.5em;
14 padding-left: 0;
15 padding-right: 0.5em;
16 white-space: pre;
17 color: white;
18 }
19
20 .pod ul {
21 list-style-type: none;
22 }
23 .pod li {
24 margin-bottom: 0 !important;
25 }
26
27 tt {
28 font-family: 'Droid Sans Mono', sans-serif;
29 font-size: inherit;
30 }
31
32 .pod h1 a, .pod h2 a, .pod h3 a, .pod h4 a {
33 text-decoration: none;
34 color: white;
35 }
36 </style>
37 <title>
38 i3test::Test</title>
39 </head>
40 <body>
41
42 <div id="main">
43 <a href="/"><h1 id="title">i3 - improved tiling WM</h1></a>
44 <ul id="nav">
45 <li><a style="border-bottom: 2px solid #fff" href="/docs">Docs</a></li>
46 <li><a href="/screenshots">Screens</a></li>
47 <li><a href="https://www.reddit.com/r/i3wm/">FAQ</a></li>
48 <li><a href="/contact">Contact</a></li>
49 <li><a href="https://bugs.i3wm.org/">Bugs</a></li>
50 </ul>
51 <br style="clear: both">
52 <div id="content" class="pod">
53 <h1>i3 Perl documentation</h1>
54
55 <a name='___top' class='dummyTopAnchor' ></a>
56
57 <div class='indexgroup'>
58 <ul class='indexList indexList1'>
59 <li class='indexItem indexItem1'><a href='#NAME'>NAME</a>
60 <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a>
61 <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a>
62 <li class='indexItem indexItem1'><a href='#EXPORT'>EXPORT</a>
63 <ul class='indexList indexList2'>
64 <li class='indexItem indexItem2'><a href='#is_num_children(%24workspace%2C_%24expected%2C_%24test_name)'>is_num_children($workspace, $expected, $test_name)</a>
65 <li class='indexItem indexItem2'><a href='#is_num_fullscreen(%24workspace%2C_%24expected%2C_%24test_name)'>is_num_fullscreen($workspace, $expected, $test_name)</a>
66 <li class='indexItem indexItem2'><a href='#cmp_float(%24a%2C_%24b)'>cmp_float($a, $b)</a>
67 <li class='indexItem indexItem2'><a href='#does_i3_live'>does_i3_live</a>
68 </ul>
69 <li class='indexItem indexItem1'><a href='#AUTHOR'>AUTHOR</a>
70 </ul>
71 </div>
72
73 <h1><a class='u' href='#___top' title='click to go to top of document'
74 name="NAME"
75 >NAME</a></h1>
76
77 <p>i3test::Test - Additional test instructions for use in i3 testcases</p>
78
79 <h1><a class='u' href='#___top' title='click to go to top of document'
80 name="SYNOPSIS"
81 >SYNOPSIS</a></h1>
82 <pre><tt> use i3test;
83
84 my $ws = fresh_workspace;
85 is_num_children($ws, 0, &#39;no containers on this workspace yet&#39;);
86 cmd &#39;open&#39;;
87 is_num_children($ws, 1, &#39;one container after &#34;open&#34;&#39;);
88
89 done_testing;</tt></pre>
90 <h1><a class='u' href='#___top' title='click to go to top of document'
91 name="DESCRIPTION"
92 >DESCRIPTION</a></h1>
93
94 <p>This module provides convenience methods for i3 testcases. If you notice that a certain pattern is present in 5 or more test cases, it should most likely be moved into this module.</p>
95
96 <h1><a class='u' href='#___top' title='click to go to top of document'
97 name="EXPORT"
98 >EXPORT</a></h1>
99
100 <h2><a class='u' href='#___top' title='click to go to top of document'
101 name="is_num_children($workspace,_$expected,_$test_name)"
102 >is_num_children($workspace, $expected, $test_name)</a></h2>
103
104 <p>Gets the number of children on the given workspace and verifies that they match the expected amount of children.</p>
105 <pre><tt> is_num_children(&#39;1&#39;, 0, &#39;no containers on workspace 1 at startup&#39;);</tt></pre>
106 <h2><a class='u' href='#___top' title='click to go to top of document'
107 name="is_num_fullscreen($workspace,_$expected,_$test_name)"
108 >is_num_fullscreen($workspace, $expected, $test_name)</a></h2>
109
110 <p>Gets the number of fullscreen containers on the given workspace and verifies that they match the expected amount.</p>
111 <pre><tt> is_num_fullscreen(&#39;1&#39;, 0, &#39;no fullscreen containers on workspace 1&#39;);</tt></pre>
112 <h2><a class='u' href='#___top' title='click to go to top of document'
113 name="cmp_float($a,_$b)"
114 >cmp_float($a, $b)</a></h2>
115
116 <p>Compares floating point numbers <code>$a</code> and <code>$b</code> and returns true if they differ less then 1e-6.</p>
117 <pre><tt> $tmp = fresh_workspace;
118
119 open_window for (1..4);
120
121 cmd &#39;resize grow width 10 px or 25 ppt&#39;;
122
123 ($nodes, $focus) = get_ws_content($tmp);
124 ok(cmp_float($nodes-&#62;[0]-&#62;{percent}, 0.166666666666667), &#39;first window got 16%&#39;);
125 ok(cmp_float($nodes-&#62;[1]-&#62;{percent}, 0.166666666666667), &#39;second window got 16%&#39;);
126 ok(cmp_float($nodes-&#62;[2]-&#62;{percent}, 0.166666666666667), &#39;third window got 16%&#39;);
127 ok(cmp_float($nodes-&#62;[3]-&#62;{percent}, 0.50), &#39;fourth window got 50%&#39;);</tt></pre>
128 <h2><a class='u' href='#___top' title='click to go to top of document'
129 name="does_i3_live"
130 >does_i3_live</a></h2>
131
132 <p>Returns true if the layout tree can still be received from i3.</p>
133 <pre><tt> # i3 used to crash on invalid commands in revision X
134 cmd &#39;invalid command&#39;;
135 does_i3_live;</tt></pre>
136 <h1><a class='u' href='#___top' title='click to go to top of document'
137 name="AUTHOR"
138 >AUTHOR</a></h1>
139
140 <p>Michael Stapelberg &#60;[email protected]&#62;</p>
141
142 <!-- end doc -->
143
144 </body></html>
0 <!doctype html>
1 <html lang="en">
2 <head>
3 <link rel="icon" type="image/png" href="/favicon.png">
4 <meta charset="utf-8">
5 <meta name="generator" content="Pod::Simple::HTML">
6 <meta name="description" content="i3 Perl documentation">
7 <link rel="stylesheet" href="https://i3wm.org/css/style.css" type="text/css" />
8 <style type="text/css">
9 .pod pre {
10 background: #333;
11 border: 1px solid #555;
12 border-left: 5px solid #555;
13 padding: 0.5em;
14 padding-left: 0;
15 padding-right: 0.5em;
16 white-space: pre;
17 color: white;
18 }
19
20 .pod ul {
21 list-style-type: none;
22 }
23 .pod li {
24 margin-bottom: 0 !important;
25 }
26
27 tt {
28 font-family: 'Droid Sans Mono', sans-serif;
29 font-size: inherit;
30 }
31
32 .pod h1 a, .pod h2 a, .pod h3 a, .pod h4 a {
33 text-decoration: none;
34 color: white;
35 }
36 </style>
37 <title>
38 i3test</title>
39 </head>
40 <body>
41
42 <div id="main">
43 <a href="/"><h1 id="title">i3 - improved tiling WM</h1></a>
44 <ul id="nav">
45 <li><a style="border-bottom: 2px solid #fff" href="/docs">Docs</a></li>
46 <li><a href="/screenshots">Screens</a></li>
47 <li><a href="https://www.reddit.com/r/i3wm/">FAQ</a></li>
48 <li><a href="/contact">Contact</a></li>
49 <li><a href="https://bugs.i3wm.org/">Bugs</a></li>
50 </ul>
51 <br style="clear: both">
52 <div id="content" class="pod">
53 <h1>i3 Perl documentation</h1>
54
55 <a name='___top' class='dummyTopAnchor' ></a>
56
57 <div class='indexgroup'>
58 <ul class='indexList indexList1'>
59 <li class='indexItem indexItem1'><a href='#NAME'>NAME</a>
60 <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a>
61 <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a>
62 <li class='indexItem indexItem1'><a href='#EXPORT'>EXPORT</a>
63 <ul class='indexList indexList2'>
64 <li class='indexItem indexItem2'><a href='#wait_for_event(%24timeout%2C_%24callback)'>wait_for_event($timeout, $callback)</a>
65 <li class='indexItem indexItem2'><a href='#wait_for_map(%24window)'>wait_for_map($window)</a>
66 <li class='indexItem indexItem2'><a href='#wait_for_unmap(%24window)'>wait_for_unmap($window)</a>
67 <li class='indexItem indexItem2'><a href='#open_window(%5B_%24args_%5D)'>open_window([ $args ])</a>
68 <li class='indexItem indexItem2'><a href='#open_floating_window(%5B_%24args_%5D)'>open_floating_window([ $args ])</a>
69 <li class='indexItem indexItem2'><a href='#get_workspace_names()'>get_workspace_names()</a>
70 <li class='indexItem indexItem2'><a href='#get_output_for_workspace()'>get_output_for_workspace()</a>
71 <li class='indexItem indexItem2'><a href='#get_unused_workspace'>get_unused_workspace</a>
72 <li class='indexItem indexItem2'><a href='#fresh_workspace(%5B_%24args_%5D)'>fresh_workspace([ $args ])</a>
73 <li class='indexItem indexItem2'><a href='#get_ws(%24workspace)'>get_ws($workspace)</a>
74 <li class='indexItem indexItem2'><a href='#get_ws_content(%24workspace)'>get_ws_content($workspace)</a>
75 <li class='indexItem indexItem2'><a href='#get_focused(%24workspace)'>get_focused($workspace)</a>
76 <li class='indexItem indexItem2'><a href='#get_dock_clients(%5B_%24dockarea_%5D)'>get_dock_clients([ $dockarea ])</a>
77 <li class='indexItem indexItem2'><a href='#cmd(%24command)'>cmd($command)</a>
78 <li class='indexItem indexItem2'><a href='#workspace_exists(%24workspace)'>workspace_exists($workspace)</a>
79 <li class='indexItem indexItem2'><a href='#focused_ws'>focused_ws</a>
80 <li class='indexItem indexItem2'><a href='#sync_with_i3(%5B_%24args_%5D)'>sync_with_i3([ $args ])</a>
81 <li class='indexItem indexItem2'><a href='#exit_gracefully(%24pid%2C_%5B_%24socketpath_%5D)'>exit_gracefully($pid, [ $socketpath ])</a>
82 <li class='indexItem indexItem2'><a href='#exit_forcefully(%24pid%2C_%5B_%24signal_%5D)'>exit_forcefully($pid, [ $signal ])</a>
83 <li class='indexItem indexItem2'><a href='#get_socket_path(%5B_%24cache_%5D)'>get_socket_path([ $cache ])</a>
84 <li class='indexItem indexItem2'><a href='#launch_with_config(%24config%2C_%5B_%24args_%5D)'>launch_with_config($config, [ $args ])</a>
85 <li class='indexItem indexItem2'><a href='#get_i3_log'>get_i3_log</a>
86 <li class='indexItem indexItem2'><a href='#kill_all_windows'>kill_all_windows</a>
87 <li class='indexItem indexItem2'><a href='#events_for(%24subscribecb%2C_%5B_%24rettype_%5D%2C_%5B_%24eventcbs_%5D)'>events_for($subscribecb, [ $rettype ], [ $eventcbs ])</a>
88 <li class='indexItem indexItem2'><a href='#listen_for_binding(%24cb)'>listen_for_binding($cb)</a>
89 <li class='indexItem indexItem2'><a href='#is_net_wm_state_focused'>is_net_wm_state_focused</a>
90 <li class='indexItem indexItem2'><a href='#cmp_tree(%5B_%24args_%5D)'>cmp_tree([ $args ])</a>
91 </ul>
92 <li class='indexItem indexItem1'><a href='#AUTHOR'>AUTHOR</a>
93 </ul>
94 </div>
95
96 <h1><a class='u' href='#___top' title='click to go to top of document'
97 name="NAME"
98 >NAME</a></h1>
99
100 <p>i3test - Testcase setup module</p>
101
102 <h1><a class='u' href='#___top' title='click to go to top of document'
103 name="SYNOPSIS"
104 >SYNOPSIS</a></h1>
105 <pre><tt> use i3test;
106
107 my $ws = fresh_workspace;
108 is_num_children($ws, 0, &#39;no containers on this workspace yet&#39;);
109 cmd &#39;open&#39;;
110 is_num_children($ws, 1, &#39;one container after &#34;open&#34;&#39;);
111
112 done_testing;</tt></pre>
113 <h1><a class='u' href='#___top' title='click to go to top of document'
114 name="DESCRIPTION"
115 >DESCRIPTION</a></h1>
116
117 <p>This module is used in every i3 testcase and takes care of automatically starting i3 before any test instructions run. It also saves you typing of lots of boilerplate in every test file.</p>
118
119 <p>i3test automatically &#34;use&#34;s <code>Test::More</code>, <code>Data::Dumper</code>, <code>AnyEvent::I3</code>, <code>Time::HiRes</code>&#8217;s <code>sleep</code> and <code>i3test::Test</code> so that all of them are available to you in your testcase.</p>
120
121 <p>See also <code>i3test::Test</code> (<a href="https://build.i3wm.org/docs/lib-i3test-test.html" class="podlinkurl"
122 >https://build.i3wm.org/docs/lib-i3test-test.html</a>) which provides additional test instructions (like <code>ok</code> or <code>is</code>).</p>
123
124 <h1><a class='u' href='#___top' title='click to go to top of document'
125 name="EXPORT"
126 >EXPORT</a></h1>
127
128 <h2><a class='u' href='#___top' title='click to go to top of document'
129 name="wait_for_event($timeout,_$callback)"
130 >wait_for_event($timeout, $callback)</a></h2>
131
132 <p>Waits for the next event and calls the given callback for every event to determine if this is the event we are waiting for.</p>
133
134 <p>Can be used to wait until a window is mapped, until a ClientMessage is received, etc.</p>
135 <pre><tt> wait_for_event 0.25, sub { $_[0]-&#62;{response_type} == MAP_NOTIFY };</tt></pre>
136 <h2><a class='u' href='#___top' title='click to go to top of document'
137 name="wait_for_map($window)"
138 >wait_for_map($window)</a></h2>
139
140 <p>Thin wrapper around wait_for_event which waits for MAP_NOTIFY. Make sure to include &#39;structure_notify&#39; in the window&#8217;s event_mask attribute.</p>
141
142 <p>This function is called by <code>open_window</code>, so in most cases, you don&#8217;t need to call it on your own. If you need special setup of the window before mapping, you might have to map it on your own and use this function:</p>
143 <pre><tt> my $window = open_window(dont_map =&#62; 1);
144 # Do something special with the window first
145 # &#8230;
146
147 # Now map it and wait until it&#8217;s been mapped
148 $window-&#62;map;
149 wait_for_map($window);</tt></pre>
150 <h2><a class='u' href='#___top' title='click to go to top of document'
151 name="wait_for_unmap($window)"
152 >wait_for_unmap($window)</a></h2>
153
154 <p>Wrapper around <code>wait_for_event</code> which waits for UNMAP_NOTIFY. Also calls <code>sync_with_i3</code> to make sure i3 also picked up and processed the UnmapNotify event.</p>
155 <pre><tt> my $ws = fresh_workspace;
156 my $window = open_window;
157 is_num_children($ws, 1, &#39;one window on workspace&#39;);
158 $window-&#62;unmap;
159 wait_for_unmap;
160 is_num_children($ws, 0, &#39;no more windows on this workspace&#39;);</tt></pre>
161 <h2><a class='u' href='#___top' title='click to go to top of document'
162 name="open_window([_$args_])"
163 >open_window([ $args ])</a></h2>
164
165 <p>Opens a new window (see <code>X11::XCB::Window</code>), maps it, waits until it got mapped and synchronizes with i3.</p>
166
167 <p>The following arguments can be passed:</p>
168
169 <dl>
170 <dt><a name="class"
171 >class</a></dt>
172
173 <dd>
174 <p>The X11 window class (e.g. WINDOW_CLASS_INPUT_OUTPUT), not to be confused with the WM_CLASS!</p>
175
176 <dt><a name="rect"
177 >rect</a></dt>
178
179 <dd>
180 <p>An arrayref with 4 members specifying the initial geometry (position and size) of the window, e.g. <code>[ 0, 100, 70, 50 ]</code> for a window appearing at x=0, y=100 with width=70 and height=50.</p>
181
182 <p>Note that this is entirely irrelevant for tiling windows.</p>
183
184 <dt><a name="background_color"
185 >background_color</a></dt>
186
187 <dd>
188 <p>The background pixel color of the window, formatted as &#34;#rrggbb&#34;, like HTML color codes (e.g. #c0c0c0). This is useful to tell windows apart when actually watching the testcases.</p>
189
190 <dt><a name="event_mask"
191 >event_mask</a></dt>
192
193 <dd>
194 <p>An arrayref containing strings which describe the X11 event mask we use for that window. The default is <code>[ &#39;structure_notify&#39; ]</code>.</p>
195
196 <dt><a name="name"
197 >name</a></dt>
198
199 <dd>
200 <p>The window&#8217;s <code>_NET_WM_NAME</code> (UTF-8 window title). By default, this is &#34;Window n&#34; with n being replaced by a counter to keep windows apart.</p>
201
202 <dt><a name="dont_map"
203 >dont_map</a></dt>
204
205 <dd>
206 <p>Set to a true value to avoid mapping the window (making it visible).</p>
207
208 <dt><a name="before_map"
209 >before_map</a></dt>
210
211 <dd>
212 <p>A coderef which is called before the window is mapped (unless <code>dont_map</code> is true). The freshly created <code>$window</code> is passed as <code>$_</code> and as the first argument.</p>
213 </dd>
214 </dl>
215
216 <p>The default values are equivalent to this call:</p>
217 <pre><tt> open_window(
218 class =&#62; WINDOW_CLASS_INPUT_OUTPUT
219 rect =&#62; [ 0, 0, 30, 30 ]
220 background_color =&#62; &#39;#c0c0c0&#39;
221 event_mask =&#62; [ &#39;structure_notify&#39; ]
222 name =&#62; &#39;Window &#60;n&#62;&#39;
223 );</tt></pre>
224 <p>Usually, though, calls are simpler:</p>
225 <pre><tt> my $top_window = open_window;</tt></pre>
226 <p>To identify the resulting window object in i3 commands, use the id property:</p>
227 <pre><tt> my $top_window = open_window;
228 cmd &#39;[id=&#34;&#39; . $top_window-&#62;id . &#39;&#34;] kill&#39;;</tt></pre>
229 <h2><a class='u' href='#___top' title='click to go to top of document'
230 name="open_floating_window([_$args_])"
231 >open_floating_window([ $args ])</a></h2>
232
233 <p>Thin wrapper around open_window which sets window_type to <code>_NET_WM_WINDOW_TYPE_UTILITY</code> to make the window floating.</p>
234
235 <p>The arguments are the same as those of <code>open_window</code>.</p>
236
237 <h2><a class='u' href='#___top' title='click to go to top of document'
238 name="get_workspace_names()"
239 >get_workspace_names()</a></h2>
240
241 <p>Returns an arrayref containing the name of every workspace (regardless of its output) which currently exists.</p>
242 <pre><tt> my $workspace_names = get_workspace_names;
243 is(scalar @$workspace_names, 3, &#39;three workspaces exist currently&#39;);</tt></pre>
244 <h2><a class='u' href='#___top' title='click to go to top of document'
245 name="get_output_for_workspace()"
246 >get_output_for_workspace()</a></h2>
247
248 <p>Returns the name of the output on which this workspace resides</p>
249 <pre><tt> cmd &#39;focus output fake-1&#39;;
250 cmd &#39;workspace 1&#39;;
251 is(get_output_for_workspace(&#39;1&#39;, &#39;fake-0&#39;, &#39;Workspace 1 in output fake-0&#39;);</tt></pre>
252 <h2><a class='u' href='#___top' title='click to go to top of document'
253 name="get_unused_workspace"
254 >get_unused_workspace</a></h2>
255
256 <p>Returns a workspace name which has not yet been used. See also <code>fresh_workspace</code> which directly switches to an unused workspace.</p>
257 <pre><tt> my $ws = get_unused_workspace;
258 cmd &#34;workspace $ws&#34;;</tt></pre>
259 <h2><a class='u' href='#___top' title='click to go to top of document'
260 name="fresh_workspace([_$args_])"
261 >fresh_workspace([ $args ])</a></h2>
262
263 <p>Switches to an unused workspace and returns the name of that workspace.</p>
264
265 <p>Optionally switches to the specified output first.</p>
266 <pre><tt> my $ws = fresh_workspace;
267
268 # Get a fresh workspace on the second output.
269 my $ws = fresh_workspace(output =&#62; 1);</tt></pre>
270 <h2><a class='u' href='#___top' title='click to go to top of document'
271 name="get_ws($workspace)"
272 >get_ws($workspace)</a></h2>
273
274 <p>Returns the container (from the i3 layout tree) which represents <code>$workspace</code>.</p>
275 <pre><tt> my $ws = fresh_workspace;
276 my $ws_con = get_ws($ws);
277 ok(!$ws_con-&#62;{urgent}, &#39;fresh workspace not marked urgent&#39;);</tt></pre>
278 <p>Here is an example which counts the number of urgent containers recursively, starting from the workspace container:</p>
279 <pre><tt> sub count_urgent {
280 my ($con) = @_;
281
282 my @children = (@{$con-&#62;{nodes}}, @{$con-&#62;{floating_nodes}});
283 my $urgent = grep { $_-&#62;{urgent} } @children;
284 $urgent += count_urgent($_) for @children;
285 return $urgent;
286 }
287 my $urgent = count_urgent(get_ws($ws));
288 is($urgent, 3, &#34;three urgent windows on workspace $ws&#34;);</tt></pre>
289 <h2><a class='u' href='#___top' title='click to go to top of document'
290 name="get_ws_content($workspace)"
291 >get_ws_content($workspace)</a></h2>
292
293 <p>Returns the content (== tree, starting from the node of a workspace) of a workspace. If called in array context, also includes the focus stack of the workspace.</p>
294 <pre><tt> my $nodes = get_ws_content($ws);
295 is(scalar @$nodes, 4, &#39;there are four containers at workspace-level&#39;);</tt></pre>
296 <p>Or, in array context:</p>
297 <pre><tt> my $window = open_window;
298 my ($nodes, $focus) = get_ws_content($ws);
299 is($focus-&#62;[0], $window-&#62;id, &#39;newly opened window focused&#39;);</tt></pre>
300 <p>Note that this function does not do recursion for you! It only returns the containers <b>on workspace level</b>. If you want to work with all containers (even nested ones) on a workspace, you have to use recursion:</p>
301 <pre><tt> # NB: This function does not count floating windows
302 sub count_urgent {
303 my ($nodes) = @_;
304
305 my $urgent = 0;
306 for my $con (@$nodes) {
307 $urgent++ if $con-&#62;{urgent};
308 $urgent += count_urgent($con-&#62;{nodes});
309 }
310
311 return $urgent;
312 }
313 my $nodes = get_ws_content($ws);
314 my $urgent = count_urgent($nodes);
315 is($urgent, 3, &#34;three urgent windows on workspace $ws&#34;);</tt></pre>
316 <p>If you also want to deal with floating windows, you have to use <code>get_ws</code> instead and access <code>-&#62;{nodes}</code> and <code>-&#62;{floating_nodes}</code> on your own.</p>
317
318 <h2><a class='u' href='#___top' title='click to go to top of document'
319 name="get_focused($workspace)"
320 >get_focused($workspace)</a></h2>
321
322 <p>Returns the container ID of the currently focused container on <code>$workspace</code>.</p>
323
324 <p>Note that the container ID is <b>not</b> the X11 window ID, so comparing the result of <code>get_focused</code> with a window&#39;s <code>-&#62;{id}</code> property does <b>not</b> work.</p>
325 <pre><tt> my $ws = fresh_workspace;
326 my $first_window = open_window;
327 my $first_id = get_focused();
328
329 my $second_window = open_window;
330 my $second_id = get_focused();
331
332 cmd &#39;focus left&#39;;
333
334 is(get_focused($ws), $first_id, &#39;second window focused&#39;);</tt></pre>
335 <h2><a class='u' href='#___top' title='click to go to top of document'
336 name="get_dock_clients([_$dockarea_])"
337 >get_dock_clients([ $dockarea ])</a></h2>
338
339 <p>Returns an array of all dock containers in <code>$dockarea</code> (one of &#34;top&#34; or &#34;bottom&#34;). If <code>$dockarea</code> is not specified, returns an array of all dock containers in any dockarea.</p>
340 <pre><tt> my @docked = get_dock_clients;
341 is(scalar @docked, 0, &#39;no dock clients yet&#39;);</tt></pre>
342 <h2><a class='u' href='#___top' title='click to go to top of document'
343 name="cmd($command)"
344 >cmd($command)</a></h2>
345
346 <p>Sends the specified command to i3 and returns the output.</p>
347 <pre><tt> my $ws = unused_workspace;
348 cmd &#34;workspace $ws&#34;;
349 cmd &#39;focus right&#39;;</tt></pre>
350 <h2><a class='u' href='#___top' title='click to go to top of document'
351 name="workspace_exists($workspace)"
352 >workspace_exists($workspace)</a></h2>
353
354 <p>Returns true if <code>$workspace</code> is the name of an existing workspace.</p>
355 <pre><tt> my $old_ws = focused_ws;
356 # switch away from where we currently are
357 fresh_workspace;
358
359 ok(workspace_exists($old_ws), &#39;old workspace still exists&#39;);</tt></pre>
360 <h2><a class='u' href='#___top' title='click to go to top of document'
361 name="focused_ws"
362 >focused_ws</a></h2>
363
364 <p>Returns the name of the currently focused workspace.</p>
365 <pre><tt> my $ws = focused_ws;
366 is($ws, &#39;1&#39;, &#39;i3 starts on workspace 1&#39;);</tt></pre>
367 <h2><a class='u' href='#___top' title='click to go to top of document'
368 name="sync_with_i3([_$args_])"
369 >sync_with_i3([ $args ])</a></h2>
370
371 <p>Sends an I3_SYNC ClientMessage with a random value to the root window. i3 will reply with the same value, but, due to the order of events it processes, only after all other events are done.</p>
372
373 <p>This can be used to ensure the results of a cmd &#39;focus left&#39; are pushed to X11 and that <code>$x-&#62;input_focus</code> returns the correct value afterwards.</p>
374
375 <p>See also <a href="https://build.i3wm.org/docs/testsuite.html" class="podlinkurl"
376 >https://build.i3wm.org/docs/testsuite.html</a> for a longer explanation.</p>
377 <pre><tt> my $window = open_window;
378 $window-&#62;add_hint(&#39;urgency&#39;);
379 # Ensure i3 picked up the change
380 sync_with_i3;</tt></pre>
381 <p>The only time when you need to use the <code>no_cache</code> argument is when you just killed your own X11 connection:</p>
382 <pre><tt> cmd &#39;kill client&#39;;
383 # We need to re-establish the X11 connection which we just killed :).
384 $x = i3test::X11-&#62;new;
385 sync_with_i3(no_cache =&#62; 1);</tt></pre>
386 <h2><a class='u' href='#___top' title='click to go to top of document'
387 name="exit_gracefully($pid,_[_$socketpath_])"
388 >exit_gracefully($pid, [ $socketpath ])</a></h2>
389
390 <p>Tries to exit i3 gracefully (with the &#39;exit&#39; cmd) or kills the PID if that fails.</p>
391
392 <p>If <code>$socketpath</code> is not specified, <code>get_socket_path()</code> will be called.</p>
393
394 <p>You only need to use this function if you have launched i3 on your own with <code>launch_with_config</code>. Otherwise, it will be automatically called when the testcase ends.</p>
395 <pre><tt> use i3test i3_autostart =&#62; 0;
396 my $pid = launch_with_config($config);
397 # &#8230;
398 exit_gracefully($pid);</tt></pre>
399 <h2><a class='u' href='#___top' title='click to go to top of document'
400 name="exit_forcefully($pid,_[_$signal_])"
401 >exit_forcefully($pid, [ $signal ])</a></h2>
402
403 <p>Tries to exit i3 forcefully by sending a signal (defaults to SIGTERM).</p>
404
405 <p>You only need to use this function if you want to test signal handling (in which case you must have launched i3 on your own with <code>launch_with_config</code>).</p>
406 <pre><tt> use i3test i3_autostart =&#62; 0;
407 my $pid = launch_with_config($config);
408 # &#8230;
409 exit_forcefully($pid);</tt></pre>
410 <h2><a class='u' href='#___top' title='click to go to top of document'
411 name="get_socket_path([_$cache_])"
412 >get_socket_path([ $cache ])</a></h2>
413
414 <p>Gets the socket path from the <code>I3_SOCKET_PATH</code> atom stored on the X11 root window. After the first call, this function will return a cached version of the socket path unless you specify a false value for <code>$cache</code>.</p>
415 <pre><tt> my $i3 = i3(get_socket_path());
416 $i3-&#62;command(&#39;nop test example&#39;)-&#62;recv;</tt></pre>
417 <p>To avoid caching:</p>
418 <pre><tt> my $i3 = i3(get_socket_path(0));</tt></pre>
419 <h2><a class='u' href='#___top' title='click to go to top of document'
420 name="launch_with_config($config,_[_$args_])"
421 >launch_with_config($config, [ $args ])</a></h2>
422
423 <p>Launches a new i3 process with <code>$config</code> as configuration file. Useful for tests which test specific config file directives.</p>
424 <pre><tt> use i3test i3_autostart =&#62; 0;
425
426 my $config = &#60;&#60;EOT;
427 # i3 config file (v4)
428 for_window [class=&#34;borderless&#34;] border none
429 for_window [title=&#34;special borderless title&#34;] border none
430 EOT
431
432 my $pid = launch_with_config($config);
433
434 # &#8230;
435
436 exit_gracefully($pid);</tt></pre>
437 <h2><a class='u' href='#___top' title='click to go to top of document'
438 name="get_i3_log"
439 >get_i3_log</a></h2>
440
441 <p>Returns the content of the log file for the current test.</p>
442
443 <h2><a class='u' href='#___top' title='click to go to top of document'
444 name="kill_all_windows"
445 >kill_all_windows</a></h2>
446
447 <p>Kills all windows to clean up between tests.</p>
448
449 <h2><a class='u' href='#___top' title='click to go to top of document'
450 name="events_for($subscribecb,_[_$rettype_],_[_$eventcbs_])"
451 >events_for($subscribecb, [ $rettype ], [ $eventcbs ])</a></h2>
452
453 <p>Helper function which returns an array containing all events of type $rettype which were generated by i3 while $subscribecb was running.</p>
454
455 <p>Set $eventcbs to subscribe to multiple event types and/or perform your own event aggregation.</p>
456
457 <h2><a class='u' href='#___top' title='click to go to top of document'
458 name="listen_for_binding($cb)"
459 >listen_for_binding($cb)</a></h2>
460
461 <p>Helper function to evaluate whether sending KeyPress/KeyRelease events via XTEST triggers an i3 key binding or not. Expects key bindings to be configured in the form &#8220;bindsym &#60;binding&#62; nop &#60;binding&#62;&#8221;, e.g. &#8220;bindsym Mod4+Return nop Mod4+Return&#8221;.</p>
462 <pre><tt> is(listen_for_binding(
463 sub {
464 xtest_key_press(133); # Super_L
465 xtest_key_press(36); # Return
466 xtest_key_release(36); # Return
467 xtest_key_release(133); # Super_L
468 xtest_sync_with_i3;
469 },
470 ),
471 &#39;Mod4+Return&#39;,
472 &#39;triggered the &#34;Mod4+Return&#34; keybinding&#39;);</tt></pre>
473 <h2><a class='u' href='#___top' title='click to go to top of document'
474 name="is_net_wm_state_focused"
475 >is_net_wm_state_focused</a></h2>
476
477 <p>Returns true if the given window has the _NET_WM_STATE_FOCUSED atom.</p>
478 <pre><tt> ok(is_net_wm_state_focused($window), &#39;_NET_WM_STATE_FOCUSED set&#39;);</tt></pre>
479 <h2><a class='u' href='#___top' title='click to go to top of document'
480 name="cmp_tree([_$args_])"
481 >cmp_tree([ $args ])</a></h2>
482
483 <p>Compares the tree layout before and after an operation inside a subtest.</p>
484
485 <p>The following arguments can be passed:</p>
486
487 <dl>
488 <dt><a name="layout_before"
489 >layout_before</a></dt>
490
491 <dd>
492 <p>Required argument. The initial layout to be created. For example, &#39;H[ V[ a* S[ b c ] d ] e ]&#39; or &#39;V[a b] T[c d*]&#39;. The layout will be converted to a JSON file which will be passed to i3&#39;s append_layout command.</p>
493
494 <p>The syntax&#39;s rules, assertions and limitations are:</p>
495
496 <ol>
497 <li>Upper case letters H, V, S, T mean horizontal, vertical, stacked and tabbed layout respectively. They must be followed by an opening square bracket and must be closed with a closing square bracket. Each of the non-leaf containers is marked with their corresponding letter followed by a number indicating the position of the container relative to other containers of the same type. For example, &#39;H[V[xxx] V[xxx] H[xxx]]&#39; will mark the non-leaf containers as H1, V1, V2, H2.</li>
498
499 <li>Spaces are ignored.</li>
500
501 <li>Other alphanumeric characters mean a new window which uses the provided character for its class and name. Eg &#39;H[a b]&#39; will open windows with classes &#39;a&#39; and &#39;b&#39; inside a horizontal split. Windows use a single character for their class, eg &#39;H[xxx]&#39; will open 3 windows with class &#39;x&#39;.</li>
502
503 <li>Asterisks after a window mean that the window must be focused after the layout is loaded. Currently, focusing non-leaf containers must be done manually, in the callback (<code>cb</code>) function.</li>
504 </ol>
505
506 <dt><a name="cb"
507 >cb</a></dt>
508
509 <dd>
510 <p>Subroutine to be called after the layout provided by <code>layout_before</code> is created but before the resulting layout (<code>layout_after</code>) is checked.</p>
511
512 <dt><a name="layout_after"
513 >layout_after</a></dt>
514
515 <dd>
516 <p>Required argument. The final layout in which the tree is expected to be after the callback is called. Uses the same syntax with <code>layout_before</code>. For non-leaf containers, their layout (horizontal, vertical, stacked, tabbed) is compared with the corresponding letter (H, V, S, T). For leaf containers, their name is compared with the provided alphanumeric.</p>
517
518 <dt><a name="ws"
519 >ws</a></dt>
520
521 <dd>
522 <p>The workspace in which the layout will be created. Will switch focus to it. If not provided, a new one is created.</p>
523
524 <dt><a name="msg"
525 >msg</a></dt>
526
527 <dd>
528 <p>Message to prepend to the subtest&#39;s name. If not empty, it will be followed by &#39;: &#39;.</p>
529
530 <dt><a name="dont_kill"
531 >dont_kill</a></dt>
532
533 <dd>
534 <p>By default, all windows are killed before the <code>layout_before</code> layout is loaded. Set to 1 to avoid this.</p>
535 </dd>
536 </dl>
537
538 <h1><a class='u' href='#___top' title='click to go to top of document'
539 name="AUTHOR"
540 >AUTHOR</a></h1>
541
542 <p>Michael Stapelberg &#60;[email protected]&#62;</p>
543
544 <!-- end doc -->
545
546 </body></html>
0 <?xml version="1.0" encoding="UTF-8"?>
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
2 "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
4 <head>
5 <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
6 <meta name="generator" content="AsciiDoc 8.6.10" />
7 <title>The multi-monitor situation</title>
8 <style type="text/css">
9 /* Shared CSS for AsciiDoc xhtml11 and html5 backends */
10
11 /* Default font. */
12 body {
13 font-family: Georgia,serif;
14 }
15
16 /* Title font. */
17 h1, h2, h3, h4, h5, h6,
18 div.title, caption.title,
19 thead, p.table.header,
20 #toctitle,
21 #author, #revnumber, #revdate, #revremark,
22 #footer {
23 font-family: Arial,Helvetica,sans-serif;
24 }
25
26 body {
27 margin: 1em 5% 1em 5%;
28 }
29
30 a {
31 color: blue;
32 text-decoration: underline;
33 }
34 a:visited {
35 color: fuchsia;
36 }
37
38 em {
39 font-style: italic;
40 color: navy;
41 }
42
43 strong {
44 font-weight: bold;
45 color: #083194;
46 }
47
48 h1, h2, h3, h4, h5, h6 {
49 color: #527bbd;
50 margin-top: 1.2em;
51 margin-bottom: 0.5em;
52 line-height: 1.3;
53 }
54
55 h1, h2, h3 {
56 border-bottom: 2px solid silver;
57 }
58 h2 {
59 padding-top: 0.5em;
60 }
61 h3 {
62 float: left;
63 }
64 h3 + * {
65 clear: left;
66 }
67 h5 {
68 font-size: 1.0em;
69 }
70
71 div.sectionbody {
72 margin-left: 0;
73 }
74
75 hr {
76 border: 1px solid silver;
77 }
78
79 p {
80 margin-top: 0.5em;
81 margin-bottom: 0.5em;
82 }
83
84 ul, ol, li > p {
85 margin-top: 0;
86 }
87 ul > li { color: #aaa; }
88 ul > li > * { color: black; }
89
90 .monospaced, code, pre {
91 font-family: "Courier New", Courier, monospace;
92 font-size: inherit;
93 color: navy;
94 padding: 0;
95 margin: 0;
96 }
97 pre {
98 white-space: pre-wrap;
99 }
100
101 #author {
102 color: #527bbd;
103 font-weight: bold;
104 font-size: 1.1em;
105 }
106 #email {
107 }
108 #revnumber, #revdate, #revremark {
109 }
110
111 #footer {
112 font-size: small;
113 border-top: 2px solid silver;
114 padding-top: 0.5em;
115 margin-top: 4.0em;
116 }
117 #footer-text {
118 float: left;
119 padding-bottom: 0.5em;
120 }
121 #footer-badges {
122 float: right;
123 padding-bottom: 0.5em;
124 }
125
126 #preamble {
127 margin-top: 1.5em;
128 margin-bottom: 1.5em;
129 }
130 div.imageblock, div.exampleblock, div.verseblock,
131 div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
132 div.admonitionblock {
133 margin-top: 1.0em;
134 margin-bottom: 1.5em;
135 }
136 div.admonitionblock {
137 margin-top: 2.0em;
138 margin-bottom: 2.0em;
139 margin-right: 10%;
140 color: #606060;
141 }
142
143 div.content { /* Block element content. */
144 padding: 0;
145 }
146
147 /* Block element titles. */
148 div.title, caption.title {
149 color: #527bbd;
150 font-weight: bold;
151 text-align: left;
152 margin-top: 1.0em;
153 margin-bottom: 0.5em;
154 }
155 div.title + * {
156 margin-top: 0;
157 }
158
159 td div.title:first-child {
160 margin-top: 0.0em;
161 }
162 div.content div.title:first-child {
163 margin-top: 0.0em;
164 }
165 div.content + div.title {
166 margin-top: 0.0em;
167 }
168
169 div.sidebarblock > div.content {
170 background: #ffffee;
171 border: 1px solid #dddddd;
172 border-left: 4px solid #f0f0f0;
173 padding: 0.5em;
174 }
175
176 div.listingblock > div.content {
177 border: 1px solid #dddddd;
178 border-left: 5px solid #f0f0f0;
179 background: #f8f8f8;
180 padding: 0.5em;
181 }
182
183 div.quoteblock, div.verseblock {
184 padding-left: 1.0em;
185 margin-left: 1.0em;
186 margin-right: 10%;
187 border-left: 5px solid #f0f0f0;
188 color: #888;
189 }
190
191 div.quoteblock > div.attribution {
192 padding-top: 0.5em;
193 text-align: right;
194 }
195
196 div.verseblock > pre.content {
197 font-family: inherit;
198 font-size: inherit;
199 }
200 div.verseblock > div.attribution {
201 padding-top: 0.75em;
202 text-align: left;
203 }
204 /* DEPRECATED: Pre version 8.2.7 verse style literal block. */
205 div.verseblock + div.attribution {
206 text-align: left;
207 }
208
209 div.admonitionblock .icon {
210 vertical-align: top;
211 font-size: 1.1em;
212 font-weight: bold;
213 text-decoration: underline;
214 color: #527bbd;
215 padding-right: 0.5em;
216 }
217 div.admonitionblock td.content {
218 padding-left: 0.5em;
219 border-left: 3px solid #dddddd;
220 }
221
222 div.exampleblock > div.content {
223 border-left: 3px solid #dddddd;
224 padding-left: 0.5em;
225 }
226
227 div.imageblock div.content { padding-left: 0; }
228 span.image img { border-style: none; vertical-align: text-bottom; }
229 a.image:visited { color: white; }
230
231 dl {
232 margin-top: 0.8em;
233 margin-bottom: 0.8em;
234 }
235 dt {
236 margin-top: 0.5em;
237 margin-bottom: 0;
238 font-style: normal;
239 color: navy;
240 }
241 dd > *:first-child {
242 margin-top: 0.1em;
243 }
244
245 ul, ol {
246 list-style-position: outside;
247 }
248 ol.arabic {
249 list-style-type: decimal;
250 }
251 ol.loweralpha {
252 list-style-type: lower-alpha;
253 }
254 ol.upperalpha {
255 list-style-type: upper-alpha;
256 }
257 ol.lowerroman {
258 list-style-type: lower-roman;
259 }
260 ol.upperroman {
261 list-style-type: upper-roman;
262 }
263
264 div.compact ul, div.compact ol,
265 div.compact p, div.compact p,
266 div.compact div, div.compact div {
267 margin-top: 0.1em;
268 margin-bottom: 0.1em;
269 }
270
271 tfoot {
272 font-weight: bold;
273 }
274 td > div.verse {
275 white-space: pre;
276 }
277
278 div.hdlist {
279 margin-top: 0.8em;
280 margin-bottom: 0.8em;
281 }
282 div.hdlist tr {
283 padding-bottom: 15px;
284 }
285 dt.hdlist1.strong, td.hdlist1.strong {
286 font-weight: bold;
287 }
288 td.hdlist1 {
289 vertical-align: top;
290 font-style: normal;
291 padding-right: 0.8em;
292 color: navy;
293 }
294 td.hdlist2 {
295 vertical-align: top;
296 }
297 div.hdlist.compact tr {
298 margin: 0;
299 padding-bottom: 0;
300 }
301
302 .comment {
303 background: yellow;
304 }
305
306 .footnote, .footnoteref {
307 font-size: 0.8em;
308 }
309
310 span.footnote, span.footnoteref {
311 vertical-align: super;
312 }
313
314 #footnotes {
315 margin: 20px 0 20px 0;
316 padding: 7px 0 0 0;
317 }
318
319 #footnotes div.footnote {
320 margin: 0 0 5px 0;
321 }
322
323 #footnotes hr {
324 border: none;
325 border-top: 1px solid silver;
326 height: 1px;
327 text-align: left;
328 margin-left: 0;
329 width: 20%;
330 min-width: 100px;
331 }
332
333 div.colist td {
334 padding-right: 0.5em;
335 padding-bottom: 0.3em;
336 vertical-align: top;
337 }
338 div.colist td img {
339 margin-top: 0.3em;
340 }
341
342 @media print {
343 #footer-badges { display: none; }
344 }
345
346 #toc {
347 margin-bottom: 2.5em;
348 }
349
350 #toctitle {
351 color: #527bbd;
352 font-size: 1.1em;
353 font-weight: bold;
354 margin-top: 1.0em;
355 margin-bottom: 0.1em;
356 }
357
358 div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
359 margin-top: 0;
360 margin-bottom: 0;
361 }
362 div.toclevel2 {
363 margin-left: 2em;
364 font-size: 0.9em;
365 }
366 div.toclevel3 {
367 margin-left: 4em;
368 font-size: 0.9em;
369 }
370 div.toclevel4 {
371 margin-left: 6em;
372 font-size: 0.9em;
373 }
374
375 span.aqua { color: aqua; }
376 span.black { color: black; }
377 span.blue { color: blue; }
378 span.fuchsia { color: fuchsia; }
379 span.gray { color: gray; }
380 span.green { color: green; }
381 span.lime { color: lime; }
382 span.maroon { color: maroon; }
383 span.navy { color: navy; }
384 span.olive { color: olive; }
385 span.purple { color: purple; }
386 span.red { color: red; }
387 span.silver { color: silver; }
388 span.teal { color: teal; }
389 span.white { color: white; }
390 span.yellow { color: yellow; }
391
392 span.aqua-background { background: aqua; }
393 span.black-background { background: black; }
394 span.blue-background { background: blue; }
395 span.fuchsia-background { background: fuchsia; }
396 span.gray-background { background: gray; }
397 span.green-background { background: green; }
398 span.lime-background { background: lime; }
399 span.maroon-background { background: maroon; }
400 span.navy-background { background: navy; }
401 span.olive-background { background: olive; }
402 span.purple-background { background: purple; }
403 span.red-background { background: red; }
404 span.silver-background { background: silver; }
405 span.teal-background { background: teal; }
406 span.white-background { background: white; }
407 span.yellow-background { background: yellow; }
408
409 span.big { font-size: 2em; }
410 span.small { font-size: 0.6em; }
411
412 span.underline { text-decoration: underline; }
413 span.overline { text-decoration: overline; }
414 span.line-through { text-decoration: line-through; }
415
416 div.unbreakable { page-break-inside: avoid; }
417
418
419 /*
420 * xhtml11 specific
421 *
422 * */
423
424 div.tableblock {
425 margin-top: 1.0em;
426 margin-bottom: 1.5em;
427 }
428 div.tableblock > table {
429 border: 3px solid #527bbd;
430 }
431 thead, p.table.header {
432 font-weight: bold;
433 color: #527bbd;
434 }
435 p.table {
436 margin-top: 0;
437 }
438 /* Because the table frame attribute is overriden by CSS in most browsers. */
439 div.tableblock > table[frame="void"] {
440 border-style: none;
441 }
442 div.tableblock > table[frame="hsides"] {
443 border-left-style: none;
444 border-right-style: none;
445 }
446 div.tableblock > table[frame="vsides"] {
447 border-top-style: none;
448 border-bottom-style: none;
449 }
450
451
452 /*
453 * html5 specific
454 *
455 * */
456
457 table.tableblock {
458 margin-top: 1.0em;
459 margin-bottom: 1.5em;
460 }
461 thead, p.tableblock.header {
462 font-weight: bold;
463 color: #527bbd;
464 }
465 p.tableblock {
466 margin-top: 0;
467 }
468 table.tableblock {
469 border-width: 3px;
470 border-spacing: 0px;
471 border-style: solid;
472 border-color: #527bbd;
473 border-collapse: collapse;
474 }
475 th.tableblock, td.tableblock {
476 border-width: 1px;
477 padding: 4px;
478 border-style: solid;
479 border-color: #527bbd;
480 }
481
482 table.tableblock.frame-topbot {
483 border-left-style: hidden;
484 border-right-style: hidden;
485 }
486 table.tableblock.frame-sides {
487 border-top-style: hidden;
488 border-bottom-style: hidden;
489 }
490 table.tableblock.frame-none {
491 border-style: hidden;
492 }
493
494 th.tableblock.halign-left, td.tableblock.halign-left {
495 text-align: left;
496 }
497 th.tableblock.halign-center, td.tableblock.halign-center {
498 text-align: center;
499 }
500 th.tableblock.halign-right, td.tableblock.halign-right {
501 text-align: right;
502 }
503
504 th.tableblock.valign-top, td.tableblock.valign-top {
505 vertical-align: top;
506 }
507 th.tableblock.valign-middle, td.tableblock.valign-middle {
508 vertical-align: middle;
509 }
510 th.tableblock.valign-bottom, td.tableblock.valign-bottom {
511 vertical-align: bottom;
512 }
513
514
515 /*
516 * manpage specific
517 *
518 * */
519
520 body.manpage h1 {
521 padding-top: 0.5em;
522 padding-bottom: 0.5em;
523 border-top: 2px solid silver;
524 border-bottom: 2px solid silver;
525 }
526 body.manpage h2 {
527 border-style: none;
528 }
529 body.manpage div.sectionbody {
530 margin-left: 3em;
531 }
532
533 @media print {
534 body.manpage div#toc { display: none; }
535 }
536
537
538 </style>
539 <script type="text/javascript">
540 /*<![CDATA[*/
541 var asciidoc = { // Namespace.
542
543 /////////////////////////////////////////////////////////////////////
544 // Table Of Contents generator
545 /////////////////////////////////////////////////////////////////////
546
547 /* Author: Mihai Bazon, September 2002
548 * http://students.infoiasi.ro/~mishoo
549 *
550 * Table Of Content generator
551 * Version: 0.4
552 *
553 * Feel free to use this script under the terms of the GNU General Public
554 * License, as long as you do not remove or alter this notice.
555 */
556
557 /* modified by Troy D. Hanson, September 2006. License: GPL */
558 /* modified by Stuart Rackham, 2006, 2009. License: GPL */
559
560 // toclevels = 1..4.
561 toc: function (toclevels) {
562
563 function getText(el) {
564 var text = "";
565 for (var i = el.firstChild; i != null; i = i.nextSibling) {
566 if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
567 text += i.data;
568 else if (i.firstChild != null)
569 text += getText(i);
570 }
571 return text;
572 }
573
574 function TocEntry(el, text, toclevel) {
575 this.element = el;
576 this.text = text;
577 this.toclevel = toclevel;
578 }
579
580 function tocEntries(el, toclevels) {
581 var result = new Array;
582 var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
583 // Function that scans the DOM tree for header elements (the DOM2
584 // nodeIterator API would be a better technique but not supported by all
585 // browsers).
586 var iterate = function (el) {
587 for (var i = el.firstChild; i != null; i = i.nextSibling) {
588 if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
589 var mo = re.exec(i.tagName);
590 if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
591 result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
592 }
593 iterate(i);
594 }
595 }
596 }
597 iterate(el);
598 return result;
599 }
600
601 var toc = document.getElementById("toc");
602 if (!toc) {
603 return;
604 }
605
606 // Delete existing TOC entries in case we're reloading the TOC.
607 var tocEntriesToRemove = [];
608 var i;
609 for (i = 0; i < toc.childNodes.length; i++) {
610 var entry = toc.childNodes[i];
611 if (entry.nodeName.toLowerCase() == 'div'
612 && entry.getAttribute("class")
613 && entry.getAttribute("class").match(/^toclevel/))
614 tocEntriesToRemove.push(entry);
615 }
616 for (i = 0; i < tocEntriesToRemove.length; i++) {
617 toc.removeChild(tocEntriesToRemove[i]);
618 }
619
620 // Rebuild TOC entries.
621 var entries = tocEntries(document.getElementById("content"), toclevels);
622 for (var i = 0; i < entries.length; ++i) {
623 var entry = entries[i];
624 if (entry.element.id == "")
625 entry.element.id = "_toc_" + i;
626 var a = document.createElement("a");
627 a.href = "#" + entry.element.id;
628 a.appendChild(document.createTextNode(entry.text));
629 var div = document.createElement("div");
630 div.appendChild(a);
631 div.className = "toclevel" + entry.toclevel;
632 toc.appendChild(div);
633 }
634 if (entries.length == 0)
635 toc.parentNode.removeChild(toc);
636 },
637
638
639 /////////////////////////////////////////////////////////////////////
640 // Footnotes generator
641 /////////////////////////////////////////////////////////////////////
642
643 /* Based on footnote generation code from:
644 * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
645 */
646
647 footnotes: function () {
648 // Delete existing footnote entries in case we're reloading the footnodes.
649 var i;
650 var noteholder = document.getElementById("footnotes");
651 if (!noteholder) {
652 return;
653 }
654 var entriesToRemove = [];
655 for (i = 0; i < noteholder.childNodes.length; i++) {
656 var entry = noteholder.childNodes[i];
657 if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
658 entriesToRemove.push(entry);
659 }
660 for (i = 0; i < entriesToRemove.length; i++) {
661 noteholder.removeChild(entriesToRemove[i]);
662 }
663
664 // Rebuild footnote entries.
665 var cont = document.getElementById("content");
666 var spans = cont.getElementsByTagName("span");
667 var refs = {};
668 var n = 0;
669 for (i=0; i<spans.length; i++) {
670 if (spans[i].className == "footnote") {
671 n++;
672 var note = spans[i].getAttribute("data-note");
673 if (!note) {
674 // Use [\s\S] in place of . so multi-line matches work.
675 // Because JavaScript has no s (dotall) regex flag.
676 note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
677 spans[i].innerHTML =
678 "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
679 "' title='View footnote' class='footnote'>" + n + "</a>]";
680 spans[i].setAttribute("data-note", note);
681 }
682 noteholder.innerHTML +=
683 "<div class='footnote' id='_footnote_" + n + "'>" +
684 "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
685 n + "</a>. " + note + "</div>";
686 var id =spans[i].getAttribute("id");
687 if (id != null) refs["#"+id] = n;
688 }
689 }
690 if (n == 0)
691 noteholder.parentNode.removeChild(noteholder);
692 else {
693 // Process footnoterefs.
694 for (i=0; i<spans.length; i++) {
695 if (spans[i].className == "footnoteref") {
696 var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
697 href = href.match(/#.*/)[0]; // Because IE return full URL.
698 n = refs[href];
699 spans[i].innerHTML =
700 "[<a href='#_footnote_" + n +
701 "' title='View footnote' class='footnote'>" + n + "</a>]";
702 }
703 }
704 }
705 },
706
707 install: function(toclevels) {
708 var timerId;
709
710 function reinstall() {
711 asciidoc.footnotes();
712 if (toclevels) {
713 asciidoc.toc(toclevels);
714 }
715 }
716
717 function reinstallAndRemoveTimer() {
718 clearInterval(timerId);
719 reinstall();
720 }
721
722 timerId = setInterval(reinstall, 500);
723 if (document.addEventListener)
724 document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
725 else
726 window.onload = reinstallAndRemoveTimer;
727 }
728
729 }
730 asciidoc.install(2);
731 /*]]>*/
732 </script>
733 </head>
734 <body class="article">
735 <div id="header">
736 <h1>The multi-monitor situation</h1>
737 <span id="author">Michael Stapelberg</span><br />
738 <span id="email"><code>&lt;<a href="mailto:[email protected]">[email protected]</a>&gt;</code></span><br />
739 <span id="revdate">April 2013</span>
740 <div id="toc">
741 <div id="toctitle">Table of Contents</div>
742 <noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
743 </div>
744 </div>
745 <div id="content">
746 <div id="preamble">
747 <div class="sectionbody">
748 <div class="paragraph"><p>Please upgrade your nVidia driver to version 302.17 or newer and i3 will just
749 work. This document is kept around for historic reasons only.</p></div>
750 </div>
751 </div>
752 <div class="sect1">
753 <h2 id="_the_quick_fix">1. The quick fix</h2>
754 <div class="sectionbody">
755 <div class="paragraph"><p>If you are using the nVidia binary graphics driver (also known as <em>blob</em>)
756 before version 302.17, you need to use the <code>--force-xinerama</code> flag (in your
757 .xsession) when starting i3, like so:</p></div>
758 <div class="listingblock">
759 <div class="title">Example:</div>
760 <div class="content">
761 <pre><code>exec i3 --force-xinerama -V &gt;&gt;~/.i3/i3log 2&gt;&amp;1</code></pre>
762 </div></div>
763 <div class="paragraph"><p>…or use <code>force_xinerama yes</code> in your configuration file.</p></div>
764 </div>
765 </div>
766 <div class="sect1">
767 <h2 id="_the_explanation">2. The explanation</h2>
768 <div class="sectionbody">
769 <div class="paragraph"><p>Starting with version 3.ε, i3 uses the RandR (Rotate and Resize) API instead
770 of Xinerama. The reason for this, is that RandR provides more information
771 about your outputs and connected screens than Xinerama does. To be specific,
772 the code which handled on-the-fly screen reconfiguration (meaning without
773 restarting the X server) was a very messy heuristic and most of the time did
774 not work correctly&#8201;&#8212;&#8201;that is just not possible with the little information
775 Xinerama offers (just a list of screen resolutions, no identifiers for the
776 screens or any additional information). Xinerama simply was not designed
777 for dynamic configuration.</p></div>
778 <div class="paragraph"><p>So RandR came along, as a more powerful alternative (RandR 1.2 to be specific).
779 It offers all of Xinerama’s possibilities and lots more. Using the RandR API
780 made our code much more robust and clean. Also, you can now reliably assign
781 workspaces to output names instead of some rather unreliable screen identifier
782 (position inside the list of screens, which could change, and so on…).</p></div>
783 <div class="paragraph"><p>As RandR has been around for about three years as of this writing, it seemed
784 like a very good idea to us, and it still is a very good one. What we did not
785 expect, however, was the nVidia binary driver. It still does not support RandR
786 (as of March 2010), even though nVidia has announced that it will support RandR
787 eventually. What does this mean for you, if you are stuck with the binary
788 driver for some reason (say the free drivers don’t work with your card)? First
789 of all, you are stuck with TwinView and cannot use <code>xrandr</code>. While this ruins
790 the user experience, the more grave problem is that the nVidia driver not only
791 does not support dynamic configuration using RandR, it also does not expose
792 correct multi-monitor information via the RandR API. So, in some setups, i3
793 will not find any screens; in others, it will find one large screen which
794 actually contains both of your physical screens (but it will not know that
795 these are two screens).</p></div>
796 <div class="paragraph"><p>For this very reason, we decided to implement the following workaround: As
797 long as the nVidia driver does not support RandR, an option called
798 <code>--force-xinerama</code> is available in i3 (alternatively, you can use the
799 <code>force_xinerama</code> configuration file directive). This option gets the list of
800 screens <strong>once</strong> when starting, and never updates it. As the nVidia driver cannot
801 do dynamic configuration anyways, this is not a big deal.</p></div>
802 <div class="paragraph"><p>Also note that your output names are not descriptive (like <code>HDMI1</code>) when using
803 Xinerama, instead they are counted up, starting at 0: <code>xinerama-0</code>, <code>xinerama-1</code>, …</p></div>
804 </div>
805 </div>
806 <div class="sect1">
807 <h2 id="_see_also">3. See also</h2>
808 <div class="sectionbody">
809 <div class="paragraph"><p>For more information on how to use multi-monitor setups, see the i3 User’s
810 Guide.</p></div>
811 </div>
812 </div>
813 </div>
814 <div id="footnotes"><hr /></div>
815 <div id="footer">
816 <div id="footer-text">
817 Last updated
818 2019-08-30 23:06:47 CEST
819 </div>
820 </div>
821 </body>
822 </html>
0 <?xml version="1.0" encoding="UTF-8"?>
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
2 "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
4 <head>
5 <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
6 <meta name="generator" content="AsciiDoc 8.6.10" />
7 <title>i3 testsuite</title>
8 <style type="text/css">
9 /* Shared CSS for AsciiDoc xhtml11 and html5 backends */
10
11 /* Default font. */
12 body {
13 font-family: Georgia,serif;
14 }
15
16 /* Title font. */
17 h1, h2, h3, h4, h5, h6,
18 div.title, caption.title,
19 thead, p.table.header,
20 #toctitle,
21 #author, #revnumber, #revdate, #revremark,
22 #footer {
23 font-family: Arial,Helvetica,sans-serif;
24 }
25
26 body {
27 margin: 1em 5% 1em 5%;
28 }
29
30 a {
31 color: blue;
32 text-decoration: underline;
33 }
34 a:visited {
35 color: fuchsia;
36 }
37
38 em {
39 font-style: italic;
40 color: navy;
41 }
42
43 strong {
44 font-weight: bold;
45 color: #083194;
46 }
47
48 h1, h2, h3, h4, h5, h6 {
49 color: #527bbd;
50 margin-top: 1.2em;
51 margin-bottom: 0.5em;
52 line-height: 1.3;
53 }
54
55 h1, h2, h3 {
56 border-bottom: 2px solid silver;
57 }
58 h2 {
59 padding-top: 0.5em;
60 }
61 h3 {
62 float: left;
63 }
64 h3 + * {
65 clear: left;
66 }
67 h5 {
68 font-size: 1.0em;
69 }
70
71 div.sectionbody {
72 margin-left: 0;
73 }
74
75 hr {
76 border: 1px solid silver;
77 }
78
79 p {
80 margin-top: 0.5em;
81 margin-bottom: 0.5em;
82 }
83
84 ul, ol, li > p {
85 margin-top: 0;
86 }
87 ul > li { color: #aaa; }
88 ul > li > * { color: black; }
89
90 .monospaced, code, pre {
91 font-family: "Courier New", Courier, monospace;
92 font-size: inherit;
93 color: navy;
94 padding: 0;
95 margin: 0;
96 }
97 pre {
98 white-space: pre-wrap;
99 }
100
101 #author {
102 color: #527bbd;
103 font-weight: bold;
104 font-size: 1.1em;
105 }
106 #email {
107 }
108 #revnumber, #revdate, #revremark {
109 }
110
111 #footer {
112 font-size: small;
113 border-top: 2px solid silver;
114 padding-top: 0.5em;
115 margin-top: 4.0em;
116 }
117 #footer-text {
118 float: left;
119 padding-bottom: 0.5em;
120 }
121 #footer-badges {
122 float: right;
123 padding-bottom: 0.5em;
124 }
125
126 #preamble {
127 margin-top: 1.5em;
128 margin-bottom: 1.5em;
129 }
130 div.imageblock, div.exampleblock, div.verseblock,
131 div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
132 div.admonitionblock {
133 margin-top: 1.0em;
134 margin-bottom: 1.5em;
135 }
136 div.admonitionblock {
137 margin-top: 2.0em;
138 margin-bottom: 2.0em;
139 margin-right: 10%;
140 color: #606060;
141 }
142
143 div.content { /* Block element content. */
144 padding: 0;
145 }
146
147 /* Block element titles. */
148 div.title, caption.title {
149 color: #527bbd;
150 font-weight: bold;
151 text-align: left;
152 margin-top: 1.0em;
153 margin-bottom: 0.5em;
154 }
155 div.title + * {
156 margin-top: 0;
157 }
158
159 td div.title:first-child {
160 margin-top: 0.0em;
161 }
162 div.content div.title:first-child {
163 margin-top: 0.0em;
164 }
165 div.content + div.title {
166 margin-top: 0.0em;
167 }
168
169 div.sidebarblock > div.content {
170 background: #ffffee;
171 border: 1px solid #dddddd;
172 border-left: 4px solid #f0f0f0;
173 padding: 0.5em;
174 }
175
176 div.listingblock > div.content {
177 border: 1px solid #dddddd;
178 border-left: 5px solid #f0f0f0;
179 background: #f8f8f8;
180 padding: 0.5em;
181 }
182
183 div.quoteblock, div.verseblock {
184 padding-left: 1.0em;
185 margin-left: 1.0em;
186 margin-right: 10%;
187 border-left: 5px solid #f0f0f0;
188 color: #888;
189 }
190
191 div.quoteblock > div.attribution {
192 padding-top: 0.5em;
193 text-align: right;
194 }
195
196 div.verseblock > pre.content {
197 font-family: inherit;
198 font-size: inherit;
199 }
200 div.verseblock > div.attribution {
201 padding-top: 0.75em;
202 text-align: left;
203 }
204 /* DEPRECATED: Pre version 8.2.7 verse style literal block. */
205 div.verseblock + div.attribution {
206 text-align: left;
207 }
208
209 div.admonitionblock .icon {
210 vertical-align: top;
211 font-size: 1.1em;
212 font-weight: bold;
213 text-decoration: underline;
214 color: #527bbd;
215 padding-right: 0.5em;
216 }
217 div.admonitionblock td.content {
218 padding-left: 0.5em;
219 border-left: 3px solid #dddddd;
220 }
221
222 div.exampleblock > div.content {
223 border-left: 3px solid #dddddd;
224 padding-left: 0.5em;
225 }
226
227 div.imageblock div.content { padding-left: 0; }
228 span.image img { border-style: none; vertical-align: text-bottom; }
229 a.image:visited { color: white; }
230
231 dl {
232 margin-top: 0.8em;
233 margin-bottom: 0.8em;
234 }
235 dt {
236 margin-top: 0.5em;
237 margin-bottom: 0;
238 font-style: normal;
239 color: navy;
240 }
241 dd > *:first-child {
242 margin-top: 0.1em;
243 }
244
245 ul, ol {
246 list-style-position: outside;
247 }
248 ol.arabic {
249 list-style-type: decimal;
250 }
251 ol.loweralpha {
252 list-style-type: lower-alpha;
253 }
254 ol.upperalpha {
255 list-style-type: upper-alpha;
256 }
257 ol.lowerroman {
258 list-style-type: lower-roman;
259 }
260 ol.upperroman {
261 list-style-type: upper-roman;
262 }
263
264 div.compact ul, div.compact ol,
265 div.compact p, div.compact p,
266 div.compact div, div.compact div {
267 margin-top: 0.1em;
268 margin-bottom: 0.1em;
269 }
270
271 tfoot {
272 font-weight: bold;
273 }
274 td > div.verse {
275 white-space: pre;
276 }
277
278 div.hdlist {
279 margin-top: 0.8em;
280 margin-bottom: 0.8em;
281 }
282 div.hdlist tr {
283 padding-bottom: 15px;
284 }
285 dt.hdlist1.strong, td.hdlist1.strong {
286 font-weight: bold;
287 }
288 td.hdlist1 {
289 vertical-align: top;
290 font-style: normal;
291 padding-right: 0.8em;
292 color: navy;
293 }
294 td.hdlist2 {
295 vertical-align: top;
296 }
297 div.hdlist.compact tr {
298 margin: 0;
299 padding-bottom: 0;
300 }
301
302 .comment {
303 background: yellow;
304 }
305
306 .footnote, .footnoteref {
307 font-size: 0.8em;
308 }
309
310 span.footnote, span.footnoteref {
311 vertical-align: super;
312 }
313
314 #footnotes {
315 margin: 20px 0 20px 0;
316 padding: 7px 0 0 0;
317 }
318
319 #footnotes div.footnote {
320 margin: 0 0 5px 0;
321 }
322
323 #footnotes hr {
324 border: none;
325 border-top: 1px solid silver;
326 height: 1px;
327 text-align: left;
328 margin-left: 0;
329 width: 20%;
330 min-width: 100px;
331 }
332
333 div.colist td {
334 padding-right: 0.5em;
335 padding-bottom: 0.3em;
336 vertical-align: top;
337 }
338 div.colist td img {
339 margin-top: 0.3em;
340 }
341
342 @media print {
343 #footer-badges { display: none; }
344 }
345
346 #toc {
347 margin-bottom: 2.5em;
348 }
349
350 #toctitle {
351 color: #527bbd;
352 font-size: 1.1em;
353 font-weight: bold;
354 margin-top: 1.0em;
355 margin-bottom: 0.1em;
356 }
357
358 div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
359 margin-top: 0;
360 margin-bottom: 0;
361 }
362 div.toclevel2 {
363 margin-left: 2em;
364 font-size: 0.9em;
365 }
366 div.toclevel3 {
367 margin-left: 4em;
368 font-size: 0.9em;
369 }
370 div.toclevel4 {
371 margin-left: 6em;
372 font-size: 0.9em;
373 }
374
375 span.aqua { color: aqua; }
376 span.black { color: black; }
377 span.blue { color: blue; }
378 span.fuchsia { color: fuchsia; }
379 span.gray { color: gray; }
380 span.green { color: green; }
381 span.lime { color: lime; }
382 span.maroon { color: maroon; }
383 span.navy { color: navy; }
384 span.olive { color: olive; }
385 span.purple { color: purple; }
386 span.red { color: red; }
387 span.silver { color: silver; }
388 span.teal { color: teal; }
389 span.white { color: white; }
390 span.yellow { color: yellow; }
391
392 span.aqua-background { background: aqua; }
393 span.black-background { background: black; }
394 span.blue-background { background: blue; }
395 span.fuchsia-background { background: fuchsia; }
396 span.gray-background { background: gray; }
397 span.green-background { background: green; }
398 span.lime-background { background: lime; }
399 span.maroon-background { background: maroon; }
400 span.navy-background { background: navy; }
401 span.olive-background { background: olive; }
402 span.purple-background { background: purple; }
403 span.red-background { background: red; }
404 span.silver-background { background: silver; }
405 span.teal-background { background: teal; }
406 span.white-background { background: white; }
407 span.yellow-background { background: yellow; }
408
409 span.big { font-size: 2em; }
410 span.small { font-size: 0.6em; }
411
412 span.underline { text-decoration: underline; }
413 span.overline { text-decoration: overline; }
414 span.line-through { text-decoration: line-through; }
415
416 div.unbreakable { page-break-inside: avoid; }
417
418
419 /*
420 * xhtml11 specific
421 *
422 * */
423
424 div.tableblock {
425 margin-top: 1.0em;
426 margin-bottom: 1.5em;
427 }
428 div.tableblock > table {
429 border: 3px solid #527bbd;
430 }
431 thead, p.table.header {
432 font-weight: bold;
433 color: #527bbd;
434 }
435 p.table {
436 margin-top: 0;
437 }
438 /* Because the table frame attribute is overriden by CSS in most browsers. */
439 div.tableblock > table[frame="void"] {
440 border-style: none;
441 }
442 div.tableblock > table[frame="hsides"] {
443 border-left-style: none;
444 border-right-style: none;
445 }
446 div.tableblock > table[frame="vsides"] {
447 border-top-style: none;
448 border-bottom-style: none;
449 }
450
451
452 /*
453 * html5 specific
454 *
455 * */
456
457 table.tableblock {
458 margin-top: 1.0em;
459 margin-bottom: 1.5em;
460 }
461 thead, p.tableblock.header {
462 font-weight: bold;
463 color: #527bbd;
464 }
465 p.tableblock {
466 margin-top: 0;
467 }
468 table.tableblock {
469 border-width: 3px;
470 border-spacing: 0px;
471 border-style: solid;
472 border-color: #527bbd;
473 border-collapse: collapse;
474 }
475 th.tableblock, td.tableblock {
476 border-width: 1px;
477 padding: 4px;
478 border-style: solid;
479 border-color: #527bbd;
480 }
481
482 table.tableblock.frame-topbot {
483 border-left-style: hidden;
484 border-right-style: hidden;
485 }
486 table.tableblock.frame-sides {
487 border-top-style: hidden;
488 border-bottom-style: hidden;
489 }
490 table.tableblock.frame-none {
491 border-style: hidden;
492 }
493
494 th.tableblock.halign-left, td.tableblock.halign-left {
495 text-align: left;
496 }
497 th.tableblock.halign-center, td.tableblock.halign-center {
498 text-align: center;
499 }
500 th.tableblock.halign-right, td.tableblock.halign-right {
501 text-align: right;
502 }
503
504 th.tableblock.valign-top, td.tableblock.valign-top {
505 vertical-align: top;
506 }
507 th.tableblock.valign-middle, td.tableblock.valign-middle {
508 vertical-align: middle;
509 }
510 th.tableblock.valign-bottom, td.tableblock.valign-bottom {
511 vertical-align: bottom;
512 }
513
514
515 /*
516 * manpage specific
517 *
518 * */
519
520 body.manpage h1 {
521 padding-top: 0.5em;
522 padding-bottom: 0.5em;
523 border-top: 2px solid silver;
524 border-bottom: 2px solid silver;
525 }
526 body.manpage h2 {
527 border-style: none;
528 }
529 body.manpage div.sectionbody {
530 margin-left: 3em;
531 }
532
533 @media print {
534 body.manpage div#toc { display: none; }
535 }
536
537
538 </style>
539 <script type="text/javascript">
540 /*<![CDATA[*/
541 var asciidoc = { // Namespace.
542
543 /////////////////////////////////////////////////////////////////////
544 // Table Of Contents generator
545 /////////////////////////////////////////////////////////////////////
546
547 /* Author: Mihai Bazon, September 2002
548 * http://students.infoiasi.ro/~mishoo
549 *
550 * Table Of Content generator
551 * Version: 0.4
552 *
553 * Feel free to use this script under the terms of the GNU General Public
554 * License, as long as you do not remove or alter this notice.
555 */
556
557 /* modified by Troy D. Hanson, September 2006. License: GPL */
558 /* modified by Stuart Rackham, 2006, 2009. License: GPL */
559
560 // toclevels = 1..4.
561 toc: function (toclevels) {
562
563 function getText(el) {
564 var text = "";
565 for (var i = el.firstChild; i != null; i = i.nextSibling) {
566 if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
567 text += i.data;
568 else if (i.firstChild != null)
569 text += getText(i);
570 }
571 return text;
572 }
573
574 function TocEntry(el, text, toclevel) {
575 this.element = el;
576 this.text = text;
577 this.toclevel = toclevel;
578 }
579
580 function tocEntries(el, toclevels) {
581 var result = new Array;
582 var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
583 // Function that scans the DOM tree for header elements (the DOM2
584 // nodeIterator API would be a better technique but not supported by all
585 // browsers).
586 var iterate = function (el) {
587 for (var i = el.firstChild; i != null; i = i.nextSibling) {
588 if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
589 var mo = re.exec(i.tagName);
590 if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
591 result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
592 }
593 iterate(i);
594 }
595 }
596 }
597 iterate(el);
598 return result;
599 }
600
601 var toc = document.getElementById("toc");
602 if (!toc) {
603 return;
604 }
605
606 // Delete existing TOC entries in case we're reloading the TOC.
607 var tocEntriesToRemove = [];
608 var i;
609 for (i = 0; i < toc.childNodes.length; i++) {
610 var entry = toc.childNodes[i];
611 if (entry.nodeName.toLowerCase() == 'div'
612 && entry.getAttribute("class")
613 && entry.getAttribute("class").match(/^toclevel/))
614 tocEntriesToRemove.push(entry);
615 }
616 for (i = 0; i < tocEntriesToRemove.length; i++) {
617 toc.removeChild(tocEntriesToRemove[i]);
618 }
619
620 // Rebuild TOC entries.
621 var entries = tocEntries(document.getElementById("content"), toclevels);
622 for (var i = 0; i < entries.length; ++i) {
623 var entry = entries[i];
624 if (entry.element.id == "")
625 entry.element.id = "_toc_" + i;
626 var a = document.createElement("a");
627 a.href = "#" + entry.element.id;
628 a.appendChild(document.createTextNode(entry.text));
629 var div = document.createElement("div");
630 div.appendChild(a);
631 div.className = "toclevel" + entry.toclevel;
632 toc.appendChild(div);
633 }
634 if (entries.length == 0)
635 toc.parentNode.removeChild(toc);
636 },
637
638
639 /////////////////////////////////////////////////////////////////////
640 // Footnotes generator
641 /////////////////////////////////////////////////////////////////////
642
643 /* Based on footnote generation code from:
644 * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
645 */
646
647 footnotes: function () {
648 // Delete existing footnote entries in case we're reloading the footnodes.
649 var i;
650 var noteholder = document.getElementById("footnotes");
651 if (!noteholder) {
652 return;
653 }
654 var entriesToRemove = [];
655 for (i = 0; i < noteholder.childNodes.length; i++) {
656 var entry = noteholder.childNodes[i];
657 if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
658 entriesToRemove.push(entry);
659 }
660 for (i = 0; i < entriesToRemove.length; i++) {
661 noteholder.removeChild(entriesToRemove[i]);
662 }
663
664 // Rebuild footnote entries.
665 var cont = document.getElementById("content");
666 var spans = cont.getElementsByTagName("span");
667 var refs = {};
668 var n = 0;
669 for (i=0; i<spans.length; i++) {
670 if (spans[i].className == "footnote") {
671 n++;
672 var note = spans[i].getAttribute("data-note");
673 if (!note) {
674 // Use [\s\S] in place of . so multi-line matches work.
675 // Because JavaScript has no s (dotall) regex flag.
676 note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
677 spans[i].innerHTML =
678 "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
679 "' title='View footnote' class='footnote'>" + n + "</a>]";
680 spans[i].setAttribute("data-note", note);
681 }
682 noteholder.innerHTML +=
683 "<div class='footnote' id='_footnote_" + n + "'>" +
684 "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
685 n + "</a>. " + note + "</div>";
686 var id =spans[i].getAttribute("id");
687 if (id != null) refs["#"+id] = n;
688 }
689 }
690 if (n == 0)
691 noteholder.parentNode.removeChild(noteholder);
692 else {
693 // Process footnoterefs.
694 for (i=0; i<spans.length; i++) {
695 if (spans[i].className == "footnoteref") {
696 var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
697 href = href.match(/#.*/)[0]; // Because IE return full URL.
698 n = refs[href];
699 spans[i].innerHTML =
700 "[<a href='#_footnote_" + n +
701 "' title='View footnote' class='footnote'>" + n + "</a>]";
702 }
703 }
704 }
705 },
706
707 install: function(toclevels) {
708 var timerId;
709
710 function reinstall() {
711 asciidoc.footnotes();
712 if (toclevels) {
713 asciidoc.toc(toclevels);
714 }
715 }
716
717 function reinstallAndRemoveTimer() {
718 clearInterval(timerId);
719 reinstall();
720 }
721
722 timerId = setInterval(reinstall, 500);
723 if (document.addEventListener)
724 document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
725 else
726 window.onload = reinstallAndRemoveTimer;
727 }
728
729 }
730 asciidoc.install(2);
731 /*]]>*/
732 </script>
733 </head>
734 <body class="article">
735 <div id="header">
736 <h1>i3 testsuite</h1>
737 <span id="author">Michael Stapelberg</span><br />
738 <span id="email"><code>&lt;<a href="mailto:[email protected]">[email protected]</a>&gt;</code></span><br />
739 <span id="revdate">September 2012</span>
740 <div id="toc">
741 <div id="toctitle">Table of Contents</div>
742 <noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
743 </div>
744 </div>
745 <div id="content">
746 <div id="preamble">
747 <div class="sectionbody">
748 <div class="paragraph"><p>This document explains how the i3 testsuite works, how to use it and extend it.
749 It is targeted at developers who not necessarily have been doing testing before
750 or have not been testing in Perl before. In general, the testsuite is not of
751 interest for end users.</p></div>
752 </div>
753 </div>
754 <div class="sect1">
755 <h2 id="_introduction">1. Introduction</h2>
756 <div class="sectionbody">
757 <div class="paragraph"><p>The i3 testsuite is a collection of files which contain testcases for various
758 i3 features. Some of them test if a certain workflow works correctly (moving
759 windows, focus behaviour, …). Others are regression tests and contain code
760 which previously made i3 crash or lead to unexpected behaviour. They then check
761 if i3 still runs (meaning it did not crash) and if it handled everything
762 correctly.</p></div>
763 <div class="paragraph"><p>The goal of having these tests is to automatically find problems and to
764 automatically get a feel for whether a change in the source code breaks any
765 existing feature. After every modification of the i3 sourcecode, the developer
766 should run the full testsuite. If one of the tests fails, the corresponding
767 problem should be fixed (or, in some cases, the testcase has to be modified).
768 For every bugreport, a testcase should be written to test the correct
769 behaviour. Initially, it will fail, but after fixing the bug, it will pass.
770 This ensures (or increases the chance) that bugs which have been fixed once
771 will never be found again.</p></div>
772 <div class="paragraph"><p>Also, when implementing a new feature, a testcase might be a good way to be
773 able to easily test if the feature is working correctly. Many developers will
774 test manually if everything works. Having a testcase not only helps you with
775 that, but it will also be useful for every future change.</p></div>
776 </div>
777 </div>
778 <div class="sect1">
779 <h2 id="_relevant_documentation">2. Relevant documentation</h2>
780 <div class="sectionbody">
781 <div class="paragraph"><p>Apart from this document, you should also have a look at:</p></div>
782 <div class="olist arabic"><ol class="arabic">
783 <li>
784 <p>
785 The "Modern Perl" book, which can be found at
786 <a href="http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf">http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf</a>
787 </p>
788 </li>
789 <li>
790 <p>
791 The latest Perl documentation of the "i3test" (general testcase setup) and
792 "i3test::Test" (additional test instructions) modules:
793 <a href="https://build.i3wm.org/docs/lib-i3test.html">https://build.i3wm.org/docs/lib-i3test.html</a> respectively
794 <a href="https://build.i3wm.org/docs/lib-i3test-test.html">https://build.i3wm.org/docs/lib-i3test-test.html</a>
795 </p>
796 </li>
797 <li>
798 <p>
799 The latest documentation on i3’s IPC interface:
800 <a href="https://build.i3wm.org/docs/ipc.html">https://build.i3wm.org/docs/ipc.html</a>
801 </p>
802 </li>
803 </ol></div>
804 </div>
805 </div>
806 <div class="sect1">
807 <h2 id="_implementation">3. Implementation</h2>
808 <div class="sectionbody">
809 <div class="paragraph"><p>For several reasons, the i3 testsuite has been implemented in Perl:</p></div>
810 <div class="olist arabic"><ol class="arabic">
811 <li>
812 <p>
813 Perl has a long tradition of testing. Every popular/bigger Perl module which
814 you can find on CPAN will not only come with documentation, but also with
815 tests. Therefore, the available infrastructure for tests is comprehensive.
816 See for example the excellent <a href="http://search.cpan.org/perldoc?Test::More">http://search.cpan.org/perldoc?Test::More</a>
817 and the referenced <a href="http://search.cpan.org/perldoc?Test::Tutorial">http://search.cpan.org/perldoc?Test::Tutorial</a>.
818 </p>
819 </li>
820 <li>
821 <p>
822 Perl is widely available and has a well-working package infrastructure.
823 </p>
824 </li>
825 <li>
826 <p>
827 The author is familiar with Perl :).
828 </p>
829 </li>
830 <li>
831 <p>
832 It is a good idea to use a different language for the tests than the
833 implementation itself.
834 </p>
835 </li>
836 </ol></div>
837 <div class="paragraph"><p>Please do not start programming language flamewars at this point.</p></div>
838 <div class="sect2">
839 <h3 id="_installing_the_dependencies">3.1. Installing the dependencies</h3>
840 <div class="paragraph"><p>As usual with Perl programs, the testsuite ships with a <code>Makefile.PL</code>.
841 This file specifies which Perl modules the testsuite depends on and can be used
842 to install all of them.</p></div>
843 <div class="paragraph"><p>Perl modules are distributed via CPAN, and there is the official, standard CPAN
844 client, simply called <code>cpan</code>. It comes with every Perl installation and can be
845 used to install the testsuite. Many users prefer to use the more modern
846 <code>cpanminus</code> instead, though (because it asks no questions and just works):</p></div>
847 <div class="paragraph"><p>The tests additionally require <code>Xephyr(1)</code> to run a nested X server. Install
848 <code>xserver-xephyr</code> on Debian or <code>xorg-server-xephyr</code> on Arch Linux.</p></div>
849 <div class="listingblock">
850 <div class="title">Installing testsuite dependencies using cpanminus (preferred)</div>
851 <div class="content">
852 <pre><code>$ cd ~/i3/testcases
853 $ sudo apt-get install cpanminus
854 $ sudo cpanm .
855 $ cd ~/i3/AnyEvent-I3
856 $ sudo cpanm Module::Install
857 $ sudo cpanm .</code></pre>
858 </div></div>
859 <div class="paragraph"><p>If you don’t want to use cpanminus for some reason, the same works with cpan:</p></div>
860 <div class="listingblock">
861 <div class="title">Installing testsuite dependencies using cpan</div>
862 <div class="content">
863 <pre><code>$ cd ~/i3/testcases
864 $ sudo cpan .
865 $ cd ~/i3/AnyEvent-I3
866 $ sudo cpan Module::Install
867 $ sudo cpan .</code></pre>
868 </div></div>
869 <div class="paragraph"><p>In case you don’t have root permissions, you can also install into your home
870 directory, see <a href="https://michael.stapelberg.de/cpan/">https://michael.stapelberg.de/cpan/</a></p></div>
871 </div>
872 <div class="sect2">
873 <h3 id="_mechanisms">3.2. Mechanisms</h3>
874 <div class="sect3">
875 <h4 id="_script_complete_run">3.2.1. Script: complete-run</h4>
876 <div class="paragraph"><p>The testcases are run by a script called <code>complete-run.pl</code>. It runs all
877 testcases by default, but you can be more specific and let it only run one or
878 more testcases. Also, it takes care of starting up a separate instance of i3
879 with an appropriate configuration file and creates a folder for each run
880 containing the appropriate i3 logfile for each testcase. The latest folder can
881 always be found under the symlink <code>latest/</code>. Unless told differently, it will
882 run the tests on a separate X server instance (using Xephyr).</p></div>
883 <div class="paragraph"><p>Xephyr will open a window where you can inspect the running test. By default,
884 tests are run under Xvfb.</p></div>
885 <div class="listingblock">
886 <div class="title">Example invocation of <code>complete-run.pl</code></div>
887 <div class="content">
888 <pre><code>$ cd ~/i3
889
890 $ autoreconf -fi
891
892 $ mkdir -p build &amp;&amp; cd build
893
894 $ ../configure
895
896 $ make -j8
897 # output omitted because it is very long
898
899 $ cd testcases
900
901 $ ./complete-run.pl
902 # output omitted because it is very long
903 All tests successful.
904 Files=78, Tests=734, 27 wallclock secs ( 0.38 usr 0.48 sys + 17.65 cusr 3.21 csys = 21.72 CPU)
905 Result: PASS
906
907 $ ./complete-run.pl t/04-floating.t
908 [:3] i3 startup: took 0.07s, status = 1
909 [:3] Running t/04-floating.t with logfile testsuite-2011-09-24-16-06-04-4.0.2-226-g1eb011a/i3-log-for-04-floating.t
910 [:3] t/04-floating.t finished
911 [:3] killing i3
912 output for t/04-floating.t:
913 ok 1 - use X11::XCB::Window;
914 ok 2 - The object isa X11::XCB::Window
915 ok 3 - Window is mapped
916 ok 4 - i3 raised the width to 75
917 ok 5 - i3 raised the height to 50
918 ok 6 - i3 did not map it to (0x0)
919 ok 7 - The object isa X11::XCB::Window
920 ok 8 - i3 let the width at 80
921 ok 9 - i3 let the height at 90
922 ok 10 - i3 mapped it to x=1
923 ok 11 - i3 mapped it to y=18
924 ok 12 - The object isa X11::XCB::Window
925 ok 13 - i3 let the width at 80
926 ok 14 - i3 let the height at 90
927 1..14
928
929 All tests successful.
930 Files=1, Tests=14, 0 wallclock secs ( 0.01 usr 0.00 sys + 0.19 cusr 0.03 csys = 0.23 CPU)
931 Result: PASS
932
933 $ less latest/i3-log-for-04-floating.t</code></pre>
934 </div></div>
935 <div class="paragraph"><p>If your attempt to run the tests with a bare call to ./complete-run.pl fails, try this:</p></div>
936 <div class="listingblock">
937 <div class="content">
938 <pre><code>$ ./complete-run.pl --parallel=1 --keep-xserver-output</code></pre>
939 </div></div>
940 <div class="paragraph"><p>This will show the output of Xephyr, which is the X server implementation we
941 use for testing.</p></div>
942 <div class="sect4">
943 <h5 id="_make_command_code_make_check_code">make command: <code>make check</code></h5>
944 <div class="paragraph"><p>Make check runs the i3 testsuite.
945 You can still use ./testcases/complete-run.pl to get the interactive progress output.</p></div>
946 <div class="listingblock">
947 <div class="title">Example invocation of <code>make check</code></div>
948 <div class="content">
949 <pre><code>$ cd ~/i3
950
951 $ autoreconf -fi
952
953 $ mkdir -p build &amp;&amp; cd build
954
955 $ ../configure
956
957 $ make -j8
958 # output omitted because it is very long
959
960 $ make check
961 # output omitted because it is very long
962 PASS: testcases/complete-run.pl
963 ============================================================================
964 Testsuite summary for i3 4.13
965 ============================================================================
966 # TOTAL: 1
967 # PASS: 1
968 # SKIP: 0
969 # XFAIL: 0
970 # FAIL: 0
971 # XPASS: 0
972 # ERROR: 0
973 ============================================================================
974
975 $ less test-suite.log</code></pre>
976 </div></div>
977 </div>
978 </div>
979 <div class="sect3">
980 <h4 id="_coverage_testing">3.2.2. Coverage testing</h4>
981 <div class="paragraph"><p>Coverage testing is possible with <code>lcov</code>, the front-end for GCC&#8217;s coverage
982 testing tool <code>gcov</code>. The testcases can generate a nice html report that tells
983 you which functions and lines were covered during a run of the tests. You can
984 use this tool to judge how effective your tests are.</p></div>
985 <div class="paragraph"><p>To use test coverage tools, first compile with coverage enabled.</p></div>
986 <div class="listingblock">
987 <div class="content">
988 <pre><code>COVERAGE=1 make</code></pre>
989 </div></div>
990 <div class="paragraph"><p>Then run the tests with the <code>--coverage-testing</code> flag.</p></div>
991 <div class="listingblock">
992 <div class="content">
993 <pre><code>./complete-run.pl --coverage-testing</code></pre>
994 </div></div>
995 <div class="paragraph"><p>Then open <code>latest/i3-coverage/index.html</code> in your web browser.</p></div>
996 </div>
997 <div class="sect3">
998 <h4 id="_ipc_interface">3.2.3. IPC interface</h4>
999 <div class="paragraph"><p>The testsuite makes extensive use of the IPC (Inter-Process Communication)
1000 interface which i3 provides. It is used for the startup process of i3, for
1001 terminating it cleanly and (most importantly) for modifying and getting the
1002 current state (layout tree).</p></div>
1003 <div class="paragraph"><p>See [<a href="https://i3wm.org/docs/ipc.html">https://i3wm.org/docs/ipc.html</a>] for documentation on the IPC interface.</p></div>
1004 </div>
1005 <div class="sect3">
1006 <h4 id="_x11_xcb">3.2.4. X11::XCB</h4>
1007 <div class="paragraph"><p>In order to open new windows, change attributes, get events, etc., the
1008 testsuite uses X11::XCB, a new (and quite specific to i3 at the moment) Perl
1009 module which uses the XCB protocol description to generate Perl bindings to
1010 X11. They work in a very similar way to libxcb (which i3 uses) and provide
1011 relatively high-level interfaces (objects such as <code>X11::XCB::Window</code>) as well as
1012 access to the low-level interface, which is very useful when testing a window
1013 manager.</p></div>
1014 </div>
1015 </div>
1016 <div class="sect2">
1017 <h3 id="_filesystem_structure">3.3. Filesystem structure</h3>
1018 <div class="paragraph"><p>In the git root of i3, the testcases live in the folder <code>testcases</code>. This
1019 folder contains the <code>complete-run.pl</code> and a base configuration file which will
1020 be used for the tests. The different testcases (their file extension is .t, not
1021 .pl) themselves can be found in the conventionally named subfolder <code>t</code>:</p></div>
1022 <div class="listingblock">
1023 <div class="title">Filesystem structure</div>
1024 <div class="content">
1025 <pre><code>├── testcases
1026 │   ├── complete-run.pl
1027 │   ├── i3-test.config
1028 │   ├── lib
1029 │   │   ├── i3test.pm
1030 │   │   ├── SocketActivation.pm
1031 │   │   └── StartXDummy.pm
1032 │   ├── t
1033 │   │   ├── 00-load.t
1034 │   │   ├── 01-tile.t
1035 │   │   ├── 02-fullscreen.t
1036 │   │   ├── ...
1037 │   │   ├── omitted for brevity
1038 │   │   ├── ...
1039 │   │   └── 74-regress-focus-toggle.t</code></pre>
1040 </div></div>
1041 </div>
1042 </div>
1043 </div>
1044 <div class="sect1">
1045 <h2 id="_anatomy_of_a_testcase">4. Anatomy of a testcase</h2>
1046 <div class="sectionbody">
1047 <div class="paragraph"><p>Learning by example is definitely a good strategy when you are wondering how to
1048 write a testcase. Let&#8217;s take <code>t/11-goto.t</code> as an easy example and go through it
1049 step by step:</p></div>
1050 <div class="listingblock">
1051 <div class="title">t/11-goto.t: Boilerplate</div>
1052 <div class="content">
1053 <pre><code>#!perl
1054 # vim:ts=4:sw=4:expandtab
1055
1056 use i3test;
1057 use File::Temp;
1058
1059 my $x = X11::XCB::Connection-&gt;new;</code></pre>
1060 </div></div>
1061 <div class="paragraph"><p>This is what we call boilerplate. It exists at the top of every test file (to
1062 some extent). The first line is the shebang, which specifies that this file is
1063 a Perl script. The second line contains VIM specific settings on how to
1064 edit/format this file (use spaces instead of tabs, indent using 4 spaces).
1065 Afterwards, the <code>i3test</code> module is used. This module contains i3 testsuite
1066 specific functions which you are strongly encouraged to use. They make writing
1067 testcases a lot easier and will make it easier for other people to read your
1068 tests.</p></div>
1069 <div class="paragraph"><p>The next line uses the <code>File::Temp</code> module. This is specific to this testcase,
1070 because it needs to generate a temporary name during the test. Many testcases
1071 use only the <code>i3test</code> module.</p></div>
1072 <div class="paragraph"><p>The last line opens a connection to X11. You might or might not need this in
1073 your testcase, depending on whether you are going to open windows (etc.) or
1074 only use i3 commands.</p></div>
1075 <div class="listingblock">
1076 <div class="title">t/11-goto.t: Setup</div>
1077 <div class="content">
1078 <pre><code>my $tmp = fresh_workspace;
1079
1080 cmd 'split h';</code></pre>
1081 </div></div>
1082 <div class="paragraph"><p>The first line calls i3test&#8217;s <code>fresh_workspace</code> function which looks for a
1083 currently unused workspace, switches to it, and returns its name. The variable
1084 <code>$tmp</code> will end up having a value such as <code>"/tmp/87kBVcHbA9"</code>. Note that this
1085 is not (necessarily) a valid path, it&#8217;s just a random workspace name.</p></div>
1086 <div class="paragraph"><p>So, now that we are on a new workspace, we ensure that the workspace uses
1087 horizontal orientation by issuing the <code>split h</code> command (see the i3 User&#8217;s
1088 Guide for a list of commands). This is not strictly necessary, but good style.
1089 In general, the <code>cmd</code> function executes the specified i3 command by using the
1090 IPC interface and returns once i3 acknowledged the command.</p></div>
1091 <div class="listingblock">
1092 <div class="title">t/11-goto.t: Setup</div>
1093 <div class="content">
1094 <pre><code>#####################################################################
1095 # Create two windows and make sure focus switching works
1096 #####################################################################
1097
1098 my $top = open_window($x);
1099 my $mid = open_window($x);
1100 my $bottom = open_window($x);</code></pre>
1101 </div></div>
1102 <div class="paragraph"><p>In every major section of a testcase, you should put a comment like the one
1103 above. This makes it immediately clear how the file is structured.</p></div>
1104 <div class="paragraph"><p>The <code>open_window</code> function opens a standard window, which will then be put into
1105 tiling mode by i3. If you want a floating window, use the
1106 <code>open_floating_window</code> function. These functions accept the same parameters as
1107 <code>X11::XCB::Window&#8594;new</code>, see the i3test documentation at TODO.</p></div>
1108 <div class="listingblock">
1109 <div class="title">t/11-goto.t: Helper function</div>
1110 <div class="content">
1111 <pre><code>#
1112 # Returns the input focus after sending the given command to i3 via IPC
1113 # and syncing with i3
1114 #
1115 sub focus_after {
1116 my $msg = shift;
1117
1118 cmd $msg;
1119 sync_with_i3 $x;
1120 return $x-&gt;input_focus;
1121 }</code></pre>
1122 </div></div>
1123 <div class="paragraph"><p>This section defines a helper function which will be used over and over in this
1124 testcase. If you have code which gets executed more than once or twice
1125 (depending on the length of your test, use your best judgement), please put it
1126 in a function. Tests should be short, concise and clear.</p></div>
1127 <div class="paragraph"><p>The <code>focus_after</code> function executes a command and returns the X11 focus after
1128 the command was executed. The <code>sync_with_i3</code> command makes sure that i3 could
1129 push its state to X11. See <a href="#i3_sync">[i3_sync]</a> to learn how this works exactly.</p></div>
1130 <div class="listingblock">
1131 <div class="title">t/11-goto.t: Test assumptions</div>
1132 <div class="content">
1133 <pre><code>$focus = $x-&gt;input_focus;
1134 is($focus, $bottom-&gt;id, "Latest window focused");
1135
1136 $focus = focus_after('focus left');
1137 is($focus, $mid-&gt;id, "Middle window focused");</code></pre>
1138 </div></div>
1139 <div class="paragraph"><p>Now, we run the first two real tests. They use <code>Test::More</code>'s <code>is</code> function,
1140 which compares two values and prints the differences if they are not the same.
1141 After the arguments, we supply a short comment to indicate what we are testing
1142 here. This makes it vastly more easy for the developer to spot which testcase
1143 is the problem in case one fails.</p></div>
1144 <div class="paragraph"><p>The first test checks that the most recently opened window is focused.
1145 Afterwards, the command <code>focus left</code> is issued and it is verified that the
1146 middle window now has focus.</p></div>
1147 <div class="paragraph"><p>Note that this is not a comprehensive test of the <code>focus</code> command&#8201;&#8212;&#8201;we would
1148 have to test wrapping, focus when using a more complex layout, focusing the
1149 parent/child containers, etc. But that is not the point of this testcase.
1150 Instead, we just want to know if <code>$x&#8594;input_focus</code> corresponds with what we are
1151 expecting. If not, something is completely wrong with the test environment and
1152 this trivial test will fail.</p></div>
1153 <div class="listingblock">
1154 <div class="title">t/11-goto.t: Test that the feature does not work (yet)</div>
1155 <div class="content">
1156 <pre><code>#####################################################################
1157 # Now goto a mark which does not exist
1158 #####################################################################
1159
1160 my $random_mark = mktemp('mark.XXXXXX');
1161
1162 $focus = focus_after(qq|[con_mark="$random_mark"] focus|);
1163 is($focus, $mid-&gt;id, "focus unchanged");</code></pre>
1164 </div></div>
1165 <div class="paragraph"><p>Syntax hint: The qq keyword is the interpolating quote operator. It lets you
1166 chose a quote character (in this case the <code>|</code> character, a pipe). This makes
1167 having double quotes in our string easy.</p></div>
1168 <div class="paragraph"><p>In this new major section, a random mark (mark is an identifier for a window,
1169 see "VIM-like marks" in the i3 User’s Guide) will be generated. Afterwards, we
1170 test that trying to focus that mark will not do anything. This is important: Do
1171 not only test that using a feature has the expected outcome, but also test that
1172 using it without properly initializing it does no harm. This command could for
1173 example have changed focus anyways (a bug) or crash i3 (obviously a bug).</p></div>
1174 <div class="listingblock">
1175 <div class="title">t/11-goto.t: Test that the feature does work</div>
1176 <div class="content">
1177 <pre><code>cmd "mark $random_mark";
1178
1179 $focus = focus_after('focus left');
1180 is($focus, $top-&gt;id, "Top window focused");
1181
1182 $focus = focus_after(qq|[con_mark="$random_mark"] focus|);
1183 is($focus, $mid-&gt;id, "goto worked");</code></pre>
1184 </div></div>
1185 <div class="paragraph"><p>Remember: Focus was on the middle window (we verified that earlier in "Test
1186 assumptions"). We now mark the middle window with our randomly generated mark.
1187 Afterwards, we switch focus away from the middle window to be able to tell if
1188 focusing it via its mark will work. If the test works, the goto command seems
1189 to be working.</p></div>
1190 <div class="listingblock">
1191 <div class="title">t/11-goto.t: Test corner case</div>
1192 <div class="content">
1193 <pre><code># check that we can specify multiple criteria
1194
1195 $focus = focus_after('focus left');
1196 is($focus, $top-&gt;id, "Top window focused");
1197
1198 $focus = focus_after(qq|[con_mark="$random_mark" con_mark="$random_mark"] focus|);
1199 is($focus, $mid-&gt;id, "goto worked");</code></pre>
1200 </div></div>
1201 <div class="paragraph"><p>Now we test the same feature, but specifying the mark twice in the command.
1202 This should have no effect, but let’s be sure: test it and see if things go
1203 wrong.</p></div>
1204 <div class="listingblock">
1205 <div class="title">t/11-goto.t: Test second code path</div>
1206 <div class="content">
1207 <pre><code>#####################################################################
1208 # Check whether the focus command will switch to a different
1209 # workspace if necessary
1210 #####################################################################
1211
1212 my $tmp2 = fresh_workspace;
1213
1214 is(focused_ws(), $tmp2, 'tmp2 now focused');
1215
1216 cmd qq|[con_mark="$random_mark"] focus|;
1217
1218 is(focused_ws(), $tmp, 'tmp now focused');</code></pre>
1219 </div></div>
1220 <div class="paragraph"><p>This part of the test checks that focusing windows by mark works across
1221 workspaces. It uses i3test&#8217;s <code>focused_ws</code> function to get the current
1222 workspace.</p></div>
1223 <div class="listingblock">
1224 <div class="title">t/11-goto.t: Test second code path</div>
1225 <div class="content">
1226 <pre><code>done_testing;</code></pre>
1227 </div></div>
1228 <div class="paragraph"><p>The end of every testcase has to contain the <code>done_testing</code> line. This tells
1229 <code>complete-run.pl</code> that the test was finished successfully. If it does not
1230 occur, the test might have crashed during execution&#8201;&#8212;&#8201;some of the reasons why
1231 that could happen are bugs in the used modules, bugs in the testcase itself or
1232 an i3 crash resulting in the testcase being unable to communicate with i3 via
1233 IPC anymore.</p></div>
1234 </div>
1235 </div>
1236 <div class="sect1">
1237 <h2 id="i3_sync">5. Appendix A: The i3 sync protocol</h2>
1238 <div class="sectionbody">
1239 <div class="paragraph"><p>Consider the following situation: You open two windows in your testcase, then
1240 you use <code>focus left</code> and want to verify that the X11 focus has been updated
1241 properly. Sounds simple, right? Let’s assume you use this straight-forward
1242 implementation:</p></div>
1243 <div class="listingblock">
1244 <div class="title">Racey focus testcase</div>
1245 <div class="content">
1246 <pre><code>my $left = open_window($x);
1247 my $right = open_window($x);
1248 cmd 'focus left';
1249 is($x-&gt;input_focus, $left-&gt;id, 'left window focused');</code></pre>
1250 </div></div>
1251 <div class="paragraph"><p>However, the test fails. Sometimes. Apparently, there is a race condition in
1252 your test. If you think about it, this is because you are using two different
1253 pieces of software: You tell i3 to update focus, i3 confirms that, and then you
1254 ask X11 to give you the current focus. There is a certain time i3 needs to
1255 update the X11 state. If the testcase gets CPU time before X11 processed i3&#8217;s
1256 requests, the test will fail.</p></div>
1257 <div class="imageblock">
1258 <div class="content">
1259 <img src="i3-sync.png" alt="Diagram of the race condition" />
1260 </div>
1261 <div class="title">Figure 1. Diagram of the race condition</div>
1262 </div>
1263 <div class="paragraph"><p>One way to "solve" this would be to add <code>sleep 0.5;</code> after the <code>cmd</code> call.
1264 After 0.5 seconds it should be safe to assume that focus has been updated,
1265 right?</p></div>
1266 <div class="paragraph"><p>In practice, this usually works. However, it has several problems:</p></div>
1267 <div class="olist arabic"><ol class="arabic">
1268 <li>
1269 <p>
1270 This is obviously not a clean solution, but a workaround. Ugly.
1271 </p>
1272 </li>
1273 <li>
1274 <p>
1275 On very slow machines, this might not work. Unlikely, but in different
1276 situations (a delay to wait for i3 to startup) the necessary time is much
1277 harder to guess, even for fast machines.
1278 </p>
1279 </li>
1280 <li>
1281 <p>
1282 This <strong>wastes a lot of time</strong>. Usually, your computer is much faster than 0.5s
1283 to update the status. However, sometimes, it might take 0.4s, so we can’t
1284 make it <code>sleep 0.1</code>.
1285 </p>
1286 </li>
1287 </ol></div>
1288 <div class="paragraph"><p>To illustrate how grave the problem with wasting time actually is: Before
1289 removing all sleeps from the testsuite, a typical run using 4 separate X
1290 servers took around 50 seconds on my machine. After removing all the sleeps,
1291 we achieved times of about 25 seconds. This is very significant and influences
1292 the way you think about tests&#8201;&#8212;&#8201;the faster they are, the more likely you are
1293 to check whether everything still works quite often (which you should).</p></div>
1294 <div class="paragraph"><p>What I am trying to say is: Delays adds up quickly and make the test suite
1295 less robust.</p></div>
1296 <div class="paragraph"><p>The real solution for this problem is a mechanism which I call "the i3 sync
1297 protocol". The idea is to send a request (which does not modify state) via X11
1298 to i3 which will then be answered. Due to the request&#8217;s position in the event
1299 queue (<strong>after</strong> all previous events), you can be sure that by the time you
1300 receive the reply, all other events have been dealt with by i3 (and, more
1301 importantly, X11).</p></div>
1302 <div class="imageblock">
1303 <div class="content">
1304 <img src="i3-sync-working.png" alt="Diagram of the i3 sync solution" />
1305 </div>
1306 <div class="title">Figure 2. Diagram of the i3 sync solution</div>
1307 </div>
1308 <div class="sect2">
1309 <h3 id="_implementation_details">5.1. Implementation details</h3>
1310 <div class="paragraph"><p>The client which wants to sync with i3 initiates the protocol by sending a
1311 ClientMessage to the X11 root window:</p></div>
1312 <div class="listingblock">
1313 <div class="title">Send ClientMessage</div>
1314 <div class="content">
1315 <pre><code># Generate a ClientMessage, see xcb_client_message_t
1316 my $msg = pack "CCSLLLLLLL",
1317 CLIENT_MESSAGE, # response_type
1318 32, # format
1319 0, # sequence
1320 $root, # destination window
1321 $x-&gt;atom(name =&gt; 'I3_SYNC')-&gt;id,
1322
1323 $_sync_window-&gt;id, # data[0]: our own window id
1324 $myrnd, # data[1]: a random value to identify the request
1325 0,
1326 0,
1327 0;
1328
1329 # Send it to the root window -- since i3 uses the SubstructureRedirect
1330 # event mask, it will get the ClientMessage.
1331 $x-&gt;send_event(0, $root, EVENT_MASK_SUBSTRUCTURE_REDIRECT, $msg);</code></pre>
1332 </div></div>
1333 <div class="paragraph"><p>i3 will then reply with the same ClientMessage, sent to the window specified in
1334 <code>data[0]</code>. In the reply, <code>data[0]</code> and <code>data[1]</code> are exactly the same as in the
1335 request. You should use a random value in <code>data[1]</code> and check that you received
1336 the same one when getting the reply.</p></div>
1337 </div>
1338 </div>
1339 </div>
1340 <div class="sect1">
1341 <h2 id="_appendix_b_socket_activation">6. Appendix B: Socket activation</h2>
1342 <div class="sectionbody">
1343 <div class="paragraph"><p>Socket activation is a mechanism which was made popular by systemd, an init
1344 replacement. It basically describes creating a listening socket before starting
1345 a program. systemd will invoke the program only when an actual connection to
1346 the socket is made, hence the term socket activation.</p></div>
1347 <div class="paragraph"><p>The interesting part of this (in the i3 context) is that you can very precisely
1348 detect when the program is ready (finished its initialization).</p></div>
1349 <div class="sect2">
1350 <h3 id="_preparing_the_listening_socket">6.1. Preparing the listening socket</h3>
1351 <div class="paragraph"><p><code>complete-run.pl</code> will create a listening UNIX socket which it will then pass
1352 to i3. This socket will be used by i3 as an additional IPC socket, just like
1353 the one it will create on its own. Passing the socket happens implicitly
1354 because children will inherit the parent’s sockets when fork()ing and sockets
1355 will continue to exist after an exec() call (unless CLOEXEC is set of course).</p></div>
1356 <div class="paragraph"><p>The only explicit things <code>complete-run.pl</code> has to do is setting the <code>LISTEN_FDS</code>
1357 environment variable to the number of sockets which exist (1 in our case) and
1358 setting the <code>LISTEN_PID</code> environment variable to the current process ID. Both
1359 variables are necessary so that the program (i3) knows how many sockets it
1360 should use and if the environment variable is actually intended for it. i3 will
1361 then start looking for sockets at file descriptor 3 (since 0, 1 and 2 are used
1362 for stdin, stdout and stderr, respectively).</p></div>
1363 <div class="paragraph"><p>The actual Perl code which sets up the socket, fork()s, makes sure the socket
1364 has file descriptor 3 and sets up the environment variables follows (shortened
1365 a bit):</p></div>
1366 <div class="listingblock">
1367 <div class="title">Setup socket and environment</div>
1368 <div class="content">
1369 <pre><code>my $socket = IO::Socket::UNIX-&gt;new(
1370 Listen =&gt; 1,
1371 Local =&gt; $args{unix_socket_path},
1372 );
1373
1374 my $pid = fork;
1375 if ($pid == 0) {
1376 $ENV{LISTEN_PID} = $$;
1377 $ENV{LISTEN_FDS} = 1;
1378
1379 # Only pass file descriptors 0 (stdin), 1 (stdout),
1380 # 2 (stderr) and 3 (socket) to the child.
1381 $^F = 3;
1382
1383 # If the socket does not use file descriptor 3 by chance
1384 # already, we close fd 3 and dup2() the socket to 3.
1385 if (fileno($socket) != 3) {
1386 POSIX::close(3);
1387 POSIX::dup2(fileno($socket), 3);
1388 }
1389
1390 exec "/usr/bin/i3";
1391 }</code></pre>
1392 </div></div>
1393 </div>
1394 <div class="sect2">
1395 <h3 id="_waiting_for_a_reply">6.2. Waiting for a reply</h3>
1396 <div class="paragraph"><p>In the parent process, we want to know when i3 is ready to answer our IPC
1397 requests and handle our windows. Therefore, after forking, we immediately close
1398 the listening socket (i3 will handle this side of the socket) and connect to it
1399 (remember, we are talking about a named UNIX socket) as a client. This connect
1400 call will immediately succeed because the kernel buffers it. Then, we send a
1401 request (of type GET_TREE, but that is not really relevant). Writing data to
1402 the socket will also succeed immediately because, again, the kernel buffers it
1403 (only up to a certain amount of data of course).</p></div>
1404 <div class="paragraph"><p>Afterwards, we just blockingly wait until we get an answer. In the child
1405 process, i3 will setup the listening socket in its event loop. Immediately
1406 after actually starting the event loop, it will notice a new client connecting
1407 (the parent process) and handle its request. Since all initialization has been
1408 completed successfully by the time the event loop is entered, we can now assume
1409 that i3 is ready.</p></div>
1410 </div>
1411 <div class="sect2">
1412 <h3 id="_timing_and_conclusion">6.3. Timing and conclusion</h3>
1413 <div class="paragraph"><p>A beautiful feature of this mechanism is that it does not depend on timing. It
1414 does not matter when the child process gets CPU time or when the parent process
1415 gets CPU time. On heavily loaded machines (or machines with multiple CPUs,
1416 cores or unreliable schedulers), this makes waiting for i3 much more robust.</p></div>
1417 <div class="paragraph"><p>Before using socket activation, we typically used a <code>sleep(1)</code> and hoped that
1418 i3 was initialized by that time. Of course, this breaks on some (slow)
1419 computers and wastes a lot of time on faster computers. By using socket
1420 activation, we decreased the total amount of time necessary to run all tests
1421 (72 files at the time of writing) from &gt; 100 seconds to 16 seconds. This makes
1422 it significantly more attractive to run the test suite more often (or at all)
1423 during development.</p></div>
1424 <div class="paragraph"><p>An alternative approach to using socket activation is polling for the existence
1425 of the IPC socket and connecting to it. While this might be slightly easier to
1426 implement, it wastes CPU time and is considerably uglier than this solution
1427 :). After all, <code>lib/SocketActivation.pm</code> contains only 54 SLOC.</p></div>
1428 </div>
1429 </div>
1430 </div>
1431 </div>
1432 <div id="footnotes"><hr /></div>
1433 <div id="footer">
1434 <div id="footer-text">
1435 Last updated
1436 2019-08-30 23:06:47 CEST
1437 </div>
1438 </div>
1439 </body>
1440 </html>
0 <?xml version="1.0" encoding="UTF-8"?>
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
2 "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
4 <head>
5 <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
6 <meta name="generator" content="AsciiDoc 8.6.10" />
7 <title>i3 User’s Guide</title>
8 <style type="text/css">
9 /* Shared CSS for AsciiDoc xhtml11 and html5 backends */
10
11 /* Default font. */
12 body {
13 font-family: Georgia,serif;
14 }
15
16 /* Title font. */
17 h1, h2, h3, h4, h5, h6,
18 div.title, caption.title,
19 thead, p.table.header,
20 #toctitle,
21 #author, #revnumber, #revdate, #revremark,
22 #footer {
23 font-family: Arial,Helvetica,sans-serif;
24 }
25
26 body {
27 margin: 1em 5% 1em 5%;
28 }
29
30 a {
31 color: blue;
32 text-decoration: underline;
33 }
34 a:visited {
35 color: fuchsia;
36 }
37
38 em {
39 font-style: italic;
40 color: navy;
41 }
42
43 strong {
44 font-weight: bold;
45 color: #083194;
46 }
47
48 h1, h2, h3, h4, h5, h6 {
49 color: #527bbd;
50 margin-top: 1.2em;
51 margin-bottom: 0.5em;
52 line-height: 1.3;
53 }
54
55 h1, h2, h3 {
56 border-bottom: 2px solid silver;
57 }
58 h2 {
59 padding-top: 0.5em;
60 }
61 h3 {
62 float: left;
63 }
64 h3 + * {
65 clear: left;
66 }
67 h5 {
68 font-size: 1.0em;
69 }
70
71 div.sectionbody {
72 margin-left: 0;
73 }
74
75 hr {
76 border: 1px solid silver;
77 }
78
79 p {
80 margin-top: 0.5em;
81 margin-bottom: 0.5em;
82 }
83
84 ul, ol, li > p {
85 margin-top: 0;
86 }
87 ul > li { color: #aaa; }
88 ul > li > * { color: black; }
89
90 .monospaced, code, pre {
91 font-family: "Courier New", Courier, monospace;
92 font-size: inherit;
93 color: navy;
94 padding: 0;
95 margin: 0;
96 }
97 pre {
98 white-space: pre-wrap;
99 }
100
101 #author {
102 color: #527bbd;
103 font-weight: bold;
104 font-size: 1.1em;
105 }
106 #email {
107 }
108 #revnumber, #revdate, #revremark {
109 }
110
111 #footer {
112 font-size: small;
113 border-top: 2px solid silver;
114 padding-top: 0.5em;
115 margin-top: 4.0em;
116 }
117 #footer-text {
118 float: left;
119 padding-bottom: 0.5em;
120 }
121 #footer-badges {
122 float: right;
123 padding-bottom: 0.5em;
124 }
125
126 #preamble {
127 margin-top: 1.5em;
128 margin-bottom: 1.5em;
129 }
130 div.imageblock, div.exampleblock, div.verseblock,
131 div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
132 div.admonitionblock {
133 margin-top: 1.0em;
134 margin-bottom: 1.5em;
135 }
136 div.admonitionblock {
137 margin-top: 2.0em;
138 margin-bottom: 2.0em;
139 margin-right: 10%;
140 color: #606060;
141 }
142
143 div.content { /* Block element content. */
144 padding: 0;
145 }
146
147 /* Block element titles. */
148 div.title, caption.title {
149 color: #527bbd;
150 font-weight: bold;
151 text-align: left;
152 margin-top: 1.0em;
153 margin-bottom: 0.5em;
154 }
155 div.title + * {
156 margin-top: 0;
157 }
158
159 td div.title:first-child {
160 margin-top: 0.0em;
161 }
162 div.content div.title:first-child {
163 margin-top: 0.0em;
164 }
165 div.content + div.title {
166 margin-top: 0.0em;
167 }
168
169 div.sidebarblock > div.content {
170 background: #ffffee;
171 border: 1px solid #dddddd;
172 border-left: 4px solid #f0f0f0;
173 padding: 0.5em;
174 }
175
176 div.listingblock > div.content {
177 border: 1px solid #dddddd;
178 border-left: 5px solid #f0f0f0;
179 background: #f8f8f8;
180 padding: 0.5em;
181 }
182
183 div.quoteblock, div.verseblock {
184 padding-left: 1.0em;
185 margin-left: 1.0em;
186 margin-right: 10%;
187 border-left: 5px solid #f0f0f0;
188 color: #888;
189 }
190
191 div.quoteblock > div.attribution {
192 padding-top: 0.5em;
193 text-align: right;
194 }
195
196 div.verseblock > pre.content {
197 font-family: inherit;
198 font-size: inherit;
199 }
200 div.verseblock > div.attribution {
201 padding-top: 0.75em;
202 text-align: left;
203 }
204 /* DEPRECATED: Pre version 8.2.7 verse style literal block. */
205 div.verseblock + div.attribution {
206 text-align: left;
207 }
208
209 div.admonitionblock .icon {
210 vertical-align: top;
211 font-size: 1.1em;
212 font-weight: bold;
213 text-decoration: underline;
214 color: #527bbd;
215 padding-right: 0.5em;
216 }
217 div.admonitionblock td.content {
218 padding-left: 0.5em;
219 border-left: 3px solid #dddddd;
220 }
221
222 div.exampleblock > div.content {
223 border-left: 3px solid #dddddd;
224 padding-left: 0.5em;
225 }
226
227 div.imageblock div.content { padding-left: 0; }
228 span.image img { border-style: none; vertical-align: text-bottom; }
229 a.image:visited { color: white; }
230
231 dl {
232 margin-top: 0.8em;
233 margin-bottom: 0.8em;
234 }
235 dt {
236 margin-top: 0.5em;
237 margin-bottom: 0;
238 font-style: normal;
239 color: navy;
240 }
241 dd > *:first-child {
242 margin-top: 0.1em;
243 }
244
245 ul, ol {
246 list-style-position: outside;
247 }
248 ol.arabic {
249 list-style-type: decimal;
250 }
251 ol.loweralpha {
252 list-style-type: lower-alpha;
253 }
254 ol.upperalpha {
255 list-style-type: upper-alpha;
256 }
257 ol.lowerroman {
258 list-style-type: lower-roman;
259 }
260 ol.upperroman {
261 list-style-type: upper-roman;
262 }
263
264 div.compact ul, div.compact ol,
265 div.compact p, div.compact p,
266 div.compact div, div.compact div {
267 margin-top: 0.1em;
268 margin-bottom: 0.1em;
269 }
270
271 tfoot {
272 font-weight: bold;
273 }
274 td > div.verse {
275 white-space: pre;
276 }
277
278 div.hdlist {
279 margin-top: 0.8em;
280 margin-bottom: 0.8em;
281 }
282 div.hdlist tr {
283 padding-bottom: 15px;
284 }
285 dt.hdlist1.strong, td.hdlist1.strong {
286 font-weight: bold;
287 }
288 td.hdlist1 {
289 vertical-align: top;
290 font-style: normal;
291 padding-right: 0.8em;
292 color: navy;
293 }
294 td.hdlist2 {
295 vertical-align: top;
296 }
297 div.hdlist.compact tr {
298 margin: 0;
299 padding-bottom: 0;
300 }
301
302 .comment {
303 background: yellow;
304 }
305
306 .footnote, .footnoteref {
307 font-size: 0.8em;
308 }
309
310 span.footnote, span.footnoteref {
311 vertical-align: super;
312 }
313
314 #footnotes {
315 margin: 20px 0 20px 0;
316 padding: 7px 0 0 0;
317 }
318
319 #footnotes div.footnote {
320 margin: 0 0 5px 0;
321 }
322
323 #footnotes hr {
324 border: none;
325 border-top: 1px solid silver;
326 height: 1px;
327 text-align: left;
328 margin-left: 0;
329 width: 20%;
330 min-width: 100px;
331 }
332
333 div.colist td {
334 padding-right: 0.5em;
335 padding-bottom: 0.3em;
336 vertical-align: top;
337 }
338 div.colist td img {
339 margin-top: 0.3em;
340 }
341
342 @media print {
343 #footer-badges { display: none; }
344 }
345
346 #toc {
347 margin-bottom: 2.5em;
348 }
349
350 #toctitle {
351 color: #527bbd;
352 font-size: 1.1em;
353 font-weight: bold;
354 margin-top: 1.0em;
355 margin-bottom: 0.1em;
356 }
357
358 div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
359 margin-top: 0;
360 margin-bottom: 0;
361 }
362 div.toclevel2 {
363 margin-left: 2em;
364 font-size: 0.9em;
365 }
366 div.toclevel3 {
367 margin-left: 4em;
368 font-size: 0.9em;
369 }
370 div.toclevel4 {
371 margin-left: 6em;
372 font-size: 0.9em;
373 }
374
375 span.aqua { color: aqua; }
376 span.black { color: black; }
377 span.blue { color: blue; }
378 span.fuchsia { color: fuchsia; }
379 span.gray { color: gray; }
380 span.green { color: green; }
381 span.lime { color: lime; }
382 span.maroon { color: maroon; }
383 span.navy { color: navy; }
384 span.olive { color: olive; }
385 span.purple { color: purple; }
386 span.red { color: red; }
387 span.silver { color: silver; }
388 span.teal { color: teal; }
389 span.white { color: white; }
390 span.yellow { color: yellow; }
391
392 span.aqua-background { background: aqua; }
393 span.black-background { background: black; }
394 span.blue-background { background: blue; }
395 span.fuchsia-background { background: fuchsia; }
396 span.gray-background { background: gray; }
397 span.green-background { background: green; }
398 span.lime-background { background: lime; }
399 span.maroon-background { background: maroon; }
400 span.navy-background { background: navy; }
401 span.olive-background { background: olive; }
402 span.purple-background { background: purple; }
403 span.red-background { background: red; }
404 span.silver-background { background: silver; }
405 span.teal-background { background: teal; }
406 span.white-background { background: white; }
407 span.yellow-background { background: yellow; }
408
409 span.big { font-size: 2em; }
410 span.small { font-size: 0.6em; }
411
412 span.underline { text-decoration: underline; }
413 span.overline { text-decoration: overline; }
414 span.line-through { text-decoration: line-through; }
415
416 div.unbreakable { page-break-inside: avoid; }
417
418
419 /*
420 * xhtml11 specific
421 *
422 * */
423
424 div.tableblock {
425 margin-top: 1.0em;
426 margin-bottom: 1.5em;
427 }
428 div.tableblock > table {
429 border: 3px solid #527bbd;
430 }
431 thead, p.table.header {
432 font-weight: bold;
433 color: #527bbd;
434 }
435 p.table {
436 margin-top: 0;
437 }
438 /* Because the table frame attribute is overriden by CSS in most browsers. */
439 div.tableblock > table[frame="void"] {
440 border-style: none;
441 }
442 div.tableblock > table[frame="hsides"] {
443 border-left-style: none;
444 border-right-style: none;
445 }
446 div.tableblock > table[frame="vsides"] {
447 border-top-style: none;
448 border-bottom-style: none;
449 }
450
451
452 /*
453 * html5 specific
454 *
455 * */
456
457 table.tableblock {
458 margin-top: 1.0em;
459 margin-bottom: 1.5em;
460 }
461 thead, p.tableblock.header {
462 font-weight: bold;
463 color: #527bbd;
464 }
465 p.tableblock {
466 margin-top: 0;
467 }
468 table.tableblock {
469 border-width: 3px;
470 border-spacing: 0px;
471 border-style: solid;
472 border-color: #527bbd;
473 border-collapse: collapse;
474 }
475 th.tableblock, td.tableblock {
476 border-width: 1px;
477 padding: 4px;
478 border-style: solid;
479 border-color: #527bbd;
480 }
481
482 table.tableblock.frame-topbot {
483 border-left-style: hidden;
484 border-right-style: hidden;
485 }
486 table.tableblock.frame-sides {
487 border-top-style: hidden;
488 border-bottom-style: hidden;
489 }
490 table.tableblock.frame-none {
491 border-style: hidden;
492 }
493
494 th.tableblock.halign-left, td.tableblock.halign-left {
495 text-align: left;
496 }
497 th.tableblock.halign-center, td.tableblock.halign-center {
498 text-align: center;
499 }
500 th.tableblock.halign-right, td.tableblock.halign-right {
501 text-align: right;
502 }
503
504 th.tableblock.valign-top, td.tableblock.valign-top {
505 vertical-align: top;
506 }
507 th.tableblock.valign-middle, td.tableblock.valign-middle {
508 vertical-align: middle;
509 }
510 th.tableblock.valign-bottom, td.tableblock.valign-bottom {
511 vertical-align: bottom;
512 }
513
514
515 /*
516 * manpage specific
517 *
518 * */
519
520 body.manpage h1 {
521 padding-top: 0.5em;
522 padding-bottom: 0.5em;
523 border-top: 2px solid silver;
524 border-bottom: 2px solid silver;
525 }
526 body.manpage h2 {
527 border-style: none;
528 }
529 body.manpage div.sectionbody {
530 margin-left: 3em;
531 }
532
533 @media print {
534 body.manpage div#toc { display: none; }
535 }
536
537
538 </style>
539 <script type="text/javascript">
540 /*<![CDATA[*/
541 var asciidoc = { // Namespace.
542
543 /////////////////////////////////////////////////////////////////////
544 // Table Of Contents generator
545 /////////////////////////////////////////////////////////////////////
546
547 /* Author: Mihai Bazon, September 2002
548 * http://students.infoiasi.ro/~mishoo
549 *
550 * Table Of Content generator
551 * Version: 0.4
552 *
553 * Feel free to use this script under the terms of the GNU General Public
554 * License, as long as you do not remove or alter this notice.
555 */
556
557 /* modified by Troy D. Hanson, September 2006. License: GPL */
558 /* modified by Stuart Rackham, 2006, 2009. License: GPL */
559
560 // toclevels = 1..4.
561 toc: function (toclevels) {
562
563 function getText(el) {
564 var text = "";
565 for (var i = el.firstChild; i != null; i = i.nextSibling) {
566 if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
567 text += i.data;
568 else if (i.firstChild != null)
569 text += getText(i);
570 }
571 return text;
572 }
573
574 function TocEntry(el, text, toclevel) {
575 this.element = el;
576 this.text = text;
577 this.toclevel = toclevel;
578 }
579
580 function tocEntries(el, toclevels) {
581 var result = new Array;
582 var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
583 // Function that scans the DOM tree for header elements (the DOM2
584 // nodeIterator API would be a better technique but not supported by all
585 // browsers).
586 var iterate = function (el) {
587 for (var i = el.firstChild; i != null; i = i.nextSibling) {
588 if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
589 var mo = re.exec(i.tagName);
590 if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
591 result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
592 }
593 iterate(i);
594 }
595 }
596 }
597 iterate(el);
598 return result;
599 }
600
601 var toc = document.getElementById("toc");
602 if (!toc) {
603 return;
604 }
605
606 // Delete existing TOC entries in case we're reloading the TOC.
607 var tocEntriesToRemove = [];
608 var i;
609 for (i = 0; i < toc.childNodes.length; i++) {
610 var entry = toc.childNodes[i];
611 if (entry.nodeName.toLowerCase() == 'div'
612 && entry.getAttribute("class")
613 && entry.getAttribute("class").match(/^toclevel/))
614 tocEntriesToRemove.push(entry);
615 }
616 for (i = 0; i < tocEntriesToRemove.length; i++) {
617 toc.removeChild(tocEntriesToRemove[i]);
618 }
619
620 // Rebuild TOC entries.
621 var entries = tocEntries(document.getElementById("content"), toclevels);
622 for (var i = 0; i < entries.length; ++i) {
623 var entry = entries[i];
624 if (entry.element.id == "")
625 entry.element.id = "_toc_" + i;
626 var a = document.createElement("a");
627 a.href = "#" + entry.element.id;
628 a.appendChild(document.createTextNode(entry.text));
629 var div = document.createElement("div");
630 div.appendChild(a);
631 div.className = "toclevel" + entry.toclevel;
632 toc.appendChild(div);
633 }
634 if (entries.length == 0)
635 toc.parentNode.removeChild(toc);
636 },
637
638
639 /////////////////////////////////////////////////////////////////////
640 // Footnotes generator
641 /////////////////////////////////////////////////////////////////////
642
643 /* Based on footnote generation code from:
644 * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
645 */
646
647 footnotes: function () {
648 // Delete existing footnote entries in case we're reloading the footnodes.
649 var i;
650 var noteholder = document.getElementById("footnotes");
651 if (!noteholder) {
652 return;
653 }
654 var entriesToRemove = [];
655 for (i = 0; i < noteholder.childNodes.length; i++) {
656 var entry = noteholder.childNodes[i];
657 if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
658 entriesToRemove.push(entry);
659 }
660 for (i = 0; i < entriesToRemove.length; i++) {
661 noteholder.removeChild(entriesToRemove[i]);
662 }
663
664 // Rebuild footnote entries.
665 var cont = document.getElementById("content");
666 var spans = cont.getElementsByTagName("span");
667 var refs = {};
668 var n = 0;
669 for (i=0; i<spans.length; i++) {
670 if (spans[i].className == "footnote") {
671 n++;
672 var note = spans[i].getAttribute("data-note");
673 if (!note) {
674 // Use [\s\S] in place of . so multi-line matches work.
675 // Because JavaScript has no s (dotall) regex flag.
676 note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
677 spans[i].innerHTML =
678 "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
679 "' title='View footnote' class='footnote'>" + n + "</a>]";
680 spans[i].setAttribute("data-note", note);
681 }
682 noteholder.innerHTML +=
683 "<div class='footnote' id='_footnote_" + n + "'>" +
684 "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
685 n + "</a>. " + note + "</div>";
686 var id =spans[i].getAttribute("id");
687 if (id != null) refs["#"+id] = n;
688 }
689 }
690 if (n == 0)
691 noteholder.parentNode.removeChild(noteholder);
692 else {
693 // Process footnoterefs.
694 for (i=0; i<spans.length; i++) {
695 if (spans[i].className == "footnoteref") {
696 var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
697 href = href.match(/#.*/)[0]; // Because IE return full URL.
698 n = refs[href];
699 spans[i].innerHTML =
700 "[<a href='#_footnote_" + n +
701 "' title='View footnote' class='footnote'>" + n + "</a>]";
702 }
703 }
704 }
705 },
706
707 install: function(toclevels) {
708 var timerId;
709
710 function reinstall() {
711 asciidoc.footnotes();
712 if (toclevels) {
713 asciidoc.toc(toclevels);
714 }
715 }
716
717 function reinstallAndRemoveTimer() {
718 clearInterval(timerId);
719 reinstall();
720 }
721
722 timerId = setInterval(reinstall, 500);
723 if (document.addEventListener)
724 document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
725 else
726 window.onload = reinstallAndRemoveTimer;
727 }
728
729 }
730 asciidoc.install(2);
731 /*]]>*/
732 </script>
733 </head>
734 <body class="article">
735 <div id="header">
736 <h1>i3 User’s Guide</h1>
737 <span id="author">Michael Stapelberg</span><br />
738 <span id="email"><code>&lt;<a href="mailto:[email protected]">[email protected]</a>&gt;</code></span><br />
739 <div id="toc">
740 <div id="toctitle">Table of Contents</div>
741 <noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
742 </div>
743 </div>
744 <div id="content">
745 <div id="preamble">
746 <div class="sectionbody">
747 <div class="paragraph"><p>This document contains all the information you need to configure and use the i3
748 window manager. If it does not, please check <a href="https://www.reddit.com/r/i3wm/">https://www.reddit.com/r/i3wm/</a>
749 first, then contact us on IRC (preferred) or post your question(s) on the
750 mailing list.</p></div>
751 </div>
752 </div>
753 <div class="sect1">
754 <h2 id="_default_keybindings">1. Default keybindings</h2>
755 <div class="sectionbody">
756 <div class="paragraph"><p>For the "too long; didn’t read" people, here is an overview of the default
757 keybindings (click to see the full-size image):</p></div>
758 <div class="paragraph"><p><strong>Keys to use with $mod (Alt):</strong></p></div>
759 <div class="paragraph"><p><span class="image">
760 <a class="image" href="keyboard-layer1.png">
761 <img src="keyboard-layer1.png" alt="Keys to use with $mod (Alt)" width="600" />
762 </a>
763 </span></p></div>
764 <div class="paragraph"><p><strong>Keys to use with Shift+$mod:</strong></p></div>
765 <div class="paragraph"><p><span class="image">
766 <a class="image" href="keyboard-layer2.png">
767 <img src="keyboard-layer2.png" alt="Keys to use with Shift+$mod" width="600" />
768 </a>
769 </span></p></div>
770 <div class="paragraph"><p>The red keys are the modifiers you need to press (by default), the blue keys
771 are your homerow.</p></div>
772 <div class="paragraph"><p>Note that when starting i3 without a config file, i3-config-wizard will offer
773 you to create a config file in which the key positions (!) match what you see
774 in the image above, regardless of the keyboard layout you are using. If you
775 prefer to use a config file where the key letters match what you are seeing
776 above, just decline i3-config-wizard’s offer and base your config on
777 <code>/etc/i3/config</code>.</p></div>
778 </div>
779 </div>
780 <div class="sect1">
781 <h2 id="_using_i3">2. Using i3</h2>
782 <div class="sectionbody">
783 <div class="paragraph"><p>Throughout this guide, the keyword <code>$mod</code> will be used to refer to the
784 configured modifier. This is the Alt key (<code>Mod1</code>) by default, with the Windows
785 key (<code>Mod4</code>) being a popular alternative that largely prevents conflicts with
786 application-defined shortcuts.</p></div>
787 <div class="sect2">
788 <h3 id="_opening_terminals_and_moving_around">2.1. Opening terminals and moving around</h3>
789 <div class="paragraph"><p>One very basic operation is opening a new terminal. By default, the keybinding
790 for this is <code>$mod+Enter</code>, that is Alt+Enter (<code>Mod1+Enter</code>) in the default
791 configuration. By pressing <code>$mod+Enter</code>, a new terminal will be opened. It
792 will fill the whole space available on your screen.</p></div>
793 <div class="paragraph"><p><span class="image">
794 <img src="single_terminal.png" alt="Single terminal" />
795 </span></p></div>
796 <div class="paragraph"><p>If you now open another terminal, i3 will place it next to the current one,
797 splitting the screen size in half. Depending on your monitor, i3 will put the
798 created window beside the existing window (on wide displays) or below the
799 existing window (rotated displays).</p></div>
800 <div class="paragraph"><p><span class="image">
801 <img src="two_terminals.png" alt="Two terminals" />
802 </span></p></div>
803 <div class="paragraph"><p>To move the focus between the two terminals, you can use the direction keys
804 which you may know from the editor <code>vi</code>. However, in i3, your homerow is used
805 for these keys (in <code>vi</code>, the keys are shifted to the left by one for
806 compatibility with most keyboard layouts). Therefore, <code>$mod+j</code> is left, <code>$mod+k</code>
807 is down, <code>$mod+l</code> is up and <code>$mod+;</code> is right. So, to switch between the
808 terminals, use <code>$mod+k</code> or <code>$mod+l</code>. Of course, you can also use the arrow keys.</p></div>
809 <div class="paragraph"><p>At the moment, your workspace is split (it contains two terminals) in a
810 specific direction (horizontal by default). Every window can be split
811 horizontally or vertically again, just like the workspace. The terminology is
812 "window" for a container that actually contains an X11 window (like a terminal
813 or browser) and "split container" for containers that consist of one or more
814 windows.</p></div>
815 <div class="paragraph"><p>TODO: picture of the tree</p></div>
816 <div class="paragraph"><p>To split a window vertically, press <code>$mod+v</code> before you create the new window.
817 To split it horizontally, press <code>$mod+h</code>.</p></div>
818 </div>
819 <div class="sect2">
820 <h3 id="_changing_the_container_layout">2.2. Changing the container layout</h3>
821 <div class="paragraph"><p>A split container can have one of the following layouts:</p></div>
822 <div class="dlist"><dl>
823 <dt class="hdlist1">
824 splith/splitv
825 </dt>
826 <dd>
827 <p>
828 Windows are sized so that every window gets an equal amount of space in the
829 container. splith distributes the windows horizontally (windows are right next
830 to each other), splitv distributes them vertically (windows are on top of each
831 other).
832 </p>
833 </dd>
834 <dt class="hdlist1">
835 stacking
836 </dt>
837 <dd>
838 <p>
839 Only the focused window in the container is displayed. You get a list of
840 windows at the top of the container.
841 </p>
842 </dd>
843 <dt class="hdlist1">
844 tabbed
845 </dt>
846 <dd>
847 <p>
848 The same principle as <code>stacking</code>, but the list of windows at the top is only
849 a single line which is vertically split.
850 </p>
851 </dd>
852 </dl></div>
853 <div class="paragraph"><p>To switch modes, press <code>$mod+e</code> for splith/splitv (it toggles), <code>$mod+s</code> for
854 stacking and <code>$mod+w</code> for tabbed.</p></div>
855 <div class="paragraph"><p><span class="image">
856 <img src="modes.png" alt="Container modes" />
857 </span></p></div>
858 </div>
859 <div class="sect2">
860 <h3 id="_toggling_fullscreen_mode_for_a_window">2.3. Toggling fullscreen mode for a window</h3>
861 <div class="paragraph"><p>To display a window in fullscreen mode or to go out of fullscreen mode again,
862 press <code>$mod+f</code>.</p></div>
863 <div class="paragraph"><p>There is also a global fullscreen mode in i3 in which the client will span all
864 available outputs (the command is <code>fullscreen toggle global</code>).</p></div>
865 </div>
866 <div class="sect2">
867 <h3 id="_opening_other_applications">2.4. Opening other applications</h3>
868 <div class="paragraph"><p>Aside from opening applications from a terminal, you can also use the handy
869 <code>dmenu</code> which is opened by pressing <code>$mod+d</code> by default. Just type the name
870 (or a part of it) of the application which you want to open. The corresponding
871 application has to be in your <code>$PATH</code> for this to work.</p></div>
872 <div class="paragraph"><p>Additionally, if you have applications you open very frequently, you can
873 create a keybinding for starting the application directly. See the section
874 <a href="#configuring">[configuring]</a> for details.</p></div>
875 </div>
876 <div class="sect2">
877 <h3 id="_closing_windows">2.5. Closing windows</h3>
878 <div class="paragraph"><p>If an application does not provide a mechanism for closing (most applications
879 provide a menu, the escape key or a shortcut like <code>Control+w</code> to close), you
880 can press <code>$mod+Shift+q</code> to kill a window. For applications which support
881 the WM_DELETE protocol, this will correctly close the application (saving
882 any modifications or doing other cleanup). If the application doesn’t support
883 the WM_DELETE protocol your X server will kill the window and the behaviour
884 depends on the application.</p></div>
885 </div>
886 <div class="sect2">
887 <h3 id="_using_workspaces">2.6. Using workspaces</h3>
888 <div class="paragraph"><p>Workspaces are an easy way to group a set of windows. By default, you are on
889 the first workspace, as the bar on the bottom left indicates. To switch to
890 another workspace, press <code>$mod+num</code> where <code>num</code> is the number of the workspace
891 you want to use. If the workspace does not exist yet, it will be created.</p></div>
892 <div class="paragraph"><p>A common paradigm is to put the web browser on one workspace, communication
893 applications (<code>mutt</code>, <code>irssi</code>, &#8230;) on another one, and the ones with which you
894 work, on the third one. Of course, there is no need to follow this approach.</p></div>
895 <div class="paragraph"><p>If you have multiple screens, a workspace will be created on each screen at
896 startup. If you open a new workspace, it will be bound to the screen you
897 created it on. When you switch to a workspace on another screen, i3 will set
898 focus to that screen.</p></div>
899 </div>
900 <div class="sect2">
901 <h3 id="_moving_windows_to_workspaces">2.7. Moving windows to workspaces</h3>
902 <div class="paragraph"><p>To move a window to another workspace, simply press <code>$mod+Shift+num</code> where
903 <code>num</code> is (like when switching workspaces) the number of the target workspace.
904 Similarly to switching workspaces, the target workspace will be created if
905 it does not yet exist.</p></div>
906 </div>
907 <div class="sect2">
908 <h3 id="_resizing">2.8. Resizing</h3>
909 <div class="paragraph"><p>The easiest way to resize a container is by using the mouse: Grab the border
910 and move it to the wanted size.</p></div>
911 <div class="paragraph"><p>You can also use <a href="#binding_modes">[binding_modes]</a> to define a mode for resizing via the
912 keyboard. To see an example for this, look at the
913 <a href="https://github.com/i3/i3/blob/next/etc/config.keycodes">default config</a> provided
914 by i3.</p></div>
915 </div>
916 <div class="sect2">
917 <h3 id="_restarting_i3_inplace">2.9. Restarting i3 inplace</h3>
918 <div class="paragraph"><p>To restart i3 in place (and thus get into a clean state if there is a bug, or
919 to upgrade to a newer version of i3) you can use <code>$mod+Shift+r</code>.</p></div>
920 </div>
921 <div class="sect2">
922 <h3 id="_exiting_i3">2.10. Exiting i3</h3>
923 <div class="paragraph"><p>To cleanly exit i3 without killing your X server, you can use <code>$mod+Shift+e</code>.
924 By default, a dialog will ask you to confirm if you really want to quit.</p></div>
925 </div>
926 <div class="sect2">
927 <h3 id="_floating">2.11. Floating</h3>
928 <div class="paragraph"><p>Floating mode is the opposite of tiling mode. The position and size of
929 a window are not managed automatically by i3, but manually by
930 you. Using this mode violates the tiling paradigm but can be useful
931 for some corner cases like "Save as" dialog windows, or toolbar
932 windows (GIMP or similar). Those windows usually set the appropriate
933 hint and are opened in floating mode by default.</p></div>
934 <div class="paragraph"><p>You can toggle floating mode for a window by pressing <code>$mod+Shift+Space</code>. By
935 dragging the window’s titlebar with your mouse you can move the window
936 around. By grabbing the borders and moving them you can resize the window. You
937 can also do that by using the <a href="#floating_modifier">[floating_modifier]</a>. Another way to resize
938 floating windows using the mouse is to right-click on the titlebar and drag.</p></div>
939 <div class="paragraph"><p>For resizing floating windows with your keyboard, see the resizing binding mode
940 provided by the i3 <a href="https://github.com/i3/i3/blob/next/etc/config.keycodes">default config</a>.</p></div>
941 <div class="paragraph"><p>Floating windows are always on top of tiling windows.</p></div>
942 </div>
943 </div>
944 </div>
945 <div class="sect1">
946 <h2 id="_tree">3. Tree</h2>
947 <div class="sectionbody">
948 <div class="paragraph"><p>i3 stores all information about the X11 outputs, workspaces and layout of the
949 windows on them in a tree. The root node is the X11 root window, followed by
950 the X11 outputs, then dock areas and a content container, then workspaces and
951 finally the windows themselves. In previous versions of i3 we had multiple lists
952 (of outputs, workspaces) and a table for each workspace. That approach turned
953 out to be complicated to use (snapping), understand and implement.</p></div>
954 <div class="sect2">
955 <h3 id="_the_tree_consists_of_containers">3.1. The tree consists of Containers</h3>
956 <div class="paragraph"><p>The building blocks of our tree are so-called <code>Containers</code>. A <code>Container</code> can
957 host a window (meaning an X11 window, one that you can actually see and use,
958 like a browser). Alternatively, it could contain one or more <code>Containers</code>. A
959 simple example is the workspace: When you start i3 with a single monitor, a
960 single workspace and you open two terminal windows, you will end up with a tree
961 like this:</p></div>
962 <div class="imageblock" style="float:right;">
963 <div class="content">
964 <img src="tree-layout2.png" alt="layout2" />
965 </div>
966 </div>
967 <div class="imageblock">
968 <div class="content">
969 <img src="tree-shot4.png" alt="shot4" />
970 </div>
971 <div class="title">Figure 1. Two terminals on standard workspace</div>
972 </div>
973 </div>
974 <div class="sect2">
975 <h3 id="OrientationSplit">3.2. Orientation and Split Containers</h3>
976 <div class="paragraph"><p>It is only natural to use so-called <code>Split Containers</code> in order to build a
977 layout when using a tree as data structure. In i3, every <code>Container</code> has an
978 orientation (horizontal, vertical or unspecified) and the orientation depends
979 on the layout the container is in (vertical for splitv and stacking, horizontal
980 for splith and tabbed). So, in our example with the workspace, the default
981 layout of the workspace <code>Container</code> is splith (most monitors are widescreen
982 nowadays). If you change the layout to splitv (<code>$mod+v</code> in the default config)
983 and <strong>then</strong> open two terminals, i3 will configure your windows like this:</p></div>
984 <div class="imageblock">
985 <div class="content">
986 <img src="tree-shot2.png" alt="shot2" />
987 </div>
988 <div class="title">Figure 2. Vertical Workspace Orientation</div>
989 </div>
990 <div class="paragraph"><p>An interesting new feature of i3 since version 4 is the ability to split anything:
991 Let’s assume you have two terminals on a workspace (with splith layout, that is
992 horizontal orientation), focus is on the right terminal. Now you want to open
993 another terminal window below the current one. If you would just open a new
994 terminal window, it would show up to the right due to the splith layout.
995 Instead, press <code>$mod+v</code> to split the container with the splitv layout (to
996 open a <code>Horizontal Split Container</code>, use <code>$mod+h</code>). Now you can open a new
997 terminal and it will open below the current one:</p></div>
998 <div class="imageblock" style="float:right;">
999 <div class="content">
1000 <img src="tree-layout1.png" alt="Layout" />
1001 </div>
1002 </div>
1003 <div class="imageblock">
1004 <div class="content">
1005 <img src="tree-shot1.png" alt="shot" />
1006 </div>
1007 <div class="title">Figure 3. Vertical Split Container</div>
1008 </div>
1009 <div style="clear:both;"></div>
1010 <div class="paragraph"><p>You probably guessed it already: There is no limit on how deep your hierarchy
1011 of splits can be.</p></div>
1012 </div>
1013 <div class="sect2">
1014 <h3 id="_focus_parent">3.3. Focus parent</h3>
1015 <div class="paragraph"><p>Let’s stay with our example from above. We have a terminal on the left and two
1016 vertically split terminals on the right, focus is on the bottom right one. When
1017 you open a new terminal, it will open below the current one.</p></div>
1018 <div class="paragraph"><p>So, how can you open a new terminal window to the <strong>right</strong> of the current one?
1019 The solution is to use <code>focus parent</code>, which will focus the <code>Parent Container</code> of
1020 the current <code>Container</code>. In default configuration, use <code>$mod+a</code> to navigate one
1021 <code>Container</code> up the tree (you can repeat this multiple times until you get to the
1022 <code>Workspace Container</code>). In this case, you would focus the <code>Vertical Split Container</code>
1023 which is <strong>inside</strong> the horizontally oriented workspace. Thus, now new windows will be
1024 opened to the right of the <code>Vertical Split Container</code>:</p></div>
1025 <div class="imageblock">
1026 <div class="content">
1027 <img src="tree-shot3.png" alt="shot3" />
1028 </div>
1029 <div class="title">Figure 4. Focus parent, then open new terminal</div>
1030 </div>
1031 </div>
1032 <div class="sect2">
1033 <h3 id="_implicit_containers">3.4. Implicit containers</h3>
1034 <div class="paragraph"><p>In some cases, i3 needs to implicitly create a container to fulfill your
1035 command.</p></div>
1036 <div class="paragraph"><p>One example is the following scenario: You start i3 with a single monitor and a
1037 single workspace on which you open three terminal windows. All these terminal
1038 windows are directly attached to one node inside i3’s layout tree, the
1039 workspace node. By default, the workspace node’s orientation is <code>horizontal</code>.</p></div>
1040 <div class="paragraph"><p>Now you move one of these terminals down (<code>$mod+Shift+k</code> by default). The
1041 workspace node’s orientation will be changed to <code>vertical</code>. The terminal window
1042 you moved down is directly attached to the workspace and appears on the bottom
1043 of the screen. A new (horizontal) container was created to accommodate the
1044 other two terminal windows. You will notice this when switching to tabbed mode
1045 (for example). You would end up having one tab with a representation of the split
1046 container (e.g., "H[urxvt firefox]") and the other one being the terminal window
1047 you moved down.</p></div>
1048 </div>
1049 </div>
1050 </div>
1051 <div class="sect1">
1052 <h2 id="configuring">4. Configuring i3</h2>
1053 <div class="sectionbody">
1054 <div class="paragraph"><p>This is where the real fun begins ;-). Most things are very dependent on your
1055 ideal working environment so we can’t make reasonable defaults for them.</p></div>
1056 <div class="paragraph"><p>While not using a programming language for the configuration, i3 stays
1057 quite flexible in regards to the things you usually want your window manager
1058 to do.</p></div>
1059 <div class="paragraph"><p>For example, you can configure bindings to jump to specific windows,
1060 you can set specific applications to start on specific workspaces, you can
1061 automatically start applications, you can change the colors of i3, and you
1062 can bind your keys to do useful things.</p></div>
1063 <div class="paragraph"><p>To change the configuration of i3, copy <code>/etc/i3/config</code> to <code>~/.i3/config</code>
1064 (or <code>~/.config/i3/config</code> if you like the XDG directory scheme) and edit it
1065 with a text editor.</p></div>
1066 <div class="paragraph"><p>On first start (and on all following starts, unless you have a configuration
1067 file), i3 will offer you to create a configuration file. You can tell the
1068 wizard to use either Alt (<code>Mod1</code>) or Windows (<code>Mod4</code>) as modifier in the config
1069 file. Also, the created config file will use the key symbols of your current
1070 keyboard layout. To start the wizard, use the command <code>i3-config-wizard</code>.
1071 Please note that you must not have <code>~/.i3/config</code>, otherwise the wizard will
1072 exit.</p></div>
1073 <div class="paragraph"><p>Since i3 4.0, a new configuration format is used. i3 will try to automatically
1074 detect the format version of a config file based on a few different keywords,
1075 but if you want to make sure that your config is read with the new format,
1076 include the following line in your config file:</p></div>
1077 <div class="listingblock">
1078 <div class="content">
1079 <pre><code># i3 config file (v4)</code></pre>
1080 </div></div>
1081 <div class="sect2">
1082 <h3 id="_comments">4.1. Comments</h3>
1083 <div class="paragraph"><p>It is possible and recommended to use comments in your configuration file to
1084 properly document your setup for later reference. Comments are started with
1085 a # and can only be used at the beginning of a line:</p></div>
1086 <div class="paragraph"><p><strong>Examples</strong>:</p></div>
1087 <div class="listingblock">
1088 <div class="content">
1089 <pre><code># This is a comment</code></pre>
1090 </div></div>
1091 </div>
1092 <div class="sect2">
1093 <h3 id="fonts">4.2. Fonts</h3>
1094 <div class="paragraph"><p>i3 has support for both X core fonts and FreeType fonts (through Pango) to
1095 render window titles.</p></div>
1096 <div class="paragraph"><p>To generate an X core font description, you can use <code>xfontsel(1)</code>. To see
1097 special characters (Unicode), you need to use a font which supports the
1098 ISO-10646 encoding.</p></div>
1099 <div class="paragraph"><p>A FreeType font description is composed by a font family, a style, a weight,
1100 a variant, a stretch and a size.
1101 FreeType fonts support right-to-left rendering and contain often more
1102 Unicode glyphs than X core fonts.</p></div>
1103 <div class="paragraph"><p>If i3 cannot open the configured font, it will output an error in the logfile
1104 and fall back to a working font.</p></div>
1105 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
1106 <div class="listingblock">
1107 <div class="content">
1108 <pre><code>font &lt;X core font description&gt;
1109 font pango:&lt;family list&gt; [&lt;style options&gt;] &lt;size&gt;</code></pre>
1110 </div></div>
1111 <div class="paragraph"><p><strong>Examples</strong>:</p></div>
1112 <div class="listingblock">
1113 <div class="content">
1114 <pre><code>font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
1115 font pango:DejaVu Sans Mono 10
1116 font pango:DejaVu Sans Mono, Terminus Bold Semi-Condensed 11
1117 font pango:Terminus 11px</code></pre>
1118 </div></div>
1119 </div>
1120 <div class="sect2">
1121 <h3 id="keybindings">4.3. Keyboard bindings</h3>
1122 <div class="paragraph"><p>A keyboard binding makes i3 execute a command (see below) upon pressing a
1123 specific key. i3 allows you to bind either on keycodes or on keysyms (you can
1124 also mix your bindings, though i3 will not protect you from overlapping ones).</p></div>
1125 <div class="ulist"><ul>
1126 <li>
1127 <p>
1128 A keysym (key symbol) is a description for a specific symbol, like "a"
1129 or "b", but also more strange ones like "underscore" instead of "_". These
1130 are the ones you use in Xmodmap to remap your keys. To get the current
1131 mapping of your keys, use <code>xmodmap -pke</code>. To interactively enter a key and
1132 see what keysym it is configured to, use <code>xev</code>.
1133 </p>
1134 </li>
1135 <li>
1136 <p>
1137 Keycodes do not need to have a symbol assigned (handy for custom vendor
1138 hotkeys on some notebooks) and they will not change their meaning as you
1139 switch to a different keyboard layout (when using <code>xmodmap</code>).
1140 </p>
1141 </li>
1142 </ul></div>
1143 <div class="paragraph"><p>My recommendation is: If you often switch keyboard layouts but you want to keep
1144 your bindings in the same physical location on the keyboard, use keycodes.
1145 If you don’t switch layouts, and want a clean and simple config file, use
1146 keysyms.</p></div>
1147 <div class="paragraph"><p>Some tools (such as <code>import</code> or <code>xdotool</code>) might be unable to run upon a
1148 KeyPress event, because the keyboard/pointer is still grabbed. For these
1149 situations, the <code>--release</code> flag can be used, which will execute the command
1150 after the keys have been released.</p></div>
1151 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
1152 <div class="listingblock">
1153 <div class="content">
1154 <pre><code>bindsym [--release] [&lt;Group&gt;+][&lt;Modifiers&gt;+]&lt;keysym&gt; command
1155 bindcode [--release] [&lt;Group&gt;+][&lt;Modifiers&gt;+]&lt;keycode&gt; command</code></pre>
1156 </div></div>
1157 <div class="paragraph"><p><strong>Examples</strong>:</p></div>
1158 <div class="listingblock">
1159 <div class="content">
1160 <pre><code># Fullscreen
1161 bindsym $mod+f fullscreen toggle
1162
1163 # Restart
1164 bindsym $mod+Shift+r restart
1165
1166 # Notebook-specific hotkeys
1167 bindcode 214 exec --no-startup-id /home/michael/toggle_beamer.sh
1168
1169 # Simulate ctrl+v upon pressing $mod+x
1170 bindsym --release $mod+x exec --no-startup-id xdotool key --clearmodifiers ctrl+v
1171
1172 # Take a screenshot upon pressing $mod+x (select an area)
1173 bindsym --release $mod+x exec --no-startup-id import /tmp/latest-screenshot.png</code></pre>
1174 </div></div>
1175 <div class="paragraph"><p>Available Modifiers:</p></div>
1176 <div class="dlist"><dl>
1177 <dt class="hdlist1">
1178 Mod1-Mod5, Shift, Control
1179 </dt>
1180 <dd>
1181 <p>
1182 Standard modifiers, see <code>xmodmap(1)</code>
1183 </p>
1184 </dd>
1185 <dt class="hdlist1">
1186 Group1, Group2, Group3, Group4
1187 </dt>
1188 <dd>
1189 <p>
1190 When using multiple keyboard layouts (e.g. with <code>setxkbmap -layout us,ru</code>), you
1191 can specify in which XKB group (also called “layout”) a keybinding should be
1192 active. By default, keybindings are translated in Group1 and are active in all
1193 groups. If you want to override keybindings in one of your layouts, specify the
1194 corresponding group. For backwards compatibility, the group “Mode_switch” is an
1195 alias for Group2.
1196 </p>
1197 </dd>
1198 </dl></div>
1199 </div>
1200 <div class="sect2">
1201 <h3 id="mousebindings">4.4. Mouse bindings</h3>
1202 <div class="paragraph"><p>A mouse binding makes i3 execute a command upon pressing a specific mouse
1203 button in the scope of the clicked container (see <a href="#command_criteria">[command_criteria]</a>). You
1204 can configure mouse bindings in a similar way to key bindings.</p></div>
1205 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
1206 <div class="listingblock">
1207 <div class="content">
1208 <pre><code>bindsym [--release] [--border] [--whole-window] [--exclude-titlebar] [&lt;Modifiers&gt;+]button&lt;n&gt; command</code></pre>
1209 </div></div>
1210 <div class="paragraph"><p>By default, the binding will only run when you click on the titlebar of the
1211 window. If the <code>--release</code> flag is given, it will run when the mouse button
1212 is released.</p></div>
1213 <div class="paragraph"><p>If the <code>--whole-window</code> flag is given, the binding will also run when any part
1214 of the window is clicked, with the exception of the border. To have a bind run
1215 when the border is clicked, specify the <code>--border</code> flag.</p></div>
1216 <div class="paragraph"><p>If the <code>--exclude-titlebar</code> flag is given, the titlebar will not be considered
1217 for the keybinding.</p></div>
1218 <div class="paragraph"><p><strong>Examples</strong>:</p></div>
1219 <div class="listingblock">
1220 <div class="content">
1221 <pre><code># The middle button over a titlebar kills the window
1222 bindsym --release button2 kill
1223
1224 # The middle button and a modifer over any part of the window kills the window
1225 bindsym --whole-window $mod+button2 kill
1226
1227 # The right button toggles floating
1228 bindsym button3 floating toggle
1229 bindsym $mod+button3 floating toggle
1230
1231 # The side buttons move the window around
1232 bindsym button9 move left
1233 bindsym button8 move right</code></pre>
1234 </div></div>
1235 </div>
1236 <div class="sect2">
1237 <h3 id="binding_modes">4.5. Binding modes</h3>
1238 <div class="paragraph"><p>You can have multiple sets of bindings by using different binding modes. When
1239 you switch to another binding mode, all bindings from the current mode are
1240 released and only the bindings defined in the new mode are valid for as long as
1241 you stay in that binding mode. The only predefined binding mode is <code>default</code>,
1242 which is the mode i3 starts out with and to which all bindings not defined in a
1243 specific binding mode belong.</p></div>
1244 <div class="paragraph"><p>Working with binding modes consists of two parts: defining a binding mode and
1245 switching to it. For these purposes, there are one config directive and one
1246 command, both of which are called <code>mode</code>. The directive is used to define the
1247 bindings belonging to a certain binding mode, while the command will switch to
1248 the specified mode.</p></div>
1249 <div class="paragraph"><p>It is recommended to use binding modes in combination with <a href="#variables">[variables]</a> in
1250 order to make maintenance easier. Below is an example of how to use a binding
1251 mode.</p></div>
1252 <div class="paragraph"><p>Note that it is advisable to define bindings for switching back to the default
1253 mode.</p></div>
1254 <div class="paragraph"><p>Note that it is possible to use <a href="#pango_markup">[pango_markup]</a> for binding modes, but you
1255 need to enable it explicitly by passing the <code>--pango_markup</code> flag to the mode
1256 definition.</p></div>
1257 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
1258 <div class="listingblock">
1259 <div class="content">
1260 <pre><code># config directive
1261 mode [--pango_markup] &lt;name&gt;
1262
1263 # command
1264 mode &lt;name&gt;</code></pre>
1265 </div></div>
1266 <div class="paragraph"><p><strong>Example</strong>:</p></div>
1267 <div class="listingblock">
1268 <div class="content">
1269 <pre><code># Press $mod+o followed by either f, t, Escape or Return to launch firefox,
1270 # thunderbird or return to the default mode, respectively.
1271 set $mode_launcher Launch: [f]irefox [t]hunderbird
1272 bindsym $mod+o mode "$mode_launcher"
1273
1274 mode "$mode_launcher" {
1275 bindsym f exec firefox
1276 bindsym t exec thunderbird
1277
1278 bindsym Escape mode "default"
1279 bindsym Return mode "default"
1280 }</code></pre>
1281 </div></div>
1282 </div>
1283 <div class="sect2">
1284 <h3 id="floating_modifier">4.6. The floating modifier</h3>
1285 <div class="paragraph"><p>To move floating windows with your mouse, you can either grab their titlebar
1286 or configure the so-called floating modifier which you can then press and
1287 click anywhere in the window itself to move it. The most common setup is to
1288 use the same key you use for managing windows (Mod1 for example). Then
1289 you can press Mod1, click into a window using your left mouse button, and drag
1290 it to the position you want.</p></div>
1291 <div class="paragraph"><p>When holding the floating modifier, you can resize a floating window by
1292 pressing the right mouse button on it and moving around while holding it. If
1293 you hold the shift button as well, the resize will be proportional (the aspect
1294 ratio will be preserved).</p></div>
1295 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
1296 <div class="listingblock">
1297 <div class="content">
1298 <pre><code>floating_modifier &lt;Modifier&gt;</code></pre>
1299 </div></div>
1300 <div class="paragraph"><p><strong>Example</strong>:</p></div>
1301 <div class="listingblock">
1302 <div class="content">
1303 <pre><code>floating_modifier Mod1</code></pre>
1304 </div></div>
1305 </div>
1306 <div class="sect2">
1307 <h3 id="_constraining_floating_window_size">4.7. Constraining floating window size</h3>
1308 <div class="paragraph"><p>The maximum and minimum dimensions of floating windows can be specified. If
1309 either dimension of <code>floating_maximum_size</code> is specified as -1, that dimension
1310 will be unconstrained with respect to its maximum value. If either dimension of
1311 <code>floating_maximum_size</code> is undefined, or specified as 0, i3 will use a default
1312 value to constrain the maximum size. <code>floating_minimum_size</code> is treated in a
1313 manner analogous to <code>floating_maximum_size</code>.</p></div>
1314 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
1315 <div class="listingblock">
1316 <div class="content">
1317 <pre><code>floating_minimum_size &lt;width&gt; x &lt;height&gt;
1318 floating_maximum_size &lt;width&gt; x &lt;height&gt;</code></pre>
1319 </div></div>
1320 <div class="paragraph"><p><strong>Example</strong>:</p></div>
1321 <div class="listingblock">
1322 <div class="content">
1323 <pre><code>floating_minimum_size 75 x 50
1324 floating_maximum_size -1 x -1</code></pre>
1325 </div></div>
1326 </div>
1327 <div class="sect2">
1328 <h3 id="_orientation_for_new_workspaces">4.8. Orientation for new workspaces</h3>
1329 <div class="paragraph"><p>New workspaces get a reasonable default orientation: Wide-screen monitors
1330 (anything wider than high) get horizontal orientation, rotated monitors
1331 (anything higher than wide) get vertical orientation.</p></div>
1332 <div class="paragraph"><p>With the <code>default_orientation</code> configuration directive, you can override that
1333 behavior.</p></div>
1334 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
1335 <div class="listingblock">
1336 <div class="content">
1337 <pre><code>default_orientation horizontal|vertical|auto</code></pre>
1338 </div></div>
1339 <div class="paragraph"><p><strong>Example</strong>:</p></div>
1340 <div class="listingblock">
1341 <div class="content">
1342 <pre><code>default_orientation vertical</code></pre>
1343 </div></div>
1344 </div>
1345 <div class="sect2">
1346 <h3 id="_layout_mode_for_new_containers">4.9. Layout mode for new containers</h3>
1347 <div class="paragraph"><p>This option determines in which mode new containers on workspace level will
1348 start.</p></div>
1349 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
1350 <div class="listingblock">
1351 <div class="content">
1352 <pre><code>workspace_layout default|stacking|tabbed</code></pre>
1353 </div></div>
1354 <div class="paragraph"><p><strong>Example</strong>:</p></div>
1355 <div class="listingblock">
1356 <div class="content">
1357 <pre><code>workspace_layout tabbed</code></pre>
1358 </div></div>
1359 </div>
1360 <div class="sect2">
1361 <h3 id="_window_title_alignment">4.10. Window title alignment</h3>
1362 <div class="paragraph"><p>This option determines the window title&#8217;s text alignment.
1363 Default is <code>left</code></p></div>
1364 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
1365 <div class="listingblock">
1366 <div class="content">
1367 <pre><code>title_align left|center|right</code></pre>
1368 </div></div>
1369 </div>
1370 <div class="sect2">
1371 <h3 id="_default_border_style_for_new_windows">4.11. Default border style for new windows</h3>
1372 <div class="paragraph"><p>This option determines which border style new windows will have. The default is
1373 <code>normal</code>. Note that default_floating_border applies only to windows which are starting out as
1374 floating windows, e.g., dialog windows, but not windows that are floated later on.</p></div>
1375 <div class="paragraph"><p>Setting border style to <code>pixel</code> eliminates title bars. The border style <code>normal</code> allows you to
1376 adjust edge border width while keeping your title bar.</p></div>
1377 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
1378 <div class="listingblock">
1379 <div class="content">
1380 <pre><code>default_border normal|none|pixel
1381 default_border normal|pixel &lt;px&gt;
1382 default_floating_border normal|none|pixel
1383 default_floating_border normal|pixel &lt;px&gt;</code></pre>
1384 </div></div>
1385 <div class="paragraph"><p>Please note that <code>new_window</code> and <code>new_float</code> have been deprecated in favor of the above options
1386 and will be removed in a future release. We strongly recommend using the new options instead.</p></div>
1387 <div class="paragraph"><p><strong>Example</strong>:</p></div>
1388 <div class="listingblock">
1389 <div class="content">
1390 <pre><code>default_border pixel</code></pre>
1391 </div></div>
1392 <div class="paragraph"><p>The "normal" and "pixel" border styles support an optional border width in
1393 pixels:</p></div>
1394 <div class="paragraph"><p><strong>Example</strong>:</p></div>
1395 <div class="listingblock">
1396 <div class="content">
1397 <pre><code># The same as default_border none
1398 default_border pixel 0
1399
1400 # A 3 px border
1401 default_border pixel 3</code></pre>
1402 </div></div>
1403 </div>
1404 <div class="sect2">
1405 <h3 id="_hiding_vertical_borders">4.12. Hiding borders adjacent to the screen edges</h3>
1406 <div class="paragraph"><p>You can hide container borders adjacent to the screen edges using
1407 <code>hide_edge_borders</code>. This is useful if you are using scrollbars, or do not want
1408 to waste even two pixels in displayspace. The "smart" setting hides borders on
1409 workspaces with only one window visible, but keeps them on workspaces with
1410 multiple windows visible. Default is none.</p></div>
1411 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
1412 <div class="listingblock">
1413 <div class="content">
1414 <pre><code>hide_edge_borders none|vertical|horizontal|both|smart</code></pre>
1415 </div></div>
1416 <div class="paragraph"><p><strong>Example</strong>:</p></div>
1417 <div class="listingblock">
1418 <div class="content">
1419 <pre><code>hide_edge_borders vertical</code></pre>
1420 </div></div>
1421 </div>
1422 <div class="sect2">
1423 <h3 id="for_window">4.13. Arbitrary commands for specific windows (for_window)</h3>
1424 <div class="paragraph"><p>With the <code>for_window</code> directive, you can let i3 execute any command when it
1425 encounters a specific window. This can be used to set windows to floating or to
1426 change their border style, for example.</p></div>
1427 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
1428 <div class="listingblock">
1429 <div class="content">
1430 <pre><code>for_window &lt;criteria&gt; &lt;command&gt;</code></pre>
1431 </div></div>
1432 <div class="paragraph"><p><strong>Examples</strong>:</p></div>
1433 <div class="listingblock">
1434 <div class="content">
1435 <pre><code># enable floating mode for all XTerm windows
1436 for_window [class="XTerm"] floating enable
1437
1438 # Make all urxvts use a 1-pixel border:
1439 for_window [class="urxvt"] border pixel 1
1440
1441 # A less useful, but rather funny example:
1442 # makes the window floating as soon as I change
1443 # directory to ~/work
1444 for_window [title="x200: ~/work"] floating enable</code></pre>
1445 </div></div>
1446 <div class="paragraph"><p>The valid criteria are the same as those for commands, see <a href="#command_criteria">[command_criteria]</a>. Only config
1447 directives with a command equivalent can be executed at runtime, see <a href="#list_of_commands">[list_of_commands]</a>.</p></div>
1448 </div>
1449 <div class="sect2">
1450 <h3 id="no_focus">4.14. Don&#8217;t focus window upon opening</h3>
1451 <div class="paragraph"><p>When a new window appears, it will be focused. The <code>no_focus</code> directive allows preventing
1452 this from happening and must be used in combination with <a href="#command_criteria">[command_criteria]</a>.</p></div>
1453 <div class="paragraph"><p>Note that this does not apply to all cases, e.g., when feeding data into a running application
1454 causing it to request being focused. To configure the behavior in such cases, refer to
1455 <a href="#focus_on_window_activation">[focus_on_window_activation]</a>.</p></div>
1456 <div class="paragraph"><p><code>no_focus</code> will also be ignored for the first window on a workspace as there shouldn&#8217;t be
1457 a reason to not focus the window in this case. This allows for better usability in
1458 combination with <code>workspace_layout</code>.</p></div>
1459 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
1460 <div class="listingblock">
1461 <div class="content">
1462 <pre><code>no_focus &lt;criteria&gt;</code></pre>
1463 </div></div>
1464 <div class="paragraph"><p><strong>Example</strong>:</p></div>
1465 <div class="listingblock">
1466 <div class="content">
1467 <pre><code>no_focus [window_role="pop-up"]</code></pre>
1468 </div></div>
1469 </div>
1470 <div class="sect2">
1471 <h3 id="variables">4.15. Variables</h3>
1472 <div class="paragraph"><p>As you learned in the section about keyboard bindings, you will have
1473 to configure lots of bindings containing modifier keys. If you want to save
1474 yourself some typing and be able to change the modifier you use later,
1475 variables can be handy.</p></div>
1476 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
1477 <div class="listingblock">
1478 <div class="content">
1479 <pre><code>set $&lt;name&gt; &lt;value&gt;</code></pre>
1480 </div></div>
1481 <div class="paragraph"><p><strong>Example</strong>:</p></div>
1482 <div class="listingblock">
1483 <div class="content">
1484 <pre><code>set $m Mod1
1485 bindsym $m+Shift+r restart</code></pre>
1486 </div></div>
1487 <div class="paragraph"><p>Variables are directly replaced in the file when parsing. Variables expansion
1488 is not recursive so it is not possible to define a variable with a value
1489 containing another variable. There is no fancy handling and there are
1490 absolutely no plans to change this. If you need a more dynamic configuration
1491 you should create a little script which generates a configuration file and run
1492 it before starting i3 (for example in your <code>~/.xsession</code> file).</p></div>
1493 <div class="paragraph"><p>Also see <a href="#xresources">[xresources]</a> to learn how to create variables based on resources
1494 loaded from the X resource database.</p></div>
1495 </div>
1496 <div class="sect2">
1497 <h3 id="xresources">4.16. X resources</h3>
1498 <div class="paragraph"><p><a href="#variables">[variables]</a> can also be created using a value configured in the X resource
1499 database. This is useful, for example, to avoid configuring color values within
1500 the i3 configuration. Instead, the values can be configured, once, in the X
1501 resource database to achieve an easily maintainable, consistent color theme
1502 across many X applications.</p></div>
1503 <div class="paragraph"><p>Defining a resource will load this resource from the resource database and
1504 assign its value to the specified variable. This is done verbatim and the value
1505 must therefore be in the format that i3 uses. A fallback must be specified in
1506 case the resource cannot be loaded from the database.</p></div>
1507 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
1508 <div class="listingblock">
1509 <div class="content">
1510 <pre><code>set_from_resource $&lt;name&gt; &lt;resource_name&gt; &lt;fallback&gt;</code></pre>
1511 </div></div>
1512 <div class="paragraph"><p><strong>Example</strong>:</p></div>
1513 <div class="listingblock">
1514 <div class="content">
1515 <pre><code># The ~/.Xresources should contain a line such as
1516 # *color0: #121212
1517 # and must be loaded properly, e.g., by using
1518 # xrdb ~/.Xresources
1519 # This value is picked up on by other applications (e.g., the URxvt terminal
1520 # emulator) and can be used in i3 like this:
1521 set_from_resource $black i3wm.color0 #000000</code></pre>
1522 </div></div>
1523 </div>
1524 <div class="sect2">
1525 <h3 id="assign_workspace">4.17. Automatically putting clients on specific workspaces</h3>
1526 <div class="paragraph"><p>To automatically make a specific window show up on a specific workspace, you
1527 can use an <strong>assignment</strong>. You can match windows by using any criteria,
1528 see <a href="#command_criteria">[command_criteria]</a>. The difference between <code>assign</code> and
1529 <code>for_window &lt;criteria&gt; move to workspace</code> is that the former will only be
1530 executed when the application maps the window (mapping means actually displaying
1531 it on the screen) but the latter will be executed whenever a window changes its
1532 properties to something that matches the specified criteria.</p></div>
1533 <div class="paragraph"><p>Thus, it is recommended that you match on window classes (and instances, when
1534 appropriate) instead of window titles whenever possible because some
1535 applications first create their window, and then worry about setting the correct
1536 title. Firefox with Vimperator comes to mind. The window starts up being named
1537 Firefox, and only when Vimperator is loaded does the title change. As i3 will
1538 get the title as soon as the application maps the window, you’d need to have to
1539 match on <em>Firefox</em> in this case.
1540 Another known issue is with Spotify, which doesn&#8217;t set the class hints when
1541 mapping the window, meaning you&#8217;ll have to use a <code>for_window</code> rule to assign
1542 Spotify to a specific workspace.
1543 Finally, using <code>assign [tiling]</code> and <code>assign [floating]</code> is not supported.</p></div>
1544 <div class="paragraph"><p>You can also assign a window to show up on a specific output. You can use RandR
1545 names such as <code>VGA1</code> or names relative to the output with the currently focused
1546 workspace such as <code>left</code> and <code>down</code>.</p></div>
1547 <div class="paragraph"><p>Assignments are processed by i3 in the order in which they appear in the config
1548 file. The first one which matches the window wins and later assignments are not
1549 considered.</p></div>
1550 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
1551 <div class="listingblock">
1552 <div class="content">
1553 <pre><code>assign &lt;criteria&gt; [→] [workspace] [number] &lt;workspace&gt;
1554 assign &lt;criteria&gt; [→] output left|right|up|down|primary|&lt;output&gt;</code></pre>
1555 </div></div>
1556 <div class="paragraph"><p><strong>Examples</strong>:</p></div>
1557 <div class="listingblock">
1558 <div class="content">
1559 <pre><code># Assign URxvt terminals to workspace 2
1560 assign [class="URxvt"] 2
1561
1562 # Same thing, but more precise (exact match instead of substring)
1563 assign [class="^URxvt$"] 2
1564
1565 # Same thing, but with a beautiful arrow :)
1566 assign [class="^URxvt$"] → 2
1567
1568 # Assignment to a named workspace
1569 assign [class="^URxvt$"] → work
1570
1571 # Assign to the workspace with number 2, regardless of name
1572 assign [class="^URxvt$"] → number 2
1573
1574 # You can also specify a number + name. If the workspace with number 2 exists,
1575 # assign will skip the text part.
1576 assign [class="^URxvt$"] → number "2: work"
1577
1578 # Start urxvt -name irssi
1579 assign [class="^URxvt$" instance="^irssi$"] → 3
1580
1581 # Assign urxvt to the output right of the current one
1582 assign [class="^URxvt$"] → output right
1583
1584 # Assign urxvt to the primary output
1585 assign [class="^URxvt$"] → output primary</code></pre>
1586 </div></div>
1587 <div class="paragraph"><p>Note that you might not have a primary output configured yet. To do so, run:</p></div>
1588 <div class="listingblock">
1589 <div class="content">
1590 <pre><code>xrandr --output &lt;output&gt; --primary</code></pre>
1591 </div></div>
1592 <div class="paragraph"><p>Also, the arrow is not required, it just looks good :-). If you decide to
1593 use it, it has to be a UTF-8 encoded arrow, not <code>-&gt;</code> or something like that.</p></div>
1594 <div class="paragraph"><p>To get the class and instance, you can use <code>xprop</code>. After clicking on the
1595 window, you will see the following output:</p></div>
1596 <div class="paragraph"><p><strong>xprop</strong>:</p></div>
1597 <div class="listingblock">
1598 <div class="content">
1599 <pre><code>WM_CLASS(STRING) = "irssi", "URxvt"</code></pre>
1600 </div></div>
1601 <div class="paragraph"><p>The first part of the WM_CLASS is the instance ("irssi" in this example), the
1602 second part is the class ("URxvt" in this example).</p></div>
1603 <div class="paragraph"><p>Should you have any problems with assignments, make sure to check the i3
1604 logfile first (see <a href="https://i3wm.org/docs/debugging.html">https://i3wm.org/docs/debugging.html</a>). It includes more
1605 details about the matching process and the window’s actual class, instance and
1606 title when starting up.</p></div>
1607 <div class="paragraph"><p>Note that if you want to start an application just once on a specific
1608 workspace, but you don’t want to assign all instances of it permanently, you
1609 can make use of i3’s startup-notification support (see <a href="#exec">[exec]</a>) in your config
1610 file in the following way:</p></div>
1611 <div class="paragraph"><p><strong>Start iceweasel on workspace 3 (once)</strong>:</p></div>
1612 <div class="listingblock">
1613 <div class="content">
1614 <pre><code># Start iceweasel on workspace 3, then switch back to workspace 1
1615 # (Being a command-line utility, i3-msg does not support startup notifications,
1616 # hence the exec --no-startup-id.)
1617 # (Starting iceweasel with i3’s exec command is important in order to make i3
1618 # create a startup notification context, without which the iceweasel window(s)
1619 # cannot be matched onto the workspace on which the command was started.)
1620 exec --no-startup-id i3-msg 'workspace 3; exec iceweasel; workspace 1'</code></pre>
1621 </div></div>
1622 </div>
1623 <div class="sect2">
1624 <h3 id="_automatically_starting_applications_on_i3_startup">4.18. Automatically starting applications on i3 startup</h3>
1625 <div class="paragraph"><p>By using the <code>exec</code> keyword outside a keybinding, you can configure
1626 which commands will be performed by i3 on initial startup. <code>exec</code>
1627 commands will not run when restarting i3, if you need a command to run
1628 also when restarting i3 you should use the <code>exec_always</code>
1629 keyword. These commands will be run in order.</p></div>
1630 <div class="paragraph"><p>See <a href="#command_chaining">[command_chaining]</a> for details on the special meaning of <code>;</code> (semicolon)
1631 and <code>,</code> (comma): they chain commands together in i3, so you need to use quoted
1632 strings (as shown in <a href="#exec_quoting">[exec_quoting]</a>) if they appear in your command.</p></div>
1633 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
1634 <div class="listingblock">
1635 <div class="content">
1636 <pre><code>exec [--no-startup-id] &lt;command&gt;
1637 exec_always [--no-startup-id] &lt;command&gt;</code></pre>
1638 </div></div>
1639 <div class="paragraph"><p><strong>Examples</strong>:</p></div>
1640 <div class="listingblock">
1641 <div class="content">
1642 <pre><code>exec chromium
1643 exec_always ~/my_script.sh
1644
1645 # Execute the terminal emulator urxvt, which is not yet startup-notification aware.
1646 exec --no-startup-id urxvt</code></pre>
1647 </div></div>
1648 <div class="paragraph"><p>The flag --no-startup-id is explained in <a href="#exec">[exec]</a>.</p></div>
1649 </div>
1650 <div class="sect2">
1651 <h3 id="workspace_screen">4.19. Automatically putting workspaces on specific screens</h3>
1652 <div class="paragraph"><p>If you assign clients to workspaces, it might be handy to put the
1653 workspaces on specific screens. Also, the assignment of workspaces to screens
1654 will determine which workspace i3 uses for a new screen when adding screens
1655 or when starting (e.g., by default it will use 1 for the first screen, 2 for
1656 the second screen and so on).</p></div>
1657 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
1658 <div class="listingblock">
1659 <div class="content">
1660 <pre><code>workspace &lt;workspace&gt; output &lt;output1&gt; [output2]…</code></pre>
1661 </div></div>
1662 <div class="paragraph"><p>The <em>output</em> is the name of the RandR output you attach your screen to. On a
1663 laptop, you might have VGA1 and LVDS1 as output names. You can see the
1664 available outputs by running <code>xrandr --current</code>.</p></div>
1665 <div class="paragraph"><p>If your X server supports RandR 1.5 or newer, i3 will use RandR monitor objects
1666 instead of output objects. Run <code>xrandr --listmonitors</code> to see a list. Usually,
1667 a monitor object contains exactly one output, and has the same name as the
1668 output; but should that not be the case, you may specify the name of either the
1669 monitor or the output in i3&#8217;s configuration. For example, the Dell UP2414Q uses
1670 two scalers internally, so its output names might be “DP1” and “DP2”, but the
1671 monitor name is “Dell UP2414Q”.</p></div>
1672 <div class="paragraph"><p>(Note that even if you specify the name of an output which doesn&#8217;t span the
1673 entire monitor, i3 will still use the entire area of the containing monitor
1674 rather than that of just the output&#8217;s.)</p></div>
1675 <div class="paragraph"><p>You can specify multiple outputs. The first available will be used.</p></div>
1676 <div class="paragraph"><p>If you use named workspaces, they must be quoted:</p></div>
1677 <div class="paragraph"><p><strong>Examples</strong>:</p></div>
1678 <div class="listingblock">
1679 <div class="content">
1680 <pre><code>workspace 1 output LVDS1
1681 workspace 2 output primary
1682 workspace 5 output VGA1 LVDS1
1683 workspace "2: vim" output VGA1</code></pre>
1684 </div></div>
1685 </div>
1686 <div class="sect2">
1687 <h3 id="_changing_colors">4.20. Changing colors</h3>
1688 <div class="paragraph"><p>You can change all colors which i3 uses to draw the window decorations.</p></div>
1689 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
1690 <div class="listingblock">
1691 <div class="content">
1692 <pre><code>&lt;colorclass&gt; &lt;border&gt; &lt;background&gt; &lt;text&gt; &lt;indicator&gt; &lt;child_border&gt;</code></pre>
1693 </div></div>
1694 <div class="paragraph"><p>Where colorclass can be one of:</p></div>
1695 <div class="dlist"><dl>
1696 <dt class="hdlist1">
1697 client.focused
1698 </dt>
1699 <dd>
1700 <p>
1701 A client which currently has the focus.
1702 </p>
1703 </dd>
1704 <dt class="hdlist1">
1705 client.focused_inactive
1706 </dt>
1707 <dd>
1708 <p>
1709 A client which is the focused one of its container, but it does not have
1710 the focus at the moment.
1711 </p>
1712 </dd>
1713 <dt class="hdlist1">
1714 client.unfocused
1715 </dt>
1716 <dd>
1717 <p>
1718 A client which is not the focused one of its container.
1719 </p>
1720 </dd>
1721 <dt class="hdlist1">
1722 client.urgent
1723 </dt>
1724 <dd>
1725 <p>
1726 A client which has its urgency hint activated.
1727 </p>
1728 </dd>
1729 <dt class="hdlist1">
1730 client.placeholder
1731 </dt>
1732 <dd>
1733 <p>
1734 Background and text color are used to draw placeholder window contents
1735 (when restoring layouts). Border and indicator are ignored.
1736 </p>
1737 </dd>
1738 <dt class="hdlist1">
1739 client.background
1740 </dt>
1741 <dd>
1742 <p>
1743 Background color which will be used to paint the background of the
1744 client window on top of which the client will be rendered. Only clients
1745 which do not cover the whole area of this window expose the color. Note
1746 that this colorclass only takes a single color.
1747 </p>
1748 </dd>
1749 </dl></div>
1750 <div class="paragraph"><p>Colors are in HTML hex format (#rrggbb), see the following example:</p></div>
1751 <div class="paragraph"><p><strong>Examples (default colors)</strong>:</p></div>
1752 <div class="listingblock">
1753 <div class="content">
1754 <pre><code># class border backgr. text indicator child_border
1755 client.focused #4c7899 #285577 #ffffff #2e9ef4 #285577
1756 client.focused_inactive #333333 #5f676a #ffffff #484e50 #5f676a
1757 client.unfocused #333333 #222222 #888888 #292d2e #222222
1758 client.urgent #2f343a #900000 #ffffff #900000 #900000
1759 client.placeholder #000000 #0c0c0c #ffffff #000000 #0c0c0c
1760
1761 client.background #ffffff</code></pre>
1762 </div></div>
1763 <div class="paragraph"><p>Note that for the window decorations, the color around the child window is the
1764 "child_border", and "border" color is only the two thin lines around the
1765 titlebar.</p></div>
1766 <div class="paragraph"><p>The indicator color is used for indicating where a new window will be opened.
1767 For horizontal split containers, the right border will be painted in indicator
1768 color, for vertical split containers, the bottom border. This only applies to
1769 single windows within a split container, which are otherwise indistinguishable
1770 from single windows outside of a split container.</p></div>
1771 </div>
1772 <div class="sect2">
1773 <h3 id="_interprocess_communication">4.21. Interprocess communication</h3>
1774 <div class="paragraph"><p>i3 uses Unix sockets to provide an IPC interface. This allows third-party
1775 programs to get information from i3, such as the current workspaces
1776 (to display a workspace bar), and to control i3.</p></div>
1777 <div class="paragraph"><p>The IPC socket is enabled by default and will be created in
1778 <code>/tmp/i3-%u.XXXXXX/ipc-socket.%p</code> where <code>%u</code> is your UNIX username, <code>%p</code> is
1779 the PID of i3 and XXXXXX is a string of random characters from the portable
1780 filename character set (see mkdtemp(3)).</p></div>
1781 <div class="paragraph"><p>You can override the default path through the environment-variable <code>I3SOCK</code> or
1782 by specifying the <code>ipc-socket</code> directive. This is discouraged, though, since i3
1783 does the right thing by default. If you decide to change it, it is strongly
1784 recommended to set this to a location in your home directory so that no other
1785 user can create that directory.</p></div>
1786 <div class="paragraph"><p><strong>Examples</strong>:</p></div>
1787 <div class="listingblock">
1788 <div class="content">
1789 <pre><code>ipc-socket ~/.i3/i3-ipc.sock</code></pre>
1790 </div></div>
1791 <div class="paragraph"><p>You can then use the <code>i3-msg</code> application to perform any command listed in
1792 <a href="#list_of_commands">[list_of_commands]</a>.</p></div>
1793 </div>
1794 <div class="sect2">
1795 <h3 id="_focus_follows_mouse">4.22. Focus follows mouse</h3>
1796 <div class="paragraph"><p>By default, window focus follows your mouse movements as the mouse crosses
1797 window borders. However, if you have a setup where your mouse usually is in your
1798 way (like a touchpad on your laptop which you do not want to disable
1799 completely), you might want to disable <em>focus follows mouse</em> and control focus
1800 only by using your keyboard. The mouse will still be useful inside the
1801 currently active window (for example to click on links in your browser window).</p></div>
1802 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
1803 <div class="listingblock">
1804 <div class="content">
1805 <pre><code>focus_follows_mouse yes|no</code></pre>
1806 </div></div>
1807 <div class="paragraph"><p><strong>Example</strong>:</p></div>
1808 <div class="listingblock">
1809 <div class="content">
1810 <pre><code>focus_follows_mouse no</code></pre>
1811 </div></div>
1812 </div>
1813 <div class="sect2">
1814 <h3 id="_mouse_warping">4.23. Mouse warping</h3>
1815 <div class="paragraph"><p>By default, when switching focus to a window on a different output (e.g.
1816 focusing a window on workspace 3 on output VGA-1, coming from workspace 2 on
1817 LVDS-1), the mouse cursor is warped to the center of that window.</p></div>
1818 <div class="paragraph"><p>With the <code>mouse_warping</code> option, you can control when the mouse cursor should
1819 be warped. <code>none</code> disables warping entirely, whereas <code>output</code> is the default
1820 behavior described above.</p></div>
1821 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
1822 <div class="listingblock">
1823 <div class="content">
1824 <pre><code>mouse_warping output|none</code></pre>
1825 </div></div>
1826 <div class="paragraph"><p><strong>Example</strong>:</p></div>
1827 <div class="listingblock">
1828 <div class="content">
1829 <pre><code>mouse_warping none</code></pre>
1830 </div></div>
1831 </div>
1832 <div class="sect2">
1833 <h3 id="_popups_during_fullscreen_mode">4.24. Popups during fullscreen mode</h3>
1834 <div class="paragraph"><p>When you are in fullscreen mode, some applications still open popup windows
1835 (take Xpdf for example). This is because these applications may not be aware
1836 that they are in fullscreen mode (they do not check the corresponding hint).
1837 There are three things which are possible to do in this situation:</p></div>
1838 <div class="olist arabic"><ol class="arabic">
1839 <li>
1840 <p>
1841 Display the popup if it belongs to the fullscreen application only. This is
1842 the default and should be reasonable behavior for most users.
1843 </p>
1844 </li>
1845 <li>
1846 <p>
1847 Just ignore the popup (don’t map it). This won’t interrupt you while you are
1848 in fullscreen. However, some apps might react badly to this (deadlock until
1849 you go out of fullscreen).
1850 </p>
1851 </li>
1852 <li>
1853 <p>
1854 Leave fullscreen mode.
1855 </p>
1856 </li>
1857 </ol></div>
1858 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
1859 <div class="listingblock">
1860 <div class="content">
1861 <pre><code>popup_during_fullscreen smart|ignore|leave_fullscreen</code></pre>
1862 </div></div>
1863 <div class="paragraph"><p><strong>Example</strong>:</p></div>
1864 <div class="listingblock">
1865 <div class="content">
1866 <pre><code>popup_during_fullscreen smart</code></pre>
1867 </div></div>
1868 </div>
1869 <div class="sect2">
1870 <h3 id="_focus_wrapping">4.25. Focus wrapping</h3>
1871 <div class="paragraph"><p>By default, when in a container with several windows or child containers, the
1872 opposite window will be focused when trying to move the focus over the edge of
1873 a container (and there are no other containers in that direction)&#8201;&#8212;&#8201;the focus
1874 wraps.</p></div>
1875 <div class="paragraph"><p>If desired, you can disable this behavior by setting the <code>focus_wrapping</code>
1876 configuration directive to the value <code>no</code>.</p></div>
1877 <div class="paragraph"><p>When enabled, focus wrapping does not occur by default if there is another
1878 window or container in the specified direction, and focus will instead be set
1879 on that window or container. This is the default behavior so you can navigate
1880 to all your windows without having to use <code>focus parent</code>.</p></div>
1881 <div class="paragraph"><p>If you want the focus to <strong>always</strong> wrap and you are aware of using <code>focus
1882 parent</code> to switch to different containers, you can instead set <code>focus_wrapping</code>
1883 to the value <code>force</code>.</p></div>
1884 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
1885 <div class="listingblock">
1886 <div class="content">
1887 <pre><code>focus_wrapping yes|no|force
1888
1889 # Legacy syntax, equivalent to "focus_wrapping force"
1890 force_focus_wrapping yes</code></pre>
1891 </div></div>
1892 <div class="paragraph"><p><strong>Examples</strong>:</p></div>
1893 <div class="listingblock">
1894 <div class="content">
1895 <pre><code># Disable focus wrapping
1896 focus_wrapping no
1897
1898 # Force focus wrapping
1899 focus_wrapping force</code></pre>
1900 </div></div>
1901 </div>
1902 <div class="sect2">
1903 <h3 id="_forcing_xinerama">4.26. Forcing Xinerama</h3>
1904 <div class="paragraph"><p>As explained in-depth in <a href="https://i3wm.org/docs/multi-monitor.html">https://i3wm.org/docs/multi-monitor.html</a>, some X11
1905 video drivers (especially the nVidia binary driver) only provide support for
1906 Xinerama instead of RandR. In such a situation, i3 must be told to use the
1907 inferior Xinerama API explicitly and therefore don’t provide support for
1908 reconfiguring your screens on the fly (they are read only once on startup and
1909 that’s it).</p></div>
1910 <div class="paragraph"><p>For people who cannot modify their <code>~/.xsession</code> to add the
1911 <code>--force-xinerama</code> commandline parameter, a configuration option is provided:</p></div>
1912 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
1913 <div class="listingblock">
1914 <div class="content">
1915 <pre><code>force_xinerama yes|no</code></pre>
1916 </div></div>
1917 <div class="paragraph"><p><strong>Example</strong>:</p></div>
1918 <div class="listingblock">
1919 <div class="content">
1920 <pre><code>force_xinerama yes</code></pre>
1921 </div></div>
1922 <div class="paragraph"><p>Also note that your output names are not descriptive (like <code>HDMI1</code>) when using
1923 Xinerama, instead they are counted up, starting at 0: <code>xinerama-0</code>, <code>xinerama-1</code>, …</p></div>
1924 </div>
1925 <div class="sect2">
1926 <h3 id="workspace_auto_back_and_forth">4.27. Automatic back-and-forth when switching to the current workspace</h3>
1927 <div class="paragraph"><p>This configuration directive enables automatic <code>workspace back_and_forth</code> (see
1928 <a href="#back_and_forth">[back_and_forth]</a>) when switching to the workspace that is currently focused.</p></div>
1929 <div class="paragraph"><p>For instance: Assume you are on workspace "1: www" and switch to "2: IM" using
1930 mod+2 because somebody sent you a message. You don’t need to remember where you
1931 came from now, you can just press $mod+2 again to switch back to "1: www".</p></div>
1932 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
1933 <div class="listingblock">
1934 <div class="content">
1935 <pre><code>workspace_auto_back_and_forth yes|no</code></pre>
1936 </div></div>
1937 <div class="paragraph"><p><strong>Example</strong>:</p></div>
1938 <div class="listingblock">
1939 <div class="content">
1940 <pre><code>workspace_auto_back_and_forth yes</code></pre>
1941 </div></div>
1942 </div>
1943 <div class="sect2">
1944 <h3 id="_delaying_urgency_hint_reset_on_workspace_change">4.28. Delaying urgency hint reset on workspace change</h3>
1945 <div class="paragraph"><p>If an application on another workspace sets an urgency hint, switching to this
1946 workspace may lead to immediate focus of the application, which also means the
1947 window decoration color would be immediately reset to <code>client.focused</code>. This
1948 may make it unnecessarily hard to tell which window originally raised the
1949 event.</p></div>
1950 <div class="paragraph"><p>In order to prevent this, you can tell i3 to delay resetting the urgency state
1951 by a certain time using the <code>force_display_urgency_hint</code> directive. Setting the
1952 value to 0 disables this feature.</p></div>
1953 <div class="paragraph"><p>The default is 500ms.</p></div>
1954 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
1955 <div class="listingblock">
1956 <div class="content">
1957 <pre><code>force_display_urgency_hint &lt;timeout&gt; ms</code></pre>
1958 </div></div>
1959 <div class="paragraph"><p><strong>Example</strong>:</p></div>
1960 <div class="listingblock">
1961 <div class="content">
1962 <pre><code>force_display_urgency_hint 500 ms</code></pre>
1963 </div></div>
1964 </div>
1965 <div class="sect2">
1966 <h3 id="focus_on_window_activation">4.29. Focus on window activation</h3>
1967 <div class="paragraph"><p>If a window is activated, e.g., via <code>google-chrome www.google.com</code>, it may request
1968 to take focus. Since this may not preferable, different reactions can be configured.</p></div>
1969 <div class="paragraph"><p>Note that this may not affect windows that are being opened. To prevent new windows
1970 from being focused, see <a href="#no_focus">[no_focus]</a>.</p></div>
1971 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
1972 <div class="listingblock">
1973 <div class="content">
1974 <pre><code>focus_on_window_activation smart|urgent|focus|none</code></pre>
1975 </div></div>
1976 <div class="paragraph"><p>The different modes will act as follows:</p></div>
1977 <div class="dlist"><dl>
1978 <dt class="hdlist1">
1979 smart
1980 </dt>
1981 <dd>
1982 <p>
1983 This is the default behavior. If the window requesting focus is on an active
1984 workspace, it will receive the focus. Otherwise, the urgency hint will be set.
1985 </p>
1986 </dd>
1987 <dt class="hdlist1">
1988 urgent
1989 </dt>
1990 <dd>
1991 <p>
1992 The window will always be marked urgent, but the focus will not be stolen.
1993 </p>
1994 </dd>
1995 <dt class="hdlist1">
1996 focus
1997 </dt>
1998 <dd>
1999 <p>
2000 The window will always be focused and not be marked urgent.
2001 </p>
2002 </dd>
2003 <dt class="hdlist1">
2004 none
2005 </dt>
2006 <dd>
2007 <p>
2008 The window will neither be focused, nor be marked urgent.
2009 </p>
2010 </dd>
2011 </dl></div>
2012 </div>
2013 <div class="sect2">
2014 <h3 id="show_marks">4.30. Drawing marks on window decoration</h3>
2015 <div class="paragraph"><p>If activated, marks (see <a href="#vim_like_marks">[vim_like_marks]</a>) on windows are drawn in their window
2016 decoration. However, any mark starting with an underscore in its name (<code>_</code>) will
2017 not be drawn even if this option is activated.</p></div>
2018 <div class="paragraph"><p>The default for this option is <code>yes</code>.</p></div>
2019 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
2020 <div class="listingblock">
2021 <div class="content">
2022 <pre><code>show_marks yes|no</code></pre>
2023 </div></div>
2024 <div class="paragraph"><p><strong>Example</strong>:</p></div>
2025 <div class="listingblock">
2026 <div class="content">
2027 <pre><code>show_marks yes</code></pre>
2028 </div></div>
2029 </div>
2030 <div class="sect2">
2031 <h3 id="line_continuation">4.31. Line continuation</h3>
2032 <div class="paragraph"><p>Config files support line continuation, meaning when you end a line in a
2033 backslash character (<code>\</code>), the line-break will be ignored by the parser. This
2034 feature can be used to create more readable configuration files.
2035 Commented lines are not continued.</p></div>
2036 <div class="paragraph"><p><strong>Examples</strong>:</p></div>
2037 <div class="listingblock">
2038 <div class="content">
2039 <pre><code>bindsym Mod1+f \
2040 fullscreen toggle
2041
2042 # this line is not continued \
2043 bindsym Mod1+F fullscreen toggle</code></pre>
2044 </div></div>
2045 </div>
2046 </div>
2047 </div>
2048 <div class="sect1">
2049 <h2 id="_configuring_i3bar">5. Configuring i3bar</h2>
2050 <div class="sectionbody">
2051 <div class="paragraph"><p>The bar at the bottom of your monitor is drawn by a separate process called
2052 i3bar. Having this part of "the i3 user interface" in a separate process has
2053 several advantages:</p></div>
2054 <div class="olist arabic"><ol class="arabic">
2055 <li>
2056 <p>
2057 It is a modular approach. If you don’t need a workspace bar at all, or if
2058 you prefer a different one (dzen2, xmobar, maybe even gnome-panel?), you can
2059 just remove the i3bar configuration and start your favorite bar instead.
2060 </p>
2061 </li>
2062 <li>
2063 <p>
2064 It follows the UNIX philosophy of "Make each program do one thing well".
2065 While i3 manages your windows well, i3bar is good at displaying a bar on
2066 each monitor (unless you configure it otherwise).
2067 </p>
2068 </li>
2069 <li>
2070 <p>
2071 It leads to two separate, clean codebases. If you want to understand i3, you
2072 don’t need to bother with the details of i3bar and vice versa.
2073 </p>
2074 </li>
2075 </ol></div>
2076 <div class="paragraph"><p>That said, i3bar is configured in the same configuration file as i3. This is
2077 because it is tightly coupled with i3 (in contrary to i3lock or i3status which
2078 are useful for people using other window managers). Therefore, it makes no
2079 sense to use a different configuration place when we already have a good
2080 configuration infrastructure in place.</p></div>
2081 <div class="paragraph"><p>Configuring your workspace bar starts with opening a <code>bar</code> block. You can have
2082 multiple bar blocks to use different settings for different outputs (monitors):</p></div>
2083 <div class="paragraph"><p><strong>Example</strong>:</p></div>
2084 <div class="listingblock">
2085 <div class="content">
2086 <pre><code>bar {
2087 status_command i3status
2088 }</code></pre>
2089 </div></div>
2090 <div class="sect2">
2091 <h3 id="_i3bar_command">5.1. i3bar command</h3>
2092 <div class="paragraph"><p>By default i3 will just pass <code>i3bar</code> and let your shell handle the execution,
2093 searching your <code>$PATH</code> for a correct version.
2094 If you have a different <code>i3bar</code> somewhere or the binary is not in your <code>$PATH</code> you can
2095 tell i3 what to execute.</p></div>
2096 <div class="paragraph"><p>The specified command will be passed to <code>sh -c</code>, so you can use globbing and
2097 have to have correct quoting etc.</p></div>
2098 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
2099 <div class="listingblock">
2100 <div class="content">
2101 <pre><code>i3bar_command &lt;command&gt;</code></pre>
2102 </div></div>
2103 <div class="paragraph"><p><strong>Example</strong>:</p></div>
2104 <div class="listingblock">
2105 <div class="content">
2106 <pre><code>bar {
2107 i3bar_command /home/user/bin/i3bar
2108 }</code></pre>
2109 </div></div>
2110 </div>
2111 <div class="sect2">
2112 <h3 id="status_command">5.2. Statusline command</h3>
2113 <div class="paragraph"><p>i3bar can run a program and display every line of its <code>stdout</code> output on the
2114 right hand side of the bar. This is useful to display system information like
2115 your current IP address, battery status or date/time.</p></div>
2116 <div class="paragraph"><p>The specified command will be passed to <code>sh -c</code>, so you can use globbing and
2117 have to have correct quoting etc. Note that for signal handling, depending on
2118 your shell (users of dash(1) are known to be affected), you have to use the
2119 shell’s exec command so that signals are passed to your program, not to the
2120 shell.</p></div>
2121 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
2122 <div class="listingblock">
2123 <div class="content">
2124 <pre><code>status_command &lt;command&gt;</code></pre>
2125 </div></div>
2126 <div class="paragraph"><p><strong>Example</strong>:</p></div>
2127 <div class="listingblock">
2128 <div class="content">
2129 <pre><code>bar {
2130 status_command i3status --config ~/.i3status.conf
2131
2132 # For dash(1) users who want signal handling to work:
2133 status_command exec ~/.bin/my_status_command
2134 }</code></pre>
2135 </div></div>
2136 </div>
2137 <div class="sect2">
2138 <h3 id="_display_mode">5.3. Display mode</h3>
2139 <div class="paragraph"><p>You can either have i3bar be visible permanently at one edge of the screen
2140 (<code>dock</code> mode) or make it show up when you press your modifier key (<code>hide</code> mode).
2141 It is also possible to force i3bar to always stay hidden (<code>invisible</code>
2142 mode). The modifier key can be configured using the <code>modifier</code> option.</p></div>
2143 <div class="paragraph"><p>The mode option can be changed during runtime through the <code>bar mode</code> command.
2144 On reload the mode will be reverted to its configured value.</p></div>
2145 <div class="paragraph"><p>The hide mode maximizes screen space that can be used for actual windows. Also,
2146 i3bar sends the <code>SIGSTOP</code> and <code>SIGCONT</code> signals to the statusline process to
2147 save battery power.</p></div>
2148 <div class="paragraph"><p>Invisible mode allows to permanently maximize screen space, as the bar is never
2149 shown. Thus, you can configure i3bar to not disturb you by popping up because
2150 of an urgency hint or because the modifier key is pressed.</p></div>
2151 <div class="paragraph"><p>In order to control whether i3bar is hidden or shown in hide mode, there exists
2152 the hidden_state option, which has no effect in dock mode or invisible mode. It
2153 indicates the current hidden_state of the bar: (1) The bar acts like in normal
2154 hide mode, it is hidden and is only unhidden in case of urgency hints or by
2155 pressing the modifier key (<code>hide</code> state), or (2) it is drawn on top of the
2156 currently visible workspace (<code>show</code> state).</p></div>
2157 <div class="paragraph"><p>Like the mode, the hidden_state can also be controlled through i3, this can be
2158 done by using the <code>bar hidden_state</code> command.</p></div>
2159 <div class="paragraph"><p>The default mode is dock mode; in hide mode, the default modifier is Mod4 (usually
2160 the windows key). The default value for the hidden_state is hide.</p></div>
2161 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
2162 <div class="listingblock">
2163 <div class="content">
2164 <pre><code>mode dock|hide|invisible
2165 hidden_state hide|show
2166 modifier &lt;Modifier&gt;|none</code></pre>
2167 </div></div>
2168 <div class="paragraph"><p><strong>Example</strong>:</p></div>
2169 <div class="listingblock">
2170 <div class="content">
2171 <pre><code>bar {
2172 mode hide
2173 hidden_state hide
2174 modifier Mod1
2175 }</code></pre>
2176 </div></div>
2177 <div class="paragraph"><p>Available modifiers are Mod1-Mod5, Shift, Control (see <code>xmodmap(1)</code>). You can
2178 also use "none" if you don&#8217;t want any modifier to trigger this behavior.</p></div>
2179 </div>
2180 <div class="sect2">
2181 <h3 id="_mouse_button_commands">5.4. Mouse button commands</h3>
2182 <div class="paragraph"><p>Specifies a command to run when a button was pressed on i3bar to override the
2183 default behavior. This is useful, e.g., for disabling the scroll wheel action
2184 or running scripts that implement custom behavior for these buttons.</p></div>
2185 <div class="paragraph"><p>A button is always named <code>button&lt;n&gt;</code>, where 1 to 5 are default buttons as follows and higher
2186 numbers can be special buttons on devices offering more buttons:</p></div>
2187 <div class="dlist"><dl>
2188 <dt class="hdlist1">
2189 button1
2190 </dt>
2191 <dd>
2192 <p>
2193 Left mouse button.
2194 </p>
2195 </dd>
2196 <dt class="hdlist1">
2197 button2
2198 </dt>
2199 <dd>
2200 <p>
2201 Middle mouse button.
2202 </p>
2203 </dd>
2204 <dt class="hdlist1">
2205 button3
2206 </dt>
2207 <dd>
2208 <p>
2209 Right mouse button.
2210 </p>
2211 </dd>
2212 <dt class="hdlist1">
2213 button4
2214 </dt>
2215 <dd>
2216 <p>
2217 Scroll wheel up.
2218 </p>
2219 </dd>
2220 <dt class="hdlist1">
2221 button5
2222 </dt>
2223 <dd>
2224 <p>
2225 Scroll wheel down.
2226 </p>
2227 </dd>
2228 </dl></div>
2229 <div class="paragraph"><p>Please note that the old <code>wheel_up_cmd</code> and <code>wheel_down_cmd</code> commands are deprecated
2230 and will be removed in a future release. We strongly recommend using the more general
2231 <code>bindsym</code> with <code>button4</code> and <code>button5</code> instead.</p></div>
2232 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
2233 <div class="listingblock">
2234 <div class="content">
2235 <pre><code>bindsym [--release] button&lt;n&gt; &lt;command&gt;</code></pre>
2236 </div></div>
2237 <div class="paragraph"><p><strong>Example</strong>:</p></div>
2238 <div class="listingblock">
2239 <div class="content">
2240 <pre><code>bar {
2241 # disable clicking on workspace buttons
2242 bindsym button1 nop
2243 # Take a screenshot by right clicking on the bar
2244 bindsym --release button3 exec --no-startup-id import /tmp/latest-screenshot.png
2245 # execute custom script when scrolling downwards
2246 bindsym button5 exec ~/.i3/scripts/custom_wheel_down
2247 }</code></pre>
2248 </div></div>
2249 </div>
2250 <div class="sect2">
2251 <h3 id="_bar_id">5.5. Bar ID</h3>
2252 <div class="paragraph"><p>Specifies the bar ID for the configured bar instance. If this option is missing,
2253 the ID is set to <em>bar-x</em>, where x corresponds to the position of the embedding
2254 bar block in the config file (<em>bar-0</em>, <em>bar-1</em>, &#8230;).</p></div>
2255 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
2256 <div class="listingblock">
2257 <div class="content">
2258 <pre><code>id &lt;bar_id&gt;</code></pre>
2259 </div></div>
2260 <div class="paragraph"><p><strong>Example</strong>:</p></div>
2261 <div class="listingblock">
2262 <div class="content">
2263 <pre><code>bar {
2264 id bar-1
2265 }</code></pre>
2266 </div></div>
2267 </div>
2268 <div class="sect2">
2269 <h3 id="i3bar_position">5.6. Position</h3>
2270 <div class="paragraph"><p>This option determines in which edge of the screen i3bar should show up.</p></div>
2271 <div class="paragraph"><p>The default is bottom.</p></div>
2272 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
2273 <div class="listingblock">
2274 <div class="content">
2275 <pre><code>position top|bottom</code></pre>
2276 </div></div>
2277 <div class="paragraph"><p><strong>Example</strong>:</p></div>
2278 <div class="listingblock">
2279 <div class="content">
2280 <pre><code>bar {
2281 position top
2282 }</code></pre>
2283 </div></div>
2284 </div>
2285 <div class="sect2">
2286 <h3 id="_output_s">5.7. Output(s)</h3>
2287 <div class="paragraph"><p>You can restrict i3bar to one or more outputs (monitors). The default is to
2288 handle all outputs. Restricting the outputs is useful for using different
2289 options for different outputs by using multiple <em>bar</em> blocks.</p></div>
2290 <div class="paragraph"><p>To make a particular i3bar instance handle multiple outputs, specify the output
2291 directive multiple times.</p></div>
2292 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
2293 <div class="listingblock">
2294 <div class="content">
2295 <pre><code>output primary|&lt;output&gt;</code></pre>
2296 </div></div>
2297 <div class="paragraph"><p><strong>Example</strong>:</p></div>
2298 <div class="listingblock">
2299 <div class="content">
2300 <pre><code># big monitor: everything
2301 bar {
2302 # The display is connected either via HDMI or via DisplayPort
2303 output HDMI2
2304 output DP2
2305 status_command i3status
2306 }
2307
2308 # laptop monitor: bright colors and i3status with less modules.
2309 bar {
2310 output LVDS1
2311 status_command i3status --config ~/.i3status-small.conf
2312 colors {
2313 background #000000
2314 statusline #ffffff
2315 }
2316 }
2317
2318 # show bar on the primary monitor and on HDMI2
2319 bar {
2320 output primary
2321 output HDMI2
2322 status_command i3status
2323 }</code></pre>
2324 </div></div>
2325 <div class="paragraph"><p>Note that you might not have a primary output configured yet. To do so, run:</p></div>
2326 <div class="listingblock">
2327 <div class="content">
2328 <pre><code>xrandr --output &lt;output&gt; --primary</code></pre>
2329 </div></div>
2330 </div>
2331 <div class="sect2">
2332 <h3 id="_tray_output">5.8. Tray output</h3>
2333 <div class="paragraph"><p>i3bar by default provides a system tray area where programs such as
2334 NetworkManager, VLC, Pidgin, etc. can place little icons.</p></div>
2335 <div class="paragraph"><p>You can configure on which output (monitor) the icons should be displayed or
2336 you can turn off the functionality entirely.</p></div>
2337 <div class="paragraph"><p>You can use multiple <code>tray_output</code> directives in your config to specify a list
2338 of outputs on which you want the tray to appear. The first available output in
2339 that list as defined by the order of the directives will be used for the tray
2340 output.</p></div>
2341 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
2342 <div class="listingblock">
2343 <div class="content">
2344 <pre><code>tray_output none|primary|&lt;output&gt;</code></pre>
2345 </div></div>
2346 <div class="paragraph"><p><strong>Example</strong>:</p></div>
2347 <div class="listingblock">
2348 <div class="content">
2349 <pre><code># disable system tray
2350 bar {
2351 tray_output none
2352 }
2353
2354 # show tray icons on the primary monitor
2355 bar {
2356 tray_output primary
2357 }
2358
2359 # show tray icons on the big monitor
2360 bar {
2361 tray_output HDMI2
2362 }</code></pre>
2363 </div></div>
2364 <div class="paragraph"><p>Note that you might not have a primary output configured yet. To do so, run:</p></div>
2365 <div class="listingblock">
2366 <div class="content">
2367 <pre><code>xrandr --output &lt;output&gt; --primary</code></pre>
2368 </div></div>
2369 <div class="paragraph"><p>Note that when you use multiple bar configuration blocks, either specify
2370 <code>tray_output primary</code> in all of them or explicitly specify <code>tray_output none</code>
2371 in bars which should not display the tray, otherwise the different instances
2372 might race each other in trying to display tray icons.</p></div>
2373 </div>
2374 <div class="sect2">
2375 <h3 id="_tray_padding">5.9. Tray padding</h3>
2376 <div class="paragraph"><p>The tray is shown on the right-hand side of the bar. By default, a padding of 2
2377 pixels is used for the upper, lower and right-hand side of the tray area and
2378 between the individual icons.</p></div>
2379 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
2380 <div class="listingblock">
2381 <div class="content">
2382 <pre><code>tray_padding &lt;px&gt; [px]</code></pre>
2383 </div></div>
2384 <div class="paragraph"><p><strong>Example</strong>:</p></div>
2385 <div class="listingblock">
2386 <div class="content">
2387 <pre><code># Obey Fitts's law
2388 tray_padding 0</code></pre>
2389 </div></div>
2390 </div>
2391 <div class="sect2">
2392 <h3 id="_font">5.10. Font</h3>
2393 <div class="paragraph"><p>Specifies the font to be used in the bar. See <a href="#fonts">[fonts]</a>.</p></div>
2394 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
2395 <div class="listingblock">
2396 <div class="content">
2397 <pre><code>font &lt;font&gt;</code></pre>
2398 </div></div>
2399 <div class="paragraph"><p><strong>Example</strong>:</p></div>
2400 <div class="listingblock">
2401 <div class="content">
2402 <pre><code>bar {
2403 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
2404 font pango:DejaVu Sans Mono 10
2405 }</code></pre>
2406 </div></div>
2407 </div>
2408 <div class="sect2">
2409 <h3 id="_custom_separator_symbol">5.11. Custom separator symbol</h3>
2410 <div class="paragraph"><p>Specifies a custom symbol to be used for the separator as opposed to the vertical,
2411 one pixel thick separator.</p></div>
2412 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
2413 <div class="listingblock">
2414 <div class="content">
2415 <pre><code>separator_symbol &lt;symbol&gt;</code></pre>
2416 </div></div>
2417 <div class="paragraph"><p><strong>Example</strong>:</p></div>
2418 <div class="listingblock">
2419 <div class="content">
2420 <pre><code>bar {
2421 separator_symbol ":|:"
2422 }</code></pre>
2423 </div></div>
2424 </div>
2425 <div class="sect2">
2426 <h3 id="_workspace_buttons">5.12. Workspace buttons</h3>
2427 <div class="paragraph"><p>Specifies whether workspace buttons should be shown or not. This is useful if
2428 you want to display a statusline-only bar containing additional information.</p></div>
2429 <div class="paragraph"><p>The default is to show workspace buttons.</p></div>
2430 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
2431 <div class="listingblock">
2432 <div class="content">
2433 <pre><code>workspace_buttons yes|no</code></pre>
2434 </div></div>
2435 <div class="paragraph"><p><strong>Example</strong>:</p></div>
2436 <div class="listingblock">
2437 <div class="content">
2438 <pre><code>bar {
2439 workspace_buttons no
2440 }</code></pre>
2441 </div></div>
2442 </div>
2443 <div class="sect2">
2444 <h3 id="_strip_workspace_numbers_name">5.13. Strip workspace numbers/name</h3>
2445 <div class="paragraph"><p>Specifies whether workspace numbers should be displayed within the workspace
2446 buttons. This is useful if you want to have a named workspace that stays in
2447 order on the bar according to its number without displaying the number prefix.</p></div>
2448 <div class="paragraph"><p>When <code>strip_workspace_numbers</code> is set to <code>yes</code>, any workspace that has a name of
2449 the form "[n][:][NAME]" will display only the name. You could use this, for
2450 instance, to display Roman numerals rather than digits by naming your
2451 workspaces to "1:I", "2:II", "3:III", "4:IV", &#8230;</p></div>
2452 <div class="paragraph"><p>When <code>strip_workspace_name</code> is set to <code>yes</code>, any workspace that has a name of
2453 the form "[n][:][NAME]" will display only the number.</p></div>
2454 <div class="paragraph"><p>The default is to display the full name within the workspace button. Be aware
2455 that the colon in the workspace name is optional, so <code>[n][NAME]</code> will also
2456 have the the workspace name and number stripped correctly.</p></div>
2457 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
2458 <div class="listingblock">
2459 <div class="content">
2460 <pre><code>strip_workspace_numbers yes|no
2461 strip_workspace_name yes|no</code></pre>
2462 </div></div>
2463 <div class="paragraph"><p><strong>Example</strong>:</p></div>
2464 <div class="listingblock">
2465 <div class="content">
2466 <pre><code>bar {
2467 strip_workspace_numbers yes
2468 }</code></pre>
2469 </div></div>
2470 </div>
2471 <div class="sect2">
2472 <h3 id="_binding_mode_indicator">5.14. Binding Mode indicator</h3>
2473 <div class="paragraph"><p>Specifies whether the current binding mode indicator should be shown or not.
2474 This is useful if you want to hide the workspace buttons but still be able
2475 to see the current binding mode indicator. See <a href="#binding_modes">[binding_modes]</a> to learn what
2476 modes are and how to use them.</p></div>
2477 <div class="paragraph"><p>The default is to show the mode indicator.</p></div>
2478 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
2479 <div class="listingblock">
2480 <div class="content">
2481 <pre><code>binding_mode_indicator yes|no</code></pre>
2482 </div></div>
2483 <div class="paragraph"><p><strong>Example</strong>:</p></div>
2484 <div class="listingblock">
2485 <div class="content">
2486 <pre><code>bar {
2487 binding_mode_indicator no
2488 }</code></pre>
2489 </div></div>
2490 </div>
2491 <div class="sect2">
2492 <h3 id="_colors">5.15. Colors</h3>
2493 <div class="paragraph"><p>As with i3, colors are in HTML hex format (#rrggbb). The following colors can
2494 be configured at the moment:</p></div>
2495 <div class="dlist"><dl>
2496 <dt class="hdlist1">
2497 background
2498 </dt>
2499 <dd>
2500 <p>
2501 Background color of the bar.
2502 </p>
2503 </dd>
2504 <dt class="hdlist1">
2505 statusline
2506 </dt>
2507 <dd>
2508 <p>
2509 Text color to be used for the statusline.
2510 </p>
2511 </dd>
2512 <dt class="hdlist1">
2513 separator
2514 </dt>
2515 <dd>
2516 <p>
2517 Text color to be used for the separator.
2518 </p>
2519 </dd>
2520 <dt class="hdlist1">
2521 focused_background
2522 </dt>
2523 <dd>
2524 <p>
2525 Background color of the bar on the currently focused monitor output. If
2526 not used, the color will be taken from <code>background</code>.
2527 </p>
2528 </dd>
2529 <dt class="hdlist1">
2530 focused_statusline
2531 </dt>
2532 <dd>
2533 <p>
2534 Text color to be used for the statusline on the currently focused
2535 monitor output. If not used, the color will be taken from <code>statusline</code>.
2536 </p>
2537 </dd>
2538 <dt class="hdlist1">
2539 focused_separator
2540 </dt>
2541 <dd>
2542 <p>
2543 Text color to be used for the separator on the currently focused
2544 monitor output. If not used, the color will be taken from <code>separator</code>.
2545 </p>
2546 </dd>
2547 <dt class="hdlist1">
2548 focused_workspace
2549 </dt>
2550 <dd>
2551 <p>
2552 Border, background and text color for a workspace button when the workspace
2553 has focus.
2554 </p>
2555 </dd>
2556 <dt class="hdlist1">
2557 active_workspace
2558 </dt>
2559 <dd>
2560 <p>
2561 Border, background and text color for a workspace button when the workspace
2562 is active (visible) on some output, but the focus is on another one.
2563 You can only tell this apart from the focused workspace when you are
2564 using multiple monitors.
2565 </p>
2566 </dd>
2567 <dt class="hdlist1">
2568 inactive_workspace
2569 </dt>
2570 <dd>
2571 <p>
2572 Border, background and text color for a workspace button when the workspace
2573 does not have focus and is not active (visible) on any output. This
2574 will be the case for most workspaces.
2575 </p>
2576 </dd>
2577 <dt class="hdlist1">
2578 urgent_workspace
2579 </dt>
2580 <dd>
2581 <p>
2582 Border, background and text color for a workspace button when the workspace
2583 contains a window with the urgency hint set.
2584 </p>
2585 </dd>
2586 <dt class="hdlist1">
2587 binding_mode
2588 </dt>
2589 <dd>
2590 <p>
2591 Border, background and text color for the binding mode indicator. If not used,
2592 the colors will be taken from <code>urgent_workspace</code>.
2593 </p>
2594 </dd>
2595 </dl></div>
2596 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
2597 <div class="listingblock">
2598 <div class="content">
2599 <pre><code>colors {
2600 background &lt;color&gt;
2601 statusline &lt;color&gt;
2602 separator &lt;color&gt;
2603
2604 &lt;colorclass&gt; &lt;border&gt; &lt;background&gt; &lt;text&gt;
2605 }</code></pre>
2606 </div></div>
2607 <div class="paragraph"><p><strong>Example (default colors)</strong>:</p></div>
2608 <div class="listingblock">
2609 <div class="content">
2610 <pre><code>bar {
2611 colors {
2612 background #000000
2613 statusline #ffffff
2614 separator #666666
2615
2616 focused_workspace #4c7899 #285577 #ffffff
2617 active_workspace #333333 #5f676a #ffffff
2618 inactive_workspace #333333 #222222 #888888
2619 urgent_workspace #2f343a #900000 #ffffff
2620 binding_mode #2f343a #900000 #ffffff
2621 }
2622 }</code></pre>
2623 </div></div>
2624 </div>
2625 <div class="sect2">
2626 <h3 id="_transparency">5.16. Transparency</h3>
2627 <div class="paragraph"><p>i3bar can support transparency by passing the <code>--transparency</code> flag in the
2628 configuration:</p></div>
2629 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
2630 <div class="listingblock">
2631 <div class="content">
2632 <pre><code>bar {
2633 i3bar_command i3bar --transparency
2634 }</code></pre>
2635 </div></div>
2636 <div class="paragraph"><p>In the i3bar color configuration and i3bar status block color attribute you can
2637 then use colors in the RGBA format, i.e. the last two (hexadecimal) digits
2638 specify the opacity. For example, <code>#00000000</code> will be completely transparent,
2639 while <code>#000000FF</code> will be a fully opaque black (the same as <code>#000000</code>).</p></div>
2640 <div class="paragraph"><p>Please note that due to the way the tray specification works, enabling this
2641 flag will cause all tray icons to have a transparent background.</p></div>
2642 </div>
2643 </div>
2644 </div>
2645 <div class="sect1">
2646 <h2 id="list_of_commands">6. List of commands</h2>
2647 <div class="sectionbody">
2648 <div class="paragraph"><p>Commands are what you bind to specific keypresses. You can also issue commands
2649 at runtime without pressing a key by using the IPC interface. An easy way to
2650 do this is to use the <code>i3-msg</code> utility:</p></div>
2651 <div class="paragraph"><p><strong>Example</strong>:</p></div>
2652 <div class="listingblock">
2653 <div class="content">
2654 <pre><code># execute this on your shell to make the current container borderless
2655 i3-msg border none</code></pre>
2656 </div></div>
2657 <div class="paragraph" id="command_chaining"><p>Commands can be chained by using <code>;</code> (a semicolon). So, to move a window to a
2658 specific workspace and immediately switch to that workspace, you can configure
2659 the following keybinding:</p></div>
2660 <div class="paragraph"><p><strong>Example</strong>:</p></div>
2661 <div class="listingblock">
2662 <div class="content">
2663 <pre><code>bindsym $mod+x move container to workspace 3; workspace 3</code></pre>
2664 </div></div>
2665 <div class="paragraph" id="command_criteria"><p>Furthermore, you can change the scope of a command - that is, which containers
2666 should be affected by that command, by using various criteria. The criteria
2667 are specified before any command in a pair of square brackets and are separated
2668 by space.</p></div>
2669 <div class="paragraph"><p>When using multiple commands, separate them by using a <code>,</code> (a comma) instead of
2670 a semicolon. Criteria apply only until the next semicolon, so if you use a
2671 semicolon to separate commands, only the first one will be executed for the
2672 matched window(s).</p></div>
2673 <div class="paragraph"><p><strong>Example</strong>:</p></div>
2674 <div class="listingblock">
2675 <div class="content">
2676 <pre><code># if you want to kill all windows which have the class Firefox, use:
2677 bindsym $mod+x [class="Firefox"] kill
2678
2679 # same thing, but case-insensitive
2680 bindsym $mod+x [class="(?i)firefox"] kill
2681
2682 # kill only the About dialog from Firefox
2683 bindsym $mod+x [class="Firefox" window_role="About"] kill
2684
2685 # enable floating mode and move container to workspace 4
2686 for_window [class="^evil-app$"] floating enable, move container to workspace 4
2687
2688 # move all floating windows to the scratchpad
2689 bindsym $mod+x [floating] move scratchpad</code></pre>
2690 </div></div>
2691 <div class="paragraph"><p>The criteria which are currently implemented are:</p></div>
2692 <div class="dlist"><dl>
2693 <dt class="hdlist1">
2694 class
2695 </dt>
2696 <dd>
2697 <p>
2698 Compares the window class (the second part of WM_CLASS). Use the
2699 special value <code>__focused__</code> to match all windows having the same window
2700 class as the currently focused window.
2701 </p>
2702 </dd>
2703 <dt class="hdlist1">
2704 instance
2705 </dt>
2706 <dd>
2707 <p>
2708 Compares the window instance (the first part of WM_CLASS). Use the
2709 special value <code>__focused__</code> to match all windows having the same window
2710 instance as the currently focused window.
2711 </p>
2712 </dd>
2713 <dt class="hdlist1">
2714 window_role
2715 </dt>
2716 <dd>
2717 <p>
2718 Compares the window role (WM_WINDOW_ROLE). Use the special value
2719 <code>__focused__</code> to match all windows having the same window role as the
2720 currently focused window.
2721 </p>
2722 </dd>
2723 <dt class="hdlist1">
2724 window_type
2725 </dt>
2726 <dd>
2727 <p>
2728 Compare the window type (_NET_WM_WINDOW_TYPE). Possible values are
2729 <code>normal</code>, <code>dialog</code>, <code>utility</code>, <code>toolbar</code>, <code>splash</code>, <code>menu</code>, <code>dropdown_menu</code>,
2730 <code>popup_menu</code>, <code>tooltip</code> and <code>notification</code>.
2731 </p>
2732 </dd>
2733 <dt class="hdlist1">
2734 id
2735 </dt>
2736 <dd>
2737 <p>
2738 Compares the X11 window ID, which you can get via <code>xwininfo</code> for example.
2739 </p>
2740 </dd>
2741 <dt class="hdlist1">
2742 title
2743 </dt>
2744 <dd>
2745 <p>
2746 Compares the X11 window title (_NET_WM_NAME or WM_NAME as fallback).
2747 Use the special value <code>__focused__</code> to match all windows having the
2748 same window title as the currently focused window.
2749 </p>
2750 </dd>
2751 <dt class="hdlist1">
2752 urgent
2753 </dt>
2754 <dd>
2755 <p>
2756 Compares the urgent state of the window. Can be "latest" or "oldest".
2757 Matches the latest or oldest urgent window, respectively.
2758 (The following aliases are also available: newest, last, recent, first)
2759 </p>
2760 </dd>
2761 <dt class="hdlist1">
2762 workspace
2763 </dt>
2764 <dd>
2765 <p>
2766 Compares the workspace name of the workspace the window belongs to. Use
2767 the special value <code>__focused__</code> to match all windows in the currently
2768 focused workspace.
2769 </p>
2770 </dd>
2771 <dt class="hdlist1">
2772 con_mark
2773 </dt>
2774 <dd>
2775 <p>
2776 Compares the marks set for this container, see <a href="#vim_like_marks">[vim_like_marks]</a>. A
2777 match is made if any of the container&#8217;s marks matches the specified
2778 mark.
2779 </p>
2780 </dd>
2781 <dt class="hdlist1">
2782 con_id
2783 </dt>
2784 <dd>
2785 <p>
2786 Compares the i3-internal container ID, which you can get via the IPC
2787 interface. Handy for scripting. Use the special value <code>__focused__</code>
2788 to match only the currently focused window.
2789 </p>
2790 </dd>
2791 <dt class="hdlist1">
2792 floating
2793 </dt>
2794 <dd>
2795 <p>
2796 Only matches floating windows. This criterion requires no value.
2797 </p>
2798 </dd>
2799 <dt class="hdlist1">
2800 tiling
2801 </dt>
2802 <dd>
2803 <p>
2804 Only matches tiling windows. This criterion requires no value.
2805 </p>
2806 </dd>
2807 </dl></div>
2808 <div class="paragraph"><p>The criteria <code>class</code>, <code>instance</code>, <code>role</code>, <code>title</code>, <code>workspace</code> and <code>mark</code> are
2809 actually regular expressions (PCRE). See <code>pcresyntax(3)</code> or <code>perldoc perlre</code> for
2810 information on how to use them.</p></div>
2811 <div class="paragraph"><p>Note that config directives listed under <a href="#configuring">[configuring]</a> cannot be changed at runtime
2812 unless they happen to have a command equivalent.</p></div>
2813 <div class="sect2">
2814 <h3 id="exec">6.1. Executing applications (exec)</h3>
2815 <div class="paragraph"><p>What good is a window manager if you can’t actually start any applications?
2816 The exec command starts an application by passing the command you specify to a
2817 shell. This implies that you can use globbing (wildcards) and programs will be
2818 searched in your <code>$PATH</code>.</p></div>
2819 <div class="paragraph"><p>See <a href="#command_chaining">[command_chaining]</a> for details on the special meaning of <code>;</code> (semicolon)
2820 and <code>,</code> (comma): they chain commands together in i3, so you need to use quoted
2821 strings (as shown in <a href="#exec_quoting">[exec_quoting]</a>) if they appear in your command.</p></div>
2822 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
2823 <div class="listingblock">
2824 <div class="content">
2825 <pre><code>exec [--no-startup-id] &lt;command&gt;</code></pre>
2826 </div></div>
2827 <div class="paragraph"><p><strong>Example</strong>:</p></div>
2828 <div class="listingblock">
2829 <div class="content">
2830 <pre><code># Start the GIMP
2831 bindsym $mod+g exec gimp
2832
2833 # Start the terminal emulator urxvt which is not yet startup-notification-aware
2834 bindsym $mod+Return exec --no-startup-id urxvt</code></pre>
2835 </div></div>
2836 <div class="paragraph"><p>The <code>--no-startup-id</code> parameter disables startup-notification support for this
2837 particular exec command. With startup-notification, i3 can make sure that a
2838 window appears on the workspace on which you used the exec command. Also, it
2839 will change the X11 cursor to <code>watch</code> (a clock) while the application is
2840 launching. So, if an application is not startup-notification aware (most GTK
2841 and Qt using applications seem to be, though), you will end up with a watch
2842 cursor for 60 seconds.</p></div>
2843 <div class="paragraph" id="exec_quoting"><p>If the command to be executed contains a <code>;</code> (semicolon) and/or a <code>,</code> (comma),
2844 the entire command must be quoted. For example, to have a keybinding for the
2845 shell command <code>notify-send Hello, i3</code>, you would add an entry to your
2846 configuration file like this:</p></div>
2847 <div class="paragraph"><p><strong>Example</strong>:</p></div>
2848 <div class="listingblock">
2849 <div class="content">
2850 <pre><code># Execute a command with a comma in it
2851 bindsym $mod+p exec "notify-send Hello, i3"</code></pre>
2852 </div></div>
2853 <div class="paragraph"><p>If however a command with a comma and/or semicolon itself requires quotes, you
2854 must escape the internal quotation marks with double backslashes, like this:</p></div>
2855 <div class="paragraph"><p><strong>Example</strong>:</p></div>
2856 <div class="listingblock">
2857 <div class="content">
2858 <pre><code># Execute a command with a comma, semicolon and internal quotes
2859 bindsym $mod+p exec "notify-send \\"Hello, i3; from $USER\\""</code></pre>
2860 </div></div>
2861 </div>
2862 <div class="sect2">
2863 <h3 id="_splitting_containers">6.2. Splitting containers</h3>
2864 <div class="paragraph"><p>The split command makes the current window a split container. Split containers
2865 can contain multiple windows. Depending on the layout of the split container,
2866 new windows get placed to the right of the current one (splith) or new windows
2867 get placed below the current one (splitv).</p></div>
2868 <div class="paragraph"><p>If you apply this command to a split container with the same orientation,
2869 nothing will happen. If you use a different orientation, the split container’s
2870 orientation will be changed (if it does not have more than one window).
2871 The <code>toggle</code> option will toggle the orientation of the split container if it
2872 contains a single window. Otherwise it makes the current window a split
2873 container with opposite orientation compared to the parent container.
2874 Use <code>layout toggle split</code> to change the layout of any split container from
2875 splitv to splith or vice-versa. You can also define a custom sequence of layouts
2876 to cycle through with <code>layout toggle</code>, see <a href="#manipulating_layout">[manipulating_layout]</a>.</p></div>
2877 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
2878 <div class="listingblock">
2879 <div class="content">
2880 <pre><code>split vertical|horizontal|toggle</code></pre>
2881 </div></div>
2882 <div class="paragraph"><p><strong>Example</strong>:</p></div>
2883 <div class="listingblock">
2884 <div class="content">
2885 <pre><code>bindsym $mod+v split vertical
2886 bindsym $mod+h split horizontal
2887 bindsym $mod+t split toggle</code></pre>
2888 </div></div>
2889 </div>
2890 <div class="sect2">
2891 <h3 id="_manipulating_layout">6.3. Manipulating layout</h3>
2892 <div class="paragraph"><p>Use <code>layout toggle split</code>, <code>layout stacking</code>, <code>layout tabbed</code>, <code>layout splitv</code>
2893 or <code>layout splith</code> to change the current container layout to splith/splitv,
2894 stacking, tabbed layout, splitv or splith, respectively.</p></div>
2895 <div class="paragraph"><p>Specify up to four layouts after <code>layout toggle</code> to cycle through them. Every
2896 time the command is executed, the layout specified after the currently active
2897 one will be applied. If the currently active layout is not in the list, the
2898 first layout in the list will be activated.</p></div>
2899 <div class="paragraph"><p>To make the current window (!) fullscreen, use <code>fullscreen enable</code> (or
2900 <code>fullscreen enable global</code> for the global mode), to leave either fullscreen
2901 mode use <code>fullscreen disable</code>, and to toggle between these two states use
2902 <code>fullscreen toggle</code> (or <code>fullscreen toggle global</code>).</p></div>
2903 <div class="paragraph"><p>Likewise, to make the current window floating (or tiling again) use <code>floating
2904 enable</code> respectively <code>floating disable</code> (or <code>floating toggle</code>):</p></div>
2905 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
2906 <div class="listingblock">
2907 <div class="content">
2908 <pre><code>layout default|tabbed|stacking|splitv|splith
2909 layout toggle [split|all]
2910 layout toggle [split|tabbed|stacking|splitv|splith] [split|tabbed|stacking|splitv|splith]…</code></pre>
2911 </div></div>
2912 <div class="paragraph"><p><strong>Examples</strong>:</p></div>
2913 <div class="listingblock">
2914 <div class="content">
2915 <pre><code>bindsym $mod+s layout stacking
2916 bindsym $mod+l layout toggle split
2917 bindsym $mod+w layout tabbed
2918
2919 # Toggle between stacking/tabbed/split:
2920 bindsym $mod+x layout toggle
2921
2922 # Toggle between stacking/tabbed/splith/splitv:
2923 bindsym $mod+x layout toggle all
2924
2925 # Toggle between stacking/tabbed/splith:
2926 bindsym $mod+x layout toggle stacking tabbed splith
2927
2928 # Toggle between splitv/tabbed
2929 bindsym $mod+x layout toggle splitv tabbed
2930
2931 # Toggle between last split layout/tabbed/stacking
2932 bindsym $mod+x layout toggle split tabbed stacking
2933
2934 # Toggle fullscreen
2935 bindsym $mod+f fullscreen toggle
2936
2937 # Toggle floating/tiling
2938 bindsym $mod+t floating toggle</code></pre>
2939 </div></div>
2940 </div>
2941 <div class="sect2">
2942 <h3 id="_focusing_moving_containers">6.4. Focusing containers</h3>
2943 <div class="paragraph"><p>To change focus, you can use the <code>focus</code> command. The following options are
2944 available:</p></div>
2945 <div class="dlist"><dl>
2946 <dt class="hdlist1">
2947 &lt;criteria&gt;
2948 </dt>
2949 <dd>
2950 <p>
2951 Sets focus to the container that matches the specified criteria.
2952 See <a href="#command_criteria">[command_criteria]</a>.
2953 </p>
2954 </dd>
2955 <dt class="hdlist1">
2956 left|right|up|down
2957 </dt>
2958 <dd>
2959 <p>
2960 Sets focus to the nearest container in the given direction.
2961 </p>
2962 </dd>
2963 <dt class="hdlist1">
2964 parent
2965 </dt>
2966 <dd>
2967 <p>
2968 Sets focus to the parent container of the current container.
2969 </p>
2970 </dd>
2971 <dt class="hdlist1">
2972 child
2973 </dt>
2974 <dd>
2975 <p>
2976 The opposite of <code>focus parent</code>, sets the focus to the last focused
2977 child container.
2978 </p>
2979 </dd>
2980 <dt class="hdlist1">
2981 floating
2982 </dt>
2983 <dd>
2984 <p>
2985 Sets focus to the last focused floating container.
2986 </p>
2987 </dd>
2988 <dt class="hdlist1">
2989 tiling
2990 </dt>
2991 <dd>
2992 <p>
2993 Sets focus to the last focused tiling container.
2994 </p>
2995 </dd>
2996 <dt class="hdlist1">
2997 mode_toggle
2998 </dt>
2999 <dd>
3000 <p>
3001 Toggles between floating/tiling containers.
3002 </p>
3003 </dd>
3004 <dt class="hdlist1">
3005 output
3006 </dt>
3007 <dd>
3008 <p>
3009 Followed by a direction or an output name, this will focus the
3010 corresponding output.
3011 </p>
3012 </dd>
3013 </dl></div>
3014 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
3015 <div class="listingblock">
3016 <div class="content">
3017 <pre><code>&lt;criteria&gt; focus
3018 focus left|right|down|up
3019 focus parent|child|floating|tiling|mode_toggle
3020 focus output left|right|up|down|primary|&lt;output&gt;</code></pre>
3021 </div></div>
3022 <div class="paragraph"><p><strong>Examples</strong>:</p></div>
3023 <div class="listingblock">
3024 <div class="content">
3025 <pre><code># Focus firefox
3026 bindsym $mod+F1 [class="Firefox"] focus
3027
3028 # Focus container on the left, bottom, top, right
3029 bindsym $mod+j focus left
3030 bindsym $mod+k focus down
3031 bindsym $mod+l focus up
3032 bindsym $mod+semicolon focus right
3033
3034 # Focus parent container
3035 bindsym $mod+u focus parent
3036
3037 # Focus last floating/tiling container
3038 bindsym $mod+g focus mode_toggle
3039
3040 # Focus the output right to the current one
3041 bindsym $mod+x focus output right
3042
3043 # Focus the big output
3044 bindsym $mod+x focus output HDMI-2
3045
3046 # Focus the primary output
3047 bindsym $mod+x focus output primary</code></pre>
3048 </div></div>
3049 <div class="paragraph"><p>Note that you might not have a primary output configured yet. To do so, run:</p></div>
3050 <div class="listingblock">
3051 <div class="content">
3052 <pre><code>xrandr --output &lt;output&gt; --primary</code></pre>
3053 </div></div>
3054 </div>
3055 <div class="sect2">
3056 <h3 id="_moving_containers">6.5. Moving containers</h3>
3057 <div class="paragraph"><p>Use the <code>move</code> command to move a container.</p></div>
3058 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
3059 <div class="listingblock">
3060 <div class="content">
3061 <pre><code># Moves the container into the given direction.
3062 # The optional pixel argument specifies how far the
3063 # container should be moved if it is floating and
3064 # defaults to 10 pixels.
3065 move &lt;left|right|down|up&gt; [&lt;px&gt; px]
3066
3067 # Moves the container to the specified pos_x and pos_y
3068 # coordinates on the screen.
3069 move position &lt;pos_x&gt; [px] &lt;pos_y&gt; [px]
3070
3071 # Moves the container to the center of the screen.
3072 # If 'absolute' is used, it is moved to the center of
3073 # all outputs.
3074 move [absolute] position center
3075
3076 # Moves the container to the current position of the
3077 # mouse cursor. Only affects floating containers.
3078 move position mouse</code></pre>
3079 </div></div>
3080 <div class="paragraph"><p><strong>Examples</strong>:</p></div>
3081 <div class="listingblock">
3082 <div class="content">
3083 <pre><code># Move container to the left, bottom, top, right
3084 bindsym $mod+j move left
3085 bindsym $mod+k move down
3086 bindsym $mod+l move up
3087 bindsym $mod+semicolon move right
3088
3089 # Move container, but make floating containers
3090 # move more than the default
3091 bindsym $mod+j move left 20 px
3092
3093 # Move floating container to the center of all outputs
3094 bindsym $mod+c move absolute position center
3095
3096 # Move container to the current position of the cursor
3097 bindsym $mod+m move position mouse</code></pre>
3098 </div></div>
3099 </div>
3100 <div class="sect2">
3101 <h3 id="_swapping_containers">6.6. Swapping containers</h3>
3102 <div class="paragraph"><p>Two containers can be swapped (i.e., move to each other&#8217;s position) by using
3103 the <code>swap</code> command. They will assume the position and geometry of the container
3104 they are swapped with.</p></div>
3105 <div class="paragraph"><p>The first container to participate in the swapping can be selected through the
3106 normal command criteria process with the focused window being the usual
3107 fallback if no criteria are specified. The second container can be selected
3108 using one of the following methods:</p></div>
3109 <div class="dlist"><dl>
3110 <dt class="hdlist1">
3111 <code>id</code>
3112 </dt>
3113 <dd>
3114 <p>
3115 The X11 window ID of a client window.
3116 </p>
3117 </dd>
3118 <dt class="hdlist1">
3119 <code>con_id</code>
3120 </dt>
3121 <dd>
3122 <p>
3123 The i3 container ID of a container.
3124 </p>
3125 </dd>
3126 <dt class="hdlist1">
3127 <code>mark</code>
3128 </dt>
3129 <dd>
3130 <p>
3131 A container with the specified mark, see <a href="#vim_like_marks">[vim_like_marks]</a>.
3132 </p>
3133 </dd>
3134 </dl></div>
3135 <div class="paragraph"><p>Note that swapping does not work with all containers. Most notably, swapping
3136 containers that have a parent-child relationship to one another does not work.</p></div>
3137 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
3138 <div class="listingblock">
3139 <div class="content">
3140 <pre><code>swap container with id|con_id|mark &lt;arg&gt;</code></pre>
3141 </div></div>
3142 <div class="paragraph"><p><strong>Examples</strong>:</p></div>
3143 <div class="listingblock">
3144 <div class="content">
3145 <pre><code># Swaps the focused container with the container marked »swapee«.
3146 swap container with mark swapee
3147
3148 # Swaps container marked »A« and »B«
3149 [con_mark="^A$"] swap container with mark B</code></pre>
3150 </div></div>
3151 </div>
3152 <div class="sect2">
3153 <h3 id="_sticky_floating_windows">6.7. Sticky floating windows</h3>
3154 <div class="paragraph"><p>If you want a window to stick to the glass, i.e., have it stay on screen even
3155 if you switch to another workspace, you can use the <code>sticky</code> command. For
3156 example, this can be useful for notepads, a media player or a video chat
3157 window.</p></div>
3158 <div class="paragraph"><p>Note that while any window can be made sticky through this command, it will
3159 only take effect if the window is floating.</p></div>
3160 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
3161 <div class="listingblock">
3162 <div class="content">
3163 <pre><code>sticky enable|disable|toggle</code></pre>
3164 </div></div>
3165 <div class="paragraph"><p><strong>Examples</strong>:</p></div>
3166 <div class="listingblock">
3167 <div class="content">
3168 <pre><code># make a terminal sticky that was started as a notepad
3169 for_window [instance=notepad] sticky enable</code></pre>
3170 </div></div>
3171 </div>
3172 <div class="sect2">
3173 <h3 id="_changing_named_workspaces_moving_to_workspaces">6.8. Changing (named) workspaces/moving to workspaces</h3>
3174 <div class="paragraph"><p>To change to a specific workspace, use the <code>workspace</code> command, followed by the
3175 number or name of the workspace. Pass the optional flag
3176 <code>--no-auto-back-and-forth</code> to disable <a href="#workspace_auto_back_and_forth">[workspace_auto_back_and_forth]</a> for this
3177 specific call only.</p></div>
3178 <div class="paragraph"><p>To move containers to specific workspaces, use <code>move container to workspace</code>.</p></div>
3179 <div class="paragraph"><p>You can also switch to the next and previous workspace with the commands
3180 <code>workspace next</code> and <code>workspace prev</code>, which is handy, for example, if you have
3181 workspace 1, 3, 4 and 9 and you want to cycle through them with a single key
3182 combination. To restrict those to the current output, use <code>workspace
3183 next_on_output</code> and <code>workspace prev_on_output</code>. Similarly, you can use <code>move
3184 container to workspace next</code>, <code>move container to workspace prev</code> to move a
3185 container to the next/previous workspace and <code>move container to workspace current</code>
3186 (the last one makes sense only when used with criteria).</p></div>
3187 <div class="paragraph"><p><code>workspace next</code> cycles through either numbered or named workspaces. But when it
3188 reaches the last numbered/named workspace, it looks for named workspaces after
3189 exhausting numbered ones and looks for numbered ones after exhausting named ones.</p></div>
3190 <div class="paragraph"><p>See <a href="#move_to_outputs">[move_to_outputs]</a> for how to move a container/workspace to a different
3191 RandR output.</p></div>
3192 <div class="paragraph"><p>Workspace names are parsed as
3193 <a href="https://developer.gnome.org/pango/stable/PangoMarkupFormat.html">Pango markup</a>
3194 by i3bar.</p></div>
3195 <div class="paragraph" id="back_and_forth"><p>To switch back to the previously focused workspace, use <code>workspace
3196 back_and_forth</code>; likewise, you can move containers to the previously focused
3197 workspace using <code>move container to workspace back_and_forth</code>.</p></div>
3198 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
3199 <div class="listingblock">
3200 <div class="content">
3201 <pre><code>workspace next|prev|next_on_output|prev_on_output
3202 workspace back_and_forth
3203 workspace [--no-auto-back-and-forth] &lt;name&gt;
3204 workspace [--no-auto-back-and-forth] number &lt;name&gt;
3205
3206 move [--no-auto-back-and-forth] [window|container] [to] workspace &lt;name&gt;
3207 move [--no-auto-back-and-forth] [window|container] [to] workspace number &lt;name&gt;
3208 move [window|container] [to] workspace prev|next|current</code></pre>
3209 </div></div>
3210 <div class="paragraph"><p><strong>Examples</strong>:</p></div>
3211 <div class="listingblock">
3212 <div class="content">
3213 <pre><code>bindsym $mod+1 workspace 1
3214 bindsym $mod+2 workspace 2
3215 bindsym $mod+3 workspace 3:&lt;span foreground="red"&gt;vim&lt;/span&gt;
3216 ...
3217
3218 bindsym $mod+Shift+1 move container to workspace 1
3219 bindsym $mod+Shift+2 move container to workspace 2
3220 ...
3221
3222 # switch between the current and the previously focused one
3223 bindsym $mod+b workspace back_and_forth
3224 bindsym $mod+Shift+b move container to workspace back_and_forth
3225
3226 # move the whole workspace to the next output
3227 bindsym $mod+x move workspace to output right
3228
3229 # move firefox to current workspace
3230 bindsym $mod+F1 [class="Firefox"] move workspace current</code></pre>
3231 </div></div>
3232 <div class="sect3">
3233 <h4 id="_named_workspaces">6.8.1. Named workspaces</h4>
3234 <div class="paragraph"><p>Workspaces are identified by their name. So, instead of using numbers in the
3235 workspace command, you can use an arbitrary name:</p></div>
3236 <div class="paragraph"><p><strong>Example</strong>:</p></div>
3237 <div class="listingblock">
3238 <div class="content">
3239 <pre><code>bindsym $mod+1 workspace mail
3240 ...</code></pre>
3241 </div></div>
3242 <div class="paragraph"><p>If you want the workspace to have a number <strong>and</strong> a name, just prefix the
3243 number, like this:</p></div>
3244 <div class="paragraph"><p><strong>Example</strong>:</p></div>
3245 <div class="listingblock">
3246 <div class="content">
3247 <pre><code>bindsym $mod+1 workspace 1: mail
3248 bindsym $mod+2 workspace 2: www
3249 ...</code></pre>
3250 </div></div>
3251 <div class="paragraph"><p>Note that the workspace will really be named "1: mail". i3 treats workspace
3252 names beginning with a number in a slightly special way. Normally, named
3253 workspaces are ordered the way they appeared. When they start with a number, i3
3254 will order them numerically. Also, you will be able to use <code>workspace number 1</code>
3255 to switch to the workspace which begins with number 1, regardless of which name
3256 it has. This is useful in case you are changing the workspace’s name
3257 dynamically. To combine both commands you can use <code>workspace number 1: mail</code> to
3258 specify a default name if there&#8217;s currently no workspace starting with a "1".</p></div>
3259 </div>
3260 <div class="sect3">
3261 <h4 id="_renaming_workspaces">6.8.2. Renaming workspaces</h4>
3262 <div class="paragraph"><p>You can rename workspaces. This might be useful to start with the default
3263 numbered workspaces, do your work, and rename the workspaces afterwards to
3264 reflect what’s actually on them. You can also omit the old name to rename
3265 the currently focused workspace. This is handy if you want to use the
3266 rename command with <code>i3-input</code>.</p></div>
3267 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
3268 <div class="listingblock">
3269 <div class="content">
3270 <pre><code>rename workspace &lt;old_name&gt; to &lt;new_name&gt;
3271 rename workspace to &lt;new_name&gt;</code></pre>
3272 </div></div>
3273 <div class="paragraph"><p><strong>Examples</strong>:</p></div>
3274 <div class="listingblock">
3275 <div class="content">
3276 <pre><code>i3-msg 'rename workspace 5 to 6'
3277 i3-msg 'rename workspace 1 to "1: www"'
3278 i3-msg 'rename workspace "1: www" to "10: www"'
3279 i3-msg 'rename workspace to "2: mail"'
3280 bindsym $mod+r exec i3-input -F 'rename workspace to "%s"' -P 'New name: '</code></pre>
3281 </div></div>
3282 <div class="paragraph"><p>If you want to rename workspaces on demand while keeping the navigation stable,
3283 you can use a setup like this:</p></div>
3284 <div class="paragraph"><p><strong>Example</strong>:</p></div>
3285 <div class="listingblock">
3286 <div class="content">
3287 <pre><code>bindsym $mod+1 workspace number "1: www"
3288 bindsym $mod+2 workspace number "2: mail"
3289 ...</code></pre>
3290 </div></div>
3291 <div class="paragraph"><p>If a workspace does not exist, the command <code>workspace number "1: mail"</code> will
3292 create workspace "1: mail".</p></div>
3293 <div class="paragraph"><p>If a workspace with number 1 does already exist, the command will switch to this
3294 workspace and ignore the text part. So even when the workspace has been renamed
3295 to "1: web", the above command will still switch to it.</p></div>
3296 </div>
3297 </div>
3298 <div class="sect2">
3299 <h3 id="_moving_workspaces_to_a_different_screen">6.9. Moving workspaces to a different screen</h3>
3300 <div class="paragraph"><p>See <a href="#move_to_outputs">[move_to_outputs]</a> for how to move a container/workspace to a different
3301 RandR output.</p></div>
3302 </div>
3303 <div class="sect2">
3304 <h3 id="move_to_outputs">6.10. <a id="_moving_containers_workspaces_to_randr_outputs"></a>Moving containers/workspaces to RandR outputs</h3>
3305 <div class="paragraph"><p>To move a container to another RandR output (addressed by names like <code>LVDS1</code> or
3306 <code>VGA1</code>) or to a RandR output identified by a specific direction (like <code>left</code>,
3307 <code>right</code>, <code>up</code> or <code>down</code>), there are two commands:</p></div>
3308 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
3309 <div class="listingblock">
3310 <div class="content">
3311 <pre><code>move container to output left|right|down|up|current|primary|&lt;output&gt;
3312 move workspace to output left|right|down|up|current|primary|&lt;output&gt;</code></pre>
3313 </div></div>
3314 <div class="paragraph"><p><strong>Examples</strong>:</p></div>
3315 <div class="listingblock">
3316 <div class="content">
3317 <pre><code># Move the current workspace to the next output
3318 # (effectively toggles when you only have two outputs)
3319 bindsym $mod+x move workspace to output right
3320
3321 # Put this window on the presentation output.
3322 bindsym $mod+x move container to output VGA1
3323
3324 # Put this window on the primary output.
3325 bindsym $mod+x move container to output primary</code></pre>
3326 </div></div>
3327 <div class="paragraph"><p>Note that you might not have a primary output configured yet. To do so, run:</p></div>
3328 <div class="listingblock">
3329 <div class="content">
3330 <pre><code>xrandr --output &lt;output&gt; --primary</code></pre>
3331 </div></div>
3332 </div>
3333 <div class="sect2">
3334 <h3 id="_moving_containers_windows_to_marks">6.11. Moving containers/windows to marks</h3>
3335 <div class="paragraph"><p>To move a container to another container with a specific mark (see <a href="#vim_like_marks">[vim_like_marks]</a>),
3336 you can use the following command.</p></div>
3337 <div class="paragraph"><p>The window will be moved right after the marked container in the tree, i.e., it ends up
3338 in the same position as if you had opened a new window when the marked container was
3339 focused. If the mark is on a split container, the window will appear as a new child
3340 after the currently focused child within that container.</p></div>
3341 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
3342 <div class="listingblock">
3343 <div class="content">
3344 <pre><code>move window|container to mark &lt;mark&gt;</code></pre>
3345 </div></div>
3346 <div class="paragraph"><p><strong>Example</strong>:</p></div>
3347 <div class="listingblock">
3348 <div class="content">
3349 <pre><code>for_window [instance="tabme"] move window to mark target</code></pre>
3350 </div></div>
3351 </div>
3352 <div class="sect2">
3353 <h3 id="resizingconfig">6.12. Resizing containers/windows</h3>
3354 <div class="paragraph"><p>If you want to resize containers/windows using your keyboard, you can use the
3355 <code>resize</code> command:</p></div>
3356 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
3357 <div class="listingblock">
3358 <div class="content">
3359 <pre><code>resize grow|shrink &lt;direction&gt; [&lt;px&gt; px [or &lt;ppt&gt; ppt]]
3360 resize set [width] &lt;width&gt; [px | ppt]
3361 resize set height &lt;height&gt; [px | ppt]
3362 resize set [width] &lt;width&gt; [px | ppt] [height] &lt;height&gt; [px | ppt]</code></pre>
3363 </div></div>
3364 <div class="paragraph"><p>Direction can either be one of <code>up</code>, <code>down</code>, <code>left</code> or <code>right</code>. Or you can be
3365 less specific and use <code>width</code> or <code>height</code>, in which case i3 will take/give space
3366 from all the other containers. The optional pixel argument specifies by how many
3367 pixels a container should be grown or shrunk (the default is 10 pixels). The
3368 optional ppt argument means "percentage points", and if specified it indicates
3369 that a <strong>tiling container</strong> should be grown or shrunk by that many points, instead
3370 of by the <code>px</code> value.</p></div>
3371 <div class="paragraph"><p>Note about <code>resize set</code>: a value of 0 for &lt;width&gt; or &lt;height&gt; means "do not
3372 resize in this direction".</p></div>
3373 <div class="paragraph"><p>It is recommended to define bindings for resizing in a dedicated binding mode.
3374 See <a href="#binding_modes">[binding_modes]</a> and the example in the i3
3375 <a href="https://github.com/i3/i3/blob/next/etc/config.keycodes">default config</a> for more
3376 context.</p></div>
3377 <div class="paragraph"><p><strong>Example</strong>:</p></div>
3378 <div class="listingblock">
3379 <div class="content">
3380 <pre><code>for_window [class="urxvt"] resize set 640 480</code></pre>
3381 </div></div>
3382 </div>
3383 <div class="sect2">
3384 <h3 id="_jumping_to_specific_windows">6.13. Jumping to specific windows</h3>
3385 <div class="paragraph"><p>Often when in a multi-monitor environment, you want to quickly jump to a
3386 specific window. For example, while working on workspace 3 you may want to
3387 jump to your mail client to email your boss that you’ve achieved some
3388 important goal. Instead of figuring out how to navigate to your mail client,
3389 it would be more convenient to have a shortcut. You can use the <code>focus</code> command
3390 with criteria for that.</p></div>
3391 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
3392 <div class="listingblock">
3393 <div class="content">
3394 <pre><code>[class="class"] focus
3395 [title="title"] focus</code></pre>
3396 </div></div>
3397 <div class="paragraph"><p><strong>Examples</strong>:</p></div>
3398 <div class="listingblock">
3399 <div class="content">
3400 <pre><code># Get me to the next open VIM instance
3401 bindsym $mod+a [class="urxvt" title="VIM"] focus</code></pre>
3402 </div></div>
3403 </div>
3404 <div class="sect2">
3405 <h3 id="vim_like_marks">6.14. VIM-like marks (mark/goto)</h3>
3406 <div class="paragraph"><p>This feature is like the jump feature: It allows you to directly jump to a
3407 specific window (this means switching to the appropriate workspace and setting
3408 focus to the windows). However, you can directly mark a specific window with
3409 an arbitrary label and use it afterwards. You can unmark the label in the same
3410 way, using the unmark command. If you don&#8217;t specify a label, unmark removes all
3411 marks. You do not need to ensure that your windows have unique classes or
3412 titles, and you do not need to change your configuration file.</p></div>
3413 <div class="paragraph"><p>As the command needs to include the label with which you want to mark the
3414 window, you cannot simply bind it to a key. <code>i3-input</code> is a tool created
3415 for this purpose: It lets you input a command and sends the command to i3. It
3416 can also prefix this command and display a custom prompt for the input dialog.</p></div>
3417 <div class="paragraph"><p>The additional <code>--toggle</code> option will remove the mark if the window already has
3418 this mark or add it otherwise. Note that you may need to use this in
3419 combination with <code>--add</code> (see below) as any other marks will otherwise be
3420 removed.</p></div>
3421 <div class="paragraph"><p>The <code>--replace</code> flag causes i3 to remove any existing marks, which is also the
3422 default behavior. You can use the <code>--add</code> flag to put more than one mark on a
3423 window.</p></div>
3424 <div class="paragraph"><p>Refer to <a href="#show_marks">[show_marks]</a> if you don&#8217;t want marks to be shown in the window decoration.</p></div>
3425 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
3426 <div class="listingblock">
3427 <div class="content">
3428 <pre><code>mark [--add|--replace] [--toggle] &lt;identifier&gt;
3429 [con_mark="identifier"] focus
3430 unmark &lt;identifier&gt;</code></pre>
3431 </div></div>
3432 <div class="paragraph"><p>You can use <code>i3-input</code> to prompt for a mark name, then use the <code>mark</code>
3433 and <code>focus</code> commands to create and jump to custom marks:</p></div>
3434 <div class="paragraph"><p><strong>Examples</strong>:</p></div>
3435 <div class="listingblock">
3436 <div class="content">
3437 <pre><code># read 1 character and mark the current window with this character
3438 bindsym $mod+m exec i3-input -F 'mark %s' -l 1 -P 'Mark: '
3439
3440 # read 1 character and go to the window with the character
3441 bindsym $mod+g exec i3-input -F '[con_mark="%s"] focus' -l 1 -P 'Goto: '</code></pre>
3442 </div></div>
3443 <div class="paragraph"><p>Alternatively, if you do not want to mess with <code>i3-input</code>, you could create
3444 separate bindings for a specific set of labels and then only use those labels:</p></div>
3445 <div class="paragraph"><p><strong>Example (in a terminal)</strong>:</p></div>
3446 <div class="listingblock">
3447 <div class="content">
3448 <pre><code># marks the focused container
3449 mark irssi
3450
3451 # focus the container with the mark "irssi"
3452 '[con_mark="irssi"] focus'
3453
3454 # remove the mark "irssi" from whichever container has it
3455 unmark irssi
3456
3457 # remove all marks on all firefox windows
3458 [class="(?i)firefox"] unmark</code></pre>
3459 </div></div>
3460 </div>
3461 <div class="sect2">
3462 <h3 id="pango_markup">6.15. Window title format</h3>
3463 <div class="paragraph"><p>By default, i3 will simply print the X11 window title. Using <code>title_format</code>,
3464 this can be customized by setting the format to the desired output. This
3465 directive supports
3466 <a href="https://developer.gnome.org/pango/stable/PangoMarkupFormat.html">Pango markup</a>
3467 and the following placeholders which will be replaced:</p></div>
3468 <div class="dlist"><dl>
3469 <dt class="hdlist1">
3470 <code>%title</code>
3471 </dt>
3472 <dd>
3473 <p>
3474 For normal windows, this is the X11 window title (_NET_WM_NAME or WM_NAME
3475 as fallback). When used on containers without a window (e.g., a split
3476 container inside a tabbed/stacked layout), this will be the tree
3477 representation of the container (e.g., "H[xterm xterm]").
3478 </p>
3479 </dd>
3480 <dt class="hdlist1">
3481 <code>%class</code>
3482 </dt>
3483 <dd>
3484 <p>
3485 The X11 window class (second part of WM_CLASS). This corresponds to the
3486 <code>class</code> criterion, see <a href="#command_criteria">[command_criteria]</a>.
3487 </p>
3488 </dd>
3489 <dt class="hdlist1">
3490 <code>%instance</code>
3491 </dt>
3492 <dd>
3493 <p>
3494 The X11 window instance (first part of WM_CLASS). This corresponds to the
3495 <code>instance</code> criterion, see <a href="#command_criteria">[command_criteria]</a>.
3496 </p>
3497 </dd>
3498 </dl></div>
3499 <div class="paragraph"><p>Using the <a href="#for_window">[for_window]</a> directive, you can set the title format for any window
3500 based on <a href="#command_criteria">[command_criteria]</a>.</p></div>
3501 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
3502 <div class="listingblock">
3503 <div class="content">
3504 <pre><code>title_format &lt;format&gt;</code></pre>
3505 </div></div>
3506 <div class="paragraph"><p><strong>Examples</strong>:</p></div>
3507 <div class="listingblock">
3508 <div class="content">
3509 <pre><code># give the focused window a prefix
3510 bindsym $mod+p title_format "Important | %title"
3511
3512 # print all window titles bold
3513 for_window [class=".*"] title_format "&lt;b&gt;%title&lt;/b&gt;"
3514
3515 # print window titles of firefox windows red
3516 for_window [class="(?i)firefox"] title_format "&lt;span foreground='red'&gt;%title&lt;/span&gt;"</code></pre>
3517 </div></div>
3518 </div>
3519 <div class="sect2">
3520 <h3 id="_changing_border_style">6.16. Changing border style</h3>
3521 <div class="paragraph"><p>To change the border of the current client, you can use <code>border normal</code> to use the normal
3522 border (including window title), <code>border pixel 1</code> to use a 1-pixel border (no window title)
3523 and <code>border none</code> to make the client borderless.</p></div>
3524 <div class="paragraph"><p>There is also <code>border toggle</code> which will toggle the different border styles. The
3525 optional pixel argument can be used to specify the border width when switching
3526 to the normal and pixel styles.</p></div>
3527 <div class="paragraph"><p>Note that "pixel" refers to logical pixel. On HiDPI displays, a logical pixel
3528 may be represented by multiple physical pixels, so <code>pixel 1</code> might not
3529 necessarily translate into a single pixel row wide border.</p></div>
3530 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
3531 <div class="listingblock">
3532 <div class="content">
3533 <pre><code>border normal|pixel|toggle [&lt;n&gt;]
3534 border none
3535
3536 # legacy syntax, equivalent to "border pixel 1"
3537 border 1pixel</code></pre>
3538 </div></div>
3539 <div class="paragraph"><p><strong>Examples</strong>:</p></div>
3540 <div class="listingblock">
3541 <div class="content">
3542 <pre><code># use window title, but no border
3543 bindsym $mod+t border normal 0
3544 # use no window title and a thick border
3545 bindsym $mod+y border pixel 3
3546 # use neither window title nor border
3547 bindsym $mod+u border none</code></pre>
3548 </div></div>
3549 </div>
3550 <div class="sect2">
3551 <h3 id="shmlog">6.17. Enabling shared memory logging</h3>
3552 <div class="paragraph"><p>As described in <a href="https://i3wm.org/docs/debugging.html">https://i3wm.org/docs/debugging.html</a>, i3 can log to a shared
3553 memory buffer, which you can dump using <code>i3-dump-log</code>. The <code>shmlog</code> command
3554 allows you to enable or disable the shared memory logging at runtime.</p></div>
3555 <div class="paragraph"><p>Note that when using <code>shmlog &lt;size_in_bytes&gt;</code>, the current log will be
3556 discarded and a new one will be started.</p></div>
3557 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
3558 <div class="listingblock">
3559 <div class="content">
3560 <pre><code>shmlog &lt;size_in_bytes&gt;
3561 shmlog on|off|toggle</code></pre>
3562 </div></div>
3563 <div class="paragraph"><p><strong>Examples</strong>:</p></div>
3564 <div class="listingblock">
3565 <div class="content">
3566 <pre><code># Enable/disable logging
3567 bindsym $mod+x shmlog toggle
3568
3569 # or, from a terminal:
3570 # increase the shared memory log buffer to 50 MiB
3571 i3-msg shmlog $((50*1024*1024))</code></pre>
3572 </div></div>
3573 </div>
3574 <div class="sect2">
3575 <h3 id="_enabling_debug_logging">6.18. Enabling debug logging</h3>
3576 <div class="paragraph"><p>The <code>debuglog</code> command allows you to enable or disable debug logging at
3577 runtime. Debug logging is much more verbose than non-debug logging. This
3578 command does not activate shared memory logging (shmlog), and as such is most
3579 likely useful in combination with the above-described <a href="#shmlog">[shmlog]</a> command.</p></div>
3580 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
3581 <div class="listingblock">
3582 <div class="content">
3583 <pre><code>debuglog on|off|toggle</code></pre>
3584 </div></div>
3585 <div class="paragraph"><p><strong>Examples</strong>:</p></div>
3586 <div class="listingblock">
3587 <div class="content">
3588 <pre><code># Enable/disable logging
3589 bindsym $mod+x debuglog toggle</code></pre>
3590 </div></div>
3591 </div>
3592 <div class="sect2">
3593 <h3 id="_reloading_restarting_exiting">6.19. Reloading/Restarting/Exiting</h3>
3594 <div class="paragraph"><p>You can make i3 reload its configuration file with <code>reload</code>. You can also
3595 restart i3 inplace with the <code>restart</code> command to get it out of some weird state
3596 (if that should ever happen) or to perform an upgrade without having to restart
3597 your X session. To exit i3 properly, you can use the <code>exit</code> command,
3598 however you don’t need to (simply killing your X session is fine as well).</p></div>
3599 <div class="paragraph"><p><strong>Examples</strong>:</p></div>
3600 <div class="listingblock">
3601 <div class="content">
3602 <pre><code>bindsym $mod+Shift+r restart
3603 bindsym $mod+Shift+w reload
3604 bindsym $mod+Shift+e exit</code></pre>
3605 </div></div>
3606 </div>
3607 <div class="sect2">
3608 <h3 id="_scratchpad">6.20. Scratchpad</h3>
3609 <div class="paragraph"><p>There are two commands to use any existing window as scratchpad window. <code>move
3610 scratchpad</code> will move a window to the scratchpad workspace. This will make it
3611 invisible until you show it again. There is no way to open that workspace.
3612 Instead, when using <code>scratchpad show</code>, the window will be shown again, as a
3613 floating window, centered on your current workspace (using <code>scratchpad show</code> on
3614 a visible scratchpad window will make it hidden again, so you can have a
3615 keybinding to toggle). Note that this is just a normal floating window, so if
3616 you want to "remove it from scratchpad", you can simple make it tiling again
3617 (<code>floating toggle</code>).</p></div>
3618 <div class="paragraph"><p>As the name indicates, this is useful for having a window with your favorite
3619 editor always at hand. However, you can also use this for other permanently
3620 running applications which you don’t want to see all the time: Your music
3621 player, alsamixer, maybe even your mail client…?</p></div>
3622 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
3623 <div class="listingblock">
3624 <div class="content">
3625 <pre><code>move scratchpad
3626
3627 scratchpad show</code></pre>
3628 </div></div>
3629 <div class="paragraph"><p><strong>Examples</strong>:</p></div>
3630 <div class="listingblock">
3631 <div class="content">
3632 <pre><code># Make the currently focused window a scratchpad
3633 bindsym $mod+Shift+minus move scratchpad
3634
3635 # Show the first scratchpad window
3636 bindsym $mod+minus scratchpad show
3637
3638 # Show the sup-mail scratchpad window, if any.
3639 bindsym mod4+s [title="^Sup ::"] scratchpad show</code></pre>
3640 </div></div>
3641 </div>
3642 <div class="sect2">
3643 <h3 id="_nop">6.21. Nop</h3>
3644 <div class="paragraph"><p>There is a no operation command <code>nop</code> which allows you to override default
3645 behavior. This can be useful for, e.g., disabling a focus change on clicks with
3646 the middle mouse button.</p></div>
3647 <div class="paragraph"><p>The optional <code>comment</code> argument is ignored, but will be printed to the log file
3648 for debugging purposes.</p></div>
3649 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
3650 <div class="listingblock">
3651 <div class="content">
3652 <pre><code>nop [&lt;comment&gt;]</code></pre>
3653 </div></div>
3654 <div class="paragraph"><p><strong>Example</strong>:</p></div>
3655 <div class="listingblock">
3656 <div class="content">
3657 <pre><code># Disable focus change for clicks on titlebars
3658 # with the middle mouse button
3659 bindsym button2 nop</code></pre>
3660 </div></div>
3661 </div>
3662 <div class="sect2">
3663 <h3 id="_i3bar_control">6.22. i3bar control</h3>
3664 <div class="paragraph"><p>There are two options in the configuration of each i3bar instance that can be
3665 changed during runtime by invoking a command through i3. The commands <code>bar
3666 hidden_state</code> and <code>bar mode</code> allow setting the current hidden_state
3667 respectively mode option of each bar. It is also possible to toggle between
3668 hide state and show state as well as between dock mode and hide mode. Each
3669 i3bar instance can be controlled individually by specifying a bar_id, if none
3670 is given, the command is executed for all bar instances.</p></div>
3671 <div class="paragraph"><p><strong>Syntax</strong>:</p></div>
3672 <div class="listingblock">
3673 <div class="content">
3674 <pre><code>bar hidden_state hide|show|toggle [&lt;bar_id&gt;]
3675
3676 bar mode dock|hide|invisible|toggle [&lt;bar_id&gt;]</code></pre>
3677 </div></div>
3678 <div class="paragraph"><p><strong>Examples</strong>:</p></div>
3679 <div class="listingblock">
3680 <div class="content">
3681 <pre><code># Toggle between hide state and show state
3682 bindsym $mod+m bar hidden_state toggle
3683
3684 # Toggle between dock mode and hide mode
3685 bindsym $mod+n bar mode toggle
3686
3687 # Set the bar instance with id 'bar-1' to switch to hide mode
3688 bindsym $mod+b bar mode hide bar-1
3689
3690 # Set the bar instance with id 'bar-1' to always stay hidden
3691 bindsym $mod+Shift+b bar mode invisible bar-1</code></pre>
3692 </div></div>
3693 </div>
3694 </div>
3695 </div>
3696 <div class="sect1">
3697 <h2 id="multi_monitor">7. Multiple monitors</h2>
3698 <div class="sectionbody">
3699 <div class="paragraph"><p>As you can see in the goal list on the website, i3 was specifically developed
3700 with support for multiple monitors in mind. This section will explain how to
3701 handle multiple monitors.</p></div>
3702 <div class="paragraph"><p>When you have only one monitor, things are simple. You usually start with
3703 workspace 1 on your monitor and open new ones as you need them.</p></div>
3704 <div class="paragraph"><p>When you have more than one monitor, each monitor will get an initial
3705 workspace. The first monitor gets 1, the second gets 2 and a possible third
3706 would get 3. When you switch to a workspace on a different monitor, i3 will
3707 switch to that monitor and then switch to the workspace. This way, you don’t
3708 need shortcuts to switch to a specific monitor, and you don’t need to remember
3709 where you put which workspace. New workspaces will be opened on the currently
3710 active monitor. It is not possible to have a monitor without a workspace.</p></div>
3711 <div class="paragraph"><p>The idea of making workspaces global is based on the observation that most
3712 users have a very limited set of workspaces on their additional monitors.
3713 They are often used for a specific task (browser, shell) or for monitoring
3714 several things (mail, IRC, syslog, …). Thus, using one workspace on one monitor
3715 and "the rest" on the other monitors often makes sense. However, as you can
3716 create an unlimited number of workspaces in i3 and tie them to specific
3717 screens, you can have the "traditional" approach of having X workspaces per
3718 screen by changing your configuration (using modes, for example).</p></div>
3719 <div class="sect2">
3720 <h3 id="_configuring_your_monitors">7.1. Configuring your monitors</h3>
3721 <div class="paragraph"><p>To help you get going if you have never used multiple monitors before, here is
3722 a short overview of the xrandr options which will probably be of interest to
3723 you. It is always useful to get an overview of the current screen configuration.
3724 Just run "xrandr" and you will get an output like the following:</p></div>
3725 <div class="listingblock">
3726 <div class="content">
3727 <pre><code>$ xrandr
3728 Screen 0: minimum 320 x 200, current 1280 x 800, maximum 8192 x 8192
3729 VGA1 disconnected (normal left inverted right x axis y axis)
3730 LVDS1 connected 1280x800+0+0 (normal left inverted right x axis y axis) 261mm x 163mm
3731 1280x800 60.0*+ 50.0
3732 1024x768 85.0 75.0 70.1 60.0
3733 832x624 74.6
3734 800x600 85.1 72.2 75.0 60.3 56.2
3735 640x480 85.0 72.8 75.0 59.9
3736 720x400 85.0
3737 640x400 85.1
3738 640x350 85.1</code></pre>
3739 </div></div>
3740 <div class="paragraph"><p>Several things are important here: You can see that <code>LVDS1</code> is connected (of
3741 course, it is the internal flat panel) but <code>VGA1</code> is not. If you have a monitor
3742 connected to one of the ports but xrandr still says "disconnected", you should
3743 check your cable, monitor or graphics driver.</p></div>
3744 <div class="paragraph"><p>The maximum resolution you can see at the end of the first line is the maximum
3745 combined resolution of your monitors. By default, it is usually too low and has
3746 to be increased by editing <code>/etc/X11/xorg.conf</code>.</p></div>
3747 <div class="paragraph"><p>So, say you connected VGA1 and want to use it as an additional screen:</p></div>
3748 <div class="listingblock">
3749 <div class="content">
3750 <pre><code>xrandr --output VGA1 --auto --left-of LVDS1</code></pre>
3751 </div></div>
3752 <div class="paragraph"><p>This command makes xrandr try to find the native resolution of the device
3753 connected to <code>VGA1</code> and configures it to the left of your internal flat panel.
3754 When running "xrandr" again, the output looks like this:</p></div>
3755 <div class="listingblock">
3756 <div class="content">
3757 <pre><code>$ xrandr
3758 Screen 0: minimum 320 x 200, current 2560 x 1024, maximum 8192 x 8192
3759 VGA1 connected 1280x1024+0+0 (normal left inverted right x axis y axis) 338mm x 270mm
3760 1280x1024 60.0*+ 75.0
3761 1280x960 60.0
3762 1152x864 75.0
3763 1024x768 75.1 70.1 60.0
3764 832x624 74.6
3765 800x600 72.2 75.0 60.3 56.2
3766 640x480 72.8 75.0 66.7 60.0
3767 720x400 70.1
3768 LVDS1 connected 1280x800+1280+0 (normal left inverted right x axis y axis) 261mm x 163mm
3769 1280x800 60.0*+ 50.0
3770 1024x768 85.0 75.0 70.1 60.0
3771 832x624 74.6
3772 800x600 85.1 72.2 75.0 60.3 56.2
3773 640x480 85.0 72.8 75.0 59.9
3774 720x400 85.0
3775 640x400 85.1
3776 640x350 85.1</code></pre>
3777 </div></div>
3778 <div class="paragraph"><p>Please note that i3 uses exactly the same API as xrandr does, so it will see
3779 only what you can see in xrandr.</p></div>
3780 <div class="paragraph"><p>See also <a href="#presentations">[presentations]</a> for more examples of multi-monitor setups.</p></div>
3781 </div>
3782 <div class="sect2">
3783 <h3 id="_interesting_configuration_for_multi_monitor_environments">7.2. Interesting configuration for multi-monitor environments</h3>
3784 <div class="paragraph"><p>There are several things to configure in i3 which may be interesting if you
3785 have more than one monitor:</p></div>
3786 <div class="olist arabic"><ol class="arabic">
3787 <li>
3788 <p>
3789 You can specify which workspace should be put on which screen. This
3790 allows you to have a different set of workspaces when starting than just
3791 1 for the first monitor, 2 for the second and so on. See
3792 <a href="#workspace_screen">[workspace_screen]</a>.
3793 </p>
3794 </li>
3795 <li>
3796 <p>
3797 If you want some applications to generally open on the bigger screen
3798 (MPlayer, Firefox, …), you can assign them to a specific workspace, see
3799 <a href="#assign_workspace">[assign_workspace]</a>.
3800 </p>
3801 </li>
3802 <li>
3803 <p>
3804 If you have many workspaces on many monitors, it might get hard to keep
3805 track of which window you put where. Thus, you can use vim-like marks to
3806 quickly switch between windows. See <a href="#vim_like_marks">[vim_like_marks]</a>.
3807 </p>
3808 </li>
3809 <li>
3810 <p>
3811 For information on how to move existing workspaces between monitors,
3812 see <a href="#move_to_outputs">[move_to_outputs]</a>.
3813 </p>
3814 </li>
3815 </ol></div>
3816 </div>
3817 </div>
3818 </div>
3819 <div class="sect1">
3820 <h2 id="_i3_and_the_rest_of_your_software_world">8. i3 and the rest of your software world</h2>
3821 <div class="sectionbody">
3822 <div class="sect2">
3823 <h3 id="_displaying_a_status_line">8.1. Displaying a status line</h3>
3824 <div class="paragraph"><p>A very common thing amongst users of exotic window managers is a status line at
3825 some corner of the screen. It is an often superior replacement to the widget
3826 approach you have in the task bar of a traditional desktop environment.</p></div>
3827 <div class="paragraph"><p>If you don’t already have your favorite way of generating such a status line
3828 (self-written scripts, conky, …), then i3status is the recommended tool for
3829 this task. It was written in C with the goal of using as few syscalls as
3830 possible to reduce the time your CPU is woken up from sleep states. Because
3831 i3status only spits out text, you need to combine it with some other tool, like
3832 i3bar. See <a href="#status_command">[status_command]</a> for how to display i3status in i3bar.</p></div>
3833 <div class="paragraph"><p>Regardless of which application you use to display the status line, you
3834 want to make sure that it registers as a dock window using EWMH hints. i3 will
3835 position the window either at the top or at the bottom of the screen, depending
3836 on which hint the application sets. With i3bar, you can configure its position,
3837 see <a href="#i3bar_position">[i3bar_position]</a>.</p></div>
3838 </div>
3839 <div class="sect2">
3840 <h3 id="presentations">8.2. Giving presentations (multi-monitor)</h3>
3841 <div class="paragraph"><p>When giving a presentation, you typically want the audience to see what you see
3842 on your screen and then go through a series of slides (if the presentation is
3843 simple). For more complex presentations, you might want to have some notes
3844 which only you can see on your screen, while the audience can only see the
3845 slides.</p></div>
3846 <div class="sect3">
3847 <h4 id="_case_1_everybody_gets_the_same_output">8.2.1. Case 1: everybody gets the same output</h4>
3848 <div class="paragraph"><p>This is the simple case. You connect your computer to the video projector,
3849 turn on both (computer and video projector) and configure your X server to
3850 clone the internal flat panel of your computer to the video output:</p></div>
3851 <div class="listingblock">
3852 <div class="content">
3853 <pre><code>xrandr --output VGA1 --mode 1024x768 --same-as LVDS1</code></pre>
3854 </div></div>
3855 <div class="paragraph"><p>i3 will then use the lowest common subset of screen resolutions, the rest of
3856 your screen will be left untouched (it will show the X background). So, in
3857 our example, this would be 1024x768 (my notebook has 1280x800).</p></div>
3858 </div>
3859 <div class="sect3">
3860 <h4 id="_case_2_you_can_see_more_than_your_audience">8.2.2. Case 2: you can see more than your audience</h4>
3861 <div class="paragraph"><p>This case is a bit harder. First of all, you should configure the VGA output
3862 somewhere near your internal flat panel, say right of it:</p></div>
3863 <div class="listingblock">
3864 <div class="content">
3865 <pre><code>xrandr --output VGA1 --mode 1024x768 --right-of LVDS1</code></pre>
3866 </div></div>
3867 <div class="paragraph"><p>Now, i3 will put a new workspace (depending on your settings) on the new screen
3868 and you are in multi-monitor mode (see <a href="#multi_monitor">[multi_monitor]</a>).</p></div>
3869 <div class="paragraph"><p>Because i3 is not a compositing window manager, there is no ability to
3870 display a window on two screens at the same time. Instead, your presentation
3871 software needs to do this job (that is, open a window on each screen).</p></div>
3872 </div>
3873 </div>
3874 <div class="sect2">
3875 <h3 id="hidpi">8.3. High-resolution displays (aka HIDPI displays)</h3>
3876 <div class="paragraph"><p>See <a href="https://wiki.archlinux.org/index.php/HiDPI">https://wiki.archlinux.org/index.php/HiDPI</a> for details on how to enable
3877 scaling in various parts of the Linux desktop. i3 will read the desired DPI from
3878 the <code>Xft.dpi</code> property. The property defaults to 96 DPI, so to achieve 200%
3879 scaling, you’d set <code>Xft.dpi: 192</code> in <code>~/.Xresources</code>.</p></div>
3880 <div class="paragraph"><p>If you are a long-time i3 user who just got a new monitor, double-check that:</p></div>
3881 <div class="ulist"><ul>
3882 <li>
3883 <p>
3884 You are using a scalable font (starting with “pango:”) in your i3 config.
3885 </p>
3886 </li>
3887 <li>
3888 <p>
3889 You are using a terminal emulator which supports scaling. You could
3890 temporarily switch to gnome-terminal, which is known to support scaling out of
3891 the box, until you figure out how to adjust the font size in your favorite
3892 terminal emulator.
3893 </p>
3894 </li>
3895 </ul></div>
3896 </div>
3897 </div>
3898 </div>
3899 </div>
3900 <div id="footnotes"><hr /></div>
3901 <div id="footer">
3902 <div id="footer-text">
3903 Last updated
3904 2019-08-30 23:06:47 CEST
3905 </div>
3906 </div>
3907 </body>
3908 </html>
0 <?xml version="1.0" encoding="UTF-8"?>
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
2 "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
4 <head>
5 <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
6 <meta name="generator" content="AsciiDoc 8.6.10" />
7 <title>External workspace bars</title>
8 <style type="text/css">
9 /* Shared CSS for AsciiDoc xhtml11 and html5 backends */
10
11 /* Default font. */
12 body {
13 font-family: Georgia,serif;
14 }
15
16 /* Title font. */
17 h1, h2, h3, h4, h5, h6,
18 div.title, caption.title,
19 thead, p.table.header,
20 #toctitle,
21 #author, #revnumber, #revdate, #revremark,
22 #footer {
23 font-family: Arial,Helvetica,sans-serif;
24 }
25
26 body {
27 margin: 1em 5% 1em 5%;
28 }
29
30 a {
31 color: blue;
32 text-decoration: underline;
33 }
34 a:visited {
35 color: fuchsia;
36 }
37
38 em {
39 font-style: italic;
40 color: navy;
41 }
42
43 strong {
44 font-weight: bold;
45 color: #083194;
46 }
47
48 h1, h2, h3, h4, h5, h6 {
49 color: #527bbd;
50 margin-top: 1.2em;
51 margin-bottom: 0.5em;
52 line-height: 1.3;
53 }
54
55 h1, h2, h3 {
56 border-bottom: 2px solid silver;
57 }
58 h2 {
59 padding-top: 0.5em;
60 }
61 h3 {
62 float: left;
63 }
64 h3 + * {
65 clear: left;
66 }
67 h5 {
68 font-size: 1.0em;
69 }
70
71 div.sectionbody {
72 margin-left: 0;
73 }
74
75 hr {
76 border: 1px solid silver;
77 }
78
79 p {
80 margin-top: 0.5em;
81 margin-bottom: 0.5em;
82 }
83
84 ul, ol, li > p {
85 margin-top: 0;
86 }
87 ul > li { color: #aaa; }
88 ul > li > * { color: black; }
89
90 .monospaced, code, pre {
91 font-family: "Courier New", Courier, monospace;
92 font-size: inherit;
93 color: navy;
94 padding: 0;
95 margin: 0;
96 }
97 pre {
98 white-space: pre-wrap;
99 }
100
101 #author {
102 color: #527bbd;
103 font-weight: bold;
104 font-size: 1.1em;
105 }
106 #email {
107 }
108 #revnumber, #revdate, #revremark {
109 }
110
111 #footer {
112 font-size: small;
113 border-top: 2px solid silver;
114 padding-top: 0.5em;
115 margin-top: 4.0em;
116 }
117 #footer-text {
118 float: left;
119 padding-bottom: 0.5em;
120 }
121 #footer-badges {
122 float: right;
123 padding-bottom: 0.5em;
124 }
125
126 #preamble {
127 margin-top: 1.5em;
128 margin-bottom: 1.5em;
129 }
130 div.imageblock, div.exampleblock, div.verseblock,
131 div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
132 div.admonitionblock {
133 margin-top: 1.0em;
134 margin-bottom: 1.5em;
135 }
136 div.admonitionblock {
137 margin-top: 2.0em;
138 margin-bottom: 2.0em;
139 margin-right: 10%;
140 color: #606060;
141 }
142
143 div.content { /* Block element content. */
144 padding: 0;
145 }
146
147 /* Block element titles. */
148 div.title, caption.title {
149 color: #527bbd;
150 font-weight: bold;
151 text-align: left;
152 margin-top: 1.0em;
153 margin-bottom: 0.5em;
154 }
155 div.title + * {
156 margin-top: 0;
157 }
158
159 td div.title:first-child {
160 margin-top: 0.0em;
161 }
162 div.content div.title:first-child {
163 margin-top: 0.0em;
164 }
165 div.content + div.title {
166 margin-top: 0.0em;
167 }
168
169 div.sidebarblock > div.content {
170 background: #ffffee;
171 border: 1px solid #dddddd;
172 border-left: 4px solid #f0f0f0;
173 padding: 0.5em;
174 }
175
176 div.listingblock > div.content {
177 border: 1px solid #dddddd;
178 border-left: 5px solid #f0f0f0;
179 background: #f8f8f8;
180 padding: 0.5em;
181 }
182
183 div.quoteblock, div.verseblock {
184 padding-left: 1.0em;
185 margin-left: 1.0em;
186 margin-right: 10%;
187 border-left: 5px solid #f0f0f0;
188 color: #888;
189 }
190
191 div.quoteblock > div.attribution {
192 padding-top: 0.5em;
193 text-align: right;
194 }
195
196 div.verseblock > pre.content {
197 font-family: inherit;
198 font-size: inherit;
199 }
200 div.verseblock > div.attribution {
201 padding-top: 0.75em;
202 text-align: left;
203 }
204 /* DEPRECATED: Pre version 8.2.7 verse style literal block. */
205 div.verseblock + div.attribution {
206 text-align: left;
207 }
208
209 div.admonitionblock .icon {
210 vertical-align: top;
211 font-size: 1.1em;
212 font-weight: bold;
213 text-decoration: underline;
214 color: #527bbd;
215 padding-right: 0.5em;
216 }
217 div.admonitionblock td.content {
218 padding-left: 0.5em;
219 border-left: 3px solid #dddddd;
220 }
221
222 div.exampleblock > div.content {
223 border-left: 3px solid #dddddd;
224 padding-left: 0.5em;
225 }
226
227 div.imageblock div.content { padding-left: 0; }
228 span.image img { border-style: none; vertical-align: text-bottom; }
229 a.image:visited { color: white; }
230
231 dl {
232 margin-top: 0.8em;
233 margin-bottom: 0.8em;
234 }
235 dt {
236 margin-top: 0.5em;
237 margin-bottom: 0;
238 font-style: normal;
239 color: navy;
240 }
241 dd > *:first-child {
242 margin-top: 0.1em;
243 }
244
245 ul, ol {
246 list-style-position: outside;
247 }
248 ol.arabic {
249 list-style-type: decimal;
250 }
251 ol.loweralpha {
252 list-style-type: lower-alpha;
253 }
254 ol.upperalpha {
255 list-style-type: upper-alpha;
256 }
257 ol.lowerroman {
258 list-style-type: lower-roman;
259 }
260 ol.upperroman {
261 list-style-type: upper-roman;
262 }
263
264 div.compact ul, div.compact ol,
265 div.compact p, div.compact p,
266 div.compact div, div.compact div {
267 margin-top: 0.1em;
268 margin-bottom: 0.1em;
269 }
270
271 tfoot {
272 font-weight: bold;
273 }
274 td > div.verse {
275 white-space: pre;
276 }
277
278 div.hdlist {
279 margin-top: 0.8em;
280 margin-bottom: 0.8em;
281 }
282 div.hdlist tr {
283 padding-bottom: 15px;
284 }
285 dt.hdlist1.strong, td.hdlist1.strong {
286 font-weight: bold;
287 }
288 td.hdlist1 {
289 vertical-align: top;
290 font-style: normal;
291 padding-right: 0.8em;
292 color: navy;
293 }
294 td.hdlist2 {
295 vertical-align: top;
296 }
297 div.hdlist.compact tr {
298 margin: 0;
299 padding-bottom: 0;
300 }
301
302 .comment {
303 background: yellow;
304 }
305
306 .footnote, .footnoteref {
307 font-size: 0.8em;
308 }
309
310 span.footnote, span.footnoteref {
311 vertical-align: super;
312 }
313
314 #footnotes {
315 margin: 20px 0 20px 0;
316 padding: 7px 0 0 0;
317 }
318
319 #footnotes div.footnote {
320 margin: 0 0 5px 0;
321 }
322
323 #footnotes hr {
324 border: none;
325 border-top: 1px solid silver;
326 height: 1px;
327 text-align: left;
328 margin-left: 0;
329 width: 20%;
330 min-width: 100px;
331 }
332
333 div.colist td {
334 padding-right: 0.5em;
335 padding-bottom: 0.3em;
336 vertical-align: top;
337 }
338 div.colist td img {
339 margin-top: 0.3em;
340 }
341
342 @media print {
343 #footer-badges { display: none; }
344 }
345
346 #toc {
347 margin-bottom: 2.5em;
348 }
349
350 #toctitle {
351 color: #527bbd;
352 font-size: 1.1em;
353 font-weight: bold;
354 margin-top: 1.0em;
355 margin-bottom: 0.1em;
356 }
357
358 div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
359 margin-top: 0;
360 margin-bottom: 0;
361 }
362 div.toclevel2 {
363 margin-left: 2em;
364 font-size: 0.9em;
365 }
366 div.toclevel3 {
367 margin-left: 4em;
368 font-size: 0.9em;
369 }
370 div.toclevel4 {
371 margin-left: 6em;
372 font-size: 0.9em;
373 }
374
375 span.aqua { color: aqua; }
376 span.black { color: black; }
377 span.blue { color: blue; }
378 span.fuchsia { color: fuchsia; }
379 span.gray { color: gray; }
380 span.green { color: green; }
381 span.lime { color: lime; }
382 span.maroon { color: maroon; }
383 span.navy { color: navy; }
384 span.olive { color: olive; }
385 span.purple { color: purple; }
386 span.red { color: red; }
387 span.silver { color: silver; }
388 span.teal { color: teal; }
389 span.white { color: white; }
390 span.yellow { color: yellow; }
391
392 span.aqua-background { background: aqua; }
393 span.black-background { background: black; }
394 span.blue-background { background: blue; }
395 span.fuchsia-background { background: fuchsia; }
396 span.gray-background { background: gray; }
397 span.green-background { background: green; }
398 span.lime-background { background: lime; }
399 span.maroon-background { background: maroon; }
400 span.navy-background { background: navy; }
401 span.olive-background { background: olive; }
402 span.purple-background { background: purple; }
403 span.red-background { background: red; }
404 span.silver-background { background: silver; }
405 span.teal-background { background: teal; }
406 span.white-background { background: white; }
407 span.yellow-background { background: yellow; }
408
409 span.big { font-size: 2em; }
410 span.small { font-size: 0.6em; }
411
412 span.underline { text-decoration: underline; }
413 span.overline { text-decoration: overline; }
414 span.line-through { text-decoration: line-through; }
415
416 div.unbreakable { page-break-inside: avoid; }
417
418
419 /*
420 * xhtml11 specific
421 *
422 * */
423
424 div.tableblock {
425 margin-top: 1.0em;
426 margin-bottom: 1.5em;
427 }
428 div.tableblock > table {
429 border: 3px solid #527bbd;
430 }
431 thead, p.table.header {
432 font-weight: bold;
433 color: #527bbd;
434 }
435 p.table {
436 margin-top: 0;
437 }
438 /* Because the table frame attribute is overriden by CSS in most browsers. */
439 div.tableblock > table[frame="void"] {
440 border-style: none;
441 }
442 div.tableblock > table[frame="hsides"] {
443 border-left-style: none;
444 border-right-style: none;
445 }
446 div.tableblock > table[frame="vsides"] {
447 border-top-style: none;
448 border-bottom-style: none;
449 }
450
451
452 /*
453 * html5 specific
454 *
455 * */
456
457 table.tableblock {
458 margin-top: 1.0em;
459 margin-bottom: 1.5em;
460 }
461 thead, p.tableblock.header {
462 font-weight: bold;
463 color: #527bbd;
464 }
465 p.tableblock {
466 margin-top: 0;
467 }
468 table.tableblock {
469 border-width: 3px;
470 border-spacing: 0px;
471 border-style: solid;
472 border-color: #527bbd;
473 border-collapse: collapse;
474 }
475 th.tableblock, td.tableblock {
476 border-width: 1px;
477 padding: 4px;
478 border-style: solid;
479 border-color: #527bbd;
480 }
481
482 table.tableblock.frame-topbot {
483 border-left-style: hidden;
484 border-right-style: hidden;
485 }
486 table.tableblock.frame-sides {
487 border-top-style: hidden;
488 border-bottom-style: hidden;
489 }
490 table.tableblock.frame-none {
491 border-style: hidden;
492 }
493
494 th.tableblock.halign-left, td.tableblock.halign-left {
495 text-align: left;
496 }
497 th.tableblock.halign-center, td.tableblock.halign-center {
498 text-align: center;
499 }
500 th.tableblock.halign-right, td.tableblock.halign-right {
501 text-align: right;
502 }
503
504 th.tableblock.valign-top, td.tableblock.valign-top {
505 vertical-align: top;
506 }
507 th.tableblock.valign-middle, td.tableblock.valign-middle {
508 vertical-align: middle;
509 }
510 th.tableblock.valign-bottom, td.tableblock.valign-bottom {
511 vertical-align: bottom;
512 }
513
514
515 /*
516 * manpage specific
517 *
518 * */
519
520 body.manpage h1 {
521 padding-top: 0.5em;
522 padding-bottom: 0.5em;
523 border-top: 2px solid silver;
524 border-bottom: 2px solid silver;
525 }
526 body.manpage h2 {
527 border-style: none;
528 }
529 body.manpage div.sectionbody {
530 margin-left: 3em;
531 }
532
533 @media print {
534 body.manpage div#toc { display: none; }
535 }
536
537
538 </style>
539 <script type="text/javascript">
540 /*<![CDATA[*/
541 var asciidoc = { // Namespace.
542
543 /////////////////////////////////////////////////////////////////////
544 // Table Of Contents generator
545 /////////////////////////////////////////////////////////////////////
546
547 /* Author: Mihai Bazon, September 2002
548 * http://students.infoiasi.ro/~mishoo
549 *
550 * Table Of Content generator
551 * Version: 0.4
552 *
553 * Feel free to use this script under the terms of the GNU General Public
554 * License, as long as you do not remove or alter this notice.
555 */
556
557 /* modified by Troy D. Hanson, September 2006. License: GPL */
558 /* modified by Stuart Rackham, 2006, 2009. License: GPL */
559
560 // toclevels = 1..4.
561 toc: function (toclevels) {
562
563 function getText(el) {
564 var text = "";
565 for (var i = el.firstChild; i != null; i = i.nextSibling) {
566 if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
567 text += i.data;
568 else if (i.firstChild != null)
569 text += getText(i);
570 }
571 return text;
572 }
573
574 function TocEntry(el, text, toclevel) {
575 this.element = el;
576 this.text = text;
577 this.toclevel = toclevel;
578 }
579
580 function tocEntries(el, toclevels) {
581 var result = new Array;
582 var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
583 // Function that scans the DOM tree for header elements (the DOM2
584 // nodeIterator API would be a better technique but not supported by all
585 // browsers).
586 var iterate = function (el) {
587 for (var i = el.firstChild; i != null; i = i.nextSibling) {
588 if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
589 var mo = re.exec(i.tagName);
590 if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
591 result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
592 }
593 iterate(i);
594 }
595 }
596 }
597 iterate(el);
598 return result;
599 }
600
601 var toc = document.getElementById("toc");
602 if (!toc) {
603 return;
604 }
605
606 // Delete existing TOC entries in case we're reloading the TOC.
607 var tocEntriesToRemove = [];
608 var i;
609 for (i = 0; i < toc.childNodes.length; i++) {
610 var entry = toc.childNodes[i];
611 if (entry.nodeName.toLowerCase() == 'div'
612 && entry.getAttribute("class")
613 && entry.getAttribute("class").match(/^toclevel/))
614 tocEntriesToRemove.push(entry);
615 }
616 for (i = 0; i < tocEntriesToRemove.length; i++) {
617 toc.removeChild(tocEntriesToRemove[i]);
618 }
619
620 // Rebuild TOC entries.
621 var entries = tocEntries(document.getElementById("content"), toclevels);
622 for (var i = 0; i < entries.length; ++i) {
623 var entry = entries[i];
624 if (entry.element.id == "")
625 entry.element.id = "_toc_" + i;
626 var a = document.createElement("a");
627 a.href = "#" + entry.element.id;
628 a.appendChild(document.createTextNode(entry.text));
629 var div = document.createElement("div");
630 div.appendChild(a);
631 div.className = "toclevel" + entry.toclevel;
632 toc.appendChild(div);
633 }
634 if (entries.length == 0)
635 toc.parentNode.removeChild(toc);
636 },
637
638
639 /////////////////////////////////////////////////////////////////////
640 // Footnotes generator
641 /////////////////////////////////////////////////////////////////////
642
643 /* Based on footnote generation code from:
644 * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
645 */
646
647 footnotes: function () {
648 // Delete existing footnote entries in case we're reloading the footnodes.
649 var i;
650 var noteholder = document.getElementById("footnotes");
651 if (!noteholder) {
652 return;
653 }
654 var entriesToRemove = [];
655 for (i = 0; i < noteholder.childNodes.length; i++) {
656 var entry = noteholder.childNodes[i];
657 if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
658 entriesToRemove.push(entry);
659 }
660 for (i = 0; i < entriesToRemove.length; i++) {
661 noteholder.removeChild(entriesToRemove[i]);
662 }
663
664 // Rebuild footnote entries.
665 var cont = document.getElementById("content");
666 var spans = cont.getElementsByTagName("span");
667 var refs = {};
668 var n = 0;
669 for (i=0; i<spans.length; i++) {
670 if (spans[i].className == "footnote") {
671 n++;
672 var note = spans[i].getAttribute("data-note");
673 if (!note) {
674 // Use [\s\S] in place of . so multi-line matches work.
675 // Because JavaScript has no s (dotall) regex flag.
676 note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
677 spans[i].innerHTML =
678 "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
679 "' title='View footnote' class='footnote'>" + n + "</a>]";
680 spans[i].setAttribute("data-note", note);
681 }
682 noteholder.innerHTML +=
683 "<div class='footnote' id='_footnote_" + n + "'>" +
684 "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
685 n + "</a>. " + note + "</div>";
686 var id =spans[i].getAttribute("id");
687 if (id != null) refs["#"+id] = n;
688 }
689 }
690 if (n == 0)
691 noteholder.parentNode.removeChild(noteholder);
692 else {
693 // Process footnoterefs.
694 for (i=0; i<spans.length; i++) {
695 if (spans[i].className == "footnoteref") {
696 var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
697 href = href.match(/#.*/)[0]; // Because IE return full URL.
698 n = refs[href];
699 spans[i].innerHTML =
700 "[<a href='#_footnote_" + n +
701 "' title='View footnote' class='footnote'>" + n + "</a>]";
702 }
703 }
704 }
705 },
706
707 install: function(toclevels) {
708 var timerId;
709
710 function reinstall() {
711 asciidoc.footnotes();
712 if (toclevels) {
713 asciidoc.toc(toclevels);
714 }
715 }
716
717 function reinstallAndRemoveTimer() {
718 clearInterval(timerId);
719 reinstall();
720 }
721
722 timerId = setInterval(reinstall, 500);
723 if (document.addEventListener)
724 document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
725 else
726 window.onload = reinstallAndRemoveTimer;
727 }
728
729 }
730 asciidoc.install(2);
731 /*]]>*/
732 </script>
733 </head>
734 <body class="article">
735 <div id="header">
736 <h1>External workspace bars</h1>
737 <span id="author">Michael Stapelberg</span><br />
738 <span id="email"><code>&lt;<a href="mailto:[email protected]">[email protected]</a>&gt;</code></span><br />
739 <span id="revdate">April 2013</span>
740 <div id="toc">
741 <div id="toctitle">Table of Contents</div>
742 <noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
743 </div>
744 </div>
745 <div id="content">
746 <div id="preamble">
747 <div class="sectionbody">
748 <div class="paragraph"><p>i3 comes with i3bar by default, a simple bar that is sufficient for most users.
749 In case you are unhappy with it, this document explains how to use a different,
750 external workspace bar. Note that we do not provide support for external
751 programs.</p></div>
752 </div>
753 </div>
754 <div class="sect1">
755 <h2 id="_internal_and_external_bars">1. Internal and external bars</h2>
756 <div class="sectionbody">
757 <div class="paragraph"><p>The internal workspace bar of i3 is meant to be a reasonable default so that
758 you can use i3 without having too much hassle when setting it up. It is quite
759 simple and intended to stay this way.</p></div>
760 </div>
761 </div>
762 <div class="sect1">
763 <h2 id="_dock_mode">2. dock mode</h2>
764 <div class="sectionbody">
765 <div class="paragraph"><p>You typically want to see the same workspace bar on every workspace on a
766 specific screen. Also, you don’t want to place the workspace bar somewhere
767 in your layout by hand. This is where dock mode comes in: When a program sets
768 the appropriate hint (_NET_WM_WINDOW_TYPE_DOCK), it will be managed in dock
769 mode by i3. That means it will be placed at the bottom or top of the screen
770 (while other edges of the screen are possible in the NetWM standard, this is
771 not yet implemented in i3), it will not overlap any other window and it will be
772 on every workspace for the specific screen it was placed on initially.</p></div>
773 </div>
774 </div>
775 <div class="sect1">
776 <h2 id="_the_ipc_interface">3. The IPC interface</h2>
777 <div class="sectionbody">
778 <div class="paragraph"><p>In the context of using an external workspace bar, the IPC interface needs to
779 provide the bar program with the current workspaces and output (as in VGA-1,
780 LVDS-1, …) configuration. In the other direction, the program has to be able
781 to switch to specific workspaces.</p></div>
782 <div class="paragraph"><p>By default, the IPC interface is enabled and you can get the path to the socket
783 by calling <code>i3 --get-socketpath</code>.</p></div>
784 <div class="paragraph"><p>To learn more about the protocol which is used for IPC, see <code>docs/ipc</code>.</p></div>
785 </div>
786 </div>
787 <div class="sect1">
788 <h2 id="_output_changes_on_the_fly">4. Output changes (on-the-fly)</h2>
789 <div class="sectionbody">
790 <div class="paragraph"><p>i3 implements the RandR API and can handle changing outputs quite well. So, an
791 external workspace bar implementation needs to make sure that when you change
792 the resolution of any of your screens (or enable/disable an output), the bars
793 will be adjusted properly.</p></div>
794 </div>
795 </div>
796 <div class="sect1">
797 <h2 id="_i3_wsbar_an_example_implementation">5. i3-wsbar, an example implementation</h2>
798 <div class="sectionbody">
799 <div class="paragraph"><p><code>i3-wsbar</code> used to be the reference implementation before we had <code>i3bar</code>.
800 Nowadays, it is not shipped with release tarballs, but you can still get it at
801 <a href="https://github.com/i3/i3/blob/next/contrib/i3-wsbar">https://github.com/i3/i3/blob/next/contrib/i3-wsbar</a></p></div>
802 <div class="sect2">
803 <h3 id="_the_big_picture">5.1. The big picture</h3>
804 <div class="paragraph"><p>The most common reason to use an external workspace bar is to integrate system
805 information such as what <code>i3status</code> or <code>conky</code> provide into the workspace bar.
806 So, we have <code>i3status</code> or a similar program, which only provides
807 text output (formatted in some way). To display this text nicely on the screen,
808 there are programs such as dzen2, xmobar and similar. We will stick to dzen2
809 from here on. So, we have the output of i3status, which needs to go into dzen2
810 somehow. But we also want to display the list of workspaces. <code>i3-wsbar</code> takes
811 input on stdin, combines it with a formatted workspace list and pipes it to
812 dzen2.</p></div>
813 <div class="paragraph"><p>Please note that <code>i3-wsbar</code> does not print its output to stdout. Instead, it
814 launches the dzen2 instances on its own. This is necessary to handle changes
815 in the available outputs (to place a new dzen2 on a new screen for example).</p></div>
816 <div class="paragraph"><p><span class="image">
817 <a class="image" href="wsbar.png">
818 <img src="wsbar.png" alt="Overview" />
819 </a>
820 </span></p></div>
821 </div>
822 <div class="sect2">
823 <h3 id="_running_i3_wsbar">5.2. Running i3-wsbar</h3>
824 <div class="paragraph"><p>The most simple usage of i3-wsbar looks like this:</p></div>
825 <div class="listingblock">
826 <div class="content">
827 <pre><code>i3-wsbar -c "dzen2 -x %x -dock"</code></pre>
828 </div></div>
829 <div class="paragraph"><p>The <code>%x</code> in the command name will be replaced by the X position of the output
830 for which this workspace bar is running. i3 will automatically place the
831 workspace bar on the correct output when dzen2 is started in dock mode. The
832 bar which you will see should look exactly like the internal bar of i3.</p></div>
833 <div class="paragraph"><p>To actually get a benefit, you want to give <code>i3-wsbar</code> some input:</p></div>
834 <div class="listingblock">
835 <div class="content">
836 <pre><code>i3status | i3-wsbar -c "dzen2 -x %x -dock"</code></pre>
837 </div></div>
838 </div>
839 </div>
840 </div>
841 </div>
842 <div id="footnotes"><hr /></div>
843 <div id="footer">
844 <div id="footer-text">
845 Last updated
846 2019-08-30 23:06:47 CEST
847 </div>
848 </div>
849 </body>
850 </html>
0 '\" t
1 .\" Title: i3-config-wizard
2 .\" Author: [see the "AUTHOR" section]
3 .\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
4 .\" Date: 08/30/2019
5 .\" Manual: i3 Manual
6 .\" Source: i3 4.17.1
7 .\" Language: English
8 .\"
9 .TH "I3\-CONFIG\-WIZARD" "1" "08/30/2019" "i3 4\&.17\&.1" "i3 Manual"
10 .\" -----------------------------------------------------------------
11 .\" * Define some portability stuff
12 .\" -----------------------------------------------------------------
13 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
14 .\" http://bugs.debian.org/507673
15 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
16 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
17 .ie \n(.g .ds Aq \(aq
18 .el .ds Aq '
19 .\" -----------------------------------------------------------------
20 .\" * set default formatting
21 .\" -----------------------------------------------------------------
22 .\" disable hyphenation
23 .nh
24 .\" disable justification (adjust text to left margin only)
25 .ad l
26 .\" -----------------------------------------------------------------
27 .\" * MAIN CONTENT STARTS HERE *
28 .\" -----------------------------------------------------------------
29 .SH "NAME"
30 i3-config-wizard \- creates a keysym based config based on your layout
31 .SH "SYNOPSIS"
32 .sp
33 i3\-config\-wizard [\fB\-s\fR \fIsocket\fR] [\fB\-m\fR \fImodifier\fR] [\fB\-v\fR] [\fB\-h\fR]
34 .SH "OPTIONS"
35 .PP
36 \fB\-s, \-\-socket\fR \fIsocket\fR
37 .RS 4
38 Overwrites the path to the i3 IPC socket\&.
39 .RE
40 .PP
41 \fB\-m, \-\-modifier\fR \fImodifier\fR
42 .RS 4
43 Generates the configuration file headlessly\&. Accepts win or alt\&.
44 .RE
45 .PP
46 \fB\-v, \-\-version\fR
47 .RS 4
48 Display version number and exit\&.
49 .RE
50 .PP
51 \fB\-h, \-\-help\fR
52 .RS 4
53 Display a short help message and exit\&.
54 .RE
55 .SH "FILES"
56 .SS "/etc/i3/config\&.keycodes"
57 .sp
58 This file contains the default configuration with keycodes\&. All the bindcode lines will be transformed to bindsym and the user\-specified modifier will be used\&.
59 .SH "DESCRIPTION"
60 .sp
61 i3\-config\-wizard is started by i3 in its default config, unless /\&.i3/config exists\&. i3\-config\-wizard creates a keysym based i3 config file (based on /etc/i3/config\&.keycodes) in /\&.i3/config\&.
62 .sp
63 The advantage of using keysyms is that the config file is easy to read, understand and modify\&. However, if we shipped with a keysym based default config file, the key positions would not be consistent across different keyboard layouts (take for example the homerow for movement)\&. Therefore, we ship with a keycode based default config and let the wizard transform it according to your current keyboard layout\&.
64 .SH "SEE ALSO"
65 .sp
66 i3(1)
67 .SH "AUTHOR"
68 .sp
69 Michael Stapelberg and contributors
0 .\" Automatically generated by Pod::Man 4.10 (Pod::Simple 3.35)
1 .\"
2 .\" Standard preamble:
3 .\" ========================================================================
4 .de Sp \" Vertical space (when we can't use .PP)
5 .if t .sp .5v
6 .if n .sp
7 ..
8 .de Vb \" Begin verbatim text
9 .ft CW
10 .nf
11 .ne \\$1
12 ..
13 .de Ve \" End verbatim text
14 .ft R
15 .fi
16 ..
17 .\" Set up some character translations and predefined strings. \*(-- will
18 .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
19 .\" double quote, and \*(R" will give a right double quote. \*(C+ will
20 .\" give a nicer C++. Capital omega is used to do unbreakable dashes and
21 .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
22 .\" nothing in troff, for use with C<>.
23 .tr \(*W-
24 .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
25 .ie n \{\
26 . ds -- \(*W-
27 . ds PI pi
28 . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
29 . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
30 . ds L" ""
31 . ds R" ""
32 . ds C` ""
33 . ds C' ""
34 'br\}
35 .el\{\
36 . ds -- \|\(em\|
37 . ds PI \(*p
38 . ds L" ``
39 . ds R" ''
40 . ds C`
41 . ds C'
42 'br\}
43 .\"
44 .\" Escape single quotes in literal strings from groff's Unicode transform.
45 .ie \n(.g .ds Aq \(aq
46 .el .ds Aq '
47 .\"
48 .\" If the F register is >0, we'll generate index entries on stderr for
49 .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
50 .\" entries marked with X<> in POD. Of course, you'll have to process the
51 .\" output yourself in some meaningful fashion.
52 .\"
53 .\" Avoid warning from groff about undefined register 'F'.
54 .de IX
55 ..
56 .nr rF 0
57 .if \n(.g .if rF .nr rF 1
58 .if (\n(rF:(\n(.g==0)) \{\
59 . if \nF \{\
60 . de IX
61 . tm Index:\\$1\t\\n%\t"\\$2"
62 ..
63 . if !\nF==2 \{\
64 . nr % 0
65 . nr F 2
66 . \}
67 . \}
68 .\}
69 .rr rF
70 .\" ========================================================================
71 .\"
72 .IX Title "I3-DMENU-DESKTOP 1"
73 .TH I3-DMENU-DESKTOP 1 "2019-08-30" "perl v5.28.1" "User Contributed Perl Documentation"
74 .\" For nroff, turn off justification. Always turn off hyphenation; it makes
75 .\" way too many mistakes in technical documents.
76 .if n .ad l
77 .nh
78 .SH "NAME"
79 .Vb 1
80 \& i3\-dmenu\-desktop \- run .desktop files with dmenu
81 .Ve
82 .SH "SYNOPSIS"
83 .IX Header "SYNOPSIS"
84 .Vb 1
85 \& i3\-dmenu\-desktop [\-\-dmenu=\*(Aqdmenu \-i\*(Aq] [\-\-entry\-type=name]
86 .Ve
87 .SH "DESCRIPTION"
88 .IX Header "DESCRIPTION"
89 i3\-dmenu\-desktop is a script which extracts the (localized) name from
90 application .desktop files, offers the user a choice via \fBdmenu\fR\|(1) and then
91 starts the chosen application via i3 (for startup notification support).
92 The advantage of using .desktop files instead of \fBdmenu_run\fR\|(1) is that dmenu_run
93 offers \fBall\fR binaries in your \f(CW$PATH\fR, including non-interactive utilities like
94 \&\*(L"sed\*(R". Also, .desktop files contain a proper name, information about whether
95 the application runs in a terminal and whether it supports startup
96 notifications.
97 .PP
98 The .desktop files are searched in \f(CW$XDG_DATA_HOME\fR/applications (by default
99 \&\f(CW$HOME\fR/.local/share/applications) and in the \*(L"applications\*(R" subdirectory of each
100 entry of \f(CW$XDG_DATA_DIRS\fR (by default /usr/local/share/:/usr/share/).
101 .PP
102 Files with the same name in \f(CW$XDG_DATA_HOME\fR/applications take precedence over
103 files in \f(CW$XDG_DATA_DIRS\fR, so that you can overwrite parts of the system-wide
104 \&.desktop files by copying them to your local directory and making changes.
105 .PP
106 i3\-dmenu\-desktop displays the \*(L"Name\*(R" value in the localized version depending
107 on \s-1LC_MESSAGES\s0 as specified in the Desktop Entry Specification.
108 .PP
109 You can pass a filename or \s-1URL\s0 (%f/%F and \f(CW%u\fR/%U field codes in the .desktop
110 file respectively) by appending it to the name of the application. E.g., if you
111 want to launch \*(L"\s-1GNU\s0 Emacs 24\*(R" with the patch /tmp/foobar.txt, you would type
112 \&\*(L"emacs\*(R", press \s-1TAB,\s0 type \*(L" /tmp/foobar.txt\*(R" and press \s-1ENTER.\s0
113 .PP
114 \&.desktop files with Terminal=true are started using \fBi3\-sensible\-terminal\fR\|(1).
115 .PP
116 \&.desktop files with NoDisplay=true or Hidden=true are skipped.
117 .PP
118 \&\s-1UTF\-8\s0 is supported, of course, but dmenu does not support displaying all
119 glyphs. E.g., xfce4\-terminal.desktop's Name[fi]=Pääte will be displayed just
120 fine, but not its Name[ru]=Терминал.
121 .SH "OPTIONS"
122 .IX Header "OPTIONS"
123 .IP "\fB\-\-dmenu=command\fR" 4
124 .IX Item "--dmenu=command"
125 Execute command instead of 'dmenu \-i'. This option can be used to pass custom
126 parameters to dmenu, or to make i3\-dmenu\-desktop start a custom (patched?)
127 version of dmenu.
128 .IP "\fB\-\-entry\-type=type\fR" 4
129 .IX Item "--entry-type=type"
130 Display the (localized) \*(L"Name\*(R" (type = name), the command (type = command) or
131 the (*.desktop) filename (type = filename) in dmenu. This option can be
132 specified multiple times.
133 .Sp
134 Examples are \*(L"\s-1GNU\s0 Image Manipulation Program\*(R" (type = name), \*(L"gimp\*(R" (type =
135 command), and \*(L"libreoffice-writer\*(R" (type = filename).
136 .SH "VERSION"
137 .IX Header "VERSION"
138 Version 1.5
139 .SH "AUTHOR"
140 .IX Header "AUTHOR"
141 Michael Stapelberg, \f(CW\*(C`<michael at i3wm.org>\*(C'\fR
142 .SH "LICENSE AND COPYRIGHT"
143 .IX Header "LICENSE AND COPYRIGHT"
144 Copyright 2012 Michael Stapelberg.
145 .PP
146 This program is free software; you can redistribute it and/or modify it
147 under the terms of the \s-1BSD\s0 license.
0 '\" t
1 .\" Title: i3-dump-log
2 .\" Author: [see the "AUTHOR" section]
3 .\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
4 .\" Date: 08/30/2019
5 .\" Manual: i3 Manual
6 .\" Source: i3 4.17.1
7 .\" Language: English
8 .\"
9 .TH "I3\-DUMP\-LOG" "1" "08/30/2019" "i3 4\&.17\&.1" "i3 Manual"
10 .\" -----------------------------------------------------------------
11 .\" * Define some portability stuff
12 .\" -----------------------------------------------------------------
13 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
14 .\" http://bugs.debian.org/507673
15 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
16 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
17 .ie \n(.g .ds Aq \(aq
18 .el .ds Aq '
19 .\" -----------------------------------------------------------------
20 .\" * set default formatting
21 .\" -----------------------------------------------------------------
22 .\" disable hyphenation
23 .nh
24 .\" disable justification (adjust text to left margin only)
25 .ad l
26 .\" -----------------------------------------------------------------
27 .\" * MAIN CONTENT STARTS HERE *
28 .\" -----------------------------------------------------------------
29 .SH "NAME"
30 i3-dump-log \- dumps the i3 SHM log
31 .SH "SYNOPSIS"
32 .sp
33 i3\-dump\-log [\-s <socketpath>] [\-f]
34 .SH "DESCRIPTION"
35 .sp
36 Debug versions of i3 automatically use 1% of your RAM (but 25 MiB max) to store full debug log output\&. This is extremely helpful for bugreports and figuring out what is going on, without permanently logging to a file\&.
37 .sp
38 With i3\-dump\-log, you can dump the SHM log to stdout\&.
39 .sp
40 The \-f flag works like tail \-f, i\&.e\&. the process does not terminate after dumping the log, but prints new lines as they appear\&.
41 .SH "EXAMPLE"
42 .sp
43 i3\-dump\-log | gzip \-9 > /tmp/i3\-log\&.gz
44 .SH "SEE ALSO"
45 .sp
46 i3(1)
47 .SH "AUTHOR"
48 .sp
49 Michael Stapelberg and contributors
0 '\" t
1 .\" Title: i3-input
2 .\" Author: [see the "AUTHOR" section]
3 .\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
4 .\" Date: 08/30/2019
5 .\" Manual: i3 Manual
6 .\" Source: i3 4.17.1
7 .\" Language: English
8 .\"
9 .TH "I3\-INPUT" "1" "08/30/2019" "i3 4\&.17\&.1" "i3 Manual"
10 .\" -----------------------------------------------------------------
11 .\" * Define some portability stuff
12 .\" -----------------------------------------------------------------
13 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
14 .\" http://bugs.debian.org/507673
15 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
16 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
17 .ie \n(.g .ds Aq \(aq
18 .el .ds Aq '
19 .\" -----------------------------------------------------------------
20 .\" * set default formatting
21 .\" -----------------------------------------------------------------
22 .\" disable hyphenation
23 .nh
24 .\" disable justification (adjust text to left margin only)
25 .ad l
26 .\" -----------------------------------------------------------------
27 .\" * MAIN CONTENT STARTS HERE *
28 .\" -----------------------------------------------------------------
29 .SH "NAME"
30 i3-input \- interactively take a command for i3 window manager
31 .SH "SYNOPSIS"
32 .sp
33 i3\-input [\-s <socket>] [\-F <format>] [\-l <limit>] [\-P <prompt>] [\-f <font>] [\-v]
34 .SH "DESCRIPTION"
35 .sp
36 i3\-input is a tool to take commands (or parts of a command) composed by the user, and send it/them to i3\&. This is useful, for example, for the mark/goto command\&.
37 .sp
38 You can press Escape to close i3\-input without sending any commands\&.
39 .SH "OPTIONS"
40 .PP
41 \-s <socket>
42 .RS 4
43 Specify the path to the i3 IPC socket (it should not be necessary to use this option, i3\-input will figure out the path on its own)\&.
44 .RE
45 .PP
46 \-F <format>
47 .RS 4
48 Every occurrence of "%s" in the <format> string is replaced by the user input, and the result is sent to i3 as a command\&. Default value is "%s"\&.
49 .RE
50 .PP
51 \-l <limit>
52 .RS 4
53 Set the maximum allowed length of the user input to <limit> characters\&. i3\-input will automatically issue the command when the user input reaches that length\&.
54 .RE
55 .PP
56 \-P <prompt>
57 .RS 4
58 Display the <prompt> string in front of user input text field\&. The prompt string is not included in the user input/command\&.
59 .RE
60 .PP
61 \-f <font>
62 .RS 4
63 Use the specified X11 core font (use
64 xfontsel
65 to chose a font)\&.
66 .RE
67 .PP
68 \-v
69 .RS 4
70 Show version and exit\&.
71 .RE
72 .SH "EXAMPLES"
73 .sp
74 Mark a container with a single character:
75 .sp
76 .if n \{\
77 .RS 4
78 .\}
79 .nf
80 i3\-input \-F \*(Aqmark %s\*(Aq \-l 1 \-P \*(AqMark: \*(Aq
81 .fi
82 .if n \{\
83 .RE
84 .\}
85 .sp
86 Go to the container marked with above example:
87 .sp
88 .if n \{\
89 .RS 4
90 .\}
91 .nf
92 i3\-input \-F \*(Aq[con_mark="%s"] focus\*(Aq \-l 1 \-P \*(AqGo to: \*(Aq
93 .fi
94 .if n \{\
95 .RE
96 .\}
97 .SH "ENVIRONMENT"
98 .SS "I3SOCK"
99 .sp
100 i3\-input handles the different sources of socket paths in the following order:
101 .sp
102 .RS 4
103 .ie n \{\
104 \h'-04'\(bu\h'+03'\c
105 .\}
106 .el \{\
107 .sp -1
108 .IP \(bu 2.3
109 .\}
110 I3SOCK environment variable
111 .RE
112 .sp
113 .RS 4
114 .ie n \{\
115 \h'-04'\(bu\h'+03'\c
116 .\}
117 .el \{\
118 .sp -1
119 .IP \(bu 2.3
120 .\}
121 I3SOCK gets overwritten by the \-s parameter, if specified
122 .RE
123 .sp
124 .RS 4
125 .ie n \{\
126 \h'-04'\(bu\h'+03'\c
127 .\}
128 .el \{\
129 .sp -1
130 .IP \(bu 2.3
131 .\}
132 if neither are available, i3\-input reads the socket path from the X11 property, which is the recommended way
133 .RE
134 .sp
135 .RS 4
136 .ie n \{\
137 \h'-04'\(bu\h'+03'\c
138 .\}
139 .el \{\
140 .sp -1
141 .IP \(bu 2.3
142 .\}
143 if everything fails, i3\-input tries
144 /tmp/i3\-ipc\&.sock
145 .RE
146 .sp
147 The socket path is necessary to connect to i3 and actually issue the command\&.
148 .SH "SEE ALSO"
149 .sp
150 i3(1)
151 .SH "AUTHOR"
152 .sp
153 Michael Stapelberg and contributors
0 '\" t
1 .\" Title: i3-migrate-config-to-v4
2 .\" Author: [see the "AUTHOR" section]
3 .\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
4 .\" Date: 08/30/2019
5 .\" Manual: i3 Manual
6 .\" Source: i3 4.17.1
7 .\" Language: English
8 .\"
9 .TH "I3\-MIGRATE\-CONFIG\" "1" "08/30/2019" "i3 4\&.17\&.1" "i3 Manual"
10 .\" -----------------------------------------------------------------
11 .\" * Define some portability stuff
12 .\" -----------------------------------------------------------------
13 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
14 .\" http://bugs.debian.org/507673
15 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
16 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
17 .ie \n(.g .ds Aq \(aq
18 .el .ds Aq '
19 .\" -----------------------------------------------------------------
20 .\" * set default formatting
21 .\" -----------------------------------------------------------------
22 .\" disable hyphenation
23 .nh
24 .\" disable justification (adjust text to left margin only)
25 .ad l
26 .\" -----------------------------------------------------------------
27 .\" * MAIN CONTENT STARTS HERE *
28 .\" -----------------------------------------------------------------
29 .SH "NAME"
30 i3-migrate-config-to-v4 \- migrates your i3 config file
31 .SH "SYNOPSIS"
32 .sp
33 .nf
34 mv ~/\&.i3/config ~/\&.i3/old\&.config
35 i3\-migrate\-config\-to\-v4 ~/\&.i3/old\&.config > ~/\&.i3/config
36 .fi
37 .SH "DESCRIPTION"
38 .sp
39 i3\-migrate\-config\-to\-v4 is a Perl script which migrates your old (< version 4) configuration files to a version 4 config file\&. The most significant changes are the new commands (see the release notes)\&.
40 .sp
41 This script will automatically be run by i3 when it detects an old config file\&. Please migrate your config file as soon as possible\&. We plan to include this script in all i3 release until 2012\-08\-01\&. Afterwards, old config files will no longer be supported\&.
42 .SH "SEE ALSO"
43 .sp
44 i3(1)
45 .SH "AUTHOR"
46 .sp
47 Michael Stapelberg and contributors
0 '\" t
1 .\" Title: i3-msg
2 .\" Author: [see the "AUTHOR" section]
3 .\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
4 .\" Date: 08/30/2019
5 .\" Manual: i3 Manual
6 .\" Source: i3 4.17.1
7 .\" Language: English
8 .\"
9 .TH "I3\-MSG" "1" "08/30/2019" "i3 4\&.17\&.1" "i3 Manual"
10 .\" -----------------------------------------------------------------
11 .\" * Define some portability stuff
12 .\" -----------------------------------------------------------------
13 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
14 .\" http://bugs.debian.org/507673
15 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
16 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
17 .ie \n(.g .ds Aq \(aq
18 .el .ds Aq '
19 .\" -----------------------------------------------------------------
20 .\" * set default formatting
21 .\" -----------------------------------------------------------------
22 .\" disable hyphenation
23 .nh
24 .\" disable justification (adjust text to left margin only)
25 .ad l
26 .\" -----------------------------------------------------------------
27 .\" * MAIN CONTENT STARTS HERE *
28 .\" -----------------------------------------------------------------
29 .SH "NAME"
30 i3-msg \- send messages to i3 window manager
31 .SH "SYNOPSIS"
32 .sp
33 i3\-msg [\-q] [\-v] [\-h] [\-s socket] [\-t type] [message]
34 .SH "OPTIONS"
35 .PP
36 \fB\-q, \-\-quiet\fR
37 .RS 4
38 Only send ipc message and suppress the output of the response\&.
39 .RE
40 .PP
41 \fB\-v, \-\-version\fR
42 .RS 4
43 Display version number and exit\&.
44 .RE
45 .PP
46 \fB\-h, \-\-help\fR
47 .RS 4
48 Display a short help\-message and exit\&.
49 .RE
50 .PP
51 \fB\-s, \-\-socket\fR \fIsock_path\fR
52 .RS 4
53 i3\-msg will use the environment variable I3SOCK or the socket path given here\&. If both fail, it will try to get the socket information from the root window and then try /tmp/i3\-ipc\&.sock before exiting with an error\&.
54 .RE
55 .PP
56 \fB\-t\fR \fItype\fR
57 .RS 4
58 Send ipc message, see below\&. This option defaults to "command"\&.
59 .RE
60 .PP
61 \fB\-m\fR, \fB\-\-monitor\fR
62 .RS 4
63 Instead of exiting right after receiving the first subscribed event, wait indefinitely for all of them\&. Can only be used with "\-t subscribe"\&. See the "subscribe" IPC message type below for details\&.
64 .RE
65 .PP
66 \fBmessage\fR
67 .RS 4
68 Send ipc message, see below\&.
69 .RE
70 .SH "IPC MESSAGE TYPES"
71 .PP
72 command
73 .RS 4
74 The payload of the message is a command for i3 (like the commands you can bind to keys in the configuration file) and will be executed directly after receiving it\&.
75 .RE
76 .PP
77 get_workspaces
78 .RS 4
79 Gets the current workspaces\&. The reply will be a JSON\-encoded list of workspaces\&.
80 .RE
81 .PP
82 get_outputs
83 .RS 4
84 Gets the current outputs\&. The reply will be a JSON\-encoded list of outputs (see the reply section of docs/ipc, e\&.g\&. at
85 \m[blue]\fBhttps://i3wm\&.org/docs/ipc\&.html#_receiving_replies_from_i3\fR\m[])\&.
86 .RE
87 .PP
88 get_tree
89 .RS 4
90 Gets the layout tree\&. i3 uses a tree as data structure which includes every container\&. The reply will be the JSON\-encoded tree\&.
91 .RE
92 .PP
93 get_marks
94 .RS 4
95 Gets a list of marks (identifiers for containers to easily jump to them later)\&. The reply will be a JSON\-encoded list of window marks\&.
96 .RE
97 .PP
98 get_bar_config
99 .RS 4
100 Gets the configuration (as JSON map) of the workspace bar with the given ID\&. If no ID is provided, an array with all configured bar IDs is returned instead\&.
101 .RE
102 .PP
103 get_binding_modes
104 .RS 4
105 Gets a list of configured binding modes\&.
106 .RE
107 .PP
108 get_version
109 .RS 4
110 Gets the version of i3\&. The reply will be a JSON\-encoded dictionary with the major, minor, patch and human\-readable version\&.
111 .RE
112 .PP
113 get_config
114 .RS 4
115 Gets the currently loaded i3 configuration\&.
116 .RE
117 .PP
118 send_tick
119 .RS 4
120 Sends a tick to all IPC connections which subscribe to tick events\&.
121 .RE
122 .PP
123 subscribe
124 .RS 4
125 The payload of the message describes the events to subscribe to\&. Upon reception, each event will be dumped as a JSON\-encoded object\&. See the \-m option for continuous monitoring\&.
126 .RE
127 .SH "DESCRIPTION"
128 .sp
129 i3\-msg is a sample implementation for a client using the unix socket IPC interface to i3\&.
130 .SS "Exit status:"
131 .sp
132 0: if OK, 1: if invalid syntax or unable to connect to ipc\-socket 2: if i3 returned an error processing your command(s)
133 .SH "EXAMPLES"
134 .sp
135 .if n \{\
136 .RS 4
137 .\}
138 .nf
139 # Use 1\-px border for current client
140 i3\-msg "border 1pixel"
141
142 # You can leave out the quotes
143 i3\-msg border normal
144
145 # Dump the layout tree
146 i3\-msg \-t get_tree
147
148 # Monitor window changes
149 i3\-msg \-t subscribe \-m \*(Aq[ "window" ]\*(Aq
150 .fi
151 .if n \{\
152 .RE
153 .\}
154 .SH "ENVIRONMENT"
155 .SS "I3SOCK"
156 .sp
157 If no ipc\-socket is specified on the commandline, this variable is used to determine the path, at which the unix domain socket is expected, on which to connect to i3\&.
158 .SH "SEE ALSO"
159 .sp
160 i3(1)
161 .SH "AUTHOR"
162 .sp
163 Michael Stapelberg and contributors
0 '\" t
1 .\" Title: i3-nagbar
2 .\" Author: [see the "AUTHOR" section]
3 .\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
4 .\" Date: 08/30/2019
5 .\" Manual: i3 Manual
6 .\" Source: i3 4.17.1
7 .\" Language: English
8 .\"
9 .TH "I3\-NAGBAR" "1" "08/30/2019" "i3 4\&.17\&.1" "i3 Manual"
10 .\" -----------------------------------------------------------------
11 .\" * Define some portability stuff
12 .\" -----------------------------------------------------------------
13 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
14 .\" http://bugs.debian.org/507673
15 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
16 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
17 .ie \n(.g .ds Aq \(aq
18 .el .ds Aq '
19 .\" -----------------------------------------------------------------
20 .\" * set default formatting
21 .\" -----------------------------------------------------------------
22 .\" disable hyphenation
23 .nh
24 .\" disable justification (adjust text to left margin only)
25 .ad l
26 .\" -----------------------------------------------------------------
27 .\" * MAIN CONTENT STARTS HERE *
28 .\" -----------------------------------------------------------------
29 .SH "NAME"
30 i3-nagbar \- displays an error bar on top of your screen
31 .SH "SYNOPSIS"
32 .sp
33 i3\-nagbar [\-m <message>] [\-b <button> <action>] [\-B <button> <action>] [\-t warning|error] [\-f <font>] [\-v]
34 .SH "OPTIONS"
35 .PP
36 \fB\-v, \-\-version\fR
37 .RS 4
38 Display version number and exit\&.
39 .RE
40 .PP
41 \fB\-h, \-\-help\fR
42 .RS 4
43 Display a short help\-message and exit\&.
44 .RE
45 .PP
46 \fB\-t, \-\-type\fR \fItype\fR
47 .RS 4
48 Display either a warning or error message\&. This only changes the color scheme for the i3\-nagbar\&. Default: error\&.
49 .RE
50 .PP
51 \fB\-m, \-\-message\fR \fImessage\fR
52 .RS 4
53 Display
54 \fImessage\fR
55 as text on the left of the i3\-nagbar\&.
56 .RE
57 .PP
58 \fB\-f, \-\-font\fR \fIfont\fR
59 .RS 4
60 Select font that is being used\&.
61 .RE
62 .PP
63 \fB\-b, \-\-button\fR \fIbutton\fR \fIaction\fR
64 .RS 4
65 Create a button with text
66 \fIbutton\fR\&. The
67 \fIaction\fR
68 are the shell commands that will be executed by this button\&. Multiple buttons can be defined\&. Will launch the shell commands inside a terminal emulator, using i3\-sensible\-terminal\&.
69 .RE
70 .PP
71 \fB\-B, \-\-button\-no\-terminal\fR \fIbutton\fR \fIaction\fR
72 .RS 4
73 Same as above, but will execute the shell commands directly, without launching a terminal emulator\&.
74 .RE
75 .SH "DESCRIPTION"
76 .sp
77 i3\-nagbar is used by i3 to tell you about errors in your configuration file (for example)\&. While these errors are logged to the logfile (if any), the past has proven that users are either not aware of their logfile or do not check it after modifying the configuration file\&.
78 .SH "EXAMPLE"
79 .sp
80 .if n \{\
81 .RS 4
82 .\}
83 .nf
84 i3\-nagbar \-m \*(AqYou have an error in your i3 config file!\*(Aq \e
85 \-b \*(Aqedit config\*(Aq \*(Aqi3\-sensible\-editor ~/\&.config/i3/config\*(Aq
86 .fi
87 .if n \{\
88 .RE
89 .\}
90 .SH "SEE ALSO"
91 .sp
92 i3(1)
93 .SH "AUTHOR"
94 .sp
95 Michael Stapelberg and contributors
0 .\" Automatically generated by Pod::Man 4.10 (Pod::Simple 3.35)
1 .\"
2 .\" Standard preamble:
3 .\" ========================================================================
4 .de Sp \" Vertical space (when we can't use .PP)
5 .if t .sp .5v
6 .if n .sp
7 ..
8 .de Vb \" Begin verbatim text
9 .ft CW
10 .nf
11 .ne \\$1
12 ..
13 .de Ve \" End verbatim text
14 .ft R
15 .fi
16 ..
17 .\" Set up some character translations and predefined strings. \*(-- will
18 .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
19 .\" double quote, and \*(R" will give a right double quote. \*(C+ will
20 .\" give a nicer C++. Capital omega is used to do unbreakable dashes and
21 .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
22 .\" nothing in troff, for use with C<>.
23 .tr \(*W-
24 .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
25 .ie n \{\
26 . ds -- \(*W-
27 . ds PI pi
28 . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
29 . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
30 . ds L" ""
31 . ds R" ""
32 . ds C` ""
33 . ds C' ""
34 'br\}
35 .el\{\
36 . ds -- \|\(em\|
37 . ds PI \(*p
38 . ds L" ``
39 . ds R" ''
40 . ds C`
41 . ds C'
42 'br\}
43 .\"
44 .\" Escape single quotes in literal strings from groff's Unicode transform.
45 .ie \n(.g .ds Aq \(aq
46 .el .ds Aq '
47 .\"
48 .\" If the F register is >0, we'll generate index entries on stderr for
49 .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
50 .\" entries marked with X<> in POD. Of course, you'll have to process the
51 .\" output yourself in some meaningful fashion.
52 .\"
53 .\" Avoid warning from groff about undefined register 'F'.
54 .de IX
55 ..
56 .nr rF 0
57 .if \n(.g .if rF .nr rF 1
58 .if (\n(rF:(\n(.g==0)) \{\
59 . if \nF \{\
60 . de IX
61 . tm Index:\\$1\t\\n%\t"\\$2"
62 ..
63 . if !\nF==2 \{\
64 . nr % 0
65 . nr F 2
66 . \}
67 . \}
68 .\}
69 .rr rF
70 .\" ========================================================================
71 .\"
72 .IX Title "I3-SAVE-TREE 1"
73 .TH I3-SAVE-TREE 1 "2019-08-30" "perl v5.28.1" "User Contributed Perl Documentation"
74 .\" For nroff, turn off justification. Always turn off hyphenation; it makes
75 .\" way too many mistakes in technical documents.
76 .if n .ad l
77 .nh
78 .SH "NAME"
79 .Vb 1
80 \& i3\-save\-tree \- save (parts of) the layout tree for restoring
81 .Ve
82 .SH "SYNOPSIS"
83 .IX Header "SYNOPSIS"
84 .Vb 1
85 \& i3\-save\-tree [\-\-workspace=name|number] [\-\-output=name]
86 .Ve
87 .SH "DESCRIPTION"
88 .IX Header "DESCRIPTION"
89 Dumps a workspace (or an entire output) to stdout. The data is supposed to be
90 edited a bit by a human, then later fed to i3 via the append_layout command.
91 .PP
92 The append_layout command will create placeholder windows, arranged in the
93 layout the input file specifies. Each container should have a swallows
94 specification. When a window is mapped (made visible on the screen) that
95 matches the specification, i3 will put it into that place and kill the
96 placeholder.
97 .PP
98 If neither argument is specified, the currently focused workspace will be used.
99 .SH "OPTIONS"
100 .IX Header "OPTIONS"
101 .IP "\fB\-\-workspace=name|number\fR" 4
102 .IX Item "--workspace=name|number"
103 Specifies the workspace that should be dumped, e.g. 1. This can either be a
104 name or the number of a workspace.
105 .IP "\fB\-\-output=name\fR" 4
106 .IX Item "--output=name"
107 Specifies the output that should be dumped, e.g. \s-1LVDS\-1.\s0
108 .SH "VERSION"
109 .IX Header "VERSION"
110 Version 0.1
111 .SH "AUTHOR"
112 .IX Header "AUTHOR"
113 Michael Stapelberg, \f(CW\*(C`<michael at i3wm.org>\*(C'\fR
114 .SH "LICENSE AND COPYRIGHT"
115 .IX Header "LICENSE AND COPYRIGHT"
116 Copyright 2013 Michael Stapelberg.
117 .PP
118 This program is free software; you can redistribute it and/or modify it
119 under the terms of the \s-1BSD\s0 license.
0 '\" t
1 .\" Title: i3-sensible-editor
2 .\" Author: [see the "AUTHOR" section]
3 .\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
4 .\" Date: 08/30/2019
5 .\" Manual: i3 Manual
6 .\" Source: i3 4.17.1
7 .\" Language: English
8 .\"
9 .TH "I3\-SENSIBLE\-EDITOR" "1" "08/30/2019" "i3 4\&.17\&.1" "i3 Manual"
10 .\" -----------------------------------------------------------------
11 .\" * Define some portability stuff
12 .\" -----------------------------------------------------------------
13 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
14 .\" http://bugs.debian.org/507673
15 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
16 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
17 .ie \n(.g .ds Aq \(aq
18 .el .ds Aq '
19 .\" -----------------------------------------------------------------
20 .\" * set default formatting
21 .\" -----------------------------------------------------------------
22 .\" disable hyphenation
23 .nh
24 .\" disable justification (adjust text to left margin only)
25 .ad l
26 .\" -----------------------------------------------------------------
27 .\" * MAIN CONTENT STARTS HERE *
28 .\" -----------------------------------------------------------------
29 .SH "NAME"
30 i3-sensible-editor \- launches $EDITOR with fallbacks
31 .SH "SYNOPSIS"
32 .sp
33 i3\-sensible\-editor [arguments]
34 .SH "DESCRIPTION"
35 .sp
36 i3\-sensible\-editor is used by i3\-nagbar(1) when you click on the edit button\&.
37 .sp
38 It tries to start one of the following (in that order):
39 .sp
40 .RS 4
41 .ie n \{\
42 \h'-04'\(bu\h'+03'\c
43 .\}
44 .el \{\
45 .sp -1
46 .IP \(bu 2.3
47 .\}
48 $VISUAL
49 .RE
50 .sp
51 .RS 4
52 .ie n \{\
53 \h'-04'\(bu\h'+03'\c
54 .\}
55 .el \{\
56 .sp -1
57 .IP \(bu 2.3
58 .\}
59 $EDITOR
60 .RE
61 .sp
62 .RS 4
63 .ie n \{\
64 \h'-04'\(bu\h'+03'\c
65 .\}
66 .el \{\
67 .sp -1
68 .IP \(bu 2.3
69 .\}
70 nano
71 .RE
72 .sp
73 .RS 4
74 .ie n \{\
75 \h'-04'\(bu\h'+03'\c
76 .\}
77 .el \{\
78 .sp -1
79 .IP \(bu 2.3
80 .\}
81 nvim
82 .RE
83 .sp
84 .RS 4
85 .ie n \{\
86 \h'-04'\(bu\h'+03'\c
87 .\}
88 .el \{\
89 .sp -1
90 .IP \(bu 2.3
91 .\}
92 vim
93 .RE
94 .sp
95 .RS 4
96 .ie n \{\
97 \h'-04'\(bu\h'+03'\c
98 .\}
99 .el \{\
100 .sp -1
101 .IP \(bu 2.3
102 .\}
103 vi
104 .RE
105 .sp
106 .RS 4
107 .ie n \{\
108 \h'-04'\(bu\h'+03'\c
109 .\}
110 .el \{\
111 .sp -1
112 .IP \(bu 2.3
113 .\}
114 emacs
115 .RE
116 .sp
117 .RS 4
118 .ie n \{\
119 \h'-04'\(bu\h'+03'\c
120 .\}
121 .el \{\
122 .sp -1
123 .IP \(bu 2.3
124 .\}
125 pico
126 .RE
127 .sp
128 .RS 4
129 .ie n \{\
130 \h'-04'\(bu\h'+03'\c
131 .\}
132 .el \{\
133 .sp -1
134 .IP \(bu 2.3
135 .\}
136 qe
137 .RE
138 .sp
139 .RS 4
140 .ie n \{\
141 \h'-04'\(bu\h'+03'\c
142 .\}
143 .el \{\
144 .sp -1
145 .IP \(bu 2.3
146 .\}
147 mg
148 .RE
149 .sp
150 .RS 4
151 .ie n \{\
152 \h'-04'\(bu\h'+03'\c
153 .\}
154 .el \{\
155 .sp -1
156 .IP \(bu 2.3
157 .\}
158 jed
159 .RE
160 .sp
161 .RS 4
162 .ie n \{\
163 \h'-04'\(bu\h'+03'\c
164 .\}
165 .el \{\
166 .sp -1
167 .IP \(bu 2.3
168 .\}
169 gedit
170 .RE
171 .sp
172 .RS 4
173 .ie n \{\
174 \h'-04'\(bu\h'+03'\c
175 .\}
176 .el \{\
177 .sp -1
178 .IP \(bu 2.3
179 .\}
180 mcedit
181 .RE
182 .sp
183 .RS 4
184 .ie n \{\
185 \h'-04'\(bu\h'+03'\c
186 .\}
187 .el \{\
188 .sp -1
189 .IP \(bu 2.3
190 .\}
191 gvim
192 .RE
193 .sp
194 Please don\(cqt complain about the order: If the user has any preference, they will have $VISUAL or $EDITOR set\&.
195 .SH "SEE ALSO"
196 .sp
197 i3(1)
198 .SH "AUTHOR"
199 .sp
200 Michael Stapelberg and contributors
0 '\" t
1 .\" Title: i3-sensible-pager
2 .\" Author: [see the "AUTHOR" section]
3 .\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
4 .\" Date: 08/30/2019
5 .\" Manual: i3 Manual
6 .\" Source: i3 4.17.1
7 .\" Language: English
8 .\"
9 .TH "I3\-SENSIBLE\-PAGER" "1" "08/30/2019" "i3 4\&.17\&.1" "i3 Manual"
10 .\" -----------------------------------------------------------------
11 .\" * Define some portability stuff
12 .\" -----------------------------------------------------------------
13 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
14 .\" http://bugs.debian.org/507673
15 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
16 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
17 .ie \n(.g .ds Aq \(aq
18 .el .ds Aq '
19 .\" -----------------------------------------------------------------
20 .\" * set default formatting
21 .\" -----------------------------------------------------------------
22 .\" disable hyphenation
23 .nh
24 .\" disable justification (adjust text to left margin only)
25 .ad l
26 .\" -----------------------------------------------------------------
27 .\" * MAIN CONTENT STARTS HERE *
28 .\" -----------------------------------------------------------------
29 .SH "NAME"
30 i3-sensible-pager \- launches $PAGER with fallbacks
31 .SH "SYNOPSIS"
32 .sp
33 i3\-sensible\-pager [arguments]
34 .SH "DESCRIPTION"
35 .sp
36 i3\-sensible\-pager is used by i3\-nagbar(1) when you click on the view button\&.
37 .sp
38 It tries to start one of the following (in that order):
39 .sp
40 .RS 4
41 .ie n \{\
42 \h'-04'\(bu\h'+03'\c
43 .\}
44 .el \{\
45 .sp -1
46 .IP \(bu 2.3
47 .\}
48 $PAGER
49 .RE
50 .sp
51 .RS 4
52 .ie n \{\
53 \h'-04'\(bu\h'+03'\c
54 .\}
55 .el \{\
56 .sp -1
57 .IP \(bu 2.3
58 .\}
59 less
60 .RE
61 .sp
62 .RS 4
63 .ie n \{\
64 \h'-04'\(bu\h'+03'\c
65 .\}
66 .el \{\
67 .sp -1
68 .IP \(bu 2.3
69 .\}
70 most
71 .RE
72 .sp
73 .RS 4
74 .ie n \{\
75 \h'-04'\(bu\h'+03'\c
76 .\}
77 .el \{\
78 .sp -1
79 .IP \(bu 2.3
80 .\}
81 w3m
82 .RE
83 .sp
84 .RS 4
85 .ie n \{\
86 \h'-04'\(bu\h'+03'\c
87 .\}
88 .el \{\
89 .sp -1
90 .IP \(bu 2.3
91 .\}
92 i3\-sensible\-editor(1)
93 .RE
94 .sp
95 Please don\(cqt complain about the order: If the user has any preference, they will have $PAGER set\&.
96 .SH "SEE ALSO"
97 .sp
98 i3(1)
99 .SH "AUTHOR"
100 .sp
101 Michael Stapelberg and contributors
0 '\" t
1 .\" Title: i3-sensible-terminal
2 .\" Author: [see the "AUTHOR" section]
3 .\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
4 .\" Date: 08/30/2019
5 .\" Manual: i3 Manual
6 .\" Source: i3 4.17.1
7 .\" Language: English
8 .\"
9 .TH "I3\-SENSIBLE\-TERMIN" "1" "08/30/2019" "i3 4\&.17\&.1" "i3 Manual"
10 .\" -----------------------------------------------------------------
11 .\" * Define some portability stuff
12 .\" -----------------------------------------------------------------
13 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
14 .\" http://bugs.debian.org/507673
15 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
16 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
17 .ie \n(.g .ds Aq \(aq
18 .el .ds Aq '
19 .\" -----------------------------------------------------------------
20 .\" * set default formatting
21 .\" -----------------------------------------------------------------
22 .\" disable hyphenation
23 .nh
24 .\" disable justification (adjust text to left margin only)
25 .ad l
26 .\" -----------------------------------------------------------------
27 .\" * MAIN CONTENT STARTS HERE *
28 .\" -----------------------------------------------------------------
29 .SH "NAME"
30 i3-sensible-terminal \- launches $TERMINAL with fallbacks
31 .SH "SYNOPSIS"
32 .sp
33 i3\-sensible\-terminal [arguments]
34 .SH "DESCRIPTION"
35 .sp
36 i3\-sensible\-terminal is invoked in the i3 default config to start a terminal\&. This wrapper script is necessary since there is no distribution\-independent terminal launcher (but for example Debian has x\-terminal\-emulator)\&. Distribution packagers are responsible for shipping this script in a way which is appropriate for the distribution\&.
37 .sp
38 It tries to start one of the following (in that order):
39 .sp
40 .RS 4
41 .ie n \{\
42 \h'-04'\(bu\h'+03'\c
43 .\}
44 .el \{\
45 .sp -1
46 .IP \(bu 2.3
47 .\}
48 $TERMINAL (this is a non\-standard variable)
49 .RE
50 .sp
51 .RS 4
52 .ie n \{\
53 \h'-04'\(bu\h'+03'\c
54 .\}
55 .el \{\
56 .sp -1
57 .IP \(bu 2.3
58 .\}
59 x\-terminal\-emulator (only present on Debian and derivatives)
60 .RE
61 .sp
62 .RS 4
63 .ie n \{\
64 \h'-04'\(bu\h'+03'\c
65 .\}
66 .el \{\
67 .sp -1
68 .IP \(bu 2.3
69 .\}
70 urxvt
71 .RE
72 .sp
73 .RS 4
74 .ie n \{\
75 \h'-04'\(bu\h'+03'\c
76 .\}
77 .el \{\
78 .sp -1
79 .IP \(bu 2.3
80 .\}
81 rxvt
82 .RE
83 .sp
84 .RS 4
85 .ie n \{\
86 \h'-04'\(bu\h'+03'\c
87 .\}
88 .el \{\
89 .sp -1
90 .IP \(bu 2.3
91 .\}
92 termit
93 .RE
94 .sp
95 .RS 4
96 .ie n \{\
97 \h'-04'\(bu\h'+03'\c
98 .\}
99 .el \{\
100 .sp -1
101 .IP \(bu 2.3
102 .\}
103 terminator
104 .RE
105 .sp
106 .RS 4
107 .ie n \{\
108 \h'-04'\(bu\h'+03'\c
109 .\}
110 .el \{\
111 .sp -1
112 .IP \(bu 2.3
113 .\}
114 Eterm
115 .RE
116 .sp
117 .RS 4
118 .ie n \{\
119 \h'-04'\(bu\h'+03'\c
120 .\}
121 .el \{\
122 .sp -1
123 .IP \(bu 2.3
124 .\}
125 aterm
126 .RE
127 .sp
128 .RS 4
129 .ie n \{\
130 \h'-04'\(bu\h'+03'\c
131 .\}
132 .el \{\
133 .sp -1
134 .IP \(bu 2.3
135 .\}
136 uxterm
137 .RE
138 .sp
139 .RS 4
140 .ie n \{\
141 \h'-04'\(bu\h'+03'\c
142 .\}
143 .el \{\
144 .sp -1
145 .IP \(bu 2.3
146 .\}
147 xterm
148 .RE
149 .sp
150 .RS 4
151 .ie n \{\
152 \h'-04'\(bu\h'+03'\c
153 .\}
154 .el \{\
155 .sp -1
156 .IP \(bu 2.3
157 .\}
158 gnome\-terminal
159 .RE
160 .sp
161 .RS 4
162 .ie n \{\
163 \h'-04'\(bu\h'+03'\c
164 .\}
165 .el \{\
166 .sp -1
167 .IP \(bu 2.3
168 .\}
169 roxterm
170 .RE
171 .sp
172 .RS 4
173 .ie n \{\
174 \h'-04'\(bu\h'+03'\c
175 .\}
176 .el \{\
177 .sp -1
178 .IP \(bu 2.3
179 .\}
180 xfce4\-terminal
181 .RE
182 .sp
183 .RS 4
184 .ie n \{\
185 \h'-04'\(bu\h'+03'\c
186 .\}
187 .el \{\
188 .sp -1
189 .IP \(bu 2.3
190 .\}
191 termite
192 .RE
193 .sp
194 .RS 4
195 .ie n \{\
196 \h'-04'\(bu\h'+03'\c
197 .\}
198 .el \{\
199 .sp -1
200 .IP \(bu 2.3
201 .\}
202 lxterminal
203 .RE
204 .sp
205 .RS 4
206 .ie n \{\
207 \h'-04'\(bu\h'+03'\c
208 .\}
209 .el \{\
210 .sp -1
211 .IP \(bu 2.3
212 .\}
213 mate\-terminal
214 .RE
215 .sp
216 .RS 4
217 .ie n \{\
218 \h'-04'\(bu\h'+03'\c
219 .\}
220 .el \{\
221 .sp -1
222 .IP \(bu 2.3
223 .\}
224 terminology
225 .RE
226 .sp
227 .RS 4
228 .ie n \{\
229 \h'-04'\(bu\h'+03'\c
230 .\}
231 .el \{\
232 .sp -1
233 .IP \(bu 2.3
234 .\}
235 st
236 .RE
237 .sp
238 .RS 4
239 .ie n \{\
240 \h'-04'\(bu\h'+03'\c
241 .\}
242 .el \{\
243 .sp -1
244 .IP \(bu 2.3
245 .\}
246 qterminal
247 .RE
248 .sp
249 .RS 4
250 .ie n \{\
251 \h'-04'\(bu\h'+03'\c
252 .\}
253 .el \{\
254 .sp -1
255 .IP \(bu 2.3
256 .\}
257 lilyterm
258 .RE
259 .sp
260 .RS 4
261 .ie n \{\
262 \h'-04'\(bu\h'+03'\c
263 .\}
264 .el \{\
265 .sp -1
266 .IP \(bu 2.3
267 .\}
268 tilix
269 .RE
270 .sp
271 .RS 4
272 .ie n \{\
273 \h'-04'\(bu\h'+03'\c
274 .\}
275 .el \{\
276 .sp -1
277 .IP \(bu 2.3
278 .\}
279 terminix
280 .RE
281 .sp
282 .RS 4
283 .ie n \{\
284 \h'-04'\(bu\h'+03'\c
285 .\}
286 .el \{\
287 .sp -1
288 .IP \(bu 2.3
289 .\}
290 konsole
291 .RE
292 .sp
293 .RS 4
294 .ie n \{\
295 \h'-04'\(bu\h'+03'\c
296 .\}
297 .el \{\
298 .sp -1
299 .IP \(bu 2.3
300 .\}
301 kitty
302 .RE
303 .sp
304 .RS 4
305 .ie n \{\
306 \h'-04'\(bu\h'+03'\c
307 .\}
308 .el \{\
309 .sp -1
310 .IP \(bu 2.3
311 .\}
312 guake
313 .RE
314 .sp
315 .RS 4
316 .ie n \{\
317 \h'-04'\(bu\h'+03'\c
318 .\}
319 .el \{\
320 .sp -1
321 .IP \(bu 2.3
322 .\}
323 tilda
324 .RE
325 .sp
326 .RS 4
327 .ie n \{\
328 \h'-04'\(bu\h'+03'\c
329 .\}
330 .el \{\
331 .sp -1
332 .IP \(bu 2.3
333 .\}
334 alacritty
335 .RE
336 .sp
337 .RS 4
338 .ie n \{\
339 \h'-04'\(bu\h'+03'\c
340 .\}
341 .el \{\
342 .sp -1
343 .IP \(bu 2.3
344 .\}
345 hyper
346 .RE
347 .sp
348 Please don\(cqt complain about the order: If the user has any preference, they will have $TERMINAL set or modified their i3 configuration file\&.
349 .SH "SEE ALSO"
350 .sp
351 i3(1)
352 .SH "AUTHOR"
353 .sp
354 Michael Stapelberg and contributors
0 '\" t
1 .\" Title: i3
2 .\" Author: [see the "AUTHOR" section]
3 .\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
4 .\" Date: 08/30/2019
5 .\" Manual: i3 Manual
6 .\" Source: i3 4.17.1
7 .\" Language: English
8 .\"
9 .TH "I3" "1" "08/30/2019" "i3 4\&.17\&.1" "i3 Manual"
10 .\" -----------------------------------------------------------------
11 .\" * Define some portability stuff
12 .\" -----------------------------------------------------------------
13 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
14 .\" http://bugs.debian.org/507673
15 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
16 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
17 .ie \n(.g .ds Aq \(aq
18 .el .ds Aq '
19 .\" -----------------------------------------------------------------
20 .\" * set default formatting
21 .\" -----------------------------------------------------------------
22 .\" disable hyphenation
23 .nh
24 .\" disable justification (adjust text to left margin only)
25 .ad l
26 .\" -----------------------------------------------------------------
27 .\" * MAIN CONTENT STARTS HERE *
28 .\" -----------------------------------------------------------------
29 .SH "NAME"
30 i3 \- an improved dynamic, tiling window manager
31 .SH "SYNOPSIS"
32 .sp
33 i3 [\-a] [\-c configfile] [\-C] [\-d all] [\-v] [\-V]
34 .SH "OPTIONS"
35 .PP
36 \-a
37 .RS 4
38 Disables autostart\&.
39 .RE
40 .PP
41 \-c
42 .RS 4
43 Specifies an alternate configuration file path\&.
44 .RE
45 .PP
46 \-C
47 .RS 4
48 Check the configuration file for validity and exit\&.
49 .RE
50 .PP
51 \-d all
52 .RS 4
53 Enables debug logging\&. The
54 \fIall\fR
55 parameter is present for historical reasons\&.
56 .RE
57 .PP
58 \-v
59 .RS 4
60 Display version number (and date of the last commit)\&.
61 .RE
62 .PP
63 \-V
64 .RS 4
65 Be verbose\&.
66 .RE
67 .PP
68 \-\-force\-xinerama
69 .RS 4
70 Use Xinerama instead of RandR\&. This option should only be used if you are stuck with the old nVidia closed source driver (older than 302\&.17) which does not support RandR\&.
71 .RE
72 .PP
73 \-\-get\-socketpath
74 .RS 4
75 Retrieve the i3 IPC socket path from X11, print it, then exit\&.
76 .RE
77 .PP
78 \-\-shmlog\-size <limit>
79 .RS 4
80 Limits the size of the i3 SHM log to <limit> bytes\&. Setting this to 0 disables SHM logging entirely\&. The default is 0 bytes\&.
81 .RE
82 .SH "DESCRIPTION"
83 .SS "INTRODUCTION"
84 .sp
85 i3 was created because wmii, our favorite window manager at the time, didn\(cqt provide some features we wanted (multi\-monitor done right, for example), had some bugs, didn\(cqt progress since quite some time and wasn\(cqt easy to hack at all (source code comments/documentation completely lacking)\&. Still, we think the wmii developers and contributors did a great job\&. Thank you for inspiring us to create i3\&.
86 .sp
87 Please be aware that i3 is primarily targeted at advanced users and developers\&.
88 .SS "IMPORTANT NOTE TO nVidia BINARY DRIVER USERS"
89 .sp
90 If you are using the nVidia binary graphics driver (also known as \fIblob\fR) before version 302\&.17, you need to use the \-\-force\-xinerama flag (in your ~/\&.xsession) when starting i3, like so:
91 .sp
92 .if n \{\
93 .RS 4
94 .\}
95 .nf
96 exec i3 \-\-force\-xinerama \-V >>~/\&.i3/i3log 2>&1
97 .fi
98 .if n \{\
99 .RE
100 .\}
101 .sp
102 See also docs/multi\-monitor for the full explanation\&.
103 .SS "TERMINOLOGY"
104 .PP
105 Tree
106 .RS 4
107 i3 keeps your layout in a tree data structure\&.
108 .RE
109 .PP
110 Window
111 .RS 4
112 An X11 window, like the Firefox browser window or a terminal emulator\&.
113 .RE
114 .PP
115 Floating Window
116 .RS 4
117 A window which "floats" on top of other windows\&. This style is used by i3 to display X11 windows with type "dialog", such as the "Print" or "Open File" dialog boxes in many GUI applications\&. Use of floating windows can be fine\-tuned with the for_window command (see HTML userguide)\&.
118 .RE
119 .PP
120 Split container
121 .RS 4
122 A split container contains multiple other split containers or windows\&.
123 .sp
124 Containers can be used in various layouts\&. The default mode is called "default" and just resizes each client equally so that it fits\&.
125 .RE
126 .PP
127 Workspace
128 .RS 4
129 A workspace is a set of containers\&. Other window managers call this "Virtual Desktops"\&.
130 .sp
131 In i3, each workspace is assigned to a specific virtual screen\&. By default, screen 1 has workspace 1, screen 2 has workspace 2 and so on\&... However, when you create a new workspace (by simply switching to it), it\(cqll be assigned the screen you are currently on\&.
132 .RE
133 .PP
134 Output
135 .RS 4
136 Using XRandR, you can have an X11 screen spanning multiple real monitors\&. Furthermore, you can set them up in cloning mode or with positions (monitor 1 is left of monitor 2)\&.
137 .sp
138 i3 uses the RandR API to query which outputs are available and which screens are connected to these outputs\&.
139 .RE
140 .SH "KEYBINDINGS"
141 .sp
142 Here is a short overview of the default keybindings:
143 .PP
144 Mod1+Enter
145 .RS 4
146 Open a new terminal emulator window\&.
147 .RE
148 .PP
149 Mod1+d
150 .RS 4
151 Open dmenu for starting any application by typing (part of) its name\&.
152 .RE
153 .PP
154 j/k/l/;
155 .RS 4
156 Direction keys (left, down, up, right)\&. They are on your homerow (see the mark on your "j" key)\&. Alternatively, you can use the cursor keys\&.
157 .RE
158 .PP
159 Mod1+<direction>
160 .RS 4
161 Focus window in <direction>\&.
162 .RE
163 .PP
164 Mod1+Shift+<direction>
165 .RS 4
166 Move window to <direction>\&.
167 .RE
168 .PP
169 Mod1+<number>
170 .RS 4
171 Switch to workspace <number>\&.
172 .RE
173 .PP
174 Mod1+Shift+<number>
175 .RS 4
176 Move window to workspace <number>\&.
177 .RE
178 .PP
179 Mod1+f
180 .RS 4
181 Toggle fullscreen mode\&.
182 .RE
183 .PP
184 Mod1+s
185 .RS 4
186 Enable stacking layout for the current container\&.
187 .RE
188 .PP
189 Mod1+e
190 .RS 4
191 Enable default layout for the current container\&.
192 .RE
193 .PP
194 Mod1+w
195 .RS 4
196 Enable tabbed layout for the current container\&.
197 .RE
198 .PP
199 Mod1+Shift+Space
200 .RS 4
201 Toggle tiling/floating for the current container\&.
202 .RE
203 .PP
204 Mod1+Space
205 .RS 4
206 Select the first tiling container if the current container is floating and vice\-versa\&.
207 .RE
208 .PP
209 Mod1+Shift+q
210 .RS 4
211 Kills the current window\&. This is equivalent to "clicking on the close button", meaning a polite request to the application to close this window\&. For example, Firefox will save its session upon such a request\&. If the application does not support that, the window will be killed and it depends on the application what happens\&.
212 .RE
213 .PP
214 Mod1+Shift+r
215 .RS 4
216 Restarts i3 in place\&. Your layout will be preserved\&.
217 .RE
218 .PP
219 Mod1+Shift+e
220 .RS 4
221 Exits i3\&.
222 .RE
223 .SH "FILES"
224 .SS "~/\&.config/i3/config (or ~/\&.i3/config)"
225 .sp
226 When starting, i3 looks for configuration files in the following order:
227 .sp
228 .RS 4
229 .ie n \{\
230 \h'-04' 1.\h'+01'\c
231 .\}
232 .el \{\
233 .sp -1
234 .IP " 1." 4.2
235 .\}
236 ~/\&.config/i3/config (or $XDG_CONFIG_HOME/i3/config if set)
237 .RE
238 .sp
239 .RS 4
240 .ie n \{\
241 \h'-04' 2.\h'+01'\c
242 .\}
243 .el \{\
244 .sp -1
245 .IP " 2." 4.2
246 .\}
247 ~/\&.i3/config
248 .RE
249 .sp
250 .RS 4
251 .ie n \{\
252 \h'-04' 3.\h'+01'\c
253 .\}
254 .el \{\
255 .sp -1
256 .IP " 3." 4.2
257 .\}
258 /etc/xdg/i3/config (or $XDG_CONFIG_DIRS/i3/config if set)
259 .RE
260 .sp
261 .RS 4
262 .ie n \{\
263 \h'-04' 4.\h'+01'\c
264 .\}
265 .el \{\
266 .sp -1
267 .IP " 4." 4.2
268 .\}
269 /etc/i3/config
270 .RE
271 .sp
272 You can specify a custom path using the \-c option\&.
273 .PP
274 \fBSample configuration\fR.
275 .sp
276 .if n \{\
277 .RS 4
278 .\}
279 .nf
280 # i3 config file (v4)
281
282 # Font for window titles\&. Will also be used by the bar unless a different font
283 # is used in the bar {} block below\&.
284 # This font is widely installed, provides lots of unicode glyphs, right\-to\-left
285 # text rendering and scalability on retina/hidpi displays (thanks to pango)\&.
286 font pango:DejaVu Sans Mono 8
287 # Before i3 v4\&.8, we used to recommend this one as the default:
288 # font \-misc\-fixed\-medium\-r\-normal\-\-13\-120\-75\-75\-C\-70\-iso10646\-1
289 # The font above is very space\-efficient, that is, it looks good, sharp and
290 # clear in small sizes\&. However, its unicode glyph coverage is limited, the old
291 # X core fonts rendering does not support right\-to\-left and this being a bitmap
292 # font, it doesn\(cqt scale on retina/hidpi displays\&.
293
294 # use Mouse+Mod1 to drag floating windows to their wanted position
295 floating_modifier Mod1
296
297 # start a terminal
298 bindsym Mod1+Return exec /usr/bin/urxvt
299
300 # kill focused window
301 bindsym Mod1+Shift+q kill
302
303 # start dmenu (a program launcher)
304 bindsym Mod1+d exec /usr/bin/dmenu_run
305
306 # change focus
307 bindsym Mod1+j focus left
308 bindsym Mod1+k focus down
309 bindsym Mod1+l focus up
310 bindsym Mod1+semicolon focus right
311
312 # alternatively, you can use the cursor keys:
313 bindsym Mod1+Left focus left
314 bindsym Mod1+Down focus down
315 bindsym Mod1+Up focus up
316 bindsym Mod1+Right focus right
317
318 # move focused window
319 bindsym Mod1+Shift+j move left
320 bindsym Mod1+Shift+k move down
321 bindsym Mod1+Shift+l move up
322 bindsym Mod1+Shift+semicolon move right
323
324 # alternatively, you can use the cursor keys:
325 bindsym Mod1+Shift+Left move left
326 bindsym Mod1+Shift+Down move down
327 bindsym Mod1+Shift+Up move up
328 bindsym Mod1+Shift+Right move right
329
330 # split in horizontal orientation
331 bindsym Mod1+h split h
332
333 # split in vertical orientation
334 bindsym Mod1+v split v
335
336 # enter fullscreen mode for the focused container
337 bindsym Mod1+f fullscreen toggle
338
339 # change container layout (stacked, tabbed, default)
340 bindsym Mod1+s layout stacking
341 bindsym Mod1+w layout tabbed
342 bindsym Mod1+e layout default
343
344 # toggle tiling / floating
345 bindsym Mod1+Shift+space floating toggle
346
347 # change focus between tiling / floating windows
348 bindsym Mod1+space focus mode_toggle
349
350 # focus the parent container
351 bindsym Mod1+a focus parent
352
353 # focus the child container
354 #bindsym Mod1+d focus child
355
356 # switch to workspace
357 bindsym Mod1+1 workspace 1
358 bindsym Mod1+2 workspace 2
359 # \&.\&.
360
361 # move focused container to workspace
362 bindsym Mod1+Shift+1 move workspace 1
363 bindsym Mod1+Shift+2 move workspace 2
364 # \&.\&.\&.
365
366 # reload the configuration file
367 bindsym Mod1+Shift+c reload
368 # restart i3 inplace (preserves your layout/session, can be used to upgrade i3)
369 bindsym Mod1+Shift+r restart
370 # exit i3 (logs you out of your X session)
371 bindsym Mod1+Shift+e exit
372
373 # display workspace buttons plus a statusline generated by i3status
374 bar {
375 status_command i3status
376 }
377 .fi
378 .if n \{\
379 .RE
380 .\}
381 .sp
382 .SS "~/\&.xsession"
383 .sp
384 This file is where you should configure your locales and start i3\&. It is run by your login manager (xdm, slim, gdm, \&...) as soon as you login\&.
385 .PP
386 \fBSample xsession\fR.
387 .sp
388 .if n \{\
389 .RS 4
390 .\}
391 .nf
392 # Disable DPMS turning off the screen
393 xset \-dpms
394 xset s off
395
396 # Disable bell
397 xset \-b
398
399 # Enable zapping (C\-A\-<Bksp> kills X)
400 setxkbmap \-option terminate:ctrl_alt_bksp
401
402 # Enforce correct locales from the beginning:
403 # LC_ALL is unset since it overwrites everything
404 # LANG=de_DE\&.UTF\-8 is used, except for:
405 # LC_MESSAGES=C never translates program output
406 # LC_TIME=en_DK leads to yyyy\-mm\-dd hh:mm date/time output
407 unset LC_ALL
408 export LANG=de_DE\&.UTF\-8
409 export LC_MESSAGES=C
410 export LC_TIME=en_DK\&.UTF\-8
411
412 # Use XToolkit in java applications
413 export AWT_TOOLKIT=XToolkit
414
415 # Set background color
416 xsetroot \-solid "#333333"
417
418 # Enable core dumps in case something goes wrong
419 ulimit \-c unlimited
420
421 # Start i3 and log to ~/\&.i3/logfile
422 echo "Starting at $(date)" >> ~/\&.i3/logfile
423 exec /usr/bin/i3 \-V \-d all >> ~/\&.i3/logfile
424 .fi
425 .if n \{\
426 .RE
427 .\}
428 .sp
429 .SH "ENVIRONMENT"
430 .SS "I3SOCK"
431 .sp
432 This variable overwrites the IPC socket path (placed in /tmp/i3\-%u\&.XXXXXX/ipc\-socket\&.%p by default, where %u is replaced with your UNIX username, %p is replaced with i3\(cqs PID and XXXXXX is a string of random characters from the portable filename character set (see mkdtemp(3)))\&. The IPC socket is used by external programs like i3\-msg(1) or i3bar(1)\&.
433 .SH "TODO"
434 .sp
435 There is still lot of work to do\&. Please check our bugtracker for up\-to\-date information about tasks which are still not finished\&.
436 .SH "SEE ALSO"
437 .sp
438 You should have a copy of the userguide (featuring nice screenshots/graphics which is why this is not integrated into this manpage), the debugging guide, and the "how to hack" guide\&. If you are building from source, run: make \-C docs
439 .sp
440 You can also access these documents online at \m[blue]\fBhttps://i3wm\&.org/\fR\m[]
441 .sp
442 i3\-input(1), i3\-msg(1), i3bar(1), i3\-nagbar(1), i3\-config\-wizard(1), i3\-migrate\-config\-to\-v4(1)
443 .SH "AUTHOR"
444 .sp
445 Michael Stapelberg and contributors
0 '\" t
1 .\" Title: i3bar
2 .\" Author: [see the "AUTHORS" section]
3 .\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
4 .\" Date: 08/30/2019
5 .\" Manual: i3 Manual
6 .\" Source: i3 4.17.1
7 .\" Language: English
8 .\"
9 .TH "I3BAR" "1" "08/30/2019" "i3 4\&.17\&.1" "i3 Manual"
10 .\" -----------------------------------------------------------------
11 .\" * Define some portability stuff
12 .\" -----------------------------------------------------------------
13 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
14 .\" http://bugs.debian.org/507673
15 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
16 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
17 .ie \n(.g .ds Aq \(aq
18 .el .ds Aq '
19 .\" -----------------------------------------------------------------
20 .\" * set default formatting
21 .\" -----------------------------------------------------------------
22 .\" disable hyphenation
23 .nh
24 .\" disable justification (adjust text to left margin only)
25 .ad l
26 .\" -----------------------------------------------------------------
27 .\" * MAIN CONTENT STARTS HERE *
28 .\" -----------------------------------------------------------------
29 .SH "NAME"
30 i3bar \- xcb\-based status\- and workspace\-bar
31 .SH "SYNOPSIS"
32 .sp
33 \fBi3bar\fR [\fB\-s\fR \fIsock_path\fR] [\fB\-b\fR \fIbar_id\fR] [\fB\-v\fR] [\fB\-h\fR]
34 .SH "WARNING"
35 .sp
36 i3bar will automatically be invoked by i3 for every \fIbar\fR configuration block\&.
37 .sp
38 Starting it manually is usually not what you want to do\&.
39 .sp
40 You have been warned!
41 .SH "OPTIONS"
42 .PP
43 \fB\-s, \-\-socket\fR \fIsock_path\fR
44 .RS 4
45 Overwrites the path to the i3 IPC socket\&.
46 .RE
47 .PP
48 \fB\-b, \-\-bar_id\fR \fIbar_id\fR
49 .RS 4
50 Specifies the bar ID for which to get the configuration from i3\&.
51 .RE
52 .PP
53 \fB\-v, \-\-version\fR
54 .RS 4
55 Display version number and exit\&.
56 .RE
57 .PP
58 \fB\-h, \-\-help\fR
59 .RS 4
60 Display a short help\-message and exit
61 .RE
62 .SH "DESCRIPTION"
63 .sp
64 \fBi3bar\fR displays a bar at the bottom (or top) of your monitor(s) containing workspace switching buttons and a statusline generated by i3status(1) or similar\&. It is automatically invoked (and configured through) i3\&.
65 .sp
66 i3bar supports colors via a JSON protocol starting from v4\&.2, see \m[blue]\fBhttps://i3wm\&.org/docs/i3bar\-protocol\&.html\fR\m[]
67 .SH "ENVIRONMENT"
68 .SS "I3SOCK"
69 .sp
70 Used as a fallback for the i3 IPC socket path if neither the commandline contains an argument nor the I3_SOCKET_PATH property is set on the X11 root window\&.
71 .SH "EXAMPLES"
72 .sp
73 Nothing to see here, move along\&. As stated above, you should not run i3bar manually\&.
74 .sp
75 Instead, see the i3 documentation, especially the User\(cqs Guide\&.
76 .SH "SEE ALSO"
77 .sp
78 i3status(1), j4status(1) or conky(1) for programs generating a statusline\&.
79 .sp
80 dzen2(1) or xmobar(1) for similar programs to i3bar\&.
81 .SH "AUTHORS"
82 .sp
83 Axel Wagner and contributors