GNU/Linux >> Linux Esercitazione >  >> Ubuntu

Blocca le scorciatoie da tastiera di Unity quando una determinata applicazione è attiva?

I grandi IDE JetBrains (IDEA et al.) Assegnano praticamente ogni possibile scorciatoia da tastiera a qualche funzione. Anche se a volte leggermente opprimente, rende anche un uso efficiente.

Il mio problema è che Unity assegna anche alcune di queste scorciatoie e hanno la precedenza. Un esempio particolarmente fastidioso è CTRL + ALT + L . Il problema è già stato esplorato qui.

Tuttavia, nessuno degli approcci è soddisfacente.

  1. Disattivazione delle scorciatoie di sistema a livello globale ostacola la mia produttività complessiva con il sistema.
  2. Il passaggio a una mappa di tasti diversa in IDEA mi confonderà a morte quando sviluppo su piattaforme diverse (e devo scegliere mappature diverse).

C'è un modo per disattivare i collegamenti di sistema solo quando una determinata applicazione è attiva, ovvero in esecuzione e attiva?

Sarei disposto a eseguire uno script ogni volta che lancio l'applicazione.

Risposta accettata:

Come disabilitare automaticamente più scorciatoie (specifiche) se (e finché) la finestra di un'applicazione specifica è attiva

Lo script seguente disabiliterà le scorciatoie da tastiera specifiche quando è attiva la finestra di un'applicazione arbitraria.

Anche se hai menzionato""Sarei disposto a eseguire uno script ogni volta che avvio l'applicazione". , Non c'è motivo di uccidere lo script in seguito, è estremamente a corto di succo.

Il copione

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

Come si usa

  1. Lo script necessita di xdotool :

    sudo apt-get install xdotool
    
  2. Copia lo script in un file vuoto, salvalo come disable_shortcuts.py

  3. Nell'intestazione dello script, sostituisci nella riga:

    app = "gedit"
    

    "gedit" dalla tua applicazione, che significa:il nome del processo proprietario della finestra.

  4. Eseguire il test dello script con il comando:

    python3 /path/to/disable_shortcuts.py
    
  5. Se tutto funziona correttamente, aggiungilo ad Applicazioni di avvio:Dash> Applicazioni di avvio> Aggiungi. Aggiungi il comando:

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

Aggiunta di più scorciatoie da disabilitare

Ad esempio, ho aggiunto la scorciatoia che hai menzionato:CTRL + ALT + L . Le scorciatoie sono impostate in dconf database e può essere impostato o disabilitato utilizzando gsettings .

Nello script, queste gsettings le voci sono impostate nella funzione:setkeys()

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

Un esempio per aggiungere (disabilitare) il collegamento di logout:

  1. Apri una finestra di terminale, esegui il comando dconf watch /
  2. Apri Impostazioni di sistema> "Tastiera"> "Scorciatoie"> "Sistema"
  3. Reimposta il collegamento su se stesso. Nel terminale puoi vedere le gsettings chiave che appartiene alla scorciatoia:

  4. Ora dobbiamo aggiungere la chiave trovata (in un aspetto leggermente diverso):

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

    …alla lista delle “chiavi” nella nostra funzione:

    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"],
            ]
    

Ora entrambi CTRL + ALT + L e CTRL + ALT + Elimina sono disabilitati se la tua applicazione è in primo piano.

Correlati:relazione tra layout della tastiera e xmodmap?

Spiegazione

Come accennato, le scorciatoie, come quelle che hai citato, sono impostate in dconf Banca dati. Nell'esempio CTRL + ALT + L , la chiave per impostare o modificare la scorciatoia è:

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

Per disabilitare la chiave, il comando è:

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

Per ripristinare la chiave al valore predefinito:

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

Lo script viene visualizzato una volta al secondo se:

  • la tua applicazione non viene eseguita affatto
  • in tal caso, controlla se una delle sue finestre è attiva
  • ancora (solo) in tal caso, disabilita le scorciatoie, elencate in

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

    …in attesa del prossimo cambio di stato.

Se la finestra attiva non è più una delle tue applicazioni, i tasti, menzionati nell'elenco, vengono ripristinati ai valori predefiniti.

Nota

Come accennato in precedenza, l'onere aggiuntivo per il processore dello script è nullo. Potresti benissimo eseguirlo all'avvio, come spiegato in "Come usarlo".

Influenza su più applicazioni

Come discusso nei commenti, nel caso specifico di OP, è utile applicare le scorciatoie di disabilitazione su un gruppo di applicazioni, tutte residenti in una directory.

Di seguito una versione per applicarlo a tutte le applicazioni di cui l'output di

pgrep -f 

includerà una directory specifica. Nel mio esempio, ho impostato il /opt directory, quindi se la finestra attiva è una delle applicazioni in /opt , le scorciatoie impostate verranno disabilitate.

portare una finestra di una delle applicazioni in /opt in primo piano disabiliterà la scorciatoia di logout

riattivare il collegamento se viene attivata un'altra finestra

Il copione

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

Come si usa

  1. Come il primo script, xdotool deve essere installato:

    sudo apt-get install xdotool
    
  2. Copia lo script in un file vuoto, salvalo come disable_shortcuts.py

  3. Nell'intestazione dello script, sostituisci nella riga:

    appdir = "/opt"
    

    "/opt" dalla directory in cui si trovano le tue applicazioni.

  4. Eseguire il test dello script con il comando:

    python3 /path/to/disable_shortcuts.py
    
  5. Se tutto funziona correttamente, aggiungilo ad Applicazioni di avvio:Dash> Applicazioni di avvio> Aggiungi. Aggiungi il comando:

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

L'aggiunta di altre scorciatoie all'elenco funziona esattamente in modo simile alla versione 1 dello script.

Correlati:non è possibile aggiornare Logitech unify Firmware utilizzando fwupd?

Funziona su tutte le applicazioni?

Nella tua risposta, menzioni:

xprop non rivela i PID per tutte le finestre. Esempio di errore:cronometro.

Windows con pid 0 (come tkinter windows, incluso Idle), non hanno window-id nell'output di xprop -id . Idle non ha scorciatoie contrastanti anche se nella mia esperienza. Se ti imbatti in un'applicazione con pid 0 che richiede la disabilitazione di scorciatoie specifiche, menziona.

In tal caso, una possibile fuga sarebbe convertire l'output di

xdotool getactivewindow

in esadecimale, il formato wmctrl utilizza e successivamente cercare il pid corrispondente nell'output di

wmctrl -lp

Anche se all'inizio sembrava la cosa più ovvia da fare, non l'ho usata nella sceneggiatura per mantenerla il più leggera possibile.


Ubuntu
  1. Come fermare Unity 2d che intercetta la chiave meta quando sono in Virtualbox?

  2. Scorciatoie da tastiera globali interrotte in 14.04?

  3. Associare globalmente il tipo di file a determinate applicazioni?

  4. La ricerca del nome di un'applicazione restituisce "scusa nessuna corrispondenza" in Ubuntu 14.04?

  5. Quando e perché usare Docker

Scorciatoie da tastiera di Ubuntu che ogni utente dovrebbe conoscere

Il potente mondo di Ubuntu Scorciatoie da tastiera

Come aggiungere collegamenti alle applicazioni su Ubuntu Desktop

È possibile posizionare Windows con scorciatoie da tastiera in Gnome-shell?

Utilizzo dell'applicazione Utility Disco come utente Sudo in Unity o su Cli?

Quando scade una versione attiva di Ubuntu?