Фокус ввода
В любой момент времени один кадр в Emacs является выбранным кадром. Выбранное окно (см. Выбор окон) всегда находится в выбранном кадре.
Когда Emacs отображает свои кадры на нескольких терминалах (см. Несколько терминалов), каждый терминал имеет свой собственный выбранный кадр. Но только один из них является выбранным кадром: это кадр, принадлежащий терминалу, из которого поступил последний ввод. То есть, когда Emacs выполняет команду, пришедшую с определённого терминала, выбранным кадром является кадр этого терминала. Поскольку Emacs выполняет только одну команду за раз, ему нужно учитывать только один выбранный кадр за раз; этот кадр и называется выбранным кадром в этом руководстве. Дисплей, на котором отображается выбранный кадр, является дисплеем выбранного кадра.
- Функция: selected-frame
Эта функция возвращает выбранный кадр.
Некоторые системы окон и менеджеры окон направляют ввод с клавиатуры объекту окна, в котором находится указатель мыши; другие требуют явных щелчков или команд для переключения фокуса на различные объекты окна. В любом случае, Emacs автоматически отслеживает, в каких кадрах находится фокус. Чтобы явно переключиться на другой кадр из функции Lisp, вызовите select-frame-set-input-focus.
Множественное число «кадры» в предыдущем абзаце употреблено намеренно: хотя сам Emacs имеет только один выбранный кадр, у Emacs могут быть кадры на многих различных терминалах (помните, что подключение к системе окон считается терминалом), и каждый терминал имеет своё представление о том, в каком кадре находится фокус ввода. Когда вы устанавливаете фокус ввода на кадр, вы устанавливаете фокус для терминала этого кадра, но кадры на других терминалах могут оставаться с фокусом.
Программы Lisp могут временно переключать кадры, вызывая функцию select-frame. Это не изменяет понятие фокуса в системе окон; скорее, это выход из-под управления менеджером окон до тех пор, пока это управление каким-то образом не будет восстановлено.
При использовании текстового терминала только один кадр может быть отображен на терминале за раз, поэтому после вызова select-frame, следующее перерисовка фактически отображает новый выбранный кадр. Этот кадр остаётся выбранным до последующего вызова select-frame. Каждый кадр на текстовом терминале имеет номер, который отображается в строке состояния перед именем буфера (см. Переменные строки состояния).
- Функция: select-frame-set-input-focus frame &optional norecord
Эта функция выбирает frame, поднимает его (если он случайно скрыт другими кадрами) и пытается дать ему фокус системы окон. На текстовом терминале при следующем перерисовке новый кадр будет отображен на весь экран терминала. Необязательный аргумент norecord имеет то же значение, что и для
select-frame(см. ниже). Возвращаемое значение этой функции не имеет значения.
В идеале, описываемая далее функция должна устанавливать фокус на кадр, не поднимая его над другими кадрами. К сожалению, многие системы или менеджеры окон могут отказать в выполнении этого требования.
- Функция: x-focus-frame frame &optional noactivate
-
Эта функция устанавливает фокус frame на сервере X без необходимости его поднятия. frame
nilозначает использовать выбранный кадр. В X, необязательный аргумент noactivate, если он неnil, означает избегание превращения окна frame в системе окон в «активное» окно, что должно немного сильнее препятствовать поднятию frame над другими кадрами.В MS-Windows аргумент noactivate не имеет эффекта. Однако, если frame является дочерним кадром (см. Дочерние кадры), эта функция обычно устанавливает фокус на frame без его поднятия над другими дочерними кадрами.
Если поддержка системы окон отсутствует, эта функция ничего не делает.
- Команда: select-frame frame &optional norecord
-
Эта функция выбирает кадр frame, временно игнорируя фокус сервера X, если таковой имеется. Выбор frame сохраняется до следующего момента, когда пользователь что-то делает для выбора другого кадра или до следующего вызова этой функции. (Если вы используете систему окон, ранее выбранный кадр может быть восстановлен как выбранный кадр после возвращения в цикл команд, так как он всё ещё может иметь фокус ввода в системе окон.)
Указанный frame становится выбранным кадром, и его терминал становится выбранным терминалом. Затем эта функция вызывает
select-windowкак подпрограмму, передавая выбранное окно в пределах frame в качестве первого аргумента и norecord в качестве второго аргумента (следовательно, если norecord неnil, это предотвращает изменение порядка недавно выбранных окон и списка буферов). См. Выбор окон.Эта функция возвращает frame или
nilесли frame был удалён.В общем случае, вы никогда не должны использовать
select-frameтаким образом, чтобы можно было переключиться на другой терминал без возврата обратно, когда вы закончите.
Emacs взаимодействует с системой окон, выбирая кадры по запросу сервера и менеджера окон. Когда система окон сообщает Emacs, что один из его кадров был выбран, Emacs внутренне генерирует событие focus-in. Когда кадр Emacs отображается на эмуляторе текстового терминала, таком как xterm, который поддерживает уведомления о переключении фокуса, события focus-in и focus-out доступны даже для кадров текстового режима. События фокуса обычно обрабатываются handle-focus-in.
- Команда: handle-focus-in event
Эта функция обрабатывает события focus-in от систем окон и терминалов, которые поддерживают явные уведомления о фокусе. Она обновляет флаги фокуса для каждого кадра, которые
frame-focus-stateзапрашивает, и вызываетafter-focus-change-function. Кроме того, она генерирует событиеswitch-frame, чтобы переключить понятие Emacs о выбранном кадре на кадр, который последним получил фокус на каком-либо терминале. Важно отметить, что это переключение выбранного кадра Emacs на последний получивший фокус кадр не означает, что другие кадры не продолжают иметь фокус на своих соответствующих терминалах. Не вызывайте эту функцию самостоятельно: вместо этого присоедините логику кafter-focus-change-function.
- Команда: handle-switch-frame frame
Эта функция обрабатывает событие переключения кадра, которое Emacs генерирует для себя при уведомлении о фокусе или при других обстоятельствах, связанных с поступлением события ввода в другой кадр, отличном от последнего события. Не вызывайте эту функцию самостоятельно.
- Функция: redirect-frame-focus frame &optional focus-frame
-
Эта функция перенаправляет фокус из frame в focus-frame. Это означает, что focus-frame будет получать последующие нажатия клавиш и события, предназначенные для frame. После такого события значение
last-event-frameбудет focus-frame. Кроме того, события переключения кадра, указывающие на frame, будут вместо этого выбирать focus-frame.Если focus-frame опущено или
nil, это отменяет любое существующее перенаправление для frame, который, таким образом, снова получает свои собственные события.Одно из применений перенаправления фокуса — для кадров, у которых нет минибуферов. Эти кадры используют минибуферы в других кадрах. Активация минибуфера в другом кадре перенаправляет фокус в этот кадр. Это устанавливает фокус на кадр минибуфера, где он должен быть, даже если указатель мыши остаётся в кадре, который активировал минибуфер.
Выбор кадра также может изменить перенаправление фокуса. Выбор кадра
bar, когдаfooбыл выбран, изменяет все перенаправления, указывающие наfoo, так что они указывают наbarвместо этого. Это позволяет правильно работать перенаправлению фокуса, когда пользователь переключается с одного кадра на другой с помощьюselect-window.Это означает, что кадр, чей фокус перенаправлен на него самого, обрабатывается по-другому, чем кадр, чей фокус не перенаправлен.
select-frameвлияет на первый, но не на второй.Перенаправление сохраняется до тех пор, пока
redirect-frame-focusне будет вызван для его изменения.
- Функция: frame-focus-state frame
-
Эта функция извлекает последнее известное состояние фокуса frame.
Она возвращает
nil, если кадр известен как нефокусированный,t, если кадр известен как фокусированный, илиunknown, если Emacs не знает состояние фокуса кадра. (Вы можете увидеть это последнее состояние в кадрах TTY, работающих на терминалах, которые не поддерживают явные уведомления о фокусе.)
- Переменная: after-focus-change-function
-
Эта функция — точка расширения, которую код может использовать для получения уведомления о том, что фокус изменился.
Эта функция вызывается без аргументов, когда Emacs замечает, что набор фокусированных кадров может измениться. Код, желающий выполнить какие-либо действия при изменении фокуса кадра, должен использовать
add-functionдля добавления функции в эту, и в этой добавленной функции повторно просматривать набор фокусированных кадров, вызываяframe-focus-stateдля извлечения последнего известного состояния фокуса каждого кадра. События фокуса доставляются асинхронно, и фокус ввода кадра согласно внешней системе может не соответствовать понятию выбранного кадра Emacs. Несколько кадров могут казаться фокусированными одновременно из-за различий в доставке событий фокуса, наличия нескольких терминалов Emacs и других факторов, и код должен быть надёжным в этой ситуации.В зависимости от системы окон, события фокуса также могут доставляться повторно и с различными состояниями фокуса, прежде чем стабилизироваться до ожидаемых значений. Код, полагающийся на уведомления о фокусе, должен «сглаживать» любые видимые пользователю обновления, возникающие из-за изменений фокуса, возможно, отложив работу до перерисовки.
Эта функция может вызываться в произвольных контекстах, включая изнутри
read-event, поэтому обратите такое же внимание, как и при написании фильтра процесса.
- Параметр пользователя: focus-follows-mouse
-
Этот параметр сообщает Emacs, следует ли и как менеджер окон передаёт фокус, когда вы перемещаете указатель мыши в фрейм. Он может принимать три значения:
nil-
Значение по умолчанию
nilследует использовать, если ваш менеджер окон следует политике «щелкните, чтобы получить фокус», где вам нужно щелкнуть мышью внутри фрейма, чтобы этот фрейм получил фокус. t-
Значение
tследует использовать, если ваш менеджер окон автоматически переводит фокус на позицию указателя мыши, но фрейм, получивший фокус, не поднимается автоматически и может даже оставаться скрытым другими окнами системы окон. auto-raiseЗначение
auto-raiseследует использовать, если ваш менеджер окон автоматически переводит фокус на позицию указателя мыши, и фрейм, получивший фокус, поднимается автоматически.
Если этот параметр не
nil, Emacs переместит указатель мыши в выбранный фрейм с помощьюselect-frame-set-input-focus. Эта функция используется несколькими командами, например,other-frameиpop-to-buffer.Различие между значениями
tиauto-raiseне требуется для «обычных» фреймов, потому что менеджер окон обычно заботится о их поднятии. Это полезно для автоматического поднятия дочерних фреймов с помощьюmouse-autoselect-window(см. Автоматический выбор окна мыши).Обратите внимание, что этот параметр не различает «неточный» фокус (где фрейм, который ранее имел фокус, сохраняет фокус, пока указатель мыши не переместится в другое окно системы окон) от «строгого» фокуса (где фрейм немедленно теряет фокус, когда из него убирается указатель мыши). Он также не распознаёт, поддерживает ли ваш менеджер окон отложенную фокусировку или автоматическое поднятие, где вы можете явно указать время, до которого новый фрейм получит фокус или будет автоматически поднят.
Вы можете задать политику «фокус следует за мышью» для отдельных окон Emacs, настроив переменную
mouse-autoselect-window(см. Автоматический выбор окна мыши).
Copyright © 1990-1996, 1998-2022 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Input-Focus.html