在由另一个应用程序打开的文件上打开文件资源管理器

在由另一个应用程序打开的文件上打开文件资源管理器

我使用以下脚本(它绑定到键盘快捷键)在 nemo 中打开选定的文件(使用快捷键后单击窗口)。它的作用是从窗口 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 文件,它就会有多个窗口。但是所有的windows都有一个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 也显示了窗口。

叶状 D 脚

现在,如果我能以某种方式从这里获取文件路径和窗口 ID,那么它就能解决我的问题。

答案1

Foliate使用 时,您可以做的是查看窗口名称属性,它似乎包含文档标题,以确定窗口中显示的文件 。您可以从xdotool selectwindow getwindowname或交互地获取此信息xprop WM_NAME

然后,您可以将其包装Foliate在 shell 脚本中,这样当您运行时,它可以将文件名(或如果以 开头)和等效标题myFoliate myfile.epub添加到日志文件中。当您稍后选择一个窗口时,您可以获得名称(即标题),并在日志中查找该名称以查找文件名。$PWD/$1$1/

获取 epub 文件的标题是可行的:格式是压缩存档,其中<title>.xml 为toc.ncx.

相反,你可以运行类似的东西

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

在脚本开始时获取当前名称/标题的列表,然后Foliate在后台启动几秒钟后再次获取。新条目将是新标题。

这将无法区分具有相同标题的同一文档的两个版本。相反,您可以在日志中记下新创建的窗口的窗口 ID(仅使用xdotool search --class Foliate它输出窗口 ID 列表)以及文件名。然后,当您选择窗口时,您将查找该数字,而不是标题。

显然,如果有许多过时的条目,则应使用日志中的最后一个匹配项。


下面是一个可能的脚本实现,myfoliate它可以使用文件名来调用,或者-q选择一个窗口并检索文件名。这有点过于复杂,因为我添加了一个锁定机制,以避免在同时打开两个新的 Foliate 窗口时获得错误的 id。这declare -A使得变量成为windows一个关联数组,以窗口 id 作为键,这样我们就可以轻松找到新的缺失条目。sleep 2如果 Foliate 启动缓慢,则可能需要增加。如果可以确定当前没有运行 Foliate,则日志文件可能应该在开始时清空。

#!/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

答案2

是的,这并不是真正可以解决的:每个窗口都属于它自己的进程的假设是完全错误的。

您必须检查 Foliate 是否提供了一些 API,您可以使用这些 API 将窗口映射到该窗口中显示的文件 - 可能没有,中间有很多抽象级别。

所以,简而言之,以你目前的做法,是不可能达到你想要的效果的。

您可以实现一些要求 Foliate 专门将 WID 转换为在该窗口中打开的文档的功能,但这可能需要在 Foliate 代码库中进行认真的开发工作。

相关内容