¿Cómo resaltar la pantalla (o ventana) actual?

11

Estoy usando la configuración de dos pantallas en el trabajo y, aunque generalmente ayuda más de lo que duele, tengo algunos problemas.

Uno de ellos es el problema con el enfoque final: a veces cometo un error al escribir en una pantalla incorrecta (el enfoque sigue a mi cursor, pero no siempre es fácil notar que el cursor está en otra pantalla cuando haces cosas apuradas). Esto es muy molesto cuando, en lugar de escribir, provoco toneladas de acciones diferentes (accesos directos de una tecla en Thunderbird).

¿Hay alguna manera de resaltar mejor la pantalla o ventana activa (por ejemplo, usando un borde fácilmente visible, incluso para ventanas maximizadas)?

EDITAR:

Creo que una buena solución sería algún tipo de animación corta cuando la ventana recibe el foco.

korda
fuente
Cual DE? En gnome-shell puede usar extensiones.gnome.org/extension/891/windows-blur-effects
Rmano
1
@Rmano the tag sais Unity :)
Jacob Vlijm
1
@JacobVlijm oops --- cierto.
Dejaré

Respuestas:

13

Resalte la pantalla enfocada (o tenue destello en el cambio de enfoque, vea EDITAR más abajo)

En una configuración de monitor dual de lado a lado (izquierda-derecha), la secuencia de comandos a continuación establecerá el brillo del monitor con la ventana enfocada en "normal" (100%), mientras que el otro se atenúa al 60%.

Si el foco cambia, el brillo seguirá al foco:

centrarse en (una ventana) en la pantalla derecha ingrese la descripción de la imagen aquí

centrarse en (una ventana) en la pantalla izquierda ingrese la descripción de la imagen aquí

La secuencia de comandos

#!/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

Cómo utilizar

  1. El script necesita wmctrl:

    sudo apt-get install wmctrl
  2. Copie el script en un archivo vacío, guárdelo como highlight_focus.py

  3. Prueba: ejecútelo con el comando:

    python3 /path/to/highlight_focus.py

    Con el segundo monitor conectado , pruebe si el script funciona como se esperaba.

  4. Si todo funciona bien, agréguelo a las aplicaciones de inicio: Tablero> Aplicaciones de inicio> Agregue el comando:

    /bin/bash -c "sleep 15 && python3 /path/to/highlight_focus.py"

Notas

  • El guión es extremadamente bajo en recursos. Para "ahorrar combustible", la configuración de la pantalla; las resoluciones, el tamaño del tramo, etc. se leen solo una vez, durante el inicio del script (no incluido en el bucle). Eso implica que debe reiniciar el script si conecta / desconecta el segundo monitor.

  • Si lo agregó a las aplicaciones de inicio, significa que debe cerrar sesión / iniciar sesión después de los cambios en la configuración del monitor.

  • Si prefiere otro porcentaje de brillo para la pantalla atenuada, cambie el valor en la línea:

    action2 = "xrandr", "--output", scr2, "--brightness", "0.6"

El valor puede estar entre 0,0(pantalla negra) y 1.0(100%).

Explicación

ingrese la descripción de la imagen aquí

Al iniciar el script, determina:

  • La resolución de las dos pantallas.
  • la resolución x de la pantalla izquierda
  • los nombres de ambas pantallas

Luego, en un bucle (una vez por segundo), se:

  • Comprueba la posición de la ventana activa con los comandos:

    • wmctrl -lG (para obtener la lista de ventanas y sus posiciones)
    • xprop -root _NET_ACTIVE_WINDOW (para obtener la identificación de la ventana frontal)

Si la posición de la ventana (x-) es mayor que la resolución x de la pantalla izquierda, la ventana aparentemente está en la pantalla derecha, a menos que sea mayor que el tamaño de expansión de las dos pantallas (entonces estaría en el espacio de trabajo en la derecha). por lo tanto:

if limit < pos < span:

determina si la ventana está en la pantalla derecha (donde limitestá la resolución x de la pantalla izquierda, poses la posición x de la ventana y spanes la resolución x combinada de ambas pantallas).

Si hay un cambio en la posición de la ventana frontal (en la pantalla izquierda o derecha), el script establece el brillo de ambas pantallas con el xrandrcomando:

xrandr --output <screen_name> --brightness <value>

EDITAR

Atenúa la pantalla enfocada en lugar de una pantalla "desenfocada" atenuada permanente

Como se solicitó en un comentario y en el chat, a continuación se muestra una versión del script que muestra un breve destello tenue en la pantalla recién enfocada:

#!/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
Jacob Vlijm
fuente
+1. Siempre me encantan tus respuestas Jacob. Buen trabajo.
Parto
Tuve que cambiar limit < pos < spanpara limit <= pos < spanque funcione. De todos modos esto es realmente agradable. Sin embargo, no estoy seguro de si quiero que funcione de esta manera (atenuando la otra pantalla). Intentaré modificarlo para hacer un solo 'pulso' brillante cuando cambie la pantalla activa.
korda
También agregué el controlador de salida, restablece el brillo de la pantalla al valor normal. (por lo que no se atenuará cuando haya eliminado el script durante las pruebas). No estoy seguro de si debo añadir aquí - No soy mucho en Python, así que no estoy seguro de si lo hice bien (pero funciona)
korda
Edité tu respuesta y la agregué.
korda
1
@JacobVlijm ¡Guau! you rock
dhiya
1

También encontré otra solución, que es un poco diferente de lo que quería en primer lugar, pero también funciona bien.

  1. Instalar en pc compizconfig-settings-manager compiz-plugins
  2. Ejecute ccsm
  3. En la Effectssección habilite el Animationscomplemento
  4. En Focus Animationeditar y seleccionar la animación deseada.

Solo el efecto de onda funcionó ... Entonces, si no te gusta, tendrás una cara tan triste como la mía.

korda
fuente
Dodge también funciona para mí, pero solo cuando la ventana de elevación estaba oculta o parcialmente oculta detrás de otra. Fade da un destello extraño y desagradable.
Paddy Landau