GNU/Linux >> LINUX-Kenntnisse >  >> Ubuntu

Unity-Tastenkombinationen blockieren, wenn eine bestimmte Anwendung aktiv ist?

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.

  1. Systemverknüpfungen global deaktivieren beeinträchtigt meine Gesamtproduktivität mit dem System.
  2. 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

  1. Das Skript benötigt xdotool :

    sudo apt-get install xdotool
    
  2. Kopieren Sie das Skript in eine leere Datei und speichern Sie es als disable_shortcuts.py

  3. Ersetzen Sie im Kopf des Skripts in der Zeile:

    app = "gedit"
    

    „gedit“ von Ihrer Anwendung, was bedeutet:der Prozessname, der das Fenster besitzt.

  4. Testen Sie das Skript mit dem folgenden Befehl:

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

  1. Öffnen Sie ein Terminalfenster, führen Sie den Befehl dconf watch / aus
  2. Öffnen Sie Systemeinstellungen> „Tastatur“> „Kurzbefehle“> „System“
  3. Setzen Sie die Verknüpfung auf sich selbst zurück. Im Terminal können Sie die gsettings sehen Taste, die zum Shortcut gehört:

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

  1. Wie das erste Skript, xdotool muss installiert werden:

    sudo apt-get install xdotool
    
  2. Kopieren Sie das Skript in eine leere Datei und speichern Sie es als disable_shortcuts.py

  3. Ersetzen Sie im Kopf des Skripts in der Zeile:

    appdir = "/opt"
    

    „/opt“ durch das Verzeichnis, in dem sich Ihre Anwendungen befinden.

  4. Testen Sie das Skript mit dem folgenden Befehl:

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

umzuwandeln
xdotool 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.


Ubuntu
  1. Bringen Sie die "Backspace"-Tastaturkürzel auf Nautilus und Thunar zurück?

  2. Werden Gebühren für Anwendungsaktualisierungen erhoben?

  3. Separate Tastenkombinationen zum Umschalten zwischen Tastaturlayouts?

  4. Dateityp global einer bestimmten Anwendung zuordnen?

  5. Zuordnen eines Schlüsselworts zu einer Anwendung in Unity Launcher?

Ubuntu-Tastaturkürzel, die jeder Benutzer kennen sollte

Die mächtige Welt der Ubuntu-Tastaturkürzel

So fügen Sie Anwendungsverknüpfungen auf Ubuntu Desktop hinzu

Ist es möglich, Windows mit Tastaturkürzeln in der Gnome-Shell zu platzieren?

Verwenden des Festplattendienstprogramms als Sudo-Benutzer in Unity oder auf Cli?

Wann läuft eine aktive Ubuntu-Version ab?