LINUX.ORG.RU

Рассинхронизация нажимаемых кнопок от ситуации на экране, синхронный клавиатурный ввод

 , ,


0

1

Заголовок покороче придумать не смог.

При работе в консоли, обычно (но, к сожалению, не всегда), можно набирать заранее весь нужный клавиатурный ввод, а софт его сам, когда надо, прочитает и обработает. К слову, в ДОСе это работало ещё чаще чем в консоли современных юниксов, но там был маленький буфер ввода всего на 16 (или 32, не помню) нажатий.

В гуи ситуация обычно кардинально другая. Вот представим, я хочу запустить терминал, запустить в нём файрфокс и открыть в этом файрфоксе какой-то урл (благо фф при запуске ставит фокус на адресную строку, иначе было бы совсем печально). Тут надо:

1) нажать хоткей (или у кого-то кнопку) запуска терминала

2) подождать пока он запустится

3) набрать в нём команду и энтер

4) подождать пока запустится фф

5) набрать в нём адрес и энтер

Если не уделить должного внимания пунктам 2 и 4, ничего хорошего не получится. Хуже того, начавшее появляться окно фф не означает что 4 пункт сделан, надо ждать пока появится курсор в адресной строке.

Я понимаю, конкретно указанное действие можно реализовать иначе, вообще без терминала и с передачей урла в аргументе, но речь не про это, а про саму концепцию взаимодействия с гуи. И ещё, речь не про скорость работы компа (на достаточно быстром компе пункты 2 и 4 станут незаметно быстрыми, но проблема не в том, что они долгие, а в том что они вообще существуют).

Неужели никто не пытался это исправить? Есть ли какие-то общеупотребительные подходы?

В терминалах кстати это тоже бывает, некоторый софт сжирает весь текущий stdin без намерения его как-то обрабатывать, но пожалуй это другая тема.

★★★★★

А зачем тебе это зачем? Не для очередного rust-зловреда?

Это же не гибко, долго нужно отлаживать, а демон еще и будет постоянно жрать лишние ресурсы.

Вообще напоминает типовую тулзу для автотестов окружения (selenium, squish, ldtp, pywinauto, etc...).

Повторюсь, какой смысл использования подобных «бегемотов» в повседневности?

hargard ★★★
()
Ответ на: комментарий от hargard

Эм, какой демон, какая тулза? Я никакой конкретной реализации не заявлял, только описал проблему - невозможность работать с гуи софтом без пристального вглядывания в монитор и ожидания пока оно ответит на очередное нажатие, чтобы нажать что-то следующее. Неужели никого кроме меня это не раздражает?

Ещё пример, замечал в том же фф много раз с адресной строкой: ввожу туда что-то жму энтер, смотрю на экран и вижу что вместо нужного там открылась какая-то чушь - либо оно сожрало начало набранной строки (адресная строка не успела активироваться от клика мышкой до ввода с клавы), либо оно сожрало конец набранной строки (я так и не понял из-за чего такое может происходить, последние символы куда-то в /dev/null отправились а энтер оно заметило успешно, подозреваю что это лаг во время открывания выпадающего меню подсказок), либо вообще, из-за того что мышка стояла в каком-то (не)удачном месте (но я на неё не нажимал) - открылось какое-нить about:preferences.

firkax ★★★★★
() автор топика
Ответ на: комментарий от EAT_INSIDE

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

firkax ★★★★★
() автор топика
Последнее исправление: firkax (всего исправлений: 1)
Ответ на: комментарий от EAT_INSIDE

я вообще-то говорил, что такое реализовать никто не будет (геморно).

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

замечательная идея (правда же?) только в реальности всё это устроено несколько иначе

anonymous
()
Ответ на: комментарий от anonymous

Не, не «кто-то создаёт», а именно юзер нажимает на клавиатуре всё это. Суть именно в том чтобы комп как-то определял, кому юзер предназначал эти нажатия. Логически это вполне возможно: если ты запустил, условно, терминал, а потом вводишь какие-то буквы - то они по идее предназначаются терминалу. То есть система должна этот ввод запомнить и отдать терминалу когда тот соизволит проверить входящие события.

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

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

Да, в текущей идеологии (когда обработчик кнопки запуска терминала совершенно не знает о том, что такое терминал, что этот терминал создаст в итоге окно) заранее понять что ввод надо запомнить невозможно. Если же все обработчики оконных/запускательных операций будут знать, к каким последствиям в плане окон будет приводить их срабатывание - предусмотреть это всё по-моему уже можно.

