Pull to refresh

Comments 29

Идея отличная! В свое время у меня была идея сделать коротко появляющийся флажок с текущим языком рядом с курсором при получении фокуса полем ввода. Но не осилил и не уверен что в windows это возможно в принципе.
UFO just landed and posted this here

Я джва(больше) года об этом мечтал, с момента появления этих подсветок. Идея такая очевидная и удобная, и странно почему до сих пор этого нет стандартной фишкой клавы-системы. Это же суперудобно, даже смотреть не надо: благодаря переферическому зернию мозг всегда будет знать какой сейчас язык.

Мб потому что большая часть компаний родом из англоязычных стран, им переключать ничего не нужно.

Мне тоже интересно, почему не было каких-то готовых решений, хотя тот же Corsair CUE, судя по копирайту, русские авторы.

Как Вы считаете, можно ли сделать это приложение сервисом, чтобы оно запускалось до входа в систему? Не силён в этой части...

Скорее всего, короткий ответ - "да", но надо будет несколько дополнительных шагов: сервисы запускаются не от юзерской учетки, и для внедрения dll в процессы пользователя все равно понадобятся отдельные приложения. Чтобы их запустить с нужными правами, придется разбираться в виндовой системе контроля доступа. Кроме того, сервисы не могут напрямую взаимодействовать с пользователем, например, создавать окна (они работают в своей отдельной сессии, если я правильно понимаю), и для работы придется вместо простых оконных сообщений городить сложный IPC, возможно, опять же, с контролем доступа.

Делал нечто подобное - правда, не с подсветкой клавиатуры, а отдельными светодиодами. Очень удобно и наглядно. Проблема в том, что приходится часто работать по RDP, а как получать язык раскладки из RDP-сеанса, придумать не получилось.

А с клавиатурой на QMK прошивке можно такое провернуть? Как клавиатура понимает какой сейчас языковой режим Windows?

Я не сталкивался с ними, но, думаю, можно, если там есть какая-то управляющая программа, с которой можно взаимодействовать. Программа определяет язык ввода из параметров при получении события HSHELL_LANGUAGE от WH_SHELL хука.

