Ubah status led keyboard, dari dalam sesi X, tanpa akses root


10

Saya mencoba untuk memaksa capslock menyala. xsettidak bekerja untuk saya, jadi saya coba gunakan setleds.

Di konsol grafis, perintah ini mengembalikan:

> LANG=C setleds -L +caps
KDGKBLED: Inappropriate ioctl for device
Error reading current flags setting. Maybe you are not on the console?

Di terminal virtual, ia berfungsi, namun efeknya bersifat lokal ke terminal virtual itu. Dari apa yang saya mengerti, berlari

> setleds -L +caps < /dev/tty1

dari terminal virtual (server X saya duduk di tty1) harus berfungsi. Namun, ini membutuhkan akses root.

Apakah ada cara untuk mengirim perintah ke konsol yang mendasari server X, baik itu dari xserver tersebut atau dari VT lain, tanpa root?

Sunting: Dari saran dari Mark Plotnik, dan berdasarkan kode yang ditemukan di sini , saya menulis dan menyusun yang berikut:

#include <X11/Xlib.h>
#include <X11/XKBlib.h>

#define SCROLLLOCK 1
#define CAPSLOCK 2
#define NUMLOCK 16

void setLeds(int leds) {
   Display *dpy = XOpenDisplay(0);
   XKeyboardControl values;
   values.led_mode = leds & SCROLLLOCK ? LedModeOn : LedModeOff;
   values.led = 3;
   XChangeKeyboardControl(dpy, KBLedMode, &values);
   XkbLockModifiers(dpy, XkbUseCoreKbd, CAPSLOCK | NUMLOCK,
                    leds & (CAPSLOCK | NUMLOCK) );
   XFlush(dpy);
   XCloseDisplay(dpy);
}

int main() {
   setLeds(CAPSLOCK);
   return 0;
}

Dari apa yang ditulis Gilles xset, saya tidak berharap itu berfungsi, tetapi ternyata ... dalam beberapa hal: itu yang mengatur, tetapi juga menetapkan status capslock. Saya tidak sepenuhnya memahami semua kode di atas, jadi saya mungkin telah melakukan kesalahan konyol. Rupanya, garis XChangeKeyboardControl...tidak mengubah perilaku program, dan XkbLockModifiersitulah yang mengatur status memimpin dan capslock.


Anda dapat melakukan sesuatu seperti xdotool key Caps_Lockdari klien X resmi, meskipun ini sebenarnya akan mengaktifkan caps lock.
Mark Plotnick

@MarkPlotnick Intinya memang bukan untuk mengaktifkan CapsLock. Apakah ada cara untuk mematikan CapsLock, tanpa menyentuh led?
T. Verron

Saya melihat xtermsumbernya, dan ia menggunakan panggilan ke XChangeKeyboardControl () untuk mengatur atau menghapus pengaturan LED tanpa memengaruhi status caps lock dll. Jadi, jika Anda dapat mengkompilasi kode C, itu salah satu pendekatan.
Mark Plotnick

@MarkPlotnick Apakah xtermmempengaruhi leds? Kedengarannya seperti ide yang bagus, saya akan mengedit pertanyaan dengan hasil saya.
T. Verron

