Screenshots don't work if XDG user dirs is disabled
Affected version
- Fedora 36
- GNOME 42
- I'm using Wayland but the same thing probably also happens with Xorg
Bug summary
I'm unable to take a screenshot in sessions where I've disabled XDG user dirs.
Steps to reproduce
- Create
~/.config/user-dirs.conf
withenabled=False
- Log into GNOME, press PrintScreen and click the white circle to take a screenshot
What happened
No screenshot was saved, and the following error appeared in my logs:
[sam@sam-desktop ~]$ journalctl -f
Jun 05 16:10:47 sam-desktop gnome-shell[2084]: JS ERROR: Error capturing screenshot: Error: Array element (type filename) may not be null
_storeScreenshot@resource:///org/gnome/shell/ui/screenshot.js:2066:48
captureScreenshot@resource:///org/gnome/shell/ui/screenshot.js:2194:21
async*_saveScreenshot@resource:///org/gnome/shell/ui/screenshot.js:1759:30
_onCaptureButtonClicked@resource:///org/gnome/shell/ui/screenshot.js:1738:18
vfunc_key_press_event@resource:///org/gnome/shell/ui/screenshot.js:1967:18
Caused by: Error: Invalid element in array
What did you expect to happen
I expected a screenshot to be taken and saved somewhere, or an error dialog.
Relevant logs, screenshots, screencasts etc.
Looking at screenshot.js:2066 (from the stack trace in the logs) I can see that it's trying to build up the directory path like this:
const dir = Gio.File.new_for_path(GLib.build_filenamev([
GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_PICTURES),
// Translators: name of the folder under ~/Pictures for screenshots.
_('Screenshots'),
]));
But this fails because, when xdg user dirs are disabled, GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_PICTURES)
evaluates to null. I can reproduce the error message from the logs using gjs:
[sam@sam-desktop ~]$ gjs
gjs> const { Gio, GLib } = imports.gi
gjs> GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_PICTURES)
null
gjs> Gio.File.new_for_path(GLib.build_filenamev([null, 'Screenshots']))
typein:4:28 Error: Array element (type filename) may not be null
@typein:4:28
@<stdin>:1:42
I think this just needs to be rewritten with a null check and a fallback directory.
I also noticed that elsewhere in the same source file (lines 2291-2294) it looks like it's trying to implement a fallback, but it's still missing a null check? That should probably change to something like:
- ].find(p => p && GLib.file_test(p, GLib.FileTest.EXISTS));
+ ].find(p => p && !!p && GLib.file_test(p, GLib.FileTest.EXISTS));