Evidenzia lo schermo messo a fuoco (o dim-flash sul cambio di messa a fuoco, vedi EDIT più avanti)
In una configurazione a doppio monitor affiancata (sinistra-destra), lo script seguente imposta la luminosità del monitor con la finestra focalizzata su "normale" (100%), mentre l'altra è oscurata al 60%.
Se la messa a fuoco cambia, la luminosità seguirà la messa a fuoco:
concentrarsi su (una finestra) sullo schermo destro
concentrarsi su (una finestra) nella schermata di sinistra
Il copione
#!/usr/bin/env python3
"""
In a side-by-side dual monitor setup (left-right), the script below will set
the brightness of the monitor with the focussed window to "normal" (100%),
while other one is dimmed to 60%. If the focus changes, the brightness will
follow the focus
"""
import subprocess
import time
def get_wposition():
# get the position of the currently frontmost window
try:
w_data = subprocess.check_output(["wmctrl", "-lG"]).decode("utf-8").splitlines()
frontmost = subprocess.check_output(["xprop", "-root", "_NET_ACTIVE_WINDOW"]).decode("utf-8").split()[-1].strip()
z = 10-len(frontmost); frontmost = frontmost[:2]+z*"0"+frontmost[2:]
return [int(l.split()[2]) for l in w_data if frontmost in l][0]
except subprocess.CalledProcessError:
pass
def get_onscreen():
# get the size of the desktop, the names of both screens and the x-resolution of the left screen
resdata = subprocess.check_output(["xrandr"]).decode("utf-8")
if resdata.count(" connected") == 2:
resdata = resdata.splitlines()
r = resdata[0].split(); span = int(r[r.index("current")+1])
screens = [l for l in resdata if " connected" in l]
lr = [[(l.split()[0], int([s.split("x")[0] for s in l.split() if "+0+0" in s][0])) for l in screens if "+0+0" in l][0],
[l.split()[0] for l in screens if not "+0+0" in l][0]]
return [span, lr]
else:
print("no second screen seems to be connected")
def scr_position(span, limit, pos):
# determine if the frontmost window is on the left- or right screen
if limit < pos < span:
return [right_scr, left_scr]
else:
return [left_scr, right_scr]
def highlight(scr1, scr2):
# highlight the "active" window, dim the other one
action1 = "xrandr", "--output", scr1, "--brightness", "1.0"
action2 = "xrandr", "--output", scr2, "--brightness", "0.6"
for action in [action1, action2]:
subprocess.Popen(action)
# determine the screen setup
screendata = get_onscreen()
left_scr = screendata[1][0][0]; right_scr = screendata[1][1]
limit = screendata[1][0][1]; span = screendata[0]
# set initial highlight
oncurrent1 = scr_position(span, limit, get_wposition())
highlight(oncurrent1[0], oncurrent1[1])
while True:
time.sleep(0.5)
pos = get_wposition()
# bypass possible incidental failures of the wmctrl command
if pos != None:
oncurrent2 = scr_position(span, limit, pos)
# only set highlight if there is a change in active window
if oncurrent2 != oncurrent1:
highlight(oncurrent1[1], oncurrent1[0])
oncurrent1 = oncurrent2
Come usare
La sceneggiatura ha bisogno di wmctrl
:
sudo apt-get install wmctrl
Copia lo script in un file vuoto, salvalo come highlight_focus.py
Prova- eseguilo con il comando:
python3 /path/to/highlight_focus.py
Con il secondo monitor collegato , verificare se lo script funziona come previsto.
Se tutto funziona correttamente, aggiungilo alle applicazioni di avvio: Dash> Applicazioni di avvio> Aggiungi il comando:
/bin/bash -c "sleep 15 && python3 /path/to/highlight_focus.py"
Appunti
Lo script ha risorse estremamente ridotte. Per "risparmiare carburante", l'impostazione dello schermo; le risoluzioni, le dimensioni dell'intervallo ecc. vengono lette una sola volta, durante l'avvio dello script (non incluso nel ciclo). Ciò implica che è necessario riavviare lo script se si collega / disconnette il secondo monitor.
Se l'hai aggiunto alle applicazioni di avvio, significa che devi disconnetterti / accedere dopo le modifiche nella configurazione del monitor.
Se preferisci un'altra percentuale di luminosità per lo schermo oscurato, modifica il valore nella riga:
action2 = "xrandr", "--output", scr2, "--brightness", "0.6"
Il valore può essere compreso tra 0,0
(schermo nero) e 1.0
(100%).
Spiegazione
All'avvio dello script, determina:
- la risoluzione spanning di entrambi gli schermi
- la risoluzione x dello schermo sinistro
- i nomi di entrambi gli schermi
Quindi, in un ciclo (una volta al secondo), esso:
Se la posizione (x-) della finestra è maggiore della risoluzione x dello schermo sinistro, la finestra apparentemente si trova sullo schermo destro, a meno che non sia maggiore della dimensione di spanning dei due schermi (quindi sarebbe nell'area di lavoro su la destra). perciò:
if limit < pos < span:
determina se la finestra si trova sullo schermo destro (dove limit
è la x-res dello schermo sinistro, pos
è la posizione x della finestra ed span
è la x-res combinata di entrambe le schermate).
Se si verifica un cambiamento nella posizione della finestra in primo piano (sullo schermo sinistro o destro), lo script imposta la luminosità di entrambi gli schermi con il xrandr
comando:
xrandr --output <screen_name> --brightness <value>
MODIFICARE
Dim-flash dello schermo focalizzato invece di uno schermo "non focalizzato" oscurato permanente
Come richiesto in un commento e in chat, di seguito una versione dello script che fornisce un breve flash sullo schermo appena focalizzato:
#!/usr/bin/env python3
"""
In a side-by-side dual monitor setup (left-right), the script below will give
a short dim- flash on the newly focussed screen if the focussed screen changes
"""
import subprocess
import time
def get_wposition():
# get the position of the currently frontmost window
try:
w_data = subprocess.check_output(["wmctrl", "-lG"]).decode("utf-8").splitlines()
frontmost = subprocess.check_output(["xprop", "-root", "_NET_ACTIVE_WINDOW"]).decode("utf-8").split()[-1].strip()
z = 10-len(frontmost); frontmost = frontmost[:2]+z*"0"+frontmost[2:]
return [int(l.split()[2]) for l in w_data if frontmost in l][0]
except subprocess.CalledProcessError:
pass
def get_onscreen():
# get the size of the desktop, the names of both screens and the x-resolution of the left screen
resdata = subprocess.check_output(["xrandr"]).decode("utf-8")
if resdata.count(" connected") == 2:
resdata = resdata.splitlines()
r = resdata[0].split(); span = int(r[r.index("current")+1])
screens = [l for l in resdata if " connected" in l]
lr = [[(l.split()[0], int([s.split("x")[0] for s in l.split() if "+0+0" in s][0])) for l in screens if "+0+0" in l][0],
[l.split()[0] for l in screens if not "+0+0" in l][0]]
return [span, lr]
else:
print("no second screen seems to be connected")
def scr_position(span, limit, pos):
# determine if the frontmost window is on the left- or right screen
if limit < pos < span:
return [right_scr, left_scr]
else:
return [left_scr, right_scr]
def highlight(scr1):
# highlight the "active" window, dim the other one
subprocess.Popen([ "xrandr", "--output", scr1, "--brightness", "0.3"])
time.sleep(0.1)
subprocess.Popen([ "xrandr", "--output", scr1, "--brightness", "1.0"])
# determine the screen setup
screendata = get_onscreen()
left_scr = screendata[1][0][0]; right_scr = screendata[1][1]
limit = screendata[1][0][1]; span = screendata[0]
# set initial highlight
oncurrent1 = []
while True:
time.sleep(0.5)
pos = get_wposition()
# bypass possible incidental failures of the wmctrl command
if pos != None:
oncurrent2 = scr_position(span, limit, pos)
# only set highlight if there is a change in active window
if oncurrent2 != oncurrent1:
highlight(oncurrent2[0])
oncurrent1 = oncurrent2