From 4869d2e78b4393aa6800a950e5a9bd3663e4cba0 Mon Sep 17 00:00:00 2001 From: Sander De la Marche Date: Tue, 22 Dec 2020 18:51:17 +0100 Subject: [PATCH 1/6] Rename all source doc files in _docs so they have the .adoc extension. This is required for AsciiDoctor to pick them up as AsciiDoc files. --- _docs/{debugging => .adoc} | 0 _docs/Makefile | 55 ---- _docs/{buildbot => buildbot.adoc} | 0 ...version => debugging-release-version.adoc} | 0 _docs/{gsoc2013-ideas => gsoc2013-ideas.adoc} | 0 _docs/{hacking-howto => hacking-howto.adoc} | 0 ...onfig-wizard.man => i3-config-wizard.adoc} | 0 _docs/{i3-input.man => i3-input.adoc} | 2 +- ...to-v4.man => i3-migrate-config-to-v4.adoc} | 0 _docs/{i3-msg.man => i3-msg.adoc} | 0 _docs/{i3-nagbar.man => i3-nagbar.adoc} | 0 _docs/{i3.man => i3.adoc} | 0 _docs/{i3bar-protocol => i3bar-protocol.adoc} | 0 _docs/{i3status.man => i3status.adoc} | 0 _docs/{ipc => ipc.adoc} | 0 _docs/{layout-saving => layout-saving.adoc} | 0 _docs/{multi-monitor => multi-monitor.adoc} | 0 _docs/refcard.html | 306 ------------------ _docs/{repositories => repositories.adoc} | 0 _docs/{testsuite => testsuite.adoc} | 10 +- _docs/{tshirts => tshirts.adoc} | 0 _docs/{userguide => userguide.adoc} | 16 +- _docs/{wsbar => wsbar.adoc} | 0 23 files changed, 14 insertions(+), 375 deletions(-) rename _docs/{debugging => .adoc} (100%) delete mode 100644 _docs/Makefile rename _docs/{buildbot => buildbot.adoc} (100%) rename _docs/{debugging-release-version => debugging-release-version.adoc} (100%) rename _docs/{gsoc2013-ideas => gsoc2013-ideas.adoc} (100%) rename _docs/{hacking-howto => hacking-howto.adoc} (100%) rename _docs/{i3-config-wizard.man => i3-config-wizard.adoc} (100%) rename _docs/{i3-input.man => i3-input.adoc} (99%) rename _docs/{i3-migrate-config-to-v4.man => i3-migrate-config-to-v4.adoc} (100%) rename _docs/{i3-msg.man => i3-msg.adoc} (100%) rename _docs/{i3-nagbar.man => i3-nagbar.adoc} (100%) rename _docs/{i3.man => i3.adoc} (100%) rename _docs/{i3bar-protocol => i3bar-protocol.adoc} (100%) rename _docs/{i3status.man => i3status.adoc} (100%) rename _docs/{ipc => ipc.adoc} (100%) rename _docs/{layout-saving => layout-saving.adoc} (100%) rename _docs/{multi-monitor => multi-monitor.adoc} (100%) delete mode 100644 _docs/refcard.html rename _docs/{repositories => repositories.adoc} (100%) rename _docs/{testsuite => testsuite.adoc} (99%) rename _docs/{tshirts => tshirts.adoc} (100%) rename _docs/{userguide => userguide.adoc} (99%) rename _docs/{wsbar => wsbar.adoc} (100%) diff --git a/_docs/debugging b/_docs/.adoc similarity index 100% rename from _docs/debugging rename to _docs/.adoc diff --git a/_docs/Makefile b/_docs/Makefile deleted file mode 100644 index bb1fa89..0000000 --- a/_docs/Makefile +++ /dev/null @@ -1,55 +0,0 @@ - -all: hacking-howto.html debugging.html debugging-release-version.html i3bar-protocol.html repositories.html buildbot.html userguide.html ipc.html multi-monitor.html wsbar.html i3status.html i3.html i3-config-wizard.html i3-nagbar.html i3-migrate-config-to-v4.html i3-msg.html testsuite.html gsoc2013-ideas.html tshirts.html layout-saving.html - -gsoc2013-ideas.html: gsoc2013-ideas - asciidoc -a linkcss -a stylesdir=/css -a scriptsdir=/js --backend=xhtml11 -f conf/i3html.conf -a toc -n $< - -hacking-howto.html: hacking-howto - asciidoc -a linkcss -a stylesdir=/css -a scriptsdir=/js --backend=xhtml11 -f conf/i3html.conf -a toc -n $< - -testsuite.html: testsuite - asciidoc -a linkcss -a stylesdir=/css -a scriptsdir=/js --backend=xhtml11 -f conf/i3html.conf -a toc -n $< - -debugging.html: debugging - asciidoc -a linkcss -a stylesdir=/css -a scriptsdir=/js --backend=xhtml11 -f conf/i3html.conf -n $< - -debugging-release-version.html: debugging-release-version - asciidoc -a linkcss -a stylesdir=/css -a scriptsdir=/js --backend=xhtml11 -f conf/i3html.conf -n $< - -i3bar-protocol.html: i3bar-protocol - asciidoc -a linkcss -a stylesdir=/css -a scriptsdir=/js --backend=xhtml11 -f conf/i3html.conf -n $< - -repositories.html: repositories - asciidoc -a linkcss -a stylesdir=/css -a scriptsdir=/js --backend=xhtml11 -f conf/i3html.conf -n $< - -buildbot.html: buildbot - asciidoc -a linkcss -a stylesdir=/css -a scriptsdir=/js --backend=xhtml11 -f conf/i3html.conf -a toc -n $< - -userguide.html: userguide - asciidoc -a linkcss -a stylesdir=/css -a scriptsdir=/js --backend=xhtml11 -f conf/i3html.conf -a toc -n $< - -ipc.html: ipc - asciidoc -a linkcss -a stylesdir=/css -a scriptsdir=/js --backend=xhtml11 -f conf/i3html.conf -a toc -n $< - -multi-monitor.html: multi-monitor - asciidoc -a linkcss -a stylesdir=/css -a scriptsdir=/js --backend=xhtml11 -f conf/i3html.conf -a toc -n $< - -layout-saving.html: layout-saving - asciidoc -a linkcss -a stylesdir=/css -a scriptsdir=/js --backend=xhtml11 -f conf/i3html.conf -a toc -n $< - -wsbar.html: wsbar - asciidoc -a linkcss -a stylesdir=/css -a scriptsdir=/js --backend=xhtml11 -f conf/i3html.conf -a toc -n $< - -tshirts.html: tshirts - asciidoc -a linkcss -a stylesdir=/css -a scriptsdir=/js --backend=xhtml11 -f conf/i3html.conf -a toc -n $< - -i3status.html: i3status.man - asciidoc -a linkcss -a stylesdir=/css -a scriptsdir=/js --backend=xhtml11 -f conf/i3html.conf -a toc -n $< - -%.html: %.man - asciidoc -a linkcss -a stylesdir=/css -a scriptsdir=/js --backend=xhtml11 -f conf/i3html.conf -a toc -n $< - -clean: - rm -f */*.{aux,log,toc,bm,pdf,dvi} - rm -f *.log - find . -maxdepth 1 -name "*.html" -and \! -name "refcard.html" -delete diff --git a/_docs/buildbot b/_docs/buildbot.adoc similarity index 100% rename from _docs/buildbot rename to _docs/buildbot.adoc diff --git a/_docs/debugging-release-version b/_docs/debugging-release-version.adoc similarity index 100% rename from _docs/debugging-release-version rename to _docs/debugging-release-version.adoc diff --git a/_docs/gsoc2013-ideas b/_docs/gsoc2013-ideas.adoc similarity index 100% rename from _docs/gsoc2013-ideas rename to _docs/gsoc2013-ideas.adoc diff --git a/_docs/hacking-howto b/_docs/hacking-howto.adoc similarity index 100% rename from _docs/hacking-howto rename to _docs/hacking-howto.adoc diff --git a/_docs/i3-config-wizard.man b/_docs/i3-config-wizard.adoc similarity index 100% rename from _docs/i3-config-wizard.man rename to _docs/i3-config-wizard.adoc diff --git a/_docs/i3-input.man b/_docs/i3-input.adoc similarity index 99% rename from _docs/i3-input.man rename to _docs/i3-input.adoc index df7c4d9..93da9cc 100644 --- a/_docs/i3-input.man +++ b/_docs/i3-input.adoc @@ -1,5 +1,5 @@ i3-input(1) -========= +=========== Michael Stapelberg v4.1, September 2011 diff --git a/_docs/i3-migrate-config-to-v4.man b/_docs/i3-migrate-config-to-v4.adoc similarity index 100% rename from _docs/i3-migrate-config-to-v4.man rename to _docs/i3-migrate-config-to-v4.adoc diff --git a/_docs/i3-msg.man b/_docs/i3-msg.adoc similarity index 100% rename from _docs/i3-msg.man rename to _docs/i3-msg.adoc diff --git a/_docs/i3-nagbar.man b/_docs/i3-nagbar.adoc similarity index 100% rename from _docs/i3-nagbar.man rename to _docs/i3-nagbar.adoc diff --git a/_docs/i3.man b/_docs/i3.adoc similarity index 100% rename from _docs/i3.man rename to _docs/i3.adoc diff --git a/_docs/i3bar-protocol b/_docs/i3bar-protocol.adoc similarity index 100% rename from _docs/i3bar-protocol rename to _docs/i3bar-protocol.adoc diff --git a/_docs/i3status.man b/_docs/i3status.adoc similarity index 100% rename from _docs/i3status.man rename to _docs/i3status.adoc diff --git a/_docs/ipc b/_docs/ipc.adoc similarity index 100% rename from _docs/ipc rename to _docs/ipc.adoc diff --git a/_docs/layout-saving b/_docs/layout-saving.adoc similarity index 100% rename from _docs/layout-saving rename to _docs/layout-saving.adoc diff --git a/_docs/multi-monitor b/_docs/multi-monitor.adoc similarity index 100% rename from _docs/multi-monitor rename to _docs/multi-monitor.adoc diff --git a/_docs/refcard.html b/_docs/refcard.html deleted file mode 100644 index d8bd286..0000000 --- a/_docs/refcard.html +++ /dev/null @@ -1,306 +0,0 @@ - - - - - i3 - Reference Card - - - - - - -
-
- -
-

i3 Reference Card

- http://i3wm.org/docs/userguide.html -

Throughout this guide, the i3 logo will be used to refer to the configured modifier. This is the Alt key (Mod1) by default, with (Mod4) being a popular alternative.

-
-
- -
-

Basics

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ Enteropen new terminal
+ jfocus left
+ kfocus down
+ lfocus up
+ ;focus right
+ afocus parent
+ Spacetoggle focus mode
-
- -
-

Moving windows

- - - - - - - - - - - - - - - - - -
+ Shift + jmove window left
+ Shift + kmove window down
+ Shift + lmove window up
+ Shift + ;move window right
-
-
- -
-
-

Modifying windows

- - - - - - - - - - - - - - - - - -
+ ftoggle fullscreen
+ vsplit a window vertically
+ hsplit a window horizontally
+ rresize mode
-

Look at the “Resizing containers / windows” section of the user guide.

-
- -
-

Changing the container layout

- - - - - - - - - - - - - -
+ edefault
+ sstacking
+ wtabbed
-
- -
-

Floating

- - - - - - - - - -
+ Shift + Spacetoggle floating
+ Left clickdrag floating
-
- -
-

Using workspaces

- - - - - - - - - -
+ 0-9switch to another workspace
+ Shift + 0-9move a window to another workspace
-
-
- -
-
-

Opening applications / Closing windows

- - - - - - - - - -
+ dopen application launcher (dmenu)
+ Shift + qkill a window
-
- -
-

Restart / Exit

- - - - - - - - - - - - - -
+ Shift + creload the configuration file
+ Shift + rrestart i3 inplace
+ Shift + eexit i3
-
- -
-

- Copyright © 2012, Michael Stapelberg -
- All rights reserved -
- Designed by Zeus Panchenko, updated by Moritz Bandemer, updated by Sander De la Marche -

-

- Permission is granted to copy, distribute and/or modify this document provided - the copyright notice and this permission notice are preserved on all copies. -

-
-
- - diff --git a/_docs/repositories b/_docs/repositories.adoc similarity index 100% rename from _docs/repositories rename to _docs/repositories.adoc diff --git a/_docs/testsuite b/_docs/testsuite.adoc similarity index 99% rename from _docs/testsuite rename to _docs/testsuite.adoc index 145da15..11e2dc6 100644 --- a/_docs/testsuite +++ b/_docs/testsuite.adoc @@ -162,7 +162,7 @@ Files=1, Tests=14, 0 wallclock secs ( 0.01 usr 0.00 sys + 0.19 cusr 0.03 csy Result: PASS $ less latest/i3-log-for-04-floating.t ----------------------------------------- +--------------------------------------- If your attempt to run the tests with a bare call to ./complete-run.pl fails, try this: @@ -204,7 +204,7 @@ Testsuite summary for i3 4.13 ============================================================================ $ less test-suite.log ----------------------------------------- +--------------------------------------- ==== Coverage testing @@ -287,7 +287,7 @@ use i3test; use File::Temp; my $x = X11::XCB::Connection->new; ------------------------ +---------------------- This is what we call boilerplate. It exists at the top of every test file (to some extent). The first line is the shebang, which specifies that this file is @@ -435,7 +435,7 @@ to be working. .t/11-goto.t: Test corner case ---------------------- -# check that we can specify multiple criteria +check that we can specify multiple criteria $focus = focus_after('focus left'); is($focus, $top->id, "Top window focused"); @@ -489,7 +489,7 @@ properly. Sounds simple, right? Let’s assume you use this straight-forward implementation: .Racey focus testcase ------------ +---------- my $left = open_window($x); my $right = open_window($x); cmd 'focus left'; diff --git a/_docs/tshirts b/_docs/tshirts.adoc similarity index 100% rename from _docs/tshirts rename to _docs/tshirts.adoc diff --git a/_docs/userguide b/_docs/userguide.adoc similarity index 99% rename from _docs/userguide rename to _docs/userguide.adoc index bc4afb3..a0964c0 100644 --- a/_docs/userguide +++ b/_docs/userguide.adoc @@ -1498,7 +1498,7 @@ output primary|nonprimary| *Example*: ------------------------------- -# big monitor: everything +big monitor: everything bar { # The display is connected either via HDMI or via DisplayPort output HDMI2 @@ -1506,7 +1506,7 @@ bar { status_command i3status } -# laptop monitor: bright colors and i3status with less modules. +laptop monitor: bright colors and i3status with less modules. bar { output LVDS1 status_command i3status --config ~/.i3status-small.conf @@ -1516,7 +1516,7 @@ bar { } } -# show bar on the primary monitor and on HDMI2 +show bar on the primary monitor and on HDMI2 bar { output primary output HDMI2 @@ -1549,17 +1549,17 @@ tray_output none|primary| *Example*: ------------------------- -# disable system tray +disable system tray bar { tray_output none } -# show tray icons on the primary monitor +show tray icons on the primary monitor bar { tray_output primary } -# show tray icons on the big monitor +show tray icons on the big monitor bar { tray_output HDMI2 } @@ -1588,7 +1588,7 @@ tray_padding [px] *Example*: ------------------------- -# Obey Fitts's law +Obey Fitts's law tray_padding 0 ------------------------- @@ -2821,7 +2821,7 @@ LVDS1 connected 1280x800+0+0 (normal left inverted right x axis y axis) 261mm x 720x400 85.0 640x400 85.1 640x350 85.1 --------------------------------------------------------------------------------------- +------------------------------------------------------------------------------- Several things are important here: You can see that +LVDS1+ is connected (of course, it is the internal flat panel) but +VGA1+ is not. If you have a monitor diff --git a/_docs/wsbar b/_docs/wsbar.adoc similarity index 100% rename from _docs/wsbar rename to _docs/wsbar.adoc From 4893bb3c088c5e9fedf940d5ae9a0472ade10cdb Mon Sep 17 00:00:00 2001 From: Sander De la Marche Date: Tue, 22 Dec 2020 18:52:14 +0100 Subject: [PATCH 2/6] Replace the old xhtml stylesheet with a new docs.css --- css/docs.css | 91 +++++++++++ css/xhtml11.css | 402 ------------------------------------------------ 2 files changed, 91 insertions(+), 402 deletions(-) create mode 100644 css/docs.css delete mode 100644 css/xhtml11.css diff --git a/css/docs.css b/css/docs.css new file mode 100644 index 0000000..1355ba8 --- /dev/null +++ b/css/docs.css @@ -0,0 +1,91 @@ +/* Reset */ + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +/* Basics */ + +body { + background-color: #2e2e2e; + color: #ddd; + font-family: "Droid Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + font-size: 1.15em; + line-height: 1.5; + overflow-y: auto; + max-width: 60rem; + margin: 0 auto; +} + +img { + max-width: 100% +} + +a { + color: #52C0FF; +} + +a:hover { + text-decoration: none; +} + +/* Typo */ + +h1, h2, h3, h4, h5, h6 { + color: #fff; + font-family: "Mako", Helvetica, Arial, sans-serif; + line-height: 1.2; + margin-top: 1.2rem; + margin-bottom: .5rem; +} + +#toc { + position: fixed; + width: 20vw; + top: 0; + left: 0; + border-right: 1px solid #ebebeb; + border-bottom: 0; + padding: 1rem; + height: 100vh; + overflow-y: scroll; +} + +body.toc2 { + padding-left: 20rem; +} + +#content > * + * { + margin-top: 1.5rem; +} + +p { + margin-top: .5rem; + margin-bottom: .5rem; +} + +ul ul { + margin-left: 1.5rem; +} + +ul li { + list-style: none; +} + +div.listingblock > div.content { + border-left: 5px solid #52C0FF; + background: #242424; + padding: .5rem 1rem; +} + +code { + background-color: #242424; + border-radius: 3px; + color: #fff; + border: 1px solid #111; + display: inline-block; + line-height: 1; + padding: .25rem .5rem; +} \ No newline at end of file diff --git a/css/xhtml11.css b/css/xhtml11.css deleted file mode 100644 index f80b163..0000000 --- a/css/xhtml11.css +++ /dev/null @@ -1,402 +0,0 @@ -a { - color: #3ec2ff; - text-decoration: underline; -} - -em { - font-style: italic; - color: #3ec2ff; -} - -strong { - font-weight: bold; - color: #3ec2ff; -} - -tt { - font-family: 'Droid Sans Mono', sans-serif; - font-size: inherit; - color: #3ec2ff; -} - -div.listingblock tt { - color: #fff; -} - -h1, h2, h3, h4, h5, h6 { - margin-top: 1.2em; - margin-bottom: 0.5em; - text-align: left; -} - -h2 { - padding-top: 0.5em; -} -h3 { - float: left; -} -h3 + * { - clear: left; -} - -div.sectionbody { - margin-left: 0; -} - -hr { - border: 1px solid silver; -} - -p { - margin-top: 0.5em; - margin-bottom: 0.5em; -} - -ul, ol, li > p { - margin-top: 0; -} -/*ul > li { color: #aaa; }*/ -/*ul > li > * { color: black; }*/ - -pre { - padding: 0; - margin: 0; -} - -span#author { - font-weight: bold; - font-size: 1.1em; -} -span#email { -} -span#revnumber, span#revdate, span#revremark { -} - -div#footer { - font-size: small; - border-top: 2px solid silver; - padding-top: 0.5em; - margin-top: 4.0em; -} -div#footer-text { - padding-bottom: 0.5em; -} -div#footer-badges { - float: right; - padding-bottom: 0.5em; -} - -div#preamble { - margin-top: 1.5em; - margin-bottom: 1.5em; -} -div.tableblock, div.imageblock, div.exampleblock, div.verseblock, -div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock, -div.admonitionblock { - margin-top: 1.0em; - margin-bottom: 1.5em; -} -div.admonitionblock { - margin-top: 2.0em; - margin-bottom: 2.0em; - margin-right: 10%; - color: #606060; -} - -div.content { /* Block element content. */ - padding: 0; -} - -/* Block element titles. */ -div.title, caption.title { - font-weight: bold; - text-align: left; - margin-top: 1.0em; - margin-bottom: 0.5em; -} -div.title + * { - margin-top: 0; -} - -td div.title:first-child { - margin-top: 0.0em; -} -div.content div.title:first-child { - margin-top: 0.0em; -} -div.content + div.title { - margin-top: 0.0em; -} - -div.sidebarblock > div.content { - border: 1px solid #dddddd; - border-left: 4px solid #f0f0f0; - padding: 0.5em; -} - -div.listingblock > div.content { - border: 1px solid #555; - border-left: 5px solid #555; - background: #333; - padding: 0.5em; - padding-right: 0em; -} - -div.quoteblock, div.verseblock { - padding-left: 1.0em; - margin-left: 1.0em; - margin-right: 10%; - border-left: 5px solid #f0f0f0; - color: #777777; -} - -div.quoteblock > div.attribution { - padding-top: 0.5em; - text-align: right; -} - -div.verseblock > pre.content { - font-family: inherit; - font-size: inherit; -} -div.verseblock > div.attribution { - padding-top: 0.75em; - text-align: left; -} -/* DEPRECATED: Pre version 8.2.7 verse style literal block. */ -div.verseblock + div.attribution { - text-align: left; -} - -div.admonitionblock .icon { - vertical-align: top; - font-size: 1.1em; - font-weight: bold; - text-decoration: underline; - color: #3ec2ff; - padding-right: 0.5em; -} -div.admonitionblock td.content { - padding-left: 0.5em; - border-left: 3px solid #dddddd; -} - -div.exampleblock > div.content { - border-left: 3px solid #dddddd; - padding-left: 0.5em; -} - -div.imageblock div.content { padding-left: 0; } -span.image img { border-style: none; } -a.image:visited { color: white; } - -dl { - margin-top: 0.8em; - margin-bottom: 0.8em; -} -dt { - margin-top: 0.5em; - margin-bottom: 0; - font-style: normal; - color: #3ec2ff; -} -dd > *:first-child { - margin-top: 0.1em; -} - -ul, ol { - list-style-position: outside; -} -ol.arabic { - list-style-type: decimal; -} -ol.loweralpha { - list-style-type: lower-alpha; -} -ol.upperalpha { - list-style-type: upper-alpha; -} -ol.lowerroman { - list-style-type: lower-roman; -} -ol.upperroman { - list-style-type: upper-roman; -} - -div.compact ul, div.compact ol, -div.compact p, div.compact p, -div.compact div, div.compact div { - margin-top: 0.1em; - margin-bottom: 0.1em; -} - -div.tableblock > table { - border: 3px solid #3ec2ff; -} -thead, p.table.header { - font-weight: bold; - color: #3ec2ff; -} -tfoot { - font-weight: bold; -} -td > div.verse { - white-space: pre; -} -p.table { - margin-top: 0; -} -/* Because the table frame attribute is overriden by CSS in most browsers. */ -div.tableblock > table[frame="void"] { - border-style: none; -} -div.tableblock > table[frame="hsides"] { - border-left-style: none; - border-right-style: none; -} -div.tableblock > table[frame="vsides"] { - border-top-style: none; - border-bottom-style: none; -} - - -div.hdlist { - margin-top: 0.8em; - margin-bottom: 0.8em; -} -div.hdlist tr { - padding-bottom: 15px; -} -dt.hdlist1.strong, td.hdlist1.strong { - font-weight: bold; -} -td.hdlist1 { - vertical-align: top; - font-style: normal; - padding-right: 0.8em; - color: navy; -} -td.hdlist2 { - vertical-align: top; -} -div.hdlist.compact tr { - margin: 0; - padding-bottom: 0; -} - -.comment { - background: yellow; -} - -.footnote, .footnoteref { - font-size: 0.8em; -} - -span.footnote, span.footnoteref { - vertical-align: super; -} - -#footnotes { - margin: 20px 0 20px 0; - padding: 7px 0 0 0; -} - -#footnotes div.footnote { - margin: 0 0 5px 0; -} - -#footnotes hr { - border: none; - border-top: 1px solid silver; - height: 1px; - text-align: left; - margin-left: 0; - width: 20%; - min-width: 100px; -} - -div.colist td { - padding-right: 0.5em; - padding-bottom: 0.3em; - vertical-align: top; -} -div.colist td img { - margin-top: 0.3em; -} - -@media print { - div#footer-badges { display: none; } -} - -div#toc { - margin-bottom: 2.5em; -} - -div#toctitle { - color: #3ec2ff; - font-size: 1.1em; - font-weight: bold; - margin-top: 1.0em; - margin-bottom: 0.1em; -} - -div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 { - margin-top: 0; - margin-bottom: 0; -} -div.toclevel2 { - margin-left: 2em; - font-size: 0.9em; -} -div.toclevel3 { - margin-left: 4em; - font-size: 0.9em; -} -div.toclevel4 { - margin-left: 6em; - font-size: 0.9em; -} - -span.aqua { color: aqua; } -span.black { color: black; } -span.blue { color: blue; } -span.fuchsia { color: fuchsia; } -span.gray { color: gray; } -span.green { color: green; } -span.lime { color: lime; } -span.maroon { color: maroon; } -span.navy { color: navy; } -span.olive { color: olive; } -span.purple { color: purple; } -span.red { color: red; } -span.silver { color: silver; } -span.teal { color: teal; } -span.white { color: white; } -span.yellow { color: yellow; } - -span.aqua-background { background: aqua; } -span.black-background { background: black; } -span.blue-background { background: blue; } -span.fuchsia-background { background: fuchsia; } -span.gray-background { background: gray; } -span.green-background { background: green; } -span.lime-background { background: lime; } -span.maroon-background { background: maroon; } -span.navy-background { background: navy; } -span.olive-background { background: olive; } -span.purple-background { background: purple; } -span.red-background { background: red; } -span.silver-background { background: silver; } -span.teal-background { background: teal; } -span.white-background { background: white; } -span.yellow-background { background: yellow; } - -span.big { font-size: 2em; } -span.small { font-size: 0.6em; } - -@font-face { - font-family: 'Droid Sans Mono'; - font-style: normal; - font-weight: normal; - src: local('Droid Sans Mono'), local('DroidSansMono'), url('/fonts/DroidSansMono.ttf') format('truetype'); -} From 900f673f1467f78af52914846703306c20d9611c Mon Sep 17 00:00:00 2001 From: Sander De la Marche Date: Tue, 22 Dec 2020 18:52:54 +0100 Subject: [PATCH 3/6] Add a new build script, using AsciiDoctor --- build.sh | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 build.sh diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..9914bf5 --- /dev/null +++ b/build.sh @@ -0,0 +1,3 @@ +#!/bin/sh +asciidoctor -B _docs -D ../docs -a linkcss -a stylesdir=../css -a stylesheet=docs.css -a toc=left '**/*.adoc' + From a3e1e6b3b4b6d3c36fbb5e94e1d66787346fb42b Mon Sep 17 00:00:00 2001 From: Sander De la Marche Date: Tue, 22 Dec 2020 18:53:12 +0100 Subject: [PATCH 4/6] Generate the docs using the new AsciiDoctor back-end --- docs/buildbot.html | 2374 +++++++------- docs/debugging-release-version.html | 402 ++- docs/debugging.html | 260 -- docs/gsoc2013-ideas.html | 412 +-- docs/hacking-howto.html | 2029 ++++++------ docs/i3-config-wizard.html | 211 +- docs/i3-input.html | 134 + docs/i3-migrate-config-to-v4.html | 185 +- docs/i3-msg.html | 219 +- docs/i3-nagbar.html | 192 +- docs/i3.html | 1019 +++--- docs/i3bar-protocol.html | 625 ++-- docs/i3status.html | 1956 ++++++----- docs/ipc.html | 2677 +++++++-------- docs/layout-saving.html | 350 +- docs/manpage.html | 530 --- docs/multi-monitor.html | 142 +- docs/repositories.html | 331 +- docs/testsuite.html | 759 +++-- docs/tree-migrating.html | 271 -- docs/tshirts.html | 412 ++- docs/userguide.html | 4720 ++++++++++++++++----------- docs/wsbar.html | 190 +- 23 files changed, 10333 insertions(+), 10067 deletions(-) delete mode 100644 docs/debugging.html create mode 100644 docs/i3-input.html delete mode 100644 docs/manpage.html delete mode 100644 docs/tree-migrating.html diff --git a/docs/buildbot.html b/docs/buildbot.html index c9d6499..924cc33 100644 --- a/docs/buildbot.html +++ b/docs/buildbot.html @@ -1,1131 +1,1243 @@ - - - - - - -i3: The i3 buildbot setup - - - - - - -
- - -
-
- - -

The i3 buildbot setup

-Michael Stapelberg
-<michael@i3wm.org>
-September 2012 -
-
Table of Contents
- -
- -
-
-
-WARNING! -

-

This document is outdated and kept for “historical” reasons. i3 uses Travis as -a CI instead.

-

-
-

This document explains the buildbot setup we use to -provide up-to-date documentation and debian packages at http://build.i3wm.org/. -We publish these information so that our setup is well-documented (thus -decreasing future maintenance effort) and because it might be interesting for -other projects.

-
-
-
-

1. Introduction

-
-

What we are doing in i3 is called Continuous Integration (see -http://en.wikipedia.org/wiki/Continuous_integration): we publish the changes we -make on our local machines as often as possible. In order to maintain a -continuously high quality, each time any developer pushes changes to the -official git repository, a number of quality assurance tools start running -automatically:

-
    -
  1. -

    -Latest documentation is generated and provided at - http://build.i3wm.org/docs/. This makes it easy to link to documentation for - features which are only in the current git version, not in the released - version. -

    -
  2. -
  3. -

    -The source code is compiled and it is automatically posted to the IRC - channel whether there were any compiler warnings. While developers should - notice compiler warnings, this mechanism creates a bit of public pressure - ("Oh, Michael introduced warnings with this commit!"). More importantly, - since this mechanism builds a dist tarball and then compiles that tarball, - any changes to the source which would result in an uncompilable dist tarball - are immediately obvious. Therefore, we could cut a release from the current - git version at any point in time. -

    -
  4. -
  5. -

    -The clang static analyzer runs and the resulting report is provided at - http://build.i3wm.org/clang-analyze/. While every developer needs to compile - his code before committing, he doesn’t necessarily use clang (so we catch - build failures when using clang) and he also probably doesn’t run a static - analyzer as part of his normal workflow. By just being available without any - friction, this mechanism encourages developers to look at the report and fix - problems. -

    -
  6. -
  7. -

    -Debian (and Ubuntu) packages are built. This not only ensures that we don’t - change anything in the source code which would lead to an FTBFS (Fails To - Build From Source) when building a Debian package, it also goes a long way - to encourage end users to test i3. To remove the need and resource - requirements for them to compile their own version of i3 regularly, we - provide packages that integrate conveniently with a normal Debian system - (e.g. that are automatically upgraded). -

    -
  8. -
-
-
-
-

2. Why buildbot?

-
-

Previously, I was unsatisfied with the current state of FOSS CI tools like -Jenkins, Tinderbox and others. They either seemed bloated, hard to use, -outdated or unappealing for some other reason.

-

Then I discovered buildbot and was impressed by its flexibility. It let me -implement everything I wanted from a CI tool and (in my opinion) it is -light-weight, easy to deploy and well maintained.

-

The only downside of buildbot is its configuration and documentation: You need -to spend quite a bit of time (I needed multiple days) until it works the way -you want it to and oftentimes, the documentation is far too sparse. This is one -of the reasons why I’m publishing the i3 setup.

-
-
-
-

3. Configuration

-
-

See the next section for a complete, copy & pasteable configuration file. This -section covers the most important aspects without covering every line.

-

This document assumes you are running buildbot 0.8.6p1.

-
-

3.1. Change sources

-

Since i3 uses a central git repository, we use the official buildbot -git -post-receive hook that sends the change information to the buildbot master.

-
-
-

3.2. Schedulers

-

There are two things (called "builders" in buildbot-language) which happen -whenever a new change in the next branch of i3 occurs:

-
    -
  1. -

    -The "docs" builder builds and uploads the latest documentation. This happens - directly from the git repository with a custom asciidoc configuration which - indicates that these docs refer to the git version. Therefore, this builder - does not benefit from having a dist tarball available (contrary to the other - builders). -

    -
  2. -
  3. -

    -The "dist" builder prepares a dist tarball and then triggers the remaining - builders. This ensures that building the dist tarball (an operation which - takes about one minute due to documentation generation) only happens once. -

    -
  4. -
-

Here is the relevant configuration part:

-

Schedulers:

-
-
-
c['schedulers'] = []
-
-c['schedulers'].append(SingleBranchScheduler(
-    name = 'dist',
-    branch = 'next',
-    treeStableTimer = 10,
-    builderNames = [ 'dist', 'docs' ],
-))
-
-c['schedulers'].append(Triggerable(
-    name = 'dist-tarball-done',
-    builderNames = [ 'compile', 'clang-analyze', 'debian-packages', 'ubuntu-packages' ],
-))
-
-
-
-

3.3. Building the dist tarball

-

This builder clones the i3 git repository and runs "make dist", which creates a -tarball that could be named "i3-4.2.tar.bz2" for example. This tarball is then -renamed to dist-%(gitversion).tar.bz2 (so that we can work with a predictable -name in the next steps) and uploaded to the buildbot master (since we can have -multiple buildslaves, we cannot just let it rest on the buildslave that built -it). Afterwards, old dist tarballs are cleaned up and the remaining builders -are triggered:

-

Building a dist tarball:

-
-
-
factories = {}
-
-f = factories['dist'] = BuildFactory()
-
-# Check out the git repository.
-f.addStep(s_git)
-
-# Fill the 'gitversion' property with the output of git describe --tags.
-f.addStep(shell.SetProperty(command = 'git describe --tags', property = 'gitversion'))
-
-# Build the dist tarball.
-cmd(f, name = 'make dist', command = [ 'make', 'dist' ])
-
-# Rename the created tarball to a well-known name.
-cmd(f,
-    name = 'rename tarball',
-    command = WithProperties('mv *.tar.bz2 dist-%(gitversion)s.tar.bz2'),
-)
-
-# Upload the dist tarball to the master (other factories download it later).
-f.addStep(transfer.FileUpload(
-    slavesrc = WithProperties('dist-%(gitversion)s.tar.bz2'),
-    masterdest = WithProperties('distballs/dist-%(gitversion)s.tar.bz2'),
-))
-
-# Cleanup old dist tarballs (everything older than tree days).
-f.addStep(master.MasterShellCommand(
-    command = "find distballs -mtime +3 -exec rm '{}' \;",
-    name = 'cleanup old dist tarballs',
-))
-
-# Everything worked fine, now trigger compilation.
-f.addStep(Trigger(
-    schedulerNames = [ 'dist-tarball-done' ],
-    copy_properties = [ 'gitversion' ],
-))
-
-

Three things are noteworthy about this part of the configuration:

-
    -
  1. -

    -For convenience, we call each factory f (just like the global buildbot - config uses c for the top-level configuration) and add it to a dictionary. - Factories in that dictionary are later automatically configured for each - buildslave. -

    -
  2. -
  3. -

    -We have a shared step called s_git so that we only have one location in - the configuration file where we specify the git repository URL and branch. -

    -
  4. -
  5. -

    -We have a custom function called cmd which is a shortcut for defining a - ShellCommand with haltOnFailure=True (since each step is critical) and - logEnviron=False (for brevity). -

    -
  6. -
-

Here are their definitions:

-

cmd:

-
-
-
def cmd(factory, **kwargs):
-    factory.addStep(ShellCommand(
-        haltOnFailure = True,
-        logEnviron = False,
-        **kwargs
-    ))
-
-

s_git:

-
-
-
s_git = Git(
-    repourl = 'git://code.i3wm.org/i3',
-    branch = 'next',
-
-    # Check out the latest revision, not the one which caused this build.
-    alwaysUseLatest = True,
-
-    # We cannot use shallow because it breaks git describe --tags.
-    shallow = False,
-
-    # Delete remnants of previous builds.
-    mode = 'full',
-
-    # Store checkouts in source/ and copy them over to build/ to save
-    # bandwidth.
-    method = 'copy',
-)
-
-
-
-

3.4. Compiling the dist tarball

-

For this builder to work, you obviously need to install all the -build-dependencies for your software on each buildslave. In the case of i3, -this can be done with apt-get build-dep i3-wm.

-

The compilation is pretty straight-forward since it uses the builtin Compile -step. We call make with -j4 (we don’t have enough buildslaves to make -figuring out the amount of cores at build-time worthwhile) and DEBUG=0 to -simulate release build conditions. Also, we pass the preprocessor flag --D_FORTIFY_SOURCE=2 and the compiler flags -Wformat and -Wformat-security -to enable additional warnings.

-

Compiling the dist tarball:

-
-
-
f = factories['compile'] = BuildFactory()
-unpack_dist_tarball(f)
-f.addStep(Compile(
-    command = [ 'make', 'DEBUG=0', '-j4' ],
-    warningPattern = '.*warning: ',
-    warnOnWarnings = True,
-    workdir = 'build/DIST',
-    env = {
-      'CPPFLAGS': '-D_FORTIFY_SOURCE=2',
-      'CFLAGS': '-Wformat -Wformat-security'
-    },
-))
-
-f.addStep(WarningsToIRC())
-
-

Again, we use custom functions (and a custom buildstep) to make our lives -easier. Here is the definition of unpack_dist_tarball which adds three steps to -the factory that download and unpack the dist tarball to the DIST/ directory:

-

unpack_dist_tarball:

-
-
-
def unpack_dist_tarball(factory):
-    factory.addStep(transfer.FileDownload(
-        mastersrc = WithProperties('distballs/dist-%(gitversion)s.tar.bz2'),
-        slavedest = 'dist.tar.bz2',
-    ))
-
-    factory.addStep(slave.MakeDirectory(dir = 'build/DIST'))
-
-    cmd(factory,
-        name = 'unpack dist tarball',
-        command = [ 'tar', 'xf', 'dist.tar.bz2', '-C', 'DIST', '--strip-components=1' ],
-    )
-
-

The WarningsToIRC build step is a custom build step which sets a property -called "ircsuffix" that is used by our custom IRC bot. This is covered later in -more detail. This property gets set to a green or red message, depending on -whether there were any warnings:

-

WarningsToIRC:

-
-
-
class WarningsToIRC(buildstep.BuildStep):
-    def start(self):
-        warnings = self.getProperty("warnings-count")
-        if warnings is not None and int(warnings) > 0:
-            warnings = int(warnings)  # just to be sure
-            self.setProperty("ircsuffix", ("\0037 with %d warning%s!" %
-                (warnings, "s" if warnings != 1 else "")))
-        else:
-            self.setProperty("ircsuffix", "\0033 without warnings")
-        self.finished(SUCCESS)
-
-
-
-

3.5. Static code analysis

-

For this builder to work, you additionally need the clang compiler on each -buildslave: apt-get install clang.

-

This builder uses only custom functions which you already know by now. It runs -scan-build, then moves scan-build’s output from a date-based directory directly -into the CLANG/ directory and uploads that to the buildmaster.

-

On the buildmaster, a webserver is configured which has a symlink to -/home/build/i3-master/htdocs/clang-analyze in its document root.

-

static code analysis:

-
-
-
f = factories['clang-analyze'] = BuildFactory()
-unpack_dist_tarball(f)
-cmd(f,
-    name='analyze',
-    command = [
-        'scan-build',
-        '-o', '../CLANG',
-        '--html-title', WithProperties('Analysis of i3 v%(gitversion)s'),
-        'make', '-j8',
-    ],
-    workdir = 'build/DIST',
-)
-
-# remove the subdirectory -- we always want to overwrite
-cmd(f, command = 'mv CLANG/*/* CLANG/')
-
-f.addStep(transfer.DirectoryUpload(
-    slavesrc = 'CLANG',
-    masterdest = 'htdocs/clang-analyze',
-    compress = 'bz2',
-    name = 'upload output',
-))
-
-f.addStep(ClangToIRC())
-
-

The ClangToIRC custom step is even simpler than WarningsToIRC. It simply -sets the ircsuffix property to a static message:

-

ClangToIRC:

-
-
-
class ClangToIRC(buildstep.BuildStep):
-    def start(self):
-        self.setProperty("ircsuffix", ", see http://build.i3wm.org/clang-analyze/")
-        self.finished(SUCCESS)
-
-
-
-

3.6. Generating documentation

-

This builder is the one which is the least clean of all. It uses the Debian -packaging information to decide which docs to publish and which manpages to -generate. Additionally, it uses a for loop instead of calling a script. I -recommend including a script to do this in your repository instead.

-

Apart from these concerns, the builder is straight-forward: It clones the git -repository, generates the documentation and then uploads the documentation to -the buildmaster:

-

Generating documentation:

-
-
-
f = factories['docs'] = BuildFactory()
-f.addStep(s_git)
-# Fill the 'gitversion' property with the output of git describe --tags.
-f.addStep(shell.SetProperty(command = 'git describe --tags', property = 'gitversion'))
-cmd(f, name = 'build docs', command = [ 'make', '-C', 'docs', "ASCIIDOC=asciidoc -a linkcss -a stylesdir=http://i3wm.org/css -a scriptsdir=http://i3wm.org/js --backend=xhtml11 -f docs/asciidoc-git.conf" ])
-cmd(f, name = 'build manpages', command = "for file in $(sed 's/\.1$/.man/g' debian/i3-wm.manpages); do asciidoc -a linkcss -a stylesdir=http://i3wm.org/css -a scriptsdir=http://i3wm.org/js --backend=xhtml11 -f docs/asciidoc-git.conf \"$file\"; done")
-f.addStep(slave.MakeDirectory(dir='build/COPY-DOCS'))
-cmd(f, name = 'copy docs', command = "cp $(tr '\\n' ' ' < debian/i3-wm.docs) COPY-DOCS")
-cmd(f, name = 'copy manpages', command = "cp $(sed 's/\.1$/.html/g' debian/i3-wm.manpages | tr '\\n' ' ') COPY-DOCS")
-
-f.addStep(transfer.DirectoryUpload(
-    slavesrc = 'COPY-DOCS',
-    masterdest = 'htdocs/docs-git',
-    compress = 'bz2',
-    name = 'upload docs'))
-
-f.addStep(DocsToIRC())
-
-

Just as ClangToIRC, DocsToIRC appends a static message:

-

DocsToIRC:

-
-
-
class DocsToIRC(buildstep.BuildStep):
-    def start(self):
-        self.setProperty("ircsuffix", ", see http://build.i3wm.org/docs/")
-        self.finished(SUCCESS)
-
-
-
-

3.7. Building Debian/Ubuntu packages

-

This is the most complex builder of all. It uses pbuilder-dist, debchange, -dpkg-buildpackage and reprepro to generate a Debian repository with a -cleanly compiled package for amd64 and i386. In order for it to work, you need -to install the following packages: apt-get install devscripts dpkg-dev -reprepro ubuntu-dev-tools pbuilder. Afterwards, you need to allow the user as -which the buildslave runs to execute pbuilder via sudo without needing a -password, so add a config file like this one:

-

sudoers.d:

-
-
-
echo 'build    ALL= NOPASSWD: SETENV: /usr/sbin/pbuilder' > /etc/sudoers.d/build
-
-

Then, as the user as which your buildslave runs, setup the pbuilder -environments (you only need to do this once):

-

pbuilder preparation:

-
-
-
sudo ln -s pbuilder-dist /usr/bin/pbuilder-sid-amd64
-sudo ln -s pbuilder-dist /usr/bin/pbuilder-sid-i386
-pbuilder-sid-amd64 create
-pbuilder-sid-i386 create
-
-

Also, you will need a GPG key to sign these packages.

-

The debian builder starts by unpacking the dist tarball, copying the Debian -packaging from git, creating an empty Debian repository with the -i3-autobuild-keyring contents in it. It then adds a new changelog entry to -reflect the git version and the fact that this package was built automatically, -builds a source package with dpkg-buildpackage and adds it to the repository. -Afterwards, it updates each pbuilder and builds binary packages for each -architecture (amd64 and i386). After adding the resulting packages to the -repository, it uploads the repository to the buildmaster:

-

Debian builder:

-
-
-
distributions = [ 'sid-amd64', 'sid-i386' ]
-gpg_key = 'BE1DB1F1'
-
-f = factories['debian-packages'] = BuildFactory()
-# We need the git repository for the Debian packaging.
-f.addStep(s_git)
-unpack_dist_tarball(f)
-cmd(f, name = 'copy packaging', command = "cp -r debian DIST/")
-
-# Add a new changelog entry to have the git version in the package version.
-cmd(f,
-    name = 'update changelog',
-    workdir = 'build/DIST',
-    command = [ 'debchange', '-m', '-l', WithProperties('+g%(gitversion)s'), 'Automatically built' ],
-)
-
-cmd(f,
-    name = 'source pkg',
-    command = [ 'dpkg-buildpackage', '-S', '-us', '-uc' ],
-    workdir = 'build/DIST',
-)
-
-for dist in distributions:
-    f.addStep(slave.MakeDirectory(dir = 'build/RESULT-' + dist))
-
-# Create debian sid repository
-f.addStep(slave.MakeDirectory(dir = 'build/REPO-sid/conf'))
-f.addStep(transfer.StringDownload(
-    """Codename: sid
-Suite: unstable
-Architectures: i386 amd64 source
-Components: main
-DebIndices: Packages Release . .gz .bz2
-DscIndices: Sources Release . .gz .bz2
-SignWith: %(gpg_key)s
-""" % { "gpg_key": gpg_key },
-    slavedest = 'REPO-sid/conf/distributions',
-))
-
-# add source package to repository
-reprepro_include(f, 'i3-wm*_source.changes', 'dsc')
-
-# Add keyring to the repository. We need to run git clone on our own because
-# the Git() step assumes there’s precisely one repository we want to deal with.
-# No big deal since the i3-autobuild-keyring repository is not big.
-cmd(f,
-    name = 'clone keyring repo',
-    command = 'git clone git://code.i3wm.org/i3-autobuild-keyring',
-)
-reprepro_include(f, 'i3-autobuild-keyring/prebuilt/*.changes')
-
-for dist in distributions:
-    # update the pbuilder
-    cmd(f, name = 'update builder', command = 'pbuilder-' + dist + ' update')
-
-    # build the package for each dist
-    f.addStep(ShellCommand(
-        logEnviron = False,
-        name = 'pkg ' + dist,
-        command = 'pbuilder-' + dist + ' build --binary-arch \
---buildresult RESULT-' + dist + ' --debbuildopts -j8 i3-wm*dsc',
-        warnOnFailure = True
-    ))
-
-    reprepro_include(f, 'RESULT-' + dist + '/*.changes')
-
-# upload the sid repo
-# Since the next step is cleaning up old files, we set haltOnFailure=True -- we
-# prefer providing old packages over providing no packages at all :).
-for directory in [ 'pool', 'dists' ]:
-    f.addStep(transfer.DirectoryUpload(
-        slavesrc = 'REPO-sid/' + directory,
-        masterdest = 'htdocs/debian/sid/' + directory,
-        compress = 'bz2',
-        name = 'upload sid ' + directory,
-        haltOnFailure = True,
-    ))
-
-f.addStep(master.MasterShellCommand(
-    command = "find htdocs/debian/sid/pool -mtime +3 -exec rm '{}' \;",
-    name = 'cleanup old packages',
-))
-
-# We ensure there is an empty i18n/Index to speed up apt (so that it does not
-# try to download Translation-*)
-f.addStep(master.MasterShellCommand(
-    command = [ 'mkdir', '-p', 'htdocs/debian/sid/dists/sid/main/i18n' ],
-    name = 'create i18n folder',
-))
-f.addStep(master.MasterShellCommand(
-    command = [ 'touch', 'htdocs/debian/sid/dists/sid/main/i18n/Index' ],
-    name = 'touch i18n/Index',
-))
-
-

The reprepro_include command is defined as follows:

-

reprepro_include:

-
-
-
def reprepro_include(factory, path, debtype='deb', **kwargs):
-    cmd(factory,
-        name = 'reprepro include',
-        command = 'reprepro --ignore=wrongdistribution -T ' + debtype + ' -b REPO-sid include sid ' + path,
-        **kwargs
-    )
-
-

Running such a builder for Ubuntu works exactly the same way, but you need to -replace "sid" with "precise" in all places (see the full configuration file for -an example).

-
-
-

3.8. Status targets

-

We don’t advertise the HTTP status target. Instead, status is posted to IRC via -a custom bot. This bot provides an HTTP end point and buildbot is configured to -push status changes to that endpoint:

-

http status target:

-
-
-
c['status'].append(buildbot.status.status_push.HttpStatusPush(
-    serverUrl = 'http://localhost:8080/push_buildbot',
-))
-
-

You can find the source code of that bot at -http://code.stapelberg.de/git/go-buildbot-announce/. As the name suggests, it -is written in Go. Also, it is quite specific to i3, so you might be better off -implementing such a bot (or plugin) on your own. It might make for a nice -example, though, especially back when its only feature was announcing the build -status:

- -
-
-

3.9. Creating the buildslave

-

One more thing to note is that when creating the buildslave, you should use the ---umask argument to configure the umask for all generated files:

-

Creating the buildslave:

-
-
-
buildslave create-slave --umask=022 i3-buildslave buildbot.i3wm.org build-1 <password>
-
-
-
-
-
-

4. Full configuration file

-
-

This is the full configuration file, as tested and currently in use (except for -the passwords, though):

-

master.cfg:

-
-
-
# -*- python -*-
-# -*- coding: utf-8
-# vim:ts=4:sw=4:expandtab:syntax=python
-#
-# i3 buildbot configuration
-# © 2012 Michael Stapelberg, Public Domain
-# see http://i3wm.org/docs/buildbot.html for more information.
-
-from buildbot.buildslave import BuildSlave
-from buildbot.changes import pb
-from buildbot.schedulers.basic import SingleBranchScheduler
-from buildbot.schedulers.triggerable import Triggerable
-from buildbot.process.properties import WithProperties
-from buildbot.process.factory import BuildFactory
-from buildbot.steps.source.git import Git
-from buildbot.steps.shell import ShellCommand
-from buildbot.steps.shell import Compile
-from buildbot.steps.trigger import Trigger
-from buildbot.steps import shell, transfer, master, slave
-from buildbot.config import BuilderConfig
-from buildbot.process import buildstep
-from buildbot.status import html
-from buildbot.status import words
-import buildbot.status.status_push
-from buildbot.status.web import auth, authz
-from buildbot.status.builder import SUCCESS, FAILURE
-
-c = BuildmasterConfig = {}
-
-c['slaves'] = [BuildSlave('docsteel-vm', 'secret')]
-c['slavePortnum'] = 9989
-# Changes are pushed to buildbot using a git hook.
-c['change_source'] = [pb.PBChangeSource(
-    user = 'i3-source',
-    passwd = 'secret',
-)]
-
-################################################################################
-# schedulers
-################################################################################
-
-c['schedulers'] = []
-
-# The first scheduler kicks off multiple builders:
-# • 'dist' builds a dist tarball and starts the triggerable schedulers
-#   'compile'
-# • 'docs' builds the documentation with a special asciidoc configuration
-#   (therefore, it does not profit from a dist tarball and can be run in
-#    parallel).
-c['schedulers'].append(SingleBranchScheduler(
-    name = 'dist',
-    branch = 'next',
-    treeStableTimer = 10,
-    builderNames = [ 'dist', 'docs' ],
-))
-
-c['schedulers'].append(Triggerable(
-    name = 'dist-tarball-done',
-    builderNames = [ 'compile', 'clang-analyze', 'debian-packages', 'ubuntu-packages' ],
-))
-
-################################################################################
-# Shortcuts for builders
-################################################################################
-
-# shortcut for a ShellCommand with haltOnFailure=True, logEnviron=False
-def cmd(factory, **kwargs):
-    factory.addStep(ShellCommand(
-        haltOnFailure=True,
-        logEnviron=False,
-        **kwargs
-    ))
-
-# Shortcut to add steps necessary to download and unpack the dist tarball.
-def unpack_dist_tarball(factory):
-    factory.addStep(transfer.FileDownload(
-        mastersrc=WithProperties('distballs/dist-%(gitversion)s.tar.bz2'),
-        slavedest='dist.tar.bz2',
-    ))
-    factory.addStep(slave.MakeDirectory(dir='build/DIST'))
-    cmd(factory,
-        name = 'unpack dist tarball',
-        command = [ 'tar', 'xf', 'dist.tar.bz2', '-C', 'DIST', '--strip-components=1' ],
-    )
-
-# Includes the given path in REPO-sid using reprepro.
-def reprepro_include(factory, path, debtype='deb', **kwargs):
-    cmd(factory,
-        name = 'reprepro include',
-        command = 'reprepro --ignore=wrongdistribution -T ' + debtype + ' -b REPO-sid include sid ' + path,
-        **kwargs
-    )
-
-def reprepro_include_ubuntu(factory, path, debtype='deb', **kwargs):
-    cmd(factory,
-        name = 'reprepro include',
-        command = 'reprepro --ignore=wrongdistribution -T ' + debtype + ' -b REPO-sid include precise ' + path,
-        **kwargs
-    )
-
-################################################################################
-# Custom steps
-################################################################################
-
-# Adds the ircsuffix property to reflect whether there were warnings.
-class WarningsToIRC(buildstep.BuildStep):
-  def start(self):
-    warnings = self.getProperty("warnings-count")
-    if warnings is not None and int(warnings) > 0:
-      warnings = int(warnings)  # just to be sure
-      self.setProperty("ircsuffix", "\0037 with %d warning%s!" % (warnings, "s" if warnings != 1 else ""))
-    else:
-      self.setProperty("ircsuffix", "\0033 without warnings")
-    self.finished(SUCCESS)
-
-# Adds a link to the automatically generated documentation.
-class DocsToIRC(buildstep.BuildStep):
-  def start(self):
-    self.setProperty("ircsuffix", ", see http://build.i3wm.org/docs/")
-    self.finished(SUCCESS)
-
-# Adds a link to the clang report.
-class ClangToIRC(buildstep.BuildStep):
-  def start(self):
-    self.setProperty("ircsuffix", ", see http://build.i3wm.org/clang-analyze/")
-    self.finished(SUCCESS)
-
-################################################################################
-# Shared steps, used in different factories.
-################################################################################
-
-s_git = Git(
-    repourl='git://code.i3wm.org/i3',
-    branch='next',
-
-    # Check out the latest revision, not the one which caused this build.
-    alwaysUseLatest=True,
-
-    # We cannot use shallow because it breaks git describe --tags.
-    shallow=False,
-
-    # Delete remnants of previous builds.
-    mode='full',
-
-    # Store checkouts in source/ and copy them over to build/ to save
-    # bandwidth.
-    method='copy',
-
-    # XXX: In newer versions of buildbot (> 0.8.6), we want to use
-    # getDescription={ 'tags': True } here and get rid of the extra git
-    # describe --tags step.
-)
-
-################################################################################
-# factory: "dist" — builds the dist tarball once (used by all other factories)
-################################################################################
-
-factories = {}
-
-f = factories['dist'] = BuildFactory()
-# Check out the git repository.
-f.addStep(s_git)
-# Fill the 'gitversion' property with the output of git describe --tags.
-f.addStep(shell.SetProperty(command = 'git describe --tags', property = 'gitversion'))
-# Build the dist tarball.
-cmd(f, name = 'make dist', command = [ 'make', 'dist' ])
-# Rename the created tarball to a well-known name.
-cmd(f, name = 'rename tarball', command = WithProperties('mv *.tar.bz2 dist-%(gitversion)s.tar.bz2'))
-# Upload the dist tarball to the master (other factories download it later).
-f.addStep(transfer.FileUpload(
-    slavesrc = WithProperties('dist-%(gitversion)s.tar.bz2'),
-    masterdest = WithProperties('distballs/dist-%(gitversion)s.tar.bz2'),
-))
-# Cleanup old dist tarballs (everything older than tree days).
-f.addStep(master.MasterShellCommand(
-    command = "find distballs -mtime +3 -exec rm '{}' \;",
-    name = 'cleanup old dist tarballs',
-))
-# Everything worked fine, now trigger compilation.
-f.addStep(Trigger(
-    schedulerNames = [ 'dist-tarball-done' ],
-    copy_properties = [ 'gitversion' ],
-))
-
-################################################################################
-# factory: "compile" — compiles the dist tarball and reports warnings
-################################################################################
-
-f = factories['compile'] = BuildFactory()
-unpack_dist_tarball(f)
-f.addStep(Compile(
-    command = [ 'make', 'DEBUG=0', '-j4' ],
-    warningPattern = '.*warning: ',
-    warnOnWarnings = True,
-    workdir = 'build/DIST',
-    env = {
-      'CPPFLAGS': '-D_FORTIFY_SOURCE=2',
-      'CFLAGS': '-Wformat -Wformat-security'
-    },
-))
-
-f.addStep(WarningsToIRC())
-
-################################################################################
-# factory: "clang-analyze" — runs a static code analysis
-################################################################################
-# $ sudo apt-get install clang
-
-f = factories['clang-analyze'] = BuildFactory()
-unpack_dist_tarball(f)
-cmd(f,
-    name='analyze',
-    command = [
-        'scan-build',
-        '-o', '../CLANG',
-        '--html-title', WithProperties('Analysis of i3 v%(gitversion)s'),
-        'make', '-j8',
-    ],
-    workdir = 'build/DIST',
-)
-
-# remove the subdirectory -- we always want to overwrite
-cmd(f, command = 'mv CLANG/*/* CLANG/')
-
-f.addStep(transfer.DirectoryUpload(
-    slavesrc = 'CLANG',
-    masterdest = 'htdocs/clang-analyze',
-    compress = 'bz2',
-    name = 'upload output',
-))
-
-f.addStep(ClangToIRC())
-
-################################################################################
-# factory: "docs" — builds documentation with a special asciidoc conf
-################################################################################
-
-f = factories['docs'] = BuildFactory()
-f.addStep(s_git)
-# Fill the 'gitversion' property with the output of git describe --tags.
-f.addStep(shell.SetProperty(command = 'git describe --tags', property = 'gitversion'))
-cmd(f, name = 'build docs', command = [ 'make', '-C', 'docs', "ASCIIDOC=asciidoc -a linkcss -a stylesdir=http://i3wm.org/css -a scriptsdir=http://i3wm.org/js --backend=xhtml11 -f docs/asciidoc-git.conf" ])
-cmd(f, name = 'build manpages', command = "for file in $(sed 's/\.1$/.man/g' debian/i3-wm.manpages); do asciidoc -a linkcss -a stylesdir=http://i3wm.org/css -a scriptsdir=http://i3wm.org/js --backend=xhtml11 -f docs/asciidoc-git.conf \"$file\"; done")
-f.addStep(slave.MakeDirectory(dir='build/COPY-DOCS'))
-cmd(f, name = 'copy docs', command = "cp $(tr '\\n' ' ' < debian/i3-wm.docs) COPY-DOCS")
-cmd(f, name = 'copy manpages', command = "cp $(sed 's/\.1$/.html/g' debian/i3-wm.manpages | tr '\\n' ' ') COPY-DOCS")
-
-f.addStep(transfer.DirectoryUpload(
-    slavesrc = 'COPY-DOCS',
-    masterdest = 'htdocs/docs-git',
-    compress = 'bz2',
-    name = 'upload docs'))
-
-f.addStep(DocsToIRC())
-
-################################################################################
-# factory: "debian-packages" — builds Debian (sid) packages for amd64 and i386
-################################################################################
-
-distributions = [ 'sid-amd64', 'sid-i386' ]
-gpg_key = 'BE1DB1F1'
-
-f = factories['debian-packages'] = BuildFactory()
-# We need the git repository for the Debian packaging.
-f.addStep(s_git)
-unpack_dist_tarball(f)
-cmd(f, name='copy packaging', command = "cp -r debian DIST/")
-
-# Add a new changelog entry to have the git version in the package version.
-cmd(f,
-    name = 'update changelog',
-    workdir = 'build/DIST',
-    command = [ 'debchange', '-m', '-l', WithProperties('+g%(gitversion)s'), 'Automatically built' ],
-)
-
-cmd(f,
-    name = 'source pkg',
-    command = [ 'dpkg-buildpackage', '-S', '-us', '-uc' ],
-    workdir = 'build/DIST',
-)
-
-for dist in distributions:
-    f.addStep(slave.MakeDirectory(dir='build/RESULT-' + dist))
-
-# Create debian sid repository
-f.addStep(slave.MakeDirectory(dir='build/REPO-sid/conf'))
-f.addStep(transfer.StringDownload(
-    """Codename: sid
-Suite: unstable
-Architectures: i386 amd64 source
-Components: main
-DebIndices: Packages Release . .gz .bz2
-DscIndices: Sources Release . .gz .bz2
-SignWith: %(gpg_key)s
-""" % { "gpg_key": gpg_key },
-    slavedest = 'REPO-sid/conf/distributions',
-))
-
-# add source package to repository
-reprepro_include(f, 'i3-wm*_source.changes', 'dsc')
-
-# Add keyring to the repository. We need to run git clone on our own because
-# the Git() step assumes there’s precisely one repository we want to deal with.
-# No big deal since the i3-autobuild-keyring repository is not big.
-cmd(f, name='clone keyring repo', command = 'git clone git://code.i3wm.org/i3-autobuild-keyring')
-reprepro_include(f, 'i3-autobuild-keyring/prebuilt/*.changes')
-
-for dist in distributions:
-    # update the pbuilder
-    cmd(f, name = 'update builder', command = 'pbuilder-' + dist + ' update')
-
-    # build the package for each dist
-    f.addStep(ShellCommand(
-        logEnviron = False,
-        name = 'pkg ' + dist,
-        command = 'pbuilder-' + dist + ' build --binary-arch \
---buildresult RESULT-' + dist + ' --debbuildopts -j8 i3-wm*dsc',
-        warnOnFailure = True
-    ))
-
-    reprepro_include(f, 'RESULT-' + dist + '/*.changes')
-
-# upload the sid repo
-# Since the next step is cleaning up old files, we set haltOnFailure=True -- we
-# prefer providing old packages over providing no packages at all :).
-for directory in [ 'pool', 'dists' ]:
-    f.addStep(transfer.DirectoryUpload(
-        slavesrc = 'REPO-sid/' + directory,
-        masterdest = 'htdocs/debian/sid/' + directory,
-        compress = 'bz2',
-        name = 'upload sid ' + directory,
-        haltOnFailure = True,
-    ))
-
-f.addStep(master.MasterShellCommand(
-    command = "find htdocs/debian/sid/pool -mtime +3 -exec rm '{}' \;",
-    name = 'cleanup old packages',
-))
-
-# We ensure there is an empty i18n/Index to speed up apt (so that it does not
-# try to download Translation-*)
-f.addStep(master.MasterShellCommand(
-    command = [ 'mkdir', '-p', 'htdocs/debian/sid/dists/sid/main/i18n' ],
-    name = 'create i18n folder',
-))
-f.addStep(master.MasterShellCommand(
-    command = [ 'touch', 'htdocs/debian/sid/dists/sid/main/i18n/Index' ],
-    name = 'touch i18n/Index',
-))
-
-################################################################################
-# factory: "ubuntu-packages" — builds Ubuntu (precise) packages for amd64 and i386
-################################################################################
-
-distributions = [ 'precise-amd64', 'precise-i386' ]
-gpg_key = 'BE1DB1F1'
-
-f = factories['ubuntu-packages'] = BuildFactory()
-# We need the git repository for the Debian packaging.
-f.addStep(s_git)
-unpack_dist_tarball(f)
-cmd(f, name='copy packaging', command = "cp -r debian DIST/")
-
-# Add a new changelog entry to have the git version in the package version.
-cmd(f,
-    name = 'update changelog',
-    workdir = 'build/DIST',
-    command = [ 'debchange', '-m', '-l', WithProperties('+g%(gitversion)s'), 'Automatically built' ],
-)
-
-cmd(f,
-    name = 'source pkg',
-    command = [ 'dpkg-buildpackage', '-S', '-us', '-uc' ],
-    workdir = 'build/DIST',
-)
-
-for dist in distributions:
-    f.addStep(slave.MakeDirectory(dir='build/RESULT-' + dist))
-
-# Create debian sid repository
-f.addStep(slave.MakeDirectory(dir='build/REPO-sid/conf'))
-f.addStep(transfer.StringDownload(
-    """Codename: precise
-Suite: unstable
-Architectures: i386 amd64 source
-Components: main
-DebIndices: Packages Release . .gz .bz2
-DscIndices: Sources Release . .gz .bz2
-SignWith: %(gpg_key)s
-""" % { "gpg_key": gpg_key },
-    slavedest = 'REPO-sid/conf/distributions',
-))
-
-# add source package to repository
-reprepro_include_ubuntu(f, 'i3-wm*_source.changes', 'dsc')
-
-# Add keyring to the repository. We need to run git clone on our own because
-# the Git() step assumes there’s precisely one repository we want to deal with.
-# No big deal since the i3-autobuild-keyring repository is not big.
-cmd(f, name='clone keyring repo', command = 'git clone git://code.i3wm.org/i3-autobuild-keyring')
-reprepro_include_ubuntu(f, 'i3-autobuild-keyring/prebuilt/*.changes')
-
-for dist in distributions:
-    # update the pbuilder
-    cmd(f, name = 'update builder', command = 'pbuilder-' + dist + ' update')
-
-    # build the package for each dist
-    f.addStep(ShellCommand(
-        logEnviron = False,
-        name = 'pkg ' + dist,
-        command = 'pbuilder-' + dist + ' build --binary-arch \
---buildresult RESULT-' + dist + ' --debbuildopts -j8 i3-wm*dsc',
-        warnOnFailure = True
-    ))
-
-    reprepro_include_ubuntu(f, 'RESULT-' + dist + '/*.changes')
-
-# upload the sid repo
-# Since the next step is cleaning up old files, we set haltOnFailure=True -- we
-# prefer providing old packages over providing no packages at all :).
-for directory in [ 'pool', 'dists' ]:
-    f.addStep(transfer.DirectoryUpload(
-        slavesrc = 'REPO-sid/' + directory,
-        masterdest = 'htdocs/ubuntu/precise/' + directory,
-        compress = 'bz2',
-        name = 'upload precise ' + directory,
-        haltOnFailure = True,
-    ))
-
-f.addStep(master.MasterShellCommand(
-    command = "find htdocs/ubuntu/precise/pool -mtime +3 -exec rm '{}' \;",
-    name = 'cleanup old packages',
-))
-
-# We ensure there is an empty i18n/Index to speed up apt (so that it does not
-# try to download Translation-*)
-f.addStep(master.MasterShellCommand(
-    command = [ 'mkdir', '-p', 'htdocs/ubuntu/precise/dists/sid/main/i18n' ],
-    name = 'create i18n folder',
-))
-f.addStep(master.MasterShellCommand(
-    command = [ 'touch', 'htdocs/ubuntu/precise/dists/sid/main/i18n/Index' ],
-    name = 'touch i18n/Index',
-))
-
-
-c['builders'] = []
-
-# Add all builders to all buildslaves.
-for factoryname in factories.keys():
-    c['builders'].append(BuilderConfig(
-        name = factoryname,
-        slavenames=['docsteel-vm'],
-        factory=factories[factoryname],
-    ))
-
-
-####### STATUS TARGETS
-
-c['status'] = []
-
-authz_cfg=authz.Authz(
-    gracefulShutdown = False,
-    forceBuild = False,
-    forceAllBuilds = False,
-    pingBuilder = False,
-    stopBuild = False,
-    stopAllBuilds = False,
-    cancelPendingBuild = False,
-)
-
-c['status'].append(html.WebStatus(http_port=8010, authz=authz_cfg))
-
-c['status'].append(buildbot.status.status_push.HttpStatusPush(
-    serverUrl = 'http://localhost:8080/push_buildbot',
-))
-
-####### PROJECT IDENTITY
-
-c['title'] = 'i3'
-c['titleURL'] = 'http://i3wm.org/'
-# Removed so that search engines don’t crawl it
-c['buildbotURL'] = 'http://localhost/'
-
-####### DB URL
-
-c['db'] = {
-    # This specifies what database buildbot uses to store its state.  You can leave
-    # this at its default for all but the largest installations.
-    'db_url' : "sqlite:///state.sqlite",
-}
-
-
-
-
-

- - - + + + + + + + + +The i3 buildbot setup + + + + +
+
+
+
+WARNING! +

+

+

This document is outdated and kept for “historical” reasons. i3 uses Travis as +a CI instead.

+
+

+
+
+

This document explains the buildbot setup we use to +provide up-to-date documentation and debian packages at http://build.i3wm.org/. +We publish these information so that our setup is well-documented (thus +decreasing future maintenance effort) and because it might be interesting for +other projects.

+
+
+
+
+

Introduction

+
+
+

What we are doing in i3 is called Continuous Integration (see +http://en.wikipedia.org/wiki/Continuous_integration): we publish the changes we +make on our local machines as often as possible. In order to maintain a +continuously high quality, each time any developer pushes changes to the +official git repository, a number of quality assurance tools start running +automatically:

+
+
+
    +
  1. +

    Latest documentation is generated and provided at +http://build.i3wm.org/docs/. This makes it easy to link to documentation for +features which are only in the current git version, not in the released +version.

    +
  2. +
  3. +

    The source code is compiled and it is automatically posted to the IRC +channel whether there were any compiler warnings. While developers should +notice compiler warnings, this mechanism creates a bit of public pressure +("Oh, Michael introduced warnings with this commit!"). More importantly, +since this mechanism builds a dist tarball and then compiles that tarball, +any changes to the source which would result in an uncompilable dist tarball +are immediately obvious. Therefore, we could cut a release from the current +git version at any point in time.

    +
  4. +
  5. +

    The clang static analyzer runs and the resulting report is provided at +http://build.i3wm.org/clang-analyze/. While every developer needs to compile +his code before committing, he doesn’t necessarily use clang (so we catch +build failures when using clang) and he also probably doesn’t run a static +analyzer as part of his normal workflow. By just being available without any +friction, this mechanism encourages developers to look at the report and fix +problems.

    +
  6. +
  7. +

    Debian (and Ubuntu) packages are built. This not only ensures that we don’t +change anything in the source code which would lead to an FTBFS (Fails To +Build From Source) when building a Debian package, it also goes a long way +to encourage end users to test i3. To remove the need and resource +requirements for them to compile their own version of i3 regularly, we +provide packages that integrate conveniently with a normal Debian system +(e.g. that are automatically upgraded).

    +
  8. +
+
+
+
+
+

Why buildbot?

+
+
+

Previously, I was unsatisfied with the current state of FOSS CI tools like +Jenkins, Tinderbox and others. They either seemed bloated, hard to use, +outdated or unappealing for some other reason.

+
+
+

Then I discovered buildbot and was impressed by its flexibility. It let me +implement everything I wanted from a CI tool and (in my opinion) it is +light-weight, easy to deploy and well maintained.

+
+
+

The only downside of buildbot is its configuration and documentation: You need +to spend quite a bit of time (I needed multiple days) until it works the way +you want it to and oftentimes, the documentation is far too sparse. This is one +of the reasons why I’m publishing the i3 setup.

+
+
+
+
+

Configuration

+
+
+

See the next section for a complete, copy & pasteable configuration file. This +section covers the most important aspects without covering every line.

+
+
+

This document assumes you are running buildbot 0.8.6p1.

+
+
+

Change sources

+
+

Since i3 uses a central git repository, we use the official buildbot +git +post-receive hook that sends the change information to the buildbot master.

+
+
+
+

Schedulers

+
+

There are two things (called "builders" in buildbot-language) which happen +whenever a new change in the next branch of i3 occurs:

+
+
+
    +
  1. +

    The "docs" builder builds and uploads the latest documentation. This happens +directly from the git repository with a custom asciidoc configuration which +indicates that these docs refer to the git version. Therefore, this builder +does not benefit from having a dist tarball available (contrary to the other +builders).

    +
  2. +
  3. +

    The "dist" builder prepares a dist tarball and then triggers the remaining +builders. This ensures that building the dist tarball (an operation which +takes about one minute due to documentation generation) only happens once.

    +
  4. +
+
+
+

Here is the relevant configuration part:

+
+
+

Schedulers:

+
+
+
+
c['schedulers'] = []
+
+c['schedulers'].append(SingleBranchScheduler(
+    name = 'dist',
+    branch = 'next',
+    treeStableTimer = 10,
+    builderNames = [ 'dist', 'docs' ],
+))
+
+c['schedulers'].append(Triggerable(
+    name = 'dist-tarball-done',
+    builderNames = [ 'compile', 'clang-analyze', 'debian-packages', 'ubuntu-packages' ],
+))
+
+
+
+
+

Building the dist tarball

+
+

This builder clones the i3 git repository and runs "make dist", which creates a +tarball that could be named "i3-4.2.tar.bz2" for example. This tarball is then +renamed to dist-%(gitversion).tar.bz2 (so that we can work with a predictable +name in the next steps) and uploaded to the buildbot master (since we can have +multiple buildslaves, we cannot just let it rest on the buildslave that built +it). Afterwards, old dist tarballs are cleaned up and the remaining builders +are triggered:

+
+
+

Building a dist tarball:

+
+
+
+
factories = {}
+
+f = factories['dist'] = BuildFactory()
+
+# Check out the git repository.
+f.addStep(s_git)
+
+# Fill the 'gitversion' property with the output of git describe --tags.
+f.addStep(shell.SetProperty(command = 'git describe --tags', property = 'gitversion'))
+
+# Build the dist tarball.
+cmd(f, name = 'make dist', command = [ 'make', 'dist' ])
+
+# Rename the created tarball to a well-known name.
+cmd(f,
+    name = 'rename tarball',
+    command = WithProperties('mv *.tar.bz2 dist-%(gitversion)s.tar.bz2'),
+)
+
+# Upload the dist tarball to the master (other factories download it later).
+f.addStep(transfer.FileUpload(
+    slavesrc = WithProperties('dist-%(gitversion)s.tar.bz2'),
+    masterdest = WithProperties('distballs/dist-%(gitversion)s.tar.bz2'),
+))
+
+# Cleanup old dist tarballs (everything older than tree days).
+f.addStep(master.MasterShellCommand(
+    command = "find distballs -mtime +3 -exec rm '{}' \;",
+    name = 'cleanup old dist tarballs',
+))
+
+# Everything worked fine, now trigger compilation.
+f.addStep(Trigger(
+    schedulerNames = [ 'dist-tarball-done' ],
+    copy_properties = [ 'gitversion' ],
+))
+
+
+
+

Three things are noteworthy about this part of the configuration:

+
+
+
    +
  1. +

    For convenience, we call each factory f (just like the global buildbot +config uses c for the top-level configuration) and add it to a dictionary. +Factories in that dictionary are later automatically configured for each +buildslave.

    +
  2. +
  3. +

    We have a shared step called s_git so that we only have one location in +the configuration file where we specify the git repository URL and branch.

    +
  4. +
  5. +

    We have a custom function called cmd which is a shortcut for defining a +ShellCommand with haltOnFailure=True (since each step is critical) and +logEnviron=False (for brevity).

    +
  6. +
+
+
+

Here are their definitions:

+
+
+

cmd:

+
+
+
+
def cmd(factory, **kwargs):
+    factory.addStep(ShellCommand(
+        haltOnFailure = True,
+        logEnviron = False,
+        **kwargs
+    ))
+
+
+
+

s_git:

+
+
+
+
s_git = Git(
+    repourl = 'git://code.i3wm.org/i3',
+    branch = 'next',
+
+    # Check out the latest revision, not the one which caused this build.
+    alwaysUseLatest = True,
+
+    # We cannot use shallow because it breaks git describe --tags.
+    shallow = False,
+
+    # Delete remnants of previous builds.
+    mode = 'full',
+
+    # Store checkouts in source/ and copy them over to build/ to save
+    # bandwidth.
+    method = 'copy',
+)
+
+
+
+
+

Compiling the dist tarball

+
+

For this builder to work, you obviously need to install all the +build-dependencies for your software on each buildslave. In the case of i3, +this can be done with apt-get build-dep i3-wm.

+
+
+

The compilation is pretty straight-forward since it uses the builtin Compile +step. We call make with -j4 (we don’t have enough buildslaves to make +figuring out the amount of cores at build-time worthwhile) and DEBUG=0 to +simulate release build conditions. Also, we pass the preprocessor flag +-D_FORTIFY_SOURCE=2 and the compiler flags -Wformat and -Wformat-security +to enable additional warnings.

+
+
+

Compiling the dist tarball:

+
+
+
+
f = factories['compile'] = BuildFactory()
+unpack_dist_tarball(f)
+f.addStep(Compile(
+    command = [ 'make', 'DEBUG=0', '-j4' ],
+    warningPattern = '.*warning: ',
+    warnOnWarnings = True,
+    workdir = 'build/DIST',
+    env = {
+      'CPPFLAGS': '-D_FORTIFY_SOURCE=2',
+      'CFLAGS': '-Wformat -Wformat-security'
+    },
+))
+
+f.addStep(WarningsToIRC())
+
+
+
+

Again, we use custom functions (and a custom buildstep) to make our lives +easier. Here is the definition of unpack_dist_tarball which adds three steps to +the factory that download and unpack the dist tarball to the DIST/ directory:

+
+
+

unpack_dist_tarball:

+
+
+
+
def unpack_dist_tarball(factory):
+    factory.addStep(transfer.FileDownload(
+        mastersrc = WithProperties('distballs/dist-%(gitversion)s.tar.bz2'),
+        slavedest = 'dist.tar.bz2',
+    ))
+
+    factory.addStep(slave.MakeDirectory(dir = 'build/DIST'))
+
+    cmd(factory,
+        name = 'unpack dist tarball',
+        command = [ 'tar', 'xf', 'dist.tar.bz2', '-C', 'DIST', '--strip-components=1' ],
+    )
+
+
+
+

The WarningsToIRC build step is a custom build step which sets a property +called "ircsuffix" that is used by our custom IRC bot. This is covered later in +more detail. This property gets set to a green or red message, depending on +whether there were any warnings:

+
+
+

WarningsToIRC:

+
+
+
+
class WarningsToIRC(buildstep.BuildStep):
+    def start(self):
+        warnings = self.getProperty("warnings-count")
+        if warnings is not None and int(warnings) > 0:
+            warnings = int(warnings)  # just to be sure
+            self.setProperty("ircsuffix", ("\0037 with %d warning%s!" %
+	        (warnings, "s" if warnings != 1 else "")))
+        else:
+            self.setProperty("ircsuffix", "\0033 without warnings")
+        self.finished(SUCCESS)
+
+
+
+
+

Static code analysis

+
+

For this builder to work, you additionally need the clang compiler on each +buildslave: apt-get install clang.

+
+
+

This builder uses only custom functions which you already know by now. It runs +scan-build, then moves scan-build’s output from a date-based directory directly +into the CLANG/ directory and uploads that to the buildmaster.

+
+
+

On the buildmaster, a webserver is configured which has a symlink to +/home/build/i3-master/htdocs/clang-analyze in its document root.

+
+
+

static code analysis:

+
+
+
+
f = factories['clang-analyze'] = BuildFactory()
+unpack_dist_tarball(f)
+cmd(f,
+    name='analyze',
+    command = [
+        'scan-build',
+        '-o', '../CLANG',
+        '--html-title', WithProperties('Analysis of i3 v%(gitversion)s'),
+        'make', '-j8',
+    ],
+    workdir = 'build/DIST',
+)
+
+# remove the subdirectory -- we always want to overwrite
+cmd(f, command = 'mv CLANG/*/* CLANG/')
+
+f.addStep(transfer.DirectoryUpload(
+    slavesrc = 'CLANG',
+    masterdest = 'htdocs/clang-analyze',
+    compress = 'bz2',
+    name = 'upload output',
+))
+
+f.addStep(ClangToIRC())
+
+
+
+

The ClangToIRC custom step is even simpler than WarningsToIRC. It simply +sets the ircsuffix property to a static message:

+
+
+

ClangToIRC:

+
+
+
+
class ClangToIRC(buildstep.BuildStep):
+    def start(self):
+        self.setProperty("ircsuffix", ", see http://build.i3wm.org/clang-analyze/")
+        self.finished(SUCCESS)
+
+
+
+
+

Generating documentation

+
+

This builder is the one which is the least clean of all. It uses the Debian +packaging information to decide which docs to publish and which manpages to +generate. Additionally, it uses a for loop instead of calling a script. I +recommend including a script to do this in your repository instead.

+
+
+

Apart from these concerns, the builder is straight-forward: It clones the git +repository, generates the documentation and then uploads the documentation to +the buildmaster:

+
+
+

Generating documentation:

+
+
+
+
f = factories['docs'] = BuildFactory()
+f.addStep(s_git)
+# Fill the 'gitversion' property with the output of git describe --tags.
+f.addStep(shell.SetProperty(command = 'git describe --tags', property = 'gitversion'))
+cmd(f, name = 'build docs', command = [ 'make', '-C', 'docs', "ASCIIDOC=asciidoc -a linkcss -a stylesdir=http://i3wm.org/css -a scriptsdir=http://i3wm.org/js --backend=xhtml11 -f docs/asciidoc-git.conf" ])
+cmd(f, name = 'build manpages', command = "for file in $(sed 's/\.1$/.man/g' debian/i3-wm.manpages); do asciidoc -a linkcss -a stylesdir=http://i3wm.org/css -a scriptsdir=http://i3wm.org/js --backend=xhtml11 -f docs/asciidoc-git.conf \"$file\"; done")
+f.addStep(slave.MakeDirectory(dir='build/COPY-DOCS'))
+cmd(f, name = 'copy docs', command = "cp $(tr '\\n' ' ' < debian/i3-wm.docs) COPY-DOCS")
+cmd(f, name = 'copy manpages', command = "cp $(sed 's/\.1$/.html/g' debian/i3-wm.manpages | tr '\\n' ' ') COPY-DOCS")
+
+f.addStep(transfer.DirectoryUpload(
+    slavesrc = 'COPY-DOCS',
+    masterdest = 'htdocs/docs-git',
+    compress = 'bz2',
+    name = 'upload docs'))
+
+f.addStep(DocsToIRC())
+
+
+
+

Just as ClangToIRC, DocsToIRC appends a static message:

+
+
+

DocsToIRC:

+
+
+
+
class DocsToIRC(buildstep.BuildStep):
+    def start(self):
+        self.setProperty("ircsuffix", ", see http://build.i3wm.org/docs/")
+        self.finished(SUCCESS)
+
+
+
+
+

Building Debian/Ubuntu packages

+
+

This is the most complex builder of all. It uses pbuilder-dist, debchange, +dpkg-buildpackage and reprepro to generate a Debian repository with a +cleanly compiled package for amd64 and i386. In order for it to work, you need +to install the following packages: apt-get install devscripts dpkg-dev +reprepro ubuntu-dev-tools pbuilder. Afterwards, you need to allow the user as +which the buildslave runs to execute pbuilder via sudo without needing a +password, so add a config file like this one:

+
+
+

sudoers.d:

+
+
+
+
echo 'build    ALL= NOPASSWD: SETENV: /usr/sbin/pbuilder' > /etc/sudoers.d/build
+
+
+
+

Then, as the user as which your buildslave runs, setup the pbuilder +environments (you only need to do this once):

+
+
+

pbuilder preparation:

+
+
+
+
sudo ln -s pbuilder-dist /usr/bin/pbuilder-sid-amd64
+sudo ln -s pbuilder-dist /usr/bin/pbuilder-sid-i386
+pbuilder-sid-amd64 create
+pbuilder-sid-i386 create
+
+
+
+

Also, you will need a GPG key to sign these packages.

+
+
+

The debian builder starts by unpacking the dist tarball, copying the Debian +packaging from git, creating an empty Debian repository with the +i3-autobuild-keyring contents in it. It then adds a new changelog entry to +reflect the git version and the fact that this package was built automatically, +builds a source package with dpkg-buildpackage and adds it to the repository. +Afterwards, it updates each pbuilder and builds binary packages for each +architecture (amd64 and i386). After adding the resulting packages to the +repository, it uploads the repository to the buildmaster:

+
+
+

Debian builder:

+
+
+
+
distributions = [ 'sid-amd64', 'sid-i386' ]
+gpg_key = 'BE1DB1F1'
+
+f = factories['debian-packages'] = BuildFactory()
+# We need the git repository for the Debian packaging.
+f.addStep(s_git)
+unpack_dist_tarball(f)
+cmd(f, name = 'copy packaging', command = "cp -r debian DIST/")
+
+# Add a new changelog entry to have the git version in the package version.
+cmd(f,
+    name = 'update changelog',
+    workdir = 'build/DIST',
+    command = [ 'debchange', '-m', '-l', WithProperties('+g%(gitversion)s'), 'Automatically built' ],
+)
+
+cmd(f,
+    name = 'source pkg',
+    command = [ 'dpkg-buildpackage', '-S', '-us', '-uc' ],
+    workdir = 'build/DIST',
+)
+
+for dist in distributions:
+    f.addStep(slave.MakeDirectory(dir = 'build/RESULT-' + dist))
+
+# Create debian sid repository
+f.addStep(slave.MakeDirectory(dir = 'build/REPO-sid/conf'))
+f.addStep(transfer.StringDownload(
+    """Codename: sid
+Suite: unstable
+Architectures: i386 amd64 source
+Components: main
+DebIndices: Packages Release . .gz .bz2
+DscIndices: Sources Release . .gz .bz2
+SignWith: %(gpg_key)s
+""" % { "gpg_key": gpg_key },
+    slavedest = 'REPO-sid/conf/distributions',
+))
+
+# add source package to repository
+reprepro_include(f, 'i3-wm*_source.changes', 'dsc')
+
+# Add keyring to the repository. We need to run git clone on our own because
+# the Git() step assumes there’s precisely one repository we want to deal with.
+# No big deal since the i3-autobuild-keyring repository is not big.
+cmd(f,
+    name = 'clone keyring repo',
+    command = 'git clone git://code.i3wm.org/i3-autobuild-keyring',
+)
+reprepro_include(f, 'i3-autobuild-keyring/prebuilt/*.changes')
+
+for dist in distributions:
+    # update the pbuilder
+    cmd(f, name = 'update builder', command = 'pbuilder-' + dist + ' update')
+
+    # build the package for each dist
+    f.addStep(ShellCommand(
+        logEnviron = False,
+        name = 'pkg ' + dist,
+        command = 'pbuilder-' + dist + ' build --binary-arch \
+--buildresult RESULT-' + dist + ' --debbuildopts -j8 i3-wm*dsc',
+        warnOnFailure = True
+    ))
+
+    reprepro_include(f, 'RESULT-' + dist + '/*.changes')
+
+# upload the sid repo
+# Since the next step is cleaning up old files, we set haltOnFailure=True -- we
+# prefer providing old packages over providing no packages at all :).
+for directory in [ 'pool', 'dists' ]:
+    f.addStep(transfer.DirectoryUpload(
+        slavesrc = 'REPO-sid/' + directory,
+        masterdest = 'htdocs/debian/sid/' + directory,
+        compress = 'bz2',
+        name = 'upload sid ' + directory,
+        haltOnFailure = True,
+    ))
+
+f.addStep(master.MasterShellCommand(
+    command = "find htdocs/debian/sid/pool -mtime +3 -exec rm '{}' \;",
+    name = 'cleanup old packages',
+))
+
+# We ensure there is an empty i18n/Index to speed up apt (so that it does not
+# try to download Translation-*)
+f.addStep(master.MasterShellCommand(
+    command = [ 'mkdir', '-p', 'htdocs/debian/sid/dists/sid/main/i18n' ],
+    name = 'create i18n folder',
+))
+f.addStep(master.MasterShellCommand(
+    command = [ 'touch', 'htdocs/debian/sid/dists/sid/main/i18n/Index' ],
+    name = 'touch i18n/Index',
+))
+
+
+
+

The reprepro_include command is defined as follows:

+
+
+

reprepro_include:

+
+
+
+
def reprepro_include(factory, path, debtype='deb', **kwargs):
+    cmd(factory,
+        name = 'reprepro include',
+        command = 'reprepro --ignore=wrongdistribution -T ' + debtype + ' -b REPO-sid include sid ' + path,
+        **kwargs
+    )
+
+
+
+

Running such a builder for Ubuntu works exactly the same way, but you need to +replace "sid" with "precise" in all places (see the full configuration file for +an example).

+
+
+
+

Status targets

+
+

We don’t advertise the HTTP status target. Instead, status is posted to IRC via +a custom bot. This bot provides an HTTP end point and buildbot is configured to +push status changes to that endpoint:

+
+
+

http status target:

+
+
+
+
c['status'].append(buildbot.status.status_push.HttpStatusPush(
+    serverUrl = 'http://localhost:8080/push_buildbot',
+))
+
+
+
+

You can find the source code of that bot at +http://code.stapelberg.de/git/go-buildbot-announce/. As the name suggests, it +is written in Go. Also, it is quite specific to i3, so you might be better off +implementing such a bot (or plugin) on your own. It might make for a nice +example, though, especially back when its only feature was announcing the build +status:

+
+ +
+
+

Creating the buildslave

+
+

One more thing to note is that when creating the buildslave, you should use the +--umask argument to configure the umask for all generated files:

+
+
+

Creating the buildslave:

+
+
+
+
buildslave create-slave --umask=022 i3-buildslave buildbot.i3wm.org build-1 <password>
+
+
+
+
+
+
+

Full configuration file

+
+
+

This is the full configuration file, as tested and currently in use (except for +the passwords, though):

+
+
+

master.cfg:

+
+
+
+
# -*- python -*-
+# -*- coding: utf-8
+# vim:ts=4:sw=4:expandtab:syntax=python
+#
+# i3 buildbot configuration
+# © 2012 Michael Stapelberg, Public Domain
+# see http://i3wm.org/docs/buildbot.html for more information.
+
+from buildbot.buildslave import BuildSlave
+from buildbot.changes import pb
+from buildbot.schedulers.basic import SingleBranchScheduler
+from buildbot.schedulers.triggerable import Triggerable
+from buildbot.process.properties import WithProperties
+from buildbot.process.factory import BuildFactory
+from buildbot.steps.source.git import Git
+from buildbot.steps.shell import ShellCommand
+from buildbot.steps.shell import Compile
+from buildbot.steps.trigger import Trigger
+from buildbot.steps import shell, transfer, master, slave
+from buildbot.config import BuilderConfig
+from buildbot.process import buildstep
+from buildbot.status import html
+from buildbot.status import words
+import buildbot.status.status_push
+from buildbot.status.web import auth, authz
+from buildbot.status.builder import SUCCESS, FAILURE
+
+c = BuildmasterConfig = {}
+
+c['slaves'] = [BuildSlave('docsteel-vm', 'secret')]
+c['slavePortnum'] = 9989
+# Changes are pushed to buildbot using a git hook.
+c['change_source'] = [pb.PBChangeSource(
+    user = 'i3-source',
+    passwd = 'secret',
+)]
+
+################################################################################
+# schedulers
+################################################################################
+
+c['schedulers'] = []
+
+# The first scheduler kicks off multiple builders:
+# • 'dist' builds a dist tarball and starts the triggerable schedulers
+#   'compile'
+# • 'docs' builds the documentation with a special asciidoc configuration
+#   (therefore, it does not profit from a dist tarball and can be run in
+#    parallel).
+c['schedulers'].append(SingleBranchScheduler(
+    name = 'dist',
+    branch = 'next',
+    treeStableTimer = 10,
+    builderNames = [ 'dist', 'docs' ],
+))
+
+c['schedulers'].append(Triggerable(
+    name = 'dist-tarball-done',
+    builderNames = [ 'compile', 'clang-analyze', 'debian-packages', 'ubuntu-packages' ],
+))
+
+################################################################################
+# Shortcuts for builders
+################################################################################
+
+# shortcut for a ShellCommand with haltOnFailure=True, logEnviron=False
+def cmd(factory, **kwargs):
+    factory.addStep(ShellCommand(
+        haltOnFailure=True,
+        logEnviron=False,
+        **kwargs
+    ))
+
+# Shortcut to add steps necessary to download and unpack the dist tarball.
+def unpack_dist_tarball(factory):
+    factory.addStep(transfer.FileDownload(
+        mastersrc=WithProperties('distballs/dist-%(gitversion)s.tar.bz2'),
+        slavedest='dist.tar.bz2',
+    ))
+    factory.addStep(slave.MakeDirectory(dir='build/DIST'))
+    cmd(factory,
+        name = 'unpack dist tarball',
+        command = [ 'tar', 'xf', 'dist.tar.bz2', '-C', 'DIST', '--strip-components=1' ],
+    )
+
+# Includes the given path in REPO-sid using reprepro.
+def reprepro_include(factory, path, debtype='deb', **kwargs):
+    cmd(factory,
+        name = 'reprepro include',
+        command = 'reprepro --ignore=wrongdistribution -T ' + debtype + ' -b REPO-sid include sid ' + path,
+        **kwargs
+    )
+
+def reprepro_include_ubuntu(factory, path, debtype='deb', **kwargs):
+    cmd(factory,
+        name = 'reprepro include',
+        command = 'reprepro --ignore=wrongdistribution -T ' + debtype + ' -b REPO-sid include precise ' + path,
+        **kwargs
+    )
+
+################################################################################
+# Custom steps
+################################################################################
+
+# Adds the ircsuffix property to reflect whether there were warnings.
+class WarningsToIRC(buildstep.BuildStep):
+  def start(self):
+    warnings = self.getProperty("warnings-count")
+    if warnings is not None and int(warnings) > 0:
+      warnings = int(warnings)  # just to be sure
+      self.setProperty("ircsuffix", "\0037 with %d warning%s!" % (warnings, "s" if warnings != 1 else ""))
+    else:
+      self.setProperty("ircsuffix", "\0033 without warnings")
+    self.finished(SUCCESS)
+
+# Adds a link to the automatically generated documentation.
+class DocsToIRC(buildstep.BuildStep):
+  def start(self):
+    self.setProperty("ircsuffix", ", see http://build.i3wm.org/docs/")
+    self.finished(SUCCESS)
+
+# Adds a link to the clang report.
+class ClangToIRC(buildstep.BuildStep):
+  def start(self):
+    self.setProperty("ircsuffix", ", see http://build.i3wm.org/clang-analyze/")
+    self.finished(SUCCESS)
+
+################################################################################
+# Shared steps, used in different factories.
+################################################################################
+
+s_git = Git(
+    repourl='git://code.i3wm.org/i3',
+    branch='next',
+
+    # Check out the latest revision, not the one which caused this build.
+    alwaysUseLatest=True,
+
+    # We cannot use shallow because it breaks git describe --tags.
+    shallow=False,
+
+    # Delete remnants of previous builds.
+    mode='full',
+
+    # Store checkouts in source/ and copy them over to build/ to save
+    # bandwidth.
+    method='copy',
+
+    # XXX: In newer versions of buildbot (> 0.8.6), we want to use
+    # getDescription={ 'tags': True } here and get rid of the extra git
+    # describe --tags step.
+)
+
+################################################################################
+# factory: "dist" — builds the dist tarball once (used by all other factories)
+################################################################################
+
+factories = {}
+
+f = factories['dist'] = BuildFactory()
+# Check out the git repository.
+f.addStep(s_git)
+# Fill the 'gitversion' property with the output of git describe --tags.
+f.addStep(shell.SetProperty(command = 'git describe --tags', property = 'gitversion'))
+# Build the dist tarball.
+cmd(f, name = 'make dist', command = [ 'make', 'dist' ])
+# Rename the created tarball to a well-known name.
+cmd(f, name = 'rename tarball', command = WithProperties('mv *.tar.bz2 dist-%(gitversion)s.tar.bz2'))
+# Upload the dist tarball to the master (other factories download it later).
+f.addStep(transfer.FileUpload(
+    slavesrc = WithProperties('dist-%(gitversion)s.tar.bz2'),
+    masterdest = WithProperties('distballs/dist-%(gitversion)s.tar.bz2'),
+))
+# Cleanup old dist tarballs (everything older than tree days).
+f.addStep(master.MasterShellCommand(
+    command = "find distballs -mtime +3 -exec rm '{}' \;",
+    name = 'cleanup old dist tarballs',
+))
+# Everything worked fine, now trigger compilation.
+f.addStep(Trigger(
+    schedulerNames = [ 'dist-tarball-done' ],
+    copy_properties = [ 'gitversion' ],
+))
+
+################################################################################
+# factory: "compile" — compiles the dist tarball and reports warnings
+################################################################################
+
+f = factories['compile'] = BuildFactory()
+unpack_dist_tarball(f)
+f.addStep(Compile(
+    command = [ 'make', 'DEBUG=0', '-j4' ],
+    warningPattern = '.*warning: ',
+    warnOnWarnings = True,
+    workdir = 'build/DIST',
+    env = {
+      'CPPFLAGS': '-D_FORTIFY_SOURCE=2',
+      'CFLAGS': '-Wformat -Wformat-security'
+    },
+))
+
+f.addStep(WarningsToIRC())
+
+################################################################################
+# factory: "clang-analyze" — runs a static code analysis
+################################################################################
+# $ sudo apt-get install clang
+
+f = factories['clang-analyze'] = BuildFactory()
+unpack_dist_tarball(f)
+cmd(f,
+    name='analyze',
+    command = [
+        'scan-build',
+        '-o', '../CLANG',
+        '--html-title', WithProperties('Analysis of i3 v%(gitversion)s'),
+        'make', '-j8',
+    ],
+    workdir = 'build/DIST',
+)
+
+# remove the subdirectory -- we always want to overwrite
+cmd(f, command = 'mv CLANG/*/* CLANG/')
+
+f.addStep(transfer.DirectoryUpload(
+    slavesrc = 'CLANG',
+    masterdest = 'htdocs/clang-analyze',
+    compress = 'bz2',
+    name = 'upload output',
+))
+
+f.addStep(ClangToIRC())
+
+################################################################################
+# factory: "docs" — builds documentation with a special asciidoc conf
+################################################################################
+
+f = factories['docs'] = BuildFactory()
+f.addStep(s_git)
+# Fill the 'gitversion' property with the output of git describe --tags.
+f.addStep(shell.SetProperty(command = 'git describe --tags', property = 'gitversion'))
+cmd(f, name = 'build docs', command = [ 'make', '-C', 'docs', "ASCIIDOC=asciidoc -a linkcss -a stylesdir=http://i3wm.org/css -a scriptsdir=http://i3wm.org/js --backend=xhtml11 -f docs/asciidoc-git.conf" ])
+cmd(f, name = 'build manpages', command = "for file in $(sed 's/\.1$/.man/g' debian/i3-wm.manpages); do asciidoc -a linkcss -a stylesdir=http://i3wm.org/css -a scriptsdir=http://i3wm.org/js --backend=xhtml11 -f docs/asciidoc-git.conf \"$file\"; done")
+f.addStep(slave.MakeDirectory(dir='build/COPY-DOCS'))
+cmd(f, name = 'copy docs', command = "cp $(tr '\\n' ' ' < debian/i3-wm.docs) COPY-DOCS")
+cmd(f, name = 'copy manpages', command = "cp $(sed 's/\.1$/.html/g' debian/i3-wm.manpages | tr '\\n' ' ') COPY-DOCS")
+
+f.addStep(transfer.DirectoryUpload(
+    slavesrc = 'COPY-DOCS',
+    masterdest = 'htdocs/docs-git',
+    compress = 'bz2',
+    name = 'upload docs'))
+
+f.addStep(DocsToIRC())
+
+################################################################################
+# factory: "debian-packages" — builds Debian (sid) packages for amd64 and i386
+################################################################################
+
+distributions = [ 'sid-amd64', 'sid-i386' ]
+gpg_key = 'BE1DB1F1'
+
+f = factories['debian-packages'] = BuildFactory()
+# We need the git repository for the Debian packaging.
+f.addStep(s_git)
+unpack_dist_tarball(f)
+cmd(f, name='copy packaging', command = "cp -r debian DIST/")
+
+# Add a new changelog entry to have the git version in the package version.
+cmd(f,
+    name = 'update changelog',
+    workdir = 'build/DIST',
+    command = [ 'debchange', '-m', '-l', WithProperties('+g%(gitversion)s'), 'Automatically built' ],
+)
+
+cmd(f,
+    name = 'source pkg',
+    command = [ 'dpkg-buildpackage', '-S', '-us', '-uc' ],
+    workdir = 'build/DIST',
+)
+
+for dist in distributions:
+    f.addStep(slave.MakeDirectory(dir='build/RESULT-' + dist))
+
+# Create debian sid repository
+f.addStep(slave.MakeDirectory(dir='build/REPO-sid/conf'))
+f.addStep(transfer.StringDownload(
+    """Codename: sid
+Suite: unstable
+Architectures: i386 amd64 source
+Components: main
+DebIndices: Packages Release . .gz .bz2
+DscIndices: Sources Release . .gz .bz2
+SignWith: %(gpg_key)s
+""" % { "gpg_key": gpg_key },
+    slavedest = 'REPO-sid/conf/distributions',
+))
+
+# add source package to repository
+reprepro_include(f, 'i3-wm*_source.changes', 'dsc')
+
+# Add keyring to the repository. We need to run git clone on our own because
+# the Git() step assumes there’s precisely one repository we want to deal with.
+# No big deal since the i3-autobuild-keyring repository is not big.
+cmd(f, name='clone keyring repo', command = 'git clone git://code.i3wm.org/i3-autobuild-keyring')
+reprepro_include(f, 'i3-autobuild-keyring/prebuilt/*.changes')
+
+for dist in distributions:
+    # update the pbuilder
+    cmd(f, name = 'update builder', command = 'pbuilder-' + dist + ' update')
+
+    # build the package for each dist
+    f.addStep(ShellCommand(
+        logEnviron = False,
+        name = 'pkg ' + dist,
+        command = 'pbuilder-' + dist + ' build --binary-arch \
+--buildresult RESULT-' + dist + ' --debbuildopts -j8 i3-wm*dsc',
+        warnOnFailure = True
+    ))
+
+    reprepro_include(f, 'RESULT-' + dist + '/*.changes')
+
+# upload the sid repo
+# Since the next step is cleaning up old files, we set haltOnFailure=True -- we
+# prefer providing old packages over providing no packages at all :).
+for directory in [ 'pool', 'dists' ]:
+    f.addStep(transfer.DirectoryUpload(
+        slavesrc = 'REPO-sid/' + directory,
+        masterdest = 'htdocs/debian/sid/' + directory,
+        compress = 'bz2',
+        name = 'upload sid ' + directory,
+        haltOnFailure = True,
+    ))
+
+f.addStep(master.MasterShellCommand(
+    command = "find htdocs/debian/sid/pool -mtime +3 -exec rm '{}' \;",
+    name = 'cleanup old packages',
+))
+
+# We ensure there is an empty i18n/Index to speed up apt (so that it does not
+# try to download Translation-*)
+f.addStep(master.MasterShellCommand(
+    command = [ 'mkdir', '-p', 'htdocs/debian/sid/dists/sid/main/i18n' ],
+    name = 'create i18n folder',
+))
+f.addStep(master.MasterShellCommand(
+    command = [ 'touch', 'htdocs/debian/sid/dists/sid/main/i18n/Index' ],
+    name = 'touch i18n/Index',
+))
+
+################################################################################
+# factory: "ubuntu-packages" — builds Ubuntu (precise) packages for amd64 and i386
+################################################################################
+
+distributions = [ 'precise-amd64', 'precise-i386' ]
+gpg_key = 'BE1DB1F1'
+
+f = factories['ubuntu-packages'] = BuildFactory()
+# We need the git repository for the Debian packaging.
+f.addStep(s_git)
+unpack_dist_tarball(f)
+cmd(f, name='copy packaging', command = "cp -r debian DIST/")
+
+# Add a new changelog entry to have the git version in the package version.
+cmd(f,
+    name = 'update changelog',
+    workdir = 'build/DIST',
+    command = [ 'debchange', '-m', '-l', WithProperties('+g%(gitversion)s'), 'Automatically built' ],
+)
+
+cmd(f,
+    name = 'source pkg',
+    command = [ 'dpkg-buildpackage', '-S', '-us', '-uc' ],
+    workdir = 'build/DIST',
+)
+
+for dist in distributions:
+    f.addStep(slave.MakeDirectory(dir='build/RESULT-' + dist))
+
+# Create debian sid repository
+f.addStep(slave.MakeDirectory(dir='build/REPO-sid/conf'))
+f.addStep(transfer.StringDownload(
+    """Codename: precise
+Suite: unstable
+Architectures: i386 amd64 source
+Components: main
+DebIndices: Packages Release . .gz .bz2
+DscIndices: Sources Release . .gz .bz2
+SignWith: %(gpg_key)s
+""" % { "gpg_key": gpg_key },
+    slavedest = 'REPO-sid/conf/distributions',
+))
+
+# add source package to repository
+reprepro_include_ubuntu(f, 'i3-wm*_source.changes', 'dsc')
+
+# Add keyring to the repository. We need to run git clone on our own because
+# the Git() step assumes there’s precisely one repository we want to deal with.
+# No big deal since the i3-autobuild-keyring repository is not big.
+cmd(f, name='clone keyring repo', command = 'git clone git://code.i3wm.org/i3-autobuild-keyring')
+reprepro_include_ubuntu(f, 'i3-autobuild-keyring/prebuilt/*.changes')
+
+for dist in distributions:
+    # update the pbuilder
+    cmd(f, name = 'update builder', command = 'pbuilder-' + dist + ' update')
+
+    # build the package for each dist
+    f.addStep(ShellCommand(
+        logEnviron = False,
+        name = 'pkg ' + dist,
+        command = 'pbuilder-' + dist + ' build --binary-arch \
+--buildresult RESULT-' + dist + ' --debbuildopts -j8 i3-wm*dsc',
+        warnOnFailure = True
+    ))
+
+    reprepro_include_ubuntu(f, 'RESULT-' + dist + '/*.changes')
+
+# upload the sid repo
+# Since the next step is cleaning up old files, we set haltOnFailure=True -- we
+# prefer providing old packages over providing no packages at all :).
+for directory in [ 'pool', 'dists' ]:
+    f.addStep(transfer.DirectoryUpload(
+        slavesrc = 'REPO-sid/' + directory,
+        masterdest = 'htdocs/ubuntu/precise/' + directory,
+        compress = 'bz2',
+        name = 'upload precise ' + directory,
+        haltOnFailure = True,
+    ))
+
+f.addStep(master.MasterShellCommand(
+    command = "find htdocs/ubuntu/precise/pool -mtime +3 -exec rm '{}' \;",
+    name = 'cleanup old packages',
+))
+
+# We ensure there is an empty i18n/Index to speed up apt (so that it does not
+# try to download Translation-*)
+f.addStep(master.MasterShellCommand(
+    command = [ 'mkdir', '-p', 'htdocs/ubuntu/precise/dists/sid/main/i18n' ],
+    name = 'create i18n folder',
+))
+f.addStep(master.MasterShellCommand(
+    command = [ 'touch', 'htdocs/ubuntu/precise/dists/sid/main/i18n/Index' ],
+    name = 'touch i18n/Index',
+))
+
+
+c['builders'] = []
+
+# Add all builders to all buildslaves.
+for factoryname in factories.keys():
+    c['builders'].append(BuilderConfig(
+        name = factoryname,
+        slavenames=['docsteel-vm'],
+        factory=factories[factoryname],
+    ))
+
+
+####### STATUS TARGETS
+
+c['status'] = []
+
+authz_cfg=authz.Authz(
+    gracefulShutdown = False,
+    forceBuild = False,
+    forceAllBuilds = False,
+    pingBuilder = False,
+    stopBuild = False,
+    stopAllBuilds = False,
+    cancelPendingBuild = False,
+)
+
+c['status'].append(html.WebStatus(http_port=8010, authz=authz_cfg))
+
+c['status'].append(buildbot.status.status_push.HttpStatusPush(
+    serverUrl = 'http://localhost:8080/push_buildbot',
+))
+
+####### PROJECT IDENTITY
+
+c['title'] = 'i3'
+c['titleURL'] = 'http://i3wm.org/'
+# Removed so that search engines don’t crawl it
+c['buildbotURL'] = 'http://localhost/'
+
+####### DB URL
+
+c['db'] = {
+    # This specifies what database buildbot uses to store its state.  You can leave
+    # this at its default for all but the largest installations.
+    'db_url' : "sqlite:///state.sqlite",
+}
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/docs/debugging-release-version.html b/docs/debugging-release-version.html index ca8abaf..945cd83 100644 --- a/docs/debugging-release-version.html +++ b/docs/debugging-release-version.html @@ -1,181 +1,221 @@ - - - - - - -i3: Debugging i3: How To (release version) - - - - - - -
- - -
-
- - -

Debugging i3: How To (release version)

-Michael Stapelberg
-<michael@i3wm.org>
-February 2012 - -
-
-

This document describes how to debug i3 suitably for sending us useful bug -reports, even if you have no clue of C programming.

-

First of all: Thank you for being interested in debugging i3. It really means -something to us to get your bug fixed. If you have any questions about the -debugging and/or need further help, do not hesitate to contact us!

-
- - - -
-
Note
-
This document is for the release version of i3. If you are using a -development version, please see Debugging i3: How To -instead.
-
-
-
-
-

1. Consider using the development version

-
-

This document is for the release version of i3. In many cases, bugs are already -fixed in the development version of i3. If they aren’t, we will still ask you -to reproduce your error with the most recent development version of i3. -Therefore, please upgrade to a development version and continue reading at -Debugging i3: How To.

-

If you absolutely cannot upgrade to a development version of i3, you may -continue reading this document.

-
-
-
-

2. Enabling logging

-
-

i3 logs useful information to stdout. To have a clearly defined place where log -files will be saved, you should redirect stdout and stderr in your -~/.xsession. While you’re at it, putting each run of i3 in a separate log -file with date/time in its filename is a good idea to not get confused about -the different log files later on.

-
-
-
exec /usr/bin/i3 >~/i3log-$(date +'%F-%k-%M-%S') 2>&1
-
-

To enable verbose output and all levels of debug output (required when -attaching logfiles to bugreports), add the parameters -V -d all, like this:

-
-
-
exec /usr/bin/i3 -V -d all >~/i3log-$(date +'%F-%k-%M-%S') 2>&1
-
-
-
-
-

3. Enabling core dumps

-
-

When i3 crashes, often you have the chance of getting a core dump (an image -of the memory of the i3 process which can be loaded into a debugger). To get a -core dump, you have to make sure that the user limit for core dump files is set -high enough. Many systems ship with a default value which even forbids core -dumps completely. To disable the limit completely and thus enable core dumps, -use the following command (in your ~/.xsession, before starting i3):

-
-
-
ulimit -c unlimited
-
-

Furthermore, to easily recognize core dumps and allow multiple of them, you -should set a custom core dump filename pattern, using a command like the -following:

-
-
-
sudo sysctl -w kernel.core_pattern=core.%e.%p
-
-

This will generate files which have the executable’s file name (%e) and the -process id (%p) in it. You can save this setting across reboots using -/etc/sysctl.conf.

-
-
-
-

4. Compiling with debug symbols

-
-

To actually get useful core dumps, you should make sure that your version of i3 -is compiled with debug symbols, that is, that the symbols are not stripped -during the build process. You can check whether your executable contains -symbols by issuing the following command:

-
-
-
file $(which i3)
-
-

You should get an output like this:

-
-
-
/usr/bin/i3: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically
-linked (uses shared libs), for GNU/Linux 2.6.18, not stripped
-
-

Notice the not stripped, which is the important part. If you have a version -which is stripped, please have a look if your distribution provides debug -symbols (package i3-wm-dbg on Debian for example) or if you can turn off -stripping. If nothing helps, please build i3 from source.

-
-
-
-

5. Generating a backtrace

-
-

Once you have made sure that your i3 is compiled with debug symbols and that -core dumps are enabled, you can start making sense out of the core dumps.

-

Because the core dump depends on the original executable (and its debug -symbols), please do this as soon as you encounter the problem. If you -re-compile i3, your core dump might be useless afterwards.

-

Please install gdb, a debugger for C. No worries, you don’t need to learn it -now. Start gdb using the following command (replacing the actual name of the -core dump of course):

-
-
-
gdb $(which i3) core.i3.3849
-
-

Then, generate a backtrace using:

-
-
-
backtrace full
-
-
-
-
-

6. Sending bug reports/debugging on IRC

-
-

When sending bug reports, please paste the relevant part of the log (if in -doubt, please send us rather too much information than too less) and the whole -backtrace (if there was a core dump).

-

When debugging with us in IRC, be prepared to use a so called nopaste service -such as http://nopaste.info or http://pastebin.com because pasting large -amounts of text in IRC sometimes leads to incomplete lines (servers have line -length limitations) or flood kicks.

-
-
-
-

- - - + + + + + + + + +Debugging i3: How To (release version) + + + + +
+
+
+
+

This document describes how to debug i3 suitably for sending us useful bug +reports, even if you have no clue of C programming.

+
+
+

First of all: Thank you for being interested in debugging i3. It really means +something to us to get your bug fixed. If you have any questions about the +debugging and/or need further help, do not hesitate to contact us!

+
+
+ + + + + +
+
Note
+
+This document is for the release version of i3. If you are using a +development version, please see Debugging i3: How To +instead. +
+
+
+
+
+

Consider using the development version

+
+
+

This document is for the release version of i3. In many cases, bugs are already +fixed in the development version of i3. If they aren’t, we will still ask you +to reproduce your error with the most recent development version of i3. +Therefore, please upgrade to a development version and continue reading at +Debugging i3: How To.

+
+
+

If you absolutely cannot upgrade to a development version of i3, you may +continue reading this document.

+
+
+
+
+

Enabling logging

+
+
+

i3 logs useful information to stdout. To have a clearly defined place where log +files will be saved, you should redirect stdout and stderr in your +~/.xsession. While you’re at it, putting each run of i3 in a separate log +file with date/time in its filename is a good idea to not get confused about +the different log files later on.

+
+
+
+
exec /usr/bin/i3 >~/i3log-$(date +'%F-%k-%M-%S') 2>&1
+
+
+
+

To enable verbose output and all levels of debug output (required when +attaching logfiles to bugreports), add the parameters -V -d all, like this:

+
+
+
+
exec /usr/bin/i3 -V -d all >~/i3log-$(date +'%F-%k-%M-%S') 2>&1
+
+
+
+
+
+

Enabling core dumps

+
+
+

When i3 crashes, often you have the chance of getting a core dump (an image +of the memory of the i3 process which can be loaded into a debugger). To get a +core dump, you have to make sure that the user limit for core dump files is set +high enough. Many systems ship with a default value which even forbids core +dumps completely. To disable the limit completely and thus enable core dumps, +use the following command (in your ~/.xsession, before starting i3):

+
+
+
+
ulimit -c unlimited
+
+
+
+

Furthermore, to easily recognize core dumps and allow multiple of them, you +should set a custom core dump filename pattern, using a command like the +following:

+
+
+
+
sudo sysctl -w kernel.core_pattern=core.%e.%p
+
+
+
+

This will generate files which have the executable’s file name (%e) and the +process id (%p) in it. You can save this setting across reboots using +/etc/sysctl.conf.

+
+
+
+
+

Compiling with debug symbols

+
+
+

To actually get useful core dumps, you should make sure that your version of i3 +is compiled with debug symbols, that is, that the symbols are not stripped +during the build process. You can check whether your executable contains +symbols by issuing the following command:

+
+
+
+
file $(which i3)
+
+
+
+

You should get an output like this:

+
+
+
+
/usr/bin/i3: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically
+linked (uses shared libs), for GNU/Linux 2.6.18, not stripped
+
+
+
+

Notice the not stripped, which is the important part. If you have a version +which is stripped, please have a look if your distribution provides debug +symbols (package i3-wm-dbg on Debian for example) or if you can turn off +stripping. If nothing helps, please build i3 from source.

+
+
+
+
+

Generating a backtrace

+
+
+

Once you have made sure that your i3 is compiled with debug symbols and that +core dumps are enabled, you can start making sense out of the core dumps.

+
+
+

Because the core dump depends on the original executable (and its debug +symbols), please do this as soon as you encounter the problem. If you +re-compile i3, your core dump might be useless afterwards.

+
+
+

Please install gdb, a debugger for C. No worries, you don’t need to learn it +now. Start gdb using the following command (replacing the actual name of the +core dump of course):

+
+
+
+
gdb $(which i3) core.i3.3849
+
+
+
+

Then, generate a backtrace using:

+
+
+
+
backtrace full
+
+
+
+
+
+

Sending bug reports/debugging on IRC

+
+
+

When sending bug reports, please paste the relevant part of the log (if in +doubt, please send us rather too much information than too less) and the whole +backtrace (if there was a core dump).

+
+
+

When debugging with us in IRC, be prepared to use a so called nopaste service +such as http://nopaste.info or http://pastebin.com because pasting large +amounts of text in IRC sometimes leads to incomplete lines (servers have line +length limitations) or flood kicks.

+
+
+
+
+ + + \ No newline at end of file diff --git a/docs/debugging.html b/docs/debugging.html deleted file mode 100644 index 3631fa6..0000000 --- a/docs/debugging.html +++ /dev/null @@ -1,260 +0,0 @@ - - - - - - -i3: Debugging i3: How To - - - - - - -
- - -
-
- - -

Debugging i3: How To

-Michael Stapelberg
-<michael@i3wm.org>
-January 2014 - -
-
-

This document describes how to debug i3 to send us useful bug -reports, even if you have no knowledge of C programming.

-

Thank you for being interested in debugging i3. It really means -something to us to get your bug fixed. If you have any questions about the -process and/or need further help, do not hesitate to contact us!

-
-
-
-

1. Verify you are using i3 ≥ 4.19

-
-

Only the latest major version of i3 is supported. To verify which version -you are running, use:

-
-
-
$ i3 --moreversion 2>&- || i3 --version
-Binary i3 version:  4.7 (2013-12-22, branch "tags/4.7")
-Running i3 version: 4.7-84-gac74a63 (2014-01-01, branch "next") (pid 1995)
-
-

Your version can look like this:

-
-
-4.7 (release version) -
-
-

-You are using a release version. In many cases, bugs are already -fixed in the development version of i3. Even if the bug is not a known fixed -one, we will still ask you to reproduce your error with the most recent -development version of i3. Therefore, please upgrade to a development version -if you can. -

-
-
-4.7-85-g9c15b95 (development version) -
-
-

-Your version is 85 commits newer than 4.7, and the git revision of your -version is 9c15b95. Go to https://github.com/i3/i3/commits/next and see if -the most recent commit starts with the same revision. If so, you are using the -latest version. -

-
-
-

Development versions of i3 have logging enabled by default and are compiled -with debug symbols.

-
-
-
-

2. Enabling logging

-
-

If you are using a development version (see previous section), you don’t need -to do anything — skip to section 3.

-

If you are using a release version with a custom ~/.xsession (or xinitrc) -file, execute i3 with a line like this:

-
-
-
# Use 25 MiB of RAM for debug logs
-exec i3 --shmlog-size=26214400
-
-

If you are NOT using an ~/.xsession file but you just chose "i3" from the -list of sessions in your desktop manager (gdm, lxdm, …), edit -/usr/share/xsessions/i3.desktop and replace the Exec=i3 line with:

-
-
-
Exec=i3 --shmlog-size=26214400
-
-

If you cannot restart i3 for some reason, you can enable debug logging on the -fly:

-
-
-
i3-msg 'debuglog on; shmlog on; reload'
-
-
-
-
-

3. Reproducing the problem

-
-

Before submitting an issue, please make sure to close down on the problem as -much as you can yourself. Here are some steps you should consider:

-
    -
  • -

    -Find a deterministic, reliable way to reproduce the problem and provide it - with your bug report. -

    -
  • -
  • -

    -Try using the default i3 config to reproduce the problem. If the issue does - not appear with the default config, gradually adapt it to track down what - change(s) to the config introduce the problem. -

    -
  • -
  • -

    -Reproduce the problem with a minimal setup, i.e., only use as few applications, - windows and steps as necessary. -

    -
  • -
  • -

    -In addition, try to stick to applications that are common and, even more - importantly, free / open source. -

    -
  • -
  • -

    -Before obtaining the log file, restart i3 in-place, execute the steps to - reproduce the problem and then save the logs. This keeps the log file as - small as possible and necessary. -

    -
  • -
-

Please be aware that we cannot support compatibility issues with closed-source -software, as digging into compatibility problems without having access to the -source code is too time-consuming. Additionally, experience has shown that -often, the software in question is responsible for the issue. Please raise an -issue with the software in question, not i3.

-
-
-
-

4. Obtaining the debug logfile

-
-
- - - -
-
Caution
-
-

Logs may contain sensitive information, so please inspect the log before -submitting it. Logs may be viewed by anyone, once posted. If you choose to -redact the log, make an effort not to discard information which may be relevant -to the issue you are reporting.

-

The best way to avoid submitting such information is to only run the necessary -steps to reproduce the behavior when saving the log file. This will also make -analyzing the log file easier.

-
-
-

No matter whether i3 misbehaved in some way without crashing or whether it just -crashed, the logfile provides all information necessary to debug the problem.

-

To upload a compressed version of the logfile (for a bugreport), use:

-
-
-
DISPLAY=:0 i3-dump-log | bzip2 -c | curl --data-binary @- https://logs.i3wm.org
-
-

This command does not depend on i3 (it also works while i3 displays -the crash dialog), but it requires a working X11 connection.

-

After running it, you will get a URL to the logfile. Please include that URL in -your bug report.

-
-
-
-

5. On crashes: Obtaining a backtrace

-
-

When i3 crashes, it will display a dialog stating “i3 just crashed”, offering -you to save a backtrace to a text file.

-

To actually get useful backtraces, you should make sure that your version of i3 -is compiled with debug symbols:

-
-
-
$ file `which i3`
-/usr/bin/i3: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically
-linked (uses shared libs), for GNU/Linux 2.6.18, not stripped
-
-

Notice the not stripped, which is the important part. If you have a version -which is stripped, please check whether your distribution provides debug -symbols (package i3-wm-dbg on Debian for example) or if you can turn off -stripping. If nothing helps, please build i3 from source.

-

Once you have made sure that your i3 is compiled with debug symbols and the C -debugger gdb is installed on your machine, you can let i3 generate a -backtrace in the crash dialog.

-

After pressing "b" in the crash dialog, you will get a file called -/tmp/i3-backtrace.%d.%d.txt where the first %d is replaced by i3’s process -id (PID) and the second one is incremented each time you generate a backtrace, -starting at 0.

-
-
-
-

6. Sending bug reports/debugging on IRC

-
-

When sending bug reports, please attach the whole log file. Even if you think -you found the section which clearly highlights the problem, additional -information might be necessary to completely diagnose the problem.

-

When debugging with us in IRC, be prepared to use a so-called nopaste service -such as https://pastebin.com because pasting large amounts of text in IRC -sometimes leads to incomplete lines (servers have line length limitations) or -flood kicks.

-
-
-
-

7. Debugging i3bar

-
-

To debug i3bar problems, use the --verbose commandline parameter, -or add verbose yes to all bar {} blocks in your i3 -config, reload your config and then restart all i3bar instances like this:

-
-
-
$ i3 reload
-$ killall i3bar
-$ for c in $(i3-msg -t get_bar_config | python -c \
-      'import json,sys;print("\n".join(json.load(sys.stdin)))'); do \
-    (i3bar --bar_id=$c >i3bar.$c.log 2>&1) & \
-  done;
-
-

There will now be i3bar.*.log files in your current directory that you can provide -in your bug report.

-
-
-
-

- - - diff --git a/docs/gsoc2013-ideas.html b/docs/gsoc2013-ideas.html index 8d178fb..8ed38d0 100644 --- a/docs/gsoc2013-ideas.html +++ b/docs/gsoc2013-ideas.html @@ -1,205 +1,207 @@ - - - - - - -i3: Google Summer of Code 2013 ideas - - - - - - -
- - -
-
- - -

Google Summer of Code 2013 ideas

-Michael Stapelberg
-<michael@i3wm.org>
-March 2013 -
-
Table of Contents
- -
- -
-

1. Idea 1: Saved sessions in i3

-
-

Many desktop environments nowadays have a way of restarting the applications -that you have been using when you reboot your computer.

-

In i3, we want to take that idea a step further: We want to make it possible -for the user to define a precise layout, which is then filled with the -application windows as they start up.

-

Many users are currently achieving a similar effect with custom scripts and -lots of sleep calls to wait for applications to launch and then simulate -interactive commands to move windows around.

-

Many of the building blocks for this feature are already in place, but there -still are a few places of code that need to be touched, a specification to be -written, user feedback to be gathered and documentation to be updated.

-
-

1.1. Desirable skills

-
    -
  • -

    -Experience with C (best) or similar programming languages such as Perl, C++ -

    -
  • -
  • -

    -Willingness and ability to write documentation -

    -
  • -
-
-
-

1.2. What you will learn

-
    -
  • -

    -How X11 and i3 work (not completely, but the most important parts) -

    -
  • -
  • -

    -How to interact with users -

    -
  • -
  • -

    -What good specification and documentation entails -

    -
  • -
-
-
-
-
-

2. Idea 2: Testsuite: better input and output

-
-

i3 uses a comprehensive testsuite and cares about test-driven development as -well as regression tests. While our testsuite covers quite a lot of code and -works well and fest, it currently only uses the IPC interface to communicate -with i3.

-

The current state enables us to simulate anything a user might also trigger by -a keypress. This does not include dragging windows around, moving the mouse, -clicking on things, or handling actual keyboard events. Furthermore, the -testsuite never sees the actual output the user gets to see. Instead, it just -looks at the data structures.

-

Therefore, it would be good to extend the testsuite so that it captures the X11 -output and compares it with saved images. Also, X11 input such as mouse and -keyboard input should be simulated somehow (e.g. captured and replayed).

-
-

2.1. Desirable skills

-
    -
  • -

    -Experience with Perl or willingness to learn it -

    -
  • -
  • -

    -Experience with automated software testing or at least a basic understanding - of the concepts -

    -
  • -
  • -

    -Willingness to learn X11 mechanisms to capture output and simulate input -

    -
  • -
-
-
-

2.2. What you will learn

-
    -
  • -

    -How real-world testsuites work -

    -
  • -
  • -

    -How X11 input/output works -

    -
  • -
  • -

    -How to implement an entirely new feature into an existing codebase -

    -
  • -
-
-
-
-
-

3. Idea 3: Improve compatibility with certain Applications

-
-

We often receive bug reports which are specific to certain toolkits and/or -applications. For example, people are reporting problems with the IntelliJ IDE, -Java applications in general, VMware or Half-Life (via Steam).

-

Most often, these problems are caused by i3 doing things slighty differently -than other window managers and can be solved by observing and comparing what -others do and what i3 does.

-

Fixing compatibility problems is a huge gain for the users of said -applications.

-
-

3.1. Desirable skills

-
    -
  • -

    -Some experience in debugging -

    -
  • -
  • -

    -Willingness to look at X11 traces for many minutes :) -

    -
  • -
-
-
-

3.2. What you will learn

-
    -
  • -

    -How real-world debugging works, sometimes with open source (Java) and - sometimes with closed source applications (Half-Life, VMware) -

    -
  • -
  • -

    -How X11 works -

    -
  • -
-
-
-
-
-

- - - + + + + + + + + +Google Summer of Code 2013 ideas + + + + +
+
+

Idea 1: Saved sessions in i3

+
+
+

Many desktop environments nowadays have a way of restarting the applications +that you have been using when you reboot your computer.

+
+
+

In i3, we want to take that idea a step further: We want to make it possible +for the user to define a precise layout, which is then filled with the +application windows as they start up.

+
+
+

Many users are currently achieving a similar effect with custom scripts and +lots of sleep calls to wait for applications to launch and then simulate +interactive commands to move windows around.

+
+
+

Many of the building blocks for this feature are already in place, but there +still are a few places of code that need to be touched, a specification to be +written, user feedback to be gathered and documentation to be updated.

+
+
+

Desirable skills

+
+
    +
  • +

    Experience with C (best) or similar programming languages such as Perl, C++

    +
  • +
  • +

    Willingness and ability to write documentation

    +
  • +
+
+
+
+

What you will learn

+
+
    +
  • +

    How X11 and i3 work (not completely, but the most important parts)

    +
  • +
  • +

    How to interact with users

    +
  • +
  • +

    What good specification and documentation entails

    +
  • +
+
+
+
+
+
+

Idea 2: Testsuite: better input and output

+
+
+

i3 uses a comprehensive testsuite and cares about test-driven development as +well as regression tests. While our testsuite covers quite a lot of code and +works well and fest, it currently only uses the IPC interface to communicate +with i3.

+
+
+

The current state enables us to simulate anything a user might also trigger by +a keypress. This does not include dragging windows around, moving the mouse, +clicking on things, or handling actual keyboard events. Furthermore, the +testsuite never sees the actual output the user gets to see. Instead, it just +looks at the data structures.

+
+
+

Therefore, it would be good to extend the testsuite so that it captures the X11 +output and compares it with saved images. Also, X11 input such as mouse and +keyboard input should be simulated somehow (e.g. captured and replayed).

+
+
+

Desirable skills

+
+
    +
  • +

    Experience with Perl or willingness to learn it

    +
  • +
  • +

    Experience with automated software testing or at least a basic understanding +of the concepts

    +
  • +
  • +

    Willingness to learn X11 mechanisms to capture output and simulate input

    +
  • +
+
+
+
+

What you will learn

+
+
    +
  • +

    How real-world testsuites work

    +
  • +
  • +

    How X11 input/output works

    +
  • +
  • +

    How to implement an entirely new feature into an existing codebase

    +
  • +
+
+
+
+
+
+

Idea 3: Improve compatibility with certain Applications

+
+
+

We often receive bug reports which are specific to certain toolkits and/or +applications. For example, people are reporting problems with the IntelliJ IDE, +Java applications in general, VMware or Half-Life (via Steam).

+
+
+

Most often, these problems are caused by i3 doing things slighty differently +than other window managers and can be solved by observing and comparing what +others do and what i3 does.

+
+
+

Fixing compatibility problems is a huge gain for the users of said +applications.

+
+
+

Desirable skills

+
+
    +
  • +

    Some experience in debugging

    +
  • +
  • +

    Willingness to look at X11 traces for many minutes :)

    +
  • +
+
+
+
+

What you will learn

+
+
    +
  • +

    How real-world debugging works, sometimes with open source (Java) and +sometimes with closed source applications (Half-Life, VMware)

    +
  • +
  • +

    How X11 works

    +
  • +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/docs/hacking-howto.html b/docs/hacking-howto.html index a690019..efbd0c7 100644 --- a/docs/hacking-howto.html +++ b/docs/hacking-howto.html @@ -1,1124 +1,1202 @@ - - - -i3: Hacking i3: How To - - - - + + + + + +Hacking i3: How To + - -
- - -
-
- - + + +
-

This document is intended to be the first thing you read before looking and/or +

+

This document is intended to be the first thing you read before looking and/or touching i3’s source code. It should contain all important information to help you understand why things are like they are. If it does not mention something -you find necessary, please do not hesitate to contact me.

+you find necessary, please do not hesitate to contact me.

+
WARNING!

-

This document is not 100% up to date. Specifically, everything up to and -including [data_structures] has been updated recently. The rest might contain -outdated information.

+
+

This document is not 100% up to date. Specifically, everything up to and +including Data structures has been updated recently. The rest might contain +outdated information.

+

-

1. Building i3

+

Building i3

-

You can build i3 like you build any other software package which uses +

+

You can build i3 like you build any other software package which uses The Meson Build system; see Quickstart -Guide → Compiling a Meson project. In case you’re unfamiliar:

+Guide → Compiling a Meson project. In case you’re unfamiliar:

+
-
$ mkdir -p build && cd build
+
$ mkdir -p build && cd build
 $ meson ..
-$ ninja
-
+$ ninja +
+
-

1.1. Build system features

-
    +

    Build system features

    +
    +
    • -

      -We use the AX_ENABLE_BUILDDIR macro to enforce builds happening in a separate - directory. This is a prerequisite for the AX_EXTEND_SRCDIR macro and building - in a separate directory is common practice anyway. In case this causes any - trouble when packaging i3 for your distribution, please open an issue. -

      +

      We use the AX_ENABLE_BUILDDIR macro to enforce builds happening in a separate +directory. This is a prerequisite for the AX_EXTEND_SRCDIR macro and building +in a separate directory is common practice anyway. In case this causes any +trouble when packaging i3 for your distribution, please open an issue.

    • -

      -make check runs the i3 testsuite. See docs/testsuite for details. -

      +

      make check runs the i3 testsuite. See docs/testsuite for details.

    • -

      -make distcheck (runs testsuite on make dist result, tiny bit quicker - feedback cycle than waiting for the travis build to catch the issue). -

      +

      make distcheck (runs testsuite on make dist result, tiny bit quicker +feedback cycle than waiting for the travis build to catch the issue).

    • -

      -make uninstall (occasionally requested by users who compile from source) -

      +

      make uninstall (occasionally requested by users who compile from source)

    • -

      -make will build manpages/docs by default if the tools are installed. - Conversely, manpages/docs are not tried to be built for users who don’t want - to install all these dependencies to get started hacking on i3. Manpages and - docs can be disabled with the --disable-mans and --disable-docs+ - configure options respectively. -

      +

      make will build manpages/docs by default if the tools are installed. +Conversely, manpages/docs are not tried to be built for users who don’t want +to install all these dependencies to get started hacking on i3. Manpages and +docs can be disabled with the --disable-mans and --disable-docs+ +configure options respectively.

    • -

      -non-release builds will enable address sanitizer by default. Use the - --disable-sanitizers configure option to turn off all sanitizers, and see - --help for available sanitizers. -

      +

      non-release builds will enable address sanitizer by default. Use the +--disable-sanitizers configure option to turn off all sanitizers, and see +--help for available sanitizers.

    • -

      -Coverage reports are now generated using make check-code-coverage, which - requires specifying --enable-code-coverage when calling configure. -

      +

      Coverage reports are now generated using make check-code-coverage, which +requires specifying --enable-code-coverage when calling configure.

    • -
    +
+
-

2. Pull requests

+

Pull requests

-

Please talk to us before working on new features to see whether they will be +

+

Please talk to us before working on new features to see whether they will be accepted. A good way for this is to open an issue and asking for opinions on it. Even for accepted features, this can be a good way to refine an idea upfront. However, we don’t want to see certain features in i3, e.g., switching window -focus in an Alt+Tab like way.

-

When working on bugfixes, please make sure you mention that you are working on it -in the corresponding bug report at https://github.com/i3/i3/issues. In case there -is no bug report yet, please create one.

-

After you are done, please submit your work for review as a pull request at -https://github.com/i3/i3. In order to make your review go as fast as possible, -you could have a look at previous reviews and see what the common mistakes are.

+focus in an Alt+Tab like way.

+
+
+

When working on bugfixes, please make sure you mention that you are working on it +in the corresponding bug report at https://github.com/i3/i3/issues. In case there +is no bug report yet, please create one.

+
+
+

After you are done, please submit your work for review as a pull request at +https://github.com/i3/i3. In order to make your review go as fast as possible, +you could have a look at previous reviews and see what the common mistakes are.

+
-

2.1. Which branch to use?

-

Work on i3 generally happens in two branches: “next” (default) and “stable”.

-

The contents of “stable” are always stable. That is, it contains the source code -of the latest release, plus any bugfixes that were applied since that release.

-

New features are only found in the “next” branch. Always use this branch when -writing new code (both bugfixes and features).

+

Which branch to use?

+
+

Work on i3 generally happens in two branches: “next” (default) and “stable”.

+
+
+

The contents of “stable” are always stable. That is, it contains the source code +of the latest release, plus any bugfixes that were applied since that release.

+
+
+

New features are only found in the “next” branch. Always use this branch when +writing new code (both bugfixes and features).

+
-

3. Window Managers

+

Window Managers

-

A window manager is not necessarily needed to run X, but it is usually used in +

+

A window manager is not necessarily needed to run X, but it is usually used in combination with X to facilitate some things. The window manager’s job is to take care of the placement of windows, to provide the user with some mechanisms to change the position/size of windows and to communicate with clients to a certain extent (for example handle fullscreen requests of clients such as -MPlayer).

-

There are no different contexts in which X11 clients run, so a window manager +MPlayer).

+
+
+

There are no different contexts in which X11 clients run, so a window manager is just another client, like all other X11 applications. However, it handles -some events which normal clients usually don’t handle.

-

In the case of i3, the tasks (and order of them) are the following:

-
    +some events which normal clients usually don’t handle.

    +
+
+

In the case of i3, the tasks (and order of them) are the following:

+
+
+
  1. -

    -Grab the key bindings (events will be sent upon keypress/keyrelease) -

    +

    Grab the key bindings (events will be sent upon keypress/keyrelease)

  2. -

    -Iterate through all existing windows (if the window manager is not started as - the first client of X) and manage them (reparent them, create window - decorations, etc.) -

    +

    Iterate through all existing windows (if the window manager is not started as +the first client of X) and manage them (reparent them, create window +decorations, etc.)

  3. -

    -When new windows are created, manage them -

    +

    When new windows are created, manage them

  4. -

    -Handle the client’s _WM_STATE property, but only _WM_STATE_FULLSCREEN and - _NET_WM_STATE_DEMANDS_ATTENTION -

    +

    Handle the client’s _WM_STATE property, but only _WM_STATE_FULLSCREEN and +_NET_WM_STATE_DEMANDS_ATTENTION

  5. -

    -Handle the client’s WM_NAME property -

    +

    Handle the client’s WM_NAME property

  6. -

    -Handle the client’s size hints to display them proportionally -

    +

    Handle the client’s size hints to display them proportionally

  7. -

    -Handle the client’s urgency hint -

    +

    Handle the client’s urgency hint

  8. -

    -Handle enter notifications (focus follows mouse) -

    +

    Handle enter notifications (focus follows mouse)

  9. -

    -Handle button (as in mouse buttons) presses for focus/raise on click -

    +

    Handle button (as in mouse buttons) presses for focus/raise on click

  10. -

    -Handle expose events to re-draw own windows such as decorations -

    +

    Handle expose events to re-draw own windows such as decorations

  11. -

    -React to the user’s commands: Change focus, Move windows, Switch workspaces, - Change the layout mode of a container (default/stacking/tabbed), start a new - application, restart the window manager -

    +

    React to the user’s commands: Change focus, Move windows, Switch workspaces, +Change the layout mode of a container (default/stacking/tabbed), start a new +application, restart the window manager

  12. -
-

In the following chapters, each of these tasks and their implementation details -will be discussed.

+ +
+
+

In the following chapters, each of these tasks and their implementation details +will be discussed.

+
-

3.1. Tiling window managers

-

Traditionally, there are two approaches to managing windows: The most common one +

Tiling window managers

+
+

Traditionally, there are two approaches to managing windows: The most common one nowadays is stacking (or floating, using i3’s terminology), which means the user can freely move/resize the windows, potentially overlapping them. The other approach is called tiling, which means that the window manager distributes -windows to use as much space as possible while not overlapping each other.

-

The idea behind tiling is that you should not need to waste your time +windows to use as much space as possible while not overlapping each other.

+
+
+

The idea behind tiling is that you should not need to waste your time moving/resizing windows while you usually want to get some work done. After all, most users sooner or later tend to lay out their windows in a way which corresponds to tiling or stacking mode in i3. Therefore, why not let i3 do this -for you? Certainly, it’s faster than you could ever do it.

-

The problem with most tiling window managers is that they are too inflexible. +for you? Certainly, it’s faster than you could ever do it.

+
+
+

The problem with most tiling window managers is that they are too inflexible. In my opinion, a window manager is just another tool, and similar to vim which can edit all kinds of text files (like source code, HTML, …) and is not limited to a specific file type, a window manager should not limit itself to a certain layout (like dwm, awesome, …) but provide mechanisms for you to easily create -the layout you need at the moment.

+the layout you need at the moment.

+
-

3.2. The layout tree

-

The data structure which i3 uses to keep track of your windows is a tree. Every -node in the tree is a container (type Con). Some containers represent actual -windows (every container with a window != NULL), some represent split +

The layout tree

+
+

The data structure which i3 uses to keep track of your windows is a tree. Every +node in the tree is a container (type Con). Some containers represent actual +windows (every container with a window != NULL), some represent split containers and a few have special purposes: they represent workspaces, outputs -(like VGA1, LVDS1, …) or the X11 root window.

-

So, when you open a terminal and immediately open another one, they reside in +(like VGA1, LVDS1, …) or the X11 root window.

+
+
+

So, when you open a terminal and immediately open another one, they reside in the same split container, which uses the default layout. In case of an empty -workspace, the split container we are talking about is the workspace.

-

To get an impression of how different layouts are represented, just play around +workspace, the split container we are talking about is the workspace.

+
+
+

To get an impression of how different layouts are represented, just play around and look at the data structures — they are exposed as a JSON hash. See -https://i3wm.org/docs/ipc.html#_tree_reply for documentation on that and an -example.

+https://i3wm.org/docs/ipc.html#_tree_reply for documentation on that and an +example.

+
-

4. Files

+

Files

-

i3’s source code is in the src folder while header files reside in include. +

+

i3’s source code is in the src folder while header files reside in include. Other tools such as i3bar and i3-nagbar have their own folders. i3 and its tools -share an internal library called “libi3” which also has its own folder.

-

The following list gives an overview of the codebase, explaining the +share an internal library called “libi3” which also has its own folder.

+
+
+

The following list gives an overview of the codebase, explaining the functionality of the most important, core source code files. Other files in the tree that are not mentioned here implement specific functionalities: for example, -src/scratchpad.c is obviously about the scratchpad functionality.

-
-
-include/data.h -
+src/scratchpad.c is obviously about the scratchpad functionality.

+
+
+
+
include/data.h
-

-Contains data definitions used by nearly all files. -

+

Contains data definitions used by nearly all files.

-
-include/*.h -
+
include/*.h
-

-Contains forward definitions for all public functions, as well as +

Contains forward definitions for all public functions, as well as doxygen-compatible comments (so if you want to get a bit more of the big -picture, either browse all header files or use doxygen if you prefer that). -

+picture, either browse all header files or use doxygen if you prefer that).

-
-src/config_directives.c -
-
-src/commands.c -
+
src/config_directives.c
+
src/commands.c
-

-Contain the definitions for all high-level config and command directives. These +

Contain the definitions for all high-level config and command directives. These are excellent places to start with a top-to-bottom approach to understand specific i3 behavior. For example, if you want to investigate a bug that happens -for the move to mark command, you can use gdb to pause in -cmd_move_con_to_mark and then work your way from there, stepping into -lower-level functions. -

+for the move to mark command, you can use gdb to pause in +cmd_move_con_to_mark and then work your way from there, stepping into +lower-level functions.

-
-src/con.c -
+
src/con.c
-

-Contains all functions which deal with containers directly (creating containers, +

Contains all functions which deal with containers directly (creating containers, searching containers, getting specific properties from containers, …). Contains abstractions and auxiliary functions necessary to work with the container -structure which is used in almost all parts of the codebase. -

+structure which is used in almost all parts of the codebase.

-
-src/tree.c -
+
src/tree.c
-

-Contains functions which deal with the tree abstraction. However, be aware that -src/con.c also contains functions that heavily interact with the tree -structure. Some functions that are included in str/tree.c are those that handle +

Contains functions which deal with the tree abstraction. However, be aware that +src/con.c also contains functions that heavily interact with the tree +structure. Some functions that are included in str/tree.c are those that handle opening and closing containers in the tree, finding the container that should be -focused next and flattening the tree. See also src/move.c for other +focused next and flattening the tree. See also src/move.c for other move-specific functions that interact with the tree, which were moved into their -own file because they are so long. -

+own file because they are so long.

-
-src/workspace.c -
+
src/workspace.c
-

-Contains functions which deal with workspaces. Includes code that creates new -workspaces, shows existing ones and deals with workspace assignments. -

+

Contains functions which deal with workspaces. Includes code that creates new +workspaces, shows existing ones and deals with workspace assignments.

-
-src/handlers.c -
+
src/handlers.c
-

-Contains all handlers for all kinds of X events (new window title, new hints, +

Contains all handlers for all kinds of X events (new window title, new hints, unmapping, key presses, button presses, …). This is a very important file to -understand how i3 interacts with changes to its environment. -

+understand how i3 interacts with changes to its environment.

-
-src/command_parser.c -
-
-src/config_parser.c -
+
src/command_parser.c
+
src/config_parser.c
-

-Contain a hand-written parser to parse commands and configuration (commands are what +

Contain a hand-written parser to parse commands and configuration (commands are what you bind on keys and what you can send to i3 using the IPC interface, like -move left or workspace 4). src/config.c is responsible for calling the -configuration parser. -

+move left or workspace 4). src/config.c is responsible for calling the +configuration parser.

-
-src/click.c -
-
-src/resize.c -
+
src/click.c
+
src/resize.c
-

-Contain functions which handle mouse button clicks (right mouse button -clicks initiate resizing and thus are relatively complex). -

+

Contain functions which handle mouse button clicks (right mouse button +clicks initiate resizing and thus are relatively complex).

-
-src/manage.c -
+
src/manage.c
-

-Looks at existing or new windows and decides whether to manage them. If so, it -reparents the window and inserts it into our data structures. -

+

Looks at existing or new windows and decides whether to manage them. If so, it +reparents the window and inserts it into our data structures.

-
-src/match.c -
+
src/match.c
-

-A "match" is a data structure which acts like a mask or expression to match +

A "match" is a data structure which acts like a mask or expression to match certain windows or not. For example, when using commands, you can specify a -command like this: [title="Firefox"] kill. The title member of the match +command like this: [title="Firefox"] kill. The title member of the match data structure will then be filled and i3 will check each window using -match_matches_window() to find the windows affected by this command. -

+match_matches_window() to find the windows affected by this command.

-
-src/randr.c -
+
src/randr.c
-

-The RandR API is used to get (and re-query) the configured outputs (monitors, -…). Legacy Xinerama support resides in src/xinerama.c. -

+

The RandR API is used to get (and re-query) the configured outputs (monitors, +…). Legacy Xinerama support resides in src/xinerama.c.

-
-src/render.c -
+
src/render.c
-

-Renders the tree data structure by assigning coordinates to every node. These -values will later be pushed to X11 in src/x.c. -

+

Renders the tree data structure by assigning coordinates to every node. These +values will later be pushed to X11 in src/x.c.

-
-src/sighandler.c -
+
src/sighandler.c
-

-Handles SIGSEGV, SIGABRT and SIGFPE by showing a dialog that i3 crashed. +

Handles SIGSEGV, SIGABRT and SIGFPE by showing a dialog that i3 crashed. You can choose to let it dump core and restart i3 in-place (either trying to -preserve layout or forget about it). -

+preserve layout or forget about it).

-
-src/window.c -
+
src/window.c
-

-Handlers to update X11 window properties like WM_CLASS, _NET_WM_NAME, -CLIENT_LEADER, etc. -

+

Handlers to update X11 window properties like WM_CLASS, _NET_WM_NAME, +CLIENT_LEADER, etc.

-
-include/.xmacro. -
+
include/.xmacro.
-

-A file containing all X11 atoms which i3 uses. This file will be included +

A file containing all X11 atoms which i3 uses. This file will be included various times (for defining, requesting and receiving the atoms), each time -with a different definition of xmacro(). -

+with a different definition of xmacro().

-
+ +
-

5. Data structures

+

Data structures

-

See include/data.h for documented data structures. The most important ones are -explained here.

-

The following picture is generated by the contrib/dump-asy.pl script.

-

- -The Big Picture - -

-

The hierarchy is:

-
    +
    +

    See include/data.h for documented data structures. The most important ones are +explained here.

    +
    +
    +

    The following picture is generated by the contrib/dump-asy.pl script.

    +
    +
    +

    The Big Picture

    +
    +
    +

    The hierarchy is:

    +
    +
    +
    1. -

      -Root container -

      +

      Root container

    2. -

      -Output containers: eDP-1 in this example and the internal __i3+ output -

      +

      Output containers: eDP-1 in this example and the internal __i3+ output

    3. -

      -Content and 2 dockarea containers -

      +

      Content and 2 dockarea containers

    4. -

      -Workspaces: Numbered workspace “1” and a “Named workspace” -

      +

      Workspaces: Numbered workspace “1” and a “Named workspace”

    5. -

      -Split containers: One horizontal in the first workspace and a tabbed one in - the named one. -

      +

      Split containers: One horizontal in the first workspace and a tabbed one in +the named one.

    6. -

      -Leaf containers: Windows like vim and an i3bar dock. -

      +

      Leaf containers: Windows like vim and an i3bar dock.

    7. -
    -

    The data type is Con, in all cases.

    +
+
+
+

The data type is Con, in all cases.

+
-

5.1. Root container

-

The root container (global variable croot) is the up-most ascendant of every i3 +

Root container

+
+

The root container (global variable croot) is the up-most ascendant of every i3 container. It can be used to iterate over the whole tree structure. E.g., it is -used to reply to the GET_WORKSPACES request, iterating over it’s children to -find all workspaces. This is different from the X11 root window.

-

The X11 root window (global variable root) is a single window per X11 display -(a display is identified by :0 or :1 etc.). The root window is what you draw -your background image on. It spans all the available outputs, e.g. VGA1 is a -specific part of the root window and LVDS1 is a specific part of the root -window.

+used to reply to the GET_WORKSPACES request, iterating over it’s children to +find all workspaces. This is different from the X11 root window.

+
+
+

The X11 root window (global variable root) is a single window per X11 display +(a display is identified by :0 or :1 etc.). The root window is what you draw +your background image on. It spans all the available outputs, e.g. VGA1 is a +specific part of the root window and LVDS1 is a specific part of the root +window.

+
-

5.2. Output container

-

Every active output obtained through RandR is represented by one output +

Output container

+
+

Every active output obtained through RandR is represented by one output container. Outputs are considered active when a mode is configured (meaning -something is actually displayed on the output) and the output is not a clone.

-

For example, if your notebook has a screen resolution of 1280x800 px and you +something is actually displayed on the output) and the output is not a clone.

+
+
+

For example, if your notebook has a screen resolution of 1280x800 px and you connect a video projector with a resolution of 1024x768 px, set it up in clone -mode (xrandr --output VGA1 --mode 1024x768 --same-as LVDS1), i3 will +mode (xrandr \--output VGA1 \--mode 1024x768 \--same-as LVDS1), i3 will reduce the resolution to the lowest common resolution and disable one of the -cloned outputs afterwards.

-

However, if you configure it using xrandr --output VGA1 --mode 1024x768 ---right-of LVDS1, i3 will set both outputs active. For each output, a new +cloned outputs afterwards.

+
+
+

However, if you configure it using xrandr \--output VGA1 \--mode 1024x768 +\--right-of LVDS1, i3 will set both outputs active. For each output, a new workspace will be assigned. New workspaces are created on the output you are -currently on.

+currently on.

+
-

5.3. Content container

-

Each output has multiple children. Two of them are dock containers which hold +

Content container

+
+

Each output has multiple children. Two of them are dock containers which hold the top and bottom dock clients. The other one is the content container, which -holds the actual content (workspaces) of this output.

+holds the actual content (workspaces) of this output.

+
-

5.4. Workspace

-

A workspace is identified by its name. Basically, you could think of +

Workspace

+
+

A workspace is identified by its name. Basically, you could think of workspaces as different desks in your office, if you like the desktop metaphor. They just contain different sets of windows and are completely separate of each other. Other window managers also call this “Virtual -desktops”.

+desktops”.

+
-

5.5. Split container

-

A split container is a container which holds an arbitrary amount of split +

Split container

+
+

A split container is a container which holds an arbitrary amount of split containers or X11 window containers. It has an orientation (horizontal or -vertical) and a layout.

-

Split containers (and X11 window containers, which are a subtype of split -containers) can have different border styles.

+vertical) and a layout.

+
+
+

Split containers (and X11 window containers, which are a subtype of split +containers) can have different border styles.

+
-

5.6. Leaf containers

-

A leaf container holds exactly one X11 window. They can’t have any children.

+

Leaf containers

+
+

A leaf container holds exactly one X11 window. They can’t have any children.

+
-

6. List/queue macros

+

List/queue macros

-

i3 makes heavy use of the list macros defined in BSD operating systems. To +

+

i3 makes heavy use of the list macros defined in BSD operating systems. To ensure that the operating system on which i3 is compiled has all the expected -features, i3 comes with include/queue.h. On BSD systems, you can use man -queue(3). On Linux, you have to use google (or read the source).

-

The lists used are SLIST (single linked lists), CIRCLEQ (circular -queues) and TAILQ (tail queues). Usually, only forward traversal is necessary, -so an SLIST works fine. If inserting elements at arbitrary positions or at -the end of a list is necessary, a TAILQ is used instead. However, for the -windows inside a container, a CIRCLEQ is necessary to go from the currently -selected window to the window above/below.

+features, i3 comes with include/queue.h. On BSD systems, you can use man +queue(3). On Linux, you have to use google (or read the source).

+
+
+

The lists used are SLIST (single linked lists), CIRCLEQ (circular +queues) and TAILQ (tail queues). Usually, only forward traversal is necessary, +so an SLIST works fine. If inserting elements at arbitrary positions or at +the end of a list is necessary, a TAILQ is used instead. However, for the +windows inside a container, a CIRCLEQ is necessary to go from the currently +selected window to the window above/below.

+
-

7. Naming conventions

+

Naming conventions

-

There is a row of standard variables used in many events. The following names -should be chosen for those:

-
    +
    +

    There is a row of standard variables used in many events. The following names +should be chosen for those:

    +
    +
    +
    • -

      -conn is the xcb_connection_t -

      +

      conn is the xcb_connection_t

    • -

      -event is the event of the particular type -

      +

      event is the event of the particular type

    • -

      -con names a container -

      +

      con names a container

    • -

      -current is a loop variable when using TAILQ_FOREACH etc. -

      +

      current is a loop variable when using TAILQ_FOREACH etc.

    • -
    +
+
-

8. Startup (src/mainx.c, main())

+

Startup (src/mainx.c, main())

-
    +
    +
    • -

      -Establish the xcb connection -

      +

      Establish the xcb connection

    • -

      -Check for XKB extension on the separate X connection, load Xcursor -

      +

      Check for XKB extension on the separate X connection, load Xcursor

    • -

      -Check for RandR screens (with a fall-back to Xinerama) -

      +

      Check for RandR screens (with a fall-back to Xinerama)

    • -

      -Grab the keycodes for which bindings exist -

      +

      Grab the keycodes for which bindings exist

    • -

      -Manage all existing windows -

      +

      Manage all existing windows

    • -

      -Enter the event loop -

      +

      Enter the event loop

    • -
    +
+
-

9. Keybindings

+

Keybindings

-

9.1. Grabbing the bindings

-

Grabbing the bindings is quite straight-forward. You pass X your combination of +

Grabbing the bindings

+
+

Grabbing the bindings is quite straight-forward. You pass X your combination of modifiers and the keycode you want to grab and whether you want to grab them actively or passively. Most bindings (everything except for bindings using Mode_switch) are grabbed passively, that is, just the window manager gets the -event and cannot replay it.

-

We need to grab bindings that use Mode_switch actively because of a bug in X. +event and cannot replay it.

+
+
+

We need to grab bindings that use Mode_switch actively because of a bug in X. When the window manager receives the keypress/keyrelease event for an actively grabbed keycode, it has to decide what to do with this event: It can either replay it so that other applications get it or it can prevent other -applications from receiving it.

-

So, why do we need to grab keycodes actively? Because X does not set the +applications from receiving it.

+
+
+

So, why do we need to grab keycodes actively? Because X does not set the state-property of keypress/keyrelease events properly. The Mode_switch bit is not set and we need to get it using XkbGetState. This means we cannot pass X our combination of modifiers containing Mode_switch when grabbing the key and therefore need to grab the keycode itself without any modifiers. This means, if you bind Mode_switch + keycode 38 ("a"), i3 will grab keycode 38 ("a") and check on each press of "a" if the Mode_switch bit is set using XKB. If yes, it -will handle the event, if not, it will replay the event.

+will handle the event, if not, it will replay the event.

+
-

9.2. Handling a keypress

-

As mentioned in "Grabbing the bindings", upon a keypress event, i3 first gets -the correct state.

-

Then, it looks through all bindings and gets the one which matches the received -event.

-

The bound command is parsed by the cmdparse lexer/parser, see parse_cmd in -src/cmdparse.y.

+

Handling a keypress

+
+

As mentioned in "Grabbing the bindings", upon a keypress event, i3 first gets +the correct state.

+
+
+

Then, it looks through all bindings and gets the one which matches the received +event.

+
+
+

The bound command is parsed by the cmdparse lexer/parser, see parse_cmd in +src/cmdparse.y.

+
-

10. Manage windows (src/main.c, manage_window() and reparent_window())

+

Manage windows (src/main.c, manage_window() and reparent_window())

-

manage_window() does some checks to decide whether the window should be -managed at all:

-
    +
    +

    manage_window() does some checks to decide whether the window should be +managed at all:

    +
    +
    +
    • -

      -Windows have to be mapped, that is, visible on screen -

      +

      Windows have to be mapped, that is, visible on screen

    • -

      -The override_redirect must not be set. Windows with override_redirect shall - not be managed by a window manager -

      +

      The override_redirect must not be set. Windows with override_redirect shall +not be managed by a window manager

    • -
    -

    Afterwards, i3 gets the initial geometry and reparents the window (see -reparent_window()) if it wasn’t already managed.

    -

    Reparenting means that for each window which is reparented, a new window, +

+
+
+

Afterwards, i3 gets the initial geometry and reparents the window (see +reparent_window()) if it wasn’t already managed.

+
+
+

Reparenting means that for each window which is reparented, a new window, slightly larger than the original one, is created. The original window is then -reparented to the bigger one (called "frame").

-

After reparenting, the window type (_NET_WM_WINDOW_TYPE) is checked to see -whether this window is a dock (_NET_WM_WINDOW_TYPE_DOCK), like dzen2 for +reparented to the bigger one (called "frame").

+
+
+

After reparenting, the window type (_NET_WM_WINDOW_TYPE) is checked to see +whether this window is a dock (_NET_WM_WINDOW_TYPE_DOCK), like dzen2 for example. Docks are handled differently, they don’t have decorations and are not assigned to a specific container. Instead, they are positioned at the bottom or top of the screen (in the appropriate dock area containers). To get the -height which needs to be reserved for the window, the _NET_WM_STRUT_PARTIAL -property is used.

-

Furthermore, the list of assignments (to other workspaces, which may be on +height which needs to be reserved for the window, the _NET_WM_STRUT_PARTIAL +property is used.

+
+
+

Furthermore, the list of assignments (to other workspaces, which may be on other screens) is checked. If the window matches one of the user’s criteria, it may either be put in floating mode or moved to a different workspace. If the -target workspace is not visible, the window will not be mapped.

+target workspace is not visible, the window will not be mapped.

+
-

11. What happens when an application is started?

+

What happens when an application is started?

-

i3 does not care about applications. All it notices is when new windows are -mapped (see src/handlers.c, handle_map_request()). The window is then -reparented (see section "Manage windows").

-

After reparenting the window, render_tree() is called which renders the +

+

i3 does not care about applications. All it notices is when new windows are +mapped (see src/handlers.c, handle_map_request()). The window is then +reparented (see section "Manage windows").

+
+
+

After reparenting the window, render_tree() is called which renders the internal layout table. The new window has been placed in the currently focused container and therefore the new window and the old windows (if any) need to be moved/resized so that the currently active layout (default/stacking/tabbed mode) is rendered correctly. To move/resize windows, a window is “configured” in -X11-speak.

-

Some applications, such as MPlayer obviously assume the window manager is +X11-speak.

+
+
+

Some applications, such as MPlayer obviously assume the window manager is stupid and try to configure their windows by themselves. This generates an event called configurerequest. i3 handles these events and tells the window the size it had before the configurerequest (with the exception of not yet mapped windows, which get configured like they want to, and floating windows, which -can reconfigure themselves).

+can reconfigure themselves).

+
-

12. _NET_WM_STATE

+

_NET_WM_STATE

-

Only the _NET_WM_STATE_FULLSCREEN and _NET_WM_STATE_DEMANDS_ATTENTION atoms -are handled.

-

The former calls toggle_fullscreen() for the specific client which just +

+

Only the _NET_WM_STATE_FULLSCREEN and _NET_WM_STATE_DEMANDS_ATTENTION atoms +are handled.

+
+
+

The former calls toggle_fullscreen() for the specific client which just configures the client to use the whole screen on which it currently is. -Also, it is set as fullscreen_client for the i3Screen.

-

The latter is used to set, read and display urgency hints.

+Also, it is set as fullscreen_client for the i3Screen.

+
+
+

The latter is used to set, read and display urgency hints.

+
-

13. WM_NAME

+

WM_NAME

-

When the WM_NAME property of a window changes, its decoration (containing the +

+

When the WM_NAME property of a window changes, its decoration (containing the title) is re-rendered. Note that WM_NAME is in COMPOUND_TEXT encoding which is totally uncommon and cumbersome. Therefore, the _NET_WM_NAME atom will be used -if present.

+if present.

+
-

14. _NET_WM_NAME

+

_NET_WM_NAME

-

Like WM_NAME, this atom contains the title of a window. However, _NET_WM_NAME +

+

Like WM_NAME, this atom contains the title of a window. However, _NET_WM_NAME is encoded in UTF-8. i3 will recode it to UCS-2 in order to be able to pass it to X. Using an appropriate font (ISO-10646), you can see most special -characters (every special character contained in your font).

+characters (every special character contained in your font).

+
-

15. Size hints

+

Size hints

-

Size hints specify the minimum/maximum size for a given window as well as its +

+

Size hints specify the minimum/maximum size for a given window as well as its aspect ratio. This is important for clients like mplayer, who only set the aspect ratio and resize their window to be as small as possible (but only with some video outputs, for example in Xv, while when using x11, mplayer does the -necessary centering for itself).

-

So, when an aspect ratio was specified, i3 adjusts the height of the window +necessary centering for itself).

+
+
+

So, when an aspect ratio was specified, i3 adjusts the height of the window until the size maintains the correct aspect ratio. For the code to do this, see -src/layout.c, function resize_client().

+src/layout.c, function resize_client().

+
-

16. Rendering (src/layout.c, render_layout() and render_container())

+

Rendering (src/layout.c, render_layout() and render_container())

-

Rendering in i3 version 4 is the step which assigns the correct sizes for +

+

Rendering in i3 version 4 is the step which assigns the correct sizes for borders, decoration windows, child windows and the stacking order of all -windows. In a separate step (x_push_changes()), these changes are pushed to -X11.

-

Keep in mind that all these properties (rect, window_rect and deco_rect) -are temporary, meaning they will be overwritten by calling render_con. -Persistent position/size information is kept in geometry.

-

The entry point for every rendering operation (except for the case of moving -floating windows around) currently is tree_render() which will re-render +windows. In a separate step (x_push_changes()), these changes are pushed to +X11.

+
+
+

Keep in mind that all these properties (rect, window_rect and deco_rect) +are temporary, meaning they will be overwritten by calling render_con. +Persistent position/size information is kept in geometry.

+
+
+

The entry point for every rendering operation (except for the case of moving +floating windows around) currently is tree_render() which will re-render everything that’s necessary (for every output, only the currently displayed workspace is rendered). This behavior is expected to change in the future, since for a lot of updates, re-rendering everything is not actually necessary. -Focus was on getting it working correct, not getting it work very fast.

-

What tree_render() actually does is calling render_con() on the root +Focus was on getting it working correct, not getting it work very fast.

+
+
+

What tree_render() actually does is calling render_con() on the root container and then pushing the changes to X11. The following sections talk about the different rendering steps, in the order of "top of the tree" (root -container) to the bottom.

+container) to the bottom.

+
-

16.1. Rendering the root container

-

The i3 root container (con→type == CT_ROOT) represents the X11 root window. +

Rendering the root container

+
+

The i3 root container (con→type == CT_ROOT) represents the X11 root window. It contains one child container for every output (like LVDS1, VGA1, …), which -is available on your computer.

-

Rendering the root will first render all tiling windows and then all floating +is available on your computer.

+
+
+

Rendering the root will first render all tiling windows and then all floating windows. This is necessary because a floating window can be positioned in such a way that it is visible on two different outputs. Therefore, by first rendering all the tiling windows (of all outputs), we make sure that floating -windows can never be obscured by tiling windows.

-

Essentially, though, this code path will just call render_con() for every -output and x_raise_con(); render_con() for every floating window.

-

In the special case of having a "global fullscreen" window (fullscreen mode -spanning all outputs), a shortcut is taken and x_raise_con(); render_con() is -only called for the global fullscreen window.

+windows can never be obscured by tiling windows.

+
+
+

Essentially, though, this code path will just call render_con() for every +output and x_raise_con(); render_con() for every floating window.

+
+
+

In the special case of having a "global fullscreen" window (fullscreen mode +spanning all outputs), a shortcut is taken and x_raise_con(); render_con() is +only called for the global fullscreen window.

+
-

16.2. Rendering an output

-

Output containers (con→layout == L_OUTPUT) represent a hardware output like +

Rendering an output

+
+

Output containers (con→layout == L_OUTPUT) represent a hardware output like LVDS1, VGA1, etc. An output container has three children (at the moment): One content container (having workspaces as children) and the top/bottom dock area -containers.

-

The rendering happens in the function render_l_output() in the following -steps:

-
    +containers.

    +
+
+

The rendering happens in the function render_l_output() in the following +steps:

+
+
+
  1. -

    -Find the content container (con→type == CT_CON) -

    +

    Find the content container (con→type == CT_CON)

  2. -

    -Get the currently visible workspace (con_get_fullscreen_con(content, - CF_OUTPUT)). -

    +

    Get the currently visible workspace (con_get_fullscreen_con(content, +CF_OUTPUT)).

  3. -

    -If there is a fullscreened window on that workspace, directly render it and - return, thus ignoring the dock areas. -

    +

    If there is a fullscreened window on that workspace, directly render it and +return, thus ignoring the dock areas.

  4. -

    -Sum up the space used by all the dock windows (they have a variable height - only). -

    +

    Sum up the space used by all the dock windows (they have a variable height +only).

  5. -

    -Set the workspace rects (x/y/width/height) based on the position of the - output (stored in con→rect) and the usable space - (con→rect.{width,height} without the space used for dock windows). -

    +

    Set the workspace rects (x/y/width/height) based on the position of the +output (stored in con→rect) and the usable space +(con→rect.{width,height} without the space used for dock windows).

  6. -

    -Recursively raise and render the output’s child containers (meaning dock - area containers and the content container). -

    +

    Recursively raise and render the output’s child containers (meaning dock +area containers and the content container).

  7. -
+ +
-

16.3. Rendering a workspace or split container

-

From here on, there really is no difference anymore. All containers are of -con→type == CT_CON (whether workspace or split container) and some of them -have a con→window, meaning they represent an actual window instead of a -split container.

+

Rendering a workspace or split container

+
+

From here on, there really is no difference anymore. All containers are of +con→type == CT_CON (whether workspace or split container) and some of them +have a con→window, meaning they represent an actual window instead of a +split container.

+
-

16.3.1. Default layout

-

In default layout, containers are placed horizontally or vertically next to -each other (depending on the con→orientation). If a child is a leaf node (as +

Default layout

+
+

In default layout, containers are placed horizontally or vertically next to +each other (depending on the con→orientation). If a child is a leaf node (as opposed to a split container) and has border style "normal", appropriate space -will be reserved for its window decoration.

+will be reserved for its window decoration.

+
-

16.3.2. Stacked layout

-

In stacked layout, only the focused window is actually shown (this is achieved -by calling x_raise_con() in reverse focus order at the end of render_con()).

-

The available space for the focused window is the size of the container minus +

Stacked layout

+
+

In stacked layout, only the focused window is actually shown (this is achieved +by calling x_raise_con() in reverse focus order at the end of render_con()).

+
+
+

The available space for the focused window is the size of the container minus the height of the window decoration for all windows inside this stacked -container.

-

If border style is "1pixel" or "none", no window decoration height will be +container.

+
+
+

If border style is "1pixel" or "none", no window decoration height will be reserved (or displayed later on), unless there is more than one window inside -the stacked container.

+the stacked container.

+
-

16.3.3. Tabbed layout

-

Tabbed layout works precisely like stacked layout, but the window decoration +

Tabbed layout

+
+

Tabbed layout works precisely like stacked layout, but the window decoration position/size is different: They are placed next to each other on a single line -(fixed height).

+(fixed height).

+
-

16.3.4. Dock area layout

-

This is a special case. Users cannot choose the dock area layout, but it will be +

Dock area layout

+
+

This is a special case. Users cannot choose the dock area layout, but it will be set for the dock area containers. In the dockarea layout (at the moment!), -windows will be placed above each other.

+windows will be placed above each other.

+
-

16.4. Rendering a window

-

A window’s size and position will be determined in the following way:

-
    +

    Rendering a window

    +
    +

    A window’s size and position will be determined in the following way:

    +
    +
    +
    1. -

      -Subtract the border if border style is not "none" (but "normal" or "1pixel"). -

      +

      Subtract the border if border style is not "none" (but "normal" or "1pixel").

    2. -

      -Subtract the X11 border, if the window has an X11 border > 0. -

      +

      Subtract the X11 border, if the window has an X11 border > 0.

    3. -

      -Obey the aspect ratio of the window (think MPlayer). -

      +

      Obey the aspect ratio of the window (think MPlayer).

    4. -

      -Obey the height- and width-increments of the window (think terminal emulator - which can only be resized in one-line or one-character steps). -

      +

      Obey the height- and width-increments of the window (think terminal emulator +which can only be resized in one-line or one-character steps).

    5. -
    +
+
-

17. Pushing updates to X11 / Drawing

+

Pushing updates to X11 / Drawing

-

A big problem with i3 before version 4 was that we just sent requests to X11 +

+

A big problem with i3 before version 4 was that we just sent requests to X11 anywhere in the source code. This was bad because nobody could understand the entirety of our interaction with X11, it lead to subtle bugs and a lot of edge -cases which we had to consider all over again.

-

Therefore, since version 4, we have a single file, src/x.c, which is -responsible for repeatedly transferring parts of our tree datastructure to X11.

-

src/x.c consists of multiple parts:

-
    +cases which we had to consider all over again.

    +
+
+

Therefore, since version 4, we have a single file, src/x.c, which is +responsible for repeatedly transferring parts of our tree datastructure to X11.

+
+
+

src/x.c consists of multiple parts:

+
+
+
  1. -

    -The state pushing: x_push_changes(), which calls x_push_node(). -

    +

    The state pushing: x_push_changes(), which calls x_push_node().

  2. -

    -State modification functions: x_con_init, x_reinit, - x_reparent_child, x_move_win, x_con_kill, x_raise_con, x_set_name - and x_set_warp_to. -

    +

    State modification functions: x_con_init, x_reinit, +x_reparent_child, x_move_win, x_con_kill, x_raise_con, x_set_name +and x_set_warp_to.

  3. -

    -Expose event handling (drawing decorations): x_deco_recurse() and - x_draw_decoration(). -

    +

    Expose event handling (drawing decorations): x_deco_recurse() and +x_draw_decoration().

  4. -
+ +
-

17.1. Pushing state to X11

-

In general, the function x_push_changes should be called to push state +

Pushing state to X11

+
+

In general, the function x_push_changes should be called to push state changes. Only when the scope of the state change is clearly defined (for example only the title of a window) and its impact is known beforehand, one can -optimize this and call x_push_node on the appropriate con directly.

-

x_push_changes works in the following steps:

-
    +optimize this and call x_push_node on the appropriate con directly.

    +
+
+

x_push_changes works in the following steps:

+
+
+
  1. -

    -Clear the eventmask for all mapped windows. This leads to not getting - useless ConfigureNotify or EnterNotify events which are caused by our - requests. In general, we only want to handle user input. -

    +

    Clear the eventmask for all mapped windows. This leads to not getting +useless ConfigureNotify or EnterNotify events which are caused by our +requests. In general, we only want to handle user input.

  2. -

    -Stack windows above each other, in reverse stack order (starting with the - most obscured/bottom window). This is relevant for floating windows which - can overlap each other, but also for tiling windows in stacked or tabbed - containers. We also update the _NET_CLIENT_LIST_STACKING hint which is - necessary for tab drag and drop in Chromium. -

    +

    Stack windows above each other, in reverse stack order (starting with the +most obscured/bottom window). This is relevant for floating windows which +can overlap each other, but also for tiling windows in stacked or tabbed +containers. We also update the _NET_CLIENT_LIST_STACKING hint which is +necessary for tab drag and drop in Chromium.

  3. -

    -x_push_node will be called for the root container, recursively calling - itself for the container’s children. This function actually pushes the - state, see the next paragraph. -

    +

    x_push_node will be called for the root container, recursively calling +itself for the container’s children. This function actually pushes the +state, see the next paragraph.

  4. -

    -If the pointer needs to be warped to a different position (for example when - changing focus to a different output), it will be warped now. -

    +

    If the pointer needs to be warped to a different position (for example when +changing focus to a different output), it will be warped now.

  5. -

    -The eventmask is restored for all mapped windows. -

    +

    The eventmask is restored for all mapped windows.

  6. -

    -Window decorations will be rendered by calling x_deco_recurse on the root - container, which then recursively calls itself for the children. -

    +

    Window decorations will be rendered by calling x_deco_recurse on the root +container, which then recursively calls itself for the children.

  7. -

    -If the input focus needs to be changed (because the user focused a different - window), it will be updated now. -

    +

    If the input focus needs to be changed (because the user focused a different +window), it will be updated now.

  8. -

    -x_push_node_unmaps will be called for the root container. This function - only pushes UnmapWindow requests. Separating the state pushing is necessary - to handle fullscreen windows (and workspace switches) in a smooth fashion: - The newly visible windows should be visible before the old windows are - unmapped. -

    +

    x_push_node_unmaps will be called for the root container. This function +only pushes UnmapWindow requests. Separating the state pushing is necessary +to handle fullscreen windows (and workspace switches) in a smooth fashion: +The newly visible windows should be visible before the old windows are +unmapped.

  9. -
-

x_push_node works in the following steps:

-
    +
+
+
+

x_push_node works in the following steps:

+
+
+
  1. -

    -Update the window’s WM_NAME, if changed (the WM_NAME is set on i3 - containers mainly for debugging purposes). -

    +

    Update the window’s WM_NAME, if changed (the WM_NAME is set on i3 +containers mainly for debugging purposes).

  2. -

    -Reparents a child window into the i3 container if the container was created - for a specific managed window. -

    +

    Reparents a child window into the i3 container if the container was created +for a specific managed window.

  3. -

    -If the size/position of the i3 container changed (due to opening a new - window or switching layouts for example), the window will be reconfigured. - Also, the pixmap which is used to draw the window decoration/border on is - reconfigured (pixmaps are size-dependent). -

    +

    If the size/position of the i3 container changed (due to opening a new +window or switching layouts for example), the window will be reconfigured. +Also, the pixmap which is used to draw the window decoration/border on is +reconfigured (pixmaps are size-dependent).

  4. -

    -Size/position for the child window is adjusted. -

    +

    Size/position for the child window is adjusted.

  5. -

    -The i3 container is mapped if it should be visible and was not yet mapped. - When mapping, WM_STATE is set to WM_STATE_NORMAL. Also, the eventmask of - the child window is updated and the i3 container’s contents are copied from - the pixmap. -

    +

    The i3 container is mapped if it should be visible and was not yet mapped. +When mapping, WM_STATE is set to WM_STATE_NORMAL. Also, the eventmask of +the child window is updated and the i3 container’s contents are copied from +the pixmap.

  6. -

    -x_push_node is called recursively for all children of the current - container. -

    +

    x_push_node is called recursively for all children of the current +container.

  7. -
-

x_push_node_unmaps handles the remaining case of an i3 container being -unmapped if it should not be visible anymore. WM_STATE will be set to -WM_STATE_WITHDRAWN.

+ +
+
+

x_push_node_unmaps handles the remaining case of an i3 container being +unmapped if it should not be visible anymore. WM_STATE will be set to +WM_STATE_WITHDRAWN.

+
-

17.2. Drawing window decorations/borders/backgrounds

-

x_draw_decoration draws window decorations. It is run for every leaf +

Drawing window decorations/borders/backgrounds

+
+

x_draw_decoration draws window decorations. It is run for every leaf container (representing an actual X11 window) and for every non-leaf container which is in a stacked/tabbed container (because stacked/tabbed containers display a window decoration for split containers, which consists of a representation -of the child container’s names.

-

Then, parameters are collected to be able to determine whether this decoration +of the child container’s names.

+
+
+

Then, parameters are collected to be able to determine whether this decoration drawing is actually necessary or was already done. This saves a substantial -number of redraws (depending on your workload, but far over 50%).

-

Assuming that we need to draw this decoration, we start by filling the empty +number of redraws (depending on your workload, but far over 50%).

+
+
+

Assuming that we need to draw this decoration, we start by filling the empty space around the child window (think of MPlayer with a specific aspect ratio) -in the user-configured client background color.

-

Afterwards, we draw the appropriate border (in case of border styles "normal" -and "1pixel") and the top bar (in case of border style "normal").

-

The last step is drawing the window title on the top bar.

+in the user-configured client background color.

+
+
+

Afterwards, we draw the appropriate border (in case of border styles "normal" +and "1pixel") and the top bar (in case of border style "normal").

+
+
+

The last step is drawing the window title on the top bar.

+
-

18. User commands (parser-specs/commands.spec)

+

User commands (parser-specs/commands.spec)

-

In the configuration file and when using i3 interactively (with i3-msg, for +

+

In the configuration file and when using i3 interactively (with i3-msg, for example), you use commands to make i3 do things, like focus a different window, -set a window to fullscreen, and so on. An example command is floating enable, +set a window to fullscreen, and so on. An example command is floating enable, which enables floating mode for the currently focused window. See the appropriate section in the User’s Guide for a reference of -all commands.

-

In earlier versions of i3, interpreting these commands was done using lex and +all commands.

+
+
+

In earlier versions of i3, interpreting these commands was done using lex and yacc, but experience has shown that lex and yacc are not well suited for our command language. Therefore, starting from version 4.2, we use a custom parser for user commands and the configuration file. The input specification for this parser can be found in the file -parser-specs/*.spec. Should you happen to use Vim as an editor, use +parser-specs/*.spec. Should you happen to use Vim as an editor, use :source parser-specs/highlighting.vim to get syntax highlighting for this file -(highlighting files for other editors are welcome).

+(highlighting files for other editors are welcome).

+
Excerpt from commands.spec
-
state INITIAL:
+
state INITIAL:
   '[' -> call cmd_criteria_init(); CRITERIA
   'move' -> MOVE
   'exec' -> EXEC
   'workspace' -> WORKSPACE
   'exit' -> call cmd_exit()
   'restart' -> call cmd_restart()
-  'reload' -> call cmd_reload()
-
-

The input specification is written in an extremely simple format. The + 'reload' -> call cmd_reload() +

+
+
+

The input specification is written in an extremely simple format. The specification is then converted into C code by the Perl script generate-commands-parser.pl (the output file names begin with GENERATED and the -files are stored in the include directory). The parser implementation -src/commands_parser.c includes the generated C code at compile-time.

-

The above excerpt from commands.spec illustrates nearly all features of our +files are stored in the include directory). The parser implementation +src/commands_parser.c includes the generated C code at compile-time.

+
+
+

The above excerpt from commands.spec illustrates nearly all features of our specification format: You describe different states and what can happen within each state. State names are all-caps; the state in the above excerpt is called INITIAL. A list of tokens and their actions (separated by an ASCII arrow) follows. In the excerpt, all tokens are literals, that is, simple text strings which will be compared with the input. An action is either the name of a state in which the parser will transition into, or the keyword call, followed by -the name of a function (and optionally a state).

+the name of a function (and optionally a state).

+
-

18.1. Example: The WORKSPACE state

-

Let’s have a look at the WORKSPACE state, which is a good example of all -features. This is its definition:

+

Example: The WORKSPACE state

+
+

Let’s have a look at the WORKSPACE state, which is a good example of all +features. This is its definition:

+
WORKSPACE state (commands.spec)
-
# workspace next|prev|next_on_output|prev_on_output
+
# workspace next|prev|next_on_output|prev_on_output
 # workspace back_and_forth
 # workspace <name>
 # workspace number <number>
@@ -1130,388 +1208,393 @@ 

18.1. Example: The WORKSPACE state

'number' -> WORKSPACE_NUMBER workspace = string - -> call cmd_workspace_name($workspace)
-
-

As you can see from the commands, there are multiple different valid variants -of the workspace command:

-
-
-workspace <direction> -
+ -> call cmd_workspace_name($workspace) +
+
+
+

As you can see from the commands, there are multiple different valid variants +of the workspace command:

+
+
+
+
workspace <direction>
-

- The word workspace can be followed by any of the tokens next, - prev, next_on_output or prev_on_output. This command will - switch to the next or previous workspace (optionally on the same - output).
- There is one function called cmd_workspace, which is defined - in src/commands.c. It will handle this kind of command. To know which - direction was specified, the direction token is stored on the stack - with the name "direction", which is what the "direction = " means in - the beginning.
-

+

The word workspace can be followed by any of the tokens next, +prev, next_on_output or prev_on_output. This command will +switch to the next or previous workspace (optionally on the same +output).
+There is one function called cmd_workspace, which is defined +in src/commands.c. It will handle this kind of command. To know which +direction was specified, the direction token is stored on the stack +with the name "direction", which is what the "direction = " means in +the beginning.

-
-
- + + +
+
+ - -
Note
Note that you can specify multiple literals in the same line. This has - exactly the same effect as if you specified direction = - next_on_output → call cmd_workspace($direction) and so forth.
+ +Note that you can specify multiple literals in the same line. This has + exactly the same effect as if you specified direction = + next_on_output → call cmd_workspace($direction) and so forth.
+ + +
-
- +
+
+ - -
Note
Also note that the order of literals is important here: If next were - ordered before next_on_output, then next_on_output would never - match.
-
-
-
-workspace back_and_forth -
+ +Also note that the order of literals is important here: If next were + ordered before next_on_output, then next_on_output would never + match. + + + +
+
+
+
workspace back_and_forth
-

- This is a very simple case: When the literal back_and_forth is found - in the input, the function cmd_workspace_back_and_forth will be - called without parameters and the parser will return to the INITIAL - state (since no other state was specified). -

+

This is a very simple case: When the literal back_and_forth is found +in the input, the function cmd_workspace_back_and_forth will be +called without parameters and the parser will return to the INITIAL +state (since no other state was specified).

-
-workspace <name> -
+
workspace <name>
-

- In this case, the workspace command is followed by an arbitrary string, - possibly in quotes, for example "workspace 3" or "workspace bleh".
- This is the first time that the token is actually not a literal (not in - single quotes), but just called string. Other possible tokens are word - (the same as string, but stops matching at a whitespace) and end - (matches the end of the input). -

+

In this case, the workspace command is followed by an arbitrary string, +possibly in quotes, for example "workspace 3" or "workspace bleh".
+This is the first time that the token is actually not a literal (not in +single quotes), but just called string. Other possible tokens are word +(the same as string, but stops matching at a whitespace) and end +(matches the end of the input).

-
-workspace number <number> -
+
workspace number <number>
-

- The workspace command has to be followed by the keyword number. It - then transitions into the state WORKSPACE_NUMBER, where the actual - parameter will be read. -

+

The workspace command has to be followed by the keyword number. It +then transitions into the state WORKSPACE_NUMBER, where the actual +parameter will be read.

-
+ +
-

18.2. Introducing a new command

-

The following steps have to be taken in order to properly introduce a new -command (or possibly extend an existing command):

-
    +

    Introducing a new command

    +
    +

    The following steps have to be taken in order to properly introduce a new +command (or possibly extend an existing command):

    +
    +
    +
    1. -

      -Define a function beginning with cmd_ in the file src/commands.c. Copy - the prototype of an existing function. -

      +

      Define a function beginning with cmd_ in the file src/commands.c. Copy +the prototype of an existing function.

    2. -

      -After adding a comment on what the function does, copy the comment and - function definition to include/commands.h. Make the comment in the header - file use double asterisks to make doxygen pick it up. -

      +

      After adding a comment on what the function does, copy the comment and +function definition to include/commands.h. Make the comment in the header +file use double asterisks to make doxygen pick it up.

    3. -

      -Write a test case (or extend an existing test case) for your feature, see - i3 testsuite. For now, it is sufficient to simply call - your command in all the various possible ways. -

      +

      Write a test case (or extend an existing test case) for your feature, see +i3 testsuite. For now, it is sufficient to simply call +your command in all the various possible ways.

    4. -

      -Extend the parser specification in parser-specs/commands.spec. Run the - testsuite and see if your new function gets called with the appropriate - arguments for the appropriate input. -

      +

      Extend the parser specification in parser-specs/commands.spec. Run the +testsuite and see if your new function gets called with the appropriate +arguments for the appropriate input.

    5. -

      -Actually implement the feature. -

      +

      Actually implement the feature.

    6. -

      -Document the feature in the User’s Guide. -

      +

      Document the feature in the User’s Guide.

    7. -
    +
+
-

19. Moving containers

+

Moving containers

-

The movement code is pretty delicate. You need to consider all cases before -making any changes or before being able to fully understand how it works.

+
+

The movement code is pretty delicate. You need to consider all cases before +making any changes or before being able to fully understand how it works.

+
-

19.1. Case 1: Moving inside the same container

-

The reference layout for this case is a single workspace in horizontal -orientation with two containers on it. Focus is on the left container (1).

-
- --+

Case 1: Moving inside the same container

+
+

The reference layout for this case is a single workspace in horizontal +orientation with two containers on it. Focus is on the left container (1).

+
+
++++ - - + +

1

2

1

2

-
-

When moving the left window to the right (command move right), tree_move will +

+

When moving the left window to the right (command move right), tree_move will look for a container with horizontal orientation and finds the parent of the left container, that is, the workspace. Afterwards, it runs the code branch commented with "the easy case": it calls TAILQ_NEXT to get the container right -of the current one and swaps both containers.

+of the current one and swaps both containers.

+
-

19.2. Case 2: Move a container into a split container

-

The reference layout for this case is a horizontal workspace with two +

Case 2: Move a container into a split container

+
+

The reference layout for this case is a horizontal workspace with two containers. The right container is a v-split with two containers. Focus is on -the left container (1).

-
- --+the left container (1).

+ +
++++ - - + + - +

1

2

1

2

3

3

-
-

When moving to the right (command move right), i3 will work like in case 1 +

+

When moving to the right (command move right), i3 will work like in case 1 ("the easy case"). However, as the right container is not a leaf container, but a v-split, the left container (1) will be inserted at the right position (below -2, assuming that 2 is focused inside the v-split) by calling insert_con_into.

-

insert_con_into detaches the container from its parent and inserts it +2, assuming that 2 is focused inside the v-split) by calling insert_con_into.

+
+
+

insert_con_into detaches the container from its parent and inserts it before/after the given target container. Afterwards, the on_remove_child callback is called on the old parent container which will then be closed, if -empty.

-

Afterwards, con_focus will be called to fix the focus stack and the tree will -be flattened.

+empty.

+
+
+

Afterwards, con_focus will be called to fix the focus stack and the tree will +be flattened.

+
-

19.3. Case 3: Moving to non-existent top/bottom

-

Like in case 1, the reference layout for this case is a single workspace in +

Case 3: Moving to non-existent top/bottom

+
+

Like in case 1, the reference layout for this case is a single workspace in horizontal orientation with two containers on it. Focus is on the left -container:

-
- --+container:

+ +
++++ - - + +

1

2

1

2

-
-

This time however, the command is move up or move down. tree_move will look +

+

This time however, the command is move up or move down. tree_move will look for a container with vertical orientation. As it will not find any, -same_orientation is NULL and therefore i3 will perform a forced orientation +same_orientation is NULL and therefore i3 will perform a forced orientation change on the workspace by creating a new h-split container, moving the workspace contents into it and then changing the workspace orientation to vertical. Now it will again search for parent containers with vertical -orientation and it will find the workspace.

-

This time, the easy case code path will not be run as we are not moving inside -the same container. Instead, insert_con_into will be called with the focused +orientation and it will find the workspace.

+
+
+

This time, the easy case code path will not be run as we are not moving inside +the same container. Instead, insert_con_into will be called with the focused container and the container above/below the current one (on the level of -same_orientation).

-

Now, con_focus will be called to fix the focus stack and the tree will be -flattened.

+same_orientation).

+
+
+

Now, con_focus will be called to fix the focus stack and the tree will be +flattened.

+
-

19.4. Case 4: Moving to existent top/bottom

-

The reference layout for this case is a vertical workspace with two containers. +

Case 4: Moving to existent top/bottom

+
+

The reference layout for this case is a vertical workspace with two containers. The bottom one is a h-split containing two containers (1 and 2). Focus is on -the bottom left container (1).

-
- --+the bottom left container (1).

+ +
++++ - + - - + +

3

3

1

2

1

2

-
-

This case is very much like case 3, only this time the forced workspace +

+

This case is very much like case 3, only this time the forced workspace orientation change does not need to be performed because the workspace already -is in vertical orientation.

+is in vertical orientation.

+
-

19.5. Case 5: Moving in one-child h-split

-

The reference layout for this case is a horizontal workspace with two +

Case 5: Moving in one-child h-split

+
+

The reference layout for this case is a horizontal workspace with two containers having a v-split on the left side with a one-child h-split on the -bottom. Focus is on the bottom left container (2(h)):

-
- --+bottom. Focus is on the bottom left container (2(h)):

+ +
++++ - - + + - +

1

3

1

3

2(h)

2(h)

-
-

In this case, same_orientation will be set to the h-split container around +

+

In this case, same_orientation will be set to the h-split container around the focused container. However, when trying the easy case, the next/previous -container swap will be NULL. Therefore, i3 will search again for a -same_orientation container, this time starting from the parent of the h-split -container.

-

After determining a new same_orientation container (if it is NULL, the +container swap will be NULL. Therefore, i3 will search again for a +same_orientation container, this time starting from the parent of the h-split +container.

+
+
+

After determining a new same_orientation container (if it is NULL, the orientation will be force-changed), this case is equivalent to case 2 or case -4.

+4.

+
-

19.6. Case 6: Floating containers

-

The reference layout for this case is a horizontal workspace with two +

Case 6: Floating containers

+
+

The reference layout for this case is a horizontal workspace with two containers plus one floating h-split container. Focus is on the floating -container.

-

TODO: nice illustration. table not possible?

-

When moving up/down, the container needs to leave the floating container and it +container.

+
+
+

TODO: nice illustration. table not possible?

+
+
+

When moving up/down, the container needs to leave the floating container and it needs to be placed on the workspace (at workspace level). This is accomplished -by calling the function attach_to_workspace.

+by calling the function attach_to_workspace.

+
-

20. Click handling

+

Click handling

-

Without much ado, here is the list of cases which need to be considered:

-
    +
    +

    Without much ado, here is the list of cases which need to be considered:

    +
    +
    +
    • -

      -click to focus (tiling + floating) and raise (floating) -

      +

      click to focus (tiling + floating) and raise (floating)

    • -

      -click to focus/raise when in stacked/tabbed mode -

      +

      click to focus/raise when in stacked/tabbed mode

    • -

      -floating_modifier + left mouse button to drag a floating con -

      +

      floating_modifier + left mouse button to drag a floating con

    • -

      -floating_modifier + right mouse button to resize a floating con -

      +

      floating_modifier + right mouse button to resize a floating con

    • -

      -click on decoration in a floating con to either initiate a resize (if there - is more than one child in the floating con) or to drag the - floating con (if it’s the one at the top). -

      +

      click on decoration in a floating con to either initiate a resize (if there +is more than one child in the floating con) or to drag the +floating con (if it’s the one at the top).

    • -

      -click on border in a floating con to resize the floating con -

      +

      click on border in a floating con to resize the floating con

    • -

      -floating_modifier + right mouse button to resize a tiling con -

      +

      floating_modifier + right mouse button to resize a tiling con

    • -

      -click on border/decoration to resize a tiling con -

      +

      click on border/decoration to resize a tiling con

    • -
    +
+
-

21. Gotchas

+

Gotchas

-
    +
    +
    • -

      -Forgetting to call xcb_flush(conn); after sending a request. This usually - leads to code which looks like it works fine but which does not work under - certain conditions. -

      +

      Forgetting to call xcb_flush(conn); after sending a request. This usually +leads to code which looks like it works fine but which does not work under +certain conditions.

    • -

      -Forgetting to call floating_fix_coordinates(con, old_rect, new_rect) after - moving workspaces across outputs. Coordinates for floating containers are - not relative to workspace boundaries, so you must correct their coordinates - or those containers will show up in the wrong workspace or not at all. -

      +

      Forgetting to call floating_fix_coordinates(con, old_rect, new_rect) after +moving workspaces across outputs. Coordinates for floating containers are +not relative to workspace boundaries, so you must correct their coordinates +or those containers will show up in the wrong workspace or not at all.

    • -
    +
+
-

22. Thought experiments

+

Thought experiments

-

In this section, we collect thought experiments, so that we don’t forget our +

+

In this section, we collect thought experiments, so that we don’t forget our thoughts about specific topics. They are not necessary to get into hacking i3, but if you are interested in one of the topics they cover, you should read them before asking us why things are the way they are or why we don’t implement -things.

+things.

+
-

22.1. Using cgroups per workspace

-

cgroups (control groups) are a linux-only feature which provides the ability to +

Using cgroups per workspace

+
+

cgroups (control groups) are a linux-only feature which provides the ability to group multiple processes. For each group, you can individually set resource limits, like allowed memory usage. Furthermore, and more importantly for our purposes, they serve as a namespace, a label which you can attach to processes -and their children.

-

One interesting use for cgroups is having one cgroup per workspace (or +and their children.

+
+
+

One interesting use for cgroups is having one cgroup per workspace (or container, doesn’t really matter). That way, you could set different priorities and have a workspace for important stuff (say, writing a LaTeX document or programming) and a workspace for unimportant background stuff (say, @@ -1519,68 +1602,74 @@

22.1. Using cgroups per workspace

this example it doesn’t really matter if JDownloader unpacks the download a minute earlier or not. However, your compiler should work as fast as possible. Having one cgroup per workspace, you would assign more resources to the -programming workspace.

-

Another interesting feature is that an inherent problem of the workspace +programming workspace.

+
+
+

Another interesting feature is that an inherent problem of the workspace concept could be solved by using cgroups: When starting an application on workspace 1, then switching to workspace 2, you will get the application’s window(s) on workspace 2 instead of the one you started it on. This is because the window manager does not have any mapping between the process it starts (or -gets started in any way) and the window(s) which appear.

-

Imagine for example using dmenu: The user starts dmenu by pressing Mod+d, dmenu +gets started in any way) and the window(s) which appear.

+
+
+

Imagine for example using dmenu: The user starts dmenu by pressing Mod+d, dmenu gets started with PID 3390. The user then decides to launch Firefox, which takes a long time. So they enter firefox into dmenu and press enter. Firefox gets started with PID 4001. When it finally finishes loading, it creates an X11 window and uses MapWindow to make it visible. This is the first time i3 actually gets in touch with Firefox. It decides to map the window, but it has no way of knowing that this window (even though it has the _NET_WM_PID property -set to 4001) belongs to the dmenu the user started before.

-

How do cgroups help with this? Well, when pressing Mod+d to launch dmenu, i3 +set to 4001) belongs to the dmenu the user started before.

+
+
+

How do cgroups help with this? Well, when pressing Mod+d to launch dmenu, i3 would create a new cgroup, let’s call it i3-3390-1. It launches dmenu in that cgroup, which gets PID 3390. As before, the user enters firefox and Firefox gets launched with PID 4001. This time, though, the Firefox process with PID 4001 is also member of the cgroup i3-3390-1 (because fork()ing in a cgroup retains the cgroup property). Therefore, when mapping the window, i3 can look up in which cgroup the process is and can establish a mapping between the -workspace and the window.

-

There are multiple problems with this approach:

-
    +workspace and the window.

    +
+
+

There are multiple problems with this approach:

+
+
+
  1. -

    -Every application has to properly set _NET_WM_PID. This is acceptable and - patches can be written for the few applications which don’t set the hint yet. -

    +

    Every application has to properly set _NET_WM_PID. This is acceptable and +patches can be written for the few applications which don’t set the hint yet.

  2. -

    -It does only work on Linux, since cgroups are a Linux-only feature. Again, - this is acceptable. -

    +

    It does only work on Linux, since cgroups are a Linux-only feature. Again, +this is acceptable.

  3. -

    -The main problem is that some applications create X11 windows completely - independent of UNIX processes. An example for this is Chromium (or - gnome-terminal), which, when being started a second time, communicates with - the first process and lets the first process open a new window. Therefore, if - you have a Chromium window on workspace 2 and you are currently working on - workspace 3, starting chromium does not lead to the desired result (the - window will open on workspace 2). -

    +

    The main problem is that some applications create X11 windows completely +independent of UNIX processes. An example for this is Chromium (or +gnome-terminal), which, when being started a second time, communicates with +the first process and lets the first process open a new window. Therefore, if +you have a Chromium window on workspace 2 and you are currently working on +workspace 3, starting chromium does not lead to the desired result (the +window will open on workspace 2).

  4. -
-

Therefore, my conclusion is that the only proper way of fixing the "window gets + +

+
+

Therefore, my conclusion is that the only proper way of fixing the "window gets opened on the wrong workspace" problem is in the application itself. Most modern applications support freedesktop startup-notifications which can be -used for this.

+used for this.

+
+
+
+
+ -
-

- - + \ No newline at end of file diff --git a/docs/i3-config-wizard.html b/docs/i3-config-wizard.html index 56e2e2f..8cfeed2 100644 --- a/docs/i3-config-wizard.html +++ b/docs/i3-config-wizard.html @@ -1,102 +1,109 @@ - - - - - - -i3: i3-config-wizard(1) - - - - - - -
- - -
-
- - -

i3-config-wizard(1)

-Michael Stapelberg
-<michael+i3@stapelberg.de>
-version 4.0, -July 2011 -
-
Table of Contents
- -
- -
-

1. NAME

-
-

i3-config-wizard - creates a keysym based config based on your layout

-
-
-
-

2. SYNOPSIS

-
-

i3-config-wizard

-
-
-
-

3. FILES

-
-
-

3.1. /etc/i3/config.keycodes

-

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.

-
-
-
-
-

4. DESCRIPTION

-
-

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.

-

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.

-
-
-
-

5. SEE ALSO

-
-

i3(1)

-
-
-
-

6. AUTHOR

-
-

Michael Stapelberg and contributors

-
-
-
-

- - - + + + + + + + + +i3-config-wizard(1) + + + + +
+
+

NAME

+
+
+

i3-config-wizard - creates a keysym based config based on your layout

+
+
+
+
+

SYNOPSIS

+
+
+

i3-config-wizard

+
+
+
+
+

FILES

+
+
+

/etc/i3/config.keycodes

+
+

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.

+
+
+
+
+
+

DESCRIPTION

+
+
+

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.

+
+
+

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.

+
+
+
+
+

SEE ALSO

+
+
+

i3(1)

+
+
+
+
+

AUTHOR

+
+
+

Michael Stapelberg and contributors

+
+
+
+
+ + + \ No newline at end of file diff --git a/docs/i3-input.html b/docs/i3-input.html new file mode 100644 index 0000000..406d317 --- /dev/null +++ b/docs/i3-input.html @@ -0,0 +1,134 @@ + + + + + + + + +i3-input(1) + + + + +
+
+

NAME

+
+
+

i3-input - interactively take a command for i3 window manager

+
+
+
+
+

SYNOPSIS

+
+
+

i3-input [-s <socket>] [-F <format>] [-l <limit>] [-P <prompt>] [-f <font>] [-v]

+
+
+
+
+

DESCRIPTION

+
+
+

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.

+
+
+

The -F option takes a format string. In this string, every occurence of %s is +replaced by the user input.

+
+
+
+
+

EXAMPLE

+
+
+
+
i3-input -F 'mark %s' -l 1 -P 'Mark: '
+
+
+
+
+
+

ENVIRONMENT

+
+
+

I3SOCK

+
+

i3-input handles the different sources of socket paths in the following order:

+
+
+
    +
  • +

    I3SOCK environment variable

    +
  • +
  • +

    I3SOCK gets overwritten by the -s parameter, if specified

    +
  • +
  • +

    if neither are available, i3-input reads the socket path from the X11 +property, which is the recommended way

    +
  • +
  • +

    if everything fails, i3-input tries /tmp/i3-ipc.sock

    +
  • +
+
+
+

The socket path is necessary to connect to i3 and actually issue the command.

+
+
+
+
+
+

SEE ALSO

+
+
+

i3(1)

+
+
+
+
+

AUTHOR

+
+
+

Michael Stapelberg and contributors

+
+
+
+
+ + + \ No newline at end of file diff --git a/docs/i3-migrate-config-to-v4.html b/docs/i3-migrate-config-to-v4.html index ecc2bd1..aa0be62 100644 --- a/docs/i3-migrate-config-to-v4.html +++ b/docs/i3-migrate-config-to-v4.html @@ -1,93 +1,92 @@ - - - - - - -i3: i3-migrate-config-to-v4(1) - - - - - - -
- - -
-
- - -

i3-migrate-config-to-v4(1)

-Michael Stapelberg
-<michael+i3@stapelberg.de>
-version 4.0, -July 2011 -
-
Table of Contents
- -
- -
-

1. NAME

-
-

i3-migrate-config-to-v4 - migrates your i3 config file

-
-
-
-

2. SYNOPSIS

-
-
-
-
mv ~/.i3/config ~/.i3/old.config
-i3-migrate-config-to-v4 ~/.i3/old.config > ~/.i3/config
-
-
-
-
-

3. DESCRIPTION

-
-

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).

-

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.

-
-
-
-

4. SEE ALSO

-
-

i3(1)

-
-
-
-

5. AUTHOR

-
-

Michael Stapelberg and contributors

-
-
-
-

- - - + + + + + + + + +i3-migrate-config-to-v4(1) + + + + +
+
+

NAME

+
+
+

i3-migrate-config-to-v4 - migrates your i3 config file

+
+
+
+
+

SYNOPSIS

+
+
+
+
mv ~/.i3/config ~/.i3/old.config
+i3-migrate-config-to-v4 ~/.i3/old.config > ~/.i3/config
+
+
+
+
+
+

DESCRIPTION

+
+
+

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).

+
+
+

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.

+
+
+
+
+

SEE ALSO

+
+
+

i3(1)

+
+
+
+
+

AUTHOR

+
+
+

Michael Stapelberg and contributors

+
+
+
+
+ + + \ No newline at end of file diff --git a/docs/i3-msg.html b/docs/i3-msg.html index a5c6d05..84da012 100644 --- a/docs/i3-msg.html +++ b/docs/i3-msg.html @@ -1,106 +1,113 @@ - - - - - - -i3: i3-msg(1) - - - - - - -
- - -
-
- - -

i3-msg(1)

-Michael Stapelberg
-<michael+i3@stapelberg.de>
-version 3.delta, -November 2009 -
-
Table of Contents
- -
- -
-

1. NAME

-
-

i3-msg - send messages to i3 window manager

-
-
-
-

2. SYNOPSIS

-
-

i3-msg "message"

-
-
-
-

3. DESCRIPTION

-
-

i3-msg is a sample implementation for a client using the unix socket IPC -interface to i3. At the moment, it can only be used for sending commands -(like in configuration file for key bindings), but this may change in the -future (staying backwards-compatible, of course).

-
-
-
-

4. EXAMPLE

-
-
-
-
i3-msg "bp" # Use 1-px border for current client
-
-
-
-
-

5. ENVIRONMENT

-
-
-

5.1. I3SOCK

-

If no ipc-socket is specified on the commandline, this variable is used -to determine the path, at wich the unix domain socket is expected, on which -to connect to i3.

-
-
-
-
-

6. SEE ALSO

-
-

i3(1)

-
-
-
-

7. AUTHOR

-
-

Michael Stapelberg and contributors

-
-
-
-

- - - + + + + + + + + +i3-msg(1) + + + + +
+
+

NAME

+
+
+

i3-msg - send messages to i3 window manager

+
+
+
+
+

SYNOPSIS

+
+
+

i3-msg "message"

+
+
+
+
+

DESCRIPTION

+
+
+

i3-msg is a sample implementation for a client using the unix socket IPC +interface to i3. At the moment, it can only be used for sending commands +(like in configuration file for key bindings), but this may change in the +future (staying backwards-compatible, of course).

+
+
+
+
+

EXAMPLE

+
+
+
+
i3-msg "bp" # Use 1-px border for current client
+
+
+
+
+
+

ENVIRONMENT

+
+
+

I3SOCK

+
+

If no ipc-socket is specified on the commandline, this variable is used +to determine the path, at wich the unix domain socket is expected, on which +to connect to i3.

+
+
+
+
+
+

SEE ALSO

+
+
+

i3(1)

+
+
+
+
+

AUTHOR

+
+
+

Michael Stapelberg and contributors

+
+
+
+
+ + + \ No newline at end of file diff --git a/docs/i3-nagbar.html b/docs/i3-nagbar.html index c755328..42e182d 100644 --- a/docs/i3-nagbar.html +++ b/docs/i3-nagbar.html @@ -1,96 +1,96 @@ - - - - - - -i3: i3-nagbar(1) - - - - - - -
- - -
-
- - -

i3-nagbar(1)

-Michael Stapelberg
-<michael+i3@stapelberg.de>
-version 4.0, -July 2011 -
-
Table of Contents
- -
- -
-

1. NAME

-
-

i3-nagbar - displays an error bar on top of your screen

-
-
-
-

2. SYNOPSIS

-
-

i3-nagbar -m message -b label action

-
-
-
-

3. DESCRIPTION

-
-

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.

-
-
-
-

4. EXAMPLE

-
-
-
-
i3-nagbar -m 'You have an error in your i3 config file!' \
--b 'edit config' 'xterm $EDITOR ~/.i3/config'
-
-
-
-
-

5. SEE ALSO

-
-

i3(1)

-
-
-
-

6. AUTHOR

-
-

Michael Stapelberg and contributors

-
-
-
-

- - - + + + + + + + + +i3-nagbar(1) + + + + +
+
+

NAME

+
+
+

i3-nagbar - displays an error bar on top of your screen

+
+
+
+
+

SYNOPSIS

+
+
+

i3-nagbar -m message -b label action

+
+
+
+
+

DESCRIPTION

+
+
+

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.

+
+
+
+
+

EXAMPLE

+
+
+
+
i3-nagbar -m 'You have an error in your i3 config file!' \
+-b 'edit config' 'xterm $EDITOR ~/.i3/config'
+
+
+
+
+
+

SEE ALSO

+
+
+

i3(1)

+
+
+
+
+

AUTHOR

+
+
+

Michael Stapelberg and contributors

+
+
+
+
+ + + \ No newline at end of file diff --git a/docs/i3.html b/docs/i3.html index 05a5037..347eab9 100644 --- a/docs/i3.html +++ b/docs/i3.html @@ -1,535 +1,484 @@ - - - - - - -i3: i3(1) - - - - - - -
- - -
-
- - -

i3(1)

-Michael Stapelberg
-<michael+i3@stapelberg.de>
-version 4.0, -July 2011 -
-
Table of Contents
- -
- -
-

1. NAME

-
-

i3 - an improved dynamic, tiling window manager

-
-
-
-

2. SYNOPSIS

-
-

i3 [-a] [-c configfile] [-C] [-d <loglevel>] [-v] [-V]

-
-
-
-

3. OPTIONS

-
-
-
--a -
-
-

-Disables autostart. -

-
-
--c -
-
-

-Specifies an alternate configuration file path. -

-
-
--C -
-
-

-Check the configuration file for validity and exit. -

-
-
--d -
-
-

-Specifies the debug loglevel. To see the most output, use -d all. -

-
-
--v -
-
-

-Display version number (and date of the last commit). -

-
-
--V -
-
-

-Be verbose. -

-
-
-
-
-
-

4. DESCRIPTION

-
-
-

4.1. INTRODUCTION

-

i3 was created because wmii, our favorite window manager at the time, didn’t -provide some features we wanted (multi-monitor done right, for example), had -some bugs, didn’t progress since quite some time and wasn’t 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.

-

Please be aware that i3 is primarily targeted at advanced users and developers.

-
-
-

4.2. IMPORTANT NOTE TO nVidia BINARY DRIVER USERS

-

If you are using the nVidia binary graphics driver (also known as blob) -you need to use the --force-xinerama flag (in your ~/.xsession) when starting -i3, like so:

-
-
-
exec i3 --force-xinerama -V >>~/.i3/i3log 2>&1
-
-

See also docs/multi-monitor for the full explanation.

-
-
-

4.3. TERMINOLOGY

-
-
-Tree -
-
-

-i3 keeps your layout in a tree data structure. -

-
-
-Window -
-
-

-An X11 window, like the Firefox browser window or a terminal emulator. -

-
-
-Split container -
-
-

-A split container contains multiple other split containers or windows. -

-

Containers can be used in various layouts. The default mode is called "default" -and just resizes each client equally so that it fits.

-
-
-Workspace -
-
-

-A workspace is a set of containers. Other window managers call this "Virtual -Desktops". -

-

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’ll be assigned the -screen you are currently on.

-
-
-Output -
-
-

-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). -

-

i3 uses the RandR API to query which outputs are available and which screens -are connected to these outputs.

-
-
-
-
-
-
-

5. KEYBINDINGS

-
-

Here is a short overview of the default keybindings:

-
-
-j/k/l/; -
-
-

-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. -

-
-
-Mod1+<direction> -
-
-

-Focus window in <direction>. -

-
-
-Mod1+Shift+<direction> -
-
-

-Move window to <direction>. -

-
-
-Mod1+<number> -
-
-

-Switch to workspace <number>. -

-
-
-Mod1+Shift+<number> -
-
-

-Move window to workspace <number>. -

-
-
-Mod1+f -
-
-

-Toggle fullscreen mode. -

-
-
-Mod1+s -
-
-

-Enable stacking layout for the current container. -

-
-
-Mod1+e -
-
-

-Enable default layout for the current container. -

-
-
-Mod1+w -
-
-

-Enable tabbed layout for the current container. -

-
-
-Mod1+Shift+Space -
-
-

-Toggle tiling/floating for the current container. -

-
-
-Mod1+Space -
-
-

-Select the first tiling container if the current container is floating and -vice-versa. -

-
-
-Mod1+Shift+q -
-
-

-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. -

-
-
-Mod1+Shift+r -
-
-

-Restarts i3 in place. Your layout will be preserved. -

-
-
-Mod1+Shift+e -
-
-

-Exits i3. -

-
-
-
-
-
-

6. FILES

-
-
-

6.1. ~/.i3/config (or ~/.config/i3/config)

-

When starting, i3 looks for configuration files in the following order:

-
    -
  1. -

    -~/.config/i3/config (or $XDG_CONFIG_HOME/i3/config if set) -

    -
  2. -
  3. -

    -/etc/xdg/i3/config (or $XDG_CONFIG_DIRS/i3/config if set) -

    -
  4. -
  5. -

    -~/.i3/config -

    -
  6. -
  7. -

    -/etc/i3/config -

    -
  8. -
-

You can specify a custom path using the -c option.

-
-
Sample configuration
-
-
# i3 config file (v4)
-
-# font for window titles. ISO 10646 = Unicode
-font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
-
-# use Mouse+Mod1 to drag floating windows to their wanted position
-floating_modifier Mod1
-
-# start a terminal
-bindsym Mod1+Return exec /usr/bin/urxvt
-
-# kill focused window
-bindsym Mod1+Shift+q kill
-
-# start dmenu (a program launcher)
-bindsym Mod1+d exec /usr/bin/dmenu_run
-
-# change focus
-bindsym Mod1+j focus left
-bindsym Mod1+k focus down
-bindsym Mod1+l focus up
-bindsym Mod1+semicolon focus right
-
-# alternatively, you can use the cursor keys:
-bindsym Mod1+Left focus left
-bindsym Mod1+Down focus down
-bindsym Mod1+Up focus up
-bindsym Mod1+Right focus right
-
-# move focused window
-bindsym Mod1+Shift+j move left
-bindsym Mod1+Shift+k move down
-bindsym Mod1+Shift+l move up
-bindsym Mod1+Shift+semicolon move right
-
-# alternatively, you can use the cursor keys:
-bindsym Mod1+Shift+Left move left
-bindsym Mod1+Shift+Down move down
-bindsym Mod1+Shift+Up move up
-bindsym Mod1+Shift+Right move right
-
-# split in horizontal orientation
-bindsym Mod1+h split h
-
-# split in vertical orientation
-bindsym Mod1+v split v
-
-# enter fullscreen mode for the focused container
-bindsym Mod1+f fullscreen
-
-# change container layout (stacked, tabbed, default)
-bindsym Mod1+s layout stacking
-bindsym Mod1+w layout tabbed
-bindsym Mod1+e layout default
-
-# toggle tiling / floating
-bindsym Mod1+Shift+space floating toggle
-
-# change focus between tiling / floating windows
-bindsym Mod1+space focus mode_toggle
-
-# focus the parent container
-bindsym Mod1+a focus parent
-
-# focus the child container
-#bindsym Mod1+d focus child
-
-# switch to workspace
-bindsym Mod1+1 workspace 1
-bindsym Mod1+2 workspace 2
-# ..
-
-# move focused container to workspace
-bindsym Mod1+Shift+1 move workspace 1
-bindsym Mod1+Shift+2 move workspace 2
-# ...
-
-# reload the configuration file
-bindsym Mod1+Shift+c reload
-# restart i3 inplace (preserves your layout/session, can be used to upgrade i3)
-bindsym Mod1+Shift+r restart
-# exit i3 (logs you out of your X session)
-bindsym Mod1+Shift+e exit
-
-# display workspace buttons plus a statusline generated by i3status
-bar {
-    status_command i3status
-}
-
-
-
-

6.2. ~/.xsession

-

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.

-
-
Sample xsession
-
-
# Disable DPMS turning off the screen
-xset -dpms
-xset s off
-
-# Disable bell
-xset -b
-
-# Enable zapping (C-A-<Bksp> kills X)
-setxkbmap -option terminate:ctrl_alt_bksp
-
-# Enforce correct locales from the beginning
-unset LC_COLLATE
-export LC_CTYPE=de_DE.UTF-8
-export LC_TIME=de_DE.UTF-8
-export LC_NUMERIC=de_DE.UTF-8
-export LC_MONETARY=de_DE.UTF-8
-export LC_MESSAGES=C
-export LC_PAPER=de_DE.UTF-8
-export LC_NAME=de_DE.UTF-8
-export LC_ADDRESS=de_DE.UTF-8
-export LC_TELEPHONE=de_DE.UTF-8
-export LC_MEASUREMENT=de_DE.UTF-8
-export LC_IDENTIFICATION=de_DE.UTF-8
-
-# Use XToolkit in java applications
-export AWT_TOOLKIT=XToolkit
-
-# Set background color
-xsetroot -solid "#333333"
-
-# Enable core dumps in case something goes wrong
-ulimit -c unlimited
-
-# Start i3 and log to ~/.i3/logfile
-echo "Starting at $(date)" >> ~/.i3/logfile
-exec /usr/bin/i3 -V -d all >> ~/.i3/logfile
-
-
-
-
-
-

7. ENVIRONMENT

-
-
-

7.1. I3SOCK

-

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’s 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).

-
-
-
-
-

8. TODO

-
-

There is still lot of work to do. Please check our bugtracker for up-to-date -information about tasks which are still not finished.

-
-
-
-

9. SEE ALSO

-
-

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

-

You can also access these documents online at http://i3.zekjur.net/

-

i3-input(1), i3-msg(1), i3-wsbar(1), i3-nagbar(1), i3-config-wizard(1), -i3-migrate-config-to-v4(1)

-
-
-
-

10. AUTHOR

-
-

Michael Stapelberg and contributors

-
-
-
-

- - - + + + + + + + + +i3(1) + + + + +
+
+

NAME

+
+
+

i3 - an improved dynamic, tiling window manager

+
+
+
+
+

SYNOPSIS

+
+
+

i3 [-a] [-c configfile] [-C] [-d <loglevel>] [-v] [-V]

+
+
+
+
+

OPTIONS

+
+
+
+
-a
+
+

Disables autostart.

+
+
-c
+
+

Specifies an alternate configuration file path.

+
+
-C
+
+

Check the configuration file for validity and exit.

+
+
-d
+
+

Specifies the debug loglevel. To see the most output, use -d all.

+
+
-v
+
+

Display version number (and date of the last commit).

+
+
-V
+
+

Be verbose.

+
+
+
+
+
+
+

DESCRIPTION

+
+
+

INTRODUCTION

+
+

i3 was created because wmii, our favorite window manager at the time, didn’t +provide some features we wanted (multi-monitor done right, for example), had +some bugs, didn’t progress since quite some time and wasn’t 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.

+
+
+

Please be aware that i3 is primarily targeted at advanced users and developers.

+
+
+
+

IMPORTANT NOTE TO nVidia BINARY DRIVER USERS

+
+

If you are using the nVidia binary graphics driver (also known as blob) +you need to use the --force-xinerama flag (in your ~/.xsession) when starting +i3, like so:

+
+
+
+
exec i3 --force-xinerama -V >>~/.i3/i3log 2>&1
+
+
+
+

See also docs/multi-monitor for the full explanation.

+
+
+
+

TERMINOLOGY

+
+
+
Tree
+
+

i3 keeps your layout in a tree data structure.

+
+
Window
+
+

An X11 window, like the Firefox browser window or a terminal emulator.

+
+
Split container
+
+

A split container contains multiple other split containers or windows.

+
+

Containers can be used in various layouts. The default mode is called "default" +and just resizes each client equally so that it fits.

+
+
+
Workspace
+
+

A workspace is a set of containers. Other window managers call this "Virtual +Desktops".

+
+

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’ll be assigned the +screen you are currently on.

+
+
+
Output
+
+

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).

+
+

i3 uses the RandR API to query which outputs are available and which screens +are connected to these outputs.

+
+
+
+
+
+
+
+
+

KEYBINDINGS

+
+
+

Here is a short overview of the default keybindings:

+
+
+
+
j/k/l/;
+
+

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.

+
+
Mod1+<direction>
+
+

Focus window in <direction>.

+
+
Mod1+Shift+<direction>
+
+

Move window to <direction>.

+
+
Mod1+<number>
+
+

Switch to workspace <number>.

+
+
Mod1+Shift+<number>
+
+

Move window to workspace <number>.

+
+
Mod1+f
+
+

Toggle fullscreen mode.

+
+
Mod1+s
+
+

Enable stacking layout for the current container.

+
+
Mod1+e
+
+

Enable default layout for the current container.

+
+
Mod1+w
+
+

Enable tabbed layout for the current container.

+
+
Mod1+Shift+Space
+
+

Toggle tiling/floating for the current container.

+
+
Mod1+Space
+
+

Select the first tiling container if the current container is floating and +vice-versa.

+
+
Mod1+Shift+q
+
+

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.

+
+
Mod1+Shift+r
+
+

Restarts i3 in place. Your layout will be preserved.

+
+
Mod1+Shift+e
+
+

Exits i3.

+
+
+
+
+
+
+

FILES

+
+
+

\~/.i3/config (or ~/.config/i3/config)

+
+

When starting, i3 looks for configuration files in the following order:

+
+
+
    +
  1. +

    ~/.config/i3/config (or $XDG_CONFIG_HOME/i3/config if set)

    +
  2. +
  3. +

    /etc/xdg/i3/config (or $XDG_CONFIG_DIRS/i3/config if set)

    +
  4. +
  5. +

    ~/.i3/config

    +
  6. +
  7. +

    /etc/i3/config

    +
  8. +
+
+
+

You can specify a custom path using the -c option.

+
+
+
Sample configuration
+
+
# i3 config file (v4)
+
+# font for window titles. ISO 10646 = Unicode
+font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
+
+# use Mouse+Mod1 to drag floating windows to their wanted position
+floating_modifier Mod1
+
+# start a terminal
+bindsym Mod1+Return exec /usr/bin/urxvt
+
+# kill focused window
+bindsym Mod1+Shift+q kill
+
+# start dmenu (a program launcher)
+bindsym Mod1+d exec /usr/bin/dmenu_run
+
+# change focus
+bindsym Mod1+j focus left
+bindsym Mod1+k focus down
+bindsym Mod1+l focus up
+bindsym Mod1+semicolon focus right
+
+# alternatively, you can use the cursor keys:
+bindsym Mod1+Left focus left
+bindsym Mod1+Down focus down
+bindsym Mod1+Up focus up
+bindsym Mod1+Right focus right
+
+# move focused window
+bindsym Mod1+Shift+j move left
+bindsym Mod1+Shift+k move down
+bindsym Mod1+Shift+l move up
+bindsym Mod1+Shift+semicolon move right
+
+# alternatively, you can use the cursor keys:
+bindsym Mod1+Shift+Left move left
+bindsym Mod1+Shift+Down move down
+bindsym Mod1+Shift+Up move up
+bindsym Mod1+Shift+Right move right
+
+# split in horizontal orientation
+bindsym Mod1+h split h
+
+# split in vertical orientation
+bindsym Mod1+v split v
+
+# enter fullscreen mode for the focused container
+bindsym Mod1+f fullscreen
+
+# change container layout (stacked, tabbed, default)
+bindsym Mod1+s layout stacking
+bindsym Mod1+w layout tabbed
+bindsym Mod1+e layout default
+
+# toggle tiling / floating
+bindsym Mod1+Shift+space floating toggle
+
+# change focus between tiling / floating windows
+bindsym Mod1+space focus mode_toggle
+
+# focus the parent container
+bindsym Mod1+a focus parent
+
+# focus the child container
+#bindsym Mod1+d focus child
+
+# switch to workspace
+bindsym Mod1+1 workspace 1
+bindsym Mod1+2 workspace 2
+# ..
+
+# move focused container to workspace
+bindsym Mod1+Shift+1 move workspace 1
+bindsym Mod1+Shift+2 move workspace 2
+# ...
+
+# reload the configuration file
+bindsym Mod1+Shift+c reload
+# restart i3 inplace (preserves your layout/session, can be used to upgrade i3)
+bindsym Mod1+Shift+r restart
+# exit i3 (logs you out of your X session)
+bindsym Mod1+Shift+e exit
+
+# display workspace buttons plus a statusline generated by i3status
+bar {
+    status_command i3status
+}
+
+
+
+
+

~/.xsession

+
+

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.

+
+
+
Sample xsession
+
+
# Disable DPMS turning off the screen
+xset -dpms
+xset s off
+
+# Disable bell
+xset -b
+
+# Enable zapping (C-A-<Bksp> kills X)
+setxkbmap -option terminate:ctrl_alt_bksp
+
+# Enforce correct locales from the beginning
+unset LC_COLLATE
+export LC_CTYPE=de_DE.UTF-8
+export LC_TIME=de_DE.UTF-8
+export LC_NUMERIC=de_DE.UTF-8
+export LC_MONETARY=de_DE.UTF-8
+export LC_MESSAGES=C
+export LC_PAPER=de_DE.UTF-8
+export LC_NAME=de_DE.UTF-8
+export LC_ADDRESS=de_DE.UTF-8
+export LC_TELEPHONE=de_DE.UTF-8
+export LC_MEASUREMENT=de_DE.UTF-8
+export LC_IDENTIFICATION=de_DE.UTF-8
+
+# Use XToolkit in java applications
+export AWT_TOOLKIT=XToolkit
+
+# Set background color
+xsetroot -solid "#333333"
+
+# Enable core dumps in case something goes wrong
+ulimit -c unlimited
+
+# Start i3 and log to ~/.i3/logfile
+echo "Starting at $(date)" >> ~/.i3/logfile
+exec /usr/bin/i3 -V -d all >> ~/.i3/logfile
+
+
+
+
+
+
+

ENVIRONMENT

+
+
+

I3SOCK

+
+

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’s 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).

+
+
+
+
+
+

TODO

+
+
+

There is still lot of work to do. Please check our bugtracker for up-to-date +information about tasks which are still not finished.

+
+
+
+
+

SEE ALSO

+
+
+

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

+
+
+

You can also access these documents online at http://i3.zekjur.net/

+
+
+

i3-input(1), i3-msg(1), i3-wsbar(1), i3-nagbar(1), i3-config-wizard(1), +i3-migrate-config-to-v4(1)

+
+
+
+
+

AUTHOR

+
+
+

Michael Stapelberg and contributors

+
+
+
+
+ + + \ No newline at end of file diff --git a/docs/i3bar-protocol.html b/docs/i3bar-protocol.html index a754c80..3a1a57d 100644 --- a/docs/i3bar-protocol.html +++ b/docs/i3bar-protocol.html @@ -1,126 +1,135 @@ - - - -i3: i3bar input protocol - - - - + + + + + +i3bar input protocol + - -
- - -
-
- - + + +
-

This document explains the protocol in which i3bar expects its input. It -provides support for colors, urgency, shortening and easy manipulation.

+
+

This document explains the protocol in which i3bar expects its input. It +provides support for colors, urgency, shortening and easy manipulation.

+
-

1. Rationale for choosing JSON

+

Rationale for choosing JSON

-

Before describing the protocol, let’s cover why JSON is a building block of -this protocol.

-
    +
    +

    Before describing the protocol, let’s cover why JSON is a building block of +this protocol.

    +
    +
    +
    1. -

      -Other bar display programs such as dzen2 or xmobar are using in-band - signaling: they recognize certain sequences (like ^fg(#330000) in your input - text). We would like to avoid that and separate information from - meta-information. By information, we mean the actual output, like the IP - address of your ethernet adapter and by meta-information, we mean in which - color it should be displayed right now. -

      +

      Other bar display programs such as dzen2 or xmobar are using in-band +signaling: they recognize certain sequences (like ^fg(#330000) in your input +text). We would like to avoid that and separate information from +meta-information. By information, we mean the actual output, like the IP +address of your ethernet adapter and by meta-information, we mean in which +color it should be displayed right now.

    2. -

      -It is easy to write a simple script which manipulates part(s) of the input. - Each block of information (like a block for the disk space indicator, a block - for the current IP address, etc.) can be identified specifically and modified - in whichever way you like. -

      +

      It is easy to write a simple script which manipulates part(s) of the input. +Each block of information (like a block for the disk space indicator, a block +for the current IP address, etc.) can be identified specifically and modified +in whichever way you like.

    3. -

      -It remains easy to write a simple script which just suffixes (or prefixes) a - status line input, because tools like i3status will output their JSON in - such a way that each line array will be terminated by a newline. Therefore, - you are not required to use a streaming JSON parser, but you can use any - JSON parser and write your script in any programming language. In fact, you - can decide to not bother with the JSON parsing at all and just inject your - output at a specific position (beginning or end). -

      +

      It remains easy to write a simple script which just suffixes (or prefixes) a +status line input, because tools like i3status will output their JSON in +such a way that each line array will be terminated by a newline. Therefore, +you are not required to use a streaming JSON parser, but you can use any +JSON parser and write your script in any programming language. In fact, you +can decide to not bother with the JSON parsing at all and just inject your +output at a specific position (beginning or end).

    4. -

      -Relying on JSON does not introduce any new dependencies. In fact, the IPC - interface of i3 also uses JSON, therefore i3bar already depends on JSON. -

      +

      Relying on JSON does not introduce any new dependencies. In fact, the IPC +interface of i3 also uses JSON, therefore i3bar already depends on JSON.

    5. -
    -

    The only point against using JSON is computational complexity. If that really +

+
+
+

The only point against using JSON is computational complexity. If that really bothers you, just use the plain text input format (which i3bar will continue to -support).

+support).

+
-

2. The protocol

+

The protocol

-

The first message of the protocol is a header block, which contains (at least) +

+

The first message of the protocol is a header block, which contains (at least) the version of the protocol to be used. In case there are significant changes (not only additions), the version will be incremented. i3bar will still understand the old protocol version, but in order to use the new one, you need to provide the correct version. The header block is terminated by a newline and -consists of a single JSON hash:

-

Minimal example:

+consists of a single JSON hash:

+
+
+

Minimal example:

+
-
{ "version": 1 }
-
-

All features example:

+
{ "version": 1 }
+
+
+
+

All features example:

+
-
{ "version": 1, "stop_signal": 10, "cont_signal": 12, "click_events": true }
-
-

(Note that before i3 v4.3 the precise format had to be {"version":1}, -byte-for-byte.)

-

What follows is an infinite array (so it should be parsed by a streaming JSON +

{ "version": 1, "stop_signal": 10, "cont_signal": 12, "click_events": true }
+
+ +
+

(Note that before i3 v4.3 the precise format had to be {"version":1}, +byte-for-byte.)

+
+
+

What follows is an infinite array (so it should be parsed by a streaming JSON parser, but as described above you can go for a simpler solution), whose elements are one array per status line. A status line is one unit of information which should be displayed at a time. i3bar will not display any input until the status line is complete. In each status line, every block will -be represented by a JSON hash:

-

Example:

+be represented by a JSON hash:

+ +
+

Example:

+
-
[
+
[
 
  [
   {
@@ -141,261 +150,202 @@ 

2. The protocol

"full_text": "2012-01-05 20:00:02" } ], - …
-
-

Please note that this example was pretty printed for human consumption. + … +

+ +
+

Please note that this example was pretty printed for human consumption. i3status and others will output single statuslines in one line, separated by -\n.

-

You can find an example of a shell script which can be used as your -status_command in the bar configuration at -https://github.com/i3/i3/blob/next/contrib/trivial-bar-script.sh

+\n.

+ +
+

You can find an example of a shell script which can be used as your +status_command in the bar configuration at +https://github.com/i3/i3/blob/next/contrib/trivial-bar-script.sh

+
-

2.1. Header in detail

-
-
-version -
+

Header in detail

+
+
+
version
-

- The version number (as an integer) of the i3bar protocol you will use. -

+

The version number (as an integer) of the i3bar protocol you will use.

-
-stop_signal -
+
stop_signal
-

- Specify the signal (as an integer) that i3bar should send to request that you - pause your output. This is used to conserve battery power when the bar is - hidden by not unnecessarily computing bar updates. The default value is SIGSTOP, - which will unconditionally stop your process. If this is an issue, this feature - can be disabled by setting the value to 0. -

+

Specify the signal (as an integer) that i3bar should send to request that you +pause your output. This is used to conserve battery power when the bar is +hidden by not unnecessarily computing bar updates. The default value is SIGSTOP, +which will unconditionally stop your process. If this is an issue, this feature +can be disabled by setting the value to 0.

-
-cont_signal -
+
cont_signal
-

- Specify to i3bar the signal (as an integer) to send to continue your - processing. - The default value (if none is specified) is SIGCONT. -

+

Specify to i3bar the signal (as an integer) to send to continue your +processing. +The default value (if none is specified) is SIGCONT.

-
-click_events -
+
click_events
-

- If specified and true i3bar will write an infinite array (same as above) - to your stdin. -

+

If specified and true i3bar will write an infinite array (same as above) +to your stdin.

-
+
+
-

2.2. Blocks in detail

-
-
-full_text -
+

Blocks in detail

+
+
+
full_text
-

- The full_text will be displayed by i3bar on the status line. This is the - only required key. If full_text is an empty string, the block will be - skipped. -

+

The full_text will be displayed by i3bar on the status line. This is the +only required key. If full_text is an empty string, the block will be +skipped.

-
-short_text -
+
short_text
-

- Where appropriate, the short_text (string) entry should also be - provided. It will be used in case the status line needs to be shortened - because it uses more space than your screen provides. For example, when - displaying an IPv6 address, the prefix is usually (!) more relevant - than the suffix, because the latter stays constant when using autoconf, - while the prefix changes. When displaying the date, the time is more - important than the date (it is more likely that you know which day it - is than what time it is). -

+

Where appropriate, the short_text (string) entry should also be +provided. It will be used in case the status line needs to be shortened +because it uses more space than your screen provides. For example, when +displaying an IPv6 address, the prefix is usually (!) more relevant +than the suffix, because the latter stays constant when using autoconf, +while the prefix changes. When displaying the date, the time is more +important than the date (it is more likely that you know which day it +is than what time it is).

-
-color -
+
color
-

- To make the current state of the information easy to spot, colors can - be used. For example, the wireless block could be displayed in red - (using the color (string) entry) if the card is not associated with - any network and in green or yellow (depending on the signal strength) - when it is associated. - Colors are specified in hex (like in HTML), starting with a leading - hash sign. For example, #ff0000 means red. -

+

To make the current state of the information easy to spot, colors can +be used. For example, the wireless block could be displayed in red +(using the color (string) entry) if the card is not associated with +any network and in green or yellow (depending on the signal strength) +when it is associated. +Colors are specified in hex (like in HTML), starting with a leading +hash sign. For example, #ff0000 means red.

-
-background -
+
background
-

- Overrides the background color for this particular block. -

+

Overrides the background color for this particular block.

-
-border -
+
border
-

- Overrides the border color for this particular block. -

+

Overrides the border color for this particular block.

-
-border_top -
+
border_top
-

- Defines the width (in pixels) of the top border of this block. Defaults - to 1. -

+

Defines the width (in pixels) of the top border of this block. Defaults +to 1.

-
-border_right -
+
border_right
-

- Defines the width (in pixels) of the right border of this block. Defaults - to 1. -

+

Defines the width (in pixels) of the right border of this block. Defaults +to 1.

-
-border_bottom -
+
border_bottom
-

- Defines the width (in pixels) of the bottom border of this block. Defaults - to 1. -

+

Defines the width (in pixels) of the bottom border of this block. Defaults +to 1.

-
-border_left -
+
border_left
-

- Defines the width (in pixels) of the left border of this block. Defaults - to 1. -

+

Defines the width (in pixels) of the left border of this block. Defaults +to 1.

-
-min_width -
+
min_width
-

- The minimum width (in pixels) of the block. If the content of the - full_text key take less space than the specified min_width, the block - will be padded to the left and/or the right side, according to the align - key. This is useful when you want to prevent the whole status line to shift - when value take more or less space between each iteration. - The value can also be a string. In this case, the width of the text given - by min_width determines the minimum width of the block. This is useful - when you want to set a sensible minimum width regardless of which font you - are using, and at what particular size. -

+

The minimum width (in pixels) of the block. If the content of the +full_text key take less space than the specified min_width, the block +will be padded to the left and/or the right side, according to the align +key. This is useful when you want to prevent the whole status line to shift +when value take more or less space between each iteration. + The value can also be a string. In this case, the width of the text given + by min_width determines the minimum width of the block. This is useful + when you want to set a sensible minimum width regardless of which font you + are using, and at what particular size.

-
-align -
+
align
-

- Align text on the center, right or left (default) of the block, when - the minimum width of the latter, specified by the min_width key, is not - reached. -

+

Align text on the center, right or left (default) of the block, when +the minimum width of the latter, specified by the min_width key, is not +reached.

-
-name and instance -
+
name and instance
-

- Every block should have a unique name (string) entry so that it can - be easily identified in scripts which process the output. i3bar - completely ignores the name and instance fields. Make sure to also - specify an instance (string) entry where appropriate. For example, - the user can have multiple disk space blocks for multiple mount points. -

+

Every block should have a unique name (string) entry so that it can +be easily identified in scripts which process the output. i3bar +completely ignores the name and instance fields. Make sure to also +specify an instance (string) entry where appropriate. For example, +the user can have multiple disk space blocks for multiple mount points.

-
-urgent -
+
urgent
-

- A boolean which specifies whether the current value is urgent. Examples - are battery charge values below 1 percent or no more available disk - space (for non-root users). The presentation of urgency is up to i3bar. -

+

A boolean which specifies whether the current value is urgent. Examples +are battery charge values below 1 percent or no more available disk +space (for non-root users). The presentation of urgency is up to i3bar.

-
-separator -
+
separator
-

- A boolean which specifies whether a separator line should be drawn - after this block. The default is true, meaning the separator line will - be drawn. Note that if you disable the separator line, there will still - be a gap after the block, unless you also use separator_block_width. -

+

A boolean which specifies whether a separator line should be drawn +after this block. The default is true, meaning the separator line will +be drawn. Note that if you disable the separator line, there will still +be a gap after the block, unless you also use separator_block_width.

-
-separator_block_width -
+
separator_block_width
-

- The amount of pixels to leave blank after the block. In the middle of - this gap, a separator line will be drawn unless separator is - disabled. Normally, you want to set this to an odd value (the default - is 9 pixels), since the separator line is drawn in the middle. -

+

The amount of pixels to leave blank after the block. In the middle of +this gap, a separator line will be drawn unless separator is +disabled. Normally, you want to set this to an odd value (the default +is 9 pixels), since the separator line is drawn in the middle.

-
-markup -
+
markup
-

- A string that indicates how the text of the block should be parsed. Set to - "pango" to use Pango markup. - Set to "none" to not use any markup (default). Pango markup only works - if you use a pango font. -

+

A string that indicates how the text of the block should be parsed. Set to +"pango" to use Pango markup. +Set to "none" to not use any markup (default). Pango markup only works +if you use a pango font.

-
-

If you want to put in your own entries into a block, prefix the key with an +

+
+
+

If you want to put in your own entries into a block, prefix the key with an underscore (_). i3bar will ignore all keys it doesn’t understand, and prefixing them with an underscore makes it clear in every script that they are not part -of the i3bar protocol.

-

Example:

+of the i3bar protocol.

+
+
+

Example:

+
-
{
+
{
  "full_text": "E: 10.0.0.1 (1000 Mbit/s)",
  "_ethernet_vendor": "Intel"
-}
-
-

In the following example, the longest (widest) possible value of the block is -used to set the minimum width:

+} + + +
+

In the following example, the longest (widest) possible value of the block is +used to set the minimum width:

+
-
{
+
{
  "full_text": "CPU 4%",
  "min_width": "CPU 100%",
  "align": "left"
-}
-
-

An example of a block which uses all possible entries follows:

-

Example:

+} + + +
+

An example of a block which uses all possible entries follows:

+
+
+

Example:

+
-
{
+
{
  "full_text": "E: 10.0.0.1 (1000 Mbit/s)",
  "short_text": "10.0.0.1",
  "color": "#00ff00",
@@ -413,85 +363,60 @@ 

2.2. Blocks in detail

"separator": true, "separator_block_width": 9, "markup": "none" -}
-
+} + +
-

2.3. Click events

-

If enabled i3bar will send you notifications if the user clicks on a block and -looks like this:

-
-
-name -
+

Click events

+
+

If enabled i3bar will send you notifications if the user clicks on a block and +looks like this:

+
+
+
+
name
-

- Name of the block, if set -

+

Name of the block, if set

-
-instance -
+
instance
-

- Instance of the block, if set -

+

Instance of the block, if set

-
-x, y -
+
x, y
-

- X11 root window coordinates where the click occurred -

+

X11 root window coordinates where the click occurred

-
-button -
+
button
-

- X11 button ID (for example 1 to 3 for left/middle/right mouse button) -

+

X11 button ID (for example 1 to 3 for left/middle/right mouse button)

-
-relative_x, relative_y -
+
relative_x, relative_y
-

- Coordinates where the click occurred, with respect to the top left corner - of the block -

+

Coordinates where the click occurred, with respect to the top left corner +of the block

-
-output_x, output_y -
+
output_x, output_y
-

- Coordinates relative to the current output where the click occurred -

+

Coordinates relative to the current output where the click occurred

-
-width, height -
+
width, height
-

- Width and height (in px) of the block -

+

Width and height (in px) of the block

-
-modifiers -
+
modifiers
-

- An array of the modifiers active when the click occurred. The order in which - modifiers are listed is not guaranteed. -

+

An array of the modifiers active when the click occurred. The order in which +modifiers are listed is not guaranteed.

-
-

Example:

+
+
+
+

Example:

+
-
{
+
{
  "name": "ethernet",
  "instance": "eth0",
  "button": 1,
@@ -504,17 +429,17 @@ 

2.3. Click events

"output_y": 1400, "width": 50, "height": 22 -}
-
+} +
+ + + + + -
-

- - + \ No newline at end of file diff --git a/docs/i3status.html b/docs/i3status.html index e86e959..f807ccc 100644 --- a/docs/i3status.html +++ b/docs/i3status.html @@ -1,843 +1,1113 @@ - - - - - - -i3: i3status(1) - - - - - - -
- - -
-
- - -

i3status(1)

-Michael Stapelberg
-<michael@i3wm.org>
-version 2.13, -June 2019 -
-
Table of Contents
- -
- -
-

1. NAME

-
-

i3status - Generates a status line for i3bar, dzen2, xmobar or lemonbar

-
-
-
-

2. SYNOPSIS

-
-

i3status [-c configfile] [-h] [-v]

-
-
-
-

3. OPTIONS

-
-
-
--c -
-
-

-Specifies an alternate configuration file path. By default, i3status looks for -configuration files in the following order: -

-
    -
  1. -

    -~/.config/i3status/config (or $XDG_CONFIG_HOME/i3status/config if set) -

    -
  2. -
  3. -

    -/etc/xdg/i3status/config (or $XDG_CONFIG_DIRS/i3status/config if set) -

    -
  4. -
  5. -

    -~/.i3status.conf -

    -
  6. -
  7. -

    -/etc/i3status.conf -

    -
  8. -
-
-
-
-
-
-

4. DESCRIPTION

-
-

i3status is a small program for generating a status bar for i3bar, dzen2, -xmobar, lemonbar or similar programs. It is designed to be very efficient by -issuing a very small number of system calls, as one generally wants to update -such a status line every second. This ensures that even under high load, your -status bar is updated correctly. Also, it saves a bit of energy by not hogging -your CPU as much as spawning the corresponding amount of shell commands would.

-
-
-
-

5. CONFIGURATION

-
-

The basic idea of i3status is that you can specify which "modules" should -be used (the order directive). You can then configure each module with its -own section. For every module, you can specify the output format. See below -for a complete reference.

-
-
Sample configuration
-
-
general {
-        output_format = "dzen2"
-        colors = true
-        interval = 5
-}
-
-order += "ipv6"
-order += "disk /"
-order += "run_watch DHCP"
-order += "run_watch VPNC"
-order += "path_exists VPN"
-order += "wireless wlan0"
-order += "ethernet eth0"
-order += "battery 0"
-order += "cpu_temperature 0"
-order += "memory"
-order += "load"
-order += "tztime local"
-order += "tztime berlin"
-
-wireless wlan0 {
-        format_up = "W: (%quality at %essid, %bitrate) %ip"
-        format_down = "W: down"
-}
-
-ethernet eth0 {
-        format_up = "E: %ip (%speed)"
-        format_down = "E: down"
-}
-
-battery 0 {
-        format = "%status %percentage %remaining %emptytime"
-        format_down = "No battery"
-        status_chr = "⚡ CHR"
-        status_bat = "🔋 BAT"
-        status_unk = "? UNK"
-        status_full = "☻ FULL"
-        path = "/sys/class/power_supply/BAT%d/uevent"
-        low_threshold = 10
-}
-
-run_watch DHCP {
-        pidfile = "/var/run/dhclient*.pid"
-}
-
-run_watch VPNC {
-        # file containing the PID of a vpnc process
-        pidfile = "/var/run/vpnc/pid"
-}
-
-path_exists VPN {
-        # path exists when a VPN tunnel launched by nmcli/nm-applet is active
-        path = "/proc/sys/net/ipv4/conf/tun0"
-}
-
-tztime local {
-        format = "%Y-%m-%d %H:%M:%S"
-        hide_if_equals_localtime = true
-}
-
-tztime berlin {
-        format = "%Y-%m-%d %H:%M:%S %Z"
-        timezone = "Europe/Berlin"
-}
-
-load {
-        format = "%5min"
-}
-
-cpu_temperature 0 {
-        format = "T: %degrees °C"
-        path = "/sys/devices/platform/coretemp.0/temp1_input"
-}
-
-memory {
-        format = "%used"
-        threshold_degraded = "10%"
-        format_degraded = "MEMORY: %free"
-}
-
-disk "/" {
-        format = "%free"
-}
-
-read_file uptime {
-        path = "/proc/uptime"
-}
-
-
-

5.1. General

-

The colors directive will disable all colors if you set it to false. You can -also specify the colors that will be used to display "good", "degraded" or "bad" -values using the color_good, color_degraded or color_bad directives, -respectively. Those directives are only used if color support is not disabled by -the colors directive. The input format for color values is the canonical RGB -hexadecimal triplet (with no separators between the colors), prefixed by a hash -character ("#").

-

Example configuration:

-
-
-
color_good = "#00FF00"
-
-

Likewise, you can use the color_separator directive to specify the color that -will be used to paint the separator bar. The separator is always output in -color, even when colors are disabled by the colors directive. This option has -no effect when output_format is set to i3bar or none.

-

The interval directive specifies the time in seconds for which i3status will -sleep before printing the next status line.

-

Using output_format you can choose which format strings i3status should -use in its output. Currently available are:

-
-
-i3bar -
-
-

-i3bar comes with i3 and provides a workspace bar which does the right thing in -multi-monitor situations. It also comes with tray support and can display the -i3status output. This output type uses JSON to pass as much meta-information to -i3bar as possible (like colors, which blocks can be shortened in which way, -etc.). -

-
-
-dzen2 -
-
-

-Dzen is a general purpose messaging, notification and menuing program for X11. -It was designed to be scriptable in any language and integrate well with window -managers like dwm, wmii and xmonad though it will work with any window manager -

-
-
-xmobar -
-
-

-xmobar is a minimalistic, text based, status bar. It was designed to work -with the xmonad Window Manager. -

-
-
-lemonbar -
-
-

-lemonbar is a lightweight bar based entirely on XCB. It has full UTF-8 support -and is EWMH compliant. -

-
-
-term -
-
-

-Use ANSI Escape sequences to produce a terminal-output as close as possible to -the graphical outputs. This makes debugging your config file a little bit -easier because the terminal-output of i3status becomes much more readable, but -should only used for such quick glances, because it will only support very -basic output-features (for example you only get 3 bits of color depth). -

-
-
-none -
-
-

-Does not use any color codes. Separates values by the pipe symbol by default. -This should be used with i3bar and can be used for custom scripts. -

-
-
-

It’s also possible to use the color_good, color_degraded, color_bad directives -to define specific colors per module. If one of these directives is defined -in a module section its value will override the value defined in the general -section just for this module.

-

If you don’t fancy the vertical separators between modules i3status/i3bar -uses by default, you can employ the separator directive to configure how -modules are separated. You can also disable the default separator altogether by -setting it to the empty string. You might then define separation as part of a -module’s format string. This is your only option when using the i3bar output -format as the separator is drawn by i3bar directly otherwise. For the other -output formats, the provided non-empty string will be automatically enclosed -with the necessary coloring bits if color support is enabled.

-

i3bar supports Pango markup, allowing your format strings to specify font, -color, size, etc. by setting the markup directive to "pango". Note that the -ampersand ("&"), less-than ("<"), greater-than (">"), single-quote ("'"), and -double-quote (""") characters need to be replaced with "&amp;", "&lt;", -"&gt;", "&apos;", and "&quot;" respectively. This is done automatically -for generated content (e.g. wireless ESSID, time).

-

Example configuration:

-
-
-
general {
-    output_format = "xmobar"
-    separator = "  "
-}
-
-order += "load"
-order += "disk /"
-
-load {
-    format = "[ load: %1min, %5min, %15min ]"
-}
-disk "/" {
-    format = "%avail"
-}
-
-
-
-

5.2. IPv6

-

This module gets the IPv6 address used for outgoing connections (that is, the -best available public IPv6 address on your computer).

-

Example format_up: %ip

-

Example format_down: no IPv6

-
-
-

5.3. Disk

-

Gets used, free, available and total amount of bytes on the given mounted filesystem.

-

These values can also be expressed in percentages with the percentage_used, -percentage_free, percentage_avail and percentage_used_of_avail formats.

-

Byte sizes are presented in a human readable format using a set of prefixes -whose type can be specified via the "prefix_type" option. Three sets of -prefixes are available:

-
-
-binary -
-
-

-IEC prefixes (Ki, Mi, Gi, Ti) represent multiples of powers of 1024. -This is the default. -

-
-
-decimal -
-
-

-SI prefixes (k, M, G, T) represent multiples of powers of 1000. -

-
-
-custom -
-
-

-The custom prefixes (K, M, G, T) represent multiples of powers of 1024. -

-
-
-

It is possible to define a low_threshold that causes the disk text to be -displayed using color_bad. The low_threshold type can be of threshold_type -"bytes_free", "bytes_avail", "percentage_free", or "percentage_avail", where -the former two can be prepended by a generic prefix (k, m, g, t) having -prefix_type. So, if you configure low_threshold to 2, threshold_type to -"gbytes_avail", and prefix_type to "binary", and the remaining available disk -space is below 2 GiB, it will be colored bad. If not specified, threshold_type -is assumed to be "percentage_avail" and low_threshold to be set to 0, which -implies no coloring at all. You can customize the output format when below -low_threshold with format_below_threshold.

-

You can define a different format with the option "format_not_mounted" -which is used if the path does not exist or is not a mount point. Defaults to "".

-

Example order: disk /mnt/usbstick

-

Example format: %free (%avail)/ %total

-

Example format: %percentage_used used, %percentage_free free, %percentage_avail avail

-

Example prefix_type: custom

-

Example low_threshold: 5

-

Example format_below_threshold: Warning: %percentage_avail

-

Example threshold_type: percentage_free

-
-
-

5.4. Run-watch

-

Expands the given path to a pidfile and checks if the process ID found inside -is valid (that is, if the process is running). You can use this to check if -a specific application, such as a VPN client or your DHCP client is running. -There also is an option "format_down". You can hide the output with -format_down="".

-

Example order: run_watch DHCP

-

Example format: %title: %status

-
-
-

5.5. Path-exists

-

Checks if the given path exists in the filesystem. You can use this to check if -something is active, like for example a VPN tunnel managed by NetworkManager. -There also is an option "format_down". You can hide the output with -format_down="".

-

Example order: path_exists VPN

-

Example format: %title: %status

-
-
-

5.6. Wireless

-

Gets the link quality, frequency and ESSID of the given wireless network -interface. You can specify different format strings for the network being -connected or not connected. The quality is padded with leading zeroes by -default; to pad with something else use format_quality.

-

The special interface name _first_ will be replaced by the first wireless -network interface found on the system (excluding devices starting with "lo").

-

Example order: wireless wlan0

-

Example format_up: W: (%quality at %essid, %bitrate / %frequency) %ip

-

Example format_down: W: down

-

Example format_quality: "%03d%s"

-
-
-

5.7. Ethernet

-

Gets the IP address and (if possible) the link speed of the given ethernet -interface. If no IPv4 address is available and an IPv6 address is, it will be -displayed.

-

The special interface name _first_ will be replaced by the first non-wireless -network interface found on the system (excluding devices starting with "lo").

-

Example order: ethernet eth0

-

Example format_up: E: %ip (%speed)

-

Example format_down: E: down

-
-
-

5.8. Battery

-

Gets the status (charging, discharging, unknown, full), percentage, remaining -time and power consumption (in Watts) of the given battery and when it’s -estimated to be empty. If you want to use the last full capacity instead of the -design capacity (when using the design capacity, it may happen that your -battery is at 23% when fully charged because it’s old. In general, I want to -see it this way, because it tells me how worn off my battery is.), just specify -last_full_capacity = true. You can show seconds in the remaining time and -empty time estimations by setting hide_seconds = false.

-

If you want the battery percentage to be shown without decimals, add -integer_battery_capacity = true.

-

If your battery is represented in a non-standard path in /sys, be sure to -modify the "path" property accordingly, i.e. pointing to the uevent file on -your system. The first occurrence of %d gets replaced with the battery number, -but you can just hard-code a path as well.

-

It is possible to define a low_threshold that causes the battery text to be -colored red. The low_threshold type can be of threshold_type "time" or -"percentage". So, if you configure low_threshold to 10 and threshold_type to -"time", and your battery lasts another 9 minutes, it will be colored red.

-

To show an aggregate of all batteries in the system, use "all" as the number. In -this case (for Linux), the /sys path must contain the "%d" sequence. Otherwise, -the number indicates the battery index as reported in /sys.

-

Optionally custom strings including any UTF-8 symbols can be used for different -battery states. This makes it possible to display individual symbols -for each state (charging, discharging, unknown, full) -Of course it will also work with special iconic fonts, such as FontAwesome. -If any of these special status strings are omitted, the default (CHR, BAT, UNK, -FULL) is used.

-

Example order (for the first battery): battery 0

-

Example order (aggregate of all batteries): battery all

-

Example format: %status %remaining (%emptytime %consumption)

-

Example format_down: No battery

-

Example status_chr: ⚡ CHR

-

Example status_bat: 🔋 BAT

-

Example status_unk: ? UNK

-

Example status_full: ☻ FULL

-

Example low_threshold: 30

-

Example threshold_type: time

-

Example path (%d replaced by title number): /sys/class/power_supply/CMB%d/uevent

-

Example path (ignoring the number): /sys/class/power_supply/CMB1/uevent

-
-
-

5.9. CPU-Temperature

-

Gets the temperature of the given thermal zone. It is possible to -define a max_threshold that will color the temperature red in case the -specified thermal zone is getting too hot. Defaults to 75 degrees C. The -output format when above max_threshold can be customized with -format_above_threshold.

-

Example order: cpu_temperature 0

-

Example format: T: %degrees °C

-

Example max_threshold: 42

-

Example format_above_threshold: Warning T above threshold: %degrees °C

-

Example path: /sys/devices/platform/coretemp.0/temp1_input

-
-
-

5.10. CPU Usage

-

Gets the percentual CPU usage from /proc/stat (Linux) or sysctl(3) -(FreeBSD/OpenBSD).

-

It is possible to define a max_threshold that will color the load -value red in case the CPU average over the last interval is getting -higher than the configured threshold. Defaults to 95. The output -format when above max_threshold can be customized with -format_above_threshold.

-

It is possible to define a degraded_threshold that will color the load -value yellow in case the CPU average over the last interval is getting -higher than the configured threshold. Defaults to 90. The output format -when above degraded threshold can be customized with -format_above_degraded_threshold.

-

For displaying the Nth CPU usage, you can use the %cpu<N> format string, -starting from %cpu0. This feature is currently not supported in FreeBSD.

-

Example order: cpu_usage

-

Example format: all: %usage CPU_0: %cpu0 CPU_1: %cpu1

-

Example max_threshold: 75

-

Example format_above_threshold: Warning above threshold: %usage

-

Example degraded_threshold: 25

-

Example format_above_degraded_threshold: Warning above degraded threshold: %usage

-
-
-

5.11. Memory

-

Gets the memory usage from system on a Linux system from /proc/meminfo. Other -systems are currently not supported.

-

As format placeholders, total, used, free, available and shared are -available. These will print human readable values. It’s also possible to prefix -the placeholders with percentage_ to get a value in percent.

-

It’s possible to define a threshold_degraded and a threshold_critical to -color the status bar output in yellow or red, if the available memory falls -below the given threshold. Possible values of the threshold can be any integer, -suffixed with an iec symbol (T, G, M, K). Alternatively, the integer -can be suffixed by a percent sign, which then rets evaluated relatively to -total memory.

-

If the format_degraded parameter is given and either the critical or the -degraded threshold applies, format_degraded will get used as format string. -It acts equivalently to format.

-

As Linux' meminfo doesn’t expose the overall memory in use, there are multiple -methods to distinguish the actually used memory.

-

Example memory_used_method: memavailable ("total memory" - "MemAvailable", matches free command)

-

Example memory_used_method: classical ("total memory" - "free" - "buffers" - "cache", matches gnome system monitor)

-

Example order: memory

-

Example format: %free %available (%used) / %total

-

Example format: %percentage_used used, %percentage_free free, %percentage_shared shared

-

Example threshold_degraded: 10%

-

Example threshold_critical: 5%

-

Example format_degraded: Memory LOW: %free

-
-
-

5.12. Load

-

Gets the system load (number of processes waiting for CPU time in the last -1, 5 and 15 minutes). It is possible to define a max_threshold that will -color the load value red in case the load average of the last minute is -getting higher than the configured threshold. Defaults to 5. The output -format when above max_threshold can be customized with -format_above_threshold.

-

Example order: load

-

Example format: %1min %5min %15min

-

Example max_threshold: "0.1"

-

Example format_above_threshold: Warning: %1min %5min %15min

-
-
-

5.13. Time

-

Outputs the current time in the local timezone. -To use a different timezone, you can set the TZ environment variable, -or use the tztime module. -See strftime(3) for details on the format string.

-

Example order: time

-

Example format: %Y-%m-%d %H:%M:%S

-
-
-

5.14. TzTime

-

Outputs the current time in the given timezone. -If no timezone is given, local time will be used. -See strftime(3) for details on the format string. -The system’s timezone database is usually installed in /usr/share/zoneinfo. -Files below that path make for valid timezone strings, e.g. for -/usr/share/zoneinfo/Europe/Berlin you can set timezone to Europe/Berlin -in the tztime module. -To override the locale settings of your environment, set the locale option. -To display time only when the set timezone has different time from localtime, set -hide_if_equals_localtime to true.

-

Example order: tztime berlin

-

Example format: %Y-%m-%d %H:%M:%S %Z

-

Example timezone: Europe/Berlin

-

Example locale: de_DE.UTF-8

-

If you would like to use markup in this section, there is a separate -format_time option that is automatically escaped. Its output then replaces -%time in the format string.

-

Example configuration (markup):

-
-
-
tztime berlin {
-        format = "<span foreground='#ffffff'>time:</span> %time"
-        format_time = "%H:%M %Z"
-        timezone = "Europe/Berlin"
-        hide_if_equals_localtime = true
-}
-
-
-
-

5.15. DDate

-

Outputs the current discordian date in user-specified format. See ddate(1) for -details on the format string. -Note: Neither %. nor %X are implemented yet.

-

Example order: ddate

-

Example format: %{%a, %b %d%}, %Y%N - %H

-
-
-

5.16. Volume

-

Outputs the volume of the specified mixer on the specified device. PulseAudio -and ALSA (Linux only) are supported. If PulseAudio is absent, a simplified -configuration can be used on FreeBSD and OpenBSD due to the lack of ALSA, the -device and mixer options can be ignored on these systems. On these systems -the OSS API is used instead to query /dev/mixer directly if mixer_idx is --1, otherwise /dev/mixer+mixer_idx+.

-

To get PulseAudio volume information, one must use the following format in the -device line:

-
-
-
device = "pulse"
-
-

or

-
-
-
device = "pulse:N"
-
-

where N is the index or name of the PulseAudio sink. You can obtain the name of -the sink with the following command:

-
-
-
$ pacmd list-sinks | grep name:
-           name: <alsa_output.pci-0000_00_14.2.analog-stereo>
-
-

The name is what’s inside the angle brackets, not including them. If no sink is -specified the default sink is used. If the device string is missing or is set -to "default", PulseAudio will be tried if detected and will fallback to ALSA -(Linux) or OSS (FreeBSD/OpenBSD).

-

Example order: volume master

-

Example format: ♪ (%devicename): %volume

-

Example format_muted: ♪ (%devicename): 0%%

-

Example configuration:

-
-
-
volume master {
-        format = "♪: %volume"
-        format_muted = "♪: muted (%volume)"
-        device = "default"
-        mixer = "Master"
-        mixer_idx = 0
-}
-
-

Example configuration (PulseAudio):

-
-
-
volume master {
-        format = "♪: %volume"
-        format_muted = "♪: muted (%volume)"
-        device = "pulse:1"
-}
-
-
-
-
volume master {
-        format = "♪: %volume"
-        format_muted = "♪: muted (%volume)"
-        device = "pulse:alsa_output.pci-0000_00_14.2.analog-stereo"
-}
-
-
-
-

5.17. File Contents

-

Outputs the contents of the specified file. You can use this to check contents -of files on your system, for example /proc/uptime. By default the function only -reads the first 254 characters of the file, if you want to override this set -the Max_characters option. It will never read beyond the first 4095 characters. -If the file is not found "no file" will be printed, if the file can’t be read -"error read" will be printed.

-

Example order: read_file UPTIME

-

Example format: %title: %content

-

Example format_bad: %title - %errno: %error

-

Example path: /proc/uptime

-

Example Max_characters: 255

-
-
-
-
-

6. Universal module options

-
-

When using the i3bar output format, there are a few additional options that -can be used with all modules to customize their appearance:

-
-
-align -
-
-

- The alignment policy to use when the minimum width (see below) is not - reached. Either center (default), right or left. -

-
-
-min_width -
-
-

- The minimum width (in pixels) the module should occupy. If the module takes - less space than the specified size, the block will be padded to the left - and/or the right side, according to the defined alignment policy. This is - useful when you want to prevent the whole status line from shifting when - values take more or less space between each iteration. - The option can also be a string. In this case, the width of the given text - determines the minimum width of the block. This is useful when you want to - set a sensible minimum width regardless of which font you are using, and at - what particular size. Please note that a number enclosed with quotes will - still be treated as a number. -

-
-
-separator -
-
-

- A boolean value which specifies whether a separator line should be drawn - after this block. The default is true, meaning the separator line will be - drawn. Note that if you disable the separator line, there will still be a - gap after the block, unless you also use separator_block_width. -

-
-
-separator_block_width -
-
-

- The amount of pixels to leave blank after the block. In the middle of this - gap, a separator symbol will be drawn unless separator is disabled. This is - why the specified width should leave enough space for the separator symbol. -

-
-
-

Example configuration:

-
-
-
disk "/" {
-    format = "%avail"
-    align = "left"
-    min_width = 100
-    separator = false
-    separator_block_width = 1
-}
-
-
-
-
-

7. Using i3status with dzen2

-
-

After installing dzen2, you can directly use it with i3status. Just ensure that -output_format is set to dzen2. Note: min_width is not supported.

-

Example for usage of i3status with dzen2:

-
-
-
i3status | dzen2 -fg white -ta r -w 1280 \
--fn "-misc-fixed-medium-r-normal--13-120-75-75-C-70-iso8859-1"
-
-
-
-
-

8. Using i3status with xmobar

-
-

To get xmobar to start, you might need to copy the default configuration -file to ~/.xmobarrc. Also, ensure that the output_format option for i3status -is set to xmobar. Note: min_width is not supported.

-

Example for usage of i3status with xmobar:

-
-
-
i3status | xmobar -o -t "%StdinReader%" -c "[Run StdinReader]"
-
-
-
-
-

9. What about CPU frequency?

-
-

While talking about specific things, please understand this section as a -general explanation why your favorite information is not included in i3status.

-

Let’s talk about CPU frequency specifically. Many people don’t understand how -frequency scaling works precisely. The generally recommended CPU frequency -governor ("ondemand") changes the CPU frequency far more often than i3status -could display it. The display number is therefore often incorrect and doesn’t -tell you anything useful either.

-

In general, i3status wants to display things which you would look at -occasionally anyways, like the current date/time, whether you are connected to -a WiFi network or not, and if you have enough disk space to fit that 4.3 GiB -download.

-

However, if you need to look at some kind of information more than once in a -while, you are probably better off with a script doing that, which pops up. -After all, the point of computers is not to burden you with additional boring -tasks like repeatedly checking a number.

-
-
-
-

10. External scripts/programs with i3status

-
-

In i3status, we don’t want to implement process management again. Therefore, -there is no module to run arbitrary scripts or commands. Instead, you should -use your shell, for example like this:

-

Example for prepending the i3status output:

-
-
-
#!/bin/sh
-# shell script to prepend i3status with more stuff
-
-i3status | while :
-do
-        read line
-        echo "mystuff | $line" || exit 1
-done
-
-

Put that in some script, say .bin/my_i3status.sh and execute that instead of i3status.

-

Note that if you want to use the JSON output format (with colors in i3bar), you -need to use a slightly more complex wrapper script. There are examples in the -contrib/ folder, see https://github.com/i3/i3status/tree/master/contrib

-
-
-
-

11. SIGNALS

-
-

When receiving SIGUSR1, i3status’s nanosleep() will be interrupted and thus -you will force an update. You can use killall -USR1 i3status to force an update -after changing the system volume, for example.

-
-
-
-

12. SEE ALSO

-
-

strftime(3), date(1), glob(3), dzen2(1), xmobar(1)

-
-
-
-

13. AUTHORS

-
-

Michael Stapelberg and contributors

-

Thorsten Toepper

-

Baptiste Daroussin

-

Axel Wagner

-

Fernando Tarlá Cardoso Lemos

-
-
-
-

- - - + + + + + + + + +i3status(1) + + + + +
+
+

NAME

+
+
+

i3status - Generates a status line for i3bar, dzen2, xmobar or lemonbar

+
+
+
+
+

SYNOPSIS

+
+
+

i3status [-c configfile] [-h] [-v]

+
+
+
+
+

OPTIONS

+
+
+
+
-c
+
+

Specifies an alternate configuration file path. By default, i3status looks for +configuration files in the following order:

+
+
    +
  1. +

    ~/.config/i3status/config (or $XDG_CONFIG_HOME/i3status/config if set)

    +
  2. +
  3. +

    /etc/xdg/i3status/config (or $XDG_CONFIG_DIRS/i3status/config if set)

    +
  4. +
  5. +

    ~/.i3status.conf

    +
  6. +
  7. +

    /etc/i3status.conf

    +
  8. +
+
+
+
+
+
+
+
+

DESCRIPTION

+
+
+

i3status is a small program for generating a status bar for i3bar, dzen2, +xmobar, lemonbar or similar programs. It is designed to be very efficient by +issuing a very small number of system calls, as one generally wants to update +such a status line every second. This ensures that even under high load, your +status bar is updated correctly. Also, it saves a bit of energy by not hogging +your CPU as much as spawning the corresponding amount of shell commands would.

+
+
+
+
+

CONFIGURATION

+
+
+

The basic idea of i3status is that you can specify which "modules" should +be used (the order directive). You can then configure each module with its +own section. For every module, you can specify the output format. See below +for a complete reference.

+
+
+
Sample configuration
+
+
general {
+        output_format = "dzen2"
+        colors = true
+        interval = 5
+}
+
+order += "ipv6"
+order += "disk /"
+order += "run_watch DHCP"
+order += "run_watch VPNC"
+order += "path_exists VPN"
+order += "wireless wlan0"
+order += "ethernet eth0"
+order += "battery 0"
+order += "cpu_temperature 0"
+order += "memory"
+order += "load"
+order += "tztime local"
+order += "tztime berlin"
+
+wireless wlan0 {
+        format_up = "W: (%quality at %essid, %bitrate) %ip"
+        format_down = "W: down"
+}
+
+ethernet eth0 {
+        format_up = "E: %ip (%speed)"
+        format_down = "E: down"
+}
+
+battery 0 {
+        format = "%status %percentage %remaining %emptytime"
+        format_down = "No battery"
+        status_chr = "⚡ CHR"
+        status_bat = "🔋 BAT"
+        status_unk = "? UNK"
+        status_full = "☻ FULL"
+        path = "/sys/class/power_supply/BAT%d/uevent"
+        low_threshold = 10
+}
+
+run_watch DHCP {
+        pidfile = "/var/run/dhclient*.pid"
+}
+
+run_watch VPNC {
+        # file containing the PID of a vpnc process
+        pidfile = "/var/run/vpnc/pid"
+}
+
+path_exists VPN {
+        # path exists when a VPN tunnel launched by nmcli/nm-applet is active
+        path = "/proc/sys/net/ipv4/conf/tun0"
+}
+
+tztime local {
+        format = "%Y-%m-%d %H:%M:%S"
+        hide_if_equals_localtime = true
+}
+
+tztime berlin {
+        format = "%Y-%m-%d %H:%M:%S %Z"
+        timezone = "Europe/Berlin"
+}
+
+load {
+	format = "%5min"
+}
+
+cpu_temperature 0 {
+	format = "T: %degrees °C"
+	path = "/sys/devices/platform/coretemp.0/temp1_input"
+}
+
+memory {
+        format = "%used"
+        threshold_degraded = "10%"
+        format_degraded = "MEMORY: %free"
+}
+
+disk "/" {
+	format = "%free"
+}
+
+read_file uptime {
+	path = "/proc/uptime"
+}
+
+
+
+

General

+
+

The colors directive will disable all colors if you set it to false. You can +also specify the colors that will be used to display "good", "degraded" or "bad" +values using the color_good, color_degraded or color_bad directives, +respectively. Those directives are only used if color support is not disabled by +the colors directive. The input format for color values is the canonical RGB +hexadecimal triplet (with no separators between the colors), prefixed by a hash +character ("#").

+
+
+

Example configuration:

+
+
+
+
color_good = "#00FF00"
+
+
+
+

Likewise, you can use the color_separator directive to specify the color that +will be used to paint the separator bar. The separator is always output in +color, even when colors are disabled by the colors directive. This option has +no effect when output_format is set to i3bar or none.

+
+
+

The interval directive specifies the time in seconds for which i3status will +sleep before printing the next status line.

+
+
+

Using output_format you can choose which format strings i3status should +use in its output. Currently available are:

+
+
+
+
i3bar
+
+

i3bar comes with i3 and provides a workspace bar which does the right thing in +multi-monitor situations. It also comes with tray support and can display the +i3status output. This output type uses JSON to pass as much meta-information to +i3bar as possible (like colors, which blocks can be shortened in which way, +etc.).

+
+
dzen2
+
+

Dzen is a general purpose messaging, notification and menuing program for X11. +It was designed to be scriptable in any language and integrate well with window +managers like dwm, wmii and xmonad though it will work with any window manager

+
+
xmobar
+
+

xmobar is a minimalistic, text based, status bar. It was designed to work +with the xmonad Window Manager.

+
+
lemonbar
+
+

lemonbar is a lightweight bar based entirely on XCB. It has full UTF-8 support +and is EWMH compliant.

+
+
term
+
+

Use ANSI Escape sequences to produce a terminal-output as close as possible to +the graphical outputs. This makes debugging your config file a little bit +easier because the terminal-output of i3status becomes much more readable, but +should only used for such quick glances, because it will only support very +basic output-features (for example you only get 3 bits of color depth).

+
+
none
+
+

Does not use any color codes. Separates values by the pipe symbol by default. +This should be used with i3bar and can be used for custom scripts.

+
+
+
+
+

It’s also possible to use the color_good, color_degraded, color_bad directives +to define specific colors per module. If one of these directives is defined +in a module section its value will override the value defined in the general +section just for this module.

+
+
+

If you don’t fancy the vertical separators between modules i3status/i3bar +uses by default, you can employ the separator directive to configure how +modules are separated. You can also disable the default separator altogether by +setting it to the empty string. You might then define separation as part of a +module’s format string. This is your only option when using the i3bar output +format as the separator is drawn by i3bar directly otherwise. For the other +output formats, the provided non-empty string will be automatically enclosed +with the necessary coloring bits if color support is enabled.

+
+
+

i3bar supports Pango markup, allowing your format strings to specify font, +color, size, etc. by setting the markup directive to "pango". Note that the +ampersand ("&"), less-than ("<"), greater-than (">"), single-quote ("'"), and +double-quote (""") characters need to be replaced with "&amp;", "&lt;", +"&gt;", "&apos;", and "&quot;" respectively. This is done automatically +for generated content (e.g. wireless ESSID, time).

+
+
+

Example configuration:

+
+
+
+
general {
+    output_format = "xmobar"
+    separator = "  "
+}
+
+order += "load"
+order += "disk /"
+
+load {
+    format = "[ load: %1min, %5min, %15min ]"
+}
+disk "/" {
+    format = "%avail"
+}
+
+
+
+
+

IPv6

+
+

This module gets the IPv6 address used for outgoing connections (that is, the +best available public IPv6 address on your computer).

+
+
+

Example format_up: %ip

+
+
+

Example format_down: no IPv6

+
+
+
+

Disk

+
+

Gets used, free, available and total amount of bytes on the given mounted filesystem.

+
+
+

These values can also be expressed in percentages with the percentage_used, +percentage_free, percentage_avail and percentage_used_of_avail formats.

+
+
+

Byte sizes are presented in a human readable format using a set of prefixes +whose type can be specified via the "prefix_type" option. Three sets of +prefixes are available:

+
+
+
+
binary
+
+

IEC prefixes (Ki, Mi, Gi, Ti) represent multiples of powers of 1024. +This is the default.

+
+
decimal
+
+

SI prefixes (k, M, G, T) represent multiples of powers of 1000.

+
+
custom
+
+

The custom prefixes (K, M, G, T) represent multiples of powers of 1024.

+
+
+
+
+

It is possible to define a low_threshold that causes the disk text to be +displayed using color_bad. The low_threshold type can be of threshold_type +"bytes_free", "bytes_avail", "percentage_free", or "percentage_avail", where +the former two can be prepended by a generic prefix (k, m, g, t) having +prefix_type. So, if you configure low_threshold to 2, threshold_type to +"gbytes_avail", and prefix_type to "binary", and the remaining available disk +space is below 2 GiB, it will be colored bad. If not specified, threshold_type +is assumed to be "percentage_avail" and low_threshold to be set to 0, which +implies no coloring at all. You can customize the output format when below +low_threshold with format_below_threshold.

+
+
+

You can define a different format with the option "format_not_mounted" +which is used if the path does not exist or is not a mount point. Defaults to "".

+
+
+

Example order: disk /mnt/usbstick

+
+
+

Example format: %free (%avail)/ %total

+
+
+

Example format: %percentage_used used, %percentage_free free, %percentage_avail avail

+
+
+

Example prefix_type: custom

+
+
+

Example low_threshold: 5

+
+
+

Example format_below_threshold: Warning: %percentage_avail

+
+
+

Example threshold_type: percentage_free

+
+
+
+

Run-watch

+
+

Expands the given path to a pidfile and checks if the process ID found inside +is valid (that is, if the process is running). You can use this to check if +a specific application, such as a VPN client or your DHCP client is running. +There also is an option "format_down". You can hide the output with +format_down="".

+
+
+

Example order: run_watch DHCP

+
+
+

Example format: %title: %status

+
+
+
+

Path-exists

+
+

Checks if the given path exists in the filesystem. You can use this to check if +something is active, like for example a VPN tunnel managed by NetworkManager. +There also is an option "format_down". You can hide the output with +format_down="".

+
+
+

Example order: path_exists VPN

+
+
+

Example format: %title: %status

+
+
+
+

Wireless

+
+

Gets the link quality, frequency and ESSID of the given wireless network +interface. You can specify different format strings for the network being +connected or not connected. The quality is padded with leading zeroes by +default; to pad with something else use format_quality.

+
+
+

The special interface name _first_ will be replaced by the first wireless +network interface found on the system (excluding devices starting with "lo").

+
+
+

Example order: wireless wlan0

+
+
+

Example format_up: W: (%quality at %essid, %bitrate / %frequency) %ip

+
+
+

Example format_down: W: down

+
+
+

Example format_quality: "%03d%s"

+
+
+
+

Ethernet

+
+

Gets the IP address and (if possible) the link speed of the given ethernet +interface. If no IPv4 address is available and an IPv6 address is, it will be +displayed.

+
+
+

The special interface name _first_ will be replaced by the first non-wireless +network interface found on the system (excluding devices starting with "lo").

+
+
+

Example order: ethernet eth0

+
+
+

Example format_up: E: %ip (%speed)

+
+
+

Example format_down: E: down

+
+
+
+

Battery

+
+

Gets the status (charging, discharging, unknown, full), percentage, remaining +time and power consumption (in Watts) of the given battery and when it’s +estimated to be empty. If you want to use the last full capacity instead of the +design capacity (when using the design capacity, it may happen that your +battery is at 23% when fully charged because it’s old. In general, I want to +see it this way, because it tells me how worn off my battery is.), just specify +last_full_capacity = true. You can show seconds in the remaining time and +empty time estimations by setting hide_seconds = false.

+
+
+

If you want the battery percentage to be shown without decimals, add +integer_battery_capacity = true.

+
+
+

If your battery is represented in a non-standard path in /sys, be sure to +modify the "path" property accordingly, i.e. pointing to the uevent file on +your system. The first occurrence of %d gets replaced with the battery number, +but you can just hard-code a path as well.

+
+
+

It is possible to define a low_threshold that causes the battery text to be +colored red. The low_threshold type can be of threshold_type "time" or +"percentage". So, if you configure low_threshold to 10 and threshold_type to +"time", and your battery lasts another 9 minutes, it will be colored red.

+
+
+

To show an aggregate of all batteries in the system, use "all" as the number. In +this case (for Linux), the /sys path must contain the "%d" sequence. Otherwise, +the number indicates the battery index as reported in /sys.

+
+
+

Optionally custom strings including any UTF-8 symbols can be used for different +battery states. This makes it possible to display individual symbols +for each state (charging, discharging, unknown, full) +Of course it will also work with special iconic fonts, such as FontAwesome. +If any of these special status strings are omitted, the default (CHR, BAT, UNK, +FULL) is used.

+
+
+

Example order (for the first battery): battery 0

+
+
+

Example order (aggregate of all batteries): battery all

+
+
+

Example format: %status %remaining (%emptytime %consumption)

+
+
+

Example format_down: No battery

+
+
+

Example status_chr: ⚡ CHR

+
+
+

Example status_bat: 🔋 BAT

+
+
+

Example status_unk: ? UNK

+
+
+

Example status_full: ☻ FULL

+
+
+

Example low_threshold: 30

+
+
+

Example threshold_type: time

+
+
+

Example path (%d replaced by title number): /sys/class/power_supply/CMB%d/uevent

+
+
+

Example path (ignoring the number): /sys/class/power_supply/CMB1/uevent

+
+
+
+

CPU-Temperature

+
+

Gets the temperature of the given thermal zone. It is possible to +define a max_threshold that will color the temperature red in case the +specified thermal zone is getting too hot. Defaults to 75 degrees C. The +output format when above max_threshold can be customized with +format_above_threshold.

+
+
+

Example order: cpu_temperature 0

+
+
+

Example format: T: %degrees °C

+
+
+

Example max_threshold: 42

+
+
+

Example format_above_threshold: Warning T above threshold: %degrees °C

+
+
+

Example path: /sys/devices/platform/coretemp.0/temp1_input

+
+
+
+

CPU Usage

+
+

Gets the percentual CPU usage from /proc/stat (Linux) or sysctl(3) +(FreeBSD/OpenBSD).

+
+
+

It is possible to define a max_threshold that will color the load +value red in case the CPU average over the last interval is getting +higher than the configured threshold. Defaults to 95. The output +format when above max_threshold can be customized with +format_above_threshold.

+
+
+

It is possible to define a degraded_threshold that will color the load +value yellow in case the CPU average over the last interval is getting +higher than the configured threshold. Defaults to 90. The output format +when above degraded threshold can be customized with +format_above_degraded_threshold.

+
+
+

For displaying the Nth CPU usage, you can use the %cpu<N> format string, +starting from %cpu0. This feature is currently not supported in FreeBSD.

+
+
+

Example order: cpu_usage

+
+
+

Example format: all: %usage CPU_0: %cpu0 CPU_1: %cpu1

+
+
+

Example max_threshold: 75

+
+
+

Example format_above_threshold: Warning above threshold: %usage

+
+
+

Example degraded_threshold: 25

+
+
+

Example format_above_degraded_threshold: Warning above degraded threshold: %usage

+
+
+
+

Memory

+
+

Gets the memory usage from system on a Linux system from /proc/meminfo. Other +systems are currently not supported.

+
+
+

As format placeholders, total, used, free, available and shared are +available. These will print human readable values. It’s also possible to prefix +the placeholders with percentage_ to get a value in percent.

+
+
+

It’s possible to define a threshold_degraded and a threshold_critical to +color the status bar output in yellow or red, if the available memory falls +below the given threshold. Possible values of the threshold can be any integer, +suffixed with an iec symbol (T, G, M, K). Alternatively, the integer +can be suffixed by a percent sign, which then rets evaluated relatively to +total memory.

+
+
+

If the format_degraded parameter is given and either the critical or the +degraded threshold applies, format_degraded will get used as format string. +It acts equivalently to format.

+
+
+

As Linux' meminfo doesn’t expose the overall memory in use, there are multiple +methods to distinguish the actually used memory.

+
+
+

Example memory_used_method: memavailable ("total memory" - "MemAvailable", matches free command)

+
+
+

Example memory_used_method: classical ("total memory" - "free" - "buffers" - "cache", matches gnome system monitor)

+
+
+

Example order: memory

+
+
+

Example format: %free %available (%used) / %total

+
+
+

Example format: %percentage_used used, %percentage_free free, %percentage_shared shared

+
+
+

Example threshold_degraded: 10%

+
+
+

Example threshold_critical: 5%

+
+
+

Example format_degraded: Memory LOW: %free

+
+
+
+

Load

+
+

Gets the system load (number of processes waiting for CPU time in the last +1, 5 and 15 minutes). It is possible to define a max_threshold that will +color the load value red in case the load average of the last minute is +getting higher than the configured threshold. Defaults to 5. The output +format when above max_threshold can be customized with +format_above_threshold.

+
+
+

Example order: load

+
+
+

Example format: %1min %5min %15min

+
+
+

Example max_threshold: "0.1"

+
+
+

Example format_above_threshold: Warning: %1min %5min %15min

+
+
+
+

Time

+
+

Outputs the current time in the local timezone. +To use a different timezone, you can set the TZ environment variable, +or use the tztime module. +See strftime(3) for details on the format string.

+
+
+

Example order: time

+
+
+

Example format: %Y-%m-%d %H:%M:%S

+
+
+
+

TzTime

+
+

Outputs the current time in the given timezone. +If no timezone is given, local time will be used. +See strftime(3) for details on the format string. +The system’s timezone database is usually installed in /usr/share/zoneinfo. +Files below that path make for valid timezone strings, e.g. for +/usr/share/zoneinfo/Europe/Berlin you can set timezone to Europe/Berlin +in the tztime module. +To override the locale settings of your environment, set the locale option. +To display time only when the set timezone has different time from localtime, set +hide_if_equals_localtime to true.

+
+
+

Example order: tztime berlin

+
+
+

Example format: %Y-%m-%d %H:%M:%S %Z

+
+
+

Example timezone: Europe/Berlin

+
+
+

Example locale: de_DE.UTF-8

+
+
+

If you would like to use markup in this section, there is a separate +format_time option that is automatically escaped. Its output then replaces +%time in the format string.

+
+
+

Example configuration (markup):

+
+
+
+
tztime berlin {
+	format = "<span foreground='#ffffff'>time:</span> %time"
+	format_time = "%H:%M %Z"
+	timezone = "Europe/Berlin"
+	hide_if_equals_localtime = true
+}
+
+
+
+
+

DDate

+
+

Outputs the current discordian date in user-specified format. See ddate(1) for +details on the format string. +Note: Neither %. nor %X are implemented yet.

+
+
+

Example order: ddate

+
+
+

Example format: %{%a, %b %d%}, %Y%N - %H

+
+
+
+

Volume

+
+

Outputs the volume of the specified mixer on the specified device. PulseAudio +and ALSA (Linux only) are supported. If PulseAudio is absent, a simplified +configuration can be used on FreeBSD and OpenBSD due to the lack of ALSA, the +device and mixer options can be ignored on these systems. On these systems +the OSS API is used instead to query /dev/mixer directly if mixer_idx is +-1, otherwise /dev/mixer+mixer_idx+.

+
+
+

To get PulseAudio volume information, one must use the following format in the +device line:

+
+
+
+
device = "pulse"
+
+
+
+

or

+
+
+
+
device = "pulse:N"
+
+
+
+

where N is the index or name of the PulseAudio sink. You can obtain the name of +the sink with the following command:

+
+
+
+
$ pacmd list-sinks | grep name:
+           name: <alsa_output.pci-0000_00_14.2.analog-stereo>
+
+
+
+

The name is what’s inside the angle brackets, not including them. If no sink is +specified the default sink is used. If the device string is missing or is set +to "default", PulseAudio will be tried if detected and will fallback to ALSA +(Linux) or OSS (FreeBSD/OpenBSD).

+
+
+

Example order: volume master

+
+
+

Example format: ♪ (%devicename): %volume

+
+
+

Example format_muted: ♪ (%devicename): 0%%

+
+
+

Example configuration:

+
+
+
+
volume master {
+	format = "♪: %volume"
+	format_muted = "♪: muted (%volume)"
+	device = "default"
+	mixer = "Master"
+	mixer_idx = 0
+}
+
+
+
+

Example configuration (PulseAudio):

+
+
+
+
volume master {
+	format = "♪: %volume"
+	format_muted = "♪: muted (%volume)"
+	device = "pulse:1"
+}
+
+
+
+
+
volume master {
+	format = "♪: %volume"
+	format_muted = "♪: muted (%volume)"
+	device = "pulse:alsa_output.pci-0000_00_14.2.analog-stereo"
+}
+
+
+
+
+

File Contents

+
+

Outputs the contents of the specified file. You can use this to check contents +of files on your system, for example /proc/uptime. By default the function only +reads the first 254 characters of the file, if you want to override this set +the Max_characters option. It will never read beyond the first 4095 characters. +If the file is not found "no file" will be printed, if the file can’t be read +"error read" will be printed.

+
+
+

Example order: read_file UPTIME

+
+
+

Example format: %title: %content

+
+
+

Example format_bad: %title - %errno: %error

+
+
+

Example path: /proc/uptime

+
+
+

Example Max_characters: 255

+
+
+
+
+
+

Universal module options

+
+
+

When using the i3bar output format, there are a few additional options that +can be used with all modules to customize their appearance:

+
+
+
+
align
+
+

The alignment policy to use when the minimum width (see below) is not +reached. Either center (default), right or left.

+
+
min_width
+
+

The minimum width (in pixels) the module should occupy. If the module takes +less space than the specified size, the block will be padded to the left +and/or the right side, according to the defined alignment policy. This is +useful when you want to prevent the whole status line from shifting when +values take more or less space between each iteration. +The option can also be a string. In this case, the width of the given text +determines the minimum width of the block. This is useful when you want to +set a sensible minimum width regardless of which font you are using, and at +what particular size. Please note that a number enclosed with quotes will +still be treated as a number.

+
+
separator
+
+

A boolean value which specifies whether a separator line should be drawn +after this block. The default is true, meaning the separator line will be +drawn. Note that if you disable the separator line, there will still be a +gap after the block, unless you also use separator_block_width.

+
+
separator_block_width
+
+

The amount of pixels to leave blank after the block. In the middle of this +gap, a separator symbol will be drawn unless separator is disabled. This is +why the specified width should leave enough space for the separator symbol.

+
+
+
+
+

Example configuration:

+
+
+
+
disk "/" {
+    format = "%avail"
+    align = "left"
+    min_width = 100
+    separator = false
+    separator_block_width = 1
+}
+
+
+
+
+
+

Using i3status with dzen2

+
+
+

After installing dzen2, you can directly use it with i3status. Just ensure that +output_format is set to dzen2. Note: min_width is not supported.

+
+
+

Example for usage of i3status with dzen2:

+
+
+
+
i3status | dzen2 -fg white -ta r -w 1280 \
+-fn "-misc-fixed-medium-r-normal--13-120-75-75-C-70-iso8859-1"
+
+
+
+
+
+

Using i3status with xmobar

+
+
+

To get xmobar to start, you might need to copy the default configuration +file to ~/.xmobarrc. Also, ensure that the output_format option for i3status +is set to xmobar. Note: min_width is not supported.

+
+
+

Example for usage of i3status with xmobar:

+
+
+
+
i3status | xmobar -o -t "%StdinReader%" -c "[Run StdinReader]"
+
+
+
+
+
+

What about CPU frequency?

+
+
+

While talking about specific things, please understand this section as a +general explanation why your favorite information is not included in i3status.

+
+
+

Let’s talk about CPU frequency specifically. Many people don’t understand how +frequency scaling works precisely. The generally recommended CPU frequency +governor ("ondemand") changes the CPU frequency far more often than i3status +could display it. The display number is therefore often incorrect and doesn’t +tell you anything useful either.

+
+
+

In general, i3status wants to display things which you would look at +occasionally anyways, like the current date/time, whether you are connected to +a WiFi network or not, and if you have enough disk space to fit that 4.3 GiB +download.

+
+
+

However, if you need to look at some kind of information more than once in a +while, you are probably better off with a script doing that, which pops up. +After all, the point of computers is not to burden you with additional boring +tasks like repeatedly checking a number.

+
+
+
+
+

External scripts/programs with i3status

+
+
+

In i3status, we don’t want to implement process management again. Therefore, +there is no module to run arbitrary scripts or commands. Instead, you should +use your shell, for example like this:

+
+
+

Example for prepending the i3status output:

+
+
+
+
#!/bin/sh
+# shell script to prepend i3status with more stuff
+
+i3status | while :
+do
+	read line
+	echo "mystuff | $line" || exit 1
+done
+
+
+
+

Put that in some script, say .bin/my_i3status.sh and execute that instead of i3status.

+
+
+

Note that if you want to use the JSON output format (with colors in i3bar), you +need to use a slightly more complex wrapper script. There are examples in the +contrib/ folder, see https://github.com/i3/i3status/tree/master/contrib

+
+
+
+
+

SIGNALS

+
+
+

When receiving SIGUSR1, i3status’s nanosleep() will be interrupted and thus +you will force an update. You can use killall -USR1 i3status to force an update +after changing the system volume, for example.

+
+
+
+
+

SEE ALSO

+
+
+

strftime(3), date(1), glob(3), dzen2(1), xmobar(1)

+
+
+
+
+

AUTHORS

+
+
+

Michael Stapelberg and contributors

+
+
+

Thorsten Toepper

+
+
+

Baptiste Daroussin

+
+
+

Axel Wagner

+
+
+

Fernando Tarlá Cardoso Lemos

+
+
+
+
+ + + \ No newline at end of file diff --git a/docs/ipc.html b/docs/ipc.html index 5a54d78..e0a7d92 100644 --- a/docs/ipc.html +++ b/docs/ipc.html @@ -1,215 +1,256 @@ - - - -i3: IPC interface (interprocess communication) - - - - + + + + + +IPC interface (interprocess communication) + - -
- - -
-
- - + + +
-

3. Receiving replies from i3

+

Receiving replies from i3

-

Replies from i3 usually consist of a simple string (the length of the string +

+

Replies from i3 usually consist of a simple string (the length of the string is the message_length, so you can consider them length-prefixed) which in turn contain the JSON serialization of a data structure. For example, the GET_WORKSPACES message returns an array of workspaces (each workspace is a map -with certain attributes).

+with certain attributes).

+
-

3.1. Reply format

-

The reply format is identical to the normal message format. There also is +

Reply format

+
+

The reply format is identical to the normal message format. There also is the magic string, then the message length, then the message type and the -payload.

-

The following reply types are implemented:

-
-
-COMMAND (0) -
+payload.

+
+
+

The following reply types are implemented:

+
+
+
+
COMMAND (0)
-

- Confirmation/Error code for the RUN_COMMAND message. -

+

Confirmation/Error code for the RUN_COMMAND message.

-
-WORKSPACES (1) -
+
WORKSPACES (1)
-

- Reply to the GET_WORKSPACES message. -

+

Reply to the GET_WORKSPACES message.

-
-SUBSCRIBE (2) -
+
SUBSCRIBE (2)
-

- Confirmation/Error code for the SUBSCRIBE message. -

+

Confirmation/Error code for the SUBSCRIBE message.

-
-OUTPUTS (3) -
+
OUTPUTS (3)
-

- Reply to the GET_OUTPUTS message. -

+

Reply to the GET_OUTPUTS message.

-
-TREE (4) -
+
TREE (4)
-

- Reply to the GET_TREE message. -

+

Reply to the GET_TREE message.

-
-MARKS (5) -
+
MARKS (5)
-

- Reply to the GET_MARKS message. -

+

Reply to the GET_MARKS message.

-
-BAR_CONFIG (6) -
+
BAR_CONFIG (6)
-

- Reply to the GET_BAR_CONFIG message. -

+

Reply to the GET_BAR_CONFIG message.

-
-VERSION (7) -
+
VERSION (7)
-

- Reply to the GET_VERSION message. -

+

Reply to the GET_VERSION message.

-
-BINDING_MODES (8) -
+
BINDING_MODES (8)
-

- Reply to the GET_BINDING_MODES message. -

+

Reply to the GET_BINDING_MODES message.

-
-GET_CONFIG (9) -
+
GET_CONFIG (9)
-

- Reply to the GET_CONFIG message. -

+

Reply to the GET_CONFIG message.

-
-TICK (10) -
+
TICK (10)
-

- Reply to the SEND_TICK message. -

+

Reply to the SEND_TICK message.

-
-GET_BINDING_STATE (12) -
+
GET_BINDING_STATE (12)
-

- Reply to the GET_BINDING_STATE message. -

+

Reply to the GET_BINDING_STATE message.

-
+ +
-

3.2. COMMAND reply

-

The reply consists of a list of serialized maps for each command that was -parsed. Each has the property success (bool) and may also include a -human-readable error message in the property error (string).

-
- +

COMMAND reply

+
+

The reply consists of a list of serialized maps for each command that was +parsed. Each has the property success (bool) and may also include a +human-readable error message in the property error (string).

+
+
+
+ - -
Note
When sending the restart command, you will get a singular reply once the + +When sending the restart command, you will get a singular reply once the restart completed. All IPC connection states (e.g. subscriptions) will reset and all but one socket will be closed. Libraries must be able to cope with this by aligning their internal states. It is also recommended that libraries close -the last remaining socket(one which replied to restart command) to achieve -the full reset.
+the last remaining socket(one which replied to restart command) to achieve +the full reset. + + +
-
- +
+
+ - -
Note
It is easiest to always send the restart command alone: due to i3’s + +It is easiest to always send the restart command alone: due to i3’s state reset, the reply messages of preceding commands are lost, and following -commands will not be executed.
+commands will not be executed. + + +
-
- +
+
+ - -
Note
When processing the exit command, i3 will immediately exit without -sending a reply. Expect the socket to be shut down.
+ +When processing the exit command, i3 will immediately exit without +sending a reply. Expect the socket to be shut down. + + + +
+
+

Example:

-

Example:

-
[{ "success": true }]
-
-

When the specified command cannot be parsed, success will be false and -parse_error will be true:

-

Example:

+
[{ "success": true }]
+
+
+
+

When the specified command cannot be parsed, success will be false and +parse_error will be true:

+
+
+

Example:

+
-
[{ "success": false, "parse_error": true }]
-
+
[{ "success": false, "parse_error": true }]
+
+
-

3.3. WORKSPACES reply

-

The reply consists of a serialized list of workspaces. Each workspace has the -following properties:

-
-
-id (integer) -
-
-

- The internal ID (actually a C pointer value) of this container. Do not - make any assumptions about it. You can use it to (re-)identify and - address containers when talking to i3. -

-
-
-num (integer) -
-
-

- The logical number of the workspace. Corresponds to the command - to switch to this workspace. For named workspaces, this will be -1. -

-
-
-name (string) -
-
-

- The name of this workspace if changed by the user, otherwise defaults - to the string representation of the num field). Encoded in UTF-8. -

-
-
-visible (boolean) -
-
-

- Whether this workspace is currently visible on an output (multiple - workspaces can be visible at the same time). -

-
-
-focused (boolean) -
-
-

- Whether this workspace currently has the focus (only one workspace - can have the focus at the same time). -

-
-
-urgent (boolean) -
-
-

- Whether a window on this workspace has the "urgent" flag set. -

-
-
-rect (map) -
-
-

- The rectangle of this workspace (equals the rect of the output it - is on), consists of x, y, width, height. -

-
-
-output (string) -
-
-

- The video output this workspace is on (LVDS1, VGA1, …). -

-
-
-

Example:

+

WORKSPACES reply

+
+

The reply consists of a serialized list of workspaces. Each workspace has the +following properties:

+
+
+
+
id (integer)
+
+

The internal ID (actually a C pointer value) of this container. Do not +make any assumptions about it. You can use it to (re-)identify and +address containers when talking to i3.

+
+
num (integer)
+
+

The logical number of the workspace. Corresponds to the command +to switch to this workspace. For named workspaces, this will be -1.

+
+
name (string)
+
+

The name of this workspace if changed by the user, otherwise defaults +to the string representation of the num field). Encoded in UTF-8.

+
+
visible (boolean)
+
+

Whether this workspace is currently visible on an output (multiple +workspaces can be visible at the same time).

+
+
focused (boolean)
+
+

Whether this workspace currently has the focus (only one workspace +can have the focus at the same time).

+
+
urgent (boolean)
+
+

Whether a window on this workspace has the "urgent" flag set.

+
+
rect (map)
+
+

The rectangle of this workspace (equals the rect of the output it +is on), consists of x, y, width, height.

+
+
output (string)
+
+

The video output this workspace is on (LVDS1, VGA1, …).

+
+
+
+
+

Example:

+
-
[
+
[
  {
   "num": 0,
   "name": "1",
@@ -493,72 +491,64 @@ 

3.3. WORKSPACES reply

}, "output": "LVDS1" } -]
-
+] +
+
-

3.4. SUBSCRIBE reply

-

The reply consists of a single serialized map. The only property is -success (bool), indicating whether the subscription was successful (the -default) or whether a JSON parse error occurred.

-

Example:

+

SUBSCRIBE reply

+
+

The reply consists of a single serialized map. The only property is +success (bool), indicating whether the subscription was successful (the +default) or whether a JSON parse error occurred.

+
+
+

Example:

+
-
{ "success": true }
-
+
{ "success": true }
+
+
-

3.5. OUTPUTS reply

-

The reply consists of a serialized list of outputs. Each output has the -following properties:

-
-
-name (string) -
-
-

- The name of this output (as seen in xrandr(1)). Encoded in UTF-8. -

-
-
-active (boolean) -
-
-

- Whether this output is currently active (has a valid mode). -

-
-
-primary (boolean) -
-
-

- Whether this output is currently the primary output. -

-
-
-current_workspace (string) -
-
-

- The name of the current workspace that is visible on this output. null if - the output is not active. -

-
-
-rect (map) -
-
-

- The rectangle of this output (equals the rect of the output it - is on), consists of x, y, width, height. -

-
-
-

Example:

+

OUTPUTS reply

+
+

The reply consists of a serialized list of outputs. Each output has the +following properties:

+
+
+
+
name (string)
+
+

The name of this output (as seen in xrandr(1)). Encoded in UTF-8.

+
+
active (boolean)
+
+

Whether this output is currently active (has a valid mode).

+
+
primary (boolean)
+
+

Whether this output is currently the primary output.

+
+
current_workspace (string)
+
+

The name of the current workspace that is visible on this output. null if +the output is not active.

+
+
rect (map)
+
+

The rectangle of this output (equals the rect of the output it +is on), consists of x, y, width, height.

+
+
+
+
+

Example:

+
-
[
+
[
  {
   "name": "LVDS1",
   "active": true,
@@ -581,307 +571,224 @@ 

3.5. OUTPUTS reply

"height": 1024 } } -]
-
+] +
+
-

3.6. TREE reply

-

The reply consists of a serialized tree. Each node in the tree (representing +

TREE reply

+
+

The reply consists of a serialized tree. Each node in the tree (representing one container) has at least the properties listed below. While the nodes might have more properties, please do not use any properties which are not documented -here. They are not yet finalized and will probably change!

-
-
-id (integer) -
-
-

- The internal ID (actually a C pointer value) of this container. Do not - make any assumptions about it. You can use it to (re-)identify and - address containers when talking to i3. -

-
-
-name (string) -
-
-

- The internal name of this container. For all containers which are part - of the tree structure down to the workspace contents, this is set to a - nice human-readable name of the container. - For containers that have an X11 window, the content is the title - (_NET_WM_NAME property) of that window. - For all other containers, the content is not defined (yet). -

-
-
-type (string) -
-
-

- Type of this container. Can be one of "root", "output", "con", - "floating_con", "workspace" or "dockarea". -

-
-
-border (string) -
-
-

- Can be either "normal", "none" or "pixel", depending on the - container’s border style. -

-
-
-current_border_width (integer) -
-
-

- Number of pixels of the border width. -

-
-
-layout (string) -
-
-

- Can be either "splith", "splitv", "stacked", "tabbed", "dockarea" or - "output". - Other values might be possible in the future, should we add new - layouts. -

-
-
-orientation (string) -
-
-

- Can be either "none" (for non-split containers), "horizontal" or - "vertical". - THIS FIELD IS OBSOLETE. It is still present, but your code should not - use it. Instead, rely on the layout field. -

-
-
-percent (float) -
-
-

- The percentage which this container takes in its parent. A value of - null means that the percent property does not make sense for this - container, for example for the root container. -

-
-
-rect (map) -
-
-

- The absolute display coordinates for this container. Display - coordinates means that when you have two 1600x1200 monitors on a single - X11 Display (the standard way), the coordinates of the first window on - the second monitor are { "x": 1600, "y": 0, "width": 1600, "height": - 1200 }. -

-
-
-window_rect (map) -
-
-

- The coordinates of the actual client window inside its container. - These coordinates are relative to the container and do not include the - window decoration (which is actually rendered on the parent container). - So, when using the default layout, you will have a 2 pixel border on - each side, making the window_rect { "x": 2, "y": 0, "width": 632, - "height": 366 } (for example). -

-
-
-deco_rect (map) -
-
-

- The coordinates of the window decoration inside its container. These - coordinates are relative to the container and do not include the actual - client window. -

-
-
-geometry (map) -
-
-

- The original geometry the window specified when i3 mapped it. Used when - switching a window to floating mode, for example. -

-
-
-window (integer) -
-
-

- The X11 window ID of the actual client window inside this container. - This field is set to null for split containers or otherwise empty - containers. This ID corresponds to what xwininfo(1) and other - X11-related tools display (usually in hex). -

-
-
-window_properties (map) -
-
-

- This optional field contains all available X11 window properties from the - following list: title, instance, class, window_role and transient_for. -

-
-
-window_type (string) -
-
-

- The window type (_NET_WM_WINDOW_TYPE). Possible values are undefined, normal, - dialog, utility, toolbar, splash, menu, dropdown_menu, popup_menu, tooltip and - notification. -

-
-
-urgent (bool) -
-
-

- Whether this container (window, split container, floating container or - workspace) has the urgency hint set, directly or indirectly. All parent - containers up until the workspace container will be marked urgent if they - have at least one urgent child. -

-
-
-marks (array of string) -
-
-

- List of marks assigned to container -

-
-
-focused (bool) -
-
-

- Whether this container is currently focused. -

-
-
-focus (array of integer) -
-
-

- List of child node IDs (see nodes, floating_nodes and id) in focus - order. Traversing the tree by following the first entry in this array - will result in eventually reaching the one node with focused set to - true. -

-
-
-fullscreen_mode (integer) -
-
-

- Whether this container is in fullscreen state or not. - Possible values are - 0 (no fullscreen), - 1 (fullscreened on output) or - 2 (fullscreened globally). - Note that all workspaces are considered fullscreened on their respective output. -

-
-
-nodes (array of node) -
-
-

- The tiling (i.e. non-floating) child containers of this node. -

-
-
-floating_nodes (array of node) -
-
-

- The floating child containers of this node. Only non-empty on nodes with - type workspace. -

-
-
-

Please note that in the following example, I have left out some keys/values +here. They are not yet finalized and will probably change!

+
+
+
+
id (integer)
+
+

The internal ID (actually a C pointer value) of this container. Do not +make any assumptions about it. You can use it to (re-)identify and +address containers when talking to i3.

+
+
name (string)
+
+

The internal name of this container. For all containers which are part +of the tree structure down to the workspace contents, this is set to a +nice human-readable name of the container. +For containers that have an X11 window, the content is the title +(_NET_WM_NAME property) of that window. +For all other containers, the content is not defined (yet).

+
+
type (string)
+
+

Type of this container. Can be one of "root", "output", "con", +"floating_con", "workspace" or "dockarea".

+
+
border (string)
+
+

Can be either "normal", "none" or "pixel", depending on the +container’s border style.

+
+
current_border_width (integer)
+
+

Number of pixels of the border width.

+
+
layout (string)
+
+

Can be either "splith", "splitv", "stacked", "tabbed", "dockarea" or +"output". +Other values might be possible in the future, should we add new +layouts.

+
+
orientation (string)
+
+

Can be either "none" (for non-split containers), "horizontal" or +"vertical". +THIS FIELD IS OBSOLETE. It is still present, but your code should not +use it. Instead, rely on the layout field.

+
+
percent (float)
+
+

The percentage which this container takes in its parent. A value of +null means that the percent property does not make sense for this +container, for example for the root container.

+
+
rect (map)
+
+

The absolute display coordinates for this container. Display +coordinates means that when you have two 1600x1200 monitors on a single +X11 Display (the standard way), the coordinates of the first window on +the second monitor are { "x": 1600, "y": 0, "width": 1600, "height": +1200 }.

+
+
window_rect (map)
+
+

The coordinates of the actual client window inside its container. +These coordinates are relative to the container and do not include the +window decoration (which is actually rendered on the parent container). +So, when using the default layout, you will have a 2 pixel border on +each side, making the window_rect { "x": 2, "y": 0, "width": 632, +"height": 366 } (for example).

+
+
deco_rect (map)
+
+

The coordinates of the window decoration inside its container. These +coordinates are relative to the container and do not include the actual +client window.

+
+
geometry (map)
+
+

The original geometry the window specified when i3 mapped it. Used when +switching a window to floating mode, for example.

+
+
window (integer)
+
+

The X11 window ID of the actual client window inside this container. +This field is set to null for split containers or otherwise empty +containers. This ID corresponds to what xwininfo(1) and other +X11-related tools display (usually in hex).

+
+
window_properties (map)
+
+

This optional field contains all available X11 window properties from the +following list: title, instance, class, window_role and transient_for.

+
+
window_type (string)
+
+

The window type (_NET_WM_WINDOW_TYPE). Possible values are undefined, normal, +dialog, utility, toolbar, splash, menu, dropdown_menu, popup_menu, tooltip and +notification.

+
+
urgent (bool)
+
+

Whether this container (window, split container, floating container or +workspace) has the urgency hint set, directly or indirectly. All parent +containers up until the workspace container will be marked urgent if they +have at least one urgent child.

+
+
marks (array of string)
+
+

List of marks assigned to container

+
+
focused (bool)
+
+

Whether this container is currently focused.

+
+
focus (array of integer)
+
+

List of child node IDs (see nodes, floating_nodes and id) in focus +order. Traversing the tree by following the first entry in this array +will result in eventually reaching the one node with focused set to +true.

+
+
fullscreen_mode (integer)
+
+

Whether this container is in fullscreen state or not. + Possible values are + 0 (no fullscreen), + 1 (fullscreened on output) or + 2 (fullscreened globally). + Note that all workspaces are considered fullscreened on their respective output.

+
+
nodes (array of node)
+
+

The tiling (i.e. non-floating) child containers of this node.

+
+
floating_nodes (array of node)
+
+

The floating child containers of this node. Only non-empty on nodes with +type workspace.

+
+
+
+
+

Please note that in the following example, I have left out some keys/values which are not relevant for the type of the node. Otherwise, the example would be by far too long (it already is quite long, despite showing only 1 window and -one dock window).

-

It is useful to have an overview of the structure before taking a look at the -JSON dump:

-
    +one dock window).

    +
+
+

It is useful to have an overview of the structure before taking a look at the +JSON dump:

+
+
+
  • -

    -root -

    -
      +

      root

      +
      +
      • -

        -LVDS1 -

        -
          +

          LVDS1

          +
          +
          • -

            -topdock -

            +

            topdock

          • -

            -content -

            -
              +

              content

              +
              +
              • -

                -workspace 1 -

                -
                  +

                  workspace 1

                  +
                  +
                  • -

                    -window 1 -

                    +

                    window 1

                  • -
                  +
                +
              • -
              +
            +
          • -

            -bottomdock -

            -
              +

              bottomdock

              +
              +
              • -

                -dock window 1 -

                +

                dock window 1

              • -
              +
            +
          • -
          +
        +
      • -

        -VGA1 -

        +

        VGA1

      • -
      +
    +
  • -
-

Example:

+ +
+
+

Example:

+
-
{
+
{
  "id": 6875648,
  "name": "root",
  "rect": {
@@ -911,9 +818,9 @@ 

3.6. TREE reply

"orientation": "vertical", "rect": { "x": 0, - "y": 0, - "width": 1280, - "height": 0 + "y": 0, + "width": 1280, + "height": 0 } }, @@ -922,46 +829,46 @@

3.6. TREE reply

"name": "content", "rect": { "x": 0, - "y": 0, - "width": 1280, - "height": 782 + "y": 0, + "width": 1280, + "height": 782 }, "nodes": [ { "id": 6880464, - "name": "1", - "orientation": "horizontal", - "rect": { + "name": "1", + "orientation": "horizontal", + "rect": { "x": 0, - "y": 0, - "width": 1280, - "height": 782 - }, - "window_properties": { - "class": "Evince", - "instance": "evince", - "title": "Properties", - "transient_for": 52428808 - }, - "floating_nodes": [], - "nodes": [ + "y": 0, + "width": 1280, + "height": 782 + }, + "window_properties": { + "class": "Evince", + "instance": "evince", + "title": "Properties", + "transient_for": 52428808 + }, + "floating_nodes": [], + "nodes": [ { "id": 6929968, - "name": "#aa0000", - "border": "normal", - "percent": 1, - "rect": { + "name": "#aa0000", + "border": "normal", + "percent": 1, + "rect": { "x": 0, - "y": 18, - "width": 1280, - "height": 782 - } - } + "y": 18, + "width": 1280, + "height": 782 + } + } - ] - } + ] + } ] }, @@ -973,252 +880,188 @@

3.6. TREE reply

"orientation": "vertical", "rect": { "x": 0, - "y": 782, - "width": 1280, - "height": 18 + "y": 782, + "width": 1280, + "height": 18 }, "nodes": [ { "id": 6931312, - "name": "#00aa00", - "percent": 1, - "rect": { + "name": "#00aa00", + "percent": 1, + "rect": { "x": 0, - "y": 782, - "width": 1280, - "height": 18 - } - } + "y": 782, + "width": 1280, + "height": 18 + } + } ] } ] } ] -}
-
+} +
+
-

3.7. MARKS reply

-

The reply consists of a single array of strings for each container that has a +

MARKS reply

+
+

The reply consists of a single array of strings for each container that has a mark. A mark can only be set on one container, so the array is unique. -The order of that array is undefined.

-

If no window has a mark the response will be the empty array [].

+The order of that array is undefined.

+
+
+

If no window has a mark the response will be the empty array [].

+
-

3.8. BAR_CONFIG reply

-

This can be used by third-party workspace bars (especially i3bar, but others -are free to implement compatible alternatives) to get the bar block -configuration from i3.

-

Depending on the input, the reply is either:

-
-
-empty input -
-
-

- An array of configured bar IDs -

-
-
-Bar ID -
-
-

- A JSON map containing the configuration for the specified bar. -

-
-
-

Each bar configuration has the following properties:

-
-
-id (string) -
-
-

- The ID for this bar. Included in case you request multiple - configurations and want to differentiate the different replies. -

-
-
-mode (string) -
-
-

- Either dock (the bar sets the dock window type) or hide (the bar - does not show unless a specific key is pressed). -

-
-
-position (string) -
-
-

- Either bottom or top at the moment. -

-
-
-status_command (string) -
-
-

- Command which will be run to generate a statusline. Each line on stdout - of this command will be displayed in the bar. At the moment, no - formatting is supported. -

-
-
-font (string) -
-
-

- The font to use for text on the bar. -

-
-
-workspace_buttons (boolean) -
-
-

- Display workspace buttons or not? Defaults to true. -

-
-
-binding_mode_indicator (boolean) -
-
-

- Display the mode indicator or not? Defaults to true. -

-
-
-verbose (boolean) -
-
-

- Should the bar enable verbose output for debugging? Defaults to false. -

-
-
-colors (map) -
-
-

- Contains key/value pairs of colors. Each value is a color code in hex, - formatted #rrggbb (like in HTML). -

-
-
-

The following colors can be configured at the moment:

-
-
-background -
-
-

- Background color of the bar. -

-
-
-statusline -
-
-

- Text color to be used for the statusline. -

-
-
-separator -
-
-

- Text color to be used for the separator. -

-
-
-focused_background -
-
-

- Background color of the bar on the currently focused monitor output. -

-
-
-focused_statusline -
-
-

- Text color to be used for the statusline on the currently focused - monitor output. -

-
-
-focused_separator -
-
-

- Text color to be used for the separator on the currently focused - monitor output. -

-
-
-focused_workspace_text/focused_workspace_bg/focused_workspace_border -
-
-

- Text/background/border color for a workspace button when the workspace - has focus. -

-
-
-active_workspace_text/active_workspace_bg/active_workspace_border -
-
-

- Text/background/border color for a workspace button when the workspace - is active (visible) on some output, but the focus is on another one. - You can only tell this apart from the focused workspace when you are - using multiple monitors. -

-
-
-inactive_workspace_text/inactive_workspace_bg/inactive_workspace_border -
-
-

- Text/background/border color for a workspace button when the workspace - does not have focus and is not active (visible) on any output. This - will be the case for most workspaces. -

-
-
-urgent_workspace_text/urgent_workspace_bg/urgent_workspace_border -
-
-

- Text/background/border color for workspaces which contain at least one - window with the urgency hint set. -

-
-
-binding_mode_text/binding_mode_bg/binding_mode_border -
-
-

- Text/background/border color for the binding mode indicator. -

-
-
-

Example of configured bars:

+

BAR_CONFIG reply

+
+

This can be used by third-party workspace bars (especially i3bar, but others +are free to implement compatible alternatives) to get the bar block +configuration from i3.

+
+
+

Depending on the input, the reply is either:

+
+
+
+
empty input
+
+

An array of configured bar IDs

+
+
Bar ID
+
+

A JSON map containing the configuration for the specified bar.

+
+
+
+
+

Each bar configuration has the following properties:

+
+
+
+
id (string)
+
+

The ID for this bar. Included in case you request multiple +configurations and want to differentiate the different replies.

+
+
mode (string)
+
+

Either dock (the bar sets the dock window type) or hide (the bar +does not show unless a specific key is pressed).

+
+
position (string)
+
+

Either bottom or top at the moment.

+
+
status_command (string)
+
+

Command which will be run to generate a statusline. Each line on stdout +of this command will be displayed in the bar. At the moment, no +formatting is supported.

+
+
font (string)
+
+

The font to use for text on the bar.

+
+
workspace_buttons (boolean)
+
+

Display workspace buttons or not? Defaults to true.

+
+
binding_mode_indicator (boolean)
+
+

Display the mode indicator or not? Defaults to true.

+
+
verbose (boolean)
+
+

Should the bar enable verbose output for debugging? Defaults to false.

+
+
colors (map)
+
+

Contains key/value pairs of colors. Each value is a color code in hex, +formatted #rrggbb (like in HTML).

+
+
+
+
+

The following colors can be configured at the moment:

+
+
+
+
background
+
+

Background color of the bar.

+
+
statusline
+
+

Text color to be used for the statusline.

+
+
separator
+
+

Text color to be used for the separator.

+
+
focused_background
+
+

Background color of the bar on the currently focused monitor output.

+
+
focused_statusline
+
+

Text color to be used for the statusline on the currently focused +monitor output.

+
+
focused_separator
+
+

Text color to be used for the separator on the currently focused +monitor output.

+
+
focused_workspace_text/focused_workspace_bg/focused_workspace_border
+
+

Text/background/border color for a workspace button when the workspace +has focus.

+
+
active_workspace_text/active_workspace_bg/active_workspace_border
+
+

Text/background/border color for a workspace button when the workspace +is active (visible) on some output, but the focus is on another one. +You can only tell this apart from the focused workspace when you are +using multiple monitors.

+
+
inactive_workspace_text/inactive_workspace_bg/inactive_workspace_border
+
+

Text/background/border color for a workspace button when the workspace +does not have focus and is not active (visible) on any output. This +will be the case for most workspaces.

+
+
urgent_workspace_text/urgent_workspace_bg/urgent_workspace_border
+
+

Text/background/border color for workspaces which contain at least one +window with the urgency hint set.

+
+
binding_mode_text/binding_mode_bg/binding_mode_border
+
+

Text/background/border color for the binding mode indicator.

+
+
+
+
+

Example of configured bars:

+
-
["bar-bxuqzf"]
-
-

Example of bar configuration:

+
["bar-bxuqzf"]
+
+ +
+

Example of bar configuration:

+
-
{
+
{
  "id": "bar-bxuqzf",
  "mode": "dock",
  "position": "bottom",
@@ -1233,245 +1076,243 @@ 

3.8. BAR_CONFIG reply

"focused_workspace_text": "#ffffff", "focused_workspace_bg": "#000000" } -}
-
+} + +
-

3.9. VERSION reply

-

The reply consists of a single JSON dictionary with the following keys:

-
-
-major (integer) -
-
-

- The major version of i3, such as 4. -

-
-
-minor (integer) -
-
-

- The minor version of i3, such as 2. Changes in the IPC interface (new - features) will only occur with new minor (or major) releases. However, - bugfixes might be introduced in patch releases, too. -

-
-
-patch (integer) -
-
-

- The patch version of i3, such as 1 (when the complete version is - 4.2.1). For versions such as 4.2, patch will be set to 0. -

-
-
-human_readable (string) -
-
-

- A human-readable version of i3 containing the precise git version, - build date and branch name. When you need to display the i3 version to - your users, use the human-readable version whenever possible (since - this is what i3 --version displays, too). -

-
-
-loaded_config_file_name (string) -
-
-

- The current config path. -

-
-
-

Example:

+

VERSION reply

+
+

The reply consists of a single JSON dictionary with the following keys:

+
+
+
+
major (integer)
+
+

The major version of i3, such as 4.

+
+
minor (integer)
+
+

The minor version of i3, such as 2. Changes in the IPC interface (new +features) will only occur with new minor (or major) releases. However, +bugfixes might be introduced in patch releases, too.

+
+
patch (integer)
+
+

The patch version of i3, such as 1 (when the complete version is +4.2.1). For versions such as 4.2, patch will be set to 0.

+
+
human_readable (string)
+
+

A human-readable version of i3 containing the precise git version, +build date and branch name. When you need to display the i3 version to +your users, use the human-readable version whenever possible (since +this is what i3 --version displays, too).

+
+
loaded_config_file_name (string)
+
+

The current config path.

+
+
+
+
+

Example:

+
-
{
+
{
    "human_readable" : "4.2-169-gf80b877 (2012-08-05, branch \"next\")",
    "loaded_config_file_name" : "/home/hwangcc23/.i3/config",
    "minor" : 2,
    "patch" : 0,
    "major" : 4
-}
-
+} +
+
-

3.10. BINDING_MODES reply

-

The reply consists of an array of all currently configured binding modes.

-

Example:

+

BINDING_MODES reply

+
+

The reply consists of an array of all currently configured binding modes.

+
+
+

Example:

+
-
["default", "resize"]
-
+
["default", "resize"]
+
+
-

3.11. CONFIG reply

-

The config reply is a map which currently only contains the "config" member, -which is a string containing the config file as loaded by i3 most recently.

-

Example:

+

CONFIG reply

+
+

The config reply is a map which currently only contains the "config" member, +which is a string containing the config file as loaded by i3 most recently.

+
+
+

Example:

+
-
{ "config": "font pango:monospace 8\nbindsym Mod4+q exit\n" }
-
+
{ "config": "font pango:monospace 8\nbindsym Mod4+q exit\n" }
+
+
-

3.12. TICK reply

-

The reply is a map containing the "success" member. After the reply was +

TICK reply

+
+

The reply is a map containing the "success" member. After the reply was received, the tick event has been written to all IPC connections which subscribe to tick events. UNIX sockets are usually buffered, but you can be certain that once you receive the tick event you just triggered, you must have received all -events generated prior to the SEND_TICK message (happened-before relation).

-

Example:

+events generated prior to the SEND_TICK message (happened-before relation).

+
+
+

Example:

+
-
{ "success": true }
-
+
{ "success": true }
+
+
-

3.13. SYNC reply

-

The reply is a map containing the "success" member. After the reply was +

SYNC reply

+
+

The reply is a map containing the "success" member. After the reply was received, the i3 sync message was -responded to.

-

Example:

+responded to.

+
+
+

Example:

+
-
{ "success": true }
-
+
{ "success": true }
+
+
-

3.14. GET_BINDING_STATE reply

-

The binding_state reply is a map which currently only contains the "name" -member, which is the name of the currently active binding mode as a string.

-

Example:

+

GET_BINDING_STATE reply

+
+

The binding_state reply is a map which currently only contains the "name" +member, which is the name of the currently active binding mode as a string.

+
+
+

Example:

+
-
{ "name": "default" }
-
+
{ "name": "default" }
+
+
-

4. Events

+

Events

-

To get informed when certain things happen in i3, clients can subscribe to +

+

To get informed when certain things happen in i3, clients can subscribe to events. Events consist of a name (like "workspace") and an event reply type (like I3_IPC_EVENT_WORKSPACE). Events sent by i3 follow a format similar to replies but with the highest bit of the message type set to 1 to indicate an event reply instead of a normal reply. Note that event types and reply types do not follow the same enumeration scheme (e.g. event type 0 corresponds to the -workspace event however reply type 0 corresponds to the COMMAND reply).

-

Caveat: As soon as you subscribe to an event, it is not guaranteed any longer +workspace event however reply type 0 corresponds to the COMMAND reply).

+
+
+

Caveat: As soon as you subscribe to an event, it is not guaranteed any longer that the requests to i3 are processed in order. This means, the following situation can happen: You send a GET_WORKSPACES request but you receive a "workspace" event before receiving the reply to GET_WORKSPACES. If your program does not want to cope which such kinds of race conditions (an event based library may not have a problem here), I suggest you create a -separate connection to receive events.

-

If an event message needs to be sent and the socket is not writeable (write +separate connection to receive events.

+
+
+

If an event message needs to be sent and the socket is not writeable (write returns EAGAIN, happens when the socket doesn’t have enough buffer space for writing new data) then i3 uses a queue system to store outgoing messages for each client. This is combined with a timer: if the message queue for a client is not empty and no data where successfully written in the past 10 seconds, the connection is killed. Practically, this means that your client should try to -always read events from the socket to avoid having its connection closed.

+always read events from the socket to avoid having its connection closed.

+
-

4.1. Subscribing to events

-

By sending a message of type SUBSCRIBE with a JSON-encoded array as payload -you can register to an event.

-

Example:

+

Subscribing to events

+
+

By sending a message of type SUBSCRIBE with a JSON-encoded array as payload +you can register to an event.

+
+
+

Example:

+
-
type: SUBSCRIBE
-payload: [ "workspace", "output" ]
-
+
type: SUBSCRIBE
+payload: [ "workspace", "output" ]
+
+
-

4.2. Available events

-

The numbers in parenthesis is the event type (keep in mind that you need to -strip the highest bit first).

-
-
-workspace (0) -
-
-

- Sent when the user switches to a different workspace, when a new - workspace is initialized or when a workspace is removed (because the - last client vanished). -

-
-
-output (1) -
-
-

- Sent when RandR issues a change notification (of either screens, - outputs, CRTCs or output properties). -

-
-
-mode (2) -
-
-

- Sent whenever i3 changes its binding mode. -

-
-
-window (3) -
-
-

- Sent when a client’s window is successfully reparented (that is when i3 - has finished fitting it into a container), when a window received input - focus or when certain properties of the window have changed. -

-
-
-barconfig_update (4) -
-
-

- Sent when the hidden_state or mode field in the barconfig of any bar - instance was updated and when the config is reloaded. -

-
-
-binding (5) -
-
-

- Sent when a configured command binding is triggered with the keyboard or - mouse -

-
-
-shutdown (6) -
-
-

- Sent when the ipc shuts down because of a restart or exit by user command -

-
-
-tick (7) -
-
-

- Sent when the ipc client subscribes to the tick event (with "first": - true) or when any ipc client sends a SEND_TICK message (with "first": - false). -

-
-
-

Example:

+

Available events

+
+

The numbers in parenthesis is the event type (keep in mind that you need to +strip the highest bit first).

+
+
+
+
workspace (0)
+
+

Sent when the user switches to a different workspace, when a new +workspace is initialized or when a workspace is removed (because the +last client vanished).

+
+
output (1)
+
+

Sent when RandR issues a change notification (of either screens, +outputs, CRTCs or output properties).

+
+
mode (2)
+
+

Sent whenever i3 changes its binding mode.

+
+
window (3)
+
+

Sent when a client’s window is successfully reparented (that is when i3 +has finished fitting it into a container), when a window received input +focus or when certain properties of the window have changed.

+
+
barconfig_update (4)
+
+

Sent when the hidden_state or mode field in the barconfig of any bar +instance was updated and when the config is reloaded.

+
+
binding (5)
+
+

Sent when a configured command binding is triggered with the keyboard or +mouse

+
+
shutdown (6)
+
+

Sent when the ipc shuts down because of a restart or exit by user command

+
+
tick (7)
+
+

Sent when the ipc client subscribes to the tick event (with "first": +true) or when any ipc client sends a SEND_TICK message (with "first": +false).

+
+
+
+
+

Example:

+
-
# the appropriate 4 bytes read from the socket are stored in $input
+
# the appropriate 4 bytes read from the socket are stored in $input
 
 # unpack a 32-bit unsigned integer
 my $message_type = unpack("L", $input);
@@ -1484,26 +1325,33 @@ 

4.2. Available events

if ($is_event) { say "Received event of type $event_type"; -}
-
+} +
+
-

4.3. workspace event

-

This event consists of a single serialized map containing a property -change (string) which indicates the type of the change ("focus", "init", +

workspace event

+
+

This event consists of a single serialized map containing a property +change (string) which indicates the type of the change ("focus", "init", "empty", "urgent", "reload", "rename", "restored", "move"). A -current (object) property will be present with the affected workspace -whenever the type of event affects a workspace (otherwise, it will be null).

-

When the change is "focus", an old (object) property will be present with the +current (object) property will be present with the affected workspace +whenever the type of event affects a workspace (otherwise, it will be null).

+
+
+

When the change is "focus", an old (object) property will be present with the previous workspace. When the first switch occurs (when i3 focuses the workspace visible at the beginning) there is no previous workspace, and the -old property will be set to null. Also note that if the previous is empty +old property will be set to null. Also note that if the previous is empty it will get destroyed when switching, but will still be present in the "old" -property.

-

Example:

+property.

+
+
+

Example:

+
-
{
+
{
  "change": "focus",
  "current": {
   "id": 28489712,
@@ -1515,168 +1363,160 @@ 

4.3. workspace event

"type": "workspace", ... } -}
-
+} +
+
-

4.4. output event

-

This event consists of a single serialized map containing a property -change (string) which indicates the type of the change (currently only -"unspecified").

-

Example:

+

output event

+
+

This event consists of a single serialized map containing a property +change (string) which indicates the type of the change (currently only +"unspecified").

+
+
+

Example:

+
-
{ "change": "unspecified" }
-
+
{ "change": "unspecified" }
+
+
-

4.5. mode event

-

This event consists of a single serialized map containing a property -change (string) which holds the name of current mode in use. The name +

mode event

+
+

This event consists of a single serialized map containing a property +change (string) which holds the name of current mode in use. The name is the same as specified in config when creating a mode. The default -mode is simply named default. It contains a second property, pango_markup, which -defines whether pango markup shall be used for displaying this mode.

-

Example:

+mode is simply named default. It contains a second property, pango_markup, which +defines whether pango markup shall be used for displaying this mode.

+
+
+

Example:

+
-
{
+
{
   "change": "default",
   "pango_markup": true
-}
-
+} +
+
-

4.6. window event

-

This event consists of a single serialized map containing a property -change (string) which indicates the type of the change

-
    +

    window event

    +
    +

    This event consists of a single serialized map containing a property +change (string) which indicates the type of the change

    +
    +
    +
    • -

      -new – the window has become managed by i3 -

      +

      new – the window has become managed by i3

    • -

      -close – the window has closed -

      +

      close – the window has closed

    • -

      -focus – the window has received input focus -

      +

      focus – the window has received input focus

    • -

      -title – the window’s title has changed -

      +

      title – the window’s title has changed

    • -

      -fullscreen_mode – the window has entered or exited fullscreen mode -

      +

      fullscreen_mode – the window has entered or exited fullscreen mode

    • -

      -move – the window has changed its position in the tree -

      +

      move – the window has changed its position in the tree

    • -

      -floating – the window has transitioned to or from floating -

      +

      floating – the window has transitioned to or from floating

    • -

      -urgent – the window has become urgent or lost its urgent status -

      +

      urgent – the window has become urgent or lost its urgent status

    • -

      -mark – a mark has been added to or removed from the window -

      +

      mark – a mark has been added to or removed from the window

    • -
    -

    Additionally a container (object) field will be present, which consists +

+
+
+

Additionally a container (object) field will be present, which consists of the window’s parent container. Be aware that for the "new" event, the container will hold the initial name of the newly reparented window (e.g. if you run urxvt with a shell that changes the title, you will still at -this point get the window title as "urxvt").

-

Example:

+this point get the window title as "urxvt").

+
+
+

Example:

+
-
{
+
{
  "change": "new",
  "container": {
   "id": 35569536,
   "type": "con",
   ...
  }
-}
-
+} + +
-

4.7. barconfig_update event

-

This event consists of a single serialized map reporting on options from the +

barconfig_update event

+
+

This event consists of a single serialized map reporting on options from the barconfig of the specified bar_id that were updated in i3. This event is the -same as a GET_BAR_CONFIG reply for the bar with the given id.

+same as a GET_BAR_CONFIG reply for the bar with the given id.

+
-

4.8. binding event

-

This event consists of a single serialized map reporting on the details of a -binding that ran a command because of user input. The change (string) field +

binding event

+
+

This event consists of a single serialized map reporting on the details of a +binding that ran a command because of user input. The change (string) field indicates what sort of binding event was triggered (right now it will always be -"run" but may be expanded in the future).

-

The binding (object) field contains details about the binding that was run:

-
-
-command (string) -
-
-

- The i3 command that is configured to run for this binding. -

-
-
-event_state_mask (array of strings) -
-
-

- The group and modifier keys that were configured with this binding. -

-
-
-input_code (integer) -
-
-

- If the binding was configured with bindcode, this will be the key code - that was given for the binding. If the binding is a mouse binding, it will be - the number of the mouse button that was pressed. Otherwise it will be 0. -

-
-
-symbol (string or null) -
-
-

- If this is a keyboard binding that was configured with bindsym, this - field will contain the given symbol. Otherwise it will be null. -

-
-
-input_type (string) -
-
-

- This will be "keyboard" or "mouse" depending on whether or not this was - a keyboard or a mouse binding. -

-
-
-

Example:

+"run" but may be expanded in the future).

+
+
+

The binding (object) field contains details about the binding that was run:

+
+
+
+
command (string)
+
+

The i3 command that is configured to run for this binding.

+
+
event_state_mask (array of strings)
+
+

The group and modifier keys that were configured with this binding.

+
+
input_code (integer)
+
+

If the binding was configured with bindcode, this will be the key code +that was given for the binding. If the binding is a mouse binding, it will be +the number of the mouse button that was pressed. Otherwise it will be 0.

+
+
symbol (string or null)
+
+

If this is a keyboard binding that was configured with bindsym, this +field will contain the given symbol. Otherwise it will be null.

+
+
input_type (string)
+
+

This will be "keyboard" or "mouse" depending on whether or not this was +a keyboard or a mouse binding.

+
+
+
+
+

Example:

+
-
{
+
{
  "change": "run",
  "binding": {
   "command": "nop",
@@ -1688,324 +1528,301 @@ 

4.8. binding event

"symbol": "t", "input_type": "keyboard" } -}
-
+} +
+
-

4.9. shutdown event

-

This event is triggered when the connection to the ipc is about to shutdown -because of a user action such as a restart or exit command. The change -(string) field indicates why the ipc is shutting down. It can be either -"restart" or "exit".

-

Example:

+

shutdown event

+
+

This event is triggered when the connection to the ipc is about to shutdown +because of a user action such as a restart or exit command. The change +(string) field indicates why the ipc is shutting down. It can be either +"restart" or "exit".

+
+
+

Example:

+
-
{
+
{
  "change": "restart"
-}
-
+} +
+
-

4.10. tick event

-

This event is triggered by a subscription to tick events or by a SEND_TICK -message.

-

Example (upon subscription):

+

tick event

+
+

This event is triggered by a subscription to tick events or by a SEND_TICK +message.

+
+
+

Example (upon subscription):

+
-
{
+
{
  "first": true,
  "payload": ""
-}
-
-

Example (upon SEND_TICK with a payload of arbitrary string):

+} +
+ +
+

Example (upon SEND_TICK with a payload of arbitrary string):

+
-
{
+
{
  "first": false,
  "payload": "arbitrary string"
-}
-
+} + +
-

5. See also (existing libraries)

+

See also (existing libraries)

-

For some languages, libraries are available (so you don’t have to implement +

+

For some languages, libraries are available (so you don’t have to implement all this on your own). This list names some (if you wrote one, please let me -know):

-
-
-C -
+know):

+
+
+
+
C
-
+
-
-C++ -
+
C++
-
-
-Go -
+
Go
-
-
-JavaScript -
+
JavaScript
-
-
-Lua -
+
Lua
-
-
-Perl -
+
Perl
-
-
-Python -
+
Python
-
-
-Ruby -
+
Ruby
-
-
-Rust -
+
Rust
-
-
-OCaml -
+
OCaml
-
-
+ +
-

6. Appendix A: Detecting byte order in memory-safe languages

+

Appendix A: Detecting byte order in memory-safe languages

-

Some programming languages such as Go don’t offer a way to serialize data in the +

+

Some programming languages such as Go don’t offer a way to serialize data in the native byte order of the machine they’re running on without resorting to tricks -involving the unsafe package.

-

The following technique can be used (and will not be broken by changes to i3) to -detect the byte order i3 is using:

-
    +involving the unsafe package.

    +
+
+

The following technique can be used (and will not be broken by changes to i3) to +detect the byte order i3 is using:

+
+
+
  1. -

    -The byte order dependent fields of an IPC message are message type and - payload length. -

    -
      +

      The byte order dependent fields of an IPC message are message type and +payload length.

      +
      +
      • -

        -The message type RUN_COMMAND (0) is the same in big and little endian, so - we can use it in either byte order to elicit a reply from i3. -

        +

        The message type RUN_COMMAND (0) is the same in big and little endian, so +we can use it in either byte order to elicit a reply from i3.

      • -

        -The payload length 65536 + 256 (0x00 01 01 00) is the same in big and - little endian, and also small enough to not worry about memory allocations - of that size. We must use payloads of length 65536 + 256 in every message - we send, so that i3 will be able to read the entire message regardless of - the byte order it uses. -

        +

        The payload length 65536 + 256 (0x00 01 01 00) is the same in big and +little endian, and also small enough to not worry about memory allocations +of that size. We must use payloads of length 65536 + 256 in every message +we send, so that i3 will be able to read the entire message regardless of +the byte order it uses.

      • -
      +
    +
  2. -

    -Send a big endian encoded message of type SUBSCRIBE (2) with payload [] - followed by 65536 + 256 - 2 SPACE (ASCII 0x20) bytes. -

    -
      +

      Send a big endian encoded message of type SUBSCRIBE (2) with payload [] +followed by 65536 + 256 - 2 SPACE (ASCII 0x20) bytes.

      +
      +
      • -

        -If i3 is running in big endian, this message is treated as a noop, - resulting in a SUBSCRIBE reply with payload {"success":true} -
        [A small payload is important: that way, we circumvent dealing - with UNIX domain socket buffer sizes, whose size depends on the - implementation/operating system. Exhausting such a buffer results in an i3 - deadlock unless you concurrently read and write, which — depending on the - programming language — makes the technique much more complicated.]
        . -

        +

        If i3 is running in big endian, this message is treated as a noop, +resulting in a SUBSCRIBE reply with payload {"success":true} +[1].

      • -

        -If i3 is running in little endian, this message is read in its entirety due - to the byte order independent payload length, then - silently - discarded due to the unknown message type. -

        +

        If i3 is running in little endian, this message is read in its entirety due +to the byte order independent payload length, then +silently +discarded due to the unknown message type.

      • -
      +
    +
  3. -

    -Send a byte order independent message, i.e. type RUN_COMMAND (0) with - payload nop byte order detection. padding:, padded to 65536 + 256 bytes - with a (ASCII 0x61) bytes. i3 will reply to this message with a reply of - type COMMAND (0). -

    -
      +

      Send a byte order independent message, i.e. type RUN_COMMAND (0) with +payload nop byte order detection. padding:, padded to 65536 + 256 bytes +with a (ASCII 0x61) bytes. i3 will reply to this message with a reply of +type COMMAND (0).

      +
      +
      • -

        -The human-readable prefix is in there to not confuse readers of the i3 log. -

        +

        The human-readable prefix is in there to not confuse readers of the i3 log.

      • -

        -This messages serves as a synchronization primitive so that we know whether - i3 discarded the SUBSCRIBE message or didn’t answer it yet. -

        +

        This messages serves as a synchronization primitive so that we know whether +i3 discarded the SUBSCRIBE message or didn’t answer it yet.

      • -
      +
    +
  4. -

    -Receive a message header from i3, decoding the message type as big endian. -

    -
      +

      Receive a message header from i3, decoding the message type as big endian.

      +
      +
      • -

        -If the message’s reply type is COMMAND (0), i3 is running in little - endian (because the SUBSCRIBE message was discarded). Decode the message - payload length as little endian, receive the message payload. -

        +

        If the message’s reply type is COMMAND (0), i3 is running in little +endian (because the SUBSCRIBE message was discarded). Decode the message +payload length as little endian, receive the message payload.

      • -

        -If the message’s reply type is anything else, i3 is running in big endian - (because our big endian encoded SUBSCRIBE message was answered). Decode - the message payload length in big endian, receive the message - payload. Then, receive the pending COMMAND message reply in big endian. -

        +

        If the message’s reply type is anything else, i3 is running in big endian +(because our big endian encoded SUBSCRIBE message was answered). Decode +the message payload length in big endian, receive the message +payload. Then, receive the pending COMMAND message reply in big endian.

      • -
      +
    +
  5. -

    -From here on out, send/receive all messages using the detected byte order. -

    +

    From here on out, send/receive all messages using the detected byte order.

  6. -
-

Find an example implementation of this technique in -https://github.com/i3/go-i3/blob/master/byteorder.go

-
-
-
-

- + + +
+

Find an example implementation of this technique in +https://github.com/i3/go-i3/blob/master/byteorder.go

+
+ + + +
+
+
+1. A small payload is important: that way, we circumvent dealing with UNIX domain socket buffer sizes, whose size depends on the implementation/operating system. Exhausting such a buffer results in an i3 deadlock unless you concurrently read and write, which — depending on the programming language — makes the technique much more complicated. +
+
+ - + \ No newline at end of file diff --git a/docs/layout-saving.html b/docs/layout-saving.html index 411a175..049119c 100644 --- a/docs/layout-saving.html +++ b/docs/layout-saving.html @@ -1,137 +1,165 @@ - - - -i3: Layout saving in i3 - - - - + + + + + +Layout saving in i3 + - -
- - -
-
- - + +
-

2. Restoring the layout

+

Restoring the layout

-

After restoring the example layout from [EditingLayoutFiles], i3 will open +

+

After restoring the example layout from Anatomy of a layout file, i3 will open placeholder windows for all the windows that were specified in the layout file. You can recognize the placeholder windows by the watch symbol -
[Depending on the font you are using, a placeholder symbol may show up -instead of the watch symbol.]
in the center of the window, and by the swallow -criteria specification at the top of the window:

-

- -Restored layout - -

-

When an application opens a window that matches the specified swallow criteria, +[1] in the center of the window, and by the swallow +criteria specification at the top of the window:

+
+
+

Restored layout

+
+
+

When an application opens a window that matches the specified swallow criteria, it will be placed in the corresponding placeholder window. We say it gets -swallowed by the placeholder container, hence the term.

-

Note: Swallowing windows into unsatisfied placeholder windows takes precedence +swallowed by the placeholder container, hence the term.

+
+
+

Note: Swallowing windows into unsatisfied placeholder windows takes precedence over assignment rules. For example, if you assign all Emacs windows to workspace 1 in your i3 configuration file, but there is a placeholder window on workspace 2 which matches Emacs as well, your newly started Emacs window will end up in the -placeholder window on workspace 2.

-

The placeholder windows are just regular windows, so feel free to move them -around or close them, for example.

+placeholder window on workspace 2.

+
+
+

The placeholder windows are just regular windows, so feel free to move them +around or close them, for example.

+
-

2.1. append_layout command

-

The append_layout command is used to load a layout file into i3. It accepts a -path (relative to i3’s current working directory or absolute) to a JSON file.

-

Syntax:

+

append_layout command

+
+

The append_layout command is used to load a layout file into i3. It accepts a +path (relative to i3’s current working directory or absolute) to a JSON file.

+
+
+

Syntax:

+
-
append_layout <path>
-
-

Examples:

+
append_layout <path>
+
+
+
+

Examples:

+
-
# From a terminal or script:
+
# From a terminal or script:
 i3-msg "workspace 1; append_layout /home/michael/.i3/workspace-1.json"
 
 # In your i3 configuration file, you can autostart i3-msg like this:
 # (Note that those lines will quickly become long, so typically you would store
 #  them in a script with proper indentation.)
-exec --no-startup-id "i3-msg 'workspace 1; append_layout /home/michael/.i3/workspace-1.json'"
-
+exec --no-startup-id "i3-msg 'workspace 1; append_layout /home/michael/.i3/workspace-1.json'" +
+
-

3. Editing layout files

+

Editing layout files

-

3.1. Anatomy of a layout file

-

Here is an example layout file that we’ll discuss:

+

Anatomy of a layout file

+
+

Here is an example layout file that we’ll discuss:

+
-
{
+
{
     // splitv split container with 2 children
     "layout": "splitv",
     "percent": 0.4,
@@ -192,107 +220,131 @@ 

3.1. Anatomy of a layout file

] } ] -}
-
-

In this layout, the screen is divided into two columns. In the left column, +} +

+
+
+

In this layout, the screen is divided into two columns. In the left column, which covers 40% of the screen, there is a terminal emulator running irssi on the top, and a stacked split container with an Emacs window and a terminal emulator on the bottom. In the right column, there is a stacked container with -a Chrome window:

-

- -Restored layout - -

-

The structure of this JSON file looks a lot like the TREE reply, see -https://build.i3wm.org/docs/ipc.html#_tree_reply for documentation on that. Some -properties are excluded because they are not relevant when restoring a layout.

-

Most importantly, look at the "swallows" section of each window. This is where +a Chrome window:

+
+
+

Restored layout

+
+
+

The structure of this JSON file looks a lot like the TREE reply, see +https://build.i3wm.org/docs/ipc.html#_tree_reply for documentation on that. Some +properties are excluded because they are not relevant when restoring a layout.

+
+
+

Most importantly, look at the "swallows" section of each window. This is where you need to be more or less specific. As an example, remember the section about -the Emacs window:

+the Emacs window:

+
-
"swallows": [
+
"swallows": [
     {
         "class": "^Emacs$",
         "instance": "^notmuch$"
     }
-]
-
-

Here you can see that i3 will require both the class and the instance to match. +] +

+
+
+

Here you can see that i3 will require both the class and the instance to match. Therefore, if you just start Emacs via dmenu, it will not get swallowed by that -container. Only if you start Emacs with the proper instance name (emacs24 ---name notmuch), it will get swallowed.

-

You can match on "class", "instance", "window_role" and "title". All values are -case-sensitive regular expressions (PCRE). Use xprop(1) and click into a -window to see its properties:

+container. Only if you start Emacs with the proper instance name (emacs24 +--name notmuch), it will get swallowed.

+ +
+

You can match on "class", "instance", "window_role" and "title". All values are +case-sensitive regular expressions (PCRE). Use xprop(1) and click into a +window to see its properties:

+
-
$ xprop
+
$ xprop
 WM_WINDOW_ROLE(STRING) = "gimp-toolbox-color-dialog"
 WM_CLASS(STRING) = "gimp-2.8", "Gimp-2.8"
-_NET_WM_NAME(UTF8_STRING) = "Change Foreground Color"
-
-

The first part of WM_CLASS is the "instance" (gimp-2.8 in this case), the +_NET_WM_NAME(UTF8_STRING) = "Change Foreground Color" +

+ +
+

The first part of WM_CLASS is the "instance" (gimp-2.8 in this case), the second part is the "class" (Gimp-2.8 in this case). "title" matches against -_NET_WM_NAME and "window_role" matches against WM_WINDOW_ROLE.

-

In general, you should try to be as specific as possible in your swallow +_NET_WM_NAME and "window_role" matches against WM_WINDOW_ROLE.

+
+
+

In general, you should try to be as specific as possible in your swallow criteria. Try to use criteria that match one window and only one window, to -have a reliable startup procedure.

-

If you specify multiple swallow criteria, the placeholder will be replaced by -the window which matches any of the criteria. As an example:

+have a reliable startup procedure.

+ +
+

If you specify multiple swallow criteria, the placeholder will be replaced by +the window which matches any of the criteria. As an example:

+
-
// Matches either Emacs or Gvim, whichever one is started first.
+
// Matches either Emacs or Gvim, whichever one is started first.
 "swallows": [
     {"class": "^Emacs$"},
     {"class": "^Gvim$"}
-]
-
+] + +
-

3.2. JSON standard non-compliance

-

A layout file as generated by i3-save-tree(1) is not strictly valid JSON:

-
    +

    JSON standard non-compliance

    +
    +

    A layout file as generated by i3-save-tree(1) is not strictly valid JSON:

    +
    +
    +
    1. -

      -Layout files contain multiple “JSON texts” at the top level. The JSON - standard doesn’t prohibit this, but in practice most JSON parsers only - allow precisely one “text” per document/file, and will mark multiple texts - as invalid JSON. -

      +

      Layout files contain multiple “JSON texts” at the top level. The JSON +standard doesn’t prohibit this, but in practice most JSON parsers only +allow precisely one “text” per document/file, and will mark multiple texts +as invalid JSON.

    2. -

      -Layout files contain comments which are not allowed by the JSON standard, - but are understood by many parsers. -

      +

      Layout files contain comments which are not allowed by the JSON standard, +but are understood by many parsers.

    3. -
    -

    Both of these deviations from the norm are to make manual editing by humans +

+
+
+

Both of these deviations from the norm are to make manual editing by humans easier. In case you are writing a more elaborate tool for manipulating these layouts, you can either use a JSON parser that supports these deviations (for example libyajl), transform the layout file to a JSON-conforming file, or submit a patch -to make i3-save-tree(1) optionally output standard-conforming JSON.

+to make i3-save-tree(1) optionally output standard-conforming JSON.

+
-

4. Troubleshooting

+

Troubleshooting

-

4.1. Restoring a vertically split workspace

-

When using i3-save-tree with the --workspace switch, only the contents of +

Restoring a vertically split workspace

+
+

When using i3-save-tree with the --workspace switch, only the contents of the workspace will be dumped. This means that properties of the workspace -itself will be lost.

-

This is relevant for, e.g., a vertically split container as the base container of +itself will be lost.

+
+
+

This is relevant for, e.g., a vertically split container as the base container of a workspace. Since the split mode is a property of the workspace, it will not be stored. In this case, you will have to manually wrap your layout in such a -container:

+container:

+
-
// vim:ts=4:sw=4:et
+
// vim:ts=4:sw=4:et
 {
     // this is a manually added container to restore the vertical split
     "layout": "splitv",
@@ -303,17 +355,23 @@ 

4.1. Restoring a vertically spl // the dumped workspace layout goes here ] -}

-
+} +
+
+
+ + + +
+
+
+1. Depending on the font you are using, a placeholder symbol may show up instead of the watch symbol. +
+ -
-

- - + \ No newline at end of file diff --git a/docs/manpage.html b/docs/manpage.html deleted file mode 100644 index 3b7596b..0000000 --- a/docs/manpage.html +++ /dev/null @@ -1,530 +0,0 @@ - - - - - -i3: i3(1) - - - - - - - -
-

i3 - improved tiling WM

- -
-
- -
-

1. NAME

-
-

i3 - an improved dynamic, tiling window manager

-
-
-
-

2. SYNOPSIS

-
-

i3 [-a] [-c configfile] [-C] [-d <loglevel>] [-v] [-V]

-
-
-
-

3. OPTIONS

-
-
-
--a -
-
-

-Disables autostart. -

-
-
--c -
-
-

-Specifies an alternate configuration file path. -

-
-
--C -
-
-

-Check the configuration file for validity and exit. -

-
-
--d -
-
-

-Specifies the debug loglevel. To see the most output, use -d all. -

-
-
--v -
-
-

-Display version number (and date of the last commit). -

-
-
--V -
-
-

-Be verbose. -

-
-
-
-
-
-

4. DESCRIPTION

-
-
-

4.1. INTRODUCTION

-

i3 was created because wmii, our favorite window manager at the time, didn’t -provide some features we wanted (multi-monitor done right, for example), had -some bugs, didn’t progress since quite some time and wasn’t 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.

-

Please be aware that i3 is primarily targeted at advanced users and developers.

-
-
-

4.2. IMPORTANT NOTE TO nVidia BINARY DRIVER USERS

-

If you are using the nVidia binary graphics driver (also known as blob) -you need to use the --force-xinerama flag (in your .xsession) when starting -i3, like so:

-
-
-
exec i3 --force-xinerama -V >>~/.i3/i3log 2>&1
-
-

See also docs/multi-monitor for the full explanation.

-
-
-

4.3. TERMINOLOGY

-
-
-Client -
-
-

-A client is X11-speak for a window. -

-
-
-Table -
-
-

-Your workspace is managed using a table. You can move windows around and create -new columns (move a client to the right) or rows (move it to the bottom) -implicitly. -

-

By "snapping" a client in a specific direction, you increase its colspan/rowspan.

-
-
-Container -
-
-

-A container contains a variable number of clients. Each cell of the table is a -container. -

-

Containers can be used in various modes. The default mode is called "default" -and just resizes each client equally so that it fits.

-
-
-Workspace -
-
-

-A workspace is a set of clients (technically speaking, it’s just a table). -Other window managers call this "Virtual Desktops". -

-

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’ll be assigned the -screen you are currently on.

-
-
-Output -
-
-

-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). -

-

i3 uses the RandR API to query which outputs are available and which screens -are connected to these outputs.

-
-
-
-
-
-
-

5. KEYBINDINGS

-
-

Here is a short overview of the default keybindings:

-
-
-j/k/l/; -
-
-

-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. -

-
-
-Mod1+<direction> -
-
-

-Focus window in <direction>. -

-
-
-Mod3+<direction> -
-
-

-Focus container in <direction>. -

-
-
-Mod1+Shift+<direction> -
-
-

-Move window to <direction>. -

-
-
-Mod3+Shift+<direction> -
-
-

-Move container to <direction>. -

-
-
-Mod1+Control+<direction> -
-
-

-Snap container to <direction>. -

-
-
-Mod1+<number> -
-
-

-Switch to workspace <number>. -

-
-
-Mod1+Shift+<number> -
-
-

-Move window to workspace <number>. -

-
-
-Mod1+f -
-
-

-Toggle fullscreen mode. -

-
-
-Mod1+h -
-
-

-Enable stacking layout for the current container. -

-
-
-Mod1+e -
-
-

-Enable default layout for the current container. -

-
-
-Mod1+Shift+Space -
-
-

-Toggle tiling/floating for the current window. -

-
-
-Mod1+t -
-
-

-Select the first tiling window if the current window is floating and vice-versa. -

-
-
-Mod1+Shift+q -
-
-

-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. -

-
-
-Mod1+Shift+r -
-
-

-Restarts i3 in place (without losing any windows, but at this time, the layout -and placement of windows is not retained). -

-
-
-Mod1+Shift+e -
-
-

-Exits i3. -

-
-
-
-
-
-

6. FILES

-
-
-

6.1. ~/.i3/config (or ~/.config/i3/config)

-

When starting, i3 looks for configuration files in the following order:

-
    -
  1. -

    -~/.config/i3/config (or $XDG_CONFIG_HOME/i3/config if set) -

    -
  2. -
  3. -

    -/etc/xdg/i3/config (or $XDG_CONFIG_DIRS/i3/config if set) -

    -
  4. -
  5. -

    -~/.i3/config -

    -
  6. -
  7. -

    -/etc/i3/config -

    -
  8. -
-

You can specify a custom path using the -c option.

-
-
Sample configuration
-
-
font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
-
-# Start terminal (Mod1+Enter)
-bind Mod1+36 exec /usr/bin/urxvt
-
-# Start dmenu (Mod1+v)
-bind Mod1+55 exec /usr/bin/dmenu_run
-
-# Kill current client (Mod1+Shift+q)
-bind Mod1+Shift+24 kill
-
-# Beamer on/off
-bind Mod1+73 exec /home/michael/toggle_beamer.sh
-
-# Screen locking
-bind Mod1+68 exec /usr/bin/i3lock
-
-# Restart i3 inplace (Mod1+Shift+r)
-bind Mod1+Shift+27 restart
-
-# Exit i3 (Mod1+Shift+e)
-bind Mod1+Shift+26 exit
-
-# Brightness
-bind Mod1+97 exec sudo sh -c "echo up > /proc/acpi/ibm/brightness"
-bind Mod1+103 exec sudo sh -c "echo down > /proc/acpi/ibm/brightness"
-
-# Fullscreen (Mod1+f)
-bind Mod1+41 f
-
-# Stacking (Mod1+h)
-bind Mod1+43 s
-
-# Default (Mod1+e)
-bind Mod1+26 d
-
-# Toggle tiling/floating of the current window (Mod1+Shift+Space)
-bind Mod1+Shift+65 t
-
-# Go into the tiling layer / floating layer, depending on whether
-# the current window is tiling / floating (Mod1+t)
-bind Mod1+28 focus ft
-
-# Focus (Mod1+j/k/l/;)
-bind Mod1+44 h
-bind Mod1+45 j
-bind Mod1+46 k
-bind Mod1+47 l
-
-# Focus Container (Mod3+j/k/l/;)
-bind Mod3+44 wch
-bind Mod3+45 wcj
-bind Mod3+46 wck
-bind Mod3+47 wcl
-
-# Snap (Mod1+Control+j/k/l/;)
-bind Mod1+Control+44 sh
-bind Mod1+Control+45 sj
-bind Mod1+Control+46 sk
-bind Mod1+Control+47 sl
-
-# Move (Mod1+Shift+j/k/l/;)
-bind Mod1+Shift+44 mh
-bind Mod1+Shift+45 mj
-bind Mod1+Shift+46 mk
-bind Mod1+Shift+47 ml
-
-# Move Container (Mod3+Shift+j/k/l/;)
-bind Mod3+Shift+44 wcmh
-bind Mod3+Shift+45 wcmj
-bind Mod3+Shift+46 wcmk
-bind Mod3+Shift+47 wcml
-
-# Workspaces
-bind Mod1+10 1
-bind Mod1+11 2
-...
-
-# Move to Workspace
-bind Mod1+Shift+10 1
-bind Mod1+Shift+11 2
-...
-
-
-
-

6.2. ~/.xsession

-

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.

-
-
Sample xsession
-
-
# Disable DPMS turning off the screen
-xset dpms force on
-xset s off
-
-# Disable bell
-xset -b
-
-# Enable zapping (C-A-<Bksp> kills X)
-setxkbmap -option terminate:ctrl_alt_bksp
-
-# Enforce correct locales from the beginning
-unset LC_COLLATE
-export LC_CTYPE=de_DE.UTF-8
-export LC_TIME=de_DE.UTF-8
-export LC_NUMERIC=de_DE.UTF-8
-export LC_MONETARY=de_DE.UTF-8
-export LC_MESSAGES=C
-export LC_PAPER=de_DE.UTF-8
-export LC_NAME=de_DE.UTF-8
-export LC_ADDRESS=de_DE.UTF-8
-export LC_TELEPHONE=de_DE.UTF-8
-export LC_MEASUREMENT=de_DE.UTF-8
-export LC_IDENTIFICATION=de_DE.UTF-8
-
-# Use XToolkit in java applications
-export AWT_TOOLKIT=XToolkit
-
-# Set background color
-xsetroot -solid "#333333"
-
-# Enable core dumps in case something goes wrong
-ulimit -c unlimited
-
-# Start i3 and log to ~/.i3/logfile
-echo "Starting at $(date)" >> ~/.i3/logfile
-exec /usr/bin/i3 -V -d all >> ~/.i3/logfile
-
-
-
-
-
-

7. TODO

-
-

There is still lot of work to do. Please check our bugtracker for up-to-date -information about tasks which are still not finished.

-
-
-
-

8. SEE ALSO

-
-

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

-

You can also access these documents online at http://i3.zekjur.net/

-

i3-input(1), i3-msg(1), i3-wsbar(1)

-
-
-
-

9. AUTHOR

-
-

Michael Stapelberg and contributors

-
-
-
-

- - - diff --git a/docs/multi-monitor.html b/docs/multi-monitor.html index 9e2b105..546cd7d 100644 --- a/docs/multi-monitor.html +++ b/docs/multi-monitor.html @@ -1,70 +1,64 @@ - - - -i3: The multi-monitor situation - - - - + + + + + +The multi-monitor situation + - -
- - -
-
- - + +
-

2. The explanation

+

The explanation

-

Starting with version 3.ε, i3 uses the RandR (Rotate and Resize) API instead +

+

Starting with version 3.ε, i3 uses the RandR (Rotate and Resize) API instead of Xinerama. The reason for this, is that RandR provides more information about your outputs and connected screens than Xinerama does. To be specific, the code which handled on-the-fly screen reconfiguration (meaning without @@ -72,48 +66,58 @@

2. The explanation

not work correctly — that is just not possible with the little information Xinerama offers (just a list of screen resolutions, no identifiers for the screens or any additional information). Xinerama simply was not designed -for dynamic configuration.

-

So RandR came along, as a more powerful alternative (RandR 1.2 to be specific). +for dynamic configuration.

+
+
+

So RandR came along, as a more powerful alternative (RandR 1.2 to be specific). It offers all of Xinerama’s possibilities and lots more. Using the RandR API made our code much more robust and clean. Also, you can now reliably assign workspaces to output names instead of some rather unreliable screen identifier -(position inside the list of screens, which could change, and so on…).

-

As RandR has been around for about three years as of this writing, it seemed +(position inside the list of screens, which could change, and so on…).

+
+
+

As RandR has been around for about three years as of this writing, it seemed like a very good idea to us, and it still is a very good one. What we did not expect, however, was the nVidia binary driver. It still does not support RandR (as of March 2010), even though nVidia has announced that it will support RandR eventually. What does this mean for you, if you are stuck with the binary driver for some reason (say the free drivers don’t work with your card)? First -of all, you are stuck with TwinView and cannot use xrandr. While this ruins +of all, you are stuck with TwinView and cannot use xrandr. While this ruins the user experience, the more grave problem is that the nVidia driver not only does not support dynamic configuration using RandR, it also does not expose correct multi-monitor information via the RandR API. So, in some setups, i3 will not find any screens; in others, it will find one large screen which actually contains both of your physical screens (but it will not know that -these are two screens).

-

For this very reason, we decided to implement the following workaround: As +these are two screens).

+
+
+

For this very reason, we decided to implement the following workaround: As long as the nVidia driver does not support RandR, an option called ---force-xinerama is available in i3 (alternatively, you can use the -force_xinerama configuration file directive). This option gets the list of +--force-xinerama is available in i3 (alternatively, you can use the +force_xinerama configuration file directive). This option gets the list of screens once when starting, and never updates it. As the nVidia driver cannot -do dynamic configuration anyways, this is not a big deal.

-

Also note that your output names are not descriptive (like HDMI1) when using -Xinerama, instead they are counted up, starting at 0: xinerama-0, xinerama-1, …

+do dynamic configuration anyways, this is not a big deal.

+
+
+

Also note that your output names are not descriptive (like HDMI1) when using +Xinerama, instead they are counted up, starting at 0: xinerama-0, xinerama-1, …

+
-

3. See also

+

See also

-

For more information on how to use multi-monitor setups, see the i3 User’s -Guide.

+
+

For more information on how to use multi-monitor setups, see the i3 User’s +Guide.

+
+
+
+
+ - -

- - + \ No newline at end of file diff --git a/docs/repositories.html b/docs/repositories.html index d77ddb3..26aca85 100644 --- a/docs/repositories.html +++ b/docs/repositories.html @@ -1,161 +1,170 @@ - - - - - - -i3: Debian and Ubuntu repositories - - - - - - -
- - -
-
- - -

Debian and Ubuntu repositories

-Michael Stapelberg
-<michael@i3wm.org>
-November 2018 - -
-

1. When should you use our repositories?

-
-

In general, you should use the repositories of your distribution. Adding -third-party repositories to your /etc/sources.list has security implications -and makes your apt-get update take longer.

-
-
-If you are using Debian stable -
-
-

- The latest version of i3 will be in Debian testing quite soon. The version - in Debian stable can be old, however (we cannot update it after stable has - been released). The best way is to add Debian testing and tell apt to - prefer Debian stable. You should not use our repository. - Alternatively, you can also use - stable-backports (e.g. wheezy-backports for - Debian wheezy). -

-
-
-If you are using Ubuntu -
-
-

- Only a handful of packages are maintained by Ubuntu developers. The rest is - synchronized periodically from Debian, every 6 months. Therefore, Ubuntu - often includes old versions of i3. You should use our Ubuntu repository. -

-
-
-If you want the latest i3 development version -
-
-

- If you are using Debian (Debian-derived systems might work, too) or Ubuntu - and want the latest development version of i3, you should use our Debian - repository. -

-
-
-
-
-
-

2. Ubuntu repository

-
-
-

2.1. Stable releases

-

This Ubuntu repository is provided by sur5r and contains the latest stable -release of i3. To use it, run the following commands:

-
-
-
$ /usr/lib/apt/apt-helper download-file https://debian.sur5r.net/i3/pool/main/s/sur5r-keyring/sur5r-keyring_2020.02.03_all.deb keyring.deb SHA256:c5dd35231930e3c8d6a9d9539c846023fe1a08e4b073ef0d2833acd815d80d48
-# dpkg -i ./keyring.deb
-# echo "deb http://debian.sur5r.net/i3/ $(grep '^DISTRIB_CODENAME=' /etc/lsb-release | cut -f2 -d=) universe" >> /etc/apt/sources.list.d/sur5r-i3.list
-# apt update
-# apt install i3
-
-

All Ubuntu versions which are currently supported by Ubuntu itself are also supported by -this repository. See Ubuntu releases for details.

-

Packages for unsupported Ubuntu versions might exist but may disappear any time.

-
-
-

2.2. Development releases

-

This Ubuntu repository contains packages which are automatically built a few -minutes after every commit. To use it, run the following commands:

-
-
-
$ /usr/lib/apt/apt-helper download-file http://dl.bintray.com/i3/i3-autobuild-ubuntu/pool/main/i/i3-autobuild-keyring/i3-autobuild-keyring_2016.10.01_all.deb keyring.deb SHA256:460e8c7f67a6ae7c3996cc8a5915548fe2fee9637b1653353ec62b954978d844
-# apt install ./keyring.deb
-# echo 'deb http://dl.bintray.com/i3/i3-autobuild-ubuntu bionic main' > /etc/apt/sources.list.d/i3-autobuild.list
-# apt update
-# apt install i3
-
-

Development versions are only available for the latest version of Ubuntu, which -is bionic at the moment.

-
-
-
-
-

3. Debian repository

-
-

Our Debian repository contains packages which are automatically built a few -minutes after every commit. To use it, run the following commands:

-
-
-
$ /usr/lib/apt/apt-helper download-file http://dl.bintray.com/i3/i3-autobuild/pool/main/i/i3-autobuild-keyring/i3-autobuild-keyring_2016.10.01_all.deb keyring.deb SHA256:460e8c7f67a6ae7c3996cc8a5915548fe2fee9637b1653353ec62b954978d844
-# apt install ./keyring.deb
-# echo 'deb http://dl.bintray.com/i3/i3-autobuild sid main' > /etc/apt/sources.list.d/i3-autobuild.list
-# apt update
-# apt install i3
-
-
-
-
-

4. Preferring the autobuilder version of i3

-
-

On installations where you have multiple sources (stable and testing, or -testing and unstable for example), apt-get install i3 might not get you the -autobuilder version.

-

To ensure that the autobuilt i3 packages will be preferred to the packages of -your distribution, create the file -/etc/apt/preferences.d/00-i3-autobuild.pref with the following contents:

-
-
-
Package: i3*
-Pin: origin "dl.bintray.com"
-Pin-Priority: 1001
-
-

Then, run apt-get update and install i3.

-
-
-
-

- - - + + + + + + + + +Debian and Ubuntu repositories + + + + +
+
+

When should you use our repositories?

+
+
+

In general, you should use the repositories of your distribution. Adding +third-party repositories to your /etc/sources.list has security implications +and makes your apt-get update take longer.

+
+
+
+
If you are using Debian stable
+
+

The latest version of i3 will be in Debian testing quite soon. The version +in Debian stable can be old, however (we cannot update it after stable has +been released). The best way is to add Debian testing and tell apt to +prefer Debian stable. You should not use our repository. +Alternatively, you can also use +stable-backports (e.g. wheezy-backports for +Debian wheezy).

+
+
If you are using Ubuntu
+
+

Only a handful of packages are maintained by Ubuntu developers. The rest is +synchronized periodically from Debian, every 6 months. Therefore, Ubuntu +often includes old versions of i3. You should use our Ubuntu repository.

+
+
If you want the latest i3 development version
+
+

If you are using Debian (Debian-derived systems might work, too) or Ubuntu +and want the latest development version of i3, you should use our Debian +repository.

+
+
+
+
+
+
+

Ubuntu repository

+
+
+

Stable releases

+
+

This Ubuntu repository is provided by sur5r and contains the latest stable +release of i3. To use it, run the following commands:

+
+
+
+
$ /usr/lib/apt/apt-helper download-file https://debian.sur5r.net/i3/pool/main/s/sur5r-keyring/sur5r-keyring_2020.02.03_all.deb keyring.deb SHA256:c5dd35231930e3c8d6a9d9539c846023fe1a08e4b073ef0d2833acd815d80d48
+# dpkg -i ./keyring.deb
+# echo "deb http://debian.sur5r.net/i3/ $(grep '^DISTRIB_CODENAME=' /etc/lsb-release | cut -f2 -d=) universe" >> /etc/apt/sources.list.d/sur5r-i3.list
+# apt update
+# apt install i3
+
+
+
+

All Ubuntu versions which are currently supported by Ubuntu itself are also supported by +this repository. See Ubuntu releases for details.

+
+
+

Packages for unsupported Ubuntu versions might exist but may disappear any time.

+
+
+
+

Development releases

+
+

This Ubuntu repository contains packages which are automatically built a few +minutes after every commit. To use it, run the following commands:

+
+
+
+
$ /usr/lib/apt/apt-helper download-file http://dl.bintray.com/i3/i3-autobuild-ubuntu/pool/main/i/i3-autobuild-keyring/i3-autobuild-keyring_2016.10.01_all.deb keyring.deb SHA256:460e8c7f67a6ae7c3996cc8a5915548fe2fee9637b1653353ec62b954978d844
+# apt install ./keyring.deb
+# echo 'deb http://dl.bintray.com/i3/i3-autobuild-ubuntu bionic main' > /etc/apt/sources.list.d/i3-autobuild.list
+# apt update
+# apt install i3
+
+
+
+

Development versions are only available for the latest version of Ubuntu, which +is bionic at the moment.

+
+
+
+
+
+

Debian repository

+
+
+

Our Debian repository contains packages which are automatically built a few +minutes after every commit. To use it, run the following commands:

+
+
+
+
$ /usr/lib/apt/apt-helper download-file http://dl.bintray.com/i3/i3-autobuild/pool/main/i/i3-autobuild-keyring/i3-autobuild-keyring_2016.10.01_all.deb keyring.deb SHA256:460e8c7f67a6ae7c3996cc8a5915548fe2fee9637b1653353ec62b954978d844
+# apt install ./keyring.deb
+# echo 'deb http://dl.bintray.com/i3/i3-autobuild sid main' > /etc/apt/sources.list.d/i3-autobuild.list
+# apt update
+# apt install i3
+
+
+
+
+
+

Preferring the autobuilder version of i3

+
+
+

On installations where you have multiple sources (stable and testing, or +testing and unstable for example), apt-get install i3 might not get you the +autobuilder version.

+
+
+

To ensure that the autobuilt i3 packages will be preferred to the packages of +your distribution, create the file +/etc/apt/preferences.d/00-i3-autobuild.pref with the following contents:

+
+
+
+
Package: i3*
+Pin: origin "dl.bintray.com"
+Pin-Priority: 1001
+
+
+
+

Then, run apt-get update and install i3.

+
+
+
+
+ + + \ No newline at end of file diff --git a/docs/testsuite.html b/docs/testsuite.html index f349726..b276748 100644 --- a/docs/testsuite.html +++ b/docs/testsuite.html @@ -1,64 +1,74 @@ - - - -i3: i3 testsuite - - - - + + + + + +i3 testsuite + - -
- - -
-
- - + +
-

3.2. Mechanisms

+

Mechanisms

-

3.2.1. Script: complete-run

-

The testcases are run by a script called complete-run.pl. It runs all +

Script: complete-run

+
+

The testcases are run by a script called complete-run.pl. It runs all testcases by default, but you can be more specific and let it only run one or more testcases. Also, it takes care of starting up a separate instance of i3 with an appropriate configuration file and creates a folder for each run containing the appropriate i3 logfile for each testcase. The latest folder can -always be found under the symlink latest/. Unless told differently, it will -run the tests on a separate X server instance (using Xephyr).

-

Xephyr will open a window where you can inspect the running test. By default, -tests are run under Xvfb.

+always be found under the symlink latest/. Unless told differently, it will +run the tests on a separate X server instance (using Xephyr).

+
+
+

Xephyr will open a window where you can inspect the running test. By default, +tests are run under Xvfb.

+
-
Example invocation of complete-run.pl
+
Example invocation of complete-run.pl
-
$ cd ~/i3
+
$ cd ~/i3
 
 $ mkdir -p build && cd build
 
@@ -226,23 +251,31 @@ 

3.2.1. Script: complete-run

Files=1, Tests=14, 0 wallclock secs ( 0.01 usr 0.00 sys + 0.19 cusr 0.03 csys = 0.23 CPU) Result: PASS -$ less latest/i3-log-for-04-floating.t
-
-

If your attempt to run the tests with a bare call to ./complete-run.pl fails, try this:

+$ less latest/i3-log-for-04-floating.t +
+
+
+

If your attempt to run the tests with a bare call to ./complete-run.pl fails, try this:

+
-
$ ./complete-run.pl --parallel=1 --keep-xserver-output
-
-

This will show the output of Xephyr, which is the X server implementation we -use for testing.

+
$ ./complete-run.pl --parallel=1 --keep-xserver-output
+ + +
+

This will show the output of Xephyr, which is the X server implementation we +use for testing.

+
-
make command: make check
-

Make check runs the i3 testsuite. -You can still use ./testcases/complete-run.pl to get the interactive progress output.

+
make command: make check
+
+

Make check runs the i3 testsuite. +You can still use ./testcases/complete-run.pl to get the interactive progress output.

+
-
Example invocation of make check
+
Example invocation of make check
-
$ cd ~/i3
+
$ cd ~/i3
 
 $ mkdir -p build && cd build
 
@@ -266,57 +299,76 @@ 
make command: make check
# ERROR: 0 ============================================================================ -$ less test-suite.log
-
+$ less test-suite.log +
+
-

3.2.2. Coverage testing

-

Coverage testing is possible with lcov, the front-end for GCC’s coverage -testing tool gcov. The testcases can generate a nice html report that tells +

Coverage testing

+
+

Coverage testing is possible with lcov, the front-end for GCC’s coverage +testing tool gcov. The testcases can generate a nice html report that tells you which functions and lines were covered during a run of the tests. You can -use this tool to judge how effective your tests are.

-

To use test coverage tools, first compile with coverage enabled.

+use this tool to judge how effective your tests are.

+
+
+

To use test coverage tools, first compile with coverage enabled.

+
-
COVERAGE=1 make
-
-

Then run the tests with the --coverage-testing flag.

+
COVERAGE=1 make
+
+ +
+

Then run the tests with the --coverage-testing flag.

+
-
./complete-run.pl --coverage-testing
-
-

Then open latest/i3-coverage/index.html in your web browser.

+
./complete-run.pl --coverage-testing
+ + +
+

Then open latest/i3-coverage/index.html in your web browser.

+
-

3.2.3. IPC interface

-

The testsuite makes extensive use of the IPC (Inter-Process Communication) +

IPC interface

+
+

The testsuite makes extensive use of the IPC (Inter-Process Communication) interface which i3 provides. It is used for the startup process of i3, for terminating it cleanly and (most importantly) for modifying and getting the -current state (layout tree).

-

See [https://i3wm.org/docs/ipc.html] for documentation on the IPC interface.

+current state (layout tree).

+
+
+

See [https://i3wm.org/docs/ipc.html] for documentation on the IPC interface.

+
-

3.2.4. X11::XCB

-

In order to open new windows, change attributes, get events, etc., the +

X11::XCB

+
+

In order to open new windows, change attributes, get events, etc., the testsuite uses X11::XCB, a new (and quite specific to i3 at the moment) Perl module which uses the XCB protocol description to generate Perl bindings to X11. They work in a very similar way to libxcb (which i3 uses) and provide -relatively high-level interfaces (objects such as X11::XCB::Window) as well as +relatively high-level interfaces (objects such as X11::XCB::Window) as well as access to the low-level interface, which is very useful when testing a window -manager.

+manager.

+
-

3.3. Filesystem structure

-

In the git root of i3, the testcases live in the folder testcases. This -folder contains the complete-run.pl and a base configuration file which will +

Filesystem structure

+
+

In the git root of i3, the testcases live in the folder testcases. This +folder contains the complete-run.pl and a base configuration file which will be used for the tests. The different testcases (their file extension is .t, not -.pl) themselves can be found in the conventionally named subfolder t:

+.pl) themselves can be found in the conventionally named subfolder t:

+
Filesystem structure
-
├── testcases
+
├── testcases
 │   ├── complete-run.pl
 │   ├── i3-test.config
 │   ├── lib
@@ -330,79 +382,99 @@ 

3.3. Filesystem structure

│   │   ├── ... │   │   ├── omitted for brevity │   │   ├── ... -│   │   └── 74-regress-focus-toggle.t
-
+│   │   └── 74-regress-focus-toggle.t +
+
-

4. Anatomy of a testcase

+

Anatomy of a testcase

-

Learning by example is definitely a good strategy when you are wondering how to -write a testcase. Let’s take t/11-goto.t as an easy example and go through it -step by step:

+
+

Learning by example is definitely a good strategy when you are wondering how to +write a testcase. Let’s take t/11-goto.t as an easy example and go through it +step by step:

+
t/11-goto.t: Boilerplate
-
#!perl
+
#!perl
 # vim:ts=4:sw=4:expandtab
 
 use i3test;
 use File::Temp;
 
-my $x = X11::XCB::Connection->new;
-
-

This is what we call boilerplate. It exists at the top of every test file (to +my $x = X11::XCB::Connection->new; +

+
+
+

This is what we call boilerplate. It exists at the top of every test file (to some extent). The first line is the shebang, which specifies that this file is a Perl script. The second line contains VIM specific settings on how to edit/format this file (use spaces instead of tabs, indent using 4 spaces). -Afterwards, the i3test module is used. This module contains i3 testsuite +Afterwards, the i3test module is used. This module contains i3 testsuite specific functions which you are strongly encouraged to use. They make writing testcases a lot easier and will make it easier for other people to read your -tests.

-

The next line uses the File::Temp module. This is specific to this testcase, +tests.

+
+
+

The next line uses the File::Temp module. This is specific to this testcase, because it needs to generate a temporary name during the test. Many testcases -use only the i3test module.

-

The last line opens a connection to X11. You might or might not need this in +use only the i3test module.

+
+
+

The last line opens a connection to X11. You might or might not need this in your testcase, depending on whether you are going to open windows (etc.) or -only use i3 commands.

+only use i3 commands.

+
t/11-goto.t: Setup
-
my $tmp = fresh_workspace;
+
my $tmp = fresh_workspace;
 
-cmd 'split h';
-
-

The first line calls i3test’s fresh_workspace function which looks for a +cmd 'split h'; +

+ +
+

The first line calls i3test’s fresh_workspace function which looks for a currently unused workspace, switches to it, and returns its name. The variable -$tmp will end up having a value such as "/tmp/87kBVcHbA9". Note that this -is not (necessarily) a valid path, it’s just a random workspace name.

-

So, now that we are on a new workspace, we ensure that the workspace uses -horizontal orientation by issuing the split h command (see the i3 User’s +$tmp will end up having a value such as "/tmp/87kBVcHbA9". Note that this +is not (necessarily) a valid path, it’s just a random workspace name.

+
+
+

So, now that we are on a new workspace, we ensure that the workspace uses +horizontal orientation by issuing the split h command (see the i3 User’s Guide for a list of commands). This is not strictly necessary, but good style. -In general, the cmd function executes the specified i3 command by using the -IPC interface and returns once i3 acknowledged the command.

+In general, the cmd function executes the specified i3 command by using the +IPC interface and returns once i3 acknowledged the command.

+
t/11-goto.t: Setup
-
#####################################################################
+
#####################################################################
 # Create two windows and make sure focus switching works
 #####################################################################
 
 my $top = open_window($x);
 my $mid = open_window($x);
-my $bottom = open_window($x);
-
-

In every major section of a testcase, you should put a comment like the one -above. This makes it immediately clear how the file is structured.

-

The open_window function opens a standard window, which will then be put into +my $bottom = open_window($x); +

+ +
+

In every major section of a testcase, you should put a comment like the one +above. This makes it immediately clear how the file is structured.

+
+
+

The open_window function opens a standard window, which will then be put into tiling mode by i3. If you want a floating window, use the -open_floating_window function. These functions accept the same parameters as -X11::XCB::Window→new, see the i3test documentation at TODO.

+open_floating_window function. These functions accept the same parameters as +X11::XCB::Window→new, see the i3test documentation at TODO.

+
t/11-goto.t: Helper function
-
#
+
#
 # Returns the input focus after sending the given command to i3 via IPC
 # and syncing with i3
 #
@@ -412,93 +484,116 @@ 

4. Anatomy of a testcase

cmd $msg; sync_with_i3 $x; return $x->input_focus; -}
-
-

This section defines a helper function which will be used over and over in this +} +

+ +
+

This section defines a helper function which will be used over and over in this testcase. If you have code which gets executed more than once or twice (depending on the length of your test, use your best judgement), please put it -in a function. Tests should be short, concise and clear.

-

The focus_after function executes a command and returns the X11 focus after -the command was executed. The sync_with_i3 command makes sure that i3 could -push its state to X11. See [i3_sync] to learn how this works exactly.

+in a function. Tests should be short, concise and clear.

+ +
+

The focus_after function executes a command and returns the X11 focus after +the command was executed. The sync_with_i3 command makes sure that i3 could +push its state to X11. See Appendix A: The i3 sync protocol to learn how this works exactly.

+
t/11-goto.t: Test assumptions
-
$focus = $x->input_focus;
+
$focus = $x->input_focus;
 is($focus, $bottom->id, "Latest window focused");
 
 $focus = focus_after('focus left');
-is($focus, $mid->id, "Middle window focused");
-
-

Now, we run the first two real tests. They use Test::More's is function, +is($focus, $mid->id, "Middle window focused"); +

+ +
+

Now, we run the first two real tests. They use Test::More's is function, which compares two values and prints the differences if they are not the same. After the arguments, we supply a short comment to indicate what we are testing here. This makes it vastly more easy for the developer to spot which testcase -is the problem in case one fails.

-

The first test checks that the most recently opened window is focused. -Afterwards, the command focus left is issued and it is verified that the -middle window now has focus.

-

Note that this is not a comprehensive test of the focus command — we would +is the problem in case one fails.

+
+
+

The first test checks that the most recently opened window is focused. +Afterwards, the command focus left is issued and it is verified that the +middle window now has focus.

+
+
+

Note that this is not a comprehensive test of the focus command — we would have to test wrapping, focus when using a more complex layout, focusing the parent/child containers, etc. But that is not the point of this testcase. -Instead, we just want to know if $x→input_focus corresponds with what we are +Instead, we just want to know if $x→input_focus corresponds with what we are expecting. If not, something is completely wrong with the test environment and -this trivial test will fail.

+this trivial test will fail.

+
t/11-goto.t: Test that the feature does not work (yet)
-
#####################################################################
+
#####################################################################
 # Now goto a mark which does not exist
 #####################################################################
 
 my $random_mark = mktemp('mark.XXXXXX');
 
 $focus = focus_after(qq|[con_mark="$random_mark"] focus|);
-is($focus, $mid->id, "focus unchanged");
-
-

Syntax hint: The qq keyword is the interpolating quote operator. It lets you -chose a quote character (in this case the | character, a pipe). This makes -having double quotes in our string easy.

-

In this new major section, a random mark (mark is an identifier for a window, +is($focus, $mid->id, "focus unchanged"); +

+ +
+

Syntax hint: The qq keyword is the interpolating quote operator. It lets you +chose a quote character (in this case the | character, a pipe). This makes +having double quotes in our string easy.

+
+
+

In this new major section, a random mark (mark is an identifier for a window, see "VIM-like marks" in the i3 User’s Guide) will be generated. Afterwards, we test that trying to focus that mark will not do anything. This is important: Do not only test that using a feature has the expected outcome, but also test that using it without properly initializing it does no harm. This command could for -example have changed focus anyways (a bug) or crash i3 (obviously a bug).

+example have changed focus anyways (a bug) or crash i3 (obviously a bug).

+
t/11-goto.t: Test that the feature does work
-
cmd "mark $random_mark";
+
cmd "mark $random_mark";
 
 $focus = focus_after('focus left');
 is($focus, $top->id, "Top window focused");
 
 $focus = focus_after(qq|[con_mark="$random_mark"] focus|);
-is($focus, $mid->id, "goto worked");
-
-

Remember: Focus was on the middle window (we verified that earlier in "Test +is($focus, $mid->id, "goto worked"); +

+ +
+

Remember: Focus was on the middle window (we verified that earlier in "Test assumptions"). We now mark the middle window with our randomly generated mark. Afterwards, we switch focus away from the middle window to be able to tell if focusing it via its mark will work. If the test works, the goto command seems -to be working.

+to be working.

+
t/11-goto.t: Test corner case
-
# check that we can specify multiple criteria
+
check that we can specify multiple criteria
 
 $focus = focus_after('focus left');
 is($focus, $top->id, "Top window focused");
 
 $focus = focus_after(qq|[con_mark="$random_mark" con_mark="$random_mark"] focus|);
-is($focus, $mid->id, "goto worked");
-
-

Now we test the same feature, but specifying the mark twice in the command. +is($focus, $mid->id, "goto worked"); +

+ +
+

Now we test the same feature, but specifying the mark twice in the command. This should have no effect, but let’s be sure: test it and see if things go -wrong.

+wrong.

+
t/11-goto.t: Test second code path
-
#####################################################################
+
#####################################################################
 # Check whether the focus command will switch to a different
 # workspace if necessary
 #####################################################################
@@ -509,104 +604,123 @@ 

4. Anatomy of a testcase

cmd qq|[con_mark="$random_mark"] focus|; -is(focused_ws(), $tmp, 'tmp now focused');
-
-

This part of the test checks that focusing windows by mark works across -workspaces. It uses i3test’s focused_ws function to get the current -workspace.

+is(focused_ws(), $tmp, 'tmp now focused'); + + +
+

This part of the test checks that focusing windows by mark works across +workspaces. It uses i3test’s focused_ws function to get the current +workspace.

+
t/11-goto.t: Test second code path
-
done_testing;
-
-

The end of every testcase has to contain the done_testing line. This tells -complete-run.pl that the test was finished successfully. If it does not +

done_testing;
+
+ +
+

The end of every testcase has to contain the done_testing line. This tells +complete-run.pl that the test was finished successfully. If it does not occur, the test might have crashed during execution — some of the reasons why that could happen are bugs in the used modules, bugs in the testcase itself or an i3 crash resulting in the testcase being unable to communicate with i3 via -IPC anymore.

+IPC anymore.

+
-

5. Appendix A: The i3 sync protocol

+

Appendix A: The i3 sync protocol

-

Consider the following situation: You open two windows in your testcase, then -you use focus left and want to verify that the X11 focus has been updated +

+

Consider the following situation: You open two windows in your testcase, then +you use focus left and want to verify that the X11 focus has been updated properly. Sounds simple, right? Let’s assume you use this straight-forward -implementation:

+implementation:

+
Racey focus testcase
-
my $left = open_window($x);
+
my $left = open_window($x);
 my $right = open_window($x);
 cmd 'focus left';
-is($x->input_focus, $left->id, 'left window focused');
-
-

However, the test fails. Sometimes. Apparently, there is a race condition in +is($x->input_focus, $left->id, 'left window focused'); +

+
+
+

However, the test fails. Sometimes. Apparently, there is a race condition in your test. If you think about it, this is because you are using two different pieces of software: You tell i3 to update focus, i3 confirms that, and then you ask X11 to give you the current focus. There is a certain time i3 needs to update the X11 state. If the testcase gets CPU time before X11 processed i3’s -requests, the test will fail.

+requests, the test will fail.

+
-Diagram of the race condition +Diagram of the race condition
Figure 1. Diagram of the race condition
-

One way to "solve" this would be to add sleep 0.5; after the cmd call. +

+

One way to "solve" this would be to add sleep 0.5; after the cmd call. After 0.5 seconds it should be safe to assume that focus has been updated, -right?

-

In practice, this usually works. However, it has several problems:

-
    +right?

    +
+
+

In practice, this usually works. However, it has several problems:

+
+
+
  1. -

    -This is obviously not a clean solution, but a workaround. Ugly. -

    +

    This is obviously not a clean solution, but a workaround. Ugly.

  2. -

    -On very slow machines, this might not work. Unlikely, but in different - situations (a delay to wait for i3 to startup) the necessary time is much - harder to guess, even for fast machines. -

    +

    On very slow machines, this might not work. Unlikely, but in different +situations (a delay to wait for i3 to startup) the necessary time is much +harder to guess, even for fast machines.

  3. -

    -This wastes a lot of time. Usually, your computer is much faster than 0.5s - to update the status. However, sometimes, it might take 0.4s, so we can’t - make it sleep 0.1. -

    +

    This wastes a lot of time. Usually, your computer is much faster than 0.5s +to update the status. However, sometimes, it might take 0.4s, so we can’t +make it sleep 0.1.

  4. -
-

To illustrate how grave the problem with wasting time actually is: Before + +

+
+

To illustrate how grave the problem with wasting time actually is: Before removing all sleeps from the testsuite, a typical run using 4 separate X servers took around 50 seconds on my machine. After removing all the sleeps, we achieved times of about 25 seconds. This is very significant and influences the way you think about tests — the faster they are, the more likely you are -to check whether everything still works quite often (which you should).

-

What I am trying to say is: Delays adds up quickly and make the test suite -less robust.

-

The real solution for this problem is a mechanism which I call "the i3 sync +to check whether everything still works quite often (which you should).

+
+
+

What I am trying to say is: Delays adds up quickly and make the test suite +less robust.

+
+
+

The real solution for this problem is a mechanism which I call "the i3 sync protocol". The idea is to send a request (which does not modify state) via X11 to i3 which will then be answered. Due to the request’s position in the event queue (after all previous events), you can be sure that by the time you receive the reply, all other events have been dealt with by i3 (and, more -importantly, X11).

+importantly, X11).

+
-Diagram of the i3 sync solution +Diagram of the i3 sync solution
Figure 2. Diagram of the i3 sync solution
-

5.1. Implementation details

-

The client which wants to sync with i3 initiates the protocol by sending a -ClientMessage to the X11 root window:

+

Implementation details

+
+

The client which wants to sync with i3 initiates the protocol by sending a +ClientMessage to the X11 root window:

+
Send ClientMessage
-
# Generate a ClientMessage, see xcb_client_message_t
+
# Generate a ClientMessage, see xcb_client_message_t
 my $msg = pack "CCSLLLLLLL",
     CLIENT_MESSAGE, # response_type
     32,     # format
@@ -622,45 +736,58 @@ 

5.1. Implementation details

# Send it to the root window -- since i3 uses the SubstructureRedirect # event mask, it will get the ClientMessage. -$x->send_event(0, $root, EVENT_MASK_SUBSTRUCTURE_REDIRECT, $msg);
-
-

i3 will then reply with the same ClientMessage, sent to the window specified in -data[0]. In the reply, data[0] and data[1] are exactly the same as in the -request. You should use a random value in data[1] and check that you received -the same one when getting the reply.

+$x->send_event(0, $root, EVENT_MASK_SUBSTRUCTURE_REDIRECT, $msg); +
+ +
+

i3 will then reply with the same ClientMessage, sent to the window specified in +data[0]. In the reply, data[0] and data[1] are exactly the same as in the +request. You should use a random value in data[1] and check that you received +the same one when getting the reply.

+
-

6. Appendix B: Socket activation

+

Appendix B: Socket activation

-

Socket activation is a mechanism which was made popular by systemd, an init +

+

Socket activation is a mechanism which was made popular by systemd, an init replacement. It basically describes creating a listening socket before starting a program. systemd will invoke the program only when an actual connection to -the socket is made, hence the term socket activation.

-

The interesting part of this (in the i3 context) is that you can very precisely -detect when the program is ready (finished its initialization).

+the socket is made, hence the term socket activation.

+
+
+

The interesting part of this (in the i3 context) is that you can very precisely +detect when the program is ready (finished its initialization).

+
-

6.1. Preparing the listening socket

-

complete-run.pl will create a listening UNIX socket which it will then pass +

Preparing the listening socket

+
+

complete-run.pl will create a listening UNIX socket which it will then pass to i3. This socket will be used by i3 as an additional IPC socket, just like the one it will create on its own. Passing the socket happens implicitly because children will inherit the parent’s sockets when fork()ing and sockets -will continue to exist after an exec() call (unless CLOEXEC is set of course).

-

The only explicit things complete-run.pl has to do is setting the LISTEN_FDS +will continue to exist after an exec() call (unless CLOEXEC is set of course).

+
+
+

The only explicit things complete-run.pl has to do is setting the LISTEN_FDS environment variable to the number of sockets which exist (1 in our case) and -setting the LISTEN_PID environment variable to the current process ID. Both +setting the LISTEN_PID environment variable to the current process ID. Both variables are necessary so that the program (i3) knows how many sockets it should use and if the environment variable is actually intended for it. i3 will then start looking for sockets at file descriptor 3 (since 0, 1 and 2 are used -for stdin, stdout and stderr, respectively).

-

The actual Perl code which sets up the socket, fork()s, makes sure the socket +for stdin, stdout and stderr, respectively).

+
+
+

The actual Perl code which sets up the socket, fork()s, makes sure the socket has file descriptor 3 and sets up the environment variables follows (shortened -a bit):

+a bit):

+
Setup socket and environment
-
my $socket = IO::Socket::UNIX->new(
+
my $socket = IO::Socket::UNIX->new(
     Listen => 1,
     Local => $args{unix_socket_path},
 );
@@ -682,52 +809,62 @@ 

6.1. Preparing the listening socket

-
+} +
+
-

6.2. Waiting for a reply

-

In the parent process, we want to know when i3 is ready to answer our IPC +

Waiting for a reply

+
+

In the parent process, we want to know when i3 is ready to answer our IPC requests and handle our windows. Therefore, after forking, we immediately close the listening socket (i3 will handle this side of the socket) and connect to it (remember, we are talking about a named UNIX socket) as a client. This connect call will immediately succeed because the kernel buffers it. Then, we send a request (of type GET_TREE, but that is not really relevant). Writing data to the socket will also succeed immediately because, again, the kernel buffers it -(only up to a certain amount of data of course).

-

Afterwards, we just blockingly wait until we get an answer. In the child +(only up to a certain amount of data of course).

+
+
+

Afterwards, we just blockingly wait until we get an answer. In the child process, i3 will setup the listening socket in its event loop. Immediately after actually starting the event loop, it will notice a new client connecting (the parent process) and handle its request. Since all initialization has been completed successfully by the time the event loop is entered, we can now assume -that i3 is ready.

+that i3 is ready.

+
-

6.3. Timing and conclusion

-

A beautiful feature of this mechanism is that it does not depend on timing. It +

Timing and conclusion

+
+

A beautiful feature of this mechanism is that it does not depend on timing. It does not matter when the child process gets CPU time or when the parent process gets CPU time. On heavily loaded machines (or machines with multiple CPUs, -cores or unreliable schedulers), this makes waiting for i3 much more robust.

-

Before using socket activation, we typically used a sleep(1) and hoped that +cores or unreliable schedulers), this makes waiting for i3 much more robust.

+
+
+

Before using socket activation, we typically used a sleep(1) and hoped that i3 was initialized by that time. Of course, this breaks on some (slow) computers and wastes a lot of time on faster computers. By using socket activation, we decreased the total amount of time necessary to run all tests (72 files at the time of writing) from > 100 seconds to 16 seconds. This makes it significantly more attractive to run the test suite more often (or at all) -during development.

-

An alternative approach to using socket activation is polling for the existence +during development.

+
+
+

An alternative approach to using socket activation is polling for the existence of the IPC socket and connecting to it. While this might be slightly easier to implement, it wastes CPU time and is considerably uglier than this solution -:). After all, lib/SocketActivation.pm contains only 54 SLOC.

+:). After all, lib/SocketActivation.pm contains only 54 SLOC.

+
+
+ + + -
-

- - + \ No newline at end of file diff --git a/docs/tree-migrating.html b/docs/tree-migrating.html deleted file mode 100644 index c5a59ec..0000000 --- a/docs/tree-migrating.html +++ /dev/null @@ -1,271 +0,0 @@ - - - - - - -i3: Tree branch: Migrating - - - - - - - -
-

i3 - improved tiling WM

- -
-
- -
-

1. Introduction

-
-

The tree branch (referring to a branch of i3 in the git repository) is the new -version of i3. Due to the very deep changes and heavy refactoring of the source -source, we decided to develop it in a seperate branch (instead of using the -next/master-branch system like before).

-
-
-
-

2. Current status

-
-

Currently, the code is mostly working. Some of the i3 core developers have been -using the tree branch version for a few weeks now. So, if you are eager to try -out the new features and help us find bugs, give it a try!

-

At the same time, a word of warning is appropriate: This version of i3 might -crash unexpectedly, so please be careful with important data (do not work for -two days without saving…).

-
-
-
-

3. Getting the latest tree branch version

-
-

Check out the latest version:

-
-
-
$ git clone -b tree git://code.stapelberg.de/i3
-
-

Then build and install it (has the same dependencies as the latest stable i3 -version):

-
-
-
$ cd i3
-$ make
-$ sudo cp i3 /usr/bin/i3-tree
-
-

…and execute i3-tree instead of i3 in your Xsession.

-

IMPORTANT: Please note that configuration file compatibility is not yet done. -So, make sure you use/customize the provided i3.config file.

-
-
-
-

4. Tree

-
-

The most important change and reason for the name is that i3 stores all -information about the X11 outputs, workspaces and layout of the windows on them -in a tree. The root node is the X11 root window, followed by the X11 outputs, -then workspaces and finally the windows themselve. In previous versions of i3 -we had multiple lists (of outputs, workspaces) and a table for each workspace. -That approach turned out to be complicated to use (snapping), understand and -implement.

-
-

4.1. The tree consists of Containers

-

The building blocks of our tree are so called Containers. A Container can -host a window (meaning an X11 window, one that you can actually see and use, -like a browser). Alternatively, it could contain one or more Containers. A -simple example is the workspace: When you start i3 with a single monitor, a -single workspace and you open two terminal windows, you will end up with a tree -like this:

-
-
-layout2 -
-
-
-
-shot4 -
-
Figure 1. Two terminals on standard workspace
-
-
-
-

4.2. Orientation and Split Containers

-

It is only natural to use so-called Split Containers in order to build a -layout when using a tree as data structure. In i3, every Container has an -orientation (horizontal, vertical or unspecified). So, in our example with the -workspace, the default orientation of the workspace Container is horizontal -(most monitors are widescreen nowadays). If you change the orientation to -vertical (Alt+v in the default config) and then open two terminals, i3 will -configure your windows like this:

-
-
-shot2 -
-
Figure 2. Vertical Workspace Orientation
-
-

An interesting new feature of the tree branch is the ability to split anything: -Let’s assume you have two terminals on a workspace (with horizontal -orientation), focus is on the right terminal. Now you want to open another -terminal window below the current one. If you would just open a new terminal -window, it would show up to the right due to the horizontal workspace -orientation. Instead, press Alt+v to create a Vertical Split Container (to -open a Horizontal Split Container, use Alt+h). Now you can open a new -terminal and it will open below the current one:

-
-
-Layout -
-
-
-
-shot -
-
Figure 3. Vertical Split Container
-
-
-

You probably guessed it already: There is no limit on how deep your hierarchy -of splits can be.

-
-
-

4.3. Level up

-

Let’s stay with our example from above. We have a terminal on the left and two -vertically split terminals on the right, focus is on the bottom right one. When -you open a new terminal, it will open below the current one.

-

So, how can you open a new terminal window to the right of the current one? -The solution is to use level up, which will focus the Parent Container of -the current Container. In this case, you would focus the Vertical Split -Container which is inside the horizontally oriented workspace. Thus, now new -windows will be opened to the right of the Vertical Split Container:

-
-
-shot3 -
-
Figure 4. Level Up, then open new terminal
-
-
-
-
-
-

5. Commands

-
-

The authoritive reference for commands is src/cmdparse.y. You can also find -most commands in i3.config. Here comes a short overview over the important -commands:

-
-

5.1. Manipulating layout

-
-
-
layout <default|stacked|tabbed>
-
-
-
-

5.2. Changing Focus

-
-
-
next <horizontal|vertical>
-prev <horizontal|vertical>
-
-
-
Examples:
-
-
bindsym Mod1+Left prev h
-bindsym Mod1+Right next h
-bindsym Mod1+Down next v
-bindsym Mod1+Up prev v
-
-
-
-

5.3. Moving

-
-
-
move <before|after> <horizontal|vertical>
-
-
-
Examples:
-
-
bindsym Mod1+Shift+Left move before h
-bindsym Mod1+Shift+Right move after h
-bindsym Mod1+Shift+Down move before v
-bindsym Mod1+Shift+Up move after v
-
-
-
-

5.4. Changing workspace

-
-
-
workspace <name>
-
-
-
Examples:
-
-
bindsym Mod1+1 workspace 1
-bindsym Mod1+2 workspace 2
-…
-
-
-
-

5.5. Moving Containers to workspaces

-
-
-
move workspace <name>
-
-
-
-
bindsym Mod1+Shift+1 move workspace 1
-bindsym Mod1+Shift+2 move workspace 2
-…
-
-
-
-

5.6. Changing border style

-
-
-
border <normal|none|1pixel>
-
-
-
-

5.7. Changing container mode

-
-
-
mode <tiling|floating|toggle>
-
-
-
-
-
-

6. The rest

-
-

What is not mentioned here explicitly is either unchanged and can be read in -the i3 User’s Guide or it is not yet -implemented.

-
-
-
-

- - - diff --git a/docs/tshirts.html b/docs/tshirts.html index c63b0ac..e0c4af9 100644 --- a/docs/tshirts.html +++ b/docs/tshirts.html @@ -1,219 +1,193 @@ - - - - - - -i3: i3wm T-shirts - - - - - - -
- - -
-
- - -

i3wm T-shirts

-Stefan Schroeder
-<ondekoza@gmail.com>
-December 2013 -
-
Table of Contents
- -
-
-
-

1. You can show everybody your appreciation for i3wm by wearing our t-shirt

-
-

The i3wm team is collaborating with a shirt manufacturer in Germany -that provides high quality t-shirts with a cool i3wm logo.

-

Since the website is in German only, we want to help with your order -in case that German is not your primary language.

-
-

1.1. The shirt

-

The shirt is black, has white text and the light blue official i3wm logo. It is -available in eight sizes (XS, S, M, L, XL, XXL, XXXL, XXXXL).

-
-
-

1.2. The order process for new customers

-

Open https://alter-shop.freddruck.de/ in your browser.

-

In the navigation bar on the left, select i3-tiling window manager.

-

Select the link below the shirt of your choice. (At the time of -this writing only black was available.)

-

On the next page you can select the size (Größe) and -the number of shirts (=Anzahl) of that size you want to order.

-

Add to cart by clicking in den Korb.

-

In the upper right corner click Kasse (checkout).

-

You now have to register with the freddruck-website. Click -"Weiter" below the left white box titled "Neuer Kunde" -(new customer).

-

On the next page you have to supply your personal information:

-
-
-Vorname -
-
-

-First name -

-
-
-Nachname -
-
-

-Last name -

-
-
-Geburtsdatum -
-
-

-Birth date, format DD.MM.YYYY -

-
-
-Firmenname -
-
-

-Company name, if applicable -

-
-
-Address -
-
-Strasse/Nr. -
-
-

-Street and number -

-
-
-Postleitzahl -
-
-

-ZIP code -

-
-
-Ort -
-
-

-City -

-
-
-Land -
-
-

-Country (“Bitte wählen” means please choose) -

-
-
-Telefonnummer -
-
-

-Phone number. Don’t forget your country code, e.g. +1-555-2368. -

-
-
-Telefaxnummer -
-
-

-Fax number -

-
-
-Newsletter -
-
-

-A checkbox for whether you want to receive their newsletter. -

-
-
-Passwort -
-
-

-Password -

-
-
-Bestätigung -
-
-

-Confirmation -

-
-
-

Then click “Weiter” (Continue).

-

On the next page you should get the confirmation -that your account was successfully created. (“Ihr Konto wurde mit Erfolg eröffnet!”)

-

You will also get a confirmation email about the -creation of the account (that’s not your order yet!).

-

Click “Weiter” (Next) to continue.

-

On the next page you can review your destination address.

-

The text field allows you to add a comment. Just leave it blank.

-

Click “Weiter” again, to choose the payment options.

-

On the payment page you can choose your method of payment:

-

Offered are

-
    -
  • -

    -Check (to be sent in advance) -

    -
  • -
  • -

    -Paypal -

    -
  • -
  • -

    -on pickup -

    -
  • -
-

On the next page you can finally confirm your order.

-
-
-
- -

- - - + + + + + + + + +i3wm T-shirts + + + + +
+
+

You can show everybody your appreciation for i3wm by wearing our t-shirt

+
+
+

The i3wm team is collaborating with a shirt manufacturer in Germany +that provides high quality t-shirts with a cool i3wm logo.

+
+
+

Since the website is in German only, we want to help with your order +in case that German is not your primary language.

+
+
+

The shirt

+
+

The shirt is black, has white text and the light blue official i3wm logo. It is +available in eight sizes (XS, S, M, L, XL, XXL, XXXL, XXXXL).

+
+
+
+

The order process for new customers

+
+

Open https://alter-shop.freddruck.de/ in your browser.

+
+
+

In the navigation bar on the left, select i3-tiling window manager.

+
+
+

Select the link below the shirt of your choice. (At the time of +this writing only black was available.)

+
+
+

On the next page you can select the size (Größe) and +the number of shirts (=Anzahl) of that size you want to order.

+
+
+

Add to cart by clicking in den Korb.

+
+
+

In the upper right corner click Kasse (checkout).

+
+
+

You now have to register with the freddruck-website. Click +"Weiter" below the left white box titled "Neuer Kunde" +(new customer).

+
+
+

On the next page you have to supply your personal information:

+
+
+
+
Vorname
+
+

First name

+
+
Nachname
+
+

Last name

+
+
Geburtsdatum
+
+

Birth date, format DD.MM.YYYY

+
+
Firmenname
+
+

Company name, if applicable

+
+
Address
+
Strasse/Nr.
+
+

Street and number

+
+
Postleitzahl
+
+

ZIP code

+
+
Ort
+
+

City

+
+
Land
+
+

Country (“Bitte wählen” means please choose)

+
+
Telefonnummer
+
+

Phone number. Don’t forget your country code, e.g. +1-555-2368.

+
+
Telefaxnummer
+
+

Fax number

+
+
Newsletter
+
+

A checkbox for whether you want to receive their newsletter.

+
+
Passwort
+
+

Password

+
+
Bestätigung
+
+

Confirmation

+
+
+
+
+

Then click “Weiter” (Continue).

+
+
+

On the next page you should get the confirmation +that your account was successfully created. (“Ihr Konto wurde mit Erfolg eröffnet!”)

+
+
+

You will also get a confirmation email about the +creation of the account (that’s not your order yet!).

+
+
+

Click “Weiter” (Next) to continue.

+
+
+

On the next page you can review your destination address.

+
+
+

The text field allows you to add a comment. Just leave it blank.

+
+
+

Click “Weiter” again, to choose the payment options.

+
+
+

On the payment page you can choose your method of payment:

+
+
+

Offered are

+
+
+
    +
  • +

    Check (to be sent in advance)

    +
  • +
  • +

    Paypal

    +
  • +
  • +

    on pickup

    +
  • +
+
+
+

On the next page you can finally confirm your order.

+
+
+
+
+
+ + + \ No newline at end of file diff --git a/docs/userguide.html b/docs/userguide.html index c08c77f..7a580b3 100644 --- a/docs/userguide.html +++ b/docs/userguide.html @@ -1,460 +1,672 @@ - - - -i3: i3 User’s Guide - - - - + + + + + +i3 User’s Guide + - -
- - -
-
- + +
-

4.3. Keyboard bindings

-

A keyboard binding makes i3 execute a command (see below) upon pressing a +

Keyboard bindings

+
+

A keyboard binding makes i3 execute a command (see below) upon pressing a specific key. i3 allows you to bind either on keycodes or on keysyms (you can -also mix your bindings, though i3 will not protect you from overlapping ones).

-
    +also mix your bindings, though i3 will not protect you from overlapping ones).

    +
+
+
  • -

    -A keysym (key symbol) is a description for a specific symbol, like "a" - or "b", but also more strange ones like "underscore" instead of "_". These - are the ones you use in Xmodmap to remap your keys. To get the current - mapping of your keys, use xmodmap -pke. To interactively enter a key and - see what keysym it is configured to, use xev. -

    +

    A keysym (key symbol) is a description for a specific symbol, like "a" +or "b", but also more strange ones like "underscore" instead of "_". These +are the ones you use in Xmodmap to remap your keys. To get the current +mapping of your keys, use xmodmap -pke. To interactively enter a key and +see what keysym it is configured to, use xev.

  • -

    -Keycodes do not need to have a symbol assigned (handy for custom vendor - hotkeys on some notebooks) and they will not change their meaning as you - switch to a different keyboard layout (when using xmodmap). -

    +

    Keycodes do not need to have a symbol assigned (handy for custom vendor +hotkeys on some notebooks) and they will not change their meaning as you +switch to a different keyboard layout (when using xmodmap).

  • -
-

My recommendation is: If you often switch keyboard layouts but you want to keep + +

+
+

My recommendation is: If you often switch keyboard layouts but you want to keep your bindings in the same physical location on the keyboard, use keycodes. If you don’t switch layouts, and want a clean and simple config file, use -keysyms.

-

Some tools (such as import or xdotool) might be unable to run upon a +keysyms.

+
+
+

Some tools (such as import or xdotool) might be unable to run upon a KeyPress event, because the keyboard/pointer is still grabbed. For these -situations, the --release flag can be used, which will execute the command -after the keys have been released.

-

Syntax:

+situations, the --release flag can be used, which will execute the command +after the keys have been released.

+
+
+

Syntax:

+
-
bindsym [--release] [<Group>+][<Modifiers>+]<keysym> command
-bindcode [--release] [<Group>+][<Modifiers>+]<keycode> command
-
-

Examples:

+
bindsym [--release] [<Group>+][<Modifiers>+]<keysym> command
+bindcode [--release] [<Group>+][<Modifiers>+]<keycode> command
+
+ +
+

Examples:

+
-
# Fullscreen
+
# Fullscreen
 bindsym $mod+f fullscreen toggle
 
 # Restart
@@ -467,55 +679,65 @@ 

4.3. Keyboard bindings

bindsym --release $mod+x exec --no-startup-id xdotool key --clearmodifiers ctrl+v # Take a screenshot upon pressing $mod+x (select an area) -bindsym --release $mod+x exec --no-startup-id import /tmp/latest-screenshot.png
-
-

Available Modifiers:

-
-
-Mod1-Mod5, Shift, Control -
+bindsym --release $mod+x exec --no-startup-id import /tmp/latest-screenshot.png +
+ +
+

Available Modifiers:

+
+
+
+
Mod1-Mod5, Shift, Control
-

-Standard modifiers, see xmodmap(1) -

+

Standard modifiers, see xmodmap(1)

-
-Group1, Group2, Group3, Group4 -
+
Group1, Group2, Group3, Group4
-

-When using multiple keyboard layouts (e.g. with setxkbmap -layout us,ru), you +

When using multiple keyboard layouts (e.g. with setxkbmap -layout us,ru), you can specify in which XKB group (also called “layout”) a keybinding should be active. By default, keybindings are translated in Group1 and are active in all groups. If you want to override keybindings in one of your layouts, specify the corresponding group. For backwards compatibility, the group “Mode_switch” is an -alias for Group2. -

+alias for Group2.

-
+ +
-

4.4. Mouse bindings

-

A mouse binding makes i3 execute a command upon pressing a specific mouse +

Mouse bindings

+
+

A mouse binding makes i3 execute a command upon pressing a specific mouse button in the scope of the clicked container (see [command_criteria]). You -can configure mouse bindings in a similar way to key bindings.

-

Syntax:

+can configure mouse bindings in a similar way to key bindings.

+
+
+

Syntax:

+
-
bindsym [--release] [--border] [--whole-window] [--exclude-titlebar] [<Modifiers>+]button<n> command
-
-

By default, the binding will only run when you click on the titlebar of the -window. If the --release flag is given, it will run when the mouse button -is released.

-

If the --whole-window flag is given, the binding will also run when any part +

bindsym [--release] [--border] [--whole-window] [--exclude-titlebar] [<Modifiers>+]button<n> command
+
+
+
+

By default, the binding will only run when you click on the titlebar of the +window. If the --release flag is given, it will run when the mouse button +is released.

+
+
+

If the --whole-window flag is given, the binding will also run when any part of the window is clicked, with the exception of the border. To have a bind run -when the border is clicked, specify the --border flag.

-

If the --exclude-titlebar flag is given, the titlebar will not be considered -for the keybinding.

-

Examples:

+when the border is clicked, specify the --border flag.

+ +
+

If the --exclude-titlebar flag is given, the titlebar will not be considered +for the keybinding.

+
+
+

Examples:

+
-
# The middle button over a titlebar kills the window
+
# The middle button over a titlebar kills the window
 bindsym --release button2 kill
 
 # The middle button and a modifer over any part of the window kills the window
@@ -527,43 +749,59 @@ 

4.4. Mouse bindings

# The side buttons move the window around bindsym button9 move left -bindsym button8 move right
-
+bindsym button8 move right + +
-

4.5. Binding modes

-

You can have multiple sets of bindings by using different binding modes. When +

Binding modes

+
+

You can have multiple sets of bindings by using different binding modes. When you switch to another binding mode, all bindings from the current mode are released and only the bindings defined in the new mode are valid for as long as -you stay in that binding mode. The only predefined binding mode is default, +you stay in that binding mode. The only predefined binding mode is default, which is the mode i3 starts out with and to which all bindings not defined in a -specific binding mode belong.

-

Working with binding modes consists of two parts: defining a binding mode and +specific binding mode belong.

+
+
+

Working with binding modes consists of two parts: defining a binding mode and switching to it. For these purposes, there are one config directive and one -command, both of which are called mode. The directive is used to define the +command, both of which are called mode. The directive is used to define the bindings belonging to a certain binding mode, while the command will switch to -the specified mode.

-

It is recommended to use binding modes in combination with [variables] in +the specified mode.

+
+
+

It is recommended to use binding modes in combination with Variables in order to make maintenance easier. Below is an example of how to use a binding -mode.

-

Note that it is advisable to define bindings for switching back to the default -mode.

-

Note that it is possible to use [pango_markup] for binding modes, but you -need to enable it explicitly by passing the --pango_markup flag to the mode -definition.

-

Syntax:

+mode.

+
+
+

Note that it is advisable to define bindings for switching back to the default +mode.

+
+
+

Note that it is possible to use Window title format for binding modes, but you +need to enable it explicitly by passing the --pango_markup flag to the mode +definition.

+
+
+

Syntax:

+
-
# config directive
+
# config directive
 mode [--pango_markup] <name>
 
 # command
-mode <name>
-
-

Example:

+mode <name> +
+ +
+

Example:

+
-
# Press $mod+o followed by either f, t, Escape or Return to launch firefox,
+
# Press $mod+o followed by either f, t, Escape or Return to launch firefox,
 # thunderbird or return to the default mode, respectively.
 set $mode_launcher Launch: [f]irefox [t]hunderbird
 bindsym $mod+o mode "$mode_launcher"
@@ -574,162 +812,236 @@ 

4.5. Binding modes

bindsym Escape mode "default" bindsym Return mode "default" -}
-
+} + +
-

4.6. The floating modifier

-

To move floating windows with your mouse, you can either grab their titlebar +

The floating modifier

+
+

To move floating windows with your mouse, you can either grab their titlebar or configure the so-called floating modifier which you can then press and click anywhere in the window itself to move it. The most common setup is to use the same key you use for managing windows (Mod1 for example). Then you can press Mod1, click into a window using your left mouse button, and drag -it to the position you want.

-

When holding the floating modifier, you can resize a floating window by +it to the position you want.

+
+
+

When holding the floating modifier, you can resize a floating window by pressing the right mouse button on it and moving around while holding it. If you hold the shift button as well, the resize will be proportional (the aspect -ratio will be preserved).

-

Syntax:

+ratio will be preserved).

+
+
+

Syntax:

+
-
floating_modifier <Modifier>
-
-

Example:

+
floating_modifier <Modifier>
+
+ +
+

Example:

+
-
floating_modifier Mod1
-
+
floating_modifier Mod1
+ +
-

4.7. Constraining floating window size

-

The maximum and minimum dimensions of floating windows can be specified. If -either dimension of floating_maximum_size is specified as -1, that dimension +

Constraining floating window size

+
+

The maximum and minimum dimensions of floating windows can be specified. If +either dimension of floating_maximum_size is specified as -1, that dimension will be unconstrained with respect to its maximum value. If either dimension of -floating_maximum_size is undefined, or specified as 0, i3 will use a default -value to constrain the maximum size. floating_minimum_size is treated in a -manner analogous to floating_maximum_size.

-

Syntax:

+floating_maximum_size is undefined, or specified as 0, i3 will use a default +value to constrain the maximum size. floating_minimum_size is treated in a +manner analogous to floating_maximum_size.

+
+
+

Syntax:

+
-
floating_minimum_size <width> x <height>
-floating_maximum_size <width> x <height>
-
-

Example:

+
floating_minimum_size <width> x <height>
+floating_maximum_size <width> x <height>
+
+ +
+

Example:

+
-
floating_minimum_size 75 x 50
-floating_maximum_size -1 x -1
-
+
floating_minimum_size 75 x 50
+floating_maximum_size -1 x -1
+ +
-

4.8. Orientation for new workspaces

-

New workspaces get a reasonable default orientation: Wide-screen monitors +

Orientation for new workspaces

+
+

New workspaces get a reasonable default orientation: Wide-screen monitors (anything wider than high) get horizontal orientation, rotated monitors -(anything higher than wide) get vertical orientation.

-

With the default_orientation configuration directive, you can override that -behavior.

-

Syntax:

+(anything higher than wide) get vertical orientation.

+
+
+

With the default_orientation configuration directive, you can override that +behavior.

+
+
+

Syntax:

+
-
default_orientation horizontal|vertical|auto
-
-

Example:

+
default_orientation horizontal|vertical|auto
+
+ +
+

Example:

+
-
default_orientation vertical
-
+
default_orientation vertical
+ +
-

4.9. Layout mode for new containers

-

This option determines in which mode new containers on workspace level will -start.

-

Syntax:

+

Layout mode for new containers

+
+

This option determines in which mode new containers on workspace level will +start.

+
+
+

Syntax:

+
-
workspace_layout default|stacking|tabbed
-
-

Example:

+
workspace_layout default|stacking|tabbed
+
+ +
+

Example:

+
-
workspace_layout tabbed
-
+
workspace_layout tabbed
+ +
-

4.10. Window title alignment

-

This option determines the window title’s text alignment. -Default is left

-

Syntax:

+

Window title alignment

+
+

This option determines the window title’s text alignment. +Default is left

+
+
+

Syntax:

+
-
title_align left|center|right
-
+
title_align left|center|right
+
+
-

4.11. Default border style for new windows

-

This option determines which border style new windows will have. The default is -normal. Note that default_floating_border applies only to windows which are starting out as -floating windows, e.g., dialog windows, but not windows that are floated later on.

-

Setting border style to pixel eliminates title bars. The border style normal allows you to -adjust edge border width while keeping your title bar.

-

Syntax:

+

Default border style for new windows

+
+

This option determines which border style new windows will have. The default is +normal. Note that default_floating_border applies only to windows which are starting out as +floating windows, e.g., dialog windows, but not windows that are floated later on.

+
+
+

Setting border style to pixel eliminates title bars. The border style normal allows you to +adjust edge border width while keeping your title bar.

+
+
+

Syntax:

+
-
default_border normal|none|pixel
+
default_border normal|none|pixel
 default_border normal|pixel <px>
 default_floating_border normal|none|pixel
-default_floating_border normal|pixel <px>
-
-

Please note that new_window and new_float have been deprecated in favor of the above options -and will be removed in a future release. We strongly recommend using the new options instead.

-

Example:

+default_floating_border normal|pixel <px> +
+ +
+

Please note that new_window and new_float have been deprecated in favor of the above options +and will be removed in a future release. We strongly recommend using the new options instead.

+
+
+

Example:

+
-
default_border pixel
-
-

The "normal" and "pixel" border styles support an optional border width in -pixels:

-

Example:

+
default_border pixel
+ + +
+

The "normal" and "pixel" border styles support an optional border width in +pixels:

+
+
+

Example:

+
-
# The same as default_border none
+
# The same as default_border none
 default_border pixel 0
 
 # A 3 px border
-default_border pixel 3
-
+default_border pixel 3 + +
-

4.12. Hiding borders adjacent to the screen edges

-

You can hide container borders adjacent to the screen edges using -hide_edge_borders. This is useful if you are using scrollbars, or do not want +

Hiding borders adjacent to the screen edges

+
+

You can hide container borders adjacent to the screen edges using +hide_edge_borders. This is useful if you are using scrollbars, or do not want to waste even two pixels in displayspace. The "smart" setting hides borders on workspaces with only one window visible, but keeps them on workspaces with -multiple windows visible. Default is none.

-

Syntax:

+multiple windows visible. Default is none.

+
+
+

Syntax:

+
-
hide_edge_borders none|vertical|horizontal|both|smart
-
-

Example:

+
hide_edge_borders none|vertical|horizontal|both|smart
+
+ +
+

Example:

+
-
hide_edge_borders vertical
-
+
hide_edge_borders vertical
+ +
-

4.13. Arbitrary commands for specific windows (for_window)

-

With the for_window directive, you can let i3 execute any command when it +

Arbitrary commands for specific windows (for_window)

+
+

With the for_window directive, you can let i3 execute any command when it encounters a specific window. This can be used to set windows to floating or to -change their border style, for example.

-

Syntax:

+change their border style, for example.

+
+
+

Syntax:

+
-
for_window <criteria> <command>
-
-

Examples:

+
for_window <criteria> <command>
+
+ +
+

Examples:

+
-
# enable floating mode for all XTerm windows
+
# enable floating mode for all XTerm windows
 for_window [class="XTerm"] floating enable
 
 # Make all urxvts use a 1-pixel border:
@@ -738,96 +1050,136 @@ 

4.13. Arbitrary commands for specific windows (for_window)

-
-

The valid criteria are the same as those for commands, see [command_criteria]. Only -commands can be executed at runtime, not config directives, see [list_of_commands].

+for_window [title="x200: ~/work"] floating enable + + +
+

The valid criteria are the same as those for commands, see [command_criteria]. Only +commands can be executed at runtime, not config directives, see List of commands.

+
-

4.14. Don’t focus window upon opening

-

When a new window appears, it will be focused. The no_focus directive allows preventing -this from happening and must be used in combination with [command_criteria].

-

Note that this does not apply to all cases, e.g., when feeding data into a running application +

Don’t focus window upon opening

+
+

When a new window appears, it will be focused. The no_focus directive allows preventing +this from happening and must be used in combination with [command_criteria].

+
+
+

Note that this does not apply to all cases, e.g., when feeding data into a running application causing it to request being focused. To configure the behavior in such cases, refer to -[focus_on_window_activation].

-

no_focus will also be ignored for the first window on a workspace as there shouldn’t be +Focus on window activation.

+
+
+

no_focus will also be ignored for the first window on a workspace as there shouldn’t be a reason to not focus the window in this case. This allows for better usability in -combination with workspace_layout.

-

Syntax:

+combination with workspace_layout.

+
+
+

Syntax:

+
-
no_focus <criteria>
-
-

Example:

+
no_focus <criteria>
+
+ +
+

Example:

+
-
no_focus [window_role="pop-up"]
-
+
no_focus [window_role="pop-up"]
+ +
-

4.15. Variables

-

As you learned in the section about keyboard bindings, you will have +

Variables

+
+

As you learned in the section about keyboard bindings, you will have to configure lots of bindings containing modifier keys. If you want to save yourself some typing and be able to change the modifier you use later, -variables can be handy.

-

Syntax:

+variables can be handy.

+
+
+

Syntax:

+
-
set $<name> <value>
-
-

Example:

+
set $<name> <value>
+
+ +
+

Example:

+
-
set $m Mod1
-bindsym $m+Shift+r restart
-
-

Variables are directly replaced in the file when parsing. Variables expansion +

set $m Mod1
+bindsym $m+Shift+r restart
+
+ +
+

Variables are directly replaced in the file when parsing. Variables expansion is not recursive so it is not possible to define a variable with a value containing another variable. There is no fancy handling and there are absolutely no plans to change this. If you need a more dynamic configuration you should create a little script which generates a configuration file and run -it before starting i3 (for example in your ~/.xsession file).

-

Also see [xresources] to learn how to create variables based on resources -loaded from the X resource database.

+it before starting i3 (for example in your ~/.xsession file).

+ +
+

Also see X resources to learn how to create variables based on resources +loaded from the X resource database.

+
-

4.16. X resources

-

[variables] can also be created using a value configured in the X resource +

X resources

+
+

Variables can also be created using a value configured in the X resource database. This is useful, for example, to avoid configuring color values within the i3 configuration. Instead, the values can be configured, once, in the X resource database to achieve an easily maintainable, consistent color theme -across many X applications.

-

Defining a resource will load this resource from the resource database and +across many X applications.

+
+
+

Defining a resource will load this resource from the resource database and assign its value to the specified variable. This is done verbatim and the value must therefore be in the format that i3 uses. A fallback must be specified in -case the resource cannot be loaded from the database.

-

Syntax:

+case the resource cannot be loaded from the database.

+
+
+

Syntax:

+
-
set_from_resource $<name> <resource_name> <fallback>
-
-

Example:

+
set_from_resource $<name> <resource_name> <fallback>
+
+ +
+

Example:

+
-
# The ~/.Xresources should contain a line such as
+
# The ~/.Xresources should contain a line such as
 #     *color0: #121212
 # and must be loaded properly, e.g., by using
 #     xrdb ~/.Xresources
 # This value is picked up on by other applications (e.g., the URxvt terminal
 # emulator) and can be used in i3 like this:
-set_from_resource $black i3wm.color0 #000000
-
+set_from_resource $black i3wm.color0 #000000 + +
-

4.17. Automatically putting clients on specific workspaces

-

To automatically make a specific window show up on a specific workspace, you +

Automatically putting clients on specific workspaces

+
+

To automatically make a specific window show up on a specific workspace, you can use an assignment. You can match windows by using any criteria, -see [command_criteria]. The difference between assign and -for_window <criteria> move to workspace is that the former will only be +see [command_criteria]. The difference between assign and +for_window <criteria> move to workspace is that the former will only be executed when the application maps the window (mapping means actually displaying it on the screen) but the latter will be executed whenever a window changes its -properties to something that matches the specified criteria.

-

Thus, it is recommended that you match on window classes (and instances, when +properties to something that matches the specified criteria.

+
+
+

Thus, it is recommended that you match on window classes (and instances, when appropriate) instead of window titles whenever possible because some applications first create their window, and then worry about setting the correct title. Firefox with Vimperator comes to mind. The window starts up being named @@ -835,25 +1187,35 @@

4.17. Automatically putting clients on specific worksp get the title as soon as the application maps the window, you’d need to have to match on Firefox in this case. Another known issue is with Spotify, which doesn’t set the class hints when -mapping the window, meaning you’ll have to use a for_window rule to assign +mapping the window, meaning you’ll have to use a for_window rule to assign Spotify to a specific workspace. -Finally, using assign [tiling] and assign [floating] is not supported.

-

You can also assign a window to show up on a specific output. You can use RandR -names such as VGA1 or names relative to the output with the currently focused -workspace such as left and down.

-

Assignments are processed by i3 in the order in which they appear in the config +Finally, using assign [tiling] and assign [floating] is not supported.

+
+
+

You can also assign a window to show up on a specific output. You can use RandR +names such as VGA1 or names relative to the output with the currently focused +workspace such as left and down.

+
+
+

Assignments are processed by i3 in the order in which they appear in the config file. The first one which matches the window wins and later assignments are not -considered.

-

Syntax:

+considered.

+
+
+

Syntax:

+
-
assign <criteria> [→] [workspace] [number] <workspace>
-assign <criteria> [→] output left|right|up|down|primary|<output>
-
-

Examples:

+
assign <criteria> [→] [workspace] [number] <workspace>
+assign <criteria> [→] output left|right|up|down|primary|<output>
+
+ +
+

Examples:

+
-
# Assign URxvt terminals to workspace 2
+
# Assign URxvt terminals to workspace 2
 assign [class="URxvt"] 2
 
 # Same thing, but more precise (exact match instead of substring)
@@ -879,764 +1241,894 @@ 

4.17. Automatically putting clients on specific worksp assign [class="^URxvt$"] → output right # Assign urxvt to the primary output -assign [class="^URxvt$"] → output primary

-
-

Note that you might not have a primary output configured yet. To do so, run:

-
-
-
xrandr --output <output> --primary
-
-

Also, the arrow is not required, it just looks good :-). If you decide to -use it, it has to be a UTF-8 encoded arrow, not -> or something like that.

-

To get the class and instance, you can use xprop. After clicking on the -window, you will see the following output:

-

xprop:

-
-
-
WM_CLASS(STRING) = "irssi", "URxvt"
-
-

The first part of the WM_CLASS is the instance ("irssi" in this example), the -second part is the class ("URxvt" in this example).

-

Should you have any problems with assignments, make sure to check the i3 -logfile first (see https://i3wm.org/docs/debugging.html). It includes more +assign [class="^URxvt$"] → output primary +

+ +
+

Note that you might not have a primary output configured yet. To do so, run:

+
+
+
+
xrandr --output <output> --primary
+
+
+
+

Also, the arrow is not required, it just looks good :-). If you decide to +use it, it has to be a UTF-8 encoded arrow, not -> or something like that.

+
+
+

To get the class and instance, you can use xprop. After clicking on the +window, you will see the following output:

+
+
+

xprop:

+
+
+
+
WM_CLASS(STRING) = "irssi", "URxvt"
+
+
+
+

The first part of the WM_CLASS is the instance ("irssi" in this example), the +second part is the class ("URxvt" in this example).

+
+
+

Should you have any problems with assignments, make sure to check the i3 +logfile first (see https://i3wm.org/docs/debugging.html). It includes more details about the matching process and the window’s actual class, instance and -title when starting up.

-

Note that if you want to start an application just once on a specific +title when starting up.

+
+
+

Note that if you want to start an application just once on a specific workspace, but you don’t want to assign all instances of it permanently, you -can make use of i3’s startup-notification support (see [exec]) in your config -file in the following way:

-

Start iceweasel on workspace 3 (once):

+can make use of i3’s startup-notification support (see Executing applications (exec)) in your config +file in the following way:

+ +
+

Start iceweasel on workspace 3 (once):

+
-
# Start iceweasel on workspace 3, then switch back to workspace 1
+
# Start iceweasel on workspace 3, then switch back to workspace 1
 # (Being a command-line utility, i3-msg does not support startup notifications,
 #  hence the exec --no-startup-id.)
 # (Starting iceweasel with i3’s exec command is important in order to make i3
 #  create a startup notification context, without which the iceweasel window(s)
 #  cannot be matched onto the workspace on which the command was started.)
-exec --no-startup-id i3-msg 'workspace 3; exec iceweasel; workspace 1'
-
+exec --no-startup-id i3-msg 'workspace 3; exec iceweasel; workspace 1' + +
-

4.18. Automatically starting applications on i3 startup

-

By using the exec keyword outside a keybinding, you can configure -which commands will be performed by i3 on initial startup. exec +

Automatically starting applications on i3 startup

+
+

By using the exec keyword outside a keybinding, you can configure +which commands will be performed by i3 on initial startup. exec commands will not run when restarting i3, if you need a command to run -also when restarting i3 you should use the exec_always -keyword. These commands will be run in order.

-

See [command_chaining] for details on the special meaning of ; (semicolon) -and , (comma): they chain commands together in i3, so you need to use quoted -strings (as shown in [exec_quoting]) if they appear in your command.

-

Syntax:

+also when restarting i3 you should use the exec_always +keyword. These commands will be run in order.

+
+
+

See [command_chaining] for details on the special meaning of ; (semicolon) +and , (comma): they chain commands together in i3, so you need to use quoted +strings (as shown in [exec_quoting]) if they appear in your command.

+
+
+

Syntax:

+
-
exec [--no-startup-id] <command>
-exec_always [--no-startup-id] <command>
-
-

Examples:

+
exec [--no-startup-id] <command>
+exec_always [--no-startup-id] <command>
+
+ +
+

Examples:

+
-
exec chromium
+
exec chromium
 exec_always ~/my_script.sh
 
 # Execute the terminal emulator urxvt, which is not yet startup-notification aware.
-exec --no-startup-id urxvt
-
-

The flag --no-startup-id is explained in [exec].

+exec --no-startup-id urxvt + + +
+

The flag --no-startup-id is explained in Executing applications (exec).

+
-

4.19. Automatically putting workspaces on specific screens

-

If you assign clients to workspaces, it might be handy to put the +

Automatically putting workspaces on specific screens

+
+

If you assign clients to workspaces, it might be handy to put the workspaces on specific screens. Also, the assignment of workspaces to screens will determine which workspace i3 uses for a new screen when adding screens or when starting (e.g., by default it will use 1 for the first screen, 2 for -the second screen and so on).

-

Syntax:

+the second screen and so on).

+
+
+

Syntax:

+
-
workspace <workspace> output <output1> [output2]…
-
-

The output is the name of the RandR output you attach your screen to. On a +

workspace <workspace> output <output1> [output2]…
+
+
+
+

The output is the name of the RandR output you attach your screen to. On a laptop, you might have VGA1 and LVDS1 as output names. You can see the -available outputs by running xrandr --current.

-

If your X server supports RandR 1.5 or newer, i3 will use RandR monitor objects -instead of output objects. Run xrandr --listmonitors to see a list. Usually, +available outputs by running xrandr --current.

+
+
+

If your X server supports RandR 1.5 or newer, i3 will use RandR monitor objects +instead of output objects. Run xrandr --listmonitors to see a list. Usually, a monitor object contains exactly one output, and has the same name as the output; but should that not be the case, you can specify the name of either the monitor or the output in i3’s configuration. For example, the Dell UP2414Q uses two scalers internally, so its output names might be “DP1” and “DP2”, but the -monitor name is “Dell UP2414Q”.

-

(Note that even if you specify the name of an output which doesn’t span the +monitor name is “Dell UP2414Q”.

+
+
+

(Note that even if you specify the name of an output which doesn’t span the entire monitor, i3 will still use the entire area of the containing monitor -rather than that of just the output’s.)

-

You can specify multiple outputs. The first available will be used.

-

If you use named workspaces, they must be quoted:

-

Examples:

+rather than that of just the output’s.)

+ +
+

You can specify multiple outputs. The first available will be used.

+
+
+

If you use named workspaces, they must be quoted:

+
+
+

Examples:

+
-
workspace 1 output LVDS1
+
workspace 1 output LVDS1
 workspace 2 output primary
 workspace 5 output VGA1 LVDS1
-workspace "2: vim" output VGA1
-
+workspace "2: vim" output VGA1 + +
-

4.20. Changing colors

-

You can change all colors which i3 uses to draw the window decorations.

-

Syntax:

+

Changing colors

+
+

You can change all colors which i3 uses to draw the window decorations.

+
+
+

Syntax:

+
-
<colorclass> <border> <background> <text> <indicator> <child_border>
-
-

Where colorclass can be one of:

-
-
-client.focused -
-
-

- A client which currently has the focus. -

-
-
-client.focused_inactive -
+
<colorclass> <border> <background> <text> <indicator> <child_border>
+
+
+
+

Where colorclass can be one of:

+
+
+
+
client.focused
-

- A client which is the focused one of its container, but it does not have - the focus at the moment. -

+

A client which currently has the focus.

-
-client.unfocused -
+
client.focused_inactive
-

- A client which is not the focused one of its container. -

+

A client which is the focused one of its container, but it does not have +the focus at the moment.

-
-client.urgent -
+
client.unfocused
-

- A client which has its urgency hint activated. -

+

A client which is not the focused one of its container.

-
-client.placeholder -
+
client.urgent
-

- Background and text color are used to draw placeholder window contents - (when restoring layouts). Border and indicator are ignored. -

+

A client which has its urgency hint activated.

-
-client.background -
+
client.placeholder
-

- Background color which will be used to paint the background of the - client window on top of which the client will be rendered. Only clients - which do not cover the whole area of this window expose the color. Note - that this colorclass only takes a single color. -

+

Background and text color are used to draw placeholder window contents +(when restoring layouts). Border and indicator are ignored.

-
-

Colors are in HTML hex format (#rrggbb), see the following example:

-

Examples (default colors):

+
client.background
+
+

Background color which will be used to paint the background of the +client window on top of which the client will be rendered. Only clients +which do not cover the whole area of this window expose the color. Note +that this colorclass only takes a single color.

+
+ + +
+

Colors are in HTML hex format (#rrggbb), see the following example:

+
+
+

Examples (default colors):

+
-
# class                 border  backgr. text    indicator child_border
+
# class                 border  backgr. text    indicator child_border
 client.focused          #4c7899 #285577 #ffffff #2e9ef4   #285577
 client.focused_inactive #333333 #5f676a #ffffff #484e50   #5f676a
 client.unfocused        #333333 #222222 #888888 #292d2e   #222222
 client.urgent           #2f343a #900000 #ffffff #900000   #900000
 client.placeholder      #000000 #0c0c0c #ffffff #000000   #0c0c0c
 
-client.background       #ffffff
-
-

Note that for the window decorations, the color around the child window is the +client.background #ffffff +

+ +
+

Note that for the window decorations, the color around the child window is the "child_border", and "border" color is only the two thin lines around the -titlebar.

-

The indicator color is used for indicating where a new window will be opened. +titlebar.

+
+
+

The indicator color is used for indicating where a new window will be opened. For horizontal split containers, the right border will be painted in indicator color, for vertical split containers, the bottom border. This only applies to single windows within a split container, which are otherwise indistinguishable -from single windows outside of a split container.

+from single windows outside of a split container.

+
-

4.21. Interprocess communication

-

i3 uses Unix sockets to provide an IPC interface. This allows third-party +

Interprocess communication

+
+

i3 uses Unix sockets to provide an IPC interface. This allows third-party programs to get information from i3, such as the current workspaces -(to display a workspace bar), and to control i3.

-

The IPC socket is enabled by default and will be created in -$XDG_RUNTIME_DIR/i3/ipc-socket.%p if the directory is available, falling back -to /tmp/i3-%u.XXXXXX/ipc-socket.%p, where %u is your UNIX username, %p is +(to display a workspace bar), and to control i3.

+
+
+

The IPC socket is enabled by default and will be created in +$XDG_RUNTIME_DIR/i3/ipc-socket.%p if the directory is available, falling back +to /tmp/i3-%u.XXXXXX/ipc-socket.%p, where %u is your UNIX username, %p is the PID of i3 and XXXXXX is a string of random characters from the portable -filename character set (see mkdtemp(3)).

-

You can override the default path through the environment-variable I3SOCK or -by specifying the ipc-socket directive. This is discouraged, though, since i3 +filename character set (see mkdtemp(3)).

+
+
+

You can override the default path through the environment-variable I3SOCK or +by specifying the ipc-socket directive. This is discouraged, though, since i3 does the right thing by default. If you decide to change it, it is strongly recommended to set this to a location in your home directory so that no other -user can create that directory.

-

Examples:

+user can create that directory.

+
+
+

Examples:

+
-
ipc-socket ~/.i3/i3-ipc.sock
-
-

You can then use the i3-msg application to perform any command listed in -[list_of_commands].

+
ipc-socket ~/.i3/i3-ipc.sock
+
+ +
+

You can then use the i3-msg application to perform any command listed in +List of commands.

+
-

4.22. Focus follows mouse

-

By default, window focus follows your mouse movements as the mouse crosses +

Focus follows mouse

+
+

By default, window focus follows your mouse movements as the mouse crosses window borders. However, if you have a setup where your mouse usually is in your way (like a touchpad on your laptop which you do not want to disable completely), you might want to disable focus follows mouse and control focus only by using your keyboard. The mouse will still be useful inside the -currently active window (for example to click on links in your browser window).

-

Syntax:

+currently active window (for example to click on links in your browser window).

+
+
+

Syntax:

+
-
focus_follows_mouse yes|no
-
-

Example:

+
focus_follows_mouse yes|no
+
+ +
+

Example:

+
-
focus_follows_mouse no
-
+
focus_follows_mouse no
+ +
-

4.23. Mouse warping

-

By default, when switching focus to a window on a different output (e.g. +

Mouse warping

+
+

By default, when switching focus to a window on a different output (e.g. focusing a window on workspace 3 on output VGA-1, coming from workspace 2 on -LVDS-1), the mouse cursor is warped to the center of that window.

-

With the mouse_warping option, you can control when the mouse cursor should -be warped. none disables warping entirely, whereas output is the default -behavior described above.

-

Syntax:

+LVDS-1), the mouse cursor is warped to the center of that window.

+
+
+

With the mouse_warping option, you can control when the mouse cursor should +be warped. none disables warping entirely, whereas output is the default +behavior described above.

+
+
+

Syntax:

+
-
mouse_warping output|none
-
-

Example:

+
mouse_warping output|none
+
+ +
+

Example:

+
-
mouse_warping none
-
+
mouse_warping none
+ +
-

4.24. Popups during fullscreen mode

-

When you are in fullscreen mode, some applications still open popup windows +

Popups during fullscreen mode

+
+

When you are in fullscreen mode, some applications still open popup windows (take Xpdf for example). This is because these applications might not be aware that they are in fullscreen mode (they do not check the corresponding hint). -There are three things which are possible to do in this situation:

-
    +There are three things which are possible to do in this situation:

    +
+
+
  1. -

    -Display the popup if it belongs to the fullscreen application only. This is - the default and should be reasonable behavior for most users. -

    +

    Display the popup if it belongs to the fullscreen application only. This is +the default and should be reasonable behavior for most users.

  2. -

    -Just ignore the popup (don’t map it). This won’t interrupt you while you are - in fullscreen. However, some apps might react badly to this (deadlock until - you go out of fullscreen). -

    +

    Just ignore the popup (don’t map it). This won’t interrupt you while you are +in fullscreen. However, some apps might react badly to this (deadlock until +you go out of fullscreen).

  3. -

    -Leave fullscreen mode. -

    +

    Leave fullscreen mode.

  4. -
-

Syntax:

+ +
+
+

Syntax:

+
-
popup_during_fullscreen smart|ignore|leave_fullscreen
-
-

Example:

+
popup_during_fullscreen smart|ignore|leave_fullscreen
+
+ +
+

Example:

+
-
popup_during_fullscreen smart
-
+
popup_during_fullscreen smart
+ +
-

4.25. Focus wrapping

-

By default, when in a container with several windows or child containers, the +

Focus wrapping

+
+

By default, when in a container with several windows or child containers, the opposite window will be focused when trying to move the focus over the edge of a container (and there are no other containers in that direction) — the focus -wraps.

-

If desired, you can disable this behavior by setting the focus_wrapping -configuration directive to the value no.

-

When enabled, focus wrapping does not occur by default if there is another +wraps.

+
+
+

If desired, you can disable this behavior by setting the focus_wrapping +configuration directive to the value no.

+
+
+

When enabled, focus wrapping does not occur by default if there is another window or container in the specified direction, and focus will instead be set on that window or container. This is the default behavior so you can navigate -to all your windows without having to use focus parent.

-

If you want the focus to always wrap and you are aware of using focus -parent to switch to different containers, you can instead set focus_wrapping -to the value force.

-

To restrict focus inside the current workspace set focus_wrapping to the -value workspace. You will need to use focus parent until a workspace is +to all your windows without having to use focus parent.

+
+
+

If you want the focus to always wrap and you are aware of using focus +parent to switch to different containers, you can instead set focus_wrapping +to the value force.

+
+
+

To restrict focus inside the current workspace set focus_wrapping to the +value workspace. You will need to use focus parent until a workspace is selected to switch to a different workspace using the focus commands (the -workspace command will still work as expected).

-

Syntax:

+workspace command will still work as expected).

+
+
+

Syntax:

+
-
focus_wrapping yes|no|force|workspace
+
focus_wrapping yes|no|force|workspace
 
 # Legacy syntax, equivalent to "focus_wrapping force"
-force_focus_wrapping yes
-
-

Examples:

+force_focus_wrapping yes +
+ +
+

Examples:

+
-
# Disable focus wrapping
+
# Disable focus wrapping
 focus_wrapping no
 
 # Force focus wrapping
-focus_wrapping force
-
+focus_wrapping force + +
-

4.26. Forcing Xinerama

-

As explained in-depth in https://i3wm.org/docs/multi-monitor.html, some X11 +

Forcing Xinerama

+
+

As explained in-depth in https://i3wm.org/docs/multi-monitor.html, some X11 video drivers (especially the nVidia binary driver) only provide support for Xinerama instead of RandR. In such a situation, i3 must be told to use the inferior Xinerama API explicitly and therefore don’t provide support for reconfiguring your screens on the fly (they are read only once on startup and -that’s it).

-

For people who cannot modify their ~/.xsession to add the ---force-xinerama commandline parameter, a configuration option is provided:

-

Syntax:

+that’s it).

+
+
+

For people who cannot modify their ~/.xsession to add the +--force-xinerama commandline parameter, a configuration option is provided:

+
+
+

Syntax:

+
-
force_xinerama yes|no
-
-

Example:

+
force_xinerama yes|no
+
+ +
+

Example:

+
-
force_xinerama yes
-
-

Also note that your output names are not descriptive (like HDMI1) when using -Xinerama, instead they are counted up, starting at 0: xinerama-0, xinerama-1, …

+
force_xinerama yes
+ + +
+

Also note that your output names are not descriptive (like HDMI1) when using +Xinerama, instead they are counted up, starting at 0: xinerama-0, xinerama-1, …

+
-

4.27. Automatic back-and-forth when switching to the current workspace

-

This configuration directive enables automatic workspace back_and_forth (see -[back_and_forth]) when switching to the workspace that is currently focused.

-

For instance: Assume you are on workspace "1: www" and switch to "2: IM" using +

Automatic back-and-forth when switching to the current workspace

+
+

This configuration directive enables automatic workspace back_and_forth (see +[back_and_forth]) when switching to the workspace that is currently focused.

+
+
+

For instance: Assume you are on workspace "1: www" and switch to "2: IM" using mod+2 because somebody sent you a message. You don’t need to remember where you -came from now, you can just press $mod+2 again to switch back to "1: www".

-

Syntax:

+came from now, you can just press $mod+2 again to switch back to "1: www".

+
+
+

Syntax:

+
-
workspace_auto_back_and_forth yes|no
-
-

Example:

+
workspace_auto_back_and_forth yes|no
+
+ +
+

Example:

+
-
workspace_auto_back_and_forth yes
-
+
workspace_auto_back_and_forth yes
+ +
-

4.28. Delaying urgency hint reset on workspace change

-

If an application on another workspace sets an urgency hint, switching to this +

Delaying urgency hint reset on workspace change

+
+

If an application on another workspace sets an urgency hint, switching to this workspace might lead to immediate focus of the application, which also means the -window decoration color would be immediately reset to client.focused. This +window decoration color would be immediately reset to client.focused. This might make it unnecessarily hard to tell which window originally raised the -event.

-

In order to prevent this, you can tell i3 to delay resetting the urgency state -by a certain time using the force_display_urgency_hint directive. Setting the -value to 0 disables this feature.

-

The default is 500ms.

-

Syntax:

+event.

+
+
+

In order to prevent this, you can tell i3 to delay resetting the urgency state +by a certain time using the force_display_urgency_hint directive. Setting the +value to 0 disables this feature.

+
+
+

The default is 500ms.

+
+
+

Syntax:

+
-
force_display_urgency_hint <timeout> ms
-
-

Example:

+
force_display_urgency_hint <timeout> ms
+
+ +
+

Example:

+
-
force_display_urgency_hint 500 ms
-
+
force_display_urgency_hint 500 ms
+ +
-

4.29. Focus on window activation

-

If a window is activated, e.g., via google-chrome www.google.com, it may request -to take focus. Since this might not be preferable, different reactions can be configured.

-

Note that this might not affect windows that are being opened. To prevent new windows -from being focused, see [no_focus].

-

Syntax:

+

Focus on window activation

+
+

If a window is activated, e.g., via google-chrome www.google.com, it may request +to take focus. Since this might not be preferable, different reactions can be configured.

+
+
+

Note that this might not affect windows that are being opened. To prevent new windows +from being focused, see Don’t focus window upon opening.

+
+
+

Syntax:

+
-
focus_on_window_activation smart|urgent|focus|none
-
-

The different modes will act as follows:

-
-
-smart -
+
focus_on_window_activation smart|urgent|focus|none
+
+
+
+

The different modes will act as follows:

+
+
+
+
smart
-

- This is the default behavior. If the window requesting focus is on an active - workspace, it will receive the focus. Otherwise, the urgency hint will be set. -

+

This is the default behavior. If the window requesting focus is on an active +workspace, it will receive the focus. Otherwise, the urgency hint will be set.

-
-urgent -
+
urgent
-

- The window will always be marked urgent, but the focus will not be stolen. -

+

The window will always be marked urgent, but the focus will not be stolen.

-
-focus -
+
focus
-

- The window will always be focused and not be marked urgent. -

+

The window will always be focused and not be marked urgent.

-
-none -
+
none
-

- The window will neither be focused, nor be marked urgent. -

+

The window will neither be focused, nor be marked urgent.

-
+ +
-

4.30. Drawing marks on window decoration

-

If activated, marks (see [vim_like_marks]) on windows are drawn in their window -decoration. However, any mark starting with an underscore in its name (_) will -not be drawn even if this option is activated.

-

The default for this option is yes.

-

Syntax:

+

Drawing marks on window decoration

+
+

If activated, marks (see VIM-like marks (mark/goto)) on windows are drawn in their window +decoration. However, any mark starting with an underscore in its name (_) will +not be drawn even if this option is activated.

+
+
+

The default for this option is yes.

+
+
+

Syntax:

+
-
show_marks yes|no
-
-

Example:

+
show_marks yes|no
+
+ +
+

Example:

+
-
show_marks yes
-
+
show_marks yes
+ +
-

4.31. Line continuation

-

Config files support line continuation, meaning when you end a line in a -backslash character (\), the line-break will be ignored by the parser. This +

Line continuation

+
+

Config files support line continuation, meaning when you end a line in a +backslash character (\), the line-break will be ignored by the parser. This feature can be used to create more readable configuration files. -Commented lines are not continued.

-

Examples:

+Commented lines are not continued.

+
+
+

Examples:

+
-
bindsym Mod1+f \
+
bindsym Mod1+f \
 fullscreen toggle
 
 # this line is not continued \
-bindsym Mod1+F fullscreen toggle
-
+bindsym Mod1+F fullscreen toggle +
+
-

5. Configuring i3bar

+

Configuring i3bar

-

The bar at the bottom of your monitor is drawn by a separate process called +

+

The bar at the bottom of your monitor is drawn by a separate process called i3bar. Having this part of "the i3 user interface" in a separate process has -several advantages:

-
    +several advantages:

    +
+
+
  1. -

    -It is a modular approach. If you don’t need a workspace bar at all, or if - you prefer a different one (dzen2, xmobar, maybe even gnome-panel?), you can - just remove the i3bar configuration and start your favorite bar instead. -

    +

    It is a modular approach. If you don’t need a workspace bar at all, or if +you prefer a different one (dzen2, xmobar, maybe even gnome-panel?), you can +just remove the i3bar configuration and start your favorite bar instead.

  2. -

    -It follows the UNIX philosophy of "Make each program do one thing well". - While i3 manages your windows well, i3bar is good at displaying a bar on - each monitor (unless you configure it otherwise). -

    +

    It follows the UNIX philosophy of "Make each program do one thing well". +While i3 manages your windows well, i3bar is good at displaying a bar on +each monitor (unless you configure it otherwise).

  3. -

    -It leads to two separate, clean codebases. If you want to understand i3, you - don’t need to bother with the details of i3bar and vice versa. -

    +

    It leads to two separate, clean codebases. If you want to understand i3, you +don’t need to bother with the details of i3bar and vice versa.

  4. -
-

That said, i3bar is configured in the same configuration file as i3. This is + +

+
+

That said, i3bar is configured in the same configuration file as i3. This is because it is tightly coupled with i3 (in contrary to i3lock or i3status which are useful for people using other window managers). Therefore, it makes no sense to use a different configuration place when we already have a good -configuration infrastructure in place.

-

Configuring your workspace bar starts with opening a bar block. You can have -multiple bar blocks to use different settings for different outputs (monitors):

-

Example:

+configuration infrastructure in place.

+
+
+

Configuring your workspace bar starts with opening a bar block. You can have +multiple bar blocks to use different settings for different outputs (monitors):

+
+
+

Example:

+
-
bar {
+
bar {
     status_command i3status
-}
-
+} +
+
-

5.1. i3bar command

-

By default i3 will just pass i3bar and let your shell handle the execution, -searching your $PATH for a correct version. -If you have a different i3bar somewhere or the binary is not in your $PATH you can -tell i3 what to execute.

-

The specified command will be passed to sh -c, so you can use globbing and -have to have correct quoting etc.

-

Syntax:

+

i3bar command

+
+

By default i3 will just pass i3bar and let your shell handle the execution, +searching your $PATH for a correct version. +If you have a different i3bar somewhere or the binary is not in your $PATH you can +tell i3 what to execute.

+
+
+

The specified command will be passed to sh -c, so you can use globbing and +have to have correct quoting etc.

+
+
+

Syntax:

+
-
i3bar_command <command>
-
-

Example:

+
i3bar_command <command>
+
+ +
+

Example:

+
-
bar {
+
bar {
     i3bar_command /home/user/bin/i3bar
-}
-
+} + +
-

5.2. Statusline command

-

i3bar can run a program and display every line of its stdout output on the +

Statusline command

+
+

i3bar can run a program and display every line of its stdout output on the right hand side of the bar. This is useful to display system information like -your current IP address, battery status or date/time.

-

The specified command will be passed to sh -c, so you can use globbing and +your current IP address, battery status or date/time.

+
+
+

The specified command will be passed to sh -c, so you can use globbing and have to have correct quoting etc. Note that for signal handling, depending on your shell (users of dash(1) are known to be affected), you have to use the shell’s exec command so that signals are passed to your program, not to the -shell.

-

Syntax:

+shell.

+
+
+

Syntax:

+
-
status_command <command>
-
-

Example:

+
status_command <command>
+
+ +
+

Example:

+
-
bar {
+
bar {
     status_command i3status --config ~/.i3status.conf
 
     # For dash(1) users who want signal handling to work:
     status_command exec ~/.bin/my_status_command
-}
-
- -
-

5.3. Display mode

-

You can either have i3bar be visible permanently at one edge of the screen -(dock mode) or make it show up when you press your modifier key (hide mode). -It is also possible to force i3bar to always stay hidden (invisible -mode). The modifier key can be configured using the modifier option.

-

The mode option can be changed during runtime through the bar mode command. -On reload the mode will be reverted to its configured value.

-

The hide mode maximizes screen space that can be used for actual windows. When -the bar is hidden, i3bar sends the SIGSTOP and SIGCONT signals to the -status_command process in order to conserve battery power. This feature can -be disabled by the status_command process by setting the appropriate values -in its JSON header message.

-

Invisible mode allows to permanently maximize screen space, as the bar is never +} +

+
+ +
+

Display mode

+
+

You can either have i3bar be visible permanently at one edge of the screen +(dock mode) or make it show up when you press your modifier key (hide mode). +It is also possible to force i3bar to always stay hidden (invisible +mode). The modifier key can be configured using the modifier option.

+
+
+

The mode option can be changed during runtime through the bar mode command. +On reload the mode will be reverted to its configured value.

+
+
+

The hide mode maximizes screen space that can be used for actual windows. When +the bar is hidden, i3bar sends the SIGSTOP and SIGCONT signals to the +status_command process in order to conserve battery power. This feature can +be disabled by the status_command process by setting the appropriate values +in its JSON header message.

+
+
+

Invisible mode allows to permanently maximize screen space, as the bar is never shown. Thus, you can configure i3bar to not disturb you by popping up because -of an urgency hint or because the modifier key is pressed.

-

In order to control whether i3bar is hidden or shown in hide mode, there exists +of an urgency hint or because the modifier key is pressed.

+
+
+

In order to control whether i3bar is hidden or shown in hide mode, there exists the hidden_state option, which has no effect in dock mode or invisible mode. It indicates the current hidden_state of the bar: (1) The bar acts like in normal hide mode, it is hidden and is only unhidden in case of urgency hints or by -pressing the modifier key (hide state), or (2) it is drawn on top of the -currently visible workspace (show state).

-

Like the mode, the hidden_state can also be controlled through i3, this can be -done by using the bar hidden_state command.

-

The default mode is dock mode; in hide mode, the default modifier is Mod4 (usually -the windows key). The default value for the hidden_state is hide.

-

Syntax:

+pressing the modifier key (hide state), or (2) it is drawn on top of the +currently visible workspace (show state).

+
+
+

Like the mode, the hidden_state can also be controlled through i3, this can be +done by using the bar hidden_state command.

+
+
+

The default mode is dock mode; in hide mode, the default modifier is Mod4 (usually +the windows key). The default value for the hidden_state is hide.

+
+
+

Syntax:

+
-
mode dock|hide|invisible
+
mode dock|hide|invisible
 hidden_state hide|show
-modifier <Modifier>|none
-
-

Example:

-
-
-
bar {
+modifier <Modifier>|none
+------------------------
+
+*Example*:
+----------------
+bar {
     mode hide
     hidden_state hide
     modifier Mod1
-}
-
-

Available modifiers are Mod1-Mod5, Shift, Control (see xmodmap(1)). You can -also use "none" if you don’t want any modifier to trigger this behavior.

- -
-

5.4. Mouse button commands

-

Specifies a command to run when a button was pressed on i3bar to override the +} +---------------- + +Available modifiers are Mod1-Mod5, Shift, Control (see +xmodmap(1)+). You can +also use "none" if you don't want any modifier to trigger this behavior. + +=== Mouse button commands + +Specifies a command to run when a button was pressed on i3bar to override the default behavior. This is useful, e.g., for disabling the scroll wheel action -or running scripts that implement custom behavior for these buttons.

-

A button is always named button<n>, where 1 to 5 are default buttons as follows and higher -numbers can be special buttons on devices offering more buttons:

-
-
-button1 -
-
-

+or running scripts that implement custom behavior for these buttons. + +A button is always named +button<n>+, where 1 to 5 are default buttons as follows and higher +numbers can be special buttons on devices offering more buttons: + +button1:: Left mouse button. -

-
-
-button2 -
-
-

+button2:: Middle mouse button. -

-
-
-button3 -
-
-

+button3:: Right mouse button. -

-
-
-button4 -
-
-

+button4:: Scroll wheel up. -

-
-
-button5 -
-
-

+button5:: Scroll wheel down. -

-
-
-button6 -
-
-

+button6:: Scroll wheel right. -

-
-
-button7 -
-
-

+button7:: Scroll wheel left. -

-
-
-

Please note that the old wheel_up_cmd and wheel_down_cmd commands are deprecated + + +Please note that the old +wheel_up_cmd+ and +wheel_down_cmd+ commands are deprecated and will be removed in a future release. We strongly recommend using the more general -bindsym with button4 and button5 instead.

-

Syntax:

-
-
-
bindsym [--release] button<n> <command>
-
-

Example:

-
-
-
bar {
++bindsym+ with +button4+ and +button5+ instead.
+
+*Syntax*:
+----------------------------
+bindsym [--release] button<n> <command>
+----------------------------
+
+*Example*:
+---------------------------------------------------------
+bar {
     # disable clicking on workspace buttons
     bindsym button1 nop
     # Take a screenshot by right clicking on the bar
     bindsym --release button3 exec --no-startup-id import /tmp/latest-screenshot.png
     # execute custom script when scrolling downwards
     bindsym button5 exec ~/.i3/scripts/custom_wheel_down
-}
-
-
-
-

5.5. Bar ID

-

Specifies the bar ID for the configured bar instance. If this option is missing, -the ID is set to bar-x, where x corresponds to the position of the embedding -bar block in the config file (bar-0, bar-1, …).

-

Syntax:

-
-
-
id <bar_id>
-
-

Example:

-
-
-
bar {
+}
+---------------------------------------------------------
+
+=== Bar ID
+
+Specifies the bar ID for the configured bar instance. If this option is missing,
+the ID is set to 'bar-x', where x corresponds to the position of the embedding
+bar block in the config file ('bar-0', 'bar-1', ...).
+
+*Syntax*:
+---------------------
+id <bar_id>
+---------------------
+
+*Example*:
+---------------------
+bar {
     id bar-1
-}
-
-
-
-

5.6. Position

-

This option determines in which edge of the screen i3bar should show up.

-

The default is bottom.

-

Syntax:

-
-
-
position top|bottom
-
-

Example:

-
-
-
bar {
+}
+---------------------
+
+[[i3bar_position]]
+=== Position
+
+This option determines in which edge of the screen i3bar should show up.
+
+The default is bottom.
+
+*Syntax*:
+-------------------
+position top|bottom
+-------------------
+
+*Example*:
+---------------------
+bar {
     position top
-}
-
-
-
-

5.7. Output(s)

-

You can restrict i3bar to one or more outputs (monitors). The default is to +} +--------------------- + +=== Output(s) + +You can restrict i3bar to one or more outputs (monitors). The default is to handle all outputs. Restricting the outputs is useful for using different -options for different outputs by using multiple bar blocks.

-

To make a particular i3bar instance handle multiple outputs, specify the output -directive multiple times.

-

These output names have a special meaning:

-
-
-primary -
-
-

+options for different outputs by using multiple 'bar' blocks. + +To make a particular i3bar instance handle multiple outputs, specify the output +directive multiple times. + +These output names have a special meaning: + +primary:: Selects the output that is configured as primary in the X server. -

-
-
-nonprimary -
-
-

+nonprimary:: Selects every output that is not configured as primary in the X server. -

-
-
-

Syntax:

-
-
-
output primary|nonprimary|<output>
-
-

Example:

-
-
-
# big monitor: everything
+
+*Syntax*:
+---------------
+output primary|nonprimary|<output>
+---------------
+
+*Example*:
+-------------------------------
+big monitor: everything
 bar {
     # The display is connected either via HDMI or via DisplayPort
     output HDMI2
@@ -1644,7 +2136,7 @@ 

5.7. Output(s)

status_command i3status } -# laptop monitor: bright colors and i3status with less modules. +laptop monitor: bright colors and i3status with less modules. bar { output LVDS1 status_command i3status --config ~/.i3status-small.conf @@ -1654,324 +2146,366 @@

5.7. Output(s)

} } -# show bar on the primary monitor and on HDMI2 +show bar on the primary monitor and on HDMI2 bar { output primary output HDMI2 status_command i3status -}
-
-

Note that you might not have a primary output configured yet. To do so, run:

+} + +------------------------------- +Note that you might not have a primary output configured yet. To do so, run: +
+ +
+

xrandr --output <output> --primary

+
-
xrandr --output <output> --primary
-
- -
-

5.8. Tray output

-

i3bar by default provides a system tray area where programs such as -NetworkManager, VLC, Pidgin, etc. can place little icons.

-

You can configure on which output (monitor) the icons should be displayed or -you can turn off the functionality entirely.

-

You can use multiple tray_output directives in your config to specify a list +

=== Tray output
+
+i3bar by default provides a system tray area where programs such as
+NetworkManager, VLC, Pidgin, etc. can place little icons.
+
+You can configure on which output (monitor) the icons should be displayed or
+you can turn off the functionality entirely.
+
+You can use multiple +tray_output+ directives in your config to specify a list
 of outputs on which you want the tray to appear. The first available output in
 that list as defined by the order of the directives will be used for the tray
-output.

-

Syntax:

-
-
-
tray_output none|primary|<output>
-
-

Example:

-
-
-
# disable system tray
+output.
+
+*Syntax*:
+---------------------------------
+tray_output none|primary|<output>
+---------------------------------
+
+*Example*:
+
+
+
+

disable system tray bar { tray_output none -} - -# show tray icons on the primary monitor +}

+
+
+

show tray icons on the primary monitor bar { tray_output primary -} - -# show tray icons on the big monitor +}

+
+
+

show tray icons on the big monitor bar { tray_output HDMI2 -} -

-

Note that you might not have a primary output configured yet. To do so, run:

-
-
-
xrandr --output <output> --primary
-
-

Note that when you use multiple bar configuration blocks, either specify -tray_output primary in all of them or explicitly specify tray_output none -in bars which should not display the tray, otherwise the different instances -might race each other in trying to display tray icons.

+}

-
-

5.9. Tray padding

-

The tray is shown on the right-hand side of the bar. By default, a padding of 2 -pixels is used for the upper, lower and right-hand side of the tray area and -between the individual icons.

-

Syntax:

-
tray_padding <px> [px]
-
-

Example:

+
Note that you might not have a primary output configured yet. To do so, run:
+
+ +
+

xrandr --output <output> --primary

+
-
# Obey Fitts's law
-tray_padding 0
-
+
Note that when you use multiple bar configuration blocks, either specify
+`tray_output primary` in all of them or explicitly specify `tray_output none`
+in bars which should not display the tray, otherwise the different instances
+might race each other in trying to display tray icons.
+
+=== Tray padding
+
+The tray is shown on the right-hand side of the bar. By default, a padding of 2
+pixels is used for the upper, lower and right-hand side of the tray area and
+between the individual icons.
+
+*Syntax*:
+ + +
+

tray_padding <px> [px]

-
-

5.10. Font

-

Specifies the font to be used in the bar. See [fonts].

-

Syntax:

-
font <font>
-
-

Example:

+
*Example*:
+
+ +
+

Obey Fitts’s law +tray_padding 0

+
-
bar {
+
=== Font
+
+Specifies the font to be used in the bar. See <<fonts>>.
+
+*Syntax*:
+---------------------
+font <font>
+---------------------
+
+*Example*:
+--------------------------------------------------------------
+bar {
     font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
     font pango:DejaVu Sans Mono 10
-}
-
+} +-------------------------------------------------------------- + +=== Custom separator symbol + +Specifies a custom symbol to be used for the separator as opposed to the vertical, +one pixel thick separator. + +*Syntax*: + + + + + +
+

separator_symbol <symbol>

+
+
+

Example:

-
-

5.11. Custom separator symbol

-

Specifies a custom symbol to be used for the separator as opposed to the vertical, -one pixel thick separator.

-

Syntax:

-
-
-
separator_symbol <symbol>
-
-

Example:

-
bar {
+
bar {
     separator_symbol ":|:"
-}
-
+} +
-

5.12. Workspace buttons

-

Specifies whether workspace buttons should be shown or not. This is useful if -you want to display a statusline-only bar containing additional information.

-

The default is to show workspace buttons.

-

Syntax:

+

Workspace buttons

+
+

Specifies whether workspace buttons should be shown or not. This is useful if +you want to display a statusline-only bar containing additional information.

+
+
+

The default is to show workspace buttons.

+
+
+

Syntax:

+
-
workspace_buttons yes|no
-
-

Example:

+
workspace_buttons yes|no
+
+
+
+

Example:

+
-
bar {
+
bar {
     workspace_buttons no
-}
-
+} + +
-

5.13. Minimal width for workspace buttons

-

By default, the width a workspace button is determined by the width of the text +

Minimal width for workspace buttons

+
+

By default, the width a workspace button is determined by the width of the text showing the workspace name. If the name is too short (say, one letter), then the -workspace button might look too small.

-

This option specifies the minimum width for workspace buttons. If the name of +workspace button might look too small.

+
+
+

This option specifies the minimum width for workspace buttons. If the name of a workspace is too short to cover the button, an additional padding is added on -both sides of the button so that the text is centered.

-

The default value of zero means that no additional padding is added.

-

The setting also applies to the current binding mode indicator.

-

Note that the specified pixels refer to logical pixels, which might translate -into more pixels on HiDPI displays.

-

Syntax:

+both sides of the button so that the text is centered.

+
+
+

The default value of zero means that no additional padding is added.

+
+
+

The setting also applies to the current binding mode indicator.

+
+
+

Note that the specified pixels refer to logical pixels, which might translate +into more pixels on HiDPI displays.

+
+
+

Syntax:

+
-
workspace_min_width <px> [px]
-
-

Example:

+
workspace_min_width <px> [px]
+
+ +
+

Example:

+
-
bar {
+
bar {
     workspace_min_width 40
-}
-
+} + +
-

5.14. Strip workspace numbers/name

-

Specifies whether workspace numbers should be displayed within the workspace +

Strip workspace numbers/name

+
+

Specifies whether workspace numbers should be displayed within the workspace buttons. This is useful if you want to have a named workspace that stays in -order on the bar according to its number without displaying the number prefix.

-

When strip_workspace_numbers is set to yes, any workspace that has a name of +order on the bar according to its number without displaying the number prefix.

+
+
+

When strip_workspace_numbers is set to yes, any workspace that has a name of the form "[n][:][NAME]" will display only the name. You could use this, for instance, to display Roman numerals rather than digits by naming your -workspaces to "1:I", "2:II", "3:III", "4:IV", …

-

When strip_workspace_name is set to yes, any workspace that has a name of -the form "[n][:][NAME]" will display only the number.

-

The default is to display the full name within the workspace button. Be aware -that the colon in the workspace name is optional, so [n][NAME] will also -have the workspace name and number stripped correctly.

-

Syntax:

+workspaces to "1:I", "2:II", "3:III", "4:IV", …​

+
+
+

When strip_workspace_name is set to yes, any workspace that has a name of +the form "[n][:][NAME]" will display only the number.

+
+
+

The default is to display the full name within the workspace button. Be aware +that the colon in the workspace name is optional, so [n][NAME] will also +have the workspace name and number stripped correctly.

+
+
+

Syntax:

+
-
strip_workspace_numbers yes|no
-strip_workspace_name yes|no
-
-

Example:

+
strip_workspace_numbers yes|no
+strip_workspace_name yes|no
+
+ +
+

Example:

+
-
bar {
+
bar {
     strip_workspace_numbers yes
-}
-
+} + +
-

5.15. Binding Mode indicator

-

Specifies whether the current binding mode indicator should be shown or not. +

Binding Mode indicator

+
+

Specifies whether the current binding mode indicator should be shown or not. This is useful if you want to hide the workspace buttons but still be able -to see the current binding mode indicator. See [binding_modes] to learn what -modes are and how to use them.

-

The default is to show the mode indicator.

-

Syntax:

+to see the current binding mode indicator. See Binding modes to learn what +modes are and how to use them.

+
+
+

The default is to show the mode indicator.

+
+
+

Syntax:

+
-
binding_mode_indicator yes|no
-
-

Example:

+
binding_mode_indicator yes|no
+
+ +
+

Example:

+
-
bar {
+
bar {
     binding_mode_indicator no
-}
-
+} + +
-

5.16. Colors

-

As with i3, colors are in HTML hex format (#rrggbb). The following colors can -be configured at the moment:

-
-
-background -
+

Colors

+
+

As with i3, colors are in HTML hex format (#rrggbb). The following colors can +be configured at the moment:

+
+
+
+
background
-

- Background color of the bar. -

+

Background color of the bar.

-
-statusline -
+
statusline
-

- Text color to be used for the statusline. -

+

Text color to be used for the statusline.

-
-separator -
+
separator
-

- Text color to be used for the separator. -

+

Text color to be used for the separator.

-
-focused_background -
+
focused_background
-

- Background color of the bar on the currently focused monitor output. If - not used, the color will be taken from background. -

+

Background color of the bar on the currently focused monitor output. If +not used, the color will be taken from background.

-
-focused_statusline -
+
focused_statusline
-

- Text color to be used for the statusline on the currently focused - monitor output. If not used, the color will be taken from statusline. -

+

Text color to be used for the statusline on the currently focused +monitor output. If not used, the color will be taken from statusline.

-
-focused_separator -
+
focused_separator
-

- Text color to be used for the separator on the currently focused - monitor output. If not used, the color will be taken from separator. -

+

Text color to be used for the separator on the currently focused +monitor output. If not used, the color will be taken from separator.

-
-focused_workspace -
+
focused_workspace
-

- Border, background and text color for a workspace button when the workspace - has focus. -

+

Border, background and text color for a workspace button when the workspace +has focus.

-
-active_workspace -
+
active_workspace
-

- Border, background and text color for a workspace button when the workspace - is active (visible) on some output, but the focus is on another one. - You can only tell this apart from the focused workspace when you are - using multiple monitors. -

+

Border, background and text color for a workspace button when the workspace +is active (visible) on some output, but the focus is on another one. +You can only tell this apart from the focused workspace when you are +using multiple monitors.

-
-inactive_workspace -
+
inactive_workspace
-

- Border, background and text color for a workspace button when the workspace - does not have focus and is not active (visible) on any output. This - will be the case for most workspaces. -

+

Border, background and text color for a workspace button when the workspace +does not have focus and is not active (visible) on any output. This +will be the case for most workspaces.

-
-urgent_workspace -
+
urgent_workspace
-

- Border, background and text color for a workspace button when the workspace - contains a window with the urgency hint set. -

+

Border, background and text color for a workspace button when the workspace +contains a window with the urgency hint set.

-
-binding_mode -
+
binding_mode
-

- Border, background and text color for the binding mode indicator. If not used, - the colors will be taken from urgent_workspace. -

+

Border, background and text color for the binding mode indicator. If not used, +the colors will be taken from urgent_workspace.

-
-

Syntax:

+
+
+
+

Syntax:

+
-
colors {
+
colors {
     background <color>
     statusline <color>
     separator <color>
 
     <colorclass> <border> <background> <text>
-}
-
-

Example (default colors):

+} +
+ +
+

Example (default colors):

+
-
bar {
+
bar {
     colors {
         background #000000
         statusline #ffffff
@@ -1983,61 +2517,87 @@ 

5.16. Colors

urgent_workspace #2f343a #900000 #ffffff binding_mode #2f343a #900000 #ffffff } -}
-
+} + +
-

5.17. Transparency

-

i3bar can support transparency by passing the --transparency flag in the -configuration:

-

Syntax:

+

Transparency

+
+

i3bar can support transparency by passing the --transparency flag in the +configuration:

+
+
+

Syntax:

+
-
bar {
+
bar {
     i3bar_command i3bar --transparency
-}
-
-

In the i3bar color configuration and i3bar status block color attribute you can +} +

+
+
+

In the i3bar color configuration and i3bar status block color attribute you can then use colors in the RGBA format, i.e. the last two (hexadecimal) digits -specify the opacity. For example, #00000000 will be completely transparent, -while #000000FF will be a fully opaque black (the same as #000000).

-

Please note that due to the way the tray specification works, enabling this -flag will cause all tray icons to have a transparent background.

+specify the opacity. For example, #00000000 will be completely transparent, +while #000000FF will be a fully opaque black (the same as #000000).

+ +
+

Please note that due to the way the tray specification works, enabling this +flag will cause all tray icons to have a transparent background.

+
-

6. List of commands

+

List of commands

-

Commands are what you bind to specific keypresses. You can also issue commands +

+

Commands are what you bind to specific keypresses. You can also issue commands at runtime without pressing a key by using the IPC interface. An easy way to -do this is to use the i3-msg utility:

-

Example:

+do this is to use the i3-msg utility:

+
+
+

Example:

+
-
# execute this on your shell to make the current container borderless
-i3-msg border none
-
-

Commands can be chained by using ; (a semicolon). So, to move a window to a +

# execute this on your shell to make the current container borderless
+i3-msg border none
+
+
+
+

Commands can be chained by using ; (a semicolon). So, to move a window to a specific workspace and immediately switch to that workspace, you can configure -the following keybinding:

-

Example:

+the following keybinding:

+
+
+

Example:

+
-
bindsym $mod+x move container to workspace 3; workspace 3
-
-

Furthermore, you can change the scope of a command - that is, which containers +

bindsym $mod+x move container to workspace 3; workspace 3
+
+ +
+

Furthermore, you can change the scope of a command - that is, which containers should be affected by that command, by using various criteria. The criteria are specified before any command in a pair of square brackets and are separated -by space.

-

When using multiple commands, separate them by using a , (a comma) instead of +by space.

+
+
+

When using multiple commands, separate them by using a , (a comma) instead of a semicolon. Criteria apply only until the next semicolon, so if you use a semicolon to separate commands, only the first one will be executed for the -matched window(s).

-

Example:

+matched window(s).

+ +
+

Example:

+
-
# if you want to kill all windows which have the class Firefox, use:
+
# if you want to kill all windows which have the class Firefox, use:
 bindsym $mod+x [class="Firefox"] kill
 
 # same thing, but case-insensitive
@@ -2050,253 +2610,249 @@ 

6. List of commands

for_window [class="^evil-app$"] floating enable, move container to workspace 4 # move all floating windows to the scratchpad -bindsym $mod+x [floating] move scratchpad
-
-

The criteria which are currently implemented are:

-
-
-class -
+bindsym $mod+x [floating] move scratchpad +
+ +
+

The criteria which are currently implemented are:

+
+
+
+
class
-

- Compares the window class (the second part of WM_CLASS). Use the - special value __focused__ to match all windows having the same window - class as the currently focused window. -

+

Compares the window class (the second part of WM_CLASS). Use the +special value _\_focused__ to match all windows having the same window +class as the currently focused window.

-
-instance -
+
instance
-

- Compares the window instance (the first part of WM_CLASS). Use the - special value __focused__ to match all windows having the same window - instance as the currently focused window. -

+

Compares the window instance (the first part of WM_CLASS). Use the +special value _\_focused__ to match all windows having the same window +instance as the currently focused window.

-
-window_role -
+
window_role
-

- Compares the window role (WM_WINDOW_ROLE). Use the special value - __focused__ to match all windows having the same window role as the - currently focused window. -

+

Compares the window role (WM_WINDOW_ROLE). Use the special value +_\_focused__ to match all windows having the same window role as the +currently focused window.

-
-window_type -
+
window_type
-

- Compare the window type (_NET_WM_WINDOW_TYPE). Possible values are - normal, dialog, utility, toolbar, splash, menu, dropdown_menu, - popup_menu, tooltip and notification. -

+

Compare the window type (_NET_WM_WINDOW_TYPE). Possible values are +normal, dialog, utility, toolbar, splash, menu, dropdown_menu, +popup_menu, tooltip and notification.

-
-id -
+
id
-

- Compares the X11 window ID, which you can get via xwininfo for example. -

+

Compares the X11 window ID, which you can get via xwininfo for example.

-
-title -
+
title
-

- Compares the X11 window title (_NET_WM_NAME or WM_NAME as fallback). - Use the special value __focused__ to match all windows having the - same window title as the currently focused window. -

+

Compares the X11 window title (_NET_WM_NAME or WM_NAME as fallback). +Use the special value \__focused__ to match all windows having the +same window title as the currently focused window.

-
-urgent -
+
urgent
-

- Compares the urgent state of the window. Can be "latest" or "oldest". - Matches the latest or oldest urgent window, respectively. - (The following aliases are also available: newest, last, recent, first) -

+

Compares the urgent state of the window. Can be "latest" or "oldest". +Matches the latest or oldest urgent window, respectively. +(The following aliases are also available: newest, last, recent, first)

-
-workspace -
+
workspace
-

- Compares the workspace name of the workspace the window belongs to. Use - the special value __focused__ to match all windows in the currently - focused workspace. -

+

Compares the workspace name of the workspace the window belongs to. Use +the special value _\_focused__ to match all windows in the currently +focused workspace.

-
-con_mark -
+
con_mark
-

- Compares the marks set for this container, see [vim_like_marks]. A - match is made if any of the container’s marks matches the specified - mark. -

+

Compares the marks set for this container, see VIM-like marks (mark/goto). A +match is made if any of the container’s marks matches the specified +mark.

-
-con_id -
+
con_id
-

- Compares the i3-internal container ID, which you can get via the IPC - interface. Handy for scripting. Use the special value __focused__ - to match only the currently focused window. -

+

Compares the i3-internal container ID, which you can get via the IPC +interface. Handy for scripting. Use the special value _\_focused__ +to match only the currently focused window.

-
-floating -
+
floating
-

- Only matches floating windows. This criterion requires no value. -

+

Only matches floating windows. This criterion requires no value.

-
-floating_from -
+
floating_from
-

- Like floating but this criterion takes two possible values: "auto" - and "user". With "auto", only windows that were automatically opened as - floating are matched. With "user", only windows that the user made - floating are matched. -

+

Like floating but this criterion takes two possible values: "auto" +and "user". With "auto", only windows that were automatically opened as +floating are matched. With "user", only windows that the user made +floating are matched.

-
-tiling -
+
tiling
-

- Only matches tiling windows. This criterion requires no value. -

+

Only matches tiling windows. This criterion requires no value.

-
-tiling_from -
+
tiling_from
-

- Like tiling but this criterion takes two possible values: "auto" and - "user". With "auto", only windows that were automatically opened as - tiling are matched. With "user", only windows that the user made tiling - are matched. -

+

Like tiling but this criterion takes two possible values: "auto" and +"user". With "auto", only windows that were automatically opened as +tiling are matched. With "user", only windows that the user made tiling +are matched.

-
-

The criteria class, instance, role, title, workspace and mark are -actually regular expressions (PCRE). See pcresyntax(3) or perldoc perlre for -information on how to use them.

+ + +
+

The criteria class, instance, role, title, workspace and mark are +actually regular expressions (PCRE). See pcresyntax(3) or perldoc perlre for +information on how to use them.

+
-

6.1. Executing applications (exec)

-

What good is a window manager if you can’t actually start any applications? +

Executing applications (exec)

+
+

What good is a window manager if you can’t actually start any applications? The exec command starts an application by passing the command you specify to a shell. This implies that you can use globbing (wildcards) and programs will be -searched in your $PATH.

-

See [command_chaining] for details on the special meaning of ; (semicolon) -and , (comma): they chain commands together in i3, so you need to use quoted -strings (as shown in [exec_quoting]) if they appear in your command.

-

Syntax:

+searched in your $PATH.

+
+
+

See [command_chaining] for details on the special meaning of ; (semicolon) +and , (comma): they chain commands together in i3, so you need to use quoted +strings (as shown in [exec_quoting]) if they appear in your command.

+
+
+

Syntax:

+
-
exec [--no-startup-id] <command>
-
-

Example:

+
exec [--no-startup-id] <command>
+
+ +
+

Example:

+
-
# Start the GIMP
+
# Start the GIMP
 bindsym $mod+g exec gimp
 
 # Start the terminal emulator urxvt which is not yet startup-notification-aware
-bindsym $mod+Return exec --no-startup-id urxvt
-
-

The --no-startup-id parameter disables startup-notification support for this +bindsym $mod+Return exec --no-startup-id urxvt +

+ +
+

The --no-startup-id parameter disables startup-notification support for this particular exec command. With startup-notification, i3 can make sure that a window appears on the workspace on which you used the exec command. Also, it -will change the X11 cursor to watch (a clock) while the application is +will change the X11 cursor to watch (a clock) while the application is launching. So, if an application is not startup-notification aware (most GTK and Qt using applications seem to be, though), you will end up with a watch -cursor for 60 seconds.

-

If the command to be executed contains a ; (semicolon) and/or a , (comma), +cursor for 60 seconds.

+
+
+

If the command to be executed contains a ; (semicolon) and/or a , (comma), the entire command must be quoted. For example, to have a keybinding for the -shell command notify-send Hello, i3, you would add an entry to your -configuration file like this:

-

Example:

+shell command notify-send Hello, i3, you would add an entry to your +configuration file like this:

+ +
+

Example:

+
-
# Execute a command with a comma in it
-bindsym $mod+p exec "notify-send Hello, i3"
-
-

If however a command with a comma and/or semicolon itself requires quotes, you -must escape the internal quotation marks with double backslashes, like this:

-

Example:

+
# Execute a command with a comma in it
+bindsym $mod+p exec "notify-send Hello, i3"
+ + +
+

If however a command with a comma and/or semicolon itself requires quotes, you +must escape the internal quotation marks with double backslashes, like this:

+
+
+

Example:

+
-
# Execute a command with a comma, semicolon and internal quotes
-bindsym $mod+p exec "notify-send \\"Hello, i3; from $USER\\""
-
+
# Execute a command with a comma, semicolon and internal quotes
+bindsym $mod+p exec "notify-send \\"Hello, i3; from $USER\\""
+ +
-

6.2. Splitting containers

-

The split command makes the current window a split container. Split containers +

Splitting containers

+
+

The split command makes the current window a split container. Split containers can contain multiple windows. Depending on the layout of the split container, new windows get placed to the right of the current one (splith) or new windows -get placed below the current one (splitv).

-

If you apply this command to a split container with the same orientation, +get placed below the current one (splitv).

+
+
+

If you apply this command to a split container with the same orientation, nothing will happen. If you use a different orientation, the split container’s orientation will be changed (if it does not have more than one window). -The toggle option will toggle the orientation of the split container if it +The toggle option will toggle the orientation of the split container if it contains a single window. Otherwise it makes the current window a split container with opposite orientation compared to the parent container. -Use layout toggle split to change the layout of any split container from +Use layout toggle split to change the layout of any split container from splitv to splith or vice-versa. You can also define a custom sequence of layouts -to cycle through with layout toggle, see [manipulating_layout].

-

Syntax:

+to cycle through with layout toggle, see Manipulating layout.

+
+
+

Syntax:

+
-
split vertical|horizontal|toggle
-
-

Example:

+
split vertical|horizontal|toggle
+
+ +
+

Example:

+
-
bindsym $mod+v split vertical
+
bindsym $mod+v split vertical
 bindsym $mod+h split horizontal
-bindsym $mod+t split toggle
-
+bindsym $mod+t split toggle + +
-

6.3. Manipulating layout

-

Use layout toggle split, layout stacking, layout tabbed, layout splitv -or layout splith to change the current container layout to splith/splitv, -stacking, tabbed layout, splitv or splith, respectively.

-

Specify up to four layouts after layout toggle to cycle through them. Every +

Manipulating layout

+
+

Use layout toggle split, layout stacking, layout tabbed, layout splitv +or layout splith to change the current container layout to splith/splitv, +stacking, tabbed layout, splitv or splith, respectively.

+
+
+

Specify up to four layouts after layout toggle to cycle through them. Every time the command is executed, the layout specified after the currently active one will be applied. If the currently active layout is not in the list, the -first layout in the list will be activated.

-

To make the current window (!) fullscreen, use fullscreen enable (or -fullscreen enable global for the global mode), to leave either fullscreen -mode use fullscreen disable, and to toggle between these two states use -fullscreen toggle (or fullscreen toggle global).

-

Likewise, to make the current window floating (or tiling again) use floating -enable respectively floating disable (or floating toggle):

-

Syntax:

+first layout in the list will be activated.

+
+
+

To make the current window (!) fullscreen, use fullscreen enable (or +fullscreen enable global for the global mode), to leave either fullscreen +mode use fullscreen disable, and to toggle between these two states use +fullscreen toggle (or fullscreen toggle global).

+
+
+

Likewise, to make the current window floating (or tiling again) use floating +enable respectively floating disable (or floating toggle):

+
+
+

Syntax:

+
-
layout default|tabbed|stacking|splitv|splith
+
layout default|tabbed|stacking|splitv|splith
 layout toggle [split|all]
-layout toggle [split|tabbed|stacking|splitv|splith] [split|tabbed|stacking|splitv|splith]…
-
-

Examples:

+layout toggle [split|tabbed|stacking|splitv|splith] [split|tabbed|stacking|splitv|splith]… +
+ +
+

Examples:

+
-
bindsym $mod+s layout stacking
+
bindsym $mod+s layout stacking
 bindsym $mod+l layout toggle split
 bindsym $mod+w layout tabbed
 
@@ -2319,107 +2875,81 @@ 

6.3. Manipulating layout

bindsym $mod+f fullscreen toggle # Toggle floating/tiling -bindsym $mod+t floating toggle
-
+bindsym $mod+t floating toggle + +
-

6.4. Focusing containers

-

To change focus, you can use the focus command. The following options are -available:

-
-
-<criteria> -
+

Focusing containers

+
+

To change focus, you can use the focus command. The following options are +available:

+
+
+
+
<criteria>
-

- Sets focus to the container that matches the specified criteria. - See [command_criteria]. -

+

Sets focus to the container that matches the specified criteria. +See [command_criteria].

-
-left|right|up|down -
+
left|right|up|down
-

- Sets focus to the nearest container in the given direction. -

+

Sets focus to the nearest container in the given direction.

-
-parent -
+
parent
-

- Sets focus to the parent container of the current container. -

+

Sets focus to the parent container of the current container.

-
-child -
+
child
-

- The opposite of focus parent, sets the focus to the last focused - child container. -

+

The opposite of focus parent, sets the focus to the last focused +child container.

-
-next|prev -
+
next|prev
-

- Automatically sets focus to the adjacent container. If sibling is - specified, the command will focus the exact sibling container, - including non-leaf containers like split containers. Otherwise, it is - an automatic version of focus left|right|up|down in the orientation - of the parent container. -

+

Automatically sets focus to the adjacent container. If sibling is +specified, the command will focus the exact sibling container, +including non-leaf containers like split containers. Otherwise, it is +an automatic version of focus left|right|up|down in the orientation +of the parent container.

-
-floating -
+
floating
-

- Sets focus to the last focused floating container. -

+

Sets focus to the last focused floating container.

-
-tiling -
+
tiling
-

- Sets focus to the last focused tiling container. -

+

Sets focus to the last focused tiling container.

-
-mode_toggle -
+
mode_toggle
-

- Toggles between floating/tiling containers. -

+

Toggles between floating/tiling containers.

-
-output -
+
output
-

- Followed by a direction or an output name, this will focus the - corresponding output. -

+

Followed by a direction or an output name, this will focus the +corresponding output.

-
-

Syntax:

+
+
+
+

Syntax:

+
-
<criteria> focus
+
<criteria> focus
 focus left|right|down|up
 focus parent|child|floating|tiling|mode_toggle
 focus next|prev [sibling]
-focus output left|right|up|down|primary|<output>
-
-

Examples:

+focus output left|right|up|down|primary|<output> +
+ +
+

Examples:

+
-
# Focus firefox
+
# Focus firefox
 bindsym $mod+F1 [class="Firefox"] focus
 
 # Focus container on the left, bottom, top, right
@@ -2441,21 +2971,29 @@ 

6.4. Focusing containers

bindsym $mod+x focus output HDMI-2 # Focus the primary output -bindsym $mod+x focus output primary
-
-

Note that you might not have a primary output configured yet. To do so, run:

+bindsym $mod+x focus output primary + + +
+

Note that you might not have a primary output configured yet. To do so, run:

+
-
xrandr --output <output> --primary
-
+
xrandr --output <output> --primary
+ +
-

6.5. Moving containers

-

Use the move command to move a container.

-

Syntax:

+

Moving containers

+
+

Use the move command to move a container.

+
+
+

Syntax:

+
-
# Moves the container into the given direction.
+
# Moves the container into the given direction.
 # The optional pixel argument specifies how far the
 # container should be moved if it is floating and
 # defaults to 10 pixels. The optional ppt argument
@@ -2475,12 +3013,15 @@ 

6.5. Moving containers

# Moves the container to the current position of the # mouse cursor. Only affects floating containers. -move position mouse
-
-

Examples:

+move position mouse +
+ +
+

Examples:

+
-
# Move container to the left, bottom, top, right
+
# Move container to the left, bottom, top, right
 bindsym $mod+j move left
 bindsym $mod+k move down
 bindsym $mod+l move up
@@ -2494,123 +3035,155 @@ 

6.5. Moving containers

bindsym $mod+c move absolute position center # Move container to the current position of the cursor -bindsym $mod+m move position mouse
-
+bindsym $mod+m move position mouse + +
-

6.6. Swapping containers

-

Two containers can be swapped (i.e., move to each other’s position) by using -the swap command. They will assume the position and geometry of the container -they are swapped with.

-

The first container to participate in the swapping can be selected through the +

Swapping containers

+
+

Two containers can be swapped (i.e., move to each other’s position) by using +the swap command. They will assume the position and geometry of the container +they are swapped with.

+
+
+

The first container to participate in the swapping can be selected through the normal command criteria process with the focused window being the usual fallback if no criteria are specified. The second container can be selected -using one of the following methods:

-
-
-id -
+using one of the following methods:

+
+
+
+
id
-

-The X11 window ID of a client window. -

+

The X11 window ID of a client window.

-
-con_id -
+
con_id
-

-The i3 container ID of a container. -

+

The i3 container ID of a container.

-
-mark -
+
mark
-

-A container with the specified mark, see [vim_like_marks]. -

+

A container with the specified mark, see VIM-like marks (mark/goto).

-
-

Note that swapping does not work with all containers. Most notably, swapping -containers that have a parent-child relationship to one another does not work.

-

Syntax:

+ +
+
+

Note that swapping does not work with all containers. Most notably, swapping +containers that have a parent-child relationship to one another does not work.

+
+
+

Syntax:

+
-
swap container with id|con_id|mark <arg>
-
-

Examples:

+
swap container with id|con_id|mark <arg>
+
+ +
+

Examples:

+
-
# Swaps the focused container with the container marked »swapee«.
+
# Swaps the focused container with the container marked »swapee«.
 swap container with mark swapee
 
 # Swaps container marked »A« and »B«
-[con_mark="^A$"] swap container with mark B
-
+[con_mark="^A$"] swap container with mark B + +
-

6.7. Sticky floating windows

-

If you want a window to stick to the glass, i.e., have it stay on screen even -if you switch to another workspace, you can use the sticky command. For +

Sticky floating windows

+
+

If you want a window to stick to the glass, i.e., have it stay on screen even +if you switch to another workspace, you can use the sticky command. For example, this can be useful for notepads, a media player or a video chat -window.

-

Note that while any window can be made sticky through this command, it will -only take effect if the window is floating.

-

Syntax:

+window.

+
+
+

Note that while any window can be made sticky through this command, it will +only take effect if the window is floating.

+
+
+

Syntax:

+
-
sticky enable|disable|toggle
-
-

Examples:

+
sticky enable|disable|toggle
+
+ +
+

Examples:

+
-
# make a terminal sticky that was started as a notepad
-for_window [instance=notepad] sticky enable
-
+
# make a terminal sticky that was started as a notepad
+for_window [instance=notepad] sticky enable
+ +
-

6.8. Changing (named) workspaces/moving to workspaces

-

To change to a specific workspace, use the workspace command, followed by the +

Changing (named) workspaces/moving to workspaces

+
+

To change to a specific workspace, use the workspace command, followed by the number or name of the workspace. Pass the optional flag ---no-auto-back-and-forth to disable [workspace_auto_back_and_forth] for this -specific call only.

-

To move containers to specific workspaces, use move container to workspace.

-

You can also switch to the next and previous workspace with the commands -workspace next and workspace prev, which is handy, for example, if you have +--no-auto-back-and-forth to disable Automatic back-and-forth when switching to the current workspace for this +specific call only.

+
+
+

To move containers to specific workspaces, use move container to workspace.

+
+
+

You can also switch to the next and previous workspace with the commands +workspace next and workspace prev, which is handy, for example, if you have workspace 1, 3, 4 and 9 and you want to cycle through them with a single key -combination. To restrict those to the current output, use workspace -next_on_output and workspace prev_on_output. Similarly, you can use move -container to workspace next, move container to workspace prev to move a -container to the next/previous workspace and move container to workspace current -(the last one makes sense only when used with criteria).

-

workspace next cycles through either numbered or named workspaces. But when it +combination. To restrict those to the current output, use workspace +next_on_output and workspace prev_on_output. Similarly, you can use move +container to workspace next, move container to workspace prev to move a +container to the next/previous workspace and move container to workspace current +(the last one makes sense only when used with criteria).

+
+
+

workspace next cycles through either numbered or named workspaces. But when it reaches the last numbered/named workspace, it looks for named workspaces after -exhausting numbered ones and looks for numbered ones after exhausting named ones.

-

See [move_to_outputs] for how to move a container/workspace to a different -RandR output.

-

Workspace names are parsed as +exhausting numbered ones and looks for numbered ones after exhausting named ones.

+
+
+

See Moving containers/workspaces to RandR outputs for how to move a container/workspace to a different +RandR output.

+
+
+

Workspace names are parsed as Pango markup -by i3bar.

-

To switch back to the previously focused workspace, use workspace -back_and_forth; likewise, you can move containers to the previously focused -workspace using move container to workspace back_and_forth.

-

Syntax:

+by i3bar.

+
+
+

To switch back to the previously focused workspace, use workspace +back_and_forth; likewise, you can move containers to the previously focused +workspace using move container to workspace back_and_forth.

+
+
+

Syntax:

+
-
workspace next|prev|next_on_output|prev_on_output
+
workspace next|prev|next_on_output|prev_on_output
 workspace back_and_forth
 workspace [--no-auto-back-and-forth] <name>
 workspace [--no-auto-back-and-forth] number <name>
 
 move [--no-auto-back-and-forth] [window|container] [to] workspace <name>
 move [--no-auto-back-and-forth] [window|container] [to] workspace number <name>
-move [window|container] [to] workspace prev|next|current
-
-

Examples:

+move [window|container] [to] workspace prev|next|current +
+ +
+

Examples:

+
-
bindsym $mod+1 workspace 1
+
bindsym $mod+1 workspace 1
 bindsym $mod+2 workspace 2
 bindsym $mod+3 workspace 3:<span foreground="red">vim</span>
 ...
@@ -2627,94 +3200,133 @@ 

6.8. Changing (named) w bindsym $mod+x move workspace to output right # move firefox to current workspace -bindsym $mod+F1 [class="Firefox"] move workspace current

-
+bindsym $mod+F1 [class="Firefox"] move workspace current + +
-

6.8.1. Named workspaces

-

Workspaces are identified by their name. So, instead of using numbers in the -workspace command, you can use an arbitrary name:

-

Example:

+

Named workspaces

+
+

Workspaces are identified by their name. So, instead of using numbers in the +workspace command, you can use an arbitrary name:

+
+
+

Example:

+
-
bindsym $mod+1 workspace mail
-...
-
-

If you want the workspace to have a number and a name, just prefix the -number, like this:

-

Example:

+
bindsym $mod+1 workspace mail
+...
+
+ +
+

If you want the workspace to have a number and a name, just prefix the +number, like this:

+
+
+

Example:

+
-
bindsym $mod+1 workspace 1: mail
+
bindsym $mod+1 workspace 1: mail
 bindsym $mod+2 workspace 2: www
-...
-
-

Note that the workspace will really be named "1: mail". i3 treats workspace +... +

+ +
+

Note that the workspace will really be named "1: mail". i3 treats workspace names beginning with a number in a slightly special way. Normally, named workspaces are ordered the way they appeared. When they start with a number, i3 -will order them numerically. Also, you will be able to use workspace number 1 +will order them numerically. Also, you will be able to use workspace number 1 to switch to the workspace which begins with number 1, regardless of which name it has. This is useful in case you are changing the workspace’s name -dynamically. To combine both commands you can use workspace number 1: mail to -specify a default name if there’s currently no workspace starting with a "1".

+dynamically. To combine both commands you can use workspace number 1: mail to +specify a default name if there’s currently no workspace starting with a "1".

+
-

6.8.2. Renaming workspaces

-

You can rename workspaces. This might be useful to start with the default +

Renaming workspaces

+
+

You can rename workspaces. This might be useful to start with the default numbered workspaces, do your work, and rename the workspaces afterwards to reflect what’s actually on them. You can also omit the old name to rename the currently focused workspace. This is handy if you want to use the -rename command with i3-input.

-

Syntax:

+rename command with i3-input.

+
+
+

Syntax:

+
-
rename workspace <old_name> to <new_name>
-rename workspace to <new_name>
-
-

Examples:

+
rename workspace <old_name> to <new_name>
+rename workspace to <new_name>
+
+ +
+

Examples:

+
-
i3-msg 'rename workspace 5 to 6'
+
i3-msg 'rename workspace 5 to 6'
 i3-msg 'rename workspace 1 to "1: www"'
 i3-msg 'rename workspace "1: www" to "10: www"'
 i3-msg 'rename workspace to "2: mail"'
-bindsym $mod+r exec i3-input -F 'rename workspace to "%s"' -P 'New name: '
-
-

If you want to rename workspaces on demand while keeping the navigation stable, -you can use a setup like this:

-

Example:

+bindsym $mod+r exec i3-input -F 'rename workspace to "%s"' -P 'New name: ' + + +
+

If you want to rename workspaces on demand while keeping the navigation stable, +you can use a setup like this:

+
+
+

Example:

+
-
bindsym $mod+1 workspace number "1: www"
+
bindsym $mod+1 workspace number "1: www"
 bindsym $mod+2 workspace number "2: mail"
-...
-
-

If a workspace does not exist, the command workspace number "1: mail" will -create workspace "1: mail".

-

If a workspace with number 1 does already exist, the command will switch to this +... +

+ +
+

If a workspace does not exist, the command workspace number "1: mail" will +create workspace "1: mail".

+
+
+

If a workspace with number 1 does already exist, the command will switch to this workspace and ignore the text part. So even when the workspace has been renamed -to "1: web", the above command will still switch to it.

+to "1: web", the above command will still switch to it.

+
-

6.9. Moving workspaces to a different screen

-

See [move_to_outputs] for how to move a container/workspace to a different -RandR output.

+

Moving workspaces to a different screen

+
+

See Moving containers/workspaces to RandR outputs for how to move a container/workspace to a different +RandR output.

+
-

6.10. Moving containers/workspaces to RandR outputs

-

To move a container to another RandR output (addressed by names like LVDS1 or -VGA1) or to a RandR output identified by a specific direction (like left, -right, up or down), there are two commands:

-

Syntax:

+

Moving containers/workspaces to RandR outputs

+
+

To move a container to another RandR output (addressed by names like LVDS1 or +VGA1) or to a RandR output identified by a specific direction (like left, +right, up or down), there are two commands:

+
+
+

Syntax:

+
-
move container to output left|right|down|up|current|primary|<output>
-move workspace to output left|right|down|up|current|primary|<output>
-
-

Examples:

+
move container to output left|right|down|up|current|primary|<output>
+move workspace to output left|right|down|up|current|primary|<output>
+
+ +
+

Examples:

+
-
# Move the current workspace to the next output
+
# Move the current workspace to the next output
 # (effectively toggles when you only have two outputs)
 bindsym $mod+x move workspace to output right
 
@@ -2722,130 +3334,188 @@ 

6.10.

Note that you might not have a primary output configured yet. To do so, run:

+bindsym $mod+x move container to output primary +
+ +
+

Note that you might not have a primary output configured yet. To do so, run:

+
-
xrandr --output <output> --primary
-
+
xrandr --output <output> --primary
+ +
-

6.11. Moving containers/windows to marks

-
-

The window will be moved right after the marked container in the tree, i.e., it ends up +

Moving containers/windows to marks

+
+

To move a container to another container with a specific mark (see VIM-like marks (mark/goto)), +you can use the following command.

+
+
+

The window will be moved right after the marked container in the tree, i.e., it ends up in the same position as if you had opened a new window when the marked container was focused. If the mark is on a split container, the window will appear as a new child -after the currently focused child within that container.

-

Syntax:

+after the currently focused child within that container.

+
+
+

Syntax:

+
-
move window|container to mark <mark>
-
-

Example:

+
move window|container to mark <mark>
+
+ +
+

Example:

+
-
for_window [instance="tabme"] move window to mark target
-
+
for_window [instance="tabme"] move window to mark target
+ +
-

6.12. Resizing containers/windows

-

If you want to resize containers/windows using your keyboard, you can use the -resize command:

-

Syntax:

+

Resizing containers/windows

+
+

If you want to resize containers/windows using your keyboard, you can use the +resize command:

+
+
+

Syntax:

+
-
resize grow|shrink <direction> [<px> px [or <ppt> ppt]]
+
resize grow|shrink <direction> [<px> px [or <ppt> ppt]]
 resize set [width] <width> [px | ppt]
 resize set height <height> [px | ppt]
-resize set [width] <width> [px | ppt] [height] <height> [px | ppt]
-
-

Direction can either be one of up, down, left or right. Or you can be -less specific and use width or height, in which case i3 will take/give space +resize set [width] <width> [px | ppt] [height] <height> [px | ppt] +

+
+
+

Direction can either be one of up, down, left or right. Or you can be +less specific and use width or height, in which case i3 will take/give space from all the other containers. The optional pixel argument specifies by how many pixels a container should be grown or shrunk (the default is 10 pixels). The optional ppt argument means "percentage points", and if specified it indicates that a tiling container should be grown or shrunk by that many points, instead -of by the px value.

-

Note about resize set: a value of 0 for <width> or <height> means "do not -resize in this direction".

-

It is recommended to define bindings for resizing in a dedicated binding mode. -See [binding_modes] and the example in the i3 +of by the px value.

+
+
+

Note about resize set: a value of 0 for <width> or <height> means "do not +resize in this direction".

+
+
+

It is recommended to define bindings for resizing in a dedicated binding mode. +See Binding modes and the example in the i3 default config for more -context.

-

Example:

+context.

+ +
+

Example:

+
-
for_window [class="urxvt"] resize set 640 480
-
+
for_window [class="urxvt"] resize set 640 480
+ +
-

6.13. Jumping to specific windows

-

Often when in a multi-monitor environment, you want to quickly jump to a +

Jumping to specific windows

+
+

Often when in a multi-monitor environment, you want to quickly jump to a specific window. For example, while working on workspace 3 you might want to jump to your mail client to email your boss that you’ve achieved some important goal. Instead of figuring out how to navigate to your mail client, -it would be more convenient to have a shortcut. You can use the focus command -with criteria for that.

-

Syntax:

+it would be more convenient to have a shortcut. You can use the focus command +with criteria for that.

+
+
+

Syntax:

+
-
[class="class"] focus
-[title="title"] focus
-
-

Examples:

+
[class="class"] focus
+[title="title"] focus
+
+ +
+

Examples:

+
-
# Get me to the next open VIM instance
-bindsym $mod+a [class="urxvt" title="VIM"] focus
-
+
# Get me to the next open VIM instance
+bindsym $mod+a [class="urxvt" title="VIM"] focus
+ +
-

6.14. VIM-like marks (mark/goto)

-

This feature is like the jump feature: It allows you to directly jump to a +

VIM-like marks (mark/goto)

+
+

This feature is like the jump feature: It allows you to directly jump to a specific window (this means switching to the appropriate workspace and setting focus to the windows). However, you can directly mark a specific window with an arbitrary label and use it afterwards. You can unmark the label in the same way, using the unmark command. If you don’t specify a label, unmark removes all marks. You do not need to ensure that your windows have unique classes or -titles, and you do not need to change your configuration file.

-

As the command needs to include the label with which you want to mark the -window, you cannot simply bind it to a key. i3-input is a tool created +titles, and you do not need to change your configuration file.

+
+
+

As the command needs to include the label with which you want to mark the +window, you cannot simply bind it to a key. i3-input is a tool created for this purpose: It lets you input a command and sends the command to i3. It -can also prefix this command and display a custom prompt for the input dialog.

-

The additional --toggle option will remove the mark if the window already has +can also prefix this command and display a custom prompt for the input dialog.

+
+
+

The additional --toggle option will remove the mark if the window already has this mark or add it otherwise. Note that you might need to use this in -combination with --add (see below) as any other marks will otherwise be -removed.

-

The --replace flag causes i3 to remove any existing marks, which is also the -default behavior. You can use the --add flag to put more than one mark on a -window.

-

Refer to [show_marks] if you don’t want marks to be shown in the window decoration.

-

Syntax:

+combination with --add (see below) as any other marks will otherwise be +removed.

+
+
+

The --replace flag causes i3 to remove any existing marks, which is also the +default behavior. You can use the --add flag to put more than one mark on a +window.

+
+
+

Refer to Drawing marks on window decoration if you don’t want marks to be shown in the window decoration.

+
+
+

Syntax:

+
-
mark [--add|--replace] [--toggle] <identifier>
+
mark [--add|--replace] [--toggle] <identifier>
 [con_mark="identifier"] focus
-unmark <identifier>
-
-

You can use i3-input to prompt for a mark name, then use the mark -and focus commands to create and jump to custom marks:

-

Examples:

+unmark <identifier> +
+ +
+

You can use i3-input to prompt for a mark name, then use the mark +and focus commands to create and jump to custom marks:

+
+
+

Examples:

+
-
# read 1 character and mark the current window with this character
+
# read 1 character and mark the current window with this character
 bindsym $mod+m exec i3-input -F 'mark %s' -l 1 -P 'Mark: '
 
 # read 1 character and go to the window with the character
-bindsym $mod+g exec i3-input -F '[con_mark="%s"] focus' -l 1 -P 'Goto: '
-
-

Alternatively, if you do not want to mess with i3-input, you could create -separate bindings for a specific set of labels and then only use those labels:

-

Example (in a terminal):

+bindsym $mod+g exec i3-input -F '[con_mark="%s"] focus' -l 1 -P 'Goto: ' + + +
+

Alternatively, if you do not want to mess with i3-input, you could create +separate bindings for a specific set of labels and then only use those labels:

+
+
+

Example (in a terminal):

+
-
# marks the focused container
+
# marks the focused container
 mark irssi
 
 # focus the container with the mark "irssi"
@@ -2855,230 +3525,293 @@ 

6.14. VIM-like marks (mark/goto)

unmark irssi # remove all marks on all firefox windows -[class="(?i)firefox"] unmark
-
+[class="(?i)firefox"] unmark + +
-

6.15. Window title format

-

By default, i3 will simply print the X11 window title. Using title_format, +

Window title format

+
+

By default, i3 will simply print the X11 window title. Using title_format, this can be customized by setting the format to the desired output. This directive supports Pango markup -and the following placeholders which will be replaced:

-
-
-%title -
+and the following placeholders which will be replaced:

+
+
+
+
%title
-

- For normal windows, this is the X11 window title (_NET_WM_NAME or WM_NAME - as fallback). When used on containers without a window (e.g., a split - container inside a tabbed/stacked layout), this will be the tree - representation of the container (e.g., "H[xterm xterm]"). -

+

For normal windows, this is the X11 window title (_NET_WM_NAME or WM_NAME +as fallback). When used on containers without a window (e.g., a split +container inside a tabbed/stacked layout), this will be the tree +representation of the container (e.g., "H[xterm xterm]").

-
-%class -
+
%class
-

- The X11 window class (second part of WM_CLASS). This corresponds to the - class criterion, see [command_criteria]. -

+

The X11 window class (second part of WM_CLASS). This corresponds to the +class criterion, see [command_criteria].

-
-%instance -
+
%instance
-

- The X11 window instance (first part of WM_CLASS). This corresponds to the - instance criterion, see [command_criteria]. -

+

The X11 window instance (first part of WM_CLASS). This corresponds to the +instance criterion, see [command_criteria].

-
-

Using the [for_window] directive, you can set the title format for any window -based on [command_criteria].

-

Syntax:

+ +
+
+

Using the Arbitrary commands for specific windows (for_window) directive, you can set the title format for any window +based on [command_criteria].

+
+
+

Syntax:

+
-
title_format <format>
-
-

Examples:

+
title_format <format>
+
+ +
+

Examples:

+
-
# give the focused window a prefix
+
# give the focused window a prefix
 bindsym $mod+p title_format "Important | %title"
 
 # print all window titles bold
 for_window [class=".*"] title_format "<b>%title</b>"
 
 # print window titles of firefox windows red
-for_window [class="(?i)firefox"] title_format "<span foreground='red'>%title</span>"
-
+for_window [class="(?i)firefox"] title_format "<span foreground='red'>%title</span>" + +
-

6.16. Changing border style

-

To change the border of the current client, you can use border normal to use the normal -border (including window title), border pixel 1 to use a 1-pixel border (no window title) -and border none to make the client borderless.

-

There is also border toggle which will toggle the different border styles. The +

Changing border style

+
+

To change the border of the current client, you can use border normal to use the normal +border (including window title), border pixel 1 to use a 1-pixel border (no window title) +and border none to make the client borderless.

+
+
+

There is also border toggle which will toggle the different border styles. The optional pixel argument can be used to specify the border width when switching -to the normal and pixel styles.

-

Note that "pixel" refers to logical pixel. On HiDPI displays, a logical pixel -is represented by multiple physical pixels, so pixel 1 might not -necessarily translate into a single pixel row wide border.

-

Syntax:

+to the normal and pixel styles.

+
+
+

Note that "pixel" refers to logical pixel. On HiDPI displays, a logical pixel +is represented by multiple physical pixels, so pixel 1 might not +necessarily translate into a single pixel row wide border.

+
+
+

Syntax:

+
-
border normal|pixel|toggle [<n>]
+
border normal|pixel|toggle [<n>]
 border none
 
 # legacy syntax, equivalent to "border pixel 1"
-border 1pixel
-
-

Examples:

+border 1pixel +
+ +
+

Examples:

+
-
# use window title, but no border
+
# use window title, but no border
 bindsym $mod+t border normal 0
 # use no window title and a thick border
 bindsym $mod+y border pixel 3
 # use neither window title nor border
-bindsym $mod+u border none
-
+bindsym $mod+u border none + +
-

6.17. Enabling shared memory logging

-

As described in https://i3wm.org/docs/debugging.html, i3 can log to a shared -memory buffer, which you can dump using i3-dump-log. The shmlog command -allows you to enable or disable the shared memory logging at runtime.

-

Note that when using shmlog <size_in_bytes>, the current log will be -discarded and a new one will be started.

-

Syntax:

+

Enabling shared memory logging

+
+

As described in https://i3wm.org/docs/debugging.html, i3 can log to a shared +memory buffer, which you can dump using i3-dump-log. The shmlog command +allows you to enable or disable the shared memory logging at runtime.

+
+
+

Note that when using shmlog <size_in_bytes>, the current log will be +discarded and a new one will be started.

+
+
+

Syntax:

+
-
shmlog <size_in_bytes>
-shmlog on|off|toggle
-
-

Examples:

+
shmlog <size_in_bytes>
+shmlog on|off|toggle
+
+ +
+

Examples:

+
-
# Enable/disable logging
+
# Enable/disable logging
 bindsym $mod+x shmlog toggle
 
 # or, from a terminal:
 # increase the shared memory log buffer to 50 MiB
-i3-msg shmlog $((50*1024*1024))
-
+i3-msg shmlog $((50*1024*1024)) + +
-

6.18. Enabling debug logging

-

The debuglog command allows you to enable or disable debug logging at +

Enabling debug logging

+
+

The debuglog command allows you to enable or disable debug logging at runtime. Debug logging is much more verbose than non-debug logging. This command does not activate shared memory logging (shmlog), and as such is most -likely useful in combination with the above-described [shmlog] command.

-

Syntax:

+likely useful in combination with the above-described Enabling shared memory logging command.

+
+
+

Syntax:

+
-
debuglog on|off|toggle
-
-

Examples:

+
debuglog on|off|toggle
+
+ +
+

Examples:

+
-
# Enable/disable logging
-bindsym $mod+x debuglog toggle
-
+
# Enable/disable logging
+bindsym $mod+x debuglog toggle
+ +
-

6.19. Reloading/Restarting/Exiting

-

You can make i3 reload its configuration file with reload. You can also -restart i3 inplace with the restart command to get it out of some weird state +

Reloading/Restarting/Exiting

+
+

You can make i3 reload its configuration file with reload. You can also +restart i3 inplace with the restart command to get it out of some weird state (if that should ever happen) or to perform an upgrade without having to restart -your X session. To exit i3 properly, you can use the exit command, -however you don’t need to (simply killing your X session is fine as well).

-

Examples:

+your X session. To exit i3 properly, you can use the exit command, +however you don’t need to (simply killing your X session is fine as well).

+
+
+

Examples:

+
-
bindsym $mod+Shift+r restart
+
bindsym $mod+Shift+r restart
 bindsym $mod+Shift+w reload
-bindsym $mod+Shift+e exit
-
+bindsym $mod+Shift+e exit +
+
-

6.20. Scratchpad

-

There are two commands to use any existing window as scratchpad window. move -scratchpad will move a window to the scratchpad workspace. This will make it +

Scratchpad

+
+

There are two commands to use any existing window as scratchpad window. move +scratchpad will move a window to the scratchpad workspace. This will make it invisible until you show it again. There is no way to open that workspace. -Instead, when using scratchpad show, the window will be shown again, as a -floating window, centered on your current workspace (using scratchpad show on +Instead, when using scratchpad show, the window will be shown again, as a +floating window, centered on your current workspace (using scratchpad show on a visible scratchpad window will make it hidden again, so you can have a keybinding to toggle). Note that this is just a normal floating window, so if you want to "remove it from scratchpad", you can simple make it tiling again -(floating toggle).

-

As the name indicates, this is useful for having a window with your favorite +(floating toggle).

+
+
+

As the name indicates, this is useful for having a window with your favorite editor always at hand. However, you can also use this for other permanently running applications which you don’t want to see all the time: Your music -player, alsamixer, maybe even your mail client…?

-

Syntax:

+player, alsamixer, maybe even your mail client…?

+
+
+

Syntax:

+
-
move scratchpad
+
move scratchpad
 
-scratchpad show
-
-

Examples:

+scratchpad show +
+ +
+

Examples:

+
-
# Make the currently focused window a scratchpad
+
# Make the currently focused window a scratchpad
 bindsym $mod+Shift+minus move scratchpad
 
 # Show the first scratchpad window
 bindsym $mod+minus scratchpad show
 
 # Show the sup-mail scratchpad window, if any.
-bindsym mod4+s [title="^Sup ::"] scratchpad show
-
+bindsym mod4+s [title="^Sup ::"] scratchpad show + +
-

6.21. Nop

-

There is a no operation command nop which allows you to override default +

Nop

+
+

There is a no operation command nop which allows you to override default behavior. This can be useful for, e.g., disabling a focus change on clicks with -the middle mouse button.

-

The optional comment argument is ignored, but will be printed to the log file -for debugging purposes.

-

Syntax:

+the middle mouse button.

+
+
+

The optional comment argument is ignored, but will be printed to the log file +for debugging purposes.

+
+
+

Syntax:

+
-
nop [<comment>]
-
-

Example:

+
nop [<comment>]
+
+ +
+

Example:

+
-
# Disable focus change for clicks on titlebars
+
# Disable focus change for clicks on titlebars
 # with the middle mouse button
-bindsym button2 nop
-
+bindsym button2 nop + +
-

6.22. i3bar control

-

There are two options in the configuration of each i3bar instance that can be -changed during runtime by invoking a command through i3. The commands bar -hidden_state and bar mode allow setting the current hidden_state +

i3bar control

+
+

There are two options in the configuration of each i3bar instance that can be +changed during runtime by invoking a command through i3. The commands bar +hidden_state and bar mode allow setting the current hidden_state respectively mode option of each bar. It is also possible to toggle between hide state and show state as well as between dock mode and hide mode. Each i3bar instance can be controlled individually by specifying a bar_id, if none -is given, the command is executed for all bar instances.

-

Syntax:

+is given, the command is executed for all bar instances.

+
+
+

Syntax:

+
-
bar hidden_state hide|show|toggle [<bar_id>]
+
bar hidden_state hide|show|toggle [<bar_id>]
 
-bar mode dock|hide|invisible|toggle [<bar_id>]
-
-

Examples:

+bar mode dock|hide|invisible|toggle [<bar_id>] +
+ +
+

Examples:

+
-
# Toggle between hide state and show state
+
# Toggle between hide state and show state
 bindsym $mod+m bar hidden_state toggle
 
 # Toggle between dock mode and hide mode
@@ -3088,43 +3821,54 @@ 

6.22. i3bar control

bindsym $mod+b bar mode hide bar-1 # Set the bar instance with id 'bar-1' to always stay hidden -bindsym $mod+Shift+b bar mode invisible bar-1
-
+bindsym $mod+Shift+b bar mode invisible bar-1 + +
-

7. Multiple monitors

+

Multiple monitors

-

As you can see in the goal list on the website, i3 was specifically developed +

+

As you can see in the goal list on the website, i3 was specifically developed with support for multiple monitors in mind. This section will explain how to -handle multiple monitors.

-

When you have only one monitor, things are simple. You usually start with -workspace 1 on your monitor and open new ones as you need them.

-

When you have more than one monitor, each monitor will get an initial +handle multiple monitors.

+
+
+

When you have only one monitor, things are simple. You usually start with +workspace 1 on your monitor and open new ones as you need them.

+
+
+

When you have more than one monitor, each monitor will get an initial workspace. The first monitor gets 1, the second gets 2 and a possible third would get 3. When you switch to a workspace on a different monitor, i3 will switch to that monitor and then switch to the workspace. This way, you don’t need shortcuts to switch to a specific monitor, and you don’t need to remember where you put which workspace. New workspaces will be opened on the currently -active monitor. It is not possible to have a monitor without a workspace.

-

The idea of making workspaces global is based on the observation that most +active monitor. It is not possible to have a monitor without a workspace.

+
+
+

The idea of making workspaces global is based on the observation that most users have a very limited set of workspaces on their additional monitors. They are often used for a specific task (browser, shell) or for monitoring several things (mail, IRC, syslog, …). Thus, using one workspace on one monitor and "the rest" on the other monitors often makes sense. However, as you can create an unlimited number of workspaces in i3 and tie them to specific screens, you can have the "traditional" approach of having X workspaces per -screen by changing your configuration (using modes, for example).

+screen by changing your configuration (using modes, for example).

+
-

7.1. Configuring your monitors

-

To help you get going if you have never used multiple monitors before, here is +

Configuring your monitors

+
+

To help you get going if you have never used multiple monitors before, here is a short overview of the xrandr options which will probably be of interest to you. It is always useful to get an overview of the current screen configuration. -Just run "xrandr" and you will get an output like the following:

+Just run "xrandr" and you will get an output like the following:

+
-
$ xrandr
+
$ xrandr
 Screen 0: minimum 320 x 200, current 1280 x 800, maximum 8192 x 8192
 VGA1 disconnected (normal left inverted right x axis y axis)
 LVDS1 connected 1280x800+0+0 (normal left inverted right x axis y axis) 261mm x 163mm
@@ -3135,26 +3879,36 @@ 

7.1. Configuring your monitors

640x480 85.0 72.8 75.0 59.9 720x400 85.0 640x400 85.1 - 640x350 85.1
-
-

Several things are important here: You can see that LVDS1 is connected (of -course, it is the internal flat panel) but VGA1 is not. If you have a monitor + 640x350 85.1 +

+
+
+

Several things are important here: You can see that LVDS1 is connected (of +course, it is the internal flat panel) but VGA1 is not. If you have a monitor connected to one of the ports but xrandr still says "disconnected", you should -check your cable, monitor or graphics driver.

-

The maximum resolution you can see at the end of the first line is the maximum +check your cable, monitor or graphics driver.

+
+
+

The maximum resolution you can see at the end of the first line is the maximum combined resolution of your monitors. By default, it is usually too low and has -to be increased by editing /etc/X11/xorg.conf.

-

So, say you connected VGA1 and want to use it as an additional screen:

+to be increased by editing /etc/X11/xorg.conf.

+
+
+

So, say you connected VGA1 and want to use it as an additional screen:

+
-
xrandr --output VGA1 --auto --left-of LVDS1
-
-

This command makes xrandr try to find the native resolution of the device -connected to VGA1 and configures it to the left of your internal flat panel. -When running "xrandr" again, the output looks like this:

+
xrandr --output VGA1 --auto --left-of LVDS1
+
+ +
+

This command makes xrandr try to find the native resolution of the device +connected to VGA1 and configures it to the left of your internal flat panel. +When running "xrandr" again, the output looks like this:

+
-
$ xrandr
+
$ xrandr
 Screen 0: minimum 320 x 200, current 2560 x 1024, maximum 8192 x 8192
 VGA1 connected 1280x1024+0+0 (normal left inverted right x axis y axis) 338mm x 270mm
    1280x1024      60.0*+   75.0
@@ -3173,135 +3927,157 @@ 

7.1. Configuring your monitors

640x480 85.0 72.8 75.0 59.9 720x400 85.0 640x400 85.1 - 640x350 85.1
-
-

Please note that i3 uses exactly the same API as xrandr does, so it will see -only what you can see in xrandr.

-

See also [presentations] for more examples of multi-monitor setups.

+ 640x350 85.1 + + +
+

Please note that i3 uses exactly the same API as xrandr does, so it will see +only what you can see in xrandr.

+
+
+

See also Giving presentations (multi-monitor) for more examples of multi-monitor setups.

+
-

7.2. Interesting configuration for multi-monitor environments

-

There are several things to configure in i3 which might be interesting if you -have more than one monitor:

-
    +

    Interesting configuration for multi-monitor environments

    +
    +

    There are several things to configure in i3 which might be interesting if you +have more than one monitor:

    +
    +
    +
    1. -

      -You can specify which workspace should be put on which screen. This - allows you to have a different set of workspaces when starting than just - 1 for the first monitor, 2 for the second and so on. See - [workspace_screen]. -

      +

      You can specify which workspace should be put on which screen. This +allows you to have a different set of workspaces when starting than just +1 for the first monitor, 2 for the second and so on. See +Automatically putting workspaces on specific screens.

    2. -

      -If you want some applications to generally open on the bigger screen - (MPlayer, Firefox, …), you can assign them to a specific workspace, see - [assign_workspace]. -

      +

      If you want some applications to generally open on the bigger screen +(MPlayer, Firefox, …), you can assign them to a specific workspace, see +Automatically putting clients on specific workspaces.

    3. -

      -If you have many workspaces on many monitors, it might get hard to keep - track of which window you put where. Thus, you can use vim-like marks to - quickly switch between windows. See [vim_like_marks]. -

      +

      If you have many workspaces on many monitors, it might get hard to keep +track of which window you put where. Thus, you can use vim-like marks to +quickly switch between windows. See VIM-like marks (mark/goto).

    4. -

      -For information on how to move existing workspaces between monitors, - see [move_to_outputs]. -

      +

      For information on how to move existing workspaces between monitors, +see Moving containers/workspaces to RandR outputs.

    5. -
    +
+
-

8. i3 and the rest of your software world

+

i3 and the rest of your software world

-

8.1. Displaying a status line

-

A very common thing amongst users of exotic window managers is a status line at +

Displaying a status line

+
+

A very common thing amongst users of exotic window managers is a status line at some corner of the screen. It is an often superior replacement to the widget -approach you have in the task bar of a traditional desktop environment.

-

If you don’t already have your favorite way of generating such a status line +approach you have in the task bar of a traditional desktop environment.

+
+
+

If you don’t already have your favorite way of generating such a status line (self-written scripts, conky, …), then i3status is the recommended tool for this task. It was written in C with the goal of using as few syscalls as possible to reduce the time your CPU is woken up from sleep states. Because i3status only spits out text, you need to combine it with some other tool, like -i3bar. See [status_command] for how to display i3status in i3bar.

-

Regardless of which application you use to display the status line, you +i3bar. See Statusline command for how to display i3status in i3bar.

+
+
+

Regardless of which application you use to display the status line, you want to make sure that it registers as a dock window using EWMH hints. i3 will position the window either at the top or at the bottom of the screen, depending on which hint the application sets. With i3bar, you can configure its position, -see [i3bar_position].

+see [i3bar_position].

+
-

8.2. Giving presentations (multi-monitor)

-

When giving a presentation, you typically want the audience to see what you see +

Giving presentations (multi-monitor)

+
+

When giving a presentation, you typically want the audience to see what you see on your screen and then go through a series of slides (if the presentation is simple). For more complex presentations, you might want to have some notes which only you can see on your screen, while the audience can only see the -slides.

+slides.

+
-

8.2.1. Case 1: everybody gets the same output

-

This is the simple case. You connect your computer to the video projector, +

Case 1: everybody gets the same output

+
+

This is the simple case. You connect your computer to the video projector, turn on both (computer and video projector) and configure your X server to -clone the internal flat panel of your computer to the video output:

+clone the internal flat panel of your computer to the video output:

+
-
xrandr --output VGA1 --mode 1024x768 --same-as LVDS1
-
-

i3 will then use the lowest common subset of screen resolutions, the rest of +

xrandr --output VGA1 --mode 1024x768 --same-as LVDS1
+
+
+
+

i3 will then use the lowest common subset of screen resolutions, the rest of your screen will be left untouched (it will show the X background). So, in -our example, this would be 1024x768 (my notebook has 1280x800).

+our example, this would be 1024x768 (my notebook has 1280x800).

+
-

8.2.2. Case 2: you can see more than your audience

-

This case is a bit harder. First of all, you should configure the VGA output -somewhere near your internal flat panel, say right of it:

+

Case 2: you can see more than your audience

+
+

This case is a bit harder. First of all, you should configure the VGA output +somewhere near your internal flat panel, say right of it:

+
-
xrandr --output VGA1 --mode 1024x768 --right-of LVDS1
-
-

Now, i3 will put a new workspace (depending on your settings) on the new screen -and you are in multi-monitor mode (see [multi_monitor]).

-

Because i3 is not a compositing window manager, there is no ability to +

xrandr --output VGA1 --mode 1024x768 --right-of LVDS1
+
+
+
+

Now, i3 will put a new workspace (depending on your settings) on the new screen +and you are in multi-monitor mode (see Multiple monitors).

+
+
+

Because i3 is not a compositing window manager, there is no ability to display a window on two screens at the same time. Instead, your presentation -software needs to do this job (that is, open a window on each screen).

+software needs to do this job (that is, open a window on each screen).

+
-

8.3. High-resolution displays (aka HIDPI displays)

-

See https://wiki.archlinux.org/index.php/HiDPI for details on how to enable +

High-resolution displays (aka HIDPI displays)

+
+

See https://wiki.archlinux.org/index.php/HiDPI for details on how to enable scaling in various parts of the Linux desktop. i3 will read the desired DPI from -the Xft.dpi property. The property defaults to 96 DPI, so to achieve 200% -scaling, you’d set Xft.dpi: 192 in ~/.Xresources.

-

If you are a long-time i3 user who just got a new monitor, double-check that:

-
    +the Xft.dpi property. The property defaults to 96 DPI, so to achieve 200% +scaling, you’d set Xft.dpi: 192 in ~/.Xresources.

    +
+
+

If you are a long-time i3 user who just got a new monitor, double-check that:

+
+
+
  • -

    -You are using a scalable font (starting with “pango:”) in your i3 config. -

    +

    You are using a scalable font (starting with “pango:”) in your i3 config.

  • -

    -You are using a terminal emulator which supports scaling. You could - temporarily switch to gnome-terminal, which is known to support scaling out of - the box, until you figure out how to adjust the font size in your favorite - terminal emulator. -

    +

    You are using a terminal emulator which supports scaling. You could +temporarily switch to gnome-terminal, which is known to support scaling out of +the box, until you figure out how to adjust the font size in your favorite +terminal emulator.

  • -
+ +
+
+ + + -
-

- - + \ No newline at end of file diff --git a/docs/wsbar.html b/docs/wsbar.html index a541254..a3130d7 100644 --- a/docs/wsbar.html +++ b/docs/wsbar.html @@ -1,147 +1,165 @@ - - - -i3: External workspace bars - - - - + + + + + +External workspace bars + - -
- - -
-
- - + + +
-

i3 comes with i3bar by default, a simple bar that is sufficient for most users. +

+

i3 comes with i3bar by default, a simple bar that is sufficient for most users. In case you are unhappy with it, this document explains how to use a different, external workspace bar. Note that we do not provide support for external -programs.

+programs.

+
-

1. Internal and external bars

+

Internal and external bars

-

The internal workspace bar of i3 is meant to be a reasonable default so that +

+

The internal workspace bar of i3 is meant to be a reasonable default so that you can use i3 without having too much hassle when setting it up. It is quite -simple and intended to stay this way.

+simple and intended to stay this way.

+
-

2. dock mode

+

dock mode

-

You typically want to see the same workspace bar on every workspace on a +

+

You typically want to see the same workspace bar on every workspace on a specific screen. Also, you don’t want to place the workspace bar somewhere in your layout by hand. This is where dock mode comes in: When a program sets the appropriate hint (_NET_WM_WINDOW_TYPE_DOCK), it will be managed in dock mode by i3. That means it will be placed at the bottom or top of the screen (while other edges of the screen are possible in the NetWM standard, this is not yet implemented in i3), it will not overlap any other window and it will be -on every workspace for the specific screen it was placed on initially.

+on every workspace for the specific screen it was placed on initially.

+
-

3. The IPC interface

+

The IPC interface

-

In the context of using an external workspace bar, the IPC interface needs to +

+

In the context of using an external workspace bar, the IPC interface needs to provide the bar program with the current workspaces and output (as in VGA-1, LVDS-1, …) configuration. In the other direction, the program has to be able -to switch to specific workspaces.

-

By default, the IPC interface is enabled and you can get the path to the socket -by calling i3 --get-socketpath.

-

To learn more about the protocol which is used for IPC, see docs/ipc.

+to switch to specific workspaces.

+
+
+

By default, the IPC interface is enabled and you can get the path to the socket +by calling i3 --get-socketpath.

+
+
+

To learn more about the protocol which is used for IPC, see docs/ipc.

+
-

4. Output changes (on-the-fly)

+

Output changes (on-the-fly)

-

i3 implements the RandR API and can handle changing outputs quite well. So, an +

+

i3 implements the RandR API and can handle changing outputs quite well. So, an external workspace bar implementation needs to make sure that when you change the resolution of any of your screens (or enable/disable an output), the bars -will be adjusted properly.

+will be adjusted properly.

+
-

5. i3-wsbar, an example implementation

+

i3-wsbar, an example implementation

-

i3-wsbar used to be the reference implementation before we had i3bar. +

+

i3-wsbar used to be the reference implementation before we had i3bar. Nowadays, it is not shipped with release tarballs, but you can still get it at -https://github.com/i3/i3/blob/next/contrib/i3-wsbar

+https://github.com/i3/i3/blob/next/contrib/i3-wsbar

+
-

5.1. The big picture

-

The most common reason to use an external workspace bar is to integrate system -information such as what i3status or conky provide into the workspace bar. -So, we have i3status or a similar program, which only provides +

The big picture

+
+

The most common reason to use an external workspace bar is to integrate system +information such as what i3status or conky provide into the workspace bar. +So, we have i3status or a similar program, which only provides text output (formatted in some way). To display this text nicely on the screen, there are programs such as dzen2, xmobar and similar. We will stick to dzen2 from here on. So, we have the output of i3status, which needs to go into dzen2 -somehow. But we also want to display the list of workspaces. i3-wsbar takes +somehow. But we also want to display the list of workspaces. i3-wsbar takes input on stdin, combines it with a formatted workspace list and pipes it to -dzen2.

-

Please note that i3-wsbar does not print its output to stdout. Instead, it +dzen2.

+
+
+

Please note that i3-wsbar does not print its output to stdout. Instead, it launches the dzen2 instances on its own. This is necessary to handle changes -in the available outputs (to place a new dzen2 on a new screen for example).

-

- -Overview - -

+in the available outputs (to place a new dzen2 on a new screen for example).

+
+
+

Overview

+
-

5.2. Running i3-wsbar

-

The most simple usage of i3-wsbar looks like this:

+

Running i3-wsbar

+
+

The most simple usage of i3-wsbar looks like this:

+
-
i3-wsbar -c "dzen2 -x %x -dock"
-
-

The %x in the command name will be replaced by the X position of the output +

i3-wsbar -c "dzen2 -x %x -dock"
+
+
+
+

The %x in the command name will be replaced by the X position of the output for which this workspace bar is running. i3 will automatically place the workspace bar on the correct output when dzen2 is started in dock mode. The -bar which you will see should look exactly like the internal bar of i3.

-

To actually get a benefit, you want to give i3-wsbar some input:

+bar which you will see should look exactly like the internal bar of i3.

+
+
+

To actually get a benefit, you want to give i3-wsbar some input:

+
-
i3status | i3-wsbar -c "dzen2 -x %x -dock"
-
+
i3status | i3-wsbar -c "dzen2 -x %x -dock"
+
+
+ + + + -
-

- - + \ No newline at end of file From 1074dae829668c22c5b94678e1a7695d77065701 Mon Sep 17 00:00:00 2001 From: Sander De la Marche Date: Tue, 22 Dec 2020 18:55:46 +0100 Subject: [PATCH 5/6] Remove old xhtml back-end config file --- _docs/conf/i3html.conf | 670 ----------------------------------------- 1 file changed, 670 deletions(-) delete mode 100644 _docs/conf/i3html.conf diff --git a/_docs/conf/i3html.conf b/_docs/conf/i3html.conf deleted file mode 100644 index b896410..0000000 --- a/_docs/conf/i3html.conf +++ /dev/null @@ -1,670 +0,0 @@ -# -# xhtml11.conf -# -# Asciidoc configuration file. -# xhtml11 backend, generates XHTML 1.1 conformant markup. -# - -[miscellaneous] -outfilesuffix=.html - -[attributes] -basebackend=html -basebackend-html= -basebackend-xhtml11= - -[replacements2] -# Line break. -(?m)^(.*)\s\+$=\1
- -[replacements] -ifdef::asciidoc7compatible[] -# Superscripts. -\^(.+?)\^=\1 -# Subscripts. -~(.+?)~=\1 -endif::asciidoc7compatible[] - -[ruler-blockmacro] -
- -[pagebreak-blockmacro] -
- -[blockdef-pass] -asciimath-style=template="asciimathblock",subs=[] -latexmath-style=template="latexmathblock",subs=[] - -[macros] -# math macros. -# Special characters are escaped in HTML math markup. -(?su)[\\]?(?Pasciimath|latexmath):(?P\S*?)\[(?P.*?)(?asciimath|latexmath)::(?P\S*?)(\[(?P.*?)\])$=#[specialcharacters] - -[asciimath-inlinemacro] -`{passtext}` - -[asciimath-blockmacro] -
-
-
{title}
-`{passtext}` -
- -[asciimathblock] -
-
-
{title}
-`|` -
- -[latexmath-inlinemacro] -{passtext} - -[latexmath-blockmacro] -
-
-
{title}
-{passtext} -
- -[latexmathblock] -
-
-
{title}
-| -
- -[image-inlinemacro] - - -{data-uri%}{alt={target}} -{data-uri#}{alt={target}} -{link#} - - -[image-blockmacro] -
- -
{caption={figure-caption} {counter:figure-number}. }{title}
-
- -[unfloat-blockmacro] -
- -[indexterm-inlinemacro] -# Index term. -{empty} - -[indexterm2-inlinemacro] -# Index term. -# Single entry index term that is visible in the primary text flow. -{1} - -[footnote-inlinemacro] -# footnote:[]. -
[{0}]
- -[footnoteref-inlinemacro] -# footnoteref:[], create reference to footnote. -{2%}
[{1}]
-# footnoteref:[,], create footnote with ID. -{2#}
[{2}]
- -[callout-inlinemacro] -ifndef::icons[] -<{index}> -endif::icons[] -ifdef::icons[] -ifndef::data-uri[] -{index} -endif::data-uri[] -ifdef::data-uri[] -{index} -endif::data-uri[] -endif::icons[] - -# Comment line macros. -[comment-inlinemacro] -{showcomments#}
{passtext}
- -[comment-blockmacro] -{showcomments#}

{passtext}

- -[literal-inlinemacro] -# Inline literal. -{passtext} - -# List tags. -[listtags-bulleted] -list=
{title?
{title}
}
    |
-item=
  • |
  • -text=

    |

    - -[listtags-numbered] -# The start attribute is not valid XHTML 1.1 but all browsers support it. -list=
    {title?
    {title}
    }
      |
    -item=
  • |
  • -text=

    |

    - -[listtags-labeled] -list=
    {title?
    {title}
    }
    |
    -entry= -label= -term=
    |
    -item=
    |
    -text=

    |

    - -[listtags-horizontal] -list=
    {title?
    {title}
    }{labelwidth?}{itemwidth?}|
    -label=| -term=|
    -entry=| -item=| -text=

    |

    - -[listtags-qanda] -list=
    {title?
    {title}
    }
      |
    -entry=
  • |
  • -label= -term=

    |

    -item= -text=

    |

    - -[listtags-callout] -ifndef::icons[] -list=
    {title?
    {title}
    }
      |
    -item=
  • |
  • -text=

    |

    -endif::icons[] -ifdef::icons[] -list=
    {title?
    {title}
    }|
    -ifndef::data-uri[] -item={listindex}| -endif::data-uri[] -ifdef::data-uri[] -item={listindex}| -endif::data-uri[] -text=| -endif::icons[] - -[listtags-glossary] -list=
    {title?
    {title}
    }
    |
    -label= -entry= -term=
    |
    -item=
    |
    -text=

    |

    - -[listtags-bibliography] -list=
    {title?
    {title}
    }
      |
    -item=
  • |
  • -text=

    |

    - -[tags] -# Quoted text. -emphasis={1?}|{1?} -strong={1?}|{1?} -monospaced={1?}|{1?} -singlequoted={lsquo}{1?}|{1?}{rsquo} -doublequoted={ldquo}{1?}|{1?}{rdquo} -unquoted={1?}|{1?} -superscript={1?}|{1?} -subscript={1?}|{1?} - -ifdef::deprecated-quotes[] -# Override with deprecated quote attributes. -emphasis={role?}|{role?} -strong={role?}|{role?} -monospaced={role?}|
    {role?} -singlequoted={role?}{1,2,3?}{amp}#8216;|{amp}#8217;{1,2,3?}{role?} -doublequoted={role?}{1,2,3?}{amp}#8220;|{amp}#8221;{1,2,3?}{role?} -unquoted={role?}{1,2,3?}|{1,2,3?}{role?} -superscript={role?}|{role?} -subscript={role?}|{role?} -endif::deprecated-quotes[] - -# Inline macros -[http-inlinemacro] -{0={name}:{target}} -[https-inlinemacro] -{0={name}:{target}} -[ftp-inlinemacro] -{0={name}:{target}} -[file-inlinemacro] -{0={name}:{target}} -[irc-inlinemacro] -{0={name}:{target}} -[mailto-inlinemacro] -{0={target}} -[link-inlinemacro] -{0={target}} -[callto-inlinemacro] -{0={target}} -# anchor:id[text] -[anchor-inlinemacro] - -# [[id,text]] -[anchor2-inlinemacro] - -# [[[id]]] -[anchor3-inlinemacro] -[{1}] -# xref:id[text] -[xref-inlinemacro] -{0=[{target}]} -# <> -[xref2-inlinemacro] -{2=[{1}]} - -# Special word substitution. -[emphasizedwords] -{words} -[monospacedwords] -{words} -[strongwords] -{words} - -# Paragraph substitution. -[paragraph] -
    {title?
    {title}
    }

    -| -

    - -[admonitionparagraph] -template::[admonitionblock] - -# Delimited blocks. -[listingblock] -
    -
    {caption=}{title}
    -
    -
    
    -|
    -
    -
    - -[literalblock] -
    -
    {title}
    -
    -
    
    -|
    -
    -
    - -[sidebarblock] -
    -
    -
    {title}
    -| -
    - -[openblock] -
    -
    {title}
    -
    -| -
    - -[partintroblock] -template::[openblock] - -[abstractblock] -template::[quoteblock] - -[quoteblock] -
    -
    {title}
    -
    -| -
    -
    -{citetitle}{attribution?
    } -— {attribution} -
    - -[verseblock] -
    -
    {title}
    -
    -|
    -
    -
    -{citetitle}{attribution?
    } -— {attribution} -
    - -[exampleblock] -
    -
    {caption={example-caption} {counter:example-number}. }{title}
    -
    -| -
    - -[admonitionblock] -
    - - - -
    -{data-uri%}{icons#}{caption} -{data-uri#}{icons#}{caption} -{icons%}
    {caption}
    -
    -
    {title}
    -| -
    -
    - -# Tables. -[tabletags-default] -colspec= -bodyrow=| -headdata=| -bodydata=| -paragraph=

    |

    - -[tabletags-header] -paragraph=

    |

    - -[tabletags-emphasis] -paragraph=

    |

    - -[tabletags-strong] -paragraph=

    |

    - -[tabletags-monospaced] -paragraph=

    |

    - -[tabletags-verse] -bodydata=
    |
    -paragraph= - -[tabletags-literal] -bodydata=
    |
    -paragraph= - -[tabletags-asciidoc] -bodydata=
    |
    -paragraph= - -[table] -
    - - -{colspecs} -{headrows#} -{headrows} -{headrows#} -{footrows#} -{footrows} -{footrows#} - -{bodyrows} - -
    {caption={table-caption} {counter:table-number}. }{title}
    -
    - -#-------------------------------------------------------------------- -# Deprecated old table definitions. -# - -[miscellaneous] -# Screen width in pixels. -pagewidth=800 -pageunits= - -[old_tabledef-default] -template=old_table -colspec= -bodyrow=| -headdata=| -footdata=| -bodydata=| - -[old_table] -
    - - -{colspecs} -{headrows#} -{headrows} -{headrows#} -{footrows#} -{footrows} -{footrows#} - -{bodyrows} - -
    {caption={table-caption}}{title}
    -
    - -# End of deprecated old table definitions. -#-------------------------------------------------------------------- - -[floatingtitle] -{title} - -[preamble] -# Untitled elements between header and first section title. -
    -
    -| -
    -
    - -# Document sections. -[sect0] -{title} -| - -[sect1] -
    -{numbered?{sectnum} }{title} -
    -| -
    -
    - -[sect2] -
    -{numbered?{sectnum} }{title} -| -
    - -[sect3] -
    -{numbered?{sectnum} }{title} -| -
    - -[sect4] -
    -{title} -| -
    - -[appendix] -
    -{numbered?{sectnum} }{appendix-caption} {counter:appendix-number:A}: {title} -
    -| -
    -
    - -[toc] -
    -
    {toc-title}
    - -
    - -[header] - - - - - - - - -i3: {title} -{title%}i3: {doctitle=} - -ifdef::linkcss[] - -{doctype-manpage} -ifdef::quirks[] - -endif::quirks[] - -ifdef::pygments[] -endif::linkcss[] -ifndef::linkcss[] - -endif::linkcss[] -ifndef::disable-javascript[] -ifdef::linkcss[] - - -endif::linkcss[] -ifndef::linkcss[] - -endif::linkcss[] -endif::disable-javascript[] -ifdef::asciimath[] -ifdef::linkcss[] - -endif::linkcss[] -ifndef::linkcss[] - -endif::linkcss[] -endif::asciimath[] -ifdef::latexmath[] -ifdef::linkcss[] - -endif::linkcss[] -ifndef::linkcss[] - -endif::linkcss[] -endif::latexmath[] -{docinfo1,docinfo2#}{include:{docdir}/docinfo.html} -{docinfo,docinfo2#}{include:{docdir}/{docname}-docinfo.html} - - -
    - - -
    -
    - -# Article, book header. -ifndef::doctype-manpage[] - -ifndef::notitle[

    {doctitle}

    ] -ifdef::doctitle[] -{author}
    -<{email}>
    -version {revnumber}{revdate?,} -{revdate} -
    {revremark} -endif::doctitle[] -ifdef::toc[{template:toc}] - -endif::doctype-manpage[] -# Man page header. -ifdef::doctype-manpage[] -

    -{doctitle} Manual Page -

    -ifdef::toc[{template:toc}] -

    {manname-title}

    -
    -

    {manname} - - {manpurpose} -

    -
    - -endif::doctype-manpage[] - -[footer] -
    -{disable-javascript%

    } - - - - -ifdef::doctype-manpage[] -[synopsis] -template::[sect1] -endif::doctype-manpage[] - -ifdef::quirks[] -include::{backend}-quirks.conf[] -endif::quirks[] From 1df4de06d046f80ca96ccb0210f31a0be78cdb81 Mon Sep 17 00:00:00 2001 From: Sander De la Marche Date: Tue, 22 Dec 2020 18:56:13 +0100 Subject: [PATCH 6/6] Fix debugging man page --- _docs/{.adoc => debugging.adoc} | 0 docs/debugging.html | 300 ++++++++++++++++++++++++++++++++ 2 files changed, 300 insertions(+) rename _docs/{.adoc => debugging.adoc} (100%) create mode 100644 docs/debugging.html diff --git a/_docs/.adoc b/_docs/debugging.adoc similarity index 100% rename from _docs/.adoc rename to _docs/debugging.adoc diff --git a/docs/debugging.html b/docs/debugging.html new file mode 100644 index 0000000..d871d3d --- /dev/null +++ b/docs/debugging.html @@ -0,0 +1,300 @@ + + + + + + + + +Debugging i3: How To + + + + +
    +
    +
    +
    +

    This document describes how to debug i3 to send us useful bug +reports, even if you have no knowledge of C programming.

    +
    +
    +

    Thank you for being interested in debugging i3. It really means +something to us to get your bug fixed. If you have any questions about the +process and/or need further help, do not hesitate to contact us!

    +
    +
    +
    +
    +

    Verify you are using i3 ≥ 4.19

    +
    +
    +

    Only the latest major version of i3 is supported. To verify which version +you are running, use:

    +
    +
    +
    +
    $ i3 --moreversion 2>&- || i3 --version
    +Binary i3 version:  4.7 (2013-12-22, branch "tags/4.7")
    +Running i3 version: 4.7-84-gac74a63 (2014-01-01, branch "next") (pid 1995)
    +
    +
    +
    +

    Your version can look like this:

    +
    +
    +
    +
    4.7 (release version)
    +
    +

    You are using a release version. In many cases, bugs are already +fixed in the development version of i3. Even if the bug is not a known fixed +one, we will still ask you to reproduce your error with the most recent +development version of i3. Therefore, please upgrade to a development version +if you can.

    +
    +
    4.7-85-g9c15b95 (development version)
    +
    +

    Your version is 85 commits newer than 4.7, and the git revision of your +version is 9c15b95. Go to https://github.com/i3/i3/commits/next and see if +the most recent commit starts with the same revision. If so, you are using the +latest version.

    +
    +
    +
    +
    +

    Development versions of i3 have logging enabled by default and are compiled +with debug symbols.

    +
    +
    +
    +
    +

    Enabling logging

    +
    +
    +

    If you are using a development version (see previous section), you don’t need +to do anything — skip to section 3.

    +
    +
    +

    If you are using a release version with a custom ~/.xsession (or xinitrc) +file, execute i3 with a line like this:

    +
    +
    +
    +
    # Use 25 MiB of RAM for debug logs
    +exec i3 --shmlog-size=26214400
    +
    +
    +
    +

    If you are NOT using an ~/.xsession file but you just chose "i3" from the +list of sessions in your desktop manager (gdm, lxdm, …), edit +/usr/share/xsessions/i3.desktop and replace the Exec=i3 line with:

    +
    +
    +
    +
    Exec=i3 --shmlog-size=26214400
    +
    +
    +
    +

    If you cannot restart i3 for some reason, you can enable debug logging on the +fly:

    +
    +
    +
    +
    i3-msg 'debuglog on; shmlog on; reload'
    +
    +
    +
    +
    +
    +

    Reproducing the problem

    +
    +
    +

    Before submitting an issue, please make sure to close down on the problem as +much as you can yourself. Here are some steps you should consider:

    +
    +
    +
      +
    • +

      Find a deterministic, reliable way to reproduce the problem and provide it +with your bug report.

      +
    • +
    • +

      Try using the default i3 config to reproduce the problem. If the issue does +not appear with the default config, gradually adapt it to track down what +change(s) to the config introduce the problem.

      +
    • +
    • +

      Reproduce the problem with a minimal setup, i.e., only use as few applications, +windows and steps as necessary.

      +
    • +
    • +

      In addition, try to stick to applications that are common and, even more +importantly, free / open source.

      +
    • +
    • +

      Before obtaining the log file, restart i3 in-place, execute the steps to +reproduce the problem and then save the logs. This keeps the log file as +small as possible and necessary.

      +
    • +
    +
    +
    +

    Please be aware that we cannot support compatibility issues with closed-source +software, as digging into compatibility problems without having access to the +source code is too time-consuming. Additionally, experience has shown that +often, the software in question is responsible for the issue. Please raise an +issue with the software in question, not i3.

    +
    +
    +
    +
    +

    Obtaining the debug logfile

    +
    +
    + + + + + +
    +
    Caution
    +
    +
    +

    Logs may contain sensitive information, so please inspect the log before +submitting it. Logs may be viewed by anyone, once posted. If you choose to +redact the log, make an effort not to discard information which may be relevant +to the issue you are reporting.

    +
    +
    +

    The best way to avoid submitting such information is to only run the necessary +steps to reproduce the behavior when saving the log file. This will also make +analyzing the log file easier.

    +
    +
    +
    +
    +

    No matter whether i3 misbehaved in some way without crashing or whether it just +crashed, the logfile provides all information necessary to debug the problem.

    +
    +
    +

    To upload a compressed version of the logfile (for a bugreport), use:

    +
    +
    +
    +
    DISPLAY=:0 i3-dump-log | bzip2 -c | curl --data-binary @- https://logs.i3wm.org
    +
    +
    +
    +

    This command does not depend on i3 (it also works while i3 displays +the crash dialog), but it requires a working X11 connection.

    +
    +
    +

    After running it, you will get a URL to the logfile. Please include that URL in +your bug report.

    +
    +
    +
    +
    +

    On crashes: Obtaining a backtrace

    +
    +
    +

    When i3 crashes, it will display a dialog stating “i3 just crashed”, offering +you to save a backtrace to a text file.

    +
    +
    +

    To actually get useful backtraces, you should make sure that your version of i3 +is compiled with debug symbols:

    +
    +
    +
    +
    $ file `which i3`
    +/usr/bin/i3: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically
    +linked (uses shared libs), for GNU/Linux 2.6.18, not stripped
    +
    +
    +
    +

    Notice the not stripped, which is the important part. If you have a version +which is stripped, please check whether your distribution provides debug +symbols (package i3-wm-dbg on Debian for example) or if you can turn off +stripping. If nothing helps, please build i3 from source.

    +
    +
    +

    Once you have made sure that your i3 is compiled with debug symbols and the C +debugger gdb is installed on your machine, you can let i3 generate a +backtrace in the crash dialog.

    +
    +
    +

    After pressing "b" in the crash dialog, you will get a file called +/tmp/i3-backtrace.%d.%d.txt where the first %d is replaced by i3’s process +id (PID) and the second one is incremented each time you generate a backtrace, +starting at 0.

    +
    +
    +
    +
    +

    Sending bug reports/debugging on IRC

    +
    +
    +

    When sending bug reports, please attach the whole log file. Even if you think +you found the section which clearly highlights the problem, additional +information might be necessary to completely diagnose the problem.

    +
    +
    +

    When debugging with us in IRC, be prepared to use a so-called nopaste service +such as https://pastebin.com because pasting large amounts of text in IRC +sometimes leads to incomplete lines (servers have line length limitations) or +flood kicks.

    +
    +
    +
    +
    +

    Debugging i3bar

    +
    +
    +

    To debug i3bar problems, use the --verbose commandline parameter, +or add verbose yes to all bar {} blocks in your i3 +config, reload your config and then restart all i3bar instances like this:

    +
    +
    +
    +
    $ i3 reload
    +$ killall i3bar
    +$ for c in $(i3-msg -t get_bar_config | python -c \
    +      'import json,sys;print("\n".join(json.load(sys.stdin)))'); do \
    +    (i3bar --bar_id=$c >i3bar.$c.log 2>&1) & \
    +  done;
    +
    +
    +
    +

    There will now be i3bar.*.log files in your current directory that you can provide +in your bug report.

    +
    +
    +
    +
    + + + \ No newline at end of file