You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Screen Toolkit] Hardcoded /tmp filenames cause cross-user Permission Denied errors on multi-user systems
#944
Plugin version: 1.3.3 (minNoctaliaVersion 4.5.0 per manifest.json)
Distro: CachyOS (Arch-based)
Compositor: Hyprland
Setup: 4 separate Linux user accounts on one machine, each with Screen Toolkit enabled independently
Summary
Capture, annotate, copy, save, and share all fail intermittently with a generic
"Screen capture failed" toast
depending on which user account last used the tool — not tied to any one
user's config.
Root cause
Several scripts and QML files write intermediate/output images to fixed,
non-per-user filenames under /tmp, e.g.:
/tmp/screen-toolkit-annotate.png
/tmp/screen-toolkit-annotate-pixel.png
/tmp/screen-toolkit-annotate-zoom.png
/tmp/screen-toolkit-overlay.png
/tmp/screen-toolkit-share.png
/tmp/screen-toolkit-palette.png
/tmp/screen-toolkit-qr.png
/tmp has the sticky bit set, so only a file's owner (or root) can
overwrite or delete it. On a multi-user system, whichever account used a
given tool most recently ends up owning that shared file — every other
account's next attempt at the same action then fails with a permission
error, since it can neither write over nor delete the existing file.
Evidence
The real error doesn't reach journalctl — Noctalia logs it internally
(readable via qs log -c noctalia-shell):
Failed to open file '/tmp/screen-toolkit-annotate.png' for writing: Permission denied
Where this shows up
scripts/capture.sh — annotate-window, pin, palette, and qr actions
Main.qml — the annotateProc/launchAnnotateFullscreen capture paths
overlays/Annotate.qml — imagePath property and the Copy / Save /
Save-overlay / Share-flatten flows (roughly 20 references across the
filenames above)
Steps to reproduce
Enable Screen Toolkit on two separate user accounts on the same machine
As user A, use annotate/pin/palette/qr/copy/save (any of the above) — succeeds
As user B, use the same action — fails with permission denied on the
collided /tmp file
Suggested fix
Use a genuinely per-user location instead of shared /tmp — e.g. Quickshell.env("XDG_RUNTIME_DIR") (/run/user/<uid>/, mode 0700,
already exclusive per user) in place of the hardcoded /tmp/... paths.
I patched just the plain-capture path locally (capture.sh + Main.qml's _grimGeometry flow) using this approach and confirmed it
resolves the collision for that path — happy to share the diff if useful,
though I didn't attempt the much larger Annotate.qml surface myself.
Workaround in the meantime rm -f /tmp/screen-toolkit-* executed by the last user to capture screen,
then retrying.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Environment
Summary
Capture, annotate, copy, save, and share all fail intermittently with a generic
"Screen capture failed" toast
depending on which user account last used the tool — not tied to any one
user's config.
Root cause
Several scripts and QML files write intermediate/output images to fixed,
non-per-user filenames under
/tmp, e.g.:/tmp/screen-toolkit-annotate.png/tmp/screen-toolkit-annotate-pixel.png/tmp/screen-toolkit-annotate-zoom.png/tmp/screen-toolkit-overlay.png/tmp/screen-toolkit-share.png/tmp/screen-toolkit-palette.png/tmp/screen-toolkit-qr.png/tmphas the sticky bit set, so only a file's owner (or root) canoverwrite or delete it. On a multi-user system, whichever account used a
given tool most recently ends up owning that shared file — every other
account's next attempt at the same action then fails with a permission
error, since it can neither write over nor delete the existing file.
Evidence
The real error doesn't reach
journalctl— Noctalia logs it internally(readable via
qs log -c noctalia-shell):Failed to open file '/tmp/screen-toolkit-annotate.png' for writing: Permission denied
Where this shows up
scripts/capture.sh—annotate-window,pin,palette, andqractionsMain.qml— theannotateProc/launchAnnotateFullscreencapture pathsoverlays/Annotate.qml—imagePathproperty and the Copy / Save /Save-overlay / Share-flatten flows (roughly 20 references across the
filenames above)
Steps to reproduce
collided
/tmpfileSuggested fix
Use a genuinely per-user location instead of shared
/tmp— e.g.Quickshell.env("XDG_RUNTIME_DIR")(/run/user/<uid>/, mode 0700,already exclusive per user) in place of the hardcoded
/tmp/...paths.I patched just the plain-capture path locally (
capture.sh+Main.qml's_grimGeometryflow) using this approach and confirmed itresolves the collision for that path — happy to share the diff if useful,
though I didn't attempt the much larger
Annotate.qmlsurface myself.Workaround in the meantime
rm -f /tmp/screen-toolkit-*executed by the last user to capture screen,then retrying.
All reactions