Ändern Sie den Status der Tastatur-LEDs innerhalb einer X-Sitzung ohne Root-Zugriff

10

Ich versuche, die geöffnete Feststelltaste zu erzwingen. xsetfunktioniert bei mir nicht, also versuche ich es zu benutzen setleds.

In einer grafischen Konsole gibt dieser Befehl Folgendes zurück:

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

In einem virtuellen Terminal funktioniert es, der Effekt ist jedoch lokal für dieses virtuelle Terminal. Soweit ich weiß, läuft

> setleds -L +caps < /dev/tty1

von einem virtuellen Terminal (mein X-Server sitzt auf tty1) sollte funktionieren. Dies erfordert jedoch Root-Zugriff.

Gibt es eine Möglichkeit, einen Befehl an die Konsole zu senden, die einem X-Server zugrunde liegt, sei es vom X-Server oder von einem anderen VT ohne Root?

Bearbeiten: Auf Vorschlag von Mark Plotnik und basierend auf dem hier gefundenen Code habe ich Folgendes geschrieben und kompiliert:

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

Nach dem, worüber Gilles schrieb xset, hatte ich nicht erwartet, dass es funktioniert, aber es funktioniert ... in gewissem Sinne: Es setzt die LED, aber es setzt auch den Capslock-Status. Ich verstehe den obigen Code nicht vollständig, daher habe ich möglicherweise einen dummen Fehler gemacht. Anscheinend XChangeKeyboardControl...ändert die Zeile das Verhalten des Programms nicht und XkbLockModifierssetzt den LED- und den Capslock-Status.

