GNU/Linux >> Tutoriales Linux >  >> Ubuntu

¿Bloquear los atajos de teclado de Unity cuando cierta aplicación está activa?

Los grandes IDE de JetBrains (IDEA et al.) asignan prácticamente todos los atajos de teclado imaginables a alguna función. Si bien a veces es un poco abrumador, también permite un uso eficiente.

Mi problema es que Unity también asigna algunos de estos accesos directos y tienen prioridad. Un ejemplo particularmente molesto es CTRL + ALT + L . El problema se ha explorado antes aquí.

Sin embargo, ninguno de los enfoques es satisfactorio.

  1. Desactivar accesos directos del sistema globalmente impide mi productividad general con el sistema.
  2. Cambiar a un mapa de teclas diferente en IDEA me confundirá mucho cuando desarrolle en diferentes plataformas (y tenga que elegir diferentes asignaciones).

¿Hay alguna manera de desactivar los accesos directos del sistema solo cuando una determinada aplicación está activa, es decir, ejecutándose y enfocada?

Estaría dispuesto a ejecutar un script cada vez que inicie la aplicación.

Respuesta aceptada:

Cómo deshabilitar automáticamente múltiples accesos directos (específicos) si (y mientras) la ventana de una aplicación específica esté activa

El siguiente script deshabilitará atajos de teclado específicos cuando la ventana de una aplicación arbitraria esté activa.

Aunque mencionaste""Estaría dispuesto a ejecutar un script cada vez que inicie la aplicación". , No hay razón para matar el guión después, es extremadamente bajo en jugo.

El guión

#!/usr/bin/env python3
import subprocess
import time
import os

app = "gedit"

f = os.path.join(os.environ["HOME"], "keylist")

def run(cmd):
    subprocess.Popen(cmd)

def get(cmd):
    try:
        return subprocess.check_output(cmd).decode("utf-8").strip()
    except:
        pass

def getactive():
    return get(["xdotool", "getactivewindow"])

def setkeys(val):
    # --- add the keys to be disabled below  
    keys = [
         ["org.gnome.settings-daemon.plugins.media-keys", "logout"],
         ["org.gnome.settings-daemon.plugins.media-keys", "screensaver"],
        ]
    # ---
    writelist = []
    if not val:
        try:
            values = open(f).read().splitlines()
        except FileNotFoundError:
            values = []
        for i, key in enumerate(keys):
            try:
                cmd = ["gsettings", "set"]+key+[values[i]]
            except IndexError:
                cmd = ["gsettings", "reset"]+key
            run(cmd)
    else:
        for key in keys:
            cmd = ["gsettings", "set"]+key+["['']"]
            read =  get(["gsettings", "get"]+key)
            writelist.append(read)
            run(cmd)

    if writelist:
        open(f, "wt").write("n".join(writelist))

front1 = None

while True:
    time.sleep(1)
    pid = get(["pgrep", app])
    if pid:
        try:
            active = get(["xdotool", "getactivewindow"])
            relevant = get(["xdotool", "search", "--all", "--pid", pid]).splitlines()
            front2 = active in relevant
        except AttributeError:
            front2 = front1           
    else:
        front2 = False
    if front2 != front1:
        if front2:
            setkeys(True)
        else:
            setkeys(False)

    front1 = front2

Cómo usar

  1. El script necesita xdotool :

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

  3. En el encabezado del script, reemplace en la línea:

    app = "gedit"
    

    "gedit" por su aplicación, lo que significa:el nombre del proceso que posee la ventana.

  4. Pruebe el script con el comando:

    python3 /path/to/disable_shortcuts.py
    
  5. Si todo funciona bien, agréguelo a Aplicaciones de inicio:Tablero> Aplicaciones de inicio> Agregar. Agregue el comando:

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

Agregar más accesos directos para deshabilitar

Como ejemplo, agregué el atajo que mencionaste:CTRL + ALT + L . Los accesos directos se establecen en el dconf base de datos, y se puede configurar o deshabilitar usando gsettings .

