A causa
O mais provável é que o problema seja o resultado de um bug (relacionado ao driver de vídeo). Presumo que a segunda tela não seja lembrada de alguma forma e "virtualmente" reconectada em um estágio bastante avançado no processo de início de sessão (log in).
contornar
Como sempre, mesmo que seja um bug, isso não significa que não podemos encontrar uma solução. Se nós:
- pode fazer algum tipo de instantâneo das posições atuais do ícone ao sair
- restaura as posições dos ícones após a segunda tela aparece corretamente após a reinicialização (login)
efetivamente o bug é contornado.
Como ler a posição do ícone na área de trabalho
Você pode obter a posição na área de trabalho de um ícone pelo comando:
gvfs-info -a 'metadata::nautilus-icon-position' '<file>'
Isso vai a.o. saída as coordenadas do ícone na sua área de trabalho, que podemos salvar em um arquivo. Se fizermos um snapshot desta forma de sua área de trabalho antes desligar o computador, poderemos posteriormente restaurar a posição do ícone depois, com o comando:
gvfs-set-attribute -t string '<file>' 'metadata::nautilus-icon-position' '500,500'
(por exemplo)
Um script para capturar um instantâneo e restaurar o layout do ícone (dependendo do argumento) seria:
#!/usr/bin/env python3
import subprocess
import os
import sys
# --- set your localized desktop name below:
dt_name = "Bureaublad"
# ---
# used strings & definitions
val = " 'metadata::nautilus-icon-position' "
search = "gvfs-info -a"+val
set_val = "gvfs-set-attribute -t string "
home = os.environ["HOME"]
dt_dir = home+"/"+dt_name
datafile = home+"/.desktop_items.txt"
arg = sys.argv[1]
get = lambda cmd: subprocess.check_output(["/bin/bash", "-c", cmd]).decode("utf-8")
def snapshot():
try:
os.remove(datafile)
except FileNotFoundError:
pass
dt_items = os.listdir(dt_dir)
dt_data = []
for f in [f for f in dt_items if all([not f.startswith("."), not f.endswith("~")])]:
f = '"'+f+'"' if f.count(" ") > 0 else f
file = dt_dir+"/"+f
cmd = search+file
try:
loc = [int(n) for n in get(cmd).split()[-1].split(",")]
# loc[0] = loc[0] - screen_pos[0]; loc[1] = loc[1] - screen_pos[1]
loc = (",").join([str(n) for n in loc])
open(datafile, "a+").write(file+"|||"+loc+"\n")
except:
pass
subprocess.Popen(["/bin/bash", "-c", "notify-send 'A snapshot was taken'"])
def restore():
items = [l.strip().split("|||") for l in open(datafile).readlines()]
for item in items:
try:
xy = [int(n) for n in item[1].split(",")]
move_to = (",").join(str(n) for n in [xy[0], xy[1]])
command = set_val+item[0]+val+move_to
subprocess.Popen(["/bin/bash", "-c", command])
except:
pass
subprocess.Popen(["/bin/bash", "-c", "notify-send 'Click on the desktop and press F5'"])
if arg == "snapshot":
snapshot()
elif arg == "restore":
restore()
Para usá-lo:
- Copie o script em um arquivo vazio, salve-o como
restore_desktop.py
-
Na seção principal do script, na linha:
# --- set your localized desktop name below: dt_name = "Desktop" # ---
defina o nome localizado da sua pasta da área de trabalho ("Bureaublad" em holandês)
-
Para tirar um snapshot do layout atual do ícone, execute o comando:
python3 /path/to/restore_desktop.py snapshot
-
Para restaurar um instantâneo tirado anteriormente:
python3 /path/to/restore_desktop.py restore
depois clique na área de trabalho e pressione F5 para atualizar a área de trabalho.
Para usar o script em nossa situação, no entanto, precisamos de algumas adições
-
A área de trabalho ainda precisa ser atualizada da linha de comando para aplicar a restauração dos ícones. Isso pode ser feito reiniciando
nautilus
ou pressionando F5 com a área de trabalho na frente. Como usamos na inicialização, a primeira opção pode ser a mais elegante. -
Precisamos tirar um instantâneo no logout como usuário atual para garantir que o último layout de ícone seja gravado em um instantâneo. Até agora, não consegui encontrar uma maneira de fazer isso. No entanto, como sempre, há uma solução alternativa. Se incluirmos o comando
gnome-session-quit --poweroff
em nosso script, podemos simplesmente chamar o script (com os argumentos certos) para incluir o procedimento de desligamento e capturar o instantâneo.
- Em seguida, para garantir que o instantâneo restaurado seja aplicado , podemos incluir o reinício do nautilus no script.
A solução
O script final torna-se então:
#!/usr/bin/env python3
import subprocess
import os
import sys
import time
# --- set your localized desktop name below:
dt_name = "Desktop"
# ---
# used strings & definitions
val = " 'metadata::nautilus-icon-position' "
search = "gvfs-info -a"+val
set_val = "gvfs-set-attribute -t string "
home = os.environ["HOME"]
dt_dir = home+"/"+dt_name
datafile = home+"/.desktop_items.txt"
arg = sys.argv[1]
get = lambda cmd: subprocess.check_output(["/bin/bash", "-c", cmd]).decode("utf-8")
def snapshot():
# remove the previous snapshot
try:
os.remove(datafile)
except FileNotFoundError:
pass
# list the items on the desktop, look up their positions
dt_items = os.listdir(dt_dir)
dt_data = []
for f in [f for f in dt_items if all([not f.startswith("."), not f.endswith("~")])]:
f = '"'+f+'"' if f.count(" ") > 0 else f
file = dt_dir+"/"+f
cmd = search+file
try:
loc = [int(n) for n in get(cmd).split()[-1].split(",")]
loc = (",").join([str(n) for n in loc])
open(datafile, "a+").write(file+"|||"+loc+"\n")
except:
pass
# notify that a snapshot was taken
subprocess.call(["/bin/bash", "-c", "notify-send 'A snapshot was taken'"])
# send the command to shutdown
subprocess.Popen(["gnome-session-quit", "--power-off"])
def restore():
# wait for 20 seconds for the desktop to be fully loaded and the screen to be found
time.sleep(20)
# read the snapshot file
items = [l.strip().split("|||") for l in open(datafile).readlines()]
for item in items:
try:
# place the icon(s) acoording to the remembered position(s)
xy = [int(n) for n in item[1].split(",")]
move_to = (",").join(str(n) for n in [xy[0], xy[1]])
command = set_val+item[0]+val+move_to
subprocess.Popen(["/bin/bash", "-c", command])
except:
pass
# restart nautilus
subprocess.call(["killall", "nautilus"])
subprocess.Popen(["nautilus"])
# send notification
subprocess.Popen(["/bin/bash", "-c", "notify-send 'Icon positions were restored'"])
if arg == "snapshot":
snapshot()
elif arg == "restore":
restore()
Como usar
- Copie o script em um arquivo vazio, salve-o como
restore_icons.py
-
Na seção head do script, defina o nome (localizado) apropriado da pasta
Desktop
:# --- set your localized desktop name below: dt_name = "Desktop" # ---
-
Teste- execute o script executando o comando:
python3 /path/to/restore_icons.py snapshot
Um instantâneo do layout atual será executado. O menu desligar aparece na sua área de trabalho, mas cancele clicando fora do menu na sua área de trabalho.
Emseguida,mexadeliberadamentecomseusícones(posições)nasuaáreadetrabalho.
Finalmente,executeoscriptnovamentecomoutroargumento:python3/path/to/restore_icons.pyrestore
Aguarde20segundos(vejaNotanaparteinferiorporqueissoestáincluídonoscript)eseusíconesdaáreadetrabalhoserãorestauradosparaaformacomoficouantesdevocêtirarafoto.
Setudofuncionarbem,adicioneumatecladeatalho:Escolha:Configuraçõesdosistema>"Teclado" > "Atalhos" > "Atalhos personalizados". Clique no botão "+" e adicione o comando:
python3 /path/to/restore_icons.py snapshot
Este será o atalho que você precisa usar para desligar seu computador.
-
Adicione o comando restore para Startup Applications: Dash > Aplicativos de inicialização > Adicionar. Adicione o comando:
python3 /path/to/restore_icons.py restore
Agora, 20 segundos após a inicialização (login), seus ícones ficarão exatamente como você os deixou no desligamento.
Nota
A pausa de 20 segundos é para garantir que o segundo monitor seja encontrado e reconectado antes que o comando restore seja executado.