29.2 Окна и фреймы

Каждое окно принадлежит ровно одному фрейму (см. Фреймы). Про все окна, принадлежащие конкретному фрейму, иногда также говорят, что эти окна принадлежат этому фрейму или просто находятся на этом фрейме.

Функция: window-frame &optional window

Эта функция возвращает фрейм указанного window’а — фрейм, которому принадлежит window. Если window опущен или равен nil, по умолчанию используется выбранное окно (см. Выбор окон).

Функция: window-list &optional frame minibuffer window

Эта функция возвращает список всех живых окон, принадлежащих указанному frame’у. Если frame опущен или равен nil, по умолчанию используется выбранный фрейм (см. Фокус ввода).

Необязательный аргумент minibuffer указывает, следует ли включать окно минибуфера (см. Окна минибуфера) в этот список. Если minibuffer равен t, окно минибуфера включается. Если равен nil или опущен, окно минибуфера включается, только если оно активно. Если minibuffer не равен ни nil, ни t, окно минибуфера никогда не включается.

Необязательный аргумент window, если не равен nil, должен быть живым окном на указанном фрейме; тогда window будет первым элементом в возвращаемом списке. Если window опущен или равен nil, окно, выбранное в пределах frame’а (см. Выбор окон), является первым элементом.

Окна на одном фрейме организованы в дерево окон, листьями которого являются живые окна. Внутренние узлы дерева окон не являются живыми; они существуют для организации взаимосвязей между живыми окнами. Корневой узел дерева окон называется корневым окном. Оно может быть либо живым окном, либо внутренним окном. Если это живое окно, то фрейм имеет только одно окно помимо окна минибуфера, или фрейм является фреймом только с минибуфером (см. Компоновка фрейма).

Окно минибуфера (см. Окна минибуфера), которое не является единственным на своем фрейме, не имеет родительского окна, поэтому строго говоря, оно не является частью дерева окон своего фрейма. Тем не менее, оно является родственным окном корневого окна фрейма и, таким образом, может быть достигнуто из корневого окна через window-next-sibling, см. ниже. Кроме того, функция window-tree, описанная в конце этого раздела, перечисляет окно минибуфера наряду с самим деревом окон.

Функция: frame-root-window &optional frame-or-window

Эта функция возвращает корневое окно для frame-or-window. Аргумент frame-or-window должен быть либо окном, либо фреймом; если опущен или равен nil, по умолчанию используется выбранный фрейм. Если frame-or-window является окном, возвращаемое значение — корневое окно фрейма этого окна.

Когда живое окно разделяется (см. Разделение окон), появляются два живых окна там, где раньше было одно. Одно из них представлено тем же Lisp-объектом окна, что и исходное окно, а другое представлено вновь созданным Lisp-объектом окна. Оба этих живых окна становятся листьями дерева окон как дочерние окна одного внутреннего окна. При необходимости Emacs автоматически создает это внутреннее окно, которое также называется родительским окном, и помещает его в соответствующую позицию в дереве окон. Набор окон, имеющих одного и того же родителя, называется родственными.

Функция: window-parent &optional window

Эта функция возвращает родительское окно window’а. Если window опущен или равен nil, по умолчанию используется выбранное окно. Возвращаемое значение равно nil, если window не имеет родителя (т.е. это окно минибуфера или корневое окно своего фрейма).

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

Дочернее окно может быть либо живым окном, либо внутренним окном (которое, в свою очередь, имеет свои собственные дочерние окна). Поэтому каждое внутреннее окно можно рассматривать как занимающее определенную прямоугольную область экрана — объединение областей, занимаемых живыми окнами, которые в конечном итоге являются его потомками.

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

     ______________________________________
    | ______  ____________________________ |
    ||      || __________________________ ||
    ||      |||                          |||
    ||      |||                          |||
    ||      |||                          |||
    ||      |||____________W4____________|||
    ||      || __________________________ ||
    ||      |||                          |||
    ||      |||                          |||
    ||      |||____________W5____________|||
    ||__W2__||_____________W3_____________ |
    |__________________W1__________________|

Корневое окно этого фрейма является внутренним окном W1. Его дочерние окна образуют горизонтальную комбинацию, состоящую из живого окна W2 и внутреннего окна W3. Дочерние окна W3 образуют вертикальную комбинацию, состоящую из живых окон W4 и W5. Следовательно, живыми окнами в этом дереве окон являются W2, W4 и W5.

Следующие функции можно использовать для получения дочернего окна внутреннего окна и родственных окон дочернего окна. Их аргумент window всегда по умолчанию равен выбранному окну (см. Выбор окон).

Функция: window-top-child &optional window

Эта функция возвращает самое верхнее дочернее окно window’а, если window является внутренним окном, дочерние элементы которого образуют вертикальную комбинацию. Для любого другого типа окна возвращаемое значение равно nil.

Функция: window-left-child &optional window

Эта функция возвращает самое левое дочернее окно window’а, если window является внутренним окном, дочерние элементы которого образуют горизонтальную комбинацию. Для любого другого типа окна возвращаемое значение равно nil.