En el script, estos gsettings las entradas se establecen en la función:setkeys()

def setkeys(val):
    # --- add the keys to be disabled below
    keys = [
        ["org.gnome.settings-daemon.plugins.media-keys", "screensaver"]
        ]
    # ---

Un ejemplo para agregar (deshabilitar) el acceso directo para cerrar sesión:

  1. Abra una ventana de terminal, ejecute el comando dconf watch /
  2. Abra Configuración del sistema> "Teclado"> "Accesos directos"> "Sistema"
  3. Vuelva a configurar el acceso directo a sí mismo. En la terminal, puedes ver la gsettings tecla que pertenece al atajo:

  4. Ahora tenemos que agregar la clave encontrada (en una apariencia ligeramente diferente):

    ["org.gnome.settings-daemon.plugins.media-keys", "logout"]
    

    …a la lista de “claves” en nuestra función:

    def setkeys(val):
        # --- add the keys to be disabled below
        keys = [
            ["org.gnome.settings-daemon.plugins.media-keys", "screensaver"],
             ["org.gnome.settings-daemon.plugins.media-keys", "logout"],
            ]
    

Ahora ambos CTRL + ALT + L y CTRL + ALT + Eliminar están deshabilitados si su aplicación está al frente.

Relacionado:¿Relación de distribución de teclado y xmodmap?

Explicación

Como se mencionó, los atajos, como los que mencionas, se establecen en el dconf base de datos. En el ejemplo CTRL + ALT + L , la clave para establecer o editar el atajo es:

org.gnome.settings-daemon.plugins.media-keys screensaver

Para deshabilitar la clave, el comando es:

gsettings set org.gnome.settings-daemon.plugins.media-keys screensaver ""

Para restablecer la clave a su valor predeterminado:

gsettings reset org.gnome.settings-daemon.plugins.media-keys screensaver

El script se ve una vez por segundo si:

  • su aplicación se ejecuta en absoluto
  • si es así, mira si alguna de sus ventanas está activa
  • de nuevo (solo) si es así, deshabilita los accesos directos, enumerados en

    # --- add the keys to be disabled below
    keys = [
        ["org.gnome.settings-daemon.plugins.media-keys", "screensaver"],
         ["org.gnome.settings-daemon.plugins.media-keys", "logout"],
       ]
    

    …esperando el próximo cambio de estado.

Si la ventana activa ya no es una de sus aplicaciones, las teclas mencionadas en la lista se restablecen a los valores predeterminados.

Nota

Como se mencionó anteriormente, la carga adicional para el procesador del script es nula. Podría muy bien ejecutarlo al inicio, como se explica en "Cómo usarlo".

Afectando a múltiples aplicaciones

Como se discutió en los comentarios, en el caso específico de OP, es útil aplicar accesos directos de desactivación en un grupo de aplicaciones, todas residiendo en un directorio.

Debajo de una versión para aplicar esto en todas las aplicaciones de las cuales la salida de

pgrep -f 

incluirá un directorio específico. En mi ejemplo, configuré /opt directorio, por lo que si la ventana activa es una de las aplicaciones en /opt , los accesos directos establecidos se desactivarán.

traer una ventana de una de las aplicaciones en /opt al frente desactivará el atajo de cierre de sesión

volver a habilitar el acceso directo si otra ventana recibe el foco

El guión

#!/usr/bin/env python3
import subprocess
import time
import os 

appdir = "/opt"

f = os.path.join(os.environ["HOME"], "keylist")

def run(cmd):
    subprocess.call(cmd)

def get(cmd):
    try:
        return subprocess.check_output(cmd).decode("utf-8").strip()
    except:
        pass

def getactive():
    return get(["xdotool", "getactivewindow"])

