You are not logged in.
Is there a way to speed up "Open file", "Save file" etc. dialogs? If I use ls -l, the content of a directory containing about 30000 files is listed in a split second, but if I try to display the same directory in such a dialog, my hard disk starts working audibly, taking at least a minute. This indicates that it is not just crunching metadata but inspecting the content of all the files, probably to guess the MIME type based on that.
I would like to force the dialogs (at least for GTK and Qt, ideally for all toolkits) to guess files types based on filename extension only in order to speed up the process. How do I accomplish that?
Offline
stracing "qarma --file-open", 71% of system calls concern "icons", 23% "mime", the files in the directory aren't opened.
Most of the action seems to concern the "hicolor" theme, it's 65% of all system calls, despite being borderline empty - nb. they're all stat and access on files that don't exist:
◉ grep -Eic 'hicolor.*ENOENT' /tmp/filedlg.strace
69173
◉ grep -Eic 'mime.*ENOENT' /tmp/filedlg.strace
24256out of 106261 system calls and I've a bunch of icon themes, incl the enforced adwaita stuff.
Offline
Thank you for the quick reply. An experiment:
sync ; echo 3 > /proc/sys/vm/drop_caches # as root
time strace zenity --file-selection --filename=/some/empty/file/in/that/directory 2>zenity.err # stopped manually when conky shows that reading stopped
real 5m0.587s
user 0m0.301s
sys 0m0.704s
cat zenity.err | grep -Ec ''
144525
grep -Eo '^[^(]+' zenity.err | sort | uniq -c | sort -n
1 ) = 93
1 arch_prctl
1 execve
1 getresgid
1 getresuid
1 getsockname
1 kcmp
1 prlimit64
1 pwrite64
1 rseq
1 set_robust_list
1 set_tid_address
1 statfs
1 strace: Process 725568 detached
2 faccessat2
2 ftruncate
2 getpeername
2 getrandom
2 kill
2 memfd_create
2 pread64
2 setsockopt
2 sysinfo
3 mkdir
3 rt_sigaction
4 connect
4 gettid
4 mremap
4 sendmsg
4 socket
6 sched_setscheduler
7 inotify_add_watch
8 flock
9 getgid
9 prctl
9 sendto
10 uname
12 sched_setaffinity
13 fcntl
13 getegid
13 geteuid
13 recvfrom
15 getuid
17 eventfd2
18 clone3
20 statx
21 lseek
53 access
54 getdents64
67 rt_sigprocmask
142 mprotect
318 brk
362 write
381 munmap
830 ioctl
940 mmap
1247 fstat
1263 close
1263 ppoll
1498 openat
1615 read
2412 readlink
4465 getpid
5352 newfstatat
5422 futex
20157 writev
36156 poll
60257 recvmsg
grep -Eic 'hicolor.*ENOENT' zenity.err
682
grep -Eic 'mime.*ENOENT' zenity.err
29
sync ; echo 3 > /proc/sys/vm/drop_caches # again, as root
time ls -l
real 0m2.906s
user 0m0.085s
sys 0m0.143sThe system partition is installed on an SSD. The HDD in question has nothing to do with GUI stuff or the system or anything, just data. It still very audibly starts working when the dialog opens. And it takes 5 minutes. ls -l in a terminal takes just below 3 seconds. I am pretty sure it is doing something with the files in that directory. Maybe it's some thumbnailing magic at work?
Last edited by itektur (2025-04-21 16:54:57)
Offline
1 strace: Process 725568 detached"strace -f"
then
gzip zenity.err
cat zenity.err.gz | curl -F 'file=@-' 0x0.stOffline
Thank you, but I am not going to upload the whole thing, think sensitive data and privacy.
Using "strace -f" really helped, I think. Thanks. I am not used to using strace but this is what I think might be relevant (slightly reconstructed and redacted):
$ find /some/empty/file/in/that/ -mindepth 1 -maxdepth 1 | wc -l
32977
$ <zenity.20250426.err grep -F '/home/user/.cache/thumbnails' | grep -Eo '^\[pid +[0-9]+\] +[^(]+' | sort | uniq -c
1230 [pid 8553] newfstatat
510 [pid 8692] newfstatat
1806 [pid 8693] newfstatat
840 [pid 8694] newfstatat
$ <zenity.20250426.err grep -F '/some/empty/file/in/that/' | grep -Eo '^\[pid +[0-9]+\] +[^(]+' | sort | uniq -c
123 [pid 8553] openat
205 [pid 8553] statx
18313 [pid 8555] openat
20000 [pid 8555] statx
54 [pid 8692] openat
85 [pid 8692] statx
12087 [pid 8693] openat
13278 [pid 8693] statx
112 [pid 8694] openat
140 [pid 8694] statxSo, apparently, at least some thumbnails are being looked up (or created, or at least there are some attempts since '/home/user/.cache/thumbnails' does not exist).
Judging by what I found looking into the log file, processes/threads 8555 and 8693 (and possibly others, but they are the most prominent) seem to inspect every file there is in the file chooser's current location. Digging further, it seems that they are both launched by another thread the main thread has spawned (if I understand this correctly):
clone3({flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, child_tid=0x7259597ff990, parent_tid=0x7259597ff990, exit_signal=0, stack=0x725958fff000, stack_size=0x7ffcc0, tls=0x7259597ff6c0} => {parent_tid=[8534]}, 88) = 8534
strace: Process 8534 attached
…
[pid 8534] clone3({flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, child_tid=0x725901ffb990, parent_tid=0x725901ffb990, exit_signal=0, stack=0x7259017fb000, stack_size=0x7ffcc0, tls=0x725901ffb6c0} <unfinished ...>
[pid 8534] <... clone3 resumed> => {parent_tid=[8555]}, 88) = 8555
strace: Process 8555 attached
…
[pid 8534] clone3({flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, child_tid=0x725939ffc990, parent_tid=0x725939ffc990, exit_signal=0, stack=0x7259397fc000, stack_size=0x7ffcc0, tls=0x725939ffc6c0} => {parent_tid=[8693]}, 88) = 8693
strace: Process 8693 attachedComparing this to yet another run, it seems that, according to htop, zenity spawns a thread named "pool-spawner", and judging by the names, it is that thread that creates more threads like "pool-1", "pool-12", "pool-13" and so on, some of which create quite some I/O (several MiB/s for several minutes) which, according to iostat, clearly means reading from the HDD in question.
Not sure how to proceed from there.
Last edited by itektur (2025-05-01 19:11:03)
Offline
Not sure how to proceed from there.
Read the strace - what are the 30.000 files being opened?
Offline
Not sure what you want me to look up, but here you are:
$ cd /some/empty/file/in/that/ && </path/to/zenity.20250426.find.err xargs -d$'\n' file -L -N --mime-type -F $'\1\1\1\1' | sed -r -n -e 's'$'\2^.*\1\1\1\1'' (.*)$'$'\2''\1'$'\2''p' | sort | uniq -c | sort -n
1 application/vnd.oasis.opendocument.spreadsheet
1 text/x-affix
1 text/xml
1 text/x-script.python
2 application/zip
3 application/gzip
4 audio/ogg
5 video/x-m4v
6 image/avif
33 image/webp
36 audio/mpeg
71 inode/directory
79 application/pdf
89 video/webm
107 application/javascript
113 image/png
401 inode/x-empty
443 text/plain
509 video/mp4
629 image/jpeg
1012 video/x-matroska
1071 application/x-ndjson
1458 application/json
26902 text/htmlOffline
What files in what paths are openat'ed (probably hinting at "why") because that's liekely the expensive part
I'm not sure what you would see in the strace concerning any privacy issues (icons? the contents of some test directory?), but w/o access to it, you'll have to investigate that yourself.
I simply cannot tell you what's causing the overhead based on "nodata"
Offline
What files in what paths are openat'ed (probably hinting at "why") because that's liekely the expensive part
The vast majority of what 8555 and 8693 were doing is something like this (slightly differently redacted):
[pid 8555] statx(AT_FDCWD, "/some/nonempty/file/in/that/directory", AT_STATX_SYNC_AS_STAT|AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0600, stx_size=93392, ...}) = 0
[pid 8555] openat(AT_FDCWD, "/some/nonempty/file/in/that/directory", O_RDONLY|O_NOATIME|O_CLOEXEC) = 16
[pid 8555] read(16, "herebecontentherebecontentherebe"..., 16384) = 16384
[pid 8555] close(16) = 0Zenity seems to open all files in the directory it tries to show its content of in the file chooser. Some stats seem to confirm this:
$ <zenity.20250426.err grep -F '[pid 8555]' | grep -Eo '\[pid 8555\] [^(<]+' | sort | uniq -c | sort -n
1 [pid 8555] connect
1 [pid 8555] getgid
1 [pid 8555] getrandom
1 [pid 8555] getuid
1 [pid 8555] ppoll
1 [pid 8555] rseq
1 [pid 8555] sendmsg
1 [pid 8555] set_robust_list
1 [pid 8555] setsockopt
1 [pid 8555] socket
2 [pid 8555] access
2 [pid 8555] gettid
2 [pid 8555] prctl
3 [pid 8555] getegid
3 [pid 8555] poll
3 [pid 8555] rt_sigprocmask
4 [pid 8555] eventfd2
4 [pid 8555] geteuid
4 [pid 8555] getpid
4 [pid 8555] munmap
4 [pid 8555] sendto
5 [pid 8555] mmap
5 [pid 8555] readlink
6 [pid 8555] fstat
6 [pid 8555] recvfrom
42 [pid 8555] write
58 [pid 8555] getdents64
72 [pid 8555] futex
197 [pid 8555] newfstatat
4146 [pid 8555] mprotect
18294 [pid 8555] read
18297 [pid 8555] close
18333 [pid 8555] openat
20000 [pid 8555] statx$ <zenity.20250426.err grep -F '[pid 8693]' | grep -Eo '\[pid 8693\] [^(<]+' | sort | uniq -c | sort -n
1 [pid 8693] prctl
1 [pid 8693] rseq
1 [pid 8693] set_robust_list
2 [pid 8693] getpid
2 [pid 8693] gettid
5 [pid 8693] rt_sigprocmask
39 [pid 8693] getdents64
346 [pid 8693] write
405 [pid 8693] futex
1916 [pid 8693] newfstatat
2747 [pid 8693] mprotect
12076 [pid 8693] close
12079 [pid 8693] read
12091 [pid 8693] openat
13282 [pid 8693] statxBy the way, letting /usr/bin/file process all the files in the directory in question takes about the same amount of time as zenity's file chooser (or any other similarly working file chooser, for that matter), i.e. about 5 minutes.
Offline
It would seem that zenity for whatever reason is indeed testing the magic byte for file identification.
Does then Qt (qarma) or gtk3 (eg. gtk3-demo-application) do the same on your site?
(I don't have any gtk4 installed and am not super-eager to change that)
Offline
Surprisingly, qarma seems to perform worse. Not only does it take about 9.5 minutes, it also tries to access everything multiple times. Some icon-related files are "access"ed up to 36 times, despite not existing in the first place! More numbers:
$ <qarma.20250502.err grep -Fc 'No such file or directory'
9397455
$ <qarma.20250502.err grep -Fc '/share/'
9398670
$ <qarma.20250502.err grep -Fc '/icons/'
440144
$ <qarma.20250502.err grep -Fc '/mime/'
8957244
$ <qarma.20250502.err grep -Fv '/mime/' | grep -Fc '/icons/'
440144
$ <qarma.20250502.err grep -Fv '/icons/' | grep -Fc '/mime/'
8957244
$ <qarma.20250502.err grep -F '/icons/' | grep -Fc '/mime/'
0
$ <qarma.20250502.err grep -Fv '/mime/' | grep -Fv '/icons/' | grep -Fc '/share/'
1283Now for the meaty part:
$ <qarma.20250502.err grep -Eo '^\[pid +[0-9]+\] *[^(<+-]+' | grep -Eo '[^ ]+$' | sort | uniq -c | sort -n
1 getrandom
1 getresgid
1 getresuid
1 inotify_rm_watch
1 ioctl
1 kill
1 restart_syscall
1 sched_getaffinity
1 sched_setscheduler
2 connect
2 geteuid
2 getsockname
2 inotify_init1
2 lseek
2 sched_get_priority_max
2 sched_get_priority_min
2 socket
2 uname
3 exit
3 inotify_add_watch
3 madvise
4 recvfrom
8 sendto
9 getcwd
12 clone3
13 prctl
13 rseq
13 set_robust_list
14 eventfd2
14 gettid
16 fcntl
16 getpid
43 rt_sigprocmask
49 sendmsg
50 munmap
99 fstat
106 mmap
107 fstatfs
133 ppoll
139 writev
172 brk
204 getdents64
228 readlink
781 recvmsg
836 poll
889 futex
988 write
21648 mprotect
122395 close
125353 read
131871 newfstatat
310926 statx
4600852 openat
5117283 access Filtering out some of the noise, we still get this:
$ <qarma.20250502.err grep -Fv '/mime/' | grep -Fv '/icons/' | grep -Fv '/share/' | grep -Eo '^\[pid +[0-9]+\] *[^(<+-]+' | grep -Eo '[^ ]+$' | sort | uniq -c | sort -n
1 getrandom
1 getresgid
1 getresuid
1 inotify_rm_watch
1 ioctl
1 kill
1 restart_syscall
1 sched_getaffinity
1 sched_setscheduler
2 connect
2 geteuid
2 getsockname
2 inotify_init1
2 lseek
2 sched_get_priority_max
2 sched_get_priority_min
2 socket
2 uname
3 exit
3 inotify_add_watch
3 madvise
4 recvfrom
8 sendto
9 getcwd
12 clone3
13 prctl
13 rseq
13 set_robust_list
14 eventfd2
14 gettid
16 fcntl
16 getpid
43 rt_sigprocmask
49 sendmsg
50 munmap
94 readlink
99 fstat
106 mmap
107 fstatfs
133 ppoll
139 writev
172 brk
204 getdents64
781 recvmsg
836 poll
889 futex
988 write
21648 mprotect
122229 openat
122395 close
125353 read
131698 newfstatat
198172 access
310297 statxHow the files in the directory are involved:
$ <qarma.20250502.err grep -F '/some/empty/file/in/that/' | grep -Eo '^\[pid +[0-9]+\] *[^(<+-]+' | grep -Eo '[^ ]+$' | sort | uniq -c | sort -n
2 readlink
32993 statx
61038 openat
65840 newfstatat
98982 accessAs it turns out, some if not all of the files are somehow involved several times, they are even read several times, even beyond the end!
[pid 26354] statx(AT_FDCWD, "/path/to/some/nonempty/file", AT_STATX_SYNC_AS_STAT|AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT, STATX_ALL, <unfinished ...>
[pid 26354] <... statx resumed>{stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0600, stx_size=14026, ...}) = 0
[pid 26354] access("/path/to/some/nonempty/file", R_OK <unfinished ...>
[pid 26354] <... access resumed>) = 0
[pid 26354] access("/path/to/some/nonempty/file", W_OK <unfinished ...>
[pid 26354] <... access resumed>) = 0
[pid 26354] access("/path/to/some/nonempty/file", X_OK <unfinished ...>
[pid 26354] <... access resumed>) = -1 EACCES (Permission denied)
[pid 26350] newfstatat(AT_FDCWD, "/path/to/some/nonempty/file", {st_mode=S_IFREG|0600, st_size=14026, ...}, 0) = 0
[pid 26350] openat(AT_FDCWD, "/path/to/some/nonempty/file", O_RDONLY|O_CLOEXEC) = 13
[pid 26350] statx(13, "", AT_STATX_SYNC_AS_STAT|AT_NO_AUTOMOUNT|AT_EMPTY_PATH, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0600, stx_size=14026, ...}) = 0
[pid 26350] statx(13, "", AT_STATX_SYNC_AS_STAT|AT_NO_AUTOMOUNT|AT_EMPTY_PATH, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0600, stx_size=14026, ...}) = 0
[pid 26350] read(13, "herebecontentherebecontentherebe"..., 16384) = 14026
[pid 26350] read(13, "", 2358) = 0
[pid 26350] close(13) = 0
[pid 26350] newfstatat(AT_FDCWD, "/path/to/some/nonempty/file", {st_mode=S_IFREG|0600, st_size=14026, ...}, 0) = 0
[pid 26350] openat(AT_FDCWD, "/path/to/some/nonempty/file", O_RDONLY|O_CLOEXEC) = 13
[pid 26350] statx(13, "", AT_STATX_SYNC_AS_STAT|AT_NO_AUTOMOUNT|AT_EMPTY_PATH, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0600, stx_size=14026, ...}) = 0
[pid 26350] statx(13, "", AT_STATX_SYNC_AS_STAT|AT_NO_AUTOMOUNT|AT_EMPTY_PATH, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0600, stx_size=14026, ...}) = 0
[pid 26350] read(13, "herebecontentherebecontentherebe"..., 16384) = 14026
[pid 26350] read(13, "", 2358) = 0
[pid 26350] close(13) = 0For comparison: emelFM2 takes about 85 seconds (measured under heavy I/O load, so it might not be as reliable), and judging by the fan noise, it's mostly CPU stuff:
$ time strace -f emelfm2 -1 '/some/empty/file/in/that/' -2 / 1> /dev/null 2> /tmp/emelfm2.20250502.err
real 1m25.201s
user 0m21.455s
sys 0m51.863sAlso, the only thing emelfm2 does to the files is to run "lstat" on them at most once.
EDIT:GTK3 seems similar to GTK4. Never measured or strace'd, but firefox' file choosers exhibit the same naïvely observable issues.
Since several toolkits seem to exhibit similar behavior (see my very first post in this thread). I was hoping that someone might know whether there is some XDG-related setting or something that controls how much energy is put into determining the type of a file.
Last edited by itektur (2025-05-02 13:03:00)
Offline
As pointed out in #2, Qt does *a lot* of icon lookups.
But it only openat's one file in the directory I tested (music) - the only .ogg (vorbis) file, so the filetype/extension might be relevant (I copied the file and it opens the copy as well, but doesn't touch any mp3, m4a, mp4, mkv or txt files.
I know that you can inject a custom icon provider into QFilesystemModel, but that's no generic solution and I doubt there's such.
These things are just implemented horribly inefficient (I noticed a steep performance decline in QFilesystemModel between Qt5 and Qt6)
cross-check, how does pcmanfm-qt perform?
Offline
cross-check, how does pcmanfm-qt perform?
Speed:
# after dropping caches:
$ time strace -f -o /tmp/pcmanfm-qt.20250503.err pcmanfm-qt /path/to/some/nonempty 1> /dev/null 2>&1
real 5m6.571s
user 0m6.938s
sys 0m5.816s
# when everything is cached:
$ time strace -f -o /tmp/pcmanfm-qt.20250503.err pcmanfm-qt /path/to/some/nonempty 1> /dev/null 2>&1
real 0m12.190s
user 0m5.938s
sys 0m4.535sSyscalls per file (typical):
[pid 125059] statx(AT_FDCWD, "/path/to/some/nonempty/file", AT_STATX_SYNC_AS_STAT|AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0600, stx_size=14026, ...}) = 0
[pid 125059] openat(AT_FDCWD, "/path/to/some/nonempty/file", O_RDONLY|O_NOATIME|O_CLOEXEC) = 30
[pid 125059] read(30, "herebecontentherebecontentherebe"..., 16384) = 14026
[pid 125059] close(30) = 0
[pid 125059] access("/path/to/some/nonempty/file", R_OK) = 0
[pid 125059] access("/path/to/some/nonempty/file", W_OK) = 0
[pid 125059] access("/path/to/some/nonempty/file", X_OK) = -1 EACCES (Permission denied)Last edited by itektur (2025-05-03 16:10:10)
Offline
I created a test directory with PNG files, all of which have the exact same content but are named differently.
$ strace -f -o /tmp/zenity-png-txt.20250503.strace zenity --file-selection --filename=testfile.txt 1> /dev/null 2>&1
$ <zenity-png-txt.20250503.strace grep -E '/tmp/test/testfile[^"]*'
398125 statx(AT_FDCWD, "/tmp/test/testfile.png", AT_STATX_SYNC_AS_STAT|AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT, STATX_ALL, <unfinished ...>
398125 openat(AT_FDCWD, "/tmp/test/testfile.png", O_RDONLY|O_NOATIME|O_CLOEXEC <unfinished ...>
398125 statx(AT_FDCWD, "/tmp/test/testfile.jpg", AT_STATX_SYNC_AS_STAT|AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT, STATX_ALL, <unfinished ...>
398125 statx(AT_FDCWD, "/tmp/test/testfile.txt", AT_STATX_SYNC_AS_STAT|AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT, STATX_ALL, <unfinished ...>
398125 statx(AT_FDCWD, "/tmp/test/testfile.html", AT_STATX_SYNC_AS_STAT|AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT, STATX_ALL, <unfinished ...>
398125 openat(AT_FDCWD, "/tmp/test/testfile.html", O_RDONLY|O_NOATIME|O_CLOEXEC <unfinished ...>
398125 statx(AT_FDCWD, "/tmp/test/testfile", AT_STATX_SYNC_AS_STAT|AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT, STATX_ALL, <unfinished ...>
398125 openat(AT_FDCWD, "/tmp/test/testfile", O_RDONLY|O_NOATIME|O_CLOEXEC <unfinished ...>
398125 statx(AT_FDCWD, "/tmp/test/testfile.mp3", AT_STATX_SYNC_AS_STAT|AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT, STATX_ALL, <unfinished ...>
398123 statx(AT_FDCWD, "/tmp/test/testfile", AT_STATX_SYNC_AS_STAT|AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT, STATX_ALL, <unfinished ...>
398123 openat(AT_FDCWD, "/tmp/test/testfile", O_RDONLY|O_NOATIME|O_CLOEXEC) = 16
398127 statx(AT_FDCWD, "/tmp/test/testfile.html", AT_STATX_SYNC_AS_STAT|AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0600, stx_size=2604058, ...}) = 0
398127 openat(AT_FDCWD, "/tmp/test/testfile.html", O_RDONLY|O_NOATIME|O_CLOEXEC) = 16
398130 statx(AT_FDCWD, "/tmp/test/testfile.jpg", AT_STATX_SYNC_AS_STAT|AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0600, stx_size=2604058, ...}) = 0
398122 statx(AT_FDCWD, "/tmp/test/testfile.mp3", AT_STATX_SYNC_AS_STAT|AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0600, stx_size=2604058, ...}) = 0
398124 statx(AT_FDCWD, "/tmp/test/testfile.png", AT_STATX_SYNC_AS_STAT|AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0600, stx_size=2604058, ...}) = 0
398124 openat(AT_FDCWD, "/tmp/test/testfile.png", O_RDONLY|O_NOATIME|O_CLOEXEC) = 16
398129 statx(AT_FDCWD, "/tmp/test/testfile.txt", AT_STATX_SYNC_AS_STAT|AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0600, stx_size=2604058, ...}) = 0I think I have an idea now of what is going on. Hypotheses:
Whether a file is being openat'ed depends on the extension of the filename (see https://bbs.archlinux.org/viewtopic.php … 4#p2239734).
openat happens when the dialog tries to determine what kind of icon to use for the respective file (and, in case of extension-less names, what to display in the "Type" field which is otherwise determined solely based on the extension) .
Since one could always use a generic icon for all files of the same type (e.g. PNG), that suggests that files are openat'ed in search for a more specific icon. In case of images, that might be a thumbnail. In case of HTML files, it might be some favicon encoded or linked to in the file in some way.
Everything is done here twice, probably the first time while scanning the whole directory, the second time for all the files currently within the viewport (which means all files in this case).
For some reason, JPEGs are not openat'ed, but PNGs are. Is there a way for thumbnails to be embedded in PNGs that is not available to JPEGs?
Okay, I just ran a few more experiments. As it turns out, some PNG files will be thumbnailed, and the thumbnail is displayed instead of a generic icon. However, in this experiment, it only happens to some PNG files and not to others. It might not have anything to do with file size, image dimensions or whether one has selected "Save thumbnail" in GIMP. Further investigation shows that the thumbnails are cached in ~/.cache/thumbnails/normal and that "actual" thumbnails are stored there together with rasterized verions of generic (SVG) icons.
Since all icons are apparently looked up in the same directory, the important questions left are
How to force file choosers to not display icons at all?
(weaker) How to force file choosers to always use generic (i.e. content-independent) icons?
There might be or at least should be an option for that …
Similar question related to GTK2: https://stackoverflow.com/questions/116 … ile-dialog
EDIT: I wonder whether JPEGs are not openat'ed because they are not icon-like enough. As in, HTML does kind of look like SVG because it looks like XML, so it's "icon enough". Same goes for PNG.
Last edited by itektur (2025-05-04 10:19:39)
Offline
There might be or at least should be an option for that …
Yes "should" …
This entire stuff should™ not be implemented so inefficiently itfp.
https://docs.gtk.org/gtk3/class.Settings.html doesn't suggest any setting for this exists.
For Qt, the platform module or visual style (on polish()) could step in and "setIconProvider(nullptr);" (tested; works and drastically accelerates things) - likewise one could inject an optimized icon provider, just going by the suffix (and probably caching the result…)
And to add some injury to this insult, QFileSystem is actually threaded off the GUI thread, but the icons seem to sync those.
I also figured that qt6ct as QT_QPA_PLATFORMTHEME enhances performance over no QPA at all (that is already w/o icons)
![]()
Offline