summaryrefslogtreecommitdiff
path: root/src/window.c
diff options
context:
space:
mode:
authorMartin Rudalics <rudalics@gmx.at>2019-03-11 09:57:23 +0100
committerMartin Rudalics <rudalics@gmx.at>2019-03-11 09:57:23 +0100
commit95373b69b34f9756d2f05b19798b763d22aa5f0a (patch)
treeffd55c71f1cccf34fc90aeb56dfeb4e78afb1915 /src/window.c
parent27466c62fdc977e8d3b23c5ae4f529a64ac7374f (diff)
downloademacs-95373b69b34f9756d2f05b19798b763d22aa5f0a.tar.gz
Rewrite minibuffer window resizing code
* src/frame.c (resize_mini_frames): New variable. * src/window.c (resize_mini_window_apply): New function. (grow_mini_window, shrink_mini_window): Remove PIXELWISE argument. Call resize_mini_window_apply to apply changes. (Fresize_mini_window_internal): Call resize_mini_window_apply to apply changes. (Qwindow__resize_mini_frame): New symbol. * src/window.h (grow_mini_window, shrink_mini_window): Adjust external declarations. * src/xdisp.c (resize_mini_window): For minibuffer-only frames call 'window--resize-mini-frame' if resize_mini_frames is non-nil. Offload parts of logic to grow_mini_window and shrink_mini_window which are now called without the PIXELWISE argument. (Vresize_mini_windows): Mention 'resize-mini-frames' in doc-string. * lisp/cus-start.el (resize-mini-frames): Add customization support. * lisp/window.el (window--resize-mini-window): Simplify code. (window--resize-mini-frame): New function. * doc/lispref/minibuf.texi (Minibuffer Windows): Describe new option 'resize-mini-frames'. * etc/NEWS: Mention new option 'resize-mini-frames'.
Diffstat (limited to 'src/window.c')
-rw-r--r--src/window.c180
1 files changed, 83 insertions, 97 deletions
diff --git a/src/window.c b/src/window.c
index c498ae81cdb..ae039b76add 100644
--- a/src/window.c
+++ b/src/window.c
@@ -5168,118 +5168,111 @@ Signal an error when WINDOW is the only window on its frame. */)
Resizing Mini-Windows
***********************************************************************/
-/* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we
- can. */
+/**
+ * resize_mini_window_apply:
+ *
+ * Assign new window sizes after resizing a mini window W by DELTA
+ * pixels. No error checking performed.
+ */
+static void
+resize_mini_window_apply (struct window *w, int delta)
+{
+ struct frame *f = XFRAME (w->frame);
+ Lisp_Object root = FRAME_ROOT_WINDOW (f);
+ struct window *r = XWINDOW (root);
+
+ block_input ();
+ w->pixel_height = w->pixel_height + delta;
+ w->total_lines = w->pixel_height / FRAME_LINE_HEIGHT (f);
+
+ window_resize_apply (r, false);
+
+ w->pixel_top = r->pixel_top + r->pixel_height;
+ w->top_line = r->top_line + r->total_lines;
+
+ /* Enforce full redisplay of the frame. */
+ /* FIXME: Shouldn't some of the caller do it? */
+ fset_redisplay (f);
+ adjust_frame_glyphs (f);
+ unblock_input ();
+}
+
+/**
+ * grow_mini_window:
+ *
+ * Grow mini-window W by DELTA pixels. If DELTA is negative, this may
+ * shrink the minibuffer window to the minimum height to display one
+ * line of text.
+ */
void
-grow_mini_window (struct window *w, int delta, bool pixelwise)
+grow_mini_window (struct window *w, int delta)
{
struct frame *f = XFRAME (w->frame);
- struct window *r;
- Lisp_Object root, height;
- int line_height, pixel_height;
+ int old_height = WINDOW_PIXEL_HEIGHT (w);
+ int min_height = FRAME_LINE_HEIGHT (f);
eassert (MINI_WINDOW_P (w));
- eassert (delta >= 0);
- if (delta > 0)
- {
- root = FRAME_ROOT_WINDOW (f);
- r = XWINDOW (root);
- height = call3 (Qwindow__resize_root_window_vertically,
- root, make_fixnum (- delta), pixelwise ? Qt : Qnil);
- if (FIXNUMP (height) && window_resize_check (r, false))
- {
- block_input ();
- window_resize_apply (r, false);
+ if (old_height + delta < min_height)
+ /* Never shrink mini-window to less than its minimum
+ height. */
+ delta = old_height > min_height ? min_height - old_height : 0;
- if (pixelwise)
- {
- pixel_height = min (-XFIXNUM (height), INT_MAX - w->pixel_height);
- line_height = pixel_height / FRAME_LINE_HEIGHT (f);
- }
- else
- {
- line_height = min (-XFIXNUM (height),
- ((INT_MAX - w->pixel_height)
- / FRAME_LINE_HEIGHT (f)));
- pixel_height = line_height * FRAME_LINE_HEIGHT (f);
- }
+ if (delta != 0)
+ {
+ Lisp_Object root = FRAME_ROOT_WINDOW (f);
+ struct window *r = XWINDOW (root);
+ Lisp_Object grow;
- /* Grow the mini-window. */
- w->pixel_top = r->pixel_top + r->pixel_height;
- w->top_line = r->top_line + r->total_lines;
- /* Make sure the mini-window has always at least one line. */
- w->pixel_height = max (w->pixel_height + pixel_height,
- FRAME_LINE_HEIGHT (f));
- w->total_lines = max (w->total_lines + line_height, 1);
-
- /* Enforce full redisplay of the frame. */
- /* FIXME: Shouldn't window--resize-root-window-vertically do it? */
- fset_redisplay (f);
- adjust_frame_glyphs (f);
- unblock_input ();
- }
- else
- error ("Failed to grow minibuffer window");
+ FRAME_WINDOWS_FROZEN (f) = true;
+ grow = call3 (Qwindow__resize_root_window_vertically,
+ root, make_fixnum (- delta), Qt);
+ if (FIXNUMP (grow) && window_resize_check (r, false))
+ resize_mini_window_apply (w, -XFIXNUM (grow));
}
}
-/* Shrink mini-window W to one line. */
+/**
+ * shrink_mini_window:
+ *
+ * Shrink mini-window W to the minimum height needed to display one
+ * line of text.
+ */
void
-shrink_mini_window (struct window *w, bool pixelwise)
+shrink_mini_window (struct window *w)
{
struct frame *f = XFRAME (w->frame);
- struct window *r;
- Lisp_Object root, delta;
- EMACS_INT height, unit;
+ int delta = WINDOW_PIXEL_HEIGHT (w) - FRAME_LINE_HEIGHT (f);
eassert (MINI_WINDOW_P (w));
- height = pixelwise ? w->pixel_height : w->total_lines;
- unit = pixelwise ? FRAME_LINE_HEIGHT (f) : 1;
- if (height > unit)
+ if (delta > 0)
{
- root = FRAME_ROOT_WINDOW (f);
- r = XWINDOW (root);
- delta = call3 (Qwindow__resize_root_window_vertically,
- root, make_fixnum (height - unit),
- pixelwise ? Qt : Qnil);
- if (FIXNUMP (delta) && window_resize_check (r, false))
- {
- block_input ();
- window_resize_apply (r, false);
-
- /* Shrink the mini-window. */
- w->top_line = r->top_line + r->total_lines;
- w->total_lines = 1;
- w->pixel_top = r->pixel_top + r->pixel_height;
- w->pixel_height = FRAME_LINE_HEIGHT (f);
- /* Enforce full redisplay of the frame. */
- /* FIXME: Shouldn't window--resize-root-window-vertically do it? */
- fset_redisplay (f);
- adjust_frame_glyphs (f);
- unblock_input ();
- }
- /* If the above failed for whatever strange reason we must make a
- one window frame here. The same routine will be needed when
- shrinking the frame (and probably when making the initial
- *scratch* window). For the moment leave things as they are. */
- else
- error ("Failed to shrink minibuffer window");
+ Lisp_Object root = FRAME_ROOT_WINDOW (f);
+ struct window *r = XWINDOW (root);
+ Lisp_Object grow;
+
+ FRAME_WINDOWS_FROZEN (f) = false;
+ grow = call3 (Qwindow__resize_root_window_vertically,
+ root, make_fixnum (delta), Qt);
+
+ if (FIXNUMP (grow) && window_resize_check (r, false))
+ resize_mini_window_apply (w, -XFIXNUM (grow));
}
}
-DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal, Sresize_mini_window_internal, 1, 1, 0,
- doc: /* Resize minibuffer window WINDOW. */)
+DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal,
+ Sresize_mini_window_internal, 1, 1, 0,
+ doc: /* Resize mini window WINDOW. */)
(Lisp_Object window)
{
struct window *w = XWINDOW (window);
struct window *r;
struct frame *f;
- int height;
+ int old_height, delta;
- CHECK_WINDOW (window);
+ CHECK_LIVE_WINDOW (window);
f = XFRAME (w->frame);
if (!EQ (FRAME_MINIBUF_WINDOW (XFRAME (w->frame)), window))
@@ -5288,26 +5281,18 @@ DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal, Sresize_mini
error ("Cannot resize a minibuffer-only frame");
r = XWINDOW (FRAME_ROOT_WINDOW (f));
- height = r->pixel_height + w->pixel_height;
+ old_height = r->pixel_height + w->pixel_height;
+ delta = XFIXNUM (w->new_pixel) - w->pixel_height;
if (window_resize_check (r, false)
&& XFIXNUM (w->new_pixel) > 0
- && height == XFIXNUM (r->new_pixel) + XFIXNUM (w->new_pixel))
+ && old_height == XFIXNUM (r->new_pixel) + XFIXNUM (w->new_pixel))
{
- block_input ();
- window_resize_apply (r, false);
-
- w->pixel_height = XFIXNAT (w->new_pixel);
- w->total_lines = w->pixel_height / FRAME_LINE_HEIGHT (f);
- w->pixel_top = r->pixel_top + r->pixel_height;
- w->top_line = r->top_line + r->total_lines;
+ resize_mini_window_apply (w, delta);
- fset_redisplay (f);
- adjust_frame_glyphs (f);
- unblock_input ();
return Qt;
}
else
- error ("Failed to resize minibuffer window");
+ error ("Cannot resize mini window");
}
/* Mark window cursors off for all windows in the window tree rooted
@@ -8047,6 +8032,7 @@ syms_of_window (void)
DEFSYM (Qwindow__resize_root_window, "window--resize-root-window");
DEFSYM (Qwindow__resize_root_window_vertically,
"window--resize-root-window-vertically");
+ DEFSYM (Qwindow__resize_mini_frame, "window--resize-mini-frame");
DEFSYM (Qwindow__sanitize_window_sizes, "window--sanitize-window-sizes");
DEFSYM (Qwindow__pixel_to_total, "window--pixel-to-total");
DEFSYM (Qsafe, "safe");