GNU/Linux >> Belajar Linux >  >> Ubuntu

Blokir Pintasan Keyboard Unity Saat Aplikasi Tertentu Aktif?

JetBrains IDEs (IDEA et al.) yang hebat menetapkan hampir semua pintasan keyboard yang mungkin ke beberapa fungsi. Meskipun kadang-kadang agak berlebihan, itu juga membuat penggunaan yang efisien.

Masalah saya adalah Unity menetapkan beberapa pintasan ini juga, dan mereka diutamakan. Salah satu contoh yang sangat mengganggu adalah CTRL + ALT + L . Masalah ini telah dieksplorasi sebelumnya di sini.

Namun, tidak satu pun dari pendekatan tersebut memuaskan.

  1. Menonaktifkan pintasan sistem secara global menghambat produktivitas saya secara keseluruhan dengan sistem.
  2. Beralih ke keymap yang berbeda di IDEA akan membuat saya bingung ketika saya mengembangkan pada platform yang berbeda (dan harus memilih pemetaan yang berbeda).

Apakah ada cara untuk mematikan pintasan sistem hanya ketika aplikasi tertentu aktif, yaitu sedang berjalan dan dalam fokus?

Saya bersedia menjalankan skrip setiap kali meluncurkan aplikasi.

Jawaban yang Diterima:

Cara menonaktifkan beberapa pintasan (khusus) secara otomatis jika (dan selama) jendela aplikasi tertentu aktif

Skrip di bawah ini akan menonaktifkan pintasan tombol tertentu saat jendela aplikasi arbitrer aktif.

Meskipun Anda menyebutkan”“Saya bersedia menjalankan skrip setiap kali saya meluncurkan aplikasi.” , Tidak ada alasan untuk mematikan skrip setelahnya, jusnya sangat rendah.

Skrip

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

Cara menggunakan

  1. Script membutuhkan xdotool :

    sudo apt-get install xdotool
    
  2. Salin skrip ke file kosong, simpan sebagai disable_shortcuts.py

  3. Di kepala skrip, ganti di baris:

    app = "gedit"
    

    “gedit” oleh aplikasi Anda, artinya:nama proses yang memiliki jendela.

  4. Uji-jalankan skrip dengan perintah:

    python3 /path/to/disable_shortcuts.py
    
  5. Jika semuanya berfungsi dengan baik, tambahkan ke Aplikasi Startup:Dash> Startup Applications> Add. Tambahkan perintah:

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

Menambahkan lebih banyak pintasan untuk dinonaktifkan

Sebagai contoh, saya menambahkan pintasan yang Anda sebutkan:CTRL + ALT + L . Pintasan diatur di dconf database, dan dapat disetel atau dinonaktifkan menggunakan gsettings .

Dalam skrip, gsettings ini entri diatur dalam fungsi:setkeys()

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

Contoh untuk menambahkan (menonaktifkan) pintasan logout:

  1. Buka jendela terminal, jalankan perintah dconf watch /
  2. Buka Pengaturan Sistem> “Keyboard”> “Pintasan”> “Sistem”
  3. Atur ulang pintasan ke dirinya sendiri. Di terminal, Anda dapat melihat gsettings kunci yang dimiliki pintasan:

  4. Sekarang kita harus menambahkan kunci yang ditemukan (dalam tampilan yang sedikit berbeda):

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

    …ke daftar “kunci” dalam fungsi kita:

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

Sekarang keduanya CTRL + ALT + L dan CTRL + ALT + Hapus dinonaktifkan jika aplikasi Anda ada di depan.

Terkait:Hubungan tata letak keyboard dan xmodmap?

Penjelasan

Seperti yang disebutkan, pintasan, seperti yang Anda sebutkan, disetel di dconf basis data. Dalam contoh CTRL + ALT + L , kunci untuk menyetel atau mengedit pintasan adalah:

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

Untuk menonaktifkan kuncinya, perintahnya adalah:

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

Untuk menyetel ulang kunci ke nilai defaultnya:

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

