Некоторые оконные системы обеспечивают поддержку устройств ввода, которые реагируют на прикосновения пользователя к экрану и перемещение пальцев во время касания экрана. Такие устройства ввода называются сенсорными экранами, и Emacs сообщает о генерируемых ими событиях как о событиях сенсорного экрана.
Большинство отдельных событий, генерируемых сенсорным экраном, имеют смысл только как часть более крупной последовательности других событий: например, простая операция касания экрана включает в себя размещение и поднятие пальца на сенсорном экране, а смахивание по экрану для прокрутки включает размещение пальца, многократное перемещение его вверх или вниз, а затем поднятие пальца.
Хотя упрощённой модели, состоящей из одного пальца, достаточно для касаний и прокрутки, более сложные жесты требуют поддержки отслеживания нескольких пальцев, где положение каждого пальца представлено точкой касания. Например, жест «сжатие для масштабирования» может состоять в том, что пользователь помещает два пальца и перемещает их по отдельности в противоположных направлениях, при этом расстояние между положениями их отдельных точек определяет величину масштабирования отображения, а центр воображаемой линии между этими позициями определяет, куда перемещать отображение после масштабирования.
Описанные ниже низкоуровневые события сенсорного экрана можно использовать для реализации всех описанных выше последовательностей касаний. В этих событиях каждая точка представлена cons-парой из произвольного числа, идентифицирующего точку, и списка позиции мыши (см. События щелчка), указывающего положение пальца в момент возникновения события.
(touchscreen-begin точка)Это событие отправляется, когда точка создаётся нажатием пальца на сенсорный экран.
К этим событиям также добавляются воображаемые префиксные клавиши read-key-sequence, когда они возникают над специальной частью фрейма или окна. См. Ввод последовательности клавиш.
(touchscreen-update точки)Это событие отправляется, когда точка на сенсорном экране изменила положение. точки — это список точек касания, содержащий актуальные положения каждой точки касания, находящейся в данный момент на сенсорном экране.
(touchscreen-end точка отменено)Это событие отправляется, когда точка больше не присутствует на дисплее из-за того, что другая программа захватила управление, или потому что пользователь поднял палец с сенсорного экрана.
отменено не равно nil, если последовательность касаний была перехвачена другой программой (например, оконным менеджером), и Emacs должен отменить или избежать любых команд редактирования, которые могли бы иначе возникнуть в результате последовательности касаний.
К этим событиям также добавляются воображаемые префиксные клавиши read-key-sequence, когда они возникают над специальной частью фрейма или окна.
Если точка касания нажата на строке меню, Emacs не будет генерировать соответствующие события touchscreen-begin или touchscreen-end; вместо этого строка меню может быть отображена после того, как touchscreen-end было бы доставлено при других обстоятельствах.
Когда ни одна команда не привязана к touchscreen-begin, touchscreen-end или touchscreen-update, Emacs вызывает «функцию трансляции клавиш» (см. Карты клавиш для трансляции последовательностей событий) для трансляции последовательностей клавиш, содержащих события сенсорного экрана, в обычные события мыши (см. События мыши). Поскольку Emacs не поддерживает различение событий, исходящих от разных устройств мыши, он предполагает, что во время трансляции активно не более двух точек касания, и не даёт никаких гарантий относительно результатов трансляции событий при нарушении этого ограничения.
Emacs применяет две различные стратегии трансляции событий касания в события мыши в зависимости от таких факторов, как команды, привязанные к картам клавиш, активным в месте расположения события touchscreen-begin. Если в этом месте к down-mouse-1 привязана команда, начальная трансляция состоит из одного события down-mouse-1, последующие события touchscreen-update транслируются в события движения мыши (см. События движения), а заключительное событие touchscreen-end транслируется в событие mouse-1 или drag-mouse-1 (если только событие touchscreen-end не указывает, что последовательность касаний была перехвачена другой программой). Это называется «простой трансляцией» и обеспечивает простое соответствие между движением точки касания и движением мыши.
Однако некоторые команды, привязанные к down-mouse-1 — например, mouse-drag-region — либо конфликтуют с определёнными жестами сенсорного экрана (такими как «долгое нажатие для перетаскивания»), либо с ожиданиями пользователя от ввода с касанием, и не должны подвергать последовательность касаний простой трансляции. Если встречается команда, имя которой содержит свойство (см. Свойства символов) ignored-mouse-command, или к down-mouse-1 не привязана ни одна команда, применяется более нерегулярная форма трансляции: здесь Emacs сначала обрабатывает жесты сенсорного экрана (см. Сенсорные экраны в Руководстве по GNU Emacs), и, наконец, пытается транслировать события сенсорного экрана в события мыши, если до завершающего события touchscreen-end (с его параметром отменено, равным nil, как и при простой трансляции) не было обнаружено никакого жеста, и к mouse-1 привязана команда в месте этого события. Перед генерацией события mouse-1 точка также устанавливается в положение события touchscreen-end, и выбирается окно, содержащее позицию этого события, в качестве компромисса для пакетов, которые предполагают, что mouse-drag-region уже установил точку в положение любого щелчка мыши и выбрал окно, в котором он произошёл.
Чтобы предотвратить нежелательные события mouse-1, поступающие после закрытия меню мыши (см. Меню и мышь), Emacs также избегает простой трансляции, если к down-mouse-1 привязана карта клавиш, делающая его префиксной клавишей. Вместо простой трансляции он транслирует завершающее событие touchscreen-end в событие down-mouse-1 с начальной позицией последовательности касаний, что приводит к отображению меню мыши.
Поскольку некоторые команды также привязаны к down-mouse-1 для целей отображения всплывающих меню, Emacs дополнительно ведёт себя так, как описано в последнем абзаце, если к down-mouse-1 привязана команда, имя которой имеет свойство mouse-1-menu-command.
Когда регистрируется вторая точка касания, в то время как уже выполняется трансляция одной точки, трансляция жестов завершается, и измеряется расстояние от второй точки касания (вспомогательный инструмент) до первой. Последующее движение любой из этих точек касания будет генерировать события touchscreen-pinch, содержащие отношение, образованное расстоянием между их новыми положениями и расстоянием, измеренным в начале, как показано в следующей таблице.
Если во время трансляции обнаруживаются жесты касания, могут генерироваться следующие входные события:
(touchscreen-scroll окно dx dy)Если во время процесса трансляции обнаружен жест «прокрутка», каждое последующее событие touchscreen-update транслируется в событие touchscreen-scroll, где dx и dy задают в пикселях относительное движение точки касания от позиции события touchscreen-begin, которое начало последовательность, или от последнего события touchscreen-scroll, в зависимости от того, что было позже.
(touchscreen-hold позиция)Если единственная активная точка касания остаётся неподвижной более touch-screen-delay секунд после генерации touchscreen-begin, во время процесса трансляции обнаруживается жест «долгое нажатие», и отправляется событие touchscreen-hold, где позиция установлена в список позиции мыши, содержащий позицию события touchscreen-begin.
(touchscreen-drag позиция)Если во время трансляции текущей последовательности касаний обнаружен жест «долгое нажатие» или «перетаскивание для выделения» возобновляется в результате пользовательской опции touch-screen-extend-selection, при каждом последующем событии touchscreen-update отправляется событие touchscreen-drag, где позиция установлена в новое положение точки касания.
(touchscreen-restart-drag позиция)Это событие отправляется в начале последовательности касаний, приводящей к продолжению жеста «перетаскивание для выделения» (в соответствии с вышеупомянутой пользовательской опцией), где позиция установлена в список позиции начального события touchscreen-begin в этой последовательности касаний.
(touchscreen-pinch позиция отношение пан-x пан-y разница-отношения)Это событие доставляется при значительных изменениях положений любой активной точки касания, когда активен вспомогательный инструмент.
позиция — это список позиции мыши для средней точки линии, проведённой от вспомогательного инструмента к другой наблюдаемой точке касания.
отношение — это расстояние между обеими наблюдаемыми точками касания, делённое на это расстояние в момент первой регистрации вспомогательной точки; иными словами, масштаб жеста «сжатие».
пан-x и пан-y — это разница между пиксельной позицией позиция и этой позицией в последнем доставленном событии, относящемся к этой серии событий касания, или, если такого события нет, центральная точка между обеими точками касания в момент первой регистрации вспомогательного инструмента.
разница-отношения — это разница между отношением этого события и отношением в последнем доставленном событии; если такого события нет, то это отношение.
Такие события отправляются, когда величина изменений, которые они представляют, приведёт к тому, что отношение будет отличаться более чем на 0.2 от предыдущего события, или сумма пан-x и пан-y превысит половину ширины символа фрейма в пикселях (см. Шрифт фрейма).
Для Lisp-программ, обрабатывающих события сенсорного экрана, предоставляется несколько функций. Предполагаемое использование первых двух описанных ниже функций — из команд, напрямую привязанных к событиям touchscreen-begin; они позволяют реагировать на часто используемые жесты сенсорного экрана отдельно от трансляции событий мыши.
Эта функция используется для отслеживания одиночного жеста «касание», исходящего из события touchscreen-begin событие, часто используемого для установки точки или активации кнопки. Она ожидает прибытия события touchscreen-end с тем же идентификатором касания, после чего возвращает t, сигнализируя об окончании жеста.
Если тем временем прибывает событие touchscreen-update, содержащее по крайней мере одну точку касания с тем же идентификатором, что и в событие, вызывается функция обновление с двумя аргументами: списком точек касания в этом событии touchscreen-update и данные.
Если порог не равен nil и такое событие указывает, что точка касания, представленная событие, переместилась за пределы порога, равного либо порог, либо 10 пикселям, если это не число, от позиции событие, возвращается nil, и трансляция событий мыши для этой точки касания возобновляется, чтобы не препятствовать распознаванию любых последующих жестов сенсорного экрана, возникающих из её последовательности.
Если тем временем прибывает любое другое событие, возвращается nil. В этом случае вызывающая сторона не должна выполнять никаких действий.
Эта функция используется для отслеживания одиночного жеста «перетаскивание», исходящего из события touchscreen-begin событие.
Она ведёт себя как touch-screen-track-tap, за исключением того, что возвращает no-drag и не вызывает обновление, если точка касания в событие не переместилась достаточно далеко (по умолчанию на 5 пикселей от своей позиции в событие), чтобы квалифицироваться как фактическое перетаскивание.
В дополнение к этим двум функциям предоставляется функция для команд, привязанных к некоторым типам событий, генерируемых через трансляцию событий мыши, чтобы предотвратить генерацию нежелательных событий после её вызова.
Эта функция запрещает генерацию событий touchscreen-drag во время трансляции событий мыши на время трансляции последовательности касаний после её вызова. Она должна вызываться из команды, привязанной к событию touchscreen-hold или touchscreen-drag, иначе сигнализирует об ошибке.
Поскольку эту функцию можно вызвать только после того, как жест уже распознан во время трансляции событий мыши, после её вызова из событий касания, составляющих вышеупомянутую последовательность касаний, не будут генерироваться события мыши.