我使用以下脚本(它绑定到键盘快捷键)在 nemo 中打开选定的文件(使用快捷键后单击窗口)。它所做的是从窗口 ID(单击窗口后)获取进程 ID,然后使用该 ID 获取属于该 pid 的文件路径。获取文件路径后,它使用 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
但问题在于叶酸。它对多个窗口使用相同的过程。如果我打开多个 .epub 文件,它有多个窗口。但是所有的窗口都有一个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
我正在使用 Zorin OS 16.2,它使用 Gnome 3。
我检查了子进程,看是否可以获取其他文件的路径,但没有太大帮助。
% 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
在 Foliate 中打开文件时,如何从窗口 ID 获取确切的文件路径?
更新 1
我做了一些研究。以下命令有效。
% dbus-send --session --print-reply --dest=com.github.johnfactotum.Foliate /com/github/johnfactotum/Foliate org.freedesktop.DBus.Introspectable.Introspect
我还用 d-feet 检查过 d-bus 也显示了窗户。
现在,如果我能以某种方式从这里获取文件路径和窗口 ID,那么它就会解决我的问题。
在使用 时,要确定窗口中显示的文件
Foliate
,您可能会做的是查看窗口名称属性,它似乎包含文档标题。您可以从xdotool selectwindow getwindowname
或以交互方式获取它xprop WM_NAME
。然后您可以将
Foliate
一个 shell 脚本包装在一个 shell 脚本中,这样当您运行时,myFoliate myfile.epub
它可以将文件名$PWD/$1
(或者$1
如果它开始/
)和等效的标题添加到日志文件中。当您稍后选择一个窗口时,您可以获得标题的名称,并在日志中查找它以找到文件名。获取 epub 文件的标题是可行的:格式是压缩存档,在
<title>
xml 中toc.ncx
。相反,你可以运行类似
在脚本的开头获取当前名称/头衔的列表,然后
Foliate
在后台启动几秒钟后再次获取。新条目将成为新标题。这将无法区分具有相同标题的同一文档的两个版本。相反,您可以在日志中记录新创建窗口的窗口 ID(仅使用
xdotool search --class Foliate
which 输出窗口 ID 列表)以及文件名。然后当您选择窗口时,您查找的是这个编号,而不是标题。显然,如果有很多过时的条目,则应使用日志中的最后一个匹配项。
下面是一个可能的脚本实现,
myfoliate
它使用文件名调用,或者-q
选择一个窗口并检索文件名。这有点过于复杂,因为我添加了一个锁定机制以避免在同时打开两个新的 Foliate 窗口时获得错误的 ID。这declare -A
使得该变量成为windows
一个关联数组,以窗口 ID 作为键,因此我们可以轻松找到一个新的缺失条目。sleep 2
如果 Foliate 启动缓慢,则可能需要增加。如果可以确定没有当前的 Foliate 在运行,则日志文件可能应该在开始时清空。是的,这并不是真正可以解决的:每个窗口都属于它自己的进程的假设是完全错误的。
您将必须检查 Foliate 是否提供了一些 API,您可以使用这些 API 将窗口映射到该窗口中显示的文件——它可能没有,两者之间有相当多的抽象级别。
所以,简而言之,用你目前的方法,不可能达到你想要的。
您可以实现一些特定要求 Foliate 将 WID 转换为在该窗口中打开的文档的东西,但这可能需要在 Foliate 代码库中进行认真的开发工作。