Commit 8e0ebb9a authored by Martin Rudalics's avatar Martin Rudalics

Handle persistence of windows' scroll bar and fringes settings (Bug#36193)

* doc/lispref/display.texi (Fringe Size/Pos): Document new
argument PERSISTENT of 'set-window-fringes'.
(Scroll Bars): Document new argument PERSISTENT of
'set-window-scroll-bars'.  Mention that HORIZONTAL-TYPE must
be 'bottom' to show a horizontal scroll bar on mini windows.
* lisp/window.el (window-min-pixel-height): For mini windows the
minimum height is one line.
(window--min-size-1): Use value returned by
'window-min-pixel-height' when dealing with mini windows.
(window--resize-mini-window): Try to handle horizontal scroll
bars and size restrictions more accurately.
(window--state-put-2): Handle persistence of scroll bar
settings.
* src/frame.c (make_frame): Allow horizontal scroll bars in
mini windows.
(adjust_frame_size): Drop PIXELWISE argument in
'resize_frame_windows' calls.
* src/window.c (set_window_buffer): Don't override WINDOW's
scroll bar and fringe settings when marked as persistent.
(resize_frame_windows): Drop fourth argument PIXELWISE - SIZE
is always specified in terms of pixels.  Try to handle height
of mini windows more accurately.
(grow_mini_window, shrink_mini_window): Use body height of
mini window when calculating expected height change.  Take
horizontal scroll bars into account.
(struct saved_window): Two new members to handle persistence
of window fringes and scroll bars.
(Fset_window_configuration, save_window_save): Handle
persistence of fringes and scroll bars.
(set_window_fringes, set_window_scroll_bars): New arguments
PERSISTENT.  Make dimension checks more accurate.
(Fset_window_fringes): New argument PERSISTENT.
(Fwindow_fringes, Fwindow_scroll_bars): Add PERSISTENT to
return values.
(Fset_window_scroll_bars): New argument PERSISTENT.  In
doc-string mention that 'bottom' must be specified to get a
horizontal scroll bar in mini windows.
(compare_window_configurations): Add checks for persistence of
fringes and scroll bars.
* src/window.h (struct window): New boolean slots
'fringes_persistent' and 'scroll_bars_persistent'.
(WINDOW_HAS_HORIZONTAL_SCROLL_BAR): Allow horizontal scroll bars
for mini windows.
(resize_frame_windows): Remove fourth argument of
'resize_frame_windows' in external declaration.
* src/xdisp.c (resize_mini_window): Use box text height to
tell whether mini window height changed.
(set_horizontal_scroll_bar): Set mini window's horizontal
scroll bar when its type is specified as 'bottom'.
* etc/NEWS: Mention new options for 'set-window-fringes' and
'set-window-scroll-bars'.
parent 5ccaee4b
Pipeline #2515 passed with stage
in 52 minutes and 12 seconds
......@@ -3959,7 +3959,7 @@ showing the buffer, unless you call @code{set-window-buffer} again in
each affected window. You can also use @code{set-window-fringes} to
control the fringe display in individual windows.
@defun set-window-fringes window left &optional right outside-margins
@defun set-window-fringes window left &optional right outside-margins persistent
This function sets the fringe widths of window @var{window}.
If @var{window} is @code{nil}, the selected window is used.
......@@ -3974,14 +3974,18 @@ desired width, this leaves the fringes of @var{window} unchanged.
The values specified here may be later overridden by invoking
@code{set-window-buffer} (@pxref{Buffers and Windows}) on @var{window}
with its @var{keep-margins} argument @code{nil} or omitted.
with its @var{keep-margins} argument @code{nil} or omitted. However,
if the optional fifth argument @var{persistent} is non-@code{nil} and
the other arguments are processed successfully, the values specified
here unconditionally survive subsequent invocations of
@code{set-window-buffer}.
@end defun
@defun window-fringes &optional window
This function returns information about the fringes of a window
@var{window}. If @var{window} is omitted or @code{nil}, the selected
window is used. The value has the form @code{(@var{left-width}
@var{right-width} @var{outside-margins})}.
@var{right-width} @var{outside-margins} @var{persistent})}.
@end defun
......@@ -4375,7 +4379,7 @@ This function returns the height of horizontal scroll bars of
You can override the frame specific settings for individual windows by
using the following function:
@defun set-window-scroll-bars window &optional width vertical-type height horizontal-type
@defun set-window-scroll-bars window &optional width vertical-type height horizontal-type persistent
This function sets the width and/or height and the types of scroll bars
for window @var{window}. If @var{window} is @code{nil}, the selected
window is used.
......@@ -4387,18 +4391,26 @@ if so, where. The possible values are @code{left}, @code{right},
@code{t}, which means to use the frame's default, and @code{nil} for no
vertical scroll bar.
@var{height} specifies the height of the horizontal scroll bar in pixels
(@code{nil} means use the height specified for the frame).
@var{horizontal-type} specifies whether to have a horizontal scroll bar.
The possible values are @code{bottom}, @code{t}, which means to use the
frame's default, and @code{nil} for no horizontal scroll bar.
@var{height} specifies the height of the horizontal scroll bar in
pixels (@code{nil} means use the height specified for the frame).
@var{horizontal-type} specifies whether to have a horizontal scroll
bar. The possible values are @code{bottom}, @code{t}, which means to
use the frame's default, and @code{nil} for no horizontal scroll bar.
Note that for a mini window the value @code{t} has the same meaning as
@code{nil}, namely to not show a horizontal scroll bar. You have to
explicitly specify @code{bottom} in order to show a horizontal scroll
bar in a mini window.
If @var{window} is not large enough to accommodate a scroll bar of the
desired dimension, this leaves the corresponding scroll bar unchanged.
The values specified here may be later overridden by invoking
@code{set-window-buffer} (@pxref{Buffers and Windows}) on @var{window}
with its @var{keep-margins} argument @code{nil} or omitted.
with its @var{keep-margins} argument @code{nil} or omitted. However,
if the optional fifth argument @var{persistent} is non-@code{nil} and
the other arguments are processed successfully, the values specified
here unconditionally survive subsequent invocations of
@code{set-window-buffer}.
@end defun
The following four functions take as argument a live window which
......@@ -4407,7 +4419,7 @@ defaults to the selected one.
@defun window-scroll-bars &optional window
This function returns a list of the form @code{(@var{width}
@var{columns} @var{vertical-type} @var{height} @var{lines}
@var{horizontal-type})}.
@var{horizontal-type} @var{persistent})}.
The value @var{width} is the value that was specified for the width of
the vertical scroll bar (which may be @code{nil}); @var{columns} is the
......@@ -4418,6 +4430,10 @@ The value @var{height} is the value that was specified for the height of
the horizontal scroll bar (which may be @code{nil}); @var{lines} is the
(possibly rounded) number of lines that the horizontally scroll bar
actually occupies.
The value of @var{persistent} is the value specified for @var{window}
with the last successful invocation of @code{set-window-scroll-bars},
@code{nil} if there never was one.
@end defun
@defun window-current-scroll-bars &optional window
......@@ -4438,7 +4454,7 @@ This function returns the height in pixels of @var{window}'s horizontal
scrollbar.
@end defun
If you don't specify these values for a window with
If you do not specify a window's scroll bar settings via
@code{set-window-scroll-bars}, the buffer-local variables
@code{vertical-scroll-bar}, @code{horizontal-scroll-bar},
@code{scroll-bar-width} and @code{scroll-bar-height} in the buffer being
......
......@@ -2075,6 +2075,12 @@ return the total and body sizes of any window during last redisplay.
See the section "(elisp) Window Hooks" in the Elisp manual for a
detailed explanation of the new behavior.
+++
** Making scroll bar and fringe settings persistent for windows.
The functions 'set-window-scroll-bars' and 'set-window-fringes' now
have a new optional argument that makes the settings they produce
reliably survive subsequent invocations of 'set-window-buffer'.
+++
** New option 'resize-mini-frames'.
This option allows to automatically resize minibuffer-only frames
......
......@@ -434,7 +434,8 @@ shorter, explicitly specify the SIZE argument of that function."
(defun window-min-pixel-height (&optional window)
"Return the minimum pixel height of window WINDOW."
(* (max window-min-height window-safe-min-height)
(* (max (if (window-minibuffer-p window) 1 window-min-height)
window-safe-min-height)
(frame-char-size window)))
;; This must go to C, finally (or get removed).
......@@ -1603,8 +1604,6 @@ return the minimum pixel-size of WINDOW."
value)
(with-current-buffer (window-buffer window)
(cond
((window-minibuffer-p window)
(if pixelwise (frame-char-height (window-frame window)) 1))
((window-size-fixed-p window horizontal ignore)
;; The minimum size of a fixed size window is its size.
(window-size window horizontal pixelwise))
......@@ -2739,30 +2738,32 @@ windows."
(when (window-right window)
(window--resize-reset-1 (window-right window) horizontal)))
;; The following is the internal function used when resizing mini
;; windows "manually", for example, when dragging a divider between
;; root and mini window. The routines for automatic minibuffer window
;; resizing call `window--resize-root-window-vertically' instead.
(defun window--resize-mini-window (window delta)
"Resize minibuffer window WINDOW by DELTA pixels.
"Change height of mini window WINDOW by DELTA pixels.
If WINDOW cannot be resized by DELTA pixels make it as large (or
as small) as possible, but don't signal an error."
(when (window-minibuffer-p window)
(let* ((frame (window-frame window))
(root (frame-root-window frame))
(height (window-pixel-height window))
(min-delta
(- (window-pixel-height root)
(window-min-size root nil nil t))))
;; Sanitize DELTA.
(cond
((<= (+ height delta) 0)
(setq delta (- (frame-char-height frame) height)))
((> delta min-delta)
(setq delta min-delta)))
(min-height (+ (frame-char-height frame)
(- (window-pixel-height window)
(window-body-height window t))))
(max-delta (- (window-pixel-height root)
(window-min-size root nil nil t))))
;; Don't make mini window too small.
(when (< (+ height delta) min-height)
(setq delta (- min-height height)))
;; Don't make root window too small.
(when (> delta max-delta)
(setq delta max-delta))
(unless (zerop delta)
;; Resize now.
(window--resize-reset frame)
;; Ideally we should be able to resize just the last child of root
;; here. See the comment in `resize-root-window-vertically' for
;; why we do not do that.
(window--resize-this-window root (- delta) nil nil t)
(set-window-new-pixel window (+ height delta))
;; The following routine catches the case where we want to resize
......@@ -5881,7 +5882,7 @@ value can be also stored on disk and read back in a new session."
(let ((scroll-bars (cdr (assq 'scroll-bars state))))
(set-window-scroll-bars
window (car scroll-bars) (nth 2 scroll-bars)
(nth 3 scroll-bars) (nth 5 scroll-bars)))
(nth 3 scroll-bars) (nth 5 scroll-bars) (nth 6 scroll-bars)))
(set-window-vscroll window (cdr (assq 'vscroll state)))
;; Adjust vertically.
(if (or (memq window-size-fixed '(t height))
......@@ -8497,7 +8498,7 @@ parameters of FRAME."
(if parent
(frame-native-height parent)
(- (nth 3 geometry) (nth 1 geometry))))
;; FRAME'S parent or workarea sizes. Used when no margins
;; FRAME's parent or workarea sizes. Used when no margins
;; are specified.
(parent-or-workarea
(if parent
......
......@@ -712,7 +712,7 @@ adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit,
if (new_windows_width != old_windows_width)
{
resize_frame_windows (f, new_windows_width, 1, 1);
resize_frame_windows (f, new_windows_width, true);
/* MSDOS frames cannot PRETEND, as they change frame size by
manipulating video hardware. */
......@@ -737,7 +737,7 @@ adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit,
left edges. */
|| WINDOW_TOP_PIXEL_EDGE (r) != FRAME_TOP_MARGIN_HEIGHT (f))
{
resize_frame_windows (f, new_windows_height, 0, 1);
resize_frame_windows (f, new_windows_height, false);
/* MSDOS frames cannot PRETEND, as they change frame size by
manipulating video hardware. */
......@@ -931,15 +931,11 @@ make_frame (bool mini_p)
}
if (mini_p)
{
set_window_buffer (mini_window,
(NILP (Vminibuffer_list)
? get_minibuffer (0)
: Fcar (Vminibuffer_list)),
0, 0);
/* No horizontal scroll bars in minibuffers. */
wset_horizontal_scroll_bar (mw, Qnil);
}
set_window_buffer (mini_window,
(NILP (Vminibuffer_list)
? get_minibuffer (0)
: Fcar (Vminibuffer_list)),
0, 0);
fset_root_window (f, root_window);
fset_selected_window (f, root_window);
......
This diff is collapsed.
......@@ -422,6 +422,14 @@ struct window
Otherwise draw them between margin areas and text. */
bool_bf fringes_outside_margins : 1;
/* True if this window's fringe specifications are persistent,
i.e., always survive Fset_window_buffer. */
bool_bf fringes_persistent : 1;
/* True if this window's croll bar specifications are persistent,
i.e., always survive Fset_window_buffer. */
bool_bf scroll_bars_persistent : 1;
/* True if window_end_pos and window_end_vpos are truly valid.
This is false if nontrivial redisplay is preempted since in that case
the frame image that window_end_pos did not get onto the frame. */
......@@ -860,7 +868,9 @@ wset_next_buffers (struct window *w, Lisp_Object val)
W. Horizontal scrollbars exist for toolkit versions only. */
#if USE_HORIZONTAL_SCROLL_BARS
#define WINDOW_HAS_HORIZONTAL_SCROLL_BAR(W) \
((WINDOW_PSEUDO_P (W) || MINI_NON_ONLY_WINDOW_P (W)) \
((WINDOW_PSEUDO_P (W) \
|| (MINI_WINDOW_P (W) \
&& !EQ (W->horizontal_scroll_bar_type, Qbottom))) \
? false \
: EQ (W->horizontal_scroll_bar_type, Qt) \
? FRAME_HAS_HORIZONTAL_SCROLL_BARS (WINDOW_XFRAME (W)) \
......@@ -1059,7 +1069,7 @@ extern Lisp_Object minibuf_selected_window;
extern Lisp_Object make_window (void);
extern Lisp_Object window_from_coordinates (struct frame *, int, int,
enum window_part *, bool);
extern void resize_frame_windows (struct frame *, int, bool, bool);
extern void resize_frame_windows (struct frame *, int, bool);
extern void restore_window_configuration (Lisp_Object);
extern void delete_all_child_windows (Lisp_Object);
extern void grow_mini_window (struct window *, int);
......
......@@ -11368,7 +11368,7 @@ bool
resize_mini_window (struct window *w, bool exact_p)
{
struct frame *f = XFRAME (w->frame);
int old_height = WINDOW_PIXEL_HEIGHT (w);
int old_height = WINDOW_BOX_TEXT_HEIGHT (w);
eassert (MINI_WINDOW_P (w));
......@@ -11400,7 +11400,6 @@ resize_mini_window (struct window *w, bool exact_p)
else
{
struct it it;
int old_height = WINDOW_PIXEL_HEIGHT (w);
int unit = FRAME_LINE_HEIGHT (f);
int height, max_height;
struct text_pos start;
......@@ -11470,7 +11469,7 @@ resize_mini_window (struct window *w, bool exact_p)
set_buffer_internal (old_current_buffer);
}
return WINDOW_PIXEL_HEIGHT (w) != old_height;
return WINDOW_BOX_TEXT_HEIGHT (w) != old_height;
}
......@@ -16679,9 +16678,7 @@ set_horizontal_scroll_bar (struct window *w)
{
int start, end, whole, portion;
if (!MINI_WINDOW_P (w)
|| (w == XWINDOW (minibuf_window)
&& NILP (echo_area_buffer[0])))
if (!MINI_WINDOW_P (w) || EQ (w->horizontal_scroll_bar_type, Qbottom))
{
struct buffer *b = XBUFFER (w->contents);
struct buffer *old_buffer = NULL;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment