summaryrefslogtreecommitdiff
path: root/README
blob: 588a45874d830eaf00cf57b58c7bc1507d419f30 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
                                    \/\/\

Modifiers:

  Mod1-r-             Modifies some desktop/context/window switching
                      operations to be reversed.  By itself is effectively
                      a noop.

                      Unlike the other modifiers, I haven't bothered
                      explicitly documenting -r's applicability below.
                      It's basically: Tab, Space, and `/Grave.

  Mod1-Shift-         Modifies many operations into "Migrates".  A migrate
                      is a focused desktop/context changing operation which
                      brings the currently focused window along.  By itself
                      is effectively a noop.

  Mod1-s-             Modifies window "Migrate" operations into "Send", by
                      itself is effectively a noop. (Was "shelve" window in
                      previous versions)

  Mod1-Shift-s-       Modifies some operations into a "Migrate"-like
                      "Send".  Where a plain "Send" tends to create a new
                      empty desktop for receiving the sent window, when
                      combined with Shift, an existing focused desktop at
                      the destination will be used to receive the sent
                      window, which is how migrates work, but unlike
                      migrate, no actual switching occurs.

                      These also haven't been explicitly documented below,
                      currently it's basically: `/Grave, and 0-9.


Built-in operations:

  Mod1-RClick         Focus the clicked window, but suppress raising.

  Mod1-RClick-drag    Focus the clicked window, suppress raising, resizing
                      the window from its nearest corner until drag
                      completes.

  Mod1-LClick         Focus and raise the clicked window.

  Mod1-LClick-drag    Focus and raise the clicked window, moving the window
                      until the drag completes.

* Mod1-l              Switch to virtual desktop to the right (if exists).

