Опубликован: 10.12.2007 | Уровень: специалист | Доступ: платный
Лекция 6:

События

6.2. Что происходит при нажатии клавиш

XUL в Mozilla поддерживает теги <keyset>, <key>, <commandset> и <command>. Эти теги используются для связи клавиш с элементами графического интерфейса и для обработки нажатий клавиш. Эти теги позволяют задавать назначения клавиш для отдельных документов или приложений. XUL также поддерживает атрибут accesskey.

Клавиша - это маленькая пластмассовая формочка с изображением символов, находящаяся на клавиатуре. Клавиши можно разделить на две группы: те, у которых есть эквивалентные глифы, и те, у которых глифов нет. Глиф - это некоторое визуальное представление, например, А. Стандарт Unicode поддерживает клавиши, которым соответствуют глифы; у сочетаний и клавиш, которым никакие глифы не соответствуют, почти нет стандартной поддержки.

Поддержка событий нажатия клавиш в Mozilla появилась раньше стандарта DOM 3 Events. Этот стандарт описывает только клавиши, которым глифы не соответствуют. В Mozilla поддержка работы с клавишами включает дополнительные клавиши с глифами. Mozilla и этот стандарт пользуются разными системами нумерации, поэтому значения кодов клавиш в них различны. Как упоминалось ранее, Mozilla поддерживает общие события keypress, keyup и keydown для объекта Document. Эти события поддерживаются не всеми тегами.

В таблице 6.3 приведены различия между кодами клавиш в двух определениях. Аббревиатура VK означает "виртуальная клавиша".

Таблица 6.3. Разница между кодами клавиш в Mozilla и DOM 3 Events
Коды клавиш, определенные в Mozilla Коды клавиш, определенные в Mozilla Коды клавиш, определенные в DOM 3 Events
DOM_VK_CANCEL DOM_VK_SEMICOLON DOM_VK_UNDEFINED
DOM_VK_HELP DOM_VK_EQUALS
DOM_VK_CLEAR DOM_VK_QUOTE DOM_VK_RIGHT_ALT
DOM_VK_MULTIPLY DOM_VK_LEFT_ALT
DOM_VK_ALT DOM_VK_ADD DOM_VK_RIGHT_CONTROL
DOM_VK_CONTROL DOM_VK_SEPARATOR DOM_VK_LEFT_CONTROL
DOM_VK_SHIFT DOM_VK_SUBTRACT DOM_VK_RIGHT_SHIFT
DOM_VK_META DOM_VK_DECIMAL DOM_VK_LEFT_SHIFT
DOM_VK_DIVIDE DOM_VK_RIGHT_META
DOM_VK_BACK_SPACE DOM_VK_COMMA DOM_VK_LEFT_META
DOM_VK_TAB DOM_VK_PERIOD
DOM_VK_RETURN DOM_VK_SLASH
DOM_VK_BACK_QUOTE
DOM_VK_0 to 9 DOM_VK_OPEN_BRACKET
DOM_VK_A to Z DOM_VK_BACK_SLASH
DOM_VK_CLOSE_BRACKET
DOM_VK_NUMPAD0 to 9

Необходимо упомянуть и два различия между Mozilla и стандартом:

  • свойство keyval в DOM 3 Events соответствует свойству charCode интерфейса nsIDOMKeyEvent в Mozilla;
  • свойство virtKeyVal в DOM 3 Events соответствует свойству keyCode интерфейса nsIDOMKeyEvent в Mozilla.

Эти различия, фактически, заключаются только в именах.

6.2.1. Откуда берутся события нажатия клавиш

Прежде чем стать событием, нажатие клавиши претерпевает ряд изменений. В разделе "Отладка" этой лекции описывается, как определить, что преобразование выполняется неверно. Здесь мы просто продемонстрируем процесс сбора событий клавиш.

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

Клавиатура не так проста, как может показаться. Она взаимодействует с компьютером. Ее встроенное программное обеспечение преобразует нажатие клавиши, ее отпускание или многократное нажатие в скан-код. Скан-код представляет собой одно- или многобайтовое значение. Абсолютного стандарта для скан-кодов не существует, есть лишь хорошо известные реализации, например, клавиатура IBM PC AT 101. Скан-коды тоже не соответствуют ASCII-таблице или чему-нибудь подобному и они отправляются и от клавиатуры, и к ней.

Некоторые скан-коды отправляются напрямую аппаратной части компьютера, например, когда пользователь при загрузке компьютера нажимает Delete, чтобы попасть в BIOS, или иногда при нажатии Pause или Control-Alt-Delete. Другие коды обрабатываются операционной системой компьютера, которая пытается преобразовать скан-код в код символа: или в ASCII-код, или в Unicode-код, или в какое-то внутреннее представление. В Microsoft Windows здесь вступает действие та часть ПО, которая обозначена пиктограммой клавиатуры на панели управления. В Linux эту работу операционная система выполняет с помощью драйвера.

