Я пытаюсь принудительно включить светодиод CapsLock. xset
У меня это не работает, поэтому я пытаюсь использовать setleds
.
В графической консоли эта команда возвращает:
> 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) должно работать. Однако для этого требуется root-доступ.
Есть ли способ отправить команду на консоль, лежащую в основе X-сервера, будь то с указанного x-сервера или с другого VT, без прав root?
Редактировать: По предложению Марка Плотника и на основе найденного кодаздесь, я написал и скомпилировал следующее:
#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;
}
Из того, что написал Жиль xset
, я не ожидал, что это сработает, но это работает... в каком-то смысле: оно устанавливает светодиод, но также устанавливает статус capslock. Я не до конца понимаю весь код выше, так что, возможно, я допустил глупую ошибку. Судя по всему, эта строка XChangeKeyboardControl...
не меняет поведение программы, а XkbLockModifiers
именно она устанавливает светодиод и статус capslock.
решение1
В принципе, вы должны быть в состоянии сделать это с почтеннымxset
команда.
xset led named 'Caps Lock'
или xset led 4
установить светодиод номер 4, если ваша система не распознает светодиоды по названию.
Однако, это, похоже, не работает надежно. На моем компьютере я могу установить Scroll Lock только таким образом, иЯ не один. Этотпохоже, это вопрос конфигурации XKB.
Следующий обходной путь на уровне пользователя должен сработать (в большинстве случаев):
Извлеките текущую конфигурацию xkb:
xkbcomp $DISPLAY myconf.xkb
Отредактируйте файл
myconf.xkb
, заменив!allowExplicit
наallowExplicit
в соответствующих блоках:indicator "Caps Lock" { allowExplicit; whichModState= locked; modifiers= Lock; }; indicator "Num Lock" { allowExplicit; whichModState= locked; modifiers= NumLock; };
Загрузить новый файл
xkbcomp myconf.xkb $DISPLAY
Теперь включение и выключение светодиодов xset
должно работать. Согласно отчету об ошибке, вы не сможете выключить светодиоды, когда они должны быть включены (например, если включен CapsLock).
решение2
С использованиемsed
$ sudo sed -i 's|\!allowExplicit|allowExplicit|g' /usr/share/X11/xkb/compat/ledcaps
После выхода из системы и повторного входа в Caps Lockсистему светодиодом можно управлять без каких-либо root
привилегий с помощью команд:
$ xset led named 'Caps Lock'
$ xset -led named 'Caps Lock'
решение3
Сочетание подхода без корневого каталога @Gilles с идеей полной автоматизации @Serge_Stroobandt.
Чтобы включить контрольCaps Lock,Num Lockи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
Чтобы включить и выключить светодиод:
# 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'