firkax ★★★★★
() автор топика
Ответ на: комментарий от firkax

Или, например, так: любая запускаемая гуи-прога по умолчанию подразумевается желающей создать окно, но она, когда прогрузилась, может отправить иксам сообщение «нет, окно я создавать не буду, шли всё накопленное куда слал бы без меня». Как отличать гуи от не гуи - другой вопрос, ведь какой-нить /bin/sh точно никому ничего слать не будет.

firkax ★★★★★
() автор топика
Последнее исправление: firkax (всего исправлений: 1)
Ответ на: комментарий от firkax

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

Ну, это не особенность именно gui, а любых интерактивных интерфейсов. Только в gui приложениях действия обычно сложнее и там меньше уделяют внимание удобству их автоматизации, а писатели cli обычно сразу думают и про применимость их творений в скриптах.

Проблеме несколько десятков лет и раздражаться попусту вредно для здоровья, со стороны она не решается. Что еще важнее, автоматизация действий пользователя в интерактивных приложениях за пределами тестирования нужна там, где пользователю изначально не предоставили подходящий способ автоматизации или взаимодействия с приложением. Раздражают ситуации, когда проблема, по хорошему, решалась бы простой командой или нужна автоматизация, а приходится вынужденно пробиваться через интерактивность и гуёвые страдания. Типа написания скриптов с expect-ом, использования burp при работе с web приложением, перекидывания скриншотов друг другу в попытках объяснить кому-нибудь, куда ему надо тыкнуть и что выставить.

altwazar ★★★★★
()

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

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

vbr ★★★★★
()
Последнее исправление: vbr (всего исправлений: 1)
Ответ на: комментарий от altwazar

Ты пишешь про автоматизацию, а тема совершенно не про неё.

а писатели cli обычно сразу думают и про применимость их творений в скриптах.

И опять нет, дело не в этом. Старые версии mc этой проблемы почти лишены, но mc точно никто не адаптировал к использованию в скриптах. Пример: допустим у тебя медленный диск и много файлов в директориях, что их списки долго считываются, или это удалённая сессия через лагающий канал, что все твои нажатия группируются по 20 секунд и приходят пачками. Так вот, там можно нажать что-то типа pgdn,up,up,enter,down,down,enter,end,up,up,enter,«grep -F qq x.log > zzz.log»,enter,end,f3 а потом ждать наблюдать пару минут пока он пройдёт по указанному пути, сделает grep и откроет просмотрщик на этот файл.

firkax ★★★★★
() автор топика
Последнее исправление: firkax (всего исправлений: 1)
Ответ на: комментарий от vbr

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

Я специально сразу в теме написал:

И ещё, речь не про скорость работы компа (на достаточно быстром компе пункты 2 и 4 станут незаметно быстрыми, но проблема не в том, что они долгие, а в том что они вообще существуют).

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

Это да, но мышь это мышь, там конечно тоже неприятно но проще смириться чем с клавиатурой, он которой ждёшь предсказуемости.

firkax ★★★★★
() автор топика
  1. нажать хоткей (или у кого-то кнопку) запуска терминала

Проблема начинается здесь.

  1. подождать пока запустится фф
  2. набрать в нём адрес и энтер

Непонимание способа запуска браузера с урлом из консоли. И общее непонимание как пользоваться браузерами.

PcheloBiaka
()
Ответ на: комментарий от firkax

И опять нет, дело не в этом. Старые версии mc этой проблемы почти лишены, но mc точно никто не адаптировал к использованию в скриптах.

Мне было лень расписывать очевидные вещи, вроде и так должно было быть понятно.

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

  • Автоматизация. Через скрипты или через ctrl-c/ctrl-v текстовых команд.

  • Удалённая работа как на локальной машине.

Терминал передаёт в обе стороны символы, там нет нажатия/отжатия клавиш. Но даже если бы они были, то в рамках удалённой работы привязываться к таймингам было бы плохой идей. Это накладывает ограничения на UI приложений в терминале, ну не будет же оно читать клавиатуру напрямую? А чтение мышки для него вообще бесполезно.

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

altwazar ★★★★★
()
Ответ на: комментарий от firkax

