GNU/Linux >> Znalost Linux >  >> Ubuntu

Blokovat klávesové zkratky Unity, když je určitá aplikace aktivní?

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ý.

  1. Vypnutí systémových zkratek globálně brzdí mou celkovou produktivitu se systémem.
  2. 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

  1. Skript potřebuje xdotool :

    sudo apt-get install xdotool
    
  2. Zkopírujte skript do prázdného souboru a uložte jej jako disable_shortcuts.py

  3. V záhlaví skriptu nahraďte v řádku:

    app = "gedit"
    

    „gedit“ vaší aplikací, což znamená:název procesu, který okno vlastní.

  4. Test spusťte skript příkazem:

    python3 /path/to/disable_shortcuts.py
    
  5. 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í:

  1. Otevřete okno terminálu a spusťte příkaz dconf watch /
  2. Otevřete Nastavení systému> „Klávesnice“> „Zkratky“> „Systém“
  3. Znovu nastavte zástupce na sebe. V terminálu můžete vidět gsettings klávesa, která patří ke zkratce:

  4. 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

  1. Stejně jako první skript xdotool je třeba nainstalovat:

    sudo apt-get install xdotool
    
  2. Zkopírujte skript do prázdného souboru a uložte jej jako disable_shortcuts.py

  3. V záhlaví skriptu nahraďte v řádku:

    appdir = "/opt"
    

    „/opt“ podle adresáře, ve kterém jsou vaše aplikace.

  4. Test spusťte skript příkazem:

    python3 /path/to/disable_shortcuts.py
    
  5. 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čí.


Ubuntu
  1. Jak zastavit zachycování Meta Key Unity 2d, když jsem ve Virtualboxu?

  2. Rozbité globální klávesové zkratky ve 14.04?

  3. Problémy s nefunkční klávesnicí při spouštění?

  1. Hledání názvu aplikace vrátí „sorry No Match“ v Ubuntu 14.04?

  2. Jak změnit klávesové zkratky Evolution?

  3. Kdy a proč používat Docker

  1. Vrátit klávesové zkratky `backspace` na Nautilus a Thunar?

  2. Klávesové zkratky pro Gnome 3 Shell?

  3. Jsou za aktualizace aplikací účtovány poplatky?