def setkeys(val):
    # --- add the keys to be disabled below  
    keys = [
         ["org.gnome.settings-daemon.plugins.media-keys", "logout"],
         ["org.gnome.settings-daemon.plugins.media-keys", "screensaver"],
         ["org.gnome.desktop.wm.keybindings", "begin-move"],
        ]
    # ---
    writelist = []
    if not val:
        try:
            values = open(f).read().splitlines()
        except FileNotFoundError:
            values = []
        # for key in keys:
        for i, key in enumerate(keys):
            try:
                cmd = ["gsettings", "set"]+key+[values[i]]
            except IndexError:
                cmd = ["gsettings", "reset"]+key
            run(cmd)
    else:
        for key in keys:
            cmd = ["gsettings", "set"]+key+["['']"]
            read =  get(["gsettings", "get"]+key)
            writelist.append(read)
            run(cmd)
    if writelist:
        open(f, "wt").write("n".join(writelist))

front1 = None

while True:
    time.sleep(1)
    # check if any of the apps runs at all
    checkpids = get(["pgrep", "-f", appdir])
    # if so:
    if checkpids:
        checkpids = checkpids.splitlines()
        active = getactive()
        # get pid frontmost (doesn't work on pid 0)
        match = [l for l in get(["xprop", "-id", active]).splitlines()
                 if "_NET_WM_PID(CARDINAL)" in l]
        if match:
            # check if pid is of any of the relevant apps
            pid = match[0].split("=")[1].strip()
            front2 = True if pid in checkpids else False
        else:
            front2 = False
    else:
        front2 = False
    if front2 != front1:
        if front2:
            setkeys(True)
        else:
            setkeys(False)
    front1 = front2

Cómo usar

  1. Como el primer script, xdotool necesita ser instalado:

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

  3. En el encabezado del script, reemplace en la línea:

    appdir = "/opt"
    

    “/opt” por el directorio donde se encuentran sus aplicaciones.

  4. Pruebe el script con el comando:

    python3 /path/to/disable_shortcuts.py
    
  5. Si todo funciona bien, agréguelo a Aplicaciones de inicio:Tablero> Aplicaciones de inicio> Agregar. Agregue el comando:

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

Agregar otros accesos directos a la lista funciona exactamente de manera similar a la versión 1 del script.

Relacionado:¿No se puede actualizar Logitech Unify Firmware usando fwupd?

¿Funciona en todas las aplicaciones?

En su respuesta, menciona:

xprop no revela los PID para todas las ventanas. Ejemplo fallido:cronómetro.

Windows con pid 0 (como tkinter windows, incluido Idle), no tiene window- id en la salida de xprop -id . Idle no tiene ningún atajo en conflicto, aunque en mi experiencia. Si se encuentra con alguna aplicación con pid 0 que requiera deshabilitar accesos directos específicos, menciónelo.

En ese caso, un posible escape sería convertir la salida de

xdotool getactivewindow

a hexadecimal, el formato wmctrl usa, y luego busca el pid correspondiente en la salida de

wmctrl -lp

Aunque eso parecía lo más obvio para empezar, no lo usé en el guión para mantener el guión lo más ligero posible.


Ubuntu
  1. ¿Cómo evitar que Unity 2d intercepte la metaclave cuando estoy en Virtualbox?

  2. ¿Atajos de teclado globales rotos en 14.04?

  3. ¿Problemas con el teclado que no funciona cuando se inicia?

  4. ¿La búsqueda de un nombre de aplicación devuelve "lo siento, no coincide" en Ubuntu 14.04?

  5. ¿Cómo cambiar los atajos de teclado de Evolution?

Atajos de teclado de Ubuntu que todo usuario debe conocer

El poderoso mundo de los atajos de teclado de Ubuntu

Cómo agregar accesos directos a aplicaciones en el escritorio de Ubuntu

¿Es posible colocar ventanas con atajos de teclado en Gnome-shell?

¿Utiliza la aplicación Disk Utility como usuario de Sudo en Unity o en CLI?

¿Cuándo caduca una versión activa de Ubuntu?