GNU/Linux >> Linux の 問題 >  >> Ubuntu

特定のアプリケーションがアクティブなときにUnityキーボードショートカットをブロックしますか?

優れたJetBrainsIDE(IDEA et al。)は、考えられるほとんどすべてのキーボードショートカットをいくつかの機能に割り当てます。時にはやや圧倒されますが、効率的に使用することもできます。

私の問題は、Unityがこれらのショートカットのいくつかも割り当て、それらが優先されることです。特に厄介な例の1つは、 CTRLです。 + ALT + L 。この問題はここまでに調査されています。

ただし、どちらのアプローチも満足のいくものではありません。

  1. システムショートカットをグローバルにオフにする システムの全体的な生産性を妨げます。
  2. IDEAで別のキーマップに切り替えると、別のプラットフォームで開発するときに混乱します(そして別のマッピングを選択する必要があります)。

特定のアプリケーションがアクティブな場合、つまり実行中でフォーカスがある場合にのみシステムショートカットをオフにする方法はありますか?

アプリケーションを起動するたびにスクリプトを実行したいと思います。

承認された回答:

特定のアプリケーションのウィンドウがアクティブな場合(およびその限り)、複数の(特定の)ショートカットを自動的に無効にする方法

以下のスクリプトは、任意のアプリケーションのウィンドウがアクティブな場合に特定のキーショートカットを無効にします。

」「アプリケーションを起動するたびにスクリプトを実行したいと思います。」 、後でスクリプトを強制終了する理由はありません。ジュースが非常に少なくなっています。

スクリプト

#!/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

使用方法

  1. スクリプトにはxdotoolが必要です :

    sudo apt-get install xdotool
    
  2. スクリプトを空のファイルにコピーし、disable_shortcuts.pyとして保存します

  3. スクリプトの先頭で、次の行を置き換えます:

    app = "gedit"
    

    アプリケーションによる「gedit」、つまりウィンドウを所有するプロセス名。

  4. 次のコマンドでスクリプトをテスト実行します:

    python3 /path/to/disable_shortcuts.py
    
  5. すべてが正常に機能する場合は、スタートアップアプリケーションに追加します:ダッシュ>スタートアップアプリケーション>追加。コマンドを追加します:

    /bin/bash -c "sleep 15 && python3 /path/to/disable_shortcuts.py"
    

無効にするショートカットを追加する

例として、あなたが言及したショートカットを追加しました: CTRL + ALT + L 。ショートカットはdconfで設定されます データベースであり、gsettingsを使用して設定または無効化できます 。

スクリプトでは、これらのgsettings エントリは関数で設定されます:setkeys()

def setkeys(val):
    # --- add the keys to be disabled below
    keys = [
        ["org.gnome.settings-daemon.plugins.media-keys", "screensaver"]
        ]
    # ---

ログアウトショートカットを追加(無効化)する例:

  1. ターミナルウィンドウを開き、コマンドdconf watch /を実行します
  2. システム設定を開く>「キーボード」>「ショートカット」>「システム」
  3. ショートカットをそれ自体にリセットします。ターミナルでは、gsettingsを見ることができます ショートカットに属するキー:

  4. 次に、見つかったキーを(わずかに異なる外観で)追加する必要があります:

    ["org.gnome.settings-daemon.plugins.media-keys", "logout"]
    

    …関数の「キー」リストへ:

    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"],
            ]
    

これで、両方の CTRL + ALT + L およびCTRL + ALT +削除 アプリケーションが前面にある場合は無効になります。

関連:キーボードレイアウトとxmodmapの関係?

説明

前述のように、あなたが言及したようなショートカットは、dconfに設定されています データベース。例では、 CTRL + ALT + L 、ショットカットを設定または編集するためのキーは次のとおりです。

org.gnome.settings-daemon.plugins.media-keys screensaver

無効にする キー、コマンドは次のとおりです。

gsettings set org.gnome.settings-daemon.plugins.media-keys screensaver ""

キーをデフォルト値にリセットするには:

gsettings reset org.gnome.settings-daemon.plugins.media-keys screensaver

