Commit 1886246f authored by Martin Rudalics's avatar Martin Rudalics

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.
parent 43147137
......@@ -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.
......
This diff is collapsed.
......@@ -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
......
This diff is collapsed.
......@@ -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."
......
This diff is collapsed.
......@@ -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))
......
This diff is collapsed.
......@@ -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))
......
This diff is collapsed.
......@@ -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);
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 = Qnil;
window_or_frame = Qnil;
return Fcons (window,
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.
......
......@@ -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;
......
......@@ -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;