Uma solução descaradamente suja
Para conseguir um comando que faz o que você quer, acaba por ser mais complicado do que parece à primeira vista. O problema é abaixar a janela e manter a ordem das janelas (z-wise) ao mesmo tempo, o que parece quase impossível. Tanto xdotool
como wmctrl
fornecem comandos para aumentar uma janela, mas não para abaixar uma janela.
A solução abaixo é um truque sujo, mas funciona bem e de forma confiável. Ele usa os dois wmctrl
e xdotool
, que não estão no seu sistema por padrão.
Embora o script seja executado por um atalho de teclado, ele realmente faz exatamente o mesmo que quando você clica com o botão do meio na parte superior da sua janela. O que faz:
- Procura a janela ativa (usando
xprop -root
) - pesquisa se a janela é "normal" (ao contrário da sua área de trabalho, que também está listada em
wmctrl -lG
como uma janela) - Se sim, calcula a posição do topo da janela, move o mouse para a posição calculada, simula o clique do meio e move o mouse de volta para onde você o deixou.
Tudo isso acontece em uma fração de segundo, então você nem notará o movimento do mouse e o movimento de volta. A única coisa que você nota é a janela enviada de volta, que é exatamente o que você quer.
O script
#!/usr/bin/env python3
import subprocess
import time
# find the frontmost window
active = [l for l in subprocess.check_output(["xprop", "-root"]).decode("utf-8").splitlines() \
if "_NET_ACTIVE_WINDOW(WINDOW)" in l][0].split("#")[-1].strip()
# convert the window-id from xprop- format to wmctrl- format
w_id = active[:2] + str((10-len(active))*"0")+active[2:]
# if the window is a "normal" window, find the window geometry in wmctrl -lG,
# move the mouse to the top of the window and click the middle button
if "_NET_WM_WINDOW_TYPE_NORMAL" in subprocess.check_output(["xprop", "-id", w_id]).decode("utf-8"):
match = [l for l in subprocess.check_output(["wmctrl", "-lG"]).decode("utf-8").splitlines() if w_id in l][0].split()[2:6]
current_mousepos = subprocess.check_output(["xdotool", "getmouselocation"]).decode("utf-8").split()
coords = ([s.replace("x:", "") for s in current_mousepos if s.startswith("x:")][0],
[s.replace("y:", "") for s in current_mousepos if s.startswith("y:")][0])
top_x = str(int(int(match[0])+(int(match[2])/2))); top_y = str(int(match[1]) -10)
# The time.sleep(0.3) possibly needs to be optimized (longer sleep = safer); the 0.3 works fine on my system when used from a keyboard shortcut (which turns out to make a difference...)
subprocess.Popen(["xdotool", "mousemove", "--sync", top_x, top_y]); time.sleep(0.3)
# move the mouse back to its original position
subprocess.Popen(["xdotool", "click", "2"]); time.sleep(0.05)
subprocess.Popen(["xdotool", "mousemove", coords[0], coords[1]])
Como usar
-
Instale os dois
wmctrl
exdotool
sudo apt-get install xdotool wmctrl
-
Copie o script acima em um arquivo vazio, salve-o como
sendtoback.py
-
Teste- execute o script abrindo um terminal, execute o comando nele:
python3 /path/to/sendtoback.py
A janela deve ser enviada para o fundo, exatamente como você estava acostumado quando clicou no meio.
-
Se tudo funcionar bem, escolha: Configurações do sistema > "Teclado" > "Atalhos" > "Atalhos personalizados". Clique no botão "+" e adicione o comando:
python3 /path/to/sendtoback.py
para um atalho-chave de sua escolha.
Nota
Em alguns casos (especialmente em sistemas mais lentos), o tempo de espera na linha:
subprocess.Popen(["xdotool", "mousemove", "--sync", top_x, top_y]); time.sleep(0.3)
precisa ser aumentado. Em sistemas mais rápidos, isso poderia ser reduzido.