Saya harus xtermmenyalakan ScrollLock LED dengan mengirimkan urutan escape ESC [3 q, sesuai file ctlseqs.txtyang disertakan dengan sumbernya, tetapi tidak bisa membuat LED Num atau CapsLock menyala dengan parameter 1 dan 2. Mungkin saya perlu lakukan konfigurasi XKB yang disebutkan dalam jawaban. xtermpanggilan XChangeKeyboardControlmasuk xtermShowLEDdan xtermClearLEDs, tetapi tidak menelepon XkbLockModifierssama sekali.
Mark Plotnick

Jawaban:


7

Pada prinsipnya, Anda harus dapat melakukannya dengan xsetperintah yang mulia .

xset led named 'Caps Lock'

atau xset led 4untuk mengatur LED nomor 4, jika sistem Anda tidak mengenali LED dengan nama.

Namun, ini tampaknya tidak berfungsi dengan baik. Di mesin saya, saya hanya dapat mengatur Scroll Lock dengan cara ini, dan saya bukan satu-satunya . Ini sepertinya masalah konfigurasi XKB .

Penanganan tingkat pengguna berikut ini harus berfungsi (sebagian besar):

  1. Ekstrak konfigurasi xkb Anda saat ini:

    xkbcomp $DISPLAY myconf.xkb
    
  2. Edit file myconf.xkb, ganti !allowExplicitdengan allowExplicitdi blok yang relevan:

    indicator "Caps Lock" {
        allowExplicit;
        whichModState= locked;
        modifiers= Lock;
    };
    indicator "Num Lock" {
        allowExplicit;
        whichModState= locked;
        modifiers= NumLock;
    };
    
  3. Muat file baru

    xkbcomp myconf.xkb $DISPLAY
    

Sekarang menyalakan dan mematikan led xsetharus bekerja. Menurut laporan bug, Anda tidak akan dapat mematikan led ketika mereka seharusnya dinyalakan (misalnya jika CapsLock diaktifkan).


Terima kasih! Saya sudah mencoba xsetsebelumnya, dan memang itu tidak berhasil. Saya belum melihat laporan bug ini. Pokoknya, "Status: Resolved Wontfix" tidak terlalu menggembirakan ... Solusi allowExplicitmungkin akan bekerja untuk saya (saya tidak perlu mematikan led off), tetapi mengubahnya masih membutuhkan root.
T. Verron

@ T. Verron Anda tidak perlu menjadi root untuk mengubah konfigurasi XKB. Anda dapat menelepon xkbcompkapan saja. Saya tidak cukup terbiasa dengan XKB untuk memberi tahu Anda dengan tepat apa yang perlu Anda ubah (mengatur aspek tertentu daripada peta yang telah ditentukan penuh dengan XKB agak menyusahkan ), tetapi unix.stackexchange.com/questions/166844/mapping -key-bindings / ... harus memiliki beberapa petunjuk.
Gilles 'SANGAT berhenti menjadi jahat'

Oh, bagus. Nah, sebagai upaya pertama, saya mencoba xkbcomp $DISPLAY output.xkb:, lalu mengganti !allowExplicitdengan allowExplicitdi indicator "Caps Lock"bagian, lalu memuat ulang file dengan xkbcomp output.xkb. Ada banyak peringatan, dan xset tidak berfungsi lebih baik setelahnya. Saya akan membaca lebih banyak tentang xkb.
T. Verron

1
Jenis pekerjaan ini untuk saya. Setelah saya mengimpor file yang dimodifikasi saya mendapat beberapa pesan kesalahan dan saya bisa menyalakan LED tetapi hal-hal lain menjadi kacau, ditambah itu tidak selamat restart. Jadi saya pergi ke depan diedit /usr/share/X11/xkb/compat/ledcapsdan ... / lednum dan ini membuatnya permanen.
jtgd

0

Menggunakan sed

$ sudo sed -i 's|\!allowExplicit|allowExplicit|g' /usr/share/X11/xkb/compat/ledcaps

Setelah keluar dan masuk lagi, Caps LockLED sekarang dapat dikontrol tanpa roothak istimewa menggunakan perintah:

$ xset led named 'Caps Lock'
$ xset -led named 'Caps Lock'

Tetapi ini membutuhkan root.
T. Verron

@ T. Verron Hanya sekali untuk mengubah file konfigurasi dengan sudodan kemudian tidak pernah lagi. Untuk mendapatkan pemahaman mengapa ini mungkin sangat penting bagi pengguna tertentu, lihat vimaplikasi ini .
Serge Stroobandt

Menjadi orang yang mengajukan pertanyaan 3 tahun yang lalu, saya pasti mengerti mengapa itu bisa penting bagi beberapa pengguna (dalam kasus saya, itu adalah untuk bekerja di sekitar penundaan keterlambatan yang dimiliki keyboard apple ketika mengaktifkan capslock, setelah memetakan capslock untuk mengontrol). Tetapi saat itu, saya secara khusus membutuhkan solusi tanpa akses root sama sekali, karena itu untuk komputer kerja. Jawaban yang diterima melibatkan beberapa langkah lagi, tetapi berhasil tanpa sudo.
T. Verron

@ T. Verron saya mengerti. Sistem bersama adalah kasus lain di mana ini tidak akan berfungsi. Meskipun demikian, saya menyukai keterusterangan komentar terakhir pada jawaban yang diterima dan membuat sedsatu kalimat dari itu.
Serge Stroobandt

0

Kombinasi pendekatan root-less oleh @Gilles dengan gagasan otomatisasi penuh oleh @Serge_Stroobandt.

Untuk mengaktifkan kontrol LED Caps Lock , Num Lock dan Shift Lock :

#!/bin/bash
# Enables to control keyboard LEDs that are not available for control by default
xkbcomp $DISPLAY /tmp/my_conf.xkb
cat /tmp/my_conf.xkb | awk -e '
    BEGIN {
        change = 0
    }

    {
        if (change == 1) {
            if ($1 == "!allowExplicit;") {
                gsub("!", "", $0)
            }
            change = 0
        }
        print $0

    }

    /indicator "Caps Lock"/ {
        change = 1
    }
    /indicator "Num Lock"/ {
        change = 1
    }
    /indicator "Shift Lock"/ {
        change = 1
    }
    ' > /tmp/my_conf_modified.xkb
xkbcomp /tmp/my_conf_modified.xkb $DISPLAY

Untuk menghidupkan dan mematikan LED:

# Turns the LED on
xset led named 'Caps Lock'

# wait 1s
sleep 1

# Resets the LED to the actual state,
# so it might still be on, if Caps Lock is activated.
xset -led named 'Caps Lock'
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.