* Mod1-h              Switch to virtual desktop to the left (if exists).

  Mod1-j              Lower focused window, if the focused window is in
                      "allscreen" mode it will simply be fullscreened first
                      without lowering.

  Mod1-k [-k [-k]     Raise focused window [a second k raises and
          [-k] [-k]]  fullscreens the window [a third k raises and
                      "allscreens" without a visible border [a fourth k
                      raises and fullscreens across all heads [a fifth k
                      raises and "allscreens" across all heads]]].

* Mod1-Shift-k        Migrate the focused window to the next/upper context
                      (if exists), keeping the window focused.

* Mod1-Shift-j        Migrate the focused window to the previous/lower
                      context (if exists), keeping the window focused.

* Mod1-Shift-l        Migrate the focused window to the virtual desktop
                      to the right (if exists), keeping the window focused.

* Mod1-Shift-h        Migrate the focused window to the virtual desktop
                      to the left (if exists), keeping the window focused.

* Mod1-s-k            Send the focused window to the next/upper context's
                      focused desktop (if exists), keeping the window
                      focused in the destination, but without switching to
                      the destination.

* Mod1-s-j            Send the focused window to the previous/lower
                      context's focused desktop (if exists), keeping the
                      window focused in the destination, but without
                      switching to the destination.

* Mod1-s-l            Send the focused window to the virtual desktop
                      to the right within the same context (if exists),
                      keeping the window focused in the destination, but
                      without switching to the destination.

* Mod1-s-h            Migrate the focused window to the virtual desktop
                      to the left within the same context (if exists),
                      keeping the window focused in the destination, but
                      without switching to the destination.

  Mod1-v              Create a new empty virtual desktop within the current
                      context and switch to it.

  Mod1-Shift-v        Create a new virtual desktop within the current
                      context and switch to it, bringing the currently
                      focused window along (if present).

  Mod1-s-v            Create a new virtual desktop within the current
                      context, send the focused window to it, but don't
                      switch to the new virtual desktop.

  Mod1-c              Create a new empty virtual desktop within the next
                      unused context, implicitly creating a new context,
                      and switch to it.

  Mod1-Shift-c        Create a new empty virtual desktop within the next
                      unused context, implicitly creating a new context,
                      and switch to it, bringing the currently focused
                      window along (if present).

  Mod1-s-c            Create a new empty virtual desktop within the next
                      unused context, implicitly creating a new context,
                      send the focused window to it, but don't switch to
                      the new virtual desktop/context.

  Mod1-0...9          Switch to the numbered context's focused desktop,
                      implicitly creating it if currently unused.

  Mod1-Shift-0..9     Switch to the numbered context's focused desktop,
                      implicitly creating it if currently unused, bringing
                      the focused window along (if present).

  Mod1-s-0..9         Send the focused window (if present) to a newly
                      created desktop within the numbered context.

* Mod1-Space          Switch to the next most recently used virtual desktop
                      within the current context (like Mod1-Tab but for
                      virtual desktops).

* Mod1-Shift-Space    Switch to the next most recently used virtual desktop
                      within the current context, bringing the focused
                      window along.

  Mod1-s-Space        Send the focused window to the next most recently
                      used desktop within the current context, keeping it
                      focused there, but without actually switching
                      desktops.

  Mod1-`              Switch to the next most recently used context's
                      focused virtual desktop.

  Mod1-Shift-`        Switch to the most recently used context's focused
                      virtual desktop, bringing the focused window along.

  Mod1-s-`            Send the currently focused window to a newly created
                      desktop within the next most recently used context,
                      without actually switching to it.

* Mod1-Tab            Focus and raise the next window in the current
                      virtual desktop, the focused window is not
                      'committed' as the MRU window until Mod1 is released,
                      so you may peruse intermediate windows without
                      affecting the MRU order until releasing Mod1.  In
                      multihead configurations the next window selection is
                      further confined to within the current screen+desktop.

  Mod1-Shift-Tab      Identical to Mod1-Tab except switches to the MRU
                      window on another screen in a multihead
                      configuration.

  Mod1-d              Request the client destroy the focused window, or
                      destroy the current virtual desktop when no windows
                      exist on it

  Mod1-Shift-d        XKillClient the focused window (useful for
                      misbehaving clients)

  Mod1-Enter          Alternate between full-screen and windowed dimensions
                      for the focused window

  Mod1-[ [-[]         Reconfigure the focused window to fill the left half
                      of the screen [ left bottom quarter of screen ]

  Mod1-] [-]]         Reconfigure the focused window to fill the right half
                      of the screen [ right top quarter of screen ]

  Mod1-Shift-[ [-[]   Reconfigure the focused window to fill the top half
                      of the screen [ top left quarter of screen ]

  Mod1-Shift-] [-]]   Reconfigure the focused window to fill the bottom
                      half of the screen [ bottom right quarter of screen ]

  Mod1-Semicolon      Toggle monitoring overlays (when active vwm becomes a
                      compositing manager, which is slower)

  Mod1-Apostrophe     Discard the "snowflakes" region of the focused
                      window's monitoring overlay

  Mod1-Right          Increase monitoring frequency (when overlays are
                      active, too high a frequency can overload X)

  Mod1-Left           Decrease monitoring frequency, the lowest setting
                      halts monitoring)

  Mod1-Esc-Esc-Esc    Exit vwm (if vwm is the child of your X server, X
                      exits too, so your X clients all lose their
                      connection and die.  However, your clients are
                      running under screen, and if your X server didn't
                      exit, they won't lose their X connection.)

  *'s above indicate commands which initiate an MRU-update to be committed
      on the next Mod1 release.  One may traverse windows and desktops
      without affecting their MRU order by returning to the original
      initiating window and/or desktop before releasing Mod1.  This permits
      one to do quite a lot of things under a single, long-duration Mod1
      press only committing to a potentially different focused
      window/desktop at the very end.

      Think of the Mod1 release as a transaction commit when coupled with
      the *'d commands.

      If a simultaneous second Mod1 is pressed at any point during a *'d
      command, the window (and its desktop) focused when the *'d command
      began will immediately be refocused - but not raised.  This is
      intentional to simplify the arranging of obscured focused windows.
      If you find yourself restored to a desktop full of windows where your
      focused window is totally obscured/invisible, simply press Mod1-k to
      raise it if desired.

      At any point during a *'d operation one may (re)press a second Mod1
      to return to the origin, it is not limited to a single use.

Default launchers (configure by editing launchers.def and rebuild):

  Mod1-x              xterm
  Mod1-b              iceweasel
  Mod1-g              gimp
  Mod1-.              xlock
  Mod1--              xset -dpms s off
  Mod1-=              xset +dpms s on


General:

  Newly created windows are raised but not focused unless they are the
  first window on an otherwise empty virtual desktop, then they are focused
  as well.

  When new windows appear on a non-empty virtual desktop, they are inserted
  immediately after the currently focused window in the windows list, so a
  Mod1-Tab will immediately focus new windows.  Windows are kept in a MRU
  (Most Recently Used) order, keeping it efficient to alternate between an
  evolving set of active windows.  Mod1-r-Tab, using r as a modifier, may
  be used to reverse the switching direction, handy for undoing an
  accidental overshoot.

  Like windows, virtual desktops are also kept on an MRU-ordered list.
  These are cycled through via Mod1-Space, created with Mod1-v, and
  destroyed with Mod1-d when empty.  As with windows, Mod1-r-Space may be
  used to reverse the switching direction.

  Virtual desktops are grouped by contexts.  Contexts are also kept on
  MRU-ordered lists, which are cycled through via Mod1-`, created with
  Mod1-c, and switched to by number with Mod1-0 through 9, which implicitly
  creates the switched-to context if needed.

  Prior versions of vwm included a "shelf" feature, this has been removed
  in favor of the more generalized contexts.  In the past Mod1-s would
  "shelve" a window, and Mod1-` would switch between the shelf and focused
  virtual desktop.  Now Mod1-s is a modifier for sending windows elsewhere,
  with one of the destinations being other contexts.

  The shelf was used as a sort of junk drawer for things like xterms
  running background processes without losing easy access to their
  interactivity/output, while not polluting the active virtual desktops.

  When vwm starts, it creates two contexts, numbers 0 and 1.  1 is what's
  focused on startup, with 0 intended to serve as the shelf equivalent.
  Now users may send windows to the shelf/junk drawer equivalent by
  pressing Mod1-s-0, or Mod1-Shift-s-0, the former creating a new virtual
  desktop for the sent window in context 0, the latter targeting the
  existing focused desktop in context 0.  Omitting the -s- from the former
  switches to the focused desktop in contetxt 0, from the latter migrates
  the focused window to the focused desktop in context 0.


Multihead/Xinerama:

  In multihead configurations, new windows are placed on the screen
  containing the pointer, if that screen is empty.  Should the pointer be
  on a non-empty screen, then new windows are placed on the screen
  containing the currently focused window.

  New windows will automatically be focused if the screen they were placed on
  is empty, even if their virtual desktop is not, which is a divergence from
  the single-headed behavior where only lone windows on virtual desktops are
  automatically focused.

  Things like Mod1-[, Mod1-], and mod1-k-k respect screen boundaries of the
  window's majority containing screen, and mod1-k-k-k mod1-k-k-k-k can be
  used to violate those boundaries for creating fullscreen/allscreen
  windows spanning multiple displays.
  
  Multihead support is currently very limited.  There's currently no
  builtin for things like migrating windows to different screens, which
  would be useful, especially for the mod1-[, mod1-], mod1-k-k style
  autoconfigured windows, since they could automatically reconfigure
  themselves migrating to different screen dimensions.  The best way to
  move windows to different screens is to Mod1-LClick-drag until the window
  is at least mostly within the destination screen.  At that point all the
  autoconfigure window builtins utilize the most-overlapped screen as the
  container.


Composite/Monitoring:

  One reason vwm was created was to provide a simplified platform for
  research and development of a window manager having integrated local
  process CPU utilization monitoring.  Early attempts were made to modify
  an existing window manager (WindowMaker) which produced unsatisfactory
  though inspiring results.  The window managers vwm[12] were created
  shortly after to flesh out the interaction model and solidify a tolerably
  usable and easily modified window manager foundation, while libvmon was
  created in parallel to facilitate the lightweight, high-frequency process
  monitoring required for such a task.

  After a number of iterations it was found that the Composite extension
  (along with the accompanying Damage and Render extensions) would give the
  best results on a modern Xorg linux system.  Compositing hurts the
  rendering performance of X applications significantly however, so a
  hybrid model has been employed.

  Monitoring overlays visibility is toggled using Mod1-Semicolon, the
  sample rate is increased using Mod1-Right, and decreased using Mod1-Left.

  When the monitoring is not visible, vwm3 continues to leave X in
  immediate rendering mode with no additional overhead in the rendering
  pipeline, just like vwm2.  The only additional overhead is the cost of
  regularly sampling process statistics and maintaining the state of window
  overlays (which does involve some X rendering of graphs and text, but
  does not introduce overhead to the drawing of client windows).

  When monitoring overlays are made visible vwm3 temporarily becomes a
  compositing manager, redirecting the rendering of all windows to
  offscreen memory and assuming the responsibility of drawing all damaged
  contents to the root window on their behalf.  This is what gives vwm3 the
  opportunity to draw alpha-blended contextual monitoring data over all of
  the windows, but it does come with a cost.

  Most modern GNU/Linux desktop environments are full-time composited,
  meaning all X clients are redirected at all times.  This makes their
  draws more costly and latent due to all the additional copies being
  performed.  Depending on how things have been implemented, in the
  interests of supporting things like transparent windows it also generally
  results in overlapping window regions being drawn repeatedly for every
  overlapping window from the bottom-up rather than just the top one.

  In vwm3 transparent windows are not supported, and shape windows (xeyes)
  are made rectangular in composited mode.  This is so overlapping regions
  are only drawn once for the top windows having damage per burst of screen
  updates.

  Immediate rendering mode is restored upon disabling the monitoring
  overlays, restoring the drawing performance to vwm[12] levels where vwm3
  is completely out of the drawing loop.

  Here are some relevant things worth noting:

  - The monitoring is only heirarchical if your kernel is configured with
    CONFIG_CHECKPOINT_RESTORE, which seems to be common nowadays.  This is
    required for the /proc/$pid/task/$tid/children files, which is what
    libvmon uses to efficiently scope monitoring to just the descendants of
    the explicitly monitored client precesses.

  - tmux orphans its backend process immediately at startup, discarding its
    parent->child relationship, so you don't get any monitoring of the
    commands running in your local tmux session.  Use GNU screen instead.

  - GNU screen orphans its backend on detach, so on reattach you've lost
    the parent->child relationship and find yourself in the same situation
    tmux puts you in immediately.  I've developed an adopt() system call
    patch for the linux kernel to enable adopting orphans in this
    situation, but it hasn't been accepted.  With this patch and a one line
    change to GNU screen the parent->child relationship is restored on
    reattach.

    You may find patches for adding the adopt() system call to Linux and
    its integration into GNU screen in the patches/ subdirectory.

  - The top row of the overlays shows:

     Total CPU Idle % (cyan):
      The height of every cyan vertical line reflects the %age of ticks
      since the previous sample which were spent in the idle task.
    
     Total CPU IOWait % (red):
      The height of every red vertical line reflects the %age of ticks
      since the previous sample which were lost to IO wait.  Many people
      don't understand this correctly.  This reflects opportunities to
      execute something other than the idle task which were lost because
      _all_ runnable tasks at the time were blocked in IO.

      An absence of IOWait does not mean nothing is blocked on IO.  It just
      means there weren't opportunities to execute something which were
      lost due to waiting on IO.

      For example, lets say you have a dual core machine, and you launch
      two "yes > /dev/null &" commands.  These two yes commands are
      essentially busy loops writing "yes" to /dev/null, they will always
      be runnable, and you will see a top row in the overlay devoid of any
      cyan _or_red_ while they execute.

      While they execute run something like:
      "sudo echo 2 > /proc/sys/vm/drop_caches && du /"

      Still no IOWait in the top row.  We know that du is blocking on IO,
      the caches are empty, but because there is always something runnable
      on the two cores thanks to the two yes commands, we'll never see
      IOWait.  The other runnable processes mask the IOWait from our
      visibility.

      Now kill the two yes commands and rerun the du command, watch the top
      row.  Some red should appear, the red indicates that there was CPU
      time available for running something, and the _only_ things available
      for that time was blocked in IO.  Had there something else runnable,
      we wouldn't see the time lost to IOWait.

      When you see IOWait time, it's just saying nothing executed for that
      time, not for lack of any runnable tasks, just that all runnable
      tasks were blocked.  It's still of value, but easily obscured on a
      system with any cpu-bound tasks constantly running.

  - The per-task (processes or threads) rows of the overlays show:

     User CPU % (cyan):
      The height of every cyan vertical line reflects the %age of ticks
      since the previous sample which were spent executing this task in the
      user context.

     System CPU % (red):
      The height of every red vertical line reflects the %age of ticks
      since the previous sample which were spent executing this task in
      kernel/system context.

     Task monitoring beginning and ending is indicated with solid and
     checkered vertical bars, respectively.  These generally coincide with
     the task clone and exit, but not always, especially the cloning.

  - You can pause sampling by lowering its rate (Mod1-Left) to 0Hz.  Just
    be aware that this also pauses the updating of the overlay contents, so
    window resizes won't be adapted to in the overlay until increasing the
    sample rate (Mod1-Right).  Pausing is useful if you've seen something
    interesting and would like to screenshot, study, or discuss.  BTW, to
    take a screenshot when composited you have to capture the root window.
    If you capture the client window, you won't get the overlays, you'll
    just get the redirected window contents.  Compositing mode composites
    everything into the root window, when you're interacting with the
    composited vwm3, you're looking at the root window the entire time.

  - The sample rate will automatically be lowered by vwm3 when it detects
    that it's having trouble maintaining the current one.  If you have many
    windows or have a slow or heavily loaded processor/GPU they can become
    bottlenecks, especially at higher sample rates.  Rather than continuing
    to bog down your X server (Xorg is not good at fairly scheduling
    clients under GPU contention), vwm3 will simply back off the sample
    rate as if you had hit Mod1-Left, to try ameliorate rather than
    exacerbate the situation.

  - The monitoring is implemented using sampling, not tracing.  Below the
    current process heirarchy for every window there is an exited tasks
    snowflakes section filling the remaining space.  Do not mistake this
    for something lossless like bash history or strace output, it's lossy
    since it's produced from sampled data.  In part to try avoid
    interpretation of these as a reliable process history I refer to them
    as snowflakes in the code, since they fall downwards and sideways.

    With sufficiently high sample rates the output starts to take on the
    appearance of tracing, and while it may happen to capture every process
    in slower executions, most automata will execute entire commands in the
    time between samples.  So try keep this in mind before thinking
    something's broken because you don't see something you expected in the
    snowflakes.

    Some artifacts you might notice due to this which are not bugs are:

     - "#missed it!"  being shown as the command name, this happens when
       libvmon caught the process but the process exited before libvmon
       caught a sample of the name.

     - A parent's command name in the child when a different command was
       executed.  In UNIX systems processes fork before execing the new
       command, in that window of time between the fork and exec, the child
       process is a clone of the parent, command and argv included.
       Sometimes the sample catches at just the right moment to see this in
       action.

     - Varying outputs in seeming identical actions.  Things like simply
       launching xterm may produce no snowflakes at all in the new xterm,
       or a few like "bash" "dircolors -b" and "utempter add :0",
       especially if you have the sample rate turned up and cause some load
       on the system to slow the xterm and interactive bash startup scripts
       down.
    
  - In the interests of being efficient, nothing is being logged
    historically.  The snowflakes area is all you get, which is limited to
    the free pixel space below the instantaneous process heirarchy within
    the window.

    Everything which falls off the edges of the screen is lost forever,
    with the exception of windows which have been made smaller than they
    were.

    You cannot scroll down or to the right to see older snowflakes or
    graphs.

    You cannot search the snowflakes.

    The native text and numeric representations of the sampled data is not
    kept any longer than the current sample, just long enough to update the
    overlays.  From that point on the information exists only as visualized
    pixels in the overlay layers with no additional indexing or
    relationships being maintained with the currently monitored state.

  - You can wipe the snowflakes of the focused window with Mod1-Apostrophe

  - The client PID is found via the _NET_WM_PID X property.  This must be
    set by the client, and not all clients cooperate (xpdf is one I've
    noticed).

    This is annoying especially considering the vast majority of X clients
    run on modern systems are local clients connected via UNIX domain
    sockets.  These sockets support ancillary messages including
    SCM_CREDENTIALS, which contains the pid of the connected process.  Some
    investigation into the Xorg sources found it already queries this
    information and has it on hand, but doesn't bother setting the
    _NET_WM_PID property even though it's well- positioned to do so.

    I've developed and submitted upstream a patch for Xorg which sets
    _NET_WM_PID on local connections, it complements vwm3 nicely.

    You can find the patch in the patches directory.

  - There are around 5 files kept open in /proc for every task monitored by
    vwm.  This applies to children processes and threads alike, so on a
    busy system it's not unrealistic to exceed 1024, a common default open
    files ulimit for GNU/Linux distributions.  You can generally change
    this limit for your user via configuration in /etc/security/limits.conf
    or /etc/security/limits.d/.


TODO finish and polish this readme...
© 2021 All Rights Reserved