優れたJetBrainsIDE(IDEA et al。)は、考えられるほとんどすべてのキーボードショートカットをいくつかの機能に割り当てます。時にはやや圧倒されますが、効率的に使用することもできます。
私の問題は、Unityがこれらのショートカットのいくつかも割り当て、それらが優先されることです。特に厄介な例の1つは、 CTRLです。 + ALT + L 。この問題はここまでに調査されています。
ただし、どちらのアプローチも満足のいくものではありません。
- システムショートカットをグローバルにオフにする システムの全体的な生産性を妨げます。
- 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
使用方法
-
スクリプトには
xdotool
が必要です :sudo apt-get install xdotool
-
スクリプトを空のファイルにコピーし、
disable_shortcuts.py
として保存します -
スクリプトの先頭で、次の行を置き換えます:
app = "gedit"
アプリケーションによる「gedit」、つまりウィンドウを所有するプロセス名。
-
次のコマンドでスクリプトをテスト実行します:
python3 /path/to/disable_shortcuts.py
-
すべてが正常に機能する場合は、スタートアップアプリケーションに追加します:ダッシュ>スタートアップアプリケーション>追加。コマンドを追加します:
/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"]
]
# ---
ログアウトショートカットを追加(無効化)する例:
- ターミナルウィンドウを開き、コマンド
dconf watch /
を実行します - システム設定を開く>「キーボード」>「ショートカット」>「システム」
-
ショートカットをそれ自体にリセットします。ターミナルでは、
gsettings
を見ることができます ショートカットに属するキー: -
次に、見つかったキーを(わずかに異なる外観で)追加する必要があります:
["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
使用方法
-
最初のスクリプトと同様に、
xdotool
インストールする必要があります:sudo apt-get install xdotool
-
スクリプトを空のファイルにコピーし、
disable_shortcuts.py
として保存します -
スクリプトの先頭で、次の行を置き換えます:
appdir = "/opt"
アプリケーションが存在するディレクトリの「/opt」。
-
次のコマンドでスクリプトをテスト実行します:
python3 /path/to/disable_shortcuts.py
-
すべてが正常に機能する場合は、スタートアップアプリケーションに追加します:ダッシュ>スタートアップアプリケーション>追加。コマンドを追加します:
/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
それは最初から最も明白なことのように思えましたが、スクリプトを可能な限り軽量にするために、スクリプトでは使用しませんでした。