monochromatic

monochromatic blog: http://blog.z3bra.org
git clone git://z3bra.org/monochromatic
Log | Files | Refs

you-are-the-wm.txt (9460B)


      1 # [You are the WM](#)
      2 ## — 08 January, 2015
      3 
      4 A window manager is a program that runs in the background, and give you keybinds
      5 and/or mouse moves to move/resize and arrange your windows on your screen.
      6 
      7 Abbreviated "WM", the window manager is an important part of your system,
      8 because without it, you'd probably end up with all your windows pop in the
      9 bottom left hand-corner of your screen, unable to switch between them.
     10 
     11 But guess what...
     12 
     13 ### You don't need it !
     14 
     15 It's a fact. A
     16 [study](http://www.nytimes.com/2005/01/11/health/11anim.html) determined that
     17 some rat could be able to determine which language you are speaking. But that's
     18 totally unrelated here, I agree.
     19 
     20 What is a window manager ?
     21 
     22 <q>It's a program !</q> woah. Thank you Timmy.
     23 
     24 A window manager is a program (thank you Timmy) that runs in the background, and
     25 wait for X events (I wont talk about wayland here).  Those X events can be of
     26 any form: key press, window creation/deletion, mouse move, and so on.
     27 
     28 The most used events being the keypress events, because the window manager will
     29 perform different actions to arrange your windows.
     30 
     31 With [dcat](http://vps.iotek.org/~dcat), we realized that some programs (sxhkd,
     32 xbindkeys and others) already handle those events, and could start programs when
     33 receiving them. Following the Ô so true Unix way, we decided to create a set of
     34 small tools to perform all the task a window manager is supposed to do.
     35 
     36 We ended up with [wmutils](http://github.com/wmutils/core).
     37 
     38 ### Coreutils, for Xorg
     39 
     40 `wmutils` stands for "window **manipulation** utilities".
     41 
     42 This project aims to provide all the tools needed to manage a list of X windows,
     43 while keeping each tool as simple as possible, so that they can easily be glued
     44 together to create complex behaviors.  
     45 Using wmutils, you can list windows, move/resize/teleport them, change their
     46 borders, change their visibility, stacking order, ignore them, focus them, and
     47 more... Its power reside in its simplicity. As you can chain commands together,
     48 you could easily perform some action that other WM can't even do.
     49 
     50 For example, here is how you kill all the windows that are not shown on screen
     51 (eg, attached to other workspaces):
     52 
     53     lsw -u | xargs killw
     54 
     55 Put a window in the top-left corner ? pff. easy:
     56 
     57     wtp 0 0 $(wattr whi `$pfw`)
     58 
     59 bottom-left corner ?
     60 
     61     wid=$(pfw)
     62     w=$(wattr w $wid)
     63     h=$(wattr h $wid)
     64     fh=$(wattr h `lsw -r`)
     65 
     66     wtp 0 $((fh - h)) $(wattr whi $wid))
     67 
     68 You get the idea. As a matter of fact, the following as been done using ONLY\*
     69 wmutils tools:
     70 
     71 [![gif showing floating
     72 mode](http://pub.z3bra.org/monochromatic/img/thumb/floater.gif)](http://pub.z3bra.org/monochromatic/img/floater.gif)
     73 [![gif showing tiling
     74 mode](http://pub.z3bra.org/monochromatic/img/thumb/tiler.gif)](http://pub.z3bra.org/monochromatic/img/tiler.gif)
     75 
     76 <span class="caption">\*only exception is the use of x-move-resize from
     77 [no-wm](https://github.com/patrickhaller/no-wm), which is planned to be added to
     78 wmutils anyway)</span>
     79 
     80 Check out the "[contrib](http://github.com/wmutils/contrib)" repo. There are
     81 some nice scripts in there !
     82 
     83 Now throw your window manager away, you don't need it anymore. **YOU ARE THE WM
     84 !**
     85 
     86 **EDIT**
     87 --------
     88 
     89 I was asked on reddit to explain my wmutils setup. I gave a fairly
     90 detailed answer which might also be useful for others, so I figured out I could
     91 add it here (original comment [here](https://www.reddit.com/r/unixporn/comments/3b42zj/people_using_wmutils_how_do_you_use_it/csj8iq4))
     92 
     93 I Have both `wmutils/core` and `wmutils/opt` installed. I need the latter for
     94 `wew`, an X event watcher.
     95 
     96 MANAGING WINDOWS
     97 ----------------
     98 
     99 The central piece of my workflow is `sxhkd`. This is a software one can use to
    100 bind key combos to commands, or **scripts**. I use it both to start my
    101 applications, but also to manage my windows via `wmutils` tools, and scripts.
    102 For instance, here is the entry that let me move windows around the screen using
    103 the keyboard (`pfw` returns the ID of the currently focused window. It's a
    104 rather important piece of software!):
    105 
    106     # move windows around
    107     super + {left,down,up,right}
    108           wmv {-20 0, 0 20, 0 -20, 20 0} $(pfw)
    109 
    110     # resize windows
    111     super + alt + {left,down,up,right}
    112           wrs {-20 0, 0 20, 0 -20, 20, 0} $(pfw)
    113 
    114 That's for tools that can be bound "directly" via sxhkd. For more complex tasks,
    115 I use a few scripts of my own:
    116 
    117 + `vroum` - manage window focus
    118 + `groaw` - manage window groups
    119 + `focus` - finer way to focus windows
    120 + `corner` - move windows to screen's corner
    121 + `fullscreen` - put a window in fullscreen mode
    122 
    123 ### vroum
    124 
    125 It can take 3 arguments: "next, prev, $wid". "next" will focus the next
    126 window on the stack, previous will focus the previously focused window, and
    127 every argument starting by `0x` will be considered a window ID to be focused
    128 directly. It will also change the border of all the inactive windows, and the
    129 active window. I use this script to cycle between them:
    130 
    131     # cycle through windows
    132     alt {, + shift} + tab
    133         vroum {next, prev}
    134 
    135 ### groaw
    136 
    137 This is my "group" manager (think of it as workspaces on steroid). By
    138 default, new windows are not assigned any groups. Without much explaning how
    139 each flag works, I just need it to perform 3 tasks:
    140 
    141 1. add the current window to a specific group
    142 2. toggle visibility state of a specific group
    143 3. remove current window from all groups
    144 
    145 This result in the following entries:
    146 
    147     # add window to a group
    148     super + shift + {1,2,3,4,5}
    149         groaw -d all; \
    150         groaw -a {1,2,3,4,5}
    151 
    152     # toggle groups' visibility
    153     super + {1,2,3,4,5}
    154         groaw -t {1,2,3,4,5}
    155 
    156     # remove window from all groups
    157     super + Backspace
    158         groaw -d all
    159 
    160 ### focus
    161 
    162 A script I'm really proud of! It focus windows besed on their cardinal
    163 positions. It takes exactly 4 different arguments:
    164 
    165             north
    166               ^
    167               |
    168      west <---+---> east
    169               |
    170               v
    171             south
    172 
    173 It will then focus the nearest window in the given direction (using top/left
    174 edge of the window) It's bound like so
    175 
    176     # select windows using directions
    177     alt + {left,down,up,right}
    178           focus {west, south, north, east} $(pfw)
    179 
    180 ### corner
    181 
    182 There's nothing special about it. It put the window in the corner passed as
    183 argument (Top-Left, Top-Right, Bottom-Left, Bottom-Right, MiDdle)
    184 
    185     # move windows to corners
    186     super + {y,u,b,n,g}
    187         corner {tl, tr, bl, br, md} $(pfw)
    188 
    189 ### fullscreen
    190 
    191 Set a window in fullscreen mode (change its size to the size of the monitor, and
    192 remove borders. The previous position/size of the window is saved to a file, so
    193 when you disable fullscreen mode, or move another window in fullscreen, the
    194 window takes its old position back
    195 
    196     # set window fullscreen
    197     super + x
    198         fullscreen $(pfw)
    199 
    200 DEALING WITH EVENTS
    201 -------------------
    202 
    203 The above only applies to existing windows. But when a new window gets created,
    204 I need to run a few commands against it, to integrate it to my workflow. This is
    205 what `wew` is for. It prints X events to stdout, and the window ID the event
    206 applies to. For example:
    207 
    208     16:0x000c00ea
    209     19:0x000c00ea
    210 
    211 Event number 16 is "window creation", 19 is "mapping request". I have a parser
    212 script that will perform different actions depending on the fired event (it's
    213 called `yawee`, I like weird names):
    214 
    215 
    216     #!/bin/sh
    217 
    218     while IFS=: read ev wid; do
    219         case $ev in
    220             # window creation: center window on the screen (except docks, menus or similar)
    221             16) wattr o $wid || corner md $wid ;;
    222 
    223             # mapping requests: just set a special border for docks, menus and
    224             # similar. Focus other windows
    225             19) wattr o $wid \
    226                 && chwb -s 2 -c 0x323232 $wid \
    227                 || vroum $wid ;;
    228 
    229             # when a window gets deleted, focus another one
    230             18) wattr $(pfw) || vroum prev 2>/dev/null;;
    231 
    232             # Focus windows when the mouse cursor enter them
    233             7) wattr o $wid || vroum $wid ;;
    234         esac
    235     done
    236 
    237 In my `$HOME/.xinitrc`, it's started as:
    238 
    239     wew | yawee &
    240 
    241 Pretty straighforward :)
    242 
    243 USING THE MOUSE
    244 ---------------
    245 
    246 Nobody's perfect. I use the mouse from time to time to manage my windows. It is
    247 sometimes more efficient to get a window out of your way quickly, or resize one
    248 approximatively.
    249 
    250 For this purpose, I STILL use sxhkd! Baskerville did an amazing job with this
    251 software, as it support integer replacement of the mouse coordinate
    252 
    253     # move windows with the mouse:
    254     super + !button{1,3}
    255         {wmv, wrs} -a %i %i $(pfw)
    256 
    257 As simple as that!
    258 
    259 MISCELLANOUS
    260 ------------
    261 
    262 For eye candy purpose, I wrote a `pulsar` script, to make my currently active
    263 window standout. It make the window's border "pulse" like in the following
    264 video: [wall-border.webm](http://pub.z3bra.org/monochromatic/vid/wall-border.webm). It uses a `$HOME/.colors`
    265 file containing the colors to be used for the gradient. It will then run `chwb`
    266 at a regular interval to change the current window's borders.
    267 
    268 
    269 That's pretty much it! If you have any question, do not hesitate to ask.
    270 Also, sorry for the huge wall of text, I was trying to be as precise as
    271 possible.
    272 
    273 As a bonus, to congratulate you from reading it all, here is a video from my
    274 actual workflow with this setup (writing my latest blogpost:
    275 [(grab some popcorns, it's 57 minutes long)](http://pub.z3bra.org/monochromatic/vid/monochromatic-0x0017-writeup.webm)