Skvělá JetBrains IDE (IDEA a spol.) přiřazují téměř všechny myslitelné klávesové zkratky nějaké funkci. I když je občas mírně ohromující, umožňuje také efektivní využití.
Můj problém je, že Unity přiřadí některé z těchto zkratek také a mají přednost. Jedním zvlášť nepříjemným příkladem je CTRL + ALT + L . Tento problém byl již dříve prozkoumán zde.
Ani jeden z přístupů však není uspokojivý.
- Vypnutí systémových zkratek globálně brzdí mou celkovou produktivitu se systémem.
- Přechod na jinou keymapu v IDEA mě sakra zmátne, když vyvíjím na různých platformách (a musím volit různá mapování).
Existuje způsob, jak vypnout systémové zkratky pouze tehdy, když je určitá aplikace aktivní, tj. spuštěná a zaostřená?
Byl bych ochoten spustit skript pokaždé, když spustím aplikaci.
Přijatá odpověď:
Jak automaticky zakázat více (konkrétních) zkratek, pokud je (a dokud) je aktivní okno konkrétní aplikace
Skript níže zakáže konkrétní klávesové zkratky, když je aktivní okno libovolné aplikace.
Ačkoli jste zmínili:„„Byl bych ochoten spustit skript pokaždé, když spustím aplikaci.“ , Není důvod scénář následně zabíjet, má extrémně málo šťávy.
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
Jak používat
-
Skript potřebuje
xdotool
:sudo apt-get install xdotool
-
Zkopírujte skript do prázdného souboru a uložte jej jako
disable_shortcuts.py
-
V záhlaví skriptu nahraďte v řádku:
app = "gedit"
„gedit“ vaší aplikací, což znamená:název procesu, který okno vlastní.
-
Test spusťte skript příkazem:
python3 /path/to/disable_shortcuts.py
-
Pokud vše funguje dobře, přidejte jej do Startup Applications:Dash> Startup Applications> Add. Přidejte příkaz:
/bin/bash -c "sleep 15 && python3 /path/to/disable_shortcuts.py"
Přidání dalších zkratek, které mají být zakázány
Jako příklad jsem přidal vámi zmíněnou zkratku:CTRL + ALT + L . Zkratky se nastavují v dconf
databázi a lze jej nastavit nebo zakázat pomocí gsettings
.
Ve skriptu tato gsettings
položky se nastavují ve funkci:setkeys()
def setkeys(val):
# --- add the keys to be disabled below
keys = [
["org.gnome.settings-daemon.plugins.media-keys", "screensaver"]
]
# ---
Příklad přidání (zakázání) zástupce pro odhlášení:
- Otevřete okno terminálu a spusťte příkaz
dconf watch /
- Otevřete Nastavení systému> „Klávesnice“> „Zkratky“> „Systém“
-
Znovu nastavte zástupce na sebe. V terminálu můžete vidět
gsettings
klávesa, která patří ke zkratce: -
Nyní musíme přidat nalezený klíč (v trochu jiném vzhledu):
["org.gnome.settings-daemon.plugins.media-keys", "logout"]
…do seznamu „klíčů“ v naší funkci:
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"], ]
Nyní obě CTRL + ALT + L a CTRL + ALT + Smazat jsou zakázány, pokud je vaše aplikace v popředí.
Související:Vztah rozložení klávesnice a xmodmap?Vysvětlení
Jak již bylo zmíněno, zkratky, jako ty, které zmiňujete, se nastavují v dconf
databáze. V příkladu CTRL + ALT + L , klíč pro nastavení nebo úpravu zástupce je:
org.gnome.settings-daemon.plugins.media-keys screensaver
Chcete-li deaktivovat klíč, příkaz je:
gsettings set org.gnome.settings-daemon.plugins.media-keys screensaver ""
Chcete-li resetovat klíč na jeho výchozí hodnotu:
gsettings reset org.gnome.settings-daemon.plugins.media-keys screensaver
Skript se podívá jednou za sekundu, pokud:
- aplikace vůbec běží
- pokud ano, vypadá, že některé z jeho oken je aktivní
-
znovu (pouze), pokud ano, zakáže zkratky uvedené v
# --- add the keys to be disabled below keys = [ ["org.gnome.settings-daemon.plugins.media-keys", "screensaver"], ["org.gnome.settings-daemon.plugins.media-keys", "logout"], ]
…čekání na další změnu stavu.
Pokud aktivní okno již není jednou z vašich aplikací, klíče uvedené v seznamu se resetují na výchozí.
Poznámka
Jak již bylo zmíněno dříve, další zátěž pro procesor skriptu je nulová. Můžete jej velmi dobře spustit při spuštění, jak je vysvětleno v části „Jak používat“.
Ovlivnění více aplikací
Jak je uvedeno v komentářích, v konkrétním případě OP je užitečné použít deaktivační zkratky na skupinu aplikací, všechny jsou umístěny v jednom adresáři.
Níže je uvedena verze, která to použije na všechny aplikace, jejichž výstup
pgrep -f
bude obsahovat konkrétní adresář. V mém příkladu jsem nastavil /opt
adresář, takže pokud je aktivní okno jednou z aplikací v /opt
, nastavení zkratek bude zakázáno.
přenesením okna jedné z aplikací v /opt dopředu deaktivujete zástupce pro odhlášení
znovu povolí zástupce, pokud je aktivní jiné okno
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
Jak používat
-
Stejně jako první skript
xdotool
je třeba nainstalovat:sudo apt-get install xdotool
-
Zkopírujte skript do prázdného souboru a uložte jej jako
disable_shortcuts.py
-
V záhlaví skriptu nahraďte v řádku:
appdir = "/opt"
„/opt“ podle adresáře, ve kterém jsou vaše aplikace.
-
Test spusťte skript příkazem:
python3 /path/to/disable_shortcuts.py
-
Pokud vše funguje dobře, přidejte jej do Startup Applications:Dash> Startup Applications> Add. Přidejte příkaz:
/bin/bash -c "sleep 15 && python3 /path/to/disable_shortcuts.py"
Přidání dalších zkratek do seznamu funguje přesně podobně jako ve verzi 1 skriptu.
Související:Nelze upgradovat Logitech unify Firmware pomocí fwupd?Funguje to ve všech aplikacích?
Ve své odpovědi uvádíte:
xprop neodhaluje PID pro všechna okna. Příklad selhání:stopky.
Windows s pid 0 (jako okna tkinter, včetně Idle), nemají ve výstupu xprop -id
žádné id okna . Idle
podle mých zkušeností nemá žádné konfliktní zkratky. Pokud narazíte na jakoukoli aplikaci s pid 0, která by vyžadovala zakázání konkrétních zkratek, uveďte to.
V takovém případě by možným únikem bylo převedení výstupu z
xdotool getactivewindow
na hex, formát wmctrl
používá a následně vyhledejte odpovídající pid
ve výstupu
wmctrl -lp
I když se to zdálo pro začátek nejzřejmější, nepoužil jsem to ve scénáři, aby byl scénář co nejlehčí.