Die großartigen JetBrains-IDEs (IDEA et al.) weisen so ziemlich jede erdenkliche Tastenkombination einer Funktion zu. Obwohl es manchmal leicht überwältigend ist, sorgt es auch für eine effiziente Nutzung.
Mein Problem ist, dass Unity auch einige dieser Verknüpfungen zuweist und sie Vorrang haben. Ein besonders ärgerliches Beispiel ist CTRL + ALT + L . Das Problem wurde hier bereits untersucht.
Jedoch ist keiner der Ansätze zufriedenstellend.
- Systemverknüpfungen global deaktivieren beeinträchtigt meine Gesamtproduktivität mit dem System.
- Der Wechsel zu einer anderen Keymap in IDEA wird mich höllisch verwirren, wenn ich auf verschiedenen Plattformen entwickle (und verschiedene Mappings wählen muss).
Gibt es eine Möglichkeit, Systemverknüpfungen nur dann zu deaktivieren, wenn eine bestimmte Anwendung aktiv ist, d. h. ausgeführt wird und im Fokus ist?
Ich wäre bereit, jedes Mal, wenn ich die Anwendung starte, ein Skript auszuführen.
Akzeptierte Antwort:
So deaktivieren Sie automatisch mehrere (bestimmte) Verknüpfungen, wenn (und solange) das Fenster einer bestimmten Anwendung aktiv ist
Das folgende Skript deaktiviert bestimmte Tastenkürzel, wenn das Fenster einer beliebigen Anwendung aktiv ist.
Obwohl Sie erwähnt haben:„„Ich wäre bereit, jedes Mal, wenn ich die Anwendung starte, ein Skript auszuführen.“ , Es gibt keinen Grund, das Skript danach zu beenden, es hat extrem wenig Saft.
Das Skript
#!/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
Verwendung
-
Das Skript benötigt
xdotool
:sudo apt-get install xdotool
-
Kopieren Sie das Skript in eine leere Datei und speichern Sie es als
disable_shortcuts.py
-
Ersetzen Sie im Kopf des Skripts in der Zeile:
app = "gedit"
„gedit“ von Ihrer Anwendung, was bedeutet:der Prozessname, der das Fenster besitzt.
-
Testen Sie das Skript mit dem folgenden Befehl:
python3 /path/to/disable_shortcuts.py
-
Wenn alles funktioniert, fügen Sie es zu Startup Applications hinzu:Dash> Startup Applications> Add. Fügen Sie den Befehl hinzu:
/bin/bash -c "sleep 15 && python3 /path/to/disable_shortcuts.py"
Hinzufügen weiterer zu deaktivierender Verknüpfungen
Als Beispiel habe ich die von Ihnen erwähnte Tastenkombination hinzugefügt:CTRL + ALT + L . Shortcuts werden in der dconf
gesetzt Datenbank und kann mit gsettings
gesetzt oder deaktiviert werden .
Im Skript diese gsettings
Einträge werden in der Funktion gesetzt:setkeys()
def setkeys(val):
# --- add the keys to be disabled below
keys = [
["org.gnome.settings-daemon.plugins.media-keys", "screensaver"]
]
# ---
Ein Beispiel zum Hinzufügen (Deaktivieren) der Verknüpfung zum Abmelden:
- Öffnen Sie ein Terminalfenster, führen Sie den Befehl
dconf watch /
aus - Öffnen Sie Systemeinstellungen> „Tastatur“> „Kurzbefehle“> „System“
-
Setzen Sie die Verknüpfung auf sich selbst zurück. Im Terminal können Sie die
gsettings
sehen Taste, die zum Shortcut gehört: -
Jetzt müssen wir den gefundenen Schlüssel hinzufügen (in etwas anderem Aussehen):
["org.gnome.settings-daemon.plugins.media-keys", "logout"]
…in die „Schlüssel“-Liste unserer Funktion:
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"], ]
Jetzt beide CTRL + ALT + L und CTRL + ALT + Löschen sind deaktiviert, wenn Ihre Anwendung im Vordergrund steht.
Verwandte:Beziehung von Tastaturlayout und xmodmap?Erklärung
Wie bereits erwähnt, werden Verknüpfungen, wie die von Ihnen erwähnten, in der dconf
festgelegt Datenbank. Im Beispiel CTRL + ALT + L , der Schlüssel zum Einstellen oder Bearbeiten des Kurzschnitts lautet:
org.gnome.settings-daemon.plugins.media-keys screensaver
Zum Deaktivieren der Schlüssel, der Befehl lautet:
gsettings set org.gnome.settings-daemon.plugins.media-keys screensaver ""
So setzen Sie den Schlüssel auf seinen Standardwert zurück:
gsettings reset org.gnome.settings-daemon.plugins.media-keys screensaver
Das Skript prüft einmal pro Sekunde, ob:
- Ihre Anwendung läuft überhaupt
- wenn ja, sieht es aus, ob eines seiner Fenster aktiv ist
-
wieder (nur) wenn ja, es deaktiviert die Verknüpfungen, aufgeführt 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"], ]
…Warten auf die nächste Zustandsänderung.
Wenn das aktive Fenster nicht mehr zu Ihrer Anwendung gehört, werden die in der Liste aufgeführten Tasten auf die Standardeinstellungen zurückgesetzt.
Hinweis
Wie bereits erwähnt, ist die zusätzliche Belastung für den Prozessor des Skripts gleich Null. Sie könnten es sehr gut beim Start ausführen, wie in „Verwendung“ erklärt.
Betrifft mehrere Anwendungen
Wie in den Kommentaren besprochen, ist es im speziellen Fall von OP nützlich, Deaktivierungsverknüpfungen auf eine Gruppe anzuwenden von Anwendungen, die sich alle in einem Verzeichnis befinden.
Nachfolgend eine Version, um dies auf alle Anwendungen anzuwenden, deren Ausgabe von
pgrep -f
enthält ein bestimmtes Verzeichnis. In meinem Beispiel setze ich den /opt
Verzeichnis, also wenn das aktive Fenster eine der Anwendungen in /opt
ist , werden die eingestellten Shortcuts deaktiviert.
Wenn Sie ein Fenster einer der Anwendungen in /opt nach vorne bringen, wird die Abmeldeverknüpfung deaktiviert
Erneutes Aktivieren der Verknüpfung, wenn ein anderes Fenster den Fokus erhält
Das Skript
#!/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
Verwendung
-
Wie das erste Skript,
xdotool
muss installiert werden:sudo apt-get install xdotool
-
Kopieren Sie das Skript in eine leere Datei und speichern Sie es als
disable_shortcuts.py
-
Ersetzen Sie im Kopf des Skripts in der Zeile:
appdir = "/opt"
„/opt“ durch das Verzeichnis, in dem sich Ihre Anwendungen befinden.
-
Testen Sie das Skript mit dem folgenden Befehl:
python3 /path/to/disable_shortcuts.py
-
Wenn alles funktioniert, fügen Sie es zu Startup Applications hinzu:Dash> Startup Applications> Add. Fügen Sie den Befehl hinzu:
/bin/bash -c "sleep 15 && python3 /path/to/disable_shortcuts.py"
Das Hinzufügen weiterer Shortcuts zur Liste funktioniert genauso wie Version 1 des Skripts.
Verwandt:Kann die Logitech Unify-Firmware nicht mit fwupd aktualisieren?Funktioniert es bei allen Anwendungen?
In Ihrer Antwort erwähnen Sie:
xprop zeigt PIDs nicht für alle Fenster an. Fehlerhaftes Beispiel:Stoppuhr.
Windows mit PID 0 (wie Tkinter-Fenster, einschließlich Leerlauf) haben keine Fenster-ID in der Ausgabe von xprop -id
. Idle
hat meiner Erfahrung nach jedoch keine kollidierenden Verknüpfungen. Wenn Sie auf eine Anwendung mit PID 0 stoßen, die das Deaktivieren bestimmter Verknüpfungen erfordern würde, erwähnen Sie dies bitte.
In diesem Fall wäre ein möglicher Ausweg, die Ausgabe von
umzuwandelnxdotool getactivewindow
zu hex, das Format wmctrl
verwendet, und schlagen Sie anschließend die entsprechende pid
nach in der Ausgabe von
wmctrl -lp
Obwohl dies anfangs das Naheliegendste zu sein schien, habe ich es im Skript nicht verwendet, um das Skript so leicht wie möglich zu halten.