เปลี่ยนสถานะของไฟ led บนคีย์บอร์ดจากภายในเซสชัน X โดยไม่ต้องเข้าถึงรูท


10

ฉันพยายามบังคับให้ capslock นำไปสู่ ไม่ทำงานสำหรับฉันดังนั้นฉันพยายามที่จะใช้xsetsetleds

ในคอนโซลกราฟิกคำสั่งนี้จะส่งคืน:

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

ในเทอร์มินัลเสมือนใช้งานได้ แต่เอฟเฟกต์นั้นเป็นโลคัลสำหรับเทอร์มินัลเสมือนนั้น จากสิ่งที่ฉันเข้าใจทำงาน

> setleds -L +caps < /dev/tty1

จากเทอร์มินัลเสมือน (เซิร์ฟเวอร์ X ของฉันกำลังนั่งอยู่บน tty1) ควรใช้งานได้ อย่างไรก็ตามต้องมีการเข้าถึงรูท

มีวิธีการส่งคำสั่งไปยังคอนโซลที่อยู่ภายใต้เซิร์ฟเวอร์ X ไม่ว่าจะเป็นจาก xserver ดังกล่าวหรือจาก VT อื่นโดยไม่ต้องรูท?

แก้ไข: จากข้อเสนอแนะจาก Mark Plotnik และจากรหัสที่พบที่นี่ฉันเขียนและรวบรวมสิ่งต่อไปนี้:

#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;
}

จากสิ่งที่ Gilles เขียนxsetฉันไม่ได้คาดหวังให้มันทำงาน แต่มัน ... ในบางแง่: มันเป็นผู้นำ แต่มันก็ตั้งสถานะของการล็อค ฉันไม่เข้าใจรหัสทั้งหมดข้างต้นอย่างสมบูรณ์ดังนั้นฉันอาจทำผิดพลาดไป เห็นได้ชัดว่าสายXChangeKeyboardControl...ไม่เปลี่ยนแปลงพฤติกรรมของโปรแกรมและXkbLockModifiersเป็นสิ่งที่กำหนดสถานะของ led และสถานะ capslock


คุณสามารถทำสิ่งต่าง ๆ เช่นxdotool key Caps_Lockจากไคลเอนต์ X ที่ได้รับอนุญาตแม้ว่าจะเป็นการเปิดใช้ตัวพิมพ์ใหญ่ก็ตาม
Mark Plotnick

@MarkPlotnick จุดนี้แน่นอนที่จะไม่เปิด CapsLock มีวิธีที่จะปิด CapsLock โดยไม่ต้องสัมผัสนำ?
T. Verron

ฉันดูที่xtermต้นทางและใช้การเรียกXChangeKeyboardControl ()เพื่อตั้งค่าหรือยกเลิกการติดตั้ง LED โดยไม่ส่งผลกระทบต่อสถานะของแคปล็อค ฯลฯ ดังนั้นหากคุณสามารถรวบรวมรหัส C นั่นเป็นวิธีหนึ่ง
Mark Plotnick

@MarkPlotnick xtermส่งผลกระทบต่อไฟled หรือไม่ ดูเหมือนความคิดที่ดีฉันจะแก้ไขคำถามด้วยผลลัพธ์ของฉัน
T. Verron

