Okular에서 동일한 파일을 두 번 열면 기존 창으로 전환됩니다.

Okular에서 동일한 파일을 두 번 열면 기존 창으로 전환됩니다.

나는 왜 Linux의 파일 관리자가 응용 프로그램이 동일한 파일을 동시에 두 번 여는 것을 방지할 수 없는지 항상 혼란스러워했습니다.

A.pdf특히, PDF 파일 리더인 Okular가 이미 파일을 열어 놓은 경우 해당 파일을 다시 열지 못하도록 하고 싶습니다 . 경고를 받거나 파일의 열린 복사본을 표시해야 합니다 A.pdf.

더 일반적으로 말하면 Okular뿐만 아니라 모든 응용 프로그램에서 이런 일이 발생할 것으로 예상됩니다. Linux의 문서 관리 동작이 Windows와 동일하기를 원합니다.

답변1

파일 관리자는 파일을 열기 위해 애플리케이션을 호출하는 역할을 담당합니다. 이는 응용 프로그램이 파일로 수행하는 작업, 특히 동일한 파일을 두 번 열 경우 응용 프로그램이 새 창을 열지 여부를 제어할 수 없습니다.

예를 들어 동일한 문서의 다른 부분을 보려는 경우 여러 창에서 동일한 파일을 여는 것이 유용할 수 있습니다. 따라서 동일한 문서에서 여러 창을 여는 것을 체계적으로 거부하는 것은 좋지 않습니다. 어떤 동작이 기본값인지는 대부분 취향의 문제입니다. 일부 앱은 기본적으로 새 창을 열고 다른 앱은 기본적으로 기존 창에 초점을 맞춥니다.

Okular는 기본적으로 새 창을 엽니다. Start All Instances 를 사용하면 okular --unique명령을 두 번째로 실행할 때 새 창이 열리지 않습니다(적어도 KDE를 실행하지 않는 경우 기존 창에 초점을 맞추지는 않지만). 첫 번째 인스턴스 --unique와 두 번째 인스턴스를 시작해야 합니다.

Gnome PDF 뷰어인 Evince는 기본적으로 원하는 동작을 수행합니다. 동일한 문서를 두 번째로 열면 기존 창에 초점을 맞춥니다. 별도의 창을 여는 명령줄 옵션이 없으며 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 파일을 사용자 폴더에 두 번 복사했습니다. 기본 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 관리자로 설정했습니다.

동일한 파일의 여러 인스턴스를 여는 경우에는 열기 대화 상자를 통해 Okular에서 파일을 열면 됩니다. 스크립트는 다음에 실행될 때 창 제목을 조정합니다.

Jumpapp에서 영감을 얻습니다.https://github.com/mkropat/jumpapp(이것은 Flatpak이 아닌 버전에서도 작동하지만 확실하지 않습니다) 및 Flatjumphttps://github.com/ceranco/platjump(이것은 나에게는 효과가 없었지만 시도해 보시기 바랍니다.)

관련 정보