Script terlihat sekali per detik jika:

  • aplikasi Anda berjalan sama sekali
  • jika ya, sepertinya ada jendela yang aktif
  • lagi (hanya) jika demikian, itu menonaktifkan pintasan, yang tercantum di

    # --- add the keys to be disabled below
    keys = [
        ["org.gnome.settings-daemon.plugins.media-keys", "screensaver"],
         ["org.gnome.settings-daemon.plugins.media-keys", "logout"],
       ]
    

    …menunggu perubahan status selanjutnya.

Jika jendela aktif bukan lagi salah satu aplikasi Anda, kunci yang disebutkan dalam daftar, akan disetel ulang ke default.

Catatan

Seperti yang disebutkan sebelumnya, beban tambahan untuk pengolah skrip adalah nihil. Anda dapat menjalankannya dengan baik saat startup, seperti yang dijelaskan di “Cara menggunakan”.

Mempengaruhi beberapa aplikasi

Seperti yang dibahas dalam komentar, dalam kasus khusus OP, berguna untuk menerapkan pintasan penonaktifan pada grup aplikasi, semua berada dalam satu direktori.

Di bawah versi untuk menerapkan ini pada semua aplikasi yang outputnya

pgrep -f 

akan menyertakan direktori tertentu. Dalam contoh saya, saya mengatur /opt direktori, jadi jika jendela aktif adalah salah satu aplikasi di /opt , pintasan yang disetel akan dinonaktifkan.

membawa jendela salah satu aplikasi di /opt ke depan akan menonaktifkan pintasan logout

mengaktifkan kembali pintasan jika jendela lain mendapat fokus

Skrip

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

Cara menggunakan

  1. Seperti skrip pertama, xdotool perlu diinstal:

    sudo apt-get install xdotool
    
  2. Salin skrip ke file kosong, simpan sebagai disable_shortcuts.py

  3. Di kepala skrip, ganti di baris:

    appdir = "/opt"
    

    “/opt” di direktori aplikasi Anda.

  4. Uji-jalankan skrip dengan perintah:

    python3 /path/to/disable_shortcuts.py
    
  5. Jika semuanya berfungsi dengan baik, tambahkan ke Aplikasi Startup:Dash> Startup Applications> Add. Tambahkan perintah:

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

Menambahkan pintasan lain ke daftar berfungsi sama persis dengan skrip versi 1.

Terkait:Tidak dapat memutakhirkan Logitech menyatukan Firmware menggunakan fwupd?

Apakah ini berfungsi di semua aplikasi?

Dalam jawaban Anda, Anda menyebutkan:

xprop tidak mengungkapkan PID untuk semua jendela. Contoh gagal:stopwatch.

Windows dengan pid 0 (seperti jendela tkinter, termasuk Idle), tidak memiliki id jendela dalam output xprop -id . Idle tidak memiliki jalan pintas yang bentrok meskipun dalam pengalaman saya. Jika Anda menemukan aplikasi apa pun dengan pid 0 yang memerlukan penonaktifan pintasan tertentu, harap sebutkan.

Dalam hal ini, jalan keluar yang mungkin adalah mengonversi output dari

xdotool getactivewindow

ke hex, format wmctrl menggunakan, dan kemudian mencari pid yang sesuai dalam keluaran

wmctrl -lp

Meskipun tampaknya itu adalah hal yang paling jelas untuk dilakukan, saya tidak menggunakannya dalam skrip untuk menjaga skrip seringan mungkin.


Ubuntu
  1. Kembalikan Pintasan Keyboard `backspace` Di Nautilus Dan Thunar?

  2. Bagaimana Menghentikan Unity 2d Mencegat Meta Key Saat Saya Di Virtualbox?

  3. Pintasan Keyboard Terpisah Untuk Beralih Antar Tata Letak Keyboard?

  1. Kaitkan Jenis File Secara Global Dengan Aplikasi Tertentu?

  2. Mencari Nama Aplikasi Mengembalikan "maaf Tidak Cocok" Di Ubuntu 14.04?

  3. Bagaimana Cara Mengubah Pintasan Keyboard Evolution?

  1. Pintasan Keyboard Global Rusak Di 14,04?

  2. Masalah Dengan Keyboard Tidak Berfungsi Saat Di-boot?

  3. Mengaitkan Kata Kunci Ke Aplikasi Di Unity Launcher?