ฉันxtermต้องเปิดไฟ LED ScrollLock โดยส่งลำดับ escape ESC [3 q ตามไฟล์ctlseqs.txtที่มาพร้อมกับแหล่งที่มา แต่ไม่สามารถรับ Num หรือ CapsLock LEDs เพื่อให้สว่างขึ้นด้วยพารามิเตอร์ 1 และ 2 บางทีฉันต้อง ทำคอนฟิกูเรชัน XKB ที่กล่าวถึงในคำตอบ xtermโทรXChangeKeyboardControlเข้าxtermShowLEDและxtermClearLEDs, แต่ไม่โทรไปXkbLockModifiersไหนเลย
Mark Plotnick

คำตอบ:


7

โดยหลักการแล้วคุณควรจะสามารถทำได้ด้วยxsetคำสั่งที่เคารพ

xset led named 'Caps Lock'

หรือxset led 4เพื่อตั้งค่า LED หมายเลข 4 หากระบบของคุณไม่รู้จัก LED ตามชื่อ

อย่างไรก็ตามสิ่งนี้ดูเหมือนจะไม่สามารถทำงานได้อย่างน่าเชื่อถือ ในเครื่องของฉันฉันสามารถตั้ง Scroll Lock ด้วยวิธีนี้และฉันไม่ได้เป็นเพียงคนเดียว นี้น่าจะเป็นเรื่องของการกำหนดค่า XKB

การแก้ไขปัญหาระดับผู้ใช้ต่อไปนี้ควรทำงานได้ (ส่วนใหญ่):

  1. แยกคอนฟิกูเรชัน xkb ปัจจุบันของคุณ:

    xkbcomp $DISPLAY myconf.xkb
    
  2. แก้ไขไฟล์myconf.xkbแทนที่!allowExplicitด้วยallowExplicitในบล็อกที่เกี่ยวข้อง:

    indicator "Caps Lock" {
        allowExplicit;
        whichModState= locked;
        modifiers= Lock;
    };
    indicator "Num Lock" {
        allowExplicit;
        whichModState= locked;
        modifiers= NumLock;
    };
    
  3. โหลดไฟล์ใหม่

    xkbcomp myconf.xkb $DISPLAY
    

ตอนนี้การตั้งค่าไฟ led และปิดด้วยxsetควรทำงาน ตามรายงานข้อผิดพลาดคุณจะไม่สามารถปิดไฟ LED เมื่อพวกเขาควรจะเปิด (ตัวอย่างเช่นถ้าเปิดใช้งาน CapsLock)


ขอบคุณ! ฉันเคยลองxsetมาก่อนและแน่นอนมันไม่ทำงาน ฉันไม่เคยเห็นรายงานข้อผิดพลาดนี้มาก่อน อย่างไรก็ตาม "Status: Resolved Wontfix" นั้นไม่ได้ให้กำลังใจจริงๆ ... การallowExplicitทำงานรอบ ๆ อาจจะเหมาะกับฉัน (ฉันไม่จำเป็นต้องปิดไฟ led) แต่การเปลี่ยนมันยังต้องใช้ root
T. Verron

@ T.Verron คุณไม่จำเป็นต้องรูทเพื่อเปลี่ยนการกำหนดค่า XKB คุณสามารถโทรxkbcompได้ตลอดเวลา ฉันไม่คุ้นเคยกับ XKB ที่จะบอกคุณว่าคุณต้องเปลี่ยนอะไร (การตั้งค่ามุมมองที่เฉพาะเจาะจงมากกว่าแผนที่ที่กำหนดไว้ล่วงหน้าด้วย XKB นั้นค่อนข้างเจ็บปวด) แต่unix.stackexchange.com/questions/166844/mapping -key-bindings / ...ควรมีตัวชี้ไม่กี่
Gilles 'ดังนั้น - หยุดความชั่วร้าย'

โอ้จุดดี เป็นความพยายามครั้งแรกที่ฉันพยายาม: xkbcomp $DISPLAY output.xkbจากนั้นแทนที่!allowExplicitด้วยallowExplicitในindicator "Caps Lock"ส่วนจากนั้นทำการโหลดไฟล์xkbcomp output.xkbใหม่อีกครั้ง มีคำเตือนจำนวนมากและ xset ไม่ทำงานได้ดีขึ้นในภายหลัง ฉันจะอ่านเพิ่มเติมเกี่ยวกับ xkb
T. Verron

1
งานประเภทนี้สำหรับฉัน หลังจากที่ฉันนำเข้าไฟล์ที่แก้ไขแล้วฉันได้รับข้อความแสดงข้อผิดพลาดและฉันสามารถทำให้ไฟ LED สว่างขึ้น แต่สิ่งอื่น ๆ เกิดความสับสนรวมถึงมันไม่รอดจากการรีสตาร์ท ดังนั้นฉันจึงไปข้างหน้าแก้ไข/usr/share/X11/xkb/compat/ledcapsและ ... / lednum และสิ่งนี้ทำให้มันถาวร
jtgd

0

การใช้ sed

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

หลังจากออกจากระบบและเข้าสู่ระบบอีกครั้งCaps Lockตอนนี้ LED สามารถควบคุมได้โดยไม่มีrootสิทธิ์ใช้คำสั่ง:

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

แต่สิ่งนี้ต้องใช้ราก
T. Verron

@ T.Verron เพียงครั้งเดียวเพื่อเปลี่ยนไฟล์การกำหนดค่าด้วยsudoแล้วไม่เคยอีกครั้ง หากต้องการทำความเข้าใจว่าเหตุใดจึงมีความสำคัญต่อผู้ใช้บางรายโปรดดูvimแอปพลิเคชันนี้
Serge Stroobandt

เป็นคนที่ถามคำถามเมื่อ 3 ปีที่แล้วฉันเข้าใจอย่างแน่นอนว่าทำไมผู้ใช้บางคนถึงมีความสำคัญ (ในกรณีของฉันมันคือการหลีกเลี่ยงความล่าช้าของแอปเปิ้ลคีย์บอร์ดเมื่อเปิดใช้งาน capslock หลังจากทำการแมปใหม่เพื่อควบคุม) แต่ก่อนหน้านี้ฉันต้องการวิธีแก้ปัญหาเป็นพิเศษโดยไม่ต้องเข้าถึงรูทเลยเพราะเป็นคอมพิวเตอร์ที่ทำงาน คำตอบที่ได้รับการยอมรับนั้นเกี่ยวข้องกับอีกไม่กี่ขั้นตอน แต่จะทำงานได้โดยไม่ต้อง sudo
T. Verron

@ T. Veron ฉันเข้าใจ ระบบที่ใช้ร่วมกันเป็นอีกกรณีหนึ่งที่ไม่สามารถใช้งานได้ แม้ว่าฉันจะชอบความตรงไปตรงมาของผู้แสดงความคิดเห็นคนสุดท้ายเกี่ยวกับคำตอบที่ยอมรับและสร้างsedหนึ่งซับออกมา
Serge Stroobandt

0

การรวมกันของวิธีการที่รูทน้อยโดย @Gilles กับความคิดของระบบอัตโนมัติเต็มรูปแบบโดย @Serge_Stroobandt

วิธีเปิดใช้งานการควบคุมCaps Lock , Num LockและLED Lock Shift :

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

วิธีเปิดและปิด 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'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.