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.
- Disattivazione delle scorciatoie di sistema a livello globale ostacola la mia produttività complessiva con il sistema.
- 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
-
Lo script necessita di
xdotool
:sudo apt-get install xdotool
-
Copia lo script in un file vuoto, salvalo come
disable_shortcuts.py
-
Nell'intestazione dello script, sostituisci nella riga:
app = "gedit"
"gedit" dalla tua applicazione, che significa:il nome del processo proprietario della finestra.
-
Eseguire il test dello script con il comando:
python3 /path/to/disable_shortcuts.py
-
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:
- Apri una finestra di terminale, esegui il comando
dconf watch /
- Apri Impostazioni di sistema> "Tastiera"> "Scorciatoie"> "Sistema"
-
Reimposta il collegamento su se stesso. Nel terminale puoi vedere le
gsettings
chiave che appartiene alla scorciatoia: -
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
-
Come il primo script,
xdotool
deve essere installato:sudo apt-get install xdotool
-
Copia lo script in un file vuoto, salvalo come
disable_shortcuts.py
-
Nell'intestazione dello script, sostituisci nella riga:
appdir = "/opt"
"/opt" dalla directory in cui si trovano le tue applicazioni.
-
Eseguire il test dello script con il comando:
python3 /path/to/disable_shortcuts.py
-
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.