Caso interessante.
O que precisamos levar em conta
O conceito não é complicado: basta definir todas as janelas fixas, no entanto :
- Como você deseja excluir alguns aplicativos, precisaremos listar esses aplicativos e verificar as janelas para a classe de janelas deles, para decidir se devemos defini-los como fixos (exibidos em todos os espaços de trabalho) ou não.
- A lista de janelas, como saída de
wmctrl -l
, também mostra alguns tipos de janelas, como DOCK e DESKTOP, das quais você não deve editar suas propriedades em geral. - Precisamos garantir que apenas o novo windows sticky seja definido, para evitar o consumo desnecessário de combustível.
Exemplo de script (python)
No script abaixo:
-
um ciclo de dois segundos é executado para comparar a lista de janelas com a anterior, usando:
wmctrl -l
e, em seguida, extrair o id da janela de cada uma das linhas
-
Posteriormente, o script é executado
xprop -id <window_id>
Em que podemos encontrar informações sobre o
_NET_WM_WINDOW_TYPE
e oWM_CLASS
- Se a nova janela "passar" nesses testes, i.o.w. a janela não pertence a nenhuma das aplicações excluídas e não é de nenhum dos tipos excluídos, ela está definida como fixada.
Como o script atua somente nas janelas recém-criadas, ele não adicionará nenhum ônus perceptível ao sistema.
O script
#!/usr/bin/env python3
import subprocess
import time
# excluded applications
apps = ["gedit", "chromium", "monkey"]
# ignored window types
ignore = [
"= _NET_WM_WINDOW_TYPE_DOCK",
"= _NET_WM_WINDOW_TYPE_DESKTOP",
]
# just a helper
def get(cmd):
try:
return subprocess.check_output(cmd).decode("utf-8").strip()
except (subprocess.CalledProcessError, TypeError):
pass
# initiate windowlist
wins1 = []
while True:
# cycle time
time.sleep(2)
# initiate new list
new_wins = []
# get the most recent window list
windata = get(["wmctrl", "-l"])
if windata:
# extract window -ids
wins2 = [w.split()[0] for w in windata.splitlines()]
new = [w for w in wins2 if w not in wins1]
# check for excluded classes and window types
for w in new:
testdata = get(["xprop", "-id", w])
if all([
not any([ig in testdata for ig in ignore]),
not any([app in testdata for app in apps]),
]):
# set the passed windows to sticky
subprocess.Popen(
["wmctrl", "-i", "-r", w, "-b", "add,sticky"]
)
# refresh the window list for next cycle
wins1 = wins2
Como configurar
-
Certifique-se de que
wmctrl
esteja instalado:sudo apt install wmctrl
- Copie o script em um arquivo vazio, salve-o como
set_sticky.py
- Na seção head do seu script, defina o
WM_CLASS
-ses para excluir (você pode querer remover o macaco, foi para fins de teste :)) -
Teste-o com o comando:
python3 /path/to/set_sticky.py
-
Se tudo funcionar bem, você poderá adicioná-lo aos aplicativos de inicialização, mas adicione uma pequena pausa para evitar que o script seja invadido em uma área de trabalho ainda não pronta:
/bin/bash -c "sleep 10 && python3 /path/to/set_sticky.py"
Divirta-se:)
Nota
Eu testei no Ubuntu Budgie (murmure) por 25 minutos sem problema. Ele deve rodar bem em qualquer gerenciador de janelas, mas caso você tenha um problema, apenas mencione.