Всё я прочитал. То что ты хочешь не имеет смысла. Вот запущу я гимп, куда надо вставлять символы что ты настучал пока гимп запускался? А электронную таблицу? А почтовик? А фрикад запущу, куда там вставлять чего? Консоль потому и консоль. Терминал. Все вводимые символы имеют один поток и одно назначение. Да даже в консоли ты вбей mc и пока запускается программа наколоти туда символов. Что файловому менеджеру с ними делать? Поток нужен только в самом терминале и неприменим нигде, кроме заранее прописаных разработчиком вариантов, когда его приложение ловило бы поток и обрабатывало. Но такое имеет смысл только если у приложения есть одно назначение. Теоретически можно было бы написать эвристику разбирающую что ты там в стандартный поток настучал. Но ради этого придётся написать, фактически, ещё одно приложение. Каждое приложение должно будет быть переработано со своими вариантами использования стандартного потока и всё это ради того, что ты хочешь стучать по клаве как одурелый пока программа запускается.

PcheloBiaka
()
Ответ на: комментарий от firkax

Это да, но мышь это мышь, там конечно тоже неприятно но проще смириться чем с клавиатурой, он которой ждёшь предсказуемости.

Ну и с предсказуемостью клавиатуры в терминале тоже есть нюансы. Больная тема - поддержка хоткеев, с ними проблема за пределами en раскладки или какая-нибудь комбинация на ctrl+j начинает работать как enter.

altwazar ★★★★★
()
Ответ на: комментарий от altwazar

Терминал передаёт в обе стороны символы, там нет нажатия/отжатия клавиш

Не вижу существенной разницы.

А чтение мышки для него вообще бесполезно.

Мышиные события в терминале тоже существуют. Тоже не напрямую, да.

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

Вот, надо в гуи так же, нигде не озадачивались?

firkax ★★★★★
() автор топика
Ответ на: комментарий от PcheloBiaka

Вот запущу я гимп, куда надо вставлять символы что ты настучал пока гимп запускался?

Не «вставлять», а отдать активному окну гимпа когда тот прочитает свою очередь событий.

Да даже в консоли ты вбей mc и пока запускается программа наколоти туда символов. Что файловому менеджеру с ними делать?

Нормальный mc эти символы обработает как положено - запишет в командную строку. А в чём проблема?

Не нужно никаких «куда вставлять», нужно просто запомнить клики и актуализировать их когда запустится тот, кому они предназначались.

firkax ★★★★★
() автор топика
Ответ на: комментарий от altwazar

Да, есть такое. Тут тоже можно в целом исправить: termios преобразования символов делать не во время нажатия кнопок а во время чтения их прогой из дескриптора. Правда остаётся небольшая проблема с ISIG (обработчик ctrl+c итд) - он по своей сути асинхроннный, а вот изменение его настройки прогой синхронное.

firkax ★★★★★
() автор топика
Ответ на: комментарий от anonymous

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

firkax ★★★★★
() автор топика
Ответ на: комментарий от firkax

Нормальный mc эти символы обработает как положено - запишет в командную строку.

Но это не для его использования,типа, скопируй те файлы туда, нет. Но их никак не использует. Он просто передаст это в консоль и выполнит для тебя, вот и всего. Это не диалог с программой, это не указание программе что делать. А вот что ты гимпу таким образом собрался передавать? «Примени прыщефильтр на моей фоточке»? Или что? Кстати. Запусти гимп, он захватит вывод, напиши в ту жеконсоль что ты хочешь и закрой гимп. И о чудо, оно выполнится. Также как и с mc, но с одним нюансом - гимп не консольный файловый менеджер работающий поверх стандартного терминала.

PcheloBiaka
()
Ответ на: комментарий от firkax

