Okularで同じファイルを2回開くと、既存のウィンドウに切り替わります。

Okularで同じファイルを2回開くと、既存のウィンドウに切り替わります。

私はなぜLinuxのファイルマネージャがアプリケーションが同じファイルを同時に2回開くのを防ぐことができないのか、いつも混乱していました。

A.pdf具体的には、PDFファイルリーダーであるOkularがすでにファイルを開いたままにしている場合は、そのファイルを再度開くのを防ぎたいと思います。警告を受け取るか、ファイルの開いたコピーを表示する必要がありますA.pdf

より一般的に言えば、Okularだけでなく、すべてのアプリケーションでこれが起こると予想されます。 Linuxのドキュメント管理動作がWindowsと同じであることを望みます。

答え1

ファイルマネージャは、ファイルを開くためにアプリケーションを呼び出す役割を担います。これは、アプリケーションがファイルとして実行する操作、特に同じファイルを2回開くと、アプリケーションが新しいウィンドウを開くかどうかを制御できません。

たとえば、同じ文書の異なる部分を表示したい場合は、複数のウィンドウで同じファイルを開くと便利です。したがって、同じ文書で複数のウィンドウを開くことを体系的に拒否することはお勧めできません。どのような動作がデフォルトであるかは、主に好みの問題です。一部のアプリはデフォルトで新しいウィンドウを開き、他のアプリはデフォルトで既存のウィンドウに焦点を当てています。

Okularはデフォルトで新しいウィンドウを開きます。 Start All Instancesを使用すると、okular --uniqueコマンドを2回目に実行すると新しいウィンドウが開きません(少なくともKDEを実行しない限り、既存のウィンドウに焦点を当てませんが)。最初のインスタンス--uniqueと2番目のインスタンスを起動する必要があります。

Gnome PDF ViewerであるEvinceは、デフォルトで目的の動作を実行します。同じ文書を2番目に開くと、既存のウィンドウに焦点を当てます。別のウィンドウを開くコマンドラインオプションはなく、GUI(メニューファイル→コピーを開く、またはCtrl+ N)でこれを行う必要があります。

答え2

私はOkularのflatpakバージョンに対して望ましい動作を達成するために次のスクリプトを書いています(私はLMDE 5を使用しています)。スクリプトはウィンドウタイトルの変更に基づいていますwmctrl

新しいウェルカム画面のために欲しい動作を得るのは難しかったですが、やったと思います。 (私はプロのプログラマーではないので、コードの改善に関する提案をいただきありがとうございます。)