Некоторые программы очень сложны. Примеры включают в себя X-Windows и текстовые процессоры с поддержкой иероглифического письма (например, китайского, корейского и японского). Если приложение настолько сложно, ему могут отправляться практически необработанные скан-коды. В X-Windows за соответствие имен, связанных со скан-кодами, и внутренней системы символов X11 ответственна программа xmodmap. В странах, где набор символов больше, чем доступно клавиш на клавиатуре, используются особые системы - методы ввода. При нажатии последовательности клавиш, означающей "Составление символа", появляется маленькое окошко. Содержимое этого окна реагирует на создание клавиш путем нескольких нажатий разных клавиш. В сборках Mozilla с поддержкой иероглифического письма реализован такой метод ввода. Пример - японская иероглифика, содержащая тысячи символов, но все их можно составить, имея клавиатуру с менее чем сотней клавиш.

6.2.2. Какие клавиши доступны

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

Некоторые коды символов всегда обрабатываются в соответствии с таблицами операционной системы, графической среды или менеджера окон. Нажатие таких клавиши никогда не достигает отдельных приложений, как, например, клавиша Windows, открывающая меню "Пуск" в Microsoft Windows, или нажатие Alt-Tab. Использование таких клавиш в приложениях бесполезно, поэтому авторам этих приложений их обработку реализовать нелегко.

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

В таблицах назначения клавиш часто применяются клавиши- модификаторы, например, Control или Alt, или еще какая-нибудь служебная клавиша. Такие модификаторы обычно устанавливаются по соглашению. Они не одинаковы для разных платформ. Mozilla решает эту проблему несовместимости с помощью клавиши быстрого доступа. Эта клавиша связывается с модификатором, который чаще всего используется для текущей платформы. Эту клавишу и пару подобных ей можно определить в пользовательских настройках. Подробнее см. http://www.mozilla.org/unix/customizing.html.

В платформу Mozilla коды символов попадают через собственную библиотеку графических элементов операционной системы, а затем преобразуются в код клавиши DOM_VK. Такие клавиши связаны с задачами, которое выполняет данное окно Mozilla. Этого можно достичь несколькими способами: с помощью общей таблицы назначения клавиш, назначая командам клавиши напрямую или ставя клавиши в соответствие наблюдателям. Далее описывается каждый из этих методов.

На самом высоком уровне то, что должна делать клавиша - дело проектирования. Список текущего резервирования клавиш в Mozilla можно найти в документе http://www.mozilla.org/projects/ui/accessibility/mozkeyplan.html.

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

6.2.2.1. Таблицы назначения клавиш XBL

Общие назначения клавиш заданы в Mozilla в XBL-файлах. Существующие примеры находятся не в chrome: это зависящие от платформы данные, хранящиеся в каталоге res/builtin. Есть два файла: общий файл htmlBindings.xml и зависящий от платформы platformHTMLBindings.xml. Эти файлы относятся к XUL и HTML в окнах Mozilla и могут служить отправной точкой для изучения XBL-связей в приложениях. XBL описывается в "XBL-связки" , "XBL-связки", но в листинге 6.13 мы приведем короткий пример назначения функции клавише.

<bindings id="myAppKeys"> 
  <binding id="CmdHistoryKeys"> 
    <handler event="keypress" 
    keycode="DOM_VK_Z" 
    command="cmd_redo" 
    modifiers="accel,shift" 
    /> 
  </binding> 
</bindings>
Листинг 6.13. Назначение клавише команды "Повторить" через XBL

Этот кусок XBL-кода создает группу связей, которая называется myAppKeys, вероятно, для конкретного приложения. Каждая связь в этой группе задает клавиши для какой-либо части приложения. Объединение клавиш в несколько наборов упрощает их повторное использование. В нашем случае набор CmdHistoryKeys указывает все клавиши, участвующие в перемещениях по журналу команд, то есть для операций "Отменить" и "Повторить". Здесь показана только одна такая клавиша.

Тег <handler> - в этом случае специальный обработчик события onkeypress. Команда, с которой связано нажатие клавиши - cmd_redo. Пока просто заметим, что это функция, реализованная где-то в платформе. Атрибуты keycode и modifiers вместе задают сочетание клавиш, которое нужно нажать, чтобы действие "Повторить" произошло только раз. В нашем примере эта комбинация состоит из трех клавиш: клавиши быстрого доступа платформы, любой клавиши Shift и клавиши Z. В записи, принятой для Microsoft Windows, это комбинация Control-Shift-Z, так как в этой операционной системе клавишей быстрого доступа Mozilla является Control.

Если атрибут command отсутствует, тогда между открывающим и закрывающим тегами <handler> может находиться JavaScript-код, который будет выполняться при нажатии на клавишу. keycode="DOM_VK_Z" можно заменить на key="z", так как у z есть символьный эквивалент. Если при этом не используются никакие модификаторы, и z, и Z означают " z в нижнем регистре".

Дмитрий Гуменюк
Дмитрий Гуменюк
Россия, Звенигород
Konstantin Grishko
Konstantin Grishko
Россия, Москва, Московский финансово-промышленный университет "Синергия", Москва