T. Verron
quelle
Sie können so etwas wie xdotool key Caps_Lockvon einem autorisierten X-Client aus tun , obwohl dadurch die Feststelltaste aktiviert wird.
Mark Plotnick
@MarkPlotnick Es geht in der Tat nicht darum, CapsLock einzuschalten. Gibt es eine Möglichkeit, CapsLock auszuschalten, ohne die LED zu berühren?
T. Verron
Ich habe mir die xtermQuelle angesehen und sie verwendet einen Aufruf von XChangeKeyboardControl () , um die LEDs zu setzen oder zu deaktivieren, ohne den Status der Feststelltaste usw. zu beeinflussen. Wenn Sie also C-Code kompilieren können, ist dies ein Ansatz.
Mark Plotnick
@MarkPlotnick xtermBeeinflusst die LEDs? Es klingt nach einer guten Idee, ich werde die Frage mit meinen Ergebnissen bearbeiten.
T. Verron
Ich xtermmusste die ScrollLock-LED durch Senden der Escape-Sequenz ESC [3 q gemäß der ctlseqs.txtmit der Quelle gelieferten Datei aufleuchten lassen, konnte aber die Num- oder CapsLock-LEDs nicht mit den Parametern 1 und 2 aufleuchten lassen. Vielleicht muss ich Führen Sie die in der Antwort angegebene XKB-Konfiguration durch. xtermruft XChangeKeyboardControlan xtermShowLEDund xtermClearLEDs, ruft aber XkbLockModifiersnirgendwo an.
Mark Plotnick

Antworten:

7

Im Prinzip sollten Sie dies mit dem ehrwürdigen xsetBefehl tun können .

xset led named 'Caps Lock'

oder xset led 4um LED Nummer 4 einzustellen, wenn Ihr System die LEDs nicht anhand des Namens erkennt.

Dies scheint jedoch nicht zuverlässig zu funktionieren. Auf meinem Computer kann ich die Bildlaufsperre nur auf diese Weise einstellen, und ich bin nicht der einzige . Dies scheint eine Frage der XKB-Konfiguration zu sein .

Die folgende Problemumgehung auf Benutzerebene sollte (größtenteils) funktionieren:

  1. Extrahieren Sie Ihre aktuelle xkb-Konfiguration:

    xkbcomp $DISPLAY myconf.xkb
    
  2. Bearbeiten Sie die Datei myconf.xkb, ersetzt !allowExplicitmit allowExplicitin den entsprechenden Blöcken:

    indicator "Caps Lock" {
        allowExplicit;
        whichModState= locked;
        modifiers= Lock;
    };
    indicator "Num Lock" {
        allowExplicit;
        whichModState= locked;
        modifiers= NumLock;
    };
    
  3. Laden Sie die neue Datei

    xkbcomp myconf.xkb $DISPLAY
    

Jetzt die LEDs mit ein- und ausschalten xset funktionieren. Laut Fehlerbericht können Sie die LEDs nicht ausschalten, wenn sie eingeschaltet sein sollen (z. B. wenn CapsLock aktiviert ist).

Gilles 'SO - hör auf böse zu sein'
quelle
Vielen Dank! Ich hatte es schon einmal versucht xset, und tatsächlich funktioniert es nicht. Ich hatte diesen Fehlerbericht jedoch nicht gesehen. Wie auch immer, "Status: Resolved Wontfix" ist nicht wirklich ermutigend ... Die Problemumgehung allowExplicitwürde wahrscheinlich für mich funktionieren (ich muss die LED nicht ausschalten), aber das Ändern erfordert immer noch root.
T. Verron
@ T.Verron Sie müssen nicht root sein, um die XKB-Konfiguration zu ändern. Sie können xkbcompjederzeit anrufen . Ich bin mit XKB nicht vertraut genug, um Ihnen genau zu sagen, was Sie ändern müssen (das Festlegen eines bestimmten Aspekts anstelle einer vollständig vordefinierten Map mit XKB ist etwas mühsam ), aber unix.stackexchange.com/questions/166844/mapping -key-bindings /… sollte ein paar Zeiger haben.
Gilles 'SO - hör auf böse zu sein'
Oh, guter Punkt. Nun, als ersten Versuch habe ich versucht:, xkbcomp $DISPLAY output.xkbdann !allowExplicitdurch allowExplicitim indicator "Caps Lock"Abschnitt zu ersetzen und dann die Datei mit neu zu laden xkbcomp output.xkb. Es gibt viele Warnungen und xset funktioniert danach nicht mehr besser. Ich werde mehr über xkb lesen.
T. Verron
1
Diese Art hat für mich funktioniert. Nachdem ich die geänderte Datei importiert hatte, bekam ich einige Fehlermeldungen und ich konnte die LEDs anzünden, aber andere Dinge wurden durcheinander gebracht und es überlebte keinen Neustart. Also habe ich ein bearbeitetes /usr/share/X11/xkb/compat/ledcapsund ... / lednum gemacht und das hat es dauerhaft gemacht.
jtgd
0

Verwenden von sed

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

Nach dem Abmelden und erneuten Anmelden kann die Caps LockLED nun ohne rootBerechtigungen mit den folgenden Befehlen gesteuert werden:

$ xset led named 'Caps Lock'
$ xset -led named 'Caps Lock'
Serge Stroobandt
quelle
Dies erfordert jedoch root.
T. Verron
@ T.Verron Nur einmal zum Ändern einer Konfigurationsdatei mit sudound dann nie wieder. In dieser vimAnwendung erfahren Sie, warum dies für bestimmte Benutzer so wichtig sein kann .
Serge Stroobandt
Als derjenige, der die Frage vor 3 Jahren gestellt hat, verstehe ich definitiv, warum es für einige Benutzer wichtig sein kann (in meinem Fall war es, die dumme Verzögerung zu umgehen, die Apple-Tastaturen beim Aktivieren von Capslock haben, nachdem Capslock zur Steuerung neu zugeordnet wurde). Aber damals brauchte ich speziell eine Lösung ohne Root-Zugriff, da es sich um einen Arbeitscomputer handelte. Die akzeptierte Antwort umfasst einige weitere Schritte, funktioniert jedoch ohne Sudo.
T. Verron
@ T.Verron Ich verstehe. Gemeinsame Systeme sind ein weiterer Fall, in dem dies nicht funktionieren würde. Trotzdem gefiel mir die Unkompliziertheit des letzten Kommentators der akzeptierten Antwort und ich machte daraus einen sedEinzeiler.
Serge Stroobandt
0

Eine Kombination des wurzellosen Ansatzes von @Gilles mit der Idee der vollständigen Automatisierung von @Serge_Stroobandt.

So aktivieren Sie die Steuerung der LEDs Caps Lock , Num Lock und 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

So schalten Sie eine LED ein und aus:

# 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'
hoijui
quelle