aboutsummaryrefslogtreecommitdiffstats
path: root/src/window.c
diff options
context:
space:
mode:
authorMartin Rudalics2019-07-22 09:19:18 +0200
committerMartin Rudalics2019-07-22 09:19:18 +0200
commit8e0ebb9a3cb9beef2f5ff50436fef1c54a3e3c92 (patch)
treeacabc59171db5611552b1a45aeea2149beefe689 /src/window.c
parent5ccaee4bbc184c53b262021361bd216af17e80f5 (diff)
downloademacs-8e0ebb9a3cb9beef2f5ff50436fef1c54a3e3c92.tar.gz
emacs-8e0ebb9a3cb9beef2f5ff50436fef1c54a3e3c92.zip
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'.
Diffstat (limited to 'src/window.c')
-rw-r--r--src/window.c432
1 files changed, 231 insertions, 201 deletions
diff --git a/src/window.c b/src/window.c
index 1b205367275..9a0a9a115c2 100644
--- a/src/window.c
+++ b/src/window.c
@@ -59,12 +59,13 @@ static void select_window_1 (Lisp_Object, bool);
59static void run_window_configuration_change_hook (struct frame *); 59static void run_window_configuration_change_hook (struct frame *);
60 60
61static struct window *set_window_fringes (struct window *, Lisp_Object, 61static struct window *set_window_fringes (struct window *, Lisp_Object,
62 Lisp_Object, Lisp_Object); 62 Lisp_Object, Lisp_Object,
63 Lisp_Object);
63static struct window *set_window_margins (struct window *, Lisp_Object, 64static struct window *set_window_margins (struct window *, Lisp_Object,
64 Lisp_Object); 65 Lisp_Object);
65static struct window *set_window_scroll_bars (struct window *, Lisp_Object, 66static struct window *set_window_scroll_bars (struct window *, Lisp_Object,
66 Lisp_Object, Lisp_Object, 67 Lisp_Object, Lisp_Object,
67 Lisp_Object); 68 Lisp_Object, Lisp_Object);
68static void apply_window_adjustment (struct window *); 69static void apply_window_adjustment (struct window *);
69 70
70/* This is the window in which the terminal's cursor should 71/* This is the window in which the terminal's cursor should
@@ -3983,14 +3984,18 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer,
3983 3984
3984 if (!keep_margins_p) 3985 if (!keep_margins_p)
3985 { 3986 {
3986 /* Set left and right marginal area width etc. from buffer. */ 3987 /* Set fringes and scroll bars from buffer unless they have been
3987 set_window_fringes (w, BVAR (b, left_fringe_width), 3988 declared as persistent. */
3988 BVAR (b, right_fringe_width), 3989 if (!w->fringes_persistent)
3989 BVAR (b, fringes_outside_margins)); 3990 set_window_fringes (w, BVAR (b, left_fringe_width),
3990 set_window_scroll_bars (w, BVAR (b, scroll_bar_width), 3991 BVAR (b, right_fringe_width),
3991 BVAR (b, vertical_scroll_bar_type), 3992 BVAR (b, fringes_outside_margins), Qnil);
3992 BVAR (b, scroll_bar_height), 3993 if (!w->scroll_bars_persistent)
3993 BVAR (b, horizontal_scroll_bar_type)); 3994 set_window_scroll_bars (w, BVAR (b, scroll_bar_width),
3995 BVAR (b, vertical_scroll_bar_type),
3996 BVAR (b, scroll_bar_height),
3997 BVAR (b, horizontal_scroll_bar_type), Qnil);
3998 /* Set left and right marginal area width from buffer. */
3994 set_window_margins (w, BVAR (b, left_margin_cols), 3999 set_window_margins (w, BVAR (b, left_margin_cols),
3995 BVAR (b, right_margin_cols)); 4000 BVAR (b, right_margin_cols));
3996 apply_window_adjustment (w); 4001 apply_window_adjustment (w);
@@ -4661,78 +4666,49 @@ values. */)
4661} 4666}
4662 4667
4663 4668
4664/* Resize frame F's windows when F's width or height is set to SIZE. 4669/**
4665 If HORFLAG is zero, F's width was set to SIZE, otherwise its height 4670Resize frame F's windows when F's inner height (inner width if HORFLAG
4666 was set. SIZE is interpreted in F's canonical character units 4671is true) has been set to SIZE pixels. */
4667 (a.k.a. "columns" or "lines"), unless PIXELWISE is non-zero, which
4668 means to interpret SIZE in pixel units. */
4669void 4672void
4670resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise) 4673resize_frame_windows (struct frame *f, int size, bool horflag)
4671{ 4674{
4672 Lisp_Object root = f->root_window; 4675 Lisp_Object root = f->root_window;
4673 struct window *r = XWINDOW (root); 4676 struct window *r = XWINDOW (root);
4674 Lisp_Object mini = f->minibuffer_window;
4675 struct window *m;
4676 /* old_size is the old size of the frame's root window. */
4677 int old_size = horflag ? r->total_cols : r->total_lines;
4678 int old_pixel_size = horflag ? r->pixel_width : r->pixel_height; 4677 int old_pixel_size = horflag ? r->pixel_width : r->pixel_height;
4679 /* new_size is the new size of the frame's root window. */
4680 int new_size, new_pixel_size; 4678 int new_size, new_pixel_size;
4681 int unit = horflag ? FRAME_COLUMN_WIDTH (f) : FRAME_LINE_HEIGHT (f); 4679 int unit = horflag ? FRAME_COLUMN_WIDTH (f) : FRAME_LINE_HEIGHT (f);
4680 Lisp_Object mini = f->minibuffer_window;
4681 struct window *m = WINDOWP (mini) ? XWINDOW (mini) : NULL;
4682 int mini_height = ((FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
4683 ? unit + m->pixel_height - window_body_height (m, true)
4684 : 0);
4682 4685
4683 /* Don't let the size drop below one unit. This is more comforting 4686 new_pixel_size = max (horflag ? size : size - mini_height, unit);
4684 when we are called from *_set_tool_bar_lines since the latter may 4687 new_size = new_pixel_size / unit;
4685 have implicitly given us a zero or negative height. */
4686 if (pixelwise)
4687 {
4688 /* Note: This does not include the size for internal borders
4689 since these are not part of the frame's text area. */
4690 new_pixel_size = max (horflag
4691 ? size
4692 : (size
4693 - ((FRAME_HAS_MINIBUF_P (f)
4694 && !FRAME_MINIBUF_ONLY_P (f))
4695 ? FRAME_LINE_HEIGHT (f) : 0)),
4696 unit);
4697 new_size = new_pixel_size / unit;
4698 }
4699 else
4700 {
4701 new_size = max (size - (!horflag
4702 && FRAME_HAS_MINIBUF_P (f)
4703 && !FRAME_MINIBUF_ONLY_P (f)),
4704 1);
4705 new_pixel_size = new_size * unit;
4706 }
4707 4688
4708 if (new_pixel_size == old_pixel_size 4689 if (new_pixel_size == old_pixel_size
4709 && (horflag || r->pixel_top == FRAME_TOP_MARGIN_HEIGHT (f))) 4690 && (horflag || r->pixel_top == FRAME_TOP_MARGIN_HEIGHT (f)))
4710 ; 4691 ;
4711 else if (WINDOW_LEAF_P (r)) 4692 else if (WINDOW_LEAF_P (r))
4712 /* For a leaf root window just set the size. */ 4693 {
4713 if (horflag) 4694 /* For a leaf root window just set the size. */
4714 { 4695 if (horflag)
4715 bool changed = r->pixel_width != new_pixel_size; 4696 {
4716 4697 r->total_cols = new_size;
4717 r->total_cols = new_size; 4698 r->pixel_width = new_pixel_size;
4718 r->pixel_width = new_pixel_size; 4699 }
4719 4700 else
4720 if (changed && !WINDOW_PSEUDO_P (r)) 4701 {
4721 FRAME_WINDOW_CHANGE (f) = true; 4702 r->top_line = FRAME_TOP_MARGIN (f);
4722 } 4703 r->pixel_top = FRAME_TOP_MARGIN_HEIGHT (f);
4723 else
4724 {
4725 bool changed = r->pixel_height != new_pixel_size;
4726
4727 r->top_line = FRAME_TOP_MARGIN (f);
4728 r->pixel_top = FRAME_TOP_MARGIN_HEIGHT (f);
4729 4704
4730 r->total_lines = new_size; 4705 r->total_lines = new_size;
4731 r->pixel_height = new_pixel_size; 4706 r->pixel_height = new_pixel_size;
4707 }
4732 4708
4733 if (changed && !WINDOW_PSEUDO_P (r)) 4709 FRAME_WINDOW_CHANGE (f)
4734 FRAME_WINDOW_CHANGE (f) = true; 4710 = !WINDOW_PSEUDO_P (r) && new_pixel_size != old_pixel_size;
4735 } 4711 }
4736 else 4712 else
4737 { 4713 {
4738 Lisp_Object delta; 4714 Lisp_Object delta;
@@ -4743,14 +4719,10 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
4743 r->pixel_top = FRAME_TOP_MARGIN_HEIGHT (f); 4719 r->pixel_top = FRAME_TOP_MARGIN_HEIGHT (f);
4744 } 4720 }
4745 4721
4746 if (pixelwise) 4722 XSETINT (delta, new_pixel_size - old_pixel_size);
4747 XSETINT (delta, new_pixel_size - old_pixel_size);
4748 else
4749 XSETINT (delta, new_size - old_size);
4750 4723
4751 /* Try a "normal" resize first. */ 4724 /* Try a "normal" resize first. */
4752 resize_root_window (root, delta, horflag ? Qt : Qnil, Qnil, 4725 resize_root_window (root, delta, horflag ? Qt : Qnil, Qnil, Qt);
4753 pixelwise ? Qt : Qnil);
4754 if (window_resize_check (r, horflag) 4726 if (window_resize_check (r, horflag)
4755 && new_pixel_size == XFIXNUM (r->new_pixel)) 4727 && new_pixel_size == XFIXNUM (r->new_pixel))
4756 { 4728 {
@@ -4760,8 +4732,7 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
4760 else 4732 else
4761 { 4733 {
4762 /* Try with "reasonable" minimum sizes next. */ 4734 /* Try with "reasonable" minimum sizes next. */
4763 resize_root_window (root, delta, horflag ? Qt : Qnil, Qt, 4735 resize_root_window (root, delta, horflag ? Qt : Qnil, Qt, Qt);
4764 pixelwise ? Qt : Qnil);
4765 if (window_resize_check (r, horflag) 4736 if (window_resize_check (r, horflag)
4766 && new_pixel_size == XFIXNUM (r->new_pixel)) 4737 && new_pixel_size == XFIXNUM (r->new_pixel))
4767 { 4738 {
@@ -4781,9 +4752,8 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
4781 } 4752 }
4782 else 4753 else
4783 { 4754 {
4784 /* Are we sure we always want 1 line here? */ 4755 m->total_lines = mini_height / unit;
4785 m->total_lines = 1; 4756 m->pixel_height = mini_height;
4786 m->pixel_height = FRAME_LINE_HEIGHT (f);
4787 m->top_line = r->top_line + r->total_lines; 4757 m->top_line = r->top_line + r->total_lines;
4788 m->pixel_top = r->pixel_top + r->pixel_height; 4758 m->pixel_top = r->pixel_top + r->pixel_height;
4789 } 4759 }
@@ -5211,17 +5181,11 @@ void
5211grow_mini_window (struct window *w, int delta) 5181grow_mini_window (struct window *w, int delta)
5212{ 5182{
5213 struct frame *f = XFRAME (w->frame); 5183 struct frame *f = XFRAME (w->frame);
5214 int old_height = WINDOW_PIXEL_HEIGHT (w); 5184 int old_height = window_body_height (w, true);
5215 int min_height = FRAME_LINE_HEIGHT (f);
5216 5185
5217 eassert (MINI_WINDOW_P (w)); 5186 eassert (MINI_WINDOW_P (w));
5218 5187
5219 if (old_height + delta < min_height) 5188 if ((delta != 0) && (old_height + delta >= FRAME_LINE_HEIGHT (f)))
5220 /* Never shrink mini-window to less than its minimum
5221 height. */
5222 delta = old_height > min_height ? min_height - old_height : 0;
5223
5224 if (delta != 0)
5225 { 5189 {
5226 Lisp_Object root = FRAME_ROOT_WINDOW (f); 5190 Lisp_Object root = FRAME_ROOT_WINDOW (f);
5227 struct window *r = XWINDOW (root); 5191 struct window *r = XWINDOW (root);
@@ -5246,7 +5210,7 @@ void
5246shrink_mini_window (struct window *w) 5210shrink_mini_window (struct window *w)
5247{ 5211{
5248 struct frame *f = XFRAME (w->frame); 5212 struct frame *f = XFRAME (w->frame);
5249 int delta = WINDOW_PIXEL_HEIGHT (w) - FRAME_LINE_HEIGHT (f); 5213 int delta = window_body_height (w, true) - FRAME_LINE_HEIGHT (f);
5250 5214
5251 eassert (MINI_WINDOW_P (w)); 5215 eassert (MINI_WINDOW_P (w));
5252 5216
@@ -5263,6 +5227,11 @@ shrink_mini_window (struct window *w)
5263 if (FIXNUMP (grow) && window_resize_check (r, false)) 5227 if (FIXNUMP (grow) && window_resize_check (r, false))
5264 resize_mini_window_apply (w, -XFIXNUM (grow)); 5228 resize_mini_window_apply (w, -XFIXNUM (grow));
5265 } 5229 }
5230 else if (delta < 0)
5231 /* delta can be less than zero after adding horizontal scroll
5232 bar. */
5233 grow_mini_window (w, -delta);
5234
5266} 5235}
5267 5236
5268DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal, 5237DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal,
@@ -6740,9 +6709,11 @@ struct saved_window
6740 Lisp_Object start_at_line_beg; 6709 Lisp_Object start_at_line_beg;
6741 Lisp_Object display_table; 6710 Lisp_Object display_table;
6742 Lisp_Object left_margin_cols, right_margin_cols; 6711 Lisp_Object left_margin_cols, right_margin_cols;
6743 Lisp_Object left_fringe_width, right_fringe_width, fringes_outside_margins; 6712 Lisp_Object left_fringe_width, right_fringe_width;
6744 Lisp_Object scroll_bar_width, vertical_scroll_bar_type, dedicated; 6713 Lisp_Object fringes_outside_margins, fringes_persistent;
6714 Lisp_Object scroll_bar_width, vertical_scroll_bar_type;
6745 Lisp_Object scroll_bar_height, horizontal_scroll_bar_type; 6715 Lisp_Object scroll_bar_height, horizontal_scroll_bar_type;
6716 Lisp_Object scroll_bars_persistent, dedicated;
6746 Lisp_Object combination_limit, window_parameters; 6717 Lisp_Object combination_limit, window_parameters;
6747}; 6718};
6748 6719
@@ -6957,8 +6928,10 @@ the return value is nil. Otherwise the value is t. */)
6957 w->left_fringe_width = XFIXNUM (p->left_fringe_width); 6928 w->left_fringe_width = XFIXNUM (p->left_fringe_width);
6958 w->right_fringe_width = XFIXNUM (p->right_fringe_width); 6929 w->right_fringe_width = XFIXNUM (p->right_fringe_width);
6959 w->fringes_outside_margins = !NILP (p->fringes_outside_margins); 6930 w->fringes_outside_margins = !NILP (p->fringes_outside_margins);
6931 w->fringes_persistent = !NILP (p->fringes_persistent);
6960 w->scroll_bar_width = XFIXNUM (p->scroll_bar_width); 6932 w->scroll_bar_width = XFIXNUM (p->scroll_bar_width);
6961 w->scroll_bar_height = XFIXNUM (p->scroll_bar_height); 6933 w->scroll_bar_height = XFIXNUM (p->scroll_bar_height);
6934 w->scroll_bars_persistent = !NILP (p->scroll_bars_persistent);
6962 wset_vertical_scroll_bar_type (w, p->vertical_scroll_bar_type); 6935 wset_vertical_scroll_bar_type (w, p->vertical_scroll_bar_type);
6963 wset_horizontal_scroll_bar_type (w, p->horizontal_scroll_bar_type); 6936 wset_horizontal_scroll_bar_type (w, p->horizontal_scroll_bar_type);
6964 wset_dedicated (w, p->dedicated); 6937 wset_dedicated (w, p->dedicated);
@@ -7279,8 +7252,10 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, ptrdiff_t i)
7279 p->left_fringe_width = make_fixnum (w->left_fringe_width); 7252 p->left_fringe_width = make_fixnum (w->left_fringe_width);
7280 p->right_fringe_width = make_fixnum (w->right_fringe_width); 7253 p->right_fringe_width = make_fixnum (w->right_fringe_width);
7281 p->fringes_outside_margins = w->fringes_outside_margins ? Qt : Qnil; 7254 p->fringes_outside_margins = w->fringes_outside_margins ? Qt : Qnil;
7255 p->fringes_persistent = w->fringes_persistent ? Qt : Qnil;
7282 p->scroll_bar_width = make_fixnum (w->scroll_bar_width); 7256 p->scroll_bar_width = make_fixnum (w->scroll_bar_width);
7283 p->scroll_bar_height = make_fixnum (w->scroll_bar_height); 7257 p->scroll_bar_height = make_fixnum (w->scroll_bar_height);
7258 p->scroll_bars_persistent = w->scroll_bars_persistent ? Qt : Qnil;
7284 p->vertical_scroll_bar_type = w->vertical_scroll_bar_type; 7259 p->vertical_scroll_bar_type = w->vertical_scroll_bar_type;
7285 p->horizontal_scroll_bar_type = w->horizontal_scroll_bar_type; 7260 p->horizontal_scroll_bar_type = w->horizontal_scroll_bar_type;
7286 p->dedicated = w->dedicated; 7261 p->dedicated = w->dedicated;
@@ -7516,49 +7491,71 @@ as nil. */)
7516 ***********************************************************************/ 7491 ***********************************************************************/
7517 7492
7518static struct window * 7493static struct window *
7519set_window_fringes (struct window *w, Lisp_Object left_width, 7494set_window_fringes (struct window *w,
7520 Lisp_Object right_width, Lisp_Object outside_margins) 7495 Lisp_Object left_width, Lisp_Object right_width,
7496 Lisp_Object outside_margins, Lisp_Object persistent)
7521{ 7497{
7522 bool outside = !NILP (outside_margins); 7498 /* Do nothing on a tty. */
7523 int left = extract_dimension (left_width); 7499 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w)))
7524 int right = extract_dimension (right_width); 7500 return NULL;
7525 7501 else
7526 /* Do nothing on a tty or if nothing to actually change. */
7527 if (FRAME_WINDOW_P (WINDOW_XFRAME (w))
7528 && (w->left_fringe_width != left
7529 || w->right_fringe_width != right
7530 || w->fringes_outside_margins != outside))
7531 { 7502 {
7532 if (left > 0 || right > 0) 7503 struct frame *f = XFRAME (WINDOW_FRAME (w));
7504 int old_left = WINDOW_LEFT_FRINGE_WIDTH (w);
7505 int old_right = WINDOW_RIGHT_FRINGE_WIDTH (w);
7506 int new_left = extract_dimension (left_width);
7507 int new_right = extract_dimension (right_width);
7508 bool outside = !NILP (outside_margins);
7509 bool changed = false;
7510 bool failed = false;
7511
7512 /* Check dimensions of new fringes. Make changes only if they
7513 fit the window's dimensions. */
7514 if ((WINDOW_PIXEL_WIDTH (w)
7515 - WINDOW_MARGINS_WIDTH (w)
7516 - WINDOW_SCROLL_BAR_AREA_WIDTH (w)
7517 - WINDOW_RIGHT_DIVIDER_WIDTH (w)
7518 - (new_left == -1 ? FRAME_LEFT_FRINGE_WIDTH (f) : new_left)
7519 - (new_right == -1 ? FRAME_RIGHT_FRINGE_WIDTH (f) : new_right))
7520 >= MIN_SAFE_WINDOW_PIXEL_WIDTH (w))
7521 {
7522 w->left_fringe_width = new_left;
7523 w->right_fringe_width = new_right;
7524 changed = new_left != old_left || new_right != old_right;
7525 }
7526 else
7527 failed = true;
7528
7529 /* Placing fringes ouside margins. */
7530 if (outside != w->fringes_outside_margins)
7533 { 7531 {
7534 /* Don't change anything if new fringes don't fit. */ 7532 w->fringes_outside_margins = outside;
7535 if ((WINDOW_PIXEL_WIDTH (w) 7533 changed = true;
7536 - WINDOW_MARGINS_WIDTH (w)
7537 - WINDOW_SCROLL_BAR_AREA_WIDTH (w)
7538 - max (left, 0) - max (right, 0))
7539 < MIN_SAFE_WINDOW_PIXEL_WIDTH (w))
7540 return NULL;
7541 } 7534 }
7542 7535
7543 w->left_fringe_width = left; 7536 /* Make settings persistent unless we failed to apply some
7544 w->right_fringe_width = right; 7537 changes. */
7545 w->fringes_outside_margins = outside; 7538 if (!failed)
7539 w->fringes_persistent = !NILP (persistent);
7546 7540
7547 /* This is needed to trigger immediate redisplay of the window 7541 /* This is needed to trigger immediate redisplay of the window
7548 when its fringes are changed, because fringes are redrawn 7542 when its fringes are changed, because fringes are redrawn
7549 only if update_window is called, so we must trigger that even 7543 only if update_window is called, so we must trigger that even
7550 if the window's glyph matrices did not change at all. */ 7544 if the window's glyph matrices did not change at all. */
7551 windows_or_buffers_changed = 35; 7545 if (changed)
7552 return w; 7546 {
7547 windows_or_buffers_changed = 35;
7548 return w;
7549 }
7550 else
7551 return NULL;
7553 } 7552 }
7554 else
7555 return NULL;
7556} 7553}
7557 7554
7558DEFUN ("set-window-fringes", Fset_window_fringes, Sset_window_fringes, 7555DEFUN ("set-window-fringes", Fset_window_fringes, Sset_window_fringes,
7559 2, 4, 0, 7556 2, 5, 0,
7560 doc: /* Set the fringe widths of window WINDOW. 7557 doc: /* Set fringes of specified WINDOW.
7561WINDOW must be a live window and defaults to the selected one. 7558WINDOW must specify a live window and defaults to the selected one.
7562 7559
7563Second arg LEFT-WIDTH specifies the number of pixels to reserve for 7560Second arg LEFT-WIDTH specifies the number of pixels to reserve for
7564the left fringe. Optional third arg RIGHT-WIDTH specifies the right 7561the left fringe. Optional third arg RIGHT-WIDTH specifies the right
@@ -7570,32 +7567,40 @@ If optional fourth arg OUTSIDE-MARGINS is non-nil, draw the fringes
7570outside of the display margins. By default, fringes are drawn between 7567outside of the display margins. By default, fringes are drawn between
7571display marginal areas and the text area. 7568display marginal areas and the text area.
7572 7569
7570Optional fifth argument PERSISTENT non-nil means that fringe settings
7571for WINDOW are persistent, i.e., remain unchanged when another buffer
7572is shown in WINDOW. PERSISTENT nil means that fringes are reset from
7573buffer local values when 'set-window-buffer' is called on WINDOW with
7574the argument KEEP-MARGINS nil.
7575
7573Leave fringes unchanged if WINDOW is not large enough to accommodate 7576Leave fringes unchanged if WINDOW is not large enough to accommodate
7574fringes of the desired width. Return t if any fringe was actually 7577fringes of the desired width. Return t if any fringe was actually
7575changed and nil otherwise. */) 7578changed and nil otherwise. */)
7576 (Lisp_Object window, Lisp_Object left_width, 7579 (Lisp_Object window, Lisp_Object left_width, Lisp_Object right_width,
7577 Lisp_Object right_width, Lisp_Object outside_margins) 7580 Lisp_Object outside_margins, Lisp_Object persistent)
7578{ 7581{
7579 struct window *w 7582 struct window *w
7580 = set_window_fringes (decode_live_window (window), 7583 = set_window_fringes (decode_live_window (window), left_width,
7581 left_width, right_width, outside_margins); 7584 right_width, outside_margins, persistent);
7582 return w ? (apply_window_adjustment (w), Qt) : Qnil; 7585 return w ? (apply_window_adjustment (w), Qt) : Qnil;
7583} 7586}
7584 7587
7585 7588
7586DEFUN ("window-fringes", Fwindow_fringes, Swindow_fringes, 7589DEFUN ("window-fringes", Fwindow_fringes, Swindow_fringes,
7587 0, 1, 0, 7590 0, 1, 0,
7588 doc: /* Get width of fringes of window WINDOW. 7591 doc: /* Return fringe settings for specified WINDOW.
7589WINDOW must be a live window and defaults to the selected one. 7592WINDOW must be a live window and defaults to the selected one.
7590 7593
7591Value is a list of the form (LEFT-WIDTH RIGHT-WIDTH OUTSIDE-MARGINS). */) 7594Value is a list of the form (LEFT-WIDTH RIGHT-WIDTH OUTSIDE-MARGINS
7595PERSISTENT), see `set-window-fringes'. */)
7592 (Lisp_Object window) 7596 (Lisp_Object window)
7593{ 7597{
7594 struct window *w = decode_live_window (window); 7598 struct window *w = decode_live_window (window);
7595 7599
7596 return list3 (make_fixnum (WINDOW_LEFT_FRINGE_WIDTH (w)), 7600 return list4 (make_fixnum (WINDOW_LEFT_FRINGE_WIDTH (w)),
7597 make_fixnum (WINDOW_RIGHT_FRINGE_WIDTH (w)), 7601 make_fixnum (WINDOW_RIGHT_FRINGE_WIDTH (w)),
7598 WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) ? Qt : Qnil); 7602 WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) ? Qt : Qnil,
7603 w->fringes_persistent ? Qt : Qnil);
7599} 7604}
7600 7605
7601 7606
@@ -7607,105 +7612,127 @@ Value is a list of the form (LEFT-WIDTH RIGHT-WIDTH OUTSIDE-MARGINS). */)
7607static struct window * 7612static struct window *
7608set_window_scroll_bars (struct window *w, Lisp_Object width, 7613set_window_scroll_bars (struct window *w, Lisp_Object width,
7609 Lisp_Object vertical_type, Lisp_Object height, 7614 Lisp_Object vertical_type, Lisp_Object height,
7610 Lisp_Object horizontal_type) 7615 Lisp_Object horizontal_type, Lisp_Object persistent)
7611{ 7616{
7612 int iwidth = extract_dimension (width); 7617 /* Do nothing on a tty. */
7613 bool changed = false; 7618 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w)))
7614 7619 return NULL;
7615 if (iwidth == 0) 7620 else
7616 vertical_type = Qnil;
7617
7618 if (!(NILP (vertical_type)
7619 || EQ (vertical_type, Qleft)
7620 || EQ (vertical_type, Qright)
7621 || EQ (vertical_type, Qt)))
7622 error ("Invalid type of vertical scroll bar");
7623
7624 if (w->scroll_bar_width != iwidth
7625 || !EQ (w->vertical_scroll_bar_type, vertical_type))
7626 { 7621 {
7627 /* Don't change anything if new scroll bar won't fit. */ 7622 struct frame *f = XFRAME (WINDOW_FRAME (w));
7623 int new_width = extract_dimension (width);
7624 bool changed = false;
7625 bool failed = false;
7626
7627 if (new_width == 0)
7628 vertical_type = Qnil;
7629 else if (!(NILP (vertical_type)
7630 || EQ (vertical_type, Qleft)
7631 || EQ (vertical_type, Qright)
7632 || EQ (vertical_type, Qt)))
7633 error ("Invalid type of vertical scroll bar");
7634
7635 /* Check dimension of new scroll bar. Make changes only if it
7636 fit the window's dimensions. */
7628 if ((WINDOW_PIXEL_WIDTH (w) 7637 if ((WINDOW_PIXEL_WIDTH (w)
7629 - WINDOW_MARGINS_WIDTH (w) 7638 - WINDOW_MARGINS_WIDTH (w)
7630 - WINDOW_FRINGES_WIDTH (w) 7639 - WINDOW_FRINGES_WIDTH (w)
7631 - max (iwidth, 0)) 7640 - WINDOW_RIGHT_DIVIDER_WIDTH (w)
7641 - (new_width == -1 ? FRAME_SCROLL_BAR_AREA_WIDTH (f) : new_width))
7632 >= MIN_SAFE_WINDOW_PIXEL_WIDTH (w)) 7642 >= MIN_SAFE_WINDOW_PIXEL_WIDTH (w))
7633 { 7643 {
7634 w->scroll_bar_width = iwidth; 7644 changed = (!EQ (vertical_type, w->vertical_scroll_bar_type)
7645 || new_width != WINDOW_SCROLL_BAR_AREA_WIDTH (w));
7635 wset_vertical_scroll_bar_type (w, vertical_type); 7646 wset_vertical_scroll_bar_type (w, vertical_type);
7636 changed = true; 7647 w->scroll_bar_width = new_width;
7637 } 7648 }
7638 } 7649 else
7650 failed = true;
7639 7651
7640#if USE_HORIZONTAL_SCROLL_BARS 7652#if USE_HORIZONTAL_SCROLL_BARS
7641 { 7653 int new_height = extract_dimension (height);
7642 int iheight = extract_dimension (height);
7643 7654
7644 if (MINI_WINDOW_P (w) || iheight == 0) 7655 if ((MINI_WINDOW_P (w) && !EQ (horizontal_type, Qbottom))
7645 horizontal_type = Qnil; 7656 || new_height == 0)
7657 horizontal_type = Qnil;
7646 7658
7647 if (!(NILP (horizontal_type) 7659 if (!(NILP (horizontal_type)
7648 || EQ (horizontal_type, Qbottom) 7660 || EQ (horizontal_type, Qbottom)
7649 || EQ (horizontal_type, Qt))) 7661 || EQ (horizontal_type, Qt)))
7650 error ("Invalid type of horizontal scroll bar"); 7662 error ("Invalid type of horizontal scroll bar");
7651 7663
7652 if (w->scroll_bar_height != iheight 7664 /* Don't change anything if new scroll bar won't fit. */
7653 || !EQ (w->horizontal_scroll_bar_type, horizontal_type)) 7665 if ((WINDOW_PIXEL_HEIGHT (w)
7654 { 7666 - WINDOW_HEADER_LINE_HEIGHT (w)
7655 /* Don't change anything if new scroll bar won't fit. */ 7667 - WINDOW_MODE_LINE_HEIGHT (w)
7656 if ((WINDOW_PIXEL_HEIGHT (w) 7668 - (new_height == -1 ? FRAME_SCROLL_BAR_AREA_HEIGHT (f) : new_height))
7657 - WINDOW_HEADER_LINE_HEIGHT (w) 7669 >= MIN_SAFE_WINDOW_PIXEL_HEIGHT (w))
7658 - WINDOW_MODE_LINE_HEIGHT (w) 7670 {
7659 - max (iheight, 0)) 7671 changed = (changed
7660 >= MIN_SAFE_WINDOW_PIXEL_HEIGHT (w)) 7672 || !EQ (horizontal_type, w->horizontal_scroll_bar_type)
7661 { 7673 || new_height != WINDOW_SCROLL_BAR_AREA_HEIGHT (w));
7662 w->scroll_bar_height = iheight; 7674 wset_horizontal_scroll_bar_type (w, horizontal_type);
7663 wset_horizontal_scroll_bar_type (w, horizontal_type); 7675 w->scroll_bar_height = new_height;
7664 changed = true; 7676 }
7665 } 7677 else
7666 } 7678 failed = true;
7667 }
7668#else 7679#else
7669 wset_horizontal_scroll_bar_type (w, Qnil); 7680 wset_horizontal_scroll_bar_type (w, Qnil);
7670#endif 7681#endif
7671 7682
7672 /* This is needed to trigger immediate redisplay of the window when 7683 /* Make settings persistent unless we failed to apply some
7673 scroll bars are changed, because scroll bars are redisplayed only 7684 changes. */
7674 if more than a single window needs to be considered, see 7685 if (!failed)
7675 redisplay_internal. */ 7686 w->scroll_bars_persistent = !NILP (persistent);
7676 if (changed) 7687
7677 windows_or_buffers_changed = 31; 7688 /* This is needed to trigger immediate redisplay of the window when
7678 return changed ? w : NULL; 7689 scroll bars are changed, because scroll bars are redisplayed only
7690 if more than a single window needs to be considered, see
7691 redisplay_internal. */
7692 if (changed)
7693 windows_or_buffers_changed = 31;
7694
7695 return changed ? w : NULL;
7696 }
7679} 7697}
7680 7698
7681DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars, 7699DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars,
7682 Sset_window_scroll_bars, 1, 5, 0, 7700 Sset_window_scroll_bars, 1, 6, 0,
7683 doc: /* Set width and type of scroll bars of window WINDOW. 7701 doc: /* Set width and type of scroll bars of specified WINDOW.
7684WINDOW must be a live window and defaults to the selected one. 7702WINDOW must specify a live window and defaults to the selected one.
7685 7703
7686Second parameter WIDTH specifies the pixel width for the vertical scroll 7704Second argument WIDTH specifies the pixel width for the vertical scroll
7687bar. If WIDTH is nil, use the scroll bar width of WINDOW's frame. 7705bar. If WIDTH is nil, use the scroll bar width of WINDOW's frame.
7688Third parameter VERTICAL-TYPE specifies the type of the vertical scroll 7706Third argument VERTICAL-TYPE specifies the type of the vertical scroll
7689bar: left, right, nil or t where nil means to not display a vertical 7707bar: left, right, nil or t where nil means to not display a vertical
7690scroll bar on WINDOW and t means to use WINDOW frame's vertical scroll 7708scroll bar on WINDOW and t means to use WINDOW frame's vertical scroll
7691bar type. 7709bar type.
7692 7710
7693Fourth parameter HEIGHT specifies the pixel height for the horizontal 7711Fourth argument HEIGHT specifies the pixel height for the horizontal
7694scroll bar. If HEIGHT is nil, use the scroll bar height of WINDOW's 7712scroll bar. If HEIGHT is nil, use the scroll bar height of WINDOW's
7695frame. Fifth parameter HORIZONTAL-TYPE specifies the type of the 7713frame. Fifth argument HORIZONTAL-TYPE specifies the type of the
7696horizontal scroll bar: bottom, nil, or t where nil means to not display 7714horizontal scroll bar: bottom, nil, or t where nil means to not
7697a horizontal scroll bar on WINDOW and t means to use WINDOW frame's 7715display a horizontal scroll bar on WINDOW and t means to use WINDOW
7698horizontal scroll bar type. 7716frame's horizontal scroll bar type. If WINDOW is a mini window, t
7717effectively behaves like nil. HORIZONTAL-TYPE must equal bottom in
7718order to show a scroll bar for mini windows.
7719
7720Optional sixth argument PERSISTENT non-nil means that scroll bar
7721settings for WINDOW are persistent, i.e., remain unchanged when
7722another buffer is shown in WINDOW. PERSISTENT nil means that scroll
7723bars are reset from buffer local values when 'set-window-buffer' is
7724called on WINDOW with the argument KEEP-MARGINS nil.
7699 7725
7700If WINDOW is not large enough to accommodate a scroll bar of the 7726If WINDOW is not large enough to accommodate a scroll bar of the
7701desired dimension, leave the corresponding scroll bar unchanged. 7727desired dimension, leave the corresponding scroll bar unchanged.
7702Return t if scroll bars were actually changed and nil otherwise. */) 7728Return t if scroll bars were actually changed and nil otherwise. */)
7703 (Lisp_Object window, Lisp_Object width, Lisp_Object vertical_type, 7729 (Lisp_Object window, Lisp_Object width, Lisp_Object vertical_type,
7704 Lisp_Object height, Lisp_Object horizontal_type) 7730 Lisp_Object height, Lisp_Object horizontal_type, Lisp_Object persistent)
7705{ 7731{
7706 struct window *w 7732 struct window *w
7707 = set_window_scroll_bars (decode_live_window (window), 7733 = set_window_scroll_bars (decode_live_window (window),
7708 width, vertical_type, height, horizontal_type); 7734 width, vertical_type, height,
7735 horizontal_type, persistent);
7709 return w ? (apply_window_adjustment (w), Qt) : Qnil; 7736 return w ? (apply_window_adjustment (w), Qt) : Qnil;
7710} 7737}
7711 7738
@@ -7716,9 +7743,9 @@ DEFUN ("window-scroll-bars", Fwindow_scroll_bars, Swindow_scroll_bars,
7716WINDOW must be a live window and defaults to the selected one. 7743WINDOW must be a live window and defaults to the selected one.
7717 7744
7718Value is a list of the form (WIDTH COLUMNS VERTICAL-TYPE HEIGHT LINES 7745Value is a list of the form (WIDTH COLUMNS VERTICAL-TYPE HEIGHT LINES
7719HORIZONTAL-TYPE). If WIDTH or HEIGHT is nil or VERTICAL-TYPE or 7746HORIZONTAL-TYPE PERSISTENT), see `set-window-scroll-bars'. If WIDTH
7720HORIZONTAL-TYPE is t, the window is using the frame's corresponding 7747or HEIGHT is nil or VERTICAL-TYPE or HORIZONTAL-TYPE is t, WINDOW is
7721value. */) 7748using the frame's corresponding value. */)
7722 (Lisp_Object window) 7749 (Lisp_Object window)
7723{ 7750{
7724 struct window *w = decode_live_window (window); 7751 struct window *w = decode_live_window (window);
@@ -7726,13 +7753,14 @@ value. */)
7726 return Fcons (((w->scroll_bar_width >= 0) 7753 return Fcons (((w->scroll_bar_width >= 0)
7727 ? make_fixnum (w->scroll_bar_width) 7754 ? make_fixnum (w->scroll_bar_width)
7728 : Qnil), 7755 : Qnil),
7729 list5 (make_fixnum (WINDOW_SCROLL_BAR_COLS (w)), 7756 Fcons (make_fixnum (WINDOW_SCROLL_BAR_COLS (w)),
7730 w->vertical_scroll_bar_type, 7757 list5 (w->vertical_scroll_bar_type,
7731 ((w->scroll_bar_height >= 0) 7758 ((w->scroll_bar_height >= 0)
7732 ? make_fixnum (w->scroll_bar_height) 7759 ? make_fixnum (w->scroll_bar_height)
7733 : Qnil), 7760 : Qnil),
7734 make_fixnum (WINDOW_SCROLL_BAR_LINES (w)), 7761 make_fixnum (WINDOW_SCROLL_BAR_LINES (w)),
7735 w->horizontal_scroll_bar_type)); 7762 w->horizontal_scroll_bar_type,
7763 w->scroll_bars_persistent ? Qt : Qnil)));
7736} 7764}
7737 7765
7738/*********************************************************************** 7766/***********************************************************************
@@ -7927,10 +7955,12 @@ compare_window_configurations (Lisp_Object configuration1,
7927 || !EQ (sw1->left_fringe_width, sw2->left_fringe_width) 7955 || !EQ (sw1->left_fringe_width, sw2->left_fringe_width)
7928 || !EQ (sw1->right_fringe_width, sw2->right_fringe_width) 7956 || !EQ (sw1->right_fringe_width, sw2->right_fringe_width)
7929 || !EQ (sw1->fringes_outside_margins, sw2->fringes_outside_margins) 7957 || !EQ (sw1->fringes_outside_margins, sw2->fringes_outside_margins)
7958 || !EQ (sw1->fringes_persistent, sw2->fringes_persistent)
7930 || !EQ (sw1->scroll_bar_width, sw2->scroll_bar_width) 7959 || !EQ (sw1->scroll_bar_width, sw2->scroll_bar_width)
7931 || !EQ (sw1->scroll_bar_height, sw2->scroll_bar_height) 7960 || !EQ (sw1->scroll_bar_height, sw2->scroll_bar_height)
7932 || !EQ (sw1->vertical_scroll_bar_type, sw2->vertical_scroll_bar_type) 7961 || !EQ (sw1->vertical_scroll_bar_type, sw2->vertical_scroll_bar_type)
7933 || !EQ (sw1->horizontal_scroll_bar_type, sw2->horizontal_scroll_bar_type)) 7962 || !EQ (sw1->horizontal_scroll_bar_type, sw2->horizontal_scroll_bar_type)
7963 || !EQ (sw1->scroll_bars_persistent, sw2->scroll_bars_persistent))
7934 return false; 7964 return false;
7935 } 7965 }
7936 7966