Функция: window-child window

Эта функция возвращает первое дочернее окно внутреннего окна window — самое верхнее дочернее окно для вертикальной комбинации или самое левое дочернее окно для горизонтальной комбинации. Если window является живым окном, возвращаемое значение равно nil.

Функция: window-combined-p &optional window horizontal

Эта функция возвращает ненулевое значение (nil) тогда и только тогда, когда window является частью вертикальной комбинации.

Если необязательный аргумент horizontal не равен nil, это означает, что нужно вернуть ненулевое значение тогда и только тогда, когда window является частью горизонтальной комбинации.

Функция: window-next-sibling &optional window

Эта функция возвращает следующее родственное окно указанного window’а. Возвращаемое значение равно nil, если window является последним дочерним элементом своего родителя.

Функция: window-prev-sibling &optional window

Эта функция возвращает предыдущее родственное окно указанного window’а. Возвращаемое значение равно nil, если window является первым дочерним элементом своего родителя.

Функции window-next-sibling и window-prev-sibling не следует путать с функциями next-window и previous-window, которые возвращают следующее и предыдущее окно в циклическом упорядочении окон (см. Циклическое упорядочение окон).

Следующие функции могут быть полезны для поиска окна в пределах его фрейма.

Функция: frame-first-window &optional frame-or-window

Эта функция возвращает живое окно в левом верхнем углу фрейма, указанного аргументом frame-or-window. Аргумент frame-or-window должен обозначать окно или живой фрейм и по умолчанию равен выбранному фрейму. Если frame-or-window указывает окно, эта функция возвращает первое окно на фрейме этого окна. В предположении, что фрейм из нашего канонического примера выбран, (frame-first-window) возвращает W2.

Функция: window-at-side-p &optional window side

Эта функция возвращает t, если window расположен у стороны side своего содержащего фрейма. Аргумент window должен быть допустимым окном и по умолчанию равен выбранному. Аргумент side может быть любым из символов left, top, right или bottom. Значение по умолчанию nil обрабатывается как bottom.

Обратите внимание, что эта функция игнорирует окно минибуфера (см. Окна минибуфера). Следовательно, при side, равном bottom, она может вернуть t также, когда окно минибуфера появляется непосредственно под window’ом.

Функция: window-in-direction direction &optional window ignore sign wrap minibuf

Эта функция возвращает ближайшее живое окно в направлении direction, если смотреть из позиции window-point в окне window. Аргумент direction должен быть одним из above, below, left или right. Необязательный аргумент window должен обозначать живое окно и по умолчанию равен выбранному.

Эта функция не возвращает окно, параметр no-other-window которого не равен nil (см. Параметры окон). Если у ближайшего окна параметр no-other-window не равен nil, эта функция пытается найти другое окно в указанном направлении, у которого параметр no-other-window равен nil. Если необязательный аргумент ignore не равен nil, окно может быть возвращено, даже если его параметр no-other-window не равен nil.

Если необязательный аргумент sign является отрицательным числом, это означает, что в качестве опорной позиции следует использовать правый или нижний край window’а вместо window-point. Если sign является положительным числом, это означает, что в качестве опорной позиции следует использовать левый или верхний край window’а.

Если необязательный аргумент wrap не равен nil, это означает, что нужно обернуть направление direction вокруг границ фрейма. Например, если window находится в верхней части фрейма, а direction равен above, то эта функция обычно возвращает окно минибуфера фрейма, если оно активно, и окно в нижней части фрейма в противном случае.

Если необязательный аргумент minibuf равен t, эта функция может возвращать окно минибуфера, даже если оно не активно. Если необязательный аргумент minibuf равен nil, это означает, что окно минибуфера возвращается тогда и только тогда, когда оно в данный момент активно. Если minibuf не равен ни nil, ни t, эта функция никогда не возвращает окно минибуфера. Однако если wrap не равен nil, он всегда действует так, как если бы minibuf был равен nil.

Если подходящее окно не найдено, эта функция возвращает nil.

Не используйте эту функцию, чтобы проверить, нет ли окна в направлении direction. Вызов window-at-side-p, описанный выше, является гораздо более эффективным способом сделать это.

Следующая функция извлекает все дерево окон фрейма:

Функция: window-tree &optional frame

Эта функция возвращает список, представляющий дерево окон для фрейма frame. Если frame опущен или равен nil, по умолчанию используется выбранный фрейм.

Возвращаемое значение — это список вида (root mini), где root представляет дерево окон корневого окна фрейма, а mini — окно минибуфера фрейма.

Если корневое окно является живым, root — это само это окно. В противном случае root — это список (dir edges w1 w2 ...), где dir равен nil для горизонтальной комбинации и t для вертикальной комбинации, edges задает размер и положение комбинации, а остальные элементы являются дочерними окнами. Каждое дочернее окно, в свою очередь, может быть объектом окна (для живого окна) или списком с тем же форматом, что и выше (для внутреннего окна). Элемент edges — это список (left top right bottom), аналогичный значению, возвращаемому window-edges (см. Координаты и окна).