スクリプトを実行する前に、「タイトルバーにドキュメントタイトルを表示する(利用可能な場合)」オプションの選択を解除し、「ドキュメントタイトルを表示しないとき」オプションを「フルファイルパスを表示」に設定します(スクリプトは変更しますが、さらに、「タブで新しいファイルを開く」オプションの選択を解除する必要があります。

#!/usr/bin/env bash
# Set expectedwindowtitle whether there is an argument or not, to handle the
# welcome screen: 
if [ -z "$1" ]
then
    expectedwindowtitle="Welcome"
else
    pdfbasename=$(basename "$1")
    pdffullpath=$(dirname "$(realpath "$1")")
    pdfpath=${pdffullpath/#$HOME/\~}
    expectedwindowtitle="$pdfbasename ($pdfpath)"
fi

# Search for a window with the substring "— Okular" in the title (with em-dash, 
# U+2014, that is, untouched), and get its ID and filename:
originaltitle=`wmctrl -l | grep -v "okularjump" | grep -v "grep" | grep -m 1 "— Okular" | awk 'BEGIN{RS="  — Okular"; FS="'$HOSTNAME' "}NF>1{print $NF}'`
originalwindowID=`wmctrl -l | grep -v "okularjump" | grep -v "grep" | grep -m 1 "— Okular" | awk '{ print $1; }'`

# If there is an existent window with the substring "— Okular" (with em-dash) 
# and a filename in the title, then rename it to a new format, as follows: 
# [basemane (short path) – Okular
# Note that the separator in the new format is an en-dash (U+2013) 
if [ ! -z "$originaltitle" ]
then
    originalfullpath=$(dirname "$originaltitle")
    originalbasename=$(basename "$originaltitle")
    originalpath=${originalfullpath/#$HOME/\~}
    newwindowname="$originalbasename ($originalpath) – Okular" # With en-dash 
    wmctrl -r $originaltitle -N "$newwindowname"  
fi

# Search for an already modified window title that matches the expected window 
# title and extract the basename and the path
existentwindowtitle=`wmctrl -l | grep -v "okularjump" | grep -v "grep" | grep "– Okular" | grep -m 1 "$expectedwindowtitle" | awk 'BEGIN{RS=" – Okular"; FS="'$HOSTNAME' "}NF>1{print $NF}'` # With en-dashes

# If expected and existent windows are the same, then switch to the existent 
# window
if [[ "$expectedwindowtitle" == "$existentwindowtitle" ]]
then
    wmctrl -a "$existentwindowtitle"
else
    # There is an argument and nothing to switch to. Then, open the argument with 
    # the new format in the title
    if [ ! -z "$1" ]
    then
        /usr/bin/flatpak run --branch=stable --arch=x86_64 --command=okular --file-forwarding org.kde.okular @@ "$1" @@ &>/dev/null &

        while ! test -n "$argoriginalwindowID"; do
            sleep 0.01
            argoriginalwindowID=`wmctrl -l | grep -v "okularjump" | grep -v "grep" | grep "— Okular" | grep -i -m 1 "$(basename "$1")" | awk '{ print $1; }'`
        done

        pdffullpath=$(dirname "$(realpath "$1")")
        pdfpath=${pdffullpath/#$HOME/\~}
        argWname="$(basename "$1") ($pdfpath) – Okular"
        wmctrl -ir $argoriginalwindowID -N "$argWname"

    else
        # There is no argument and nothing to switch to. Open a welcome screen 
        # with the word Welcome in the title (to make possible to find it later)
        /usr/bin/flatpak run --branch=stable --arch=x86_64 --command=okular --file-forwarding org.kde.okular --title "Welcome" &>/dev/null &
        while ! test -n "$welcomeWname"; do
            sleep 0.01
            welcomeWname=`wmctrl -l | grep -v "okularjump" | grep -v "grep" | grep -m 1 "— Okular" | grep -m 1 "Welcome"`
        done
        originalwindowID=`wmctrl -l | grep -v "okularjump" | grep -v "grep" | grep -m 1 "— Okular" | grep -m 1 "Welcome" | awk '{ print $1; }'`
        newwindowname="Welcome – Okular"
        wmctrl -ir $originalwindowID -N "$newwindowname"
    fi
fi

システムでデフォルトでスクリプトを使用できるようにするために、コードを ~/okularjump として保存し、実行可能にしてからコピーしました/usr/bin。その後、デフォルトの.desktopファイルをユーザーフォルダに2回コピーしました。デフォルトのflatpakランチャーを隠す時間:

chmod +x okularjump
sudo cp okularjump /usr/bin/
cp /var/lib/flatpak/app/org.kde.okular/current/active/export/share/applications/org.kde.okular.desktop ~/.local/share/applications/
cp /var/lib/flatpak/app/org.kde.okular/current/active/export/share/applications/org.kde.okular.desktop ~/.local/share/applications/okular.desktop
echo "Hidden=true" >> ~/.local/share/applications/org.kde.okular.desktop

その後、 ~/.local/share/applications/okular.desktop の Exec 行を次のように変更しました。Exec=okularjump %U

最後に、システム設定でOkularをデフォルトのPDFマネージャに設定しました。

同じファイルの複数のインスタンスを開く場合は、OpenダイアログでOkularでファイルを開くだけです。スクリプトは、次回実行時にウィンドウのタイトルを調整します。

Jumpappからインスピレーションを得ます。https://github.com/mkropat/jumpapp(これはFlatpak以外のバージョンでも動作しますが、わかりません)とFlatjumphttps://github.com/ceranco/platjump(これは私には効果がありませんでしたが、試してみてください。)

関連情報