mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-02-16 17:24:23 +00:00
Provide additional support for child frames
Provide mouse dragging and resizing of frames. Allow resizing frames proportionally. Provide additional functionality for child frames. Minor bug fixes. * lisp/frame.el (frame-border-width, frame-pixel-width) (frame-pixel-height): Alias to `frame-internal-border-width', `frame-native-width' and `frame-native-height'. (frame-inner-width, frame-inner-height, frame-outer-width) (frame-outer-height): New functions. * lisp/minibuffer.el (completion-auto-help): Fix typo. * lisp/mouse.el (mouse-drag-line, mouse-drag-mode-line) (mouse-drag-header-line): Allow moving a frame by dragging the mode line of its bottommost window (on a minibuffer-less frame) or the header line of its topmost window. (mouse-drag-vertical-line): Mention argument in doc-string. (mouse-resize-frame, mouse-drag-frame, mouse-drag-left-edge) (mouse-drag-top-left-corner, mouse-drag-top-edge) (mouse-drag-top-right-corner, mouse-drag-right-edge) (mouse-drag-bottom-right-corner, mouse-drag-bottom-edge) (mouse-drag-bottom-left-corner): New functions for resizing a frame by dragging its internal border together with corresponding key bindings. * lisp/tooltip.el (tooltip-frame-parameters): Add 'no-special-glyphs' to default parameters and update version tag. * lisp/window.el (frame-auto-hide-function): Add choice to make frame invisible and update version tag. (window--delete): Handle 'auto-hide-function' frame parameter. (window--maybe-raise-frame): Respect 'no-focus-on-map' and 'no-accept-focus' frame parameters. (display-buffer--action-function-custom-type): Add `display-buffer-in-child-frame'. (display-buffer): Mention `display-buffer-in-child-frame' in doc-string. (display-buffer-in-child-frame): New action function for `display-buffer'. (window--sanitize-margin): Return zero when MARGIN cannot be sanitized. (fit-frame-to-buffer): Major rewrite to handle child frames and 'fit-frame-to-buffer-sizes' and 'fit-frame-to-buffer-margins' frame parameters. (window-largest-empty-rectangle--maximums-1) (window-largest-empty-rectangle--maximums) (window-largest-empty-rectangle--disjoint-maximums) (window-largest-empty-rectangle): New functions. * src/dispextern.h (WINDOW_WANTS_MODELINE_P) (WINDOW_WANTS_HEADER_LINE_P): Remove. Functionality is now provided by corresponding functions window_wants_modeline and window_wants_header_line in window.c. Adjust users. * src/dispnew.c (adjust_glyph_matrix) (buffer_posn_from_coords): Use window_wants_modeline and window_wants_header_line instead of WINDOW_WANTS_MODELINE_P and WINDOW_WANTS_HEADER_LINE_P. * src/frame.c (keep_ratio): New function. (adjust_frame_size): Call keep_ratio for each of F's child frames. (make_frame): Initialize no_special_glyphs slot. (frame_internal_border_part): New function. (Fframe_pixel_width, Fframe_pixel_height, Fborder_width): Rename to Fframe_native_width, Fframe_native_height mand Fframe_internal_border_width. (frame_parm_table): Add Qno_special_glyphs entry. (frame_float_type): New enumeration type. (frame_float): New function to handle frame size and position ratios. (x_set_frame_parameters): Handle size and position ratios. (x_set_no_special_glyphs): New function (x_figure_window_size): Handle size and position ratios. (syms_of_frame): Add Qdisplay_monitor_attributes_list, Qno_special_glyphs, Qframe_edges, Qkeep_ratio, Qwidth_only, Qheight_only, Qleft_only and Qtop_only. * src/frame.h (internal_border_part): New enumeration type. (struct frame): New slot no_special_glyphs. (FRAME_NO_SPECIAL_GLYPHS): New macro. * src/gtkutil.c (xg_frame_restack): Return immediately for GTK versions before 2.18.0. * src/keyboard.c (internal_border_parts): New array constant. (make_lispy_position): For frames with border dragging enabled return internal border part. (syms_of_keyboard): New symbols Qdrag_internal_border, Qleft_edge, Qtop_left_corner, Qtop_edge, Qtop_right_corner, Qright_edge, Qbottom_right_corner, Qbottom_edge and Qbottom_left_corner. * src/minibuf.c (read_minibuf_unwind): When exiting the minibuffer deal with frames that have the 'minibuffer-exit' parameter set. (syms_of_minibuf): New symbol Qminibuffer_exit. * src/nsfns.m (frame_parm_handler): Add entry for x_set_no_special_glyphs. (Fx_create_frame): Handle 'no-special-glyphs' parameter. Intitialize new cursor types for dragging frame borders. * src/nsterm.h (struct ns_output): Add new cursor types for dragging frame borders. * src/w32fns.c (w32_frame_parm_handlers): Add entry for x_set_no_special_glyphs. (Fx_create_frame): Handle 'no-special-glyphs' parameter. Intitialize new cursor types for dragging frame borders. * src/w32term.h (struct w32_output): Add new cursor types for dragging frame borders. * src/window.c (coordinates_in_window) (Fwindow_line_height, window_internal_height): Use window_wants_modeline and window_wants_header_line instead of WINDOW_WANTS_MODELINE_P and WINDOW_WANTS_HEADER_LINE_P. (Fwindow_lines_pixel_dimensions): New function. (window_parameter): New function. (Fwindow_parameter): Call window_parameter. (window_wants_mode_line, window_wants_header_line): New functions replacing the macros WINDOW_WANTS_MODELINE_P and WINDOW_WANTS_HEADER_LINE_P from dispextern.h. (syms_of_window): New symbols Qmode_line_format and Qheader_line_format. * src/window.h: Reorganize and re-comment macros. Use window_wants_modeline and window_wants_header_line instead of WINDOW_WANTS_MODELINE_P and WINDOW_WANTS_HEADER_LINE_P. (MINI_NON_ONLY_WINDOW_P, MINI_ONLY_WINDOW_P): Minor rewrite. (WINDOW_BUFFER): New macro. (WINDOW_BOX_LEFT_EDGE_COL, WINDOW_BOX_RIGHT_EDGE_COL): Remove. * src/xdisp.c (window_text_bottom_y, window_box_height) (window_box, start_display) (compute_window_start_on_continuation_line) (try_cursor_movement, redisplay_window) (try_window_reusing_current_matrix, try_window_id) (display_line, expose_window): Use window_wants_modeline and window_wants_header_line instead of WINDOW_WANTS_MODELINE_P and WINDOW_WANTS_HEADER_LINE_P. (pos_visible_p, display_mode_lines): Respect W's 'mode-line-format' and 'header-line-format' window parameters. (init_iterator): Use window_wants_modeline and window_wants_header_line instead of WINDOW_WANTS_MODELINE_P and WINDOW_WANTS_HEADER_LINE_P. For tip frames respect no_special_glyphs value. (note_mouse_highlight): Set frame border cursors when on internal border. (x_draw_right_divider, x_draw_bottom_divider): Try to improve drawing of window dividers. * src/xfns.c (mouse_cursor): Add entries for border parts. (mouse_cursor_types): Add entries for cursor types to drag frame borders. (INSTALL_CURSOR): Add entries for new cursor types to drag frame borders. (Fx_create_frame): Handle 'no-special-glyphs' parameter. (x_frame_parm_handlers): Add entry for x_set_no_special_glyphs. (Vx_window_left_edge_shape, Vx_window_top_left_corner_shape) (Vx_window_top_edge_shape, Vx_window_top_right_corner_shape) (Vx_window_right_edge_shape) (Vx_window_bottom_right_corner_shape) (Vx_window_bottom_edge_shape) (Vx_window_bottom_left_corner_shape): New variables. (x_frame_restack): Call xg_frame_restack only for GTK versions starting with 2.18.0. * src/xterm.c (x_free_frame_resources): Remove new cursors for dragging frame borders. * src/xterm.h (struct x_output): Add new cursor types for dragging frame borders. * doc/lispref/display.texi (Size of Displayed Text): Document `window-lines-pixel-dimensions'. * doc/lispref/elisp.texi (Top): Add entry for "Mouse Dragging Parameters". * doc/lispref/frames.texi (Frame Size): Replace frame-pixel-width/-height by frame-native-width/-height. Add frame-inner-width/-height and frame-outer-width/-height docs. (Position Parameters): Describe specifying position as ratios. Clarify remark about positions relative to bottom/ridge display edge. (Size Parameters): Describe specifying sizes as ratios. Describe 'fit-frame-to-buffer-margins' and 'fit-frame-to-buffer-sizes' parameters. (Layout Parameters): Describe 'no-special-glyphs' parameter. (Frame Interaction Parameters): Describe 'auto-hide-function', 'minibuffer-exit' and 'keep-ratio' parameters. (Mouse Dragging Parameters): New section describing 'drag-internal-border', 'drag-with-header-line', 'drag-with-mode-line', 'snap-width', 'top-visible' and 'bottom-visible' parameters. (Management Parameters): Mention that `override-redirect' has no effect on MS Windows. (Font and Color Parameters): Mention child frames for `alpha' parameter. (Child Frames): Rewrite section with description and cross references to new frame parameters added. * doc/lispref/modes.texi (Mode Line Basics): Mention 'mode-line-format' and 'header-line-format' window parameters. * doc/lispref/windows.texi (Resizing Windows): Mention effect of `fit-frame-to-buffer-margins' for child frames. (Display Action Functions): New action function `display-buffer-in-child-frame'. (Quitting Windows): Mention `make-frame-invisible' as optional value of `frame-auto-hide-function' and `auto-hide-function' frame paameter. (Coordinates and Windows): Describe new function `window-largest-empty-rectangle'. (Window Parameters): Describe new parameters 'mode-line-format' and 'header-line-format'. Index all window parameters described in this section.
This commit is contained in:
parent
4314713764
commit
1886246f6f
29 changed files with 2907 additions and 752 deletions
|
|
@ -1974,6 +1974,71 @@ line, if present, in the return value. If it is @code{t}, include the
|
|||
height of both, if present, in the return value.
|
||||
@end defun
|
||||
|
||||
@code{window-text-pixel-size} treats the text displayed in a window as a
|
||||
whole and does not care about the size of individual lines. The
|
||||
following function does.
|
||||
|
||||
@defun window-lines-pixel-dimensions &optional window first last body inverse
|
||||
This function calculates the pixel dimensions of each line displayed in
|
||||
the specified @var{window}. It does so by walking @var{window}'s
|
||||
current glyph matrix---a matrix storing the glyph (@pxref{Glyphs}) of
|
||||
each buffer character currently displayed in @var{window}. If
|
||||
successful, it returns a list of cons pairs representing the x- and
|
||||
y-coordinates of the lower right corner of the last character of each
|
||||
line. Coordinates are measured in pixels from an origin (0, 0) at the
|
||||
top-left corner of @var{window}. @var{window} must be a live window and
|
||||
defaults to the selected one.
|
||||
|
||||
If the optional argument @var{first} is an integer, it denotes the index
|
||||
(starting with 0) of the first line of @var{window}'s glyph matrix to be
|
||||
returned. Note that if @var{window} has a header line, the line with
|
||||
index 0 is that header line. If @var{first} is nil, the first line to
|
||||
be considered is determined by the value of the optional argument
|
||||
@var{body}: If @var{body} is non-@code{nil}, this means to start with
|
||||
the first line of @var{window}'s body, skipping any header line, if
|
||||
present. Otherwise, this function will start with the first line of
|
||||
@var{window}'s glyph matrix, possibly the header line.
|
||||
|
||||
If the optional argument @var{last} is an integer, it denotes the index
|
||||
of the last line of @var{window}'s glyph matrix that shall be returned.
|
||||
If @var{last} is nil, the last line to be considered is determined by
|
||||
the value of @var{body}: If @var{body} is non-@code{nil}, this means to
|
||||
use the last line of @var{window}'s body, omitting @var{window}'s mode
|
||||
line, if present. Otherwise, this means to use the last line of
|
||||
@var{window} which may be the mode line.
|
||||
|
||||
The optional argument @var{inverse}, if @code{nil}, means that the
|
||||
y-pixel value returned for any line specifies the distance in pixels
|
||||
from the left edge (body edge if @var{body} is non-@code{nil}) of
|
||||
@var{window} to the right edge of the last glyph of that line.
|
||||
@var{inverse} non-@code{nil} means that the y-pixel value returned for
|
||||
any line specifies the distance in pixels from the right edge of the
|
||||
last glyph of that line to the right edge (body edge if @var{body} is
|
||||
non-@code{nil}) of @var{window}. This is useful for determining the
|
||||
amount of slack space at the end of each line.
|
||||
|
||||
The optional argument @var{left}, if non-@code{nil} means to return the
|
||||
x- and y-coordinates of the lower left corner of the leftmost character
|
||||
on each line. This is the value that should be used for windows that
|
||||
mostly display text from right to left.
|
||||
|
||||
If @var{left} is non-@code{nil} and @var{inverse} is @code{nil}, this
|
||||
means that the y-pixel value returned for any line specifies the
|
||||
distance in pixels from the left edge of the last (leftmost) glyph of
|
||||
that line to the right edge (body edge if @var{body} is non-@code{nil})
|
||||
of @var{window}. If @var{left} and @var{inverse} are both
|
||||
non-@code{nil}, the y-pixel value returned for any line specifies the
|
||||
distance in pixels from the left edge (body edge if @var{body} is
|
||||
non-@code{nil}) of @var{window} to the left edge of the last (leftmost)
|
||||
glyph of that line.
|
||||
|
||||
This function returns @code{nil} if the current glyph matrix of
|
||||
@var{window} is not up-to-date which usually happens when Emacs is busy,
|
||||
for example, when processing a command. The value should be retrievable
|
||||
though when this function is run from an idle timer with a delay of zero
|
||||
seconds.
|
||||
@end defun
|
||||
|
||||
@defun line-pixel-height
|
||||
This function returns the height in pixels of the line at point in the
|
||||
selected window. The value includes the line spacing of the line
|
||||
|
|
|
|||
|
|
@ -1130,6 +1130,8 @@ Window Frame Parameters
|
|||
* Buffer Parameters:: Which buffers have been or should be shown.
|
||||
* Frame Interaction Parameters:: Parameters for interacting with other
|
||||
frames.
|
||||
* Mouse Dragging Parameters:: Parameters for resizing and moving
|
||||
frames with the mouse.
|
||||
* Management Parameters:: Communicating with the window manager.
|
||||
* Cursor Parameters:: Controlling the cursor appearance.
|
||||
* Font and Color Parameters:: Fonts and colors for the frame text.
|
||||
|
|
|
|||
|
|
@ -974,14 +974,7 @@ Parameters}). The text size of the initial frame can be also set with
|
|||
the help of an X-style geometry specification. @xref{Emacs Invocation,,
|
||||
Command Line Arguments for Emacs Invocation, emacs, The GNU Emacs
|
||||
Manual}. Below we list some functions to access and set the size of an
|
||||
existing, visible frame.
|
||||
|
||||
@defun frame-text-height &optional frame
|
||||
@defunx frame-text-width &optional frame
|
||||
These functions return the height and width of the text area of
|
||||
@var{frame} (@pxref{Frame Layout}), measured in pixels. For a text
|
||||
terminal, the results are in characters rather than pixels.
|
||||
@end defun
|
||||
existing, visible frame, by default the selected one.
|
||||
|
||||
@defun frame-height &optional frame
|
||||
@defunx frame-width &optional frame
|
||||
|
|
@ -997,11 +990,33 @@ rounded down to the number of characters of the default font that fully
|
|||
fit into the text area.
|
||||
@end defun
|
||||
|
||||
@defun frame-pixel-height &optional frame
|
||||
@defunx frame-pixel-width &optional frame
|
||||
These functions return the native width and height, see @ref{Frame
|
||||
Layout}) of @var{frame} in pixels. For a text terminal, the results are
|
||||
in characters rather than pixels.
|
||||
The functions following next return the pixel widths and heights of the
|
||||
native, outer and inner frame and the text area (@pxref{Frame Layout})
|
||||
of a given frame. For a text terminal, the results are in characters
|
||||
rather than pixels.
|
||||
|
||||
@defun frame-outer-width &optional frame
|
||||
@defunx frame-outer-height &optional frame
|
||||
These functions return the outer width and height of @var{frame} in
|
||||
pixels.
|
||||
@end defun
|
||||
|
||||
@defun frame-native-height &optional frame
|
||||
@defunx frame-native-width &optional frame
|
||||
These functions return the native width and height of @var{frame} in
|
||||
pixels.
|
||||
@end defun
|
||||
|
||||
@defun frame-inner-width &optional frame
|
||||
@defunx frame-inner-height &optional frame
|
||||
These functions return the inner width and height of @var{frame} in
|
||||
pixels.
|
||||
@end defun
|
||||
|
||||
@defun frame-text-width &optional frame
|
||||
@defunx frame-text-height &optional frame
|
||||
These functions return the width and height of the text area of
|
||||
@var{frame} in pixels.
|
||||
@end defun
|
||||
|
||||
On window systems that support it, Emacs tries by default to make the
|
||||
|
|
@ -1345,6 +1360,8 @@ text terminals.
|
|||
* Buffer Parameters:: Which buffers have been or should be shown.
|
||||
* Frame Interaction Parameters:: Parameters for interacting with other
|
||||
frames.
|
||||
* Mouse Dragging Parameters:: Parameters for resizing and moving
|
||||
frames with the mouse.
|
||||
* Management Parameters:: Communicating with the window manager.
|
||||
* Cursor Parameters:: Controlling the cursor appearance.
|
||||
* Font and Color Parameters:: Fonts and colors for the frame text.
|
||||
|
|
@ -1404,18 +1421,19 @@ named, this parameter will be @code{nil}.
|
|||
@cindex frame position
|
||||
|
||||
Parameters describing the X- and Y-offsets of a frame are always
|
||||
measured in pixels. For normal, non-child frames they specify the
|
||||
frame's absolute outer position (@pxref{Frame Geometry}) with respect to
|
||||
its display's origin. For a child frame (@pxref{Child Frames}) they
|
||||
specify the frame's outer position relative to the native position of
|
||||
the frame's parent frame. (Note that none of these parameters is
|
||||
meaningful on TTY frames.)
|
||||
measured in pixels. For a normal, non-child frame they specify the
|
||||
frame's outer position (@pxref{Frame Geometry}) relative to its
|
||||
display's origin. For a child frame (@pxref{Child Frames}) they specify
|
||||
the frame's outer position relative to the native position of the
|
||||
frame's parent frame. (Note that none of these parameters is meaningful
|
||||
on TTY frames.)
|
||||
|
||||
@table @code
|
||||
@vindex left, a frame parameter
|
||||
@item left
|
||||
The position, in pixels, of the left outer edge of the frame with
|
||||
respect to the left edge of the frame's display or parent frame.
|
||||
respect to the left edge of the frame's display or parent frame. It can
|
||||
be specified in one of the following ways.
|
||||
|
||||
@table @asis
|
||||
@item an integer
|
||||
|
|
@ -1436,6 +1454,30 @@ right edge of the display or parent frame. The integer @var{pos} may be
|
|||
positive or negative; a negative value specifies a position outside the
|
||||
screen or parent frame or on a monitor other than the primary one (for
|
||||
multi-monitor displays).
|
||||
|
||||
@cindex left position ratio
|
||||
@cindex top position ratio
|
||||
@item a floating-point value
|
||||
A floating-point value in the range 0.0 to 1.0 specifies the left edge's
|
||||
offset via the @dfn{left position ratio} of the frame---the ratio of the
|
||||
left edge of its outer frame to the width of the frame's workarea
|
||||
(@pxref{Multiple Terminals}) or its parent's native frame (@pxref{Child
|
||||
Frames}) minus the width of the outer frame. Thus, a left position
|
||||
ratio of 0.0 flushes a frame to the left, a ratio of 0.5 centers it and
|
||||
a ratio of 1.0 flushes it to the right of its display or parent frame.
|
||||
Similarly, the @dfn{top position ratio} of a frame is the ratio of the
|
||||
frame's top position to the height of its workarea or parent frame minus
|
||||
the height of the frame.
|
||||
|
||||
Emacs will try to keep the position ratios of a child frame unaltered if
|
||||
that frame has a non-@code{nil} @code{keep-ratio} parameter
|
||||
(@pxref{Frame Interaction Parameters}) and its parent frame is resized.
|
||||
|
||||
Since the outer size of a frame (@pxref{Frame Geometry}) is usually
|
||||
unavailable before a frame has been made visible, it is generally not
|
||||
advisable to use floating-point values when creating decorated frames.
|
||||
Floating-point values are more suited for ensuring that an (undecorated)
|
||||
child frame is positioned nicely within the area of its parent frame.
|
||||
@end table
|
||||
|
||||
Some window managers ignore program-specified positions. If you want to
|
||||
|
|
@ -1448,17 +1490,19 @@ following example:
|
|||
nil '((user-position . t) (left . (+ -4))))
|
||||
@end example
|
||||
|
||||
In general, it is not a good idea to specify negative offsets to
|
||||
position a frame relative to the right or bottom edge of its display.
|
||||
Positioning the initial or a new frame is either not accurate (because
|
||||
the size of the outer frame is not yet fully known before the frame has
|
||||
been made visible) or will cause additional flicker (if the frame is
|
||||
repositioned after becoming visible).
|
||||
In general, it is not a good idea to position a frame relative to the
|
||||
right or bottom edge of its display. Positioning the initial or a new
|
||||
frame is either not accurate (because the size of the outer frame is not
|
||||
yet fully known before the frame has been made visible) or will cause
|
||||
additional flicker (if the frame has to be repositioned after becoming
|
||||
visible).
|
||||
|
||||
Note also, that negative offsets are not stored internally and are not
|
||||
returned by the function @code{frame-parameters}. This means that the
|
||||
desktop saving routines will restore the frame from the positive offsets
|
||||
obtained by that function.
|
||||
Note also, that positions specified relative to the right/bottom edge
|
||||
of a display, workarea or parent frame as well as floating-point offsets
|
||||
are stored internally as integer offsets relative to the left/top edge
|
||||
of the display, workarea or parent frame edge. They are also returned
|
||||
as such by functions like @code{frame-parameters} and restored as such
|
||||
by the desktop saving routines.
|
||||
|
||||
@vindex top, a frame parameter
|
||||
@item top
|
||||
|
|
@ -1523,24 +1567,61 @@ function @code{frame-restack} (@pxref{Raising and Lowering}).
|
|||
@subsubsection Size Parameters
|
||||
@cindex window size on display
|
||||
|
||||
Frame parameters specify frame sizes in character units. On
|
||||
graphical displays, the @code{default} face determines the actual
|
||||
pixel sizes of these character units (@pxref{Face Attributes}).
|
||||
Frame parameters usually specify frame sizes in character units. On
|
||||
graphical displays, the @code{default} face determines the actual pixel
|
||||
sizes of these character units (@pxref{Face Attributes}).
|
||||
|
||||
@table @code
|
||||
@vindex width, a frame parameter
|
||||
@item width
|
||||
The width of the frame's text area (@pxref{Frame Geometry}), in
|
||||
characters. The value can be also a cons cell of the symbol
|
||||
@code{text-pixels} and an integer denoting the width of the text area in
|
||||
pixels.
|
||||
This parameter specifies the width of the frame. It can be specified as
|
||||
in the following ways:
|
||||
|
||||
@table @asis
|
||||
@item an integer
|
||||
A positive integer specifies the width of the frame's text area
|
||||
(@pxref{Frame Geometry}) in characters.
|
||||
|
||||
@item a cons cell
|
||||
If this is a cons cell with the symbol @code{text-pixels} in its
|
||||
@sc{car}, the @sc{cdr} of that cell specifies the width of the frame's
|
||||
text area in pixels.
|
||||
|
||||
@cindex frame width ratio
|
||||
@cindex frame height ratio
|
||||
@item a floating-point value
|
||||
A floating-point number between 0.0 and 1.0 can be used to specify the
|
||||
width of a frame via its @dfn{width ratio}---the ratio of its outer
|
||||
width (@pxref{Frame Geometry}) to the width of the frame's workarea
|
||||
(@pxref{Multiple Terminals}) or its parent frame's (@pxref{Child
|
||||
Frames}) native frame. Thus, a value of 0.5 makes the frame occupy half
|
||||
of the width of its workarea or parent frame, a value of 1.0 the full
|
||||
width. Similarly, the @dfn{height ratio} of a frame is the ratio of its
|
||||
outer height to the height of its workarea or its parent's native frame.
|
||||
|
||||
Emacs will try to keep the width and height ratio of a child frame
|
||||
unaltered if that frame has a non-@code{nil} @code{keep-ratio} parameter
|
||||
(@pxref{Frame Interaction Parameters}) and its parent frame is resized.
|
||||
|
||||
Since the outer size of a frame is usually unavailable before a frame
|
||||
has been made visible, it is generally not advisable to use
|
||||
floating-point values when creating decorated frames. Floating-point
|
||||
values are more suited to ensure that a child frame always fits within
|
||||
the area of its parent frame as, for example, when customizing
|
||||
@code{display-buffer-alist} (@pxref{Choosing Window}) via
|
||||
@code{display-buffer-in-child-frame}.
|
||||
@end table
|
||||
|
||||
Regardless of how this parameter was specified, functions reporting the
|
||||
value of this parameter like @code{frame-parameters} always report the
|
||||
width of the frame's text area in characters as an integer rounded, if
|
||||
necessary, to a multiple of the frame's default character width. That
|
||||
value is also used by the desktop saving routines.
|
||||
|
||||
@vindex height, a frame parameter
|
||||
@item height
|
||||
The height of the frame's text area (@pxref{Frame Geometry}), in
|
||||
characters. The value can be also a cons cell of the symbol
|
||||
@code{text-pixels} and an integer denoting the height of the text area
|
||||
in pixels.
|
||||
This parameter specifies the height of the frame. It works just like
|
||||
@code{width}, except vertically instead of horizontally.
|
||||
|
||||
@vindex user-size, a frame parameter
|
||||
@item user-size
|
||||
|
|
@ -1551,25 +1632,25 @@ user-position}) does for the position parameters @code{top} and
|
|||
|
||||
@vindex min-width, a frame parameter
|
||||
@item min-width
|
||||
This parameter specifies the minimum native width of the frame
|
||||
(@pxref{Frame Geometry}), in characters. Normally, the functions that
|
||||
This parameter specifies the minimum native width (@pxref{Frame
|
||||
Geometry}) of the frame, in characters. Normally, the functions that
|
||||
establish a frame's initial width or resize a frame horizontally make
|
||||
sure that all the frame's windows, vertical scroll bars, fringes,
|
||||
margins and vertical dividers can be displayed. This parameter, if
|
||||
non-@code{nil} allows to make a frame narrower than that with the
|
||||
consequence that any components that do not fit on the frame will be
|
||||
clipped by the window manager.
|
||||
consequence that any components that do not fit will be clipped by the
|
||||
window manager.
|
||||
|
||||
@vindex min-height, a frame parameter
|
||||
@item min-height
|
||||
This parameter specifies the minimum height of the native (@pxref{Frame
|
||||
Geometry}), in characters. Normally, the functions that establish a
|
||||
frame's initial size or resize a frame make sure that all the frame's
|
||||
windows, horizontal scroll bars and dividers, mode and header lines, the
|
||||
echo area and the internal menu and tool bar can be displayed. This
|
||||
parameter, if non-@code{nil} allows to make a frame smaller than that
|
||||
with the consequence that any components that do not fit on the frame
|
||||
will be clipped by the window-system or window manager.
|
||||
This parameter specifies the minimum native height (@pxref{Frame
|
||||
Geometry}) of the frame, in characters. Normally, the functions that
|
||||
establish a frame's initial size or resize a frame make sure that all
|
||||
the frame's windows, horizontal scroll bars and dividers, mode and
|
||||
header lines, the echo area and the internal menu and tool bar can be
|
||||
displayed. This parameter, if non-@code{nil} allows to make a frame
|
||||
smaller than that with the consequence that any components that do not
|
||||
fit will be clipped by the window manager.
|
||||
|
||||
@cindex fullboth frames
|
||||
@cindex fullheight frames
|
||||
|
|
@ -1623,6 +1704,20 @@ file as, for example
|
|||
|
||||
This will give a new frame full height after typing in it @key{F11} for
|
||||
the first time.
|
||||
|
||||
@vindex fit-frame-to-buffer-margins, a frame parameter
|
||||
@item fit-frame-to-buffer-margins
|
||||
This parameter allows to override the value of the option
|
||||
@code{fit-frame-to-buffer-margins} when fitting this frame to the buffer
|
||||
of its root window with @code{fit-frame-to-buffer} (@pxref{Resizing
|
||||
Windows}).
|
||||
|
||||
@vindex fit-frame-to-buffer-sizes, a frame parameter
|
||||
@item fit-frame-to-buffer-sizes
|
||||
This parameter allows to override the value of the option
|
||||
@code{fit-frame-to-buffer-sizes} when fitting this frame to the buffer
|
||||
of its root window with @code{fit-frame-to-buffer} (@pxref{Resizing
|
||||
Windows}).
|
||||
@end table
|
||||
|
||||
|
||||
|
|
@ -1646,9 +1741,9 @@ Geometry}).
|
|||
|
||||
@vindex vertical-scroll-bars, a frame parameter
|
||||
@item vertical-scroll-bars
|
||||
Whether the frame has scroll bars for vertical scrolling, and which side
|
||||
of the frame they should be on. The possible values are @code{left},
|
||||
@code{right}, and @code{nil} for no scroll bars.
|
||||
Whether the frame has scroll bars (@pxref{Scroll Bars}) for vertical
|
||||
scrolling, and which side of the frame they should be on. The possible
|
||||
values are @code{left}, @code{right}, and @code{nil} for no scroll bars.
|
||||
|
||||
@vindex horizontal-scroll-bars, a frame parameter
|
||||
@item horizontal-scroll-bars
|
||||
|
|
@ -1692,30 +1787,40 @@ to not draw bottom dividers.
|
|||
|
||||
@vindex menu-bar-lines frame parameter
|
||||
@item menu-bar-lines
|
||||
The number of lines to allocate at the top of the frame for a menu bar.
|
||||
The default is one if Menu Bar mode is enabled and zero otherwise.
|
||||
@xref{Menu Bars,,,emacs, The GNU Emacs Manual}. For an external menu
|
||||
bar, this value remains unchanged even when the menu bar wraps to two or
|
||||
more lines. In that case, the @code{menu-bar-size} value returned by
|
||||
@code{frame-geometry} (@pxref{Frame Geometry}) allows to derive whether
|
||||
the menu bar actually occupies one or more lines.
|
||||
The number of lines to allocate at the top of the frame for a menu bar
|
||||
(@pxref{Menu Bar}). The default is one if Menu Bar mode is enabled and
|
||||
zero otherwise. @xref{Menu Bars,,,emacs, The GNU Emacs Manual}. For an
|
||||
external menu bar (@pxref{Frame Layout}), this value remains unchanged
|
||||
even when the menu bar wraps to two or more lines. In that case, the
|
||||
@code{menu-bar-size} value returned by @code{frame-geometry}
|
||||
(@pxref{Frame Geometry}) allows to derive whether the menu bar actually
|
||||
occupies one or more lines.
|
||||
|
||||
@vindex tool-bar-lines frame parameter
|
||||
@item tool-bar-lines
|
||||
The number of lines to use for the tool bar. The default is one if Tool
|
||||
Bar mode is enabled and zero otherwise. @xref{Tool Bars,,,emacs, The
|
||||
GNU Emacs Manual}. This value may change whenever the tool bar wraps.
|
||||
The number of lines to use for the tool bar (@pxref{Tool Bar}). The
|
||||
default is one if Tool Bar mode is enabled and zero otherwise.
|
||||
@xref{Tool Bars,,,emacs, The GNU Emacs Manual}. This value may change
|
||||
whenever the tool bar wraps (@pxref{Frame Layout}).
|
||||
|
||||
@vindex tool-bar-position frame parameter
|
||||
@item tool-bar-position
|
||||
The position of the tool bar. Currently only for the GTK tool bar.
|
||||
Value can be one of @code{top}, @code{bottom} @code{left}, @code{right}.
|
||||
The default is @code{top}.
|
||||
The position of the tool bar when Emacs was built with GTK+. Its value
|
||||
can be one of @code{top}, @code{bottom} @code{left}, @code{right}. The
|
||||
default is @code{top}.
|
||||
|
||||
@vindex line-spacing, a frame parameter
|
||||
@item line-spacing
|
||||
Additional space to leave below each text line, in pixels (a positive
|
||||
integer). @xref{Line Height}, for more information.
|
||||
|
||||
@vindex no-special-glyphs, a frame parameter
|
||||
@item no-special-glyphs
|
||||
If this is non-@code{nil}, it suppresses the display of any truncation
|
||||
and continuation glyphs (@pxref{Truncation}) for all buffers displayed
|
||||
by this frame. This is useful to eliminate such glyphs when fitting a
|
||||
frame to its buffer via @code{fit-frame-to-buffer} (@pxref{Resizing
|
||||
Windows}).
|
||||
@end table
|
||||
|
||||
|
||||
|
|
@ -1781,15 +1886,115 @@ Frames}.
|
|||
@item mouse-wheel-frame
|
||||
If non-@code{nil}, this parameter specifies the frame whose windows will
|
||||
be scrolled whenever the mouse wheel is scrolled with the mouse pointer
|
||||
hovering over this frame (@pxref{Mouse Commands,,, emacs, The GNU Emacs
|
||||
Manual}).
|
||||
hovering over this frame, see @ref{Mouse Commands,,, emacs, The GNU
|
||||
Emacs Manual}.
|
||||
|
||||
@vindex no-other-frame, a frame parameter
|
||||
@item no-other-frame
|
||||
If this is non-@code{nil}, then this frame is not eligible as candidate
|
||||
for the functions @code{next-frame}, @code{previous-frame}
|
||||
(@pxref{Finding All Frames}) and @code{other-frame} (@pxref{Frame
|
||||
Commands,,, emacs, The GNU Emacs Manual}).
|
||||
(@pxref{Finding All Frames}) and @code{other-frame}, see @ref{Frame
|
||||
Commands,,, emacs, The GNU Emacs Manual}.
|
||||
|
||||
@vindex auto-hide-function, a frame parameter
|
||||
@item auto-hide-function
|
||||
When this parameter specifies a function, that function will be called
|
||||
instead of the function specified by the variable
|
||||
@code{frame-auto-hide-function} when quitting the frame's only window
|
||||
(@pxref{Quitting Windows}) and there are other frames left.
|
||||
|
||||
@vindex minibuffer-exit, a frame parameter
|
||||
@item minibuffer-exit
|
||||
When this parameter is non-@code{nil}, Emacs will by default make this
|
||||
frame invisible whenever the minibuffer (@pxref{Minibuffers}) is exited.
|
||||
Alternatively, it can specify the functions @code{iconify-frame} and
|
||||
@code{delete-frame}. This parameter is useful to make a child frame
|
||||
disappear automatically (similar to how Emacs deals with a window) when
|
||||
exiting the minibuffer.
|
||||
|
||||
@vindex keep-ratio, a frame parameter
|
||||
@item keep-ratio
|
||||
This parameter is currently meaningful for child frames (@pxref{Child
|
||||
Frames}) only. If it is non-@code{nil}, then Emacs will try to keep the
|
||||
frame's size (width and height) ratios (@pxref{Size Parameters}) as well
|
||||
as its left and right position ratios (@pxref{Position Parameters})
|
||||
unaltered whenever its parent frame is resized.
|
||||
|
||||
If the value of this parameter is @code{nil}, the frame's position and
|
||||
size remain unaltered when the parent frame is resized, so the position
|
||||
and size ratios may change. If the value of this parameter is @code{t},
|
||||
Emacs will try to preserve the frame's size and position ratios, hence
|
||||
the frame's size and position relative to its parent frame may change.
|
||||
|
||||
More individual control is possible by using a cons cell: In that case
|
||||
the frame's width ratio is preserved if the @sc{car} of the cell is
|
||||
either @code{t} or @code{width-only}. The height ratio is preserved if
|
||||
the @sc{car} of the cell is either @code{t} or @code{height-only}. The
|
||||
left position ratio is preserved if the @sc{cdr} of the cell is either
|
||||
@code{t} or @code{left-only}. The top position ratio is preserved if
|
||||
the @sc{cdr} of the cell is either @code{t} or @code{top-only}.
|
||||
@end table
|
||||
|
||||
|
||||
@node Mouse Dragging Parameters
|
||||
@subsubsection Mouse Dragging Parameters
|
||||
@cindex mouse dragging parameters
|
||||
@cindex parameters for resizing frames with the mouse
|
||||
@cindex parameters for moving frames with the mouse
|
||||
|
||||
The parameters described below provide support for resizing a frame by
|
||||
dragging its internal borders with the mouse. They also allow moving a
|
||||
frame with the mouse by dragging the header line of its topmost or the
|
||||
mode line of its bottommost window.
|
||||
|
||||
These parameters are mostly useful for child frames (@pxref{Child
|
||||
Frames}) that come without window manager decorations. If necessary,
|
||||
they can be used for undecorated top-level frames as well.
|
||||
|
||||
@table @code
|
||||
@vindex drag-internal-border, a frame parameter
|
||||
@item drag-internal-border
|
||||
If non-@code{nil}, the frame can be resized by dragging its internal
|
||||
borders, if present, with the mouse.
|
||||
|
||||
@vindex drag-with-header-line, a frame parameter
|
||||
@item drag-with-header-line
|
||||
If non-@code{nil}, the frame can be moved with the mouse by dragging the
|
||||
header line of its topmost window.
|
||||
|
||||
@vindex drag-with-mode-line, a frame parameter
|
||||
@item drag-with-mode-line
|
||||
If non-@code{nil}, the frame can be moved with the mouse by dragging the
|
||||
mode line of its bottommost window. Note that such a frame is not
|
||||
allowed to have its own minibuffer window.
|
||||
|
||||
@vindex snap-width, a frame parameter
|
||||
@item snap-width
|
||||
A frame that is moved with the mouse will ``snap'' at the border(s) of
|
||||
the display or its parent frame whenever it is dragged as near to such
|
||||
an edge as the number of pixels specified by this parameter.
|
||||
|
||||
@vindex top-visible, a frame parameter
|
||||
@item top-visible
|
||||
If this parameter is a number, the top edge of the frame never appears
|
||||
above the top edge of its display or parent frame. Moreover, as many
|
||||
pixels of the frame as specified by that number will remain visible when
|
||||
the frame is moved against any of the remaining edges of its display or
|
||||
parent frame. Setting this parameter is useful to guard against
|
||||
dragging a child frame with a non-@code{nil}
|
||||
@code{drag-with-header-line} parameter completely out of the area
|
||||
of its parent frame.
|
||||
|
||||
@vindex bottom-visible, a frame parameter
|
||||
@item bottom-visible
|
||||
If this parameter is a number, the bottom edge of the frame never
|
||||
appears below the bottom edge of its display or parent frame. Moreover,
|
||||
as many pixels of the frame as specified by that number will remain
|
||||
visible when the frame is moved against any of the remaining edges of
|
||||
its display or parent frame. Setting this parameter is useful to guard
|
||||
against dragging a child frame with a non-@code{nil}
|
||||
@code{drag-with-mode-line} parameter completely out of the area of
|
||||
its parent frame.
|
||||
@end table
|
||||
|
||||
|
||||
|
|
@ -1797,9 +2002,9 @@ Commands,,, emacs, The GNU Emacs Manual}).
|
|||
@subsubsection Window Management Parameters
|
||||
@cindex window manager interaction, and frame parameters
|
||||
|
||||
The following frame parameters control various aspects of the
|
||||
frame's interaction with the window manager. They have no effect on
|
||||
text terminals.
|
||||
The following frame parameters control various aspects of the frame's
|
||||
interaction with the window manager or window system. They have no
|
||||
effect on text terminals.
|
||||
|
||||
@table @code
|
||||
@vindex visibility, a frame parameter
|
||||
|
|
@ -1908,7 +2113,8 @@ If non-@code{nil}, this means that this is an @dfn{override redirect}
|
|||
frame---a frame not handled by window managers under X. Override
|
||||
redirect frames have no window manager decorations, can be positioned
|
||||
and resized only via Emacs' positioning and resizing functions and are
|
||||
usually drawn on top of all other frames.
|
||||
usually drawn on top of all other frames. Setting this parameter has
|
||||
no effect on MS-Windows.
|
||||
|
||||
@ignore
|
||||
@vindex parent-id, a frame parameter
|
||||
|
|
@ -2080,6 +2286,9 @@ The @code{alpha} frame parameter can also be a cons cell
|
|||
@code{(@var{active} . @var{inactive})}, where @var{active} is the
|
||||
opacity of the frame when it is selected, and @var{inactive} is the
|
||||
opacity when it is not selected.
|
||||
|
||||
Some window systems do not support the @code{alpha} parameter for child
|
||||
frames (@pxref{Child Frames}).
|
||||
@end table
|
||||
|
||||
The following frame parameters are semi-obsolete in that they are
|
||||
|
|
@ -2824,57 +3033,78 @@ unwanted frames are iconified instead.
|
|||
@cindex child frames
|
||||
@cindex parent frames
|
||||
|
||||
On some window-systems the @code{parent-frame} parameter (@pxref{Frame
|
||||
Interaction Parameters}) can be used to make a frame a child of the
|
||||
frame specified by that parameter. The frame specified by that
|
||||
parameter will then be the frame's parent frame as long as the parameter
|
||||
is not changed or reset. Technically, this makes the child frame's
|
||||
window-system window a child window of the parent frame's window-system
|
||||
window.
|
||||
Child frames are objects halfway between windows (@pxref{Windows}) and
|
||||
``normal'' frames. Like windows, they are attached to an owning frame.
|
||||
Unlike windows, they may overlap each other---changing the size or
|
||||
position of one child frame does not change the size or position of any
|
||||
of its sibling child frames.
|
||||
|
||||
By design, operations to make or modify child frames are implemented
|
||||
with the help of frame parameters (@pxref{Frame Parameters}) without any
|
||||
specialized functions or customizable variables. Note that child frames
|
||||
are meaningful on graphical terminals only.
|
||||
|
||||
To create a new child frame or to convert a normal frame into a child
|
||||
frame, set that frame's @code{parent-frame} parameter (@pxref{Frame
|
||||
Interaction Parameters}) to that of an already existing frame. The
|
||||
frame specified by that parameter will then be the frame's parent frame
|
||||
as long as the parameter is not changed or reset. Technically, this
|
||||
makes the child frame's window-system window a child window of the
|
||||
parent frame's window-system window.
|
||||
|
||||
@cindex top-level frame
|
||||
@cindex reparent frame
|
||||
@cindex nest frame
|
||||
The @code{parent-frame} parameter can be changed at any time. Setting
|
||||
it to another frame ``reparents'' the child frame. Setting it to
|
||||
another child frame makes the frame a ``nested'' child frame. Setting
|
||||
it to @code{nil} restores the frame's status as a top-level frame---one
|
||||
whose window-system window is a child of its display's root window.
|
||||
it to another frame @dfn{reparents} the child frame. Setting it to
|
||||
another child frame makes the frame a @dfn{nested} child frame. Setting
|
||||
it to @code{nil} restores the frame's status as a @dfn{top-level
|
||||
frame}---a frame whose window-system window is a child of its display's
|
||||
root window.
|
||||
|
||||
Since child frames can be arbitrarily nested, a frame can be both a
|
||||
child and a parent frame. Also, the relative roles of child and parent
|
||||
frame may be reversed at any time (though it's usually a good idea to
|
||||
keep the size of child frames sufficiently smaller than that of their
|
||||
keep the size of a child frame sufficiently smaller than that of its
|
||||
parent). An error will be signaled for the attempt to make a frame an
|
||||
ancestor of itself.
|
||||
|
||||
A child frame is clipped at the native edges (@pxref{Frame Geometry})
|
||||
of its parent frame---everything outside these edges is invisible. Its
|
||||
@code{left} and @code{top} parameters specify positions relative to the
|
||||
top-left corner of its parent's native frame. When either of the frames
|
||||
is resized, the relative position of the child frame remains unaltered.
|
||||
Hence, resizing either of these frames can hide or reveal parts of the
|
||||
child frame.
|
||||
Most window-systems clip a child frame at the native edges
|
||||
(@pxref{Frame Geometry}) of its parent frame---everything outside these
|
||||
edges is usually invisible. A child frame's @code{left} and @code{top}
|
||||
parameters specify a position relative to the top-left corner of its
|
||||
parent's native frame. When the parent frame is resized, this position
|
||||
remains conceptually unaltered.
|
||||
|
||||
NS builds do not clip child frames at the parent frame's edges,
|
||||
allowing them to be positioned so they do not obscure the parent
|
||||
frame while still being visible themselves.
|
||||
allowing them to be positioned so they do not obscure the parent frame
|
||||
while still being visible themselves.
|
||||
|
||||
Usually, moving a parent frame moves along all its child frames and
|
||||
their descendants as well, keeping their relative positions unaltered.
|
||||
The hook @code{move-frame-functions} (@pxref{Frame Position}) is run for
|
||||
a child frame only when the position of the child frame relative to its
|
||||
parent frame changes. When a parent frame is resized, the child frame
|
||||
retains its position respective to the left and upper native edges of
|
||||
its parent. In this case, the position respective to the lower or right
|
||||
native edge of the parent frame is usually lost.
|
||||
Note that the hook @code{move-frame-functions} (@pxref{Frame Position})
|
||||
is run for a child frame only when the position of the child frame
|
||||
relative to its parent frame changes. It is not run for a child frame
|
||||
when the position of the parent frame changes.
|
||||
|
||||
When a parent frame is resized, its child frames conceptually retain
|
||||
their previous sizes and their positions relative to the left upper
|
||||
corner of the parent. This means that a child frame may become
|
||||
(partially) invisible when its parent frame shrinks. The parameter
|
||||
@code{keep-ratio} (@pxref{Frame Interaction Parameters}) can be used to
|
||||
resize and reposition a child frame proportionally whenever its parent
|
||||
frame is resized. This may avoid obscuring parts of a frame when its
|
||||
parent frame is shrunk.
|
||||
|
||||
A visible child frame always appears on top of its parent frame thus
|
||||
obscuring parts of it, except on NS builds where it may be positioned
|
||||
beneath the parent. This is comparable to the window-system window of
|
||||
a top-level frame which also always appears on top of its parent
|
||||
window---the desktop's root window. When a parent frame is iconified
|
||||
or made invisible (@pxref{Visibility of Frames}), its child frames are
|
||||
made invisible. When a parent frame is deiconified or made visible,
|
||||
its child frames are made visible. When a parent frame is about to be
|
||||
deleted, (@pxref{Deleting Frames}) its child frames are recursively
|
||||
beneath the parent. This is comparable to the window-system window of a
|
||||
top-level frame which also always appears on top of its parent
|
||||
window---the desktop's root window. When a parent frame is iconified or
|
||||
made invisible (@pxref{Visibility of Frames}), its child frames are made
|
||||
invisible. When a parent frame is deiconified or made visible, its
|
||||
child frames are made visible. When a parent frame is about to be
|
||||
deleted (@pxref{Deleting Frames}), its child frames are recursively
|
||||
deleted before it.
|
||||
|
||||
Whether a child frame can have a menu or tool bar is window-system or
|
||||
|
|
@ -2892,7 +3122,55 @@ outer border can be used. On MS-Windows, specifying a non-zero outer
|
|||
border width will show a one-pixel wide external border. Under all
|
||||
window-systems, the internal border can be used. In either case, it's
|
||||
advisable to disable a child frame's window manager decorations with the
|
||||
@code{undecorated} frame parameter @pxref{Management Parameters}).
|
||||
@code{undecorated} frame parameter (@pxref{Management Parameters}).
|
||||
|
||||
To resize or move an undecorated child frame with the mouse, special
|
||||
frame parameters (@pxref{Mouse Dragging Parameters}) have to be used.
|
||||
The internal border of a child frame, if present, can be used to resize
|
||||
the frame with the mouse, provided that frame has a non-@code{nil}
|
||||
@code{drag-internal-border} parameter. If set, the @code{snap-width}
|
||||
parameter indicates the number of pixels where the frame @dfn{snaps} at
|
||||
the respective edge or corner of its parent frame.
|
||||
|
||||
There are two ways to drag an entire child frame with the mouse: The
|
||||
@code{drag-with-mode-line} parameter, if non-@code{nil}, allows to drag
|
||||
a frame without minibuffer window (@pxref{Minibuffer Windows}) via the
|
||||
mode line area of its bottommost window. The
|
||||
@code{drag-with-header-line} parameter, if non-@code{nil}, allows to
|
||||
drag the frame via the header line area of its topmost window.
|
||||
|
||||
In order to give a child frame a draggable header or mode line, the
|
||||
window parameters @code{mode-line-format} and @code{header-line-format}
|
||||
are handy (@pxref{Window Parameters}). These allow to remove an
|
||||
unwanted mode line (when @code{drag-with-header-line} is chosen) and to
|
||||
remove mouse-sensitive areas which might interfere with frame dragging.
|
||||
|
||||
To avoid that dragging moves a frame completely out of its parent's
|
||||
native frame, something which might happen when the mouse cursor
|
||||
overshoots and makes the frame difficult to retrieve once the mouse
|
||||
button has been released, it is advisable to set the frame's
|
||||
@code{top-visible} or @code{bottom-visible} parameter correspondingly.
|
||||
|
||||
The @code{top-visible} parameter specifies the number of pixels at the
|
||||
top of the frame that always remain visible within the parent's native
|
||||
frame during dragging and should be set when specifying a non-@code{nil}
|
||||
@code{drag-with-header-line} parameter. The @code{bottom-visible}
|
||||
parameter specifies the number of pixels at the bottom of the frame that
|
||||
always remain visible within the parent's native frame during dragging
|
||||
and should be preferred when specifying a non-@code{nil}
|
||||
@code{drag-with-mode-line} parameter.
|
||||
|
||||
When a child frame is used for displaying a buffer via
|
||||
@code{display-buffer-in-child-frame} (@pxref{Display Action Functions}),
|
||||
the frame's @code{auto-hide-function} parameter (@pxref{Frame
|
||||
Interaction Parameters}) can be set to a function, in order to
|
||||
appropriately deal with the frame when the window displaying the buffer
|
||||
shall be quit.
|
||||
|
||||
When a child frame is used during minibuffer interaction, for example,
|
||||
to display completions in a separate window, the @code{minibuffer-exit}
|
||||
parameter (@pxref{Frame Interaction Parameters}) is useful in order to
|
||||
deal with the frame when the minibuffer is exited.
|
||||
|
||||
The behavior of child frames deviates from that of top-level frames in
|
||||
a number of other ways as well. Here we sketch a few of them:
|
||||
|
|
@ -2930,7 +3208,7 @@ work on all window-systems. Some will drop the object on the parent
|
|||
frame or on some ancestor instead.
|
||||
@end itemize
|
||||
|
||||
The following two functions may be useful when working with child and
|
||||
The following two functions can be useful when working with child and
|
||||
parent frames:
|
||||
|
||||
@defun frame-parent &optional frame
|
||||
|
|
@ -2951,6 +3229,12 @@ of @var{descendant}'s parent frame. Both, @var{ancestor} and
|
|||
frame.
|
||||
@end defun
|
||||
|
||||
Note also the function @code{window-largest-empty-rectangle}
|
||||
(@pxref{Coordinates and Windows}) which can be used to inscribe a child
|
||||
frame in the largest empty area of an existing window. This can be
|
||||
useful to avoid that a child frame obscures any text shown in that
|
||||
window.
|
||||
|
||||
|
||||
@node Mouse Tracking
|
||||
@section Mouse Tracking
|
||||
|
|
|
|||
|
|
@ -1737,7 +1737,9 @@ holds a @dfn{mode line construct}: a template that controls what is
|
|||
displayed on the buffer's mode line. The value of
|
||||
@code{header-line-format} specifies the buffer's header line in the same
|
||||
way. All windows for the same buffer use the same
|
||||
@code{mode-line-format} and @code{header-line-format}.
|
||||
@code{mode-line-format} and @code{header-line-format} unless a
|
||||
@code{mode-line-format} or @code{header-line-format} parameter has been
|
||||
specified for that window (@pxref{Window Parameters}).
|
||||
|
||||
For efficiency, Emacs does not continuously recompute each window's
|
||||
mode line and header line. It does so when circumstances appear to call
|
||||
|
|
|
|||
|
|
@ -752,6 +752,7 @@ The optional argument @var{pixelwise} non-@code{nil} means to return the
|
|||
minimum size of @var{window} counted in pixels.
|
||||
@end defun
|
||||
|
||||
|
||||
@node Resizing Windows
|
||||
@section Resizing Windows
|
||||
@cindex window resizing
|
||||
|
|
@ -943,7 +944,8 @@ help of the two options listed next.
|
|||
@defopt fit-frame-to-buffer-margins
|
||||
This option can be used to specify margins around frames to be fit by
|
||||
@code{fit-frame-to-buffer}. Such margins can be useful to avoid, for
|
||||
example, that such frames overlap the taskbar.
|
||||
example, that the resized frame overlaps the taskbar or parts of its
|
||||
parent frame.
|
||||
|
||||
It specifies the numbers of pixels to be left free on the left, above,
|
||||
the right, and below a frame that shall be fit. The default specifies
|
||||
|
|
@ -2484,6 +2486,25 @@ the function specified in @code{pop-up-frame-function}
|
|||
is added to the newly created frame's parameters.
|
||||
@end defun
|
||||
|
||||
@defun display-buffer-in-child-frame buffer alist
|
||||
This function tries to display @var{buffer} in a child frame
|
||||
(@pxref{Child Frames}) of the selected frame, either reusing an existing
|
||||
child frame or by making a new one. If @var{alist} has a non-@code{nil}
|
||||
@code{child-frame-parameters} entry, the corresponding value is an alist
|
||||
of frame parameters to give the new frame. A @code{parent-frame}
|
||||
parameter specifying the selected frame is provided by default. If the
|
||||
child frame should be or become the child of another frame, a
|
||||
corresponding entry must be added to @var{alist}.
|
||||
|
||||
The appearance of child frames is largely dependent on the parameters
|
||||
provided via @var{alist}. It is advisable to use at least ratios to
|
||||
specify the size (@pxref{Size Parameters}) and the position
|
||||
(@pxref{Position Parameters}) of the child frame and to add the
|
||||
@code{keep-ratio} in order to make sure that the child frame remains
|
||||
visible. For other parameters that should be considered see @ref{Child
|
||||
Frames}.
|
||||
@end defun
|
||||
|
||||
@defun display-buffer-use-some-frame buffer alist
|
||||
This function tries to display @var{buffer} by trying to find a
|
||||
frame that meets a predicate (by default any frame other than the
|
||||
|
|
@ -3124,12 +3145,17 @@ killed.
|
|||
The default is to call @code{iconify-frame} (@pxref{Visibility of
|
||||
Frames}). Alternatively, you may specify either @code{delete-frame}
|
||||
(@pxref{Deleting Frames}) to remove the frame from its display,
|
||||
@code{ignore} to leave the frame unchanged, or any other function that
|
||||
can take a frame as its sole argument.
|
||||
@code{make-frame-invisible} to make the frame invisible, @code{ignore}
|
||||
to leave the frame unchanged, or any other function that can take a
|
||||
frame as its sole argument.
|
||||
|
||||
Note that the function specified by this option is called only if the
|
||||
specified frame contains just one live window and there is at least one
|
||||
other frame on the same terminal.
|
||||
|
||||
For a particular frame, the value specified here may be overridden by
|
||||
that frame's @code{auto-hide-function} frame parameter (@pxref{Frame
|
||||
Interaction Parameters}).
|
||||
@end defopt
|
||||
|
||||
|
||||
|
|
@ -4364,13 +4390,12 @@ is off the screen due to horizontal scrolling:
|
|||
@cindex coordinate, relative to frame
|
||||
@cindex window position
|
||||
|
||||
This section describes functions that report the position of a window.
|
||||
Most of these functions report positions relative to an origin at the
|
||||
native position of the window's frame (@pxref{Frame Geometry}). Some
|
||||
functions report positions relative to the origin of the display of the
|
||||
window's frame. In any case, the origin has the coordinates (0, 0) and
|
||||
X and Y coordinates increase rightward and downward
|
||||
respectively.
|
||||
This section describes functions that report positions of and within a
|
||||
window. Most of these functions report positions relative to an origin
|
||||
at the native position of the window's frame (@pxref{Frame Geometry}).
|
||||
Some functions report positions relative to the origin of the display of
|
||||
the window's frame. In any case, the origin has the coordinates (0, 0)
|
||||
and X and Y coordinates increase rightward and downward respectively.
|
||||
|
||||
For the following functions, X and Y coordinates are reported in
|
||||
integer character units, i.e., numbers of lines and columns
|
||||
|
|
@ -4608,6 +4633,49 @@ point in the selected window, it's sufficient to write:
|
|||
@end example
|
||||
@end defun
|
||||
|
||||
The following function returns the largest rectangle that can be
|
||||
inscribed in a window without covering text displayed in that window.
|
||||
|
||||
@defun window-largest-empty-rectangle &optional window count min-width min-height positions left
|
||||
This function calculates the dimensions of the largest empty rectangle
|
||||
that can be inscribed in the specified @var{window}'s text area.
|
||||
@var{window} must be a live window and defaults to the selected one.
|
||||
|
||||
The return value is a triple of the width and the start and end
|
||||
y-coordinates of the largest rectangle that can be inscribed into the
|
||||
empty space (space not displaying any text) of the text area of
|
||||
@var{window}. No x-coordinates are returned by this function---any such
|
||||
rectangle is assumed to end at the right edge of @var{window}'s text
|
||||
area. If no empty space can be found, the return value is @code{nil}.
|
||||
|
||||
The optional argument @var{count}, if non-@code{nil}, specifies a
|
||||
maximum number of rectangles to return. This means that the return
|
||||
value is a list of triples specifying rectangles with the largest
|
||||
rectangle first. @var{count} can be also a cons cell whose car
|
||||
specifies the number of rectangles to return and whose @sc{cdr}, if
|
||||
non-@code{nil}, states that all rectangles returned must be disjoint.
|
||||
|
||||
The optional arguments @var{min-width} and @var{min-height}, if
|
||||
non-@code{nil}, specify the minimum width and height of any rectangle
|
||||
returned.
|
||||
|
||||
The optional argument @var{positions}, if non-@code{nil}, is a cons cell
|
||||
whose @sc{car} specifies the uppermost and whose @sc{cdr} specifies the
|
||||
lowermost pixel position that must be covered by any rectangle returned.
|
||||
These positions measure from the start of the text area of @var{window}.
|
||||
|
||||
The optional argument @var{left}, if non-@code{nil}, means to return
|
||||
values suitable for buffers displaying right to left text. In that
|
||||
case, any rectangle returned is assumed to start at the left edge of
|
||||
@var{window}'s text area.
|
||||
|
||||
Note that this function has to retrieve the dimensions of each line of
|
||||
@var{window}'s glyph matrix via @code{window-lines-pixel-dimensions}
|
||||
(@pxref{Size of Displayed Text}). Hence, this function may also return
|
||||
@code{nil} when the current glyph matrix of @var{window} is not
|
||||
up-to-date.
|
||||
@end defun
|
||||
|
||||
|
||||
@node Mouse Window Auto-selection
|
||||
@section Mouse Window Auto-selection
|
||||
|
|
@ -4911,37 +4979,45 @@ windows when exiting that function.
|
|||
The following parameters are currently used by the window management
|
||||
code:
|
||||
|
||||
@table @asis
|
||||
@item @code{delete-window}
|
||||
@table @code
|
||||
@item delete-window
|
||||
@vindex delete-window, a window parameter
|
||||
This parameter affects the execution of @code{delete-window}
|
||||
(@pxref{Deleting Windows}).
|
||||
|
||||
@item @code{delete-other-windows}
|
||||
@item delete-other-windows
|
||||
@vindex delete-other-windows, a window parameter
|
||||
This parameter affects the execution of @code{delete-other-windows}
|
||||
(@pxref{Deleting Windows}).
|
||||
|
||||
@item @code{no-delete-other-window}
|
||||
@item no-delete-other-window
|
||||
@vindex no-delete-other-window, a window parameter
|
||||
This parameter marks the window as not deletable by
|
||||
@code{delete-other-windows} (@pxref{Deleting Windows}).
|
||||
|
||||
@item @code{split-window}
|
||||
@item split-window
|
||||
@vindex split-window, a window parameter
|
||||
This parameter affects the execution of @code{split-window}
|
||||
(@pxref{Splitting Windows}).
|
||||
|
||||
@item @code{other-window}
|
||||
@item other-window
|
||||
@vindex other-window, a window parameter
|
||||
This parameter affects the execution of @code{other-window}
|
||||
(@pxref{Cyclic Window Ordering}).
|
||||
|
||||
@item @code{no-other-window}
|
||||
@item no-other-window
|
||||
@vindex no-other-window, a window parameter
|
||||
This parameter marks the window as not selectable by @code{other-window}
|
||||
(@pxref{Cyclic Window Ordering}).
|
||||
|
||||
@item @code{clone-of}
|
||||
@item clone-of
|
||||
@vindex clone-of, a window parameter
|
||||
This parameter specifies the window that this one has been cloned
|
||||
from. It is installed by @code{window-state-get} (@pxref{Window
|
||||
Configurations}).
|
||||
|
||||
@item @code{preserved-size}
|
||||
@item preserved-size
|
||||
@vindex preserved-size, a window parameter
|
||||
This parameter specifies a buffer, a direction where @code{nil} means
|
||||
vertical and @code{t} horizontal, and a size in pixels. If this window
|
||||
displays the specified buffer and its size in the indicated direction
|
||||
|
|
@ -4950,7 +5026,8 @@ preserve the size of this window in the indicated direction. This
|
|||
parameter is installed and updated by the function
|
||||
@code{window-preserve-size} (@pxref{Preserving Window Sizes}).
|
||||
|
||||
@item @code{quit-restore}
|
||||
@item quit-restore
|
||||
@vindex quit-restore, a window parameter
|
||||
This parameter is installed by the buffer display functions
|
||||
(@pxref{Choosing Window}) and consulted by @code{quit-restore-window}
|
||||
(@pxref{Quitting Windows}). It contains four elements:
|
||||
|
|
@ -4981,15 +5058,37 @@ only if it still shows that buffer.
|
|||
See the description of @code{quit-restore-window} in @ref{Quitting
|
||||
Windows} for details.
|
||||
|
||||
@item @code{window-side} @code{window-slot}
|
||||
@item window-side window-slot
|
||||
@vindex window-side, a window parameter
|
||||
@vindex window-slot, a window parameter
|
||||
These parameters are used for implementing side windows (@pxref{Side
|
||||
Windows}).
|
||||
|
||||
@item @code{window-atom}
|
||||
@item window-atom
|
||||
@vindex window-atom, a window parameter
|
||||
This parameter is used for implementing atomic windows, see @ref{Atomic
|
||||
Windows}.
|
||||
|
||||
@item @code{min-margins}
|
||||
@item mode-line-format
|
||||
@vindex mode-line-format, a window parameter
|
||||
This parameter replaces the value of the buffer-local variable
|
||||
@code{mode-line-format} (@pxref{Mode Line Basics}) of this window's
|
||||
buffer whenever this window is displayed. The symbol @code{none} means
|
||||
to suppress display of a mode line for this window. Display and
|
||||
contents of the mode line on other windows showing this buffer are not
|
||||
affected.
|
||||
|
||||
@item header-line-format
|
||||
@vindex header-line-format, a window parameter
|
||||
This parameter replaces the value of the buffer-local variable
|
||||
@code{header-line-format} (@pxref{Mode Line Basics}) of this window's
|
||||
buffer whenever this window is displayed. The symbol @code{none} means
|
||||
to suppress display of a header line for this window. Display and
|
||||
contents of the header line on other windows showing this buffer are not
|
||||
affected.
|
||||
|
||||
@item min-margins
|
||||
@vindex min-margins, a window parameter
|
||||
The value of this parameter is a cons cell whose @sc{car} and @sc{cdr},
|
||||
if non-@code{nil}, specify the minimum values (in columns) for the left
|
||||
and right margin of this window. When present, Emacs will use these
|
||||
|
|
|
|||
43
etc/NEWS
43
etc/NEWS
|
|
@ -1205,7 +1205,7 @@ run.
|
|||
frame's outer border.
|
||||
|
||||
+++
|
||||
*** New frame parameters
|
||||
*** New frame parameters and changed semantics for older ones
|
||||
|
||||
+++
|
||||
**** 'z-group' positions a frame above or below all others.
|
||||
|
|
@ -1250,10 +1250,32 @@ focus via the mouse.
|
|||
frame.
|
||||
|
||||
+++
|
||||
*** The 'width' and 'height' frame parameters allow to specify pixel
|
||||
values now.
|
||||
**** 'width' and 'height' allow to specify pixel values and ratios now.
|
||||
|
||||
+++
|
||||
**** 'left' and 'top' allow to specify ratios now.
|
||||
|
||||
+++
|
||||
**** 'keep-ratio' preserves size and position of child frames when their
|
||||
parent frame is resized.
|
||||
|
||||
+++
|
||||
**** 'no-special-glyphs' suppresses display of truncation and
|
||||
continuation glyphs in a frame.
|
||||
|
||||
+++
|
||||
**** 'auto-hide-function' and 'minibuffer-exit' handle auto hiding of
|
||||
frames and exiting from minibuffer individually.
|
||||
|
||||
+++
|
||||
**** 'fit-frame-to-buffer-margins' and 'fit-frame-to-buffer-sizes'
|
||||
handle fitting a frame to its buffer individually.
|
||||
|
||||
+++
|
||||
**** 'drag-internal-border', 'drag-with-header-line',
|
||||
'drag-with-mode-line', 'snap-width', 'top-visible' and 'bottom-visible'
|
||||
allow to drag and resize frames with the mouse.
|
||||
|
||||
*** The new function 'frame-list-z-order' returns a list of all frames
|
||||
in Z (stacking) order.
|
||||
|
||||
|
|
@ -1311,6 +1333,10 @@ a new window when opening man pages when there's already one, use
|
|||
*** New window parameter 'no-delete-other-window' prevents that
|
||||
its window gets deleted by 'delete-other-windows'.
|
||||
|
||||
+++
|
||||
*** New window parameters 'mode-line-format' and 'header-line-format'
|
||||
allow to override the buffer-local formats for this window.
|
||||
|
||||
+++
|
||||
*** New command 'window-swap-states' swaps the states of two live
|
||||
windows.
|
||||
|
|
@ -1320,6 +1346,15 @@ windows.
|
|||
'window-pixel-height-before-size-change' support detecting which
|
||||
window changed size when 'window-size-change-functions' are run.
|
||||
|
||||
+++
|
||||
*** The new function 'window-lines-pixel-dimensions' returns the pixel
|
||||
dimensions of a window's text lines.
|
||||
|
||||
+++
|
||||
*** The new function 'window-largest-empty-rectangle' returns the
|
||||
dimensions of the largest rectangular area not occupying any text in a
|
||||
window's body.
|
||||
|
||||
+++
|
||||
*** The semantics of 'mouse-autoselect-window' has changed slightly.
|
||||
For details see the section "Mouse Window Auto-selection" in the Elisp
|
||||
|
|
@ -1366,7 +1401,7 @@ This is in contrast to the default action on POSIX Systems, where it
|
|||
causes the receiving process to terminate with a core dump if no
|
||||
debugger has been attached to it.
|
||||
|
||||
** `set-mouse-position' and `set-mouse-absolute-pixel-position' work
|
||||
** 'set-mouse-position' and 'set-mouse-absolute-pixel-position' work
|
||||
on macOS.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1110,6 +1110,38 @@ differing font heights."
|
|||
If FRAME is omitted, describe the currently selected frame."
|
||||
(cdr (assq 'width (frame-parameters frame))))
|
||||
|
||||
(defalias 'frame-border-width 'frame-internal-border-width)
|
||||
(defalias 'frame-pixel-width 'frame-native-width)
|
||||
(defalias 'frame-pixel-height 'frame-native-height)
|
||||
|
||||
(defun frame-inner-width (&optional frame)
|
||||
"Return inner width of FRAME in pixels.
|
||||
FRAME defaults to the selected frame."
|
||||
(setq frame (window-normalize-frame frame))
|
||||
(- (frame-native-width frame)
|
||||
(* 2 (frame-internal-border-width frame))))
|
||||
|
||||
(defun frame-inner-height (&optional frame)
|
||||
"Return inner height of FRAME in pixels.
|
||||
FRAME defaults to the selected frame."
|
||||
(setq frame (window-normalize-frame frame))
|
||||
(- (frame-native-height frame)
|
||||
(* 2 (frame-internal-border-width frame))))
|
||||
|
||||
(defun frame-outer-width (&optional frame)
|
||||
"Return outer width of FRAME in pixels.
|
||||
FRAME defaults to the selected frame."
|
||||
(setq frame (window-normalize-frame frame))
|
||||
(let ((edges (frame-edges frame 'outer-edges)))
|
||||
(- (nth 2 edges) (nth 0 edges))))
|
||||
|
||||
(defun frame-outer-height (&optional frame)
|
||||
"Return outer height of FRAME in pixels.
|
||||
FRAME defaults to the selected frame."
|
||||
(setq frame (window-normalize-frame frame))
|
||||
(let ((edges (frame-edges frame 'outer-edges)))
|
||||
(- (nth 3 edges) (nth 1 edges))))
|
||||
|
||||
(declare-function x-list-fonts "xfaces.c"
|
||||
(pattern &optional face frame maximum width))
|
||||
|
||||
|
|
|
|||
|
|
@ -746,7 +746,7 @@ If the current buffer is not a minibuffer, erase its entire contents."
|
|||
|
||||
(defcustom completion-auto-help t
|
||||
"Non-nil means automatically provide help for invalid completion input.
|
||||
If the value is t the *Completion* buffer is displayed whenever completion
|
||||
If the value is t the *Completions* buffer is displayed whenever completion
|
||||
is requested but cannot be done.
|
||||
If the value is `lazy', the *Completions* buffer is only displayed after
|
||||
the second failed attempt to complete."
|
||||
|
|
|
|||
433
lisp/mouse.el
433
lisp/mouse.el
|
|
@ -380,7 +380,7 @@ This command must be bound to a mouse click."
|
|||
|
||||
(defun mouse-drag-line (start-event line)
|
||||
"Drag a mode line, header line, or vertical line with the mouse.
|
||||
START-EVENT is the starting mouse-event of the drag action. LINE
|
||||
START-EVENT is the starting mouse event of the drag action. LINE
|
||||
must be one of the symbols `header', `mode', or `vertical'."
|
||||
;; Give temporary modes such as isearch a chance to turn off.
|
||||
(run-hooks 'mouse-leave-buffer-hook)
|
||||
|
|
@ -405,29 +405,15 @@ must be one of the symbols `header', `mode', or `vertical'."
|
|||
;; window's edge we drag.
|
||||
(cond
|
||||
((eq line 'header)
|
||||
(if (window-at-side-p window 'top)
|
||||
;; We can't drag the header line of a topmost window.
|
||||
(setq draggable nil)
|
||||
;; Drag bottom edge of window above the header line.
|
||||
(setq window (window-in-direction 'above window t))))
|
||||
((eq line 'mode)
|
||||
(if (and (window-at-side-p window 'bottom)
|
||||
;; Allow resizing the minibuffer window if it's on the
|
||||
;; same frame as and immediately below `window', and it's
|
||||
;; either active or `resize-mini-windows' is nil.
|
||||
(let ((minibuffer-window (minibuffer-window frame)))
|
||||
(not (and (eq (window-frame minibuffer-window) frame)
|
||||
(or (not resize-mini-windows)
|
||||
(eq minibuffer-window
|
||||
(active-minibuffer-window)))))))
|
||||
(setq draggable nil)))
|
||||
;; Drag bottom edge of window above the header line.
|
||||
(setq window (window-in-direction 'above window t)))
|
||||
((eq line 'mode))
|
||||
((eq line 'vertical)
|
||||
(let ((divider-width (frame-right-divider-width frame)))
|
||||
(when (and (or (not (numberp divider-width))
|
||||
(zerop divider-width))
|
||||
(eq (frame-parameter frame 'vertical-scroll-bars) 'left))
|
||||
(setq window (window-in-direction 'left window t))))))
|
||||
|
||||
(let* ((exitfun nil)
|
||||
(move
|
||||
(lambda (event) (interactive "e")
|
||||
|
|
@ -530,20 +516,405 @@ must be one of the symbols `header', `mode', or `vertical'."
|
|||
t (lambda () (setq track-mouse old-track-mouse)))))))
|
||||
|
||||
(defun mouse-drag-mode-line (start-event)
|
||||
"Change the height of a window by dragging on the mode line."
|
||||
"Change the height of a window by dragging on its mode line.
|
||||
START-EVENT is the starting mouse event of the drag action.
|
||||
|
||||
If the drag happens in a mode line on the bottom of a frame and
|
||||
that frame's `drag-with-mode-line' parameter is non-nil, drag the
|
||||
frame instead."
|
||||
(interactive "e")
|
||||
(mouse-drag-line start-event 'mode))
|
||||
(let* ((start (event-start start-event))
|
||||
(window (posn-window start))
|
||||
(frame (window-frame window)))
|
||||
(cond
|
||||
((not (window-live-p window)))
|
||||
((or (not (window-at-side-p window 'bottom))
|
||||
;; Allow resizing the minibuffer window if it's on the
|
||||
;; same frame as and immediately below `window', and it's
|
||||
;; either active or `resize-mini-windows' is nil.
|
||||
(let ((minibuffer-window (minibuffer-window frame)))
|
||||
(and (eq (window-frame minibuffer-window) frame)
|
||||
(or (not resize-mini-windows)
|
||||
(eq minibuffer-window
|
||||
(active-minibuffer-window))))))
|
||||
(mouse-drag-line start-event 'mode))
|
||||
((and (frame-parameter frame 'drag-with-mode-line)
|
||||
(window-at-side-p window 'bottom)
|
||||
(let ((minibuffer-window (minibuffer-window frame)))
|
||||
(not (eq (window-frame minibuffer-window) frame))))
|
||||
;; Drag frame when the window is on the bottom of its frame and
|
||||
;; there is no minibuffer window below.
|
||||
(mouse-drag-frame start-event 'move)))))
|
||||
|
||||
(defun mouse-drag-header-line (start-event)
|
||||
"Change the height of a window by dragging on the header line."
|
||||
"Change the height of a window by dragging on its header line.
|
||||
START-EVENT is the starting mouse event of the drag action.
|
||||
|
||||
If the drag happens in a header line on the top of a frame and
|
||||
that frame's `drag-with-header-line' parameter is non-nil, drag
|
||||
the frame instead."
|
||||
(interactive "e")
|
||||
(mouse-drag-line start-event 'header))
|
||||
(let* ((start (event-start start-event))
|
||||
(window (posn-window start)))
|
||||
(if (and (window-live-p window)
|
||||
(not (window-at-side-p window 'top)))
|
||||
(mouse-drag-line start-event 'header)
|
||||
(let ((frame (window-frame window)))
|
||||
(when (frame-parameter frame 'drag-with-header-line)
|
||||
(mouse-drag-frame start-event 'move))))))
|
||||
|
||||
(defun mouse-drag-vertical-line (start-event)
|
||||
"Change the width of a window by dragging on the vertical line."
|
||||
"Change the width of a window by dragging on a vertical line.
|
||||
START-EVENT is the starting mouse event of the drag action."
|
||||
(interactive "e")
|
||||
(mouse-drag-line start-event 'vertical))
|
||||
|
||||
(defun mouse-resize-frame (frame x-diff y-diff &optional x-move y-move)
|
||||
"Helper function for `mouse-drag-frame'."
|
||||
(let* ((frame-x-y (frame-position frame))
|
||||
(frame-x (car frame-x-y))
|
||||
(frame-y (cdr frame-x-y))
|
||||
alist)
|
||||
(if (> x-diff 0)
|
||||
(when x-move
|
||||
(setq x-diff (min x-diff frame-x))
|
||||
(setq x-move (- frame-x x-diff)))
|
||||
(let* ((min-width (frame-windows-min-size frame t nil t))
|
||||
(min-diff (max 0 (- (frame-inner-width frame) min-width))))
|
||||
(setq x-diff (max x-diff (- min-diff)))
|
||||
(when x-move
|
||||
(setq x-move (+ frame-x (- x-diff))))))
|
||||
|
||||
(if (> y-diff 0)
|
||||
(when y-move
|
||||
(setq y-diff (min y-diff frame-y))
|
||||
(setq y-move (- frame-y y-diff)))
|
||||
(let* ((min-height (frame-windows-min-size frame nil nil t))
|
||||
(min-diff (max 0 (- (frame-inner-height frame) min-height))))
|
||||
(setq y-diff (max y-diff (- min-diff)))
|
||||
(when y-move
|
||||
(setq y-move (+ frame-y (- y-diff))))))
|
||||
|
||||
(unless (zerop x-diff)
|
||||
(when x-move
|
||||
(push `(left . ,x-move) alist))
|
||||
(push `(width . (text-pixels . ,(+ (frame-text-width frame) x-diff)))
|
||||
alist))
|
||||
(unless (zerop y-diff)
|
||||
(when y-move
|
||||
(push `(top . ,y-move) alist))
|
||||
(push `(height . (text-pixels . ,(+ (frame-text-height frame) y-diff)))
|
||||
alist))
|
||||
(when alist
|
||||
(modify-frame-parameters frame alist))))
|
||||
|
||||
(defun mouse-drag-frame (start-event part)
|
||||
"Drag a frame or one of its edges with the mouse.
|
||||
START-EVENT is the starting mouse event of the drag action. Its
|
||||
position window denotes the frame that will be dragged.
|
||||
|
||||
PART specifies the part that has been dragged and must be one of
|
||||
the symbols 'left', 'top', 'right', 'bottom', 'top-left',
|
||||
'top-right', 'bottom-left', 'bottom-right' to drag an internal
|
||||
border or edge. If PART equals 'move', this means to move the
|
||||
frame with the mouse."
|
||||
;; Give temporary modes such as isearch a chance to turn off.
|
||||
(run-hooks 'mouse-leave-buffer-hook)
|
||||
(let* ((echo-keystrokes 0)
|
||||
(start (event-start start-event))
|
||||
(window (posn-window start))
|
||||
;; FRAME is the frame to drag.
|
||||
(frame (if (window-live-p window)
|
||||
(window-frame window)
|
||||
window))
|
||||
(width (frame-native-width frame))
|
||||
(height (frame-native-height frame))
|
||||
;; PARENT is the parent frame of FRAME or, if FRAME is a
|
||||
;; top-level frame, FRAME's workarea.
|
||||
(parent (frame-parent frame))
|
||||
(parent-edges
|
||||
(if parent
|
||||
`(0 0 ,(frame-native-width parent) ,(frame-native-height parent))
|
||||
(let* ((attributes
|
||||
(car (display-monitor-attributes-list)))
|
||||
(workarea (assq 'workarea attributes)))
|
||||
(and workarea
|
||||
`(,(nth 1 workarea) ,(nth 2 workarea)
|
||||
,(+ (nth 1 workarea) (nth 3 workarea))
|
||||
,(+ (nth 2 workarea) (nth 4 workarea)))))))
|
||||
(parent-left (and parent-edges (nth 0 parent-edges)))
|
||||
(parent-top (and parent-edges (nth 1 parent-edges)))
|
||||
(parent-right (and parent-edges (nth 2 parent-edges)))
|
||||
(parent-bottom (and parent-edges (nth 3 parent-edges)))
|
||||
;; `pos-x' and `pos-y' record the x- and y-coordinates of the
|
||||
;; last sampled mouse position. Note that we sample absolute
|
||||
;; mouse positions to avoid that moving the mouse from one
|
||||
;; frame into another gets into our way. `last-x' and `last-y'
|
||||
;; records the x- and y-coordinates of the previously sampled
|
||||
;; position. The differences between `last-x' and `pos-x' as
|
||||
;; well as `last-y' and `pos-y' determine the amount the mouse
|
||||
;; has been dragged between the last two samples.
|
||||
pos-x-y pos-x pos-y
|
||||
(last-x-y (mouse-absolute-pixel-position))
|
||||
(last-x (car last-x-y))
|
||||
(last-y (cdr last-x-y))
|
||||
;; `snap-x' and `snap-y' record the x- and y-coordinates of the
|
||||
;; mouse position when FRAME snapped. As soon as the
|
||||
;; difference between `pos-x' and `snap-x' (or `pos-y' and
|
||||
;; `snap-y') exceeds the value of FRAME's `snap-width'
|
||||
;; parameter, unsnap FRAME (at the respective side). `snap-x'
|
||||
;; and `snap-y' nil mean FRAME is curerntly not snapped.
|
||||
snap-x snap-y
|
||||
(exitfun nil)
|
||||
(move
|
||||
(lambda (event)
|
||||
(interactive "e")
|
||||
(when (consp event)
|
||||
(setq pos-x-y (mouse-absolute-pixel-position))
|
||||
(setq pos-x (car pos-x-y))
|
||||
(setq pos-y (cdr pos-x-y))
|
||||
(cond
|
||||
((eq part 'left)
|
||||
(mouse-resize-frame frame (- last-x pos-x) 0 t))
|
||||
((eq part 'top)
|
||||
(mouse-resize-frame frame 0 (- last-y pos-y) nil t))
|
||||
((eq part 'right)
|
||||
(mouse-resize-frame frame (- pos-x last-x) 0))
|
||||
((eq part 'bottom)
|
||||
(mouse-resize-frame frame 0 (- pos-y last-y)))
|
||||
((eq part 'top-left)
|
||||
(mouse-resize-frame
|
||||
frame (- last-x pos-x) (- last-y pos-y) t t))
|
||||
((eq part 'top-right)
|
||||
(mouse-resize-frame
|
||||
frame (- pos-x last-x) (- last-y pos-y) nil t))
|
||||
((eq part 'bottom-left)
|
||||
(mouse-resize-frame
|
||||
frame (- last-x pos-x) (- pos-y last-y) t))
|
||||
((eq part 'bottom-right)
|
||||
(mouse-resize-frame
|
||||
frame (- pos-x last-x) (- pos-y last-y)))
|
||||
((eq part 'move)
|
||||
(let* ((old-position (frame-position frame))
|
||||
(old-left (car old-position))
|
||||
(old-top (cdr old-position))
|
||||
(left (+ old-left (- pos-x last-x)))
|
||||
(top (+ old-top (- pos-y last-y)))
|
||||
right bottom
|
||||
;; `snap-width' (maybe also a yet to be provided
|
||||
;; `snap-height') could become floats to handle
|
||||
;; proportionality wrt PARENT. We don't do any
|
||||
;; checks on this parameter so far.
|
||||
(snap-width (frame-parameter frame 'snap-width)))
|
||||
;; Docking and constraining.
|
||||
(when (and (numberp snap-width) parent-edges)
|
||||
(cond
|
||||
;; Docking at the left parent edge.
|
||||
((< pos-x last-x)
|
||||
(cond
|
||||
((and (> left parent-left)
|
||||
(<= (- left parent-left) snap-width))
|
||||
;; Snap when the mouse moved leftward and
|
||||
;; FRAME's left edge would end up within
|
||||
;; `snap-width' pixels from PARENT's left edge.
|
||||
(setq snap-x pos-x)
|
||||
(setq left parent-left))
|
||||
((and (<= left parent-left)
|
||||
(<= (- parent-left left) snap-width)
|
||||
snap-x (<= (- snap-x pos-x) snap-width))
|
||||
;; Stay snapped when the mouse moved leftward
|
||||
;; but not more than `snap-width' pixels from
|
||||
;; the time FRAME snapped.
|
||||
(setq left parent-left))
|
||||
(t
|
||||
;; Unsnap when the mouse moved more than
|
||||
;; `snap-width' pixels leftward from the time
|
||||
;; FRAME snapped.
|
||||
(setq snap-x nil))))
|
||||
((> pos-x last-x)
|
||||
(setq right (+ left width))
|
||||
(cond
|
||||
((and (< right parent-right)
|
||||
(<= (- parent-right right) snap-width))
|
||||
;; Snap when the mouse moved rightward and
|
||||
;; FRAME's right edge would end up within
|
||||
;; `snap-width' pixels from PARENT's right edge.
|
||||
(setq snap-x pos-x)
|
||||
(setq left (- parent-right width)))
|
||||
((and (>= right parent-right)
|
||||
(<= (- right parent-right) snap-width)
|
||||
snap-x (<= (- pos-x snap-x) snap-width))
|
||||
;; Stay snapped when the mouse moved rightward
|
||||
;; but not more more than `snap-width' pixels
|
||||
;; from the time FRAME snapped.
|
||||
(setq left (- parent-right width)))
|
||||
(t
|
||||
;; Unsnap when the mouse moved rightward more
|
||||
;; than `snap-width' pixels from the time FRAME
|
||||
;; snapped.
|
||||
(setq snap-x nil)))))
|
||||
|
||||
(cond
|
||||
((< pos-y last-y)
|
||||
(cond
|
||||
((and (> top parent-top)
|
||||
(<= (- top parent-top) snap-width))
|
||||
;; Snap when the mouse moved upward and FRAME's
|
||||
;; top edge would end up within `snap-width'
|
||||
;; pixels from PARENT's top edge.
|
||||
(setq snap-y pos-y)
|
||||
(setq top parent-top))
|
||||
((and (<= top parent-top)
|
||||
(<= (- parent-top top) snap-width)
|
||||
snap-y (<= (- snap-y pos-y) snap-width))
|
||||
;; Stay snapped when the mouse moved upward but
|
||||
;; not more more than `snap-width' pixels from
|
||||
;; the time FRAME snapped.
|
||||
(setq top parent-top))
|
||||
(t
|
||||
;; Unsnap when the mouse moved upward more than
|
||||
;; `snap-width' pixels from the time FRAME
|
||||
;; snapped.
|
||||
(setq snap-y nil))))
|
||||
((> pos-y last-y)
|
||||
(setq bottom (+ top height))
|
||||
(cond
|
||||
((and (< bottom parent-bottom)
|
||||
(<= (- parent-bottom bottom) snap-width))
|
||||
;; Snap when the mouse moved downward and
|
||||
;; FRAME's bottom edge would end up within
|
||||
;; `snap-width' pixels from PARENT's bottom
|
||||
;; edge.
|
||||
(setq snap-y pos-y)
|
||||
(setq top (- parent-bottom height)))
|
||||
((and (>= bottom parent-bottom)
|
||||
(<= (- bottom parent-bottom) snap-width)
|
||||
snap-y (<= (- pos-y snap-y) snap-width))
|
||||
;; Stay snapped when the mouse moved downward
|
||||
;; but not more more than `snap-width' pixels
|
||||
;; from the time FRAME snapped.
|
||||
(setq top (- parent-bottom height)))
|
||||
(t
|
||||
;; Unsnap when the mouse moved downward more
|
||||
;; than `snap-width' pixels from the time FRAME
|
||||
;; snapped.
|
||||
(setq snap-y nil))))))
|
||||
|
||||
;; If requested, constrain FRAME's draggable areas to
|
||||
;; PARENT's edges. The `top-visible' parameter should
|
||||
;; be set when FRAME has a draggable header-line. If
|
||||
;; set to a number, it ascertains that the top of
|
||||
;; FRAME is always constrained to the top of PARENT
|
||||
;; and that at least as many pixels of FRAME as
|
||||
;; specified by that number are visible on each of the
|
||||
;; three remaining sides of PARENT.
|
||||
;;
|
||||
;; The `bottom-visible' parameter should be set when
|
||||
;; FRAME has a draggable mode-line. If set to a
|
||||
;; number, it ascertains that the bottom of FRAME is
|
||||
;; always constrained to the bottom of PARENT and that
|
||||
;; at least as many pixels of FRAME as specified by
|
||||
;; that number are visible on each of the three
|
||||
;; remaining sides of PARENT.
|
||||
(let ((par (frame-parameter frame 'top-visible))
|
||||
bottom-visible)
|
||||
(unless par
|
||||
(setq par (frame-parameter frame 'bottom-visible))
|
||||
(setq bottom-visible t))
|
||||
(when (and (numberp par) parent-edges)
|
||||
(setq left
|
||||
(max (min (- parent-right par) left)
|
||||
(+ (- parent-left width) par)))
|
||||
(setq top
|
||||
(if bottom-visible
|
||||
(min (max top (- parent-top (- height par)))
|
||||
(- parent-bottom height))
|
||||
(min (max top parent-top)
|
||||
(- parent-bottom par))))))
|
||||
|
||||
;; Use `modify-frame-parameters' since `left' and
|
||||
;; `top' may want to move FRAME out of its PARENT.
|
||||
(modify-frame-parameters
|
||||
frame
|
||||
`((left . (+ ,left)) (top . (+ ,top)))))))
|
||||
(setq last-x pos-x)
|
||||
(setq last-y pos-y))))
|
||||
(old-track-mouse track-mouse))
|
||||
;; Start tracking. The special value 'dragging' signals the
|
||||
;; display engine to freeze the mouse pointer shape for as long
|
||||
;; as we drag.
|
||||
(setq track-mouse 'dragging)
|
||||
;; Loop reading events and sampling the position of the mouse.
|
||||
(setq exitfun
|
||||
(set-transient-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map [switch-frame] #'ignore)
|
||||
(define-key map [select-window] #'ignore)
|
||||
(define-key map [scroll-bar-movement] #'ignore)
|
||||
(define-key map [mouse-movement] move)
|
||||
;; Swallow drag-mouse-1 events to avoid selecting some other window.
|
||||
(define-key map [drag-mouse-1]
|
||||
(lambda () (interactive) (funcall exitfun)))
|
||||
;; Some of the events will of course end up looked up
|
||||
;; with a mode-line, header-line or vertical-line prefix ...
|
||||
(define-key map [mode-line] map)
|
||||
(define-key map [header-line] map)
|
||||
(define-key map [vertical-line] map)
|
||||
;; ... and some maybe even with a right- or bottom-divider
|
||||
;; prefix.
|
||||
(define-key map [right-divider] map)
|
||||
(define-key map [bottom-divider] map)
|
||||
map)
|
||||
t (lambda () (setq track-mouse old-track-mouse))))))
|
||||
|
||||
(defun mouse-drag-left-edge (start-event)
|
||||
"Drag left edge of a frame with the mouse.
|
||||
START-EVENT is the starting mouse event of the drag action."
|
||||
(interactive "e")
|
||||
(mouse-drag-frame start-event 'left))
|
||||
|
||||
(defun mouse-drag-top-left-corner (start-event)
|
||||
"Drag top left corner of a frame with the mouse.
|
||||
START-EVENT is the starting mouse event of the drag action."
|
||||
(interactive "e")
|
||||
(mouse-drag-frame start-event 'top-left))
|
||||
|
||||
(defun mouse-drag-top-edge (start-event)
|
||||
"Drag top edge of a frame with the mouse.
|
||||
START-EVENT is the starting mouse event of the drag action."
|
||||
(interactive "e")
|
||||
(mouse-drag-frame start-event 'top))
|
||||
|
||||
(defun mouse-drag-top-right-corner (start-event)
|
||||
"Drag top right corner of a frame with the mouse.
|
||||
START-EVENT is the starting mouse event of the drag action."
|
||||
(interactive "e")
|
||||
(mouse-drag-frame start-event 'top-right))
|
||||
|
||||
(defun mouse-drag-right-edge (start-event)
|
||||
"Drag right edge of a frame with the mouse.
|
||||
START-EVENT is the starting mouse event of the drag action."
|
||||
(interactive "e")
|
||||
(mouse-drag-frame start-event 'right))
|
||||
|
||||
(defun mouse-drag-bottom-right-corner (start-event)
|
||||
"Drag bottom right corner of a frame with the mouse.
|
||||
START-EVENT is the starting mouse event of the drag action."
|
||||
(interactive "e")
|
||||
(mouse-drag-frame start-event 'bottom-right))
|
||||
|
||||
(defun mouse-drag-bottom-edge (start-event)
|
||||
"Drag bottom edge of a frame with the mouse.
|
||||
START-EVENT is the starting mouse event of the drag action."
|
||||
(interactive "e")
|
||||
(mouse-drag-frame start-event 'bottom))
|
||||
|
||||
(defun mouse-drag-bottom-left-corner (start-event)
|
||||
"Drag bottom left corner of a frame with the mouse.
|
||||
START-EVENT is the starting mouse event of the drag action."
|
||||
(interactive "e")
|
||||
(mouse-drag-frame start-event 'bottom-left))
|
||||
|
||||
(defcustom mouse-select-region-move-to-beginning nil
|
||||
"Effect of selecting a region extending backward from double click.
|
||||
Nil means keep point at the position clicked (region end);
|
||||
|
|
@ -2078,6 +2449,22 @@ is copied instead of being cut."
|
|||
(global-set-key [bottom-divider down-mouse-1] 'mouse-drag-mode-line)
|
||||
(global-set-key [bottom-divider mouse-1] 'ignore)
|
||||
(global-set-key [bottom-divider C-mouse-2] 'mouse-split-window-horizontally)
|
||||
(global-set-key [left-edge down-mouse-1] 'mouse-drag-left-edge)
|
||||
(global-set-key [left-edge mouse-1] 'ignore)
|
||||
(global-set-key [top-left-corner down-mouse-1] 'mouse-drag-top-left-corner)
|
||||
(global-set-key [top-left-corner mouse-1] 'ignore)
|
||||
(global-set-key [top-edge down-mouse-1] 'mouse-drag-top-edge)
|
||||
(global-set-key [top-edge mouse-1] 'ignore)
|
||||
(global-set-key [top-right-corner down-mouse-1] 'mouse-drag-top-right-corner)
|
||||
(global-set-key [top-right-corner mouse-1] 'ignore)
|
||||
(global-set-key [right-edge down-mouse-1] 'mouse-drag-right-edge)
|
||||
(global-set-key [right-edge mouse-1] 'ignore)
|
||||
(global-set-key [bottom-right-corner down-mouse-1] 'mouse-drag-bottom-right-corner)
|
||||
(global-set-key [bottom-right-corner mouse-1] 'ignore)
|
||||
(global-set-key [bottom-edge down-mouse-1] 'mouse-drag-bottom-edge)
|
||||
(global-set-key [bottom-edge mouse-1] 'ignore)
|
||||
(global-set-key [bottom-left-corner down-mouse-1] 'mouse-drag-bottom-left-corner)
|
||||
(global-set-key [bottom-left-corner mouse-1] 'ignore)
|
||||
|
||||
(provide 'mouse)
|
||||
|
||||
|
|
|
|||
|
|
@ -119,7 +119,8 @@ the value of `tooltip-y-offset' is ignored."
|
|||
(defcustom tooltip-frame-parameters
|
||||
'((name . "tooltip")
|
||||
(internal-border-width . 2)
|
||||
(border-width . 1))
|
||||
(border-width . 1)
|
||||
(no-special-glyphs . t))
|
||||
"Frame parameters used for tooltips.
|
||||
|
||||
If `left' or `top' parameters are included, they specify the absolute
|
||||
|
|
@ -130,7 +131,8 @@ of the `tooltip' face are used instead."
|
|||
:type '(repeat (cons :format "%v"
|
||||
(symbol :tag "Parameter")
|
||||
(sexp :tag "Value")))
|
||||
:group 'tooltip)
|
||||
:group 'tooltip
|
||||
:version "26.1")
|
||||
|
||||
(defface tooltip
|
||||
'((((class color))
|
||||
|
|
|
|||
615
lisp/window.el
615
lisp/window.el
|
|
@ -3703,7 +3703,7 @@ are one more than the actual value of these edges. Note that if
|
|||
ABSOLUTE is non-nil, PIXELWISE is implicitly non-nil too."
|
||||
(let* ((window (window-normalize-window window body))
|
||||
(frame (window-frame window))
|
||||
(border-width (frame-border-width frame))
|
||||
(border-width (frame-internal-border-width frame))
|
||||
(char-width (frame-char-width frame))
|
||||
(char-height (frame-char-height frame))
|
||||
(left (if pixelwise
|
||||
|
|
@ -4572,12 +4572,13 @@ The function is called with one argument - a frame.
|
|||
Functions affected by this option are those that bury a buffer
|
||||
shown in a separate frame like `quit-window' and `bury-buffer'."
|
||||
:type '(choice (const :tag "Iconify" iconify-frame)
|
||||
(const :tag "Make invisible" make-frame-invisible)
|
||||
(const :tag "Delete" delete-frame)
|
||||
(const :tag "Do nothing" ignore)
|
||||
function)
|
||||
:group 'windows
|
||||
:group 'frames
|
||||
:version "24.1")
|
||||
:version "26.1")
|
||||
|
||||
(defun window--delete (&optional window dedicated-only kill)
|
||||
"Delete WINDOW if possible.
|
||||
|
|
@ -4595,7 +4596,9 @@ if WINDOW gets deleted or its frame is auto-hidden."
|
|||
(cond
|
||||
(kill
|
||||
(delete-frame frame))
|
||||
((functionp frame-auto-hide-function)
|
||||
((functionp (frame-parameter frame 'auto-hide-function))
|
||||
(funcall (frame-parameter frame 'auto-hide-function)))
|
||||
((functionp frame-auto-hide-function)
|
||||
(funcall frame-auto-hide-function frame))))
|
||||
'frame)
|
||||
(deletable
|
||||
|
|
@ -6734,15 +6737,17 @@ live."
|
|||
window))
|
||||
|
||||
(defun window--maybe-raise-frame (frame)
|
||||
(let ((visible (frame-visible-p frame)))
|
||||
(unless (or (not visible)
|
||||
;; Assume the selected frame is already visible enough.
|
||||
(eq frame (selected-frame))
|
||||
;; Assume the frame from which we invoked the
|
||||
;; minibuffer is visible.
|
||||
(and (minibuffer-window-active-p (selected-window))
|
||||
(eq frame (window-frame (minibuffer-selected-window)))))
|
||||
(raise-frame frame))))
|
||||
(make-frame-visible frame)
|
||||
(unless (or (frame-parameter frame 'no-focus-on-map)
|
||||
;; Don't raise frames that should not get focus.
|
||||
(frame-parameter frame 'no-accept-focus)
|
||||
;; Assume the selected frame is already visible enough.
|
||||
(eq frame (selected-frame))
|
||||
;; Assume the frame from which we invoked the
|
||||
;; minibuffer is visible.
|
||||
(and (minibuffer-window-active-p (selected-window))
|
||||
(eq frame (window-frame (minibuffer-selected-window)))))
|
||||
(raise-frame frame)))
|
||||
|
||||
;; FIXME: Not implemented.
|
||||
;; FIXME: By the way, there could be more levels of dedication:
|
||||
|
|
@ -6762,6 +6767,7 @@ The actual non-nil value of this variable will be copied to the
|
|||
(const display-buffer-pop-up-window)
|
||||
(const display-buffer-same-window)
|
||||
(const display-buffer-pop-up-frame)
|
||||
(const display-buffer-in-child-frame)
|
||||
(const display-buffer-below-selected)
|
||||
(const display-buffer-at-bottom)
|
||||
(const display-buffer-in-previous-window)
|
||||
|
|
@ -6908,6 +6914,7 @@ Available action functions include:
|
|||
`display-buffer-same-window'
|
||||
`display-buffer-reuse-window'
|
||||
`display-buffer-pop-up-frame'
|
||||
`display-buffer-in-child-frame'
|
||||
`display-buffer-pop-up-window'
|
||||
`display-buffer-in-previous-window'
|
||||
`display-buffer-use-some-window'
|
||||
|
|
@ -7239,6 +7246,7 @@ raising the frame."
|
|||
(get-largest-window frame t) alist)
|
||||
(window--try-to-split-window
|
||||
(get-lru-window frame t) alist))))
|
||||
|
||||
(prog1 (window--display-buffer
|
||||
buffer window 'window alist display-buffer-mark-dedicated)
|
||||
(unless (cdr (assq 'inhibit-switch-frame alist))
|
||||
|
|
@ -7258,6 +7266,47 @@ again with `display-buffer-pop-up-window'."
|
|||
(and pop-up-windows
|
||||
(display-buffer-pop-up-window buffer alist))))
|
||||
|
||||
(defun display-buffer-in-child-frame (buffer alist)
|
||||
"Display BUFFER in a child frame.
|
||||
By default, this either reuses a child frame of the selected
|
||||
frame or makes a new child frame of the selected frame. If
|
||||
successful, return the window used; otherwise return nil.
|
||||
|
||||
If ALIST has a non-nil 'child-frame-parameters' entry, the
|
||||
corresponding value is an alist of frame parameters to give the
|
||||
new frame. A 'parent-frame' parameter specifying the selected
|
||||
frame is provided by default. If the child frame should be or
|
||||
become the child of any other frame, a corresponding entry must
|
||||
be added to ALIST."
|
||||
(let* ((parameters
|
||||
(append
|
||||
(cdr (assq 'child-frame-parameters alist))
|
||||
`((parent-frame . ,(selected-frame)))))
|
||||
(parent (or (assq 'parent-frame parameters)
|
||||
(selected-frame)))
|
||||
(share (assq 'share-child-frame parameters))
|
||||
share1 frame window)
|
||||
(with-current-buffer buffer
|
||||
(when (frame-live-p parent)
|
||||
(catch 'frame
|
||||
(dolist (frame1 (frame-list))
|
||||
(when (eq (frame-parent frame1) parent)
|
||||
(setq share1 (assq 'share-child-frame
|
||||
(frame-parameters frame1)))
|
||||
(when (eq share share1)
|
||||
(setq frame frame1)
|
||||
(throw 'frame t))))))
|
||||
|
||||
(if frame
|
||||
(setq window (frame-selected-window frame))
|
||||
(setq frame (make-frame parameters))
|
||||
(setq window (frame-selected-window frame))))
|
||||
|
||||
(prog1 (window--display-buffer
|
||||
buffer window 'frame alist display-buffer-mark-dedicated)
|
||||
(unless (cdr (assq 'inhibit-switch-frame alist))
|
||||
(window--maybe-raise-frame frame)))))
|
||||
|
||||
(defun display-buffer-below-selected (buffer alist)
|
||||
"Try displaying BUFFER in a window below the selected window.
|
||||
If there is a window below the selected one and that window
|
||||
|
|
@ -7272,7 +7321,8 @@ below the selected one, use that window."
|
|||
(and (not (frame-parameter nil 'unsplittable))
|
||||
(let ((split-height-threshold 0)
|
||||
split-width-threshold)
|
||||
(setq window (window--try-to-split-window (selected-window) alist)))
|
||||
(setq window (window--try-to-split-window
|
||||
(selected-window) alist)))
|
||||
(window--display-buffer
|
||||
buffer window 'window alist display-buffer-mark-dedicated))
|
||||
(and (setq window (window-in-direction 'below))
|
||||
|
|
@ -7885,10 +7935,12 @@ See also `fit-frame-to-buffer-margins'."
|
|||
(declare-function x-display-pixel-height "xfns.c" (&optional terminal))
|
||||
|
||||
(defun window--sanitize-margin (margin left right)
|
||||
"Return MARGIN if it's a number between LEFT and RIGHT."
|
||||
(when (and (numberp margin)
|
||||
(<= left (- right margin)) (<= margin right))
|
||||
margin))
|
||||
"Return MARGIN if it's a number between LEFT and RIGHT.
|
||||
Return 0 otherwise."
|
||||
(if (and (numberp margin)
|
||||
(<= left (- right margin)) (<= margin right))
|
||||
margin
|
||||
0))
|
||||
|
||||
(declare-function tool-bar-height "xdisp.c" (&optional frame pixelwise))
|
||||
|
||||
|
|
@ -7906,190 +7958,197 @@ horizontally only.
|
|||
|
||||
The new position and size of FRAME can be additionally determined
|
||||
by customizing the options `fit-frame-to-buffer-sizes' and
|
||||
`fit-frame-to-buffer-margins' or the corresponding parameters of
|
||||
FRAME."
|
||||
`fit-frame-to-buffer-margins' or setting the corresponding
|
||||
parameters of FRAME."
|
||||
(interactive)
|
||||
(unless (and (fboundp 'x-display-pixel-height)
|
||||
;; We need the respective sizes now.
|
||||
(fboundp 'display-monitor-attributes-list))
|
||||
(unless (fboundp 'display-monitor-attributes-list)
|
||||
(user-error "Cannot resize frame in non-graphic Emacs"))
|
||||
(setq frame (window-normalize-frame frame))
|
||||
(when (window-live-p (frame-root-window frame))
|
||||
(with-selected-window (frame-root-window frame)
|
||||
(let* ((char-width (frame-char-width))
|
||||
(char-height (frame-char-height))
|
||||
(monitor-attributes (car (display-monitor-attributes-list
|
||||
(frame-parameter frame 'display))))
|
||||
(geometry (cdr (assq 'geometry monitor-attributes)))
|
||||
(display-width (- (nth 2 geometry) (nth 0 geometry)))
|
||||
(display-height (- (nth 3 geometry) (nth 1 geometry)))
|
||||
(workarea (cdr (assq 'workarea monitor-attributes)))
|
||||
;; Handle margins.
|
||||
(margins (or (frame-parameter frame 'fit-frame-to-buffer-margins)
|
||||
fit-frame-to-buffer-margins))
|
||||
(left-margin (if (nth 0 margins)
|
||||
(or (window--sanitize-margin
|
||||
(nth 0 margins) 0 display-width)
|
||||
0)
|
||||
(nth 0 workarea)))
|
||||
(top-margin (if (nth 1 margins)
|
||||
(or (window--sanitize-margin
|
||||
(nth 1 margins) 0 display-height)
|
||||
0)
|
||||
(nth 1 workarea)))
|
||||
(workarea-width (nth 2 workarea))
|
||||
(right-margin (if (nth 2 margins)
|
||||
(- display-width
|
||||
(or (window--sanitize-margin
|
||||
(nth 2 margins) left-margin display-width)
|
||||
0))
|
||||
(nth 2 workarea)))
|
||||
(workarea-height (nth 3 workarea))
|
||||
(bottom-margin (if (nth 3 margins)
|
||||
(- display-height
|
||||
(or (window--sanitize-margin
|
||||
(nth 3 margins) top-margin display-height)
|
||||
0))
|
||||
(nth 3 workarea)))
|
||||
;; The pixel width of FRAME (which does not include the
|
||||
;; window manager's decorations).
|
||||
(frame-width (frame-pixel-width))
|
||||
;; The pixel width of the body of FRAME's root window.
|
||||
(window-body-width (window-body-width nil t))
|
||||
;; The difference in pixels between total and body width of
|
||||
;; FRAME's window.
|
||||
(window-extra-width (- (window-pixel-width) window-body-width))
|
||||
;; The difference in pixels between the frame's pixel width
|
||||
;; and the window's body width. This is the space we can't
|
||||
;; use for fitting.
|
||||
(extra-width (- frame-width window-body-width))
|
||||
;; The pixel position of FRAME's left border. We usually
|
||||
;; try to leave this alone.
|
||||
(left
|
||||
(let ((left (frame-parameter nil 'left)))
|
||||
(if (consp left)
|
||||
(funcall (car left) (cadr left))
|
||||
left)))
|
||||
;; The pixel height of FRAME (which does not include title
|
||||
;; line, decorations, and sometimes neither the menu nor
|
||||
;; the toolbar).
|
||||
(frame-height (frame-pixel-height))
|
||||
;; The pixel height of FRAME's root window (we don't care
|
||||
;; about the window's body height since the return value of
|
||||
;; `window-text-pixel-size' includes header and mode line).
|
||||
(window-height (window-pixel-height))
|
||||
;; The difference in pixels between the frame's pixel
|
||||
;; height and the window's height.
|
||||
(extra-height (- frame-height window-height))
|
||||
;; The pixel position of FRAME's top border.
|
||||
(top
|
||||
(let ((top (frame-parameter nil 'top)))
|
||||
(if (consp top)
|
||||
(funcall (car top) (cadr top))
|
||||
top)))
|
||||
;; Sanitize minimum and maximum sizes.
|
||||
(sizes (or (frame-parameter frame 'fit-frame-to-buffer-sizes)
|
||||
fit-frame-to-buffer-sizes))
|
||||
(max-height
|
||||
(cond
|
||||
((numberp (nth 0 sizes)) (* (nth 0 sizes) char-height))
|
||||
((numberp max-height) (* max-height char-height))
|
||||
(t display-height)))
|
||||
(min-height
|
||||
(cond
|
||||
((numberp (nth 1 sizes)) (* (nth 1 sizes) char-height))
|
||||
((numberp min-height) (* min-height char-height))
|
||||
(t (* window-min-height char-height))))
|
||||
(max-width
|
||||
(cond
|
||||
((numberp (nth 2 sizes))
|
||||
(- (* (nth 2 sizes) char-width) window-extra-width))
|
||||
((numberp max-width)
|
||||
(- (* max-width char-width) window-extra-width))
|
||||
(t display-width)))
|
||||
(min-width
|
||||
(cond
|
||||
((numberp (nth 3 sizes))
|
||||
(- (* (nth 3 sizes) char-width) window-extra-width))
|
||||
((numberp min-width)
|
||||
(- (* min-width char-width) window-extra-width))
|
||||
(t (* window-min-width char-width))))
|
||||
;; Note: Currently, for a new frame the sizes of the header
|
||||
;; and mode line may be estimated incorrectly
|
||||
(value (window-text-pixel-size
|
||||
nil t t workarea-width workarea-height t))
|
||||
(width (+ (car value) (window-right-divider-width)))
|
||||
(height
|
||||
(+ (cdr value)
|
||||
(window-bottom-divider-width)
|
||||
(window-scroll-bar-height))))
|
||||
;; Don't change height or width when the window's size is fixed
|
||||
;; in either direction or ONLY forbids it.
|
||||
(cond
|
||||
((or (eq window-size-fixed 'width) (eq only 'vertically))
|
||||
(setq width nil))
|
||||
((or (eq window-size-fixed 'height) (eq only 'horizontally))
|
||||
(setq height nil)))
|
||||
;; Fit width to constraints.
|
||||
(when width
|
||||
(unless frame-resize-pixelwise
|
||||
;; Round to character sizes.
|
||||
(setq width (* (/ (+ width char-width -1) char-width)
|
||||
char-width)))
|
||||
;; Fit to maximum and minimum widths.
|
||||
(setq width (max (min width max-width) min-width))
|
||||
;; Add extra width.
|
||||
(setq width (+ width extra-width))
|
||||
;; Preserve margins.
|
||||
(let ((right (+ left width)))
|
||||
(cond
|
||||
((> right right-margin)
|
||||
;; Move frame to left (we don't know its real width).
|
||||
(setq left (max left-margin (- left (- right right-margin)))))
|
||||
((< left left-margin)
|
||||
;; Move frame to right.
|
||||
(setq left left-margin)))))
|
||||
;; Fit height to constraints.
|
||||
(when height
|
||||
(unless frame-resize-pixelwise
|
||||
(setq height (* (/ (+ height char-height -1) char-height)
|
||||
char-height)))
|
||||
;; Fit to maximum and minimum heights.
|
||||
(setq height (max (min height max-height) min-height))
|
||||
;; Add extra height.
|
||||
(setq height (+ height extra-height))
|
||||
;; Preserve margins.
|
||||
(let ((bottom (+ top height)))
|
||||
(cond
|
||||
((> bottom bottom-margin)
|
||||
;; Move frame up (we don't know its real height).
|
||||
(setq top (max top-margin (- top (- bottom bottom-margin)))))
|
||||
((< top top-margin)
|
||||
;; Move frame down.
|
||||
(setq top top-margin)))))
|
||||
;; Apply changes.
|
||||
(set-frame-position frame left top)
|
||||
;; Clumsily try to translate our calculations to what
|
||||
;; `set-frame-size' wants.
|
||||
(when width
|
||||
(setq width (- (+ (frame-text-width) width)
|
||||
extra-width window-body-width)))
|
||||
(when height
|
||||
(setq height (- (+ (frame-text-height) height)
|
||||
extra-height window-height)))
|
||||
(set-frame-size
|
||||
frame
|
||||
(if width
|
||||
(if frame-resize-pixelwise
|
||||
width
|
||||
(/ width char-width))
|
||||
(frame-text-width))
|
||||
(if height
|
||||
(if frame-resize-pixelwise
|
||||
height
|
||||
(/ height char-height))
|
||||
(frame-text-height))
|
||||
frame-resize-pixelwise)))))
|
||||
(let* ((char-width (frame-char-width frame))
|
||||
(char-height (frame-char-height frame))
|
||||
;; WINDOW is FRAME's root window.
|
||||
(window (frame-root-window frame))
|
||||
(parent (frame-parent frame))
|
||||
(monitor-attributes
|
||||
(unless parent
|
||||
(car (display-monitor-attributes-list
|
||||
(frame-parameter frame 'display)))))
|
||||
;; FRAME'S parent or display sizes. Used in connection
|
||||
;; with margins.
|
||||
(geometry
|
||||
(unless parent
|
||||
(cdr (assq 'geometry monitor-attributes))))
|
||||
(parent-or-display-width
|
||||
(if parent
|
||||
(frame-native-width parent)
|
||||
(- (nth 2 geometry) (nth 0 geometry))))
|
||||
(parent-or-display-height
|
||||
(if parent
|
||||
(frame-native-height parent)
|
||||
(- (nth 3 geometry) (nth 1 geometry))))
|
||||
;; FRAME'S parent or workarea sizes. Used when no margins
|
||||
;; are specified.
|
||||
(parent-or-workarea
|
||||
(if parent
|
||||
`(0 0 ,parent-or-display-width ,parent-or-display-height)
|
||||
(cdr (assq 'workarea monitor-attributes))))
|
||||
;; The outer size of FRAME. Needed to calculate the
|
||||
;; margins around the root window's body that have to
|
||||
;; remain untouched by fitting.
|
||||
(outer-edges (frame-edges frame 'outer-edges))
|
||||
(outer-width (if outer-edges
|
||||
(- (nth 2 outer-edges) (nth 0 outer-edges))
|
||||
;; A poor guess.
|
||||
(frame-pixel-width frame)))
|
||||
(outer-height (if outer-edges
|
||||
(- (nth 3 outer-edges) (nth 1 outer-edges))
|
||||
;; Another poor guess.
|
||||
(frame-pixel-height frame)))
|
||||
;; The text size of of FRAME. Needed to specify FRAME's
|
||||
;; text size after the root window's body's new sizes have
|
||||
;; been calculated.
|
||||
(text-width (frame-text-width frame))
|
||||
(text-height (frame-text-height frame))
|
||||
;; WINDOW's body size.
|
||||
(body-width (window-body-width window t))
|
||||
(body-height (window-body-height window t))
|
||||
;; The difference between FRAME's outer size and WINDOW's
|
||||
;; body size.
|
||||
(outer-minus-body-width (- outer-width body-width))
|
||||
(outer-minus-body-height (- outer-height body-height))
|
||||
;; The difference between FRAME's text size and WINDOW's
|
||||
;; body size (these values "should" be positive).
|
||||
(text-minus-body-width (- text-width body-width))
|
||||
(text-minus-body-height (- text-height body-height))
|
||||
;; The current position of FRAME.
|
||||
(position (frame-position frame))
|
||||
(left (car position))
|
||||
(top (cdr position))
|
||||
;; The margins specified for FRAME. These represent pixel
|
||||
;; offsets from the left, top, right and bottom edge of the
|
||||
;; display or FRAME's parent's native rectangle and have to
|
||||
;; take care of the display's taskbar and other obstacles.
|
||||
;; If they are unspecified, constrain the resulting frame
|
||||
;; to its workarea or the parent frame's native rectangle.
|
||||
(margins (or (frame-parameter frame 'fit-frame-to-buffer-margins)
|
||||
fit-frame-to-buffer-margins))
|
||||
;; Convert margins intto pixel offsets from the left-top
|
||||
;; corner of FRAME's display or parent.
|
||||
(left-margin (if (nth 0 margins)
|
||||
(window--sanitize-margin
|
||||
(nth 0 margins) 0 parent-or-display-width)
|
||||
(nth 0 parent-or-workarea)))
|
||||
(top-margin (if (nth 1 margins)
|
||||
(window--sanitize-margin
|
||||
(nth 1 margins) 0 parent-or-display-height)
|
||||
(nth 1 parent-or-workarea)))
|
||||
(right-margin (if (nth 2 margins)
|
||||
(- parent-or-display-width
|
||||
(window--sanitize-margin
|
||||
(nth 2 margins) left-margin
|
||||
parent-or-display-width))
|
||||
(nth 2 parent-or-workarea)))
|
||||
(bottom-margin (if (nth 3 margins)
|
||||
(- parent-or-display-height
|
||||
(window--sanitize-margin
|
||||
(nth 3 margins) top-margin
|
||||
parent-or-display-height))
|
||||
(nth 3 parent-or-workarea)))
|
||||
;; Minimum and maximum sizes specified for FRAME.
|
||||
(sizes (or (frame-parameter frame 'fit-frame-to-buffer-sizes)
|
||||
fit-frame-to-buffer-sizes))
|
||||
;; Calculate the minimum and maximum pixel sizes of FRAME
|
||||
;; from the values provided by the MAX-HEIGHT, MIN-HEIGHT,
|
||||
;; MAX-WIDTH and MIN-WIDTH arguments or, if these are nil,
|
||||
;; from those provided by `fit-frame-to-buffer-sizes'.
|
||||
(max-height
|
||||
(min
|
||||
(cond
|
||||
((numberp max-height) (* max-height char-height))
|
||||
((numberp (nth 0 sizes)) (* (nth 0 sizes) char-height))
|
||||
(t parent-or-display-height))
|
||||
;; The following is the maximum height that fits into the
|
||||
;; top and bottom margins.
|
||||
(max (- bottom-margin top-margin outer-minus-body-height))))
|
||||
(min-height
|
||||
(cond
|
||||
((numberp min-height) (* min-height char-height))
|
||||
((numberp (nth 1 sizes)) (* (nth 1 sizes) char-height))
|
||||
(t (window-min-size window nil nil t))))
|
||||
(max-width
|
||||
(min
|
||||
(cond
|
||||
((numberp max-width) (* max-width char-width))
|
||||
((numberp (nth 2 sizes)) (* (nth 2 sizes) char-width))
|
||||
(t parent-or-display-width))
|
||||
;; The following is the maximum width that fits into the
|
||||
;; left and right margins.
|
||||
(max (- right-margin left-margin outer-minus-body-width))))
|
||||
(min-width
|
||||
(cond
|
||||
((numberp min-width) (* min-width char-width))
|
||||
((numberp (nth 3 sizes)) (nth 3 sizes))
|
||||
(t (window-min-size window t nil t))))
|
||||
;; Note: Currently, for a new frame the sizes of the header
|
||||
;; and mode line may be estimated incorrectly
|
||||
(size
|
||||
(window-text-pixel-size window t t max-width max-height))
|
||||
(width (max (car size) min-width))
|
||||
(height (max (cdr size) min-height)))
|
||||
;; Don't change height or width when the window's size is fixed
|
||||
;; in either direction or ONLY forbids it.
|
||||
(cond
|
||||
((or (eq window-size-fixed 'width) (eq only 'vertically))
|
||||
(setq width nil))
|
||||
((or (eq window-size-fixed 'height) (eq only 'horizontally))
|
||||
(setq height nil)))
|
||||
;; Fit width to constraints.
|
||||
(when width
|
||||
(unless frame-resize-pixelwise
|
||||
;; Round to character sizes.
|
||||
(setq width (* (/ (+ width char-width -1) char-width)
|
||||
char-width)))
|
||||
;; The new outer width (in pixels).
|
||||
(setq outer-width (+ width outer-minus-body-width))
|
||||
;; Maybe move FRAME to preserve margins.
|
||||
(let ((right (+ left outer-width)))
|
||||
(cond
|
||||
((> right right-margin)
|
||||
;; Move frame to left.
|
||||
(setq left (max left-margin (- left (- right right-margin)))))
|
||||
((< left left-margin)
|
||||
;; Move frame to right.
|
||||
(setq left left-margin)))))
|
||||
;; Fit height to constraints.
|
||||
(when height
|
||||
(unless frame-resize-pixelwise
|
||||
(setq height (* (/ (+ height char-height -1) char-height)
|
||||
char-height)))
|
||||
;; The new outer height.
|
||||
(setq outer-height (+ height outer-minus-body-height))
|
||||
;; Preserve margins.
|
||||
(let ((bottom (+ top outer-height)))
|
||||
(cond
|
||||
((> bottom bottom-margin)
|
||||
;; Move frame up.
|
||||
(setq top (max top-margin (- top (- bottom bottom-margin)))))
|
||||
((< top top-margin)
|
||||
;; Move frame down.
|
||||
(setq top top-margin)))))
|
||||
;; Apply our changes.
|
||||
(setq text-width
|
||||
(if width
|
||||
(+ width text-minus-body-width)
|
||||
(frame-text-width frame)))
|
||||
(setq text-height
|
||||
(if height
|
||||
(+ height text-minus-body-height)
|
||||
(frame-text-height frame)))
|
||||
(modify-frame-parameters
|
||||
frame `((left . ,left) (top . ,top)
|
||||
(width . (text-pixels . ,text-width))
|
||||
(height . (text-pixels . ,text-height)))))))
|
||||
|
||||
(defun fit-window-to-buffer (&optional window max-height min-height max-width min-width preserve-size)
|
||||
"Adjust size of WINDOW to display its buffer's contents exactly.
|
||||
|
|
@ -8286,6 +8345,168 @@ Return non-nil if the window was shrunk, nil otherwise."
|
|||
(when (and (window-combined-p window)
|
||||
(pos-visible-in-window-p (point-min) window))
|
||||
(fit-window-to-buffer window (window-total-height window))))
|
||||
|
||||
(defun window-largest-empty-rectangle--maximums-1 (quad maximums)
|
||||
"Support function for `window-largest-empty-rectangle'."
|
||||
(cond
|
||||
((null maximums)
|
||||
(list quad))
|
||||
((> (car quad) (caar maximums))
|
||||
(cons quad maximums))
|
||||
(t
|
||||
(cons (car maximums)
|
||||
(window-largest-empty-rectangle--maximums-1 quad (cdr maximums))))))
|
||||
|
||||
(defun window-largest-empty-rectangle--maximums (quad maximums count)
|
||||
"Support function for `window-largest-empty-rectangle'."
|
||||
(setq maximums (window-largest-empty-rectangle--maximums-1 quad maximums))
|
||||
(if (> (length maximums) count)
|
||||
(nbutlast maximums)
|
||||
maximums))
|
||||
|
||||
(defun window-largest-empty-rectangle--disjoint-maximums (maximums count)
|
||||
"Support function for `window-largest-empty-rectangle'."
|
||||
(setq maximums (sort maximums (lambda (x y) (> (car x) (car y)))))
|
||||
(let ((new-length 0)
|
||||
new-maximums)
|
||||
(while (and maximums (< new-length count))
|
||||
(let* ((maximum (car maximums))
|
||||
(at (nth 2 maximum))
|
||||
(to (nth 3 maximum)))
|
||||
(catch 'drop
|
||||
(dolist (new-maximum new-maximums)
|
||||
(let ((new-at (nth 2 new-maximum))
|
||||
(new-to (nth 3 new-maximum)))
|
||||
(when (if (< at new-at) (> to new-at) (< at new-to))
|
||||
;; Intersection -> drop.
|
||||
(throw 'drop nil))))
|
||||
(setq new-maximums (cons maximum new-maximums))
|
||||
(setq new-length (1+ new-length)))
|
||||
(setq maximums (cdr maximums))))
|
||||
|
||||
(nreverse new-maximums)))
|
||||
|
||||
(defun window-largest-empty-rectangle (&optional window count min-width min-height positions left)
|
||||
"Return dimensions of largest empty rectangle in WINDOW.
|
||||
WINDOW must be a live window and defaults to the selected one.
|
||||
|
||||
The return value is a triple of the width and the start and end
|
||||
Y-coordinates of the largest rectangle that can be inscribed into
|
||||
the empty space (the space not displaying any text) of WINDOW's
|
||||
text area. The return value is nil if the current glyph matrix
|
||||
of WINDOW is not up-to-date.
|
||||
|
||||
Optional argument COUNT, if non-nil, specifies the maximum number
|
||||
of rectangles to return. This means that the return value is a
|
||||
list of triples specifying rectangles with the largest rectangle
|
||||
first. COUNT can be also a cons cell whose car specifies the
|
||||
number of rectangles to return and whose cdr, if non-nil, states
|
||||
that all rectangles returned must be disjoint.
|
||||
|
||||
Note that the right edge of any rectangle returned by this
|
||||
function is the right edge of WINDOW (the left edge if its buffer
|
||||
displays RTL text).
|
||||
|
||||
Optional arguments MIN-WIDTH and MIN-HEIGHT, if non-nil, specify
|
||||
the minimum width and height of any rectangle returned.
|
||||
|
||||
Optional argument POSITIONS, if non-nil, is a cons cell whose car
|
||||
specifies the uppermost and whose cdr specifies the lowermost
|
||||
pixel position that must be covered by any rectangle returned.
|
||||
Note that positions are counted from the start of the text area
|
||||
of WINDOW.
|
||||
|
||||
Optional argument LEFT, if non-nil, means to return values suitable for
|
||||
buffers displaying right to left text."
|
||||
;; Process lines as returned by ‘window-lines-pixel-dimensions’.
|
||||
;; STACK is a stack that contains rows that have to be processed yet.
|
||||
(let* ((window (window-normalize-window window t))
|
||||
(disjoint (and (consp count) (cdr count)))
|
||||
(count (or (and (numberp count) count)
|
||||
(and (consp count) (numberp (car count)) (car count))))
|
||||
(rows (window-lines-pixel-dimensions window nil nil t t left))
|
||||
(rows-at 0)
|
||||
(max-size 0)
|
||||
row stack stack-at stack-to
|
||||
top top-width top-at top-to top-size
|
||||
max-width max-at max-to maximums)
|
||||
;; ROWS-AT is the position where the first element of ROWS starts.
|
||||
;; STACK-AT is the position where the first element of STACK starts.
|
||||
(while rows
|
||||
(setq row (car rows))
|
||||
(if (or (not stack) (>= (car row) (caar stack)))
|
||||
(progn
|
||||
(unless stack
|
||||
(setq stack-at rows-at))
|
||||
(setq stack (cons row stack))
|
||||
;; Set ROWS-AT to where the first element of ROWS ends
|
||||
;; which, after popping ROW, makes it the start position of
|
||||
;; the next ROW.
|
||||
(setq rows-at (cdr row))
|
||||
(setq rows (cdr rows)))
|
||||
(setq top (car stack))
|
||||
(setq stack (cdr stack))
|
||||
(setq top-width (car top))
|
||||
(setq top-at (if stack (cdar stack) stack-at))
|
||||
(setq top-to (cdr top))
|
||||
(setq top-size (* top-width (- top-to top-at)))
|
||||
(unless (or (and min-width (< top-width min-width))
|
||||
(and min-height (< (- top-to top-at) min-height))
|
||||
(and positions
|
||||
(or (> top-at (car positions))
|
||||
(< top-to (cdr positions)))))
|
||||
(if count
|
||||
(if disjoint
|
||||
(setq maximums (cons (list top-size top-width top-at top-to)
|
||||
maximums))
|
||||
(setq maximums (window-largest-empty-rectangle--maximums
|
||||
(list top-size top-width top-at top-to)
|
||||
maximums count)))
|
||||
(when (> top-size max-size)
|
||||
(setq max-size top-size)
|
||||
(setq max-width top-width)
|
||||
(setq max-at top-at)
|
||||
(setq max-to top-to))))
|
||||
(if (and stack (> (caar stack) (car row)))
|
||||
;; Have new top element of stack include old top.
|
||||
(setq stack (cons (cons (caar stack) (cdr top)) (cdr stack)))
|
||||
;; Move rows-at backwards to top-at.
|
||||
(setq rows-at top-at))))
|
||||
|
||||
(when stack
|
||||
;; STACK-TO is the position where the stack ends.
|
||||
(setq stack-to (cdar stack))
|
||||
(while stack
|
||||
(setq top (car stack))
|
||||
(setq stack (cdr stack))
|
||||
(setq top-width (car top))
|
||||
(setq top-at (if stack (cdar stack) stack-at))
|
||||
(setq top-size (* top-width (- stack-to top-at)))
|
||||
(unless (or (and min-width (< top-width min-width))
|
||||
(and min-height (< (- stack-to top-at) min-height))
|
||||
(and positions
|
||||
(or (> top-at (car positions))
|
||||
(< stack-to (cdr positions)))))
|
||||
(if count
|
||||
(if disjoint
|
||||
(setq maximums (cons (list top-size top-width top-at stack-to)
|
||||
maximums))
|
||||
(setq maximums (window-largest-empty-rectangle--maximums
|
||||
(list top-size top-width top-at stack-to)
|
||||
maximums count)))
|
||||
(when (> top-size max-size)
|
||||
(setq max-size top-size)
|
||||
(setq max-width top-width)
|
||||
(setq max-at top-at)
|
||||
(setq max-to stack-to))))))
|
||||
|
||||
(cond
|
||||
(maximums
|
||||
(if disjoint
|
||||
(window-largest-empty-rectangle--disjoint-maximums maximums count)
|
||||
maximums))
|
||||
((> max-size 0)
|
||||
(list max-width max-at max-to)))))
|
||||
|
||||
(defun kill-buffer-and-window ()
|
||||
"Kill the current buffer and delete the selected window."
|
||||
|
|
|
|||
|
|
@ -1106,7 +1106,7 @@ struct glyph_row *matrix_row (struct glyph_matrix *, int);
|
|||
#define MATRIX_BOTTOM_TEXT_ROW(MATRIX, W) \
|
||||
((MATRIX)->rows \
|
||||
+ (MATRIX)->nrows \
|
||||
- (WINDOW_WANTS_MODELINE_P ((W)) ? 1 : 0))
|
||||
- (window_wants_mode_line ((W)) ? 1 : 0))
|
||||
|
||||
/* Non-zero if the face of the last glyph in ROW's text area has
|
||||
to be drawn to the end of the text area. */
|
||||
|
|
@ -1469,40 +1469,6 @@ struct glyph_string
|
|||
#define DESIRED_HEADER_LINE_HEIGHT(W) \
|
||||
MATRIX_HEADER_LINE_HEIGHT ((W)->desired_matrix)
|
||||
|
||||
/* PXW: The height checks below serve to show at least one text line
|
||||
instead of a mode- and/or header line when a window gets very small.
|
||||
But (1) the check fails when the mode- or header-line is taller than
|
||||
the associated frame's line height and (2) we don't care much about
|
||||
text visibility anyway when shrinking a frame containing a toolbar.
|
||||
|
||||
So maybe these checks should be removed and any clipping left to the
|
||||
window manager. */
|
||||
|
||||
/* Value is true if window W wants a mode line and is large enough
|
||||
to accommodate it. */
|
||||
#define WINDOW_WANTS_MODELINE_P(W) \
|
||||
(BUFFERP ((W)->contents) \
|
||||
? (!MINI_WINDOW_P (W) \
|
||||
&& !(W)->pseudo_window_p \
|
||||
&& FRAME_WANTS_MODELINE_P (XFRAME (WINDOW_FRAME (W))) \
|
||||
&& !NILP (BVAR (XBUFFER ((W)->contents), mode_line_format)) \
|
||||
&& WINDOW_PIXEL_HEIGHT (W) > WINDOW_FRAME_LINE_HEIGHT (W)) \
|
||||
: false)
|
||||
|
||||
/* Value is true if window W wants a header line and is large enough
|
||||
to accommodate it. */
|
||||
#define WINDOW_WANTS_HEADER_LINE_P(W) \
|
||||
(BUFFERP ((W)->contents) \
|
||||
? (!MINI_WINDOW_P (W) \
|
||||
&& !(W)->pseudo_window_p \
|
||||
&& FRAME_WANTS_MODELINE_P (XFRAME (WINDOW_FRAME (W))) \
|
||||
&& !NILP (BVAR (XBUFFER ((W)->contents), header_line_format)) \
|
||||
&& (WINDOW_PIXEL_HEIGHT (W) \
|
||||
> (WINDOW_WANTS_MODELINE_P (W) \
|
||||
? (2 * WINDOW_FRAME_LINE_HEIGHT (W)) \
|
||||
: WINDOW_FRAME_LINE_HEIGHT (W)))) \
|
||||
: false)
|
||||
|
||||
/* Return proper value to be used as baseline offset of font that has
|
||||
ASCENT and DESCENT to draw characters by the font at the vertical
|
||||
center of the line of frame F.
|
||||
|
|
|
|||
|
|
@ -377,7 +377,7 @@ adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y
|
|||
{
|
||||
window_box (w, ANY_AREA, 0, 0, &window_width, &window_height);
|
||||
|
||||
header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
|
||||
header_line_p = window_wants_header_line (w);
|
||||
header_line_changed_p = header_line_p != matrix->header_line_p;
|
||||
}
|
||||
matrix->header_line_p = header_line_p;
|
||||
|
|
@ -446,7 +446,7 @@ adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y
|
|||
|
||||
if (w == NULL
|
||||
|| (row == matrix->rows + dim.height - 1
|
||||
&& WINDOW_WANTS_MODELINE_P (w))
|
||||
&& window_wants_mode_line (w))
|
||||
|| (row == matrix->rows && matrix->header_line_p))
|
||||
{
|
||||
row->glyphs[TEXT_AREA]
|
||||
|
|
@ -491,7 +491,7 @@ adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y
|
|||
|
||||
/* The mode line, if displayed, never has marginal areas. */
|
||||
if ((row == matrix->rows + dim.height - 1
|
||||
&& !(w && WINDOW_WANTS_MODELINE_P (w)))
|
||||
&& !(w && window_wants_mode_line (w)))
|
||||
|| (row == matrix->rows && matrix->header_line_p))
|
||||
{
|
||||
row->glyphs[TEXT_AREA]
|
||||
|
|
@ -570,7 +570,7 @@ adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y
|
|||
the mode line, if any, since otherwise it will remain
|
||||
disabled in the current matrix, and expose events won't
|
||||
redraw it. */
|
||||
if (WINDOW_WANTS_MODELINE_P (w))
|
||||
if (window_wants_mode_line (w))
|
||||
w->update_mode_line = 1;
|
||||
}
|
||||
else if (matrix == w->desired_matrix)
|
||||
|
|
@ -5188,7 +5188,7 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p
|
|||
start position, i.e. it excludes the header-line row, but
|
||||
MATRIX_ROW includes the header-line row. Adjust for a possible
|
||||
header-line row. */
|
||||
it_vpos = it.vpos + WINDOW_WANTS_HEADER_LINE_P (w);
|
||||
it_vpos = it.vpos + window_wants_header_line (w);
|
||||
if (it_vpos < w->current_matrix->nrows
|
||||
&& (row = MATRIX_ROW (w->current_matrix, it_vpos),
|
||||
row->enabled_p))
|
||||
|
|
|
|||
789
src/frame.c
789
src/frame.c
|
|
@ -328,8 +328,8 @@ DEFUN ("frame-windows-min-size", Fframe_windows_min_size,
|
|||
* frame_windows_min_size:
|
||||
*
|
||||
* Return the minimum number of lines (columns if HORIZONTAL is non-nil)
|
||||
* of FRAME. If PIXELWISE is non-nil, return the minimum height (width)
|
||||
* in pixels.
|
||||
* of FRAME. If PIXELWISE is non-nil, return the minimum inner height
|
||||
* (width) of FRAME in pixels.
|
||||
*
|
||||
* This value is calculated by the function `frame-windows-min-size' in
|
||||
* window.el unless the `min-height' (`min-width' if HORIZONTAL is
|
||||
|
|
@ -341,7 +341,7 @@ DEFUN ("frame-windows-min-size", Fframe_windows_min_size,
|
|||
* of `window-min-height' (`window-min-width' if HORIZONTAL is non-nil).
|
||||
* With IGNORE non-nil the values of these variables are ignored.
|
||||
*
|
||||
* In either case never return a value less than 1.
|
||||
* In either case, never return a value less than 1.
|
||||
*/
|
||||
static int
|
||||
frame_windows_min_size (Lisp_Object frame, Lisp_Object horizontal,
|
||||
|
|
@ -373,46 +373,179 @@ frame_windows_min_size (Lisp_Object frame, Lisp_Object horizontal,
|
|||
}
|
||||
|
||||
|
||||
/* Make sure windows sizes of frame F are OK. new_width and new_height
|
||||
are in pixels. A value of -1 means no change is requested for that
|
||||
size (but the frame may still have to be resized to accommodate
|
||||
windows with their minimum sizes). This can either issue a request
|
||||
to resize the frame externally (via x_set_window_size), to resize the
|
||||
frame internally (via resize_frame_windows) or do nothing at all.
|
||||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
/**
|
||||
* keep_ratio:
|
||||
*
|
||||
* Preserve ratios of frame F which usually happens after its parent
|
||||
* frame got resized. OLD_WIDTH, OLD_HEIGHT specifies the old native
|
||||
* size of F's parent, NEW_WIDTH and NEW_HEIGHT its new size.
|
||||
*
|
||||
* Adjust F's width if F's 'keep_ratio' parameter is non-nil and, if
|
||||
* it is a cons, its car is not 'height-only'. Adjust F's height if F's
|
||||
* 'keep_ratio' parameter is non-nil and, if it is a cons, its car
|
||||
* is not 'width-only'.
|
||||
*
|
||||
* Adjust F's left position if F's 'keep_ratio' parameter is non-nil
|
||||
* and, if its is a cons, its cdr is non-nil and not 'top-only'. Adjust
|
||||
* F's top position if F's 'keep_ratio' parameter is non-nil and, if
|
||||
* its is a cons, its cdr is non-nil and not 'left-only'.
|
||||
*
|
||||
* Note that when positional adjustment is requested but the size of F
|
||||
* should remain unaltered in the corresponding direction, this routine
|
||||
* tries to constrain F to its parent frame - something which usually
|
||||
* happens when the parent frame shrinks. This means, however, that
|
||||
* when the parent frame is re-enlarged later, the child's original
|
||||
* position will not get restored to its pre-shrinking value.
|
||||
*
|
||||
* This routine is currently useful for child frames only. It might be
|
||||
* eventually useful when moving non-child frames between monitors with
|
||||
* different resolutions.
|
||||
*/
|
||||
static void
|
||||
keep_ratio (struct frame *f, int old_width, int old_height,
|
||||
int new_width, int new_height)
|
||||
{
|
||||
Lisp_Object keep_ratio = get_frame_param (f, Qkeep_ratio);
|
||||
|
||||
The argument INHIBIT can assume the following values:
|
||||
|
||||
0 means to unconditionally call x_set_window_size even if sizes
|
||||
apparently do not change. Fx_create_frame uses this to pass the
|
||||
initial size to the window manager.
|
||||
if (!NILP (keep_ratio))
|
||||
{
|
||||
double width_factor = (double)new_width / (double)old_width;
|
||||
double height_factor = (double)new_height / (double)old_height;
|
||||
int pixel_width, pixel_height, pos_x, pos_y;
|
||||
|
||||
1 means to call x_set_window_size if the outer frame size really
|
||||
changes. Fset_frame_size, Fset_frame_height, ... use this.
|
||||
if (!CONSP (keep_ratio) || !NILP (Fcdr (keep_ratio)))
|
||||
{
|
||||
if (CONSP (keep_ratio) && EQ (Fcdr (keep_ratio), Qtop_only))
|
||||
pos_x = f->left_pos;
|
||||
else
|
||||
{
|
||||
pos_x = (int)(f->left_pos * width_factor + 0.5);
|
||||
|
||||
2 means to call x_set_window_size provided frame_inhibit_resize
|
||||
allows it. The menu and tool bar code use this ("3" won't work
|
||||
here in general because menu and tool bar are often not counted in
|
||||
the frame's text height).
|
||||
if (CONSP (keep_ratio) &&
|
||||
(NILP (Fcar (keep_ratio)) || EQ (Fcar (keep_ratio), Qheight_only)))
|
||||
{
|
||||
struct frame *p = FRAME_PARENT_FRAME (f);
|
||||
|
||||
3 means call x_set_window_size if window minimum sizes must be
|
||||
preserved or frame_inhibit_resize allows it. x_set_left_fringe,
|
||||
x_set_scroll_bar_width, x_new_font ... use (or should use) this.
|
||||
if (pos_x + f->pixel_width > p->pixel_width)
|
||||
{
|
||||
int p_f_width = p->pixel_width - f->pixel_width;
|
||||
|
||||
4 means call x_set_window_size only if window minimum sizes must be
|
||||
preserved. x_set_right_divider_width, x_set_border_width and the
|
||||
code responsible for wrapping the tool bar use this.
|
||||
if (p_f_width <= 0)
|
||||
pos_x = 0;
|
||||
else
|
||||
pos_x = (int)(p_f_width * width_factor * 0.5 + 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
5 means to never call x_set_window_size. change_frame_size uses
|
||||
this.
|
||||
f->left_pos = pos_x;
|
||||
}
|
||||
|
||||
Note that even when x_set_window_size is not called, individual
|
||||
windows may have to be resized (via `window--sanitize-window-sizes')
|
||||
in order to support minimum size constraints.
|
||||
if (CONSP (keep_ratio) && EQ (Fcdr (keep_ratio), Qleft_only))
|
||||
pos_y = f->top_pos;
|
||||
else
|
||||
{
|
||||
pos_y = (int)(f->top_pos * height_factor + 0.5);
|
||||
|
||||
PRETEND is as for change_frame_size. PARAMETER, if non-nil, is the
|
||||
symbol of the parameter changed (like `menu-bar-lines', `font', ...).
|
||||
This is passed on to frame_inhibit_resize to let the latter decide on
|
||||
a case-by-case basis whether the frame may be resized externally. */
|
||||
if (CONSP (keep_ratio) &&
|
||||
(NILP (Fcar (keep_ratio)) || EQ (Fcar (keep_ratio), Qwidth_only)))
|
||||
/* When positional adjustment was requested and the
|
||||
width of F should remain unaltered, try to constrain
|
||||
F to its parent. This means that when the parent
|
||||
frame is enlarged later the child's original position
|
||||
won't get restored. */
|
||||
{
|
||||
struct frame *p = FRAME_PARENT_FRAME (f);
|
||||
|
||||
if (pos_y + f->pixel_height > p->pixel_height)
|
||||
{
|
||||
int p_f_height = p->pixel_height - f->pixel_height;
|
||||
|
||||
if (p_f_height <= 0)
|
||||
pos_y = 0;
|
||||
else
|
||||
pos_y = (int)(p_f_height * height_factor * 0.5 + 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
f->top_pos = pos_y;
|
||||
}
|
||||
|
||||
x_set_offset (f, pos_x, pos_y, -1);
|
||||
}
|
||||
|
||||
if (!CONSP (keep_ratio) || !NILP (Fcar (keep_ratio)))
|
||||
{
|
||||
if (CONSP (keep_ratio) && EQ (Fcar (keep_ratio), Qheight_only))
|
||||
pixel_width = -1;
|
||||
else
|
||||
{
|
||||
pixel_width = (int)(f->pixel_width * width_factor + 0.5);
|
||||
pixel_width = FRAME_PIXEL_TO_TEXT_WIDTH (f, pixel_width);
|
||||
}
|
||||
|
||||
if (CONSP (keep_ratio) && EQ (Fcar (keep_ratio), Qwidth_only))
|
||||
pixel_height = -1;
|
||||
else
|
||||
{
|
||||
pixel_height = (int)(f->pixel_height * height_factor + 0.5);
|
||||
pixel_height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixel_height);
|
||||
}
|
||||
|
||||
adjust_frame_size (f, pixel_width, pixel_height, 1, 0,
|
||||
Qkeep_ratio);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* adjust_frame_size:
|
||||
*
|
||||
* Adjust size of frame F. NEW_WIDTH and NEW_HEIGHT specify the new
|
||||
* text size of F in pixels. A value of -1 means no change is requested
|
||||
* for that direction (but the frame may still have to be resized to
|
||||
* accommodate windows with their minimum sizes). This can either issue
|
||||
* a request to resize the frame externally (via x_set_window_size), to
|
||||
* resize the frame internally (via resize_frame_windows) or do nothing
|
||||
* at all.
|
||||
*
|
||||
* The argument INHIBIT can assume the following values:
|
||||
*
|
||||
* 0 means to unconditionally call x_set_window_size even if sizes
|
||||
* apparently do not change. Fx_create_frame uses this to pass the
|
||||
* initial size to the window manager.
|
||||
*
|
||||
* 1 means to call x_set_window_size if the native frame size really
|
||||
* changes. Fset_frame_size, Fset_frame_height, ... use this.
|
||||
*
|
||||
* 2 means to call x_set_window_size provided frame_inhibit_resize
|
||||
* allows it. The menu and tool bar code use this ("3" won't work
|
||||
* here in general because menu and tool bar are often not counted in
|
||||
* the frame's text height).
|
||||
*
|
||||
* 3 means call x_set_window_size if window minimum sizes must be
|
||||
* preserved or frame_inhibit_resize allows it. x_set_left_fringe,
|
||||
* x_set_scroll_bar_width, x_new_font ... use (or should use) this.
|
||||
*
|
||||
* 4 means call x_set_window_size only if window minimum sizes must be
|
||||
* preserved. x_set_right_divider_width, x_set_border_width and the
|
||||
* code responsible for wrapping the tool bar use this.
|
||||
*
|
||||
* 5 means to never call x_set_window_size. change_frame_size uses
|
||||
* this.
|
||||
*
|
||||
* Note that even when x_set_window_size is not called, individual
|
||||
* windows may have to be resized (via `window--sanitize-window-sizes')
|
||||
* in order to support minimum size constraints.
|
||||
*
|
||||
* PRETEND is as for change_frame_size. PARAMETER, if non-nil, is the
|
||||
* symbol of the parameter changed (like `menu-bar-lines', `font', ...).
|
||||
* This is passed on to frame_inhibit_resize to let the latter decide on
|
||||
* a case-by-case basis whether the frame may be resized externally.
|
||||
*/
|
||||
void
|
||||
adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit,
|
||||
bool pretend, Lisp_Object parameter)
|
||||
|
|
@ -636,6 +769,18 @@ adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit,
|
|||
|| new_pixel_height != old_pixel_height);
|
||||
|
||||
unblock_input ();
|
||||
|
||||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
{
|
||||
/* Adjust size of F's child frames. */
|
||||
Lisp_Object frames, frame1;
|
||||
|
||||
FOR_EACH_FRAME (frames, frame1)
|
||||
if (FRAME_PARENT_FRAME (XFRAME (frame1)) == f)
|
||||
keep_ratio (XFRAME (frame1), old_pixel_width, old_pixel_height,
|
||||
new_pixel_width, new_pixel_height);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Allocate basically initialized frame. */
|
||||
|
|
@ -684,6 +829,7 @@ make_frame (bool mini_p)
|
|||
f->horizontal_scroll_bars = false;
|
||||
f->want_fullscreen = FULLSCREEN_NONE;
|
||||
f->undecorated = false;
|
||||
f->no_special_glyphs = false;
|
||||
#ifndef HAVE_NTGUI
|
||||
f->override_redirect = false;
|
||||
#endif
|
||||
|
|
@ -2004,8 +2150,101 @@ The functions are run with one argument, the frame to be deleted. */)
|
|||
{
|
||||
return delete_frame (frame, !NILP (force) ? Qt : Qnil);
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
/**
|
||||
* frame_internal_border_part:
|
||||
*
|
||||
* Return part of internal border the coordinates X and Y relative to
|
||||
* frame F are on. Return nil if the coordinates are not on the
|
||||
* internal border of F.
|
||||
*
|
||||
* Return one of INTERNAL_BORDER_LEFT_EDGE, INTERNAL_BORDER_TOP_EDGE,
|
||||
* INTERNAL_BORDER_RIGHT_EDGE or INTERNAL_BORDER_BOTTOM_EDGE when the
|
||||
* mouse cursor is on the corresponding border with an offset of at
|
||||
* least one canonical character height from that border's edges.
|
||||
*
|
||||
* If no border part could be found this way, return one of
|
||||
* INTERNAL_BORDER_TOP_LEFT_CORNER, INTERNAL_BORDER_TOP_RIGHT_CORNER,
|
||||
* INTERNAL_BORDER_BOTTOM_LEFT_CORNER or
|
||||
* INTERNAL_BORDER_BOTTOM_RIGHT_CORNER to indicate that the mouse is in
|
||||
* one of the corresponding corners. This means that for very small
|
||||
* frames an `edge' return value is preferred.
|
||||
*/
|
||||
enum internal_border_part
|
||||
frame_internal_border_part (struct frame *f, int x, int y)
|
||||
{
|
||||
int border = FRAME_INTERNAL_BORDER_WIDTH (f);
|
||||
int offset = FRAME_LINE_HEIGHT (f);
|
||||
int width = FRAME_PIXEL_WIDTH (f);
|
||||
int height = FRAME_PIXEL_HEIGHT (f);
|
||||
enum internal_border_part part = INTERNAL_BORDER_NONE;
|
||||
|
||||
if (offset < border)
|
||||
/* For very wide borders make offset at least as large as
|
||||
border. */
|
||||
offset = border;
|
||||
|
||||
if (offset < x && x < width - offset)
|
||||
/* Top or bottom border. */
|
||||
{
|
||||
if (0 <= y && y <= border)
|
||||
part = INTERNAL_BORDER_TOP_EDGE;
|
||||
else if (height - border <= y && y <= height)
|
||||
part = INTERNAL_BORDER_BOTTOM_EDGE;
|
||||
}
|
||||
else if (offset < y && y < height - offset)
|
||||
/* Left or right border. */
|
||||
{
|
||||
if (0 <= x && x <= border)
|
||||
part = INTERNAL_BORDER_LEFT_EDGE;
|
||||
else if (width - border <= x && x <= width)
|
||||
part = INTERNAL_BORDER_RIGHT_EDGE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* An edge. */
|
||||
int half_width = width / 2;
|
||||
int half_height = height / 2;
|
||||
|
||||
if (0 <= x && x <= border)
|
||||
{
|
||||
/* A left edge. */
|
||||
if (0 <= y && y <= half_height)
|
||||
part = INTERNAL_BORDER_TOP_LEFT_CORNER;
|
||||
else if (half_height < y && y <= height)
|
||||
part = INTERNAL_BORDER_BOTTOM_LEFT_CORNER;
|
||||
}
|
||||
else if (width - border <= x && x <= width)
|
||||
{
|
||||
/* A right edge. */
|
||||
if (0 <= y && y <= half_height)
|
||||
part = INTERNAL_BORDER_TOP_RIGHT_CORNER;
|
||||
else if (half_height < y && y <= height)
|
||||
part = INTERNAL_BORDER_BOTTOM_RIGHT_CORNER;
|
||||
}
|
||||
else if (0 <= y && y <= border)
|
||||
{
|
||||
/* A top edge. */
|
||||
if (0 <= x && x <= half_width)
|
||||
part = INTERNAL_BORDER_TOP_LEFT_CORNER;
|
||||
else if (half_width < x && x <= width)
|
||||
part = INTERNAL_BORDER_TOP_RIGHT_CORNER;
|
||||
}
|
||||
else if (height - border <= y && y <= height)
|
||||
{
|
||||
/* A bottom edge. */
|
||||
if (0 <= x && x <= half_width)
|
||||
part = INTERNAL_BORDER_BOTTOM_LEFT_CORNER;
|
||||
else if (half_width < x && x <= width)
|
||||
part = INTERNAL_BORDER_BOTTOM_RIGHT_CORNER;
|
||||
}
|
||||
}
|
||||
|
||||
return part;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Return mouse position in character cell units. */
|
||||
|
||||
DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
|
||||
|
|
@ -2962,18 +3201,33 @@ For a terminal screen, the value is always 1. */)
|
|||
return make_number (1);
|
||||
}
|
||||
|
||||
DEFUN ("frame-pixel-height", Fframe_pixel_height,
|
||||
Sframe_pixel_height, 0, 1, 0,
|
||||
doc: /* Return a FRAME's height in pixels.
|
||||
DEFUN ("frame-native-width", Fframe_native_width,
|
||||
Sframe_native_width, 0, 1, 0,
|
||||
doc: /* Return FRAME's native width in pixels.
|
||||
For a terminal frame, the result really gives the width in characters.
|
||||
If FRAME is omitted or nil, the selected frame is used. */)
|
||||
(Lisp_Object frame)
|
||||
{
|
||||
struct frame *f = decode_any_frame (frame);
|
||||
|
||||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
if (FRAME_WINDOW_P (f))
|
||||
return make_number (FRAME_PIXEL_WIDTH (f));
|
||||
else
|
||||
#endif
|
||||
return make_number (FRAME_TOTAL_COLS (f));
|
||||
}
|
||||
|
||||
DEFUN ("frame-native-height", Fframe_native_height,
|
||||
Sframe_native_height, 0, 1, 0,
|
||||
doc: /* Return FRAME's native height in pixels.
|
||||
If FRAME is omitted or nil, the selected frame is used. The exact value
|
||||
of the result depends on the window-system and toolkit in use:
|
||||
|
||||
In the Gtk+ version of Emacs, it includes only any window (including
|
||||
the minibuffer or echo area), mode line, and header line. It does not
|
||||
include the tool bar or menu bar.
|
||||
|
||||
With other graphical versions, it also includes the tool bar and the
|
||||
menu bar.
|
||||
In the Gtk+ and NS versions, it includes only any window (including the
|
||||
minibuffer or echo area), mode line, and header line. It does not
|
||||
include the tool bar or menu bar. With other graphical versions, it may
|
||||
also include the tool bar and the menu bar.
|
||||
|
||||
For a text terminal, it includes the menu bar. In this case, the
|
||||
result is really in characters rather than pixels (i.e., is identical
|
||||
|
|
@ -2990,23 +3244,6 @@ to `frame-height'). */)
|
|||
return make_number (FRAME_TOTAL_LINES (f));
|
||||
}
|
||||
|
||||
DEFUN ("frame-pixel-width", Fframe_pixel_width,
|
||||
Sframe_pixel_width, 0, 1, 0,
|
||||
doc: /* Return FRAME's width in pixels.
|
||||
For a terminal frame, the result really gives the width in characters.
|
||||
If FRAME is omitted or nil, the selected frame is used. */)
|
||||
(Lisp_Object frame)
|
||||
{
|
||||
struct frame *f = decode_any_frame (frame);
|
||||
|
||||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
if (FRAME_WINDOW_P (f))
|
||||
return make_number (FRAME_PIXEL_WIDTH (f));
|
||||
else
|
||||
#endif
|
||||
return make_number (FRAME_TOTAL_COLS (f));
|
||||
}
|
||||
|
||||
DEFUN ("tool-bar-pixel-width", Ftool_bar_pixel_width,
|
||||
Stool_bar_pixel_width, 0, 1, 0,
|
||||
doc: /* Return width in pixels of FRAME's tool bar.
|
||||
|
|
@ -3087,8 +3324,8 @@ DEFUN ("frame-fringe-width", Ffringe_width, Sfringe_width, 0, 1, 0,
|
|||
return make_number (FRAME_TOTAL_FRINGE_WIDTH (decode_any_frame (frame)));
|
||||
}
|
||||
|
||||
DEFUN ("frame-border-width", Fborder_width, Sborder_width, 0, 1, 0,
|
||||
doc: /* Return border width of FRAME in pixels. */)
|
||||
DEFUN ("frame-internal-border-width", Fframe_internal_border_width, Sframe_internal_border_width, 0, 1, 0,
|
||||
doc: /* Return width of FRAME's internal border in pixels. */)
|
||||
(Lisp_Object frame)
|
||||
{
|
||||
return make_number (FRAME_INTERNAL_BORDER_WIDTH (decode_any_frame (frame)));
|
||||
|
|
@ -3224,7 +3461,6 @@ bottom edge of FRAME's display. */)
|
|||
|
||||
return Qt;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
Frame Parameters
|
||||
|
|
@ -3289,10 +3525,193 @@ static const struct frame_parm_table frame_parms[] =
|
|||
{"no-accept-focus", SYMBOL_INDEX (Qno_accept_focus)},
|
||||
{"z-group", SYMBOL_INDEX (Qz_group)},
|
||||
{"override-redirect", SYMBOL_INDEX (Qoverride_redirect)},
|
||||
{"no-special-glyphs", SYMBOL_INDEX (Qno_special_glyphs)},
|
||||
};
|
||||
|
||||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
|
||||
/* Enumeration type for switch in frame_float. */
|
||||
enum frame_float_type
|
||||
{
|
||||
FRAME_FLOAT_WIDTH,
|
||||
FRAME_FLOAT_HEIGHT,
|
||||
FRAME_FLOAT_LEFT,
|
||||
FRAME_FLOAT_TOP
|
||||
};
|
||||
|
||||
/**
|
||||
* frame_float:
|
||||
*
|
||||
* Process the value VAL of the float type frame parameter 'width',
|
||||
* 'height', 'left', or 'top' specified via a frame_float_type
|
||||
* enumeration type WHAT for frame F. Such parameters relate the outer
|
||||
* size or position of F to the size of the F's display or parent frame
|
||||
* which have to be both available in some way.
|
||||
*
|
||||
* The return value is a size or position value in pixels. VAL must be
|
||||
* in the range 0.0 to 1.0 where a width/height of 0.0 means to return 0
|
||||
* and 1.0 means to return the full width/height of the display/parent.
|
||||
* For positions, 0.0 means position in the left/top corner of the
|
||||
* display/parent while 1.0 means to position at the right/bottom corner
|
||||
* of the display/parent frame.
|
||||
*
|
||||
* Set PARENT_DONE and OUTER_DONE to avoid recalculation of the outer
|
||||
* size or parent or display attributes when more float parameters are
|
||||
* calculated in a row: -1 means not processed yet, 0 means processing
|
||||
* failed, 1 means processing succeeded.
|
||||
*
|
||||
* Return DEFAULT_VALUE when processing fails for whatever reason with
|
||||
* one exception: When calculating F's outer edges fails (probably
|
||||
* because F has not been created yet) return the difference between F's
|
||||
* native and text size.
|
||||
*/
|
||||
static int
|
||||
frame_float (struct frame *f, Lisp_Object val, enum frame_float_type what,
|
||||
int *parent_done, int *outer_done, int default_value)
|
||||
{
|
||||
double d_val = XFLOAT_DATA (val);
|
||||
|
||||
if (d_val < 0.0 || d_val > 1.0)
|
||||
/* Invalid VAL. */
|
||||
return default_value;
|
||||
else
|
||||
{
|
||||
static unsigned parent_width, parent_height;
|
||||
static int parent_left, parent_top;
|
||||
static unsigned outer_minus_text_width, outer_minus_text_height;
|
||||
struct frame *p = FRAME_PARENT_FRAME (f);
|
||||
|
||||
if (*parent_done == 1)
|
||||
;
|
||||
else if (p)
|
||||
{
|
||||
parent_width = FRAME_PIXEL_WIDTH (p);
|
||||
parent_height = FRAME_PIXEL_HEIGHT (p);
|
||||
*parent_done = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*parent_done == 0)
|
||||
/* No workarea available. */
|
||||
return default_value;
|
||||
else if (*parent_done == -1)
|
||||
{
|
||||
Lisp_Object monitor_attributes;
|
||||
Lisp_Object workarea;
|
||||
Lisp_Object frame;
|
||||
|
||||
XSETFRAME (frame, f);
|
||||
monitor_attributes = Fcar (call1 (Qdisplay_monitor_attributes_list, frame));
|
||||
if (NILP (monitor_attributes))
|
||||
{
|
||||
/* No monitor attributes available. */
|
||||
*parent_done = 0;
|
||||
|
||||
return default_value;
|
||||
}
|
||||
|
||||
workarea = Fcdr (Fassq (Qworkarea, monitor_attributes));
|
||||
if (NILP (workarea))
|
||||
{
|
||||
/* No workarea available. */
|
||||
*parent_done = 0;
|
||||
|
||||
return default_value;
|
||||
}
|
||||
|
||||
/* Workarea available. */
|
||||
parent_left = XINT (Fnth (make_number (0), workarea));
|
||||
parent_top = XINT (Fnth (make_number (1), workarea));
|
||||
parent_width = XINT (Fnth (make_number (2), workarea));
|
||||
parent_height = XINT (Fnth (make_number (3), workarea));
|
||||
*parent_done = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (*outer_done == 1)
|
||||
;
|
||||
else if (FRAME_UNDECORATED (f))
|
||||
{
|
||||
outer_minus_text_width
|
||||
= FRAME_PIXEL_WIDTH (f) - FRAME_TEXT_WIDTH (f);
|
||||
outer_minus_text_height
|
||||
= FRAME_PIXEL_HEIGHT (f) - FRAME_TEXT_HEIGHT (f);
|
||||
*outer_done = 1;
|
||||
}
|
||||
else if (*outer_done == 0)
|
||||
/* No outer size available. */
|
||||
return default_value;
|
||||
else if (*outer_done == -1)
|
||||
{
|
||||
Lisp_Object frame, outer_edges;
|
||||
|
||||
XSETFRAME (frame, f);
|
||||
outer_edges = call2 (Qframe_edges, frame, Qouter_edges);
|
||||
|
||||
if (!NILP (outer_edges))
|
||||
{
|
||||
outer_minus_text_width
|
||||
= (XINT (Fnth (make_number (2), outer_edges))
|
||||
- XINT (Fnth (make_number (0), outer_edges))
|
||||
- FRAME_TEXT_WIDTH (f));
|
||||
outer_minus_text_height
|
||||
= (XINT (Fnth (make_number (3), outer_edges))
|
||||
- XINT (Fnth (make_number (1), outer_edges))
|
||||
- FRAME_TEXT_HEIGHT (f));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If we can't get any outer edges, proceed as if the frame
|
||||
were undecorated. */
|
||||
outer_minus_text_width
|
||||
= FRAME_PIXEL_WIDTH (f) - FRAME_TEXT_WIDTH (f);
|
||||
outer_minus_text_height
|
||||
= FRAME_PIXEL_HEIGHT (f) - FRAME_TEXT_HEIGHT (f);
|
||||
}
|
||||
|
||||
*outer_done = 1;
|
||||
}
|
||||
|
||||
switch (what)
|
||||
{
|
||||
case FRAME_FLOAT_WIDTH:
|
||||
return parent_width * d_val - outer_minus_text_width;
|
||||
|
||||
case FRAME_FLOAT_HEIGHT:
|
||||
return parent_height * d_val - outer_minus_text_height;
|
||||
|
||||
case FRAME_FLOAT_LEFT:
|
||||
{
|
||||
int rest_width = (parent_width
|
||||
- FRAME_TEXT_WIDTH (f)
|
||||
- outer_minus_text_width);
|
||||
|
||||
if (p)
|
||||
return (rest_width <= 0 ? 0 : d_val * rest_width);
|
||||
else
|
||||
return (rest_width <= 0
|
||||
? parent_left
|
||||
: parent_left + d_val * rest_width);
|
||||
}
|
||||
case FRAME_FLOAT_TOP:
|
||||
{
|
||||
int rest_height = (parent_height
|
||||
- FRAME_TEXT_HEIGHT (f)
|
||||
- outer_minus_text_height);
|
||||
|
||||
if (p)
|
||||
return (rest_height <= 0 ? 0 : d_val * rest_height);
|
||||
else
|
||||
return (rest_height <= 0
|
||||
? parent_top
|
||||
: parent_top + d_val * rest_height);
|
||||
}
|
||||
default:
|
||||
emacs_abort ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Change the parameters of frame F as specified by ALIST.
|
||||
If a parameter is not specially recognized, do nothing special;
|
||||
otherwise call the `x_set_...' function for that parameter.
|
||||
|
|
@ -3302,7 +3721,8 @@ static const struct frame_parm_table frame_parms[] =
|
|||
void
|
||||
x_set_frame_parameters (struct frame *f, Lisp_Object alist)
|
||||
{
|
||||
Lisp_Object tail;
|
||||
Lisp_Object tail, frame;
|
||||
|
||||
|
||||
/* If both of these parameters are present, it's more efficient to
|
||||
set them both at once. So we wait until we've looked at the
|
||||
|
|
@ -3327,7 +3747,9 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist)
|
|||
#ifdef HAVE_X_WINDOWS
|
||||
bool icon_left_no_change = 0, icon_top_no_change = 0;
|
||||
#endif
|
||||
int parent_done = -1, outer_done = -1;
|
||||
|
||||
XSETFRAME (frame, f);
|
||||
for (size = 0, tail = alist; CONSP (tail); tail = XCDR (tail))
|
||||
size++;
|
||||
CHECK_LIST_END (tail, alist);
|
||||
|
|
@ -3388,6 +3810,9 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist)
|
|||
else if (CONSP (val) && EQ (XCAR (val), Qtext_pixels)
|
||||
&& RANGED_INTEGERP (0, XCDR (val), INT_MAX))
|
||||
width = XFASTINT (XCDR (val));
|
||||
else if (FLOATP (val))
|
||||
width = frame_float (f, val, FRAME_FLOAT_WIDTH, &parent_done,
|
||||
&outer_done, -1);
|
||||
}
|
||||
else if (EQ (prop, Qheight))
|
||||
{
|
||||
|
|
@ -3396,6 +3821,9 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist)
|
|||
else if (CONSP (val) && EQ (XCAR (val), Qtext_pixels)
|
||||
&& RANGED_INTEGERP (0, XCDR (val), INT_MAX))
|
||||
height = XFASTINT (XCDR (val));
|
||||
else if (FLOATP (val))
|
||||
height = frame_float (f, val, FRAME_FLOAT_HEIGHT, &parent_done,
|
||||
&outer_done, -1);
|
||||
}
|
||||
else if (EQ (prop, Qtop))
|
||||
top = val;
|
||||
|
|
@ -3472,105 +3900,100 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist)
|
|||
Don't set these parameters unless they actually differ from the
|
||||
window's current parameters; the window may not actually exist
|
||||
yet. */
|
||||
{
|
||||
Lisp_Object frame;
|
||||
if ((width != -1 && width != FRAME_TEXT_WIDTH (f))
|
||||
|| (height != -1 && height != FRAME_TEXT_HEIGHT (f)))
|
||||
/* We could consider checking f->after_make_frame here, but I
|
||||
don't have the faintest idea why the following is needed at
|
||||
all. With the old setting it can get a Heisenbug when
|
||||
EmacsFrameResize intermittently provokes a delayed
|
||||
change_frame_size in the middle of adjust_frame_size. */
|
||||
/** || (f->can_x_set_window_size && (f->new_height || f->new_width))) **/
|
||||
adjust_frame_size (f, width, height, 1, 0, Qx_set_frame_parameters);
|
||||
|
||||
XSETFRAME (frame, f);
|
||||
if ((!NILP (left) || !NILP (top))
|
||||
&& ! (left_no_change && top_no_change)
|
||||
&& ! (NUMBERP (left) && XINT (left) == f->left_pos
|
||||
&& NUMBERP (top) && XINT (top) == f->top_pos))
|
||||
{
|
||||
int leftpos = 0;
|
||||
int toppos = 0;
|
||||
|
||||
if ((width != -1 && width != FRAME_TEXT_WIDTH (f))
|
||||
|| (height != -1 && height != FRAME_TEXT_HEIGHT (f)))
|
||||
/* We could consider checking f->after_make_frame here, but I
|
||||
don't have the faintest idea why the following is needed at
|
||||
all. With the old setting it can get a Heisenbug when
|
||||
EmacsFrameResize intermittently provokes a delayed
|
||||
change_frame_size in the middle of adjust_frame_size. */
|
||||
/** || (f->can_x_set_window_size && (f->new_height || f->new_width))) **/
|
||||
adjust_frame_size (f, width, height, 1, 0, Qx_set_frame_parameters);
|
||||
|
||||
if ((!NILP (left) || !NILP (top))
|
||||
&& ! (left_no_change && top_no_change)
|
||||
&& ! (NUMBERP (left) && XINT (left) == f->left_pos
|
||||
&& NUMBERP (top) && XINT (top) == f->top_pos))
|
||||
{
|
||||
int leftpos = 0;
|
||||
int toppos = 0;
|
||||
|
||||
/* Record the signs. */
|
||||
f->size_hint_flags &= ~ (XNegative | YNegative);
|
||||
if (EQ (left, Qminus))
|
||||
f->size_hint_flags |= XNegative;
|
||||
else if (TYPE_RANGED_INTEGERP (int, left))
|
||||
{
|
||||
leftpos = XINT (left);
|
||||
if (leftpos < 0)
|
||||
f->size_hint_flags |= XNegative;
|
||||
}
|
||||
else if (CONSP (left) && EQ (XCAR (left), Qminus)
|
||||
&& CONSP (XCDR (left))
|
||||
&& RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (left)), INT_MAX))
|
||||
{
|
||||
leftpos = - XINT (XCAR (XCDR (left)));
|
||||
/* Record the signs. */
|
||||
f->size_hint_flags &= ~ (XNegative | YNegative);
|
||||
if (EQ (left, Qminus))
|
||||
f->size_hint_flags |= XNegative;
|
||||
else if (TYPE_RANGED_INTEGERP (int, left))
|
||||
{
|
||||
leftpos = XINT (left);
|
||||
if (leftpos < 0)
|
||||
f->size_hint_flags |= XNegative;
|
||||
}
|
||||
else if (CONSP (left) && EQ (XCAR (left), Qplus)
|
||||
&& CONSP (XCDR (left))
|
||||
&& TYPE_RANGED_INTEGERP (int, XCAR (XCDR (left))))
|
||||
{
|
||||
leftpos = XINT (XCAR (XCDR (left)));
|
||||
}
|
||||
}
|
||||
else if (CONSP (left) && EQ (XCAR (left), Qminus)
|
||||
&& CONSP (XCDR (left))
|
||||
&& RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (left)), INT_MAX))
|
||||
{
|
||||
leftpos = - XINT (XCAR (XCDR (left)));
|
||||
f->size_hint_flags |= XNegative;
|
||||
}
|
||||
else if (CONSP (left) && EQ (XCAR (left), Qplus)
|
||||
&& CONSP (XCDR (left))
|
||||
&& TYPE_RANGED_INTEGERP (int, XCAR (XCDR (left))))
|
||||
leftpos = XINT (XCAR (XCDR (left)));
|
||||
else if (FLOATP (left))
|
||||
leftpos = frame_float (f, left, FRAME_FLOAT_LEFT, &parent_done,
|
||||
&outer_done, 0);
|
||||
|
||||
if (EQ (top, Qminus))
|
||||
f->size_hint_flags |= YNegative;
|
||||
else if (TYPE_RANGED_INTEGERP (int, top))
|
||||
{
|
||||
toppos = XINT (top);
|
||||
if (toppos < 0)
|
||||
f->size_hint_flags |= YNegative;
|
||||
}
|
||||
else if (CONSP (top) && EQ (XCAR (top), Qminus)
|
||||
&& CONSP (XCDR (top))
|
||||
&& RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (top)), INT_MAX))
|
||||
{
|
||||
toppos = - XINT (XCAR (XCDR (top)));
|
||||
if (EQ (top, Qminus))
|
||||
f->size_hint_flags |= YNegative;
|
||||
else if (TYPE_RANGED_INTEGERP (int, top))
|
||||
{
|
||||
toppos = XINT (top);
|
||||
if (toppos < 0)
|
||||
f->size_hint_flags |= YNegative;
|
||||
}
|
||||
else if (CONSP (top) && EQ (XCAR (top), Qplus)
|
||||
&& CONSP (XCDR (top))
|
||||
&& TYPE_RANGED_INTEGERP (int, XCAR (XCDR (top))))
|
||||
{
|
||||
toppos = XINT (XCAR (XCDR (top)));
|
||||
}
|
||||
}
|
||||
else if (CONSP (top) && EQ (XCAR (top), Qminus)
|
||||
&& CONSP (XCDR (top))
|
||||
&& RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (top)), INT_MAX))
|
||||
{
|
||||
toppos = - XINT (XCAR (XCDR (top)));
|
||||
f->size_hint_flags |= YNegative;
|
||||
}
|
||||
else if (CONSP (top) && EQ (XCAR (top), Qplus)
|
||||
&& CONSP (XCDR (top))
|
||||
&& TYPE_RANGED_INTEGERP (int, XCAR (XCDR (top))))
|
||||
toppos = XINT (XCAR (XCDR (top)));
|
||||
else if (FLOATP (top))
|
||||
toppos = frame_float (f, top, FRAME_FLOAT_TOP, &parent_done,
|
||||
&outer_done, 0);
|
||||
|
||||
/* Store the numeric value of the position. */
|
||||
f->top_pos = toppos;
|
||||
f->left_pos = leftpos;
|
||||
|
||||
/* Store the numeric value of the position. */
|
||||
f->top_pos = toppos;
|
||||
f->left_pos = leftpos;
|
||||
f->win_gravity = NorthWestGravity;
|
||||
|
||||
f->win_gravity = NorthWestGravity;
|
||||
/* Actually set that position, and convert to absolute. */
|
||||
x_set_offset (f, leftpos, toppos, -1);
|
||||
}
|
||||
|
||||
/* Actually set that position, and convert to absolute. */
|
||||
x_set_offset (f, leftpos, toppos, -1);
|
||||
}
|
||||
if (fullscreen_change)
|
||||
{
|
||||
Lisp_Object old_value = get_frame_param (f, Qfullscreen);
|
||||
|
||||
if (fullscreen_change)
|
||||
{
|
||||
Lisp_Object old_value = get_frame_param (f, Qfullscreen);
|
||||
frame_size_history_add
|
||||
(f, Qx_set_fullscreen, 0, 0, list2 (old_value, fullscreen));
|
||||
|
||||
frame_size_history_add
|
||||
(f, Qx_set_fullscreen, 0, 0, list2 (old_value, fullscreen));
|
||||
|
||||
store_frame_param (f, Qfullscreen, fullscreen);
|
||||
if (!EQ (fullscreen, old_value))
|
||||
x_set_fullscreen (f, fullscreen, old_value);
|
||||
}
|
||||
store_frame_param (f, Qfullscreen, fullscreen);
|
||||
if (!EQ (fullscreen, old_value))
|
||||
x_set_fullscreen (f, fullscreen, old_value);
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_X_WINDOWS
|
||||
if ((!NILP (icon_left) || !NILP (icon_top))
|
||||
&& ! (icon_left_no_change && icon_top_no_change))
|
||||
x_wm_set_icon_position (f, XINT (icon_left), XINT (icon_top));
|
||||
if ((!NILP (icon_left) || !NILP (icon_top))
|
||||
&& ! (icon_left_no_change && icon_top_no_change))
|
||||
x_wm_set_icon_position (f, XINT (icon_left), XINT (icon_top));
|
||||
#endif /* HAVE_X_WINDOWS */
|
||||
}
|
||||
|
||||
SAFE_FREE ();
|
||||
}
|
||||
|
|
@ -3990,7 +4413,6 @@ x_set_right_divider_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
|
|||
adjust_frame_glyphs (f);
|
||||
SET_FRAME_GARBAGED (f);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -4204,6 +4626,22 @@ x_set_alpha (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* x_set_no_special_glyphs:
|
||||
*
|
||||
* Set frame F's `no-special-glyphs' parameter which, if non-nil,
|
||||
* suppresses the display of truncation and continuation glyphs
|
||||
* outside fringes.
|
||||
*/
|
||||
void
|
||||
x_set_no_special_glyphs (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
|
||||
{
|
||||
if (!EQ (new_value, old_value))
|
||||
FRAME_NO_SPECIAL_GLYPHS (f) = !NILP (new_value);
|
||||
}
|
||||
|
||||
|
||||
#ifndef HAVE_NS
|
||||
|
||||
/* Non-zero if mouse is grabbed on DPYINFO
|
||||
|
|
@ -4759,6 +5197,7 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p, int *x
|
|||
Lisp_Object height, width, user_size, top, left, user_position;
|
||||
long window_prompting = 0;
|
||||
Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
|
||||
int parent_done = -1, outer_done = -1;
|
||||
|
||||
/* Default values if we fall through.
|
||||
Actually, if that happens we should get
|
||||
|
|
@ -4823,6 +5262,21 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p, int *x
|
|||
f->inhibit_horizontal_resize = true;
|
||||
*x_width = XINT (XCDR (width));
|
||||
}
|
||||
else if (FLOATP (width))
|
||||
{
|
||||
double d_width = XFLOAT_DATA (width);
|
||||
|
||||
if (d_width < 0.0 || d_width > 1.0)
|
||||
xsignal1 (Qargs_out_of_range, width);
|
||||
else
|
||||
{
|
||||
int new_width = frame_float (f, width, FRAME_FLOAT_WIDTH,
|
||||
&parent_done, &outer_done, -1);
|
||||
|
||||
if (new_width > -1)
|
||||
SET_FRAME_WIDTH (f, new_width);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK_NUMBER (width);
|
||||
|
|
@ -4845,6 +5299,21 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p, int *x
|
|||
f->inhibit_vertical_resize = true;
|
||||
*x_height = XINT (XCDR (height));
|
||||
}
|
||||
else if (FLOATP (height))
|
||||
{
|
||||
double d_height = XFLOAT_DATA (height);
|
||||
|
||||
if (d_height < 0.0 || d_height > 1.0)
|
||||
xsignal1 (Qargs_out_of_range, height);
|
||||
else
|
||||
{
|
||||
int new_height = frame_float (f, height, FRAME_FLOAT_HEIGHT,
|
||||
&parent_done, &outer_done, -1);
|
||||
|
||||
if (new_height > -1)
|
||||
SET_FRAME_HEIGHT (f, new_height);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK_NUMBER (height);
|
||||
|
|
@ -4885,6 +5354,9 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p, int *x
|
|||
{
|
||||
f->top_pos = XINT (XCAR (XCDR (top)));
|
||||
}
|
||||
else if (FLOATP (top))
|
||||
f->top_pos = frame_float (f, top, FRAME_FLOAT_TOP, &parent_done,
|
||||
&outer_done, 0);
|
||||
else if (EQ (top, Qunbound))
|
||||
f->top_pos = 0;
|
||||
else
|
||||
|
|
@ -4913,6 +5385,9 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p, int *x
|
|||
{
|
||||
f->left_pos = XINT (XCAR (XCDR (left)));
|
||||
}
|
||||
else if (FLOATP (left))
|
||||
f->left_pos = frame_float (f, left, FRAME_FLOAT_LEFT, &parent_done,
|
||||
&outer_done, 0);
|
||||
else if (EQ (left, Qunbound))
|
||||
f->left_pos = 0;
|
||||
else
|
||||
|
|
@ -5071,12 +5546,14 @@ syms_of_frame (void)
|
|||
DEFSYM (Qframep, "framep");
|
||||
DEFSYM (Qframe_live_p, "frame-live-p");
|
||||
DEFSYM (Qframe_windows_min_size, "frame-windows-min-size");
|
||||
DEFSYM (Qdisplay_monitor_attributes_list, "display-monitor-attributes-list");
|
||||
DEFSYM (Qwindow__pixel_to_total, "window--pixel-to-total");
|
||||
DEFSYM (Qexplicit_name, "explicit-name");
|
||||
DEFSYM (Qheight, "height");
|
||||
DEFSYM (Qicon, "icon");
|
||||
DEFSYM (Qminibuffer, "minibuffer");
|
||||
DEFSYM (Qundecorated, "undecorated");
|
||||
DEFSYM (Qno_special_glyphs, "no-special-glyphs");
|
||||
DEFSYM (Qparent_frame, "parent-frame");
|
||||
DEFSYM (Qskip_taskbar, "skip-taskbar");
|
||||
DEFSYM (Qno_focus_on_map, "no-focus-on-map");
|
||||
|
|
@ -5129,6 +5606,7 @@ syms_of_frame (void)
|
|||
DEFSYM (Qframes, "frames");
|
||||
DEFSYM (Qsource, "source");
|
||||
|
||||
DEFSYM (Qframe_edges, "frame-edges");
|
||||
DEFSYM (Qouter_edges, "outer-edges");
|
||||
DEFSYM (Qouter_position, "outer-position");
|
||||
DEFSYM (Qouter_size, "outer-size");
|
||||
|
|
@ -5220,6 +5698,11 @@ syms_of_frame (void)
|
|||
DEFSYM (Qmin_width, "min-width");
|
||||
DEFSYM (Qmin_height, "min-height");
|
||||
DEFSYM (Qmouse_wheel_frame, "mouse-wheel-frame");
|
||||
DEFSYM (Qkeep_ratio, "keep-ratio");
|
||||
DEFSYM (Qwidth_only, "width-only");
|
||||
DEFSYM (Qheight_only, "height-only");
|
||||
DEFSYM (Qleft_only, "left-only");
|
||||
DEFSYM (Qtop_only, "top-only");
|
||||
|
||||
{
|
||||
int i;
|
||||
|
|
@ -5564,8 +6047,8 @@ Gtk+ tooltips are not used) and on Windows. */);
|
|||
defsubr (&Smodify_frame_parameters);
|
||||
defsubr (&Sframe_char_height);
|
||||
defsubr (&Sframe_char_width);
|
||||
defsubr (&Sframe_pixel_height);
|
||||
defsubr (&Sframe_pixel_width);
|
||||
defsubr (&Sframe_native_height);
|
||||
defsubr (&Sframe_native_width);
|
||||
defsubr (&Sframe_text_cols);
|
||||
defsubr (&Sframe_text_lines);
|
||||
defsubr (&Sframe_total_cols);
|
||||
|
|
@ -5575,7 +6058,7 @@ Gtk+ tooltips are not used) and on Windows. */);
|
|||
defsubr (&Sscroll_bar_width);
|
||||
defsubr (&Sscroll_bar_height);
|
||||
defsubr (&Sfringe_width);
|
||||
defsubr (&Sborder_width);
|
||||
defsubr (&Sframe_internal_border_width);
|
||||
defsubr (&Sright_divider_width);
|
||||
defsubr (&Sbottom_divider_width);
|
||||
defsubr (&Stool_bar_pixel_width);
|
||||
|
|
|
|||
28
src/frame.h
28
src/frame.h
|
|
@ -52,6 +52,19 @@ enum z_group
|
|||
z_group_below,
|
||||
z_group_above_suspended,
|
||||
};
|
||||
|
||||
enum internal_border_part
|
||||
{
|
||||
INTERNAL_BORDER_NONE,
|
||||
INTERNAL_BORDER_LEFT_EDGE,
|
||||
INTERNAL_BORDER_TOP_LEFT_CORNER,
|
||||
INTERNAL_BORDER_TOP_EDGE,
|
||||
INTERNAL_BORDER_TOP_RIGHT_CORNER,
|
||||
INTERNAL_BORDER_RIGHT_EDGE,
|
||||
INTERNAL_BORDER_BOTTOM_RIGHT_CORNER,
|
||||
INTERNAL_BORDER_BOTTOM_EDGE,
|
||||
INTERNAL_BORDER_BOTTOM_LEFT_CORNER,
|
||||
};
|
||||
#endif /* HAVE_WINDOW_SYSTEM */
|
||||
|
||||
/* The structure representing a frame. */
|
||||
|
|
@ -354,7 +367,11 @@ struct frame
|
|||
|
||||
/* The z-group this frame's window belongs to. */
|
||||
ENUM_BF (z_group) z_group : 2;
|
||||
#endif /* HAVE_WINDOW_SYSTEM and not HAVE_NS */
|
||||
|
||||
/* Non-zero if display of truncation and continuation glyphs outside
|
||||
the fringes is suppressed. */
|
||||
bool_bf no_special_glyphs : 1;
|
||||
#endif /* HAVE_WINDOW_SYSTEM */
|
||||
|
||||
/* Whether new_height and new_width shall be interpreted
|
||||
in pixels. */
|
||||
|
|
@ -928,6 +945,7 @@ default_pixels_per_inch_y (void)
|
|||
#define FRAME_SKIP_TASKBAR(f) ((f)->skip_taskbar)
|
||||
#define FRAME_NO_FOCUS_ON_MAP(f) ((f)->no_focus_on_map)
|
||||
#define FRAME_NO_ACCEPT_FOCUS(f) ((f)->no_accept_focus)
|
||||
#define FRAME_NO_SPECIAL_GLYPHS(f) ((f)->no_special_glyphs)
|
||||
#define FRAME_Z_GROUP(f) ((f)->z_group)
|
||||
#define FRAME_Z_GROUP_NONE(f) ((f)->z_group == z_group_none)
|
||||
#define FRAME_Z_GROUP_ABOVE(f) ((f)->z_group == z_group_above)
|
||||
|
|
@ -941,6 +959,7 @@ default_pixels_per_inch_y (void)
|
|||
#define FRAME_SKIP_TASKBAR(f) ((void) f, 0)
|
||||
#define FRAME_NO_FOCUS_ON_MAP(f) ((void) f, 0)
|
||||
#define FRAME_NO_ACCEPT_FOCUS(f) ((void) f, 0)
|
||||
#define FRAME_NO_SPECIAL_GLYPHS(f) ((void) f, 0)
|
||||
#define FRAME_Z_GROUP(f) ((void) f, z_group_none)
|
||||
#define FRAME_Z_GROUP_NONE(f) ((void) f, true)
|
||||
#define FRAME_Z_GROUP_ABOVE(f) ((void) f, false)
|
||||
|
|
@ -1288,19 +1307,20 @@ FRAME_TOTAL_FRINGE_WIDTH (struct frame *f)
|
|||
return FRAME_LEFT_FRINGE_WIDTH (f) + FRAME_RIGHT_FRINGE_WIDTH (f);
|
||||
}
|
||||
|
||||
/* Pixel-width of internal border lines */
|
||||
/* Pixel-width of internal border lines. */
|
||||
INLINE int
|
||||
FRAME_INTERNAL_BORDER_WIDTH (struct frame *f)
|
||||
{
|
||||
return frame_dimension (f->internal_border_width);
|
||||
}
|
||||
|
||||
/* Pixel-size of window divider lines */
|
||||
/* Pixel-size of window divider lines. */
|
||||
INLINE int
|
||||
FRAME_RIGHT_DIVIDER_WIDTH (struct frame *f)
|
||||
{
|
||||
return frame_dimension (f->right_divider_width);
|
||||
}
|
||||
|
||||
INLINE int
|
||||
FRAME_BOTTOM_DIVIDER_WIDTH (struct frame *f)
|
||||
{
|
||||
|
|
@ -1498,6 +1518,7 @@ extern void x_set_scroll_bar_height (struct frame *, Lisp_Object, Lisp_Object);
|
|||
extern long x_figure_window_size (struct frame *, Lisp_Object, bool, int *, int *);
|
||||
|
||||
extern void x_set_alpha (struct frame *, Lisp_Object, Lisp_Object);
|
||||
extern void x_set_no_special_glyphs (struct frame *, Lisp_Object, Lisp_Object);
|
||||
|
||||
extern void validate_x_resource_name (void);
|
||||
|
||||
|
|
@ -1521,6 +1542,7 @@ extern void x_real_positions (struct frame *, int *, int *);
|
|||
extern void free_frame_menubar (struct frame *);
|
||||
extern void x_free_frame_resources (struct frame *);
|
||||
extern bool frame_ancestor_p (struct frame *af, struct frame *df);
|
||||
extern enum internal_border_part frame_internal_border_part (struct frame *f, int x, int y);
|
||||
|
||||
#if defined HAVE_X_WINDOWS
|
||||
extern void x_wm_set_icon_position (struct frame *, int, int);
|
||||
|
|
|
|||
|
|
@ -1503,6 +1503,7 @@ xg_set_undecorated (struct frame *f, Lisp_Object undecorated)
|
|||
void
|
||||
xg_frame_restack (struct frame *f1, struct frame *f2, bool above_flag)
|
||||
{
|
||||
#if GTK_CHECK_VERSION (2, 18, 0)
|
||||
block_input ();
|
||||
if (FRAME_GTK_OUTER_WIDGET (f1) && FRAME_GTK_OUTER_WIDGET (f2))
|
||||
{
|
||||
|
|
@ -1517,6 +1518,7 @@ xg_frame_restack (struct frame *f1, struct frame *f2, bool above_flag)
|
|||
x_sync (f1);
|
||||
}
|
||||
unblock_input ();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -5127,6 +5127,17 @@ static short const scroll_bar_parts[] = {
|
|||
SYMBOL_INDEX (Qrightmost), SYMBOL_INDEX (Qend_scroll), SYMBOL_INDEX (Qratio)
|
||||
};
|
||||
|
||||
/* An array of symbol indexes of internal border parts, indexed by an enum
|
||||
internal_border_part value. Note that Qnil corresponds to
|
||||
internal_border_part_none and should not appear in Lisp events. */
|
||||
static short const internal_border_parts[] = {
|
||||
SYMBOL_INDEX (Qnil), SYMBOL_INDEX (Qleft_edge),
|
||||
SYMBOL_INDEX (Qtop_left_corner), SYMBOL_INDEX (Qtop_edge),
|
||||
SYMBOL_INDEX (Qtop_right_corner), SYMBOL_INDEX (Qright_edge),
|
||||
SYMBOL_INDEX (Qbottom_right_corner), SYMBOL_INDEX (Qbottom_edge),
|
||||
SYMBOL_INDEX (Qbottom_left_corner)
|
||||
};
|
||||
|
||||
/* A vector, indexed by button number, giving the down-going location
|
||||
of currently depressed buttons, both scroll bar and non-scroll bar.
|
||||
|
||||
|
|
@ -5164,15 +5175,15 @@ make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y,
|
|||
Lisp_Object extra_info = Qnil;
|
||||
/* Coordinate pixel positions to return. */
|
||||
int xret = 0, yret = 0;
|
||||
/* The window under frame pixel coordinates (x,y) */
|
||||
Lisp_Object window = f
|
||||
/* The window or frame under frame pixel coordinates (x,y) */
|
||||
Lisp_Object window_or_frame = f
|
||||
? window_from_coordinates (f, XINT (x), XINT (y), &part, 0)
|
||||
: Qnil;
|
||||
|
||||
if (WINDOWP (window))
|
||||
if (WINDOWP (window_or_frame))
|
||||
{
|
||||
/* It's a click in window WINDOW at frame coordinates (X,Y) */
|
||||
struct window *w = XWINDOW (window);
|
||||
struct window *w = XWINDOW (window_or_frame);
|
||||
Lisp_Object string_info = Qnil;
|
||||
ptrdiff_t textpos = 0;
|
||||
int col = -1, row = -1;
|
||||
|
|
@ -5361,17 +5372,31 @@ make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y,
|
|||
make_number (row)),
|
||||
extra_info)));
|
||||
}
|
||||
else if (f != 0)
|
||||
|
||||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
else if (f)
|
||||
{
|
||||
/* Return mouse pixel coordinates here. */
|
||||
XSETFRAME (window, f);
|
||||
XSETFRAME (window_or_frame, f);
|
||||
xret = XINT (x);
|
||||
yret = XINT (y);
|
||||
}
|
||||
else
|
||||
window = Qnil;
|
||||
|
||||
return Fcons (window,
|
||||
if (FRAME_LIVE_P (f)
|
||||
&& FRAME_INTERNAL_BORDER_WIDTH (f) > 0
|
||||
&& !NILP (get_frame_param (f, Qdrag_internal_border)))
|
||||
{
|
||||
enum internal_border_part part
|
||||
= frame_internal_border_part (f, xret, yret);
|
||||
|
||||
posn = builtin_lisp_symbol (internal_border_parts[part]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
else
|
||||
window_or_frame = Qnil;
|
||||
|
||||
return Fcons (window_or_frame,
|
||||
Fcons (posn,
|
||||
Fcons (Fcons (make_number (xret),
|
||||
make_number (yret)),
|
||||
|
|
@ -11159,6 +11184,17 @@ syms_of_keyboard (void)
|
|||
Fset (Qinput_method_exit_on_first_char, Qnil);
|
||||
Fset (Qinput_method_use_echo_area, Qnil);
|
||||
|
||||
/* Symbols for dragging internal borders. */
|
||||
DEFSYM (Qdrag_internal_border, "drag-internal-border");
|
||||
DEFSYM (Qleft_edge, "left-edge");
|
||||
DEFSYM (Qtop_left_corner, "top-left-corner");
|
||||
DEFSYM (Qtop_edge, "top-edge");
|
||||
DEFSYM (Qtop_right_corner, "top-right-corner");
|
||||
DEFSYM (Qright_edge, "right-edge");
|
||||
DEFSYM (Qbottom_right_corner, "bottom-right-corner");
|
||||
DEFSYM (Qbottom_edge, "bottom-edge");
|
||||
DEFSYM (Qbottom_left_corner, "bottom-left-corner");
|
||||
|
||||
/* Symbols to head events. */
|
||||
DEFSYM (Qmouse_movement, "mouse-movement");
|
||||
DEFSYM (Qscroll_bar_movement, "scroll-bar-movement");
|
||||
|
|
|
|||
|
|
@ -874,6 +874,30 @@ read_minibuf_unwind (void)
|
|||
if (minibuf_level == 0)
|
||||
resize_mini_window (XWINDOW (window), 0);
|
||||
|
||||
/* Deal with frames that should be removed when exiting the
|
||||
minibuffer. */
|
||||
{
|
||||
Lisp_Object frames, frame1, val;
|
||||
struct frame *f1;
|
||||
|
||||
FOR_EACH_FRAME (frames, frame1)
|
||||
{
|
||||
f1 = XFRAME (frame1);
|
||||
|
||||
if ((FRAME_PARENT_FRAME (f1)
|
||||
|| !NILP (get_frame_param (f1, Qdelete_before)))
|
||||
&& !NILP (val = (get_frame_param (f1, Qminibuffer_exit))))
|
||||
{
|
||||
if (EQ (val, Qiconify_frame))
|
||||
Ficonify_frame (frame1);
|
||||
else if (EQ (val, Qdelete_frame))
|
||||
Fdelete_frame (frame1, Qnil);
|
||||
else
|
||||
Fmake_frame_invisible (frame1, Qnil);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* In case the previous minibuffer displayed in this miniwindow is
|
||||
dead, we may keep displaying this buffer (tho it's inactive), so reset it,
|
||||
to make sure we don't leave around bindings and stuff which only
|
||||
|
|
@ -1930,6 +1954,8 @@ syms_of_minibuf (void)
|
|||
DEFSYM (Qactivate_input_method, "activate-input-method");
|
||||
DEFSYM (Qcase_fold_search, "case-fold-search");
|
||||
DEFSYM (Qmetadata, "metadata");
|
||||
/* A frame parameter. */
|
||||
DEFSYM (Qminibuffer_exit, "minibuffer-exit");
|
||||
|
||||
DEFVAR_LISP ("read-expression-history", Vread_expression_history,
|
||||
doc: /* A history list for arguments that are Lisp expressions to evaluate.
|
||||
|
|
|
|||
12
src/nsfns.m
12
src/nsfns.m
|
|
@ -984,6 +984,7 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side
|
|||
x_set_no_accept_focus,
|
||||
x_set_z_group, /* x_set_z_group */
|
||||
0, /* x_set_override_redirect */
|
||||
x_set_no_special_glyphs,
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -1256,6 +1257,8 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side
|
|||
"leftFringe", "LeftFringe", RES_TYPE_NUMBER);
|
||||
x_default_parameter (f, parms, Qright_fringe, Qnil,
|
||||
"rightFringe", "RightFringe", RES_TYPE_NUMBER);
|
||||
x_default_parameter (f, parms, Qno_special_glyphs, Qnil,
|
||||
NULL, NULL, RES_TYPE_BOOLEAN);
|
||||
|
||||
init_frame_faces (f);
|
||||
|
||||
|
|
@ -1325,6 +1328,15 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side
|
|||
f->output_data.ns->hourglass_cursor = [NSCursor disappearingItemCursor];
|
||||
f->output_data.ns->horizontal_drag_cursor = [NSCursor resizeLeftRightCursor];
|
||||
f->output_data.ns->vertical_drag_cursor = [NSCursor resizeUpDownCursor];
|
||||
f->output_data.ns->left_edge_cursor = [NSCursor resizeLeftRightCursor];
|
||||
f->output_data.ns->top_left_corner_cursor = [NSCursor arrowCursor];
|
||||
f->output_data.ns->top_edge_cursor = [NSCursor resizeUpDownCursor];
|
||||
f->output_data.ns->top_right_corner_cursor = [NSCursor arrowCursor];
|
||||
f->output_data.ns->right_edge_cursor = [NSCursor resizeLeftRightCursor];
|
||||
f->output_data.ns->bottom_right_corner_cursor = [NSCursor arrowCursor];
|
||||
f->output_data.ns->bottom_edge_cursor = [NSCursor resizeUpDownCursor];
|
||||
f->output_data.ns->bottom_left_corner_cursor = [NSCursor arrowCursor];
|
||||
|
||||
FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor
|
||||
= [NSCursor arrowCursor];
|
||||
FRAME_DISPLAY_INFO (f)->horizontal_scroll_bar_cursor
|
||||
|
|
|
|||
|
|
@ -957,6 +957,14 @@ struct ns_output
|
|||
Cursor hourglass_cursor;
|
||||
Cursor horizontal_drag_cursor;
|
||||
Cursor vertical_drag_cursor;
|
||||
Cursor left_edge_cursor;
|
||||
Cursor top_left_corner_cursor;
|
||||
Cursor top_edge_cursor;
|
||||
Cursor top_right_corner_cursor;
|
||||
Cursor right_edge_cursor;
|
||||
Cursor bottom_right_corner_cursor;
|
||||
Cursor bottom_edge_cursor;
|
||||
Cursor bottom_left_corner_cursor;
|
||||
|
||||
/* NS-specific */
|
||||
Cursor current_pointer;
|
||||
|
|
|
|||
41
src/w32fns.c
41
src/w32fns.c
|
|
@ -5889,6 +5889,8 @@ This function is an internal primitive--use `make-frame' instead. */)
|
|||
NULL, NULL, RES_TYPE_BOOLEAN);
|
||||
x_default_parameter (f, parameters, Qno_accept_focus, Qnil,
|
||||
NULL, NULL, RES_TYPE_BOOLEAN);
|
||||
x_default_parameter (f, parameters, Qno_special_glyphs, Qnil,
|
||||
NULL, NULL, RES_TYPE_BOOLEAN);
|
||||
|
||||
/* Process alpha here (Bug#16619). On XP this fails with child
|
||||
frames. For `no-focus-on-map' frames delay processing of alpha
|
||||
|
|
@ -5957,6 +5959,14 @@ This function is an internal primitive--use `make-frame' instead. */)
|
|||
f->output_data.w32->hourglass_cursor = w32_load_cursor (IDC_WAIT);
|
||||
f->output_data.w32->horizontal_drag_cursor = w32_load_cursor (IDC_SIZEWE);
|
||||
f->output_data.w32->vertical_drag_cursor = w32_load_cursor (IDC_SIZENS);
|
||||
f->output_data.w32->left_edge_cursor = w32_load_cursor (IDC_SIZEWE);
|
||||
f->output_data.w32->top_left_corner_cursor = w32_load_cursor (IDC_SIZENWSE);
|
||||
f->output_data.w32->top_edge_cursor = w32_load_cursor (IDC_SIZENS);
|
||||
f->output_data.w32->top_right_corner_cursor = w32_load_cursor (IDC_SIZENESW);
|
||||
f->output_data.w32->right_edge_cursor = w32_load_cursor (IDC_SIZEWE);
|
||||
f->output_data.w32->bottom_right_corner_cursor = w32_load_cursor (IDC_SIZENWSE);
|
||||
f->output_data.w32->bottom_edge_cursor = w32_load_cursor (IDC_SIZENS);
|
||||
f->output_data.w32->bottom_left_corner_cursor = w32_load_cursor (IDC_SIZENESW);
|
||||
|
||||
f->output_data.w32->current_cursor = f->output_data.w32->nontext_cursor;
|
||||
|
||||
|
|
@ -7049,6 +7059,8 @@ x_create_tip_frame (struct w32_display_info *dpyinfo, Lisp_Object parms)
|
|||
"cursorColor", "Foreground", RES_TYPE_STRING);
|
||||
x_default_parameter (f, parms, Qborder_color, build_string ("black"),
|
||||
"borderColor", "BorderColor", RES_TYPE_STRING);
|
||||
x_default_parameter (f, parms, Qno_special_glyphs, Qt,
|
||||
NULL, NULL, RES_TYPE_BOOLEAN);
|
||||
|
||||
/* Init faces before x_default_parameter is called for the
|
||||
scroll-bar-width parameter because otherwise we end up in
|
||||
|
|
@ -8950,33 +8962,47 @@ menu bar or tool bar of FRAME. */)
|
|||
if (EQ (type, Qouter_edges))
|
||||
{
|
||||
RECT rectangle;
|
||||
BOOL success = false;
|
||||
|
||||
block_input ();
|
||||
/* Outer frame rectangle, including outer borders and title bar. */
|
||||
GetWindowRect (FRAME_W32_WINDOW (f), &rectangle);
|
||||
success = GetWindowRect (FRAME_W32_WINDOW (f), &rectangle);
|
||||
unblock_input ();
|
||||
|
||||
return list4 (make_number (rectangle.left),
|
||||
make_number (rectangle.top),
|
||||
make_number (rectangle.right),
|
||||
make_number (rectangle.bottom));
|
||||
if (success)
|
||||
return list4 (make_number (rectangle.left),
|
||||
make_number (rectangle.top),
|
||||
make_number (rectangle.right),
|
||||
make_number (rectangle.bottom));
|
||||
else
|
||||
return Qnil;
|
||||
}
|
||||
else
|
||||
{
|
||||
RECT rectangle;
|
||||
POINT pt;
|
||||
int left, top, right, bottom;
|
||||
BOOL success;
|
||||
|
||||
block_input ();
|
||||
/* Inner frame rectangle, excluding borders and title bar. */
|
||||
GetClientRect (FRAME_W32_WINDOW (f), &rectangle);
|
||||
success = GetClientRect (FRAME_W32_WINDOW (f), &rectangle);
|
||||
/* Get top-left corner of native rectangle in screen
|
||||
coordinates. */
|
||||
if (!success)
|
||||
{
|
||||
unblock_input ();
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
pt.x = 0;
|
||||
pt.y = 0;
|
||||
ClientToScreen (FRAME_W32_WINDOW (f), &pt);
|
||||
success = ClientToScreen (FRAME_W32_WINDOW (f), &pt);
|
||||
unblock_input ();
|
||||
|
||||
if (!success)
|
||||
return Qnil;
|
||||
|
||||
left = pt.x;
|
||||
top = pt.y;
|
||||
right = left + rectangle.right;
|
||||
|
|
@ -10330,6 +10356,7 @@ frame_parm_handler w32_frame_parm_handlers[] =
|
|||
x_set_no_accept_focus,
|
||||
x_set_z_group,
|
||||
0, /* x_set_override_redirect */
|
||||
x_set_no_special_glyphs,
|
||||
};
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -5086,6 +5086,51 @@ w32_read_socket (struct terminal *terminal,
|
|||
}
|
||||
|
||||
case WM_WINDOWPOSCHANGED:
|
||||
f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
|
||||
|
||||
if (f)
|
||||
{
|
||||
RECT rect;
|
||||
int /* rows, columns, */ width, height, text_width, text_height;
|
||||
|
||||
if (GetClientRect (msg.msg.hwnd, &rect)
|
||||
/* GetClientRect evidently returns (0, 0, 0, 0) if
|
||||
called on a minimized frame. Such "dimensions"
|
||||
aren't useful anyway. */
|
||||
&& !(rect.bottom == 0
|
||||
&& rect.top == 0
|
||||
&& rect.left == 0
|
||||
&& rect.right == 0))
|
||||
{
|
||||
height = rect.bottom - rect.top;
|
||||
width = rect.right - rect.left;
|
||||
text_width = FRAME_PIXEL_TO_TEXT_WIDTH (f, width);
|
||||
text_height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, height);
|
||||
/* rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, height); */
|
||||
/* columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, width); */
|
||||
|
||||
/* TODO: Clip size to the screen dimensions. */
|
||||
|
||||
/* Even if the number of character rows and columns
|
||||
has not changed, the font size may have changed,
|
||||
so we need to check the pixel dimensions as well. */
|
||||
|
||||
if (width != FRAME_PIXEL_WIDTH (f)
|
||||
|| height != FRAME_PIXEL_HEIGHT (f)
|
||||
|| text_width != FRAME_TEXT_WIDTH (f)
|
||||
|| text_height != FRAME_TEXT_HEIGHT (f))
|
||||
{
|
||||
change_frame_size (f, text_width, text_height, 0, 1, 0, 1);
|
||||
SET_FRAME_GARBAGED (f);
|
||||
cancel_mouse_face (f);
|
||||
f->win_gravity = NorthWestGravity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
check_visibility = 1;
|
||||
break;
|
||||
|
||||
case WM_ACTIVATE:
|
||||
case WM_ACTIVATEAPP:
|
||||
f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
|
||||
|
|
@ -6052,7 +6097,7 @@ x_calc_absolute_position (struct frame *f)
|
|||
int display_top = 0;
|
||||
struct frame *p = FRAME_PARENT_FRAME (f);
|
||||
|
||||
if (flags & (XNegative | YNegative))
|
||||
if (!p && flags & (XNegative | YNegative))
|
||||
{
|
||||
Lisp_Object list;
|
||||
|
||||
|
|
@ -6078,20 +6123,26 @@ x_calc_absolute_position (struct frame *f)
|
|||
}
|
||||
|
||||
/* Treat negative positions as relative to the rightmost bottommost
|
||||
position that fits on the screen. */
|
||||
position that fits on the screen or parent frame.
|
||||
|
||||
I see no need for subtracting 1 from the border widths - is there
|
||||
any on the remaining platforms? Here these subtractions did put
|
||||
the last pixel line/column of a frame off-display when, for
|
||||
example, a (set-frame-parameter nil 'left '(- 0)) specification was
|
||||
used - martin 20017-05-05. */
|
||||
if (flags & XNegative)
|
||||
{
|
||||
if (p)
|
||||
f->left_pos = (FRAME_PIXEL_WIDTH (p)
|
||||
- FRAME_PIXEL_WIDTH (f)
|
||||
+ f->left_pos
|
||||
- (left_right_borders_width - 1));
|
||||
- left_right_borders_width);
|
||||
else
|
||||
f->left_pos = (x_display_pixel_width (FRAME_DISPLAY_INFO (f))
|
||||
+ display_left
|
||||
- FRAME_PIXEL_WIDTH (f)
|
||||
+ f->left_pos
|
||||
- (left_right_borders_width - 1));
|
||||
- left_right_borders_width);
|
||||
}
|
||||
|
||||
if (flags & YNegative)
|
||||
|
|
@ -6100,13 +6151,13 @@ x_calc_absolute_position (struct frame *f)
|
|||
f->top_pos = (FRAME_PIXEL_HEIGHT (p)
|
||||
- FRAME_PIXEL_HEIGHT (f)
|
||||
+ f->top_pos
|
||||
- (top_bottom_borders_height - 1));
|
||||
- top_bottom_borders_height);
|
||||
else
|
||||
f->top_pos = (x_display_pixel_height (FRAME_DISPLAY_INFO (f))
|
||||
+ display_top
|
||||
- FRAME_PIXEL_HEIGHT (f)
|
||||
+ f->top_pos
|
||||
- (top_bottom_borders_height - 1));
|
||||
- top_bottom_borders_height);
|
||||
}
|
||||
|
||||
/* The left_pos and top_pos are now relative to the top and left
|
||||
|
|
|
|||
|
|
@ -345,6 +345,14 @@ struct w32_output
|
|||
Cursor hourglass_cursor;
|
||||
Cursor horizontal_drag_cursor;
|
||||
Cursor vertical_drag_cursor;
|
||||
Cursor left_edge_cursor;
|
||||
Cursor top_left_corner_cursor;
|
||||
Cursor top_edge_cursor;
|
||||
Cursor top_right_corner_cursor;
|
||||
Cursor right_edge_cursor;
|
||||
Cursor bottom_right_corner_cursor;
|
||||
Cursor bottom_edge_cursor;
|
||||
Cursor bottom_left_corner_cursor;
|
||||
|
||||
/* Non-zero means hourglass cursor is currently displayed. */
|
||||
unsigned hourglass_p : 1;
|
||||
|
|
|
|||
213
src/window.c
213
src/window.c
|
|
@ -1208,13 +1208,13 @@ coordinates_in_window (register struct window *w, int x, int y)
|
|||
- WINDOW_BOTTOM_DIVIDER_WIDTH (w))))
|
||||
return ON_HORIZONTAL_SCROLL_BAR;
|
||||
/* On the mode or header line? */
|
||||
else if ((WINDOW_WANTS_MODELINE_P (w)
|
||||
else if ((window_wants_mode_line (w)
|
||||
&& y >= (bottom_y
|
||||
- CURRENT_MODE_LINE_HEIGHT (w)
|
||||
- WINDOW_BOTTOM_DIVIDER_WIDTH (w))
|
||||
&& y <= bottom_y - WINDOW_BOTTOM_DIVIDER_WIDTH (w)
|
||||
&& (part = ON_MODE_LINE))
|
||||
|| (WINDOW_WANTS_HEADER_LINE_P (w)
|
||||
|| (window_wants_header_line (w)
|
||||
&& y < top_y + CURRENT_HEADER_LINE_HEIGHT (w)
|
||||
&& (part = ON_HEADER_LINE)))
|
||||
{
|
||||
|
|
@ -1851,7 +1851,7 @@ Return nil if window display is not up-to-date. In that case, use
|
|||
|
||||
if (EQ (line, Qheader_line))
|
||||
{
|
||||
if (!WINDOW_WANTS_HEADER_LINE_P (w))
|
||||
if (!window_wants_header_line (w))
|
||||
return Qnil;
|
||||
row = MATRIX_HEADER_LINE_ROW (w->current_matrix);
|
||||
return row->enabled_p ? list4i (row->height, 0, 0, 0) : Qnil;
|
||||
|
|
@ -1898,6 +1898,129 @@ Return nil if window display is not up-to-date. In that case, use
|
|||
return list4i (row->height + min (0, row->y) - crop, i, row->y, crop);
|
||||
}
|
||||
|
||||
DEFUN ("window-lines-pixel-dimensions", Fwindow_lines_pixel_dimensions, Swindow_lines_pixel_dimensions, 0, 6, 0,
|
||||
doc: /* Return pixel dimensions of WINDOW's lines.
|
||||
The return value is a list of the x- and y-coordinates of the lower
|
||||
right corner of the last character of each line. Return nil if the
|
||||
current glyph matrix of WINDOW is not up-to-date.
|
||||
|
||||
Optional argument WINDOW specifies the window whose lines' dimensions
|
||||
shall be returned. Nil or omitted means to return the dimensions for
|
||||
the selected window.
|
||||
|
||||
FIRST, if non-nil, specifies the index of the first line whose
|
||||
dimensions shall be returned. If FIRST is nil and BODY is non-nil,
|
||||
start with the first text line of WINDOW. Otherwise, start with the
|
||||
first line of WINDOW.
|
||||
|
||||
LAST, if non-nil, specifies the last line whose dimensions shall be
|
||||
returned. If LAST is nil and BODY is non-nil, the last line is the last
|
||||
line of the body (text area) of WINDOW. Otherwise, last is the last
|
||||
line of WINDOW.
|
||||
|
||||
INVERSE, if nil, means that the y-pixel value returned for a specific
|
||||
line specifies the distance in pixels from the left edge (body edge if
|
||||
BODY is non-nil) of WINDOW to the right edge of the last glyph of that
|
||||
line. INVERSE non-nil means that the y-pixel value returned for a
|
||||
specific line specifies the distance in pixels from the right edge of
|
||||
the last glyph of that line to the right edge (body edge if BODY is
|
||||
non-nil) of WINDOW.
|
||||
|
||||
LEFT non-nil means to return the x- and y-coordinates of the lower left
|
||||
corner of the leftmost character on each line. This is the value that
|
||||
should be used for buffers that mostly display text from right to left.
|
||||
|
||||
If LEFT is non-nil and INVERSE is nil, this means that the y-pixel value
|
||||
returned for a specific line specifies the distance in pixels from the
|
||||
left edge of the last (leftmost) glyph of that line to the right edge
|
||||
(body edge if BODY is non-nil) of WINDOW. If LEFT and INVERSE are both
|
||||
non-nil, the y-pixel value returned for a specific line specifies the
|
||||
distance in pixels from the left edge (body edge if BODY is non-nil) of
|
||||
WINDOW to the left edge of the last (leftmost) glyph of that line.
|
||||
|
||||
Normally, the value of this function is not available while Emacs is
|
||||
busy, for example, when processing a command. It should be retrievable
|
||||
though when run from an idle timer with a delay of zero seconds. */)
|
||||
(Lisp_Object window, Lisp_Object first, Lisp_Object last, Lisp_Object body, Lisp_Object inverse, Lisp_Object left)
|
||||
{
|
||||
struct window *w = decode_live_window (window);
|
||||
struct buffer *b;
|
||||
struct glyph_row *row, *end_row;
|
||||
int max_y = NILP (body) ? WINDOW_PIXEL_HEIGHT (w) : window_text_bottom_y (w);
|
||||
Lisp_Object rows = Qnil;
|
||||
int window_width = NILP (body) ? w->pixel_width : window_body_width (w, true);
|
||||
int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
|
||||
int subtract = NILP (body) ? 0 : header_line_height;
|
||||
bool invert = !NILP (inverse);
|
||||
bool left_flag = !NILP (left);
|
||||
|
||||
if (noninteractive || w->pseudo_window_p)
|
||||
return Qnil;
|
||||
|
||||
CHECK_BUFFER (w->contents);
|
||||
b = XBUFFER (w->contents);
|
||||
|
||||
/* Fail if current matrix is not up-to-date. */
|
||||
if (!w->window_end_valid
|
||||
|| windows_or_buffers_changed
|
||||
|| b->clip_changed
|
||||
|| b->prevent_redisplay_optimizations_p
|
||||
|| window_outdated (w))
|
||||
return Qnil;
|
||||
|
||||
if (NILP (first))
|
||||
row = (NILP (body)
|
||||
? MATRIX_ROW (w->current_matrix, 0)
|
||||
: MATRIX_FIRST_TEXT_ROW (w->current_matrix));
|
||||
else if (NUMBERP (first))
|
||||
{
|
||||
CHECK_RANGED_INTEGER (first, 0, w->current_matrix->nrows);
|
||||
row = MATRIX_ROW (w->current_matrix, XINT (first));
|
||||
}
|
||||
else
|
||||
error ("Invalid specification of first line");
|
||||
|
||||
if (NILP (last))
|
||||
|
||||
end_row = (NILP (body)
|
||||
? MATRIX_ROW (w->current_matrix, w->current_matrix->nrows)
|
||||
: MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w));
|
||||
else if (NUMBERP (last))
|
||||
{
|
||||
CHECK_RANGED_INTEGER (last, 0, w->current_matrix->nrows);
|
||||
end_row = MATRIX_ROW (w->current_matrix, XINT (last));
|
||||
}
|
||||
else
|
||||
error ("Invalid specification of last line");
|
||||
|
||||
while (row <= end_row && row->enabled_p
|
||||
&& row->y + row->height < max_y)
|
||||
{
|
||||
|
||||
if (left_flag)
|
||||
{
|
||||
struct glyph *glyph = row->glyphs[TEXT_AREA];
|
||||
|
||||
rows = Fcons (Fcons (make_number
|
||||
(invert
|
||||
? glyph->pixel_width
|
||||
: window_width - glyph->pixel_width),
|
||||
make_number (row->y + row->height - subtract)),
|
||||
rows);
|
||||
}
|
||||
else
|
||||
rows = Fcons (Fcons (make_number
|
||||
(invert
|
||||
? window_width - row->pixel_width
|
||||
: row->pixel_width),
|
||||
make_number (row->y + row->height - subtract)),
|
||||
rows);
|
||||
row++;
|
||||
}
|
||||
|
||||
return Fnreverse (rows);
|
||||
}
|
||||
|
||||
DEFUN ("window-dedicated-p", Fwindow_dedicated_p, Swindow_dedicated_p,
|
||||
0, 1, 0,
|
||||
doc: /* Return non-nil when WINDOW is dedicated to its buffer.
|
||||
|
|
@ -2003,16 +2126,24 @@ return value is a list of elements of the form (PARAMETER . VALUE). */)
|
|||
return Fcopy_alist (decode_valid_window (window)->window_parameters);
|
||||
}
|
||||
|
||||
Lisp_Object
|
||||
window_parameter (struct window *w, Lisp_Object parameter)
|
||||
{
|
||||
Lisp_Object result = Fassq (parameter, w->window_parameters);
|
||||
|
||||
return CDR_SAFE (result);
|
||||
}
|
||||
|
||||
|
||||
DEFUN ("window-parameter", Fwindow_parameter, Swindow_parameter,
|
||||
2, 2, 0,
|
||||
doc: /* Return WINDOW's value for PARAMETER.
|
||||
WINDOW can be any window and defaults to the selected one. */)
|
||||
(Lisp_Object window, Lisp_Object parameter)
|
||||
{
|
||||
Lisp_Object result;
|
||||
struct window *w = decode_any_window (window);
|
||||
|
||||
result = Fassq (parameter, decode_any_window (window)->window_parameters);
|
||||
return CDR_SAFE (result);
|
||||
return window_parameter (w, parameter);
|
||||
}
|
||||
|
||||
DEFUN ("set-window-parameter", Fset_window_parameter,
|
||||
|
|
@ -4740,6 +4871,69 @@ mark_window_cursors_off (struct window *w)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* window_wants_mode_line:
|
||||
*
|
||||
* Return 1 if window W wants a mode line and is high enough to
|
||||
* accomodate it, 0 otherwise.
|
||||
*
|
||||
* W wants a mode line if it's a leaf window and neither a minibuffer
|
||||
* nor a pseudo window. Moreover, its 'window-mode-line-format'
|
||||
* parameter must not be 'none' and either that parameter or W's
|
||||
* buffer's 'mode-line-format' value must be non-nil. Finally, W must
|
||||
* be higher than its frame's canonical character height.
|
||||
*/
|
||||
bool
|
||||
window_wants_mode_line (struct window *w)
|
||||
{
|
||||
Lisp_Object window_mode_line_format =
|
||||
window_parameter (w, Qmode_line_format);
|
||||
|
||||
return ((WINDOW_LEAF_P (w)
|
||||
&& !MINI_WINDOW_P (w)
|
||||
&& !WINDOW_PSEUDO_P (w)
|
||||
&& !EQ (window_mode_line_format, Qnone)
|
||||
&& (!NILP (window_mode_line_format)
|
||||
|| !NILP (BVAR (XBUFFER (WINDOW_BUFFER (w)), mode_line_format)))
|
||||
&& WINDOW_PIXEL_HEIGHT (w) > WINDOW_FRAME_LINE_HEIGHT (w))
|
||||
? 1
|
||||
: 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* window_wants_header_line:
|
||||
*
|
||||
* Return 1 if window W wants a header line and is high enough to
|
||||
* accomodate it, 0 otherwise.
|
||||
*
|
||||
* W wants a header line if it's a leaf window and neither a minibuffer
|
||||
* nor a pseudo window. Moreover, its 'window-mode-line-format'
|
||||
* parameter must not be 'none' and either that parameter or W's
|
||||
* buffer's 'mode-line-format' value must be non-nil. Finally, W must
|
||||
* be higher than its frame's canonical character height and be able to
|
||||
* accomodate a mode line too if necessary (the mode line prevails).
|
||||
*/
|
||||
bool
|
||||
window_wants_header_line (struct window *w)
|
||||
{
|
||||
Lisp_Object window_header_line_format =
|
||||
window_parameter (w, Qheader_line_format);
|
||||
|
||||
return ((WINDOW_LEAF_P (w)
|
||||
&& !MINI_WINDOW_P (w)
|
||||
&& !WINDOW_PSEUDO_P (w)
|
||||
&& !EQ (window_header_line_format, Qnone)
|
||||
&& (!NILP (window_header_line_format)
|
||||
|| !NILP (BVAR (XBUFFER (WINDOW_BUFFER (w)), header_line_format)))
|
||||
&& (WINDOW_PIXEL_HEIGHT (w)
|
||||
> (window_wants_mode_line (w)
|
||||
? 2 * WINDOW_FRAME_LINE_HEIGHT (w)
|
||||
: WINDOW_FRAME_LINE_HEIGHT (w))))
|
||||
? 1
|
||||
: 0);
|
||||
}
|
||||
|
||||
/* Return number of lines of text (not counting mode lines) in W. */
|
||||
|
||||
int
|
||||
|
|
@ -4753,10 +4947,10 @@ window_internal_height (struct window *w)
|
|||
|| WINDOWP (w->contents)
|
||||
|| !NILP (w->next)
|
||||
|| !NILP (w->prev)
|
||||
|| WINDOW_WANTS_MODELINE_P (w))
|
||||
|| window_wants_mode_line (w))
|
||||
--ht;
|
||||
|
||||
if (WINDOW_WANTS_HEADER_LINE_P (w))
|
||||
if (window_wants_header_line (w))
|
||||
--ht;
|
||||
}
|
||||
|
||||
|
|
@ -7354,6 +7548,8 @@ syms_of_window (void)
|
|||
DEFSYM (Qfloor, "floor");
|
||||
DEFSYM (Qceiling, "ceiling");
|
||||
DEFSYM (Qmark_for_redisplay, "mark-for-redisplay");
|
||||
DEFSYM (Qmode_line_format, "mode-line-format");
|
||||
DEFSYM (Qheader_line_format, "header-line-format");
|
||||
|
||||
staticpro (&Vwindow_list);
|
||||
|
||||
|
|
@ -7603,6 +7799,7 @@ displayed after a scrolling operation to be somewhat inaccurate. */);
|
|||
defsubr (&Sset_window_point);
|
||||
defsubr (&Sset_window_start);
|
||||
defsubr (&Swindow_dedicated_p);
|
||||
defsubr (&Swindow_lines_pixel_dimensions);
|
||||
defsubr (&Sset_window_dedicated_p);
|
||||
defsubr (&Swindow_display_table);
|
||||
defsubr (&Sset_window_display_table);
|
||||
|
|
|
|||
200
src/window.h
200
src/window.h
|
|
@ -328,8 +328,9 @@ struct window
|
|||
/* True if this window is a minibuffer window. */
|
||||
bool_bf mini : 1;
|
||||
|
||||
/* Meaningful only if contents is a window, true if this
|
||||
internal window is used in horizontal combination. */
|
||||
/* Meaningful for internal windows only: true if this window is a
|
||||
horizontal combination, false if it is a vertical
|
||||
combination. */
|
||||
bool_bf horizontal : 1;
|
||||
|
||||
/* True means must regenerate mode line of this window. */
|
||||
|
|
@ -481,15 +482,14 @@ wset_next_buffers (struct window *w, Lisp_Object val)
|
|||
/* True if W is a minibuffer window. */
|
||||
#define MINI_WINDOW_P(W) ((W)->mini)
|
||||
|
||||
/* 1 if W is a non-only minibuffer window. */
|
||||
/* The first check is redundant and the second overly complicated. */
|
||||
#define MINI_NON_ONLY_WINDOW_P(W) \
|
||||
(MINI_WINDOW_P (W) \
|
||||
&& (EQ (W->prev, FRAME_ROOT_WINDOW (WINDOW_XFRAME (W)))))
|
||||
/* True if W is a minibuffer window on a frame that contains at least
|
||||
one other window. */
|
||||
#define MINI_NON_ONLY_WINDOW_P(W) \
|
||||
(MINI_WINDOW_P (W) && !NILP ((W)->prev))
|
||||
|
||||
/* 1 if W is a minibuffer-only window. */
|
||||
#define MINI_ONLY_WINDOW_P(W) \
|
||||
(MINI_WINDOW_P (W) && NILP (W->prev))
|
||||
/* True if W is a minibuffer window that is alone on its frame. */
|
||||
#define MINI_ONLY_WINDOW_P(W) \
|
||||
(MINI_WINDOW_P (W) && NILP ((W)->prev))
|
||||
|
||||
/* General window layout:
|
||||
|
||||
|
|
@ -518,29 +518,34 @@ wset_next_buffers (struct window *w, Lisp_Object val)
|
|||
|
||||
/* A handy macro. */
|
||||
|
||||
/* Non-nil if W is leaf (carry the buffer). */
|
||||
|
||||
/* Non-nil if window W is leaf window (has a buffer). */
|
||||
#define WINDOW_LEAF_P(W) \
|
||||
(BUFFERP ((W)->contents))
|
||||
|
||||
/* Non-nil if W is internal. */
|
||||
/* Non-nil if window W is internal (is a parent window). */
|
||||
#define WINDOW_INTERNAL_P(W) \
|
||||
(WINDOWP ((W)->contents))
|
||||
|
||||
/* True if W is a member of horizontal combination. */
|
||||
/* True if window W is a horizontal combination of windows. */
|
||||
#define WINDOW_HORIZONTAL_COMBINATION_P(W) \
|
||||
(WINDOW_INTERNAL_P (W) && (W)->horizontal)
|
||||
|
||||
/* True if W is a member of vertical combination. */
|
||||
/* True if window W is a vertical combination of windows. */
|
||||
#define WINDOW_VERTICAL_COMBINATION_P(W) \
|
||||
(WINDOW_INTERNAL_P (W) && !(W)->horizontal)
|
||||
|
||||
/* WINDOW's XFRAME. */
|
||||
/* Window W's XFRAME. */
|
||||
#define WINDOW_XFRAME(W) (XFRAME (WINDOW_FRAME ((W))))
|
||||
|
||||
/* Whether WINDOW is a pseudo window. */
|
||||
/* Whether window W is a pseudo window. */
|
||||
#define WINDOW_PSEUDO_P(W) ((W)->pseudo_window_p)
|
||||
|
||||
/* Window W's buffer. */
|
||||
#define WINDOW_BUFFER(W) \
|
||||
(WINDOW_LEAF_P(W) \
|
||||
? (W)->contents \
|
||||
: Qnil) \
|
||||
|
||||
/* Return the canonical column width of the frame of window W. */
|
||||
#define WINDOW_FRAME_COLUMN_WIDTH(W) \
|
||||
(FRAME_COLUMN_WIDTH (WINDOW_XFRAME ((W))))
|
||||
|
|
@ -549,24 +554,24 @@ wset_next_buffers (struct window *w, Lisp_Object val)
|
|||
#define WINDOW_FRAME_LINE_HEIGHT(W) \
|
||||
(FRAME_LINE_HEIGHT (WINDOW_XFRAME ((W))))
|
||||
|
||||
/* Return the pixel width of window W.
|
||||
This includes scroll bars and fringes. */
|
||||
/* Return the pixel width of window W. This includes dividers, scroll
|
||||
bars, fringes and margins, if any. */
|
||||
#define WINDOW_PIXEL_WIDTH(W) (W)->pixel_width
|
||||
|
||||
/* Return the pixel height of window W.
|
||||
This includes header and mode lines, if any. */
|
||||
/* Return the pixel height of window W. This includes dividers, scroll
|
||||
bars, header and mode lines, if any. */
|
||||
#define WINDOW_PIXEL_HEIGHT(W) (W)->pixel_height
|
||||
|
||||
/* Return the width of window W in canonical column units.
|
||||
This includes scroll bars and fringes.
|
||||
This value is adjusted such that the sum of the widths of all child
|
||||
/* Return the width of window W in canonical column units. This
|
||||
includes dividers, scroll bars, fringes and margins, if any. The
|
||||
value is adjusted such that the sum of the widths of all child
|
||||
windows equals the width of their parent window. */
|
||||
#define WINDOW_TOTAL_COLS(W) (W)->total_cols
|
||||
|
||||
/* Return the height of window W in canonical line units.
|
||||
This includes header and mode lines, if any.
|
||||
This value is adjusted such that the sum of the heights of all child
|
||||
windows equals the height of their parent window. */
|
||||
/* Return the height of window W in canonical line units. This includes
|
||||
dividers, scroll bars, header and mode lines, if any. The value is
|
||||
adjusted such that the sum of the heights of all child windows equals
|
||||
the height of their parent window. */
|
||||
#define WINDOW_TOTAL_LINES(W) (W)->total_lines
|
||||
|
||||
/* The smallest acceptable dimensions for a window. Anything smaller
|
||||
|
|
@ -581,31 +586,63 @@ wset_next_buffers (struct window *w, Lisp_Object val)
|
|||
#define MIN_SAFE_WINDOW_PIXEL_HEIGHT(W) \
|
||||
(WINDOW_FRAME_LINE_HEIGHT (W))
|
||||
|
||||
/* True if window W has no other windows to its left on its frame. */
|
||||
#define WINDOW_LEFTMOST_P(W) \
|
||||
(WINDOW_LEFT_PIXEL_EDGE (W) == 0)
|
||||
|
||||
/* True if window W has no other windows above it on its frame. */
|
||||
#define WINDOW_TOPMOST_P(W) \
|
||||
(WINDOW_TOP_PIXEL_EDGE (W) == 0)
|
||||
|
||||
/* True if window W has no other windows to its right on its frame. */
|
||||
#define WINDOW_RIGHTMOST_P(W) \
|
||||
(WINDOW_RIGHT_PIXEL_EDGE (W) \
|
||||
== (WINDOW_RIGHT_PIXEL_EDGE \
|
||||
(XWINDOW (FRAME_ROOT_WINDOW (WINDOW_XFRAME (W)))))) \
|
||||
|
||||
/* True if window W has no other windows below it on its frame (the
|
||||
minibuffer window is not counted in this respect unless W itself is a
|
||||
minibuffer window). */
|
||||
#define WINDOW_BOTTOMMOST_P(W) \
|
||||
(WINDOW_BOTTOM_PIXEL_EDGE (W) \
|
||||
== (WINDOW_BOTTOM_PIXEL_EDGE \
|
||||
(XWINDOW (FRAME_ROOT_WINDOW (WINDOW_XFRAME (W)))))) \
|
||||
|
||||
/* True if window W takes up the full width of its frame. */
|
||||
#define WINDOW_FULL_WIDTH_P(W) \
|
||||
(WINDOW_PIXEL_WIDTH (W) \
|
||||
== (WINDOW_PIXEL_WIDTH \
|
||||
(XWINDOW (FRAME_ROOT_WINDOW (WINDOW_XFRAME (W)))))) \
|
||||
|
||||
/* Width of right divider of window W. */
|
||||
#define WINDOW_RIGHT_DIVIDER_WIDTH(W) \
|
||||
((WINDOW_RIGHTMOST_P (W) || MINI_WINDOW_P (W)) \
|
||||
? 0 \
|
||||
: FRAME_RIGHT_DIVIDER_WIDTH (WINDOW_XFRAME (W)))
|
||||
(WINDOW_RIGHTMOST_P (W) \
|
||||
? 0 : FRAME_RIGHT_DIVIDER_WIDTH (WINDOW_XFRAME (W)))
|
||||
|
||||
/* Width of bottom divider of window W. */
|
||||
#define WINDOW_BOTTOM_DIVIDER_WIDTH(W) \
|
||||
(((WINDOW_BOTTOMMOST_P (W) \
|
||||
&& NILP ((XWINDOW (FRAME_ROOT_WINDOW \
|
||||
(WINDOW_XFRAME (W))))->next)) \
|
||||
|| EQ ((W)->prev, FRAME_ROOT_WINDOW (WINDOW_XFRAME (W))) \
|
||||
|| (W)->pseudo_window_p) \
|
||||
? 0 : FRAME_BOTTOM_DIVIDER_WIDTH (WINDOW_XFRAME (W)))
|
||||
|
||||
/* Return the canonical frame column at which window W starts.
|
||||
This includes a left-hand scroll bar, if any. */
|
||||
|
||||
#define WINDOW_LEFT_EDGE_COL(W) (W)->left_col
|
||||
|
||||
/* Return the canonical frame column before which window W ends.
|
||||
This includes a right-hand scroll bar, if any. */
|
||||
|
||||
#define WINDOW_RIGHT_EDGE_COL(W) \
|
||||
(WINDOW_LEFT_EDGE_COL (W) + WINDOW_TOTAL_COLS (W))
|
||||
|
||||
/* Return the canonical frame line at which window W starts.
|
||||
This includes a header line, if any. */
|
||||
|
||||
#define WINDOW_TOP_EDGE_LINE(W) (W)->top_line
|
||||
|
||||
/* Return the canonical frame line before which window W ends.
|
||||
This includes a mode line, if any. */
|
||||
|
||||
#define WINDOW_BOTTOM_EDGE_LINE(W) \
|
||||
(WINDOW_TOP_EDGE_LINE (W) + WINDOW_TOTAL_LINES (W))
|
||||
|
||||
|
|
@ -629,20 +666,17 @@ wset_next_buffers (struct window *w, Lisp_Object val)
|
|||
|
||||
/* Return the frame x-position at which window W starts.
|
||||
This includes a left-hand scroll bar, if any. */
|
||||
|
||||
#define WINDOW_LEFT_EDGE_X(W) \
|
||||
(FRAME_INTERNAL_BORDER_WIDTH (WINDOW_XFRAME (W)) \
|
||||
+ WINDOW_LEFT_PIXEL_EDGE (W))
|
||||
|
||||
/* Return the frame x- position before which window W ends.
|
||||
This includes a right-hand scroll bar, if any. */
|
||||
|
||||
#define WINDOW_RIGHT_EDGE_X(W) \
|
||||
(FRAME_INTERNAL_BORDER_WIDTH (WINDOW_XFRAME (W)) \
|
||||
+ WINDOW_RIGHT_PIXEL_EDGE (W))
|
||||
|
||||
/* True if W is a menu bar window. */
|
||||
|
||||
#if defined (HAVE_X_WINDOWS) && ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
|
||||
#define WINDOW_MENU_BAR_P(W) \
|
||||
(WINDOWP (WINDOW_XFRAME (W)->menu_bar_window) \
|
||||
|
|
@ -661,72 +695,24 @@ wset_next_buffers (struct window *w, Lisp_Object val)
|
|||
#define WINDOW_TOOL_BAR_P(W) false
|
||||
#endif
|
||||
|
||||
/* Return the frame y-position at which window W starts.
|
||||
This includes a header line, if any.
|
||||
|
||||
PXW: With a menu or tool bar this is not symmetric to the _X values
|
||||
since it _does_ include the internal border width. */
|
||||
/* Return the frame y-position at which window W starts. */
|
||||
#define WINDOW_TOP_EDGE_Y(W) \
|
||||
(((WINDOW_MENU_BAR_P (W) || WINDOW_TOOL_BAR_P (W)) \
|
||||
? 0 : FRAME_INTERNAL_BORDER_WIDTH (WINDOW_XFRAME (W))) \
|
||||
+ WINDOW_TOP_PIXEL_EDGE (W))
|
||||
|
||||
/* Return the frame y-position before which window W ends.
|
||||
This includes a mode line, if any. */
|
||||
/* Return the frame y-position before which window W ends. */
|
||||
#define WINDOW_BOTTOM_EDGE_Y(W) \
|
||||
(((WINDOW_MENU_BAR_P (W) || WINDOW_TOOL_BAR_P (W)) \
|
||||
? 0 : FRAME_INTERNAL_BORDER_WIDTH (WINDOW_XFRAME (W))) \
|
||||
+ WINDOW_BOTTOM_PIXEL_EDGE (W))
|
||||
|
||||
/* True if window W takes up the full width of its frame. */
|
||||
#define WINDOW_FULL_WIDTH_P(W) \
|
||||
(WINDOW_PIXEL_WIDTH (W) \
|
||||
== (WINDOW_PIXEL_WIDTH \
|
||||
(XWINDOW (FRAME_ROOT_WINDOW (WINDOW_XFRAME (W)))))) \
|
||||
|
||||
/* True if window W's has no other windows to its left in its frame. */
|
||||
|
||||
#define WINDOW_LEFTMOST_P(W) \
|
||||
(WINDOW_LEFT_PIXEL_EDGE (W) == 0)
|
||||
|
||||
/* True if window W's has no other windows above in its frame. */
|
||||
#define WINDOW_TOPMOST_P(W) \
|
||||
(WINDOW_TOP_PIXEL_EDGE (W) == 0)
|
||||
|
||||
/* True if window W's has no other windows to its right in its frame. */
|
||||
#define WINDOW_RIGHTMOST_P(W) \
|
||||
(WINDOW_RIGHT_PIXEL_EDGE (W) \
|
||||
== (WINDOW_RIGHT_PIXEL_EDGE \
|
||||
(XWINDOW (FRAME_ROOT_WINDOW (WINDOW_XFRAME (W)))))) \
|
||||
|
||||
/* True if window W's has no other windows below it in its frame
|
||||
(the minibuffer window is not counted in this respect). */
|
||||
#define WINDOW_BOTTOMMOST_P(W) \
|
||||
(WINDOW_BOTTOM_PIXEL_EDGE (W) \
|
||||
== (WINDOW_BOTTOM_PIXEL_EDGE \
|
||||
(XWINDOW (FRAME_ROOT_WINDOW (WINDOW_XFRAME (W)))))) \
|
||||
|
||||
/* Return the frame column at which the text (or left fringe) in
|
||||
window W starts. This is different from the `LEFT_EDGE' because it
|
||||
does not include a left-hand scroll bar if any. */
|
||||
#define WINDOW_BOX_LEFT_EDGE_COL(W) \
|
||||
(WINDOW_LEFT_EDGE_COL (W) \
|
||||
+ WINDOW_LEFT_SCROLL_BAR_COLS (W))
|
||||
|
||||
/* Return the pixel value where the text (or left fringe) in
|
||||
window W starts. This is different from the `LEFT_EDGE' because it
|
||||
does not include a left-hand scroll bar if any. */
|
||||
/* Return the pixel value where the text (or left fringe) in window W
|
||||
starts. */
|
||||
#define WINDOW_BOX_LEFT_PIXEL_EDGE(W) \
|
||||
(WINDOW_LEFT_PIXEL_EDGE (W) \
|
||||
+ WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (W))
|
||||
|
||||
/* Return the window column before which the text in window W ends.
|
||||
This is different from WINDOW_RIGHT_EDGE_COL because it does not
|
||||
include a scroll bar or window-separating line on the right edge. */
|
||||
#define WINDOW_BOX_RIGHT_EDGE_COL(W) \
|
||||
(WINDOW_RIGHT_EDGE_COL (W) \
|
||||
- WINDOW_RIGHT_SCROLL_BAR_COLS (W))
|
||||
|
||||
/* Return the pixel value before which the text in window W ends. This
|
||||
is different from the `RIGHT_EDGE' because it does not include a
|
||||
right-hand scroll bar or window-separating line on the right
|
||||
|
|
@ -736,16 +722,16 @@ wset_next_buffers (struct window *w, Lisp_Object val)
|
|||
- WINDOW_RIGHT_DIVIDER_WIDTH (W) \
|
||||
- WINDOW_RIGHT_SCROLL_BAR_AREA_WIDTH (W))
|
||||
|
||||
/* Return the frame position at which the text (or left fringe) in
|
||||
window W starts. This is different from the `LEFT_EDGE' because it
|
||||
does not include a left-hand scroll bar if any. */
|
||||
/* Return the frame x-position at which the text (or left fringe) in
|
||||
window W starts. This does not include a left-hand scroll bar if
|
||||
any. */
|
||||
#define WINDOW_BOX_LEFT_EDGE_X(W) \
|
||||
(FRAME_INTERNAL_BORDER_WIDTH (WINDOW_XFRAME (W)) \
|
||||
+ WINDOW_BOX_LEFT_PIXEL_EDGE (W))
|
||||
|
||||
/* Return the window column before which the text in window W ends.
|
||||
This is different from WINDOW_RIGHT_EDGE_COL because it does not
|
||||
include a scroll bar or window-separating line on the right edge. */
|
||||
/* Return the frame x-position before which the text in window W ends.
|
||||
This does not include a scroll bar, divider or window-separating line
|
||||
on the right edge. */
|
||||
#define WINDOW_BOX_RIGHT_EDGE_X(W) \
|
||||
(FRAME_INTERNAL_BORDER_WIDTH (WINDOW_XFRAME (W)) \
|
||||
+ WINDOW_BOX_RIGHT_PIXEL_EDGE (W))
|
||||
|
|
@ -899,16 +885,6 @@ wset_next_buffers (struct window *w, Lisp_Object val)
|
|||
? WINDOW_BOX_RIGHT_EDGE_X (W) \
|
||||
: WINDOW_LEFT_EDGE_X (W))
|
||||
|
||||
/* Width of bottom divider of window W. */
|
||||
#define WINDOW_BOTTOM_DIVIDER_WIDTH(W) \
|
||||
(((WINDOW_BOTTOMMOST_P (W) \
|
||||
&& NILP ((XWINDOW (FRAME_ROOT_WINDOW \
|
||||
(WINDOW_XFRAME (W))))->next)) \
|
||||
|| EQ ((W)->prev, FRAME_ROOT_WINDOW (WINDOW_XFRAME (W))) \
|
||||
|| (W)->pseudo_window_p) \
|
||||
? 0 \
|
||||
: FRAME_BOTTOM_DIVIDER_WIDTH (WINDOW_XFRAME (W)))
|
||||
|
||||
/* Height that a scroll bar in window W should have, if there is one.
|
||||
Measured in pixels. If scroll bars are turned off, this is still
|
||||
nonzero. */
|
||||
|
|
@ -942,22 +918,22 @@ wset_next_buffers (struct window *w, Lisp_Object val)
|
|||
/* Height in pixels of the mode line.
|
||||
May be zero if W doesn't have a mode line. */
|
||||
#define WINDOW_MODE_LINE_HEIGHT(W) \
|
||||
(WINDOW_WANTS_MODELINE_P ((W)) \
|
||||
(window_wants_mode_line ((W)) \
|
||||
? CURRENT_MODE_LINE_HEIGHT (W) \
|
||||
: 0)
|
||||
|
||||
#define WINDOW_MODE_LINE_LINES(W) \
|
||||
WINDOW_WANTS_MODELINE_P (W)
|
||||
window_wants_mode_line (W)
|
||||
|
||||
/* Height in pixels of the header line.
|
||||
Zero if W doesn't have a header line. */
|
||||
#define WINDOW_HEADER_LINE_HEIGHT(W) \
|
||||
(WINDOW_WANTS_HEADER_LINE_P (W) \
|
||||
(window_wants_header_line (W) \
|
||||
? CURRENT_HEADER_LINE_HEIGHT (W) \
|
||||
: 0)
|
||||
|
||||
#define WINDOW_HEADER_LINE_LINES(W) \
|
||||
WINDOW_WANTS_HEADER_LINE_P (W)
|
||||
window_wants_header_line (W)
|
||||
|
||||
/* Pixel height of window W without mode line, bottom scroll bar and
|
||||
bottom divider. */
|
||||
|
|
@ -1114,10 +1090,13 @@ struct glyph *get_phys_cursor_glyph (struct window *w);
|
|||
extern Lisp_Object Vwindow_list;
|
||||
|
||||
extern Lisp_Object window_list (void);
|
||||
extern Lisp_Object window_parameter (struct window *, Lisp_Object parameter);
|
||||
extern struct window *decode_live_window (Lisp_Object);
|
||||
extern struct window *decode_any_window (Lisp_Object);
|
||||
extern bool compare_window_configurations (Lisp_Object, Lisp_Object, bool);
|
||||
extern void mark_window_cursors_off (struct window *);
|
||||
extern bool window_wants_mode_line (struct window *);
|
||||
extern bool window_wants_header_line (struct window *);
|
||||
extern int window_internal_height (struct window *);
|
||||
extern int window_body_width (struct window *w, bool);
|
||||
enum margin_unit { MARGIN_IN_LINES, MARGIN_IN_PIXELS };
|
||||
|
|
@ -1133,7 +1112,6 @@ extern void init_window_once (void);
|
|||
extern void init_window (void);
|
||||
extern void syms_of_window (void);
|
||||
extern void keys_of_window (void);
|
||||
|
||||
/* Move cursor to row/column position VPOS/HPOS, pixel coordinates
|
||||
Y/X. HPOS/VPOS are window-relative row and column numbers and X/Y
|
||||
are window-relative pixel positions. This is always done during
|
||||
|
|
|
|||
185
src/xdisp.c
185
src/xdisp.c
|
|
@ -921,7 +921,7 @@ window_text_bottom_y (struct window *w)
|
|||
|
||||
height -= WINDOW_BOTTOM_DIVIDER_WIDTH (w);
|
||||
|
||||
if (WINDOW_WANTS_MODELINE_P (w))
|
||||
if (window_wants_mode_line (w))
|
||||
height -= CURRENT_MODE_LINE_HEIGHT (w);
|
||||
|
||||
height -= WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
|
||||
|
|
@ -978,7 +978,7 @@ window_box_height (struct window *w)
|
|||
the appropriate glyph row has its `mode_line_p' flag set,
|
||||
and if it doesn't, uses estimate_mode_line_height instead. */
|
||||
|
||||
if (WINDOW_WANTS_MODELINE_P (w))
|
||||
if (window_wants_mode_line (w))
|
||||
{
|
||||
struct glyph_row *ml_row
|
||||
= (w->current_matrix && w->current_matrix->rows
|
||||
|
|
@ -990,7 +990,7 @@ window_box_height (struct window *w)
|
|||
height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
|
||||
}
|
||||
|
||||
if (WINDOW_WANTS_HEADER_LINE_P (w))
|
||||
if (window_wants_header_line (w))
|
||||
{
|
||||
struct glyph_row *hl_row
|
||||
= (w->current_matrix && w->current_matrix->rows
|
||||
|
|
@ -1102,7 +1102,7 @@ window_box (struct window *w, enum glyph_row_area area, int *box_x,
|
|||
if (box_y)
|
||||
{
|
||||
*box_y = WINDOW_TOP_EDGE_Y (w);
|
||||
if (WINDOW_WANTS_HEADER_LINE_P (w))
|
||||
if (window_wants_header_line (w))
|
||||
*box_y += CURRENT_HEADER_LINE_HEIGHT (w);
|
||||
}
|
||||
}
|
||||
|
|
@ -1322,15 +1322,29 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
|
|||
return visible_p;
|
||||
|
||||
/* Compute exact mode line heights. */
|
||||
if (WINDOW_WANTS_MODELINE_P (w))
|
||||
w->mode_line_height
|
||||
= display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
|
||||
BVAR (current_buffer, mode_line_format));
|
||||
if (window_wants_mode_line (w))
|
||||
{
|
||||
Lisp_Object window_mode_line_format
|
||||
= window_parameter (w, Qmode_line_format);
|
||||
|
||||
if (WINDOW_WANTS_HEADER_LINE_P (w))
|
||||
w->header_line_height
|
||||
= display_mode_line (w, HEADER_LINE_FACE_ID,
|
||||
BVAR (current_buffer, header_line_format));
|
||||
w->mode_line_height
|
||||
= display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
|
||||
NILP (window_mode_line_format)
|
||||
? BVAR (current_buffer, mode_line_format)
|
||||
: window_mode_line_format);
|
||||
}
|
||||
|
||||
if (window_wants_header_line (w))
|
||||
{
|
||||
Lisp_Object window_header_line_format
|
||||
= window_parameter (w, Qheader_line_format);
|
||||
|
||||
w->header_line_height
|
||||
= display_mode_line (w, HEADER_LINE_FACE_ID,
|
||||
NILP (window_header_line_format)
|
||||
? BVAR (current_buffer, header_line_format)
|
||||
: window_header_line_format);
|
||||
}
|
||||
|
||||
start_display (&it, w, top);
|
||||
move_it_to (&it, charpos, -1, it.last_visible_y - 1, -1,
|
||||
|
|
@ -2842,13 +2856,12 @@ init_iterator (struct it *it, struct window *w,
|
|||
|
||||
/* Get dimensions of truncation and continuation glyphs. These are
|
||||
displayed as fringe bitmaps under X, but we need them for such
|
||||
frames when the fringes are turned off. But leave the dimensions
|
||||
zero for tooltip frames, as these glyphs look ugly there and also
|
||||
sabotage calculations of tooltip dimensions in x-show-tip. */
|
||||
frames when the fringes are turned off. The no_special_glyphs slot
|
||||
of the iterator's frame, when set, suppresses their display - by
|
||||
default for tooltip frames and when set via the 'no-special-glyphs'
|
||||
frame parameter. */
|
||||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
if (!(FRAME_WINDOW_P (it->f)
|
||||
&& FRAMEP (tip_frame)
|
||||
&& it->f == XFRAME (tip_frame)))
|
||||
if (!(FRAME_WINDOW_P (it->f) && it->f->no_special_glyphs))
|
||||
#endif
|
||||
{
|
||||
if (it->line_wrap == TRUNCATE)
|
||||
|
|
@ -2920,7 +2933,7 @@ init_iterator (struct it *it, struct window *w,
|
|||
it->last_visible_x -= it->continuation_pixel_width;
|
||||
}
|
||||
|
||||
it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
|
||||
it->header_line_p = window_wants_header_line (w);
|
||||
it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
|
||||
}
|
||||
|
||||
|
|
@ -3019,7 +3032,7 @@ void
|
|||
start_display (struct it *it, struct window *w, struct text_pos pos)
|
||||
{
|
||||
struct glyph_row *row;
|
||||
bool first_vpos = WINDOW_WANTS_HEADER_LINE_P (w);
|
||||
bool first_vpos = window_wants_header_line (w);
|
||||
|
||||
row = w->desired_matrix->rows + first_vpos;
|
||||
init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
|
||||
|
|
@ -15799,7 +15812,7 @@ compute_window_start_on_continuation_line (struct window *w)
|
|||
|
||||
/* Find the start of the continued line. This should be fast
|
||||
because find_newline is fast (newline cache). */
|
||||
row = w->desired_matrix->rows + WINDOW_WANTS_HEADER_LINE_P (w);
|
||||
row = w->desired_matrix->rows + window_wants_header_line (w);
|
||||
init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
|
||||
row, DEFAULT_FACE_ID);
|
||||
reseat_at_previous_visible_line_start (&it);
|
||||
|
|
@ -15949,7 +15962,7 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp,
|
|||
this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
|
||||
|
||||
top_scroll_margin = this_scroll_margin;
|
||||
if (WINDOW_WANTS_HEADER_LINE_P (w))
|
||||
if (window_wants_header_line (w))
|
||||
top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
|
||||
|
||||
/* Start with the row the cursor was displayed during the last
|
||||
|
|
@ -16732,7 +16745,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
|
|||
margin, even though this part handles windows that didn't
|
||||
scroll at all. */
|
||||
int pixel_margin = margin * frame_line_height;
|
||||
bool header_line = WINDOW_WANTS_HEADER_LINE_P (w);
|
||||
bool header_line = window_wants_header_line (w);
|
||||
|
||||
/* Note: We add an extra FRAME_LINE_HEIGHT, because the loop
|
||||
below, which finds the row to move point to, advances by
|
||||
|
|
@ -17299,15 +17312,15 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
|
|||
|| (w->column_number_displayed != -1
|
||||
&& (w->column_number_displayed != current_column ())))
|
||||
/* This means that the window has a mode line. */
|
||||
&& (WINDOW_WANTS_MODELINE_P (w)
|
||||
|| WINDOW_WANTS_HEADER_LINE_P (w)))
|
||||
&& (window_wants_mode_line (w)
|
||||
|| window_wants_header_line (w)))
|
||||
{
|
||||
|
||||
display_mode_lines (w);
|
||||
|
||||
/* If mode line height has changed, arrange for a thorough
|
||||
immediate redisplay using the correct mode line height. */
|
||||
if (WINDOW_WANTS_MODELINE_P (w)
|
||||
if (window_wants_mode_line (w)
|
||||
&& CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
|
||||
{
|
||||
f->fonts_changed = true;
|
||||
|
|
@ -17318,7 +17331,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
|
|||
|
||||
/* If header line height has changed, arrange for a thorough
|
||||
immediate redisplay using the correct header line height. */
|
||||
if (WINDOW_WANTS_HEADER_LINE_P (w)
|
||||
if (window_wants_header_line (w)
|
||||
&& CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
|
||||
{
|
||||
f->fonts_changed = true;
|
||||
|
|
@ -17583,7 +17596,7 @@ try_window_reusing_current_matrix (struct window *w)
|
|||
return false;
|
||||
|
||||
/* If top-line visibility has changed, give up. */
|
||||
if (WINDOW_WANTS_HEADER_LINE_P (w)
|
||||
if (window_wants_header_line (w)
|
||||
!= MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
|
||||
return false;
|
||||
|
||||
|
|
@ -18818,7 +18831,7 @@ try_window_id (struct window *w)
|
|||
= MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
|
||||
int from = WINDOW_TOP_EDGE_LINE (w) + from_vpos;
|
||||
int end = (WINDOW_TOP_EDGE_LINE (w)
|
||||
+ WINDOW_WANTS_HEADER_LINE_P (w)
|
||||
+ window_wants_header_line (w)
|
||||
+ window_internal_height (w));
|
||||
|
||||
#if defined (HAVE_GPM) || defined (MSDOS)
|
||||
|
|
@ -18996,7 +19009,7 @@ try_window_id (struct window *w)
|
|||
{
|
||||
/* Displayed to end of window, but no line containing text was
|
||||
displayed. Lines were deleted at the end of the window. */
|
||||
bool first_vpos = WINDOW_WANTS_HEADER_LINE_P (w);
|
||||
bool first_vpos = window_wants_header_line (w);
|
||||
int vpos = w->window_end_vpos;
|
||||
struct glyph_row *current_row = current_matrix->rows + vpos;
|
||||
struct glyph_row *desired_row = desired_matrix->rows + vpos;
|
||||
|
|
@ -20696,7 +20709,7 @@ display_line (struct it *it, int cursor_vpos)
|
|||
ptrdiff_t min_pos = ZV + 1, max_pos = 0;
|
||||
ptrdiff_t min_bpos UNINIT, max_bpos UNINIT;
|
||||
bool pending_handle_line_prefix = false;
|
||||
int header_line = WINDOW_WANTS_HEADER_LINE_P (it->w);
|
||||
int header_line = window_wants_header_line (it->w);
|
||||
bool hscroll_this_line = (cursor_vpos >= 0
|
||||
&& it->vpos == cursor_vpos - header_line
|
||||
&& hscrolling_current_line_p (it->w));
|
||||
|
|
@ -22649,20 +22662,30 @@ display_mode_lines (struct window *w)
|
|||
line_number_displayed = false;
|
||||
w->column_number_displayed = -1;
|
||||
|
||||
if (WINDOW_WANTS_MODELINE_P (w))
|
||||
if (window_wants_mode_line (w))
|
||||
{
|
||||
Lisp_Object window_mode_line_format
|
||||
= window_parameter (w, Qmode_line_format);
|
||||
|
||||
struct window *sel_w = XWINDOW (old_selected_window);
|
||||
|
||||
/* Select mode line face based on the real selected window. */
|
||||
display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
|
||||
BVAR (current_buffer, mode_line_format));
|
||||
NILP (window_mode_line_format)
|
||||
? BVAR (current_buffer, mode_line_format)
|
||||
: window_mode_line_format);
|
||||
++n;
|
||||
}
|
||||
|
||||
if (WINDOW_WANTS_HEADER_LINE_P (w))
|
||||
if (window_wants_header_line (w))
|
||||
{
|
||||
Lisp_Object window_header_line_format
|
||||
= window_parameter (w, Qheader_line_format);
|
||||
|
||||
display_mode_line (w, HEADER_LINE_FACE_ID,
|
||||
BVAR (current_buffer, header_line_format));
|
||||
NILP (window_header_line_format)
|
||||
? BVAR (current_buffer, header_line_format)
|
||||
: window_header_line_format);
|
||||
++n;
|
||||
}
|
||||
|
||||
|
|
@ -30442,13 +30465,67 @@ note_mouse_highlight (struct frame *f, int x, int y)
|
|||
&& part != ON_HEADER_LINE))
|
||||
clear_mouse_face (hlinfo);
|
||||
|
||||
/* Reset help_echo_string. It will get recomputed below. */
|
||||
help_echo_string = Qnil;
|
||||
|
||||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
/* If the cursor is on the internal border of FRAME and FRAME's
|
||||
internal border is draggable, provide some visual feedback. */
|
||||
if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0
|
||||
&& !NILP (get_frame_param (f, Qdrag_internal_border)))
|
||||
{
|
||||
enum internal_border_part part = frame_internal_border_part (f, x, y);
|
||||
|
||||
switch (part)
|
||||
{
|
||||
case INTERNAL_BORDER_NONE:
|
||||
if (cursor != FRAME_X_OUTPUT (f)->nontext_cursor)
|
||||
/* Reset cursor. */
|
||||
cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
|
||||
break;
|
||||
case INTERNAL_BORDER_LEFT_EDGE:
|
||||
cursor = FRAME_X_OUTPUT (f)->left_edge_cursor;
|
||||
break;
|
||||
case INTERNAL_BORDER_TOP_LEFT_CORNER:
|
||||
cursor = FRAME_X_OUTPUT (f)->top_left_corner_cursor;
|
||||
break;
|
||||
case INTERNAL_BORDER_TOP_EDGE:
|
||||
cursor = FRAME_X_OUTPUT (f)->top_edge_cursor;
|
||||
break;
|
||||
case INTERNAL_BORDER_TOP_RIGHT_CORNER:
|
||||
cursor = FRAME_X_OUTPUT (f)->top_right_corner_cursor;
|
||||
break;
|
||||
case INTERNAL_BORDER_RIGHT_EDGE:
|
||||
cursor = FRAME_X_OUTPUT (f)->right_edge_cursor;
|
||||
break;
|
||||
case INTERNAL_BORDER_BOTTOM_RIGHT_CORNER:
|
||||
cursor = FRAME_X_OUTPUT (f)->bottom_right_corner_cursor;
|
||||
break;
|
||||
case INTERNAL_BORDER_BOTTOM_EDGE:
|
||||
cursor = FRAME_X_OUTPUT (f)->bottom_edge_cursor;
|
||||
break;
|
||||
case INTERNAL_BORDER_BOTTOM_LEFT_CORNER:
|
||||
cursor = FRAME_X_OUTPUT (f)->bottom_left_corner_cursor;
|
||||
break;
|
||||
default:
|
||||
/* This should not happen. */
|
||||
if (cursor != FRAME_X_OUTPUT (f)->nontext_cursor)
|
||||
cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
|
||||
}
|
||||
|
||||
if (cursor != FRAME_X_OUTPUT (f)->nontext_cursor)
|
||||
{
|
||||
/* Do we really want a help echo here? */
|
||||
help_echo_string = build_string ("drag-mouse-1: resize frame");
|
||||
goto set_cursor;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_WINDOW_SYSTEM */
|
||||
|
||||
/* Not on a window -> return. */
|
||||
if (!WINDOWP (window))
|
||||
return;
|
||||
|
||||
/* Reset help_echo_string. It will get recomputed below. */
|
||||
help_echo_string = Qnil;
|
||||
|
||||
/* Convert to window-relative pixel coordinates. */
|
||||
w = XWINDOW (window);
|
||||
frame_to_window_pixel_xy (w, &x, &y);
|
||||
|
|
@ -30486,11 +30563,13 @@ note_mouse_highlight (struct frame *f, int x, int y)
|
|||
{
|
||||
cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
|
||||
help_echo_string = build_string ("drag-mouse-1: resize");
|
||||
goto set_cursor;
|
||||
}
|
||||
else if (part == ON_RIGHT_DIVIDER)
|
||||
{
|
||||
cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
|
||||
help_echo_string = build_string ("drag-mouse-1: resize");
|
||||
goto set_cursor;
|
||||
}
|
||||
else if (part == ON_BOTTOM_DIVIDER)
|
||||
if (! WINDOW_BOTTOMMOST_P (w)
|
||||
|
|
@ -30499,6 +30578,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
|
|||
{
|
||||
cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
|
||||
help_echo_string = build_string ("drag-mouse-1: resize");
|
||||
goto set_cursor;
|
||||
}
|
||||
else
|
||||
cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
|
||||
|
|
@ -31193,8 +31273,15 @@ x_draw_right_divider (struct window *w)
|
|||
int x0 = WINDOW_RIGHT_EDGE_X (w) - WINDOW_RIGHT_DIVIDER_WIDTH (w);
|
||||
int x1 = WINDOW_RIGHT_EDGE_X (w);
|
||||
int y0 = WINDOW_TOP_EDGE_Y (w);
|
||||
/* The bottom divider prevails. */
|
||||
int y1 = WINDOW_BOTTOM_EDGE_Y (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
|
||||
int y1 = WINDOW_BOTTOM_EDGE_Y (w);
|
||||
|
||||
/* If W is horizontally combined and has a right sibling, don't
|
||||
draw over any bottom divider. */
|
||||
if (WINDOW_BOTTOM_DIVIDER_WIDTH (w)
|
||||
&& !NILP (w->parent)
|
||||
&& WINDOW_HORIZONTAL_COMBINATION_P (XWINDOW (w->parent))
|
||||
&& !NILP (w->next))
|
||||
y1 -= WINDOW_BOTTOM_DIVIDER_WIDTH (w);
|
||||
|
||||
FRAME_RIF (f)->draw_window_divider (w, x0, x1, y0, y1);
|
||||
}
|
||||
|
|
@ -31213,8 +31300,22 @@ x_draw_bottom_divider (struct window *w)
|
|||
int x1 = WINDOW_RIGHT_EDGE_X (w);
|
||||
int y0 = WINDOW_BOTTOM_EDGE_Y (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
|
||||
int y1 = WINDOW_BOTTOM_EDGE_Y (w);
|
||||
struct window *p = !NILP (w->parent) ? XWINDOW (w->parent) : false;
|
||||
|
||||
FRAME_RIF (f)->draw_window_divider (w, x0, x1, y0, y1);
|
||||
/* If W is vertically combined and has a sibling below, don't draw
|
||||
over any right divider. */
|
||||
if (WINDOW_RIGHT_DIVIDER_WIDTH (w)
|
||||
&& p
|
||||
&& ((WINDOW_VERTICAL_COMBINATION_P (p)
|
||||
&& !NILP (w->next))
|
||||
|| (WINDOW_HORIZONTAL_COMBINATION_P (p)
|
||||
&& NILP (w->next)
|
||||
&& !NILP (p->parent)
|
||||
&& WINDOW_VERTICAL_COMBINATION_P (XWINDOW (p->parent))
|
||||
&& !NILP (XWINDOW (p->parent)->next))))
|
||||
x1 -= WINDOW_RIGHT_DIVIDER_WIDTH (w);
|
||||
|
||||
FRAME_RIF (f)->draw_window_divider (w, x0, x1, y0, y1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -31329,7 +31430,7 @@ expose_window (struct window *w, XRectangle *fr)
|
|||
}
|
||||
|
||||
/* Display the mode line if there is one. */
|
||||
if (WINDOW_WANTS_MODELINE_P (w)
|
||||
if (window_wants_mode_line (w)
|
||||
&& (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
|
||||
row->enabled_p)
|
||||
&& row->y < r_bottom)
|
||||
|
|
|
|||
101
src/xfns.c
101
src/xfns.c
|
|
@ -1120,6 +1120,14 @@ enum mouse_cursor {
|
|||
mouse_cursor_hand,
|
||||
mouse_cursor_horizontal_drag,
|
||||
mouse_cursor_vertical_drag,
|
||||
mouse_cursor_left_edge,
|
||||
mouse_cursor_top_left_corner,
|
||||
mouse_cursor_top_edge,
|
||||
mouse_cursor_top_right_corner,
|
||||
mouse_cursor_right_edge,
|
||||
mouse_cursor_bottom_right_corner,
|
||||
mouse_cursor_bottom_edge,
|
||||
mouse_cursor_bottom_left_corner,
|
||||
mouse_cursor_max
|
||||
};
|
||||
|
||||
|
|
@ -1139,13 +1147,21 @@ struct mouse_cursor_types {
|
|||
|
||||
/* This array must stay in sync with enum mouse_cursor above! */
|
||||
static const struct mouse_cursor_types mouse_cursor_types[] = {
|
||||
{ "text", &Vx_pointer_shape, XC_xterm },
|
||||
{ "nontext", &Vx_nontext_pointer_shape, XC_left_ptr },
|
||||
{ "hourglass", &Vx_hourglass_pointer_shape, XC_watch },
|
||||
{ "modeline", &Vx_mode_pointer_shape, XC_xterm },
|
||||
{ NULL, &Vx_sensitive_text_pointer_shape, XC_hand2 },
|
||||
{ NULL, &Vx_window_horizontal_drag_shape, XC_sb_h_double_arrow },
|
||||
{ NULL, &Vx_window_vertical_drag_shape, XC_sb_v_double_arrow },
|
||||
{ "text", &Vx_pointer_shape, XC_xterm },
|
||||
{ "nontext", &Vx_nontext_pointer_shape, XC_left_ptr },
|
||||
{ "hourglass", &Vx_hourglass_pointer_shape, XC_watch },
|
||||
{ "modeline", &Vx_mode_pointer_shape, XC_xterm },
|
||||
{ NULL, &Vx_sensitive_text_pointer_shape, XC_hand2 },
|
||||
{ NULL, &Vx_window_horizontal_drag_shape, XC_sb_h_double_arrow },
|
||||
{ NULL, &Vx_window_vertical_drag_shape, XC_sb_v_double_arrow },
|
||||
{ NULL, &Vx_window_left_edge_shape, XC_left_side },
|
||||
{ NULL, &Vx_window_top_left_corner_shape, XC_top_left_corner },
|
||||
{ NULL, &Vx_window_top_edge_shape, XC_top_side },
|
||||
{ NULL, &Vx_window_top_right_corner_shape, XC_top_right_corner },
|
||||
{ NULL, &Vx_window_right_edge_shape, XC_right_side },
|
||||
{ NULL, &Vx_window_bottom_right_corner_shape, XC_bottom_right_corner },
|
||||
{ NULL, &Vx_window_bottom_edge_shape, XC_bottom_side },
|
||||
{ NULL, &Vx_window_bottom_left_corner_shape, XC_bottom_left_corner },
|
||||
};
|
||||
|
||||
struct mouse_cursor_data {
|
||||
|
|
@ -1296,6 +1312,14 @@ x_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
|
|||
INSTALL_CURSOR (hand_cursor, hand);
|
||||
INSTALL_CURSOR (horizontal_drag_cursor, horizontal_drag);
|
||||
INSTALL_CURSOR (vertical_drag_cursor, vertical_drag);
|
||||
INSTALL_CURSOR (left_edge_cursor, left_edge);
|
||||
INSTALL_CURSOR (top_left_corner_cursor, top_left_corner);
|
||||
INSTALL_CURSOR (top_edge_cursor, top_edge);
|
||||
INSTALL_CURSOR (top_right_corner_cursor, top_right_corner);
|
||||
INSTALL_CURSOR (right_edge_cursor, right_edge);
|
||||
INSTALL_CURSOR (bottom_right_corner_cursor, bottom_right_corner);
|
||||
INSTALL_CURSOR (bottom_edge_cursor, bottom_edge);
|
||||
INSTALL_CURSOR (bottom_left_corner_cursor, bottom_left_corner);
|
||||
|
||||
#undef INSTALL_CURSOR
|
||||
|
||||
|
|
@ -3814,6 +3838,8 @@ This function is an internal primitive--use `make-frame' instead. */)
|
|||
"leftFringe", "LeftFringe", RES_TYPE_NUMBER);
|
||||
x_default_parameter (f, parms, Qright_fringe, Qnil,
|
||||
"rightFringe", "RightFringe", RES_TYPE_NUMBER);
|
||||
x_default_parameter (f, parms, Qno_special_glyphs, Qnil,
|
||||
NULL, NULL, RES_TYPE_BOOLEAN);
|
||||
|
||||
x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_foreground,
|
||||
"scrollBarForeground",
|
||||
|
|
@ -5286,7 +5312,7 @@ Frames are listed from topmost (first) to bottommost (last). */)
|
|||
static void
|
||||
x_frame_restack (struct frame *f1, struct frame *f2, bool above_flag)
|
||||
{
|
||||
#ifdef USE_GTK
|
||||
#if defined (USE_GTK) && GTK_CHECK_VERSION (2, 18, 0)
|
||||
block_input ();
|
||||
xg_frame_restack (f1, f2, above_flag);
|
||||
unblock_input ();
|
||||
|
|
@ -6196,6 +6222,8 @@ x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms)
|
|||
"cursorColor", "Foreground", RES_TYPE_STRING);
|
||||
x_default_parameter (f, parms, Qborder_color, build_string ("black"),
|
||||
"borderColor", "BorderColor", RES_TYPE_STRING);
|
||||
x_default_parameter (f, parms, Qno_special_glyphs, Qnil,
|
||||
NULL, NULL, RES_TYPE_BOOLEAN);
|
||||
|
||||
/* Init faces before x_default_parameter is called for the
|
||||
scroll-bar-width parameter because otherwise we end up in
|
||||
|
|
@ -7486,6 +7514,7 @@ frame_parm_handler x_frame_parm_handlers[] =
|
|||
x_set_no_accept_focus,
|
||||
x_set_z_group,
|
||||
x_set_override_redirect,
|
||||
x_set_no_special_glyphs,
|
||||
};
|
||||
|
||||
void
|
||||
|
|
@ -7564,6 +7593,62 @@ This variable takes effect when you create a new frame
|
|||
or when you set the mouse color. */);
|
||||
Vx_window_vertical_drag_shape = Qnil;
|
||||
|
||||
DEFVAR_LISP ("x-window-left-edge-cursor",
|
||||
Vx_window_left_edge_shape,
|
||||
doc: /* Pointer shape indicating a left x-window edge can be dragged.
|
||||
This variable takes effect when you create a new frame
|
||||
or when you set the mouse color. */);
|
||||
Vx_window_left_edge_shape = Qnil;
|
||||
|
||||
DEFVAR_LISP ("x-window-top-left-corner-cursor",
|
||||
Vx_window_top_left_corner_shape,
|
||||
doc: /* Pointer shape indicating a top left x-window corner can be dragged.
|
||||
This variable takes effect when you create a new frame
|
||||
or when you set the mouse color. */);
|
||||
Vx_window_top_left_corner_shape = Qnil;
|
||||
|
||||
DEFVAR_LISP ("x-window-top-edge-cursor",
|
||||
Vx_window_top_edge_shape,
|
||||
doc: /* Pointer shape indicating a top x-window edge can be dragged.
|
||||
This variable takes effect when you create a new frame
|
||||
or when you set the mouse color. */);
|
||||
Vx_window_top_edge_shape = Qnil;
|
||||
|
||||
DEFVAR_LISP ("x-window-top-right-corner-cursor",
|
||||
Vx_window_top_right_corner_shape,
|
||||
doc: /* Pointer shape indicating a top right x-window corner can be dragged.
|
||||
This variable takes effect when you create a new frame
|
||||
or when you set the mouse color. */);
|
||||
Vx_window_top_right_corner_shape = Qnil;
|
||||
|
||||
DEFVAR_LISP ("x-window-right-edge-cursor",
|
||||
Vx_window_right_edge_shape,
|
||||
doc: /* Pointer shape indicating a right x-window edge can be dragged.
|
||||
This variable takes effect when you create a new frame
|
||||
or when you set the mouse color. */);
|
||||
Vx_window_right_edge_shape = Qnil;
|
||||
|
||||
DEFVAR_LISP ("x-window-bottom-right-corner-cursor",
|
||||
Vx_window_bottom_right_corner_shape,
|
||||
doc: /* Pointer shape indicating a bottom right x-window corner can be dragged.
|
||||
This variable takes effect when you create a new frame
|
||||
or when you set the mouse color. */);
|
||||
Vx_window_bottom_right_corner_shape = Qnil;
|
||||
|
||||
DEFVAR_LISP ("x-window-bottom-edge-cursor",
|
||||
Vx_window_bottom_edge_shape,
|
||||
doc: /* Pointer shape indicating a bottom x-window edge can be dragged.
|
||||
This variable takes effect when you create a new frame
|
||||
or when you set the mouse color. */);
|
||||
Vx_window_bottom_edge_shape = Qnil;
|
||||
|
||||
DEFVAR_LISP ("x-window-bottom-left-corner-cursor",
|
||||
Vx_window_bottom_left_corner_shape,
|
||||
doc: /* Pointer shape indicating a bottom left x-window corner can be dragged.
|
||||
This variable takes effect when you create a new frame
|
||||
or when you set the mouse color. */);
|
||||
Vx_window_bottom_left_corner_shape = Qnil;
|
||||
|
||||
DEFVAR_LISP ("x-cursor-fore-pixel", Vx_cursor_fore_pixel,
|
||||
doc: /* A string indicating the foreground color of the cursor box. */);
|
||||
Vx_cursor_fore_pixel = Qnil;
|
||||
|
|
|
|||
16
src/xterm.c
16
src/xterm.c
|
|
@ -11757,6 +11757,22 @@ x_free_frame_resources (struct frame *f)
|
|||
XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->horizontal_drag_cursor);
|
||||
if (f->output_data.x->vertical_drag_cursor != 0)
|
||||
XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->vertical_drag_cursor);
|
||||
if (f->output_data.x->left_edge_cursor != 0)
|
||||
XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->left_edge_cursor);
|
||||
if (f->output_data.x->top_left_corner_cursor != 0)
|
||||
XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->top_left_corner_cursor);
|
||||
if (f->output_data.x->top_edge_cursor != 0)
|
||||
XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->top_edge_cursor);
|
||||
if (f->output_data.x->top_right_corner_cursor != 0)
|
||||
XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->top_right_corner_cursor);
|
||||
if (f->output_data.x->right_edge_cursor != 0)
|
||||
XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->right_edge_cursor);
|
||||
if (f->output_data.x->bottom_right_corner_cursor != 0)
|
||||
XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->bottom_right_corner_cursor);
|
||||
if (f->output_data.x->bottom_edge_cursor != 0)
|
||||
XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->bottom_edge_cursor);
|
||||
if (f->output_data.x->bottom_left_corner_cursor != 0)
|
||||
XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->bottom_left_corner_cursor);
|
||||
|
||||
XFlush (FRAME_X_DISPLAY (f));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -637,6 +637,14 @@ struct x_output
|
|||
Cursor horizontal_drag_cursor;
|
||||
Cursor vertical_drag_cursor;
|
||||
Cursor current_cursor;
|
||||
Cursor left_edge_cursor;
|
||||
Cursor top_left_corner_cursor;
|
||||
Cursor top_edge_cursor;
|
||||
Cursor top_right_corner_cursor;
|
||||
Cursor right_edge_cursor;
|
||||
Cursor bottom_right_corner_cursor;
|
||||
Cursor bottom_edge_cursor;
|
||||
Cursor bottom_left_corner_cursor;
|
||||
|
||||
/* Window whose cursor is hourglass_cursor. This window is temporarily
|
||||
mapped to display an hourglass cursor. */
|
||||
|
|
|
|||
Loading…
Reference in a new issue