Если ты запустил программу, то ты ожидаешь,что она откроет окно и покажет его тебе. Если же ты хочешь, чтобы новые окна не воровали фокус, то одна галочка в твоём оконном менеджере легко это предотвратит. Никаких трагедий по поводу «я писал в консоль rm -rf /* а онапереключилась на ту дурацкую программу!!»

Не выдумывай проблемы. Их в мире реальных столько, что ой.

PcheloBiaka
()
Ответ на: комментарий от PcheloBiaka

Не, если ты введёшь не только буквы, но и функциональные кнопки (стрелки, pgup pgdn, f5 f6 итд) - это всё тоже по очереди обработается как нужно. Если ты заранее помнить на каком месте в списке располагаются нужные файлы - можешь вслепую пронажать всю навигацию и выполнить действие. Проблема там юудет позже: когда начнётся копирование или ещё что-то, mc уже начнёт интеркартивно опрашивать клавиатуру на предмет «а не нажал ли ты отмену операции» - и все последующие кнопки в очереди оно уже съест. Это проблема, да, но до первого запуска какого либо действия очередь выстроить можно.

Переделать можно чтобы убрать эту проблему: использовать для отмены операции асинхронное ctrl-c SIGINT (и разрешить его в termios), тогда сжирать буфер ввода не потребуется.

firkax ★★★★★
() автор топика
Ответ на: комментарий от PcheloBiaka

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

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

firkax ★★★★★
() автор топика
Ответ на: комментарий от firkax

Это спортивный анонизм никакого отношения к реальному использованию уомпьютера не предназначеный.

Поток символов вводимый в консоли обрабатывается последовательно и только когда надо. Графические же приложения используют сигналы. Никто посимвольно и поочерёдно из какого-то буффера обрабатывать этого не должен. Вот ты запустил тот же гимп и нажал шорткат для открытия файла, два раза вниз кликнул и нажал энтер. Вот сейчас ты гимп. опиши мне как ты должен это воспринять? Ты ожидаешь каждого нового символа и только тогда делаешь простейшую операциюи передаёшь ей следующий символ? А сколько символов надо передать? Как оконный менеджер знает что есть команда для гимпа? Ctrl - это уже хоткей? Или ждать следующего? А то что потом передать гимпу, или его диалоговомуокну? А потом куда девать всё? А ты на третье окно переключился теперь и ему напихать по самые щёки твоего клавиатурного комлания? WM не хранит твой ввод. Это неправильно впринципе. А для mc всё просто продолжает быть потоком, который за него принимает программа терминала ипередаёт ему в щель, которая уже и сохраняет введёные символы в очередь и mc просто реагирует. Его работа с твоим вводом построена абсолютно по другому. Это телетайп.

PcheloBiaka
()
Последнее исправление: PcheloBiaka (всего исправлений: 1)
Ответ на: комментарий от PcheloBiaka

Вот сейчас ты гимп. опиши мне как ты должен это воспринять?

Так же как если бы эти кнопки нажали после того как гимп уже запустился.

Неужели это так сложно?

А то что потом передать гимпу, или его диалоговомуокну?

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

Его работа с твоим вводом построена абсолютно по другому.

В том и дело - его работа с вводом построена правильно и удобно. В гуи надо так же сделать.

firkax ★★★★★
() автор топика
Ответ на: комментарий от firkax

Так же как если бы эти кнопки нажали после того как гимп уже запустился.

Ты думаешь, что это гимп передаёт твои нажатия диалоговому окну? Ты очень ошибаешься. Ты просто попробуй подумать.ты гимп. Тебя запустили и нажали Ctrl+O, два раза стрелочку вниз и энтер. Допустим ты получив команду открытия файла запустил диалоговое окно. С остальным что тебе делать?

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

А что есть «остальные кнопки»? Кто это должен решать? Гимп? Оконный менеджер? Консоль? Ядро? Кто должен расчленить твой ввод и решить, что вот этой программе уже хватит, остальное (и только то, что нужно) передать другому окну/программе?

Пока ты это не поймёшь, ты не поймёшь ничего.

PcheloBiaka
()
Ответ на: комментарий от PcheloBiaka

Я ни разу не пользовался гимпом и не знал что там за что отвечает. Теперь понял. Ну, очевидно следующие нажатия должны быть предназначены этому самому диалоговому окну. И я не сомневаюсь, что реализовать это возможно: реализовать можно любую штуку, которую ты можешь алгоритмически описать. Вопрос только в том, насколько много для этого придётся кодить.

А что есть «остальные кнопки»? Кто это должен решать? Гимп? Оконный менеджер? Консоль? Ядро?

Остальные это всё что нажато после хоткея открывания.

Кто должен решить - ну, кто-то из списка: графический сервер, wm, клиентская библиотека к графическому серверу на стороне гимпа. Возможно, сообща. Если бы у меня была реализация, я бы тут вопросов не задавал, а написал бы лучше новость про неё чтобы поделитьс с остальными.

Кто должен расчленить твой ввод и решить, что вот этой программе уже хватит,

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

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

firkax ★★★★★
() автор топика
Последнее исправление: firkax (всего исправлений: 1)
Ответ на: комментарий от firkax

Ты даже не замечаешь какую ерунду фантазируешь. Вот сядут оконный менеджер с иксами с… со всеми запущеными программами, откроют стиралку и станут разгребать носки, где чьи… Есть один единственный аппаратно-програмный комплекс, который может это всё разгрести и понять что кому. Это пользователь. Если он не в состоянии понять что и куда он вводит, ни один сервер этого не решит.

PcheloBiaka
()