4

I use the following script (it is bound to a keyboard shortcut) to open selected file (clicking on a window after using the shortcut) in nemo. What is does is from window id (after clicking on the window), it get the process id, then using that get the file path that belong to the pid. After acquiring the file path, it opens that file with nemo.

#!/bin/bash WINDOW_ID=$(xdotool getactivewindow) PID_OF_ACTIVE_WINDOW=$(xdotool getwindowpid $WINDOW_ID) MY_COMMAND_PATH=$(ps -p $PID_OF_ACTIVE_WINDOW -o command) # https://stackoverflow.com/q/76028252/1772898 if printf -- '%s\n' "$MY_COMMAND_PATH" | grep -qoP '(file://)?(?<!\w)/(?!usr/).*?\.\w{3,4}+'; then nemo "$(printf -- '%s\n' "$MY_COMMAND_PATH" | grep -oP '(file://)?(?<!\w)/(?!usr/).*?\.\w{3,4}+')" fi 

But the problem is with Foliate. It use the same process for multiple windows. If I open multiple .epub files, it has multiple windows. But all the windows have one pid.

% xdotool getwindowpid 59418676 15977 % xdotool getwindowpid 59422435 15977 % ps -aux | grep 15977 ismail 15977 0.1 0.7 95405880 128992 ? Sl May05 10:23 /usr/bin/gjs /usr/bin/com.github.johnfactotum.Foliate /media/ismail/SSDWorking/book-collection/_Books/self-development-anxiety-self-talk/child/Freeing Your Child from Anxiety Powerful, Practical Solutions to Overcome Your Childs Fears, Worries, and Phobias (Tamar Chansky Ph.D.).epub % readlink -f /proc/15977/exe /usr/bin/gjs-console 

I am using Zorin OS 16.2, which use Gnome 3.

I checked the sub-processes to see if I can get the path of other files, but did not help much.

% pgrep -P 15977 15995 15998 16011 139458 139662 % ps -p 15995 -o command COMMAND /usr/lib/x86_64-linux-gnu/webkit2gtk-4.0/WebKitNetworkProcess 7 16 % ps -p 15998 -o command COMMAND /usr/lib/x86_64-linux-gnu/webkit2gtk-4.0/WebKitNetworkProcess 8 19 % ps -p 16011 -o command COMMAND /usr/bin/bwrap --args 29 -- /usr/bin/xdg-dbus-proxy --args=26 % ps -p 139458 -o command COMMAND /usr/bin/bwrap --args 58 -- /usr/lib/x86_64-linux-gnu/webkit2gtk-4.0/WebKitWebProcess 59 54 % ps -p 139662 -o command COMMAND /usr/bin/bwrap --args 62 -- /usr/lib/x86_64-linux-gnu/webkit2gtk-4.0/WebKitWebProcess 73 58 

How can I get the exact file path from window ID, when file is opened in Foliate?

Update 1

I have done some research. The following command works.

% dbus-send --session --print-reply --dest=com.github.johnfactotum.Foliate /com/github/johnfactotum/Foliate org.freedesktop.DBus.Introspectable.Introspect 

I have also checked with d-feet that d-bus also show the windows.

Foliate D-Feet

Now if I could somehow get the file path and window id from here then it would solve my problem.

2 Answers 2

3

What you might do to identify what file is shown in a window when using Foliate, is to look at the window name propery, which seems to hold the document title. You can get this interactively from xdotool selectwindow getwindowname or xprop WM_NAME.

You can then wrap Foliate inside a shell script so that when you run, say, myFoliate myfile.epub it can add to a log file the filename $PWD/$1 (or $1 if it begins /) and the equivalent title. When you later select a window, you can get the name which is the title, and look up this in the log to find the filename.

Getting the title for an epub file is feasible: the format is a zipped archive, with the <title> in xml in toc.ncx.

Instead, you can run something like

