After the initial proof of concept of the shotman rewrite, my next goal was to have an implementation that could fully replace the previous version for daily usage.
My main use of shotman is “take screenshot of current window”, and I have two other (less frequent) use cases. They are all mapped to global hotkeys:
- Super+p to screenshot the current window.
- Super+Shift+p to screenshot a region.
- Super+Ctrl+p to screenshot the entire output.
There’s no “take screenshot of another window” use-case, since I can just focus that other window and then take the press Super+p.
As I’d mentioned before, there’s currently no Wayland API to request a screenshot of the current window – actually, “current window” is somewhat of a vague term. On a single-user desktop system, it’s obviously the focused window, but on a non-desktop or multi-user system it’s not as obvious. An API to take a screenshot of a specific window is also not yet available, although this is currently under discussion and I plan on switching to it once it’s been stabilised and implemented.
In the meantime, I’m using
swaymsg to determine the position of the currently
focused window, and merely capturing a screenshot of that on-screen region. A
small caveat is that this will also capture any partially overlaid window in
that region. It also works only on
sway, and not other compositors, but I
hope to improve on this when the above proposal has been stabilised (I don’t
expect this to be too soon though).
There’s also no standard wayland API to take a screenshot of the current output; there’s only an API to take a screenshot of a single output, but the output must be explicitly specified by the application. Again, the concept of “current output” is obvious on a desktop/laptop, but vague on other systems (e.g.: a car’s HUD which has multiple displays but no “currently focused” one). Shotman targets desktops/laptops and my intent is to support phones and tablets in futures, but cars are definitely out of scope.
For now, I’m using a bit of a hack. The thumbnail window already renders on the current output. Technically, this is the “preferred output”, which on desktop compositors usually matches “the currently focused output”. Since I can determine the preferred output for rendering the thumbnail window, I can request a screenshot of that same output. It works, and there’s not obvious pitfalls, despite it being a hack. I’ve suggested the idea of extending the existing API to support capturing the preferred output (without requiring hacks to determine it myself), but it’s still unclear whether this will happen or not.
The screencopy protocol is also being standardised beyond just wlroots compositors, and I’ve mirrored the same request there.
To screenshot a region, the user is expected to pick that region. I’ve used
slurp for this, since it works perfectly for this use-case, and has
nothing sway-specific (it should work on any compositor that implements the
layer-shell protocol, which we already require anyway).
Results so far
After finalising the changes to make this usable, I’ve tagged version 0.2.0, and switched to using it myself for my daily screenshot needs. I’m sure I’ll encounter bugs soon and will address then as I find them.
The speed difference is undeniable, and it’s mainly because shotman does extremely little work, and copies data around as little as possible.
There’s still quite a few code smells that need to be fixed. It’s mostly good hygiene and nothing that would have obvious issues, but some further (quite minor) optimisations are still possible.
In future, I want to add buttons for actions (which are currently are all keybord-only). This is mostly for touch-displays, and once I’ve added these, I’ll start experimenting on how this works on postmarketOS.
For more details on shotman and how its usage, see the README at the project’s repository:
Want to sponsor my work? See this page for details.