Я такую проблему решил с помощью разных слоев для разных раскладок (+ так же помогает не думать какая там в ОС раскладка по клавишам и менять их как угодно), сменой раскладок на Ctrl+Shift+ число и вот такого кода:
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  switch (keycode) {
    case TO(1):
      if (record->event.pressed) {
        SEND_STRING(SS_LCTL(SS_LSFT(SS_TAP(X_2))));
      }
      break;
    case TO(0):
      if (record->event.pressed) {
        SEND_STRING(SS_LCTL(SS_LSFT(SS_TAP(X_1))));
      }
      break;

При переключении на слой с русской раскладкой отправляется Ctrl+Shift+2 и меняется раскладка на русскую, при переключении на слой с английской раскладкой отправляется Ctrl+Shift+1 и меняется раскладка на, соответственно, английскую. И для разных слоев разная подсветка.

Проблема рассинхронизации при этом не возникает? Не бывает, что какая-нибудь программа сама язык переключает?

Если настроить ОС включить глобальное переключение раскладки то вроде бы нет такого. Не могу более уверенно говорить, я только месяц своей клавиатурой на QMK пользуюсь. При использовании виртуалок есть проблемы, хотя не могу сказать что большие, видишь что раскладка не та, жмешь кнопку смены слоя и все решается.
Я писал себе такое для ZSA Moonlander (он на QMK). Сперва сделал примерно как у вас (у каждого языкового слоя свой цвет, прошивка при переключении слоя отправляет хоткей на включение соответствующего языка). Но я не люблю глобальное переключение раскладки, мне больше нравится, чтобы приложения помнили язык, мне так удобнее, я так привык. Написал дополнительно программу, которая постоянно запущена на компьютере и посылает клавиатуре сигнал, если язык сменился. Можно переключать языки не конкретными хоткеями, а просто в цикле по Ctrl-Shift, программы помнят язык ввода, при смене фокуса, если сменился язык, меняется подсветка. Сейчас использую три языка: английский (синий цвет), русский (зелёный), японский (жёлтый). По-умолчанию цвета приглушённые, если зажат Shift или Caps, то вдвое ярче. При том что печатаю вслепую на всех языках, периферическое зрение отлично ловит цветовые переходы. Правда, с хуками, как автор статьи, не стал заморачиваться — как сделал на Питоне прототип, который тупо проверяет активный язык два раза в секунду, так в итоге на нём и остался: работает, систему не грузит, скорости хватает (ну не переключаю я языки чаще двух раз в секунду). Были, конечно, мысли переделать всё красиво, на хуках. С другой стороны, были мысли прикрутить дополнительно что-нибудь, в зависимости не только от языка, а и от активной программы, например, а с «тупой» проверкой, вроде, как-то универсальнее. Так и живу пока.
UFO just landed and posted this here

Предлагаете ловить сами нажатия комбинации смены языка?

UFO just landed and posted this here

А тиньке как сообщать, что там наловил хук?

UFO just landed and posted this here

(Не совсем по теме, зато работает с любой клавиатурой)

Последние 15 лет пользуюсь утилитой KbLangLED (14.5 Kb). При переключении раскладки она переключает (светодиод) ScrollLock. К ней прилагается исходник, источник alt-soft.info мёртв.

Source Code
program KbLangLED;

uses
  Windows;


type
  TKbLEDTag = (kbledNum, kbledCaps, kbledScroll);

procedure ToggleKeybrdLED(LEDTag: TKbLEDTag);

  procedure SimulateLkKey(KeyDown: Boolean);
  const
    VKeyCodes: array[TKbLEDTag] of Byte = (VK_NUMLOCK, VK_CAPITAL, VK_SCROLL);
    ScanCodes: array[TKbLEDTag] of Byte = ($45, $3A, $46);
  begin
    keybd_event(VKeyCodes[LEDTag], ScanCodes[LEDTag], KEYEVENTF_EXTENDEDKEY +
      Ord(not KeyDown) * KEYEVENTF_KEYUP, 0);
  end;

begin
  SimulateLkKey(True);
  SimulateLkKey(False);
end;


const
  LangKbLED = kbledScroll;  // LED to indicate language

var
  Mutex: THandle;
  EnUS: Boolean;
  OldEnUS: Boolean = True;
  Msg: TMsg;

begin
  // Check already running
  Mutex := CreateMutex(nil, True, 'KbLangLED_Running');
  if WaitForSingleObject(Mutex, 0) <> WAIT_OBJECT_0 then
    Exit;

  // Turn off the feedback cursor
  if PostThreadMessage(GetCurrentThreadId, 0, 0, 0) then
    GetMessage(Msg, 0, 0, 0);

  while True do
  begin
    EnUS := GetKeyboardLayout(GetWindowThreadProcessId(GetForegroundWindow)) and
      $FFFF = $0409;
    if EnUS <> OldEnUS then
    begin
      ToggleKeybrdLED(LangKbLED);
      OldEnUS := EnUS;
    end;
    Sleep(100);
  end;
end.

Я в свое время делал такой переключатель, и даже написал статью Добавляем подсветку символов национального алфавита в клавиатуру (ixbt.com)

Но в программе (скачивается если кому надо, по ссылке в статье, браузер ругается, но вирусов нет в ней) есть баг - в командной строке она не ловила переключение, программист сказал что винда не отдает и это можно решить только написав свой драйвер. Так это или нет - не знаю.

Идея класс.

Но в текущих реалиях интересует осилит ли хук SetWindowsHookEx заметить изменения языка при работе с RDP и подобным. Нередко что язык хоста у меня один - RDP другой, сработает ли ваше решение в этом случае или нет? Было бы интересно узнать.

На всех машинах с которыми работаю по RDP поставил андед раскладку https://habr.com/ru/articles/301882/

Всё синхронно т.к. работает по состоянию капса, очень удобно

Использую такое же под линуксом. там это можно реализовать "штатными" средствами. В моем случае это OpenRazer + KDE (в нем можно настроить запуск произвольного скрипта при переключени раскладки, им дергается настройка подсветки из OpenRazer). Клавиатура - Razer Cynosa Lite, у неё прозрачные символы, они подсвечиваются в зависимости от раскладки. С одной стороны, это лучше, чем сплошная подсветка под клавишами, не бьет по глазам в вечернее время. С другой - они в целом выглядят тусклее, чем на обычной клавиатуре: серый на черном вместо белого на черном. Видимо, это проблема большинства игровых клавиатур.

Теоретически, светодиоды в моей клавиатуре поддерживают RGB, а значит, можно выставить значения около 0, что должно дать тусклый свет. На практике я так делать еще не пробовал :)

Sign up to leave a comment.

Articles