ХаритоновСофт
55 subscribers
36 photos
1 video
11 files
116 links
Download Telegram
Виндовс и системный индикатор языка

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

Напомню вкратце. Брать язык как пишут во всех мануалах, через winAPI нельзя. Не будет работать в целых классах приложений: консольных, из winstore (он вообще нормально никогда не работает) и системных.
Даже в модном блокноте из вин11 уже такой метод бессилен.

Передавая мысль гласит, что существует TSF (Text Services Framework) и он-то призван решить все проблемы связанные с языком. Вот только чтобы он заработал как глобальный монитор раскладки, нужно сплясать такой хитрый танец, что я до сих пор не осилил все его па. Нужно создать свой компонент, на C++ (C# плохо для этого подходит), зарегистрировать его и пытаться с ним общаться из приложения. Но и то, это не гарантирует надёжность которая есть у системного индикатора.

Вот и приходится выковыривать его из недр UI.

Добыть элемент индикатора становилось сложнее от года к году. Сначала получилось очень легко — простой поиск потомков таскбара, строим дерево элементов, находим по имени того кто совпадает текстом с раскладкой из системного списка. Быстро выяснилось, что положение в дереве элементов разнится от версии к версии. Один раз даже видел как местоположение зависело от языка интерфейса ОС.

Сначала, наивно полагая, что вариантов будет не так уж и много, добавлял проверки на каждый случай.

В один из дней, кажется это случилось в каких-то версиях 11ой, такой способ перестал работать. И тогда я открыл для себя чудесный мир UIAutomation. Эта технология отчасти сделана для слепых и слабовидящих, чтобы их читалки могли понять, что происходит на экране. Пришлось брать элементы таскбара и строить UIAutomation-деревья от них. Именно деревья, потому что каждый элемент из обычного дерева UI может породить отдельное UIAutomation-дерево. Операция это дорогая, поэтому в начале брал первый уровень
обычного дерева и 5 уровней дерева автоматизации.

Получая отзывы и файлы деревьев узнал много интересного. Во-первых, индикатор может скрываться на разной глубине деревьев, это зависит как от версии ОС так и дополнительного софта, который занимается украшательством и подменяет системные элементы. Во-вторых, деревья могут иметь циклические ссылки, просматривая которые ты попадёшь в бесконечный цикл. Не догадался бы, что так бывает, если б не получил два дампа с крахом по необработанному исключению (большое спасибо за файлы!).

В итоге, наш чудесный алгоритм получения индикатора выглядит так:
1. Смотрим первый уровень элементов таскбара, строим их деревья, ищем по совпадению с названиями раскладок (там тоже есть нюансы, они называются не совсем так как в системе, но это уж мелочи)
2. Если не нашли смотрим второй уровень и после него третий, если опять не повезло.

Всё это с защитой от циклических ссылок.

И если бы на свете была только десятая виндовс, то всё было бы не так уж и плохо. Нашли элемент, закэшировали, каждый раз для получения нового значения достаточно просто обновить — радость и счастье, никакого дорогого хождения по деревьям.

Но в 11й нельзя просто обновить элемент и получить новое значение. У них там «другая внутренняя реализация».

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

Сначала мы находим индикатор обычным способом. И запоминаем уровень с индексом где он лежал в обычном дереве элементов таскбара, их у нас 3. Дальше мы запоминаем номера элементов UIAumation-дерева, получается что-то типа 3->1->5 — это значит что в третьем потомке 1-го уровня берём первый элемент и его пятый потомок это наш индикатор.

Получается такой нехитрый набор координат, который на порядки ускоряет поиск и устойчив к изменениям в структуре.
🤯5🔥1
А ведь мог бы просто сделать один системный вызов и ОС бы ответила: «конечно, родной, вот тебе текущий язык пользователя, который я уже показываю в своём индикаторе, бери на здоровье.». Эх, мечты, мечты.

Всем кто тестирует — большое спасибо!

https://khsoft.ru/download/test/LayoutIndicator.v3.2.6.test.zip
🔥4💯4
Удалось поработать со старой ошибкой — индикатор вылетал после гибернации.
Исправил считай в слепую, на виртуалке эта функция ОС не работает, перезагружать для тестов рабочую машину нет возможности.

Плюс закрыл пару минорных багов которые раздражали.

🛠 (исправление) Крах после гибернации
🛠 (исправление) Не всегда отображалась иконка программы после запуска
🛠 (исправление) Поиск системного индикатора в Windows 11 не всегда смотрел кэшированный путь
🛠 (исправление) Не верно отображалась раскладка сразу после старта

https://khsoft.ru/download/test/LayoutIndicator.v3.2.7.test.zip
👍4❤1
Долгие годы Индикатор хранил следы моего психоза.

Как-то меня на столько взбесили ошибки переключения, что я сделал индикацию прямоугольником — огромный прозрачный прямоугольник висел точно по центру экрана и напоминал о раскладке. Его нельзя было переместить, только увеличить в размере, растянуть, например, на весь экран.

Какое-то время даже работал так, но потом отпустило, а функция осталась. Не знаю, пользовался ли ей кто-то ещё хоть раз в жизни. Ни одного багрепорта или отзыва небыло.

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

Теперь это настройка экранной индикации «Рамка». Размер (толщина) задаётся в пикселях а не процентах. Можно настроить прозрачность. Поставил себе такую, пока нравится, посмотрим как себя покажет на длинной дистанции.

Приятно порадовала скорость с которой Codex запилил эту фичу. Была даже лёгкая эйфория и ощущение, что такое можно делать быстро и легко. Но при тестировании выяснилось, что в одной из сборок 11й виндовс, формы для покраски панелей задач - перекрывают их именно когда включается рамка. Тут-то и начались циклы переписывания одного и того же без результата, зато с деградациями. Но я был уже на опыте, каждый рефакторинг коммитил с комментариями, поэтому где надо откатывался, уточнял промты, добавлял диагностики в логи.

Удалось найти различия в работе со стилями окон между разными билдами ОС. Кодекс ходил читать документацию от майкрософт. Это отдельный вид технического страдания. Они как знали и сразу писали её для ИИ. Живой человек не должен такое видеть. В итоге нашли нюансы, всё поправили и восстановили как было, но теперь с работающей рамкой.

Вдоволь навозившись с формами-подложками, решил, что пора включать покраску через Aero там где это поддерживается. Так и сделал. Быстро накидал проверку поддержки. Теперь если ОС позволяет, красим панель задач без форм. Осталось отложить для таких случаев их инициализации и можно ускорить запуск программы на несколько секунд, займусь следующий раз.

С проектами на работе так не разгуляешься конечно. Тут больше свободы. Как «руки» ИИ уже незаменим. Когда пишешь: «переведи название настройки не все три языка и замени в ресурсах», а он делает это за пару секунд — испытываешь кайф. Я могу сделать это сам, но сколько при этом глупой механической возни, а тут просто попросил.

Так же сделал фичу, которую давно пора было сделать - настройку для отдельной раскладки «Отключить индикацию». Это когда для одного языка вообще ничего не отсвечивает, ни флагов, ни рамок, ни цветных панелей. Ибо отсутствие индикации — тоже индикация.

Сам я только так и работал, но для этого были внедрены костыли: пустой альтернативный текст убирал флаг и надпись, а чёрный цвет не красил таскбар. Теперь того же эффекта можно добиться понятной настройкой.

Разобрался с позицией экранного индикатора «Надпись», там для разных мониторов был разбег интервалов от -10000 до +10000 px, что-то выцелить было сложно. Перевёл на проценты.

Добавил лог краха. Столкнулся на виртуалке с падением связанным с особым файлом настроек. В логах тишина, Индикатор не успевал до них дожить. Добавил аварийные логи, нашёл и исправил ошибку.

Это самая плотная сессия по взаимодействию с ИИ. Очень быстро привыкаешь к такой разработке. Когда кончаются токены, ощущаешь себя посреди непаханного поля, с поломанным трактором.

P.S. Дистрибутив теперь msi, ИИ говорит так будет меньше сообщений о вредоносном ПО.

Спасибо всем кто тестирует!

https://khsoft.ru/download/test/LayoutIndicator.v3.2.8.test.zip
https://khsoft.ru/download/LayoutIndicator.msi
❤4👀2
Краткая сводка изменений не влезла целиком:

✅ Индикация «Прямоугольник» заменена на рамку
✅ Добавлена настройка отключающая индикацию флагами и цветом таскбара для выбранной раскладки
✅ Изменение логики пустого альтернативного текста: если пусто - не показываем флаги и надпись на экране. Рамку и всё остальное показываем
✅ Положение надписи экранной индикации теперь задаются в процентах а не пикселях
✅ Поменялся формат дистрибутива exe -> MSI
✅ В окне с сообщением о новой версии, ссылка ведёт сразу на файл дистрибутива а не на сайт
✅ При поддержке ОС Aero, панели красятся с её помощью по умолчанию
✅ Добавлено создание файла диагностики для ошибок возникающих при старте программы, когда она не смогла добраться до основной системы логирования
🛠 (исправление) В 11й Виндовс (билд 22631) формы покраски панели задач перекрывали её
🛠 (исправление) При определённых значениях настроек, программа не запускалась в 11й Виндовс (билд 22631)
Релиз Индикатора 3.3.0

Созрели до релиза. Пощупали потестировали, отзывы хорошие.

Из последнего, что успело заехать:

1. Изменилась политика лицензий.

Как было: купленный ключ вечно действовал на зарегистрированную копию и все последующие обновления.
Как стало: ключ вечно действует на купленную версию и на все обновления в течении года.

Довольно справедливая схема. Если, по истечению года, обновлений нет или они не нужны — ничего не покупаете. Если обновления интересуют или просто хочется поддержать проект — покупаете новый ключ на ещё один год.

Начиная с 1 мая 2026, пойдёт год бесплатных обновлений для старых ключей. Т.е. 1 мая 2027 старые ключи перестанут активировать новые версии.

2. При помощи Кодекса удалось быстро реализовать доработку, которую давно хотелось. Индикаторы теперь не попадают на скриншоты! Сколько раз я перефотографировал какой-нибудь кусок экрана, потому что там затесался флаг. Теперь об этом можно забыть.

Всё время забываю написать, что у проекта, благодаря ИИ, появилась внутренняя документация. Одно удовольствие делегировать эту процедуру. Он её и пишет и обновляет. Так приятно перед разработкой посмотреть нужный раздел и быстро погрузиться в контекст. Мега-Лайк!

https://khsoft.ru/download/LayoutIndicator.msi

Полный список изменений релиза:

✅ Определение раскладки по системному индикатору теперь работает даже есть панель на автоскрытии
✅ Отдельная кнопка для сохранения UI-дерева таскбара в файл
✅ Улучшен алгоритм поиска системного индикатора
✅ Перенёс системный файл настроек в директорию с программой
✅ Улучшено определение раскладки по системному индикатору. Программа теперь нормально обрабатывает ситуации когда он пропадает, например, на экране приложений (win+tab). Само определение стало быстрее, потребляет меньше ресурсов
✅ Повышена стабильность формы мышиного индикатора. В определённый ситуациях, он начинал сворачиваться как обычные окна.
✅ Индикация «Прямоугольник» заменена на рамку
✅ Добавлена настройка отключающая индикацию флагами и цветом таскбара для выбранной раскладки
✅ Изменение логики пустого альтернативного текста: если пусто - не показываем флаги и надпись на экране. рамку и всё остальное показываем
✅ Изменились единицы измерения положение надписи экранной индикации: были в пикселях, стали в процентах от экрана
✅ В окне с сообщением о новой версии, ссылка ведёт сразу на файл дистрибутива а не на сайт
✅ Поменялся формат дистрибутива: exe -> MSI
✅ Ускорение запуска программы в два раза
✅ Улучшена работа индикаторов зависящих от параметров экрана
✅ Новая лицензионная политика. Ключ действует бесконечно на купленную версию и на все обновления в течении одного года с момента покупки.
✅ Индикаторы (флаги, надписи) больше не попадают на скриншоты
🛠 (исправление) При переключении способа покраски панели задач с режима Aero и обратно - не восстанавливался уровень прозрачности панели
🛠 (исправление) Улучшен внешний вид флагов, Были серые линии снизу и справа
🛠 (исправление) В виндовс 11 не всегда выставлялся флаг определения раскладки по системному индикатору, даже если он работал
🛠 (исправление) В 11й Виндовс (билд 22631) формы покраски панели задач перекрывали её
🛠 (исправление) При определённых значениях настроек, программа не запускалась в 11й Виндовс (билд 22631)
🛠 (исправление) Увеличена скорость запуска программы
🛠 (исправление) Была ошибка при поиске по дереву UI
🛠 (исправление) Оптимизирован поиск системного индикатора в win11
🛠 (исправление) Крах после гибернации
🛠 (исправление) Не всегда отображалась иконка программы после запуска
🛠 (исправление) Не верно отображалась раскладка сразу поле старта
🛠 (исправление) Поиск системного индикатора в Windows 11 не всегда смотрел кэшированный путь
🛠 (исправление) Устранена рассинхронизация индикатора каретки, при определении раскладки по нажатию клавиш
👍7
Новый дроп от ХаритоновСофт 😎

Переключатель окон для Windows — Hotkey Window Switcher

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

Для этого даже есть специальные программы, да и написать скрипт на AHK не сложно. Что я сначала и сделал. Опробовал, мне понравилось, захотелось больше гибкости и упёрся в ограничения AHK. Написал приложение на C# которое вызывал из AKH по нужным хоткеям. Это работало. Не так как мне хотелось, но задачу свою выполняло и очень быстро стало неотъемлемой частью рабочего процесса.

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

Время от времени продолжал допиливать эту поделку, выбрал новый UI-фреймворк (Avalonia), шло тяжело.

А желание быстро настраивать запуск (без вспоминания синтаксиса AHK) и добавлять в процесс новые фичи — росло.

И тут наступила эра ИИ-помощников. Пощупав их, осознал, что можно без большого опыта, быстро писать на низкоуровневых языках и быть ближе к железу. Всё было переписано с нуля, на Nim. Этот язык транслируется в Си, а Си — это завуалированный ассемблер. Можно было конечно и на ассемблере но я хочу быстро понимать, что происходит в коде и оперативно править.

Помимо такого низкоуровневого языка, решил вообще не использовать зависимости, всё работает на чистом WinAPI. Минимально возможный компромисс между удобством пользователя и программиста. Сами понимаете в чью пользу (Юзера конечно). Весь ад работы с WinAPI взял на себя ИИ.

Получилось 652.5 КБ красоты. Работает молниеносно. UI - минимальный, но всё что от него нужно — делает. Программа полностью портативна, может записать автозапуск в реестр если включить в настройках.

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

Монетизация в этот раз другая — вместо пробного периода бесконечная бесплатная версия с ограничениями — максимум три приложения-фильтра и закрыта функция перевода окна на задний план.

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

Ниже будет небольшая инструкция как пользоваться и ссылка для скачивания.
🔥5
This media is not supported in your browser
VIEW IN TELEGRAM
Принцип простой — есть список фильтров окон и хоткеи которые им соответствуют.

1. Для начала работы добавляете фильтр (Add Filter) - кнопка в левом нижнем углу.
2. На форме добавления фильтра указываете название и задаёте сочетание клавиш.
3. Зажимаете мышкой мишень в левом нижнем углу и перетаскиваете на окно приложения которое хотите вызывать, там отпускаете.
4. После этого заполнятся критерии поиска окна. Нужно выбрать хотя бы один.
Самое простое Path (путь до программы), если оно включено, можно так же включить Launch if window missing, тогда программа запустится если оно не найдено. Мозг привыкает, что окно появляется после хоткея в любом случае.

Всё, дальше только пользоваться и радоваться.
Осторожно, вызывает дикое привыкание! 😁

https://khsoft.ru/download/test/HotkeyWindowSwitcher-v110.zip
👍3
Свитчер продвинутого пользователя.

Notepad добавил для тестов, остальное живое.

Через F13-23 у меня функциональный слой клавиатуры работает. Так удобнее ни с кем не пересекаться по клавишам.
🔥1
Вот такой маркетинг могут позволить себе независимые разработчики 😎
https://khsoft.ru/ws/
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥1😁1😐1
This media is not supported in your browser
VIEW IN TELEGRAM
Переключатель добрался до версии 1.1.1

Думал быстренько напишу небольшую утилиту но начал входить во вкус. Тема переключения окон оказалась такой же бездонной как индикация (а то и бездоннее).

Самая первая проблема с которой сталкиваешься, когда назначаешь хоткей для программы — а что если у неё несколько окон?

Прошлые версии могли предложить только опцию «циклическое переключение», это когда повторное нажатие выхватывает следующее окно. В паре с настройкой «игнорировать свёрнутые» вполне можно пользоваться.

В этот раз решил подойти к проблеме более качественно — добавил новую опцию: «Показать выбор окна».
Если включено, то появляется панель, где можно выбрать куда именно переключиться. Цифры работают как хоткеи, можно выбрать курсорными клавишами или тыкнуть мышкой.

Дальше предстоит подумать над следующей проблемой — у меня 20 приложений и я не хочу запоминать 20 хоткеев, которые к тому же начнут с кем-нибудь конфликтовать.

Сайт программы https://khsoft.ru/ws/

Изменения

✅ Добавлен русский язык
✅ Улучшен внешний вид
✅ Новая опция - показывать выбор окна если их несколько
🔥2
LayoutIndicator.v3.3.4.test.zip
2.3 MB
Центр сертификации Let's Encrypt обещал как-то мягко начать блокировать РФ, но, внезапно, перестали работать все сайты, подписанные ими. Если появилась ошибка об отсутствии сети, поставьте эту версию, в ней отключена проверка, всё будет работать. Сайты восстановлю в ближайшее время.
Всё восстановлено. Похоже, я просто забыл продлить все домены перед отъездом. Вот что отпуск животворящий делает 😁
👍3😁2
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Новая версия переключателя окон — 1.1.8

Получил письмо с багом новой версии Переключателя окон. Он просто не стартовал, выдавая ошибку "Illegal operation". Напомню, код написан на Nim, который транслируется в чистый Си. По характеру ошибки примерно понял, что дело в чём-то глубоко системном. В логах тишина, обработчик ошибок ничего не поймал. При этом на другом компьютере пользователя всё работает.

Запросив конфигурацию, на которой происходит ошибка, попробовал воспроизвести у себя — ошибки нет. Гипотезу, что это какие-то специфические настройки самого приложения, отмёл.

Получилась золотая классика разработки — не работает там, куда нет прямого доступа. Тут без помощи человека, у которого этот доступ есть, не обойтись. Благо была возможность быстро проверять новые сборки, за что отдельное спасибо.

Схема уже обкатанная: усиливаем диагностику, чтобы в логи попали грязные подробности краха. ИИ-агент быстро накодил модуль, пообещал новый лог старта приложения и дамп краха — слепок состояния программы в момент падения. По нему уже можно было понять, где именно всё рухнуло.

Первая итерация не принесла успеха: логи не создались, дамп тоже. После падения появился невнятный файл с иероглифами в имени. Чуть поправили код, и вот у меня на руках дамп. Скормил дамп на анализ — и причина нашлась. Программа использовала процессорную инструкцию, которую не поддерживал старый Intel Core 2 Duo на той машине. Так давно не программировал на языках низкого уровня, что забыл о существовании таких ошибок.

Выяснив, какая именно инструкция даёт такой эффект, вырезал код, который её генерил. Попутно ИИ добавил специальные флаги компиляции, чтобы избежать подобных ошибок. И уже по моей просьбе он обновил гайд разработки с описанием этого случая и добавил в скрипт релиза проверку на наличие подобных инструкций в коде.

Не будучи системным программистом, страшно подумать, сколько времени и итераций ушло бы на поимку такой ошибки. Но дело даже не во времени — без ИИ я бы вообще не полез писать такую штуку на Nim который транслируется в Си.

Скачать новую версию
👀2
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2