Here is a quick and dirty trick : it is a Python script that just checks for an existing instance.
To use it, rename /usr/bin/okular
to /usr/bin/okular.real
and save this script as /usr/bin/okular
.
#! /usr/bin/env python3
import subprocess
import sys
import os
import getpass
OKULAR_FN = "okular.real"
def get_okular_instance(filename) :
try :
lproc = subprocess.check_output(["ps", "-C", OKULAR_FN, "-o", "pid,user,args", "--no-headers"], universal_newlines=True).splitlines()
except subprocess.CalledProcessError :
return []
result = []
me = getpass.getuser()
for proc in lproc :
pid, user, _, args = proc.split(maxsplit=3)
if user == me and args == filename :
result.append(pid)
return result
def get_window_id(pid) :
fenetres = subprocess.check_output(["wmctrl", "-ulp"], universal_newlines=True)
for f in fenetres.splitlines() :
donnees = f.split()
if len(donnees) < 3 :
continue
if donnees[2] == pid :
return donnees[0]
return None
def raise_window(wid) :
subprocess.call(["wmctrl", "-i", "-a", wid])
def runcmd(cmdl) :
subprocess.Popen(cmdl, stdin=None, stdout=None, stderr=None, close_fds=True)
def main() :
if len(sys.argv) < 2 :
runcmd([OKULAR_FN])
else :
filename = os.path.abspath(sys.argv[1])
pidl = get_okular_instance(filename)
if len(pidl) != 1 :
runcmd([OKULAR_FN, filename])
else :
wid = get_window_id(pidl[0])
if wid is None :
runcmd([OKULAR_FN, filename])
else :
raise_window(wid)
if __name__ == "__main__" :
main()
Thanks, I'm using this to provide the same desired behaviour with Lyx, and it's perfect. – Autumn – 2019-10-04T21:37:59.920
Thanks, would it be possible with a similar python or bash function and .bashrc shortcut that internally finds whether an instance exists and should be used. Then you can call this function from terminal, without modifying okular in bin. Or isn't changing the okular in bin a problem (package manager, etc.)? Thanks anyway for sharing your useful code with this answer – Peruz – 2020-02-27T18:04:43.260
You might want to leave /usr/bin/okular untouched and create the script in /usr/local/bin/okular or even ~/bin/okular. It should take precedence but you may have to adapt the code slightly. – ysalmon – 2020-02-28T15:23:42.053