xdotool search --class 'Foliate' | xargs -i xdotool getwindowname {} 

at the start of the script to get the list of current names/titles, then again a few seconds after starting Foliate in the background. The new entry will be the new title.

This will not be able to distinguish between two versions of the same document with the same title. Instead, you can note in the log the window-id of the newly created window (using just xdotool search --class Foliate which outputs the list of window-ids), together with the filename. Then when you select the window, you lookup this number, rather than the title.

Obviously, the last match in the log should be used, if there are many out-of-date entries.


Here is a possible implementation as a script, myfoliate, which is called with either a filename, or -q to select a window and retrieve a filename. It is a bit overcomplicated as I added a locking mechanism to avoid getting the wrong id if two new Foliate windows are opened at once. The declare -A makes the variable windows an associative array, with the window ids as keys so we can easily find a new missing entry. The sleep 2 may need to be increased if Foliate is slow to start. The log file should probably be emptied at the start if it can be determined that there is no current Foliate running.

#!/bin/bash log=$HOME/.myfoliate.log if [ $# -ne 1 ] then echo "$0: usage: <filename> or -q" exit 1 fi if [ '-q' = "$1" ] then id=$(xdotool selectwindow) gawk <$log -v id="$id" ' $1==id { $1 = ""; file=$0; } END{ print file; exit(file==""); }' exit fi if [[ "$1" =~ ^/ ]] then file=$1 else file=$PWD/$1 fi listwindows(){ xdotool search --class 'Foliate' } ( flock -n 9 || exit 2 declare -A windows for id in $(listwindows) do windows[$id]=1 done Foliate "$1" 9>&- & sleep 2 for id in $(listwindows) do if [ "${windows[$id]}" == "" ] then newwin=$id fi done if [ -z "$newwin" ] then echo "$0: failed" exit 3 fi echo "$newwin $file" >&9 ) 9>>$log 
6
  • This is the correct answer. Can you please give us some code. It will be very helpful for people who later come to find a solution for this problem. Commented May 9, 2023 at 18:26
  • 1
    I've added a possible shell script. Commented May 9, 2023 at 20:31
  • 1
    You might have to replace Foliate with com.github.johnfactotum.Foliate. In my machine to check version of Foliate, i have to run com.github.johnfactotum.Foliate -v. In /home/ismail/.local/share/applications/com.github.johnfactotum.Foliate.desktop i have replaced Exec=com.github.johnfactotum.Foliate %U with Exec=/home/ismail/.dotfiles/.resources/bash-scripts/foliate.sh %U. Now it works like a charm. Commented May 10, 2023 at 6:40
  • Just to be clear, I have copied /usr/share/applications/com.github.johnfactotum.Foliate.desktop to /home/ismail/.local/share/applications/com.github.johnfactotum.Foliate.desktop and then edited it. Commented May 10, 2023 at 6:42
  • I have answered a question based on your answer. unix.stackexchange.com/a/745519/206574 Please review the answer (and suggest improvement, specially my coding skill is amateur at best, also i am not a native english speaker) and give us a feedback. It would be better if you could give an answer to that question based on our work (improve the code and logic, and also make it more generic). That way this problem of "opening a file on file explorer that is open on a gui app" will have better solution and help other linux users. Commented May 11, 2023 at 8:59
2

Yeah, that isn't really solvable: The assumption that each window belongs to a process of its own is simply wrong.

You will have to check whether Foliate offers some API with which you can map windows to the file shown in that window – it probably doesn't, there's quite a few levels of abstractions in between.

So, in short, with your current approach, it's impossible to achieve what you want.

You can possibly implement something that asks Foliate specifically to convert a WID to the document opened in that window, but it might take serious development effort within the Foliate code base.

2
  • 1
    Question updated with image. Commented May 9, 2023 at 11:49
  • You will have to check whether that dbus interface offers a call with which you can achieve what you want! Commented May 9, 2023 at 12:02

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.