Redirecionando o comando para executar um aplicativo
A maioria dos aplicativos abre a janela na tela em que foram iniciados (a partir do Dash ou do inicializador). Algumas aplicações, no entanto, não o fazem, mas podem ser forçadas a redirecionar o comando para executar a aplicação através do script abaixo. Para fazer isso, você precisará editar o arquivo .desktop
(launcher) correspondente.
A configuração parece um pouco complicada, mas se o procedimento for seguido ("Como usar"), não deve ser muito difícil.
Como funciona
- O script lê a posição do mouse no momento em que você clica no iniciador ou escolhe o aplicativo no Dash e determina em qual tela está (esquerda / direita).
- Subsequentemente, aguarda a nova janela aparecer, de propriedade do aplicativo (pid) que você iniciou.
- Quando a janela aparecer, ela verifica se a posição da janela (tela-) corresponde à posição inicial do mouse (tela-).
- Se não, move a janela para a tela da qual você iniciou o aplicativo. Na maioria dos casos, a ação estará em um estágio (muito) inicial da existência da janela, então você nem perceberá isso.
Problema / solução
Há um ponto negativo: se você substituir o comando main do arquivo .desktop
pelo comando para chamar este script, o botão direito do mouse "aberto com" não será trabalhe corretamente. No caso de um web browser como o Google Chrome, isso não será um problema muito grande. Com outros aplicativos, uma solução simples seria adicionar a opção de abrir uma nova janela na tela atual como um atalho (veja mais abaixo).
Como usar:
-
O script usa
wmctrl
exautomation
:sudo apt-get install xautomation sudo apt-get install wmctrl
-
Crie um diretório
~/bin
se ainda não existir. -
Copie o script em um arquivo vazio, salve-o como
open_oncurrent
(sem extensão) em~/bin
- Torne-o executável (!)
-
Copie o arquivo
.desktop
correspondente de/usr/share/applications
para~/.local/share/applications
:cp /usr/share/applications/google-chrome.desktop ~/.local/share/applications/google-chrome.desktop
-
Abra a cópia local em
~/.local/share/applications
:gedit ~/.local/share/applications/google-chrome.desktop
-
Edite o arquivo (duas opções):
-
Para alterar o comando main do iniciador:
-
encontre a linha:
Exec=/usr/bin/google-chrome-stable %U
-
altere para
Exec=/bin/bash -c "open_oncurrent /usr/bin/google-chrome-stable"
-
-
Para adicionar a opção como um atalho (como na imagem acima):
-
encontre a linha:
X-Ayatana-Desktop-Shortcuts=NewWindow;NewIncognito;
-
substitua por:
X-Ayatana-Desktop-Shortcuts=NewWindow;NewIncognito;New window on this screen;
-
Em seguida, adicione a seguinte seção ao final do arquivo:
[New window on this screen Shortcut Group] Name=New window on this screen Exec=/bin/bash -c "open_oncurrent /usr/bin/google-chrome-stable" TargetEnvironment=Unity
-
-
Como usar com outros aplicativos:
Da mesma forma, você pode aplicar a solução a outros aplicativos. A sintaxe do comando para usar no arquivo .desktop
é como no exemplo:
Exec=/bin/bash -c "open_oncurrent <command>"
Uma pequena explicação adicional sobre como lidar com exceções está no script.
O script
#!/usr/bin/env python3
import subprocess
import sys
import time
import getpass
t = 0; user = getpass.getuser(); application = sys.argv[1]
"""
In most cases, the command to run an application is the same as the process
name. There are however exceptions, to be listed below, if you use these appli-
cations i.c.w. this script. Just add an item to the list in the format:
["<command>", "<process_name>"],
"""
exceptions = [
["/usr/bin/google-chrome-stable", "chrome"],
]
try:
procname = [app[1] for app in exceptions if app[0] == application][0]
except IndexError:
procname = application
get = lambda cmd: subprocess.check_output(["/bin/bash", "-c", cmd]).decode("utf-8")
# initial position of the mouse (click position)
start_pos = int(get("xmousepos").strip().split()[0])
# x- position of right side of the screen
x_res = [int(s.split("x")[0]) for s in get("xrandr").split() if s.endswith("+0+0")][0]
# current windows
start_windows = get("wmctrl -l")
# open application
subprocess.call(["/bin/bash", "-c", application+"&"])
while t < 30:
procs = get("ps -u "+user).splitlines()
new = [w for w in get("wmctrl -lpG").splitlines() if not w.split()[0] in start_windows]
match = sum([[line for line in procs if w.split()[2] in line and procname[:15] in line] for w in new], [])
if len(match) == 1:
data = new[0].split(); curr_pos = int(data[3]); compare = (start_pos > x_res, curr_pos > x_res)
if compare[0] == compare[1]:
pass
else:
if compare[0] == True:
data[3] = str(int(data[3])+x_res)
else:
data[3] = str(int(data[3])-x_res)
cmd1 = "wmctrl -r "+data[0]+" -b remove,maximized_vert,maximized_horz"
cmd2 = "wmctrl -ir "+data[0]+" -e 0,"+(",").join(data[3:7])
for cmd in [cmd1, cmd2]:
subprocess.Popen(["/bin/bash", "-c", cmd])
break
t = t + 1
time.sleep(0.5)