[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

29. Window and Frame Geometry


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

29.1 Intro to Window and Frame Geometry

Here is an ASCII diagram:

 
+------------------------------------------------------------------------|
|                         window-manager decoration                      |
| +--------------------------------------------------------------------+ |
| |                               menubar                              | |
| ###################################################################### |
| #                               toolbar                              # |
| #--------------------------------------------------------------------# |
| #  |                        internal border                       |  # |
| #  | +----------------------------------------------------------+ |  # |
| #  | |                          gutter                          | |  # |
| #  | |-********************************************************-| |  # |
|w#  | | *        scrollbar        |v*                      |s* | |  #w|
|i#  | | *-+-------------------------|e*                      |c* | |  #i|
|n#  | | *s|                         |r*                      |r* | |  #n|
|d#  | | *c|                         |t*                      |o* | |  #d|
|o#  | | *r|                         |.*      text area       |l* | |  #o|
|w#  |i| *o|                         | *                      |l* |i|  #w|
|-#  |n| *l|        text area        |d*                      |b* |n|  #-|
|m#  |t| *l|                         |i*                      |a* |t|  #m|
|a#  |e| *b|                         |v*                      |r* |e|  #a|
|n# t|r| *a|                         |i*----------------------+-* |r|t #n|
|a# o|n|g*r|                         |d*      scrollbar       |
g|n|o #a|
|g# o|a|u*-+-------------------------|e*----------------------+-*u|a|o #g|
|e# l|l|t*        modeline           |r*      modeline          *t|l|l #e|
|r# b| |t********************************************************t| |b #r|
| # a|b|e*   =..texttexttex....=   |s|v*                      |s*e|b|a # |
|d# r|o|r*o m=..texttexttextt..=o m|c|e*                      |c*r|o|r #d|
|e#  |r| *u a=.exttexttextte...=u a|r|r*                      |r* |r|  #e|
|c#  |d| *t r=....texttexttex..=t r|o|t*                      |o* |d|  #c|
|o#  |e| *s g=        etc.     =s g|l|.*      text area       |l* |e|  #o|
|r#  |r| *i i=                 =i i|l| *                      |l* |r|  #r|
|a#  | | *d n=                 =d n|b|d*                      |b* | |  #a|
|t#  | | *e  = inner text area =e  |a|i*                      |a* | |  #t|
|i#  | | *   =                 =   |r|v*                      |r* | |  #i|
|o#  | | *---===================---+-|i*----------------------+-* | |  #o|
|n#  | | *        scrollbar        |d*      scrollbar       |
 | |  #n|
| #  | | *-------------------------+-|e*----------------------+-* | |  # |
| #  | | *        modeline           |r*      modeline          * | |  # |
| #  | |-********************************************************-| |  # |
| #  | |                           gutter                         | |  # |
| #  | |-********************************************************-| |  # |
| #  | |
                       minibuffer                     * |  # |
| #  | +-********************************************************-+ |  # |
| #  |                         internal border                      |  # |
| #--------------------------------------------------------------------# |
| #                                toolbar                             # |
| ###################################################################### |
|                          window manager decoration                     |
+------------------------------------------------------------------------+

# = boundary of client area; * = window boundaries, boundary of paned area
= = boundary of inner text area; . = inside margin area;  = dead boxes

Note in particular what happens at the corners, where a “corner box” occurs. Top and bottom toolbars take precedence over left and right toolbars, extending out horizontally into the corner boxes. Gutters work the same way. The corner box where the scrollbars meet, however, is assigned to neither scrollbar, and is known as the “dead box”; it is an area that must be cleared specially. There are similar dead boxes at the bottom-right and bottom-left corners where the minibuffer and left/right gutters meet, but there is currently a bug in that these dead boxes are not explicitly cleared and may contain junk.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

29.2 The Frame

The “top-level window area” is the entire area of a top-level window (or “frame”). The “client area” (a term from MS Windows) is the area of a top-level window that XEmacs draws into and manages with redisplay. This includes the toolbar, scrollbars, gutters, dividers, text area, modeline and minibuffer. It does not include the menubar, title or outer borders. The “non-client area” is the area of a top-level window outside of the client area and includes the menubar, title and outer borders. Internally, all frame coordinates are relative to the client area.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

29.3 The Non-Client Area

Under X, the non-client area is split into two parts:

  1. The outer layer is the window-manager decorations: The title and borders. These are controlled by the window manager, a separate process that controls the desktop, the location of icons, etc. When a process tries to create a window, the window manager intercepts this action and “reparents” the window, placing another window around it which contains the window decorations, including the title bar, outer borders used for resizing, etc. The window manager also implements any actions involving the decorations, such as the ability to resize a window by dragging its borders, move a window by dragging its title bar, etc. If there is no window manager or you kill it, windows will have no decorations (and will lose them if they previously had any) and you will not be able to move or resize them.
  2. Inside of the window-manager decorations is the “shell”, which is managed by the toolkit and widget libraries your program is linked with. The code in ‘*-x.c’ uses the Xt toolkit and various possible widget libraries built on top of Xt, such as Motif, Athena, the “Lucid” widgets, etc. Another possibility is GTK (‘*-gtk.c’), which implements both the toolkit and widgets. Under Xt, the “shell” window is an EmacsShell widget, containing an EmacsManager widget of the same size, which in turn contains a menubar widget and an EmacsFrame widget, inside of which is the client area. (The division into EmacsShell and EmacsManager is due to the complex and screwy geometry-management system in Xt [and X more generally]. The EmacsShell handles negotiation with the window manager; the place of the EmacsManager widget is normally assumed by a widget that manages the geometry of its child widgets, but the EmacsManager widget just lets the XEmacs redisplay mechanism do the positioning.)

Under Windows, the non-client area is managed by the window system. There is no division such as under X. Part of the window-system API (‘USER.DLL’) of Win32 includes functions to control the menubars, title, etc. and implements the move and resize behavior. There is an equivalent of the window manager, called the “shell”, but it manages only the desktop, not the windows themselves. The normal shell under Windows is ‘EXPLORER.EXE’; if you kill this, you will lose the bar containing the “Start” menu and tray and such, but the windows themselves will not be affected or lose their decorations.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

29.4 The Client Area

Inside of the client area is the toolbars, the gutters (where the buffer tabs are displayed), the minibuffer, the internal border width, and one or more non-overlapping “windows” (this is old Emacs terminology, from before the time when frames existed at all; the standard terminology for this would be “pane”). Each window can contain a modeline, horizontal and/or vertical scrollbars, and (for non-rightmost windows) a vertical divider, surrounding a text area.

The dimensions of the toolbars and gutters are determined by the formula (THICKNESS + 2 * BORDER-THICKNESS), where “thickness” is a cover term for height or width, as appropriate. The height and width come from default-toolbar-height and default-toolbar-width and the specific versions of these (top-toolbar-height, left-toolbar-width, etc.). The border thickness comes from default-toolbar-border-height and default-toolbar-border-width, and the specific versions of these. The gutter works exactly equivalently.

Note that for any particular toolbar or gutter, it will only be displayed if [a] its visibility specifier (default-toolbar-visible-p etc.) is non-nil; [b] its thickness (default-toolbar-height etc.) is greater than 0; [c] its contents (default-toolbar etc.) are non-nil.

The position-specific toolbars interact with the default specifications as follows: If the value for a position-specific specifier is not defined in a particular domain (usually a window), and the position of that specifier is set as the default position (using default-toolbar-position), then the value from the corresponding default specifier in that domain will be used. The gutters work the same.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

29.5 The Paned Area

The area occupied by the “windows” is called the paned area. Unfortunately, because of the presence of the gutter between the minibuffer and other windows, the bottom of the paned area is not well-defined – does it include the minibuffer (in which case it also includes the bottom gutter, but none others) or does it not include the minibuffer? (In which case not all windows are included.) It would be cleaner to put the bottom gutter below the minibuffer instead of above it.

Each window can include a horizontal and/or vertical scrollbar, a modeline and a vertical divider to its right, as well as the text area. Only non-rightmost windows can include a vertical divider. (The minibuffer normally does not include either modeline or scrollbars.)

Note that, because the toolbars and gutters are controlled by specifiers, and specifiers can have window-specific and buffer-specific values, the size of the paned area can change depending on which window is selected: In other words, if the selected window or buffer changes, the entire paned area for the frame may change.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

29.6 Text Areas, Fringes, Margins

The space occupied by a window can be divided into the text area and the fringes. The fringes include the modeline, scrollbars and vertical divider on the right side (if any); inside of this is the text area, where the text actually occurs. Note that a window may or may not contain any of the elements that are part of the fringe – this is controlled by specifiers, e.g. has-modeline-p, horizontal-scrollbar-visible-p, vertical-scrollbar-visible-p, vertical-divider-always-visible-p, etc.

In addition, it is possible to set margins in the text area using the specifiers left-margin-width and right-margin-width. When this is done, only the “inner text area” (the area inside of the margins) will be used for normal display of text; the margins will be used for glyphs with a layout policy of outside-margin (as set on an extent containing the glyph by set-extent-begin-glyph-layout or set-extent-end-glyph-layout). However, the calculation of the text area size (e.g. in the function window-text-area-width) includes the margins. Which margin is used depends on whether a glyph has been set as the begin-glyph or end-glyph of an extent (set-extent-begin-glyph etc.), using the left and right margins, respectively.

Technically, the margins outside of the inner text area are known as the “outside margins”. The “inside margins” are in the inner text area and constitute the whitespace between the outside margins and the first or last non-whitespace character in a line; their width can vary from line to line. Glyphs will be placed in the inside margin if their layout policy is inside-margin or whitespace, with whitespace glyphs on the inside and inside-margin glyphs on the outside. Inside-margin glyphs can spill over into the outside margin if use-left-overflow or use-right-overflow, respectively, is non-nil.

See the Lisp Reference manual, under Annotations, for more details.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

29.7 The Displayable Area

The “displayable area” is not so much an actual area as a convenient fiction. It is the area used to convert between pixel and character dimensions for frames. The character dimensions for a frame (e.g. as returned by frame-width and frame-height and set by set-frame-width and set-frame-height) are determined from the displayable area by dividing by the pixel size of the default font as instantiated in the frame. (For proportional fonts, the “average” width is used. Under Windows, this is a built-in property of the fonts. Under X, this is based on the width of the lowercase ’n’, or if this is zero then the width of the default character. [We prefer ’n’ to the specified default character because many X fonts have a default character with a zero or otherwise non-representative width.])

The displayable area is essentially the “theoretical” gutter area of the frame, excluding the rightmost and bottom-most scrollbars. That is, it starts from the client (or “total”) area and then excludes the “theoretical” toolbars and bottom-most/rightmost scrollbars, and the internal border width. In this context, “theoretical” means that all calculations on based on frame-level values for toolbar and scrollbar thicknesses. Because these thicknesses are controlled by specifiers, and specifiers can have window-specific and buffer-specific values, these calculations may or may not reflect the actual size of the paned area or of the scrollbars when any particular window is selected. Note also that the “displayable area” may not even be contiguous! In particular, the gutters are included, but the bottom-most and rightmost scrollbars are excluded even though they are inside of the gutters. Furthermore, if the frame-level value of the horizontal scrollbar height is non-zero, then the displayable area includes the paned area above and below the bottom horizontal scrollbar (i.e. the modeline and minibuffer) but not the scrollbar itself.

As a further twist, the character-dimension calculations are adjusted so that the truncation and continuation glyphs (see truncation-glyph and continuation-glyph) count as a single character even if they are wider than the default font width. (Technically, the character width is computed from the displayable-area width by subtracting the maximum of the truncation-glyph width, continuation-glyph width and default-font width before dividing by the default-font width, and then adding 1 to the result.) (The ultimate motivation for this kludge as well as the subtraction of the scrollbars, but not the minibuffer or bottom-most modeline, is to maintain compatibility with TTY’s.)

Despite all these concerns and kludges, however, the “displayable area” concept works well in practice and mostly ensures that by default the frame will actually fit 79 characters + continuation/truncation glyph.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

29.8 Which Functions Use Which?

  1. Top-level window area:
     
    set-frame-position
    left and top frame properties
    
  2. Client area:
     
    frame-pixel-*, set-frame-pixel-*
    
  3. Paned area:
     
    window-pixel-edges
    event-x-pixel, event-y-pixel, event-properties, make-event
    
  4. Displayable area:
     
    frame-width, frame-height and other all functions specifying frame size
      in characters
    frame-displayable-pixel-*
    

[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Aidan Kehoe on December 27, 2016 using texi2html 1.82.