Начал с того, что продолжил переходить на однопоточную модель. Очень понравилось полноценно дебажить. Гораздо быстрее чем вдумчиво смотреть на логи. Тем кто не смотрел на логи Индикатора, стоит ради интереса врубить как-нибудь галку «Писать лог-файл» и удивиться, сколько работы идёт под капотом. Уже давно несмотрю их в лоб. Каждый модуль имеет свой тэг, по нему и фильтрую. Помогает линуксовый серверный опыт, "tail -f LayoutIndicator.log | grep CaretIndicator" и вот уже в реальном времени можно дивиться удивительной жизнью индикатора каретки. Кто ещё не использует линуксовые утилиты в Windows, люто рекомендую.
Прелопатив основную часть, запустил новую версию на своих настройках и словил жуткие фризы, всё залипало и еле двигалось. Оказалось, из-за поддержки клавиатур Corsair. Попытки подключится к ним, жили в отдельном потоке. Немного помучив нейронку вопросами как бы дождаться подключения и UI не зафризить, по старинке написал колбэк, хоть и очень не хотелось специально для этого менять код.
Достал из сусеков клавиатуру и затестил, всё мигает как раньше, ничего не виснет, во всех кейсах. Там своя атмосфера. Стандартная библиотека реализует работу не с самой клавиатурой а с API сервера для устройств Corsair. Поэтому, много чего может не быть. Сервера, подключения к серверу, подключения клавиатуры к серверу. Не так-то просто мигать подсветкой кнопочек.
Есть, кстати, прекрасная открытая библиотека, которая управляет цветом и поддерживает кучу устройств. Там и мыши и кулеры и материнские платы. Она даже дотнетовская, смотрел код когда писал свою поддержку. Получается можно всё это затащить в Индикатор, но как это тестировать без реального железа — не представляю.
Победив подвисания, начал жить на новой версии и сразу заметил, что индикация чуть запаздывает. Какие-то жалкие миллисекунды, работать можно, но раздражает страшно. Тут же попробовал прошлую версию, подтвердил, что дело в однопотоке. Покопался в обработке очереди на таймер — не помогло. Откатываться на мультитред — не вариант. Пришла идея сделать переключатель планировщика задач из однопоточного режима в многопоточный, таким образом, чтобы не менять код добавления задач. Довольно легко запилил, задержка ушла. Задав командой препроцессора #if DEBUG переключение в сингл-режим, я получил и отладку и скорость прошлых версий. Вот это я называю вин-вин.
Потом правда, выяснилось, что бывают багули, которые вылезают только в потоках и отладить их не получится, но тогда есть знание, что они именно такие, а это уже пол дела.
Дойдя до логического конца с этим режимом, занялся проблемой с которой чаще всего обращались в последнее время — определение раскладки по системному индикатору. Он мистическим образом пропадал с радаров, а где-то и вовсе не находился в известных местах.
К задаче подошёл творчески, спросил что делать у GPT, не давая никаких намёков на пути решения. За много лет, я уже, наверное, знаю все способы получения языка в Windows. Причём, львиную долю пробовал либо реализовывал на практике.
ИИ не обрадовал. Единственный новый способ, который он выдал, внутри, опирался на старый добрый вызов winapi, это первое, что предлагают бедолагам, решившим программно получить текущую раскладку. Но! В дебрях его решения был один нюанс, который не сразу бросился в глаза, а при проверке оказалось, позволяет решить проблему получения разных раскладок внутри одного языка, если способ определения — не системный индикатор.
Без понятия сколько людей на земле используют разные раскладки одного языка. И сколько из них не работают в консольных и UWP-приложениях, чтобы можно было отрубить определялку по системному индикатору. Но на их улице сегодня праздник. Жители ликуют. Боже, чем я занимаюсь... (Смеюсь).
У меня был коварный план — посмотреть предложения от нейронки а потом покапать уже целенаправленно, туда где мне грезилось универсальное решение. Но об этом в следующей заметке сумасшедшего.
Прелопатив основную часть, запустил новую версию на своих настройках и словил жуткие фризы, всё залипало и еле двигалось. Оказалось, из-за поддержки клавиатур Corsair. Попытки подключится к ним, жили в отдельном потоке. Немного помучив нейронку вопросами как бы дождаться подключения и UI не зафризить, по старинке написал колбэк, хоть и очень не хотелось специально для этого менять код.
Достал из сусеков клавиатуру и затестил, всё мигает как раньше, ничего не виснет, во всех кейсах. Там своя атмосфера. Стандартная библиотека реализует работу не с самой клавиатурой а с API сервера для устройств Corsair. Поэтому, много чего может не быть. Сервера, подключения к серверу, подключения клавиатуры к серверу. Не так-то просто мигать подсветкой кнопочек.
Есть, кстати, прекрасная открытая библиотека, которая управляет цветом и поддерживает кучу устройств. Там и мыши и кулеры и материнские платы. Она даже дотнетовская, смотрел код когда писал свою поддержку. Получается можно всё это затащить в Индикатор, но как это тестировать без реального железа — не представляю.
Победив подвисания, начал жить на новой версии и сразу заметил, что индикация чуть запаздывает. Какие-то жалкие миллисекунды, работать можно, но раздражает страшно. Тут же попробовал прошлую версию, подтвердил, что дело в однопотоке. Покопался в обработке очереди на таймер — не помогло. Откатываться на мультитред — не вариант. Пришла идея сделать переключатель планировщика задач из однопоточного режима в многопоточный, таким образом, чтобы не менять код добавления задач. Довольно легко запилил, задержка ушла. Задав командой препроцессора #if DEBUG переключение в сингл-режим, я получил и отладку и скорость прошлых версий. Вот это я называю вин-вин.
Потом правда, выяснилось, что бывают багули, которые вылезают только в потоках и отладить их не получится, но тогда есть знание, что они именно такие, а это уже пол дела.
Дойдя до логического конца с этим режимом, занялся проблемой с которой чаще всего обращались в последнее время — определение раскладки по системному индикатору. Он мистическим образом пропадал с радаров, а где-то и вовсе не находился в известных местах.
К задаче подошёл творчески, спросил что делать у GPT, не давая никаких намёков на пути решения. За много лет, я уже, наверное, знаю все способы получения языка в Windows. Причём, львиную долю пробовал либо реализовывал на практике.
ИИ не обрадовал. Единственный новый способ, который он выдал, внутри, опирался на старый добрый вызов winapi, это первое, что предлагают бедолагам, решившим программно получить текущую раскладку. Но! В дебрях его решения был один нюанс, который не сразу бросился в глаза, а при проверке оказалось, позволяет решить проблему получения разных раскладок внутри одного языка, если способ определения — не системный индикатор.
Без понятия сколько людей на земле используют разные раскладки одного языка. И сколько из них не работают в консольных и UWP-приложениях, чтобы можно было отрубить определялку по системному индикатору. Но на их улице сегодня праздник. Жители ликуют. Боже, чем я занимаюсь... (Смеюсь).
У меня был коварный план — посмотреть предложения от нейронки а потом покапать уже целенаправленно, туда где мне грезилось универсальное решение. Но об этом в следующей заметке сумасшедшего.
👍2
«А что, если получить доступ к памяти индикатора Windows?» — подумал как-то я. Отладчики же умеют, чем мы хуже? Подцепимся к процессу, сдампим память, покопаемся в байтиках. Понимаю, звучит утопически, но вдруг. Выслушав грязные подробности об архитектуре индикации языка, да, там целая архитектура, вкрадчиво поинтересовался у ИИ: «а вот если, допустим, один мой друг, хочет вскрыть память индикации винды и всё от туда узнать про текущую раскладку. Как ему это сделать? Спрашиваю не для себя, сам таким не занимаюсь, конечно же».
Ответ меня обрадовал. Говорит: «вот тебе код, получай дамп, ищи вот эти байты, оно и есть ID раскладки». Заранее радовался не сильно, т.к. опытный заклинатель ИИ. Получив первые дампы для разных раскладок и обнаружив их абсолютную идентичность, спросил, с праведным гневом, где же мой ID раскладки? А там всё по классике: «Да он там вообще не бывает, с чего ты решил тут искать, что, я посоветовал? Извини, бес попутал, то, что тебе нужно вообще невозможно. Хочешь адрес ближайшей психологической помощи, скажи, я напишу».
Сохранив наработочки для будущих обострений, идею отложил.
Как не удивительно, но единственный, более-менее простой, способ, программно узнать текущую раскладку ввода в Windows, во всех классах приложений — воспользоваться технологией, созданной для слепых. Благодаря таким людям, мы можем программно считать с экрана называние языка. На дворе 2025й. Но и тут не всё так просто. Разработчикам майкрософт не занимать творческой энергии и бОльшая её часть расходуются, на перемещение индикатора раскладки внутри компонентов панели задач. Сам лично видел пять-шесть вариантов в разных версиях, плюс пользователи присылали интересные логи.
Изначально, переоценил свои силы: встроил генерацию файла, в случае ошибки, при работе с системным индикатором. Сама мысль верная, но внутрь положил деревья описывающие UI, от самого корня, двумя способами. Только такое количество данных, позволяло вдумчиво написать фильтры получения нужного компонента. Подразумевалось, что человек увидит сообщение с просьбой о помощи и перешлёт файл.
Тут сразу несколько минусов. Во-первых всё это генерировалось довольно долго, сделать видимость процесса поленился, поэтому нужно было подождать, найти файл и отправить его. За всё время существования такой возможности, прошёл этот квест всего один человек, за что ему огромное спасибо.
Конечно, можно было автоматически кинуть инфу на какой-нибудь из своих серверов, но это чистой воды троян. Утечь могло всё что угодно, включая чувствительные данные. Мы такое не делаем.
Во-вторых, задумывалось, что я каждый раз буду внимательно изучать этот дар богов и писать правила поиска в деревьях. Под каждый случай творческого припадка Windows-разработчиков. Жизнь показала, что у меня нет на это времени и сил. Конечно, если бы какой-нибудь очень богатый мужчина или женщина, решили регулярно поддерживать столь экзотическую активность, можно было бы подумать. Но у меня работа, шесть котов, велосипед и лодка.
Поэтому, было принято радикальное решение — снести к чертям все эти городульки и сделать божественно простой алгоритм поиска родного индикатора языка. Поделюсь им с вами: берём дерево элементов таскбара с основного монитора (на нём живёт индикатор), с глубиной потомков 3 (хватает 2, ещё одно поколение заложил на будущее), ищем первый элемент, текст с которого совпадёт с названием любой из раскладок, установленных в системе. Всё.
Ладно, не совсем всё, для некоторых версий десятой Windows, невозможно получить полный текст подсказки элемента, если в нём присутствуют переводы строк (обожаю IT!). Так что за простоту мы заплатили деградацией функционала: на особых версиях десятки, будут неправильно определяться разные раскладки одного языка. Такова жизнь.
Поэтому искать пришлось не только по имени раскладки но и по языку, если по имени не получилось. Закончилось всё хорошо, стабильно нахожу нужный элемент, в всех доступных мне версиях.
Ответ меня обрадовал. Говорит: «вот тебе код, получай дамп, ищи вот эти байты, оно и есть ID раскладки». Заранее радовался не сильно, т.к. опытный заклинатель ИИ. Получив первые дампы для разных раскладок и обнаружив их абсолютную идентичность, спросил, с праведным гневом, где же мой ID раскладки? А там всё по классике: «Да он там вообще не бывает, с чего ты решил тут искать, что, я посоветовал? Извини, бес попутал, то, что тебе нужно вообще невозможно. Хочешь адрес ближайшей психологической помощи, скажи, я напишу».
Сохранив наработочки для будущих обострений, идею отложил.
Как не удивительно, но единственный, более-менее простой, способ, программно узнать текущую раскладку ввода в Windows, во всех классах приложений — воспользоваться технологией, созданной для слепых. Благодаря таким людям, мы можем программно считать с экрана называние языка. На дворе 2025й. Но и тут не всё так просто. Разработчикам майкрософт не занимать творческой энергии и бОльшая её часть расходуются, на перемещение индикатора раскладки внутри компонентов панели задач. Сам лично видел пять-шесть вариантов в разных версиях, плюс пользователи присылали интересные логи.
Изначально, переоценил свои силы: встроил генерацию файла, в случае ошибки, при работе с системным индикатором. Сама мысль верная, но внутрь положил деревья описывающие UI, от самого корня, двумя способами. Только такое количество данных, позволяло вдумчиво написать фильтры получения нужного компонента. Подразумевалось, что человек увидит сообщение с просьбой о помощи и перешлёт файл.
Тут сразу несколько минусов. Во-первых всё это генерировалось довольно долго, сделать видимость процесса поленился, поэтому нужно было подождать, найти файл и отправить его. За всё время существования такой возможности, прошёл этот квест всего один человек, за что ему огромное спасибо.
Конечно, можно было автоматически кинуть инфу на какой-нибудь из своих серверов, но это чистой воды троян. Утечь могло всё что угодно, включая чувствительные данные. Мы такое не делаем.
Во-вторых, задумывалось, что я каждый раз буду внимательно изучать этот дар богов и писать правила поиска в деревьях. Под каждый случай творческого припадка Windows-разработчиков. Жизнь показала, что у меня нет на это времени и сил. Конечно, если бы какой-нибудь очень богатый мужчина или женщина, решили регулярно поддерживать столь экзотическую активность, можно было бы подумать. Но у меня работа, шесть котов, велосипед и лодка.
Поэтому, было принято радикальное решение — снести к чертям все эти городульки и сделать божественно простой алгоритм поиска родного индикатора языка. Поделюсь им с вами: берём дерево элементов таскбара с основного монитора (на нём живёт индикатор), с глубиной потомков 3 (хватает 2, ещё одно поколение заложил на будущее), ищем первый элемент, текст с которого совпадёт с названием любой из раскладок, установленных в системе. Всё.
Ладно, не совсем всё, для некоторых версий десятой Windows, невозможно получить полный текст подсказки элемента, если в нём присутствуют переводы строк (обожаю IT!). Так что за простоту мы заплатили деградацией функционала: на особых версиях десятки, будут неправильно определяться разные раскладки одного языка. Такова жизнь.
Поэтому искать пришлось не только по имени раскладки но и по языку, если по имени не получилось. Закончилось всё хорошо, стабильно нахожу нужный элемент, в всех доступных мне версиях.
🔥2🤯1
Дальше был классический реалити-чек. Элемент есть, а текст его считывается не всегда, примерно, один раз из ста может не считаться, плюс минус двести обращений, это не точно, зависит от частоты попыток, но не всегда. Что ты пристал, скажи спасибо, что он с экрана не пропадает. Хотя, может и пропадает, просто мы не видим — очень быстро восстанавливается, по сверхбыстрому таймеру. Вообще не удивлюсь, если это так.
Отлавливаю эти провалы в логах и вижу рейскондишн, это когда потоки начинают глючить из-за одновременного доступа к общим частям кода. Ставлю лок-блок, это когда ты помечаешь место которое должно выполняться одним потоком, в один момент времени, остальные ждут своей очереди. И чтобы вы думали? Рейскондишн сохраняется. Иду к GPT, он объясняет, что свой код ты конечно обезопасил, молодец, но вот этот вот AutomationElement который ты дёргаешь, он вообще сделан нот сафети мультитред, да и пропадает часто, нет ему никакой веры! И вообще, они когда эту штуку для слабовидящих делали, ни про какую многопоточность не думали.
На опыте делаю сигнл-тред планировщик и оборачиваю им получение элемента. Проблема параллельного кода ушла. Ура. Теперь элемент не отдавал текст уже в одном потоке, изредка. Пришлось всю эту конструкцию украсить повторением проверки. Не получилось с первого раза? Не беда, попробуем ещё раз. И ещё. И только если три раза не вышло, генерим файл с нашим небольшим деревом (на моём таскбаре — 150 строк), в котором минимум информации, только необходимое и слёзно просим прислать. Благо такое можно и мессенжере кинуть.
Попутно разрулил старый баг, который то пропадал то возвращался. Помогло общение с ИИ. Часто менял тред в котором работаю с UI, но уже постфактум, когда всплывали ошибки. А тут он мне популярно объяснил: есть UI-поток, и всё, что касается интерфейса, нужно делать в нём. Красить, менять, скрывать, показывать, просто перемещать, всё в нём. Преисполнившись этим знанием переписал пару мест, багули рассосались.
Как же я долго программировал... Ещё одна прохладная история в следующем посте и спать.
Отлавливаю эти провалы в логах и вижу рейскондишн, это когда потоки начинают глючить из-за одновременного доступа к общим частям кода. Ставлю лок-блок, это когда ты помечаешь место которое должно выполняться одним потоком, в один момент времени, остальные ждут своей очереди. И чтобы вы думали? Рейскондишн сохраняется. Иду к GPT, он объясняет, что свой код ты конечно обезопасил, молодец, но вот этот вот AutomationElement который ты дёргаешь, он вообще сделан нот сафети мультитред, да и пропадает часто, нет ему никакой веры! И вообще, они когда эту штуку для слабовидящих делали, ни про какую многопоточность не думали.
На опыте делаю сигнл-тред планировщик и оборачиваю им получение элемента. Проблема параллельного кода ушла. Ура. Теперь элемент не отдавал текст уже в одном потоке, изредка. Пришлось всю эту конструкцию украсить повторением проверки. Не получилось с первого раза? Не беда, попробуем ещё раз. И ещё. И только если три раза не вышло, генерим файл с нашим небольшим деревом (на моём таскбаре — 150 строк), в котором минимум информации, только необходимое и слёзно просим прислать. Благо такое можно и мессенжере кинуть.
Попутно разрулил старый баг, который то пропадал то возвращался. Помогло общение с ИИ. Часто менял тред в котором работаю с UI, но уже постфактум, когда всплывали ошибки. А тут он мне популярно объяснил: есть UI-поток, и всё, что касается интерфейса, нужно делать в нём. Красить, менять, скрывать, показывать, просто перемещать, всё в нём. Преисполнившись этим знанием переписал пару мест, багули рассосались.
Как же я долго программировал... Ещё одна прохладная история в следующем посте и спать.
❤3
Во время всей этой вакханалии, мне захотелось запустить Индикатор на чистой винде. Для этого пришлось реанимировать VirtualBox. Я давно перешёл на VMWare, он пошустрее, писал прямо там, но в бесплатной версии не дают делать точки восстановления. Сейчас кстати, подумал, что их можно было делать в самой винде, на виртуалке.
Вибокс был такой старый, что там почему-то была прописана несуществующая сетевая карта, поменять которую конечно же просто так нельзя. Я говорил вам что обожаю IT? Под это дело решил обновиться. При установке драйвера USB-монитора, входящего в комплект бокса, Windows потушила два монитора из четырёх и повисла намертво. Обожаю перезагружаться. Дальше ушло какое-то время, чтобы вспомнить — на вибоксе не будет интернета по не установишь гостевые приблуды. Этим он отличается от vmware, поэтому забыл. Хорошо хоть помню, что без этих гостевых штук нельзя подрубить директорию с хоста, пару раз тупил с этим.
Вжух! И у меня чистая винда с пошареной папкой хоста и точкой восстановления. Запускаю программу. В ответ тишина, и даже логов нет. Процесс помирает. Такое поведение сделано для кулхацкеров которые решили обойти мою мега-защиту и кинуть инди-разработчика на бабки. Но это дев-версия, тут ничего такого быть не может. Или может? Диагностика без логов, ммм, заверните две. Оказалось, что ошибка в таком месте, что система логирования ещё не готова там работать, тут моя вина, признаю.
Вляпав старый добрый MessageBox.Show узнаю, что не может загрузиться библиотека для работы со звуком. Всю жизнь работала, а тут вдруг не может. Специально вшил её dll в ресурсы и копирую, самостоятельно. Нет говорят, либо разрядность не та, либо ты не все её dll, от которых она зависит, скопировал. Если работает на другой машине, значит с разрядностью всё ок. Иду в исходники либы и копирую все dll. Ошибка сохраняется. Мне предлагают посмотреть зависимости через специальный софт. С удивлением узнаю, что зависимостей дохрена, как же это работало?
Вообще, в проекте, стоит пакет Costura.Fody который как раз вшивает все зависимости в exe-файл. Но я же недавно перешёл на Rider с VS, может он перестал работать? Сношу, генерю exe, ставлю заново, генерю. Экзешник пухнет, пакет явно работает. Начинаю копать и узнаю, что Fody занимается только .net-зависимостями, всё остальное, будь добр подтяни сам.
Так мне открылась страшная правда — с того момента как в Индикаторе появилась поддержка звука, люди без установленного пакета «Visual C++ Redistributable for Visual Studio 2015–2022», запуская мою программу, не получали ничего кроме разочарования. Ни тебе сообщения об ошибке, ни каких-либо сигналов. Процесс просто умирал. Зная, что редкий юзер будет слать репорты в таких случаях, могу предположить, что было какое-то количество людей, которые просто забили и пошли жить дальше. А может и нет, этот пакет требуется много где, поэтому так долго не видел ошибку. Мы никогда не узнаем.
Требовать установку пакета не стал, получил список недостающих dll и вшил их в exe, руками. Пишу эти строки и понимаю, что официальный релиз лежит с этой багулей, прямо сейчас. Что ж, будет повод не затягивать с новой версией. Такой ценой был приобретён опыт.
У меня всё. Спасибо за внимание.
Вибокс был такой старый, что там почему-то была прописана несуществующая сетевая карта, поменять которую конечно же просто так нельзя. Я говорил вам что обожаю IT? Под это дело решил обновиться. При установке драйвера USB-монитора, входящего в комплект бокса, Windows потушила два монитора из четырёх и повисла намертво. Обожаю перезагружаться. Дальше ушло какое-то время, чтобы вспомнить — на вибоксе не будет интернета по не установишь гостевые приблуды. Этим он отличается от vmware, поэтому забыл. Хорошо хоть помню, что без этих гостевых штук нельзя подрубить директорию с хоста, пару раз тупил с этим.
Вжух! И у меня чистая винда с пошареной папкой хоста и точкой восстановления. Запускаю программу. В ответ тишина, и даже логов нет. Процесс помирает. Такое поведение сделано для кулхацкеров которые решили обойти мою мега-защиту и кинуть инди-разработчика на бабки. Но это дев-версия, тут ничего такого быть не может. Или может? Диагностика без логов, ммм, заверните две. Оказалось, что ошибка в таком месте, что система логирования ещё не готова там работать, тут моя вина, признаю.
Вляпав старый добрый MessageBox.Show узнаю, что не может загрузиться библиотека для работы со звуком. Всю жизнь работала, а тут вдруг не может. Специально вшил её dll в ресурсы и копирую, самостоятельно. Нет говорят, либо разрядность не та, либо ты не все её dll, от которых она зависит, скопировал. Если работает на другой машине, значит с разрядностью всё ок. Иду в исходники либы и копирую все dll. Ошибка сохраняется. Мне предлагают посмотреть зависимости через специальный софт. С удивлением узнаю, что зависимостей дохрена, как же это работало?
Вообще, в проекте, стоит пакет Costura.Fody который как раз вшивает все зависимости в exe-файл. Но я же недавно перешёл на Rider с VS, может он перестал работать? Сношу, генерю exe, ставлю заново, генерю. Экзешник пухнет, пакет явно работает. Начинаю копать и узнаю, что Fody занимается только .net-зависимостями, всё остальное, будь добр подтяни сам.
Так мне открылась страшная правда — с того момента как в Индикаторе появилась поддержка звука, люди без установленного пакета «Visual C++ Redistributable for Visual Studio 2015–2022», запуская мою программу, не получали ничего кроме разочарования. Ни тебе сообщения об ошибке, ни каких-либо сигналов. Процесс просто умирал. Зная, что редкий юзер будет слать репорты в таких случаях, могу предположить, что было какое-то количество людей, которые просто забили и пошли жить дальше. А может и нет, этот пакет требуется много где, поэтому так долго не видел ошибку. Мы никогда не узнаем.
Требовать установку пакета не стал, получил список недостающих dll и вшил их в exe, руками. Пишу эти строки и понимаю, что официальный релиз лежит с этой багулей, прямо сейчас. Что ж, будет повод не затягивать с новой версией. Такой ценой был приобретён опыт.
У меня всё. Спасибо за внимание.
🔥4👍2❤1
Делаю клавиатуру мечты из детского конструктора.
Эксперименты в области клавиатуростроения
Эксперименты в области клавиатуростроения
YouTube
Клавиатура, трекбол и детский конструктор
🔧 АСМР-видео без слов: собираю сплит-клавиатуру с трекболом на подставке из детского конструктора. Всё — своими руками. Получается удобное устройство: можно печатать и управлять курсором
🎧 Звук настоящих нажатий, щелчков, вращения трекбола и деталей конструктора.…
🎧 Звук настоящих нажатий, щелчков, вращения трекбола и деталей конструктора.…
🔥3
Добрался до релиз-кандидата. Замораживаю для новых фич, правлю багули.
Переход с VisualCode на Rider оказался прорывным. Поработал с профилировщиком, очень достойно. Это такая штука, которая показывает, как и где твоё приложение расходует ресурсы.
Тестирование, во время разработки, сводится частому переключению раскладок. В один из таких сеансов, заметил повышенную нагрузку на процессор в некоторых приложениях. Подозрение сразу пало на текстовый курсор (каретку), только у него сильная зависимость от текущего окна.
Поиск координат каретки в Windows — отдельный вид извращения. Есть два известных способа. Первый, быстрый и лёгкий, мгновенно выдаёт результат, но работает не везде. Второй тяжёлый и сложный, может сработать там, где первый не справился. Работает ли он везде? Конечно же нет. Очень много приложений не отдают информацию о своей каретке, не знаю почему, может сами её рисуют, в обход системных средств.
Так и живём, пробуем первый путь, если не сработало, переключаемся на второй. При этом нельзя сделать список приложений, где искать каретку бессмысленно. Потому что, внутри может быть бесконечная сложность интерфейса, когда и где в нём внезапно обнаружится текстовое поле, предсказать невозможно. Приходится постоянно теребить систему, после каждого клика, нажатия клавиши или переключения приложения.
И можно забить, если бы не потребление ресурсов. Максимально универсальным, этот метод делал самостоятельно, просто копаясь в дебрях ОС. Получился такой алгоритм:
1. Берём процесс активного окна. Тут можно кэшировать. Первый раз запоминаем у какого окна какой процесс, все последующие обращения идут в память.
2. Начинаем перебирать все треды процесса. Потому-что получить координаты вторым способом можно только из тредов. А их может быть овердофига. Практика показала, что можно смотреть первые 10, этого достаточно для большинства случаев.
Процессору это тяжело, особенно если каждый раз ничего не находится.
Начал ещё раз копать эту тему и почти сразу обнаружил, что искать имеет смысл только в GUI-потоке, о существовании которого узнал недавно. Это так логично: если для операций с интерфейсом есть специальный поток, то и каретку нужно искать в нём. Имеется специальный метод, чтобы его получить. Плюс он кэшируемый, менять GUI-поток — лютая экзотика, которой можно пренебречь.
Переписал, проверил, нагрузка ушла, полегчало значительно. Сколько же лишних тактов моё детище сожрало по всему миру? Иран, Венгрия, Россия-матушка... пожрал электричество почём зря. Такова цена опыта.
Ещё, в арсенале для разработки Индикатора, есть стресс-тест: цикл на 4000 операций. В каждой запрашиваем раскладку и мигаем всеми индикаторами. Давно не пускал, а тут удача — удалось воспроизвести очень редкий баг с переполнением GDI объектов. Оказалось, при смене иконки приложения в системном лотке, нужно обязательно вызывать метод ОС для чистки памяти. Поправил.
В процессе изменений, поймал ошибку — не все индикаторы совпадали. Например, на экране одна раскладка, возле курсора другая. У этого явления интересная природа, причина которой опять упирается в нестабильность методов ОС. Есть стандартный способ подписаться на событие «смена языка ввода», угадайте, работает ли это всегда и везде?
Поэтому приходится полагаться на целую группу событий, если хоть одно произошло, возможно, сменится раскладка. Мой минимальный список:
1. Нажатие клавиш. Тут всё понятно, просто переключили язык, аль-табнулись в приложение, где он другой.
2. Клик. Могут выбрать язык через системный индикатор, либо переключить приложение.
3. Переключение приложений. Это может случится без нажатия на клавиши и кликов. Например, всплытие модального окна или тупо перехват фокуса.
Переход с VisualCode на Rider оказался прорывным. Поработал с профилировщиком, очень достойно. Это такая штука, которая показывает, как и где твоё приложение расходует ресурсы.
Тестирование, во время разработки, сводится частому переключению раскладок. В один из таких сеансов, заметил повышенную нагрузку на процессор в некоторых приложениях. Подозрение сразу пало на текстовый курсор (каретку), только у него сильная зависимость от текущего окна.
Поиск координат каретки в Windows — отдельный вид извращения. Есть два известных способа. Первый, быстрый и лёгкий, мгновенно выдаёт результат, но работает не везде. Второй тяжёлый и сложный, может сработать там, где первый не справился. Работает ли он везде? Конечно же нет. Очень много приложений не отдают информацию о своей каретке, не знаю почему, может сами её рисуют, в обход системных средств.
Так и живём, пробуем первый путь, если не сработало, переключаемся на второй. При этом нельзя сделать список приложений, где искать каретку бессмысленно. Потому что, внутри может быть бесконечная сложность интерфейса, когда и где в нём внезапно обнаружится текстовое поле, предсказать невозможно. Приходится постоянно теребить систему, после каждого клика, нажатия клавиши или переключения приложения.
И можно забить, если бы не потребление ресурсов. Максимально универсальным, этот метод делал самостоятельно, просто копаясь в дебрях ОС. Получился такой алгоритм:
1. Берём процесс активного окна. Тут можно кэшировать. Первый раз запоминаем у какого окна какой процесс, все последующие обращения идут в память.
2. Начинаем перебирать все треды процесса. Потому-что получить координаты вторым способом можно только из тредов. А их может быть овердофига. Практика показала, что можно смотреть первые 10, этого достаточно для большинства случаев.
Процессору это тяжело, особенно если каждый раз ничего не находится.
Начал ещё раз копать эту тему и почти сразу обнаружил, что искать имеет смысл только в GUI-потоке, о существовании которого узнал недавно. Это так логично: если для операций с интерфейсом есть специальный поток, то и каретку нужно искать в нём. Имеется специальный метод, чтобы его получить. Плюс он кэшируемый, менять GUI-поток — лютая экзотика, которой можно пренебречь.
Переписал, проверил, нагрузка ушла, полегчало значительно. Сколько же лишних тактов моё детище сожрало по всему миру? Иран, Венгрия, Россия-матушка... пожрал электричество почём зря. Такова цена опыта.
Ещё, в арсенале для разработки Индикатора, есть стресс-тест: цикл на 4000 операций. В каждой запрашиваем раскладку и мигаем всеми индикаторами. Давно не пускал, а тут удача — удалось воспроизвести очень редкий баг с переполнением GDI объектов. Оказалось, при смене иконки приложения в системном лотке, нужно обязательно вызывать метод ОС для чистки памяти. Поправил.
В процессе изменений, поймал ошибку — не все индикаторы совпадали. Например, на экране одна раскладка, возле курсора другая. У этого явления интересная природа, причина которой опять упирается в нестабильность методов ОС. Есть стандартный способ подписаться на событие «смена языка ввода», угадайте, работает ли это всегда и везде?
Поэтому приходится полагаться на целую группу событий, если хоть одно произошло, возможно, сменится раскладка. Мой минимальный список:
1. Нажатие клавиш. Тут всё понятно, просто переключили язык, аль-табнулись в приложение, где он другой.
2. Клик. Могут выбрать язык через системный индикатор, либо переключить приложение.
3. Переключение приложений. Это может случится без нажатия на клавиши и кликов. Например, всплытие модального окна или тупо перехват фокуса.
👍2🔥2🤯1
Если проверять раскладку после этих событий, вы гарантировано отловите момент переключения. Можно разгрузить систему и поставить проверку только по клавишам – есть в настройках, сам использую такой способ.
И всё было бы просто, если не один нюанс — переключение раскладки не мгновенная операция. Если вы кликнете в системном индикаторе на новый язык, то в обработчике клика, он будет старым, проверять нужно, примерно, через 100 миллисекунд. Тайминги зависят от нагрузки и конфигурации компьютера.
Вот и получается, что где-то изменение не обработалось, показали не то, а новая проверка не сгенерирует событие «язык поменяли», он такой же.
Хорошая новость — такое решается архитектурно. Каждому индикатору положил внутрь объект «состояние индикации», теперь все они знают, какое состояние показали последний раз. Синхронизация упростилась. Теперь если и лажанёмся, то все вместе 😁.
Так же было замечено, что не все звуки для переключения раскладки работали. Оказалось, звуковой библиотеке не нравятся некоторые параметры сэмплов. Быстро перекодировал и исправил, благо их было всего три. Пока возился, услышал неприятный щелчок в конце уханья совы. На спектрограмме его не было видно. Дело оказалось в каких-то фреймах и прочей мути аудиокодирования, спасибо ИИ, подсказала, что можно залечить небольшим фейдом. Самое главное исправление в этой версии — убран неприятный щелчок в звуке для переключения «Сова» 😁.
Изменения в 3.0.7
✅ Добавлена кнопка настройки языков Windows (вкладка Dev)
✅ Улучшены алгоритмы индикации и синхронизации раскладок
✅ В taskbar_tree.json добавлены установленные раскладки
✅ Переработаны алгоритмы, отвечающие за индикацию раскладок
🛠 (исправление) Исправлена ошибка GDI+
🛠 (исправление) Снижена нагрузка на CPU при поиске каретки
🛠 (исправление) Исправлены параметры аудиофайлов (не все звуки проигрывались)
🛠 (исправление) Убран щелчок в конце звука «Сова»
Индикатор 3.0.7
https://khsoft.ru/download/test/LayoutIndicatorSetup.v3.0.7.test.zip
И всё было бы просто, если не один нюанс — переключение раскладки не мгновенная операция. Если вы кликнете в системном индикаторе на новый язык, то в обработчике клика, он будет старым, проверять нужно, примерно, через 100 миллисекунд. Тайминги зависят от нагрузки и конфигурации компьютера.
Вот и получается, что где-то изменение не обработалось, показали не то, а новая проверка не сгенерирует событие «язык поменяли», он такой же.
Хорошая новость — такое решается архитектурно. Каждому индикатору положил внутрь объект «состояние индикации», теперь все они знают, какое состояние показали последний раз. Синхронизация упростилась. Теперь если и лажанёмся, то все вместе 😁.
Так же было замечено, что не все звуки для переключения раскладки работали. Оказалось, звуковой библиотеке не нравятся некоторые параметры сэмплов. Быстро перекодировал и исправил, благо их было всего три. Пока возился, услышал неприятный щелчок в конце уханья совы. На спектрограмме его не было видно. Дело оказалось в каких-то фреймах и прочей мути аудиокодирования, спасибо ИИ, подсказала, что можно залечить небольшим фейдом. Самое главное исправление в этой версии — убран неприятный щелчок в звуке для переключения «Сова» 😁.
Изменения в 3.0.7
✅ Добавлена кнопка настройки языков Windows (вкладка Dev)
✅ Улучшены алгоритмы индикации и синхронизации раскладок
✅ В taskbar_tree.json добавлены установленные раскладки
✅ Переработаны алгоритмы, отвечающие за индикацию раскладок
🛠 (исправление) Исправлена ошибка GDI+
🛠 (исправление) Снижена нагрузка на CPU при поиске каретки
🛠 (исправление) Исправлены параметры аудиофайлов (не все звуки проигрывались)
🛠 (исправление) Убран щелчок в конце звука «Сова»
Индикатор 3.0.7
https://khsoft.ru/download/test/LayoutIndicatorSetup.v3.0.7.test.zip
❤8
Релиз Индикатора. Версия 3.0.8
Спасибо всем, кто качал тестовую сборку. Сам тоже проверил, до чего успел добрался.
Отправляю в свободное плавание. По статистике сайта, кучка роботов проверяет номер версии каждый день. После релиза всегда всплеск скачиваний. Мне представляется группа людей, качающих Индикатор, приговаривая: «ну что, может хоть в этой версии он всё починил» 😁.
Получилось довольно плотное обновление. Доволен. Но это пока не полетели баг-репорты 😁 — бывали у меня релизы-провалы.
Если у вас уже стоит 3.0.7 (тестовая), можете не спешить с обновлением: основные отличия — в доработке интерфейса, было криво при масштабировании, в паре мест.
Из 25 изменений, ИИ выделил 6 самых значимых:
* Обновлён пользовательский интерфейс
* Индикатор положения каретки теперь можно перемещать с помощью мыши
* Улучшен алгоритм определения раскладки по системному индикатору — стал быстрее и надёжнее
* Повышена точность индикации и синхронизации языковых раскладок
* Оптимизирован поиск каретки — снижена нагрузка на процессор
* Исправлен сбой при отключении отображения флагов — работа программы больше не прерывается
Сайт программы: https://khsoft.ru/li
Всем чёткой индикации!
Спасибо всем, кто качал тестовую сборку. Сам тоже проверил, до чего успел добрался.
Отправляю в свободное плавание. По статистике сайта, кучка роботов проверяет номер версии каждый день. После релиза всегда всплеск скачиваний. Мне представляется группа людей, качающих Индикатор, приговаривая: «ну что, может хоть в этой версии он всё починил» 😁.
Получилось довольно плотное обновление. Доволен. Но это пока не полетели баг-репорты 😁 — бывали у меня релизы-провалы.
Если у вас уже стоит 3.0.7 (тестовая), можете не спешить с обновлением: основные отличия — в доработке интерфейса, было криво при масштабировании, в паре мест.
Из 25 изменений, ИИ выделил 6 самых значимых:
* Обновлён пользовательский интерфейс
* Индикатор положения каретки теперь можно перемещать с помощью мыши
* Улучшен алгоритм определения раскладки по системному индикатору — стал быстрее и надёжнее
* Повышена точность индикации и синхронизации языковых раскладок
* Оптимизирован поиск каретки — снижена нагрузка на процессор
* Исправлен сбой при отключении отображения флагов — работа программы больше не прерывается
Сайт программы: https://khsoft.ru/li
Всем чёткой индикации!
❤6
По наводке из чата, добавил индикатор на alternativeto.net
Не знал о существовании этого сайта, а он оказался полезным.
Нашёл пару неизвестных мне программ, может что-то войдёт в будничный инструментарий.
Буду благодарен если лайкните или свяжите с другим софтом. Там очень разнообразно можно помочь приложению.
Не знал о существовании этого сайта, а он оказался полезным.
Нашёл пару неизвестных мне программ, может что-то войдёт в будничный инструментарий.
Буду благодарен если лайкните или свяжите с другим софтом. Там очень разнообразно можно помочь приложению.
Делал недавно спецверсию Индикатора — без требования админских прав. Уже не помню, что стало первой причиной, по которой пришлось повышать права, но потом, без них, Windows просто не отдавала координаты мыши, если приложение запущено под админом, а Индикатор нет.
Это было забавно, получить нажатые клавиши, из админского приложения, можно, а координаты мыши ни-ни, они же важнее 🤭. Что, приложение с правами юзера может смотреть, что напечатали в админском? Но зато никто не узнает, какие там были траектории мыши!
При сборке в Rider заметил: всё работает и без прав. Посмотрел мышиный индикатор — работает! То ли Rider как-то влияет, то ли Windows поменялась, проверять глубже лень.
А тут пользователь попросил спецверсию под последний релиз. Пошёл разбираться — оказалось, права требовал не сам Индикатор, а установщик, который я изначально так настроил. Чтобы сразу дать понять — права нужны и без них ничего не получится. В противном случае, можно было прокликать установку и в конце получить квест на чистку компьютера от бесполезного мусора.
Поменял дистрибутив. Теперь, по умолчанию, скачивается версия без прав администратора. Самый худший исход такого решения — отказ работы мышиного индикатора в приложениях, запущенных под админом, в старых версиях Windows.
Это было забавно, получить нажатые клавиши, из админского приложения, можно, а координаты мыши ни-ни, они же важнее 🤭. Что, приложение с правами юзера может смотреть, что напечатали в админском? Но зато никто не узнает, какие там были траектории мыши!
При сборке в Rider заметил: всё работает и без прав. Посмотрел мышиный индикатор — работает! То ли Rider как-то влияет, то ли Windows поменялась, проверять глубже лень.
А тут пользователь попросил спецверсию под последний релиз. Пошёл разбираться — оказалось, права требовал не сам Индикатор, а установщик, который я изначально так настроил. Чтобы сразу дать понять — права нужны и без них ничего не получится. В противном случае, можно было прокликать установку и в конце получить квест на чистку компьютера от бесполезного мусора.
Поменял дистрибутив. Теперь, по умолчанию, скачивается версия без прав администратора. Самый худший исход такого решения — отказ работы мышиного индикатора в приложениях, запущенных под админом, в старых версиях Windows.
🔥3👍1
Первая, послерелизная, жатва собрана. Как всегда много нового и удивительного. За время разработки Индикатора, узнал столько, что пользуйся я им в одно лицо, даже и помыслить бы не смог, что такое бывает.
Открытие первое — существует целый класс программ, которые подменяют стандартные UI Windows. Не просто рейстайлят их, прикручивая свистоперделки, а прямо заменяют на свои, чтобы ничего не ограничивало свободу творчества. Понимаю и одобряю. Тут мне помог новый подход обработки системного индикатора. Не полагаться на место элемента в иерархии и его параметры — было правильным решением. И всё бы заработало, если бы не смена элемента. Оказалось, при работе таких программ, нельзя кэшировать индикатор, нужно каждый раз его находить. Благо это не так затратно.
А кэшировать нельзя, потому что происходит какая-то чёрная магия — они связывают свои элементы с родными, через особый механизм, при этом мой объект, связанный с системным, до них, перестаёт быть валидным, но остаётся живым. Мрак.
Тупо ищу каждый раз и не забиваю голову. Похоже, нечто подобное случается при впадании компьютера в спячку, потому что этот фикс поправил багулю с выходом из сна.
Сам бы я, конечно, ничего этого не поймал. Не выключаю компьютер и не юзаю спящий ражим уже много лет.
Открытие второе — настойчивая перерисовка некоторых индикаторов нужна. После введения состояний, таскбары начали красится только когда меняется раскладка. Но, похоже, их нужно перекрашивать по таймеру, т.к. все норовят их перекрыть. Буду надеяться, что это поможет.
На альтернативо никто даже лайка не поставил! Поддержите независимого разработчика лайком, что вам стоит?
Изменения (3.1.0)
🛠 (исправление) Добавил поддержку индикаторов таскбара, они пропадали
🛠 (исправление) Не считывалось состояние системного индикатора, если были запущены программы, подменяющие стандартные компоненты Windows
https://khsoft.ru/download/test/LayoutIndicator.v3.1.0.test.zip
Открытие первое — существует целый класс программ, которые подменяют стандартные UI Windows. Не просто рейстайлят их, прикручивая свистоперделки, а прямо заменяют на свои, чтобы ничего не ограничивало свободу творчества. Понимаю и одобряю. Тут мне помог новый подход обработки системного индикатора. Не полагаться на место элемента в иерархии и его параметры — было правильным решением. И всё бы заработало, если бы не смена элемента. Оказалось, при работе таких программ, нельзя кэшировать индикатор, нужно каждый раз его находить. Благо это не так затратно.
А кэшировать нельзя, потому что происходит какая-то чёрная магия — они связывают свои элементы с родными, через особый механизм, при этом мой объект, связанный с системным, до них, перестаёт быть валидным, но остаётся живым. Мрак.
Тупо ищу каждый раз и не забиваю голову. Похоже, нечто подобное случается при впадании компьютера в спячку, потому что этот фикс поправил багулю с выходом из сна.
Сам бы я, конечно, ничего этого не поймал. Не выключаю компьютер и не юзаю спящий ражим уже много лет.
Открытие второе — настойчивая перерисовка некоторых индикаторов нужна. После введения состояний, таскбары начали красится только когда меняется раскладка. Но, похоже, их нужно перекрашивать по таймеру, т.к. все норовят их перекрыть. Буду надеяться, что это поможет.
На альтернативо никто даже лайка не поставил! Поддержите независимого разработчика лайком, что вам стоит?
Изменения (3.1.0)
🛠 (исправление) Добавил поддержку индикаторов таскбара, они пропадали
🛠 (исправление) Не считывалось состояние системного индикатора, если были запущены программы, подменяющие стандартные компоненты Windows
https://khsoft.ru/download/test/LayoutIndicator.v3.1.0.test.zip
👍6
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5😁1
Релиз 3.1.3
Кодовое имя «Судорожный». Слишком много критичных багов в прошлом выпуске.
Девлог в следующем посте.
Изменения
✅ Уменьшена нагрузка на процессор при получении раскладки по системному индикатору
✅ Повышена стабильность при работе с системным индикатором
🛠 (исправление) Добавил дополнительную проверку индикаторов таскбара, они пропадали
🛠 (исправление) Не считывалось состояние системного индикатора, если были запущены программы, подменяющие стандартные компоненты Windows
🛠 (исправление) Устранена утечка памяти, при определении раскладки по системному индикатору в Windows 11
🛠 (исправление) Программа опять начнёт требовать права администратора, т.к. это необходимо для её работы на некоторых конфигурация Windows
https://khsoft.ru/li/
Кодовое имя «Судорожный». Слишком много критичных багов в прошлом выпуске.
Девлог в следующем посте.
Изменения
✅ Уменьшена нагрузка на процессор при получении раскладки по системному индикатору
✅ Повышена стабильность при работе с системным индикатором
🛠 (исправление) Добавил дополнительную проверку индикаторов таскбара, они пропадали
🛠 (исправление) Не считывалось состояние системного индикатора, если были запущены программы, подменяющие стандартные компоненты Windows
🛠 (исправление) Устранена утечка памяти, при определении раскладки по системному индикатору в Windows 11
🛠 (исправление) Программа опять начнёт требовать права администратора, т.к. это необходимо для её работы на некоторых конфигурация Windows
https://khsoft.ru/li/
👍5
3.2.3 — тестовая
Я смог. Добрался до любимого индикатора.
Меня закидали письмами о багах. У большинства одна природа — вязнем в дебрях элементов управления ОС, при поиске системного индикатора языка. А без него получать точное значение раскладки мы не умеем.
За одно хороший повод пощупать codex от openAi. Мне, кстати, он понравился. Пока бесплатный и в лимит токенов пока не упирался.
А теперь о том, что удалось сделать.
Я предусмотрительно встроил функцию сохранения дерева UI виндовс в файл, при ошибке поиска. И мне уже наприсылали (спасибо всем большое) неплохую коллекцию. Вдумчиво её изучив, я понял три вещи:
1. В зависимости от версии виндовс, набора пользовательских программ (меняющих UI ОС), настроек ОС и фазы луны — индикатор может менять своё местоположение.
2. У некоторых в таскбаре целая вселенная, перебирать которую каждый раз накладно. Функция обхода UI-дерева дорогая.
3. Системный индикатор может исчезнуть вовсе (например, когда нажимаем win+tab) но потом появится и это обычное положение дел.
Обдумав всё это, полностью переделал взаимодействие с ним.
Теперь, сообщение, о том что системный индикатор не найден, с просьбой прислать файл, будет появляться только при первом запуске программы, где мы определяем, включать соответствующую настройку или нет и при ручном включении этой самой настройки.
Всё остальное время, если эту опцию удалось включить, мы будем раз в секунду поглядывать на системный индикатор и находить его в дебрях UI. Если поиск не удался, молча определяем раскладку старым-кривым методом, и так до следующей проверки.
Что это не отнимало кучу ресурсов довёл до ума кэширование и жёстко задал, что следующий поиск не начнётся пока не закончится предыдущий. Всё это в фоновом режиме.
Так же уделил внимание курсорному индикатору. Он у меня пару раз просто пропадал, это удавалось лечить двойным нажатием win+d, из чего я сделал вывод, что формы слетали спец. настройки, запрещающие ей сворачиваться. Добавил автоматическую установку этих свойств по таймеру.
За всё время разработки индикатора, в этот таймер для поддержания жизни уже добавилось куча всего. Такое ощущение, что программа работает в жутко агрессивной среде и вынуждена постоянно чекать своё состояние и восстанавливать себя то там то сям.
Ну и мая любимая доработка доработка за сегодня - ускорение загрузки. Это старый тех. долг.
Когда у программы было 5 настроек (боже, всего пять) я тупо сохранял их при каждом изменении контролов и загружал сразу выставляя на форме. Потом они продолжили добавляться и усложняться, появились настройки влияющие на другие настройки. И вот, когда ты выставляешь значение элементов на форме, они трогают другие элементы, те трогают ещё и всё это каждый раз дёргало метод обновления всех настроек вообще.
Особенно эта бесполезная работа проявлялась при загрузке программы. Каждый раз, мысленно подходя к решению, спотыкался о то, что не хочу ходить по всем методам обработки настроек, надо придумать что-то хитрое и быстрое. Только это хитрое не придумывалось годами. А когда ИИ показал особо жёсткие места, исправление которых дало бы максимальный эффект, оказалось, что обойти всё это добро не так уж и долго.
Испытал удовольствие.
Всем кто поставит эту тестовую — большое спасибо!
Изменения
✅ Улучшено определение раскладки по системному индикатору. Программа теперть нормально обрабатывает ситуации когда он пропадает, например, на экране приложений (win+tab). Само определение стало быстрее, потребляет меньше ресурсов
✅ Повышена стабильность формы мышиного индикатора. В определённый ситуациях, он начинал сворачиваться как обычные окна.
🛠 (исправление) Увеличена скорость запуска программы
https://khsoft.ru/download/test/LayoutIndicator.v3.2.3.test.zip
Я смог. Добрался до любимого индикатора.
Меня закидали письмами о багах. У большинства одна природа — вязнем в дебрях элементов управления ОС, при поиске системного индикатора языка. А без него получать точное значение раскладки мы не умеем.
За одно хороший повод пощупать codex от openAi. Мне, кстати, он понравился. Пока бесплатный и в лимит токенов пока не упирался.
А теперь о том, что удалось сделать.
Я предусмотрительно встроил функцию сохранения дерева UI виндовс в файл, при ошибке поиска. И мне уже наприсылали (спасибо всем большое) неплохую коллекцию. Вдумчиво её изучив, я понял три вещи:
1. В зависимости от версии виндовс, набора пользовательских программ (меняющих UI ОС), настроек ОС и фазы луны — индикатор может менять своё местоположение.
2. У некоторых в таскбаре целая вселенная, перебирать которую каждый раз накладно. Функция обхода UI-дерева дорогая.
3. Системный индикатор может исчезнуть вовсе (например, когда нажимаем win+tab) но потом появится и это обычное положение дел.
Обдумав всё это, полностью переделал взаимодействие с ним.
Теперь, сообщение, о том что системный индикатор не найден, с просьбой прислать файл, будет появляться только при первом запуске программы, где мы определяем, включать соответствующую настройку или нет и при ручном включении этой самой настройки.
Всё остальное время, если эту опцию удалось включить, мы будем раз в секунду поглядывать на системный индикатор и находить его в дебрях UI. Если поиск не удался, молча определяем раскладку старым-кривым методом, и так до следующей проверки.
Что это не отнимало кучу ресурсов довёл до ума кэширование и жёстко задал, что следующий поиск не начнётся пока не закончится предыдущий. Всё это в фоновом режиме.
Так же уделил внимание курсорному индикатору. Он у меня пару раз просто пропадал, это удавалось лечить двойным нажатием win+d, из чего я сделал вывод, что формы слетали спец. настройки, запрещающие ей сворачиваться. Добавил автоматическую установку этих свойств по таймеру.
За всё время разработки индикатора, в этот таймер для поддержания жизни уже добавилось куча всего. Такое ощущение, что программа работает в жутко агрессивной среде и вынуждена постоянно чекать своё состояние и восстанавливать себя то там то сям.
Ну и мая любимая доработка доработка за сегодня - ускорение загрузки. Это старый тех. долг.
Когда у программы было 5 настроек (боже, всего пять) я тупо сохранял их при каждом изменении контролов и загружал сразу выставляя на форме. Потом они продолжили добавляться и усложняться, появились настройки влияющие на другие настройки. И вот, когда ты выставляешь значение элементов на форме, они трогают другие элементы, те трогают ещё и всё это каждый раз дёргало метод обновления всех настроек вообще.
Особенно эта бесполезная работа проявлялась при загрузке программы. Каждый раз, мысленно подходя к решению, спотыкался о то, что не хочу ходить по всем методам обработки настроек, надо придумать что-то хитрое и быстрое. Только это хитрое не придумывалось годами. А когда ИИ показал особо жёсткие места, исправление которых дало бы максимальный эффект, оказалось, что обойти всё это добро не так уж и долго.
Испытал удовольствие.
Всем кто поставит эту тестовую — большое спасибо!
Изменения
✅ Улучшено определение раскладки по системному индикатору. Программа теперть нормально обрабатывает ситуации когда он пропадает, например, на экране приложений (win+tab). Само определение стало быстрее, потребляет меньше ресурсов
✅ Повышена стабильность формы мышиного индикатора. В определённый ситуациях, он начинал сворачиваться как обычные окна.
🛠 (исправление) Увеличена скорость запуска программы
https://khsoft.ru/download/test/LayoutIndicator.v3.2.3.test.zip
👍4
Случайно обнаружил, что 11я виндовс кэширует не только имена элементов UIAuto но и сами эти элементы. Десятка такого себе не позволяет. Пришлось ужесточать валидацию кэша в зависимости от версии ОС.
Новая сборка: https://khsoft.ru/download/test/LayoutIndicator.v3.2.4.test.zip
Новая сборка: https://khsoft.ru/download/test/LayoutIndicator.v3.2.4.test.zip
👍1🤯1
Виндовс и системный индикатор языка
Внезапно сделал большие изменения в алгоритме поиска системного индикатора. Не перестаю удивляться на какие ухищрения нужно идти, чтобы просто узнать какой язык ввода сейчас активный.
Напомню вкратце. Брать язык как пишут во всех мануалах, через 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-го уровня берём первый элемент и его пятый потомок это наш индикатор.
Получается такой нехитрый набор координат, который на порядки ускоряет поиск и устойчив к изменениям в структуре.
Внезапно сделал большие изменения в алгоритме поиска системного индикатора. Не перестаю удивляться на какие ухищрения нужно идти, чтобы просто узнать какой язык ввода сейчас активный.
Напомню вкратце. Брать язык как пишут во всех мануалах, через 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
Всем кто тестирует — большое спасибо!
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
Исправил считай в слепую, на виртуалке эта функция ОС не работает, перезагружать для тестов рабочую машину нет возможности.
Плюс закрыл пару минорных багов которые раздражали.
🛠 (исправление) Крах после гибернации
🛠 (исправление) Не всегда отображалась иконка программы после запуска
🛠 (исправление) Поиск системного индикатора в Windows 11 не всегда смотрел кэшированный путь
🛠 (исправление) Не верно отображалась раскладка сразу после старта
https://khsoft.ru/download/test/LayoutIndicator.v3.2.7.test.zip
👍4❤1