Age | Commit message (Collapse) | Author |
|
There's still assumptions that everything in the hierarchy fits
within the canvas... the Xlib stuff would clip all this behind
the scenes, but vcr/headless mode doesn't have such guard rails.
At some point I need to sit down and do a thorough pass in this
vein... Fortunately most my headless use cases have the canvas
configured appropriately.
|
|
When using vmon to monitor a system PID1 will kill it @
shutdown/reboot, and we should save one last snapshot of what's
been captured before we exit in that case.
SIGTERM is sent first before the SIGKILL killing spree, so let's
handle the SIGTERM by writing the snapshot, then exiting the main
loop.
The service manager can then do something with the produced
snapshots after we've exited, if they're considered interesting.
|
|
8 layers is no longer supported as a future expansion path...
|
|
These snuck in during the Xlib->vcr refactor which involved a lot
of copy-n-pasta taking Xlib sections from charts.c
|
|
This mostly works, but the maintenance of text shadows are a
gross naive conversion of the pre-nibbles code. It would
probably be better to add the shadows @ mem->png serialization
time and not bother maintaining them at all for headless.
It seems to work well enough to exercise and evaluate memory
footprints though...
The reason for "nibbles" is to save memory. Prior to this, the
mem backend would use a byte per pixel of layer information. By
not storing the background layer in this space, the current set
of layers used can fit in 4 bits (aka a nibble).
So this commit pivots to packing two pixels worth of layer data
into each of those bytes, effectively cutting the memory
requirements of the mem backend (headless mode) in half.
It matters for embedded use cases. The next step from here to
use substantially less memory in headless mode would require a
deeper refactor where we don't maintain a bitmap style
representation at all. It's doable, but not in the cards for my
free time right now.
|
|
--wip-name sets a constant name to use for the pre-rename temp
name of snapshots.
Otherwise a dynamic dot-filename augmented from the destination
name is used.
The impetus for this is to simplify garbage collection of
produced PNGs. We'll ignore dot-files to never step on the WIP
file during GC, but would like vmon to truncate and reuse the
same WIP name so it's not potentially accumulating the dot-files
in weird failure modes where the snapshots repeatedly fail to
complete and get renamed.
So in such a scenario we'll pass a dot-file for --wip-name and
vmon will keep reusing that name, never leaking more than the
single WIP file in even a persistent a failure mode.
|
|
cosmetic change; insert a space after the "#" in the string used
when comm/argv can't be sampled
|
|
Much of this stuff is pretty sloppy ever since it was first
written as a casual experiment. Fixup types to use
size_t/ssize_t where appropriate, and free the actual realloc'd
member of the char_array struct - the container struct with the
assumption that the member is at the struct start.
|
|
|
|
|
|
This switches to constructing the WIP png in a temporary dot-file
derived from the final name, then an atomic rename from the
dot-file to the final name. The temporary name is placed in the
same directory as the final one.
|
|
|
|
This upsets clang in particular, mechanical type substitution.
|
|
proc->stores is always allocated as part of vmon_proc_t, so this
can't possibly be NULL. IIRC an earlier form of libvmon
allocated the stores array lazily once needed.
|
|
There's no children processes expected for threads, and the
sampler assumes this is the case - but let's assert it holds
true.
|
|
Clarify the naming here so it's more obvious this only applies to
the single-pass mode (!VMON_FLAG_2PASS && !VMON_FLAG_PROC_ARRAY).
|
|
libvmon's internal api for samplers is extremely ad-hoc and
implicit.
This was done at the time to keep the source compact and have the
sampler ctor/dtor branches commingled immediately adjacent to
eachother... the thinking being this would help keep them in sync
as the code evolved. The ctor branches generally open fds and
allocate resources, with the dtor intended to undo those things.
With them kept more or less in the same page of code, it /should/
be obvious when one changes the other must as well.
In the long-term it probably makes sense to just explode this api
to something more formal and step back from those assumptions.
In lieu of doing such a refactor, let's improve the situation by
asserting the return codes at least stay within the expected
range. i.e. let's abort when a sample_changed/unchanged/error
return code comes from an dtor invocation, since this implies a
program error where someone isn't handling the implicit dtor
branches properly, instead falling through sampling paths.
|
|
Mechnical fix of longstanding typo I'm tired of ignoring...
|
|
Funny how long one can ignore something like this in their window
manager when X resources are in play, plus having 16G RAM helps.
|
|
It's actually pretty useful to see the relative PID values
across snowflakes...
|
|
Part of the reason for adding headless support in vmon is to
facilitate embedded use cases. These are often incompatible with
anti-tivoization aspects of gplv3.
I am the copyright holder of all this stuff so it's entirely fine
to switch to gplv2. Phil Freeman contributed one trivial patch
(4183fbd), regardless I checked if he had any objections to the
gplv2 switch and he had none.
So here we go, gplv2 all the things.
|
|
|
|
This avoids a bunch of pread() returning 0 EOF-finding calls.
These are proc files, and actually shouldn't be getting read in a
loop like this at all because it's racy to do so. With proc
files you need to atomically read everything you wish to parse as
one sample as an atomic unit.
So this needs to be properly reworked to enlarge the buffer when
a read exhausts it, throwing away what was read, then repeating
the sample with the enlarged buffer.
But this is tenable for now until I get around to the proper
rework... just looking to reduce some sampling overheads on lower
end embedded devices.
|
|
This causes snapshot filenames to always get the current time
instead of the start time of the vmon session
|
|
Takes a number of seconds interval argument, arranges for an
interval timer to trigger the sigusr1 handler which causes a
snapshot to be generated.
e.g. `./vmon --snapshots 1` will produce a .png per second
|
|
|
|
This isn't currently very discoverable, and without mention of it
one is likely to just try sending SIGCHLD to vmon for snapshots.
|
|
I don't use these, this isn't really the way vwm is intended to
be used.
For launching higher-order applications that don't need special
wm integrations like recordMyDesktop, or just aren't launched
numerous times daily (like xterm, or xlock), the user is expected
to just use the "console" screen session's available shell to do
things like `firefox &` or `gimp &`... these things aren't
generally started hundreds or thousands of times per day like say
xterm where the launcher shortcut pays clear dividends.
xterm itself in vwm is also used as a sort of throwaway launcher
window. Since everything is kept in MRU order it really doesn't
matter that you've got tons of xterms littering the environment
in contexts/virtual-desktops you just never visit after using
them to launch the thing you are using.
|
|
This requires a current recordMyDesktop build supporting
--need-shortcuts which was just added for this use case.
You can omit --need-shortcuts to support older rmd versions, but
this is leaning on --need-shortcuts to prevent multiple rmd
instances from accidentally being executed concurrently. Also
the shortcuts are expected to be how one pauses/stops the
capture, no vwm-level integration has been added to signal the
process for this purpose.
The default shortcut in rmd for stopping is ctrl+mod1+s which
doesn't collide with vwm's grabs, so everything Just Works.
You can utilize the vwm process monitors as a convenient way to
observe rmd's status in terms of encoding after stopping a
capture. You can see the reduced Idle %age in the top row during
the encode, it'll go back to normal when completed. Or you can
focus the vwm console (the attached screen session) and actually
observe the rmd output to watch the encoding progress - one of
the advantages of vwm's console. Furthermore, you can also
observe the CPU use of recordMyDesktop in that window with the
monitors active.
The key bindings as of now are:
Mod1+Backspace: record the focused window (root window if there
are no windows / empty desktop is focused)
Mod1+Delete: record the whole desktop / root window, even if
there are windows focused, unlike Backspace which will capture
just the focused window if there are windows.
As-is this doesn't specify --full-shots, so it's always in
damage-tracking mode, which might not work well with OpenGL style
captures. There needs to be a way to specify variants in
launchers.def with modifiers, then there could be a +Shift
variant for these where --full-shots is added, or something.
Ideally there should be a pop-up dialog where you get an
opportunity to manipulate the flags passed on from a set of
options, but I'm not doing that right now. That way we could
toggle stuff like sound/no-sound, tweak the FPS rate, toggle
full-shots/damage-tracking, sound/video quality, etc. Maybe it's
best to just use an rmd front-end for that, but it feels like
it'd be nice for vwm to just have a generic little dialog
mechanism for launchers, then launchers.def could describe the
parameterized args for the dialog to present controls for.
^^ TODO
|
|
This borrows from vmon.c to support argument interpolation.
The only interpolation supported right now is %W for a hex
windowid of the focused window.
When no window is focused, the id of the root window is supplied.
This is a preparatory commit for rmd integration
|
|
There needs to be a bunch of this throughout the codebase, but
just doing this spot fix to silence warnings introduced by
subsequent commits... preparatory commit for rmd integration
|
|
|
|
It doesn't look like the /bin/sh -c style invocation is going
away anytime soon, so let's just rely on the PATH searching and
this becomes more tolerant of stuff being in /usr vs. /usr/local
etc. (preparatory commit for rmd integration)
|
|
Now you can explicitly set 0Hz for the monitoring, instead of
hitting a pile of Mod1+Left to get there. Leaving the blind
hammering on Mod1+Left to just lower the frequency to 1Hz rather
than disabling it.
|
|
It's nice to be able to blindly hit Mod1+Left a bunch to minimize
the monitoring overhead, like when trying to preserve battery
etc. But I've found myself sometimes annoyed that I've
completely disabled the monitors when I reach for the overlays.
This change removes the 0Hz option from the preset intervals, so
now when you lower monitoring by blindly hitting Mod1+Left a
bunch it'll bottom out at 1HZ.
A subsequent commit will wire up disabling the monitors to an
explicit vwm key combo (probably Mod1+z).
|
|
vmon steps on this edge case, in vwm it was largely benign
since nothing ever happens immediately at vwm startup.
But in vmon you do things monitor commands which might
immediately send SIGUSR1 to vmon for .png snapshots, producing an
empty .png because the first update didn't sample because the
time delta hadn't passed.
This change just maintains a "primed" charts flag to ensure the
initial charts update always samples. This way if got_sigusr1 is
already set on the first iteration, at least the first charts
update will have sampled and composited *something*.
|
|
When this code changed to use a local, potentially heap-allocated
name variable, it started producing "(null)" when no -n/--name
was supplied, that wasn't intended.
Just use a "" name when NULL, enabling bare date-derived snapshot
filenames. This seems preferable since even if you supplied an
empty -n/--name you'd get a hyphen at the start of the name. I
can see scenarios where you have unnamed files labeled by the
output dir instead.
|
|
I don't think I intended this to be permanent, though it might be
nice to have /something/ printed to signify the transition to
breaking the main loop. Something more appropriate can come back
if necessary.
|
|
vmon already handles SIGUSR1 for producing png snapshots on
demand, adding a fmt specifier for substituting the vmon PID
makes for convenient scripting of triggering such snapshots.
i.e:
$ vmon -- /bin/bash -c 'for((i = 0; i < 10; i++)); do kill -USR1 %P; sleep 1s; done'
Would produce ten png snapshots of the charts on 1-second
intervals.
|
|
When the context has a lone desktop, attempting a migrate to the
next MRU desktop does nothing.
This change treats the situation exceptionally and creates a new
desktop in the context for receiving the migrated window, as it's
likely the desired result.
|
|
This adds runtime expansion of the executed command's argv, to
support things like passing the vmon X window id to the executed
command, session name, and output dir.
Format specifiers currently supported by this commit:
%W X window id for vmon in hexadecimal
%n verbatim name supplied via --name
%N filename-safe variant of name supplied via --name
%O output directory supplied via --output-dir (or ".")
%% literal %
There's not curerrently any escaping syntax implemented, relying
entirely on %-stuffing to escape interpolation. i.e. use %%N to
express %N post-interpolation.
This commit also adds SIGINT and SIGQUIT handlers when executing
a command. The first such signal received is simply propagated
to the child command's process, which upon exiting will trigger
the existing SIGCHLD behavior (snapshot if requested, exit).
If a subsequent repeated SIGINT or SIGQUIT is received, an abrupt
exit is performed without waiting for SIGCHLD or otherwise
synchronizing with the child process.
The impetus for this is to enable running recordMyDesktop
alongside the executed command to record the vmon window while
running things like benchmarks or other high-level profiling/CPU
usage over time observations.
The recordMyDesktop utility already responds to SIGINT for ending
a recording, so SIGINT propagation should be sufficient for
recording vmon sessions - provided the recordMyDesktop process is
positioned to receive signals in the executed command. i.e. is
the foreground process or session leader if executed via
something like a `/bin/bash -c` construction.
Some effort has been made to ensure the vmon window is mapped
before running the executed command (XMapWindow() && XSync()).
But with SubstructureRedirect in play, as when a window manager
is active, this alone isn't sufficient to ensure the window is
actually mapped and viewable.
This poses a problem with for the current `recordMyDesktop
--windowid` implementation, which hard fails when the specified
window isn't already mapped and visible. Depending on who wins
the race, the window may not yet actually be mapped by the window
manager by the time recordMyDesktop queries its attributes. But
this is something to fix in recordMyDesktop, even if vmon waited
for a MapNotify event before executing the command, the window
could become unmapped by the window manager - or maybe it
wouldn't even become mapped in a timely fashion if it's placed on
a hidden virtual desktop at the time. The recording tool needs
to just be more robust in this regard, and should really follow
the window around anyways, as well as do things like maybe pause
the recording when unmapped, etc. Out of scope for vmon.
The aforementioned `recordMyDesktop --windowid` race has been
filed as an issue @
https://github.com/recordmydesktop/recordmydesktop/issues/7
|
|
Just expanding the heuristic to everything >= fullscreen instead
of precisely fullscreen. The specific impetus for this was
fullscreen games, but from a security standpoint it makes sense
to manage everything larger as well.
|
|
Now vwm ignores override_redirect for fullscreen windows.
|
|
Preparatory commit for applying a heuristic to honoring
override_redirect.
The X11 specification more or less requires honoring this window
flag, but it's really a disaster to blindly do so.
This function will be used to evaluate override_redirect wherever
it's currently being directly used to determine wether a window
should be managed or not.
As-implemented it only ignores override_redirect when the window
dimensions match its screen dimensions (fullscreen windows). In
the future this might get loosened up a bit to encompass windows
covering more than something unexpectedly large for a
tooltip/popup, like 50% of the screen, since valid
override_redirect uses should arguably be limited to small
windows.
|
|
Once upon a time names were going to be added, but that never came
to be and at some point that unused member was removed. Turns out
-DTRACE builds have been broken since.
|
|
Lack of any statement angers some compilers, just drop it.
|
|
the non-empty focused_desktop having NULL focused_window shouldn't
be possible, but it just happened to me again while playing with
eon's WIP windowed/fullscreen/fillscreen tristate branch.
Though exceedingly rare, it's annoying, so log the bug and don't crash.
|
|
Since libvmon samples the sys_wants before proc_wants, it's
entirely possible the proc_stat->start will be later than
sys_stat->boottime by the time a given process gets sampled.
Simply treat this analogous to being unable to sample the start,
either of which will only leave the Wall as ??s in the highly
ephemeral short-lived process scenario. In the > boottime case,
the next sample for the same process would have start <= boottime
|
|
Tidying some vestigial cruft from the pre-VWM_COLUMN* transition,
still feels relatively crufty and fragile, but this is about all I
have time for spending on this at the moment...
|
|
This adds an externally triggered means of snapshotting, which
is always available, not only with --snapshot.
|