次の場合、スクリプトは1秒に1回表示されます。

  • アプリケーションはまったく実行されません
  • その場合、そのウィンドウのいずれかがアクティブであるかどうかを確認します
  • 再度(のみ)その場合、

    にリストされているショートカットを無効にします
    # --- add the keys to be disabled below
    keys = [
        ["org.gnome.settings-daemon.plugins.media-keys", "screensaver"],
         ["org.gnome.settings-daemon.plugins.media-keys", "logout"],
       ]
    

    …次の状態変化を待っています。

アクティブなウィンドウがアプリケーションの1つではなくなった場合、リストに記載されているキーはデフォルトにリセットされます。

前述のように、スクリプトのプロセッサに対する追加の負担はnihilです。 「使用方法」で説明されているように、起動時に非常にうまく実行できます。

複数のアプリケーションに影響を与える

コメントで説明されているように、OPの特定のケースでは、グループに無効化ショートカットを適用すると便利です。 すべてが1つのディレクトリにあるアプリケーションの数。

の出力が含まれるすべてのアプリケーションにこれを適用するバージョンの下
pgrep -f 

特定のディレクトリが含まれます。私の例では、/optを設定します したがって、アクティブなウィンドウが/opt内のアプリケーションのいずれかである場合 、設定されたショートカットは無効になります。

/ optにあるアプリケーションの1つのウィンドウを前面に表示すると、ログアウトショートカットが無効になります

別のウィンドウがフォーカスされた場合にショートカットを再度有効にする

スクリプト

#!/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

使用方法

  1. 最初のスクリプトと同様に、xdotool インストールする必要があります:

    sudo apt-get install xdotool
    
  2. スクリプトを空のファイルにコピーし、disable_shortcuts.pyとして保存します

  3. スクリプトの先頭で、次の行を置き換えます:

    appdir = "/opt"
    

    アプリケーションが存在するディレクトリの「/opt」。

  4. 次のコマンドでスクリプトをテスト実行します:

    python3 /path/to/disable_shortcuts.py
    
  5. すべてが正常に機能する場合は、スタートアップアプリケーションに追加します:ダッシュ>スタートアップアプリケーション>追加。コマンドを追加します:

    /bin/bash -c "sleep 15 && python3 /path/to/disable_shortcuts.py"
    

リストに他のショートカットを追加することは、スクリプトのバージョン1とまったく同じように機能します。

関連:fwupdを使用してLogitech unifyファームウェアをアップグレードできませんか?

すべてのアプリケーションで機能しますか?

あなたの答えでは、あなたは次のように述べています:

xpropは、すべてのウィンドウのPIDを表示するわけではありません。失敗例:ストップウォッチ。

pid 0のウィンドウ(アイドルを含むtkinterウィンドウなど)では、xprop -idの出力にwindow-idがありません。 。 Idle 私の経験では、衝突するショートカットはありません。特定のショートカットを無効にする必要があるpid0のアプリケーションに遭遇した場合は、言及してください。

その場合、考えられる回避策は、

の出力を変換することです。
xdotool getactivewindow

16進数の場合、wmctrlの形式 を使用し、続いて対応するpidを検索します

の出力で
wmctrl -lp

それは最初から最も明白なことのように思えましたが、スクリプトを可能な限り軽量にするために、スクリプトでは使用しませんでした。


Ubuntu
  1. Virtualboxを使用しているときにUnity2dがメタキーをインターセプトするのを停止するにはどうすればよいですか?

  2. キーボードレイアウトを切り替えるための個別のキーボードショートカット?

  3. ファイルタイプを特定のアプリケーションにグローバルに関連付けますか?

  1. 起動時にキーボードが機能しない問題?

  2. アプリケーション名を検索すると、Ubuntu 14.04で「申し訳ありませんが一致しません」が返されますか?

  3. Unity Launcherでキーワードをアプリケーションに関連付けますか?

  1. NautilusとThunarの`backspace`キーボードショートカットを復活させますか?

  2. Gnome 3シェルキーボード/マウスのショートカット?

  3. Dockerを使用する時期と理由