aboutsummaryrefslogtreecommitdiffstats
path: root/src/window.c
diff options
context:
space:
mode:
authorMartin Rudalics2014-07-27 15:21:30 +0200
committerMartin Rudalics2014-07-27 15:21:30 +0200
commit3477e27021dbe9366c3c1aaba80feb72f1138b29 (patch)
treec1ebfb6695e8d7f90ddad1a5bfaaf353be677514 /src/window.c
parent11fb71017b03f01a7e9e2db24973e756a41e16ec (diff)
downloademacs-3477e27021dbe9366c3c1aaba80feb72f1138b29.tar.gz
emacs-3477e27021dbe9366c3c1aaba80feb72f1138b29.zip
Complete pixelwise frame/window resizing, add horizontal scrollbar support.
* frame.el (frame-notice-user-settings): Rewrite using frame-initial-frame-tool-bar-height. * menu-bar.el (menu-bar-horizontal-scroll-bar) (menu-bar-no-horizontal-scroll-bar): New functions. (menu-bar-showhide-scroll-bar-menu): Add bindings for horizontal scroll bars. * scroll-bar.el (scroll-bar-lines) (set-horizontal-scroll-bar-mode) (get-horizontal-scroll-bar-mode, horizontal-scroll-bar-mode) (scroll-bar-horizontal-drag-1, scroll-bar-horizontal-drag) (scroll-bar-toolkit-horizontal-scroll): New functions. (horizontal-scroll-bar-mode) (previous-horizontal-scroll-bar-mode) (horizontal-scroll-bar-mode-explicit): New variables. (horizontal-scroll-bar-mode): New option. (toggle-horizontal-scroll-bar): Do something. (top-level): Bind horizontal-scroll-bar mouse-1. * startup.el (tool-bar-originally-present): Remove variable. (command-line): Don't set tool-bar-originally-present. * window.el (window-min-height): Update doc-string. (window--dump-frame): Dump horizontal scroll bar values. (window--min-size-1): Handle minibuffer window separately. Count in margins and horizontal scroll bar. Return safe value iff IGNORE equals 'safe. (frame-windows-min-size): New function (used by frame resizing routines). (fit-frame-to-buffer, fit-window-to-buffer): Count in horizontal scroll bars. (window--sanitize-window-sizes): New function. (window-split-min-size): Remove. (split-window): Count divider-width. Don't use `window-split-min-size' any more. Reword error messages. Sanitize windows sizes after splitting. * buffer.h (struct buffer): New fields scroll_bar_height and horizontal_scroll_bar_type. * buffer.c (bset_scroll_bar_height) (bset_horizontal_scroll_bar_type): New functions. (Fbuffer_swap_text): Handle old_pointm field. (init_buffer_once): Set defaults for scroll_bar_height and horizontal_scroll_bar_type. (syms_of_buffer): New variables scroll_bar_height and horizontal_scroll_bar_type. * dispextern.h (window_part): Rename ON_SCROLL_BAR to ON_VERTICAL_SCROLL_BAR. Add ON_HORIZONTAL_SCROLL_BAR. (set_vertical_scroll_bar): Remove prototype. (x_change_tool_bar_height): Add prototype. * dispnew.c (adjust_frame_glyphs_for_frame_redisplay) (window_to_frame_vpos, update_frame_1, scrolling, init_display): Use FRAME_TOTAL_COLS and FRAME_TOTAL_LINES instead of FRAME_COLS and FRAME_LINES. (adjust_frame_glyphs_for_window_redisplay): Rearrange lines. (update_window): Start mode_line_row->y after horizontal scroll bar. (change_frame_size_1): Call adjust_frame_size. (init_display): When changing the size of a tty frame do not pass height of menu bar. (Qframe_windows_min_size): New symbol. * frame.h (struct frame): List tool bar fields after menu bar fields. Add official, total_lines, horizontal_scroll_bars, config_scroll_bar_height and config_scroll_bar_lines fields. (FRAME_HAS_HORIZONTAL_SCROLL_BARS) (FRAME_CONFIG_SCROLL_BAR_HEIGHT, FRAME_CONFIG_SCROLL_BAR_LINES) (FRAME_SCROLL_BAR_AREA_HEIGHT, FRAME_SCROLL_BAR_COLS) (FRAME_SCROLL_BAR_LINES, FRAME_TOTAL_LINES, SET_FRAME_LINES) (FRAME_WINDOWS_HEIGHT): New macros. (SET_FRAME_HEIGHT, FRAME_TEXT_LINES_TO_PIXEL_HEIGHT) (FRAME_PIXEL_Y_TO_LINE, FRAME_PIXEL_HEIGHT_TO_TEXT_LINES) (FRAME_TEXT_TO_PIXEL_HEIGHT): Separately count top margin and horizontal scroll bar. (frame_inhibit_resize, adjust_frame_size) (frame_windows_min_size): Add declarations. (Qscroll_bar_height, Qhorizontal_scroll_bars) (x_set_scroll_bar_default_height, x_set_left_fringe) (x_set_right_fringe, x_set_vertical_scroll_bars) (x_set_horizontal_scroll_bars, x_set_scroll_bar_width) (x_set_scroll_bar_height): Add external declarations. * frame.c: (frame_inhibit_resize, frame_windows_min_size) (adjust_frame_size): New functions. (make_frame): Initial horizontal_scroll_bars field. Use SET_FRAME_LINES. Don't allow horizontal scroll bar in minibuffer window. (make_initial_frame, make_terminal_frame): No horizontal scroll bar in initial and terminal frames. Use adjust_frame_size. (Fframe_total_cols): Fix doc-string. (Fframe_total_lines, Fscroll_bar_height): New Lisp functions. (Fset_frame_height, Fset_frame_width, Fset_frame_size): Rewrite using adjust_frame_size. (Qscroll_bar_height, Qhorizontal_scroll_bars) (Qframe_windows_min_size): New symbols. (x_set_frame_parameters): Remove call of check_frame_size. (x_report_frame_params): Return scroll_bar_height value. (x_set_left_fringe, x_set_right_fringe): New functions. (adjust_frame_height, x_set_internal_border_width) (x_set_fringe_width): Remove. (x_set_internal_border_width, x_set_vertical_scroll_bars) (x_set_scroll_bar_width, x_set_right_divider_width) (x_set_bottom_divider_width): Rewrite using adjust_frame_size. (x_set_horizontal_scroll_bars, x_set_scroll_bar_height): New functions. (x_figure_window_size): Rewrite to make frame display the expected number of lines. (Vdefault_frame_scroll_bars): Rewrite doc-string. (Vdefault_frame_horizontal_scroll_bars) (Vframe_initial_frame_tool_bar_height) (frame_inhibit_implied_resize): New variables. * fringe.c (compute_fringe_widths): Remove. * gtkutil.h (YG_SB_MIN, YG_SB_MAX, YG_SB_RANGE): Define. (xg_create_horizontal_scroll_bar) (xg_update_horizontal_scrollbar_pos) (xg_set_toolkit_horizontal_scroll_bar_thumb) (xg_get_default_scrollbar_height) (xg_clear_under_internal_border): Extern. * gtkutil.c (xg_frame_resized): Don't call do_pending_window_change. (xg_frame_set_char_size): Use adjust_frame_size. (style_changed_cb): Call update_theme_scrollbar_height and x_set_scroll_bar_default_height. (x_wm_set_size_hint): Don't call check_frame_size. (update_theme_scrollbar_height) (xg_get_default_scrollbar_height) (xg_create_horizontal_scroll_bar) (xg_update_horizontal_scrollbar_pos) (xg_set_toolkit_horizontal_scroll_bar_thumb): New functions. (xg_create_scroll_bar): Set horizontal slot of bar. (xg_initialize): Call update_theme_scrollbar_height. (xg_clear_under_internal_border): No more static. * insdel.c (adjust_suspend_auto_hscroll): New function. (adjust_markers_for_delete, adjust_markers_for_insert) (adjust_markers_for_replace): Call adjust_suspend_auto_hscroll. * keyboard.c (readable_events, discard_mouse_events) (make_lispy_event): Handle horizontal scroll bar click events. (Fsuspend_emacs): When changing the size of a tty frame do not pass height of menu bar. (Qbefore_handle, Qhorizontal_handle, Qafter_handle, Qleft) (Qright, Qleftmost, Qrightmost): New symbols. * menu.c (Fx_popup_dialog): Use FRAME_TOTAL_LINES instead of FRAME_LINES. * minibuf.c (read_minibuf): Initialize suspend_auto_hscroll. * nsfns.m (x_set_internal_border_width): New function. * nsterm.m (ns_draw_fringe_bitmap, ns_set_vertical_scroll_bar): Remove extended fringe code. (x_set_window_size, x_new_font): Don't call compute_fringe_widths. * term.c (Fresume_tty): When changing the size of a tty frame do not pass height of menu bar. (clear_tty_hooks, set_tty_hooks): Clear horizontal_scroll_bar_hook. (init_tty): Frame has no horizontal scroll bars. * termhooks.h (enum scroll_bar_part): Add scroll_bar_move_ratio, scroll_bar_before_handle, scroll_bar_horizontal_handle, scroll_bar_after_handle, scroll_bar_left_arrow, scroll_bar_right_arrow, scroll_bar_to_leftmost and scroll_bar_to_rightmost entries. (enum event_kind): Add HORIZONTAL_SCROLL_BAR_CLICK_EVENT (struct terminal): Add set_horizontal_scroll_bar_hook. * w32console.c (initialize_w32_display): Clear horizontal_scroll_bar_hook. * w32fns.c (x_set_mouse_color): Use FRAME_W32_DISPLAY instead of FRAME_X_DISPLAY. (x_clear_under_internal_border, x_set_internal_border_width): New functions. (x_set_menu_bar_lines): Rewrite using frame_inhibit_resize. Set windows_or_buffers_changed when adding the menu bar. (x_set_tool_bar_lines): Rewrite using adjust_frame_size. (x_change_tool_bar_height, x_set_scroll_bar_default_height) (w32_createhscrollbar): New functions. (w32_createscrollbar): Rename to w32_createvscrollbar. (w32_createwindow): Init WND_HSCROLLBAR_INDEX. (w32_name_of_message): Replace WM_EMACS_CREATESCROLLBAR by WM_EMACS_CREATEVSCROLLBAR and WM_EMACS_CREATEHSCROLLBAR. Add WM_EMACS_SHOWCURSOR. (w32_wnd_proc): Handle WM_HSCROLL case. In WM_WINDOWPOSCHANGING case do not artificially impose WM size hints. Handle WM_EMACS_SHOWCURSOR case. Replace WM_EMACS_CREATESCROLLBAR case by WM_EMACS_CREATEVSCROLLBAR and WM_EMACS_CREATEHSCROLLBAR cases. (my_create_tip_window): Replace WND_SCROLLBAR_INDEX by WND_VSCROLLBAR_INDEX and WND_HSCROLLBAR_INDEX. (unwind_create_frame_1): Remove. (Fx_create_frame): Make both scrollbars the system standard width and height. Use official field of frame structure to inhibit running window-configuration-change-hook. (x_create_tip_frame): Call SET_FRAME_LINES and change_frame_size pixelwise. Handle frame's official field. (w32_frame_parm_handlers): Remove x_set_fringe_width entries. Add x_set_scroll_bar_height, x_set_horizontal_scroll_bars, x_set_left_fringe and x_set_right_fringe. * w32inevt.c (resize_event, maybe_generate_resize_event): Do not pass height of menu bar to change_frame_size. * w32menu.c (set_frame_menubar): Rewrite using frame_inhibit_resize. * w32term.h (struct w32_display_info): Add horizontal_scroll_bar_cursor and cursor_display_counter. (struct scroll_bar): Add horizontal. (HORIZONTAL_SCROLL_BAR_INSIDE_HEIGHT) (HORIZONTAL_SCROLL_BAR_LEFT_RANGE) (HORIZONTAL_SCROLL_BAR_INSIDE_WIDTH) (HORIZONTAL_SCROLL_BAR_LEFT_BORDER) (HORIZONTAL_SCROLL_BAR_RIGHT_BORDER) (HORIZONTAL_SCROLL_BAR_TOP_BORDER) (HORIZONTAL_SCROLL_BAR_BOTTOM_BORDER) (HORIZONTAL_SCROLL_BAR_MIN_HANDLE): New macros. (WM_EMACS_CREATEVSCROLLBAR, WM_EMACS_CREATEHSCROLLBAR): Define instead of WM_EMACS_CREATESCROLLBAR. (WND_VSCROLLBAR_INDEX, WND_HSCROLLBAR_INDEX): Define instead of WND_SCROLLBAR_INDEX. * w32term.c (horizontal_scroll_bar_min_handle) (horizontal_scroll_bar_left_border) (horizontal_scroll_bar_right_border): New integers. (x_set_frame_alpha): Replace x_highlight_frame by w32_focus_frame. (x_window_to_scroll_bar): New argument "type". Update callers accordingly. (w32_set_horizontal_scroll_bar_thumb) (x_horizontal_scroll_bar_report_motion) (w32_set_horizontal_scroll_bar) (w32_horizontal_scroll_bar_handle_click) (x_horizontal_scroll_bar_report_motion): New functions. (w32_mouse_position): Discriminate horizontal and vertical scrollbar cases. (my_create_scrollbar): Replace with two new functions my_create_vscrollbar and my_create_hscrollbar. (x_scroll_bar_create): New argument "horizontal". Update callers accordingly. (x_scroll_bar_remove, w32_condemn_scroll_bars) (w32_redeem_scroll_bar, x_scroll_bar_clear): Handle horizontal scroll bar case. (w32_read_socket): Handle WM_HSCROLL cae. (x_new_font): Don't recompute fringe widths. Use frame_inhibit_resize. Calculate new menu bar height iff we build without toolkit. Always clear under internal border. (x_set_window_size): Don't check frame size or recompute fringes. Reset fullscreen status before applying sizes. Always resize as requested by pixelwise argument. Don't call do_pending_window_change. (x_wm_set_size_hint): Add call for FRAME_SCROLL_BAR_AREA_HEIGHT. (w32_initialize_display_info): Initialize dpyinfo's horizontal_scroll_bar_cursor entry. (w32_create_terminal): Add set_horizontal_scroll_bar_hook. (w32_initialize): Init horizontal_scroll_bar_min_handle and horizontal_scroll_bar_left_border. (w32fullscreen_hook): Intermittently resize window to normal when switching from fullscreen to maximized state. (run_window_configuration_change_hook): Don't run it if frame is not official yet. (unwind_change_frame): Remove. (Fset_window_configuration): Rewrite using frame's official field. * widget.c (set_frame_size): Don't call compute_fringe_widths. (EmacsFrameSetCharSize): Obey frame_inhibit_resize. * window.h (struct window): New fields old_pointm, horizontal_scroll_bar, horizontal_scroll_bar_type, hscroll_whole, scroll_bar_height and suspend_auto_hscroll. (wset_horizontal_scroll_bar, wset_horizontal_scroll_bar_type): New functions. (sanitize_window_sizes): Extern. (MINI_NON_ONLY_WINDOW_P, MINI_ONLY_WINDOW_P, WINDOW_PSEUDO_P) (WINDOW_TOPMOST_P, WINDOW_HAS_HORIZONTAL_SCROLL_BAR) (WINDOW_CONFIG_SCROLL_BAR_HEIGHT) (WINDOW_CONFIG_SCROLL_BAR_LINES) (WINDOW_SCROLL_BAR_LINES, WINDOW_SCROLL_BAR_AREA_HEIGHT): New macros. (WINDOW_LEFT_FRINGE_COLS, WINDOW_RIGHT_FRINGE_COLS) (WINDOW_FRINGE_COLS, WINDOW_FRINGE_EXTENDED_P): Remove macros. (WINDOW_VERTICAL_SCROLL_BAR_TYPE) (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT) (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT) (WINDOW_HAS_VERTICAL_SCROLL_BAR): Minor rewrite. (WINDOW_BOX_HEIGHT_NO_MODE_LINE, WINDOW_BOX_TEXT_HEIGHT) (WINDOW_SCROLL_BAR_AREA_Y): Count in scroll bar height. * window.c (wset_old_pointm, Fwindow_scroll_bar_height) (Fwindow_old_point, sanitize_window_sizes): New functions. (Qwindow_sanitize_window_sizes): New symbol. (window_body_height): Count in horizontal scroll bar. (set_window_hscroll, Fscroll_left, Fscroll_right): Set suspend_auto_hscroll slot. (Fwindow_inside_edges): Count fringes pixelwise. (coordinates_in_window, Fcoordinates_in_window_p): Consider horizontal scroll bar. (check_frame_size, adjust_window_margins): Remove functions and corresponding calls. (set_window_buffer): Initialize old_pointm and horizontal scroll bars. (temp_output_buffer_show): Reset hscroll related fields. Initialize old_pointm. (make_parent_window): Initialize old_pointm. (make_window): Initialize old_pointm, horizontal scroll bar type, and scroll bar height. (resize_frame_windows): Don't count top margin in new sizes. Don't use safe sizes when shrinking a frame; let the window manager do the clipping. (Fsplit_window_internal): Inherit horizontal scroll bar type and height. (Fdelete_window_internal): Unchain old_pointm marker. (window_scroll_pixel_based, Fscroll_other_window): Adjust old_pointm. (Fwindow_text_width, Fwindow_text_height): New argument "pixelwise". (struct saved_window): New fields, old_pointm, hscroll_whole, suspend_auto_hscroll, scroll_bar_height and horizontal_scroll_bar_type. (Fset_window_configuration, save_window_save): Set new fields of saved_window. (apply_window_adjustment): Don't call adjust_window_margins. (set_window_margins): Don't change margins if new sizes don't fit into window. (set_window_scroll_bars): New argument "horizontal_type". Handle horizontal scroll bars. Don't change scroll bars if they don't fit into window. (Fset_window_scroll_bars): New argument "horizontal_type". (Fwindow_scroll_bars): Return values for horizontal scroll bars. (compare_window_configurations): Compare horizontal scroll bar settings. * xdisp.c (window_text_bottom_y, window_box_height): Count in horizontal scroll bar height. (pixel_to_glyph_coords, init_xdisp): Use FRAME_TOTAL_LINES instead of FRAME_LINES. (remember_mouse_glyph): Case ON_SCROLL_BAR changed to ON_VERTICAL_SCROLL_BAR. (with_echo_area_buffer): Initialize old_pointm. (with_echo_area_buffer_unwind_data): Store old_pointm values in vector. (unwind_with_echo_area_buffer): Handle old_pointm. (update_tool_bar): Set do_update when the tool bar window has at least one line (since this is what the user sets). (MAX_FRAME_TOOL_BAR_HEIGHT): Remove macro. (redisplay_tool_bar): Return early when toolbar has zero lines. Call x_change_tool_bar_height. Don't use max_tool_bar_height. (hscroll_window_tree): Handle suspension of auto_hscroll and old_pointm. (set_horizontal_scroll_bar): New function. (redisplay_window): Set ignore_mouse_drag_p when tool bar has more than one line. Handle horizontal scroll bars. (note_mouse_highlight): Handle horizontal scrol bars. (expose_frame): Set dimensions of XRectangle from frame's text sizes. (Vvoid_text_area_pointer): Update doc-string. * xfns.c (x_set_menu_bar_lines): Use adjust_frame_size. (x_change_tool_bar_height, x_set_scroll_bar_default_height) (x_set_internal_border_width): New functions. (x_set_tool_bar_lines): Call x_change_tool_bar_height. (unwind_create_frame_1): Remove. (Fx_create_frame): Handle horizontal scroll bars. Use official field of frame structure to inhibit running window-configuration-change-hook. (x_create_tip_frame): Call SET_FRAME_LINES and change_frame_size pixelwise. Handle frame's official field. (x_frame_parm_handlers): Add x_set_scroll_bar_height, x_set_horizontal_scroll_bars, x_set_left_fringe, x_set_right_fringe. * xmenu.c (update_frame_menubar, free_frame_menubar): Use adjust_frame_size. * xterm.h (struct x_display_info): Add horizontal_scroll_bar_cursor and Xatom_Horizontal_Scrollbar slots. (struct scroll_bar): Add horizontal slot. (HORIZONTAL_SCROLL_BAR_INSIDE_HEIGHT) (HORIZONTAL_SCROLL_BAR_LEFT_RANGE) (HORIZONTAL_SCROLL_BAR_INSIDE_WIDTH): New macros. (HORIZONTAL_SCROLL_BAR_LEFT_BORDER) (HORIZONTAL_SCROLL_BAR_RIGHT_BORDER) (HORIZONTAL_SCROLL_BAR_TOP_BORDER) (HORIZONTAL_SCROLL_BAR_BOTTOM_BORDER) (HORIZONTAL_SCROLL_BAR_MIN_HANDLE): Define. (x_clear_under_internal_border): Remove. * xterm.c (XTmouse_position): Handle horizontal scroll bars. (x_window_to_scroll_bar): New argument TYPE. Update callers. (x_send_scroll_bar_event, x_scroll_bar_create): New arguments HORIZONTAL. Update callers. (horizontal_action_hook_id): New action hook id. (x_horizontal_scroll_bar_to_input_event) (x_create_horizontal_toolkit_scroll_bar) (xt_horizontal_action_hook) (x_set_toolkit_horizontal_scroll_bar_thumb) (XTset_horizontal_scroll_bar, x_net_wm_state) (x_horizontal_scroll_bar_report_motion): New functions. (xg_scroll_callback, x_scroll_bar_handle_click): Handle horizontal scroll bars. (SCROLL_BAR_HORIZONTAL_NAME): Define. (XTset_vertical_scroll_bar): Attempt to clear areas not covered by scroll bar. (XTcondemn_scroll_bars, XTredeem_scroll_bar): Rewrite. Handle horizontal scroll bars. (handle_one_xevent): Handle horizontal scroll bar events. Call x_net_wm_state. (x_set_window_size_1, x_wm_set_size_hint): Don't call check_frame_size. (x_set_window_size): Don't call check_frame_size and do_pending_window_change. (x_term_init): Init horizontal_scroll_bar_cursor display info. (x_create_terminal): Add set_horizontal_scroll_bar_hook. (x_scroll_bar_set_handle): Add some checks when calling x_clear_area.
Diffstat (limited to 'src/window.c')
-rw-r--r--src/window.c824
1 files changed, 651 insertions, 173 deletions
diff --git a/src/window.c b/src/window.c
index 6afe7454149..ae28b714720 100644
--- a/src/window.c
+++ b/src/window.c
@@ -52,6 +52,7 @@ static Lisp_Object Qrecord_window_buffer;
52static Lisp_Object Qwindow_deletable_p, Qdelete_window, Qdisplay_buffer; 52static Lisp_Object Qwindow_deletable_p, Qdelete_window, Qdisplay_buffer;
53static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window; 53static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window;
54static Lisp_Object Qwindow_resize_root_window, Qwindow_resize_root_window_vertically; 54static Lisp_Object Qwindow_resize_root_window, Qwindow_resize_root_window_vertically;
55static Lisp_Object Qwindow_sanitize_window_sizes;
55static Lisp_Object Qwindow_pixel_to_total; 56static Lisp_Object Qwindow_pixel_to_total;
56static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command; 57static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command;
57static Lisp_Object Qsafe, Qabove, Qbelow, Qwindow_size, Qclone_of; 58static Lisp_Object Qsafe, Qabove, Qbelow, Qwindow_size, Qclone_of;
@@ -87,7 +88,7 @@ static struct window *set_window_fringes (struct window *, Lisp_Object,
87static struct window *set_window_margins (struct window *, Lisp_Object, 88static struct window *set_window_margins (struct window *, Lisp_Object,
88 Lisp_Object); 89 Lisp_Object);
89static struct window *set_window_scroll_bars (struct window *, Lisp_Object, 90static struct window *set_window_scroll_bars (struct window *, Lisp_Object,
90 Lisp_Object, Lisp_Object); 91 Lisp_Object, Lisp_Object, Lisp_Object);
91static void apply_window_adjustment (struct window *); 92static void apply_window_adjustment (struct window *);
92 93
93/* This is the window in which the terminal's cursor should 94/* This is the window in which the terminal's cursor should
@@ -143,66 +144,85 @@ wset_combination_limit (struct window *w, Lisp_Object val)
143{ 144{
144 w->combination_limit = val; 145 w->combination_limit = val;
145} 146}
147
146static void 148static void
147wset_dedicated (struct window *w, Lisp_Object val) 149wset_dedicated (struct window *w, Lisp_Object val)
148{ 150{
149 w->dedicated = val; 151 w->dedicated = val;
150} 152}
153
151static void 154static void
152wset_display_table (struct window *w, Lisp_Object val) 155wset_display_table (struct window *w, Lisp_Object val)
153{ 156{
154 w->display_table = val; 157 w->display_table = val;
155} 158}
159
156static void 160static void
157wset_new_normal (struct window *w, Lisp_Object val) 161wset_new_normal (struct window *w, Lisp_Object val)
158{ 162{
159 w->new_normal = val; 163 w->new_normal = val;
160} 164}
165
161static void 166static void
162wset_new_total (struct window *w, Lisp_Object val) 167wset_new_total (struct window *w, Lisp_Object val)
163{ 168{
164 w->new_total = val; 169 w->new_total = val;
165} 170}
171
166static void 172static void
167wset_normal_cols (struct window *w, Lisp_Object val) 173wset_normal_cols (struct window *w, Lisp_Object val)
168{ 174{
169 w->normal_cols = val; 175 w->normal_cols = val;
170} 176}
177
171static void 178static void
172wset_normal_lines (struct window *w, Lisp_Object val) 179wset_normal_lines (struct window *w, Lisp_Object val)
173{ 180{
174 w->normal_lines = val; 181 w->normal_lines = val;
175} 182}
183
176static void 184static void
177wset_parent (struct window *w, Lisp_Object val) 185wset_parent (struct window *w, Lisp_Object val)
178{ 186{
179 w->parent = val; 187 w->parent = val;
180} 188}
189
181static void 190static void
182wset_pointm (struct window *w, Lisp_Object val) 191wset_pointm (struct window *w, Lisp_Object val)
183{ 192{
184 w->pointm = val; 193 w->pointm = val;
185} 194}
195
196static void
197wset_old_pointm (struct window *w, Lisp_Object val)
198{
199 w->old_pointm = val;
200}
201
186static void 202static void
187wset_start (struct window *w, Lisp_Object val) 203wset_start (struct window *w, Lisp_Object val)
188{ 204{
189 w->start = val; 205 w->start = val;
190} 206}
207
191static void 208static void
192wset_temslot (struct window *w, Lisp_Object val) 209wset_temslot (struct window *w, Lisp_Object val)
193{ 210{
194 w->temslot = val; 211 w->temslot = val;
195} 212}
213
196static void 214static void
197wset_vertical_scroll_bar_type (struct window *w, Lisp_Object val) 215wset_vertical_scroll_bar_type (struct window *w, Lisp_Object val)
198{ 216{
199 w->vertical_scroll_bar_type = val; 217 w->vertical_scroll_bar_type = val;
200} 218}
219
201static void 220static void
202wset_window_parameters (struct window *w, Lisp_Object val) 221wset_window_parameters (struct window *w, Lisp_Object val)
203{ 222{
204 w->window_parameters = val; 223 w->window_parameters = val;
205} 224}
225
206static void 226static void
207wset_combination (struct window *w, bool horflag, Lisp_Object val) 227wset_combination (struct window *w, bool horflag, Lisp_Object val)
208{ 228{
@@ -871,6 +891,9 @@ window_body_height (struct window *w, bool pixelwise)
871{ 891{
872 int height = (w->pixel_height 892 int height = (w->pixel_height
873 - WINDOW_HEADER_LINE_HEIGHT (w) 893 - WINDOW_HEADER_LINE_HEIGHT (w)
894 - (WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w)
895 ? WINDOW_SCROLL_BAR_AREA_HEIGHT (w)
896 : 0)
874 - WINDOW_MODE_LINE_HEIGHT (w) 897 - WINDOW_MODE_LINE_HEIGHT (w)
875 - WINDOW_BOTTOM_DIVIDER_WIDTH (w)); 898 - WINDOW_BOTTOM_DIVIDER_WIDTH (w));
876 899
@@ -991,6 +1014,15 @@ WINDOW must be a live window and defaults to the selected one. */)
991 return (make_number (WINDOW_SCROLL_BAR_AREA_WIDTH (decode_live_window (window)))); 1014 return (make_number (WINDOW_SCROLL_BAR_AREA_WIDTH (decode_live_window (window))));
992} 1015}
993 1016
1017DEFUN ("window-scroll-bar-height", Fwindow_scroll_bar_height,
1018 Swindow_scroll_bar_height, 0, 1, 0,
1019 doc: /* Return the height in pixels of WINDOW's horizontal scrollbar.
1020WINDOW must be a live window and defaults to the selected one. */)
1021 (Lisp_Object window)
1022{
1023 return (make_number (WINDOW_SCROLL_BAR_AREA_HEIGHT (decode_live_window (window))));
1024}
1025
994DEFUN ("window-hscroll", Fwindow_hscroll, Swindow_hscroll, 0, 1, 0, 1026DEFUN ("window-hscroll", Fwindow_hscroll, Swindow_hscroll, 0, 1, 0,
995 doc: /* Return the number of columns by which WINDOW is scrolled from left margin. 1027 doc: /* Return the number of columns by which WINDOW is scrolled from left margin.
996WINDOW must be a live window and defaults to the selected one. */) 1028WINDOW must be a live window and defaults to the selected one. */)
@@ -1018,6 +1050,8 @@ set_window_hscroll (struct window *w, EMACS_INT hscroll)
1018 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1; 1050 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
1019 1051
1020 w->hscroll = new_hscroll; 1052 w->hscroll = new_hscroll;
1053 w->suspend_auto_hscroll = 1;
1054
1021 return make_number (new_hscroll); 1055 return make_number (new_hscroll);
1022} 1056}
1023 1057
@@ -1167,12 +1201,16 @@ display margins, fringes, header line, and/or mode line. */)
1167 1201
1168 return list4i ((WINDOW_BOX_LEFT_EDGE_COL (w) 1202 return list4i ((WINDOW_BOX_LEFT_EDGE_COL (w)
1169 + WINDOW_LEFT_MARGIN_COLS (w) 1203 + WINDOW_LEFT_MARGIN_COLS (w)
1170 + WINDOW_LEFT_FRINGE_COLS (w)), 1204 + ((WINDOW_LEFT_FRINGE_WIDTH (w)
1205 + WINDOW_FRAME_COLUMN_WIDTH (w) - 1)
1206 / WINDOW_FRAME_COLUMN_WIDTH (w))),
1171 (WINDOW_TOP_EDGE_LINE (w) 1207 (WINDOW_TOP_EDGE_LINE (w)
1172 + WINDOW_HEADER_LINE_LINES (w)), 1208 + WINDOW_HEADER_LINE_LINES (w)),
1173 (WINDOW_BOX_RIGHT_EDGE_COL (w) 1209 (WINDOW_BOX_RIGHT_EDGE_COL (w)
1174 - WINDOW_RIGHT_MARGIN_COLS (w) 1210 - WINDOW_RIGHT_MARGIN_COLS (w)
1175 - WINDOW_RIGHT_FRINGE_COLS (w)), 1211 - ((WINDOW_RIGHT_FRINGE_WIDTH (w)
1212 + WINDOW_FRAME_COLUMN_WIDTH (w) - 1)
1213 / WINDOW_FRAME_COLUMN_WIDTH (w))),
1176 (WINDOW_BOTTOM_EDGE_LINE (w) 1214 (WINDOW_BOTTOM_EDGE_LINE (w)
1177 - WINDOW_MODE_LINE_LINES (w))); 1215 - WINDOW_MODE_LINE_LINES (w)));
1178} 1216}
@@ -1286,6 +1324,17 @@ coordinates_in_window (register struct window *w, int x, int y)
1286 && x >= right_x - WINDOW_RIGHT_DIVIDER_WIDTH (w) 1324 && x >= right_x - WINDOW_RIGHT_DIVIDER_WIDTH (w)
1287 && x <= right_x) 1325 && x <= right_x)
1288 return ON_RIGHT_DIVIDER; 1326 return ON_RIGHT_DIVIDER;
1327 /* On the horizontal scroll bar? (Including the empty space at its
1328 right!) */
1329 else if ((WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w)
1330 && y >= (bottom_y
1331 - WINDOW_SCROLL_BAR_AREA_HEIGHT (w)
1332 - CURRENT_MODE_LINE_HEIGHT (w)
1333 - WINDOW_BOTTOM_DIVIDER_WIDTH (w))
1334 && y <= (bottom_y
1335 - CURRENT_MODE_LINE_HEIGHT (w)
1336 - WINDOW_BOTTOM_DIVIDER_WIDTH (w))))
1337 return ON_HORIZONTAL_SCROLL_BAR;
1289 /* On the mode or header line? */ 1338 /* On the mode or header line? */
1290 else if ((WINDOW_WANTS_MODELINE_P (w) 1339 else if ((WINDOW_WANTS_MODELINE_P (w)
1291 && y >= (bottom_y 1340 && y >= (bottom_y
@@ -1329,7 +1378,7 @@ coordinates_in_window (register struct window *w, int x, int y)
1329 1378
1330 /* Outside any interesting column? */ 1379 /* Outside any interesting column? */
1331 if (x < left_x || x > right_x) 1380 if (x < left_x || x > right_x)
1332 return ON_SCROLL_BAR; 1381 return ON_VERTICAL_SCROLL_BAR;
1333 1382
1334 lmargin_width = window_box_width (w, LEFT_MARGIN_AREA); 1383 lmargin_width = window_box_width (w, LEFT_MARGIN_AREA);
1335 rmargin_width = window_box_width (w, RIGHT_MARGIN_AREA); 1384 rmargin_width = window_box_width (w, RIGHT_MARGIN_AREA);
@@ -1493,10 +1542,13 @@ If they are in the windows's left or right marginal areas, `left-margin'\n\
1493 case ON_RIGHT_MARGIN: 1542 case ON_RIGHT_MARGIN:
1494 return Qright_margin; 1543 return Qright_margin;
1495 1544
1496 case ON_SCROLL_BAR: 1545 case ON_VERTICAL_SCROLL_BAR:
1497 /* Historically we are supposed to return nil in this case. */ 1546 /* Historically we are supposed to return nil in this case. */
1498 return Qnil; 1547 return Qnil;
1499 1548
1549 case ON_HORIZONTAL_SCROLL_BAR:
1550 return Qnil;
1551
1500 case ON_RIGHT_DIVIDER: 1552 case ON_RIGHT_DIVIDER:
1501 return Qright_divider; 1553 return Qright_divider;
1502 1554
@@ -1637,6 +1689,14 @@ correct to return the top-level value of `point', outside of any
1637 return Fmarker_position (w->pointm); 1689 return Fmarker_position (w->pointm);
1638} 1690}
1639 1691
1692DEFUN ("window-old-point", Fwindow_old_point, Swindow_old_point, 0, 1, 0,
1693 doc: /* Return old value of point in WINDOW.
1694WINDOW must be a live window and defaults to the selected one. */)
1695 (Lisp_Object window)
1696{
1697 return Fmarker_position (decode_live_window (window)->old_pointm);
1698}
1699
1640DEFUN ("window-start", Fwindow_start, Swindow_start, 0, 1, 0, 1700DEFUN ("window-start", Fwindow_start, Swindow_start, 0, 1, 0,
1641 doc: /* Return position at which display currently starts in WINDOW. 1701 doc: /* Return position at which display currently starts in WINDOW.
1642WINDOW must be a live window and defaults to the selected one. 1702WINDOW must be a live window and defaults to the selected one.
@@ -2915,6 +2975,7 @@ selected frame and no others. */)
2915 return Qnil; 2975 return Qnil;
2916} 2976}
2917 2977
2978
2918static Lisp_Object 2979static Lisp_Object
2919resize_root_window (Lisp_Object window, Lisp_Object delta, Lisp_Object horizontal, Lisp_Object ignore, Lisp_Object pixelwise) 2980resize_root_window (Lisp_Object window, Lisp_Object delta, Lisp_Object horizontal, Lisp_Object ignore, Lisp_Object pixelwise)
2920{ 2981{
@@ -2922,10 +2983,17 @@ resize_root_window (Lisp_Object window, Lisp_Object delta, Lisp_Object horizonta
2922} 2983}
2923 2984
2924 2985
2986Lisp_Object
2987sanitize_window_sizes (Lisp_Object frame, Lisp_Object horizontal)
2988{
2989 return call2 (Qwindow_sanitize_window_sizes, frame, horizontal);
2990}
2991
2992
2925static Lisp_Object 2993static Lisp_Object
2926window_pixel_to_total (Lisp_Object frame, Lisp_Object horizontal) 2994window_pixel_to_total (Lisp_Object frame, Lisp_Object horizontal)
2927{ 2995{
2928 return call2(Qwindow_pixel_to_total, frame, horizontal); 2996 return call2 (Qwindow_pixel_to_total, frame, horizontal);
2929} 2997}
2930 2998
2931 2999
@@ -3204,89 +3272,6 @@ replace_buffer_in_windows_safely (Lisp_Object buffer)
3204 window_loop (REPLACE_BUFFER_IN_WINDOWS_SAFELY, buffer, 1, frame); 3272 window_loop (REPLACE_BUFFER_IN_WINDOWS_SAFELY, buffer, 1, frame);
3205 } 3273 }
3206} 3274}
3207
3208/* If *HEIGHT or *WIDTH are too small a size for FRAME, set them to the
3209 minimum allowable size. PIXELWISE means interpret these as pixel
3210 sizes. */
3211
3212void
3213check_frame_size (struct frame *frame, int *width, int *height, bool pixelwise)
3214{
3215 /* For height, we have to see:
3216 how many windows the frame has at minimum (one or two),
3217 and whether it has a menu bar or other special stuff at the top. */
3218 if (pixelwise)
3219 {
3220 int min_height = MIN_SAFE_WINDOW_HEIGHT * FRAME_LINE_HEIGHT (frame);
3221 int min_width = MIN_SAFE_WINDOW_WIDTH * FRAME_COLUMN_WIDTH (frame);
3222
3223 if (!FRAME_MINIBUF_ONLY_P (frame) && FRAME_HAS_MINIBUF_P (frame))
3224 min_height = 2 * min_height;
3225
3226 min_height += FRAME_TOP_MARGIN_HEIGHT (frame);
3227 min_height += FRAME_INTERNAL_BORDER_WIDTH (frame);
3228
3229 if (*height < min_height)
3230 *height = min_height;
3231 if (*width < min_width)
3232 *width = min_width;
3233 }
3234 else
3235 {
3236 int min_height
3237 = ((FRAME_MINIBUF_ONLY_P (frame) || ! FRAME_HAS_MINIBUF_P (frame))
3238 ? MIN_SAFE_WINDOW_HEIGHT
3239 : 2 * MIN_SAFE_WINDOW_HEIGHT);
3240
3241 if (FRAME_TOP_MARGIN (frame) > 0)
3242 min_height += FRAME_TOP_MARGIN (frame);
3243
3244 if (*height < min_height)
3245 *height = min_height;
3246 if (*width < MIN_SAFE_WINDOW_WIDTH)
3247 *width = MIN_SAFE_WINDOW_WIDTH;
3248 }
3249}
3250
3251/* Adjust the margins of window W if text area is too small.
3252 Return 1 if window width is ok after adjustment; 0 if window
3253 is still too narrow. */
3254
3255static int
3256adjust_window_margins (struct window *w)
3257{
3258 int box_width = (WINDOW_PIXEL_WIDTH (w)
3259 - WINDOW_FRINGES_WIDTH (w)
3260 - WINDOW_SCROLL_BAR_AREA_WIDTH (w));
3261 int margin_width = WINDOW_MARGINS_WIDTH (w);
3262
3263 if (box_width - margin_width >= MIN_SAFE_WINDOW_PIXEL_WIDTH (w))
3264 return 1;
3265
3266 if (margin_width < 0 || box_width < MIN_SAFE_WINDOW_PIXEL_WIDTH (w))
3267 return 0;
3268 else
3269 /* Window's text area is too narrow, but reducing the window
3270 margins will fix that. */
3271 {
3272 int unit = WINDOW_FRAME_COLUMN_WIDTH (w);
3273
3274 margin_width = box_width - MIN_SAFE_WINDOW_PIXEL_WIDTH (w);
3275
3276 if (WINDOW_RIGHT_MARGIN_WIDTH (w) > 0)
3277 {
3278 if (WINDOW_LEFT_MARGIN_WIDTH (w) > 0)
3279 w->left_margin_cols = w->right_margin_cols =
3280 margin_width / (2 * unit);
3281 else
3282 w->right_margin_cols = margin_width / unit;
3283 }
3284 else
3285 w->left_margin_cols = margin_width / unit;
3286
3287 return 1;
3288 }
3289}
3290 3275
3291/* The following three routines are needed for running a window's 3276/* The following three routines are needed for running a window's
3292 configuration change hook. */ 3277 configuration change hook. */
@@ -3320,7 +3305,7 @@ run_window_configuration_change_hook (struct frame *f)
3320 = Fdefault_value (Qwindow_configuration_change_hook); 3305 = Fdefault_value (Qwindow_configuration_change_hook);
3321 XSETFRAME (frame, f); 3306 XSETFRAME (frame, f);
3322 3307
3323 if (NILP (Vrun_hooks) || !NILP (inhibit_lisp_code)) 3308 if (NILP (Vrun_hooks) || !(f->official))
3324 return; 3309 return;
3325 3310
3326 /* Use the right buffer. Matters when running the local hooks. */ 3311 /* Use the right buffer. Matters when running the local hooks. */
@@ -3415,17 +3400,21 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer,
3415 w->last_cursor_vpos = 0; 3400 w->last_cursor_vpos = 0;
3416 3401
3417 if (!(keep_margins_p && samebuf)) 3402 if (!(keep_margins_p && samebuf))
3418 { /* If we're not actually changing the buffer, don't reset hscroll and 3403 { /* If we're not actually changing the buffer, don't reset hscroll
3419 vscroll. This case happens for example when called from 3404 and vscroll. This case happens for example when called from
3420 change_frame_size_1, where we use a dummy call to 3405 change_frame_size_1, where we use a dummy call to
3421 Fset_window_buffer on the frame's selected window (and no other) 3406 Fset_window_buffer on the frame's selected window (and no
3422 just in order to run window-configuration-change-hook. 3407 other) just in order to run window-configuration-change-hook
3423 Resetting hscroll and vscroll here is problematic for things like 3408 (no longer true since change_frame_size_1 directly calls
3424 image-mode and doc-view-mode since it resets the image's position 3409 run_window_configuration_change_hook). Resetting hscroll and
3425 whenever we resize the frame. */ 3410 vscroll here is problematic for things like image-mode and
3426 w->hscroll = w->min_hscroll = 0; 3411 doc-view-mode since it resets the image's position whenever we
3412 resize the frame. */
3413 w->hscroll = w->min_hscroll = w->hscroll_whole = 0;
3414 w->suspend_auto_hscroll = 0;
3427 w->vscroll = 0; 3415 w->vscroll = 0;
3428 set_marker_both (w->pointm, buffer, BUF_PT (b), BUF_PT_BYTE (b)); 3416 set_marker_both (w->pointm, buffer, BUF_PT (b), BUF_PT_BYTE (b));
3417 set_marker_both (w->old_pointm, buffer, BUF_PT (b), BUF_PT_BYTE (b));
3429 set_marker_restricted (w->start, 3418 set_marker_restricted (w->start,
3430 make_number (b->last_window_start), 3419 make_number (b->last_window_start),
3431 buffer); 3420 buffer);
@@ -3443,6 +3432,7 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer,
3443 Fset_buffer (buffer); 3432 Fset_buffer (buffer);
3444 3433
3445 XMARKER (w->pointm)->insertion_type = !NILP (Vwindow_point_insertion_type); 3434 XMARKER (w->pointm)->insertion_type = !NILP (Vwindow_point_insertion_type);
3435 XMARKER (w->old_pointm)->insertion_type = !NILP (Vwindow_point_insertion_type);
3446 3436
3447 if (!keep_margins_p) 3437 if (!keep_margins_p)
3448 { 3438 {
@@ -3451,7 +3441,9 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer,
3451 BVAR (b, right_fringe_width), 3441 BVAR (b, right_fringe_width),
3452 BVAR (b, fringes_outside_margins)); 3442 BVAR (b, fringes_outside_margins));
3453 set_window_scroll_bars (w, BVAR (b, scroll_bar_width), 3443 set_window_scroll_bars (w, BVAR (b, scroll_bar_width),
3454 BVAR (b, vertical_scroll_bar_type), Qnil); 3444 BVAR (b, vertical_scroll_bar_type),
3445 BVAR (b, scroll_bar_height),
3446 BVAR (b, horizontal_scroll_bar_type));
3455 set_window_margins (w, BVAR (b, left_margin_cols), 3447 set_window_margins (w, BVAR (b, left_margin_cols),
3456 BVAR (b, right_margin_cols)); 3448 BVAR (b, right_margin_cols));
3457 apply_window_adjustment (w); 3449 apply_window_adjustment (w);
@@ -3597,10 +3589,11 @@ temp_output_buffer_show (register Lisp_Object buf)
3597 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window))); 3589 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window)));
3598 Vminibuf_scroll_window = window; 3590 Vminibuf_scroll_window = window;
3599 w = XWINDOW (window); 3591 w = XWINDOW (window);
3600 w->hscroll = 0; 3592 w->hscroll = w->min_hscroll = w->hscroll_whole = 0;
3601 w->min_hscroll = 0; 3593 w->suspend_auto_hscroll = 0;
3602 set_marker_restricted_both (w->start, buf, BEG, BEG); 3594 set_marker_restricted_both (w->start, buf, BEG, BEG);
3603 set_marker_restricted_both (w->pointm, buf, BEG, BEG); 3595 set_marker_restricted_both (w->pointm, buf, BEG, BEG);
3596 set_marker_restricted_both (w->old_pointm, buf, BEG, BEG);
3604 3597
3605 /* Run temp-buffer-show-hook, with the chosen window selected 3598 /* Run temp-buffer-show-hook, with the chosen window selected
3606 and its buffer current. */ 3599 and its buffer current. */
@@ -3652,6 +3645,7 @@ make_parent_window (Lisp_Object window, bool horflag)
3652 /* ...but now P becomes an internal window. */ 3645 /* ...but now P becomes an internal window. */
3653 wset_start (p, Qnil); 3646 wset_start (p, Qnil);
3654 wset_pointm (p, Qnil); 3647 wset_pointm (p, Qnil);
3648 wset_old_pointm (p, Qnil);
3655 wset_buffer (p, Qnil); 3649 wset_buffer (p, Qnil);
3656 wset_combination (p, horflag, window); 3650 wset_combination (p, horflag, window);
3657 wset_combination_limit (p, Qnil); 3651 wset_combination_limit (p, Qnil);
@@ -3675,7 +3669,9 @@ make_window (void)
3675 wset_new_pixel (w, make_number (0)); 3669 wset_new_pixel (w, make_number (0));
3676 wset_start (w, Fmake_marker ()); 3670 wset_start (w, Fmake_marker ());
3677 wset_pointm (w, Fmake_marker ()); 3671 wset_pointm (w, Fmake_marker ());
3672 wset_old_pointm (w, Fmake_marker ());
3678 wset_vertical_scroll_bar_type (w, Qt); 3673 wset_vertical_scroll_bar_type (w, Qt);
3674 wset_horizontal_scroll_bar_type (w, Qt);
3679 /* These Lisp fields are marked specially so they're not set to nil by 3675 /* These Lisp fields are marked specially so they're not set to nil by
3680 allocate_window. */ 3676 allocate_window. */
3681 wset_prev_buffers (w, Qnil); 3677 wset_prev_buffers (w, Qnil);
@@ -3692,8 +3688,8 @@ make_window (void)
3692#endif 3688#endif
3693 w->sequence_number = ++sequence_number; 3689 w->sequence_number = ++sequence_number;
3694 w->scroll_bar_width = -1; 3690 w->scroll_bar_width = -1;
3691 w->scroll_bar_height = -1;
3695 w->column_number_displayed = -1; 3692 w->column_number_displayed = -1;
3696
3697 /* Reset window_list. */ 3693 /* Reset window_list. */
3698 Vwindow_list = Qnil; 3694 Vwindow_list = Qnil;
3699 /* Return window. */ 3695 /* Return window. */
@@ -3943,11 +3939,8 @@ window_resize_apply (struct window *w, bool horflag)
3943 } 3939 }
3944 } 3940 }
3945 else 3941 else
3946 { 3942 /* Bug#15957. */
3947 adjust_window_margins (w); 3943 w->window_end_valid = 0;
3948 /* Bug#15957. */
3949 w->window_end_valid = 0;
3950 }
3951} 3944}
3952 3945
3953 3946
@@ -4107,6 +4100,7 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
4107 /* old_size is the old size of the frame's root window. */ 4100 /* old_size is the old size of the frame's root window. */
4108 int old_size = horflag ? r->total_cols : r->total_lines; 4101 int old_size = horflag ? r->total_cols : r->total_lines;
4109 int old_pixel_size = horflag ? r->pixel_width : r->pixel_height; 4102 int old_pixel_size = horflag ? r->pixel_width : r->pixel_height;
4103 int old_pixel_top = r->pixel_top;
4110 /* new_size is the new size of the frame's root window. */ 4104 /* new_size is the new size of the frame's root window. */
4111 int new_size, new_pixel_size; 4105 int new_size, new_pixel_size;
4112 int unit = horflag ? FRAME_COLUMN_WIDTH (f) : FRAME_LINE_HEIGHT (f); 4106 int unit = horflag ? FRAME_COLUMN_WIDTH (f) : FRAME_LINE_HEIGHT (f);
@@ -4121,7 +4115,7 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
4121 new_pixel_size = max (horflag 4115 new_pixel_size = max (horflag
4122 ? size 4116 ? size
4123 : (size 4117 : (size
4124 - FRAME_TOP_MARGIN_HEIGHT (f) 4118/** - FRAME_TOP_MARGIN_HEIGHT (f) **/
4125 - ((FRAME_HAS_MINIBUF_P (f) 4119 - ((FRAME_HAS_MINIBUF_P (f)
4126 && !FRAME_MINIBUF_ONLY_P (f)) 4120 && !FRAME_MINIBUF_ONLY_P (f))
4127 ? FRAME_LINE_HEIGHT (f) : 0)), 4121 ? FRAME_LINE_HEIGHT (f) : 0)),
@@ -4133,7 +4127,7 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
4133 new_size = max (horflag 4127 new_size = max (horflag
4134 ? size 4128 ? size
4135 : (size 4129 : (size
4136 - FRAME_TOP_MARGIN (f) 4130/** - FRAME_TOP_MARGIN (f) **/
4137 - ((FRAME_HAS_MINIBUF_P (f) 4131 - ((FRAME_HAS_MINIBUF_P (f)
4138 && !FRAME_MINIBUF_ONLY_P (f)) 4132 && !FRAME_MINIBUF_ONLY_P (f))
4139 ? 1 : 0)), 4133 ? 1 : 0)),
@@ -4144,7 +4138,8 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
4144 r->top_line = FRAME_TOP_MARGIN (f); 4138 r->top_line = FRAME_TOP_MARGIN (f);
4145 r->pixel_top = FRAME_TOP_MARGIN_HEIGHT (f); 4139 r->pixel_top = FRAME_TOP_MARGIN_HEIGHT (f);
4146 4140
4147 if (new_pixel_size == old_pixel_size) 4141 if (new_pixel_size == old_pixel_size
4142 && r->pixel_top == old_pixel_top)
4148 ; 4143 ;
4149 else if (WINDOW_LEAF_P (r)) 4144 else if (WINDOW_LEAF_P (r))
4150 /* For a leaf root window just set the size. */ 4145 /* For a leaf root window just set the size. */
@@ -4186,6 +4181,7 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
4186 { 4181 {
4187 window_resize_apply (r, horflag); 4182 window_resize_apply (r, horflag);
4188 window_pixel_to_total (r->frame, horflag ? Qt : Qnil); 4183 window_pixel_to_total (r->frame, horflag ? Qt : Qnil);
4184#if 0 /* Let's try without safe sizes and/or killing other windows. */
4189 } 4185 }
4190 else 4186 else
4191 { 4187 {
@@ -4198,7 +4194,6 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
4198 window_resize_apply (r, horflag); 4194 window_resize_apply (r, horflag);
4199 window_pixel_to_total (r->frame, horflag ? Qt : Qnil); 4195 window_pixel_to_total (r->frame, horflag ? Qt : Qnil);
4200 } 4196 }
4201#if 0 /* Let's try without killing other windows. */
4202 else 4197 else
4203 { 4198 {
4204 /* We lost. Delete all windows but the frame's 4199 /* We lost. Delete all windows but the frame's
@@ -4402,7 +4397,9 @@ set correctly. See the code of `split-window' for how this is done. */)
4402 n->right_fringe_width = r->right_fringe_width; 4397 n->right_fringe_width = r->right_fringe_width;
4403 n->fringes_outside_margins = r->fringes_outside_margins; 4398 n->fringes_outside_margins = r->fringes_outside_margins;
4404 n->scroll_bar_width = r->scroll_bar_width; 4399 n->scroll_bar_width = r->scroll_bar_width;
4400 n->scroll_bar_height = r->scroll_bar_height;
4405 wset_vertical_scroll_bar_type (n, r->vertical_scroll_bar_type); 4401 wset_vertical_scroll_bar_type (n, r->vertical_scroll_bar_type);
4402 wset_horizontal_scroll_bar_type (n, r->horizontal_scroll_bar_type);
4406 4403
4407 /* Directly assign orthogonal coordinates and sizes. */ 4404 /* Directly assign orthogonal coordinates and sizes. */
4408 if (horflag) 4405 if (horflag)
@@ -4546,6 +4543,7 @@ Signal an error when WINDOW is the only window on its frame. */)
4546 { 4543 {
4547 unshow_buffer (w); 4544 unshow_buffer (w);
4548 unchain_marker (XMARKER (w->pointm)); 4545 unchain_marker (XMARKER (w->pointm));
4546 unchain_marker (XMARKER (w->old_pointm));
4549 unchain_marker (XMARKER (w->start)); 4547 unchain_marker (XMARKER (w->start));
4550 wset_buffer (w, Qnil); 4548 wset_buffer (w, Qnil);
4551 } 4549 }
@@ -4807,6 +4805,7 @@ window_internal_height (struct window *w)
4807 4805
4808 return ht; 4806 return ht;
4809} 4807}
4808
4810 4809
4811/************************************************************************ 4810/************************************************************************
4812 Window Scrolling 4811 Window Scrolling
@@ -4857,6 +4856,8 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, int noerror)
4857 void *itdata = NULL; 4856 void *itdata = NULL;
4858 int window_total_lines; 4857 int window_total_lines;
4859 int frame_line_height = default_line_pixel_height (w); 4858 int frame_line_height = default_line_pixel_height (w);
4859 bool adjust_old_pointm = !NILP (Fequal (Fwindow_point (window),
4860 Fwindow_old_point (window)));
4860 4861
4861 SET_TEXT_POS_FROM_MARKER (start, w->start); 4862 SET_TEXT_POS_FROM_MARKER (start, w->start);
4862 /* Scrolling a minibuffer window via scroll bar when the echo area 4863 /* Scrolling a minibuffer window via scroll bar when the echo area
@@ -4985,6 +4986,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, int noerror)
4985 { 4986 {
4986 ptrdiff_t start_pos = IT_CHARPOS (it); 4987 ptrdiff_t start_pos = IT_CHARPOS (it);
4987 int dy = frame_line_height; 4988 int dy = frame_line_height;
4989
4988 dy = max ((window_box_height (w) 4990 dy = max ((window_box_height (w)
4989 - next_screen_context_lines * dy), 4991 - next_screen_context_lines * dy),
4990 dy) * n; 4992 dy) * n;
@@ -5228,6 +5230,13 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, int noerror)
5228 } 5230 }
5229 } 5231 }
5230 bidi_unshelve_cache (itdata, 0); 5232 bidi_unshelve_cache (itdata, 0);
5233
5234 if (adjust_old_pointm)
5235 Fset_marker (w->old_pointm,
5236 ((w == XWINDOW (selected_window))
5237 ? make_number (BUF_PT (XBUFFER (w->contents)))
5238 : Fmarker_position (w->pointm)),
5239 w->contents);
5231} 5240}
5232 5241
5233 5242
@@ -5252,6 +5261,8 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, int noerror)
5252 ptrdiff_t startpos = marker_position (w->start); 5261 ptrdiff_t startpos = marker_position (w->start);
5253 ptrdiff_t startbyte = marker_byte_position (w->start); 5262 ptrdiff_t startbyte = marker_byte_position (w->start);
5254 Lisp_Object original_pos = Qnil; 5263 Lisp_Object original_pos = Qnil;
5264 bool adjust_old_pointm = !NILP (Fequal (Fwindow_point (window),
5265 Fwindow_old_point (window)));
5255 5266
5256 /* If scrolling screen-fulls, compute the number of lines to 5267 /* If scrolling screen-fulls, compute the number of lines to
5257 scroll from the window's height. */ 5268 scroll from the window's height. */
@@ -5267,6 +5278,7 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, int noerror)
5267 struct position posit 5278 struct position posit
5268 = *compute_motion (startpos, startbyte, 0, 0, 0, 5279 = *compute_motion (startpos, startbyte, 0, 0, 0,
5269 PT, ht, 0, -1, w->hscroll, 0, w); 5280 PT, ht, 0, -1, w->hscroll, 0, w);
5281
5270 window_scroll_preserve_vpos = posit.vpos; 5282 window_scroll_preserve_vpos = posit.vpos;
5271 window_scroll_preserve_hpos = posit.hpos + w->hscroll; 5283 window_scroll_preserve_hpos = posit.hpos + w->hscroll;
5272 } 5284 }
@@ -5382,6 +5394,13 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, int noerror)
5382 else 5394 else
5383 xsignal0 (Qend_of_buffer); 5395 xsignal0 (Qend_of_buffer);
5384 } 5396 }
5397
5398 if (adjust_old_pointm)
5399 Fset_marker (w->old_pointm,
5400 ((w == XWINDOW (selected_window))
5401 ? make_number (BUF_PT (XBUFFER (w->contents)))
5402 : Fmarker_position (w->pointm)),
5403 w->contents);
5385} 5404}
5386 5405
5387 5406
@@ -5518,6 +5537,7 @@ specifies the window to scroll. This takes precedence over
5518 5537
5519 Fset_buffer (w->contents); 5538 Fset_buffer (w->contents);
5520 SET_PT_BOTH (marker_position (w->pointm), marker_byte_position (w->pointm)); 5539 SET_PT_BOTH (marker_position (w->pointm), marker_byte_position (w->pointm));
5540 SET_PT_BOTH (marker_position (w->old_pointm), marker_byte_position (w->old_pointm));
5521 5541
5522 if (NILP (arg)) 5542 if (NILP (arg))
5523 window_scroll (window, 1, 1, 1); 5543 window_scroll (window, 1, 1, 1);
@@ -5532,6 +5552,7 @@ specifies the window to scroll. This takes precedence over
5532 } 5552 }
5533 5553
5534 set_marker_both (w->pointm, Qnil, PT, PT_BYTE); 5554 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
5555 set_marker_both (w->old_pointm, Qnil, PT, PT_BYTE);
5535 unbind_to (count, Qnil); 5556 unbind_to (count, Qnil);
5536 5557
5537 return Qnil; 5558 return Qnil;
@@ -5557,6 +5578,8 @@ by this function. This happens in an interactive call. */)
5557 if (!NILP (set_minimum)) 5578 if (!NILP (set_minimum))
5558 w->min_hscroll = w->hscroll; 5579 w->min_hscroll = w->hscroll;
5559 5580
5581 w->suspend_auto_hscroll = 1;
5582
5560 return result; 5583 return result;
5561} 5584}
5562 5585
@@ -5580,6 +5603,8 @@ by this function. This happens in an interactive call. */)
5580 if (!NILP (set_minimum)) 5603 if (!NILP (set_minimum))
5581 w->min_hscroll = w->hscroll; 5604 w->min_hscroll = w->hscroll;
5582 5605
5606 w->suspend_auto_hscroll = 1;
5607
5583 return result; 5608 return result;
5584} 5609}
5585 5610
@@ -5677,7 +5702,7 @@ and redisplay normally--don't erase and redraw the frame. */)
5677 5702
5678 if (buf != current_buffer) 5703 if (buf != current_buffer)
5679 error ("`recenter'ing a window that does not display current-buffer."); 5704 error ("`recenter'ing a window that does not display current-buffer.");
5680 5705
5681 /* If redisplay is suppressed due to an error, try again. */ 5706 /* If redisplay is suppressed due to an error, try again. */
5682 buf->display_error_modiff = 0; 5707 buf->display_error_modiff = 0;
5683 5708
@@ -5847,34 +5872,46 @@ and redisplay normally--don't erase and redraw the frame. */)
5847} 5872}
5848 5873
5849DEFUN ("window-text-width", Fwindow_text_width, Swindow_text_width, 5874DEFUN ("window-text-width", Fwindow_text_width, Swindow_text_width,
5850 0, 1, 0, 5875 0, 2, 0,
5851 doc: /* Return the width in columns of the text display area of WINDOW. 5876 doc: /* Return the width in columns of the text display area of WINDOW.
5852WINDOW must be a live window and defaults to the selected one. 5877WINDOW must be a live window and defaults to the selected one.
5853 5878
5854The returned width does not include dividers, scrollbars, margins, 5879The returned width does not include dividers, scrollbars, margins,
5855fringes, nor any partial-width columns at the right of the text 5880fringes, nor any partial-width columns at the right of the text
5856area. */) 5881area.
5857 (Lisp_Object window) 5882
5883Optional argument PIXELWISE non-nil, means to return the width in
5884pixels. */)
5885 (Lisp_Object window, Lisp_Object pixelwise)
5858{ 5886{
5859 struct window *w = decode_live_window (window); 5887 struct window *w = decode_live_window (window);
5860 5888
5861 return make_number (window_box_width (w, TEXT_AREA) 5889 if (NILP (pixelwise))
5862 / FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w))); 5890 return make_number (window_box_width (w, TEXT_AREA)
5891 / FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w)));
5892 else
5893 return make_number (window_box_width (w, TEXT_AREA));
5863} 5894}
5864 5895
5865DEFUN ("window-text-height", Fwindow_text_height, Swindow_text_height, 5896DEFUN ("window-text-height", Fwindow_text_height, Swindow_text_height,
5866 0, 1, 0, 5897 0, 2, 0,
5867 doc: /* Return the height in lines of the text display area of WINDOW. 5898 doc: /* Return the height in lines of the text display area of WINDOW.
5868WINDOW must be a live window and defaults to the selected one. 5899WINDOW must be a live window and defaults to the selected one.
5869 5900
5870The returned height does not include dividers, the mode line, any header 5901The returned height does not include dividers, the mode line, any header
5871line, nor any partial-height lines at the bottom of the text area. */) 5902line, nor any partial-height lines at the bottom of the text area.
5872 (Lisp_Object window) 5903
5904Optional argument PIXELWISE non-nil, means to return the height in
5905pixels. */)
5906 (Lisp_Object window, Lisp_Object pixelwise)
5873{ 5907{
5874 struct window *w = decode_live_window (window); 5908 struct window *w = decode_live_window (window);
5875 5909
5876 return make_number (window_box_height (w) 5910 if (NILP (pixelwise))
5877 / FRAME_LINE_HEIGHT (WINDOW_XFRAME (w))); 5911 return make_number (window_box_height (w)
5912 / FRAME_LINE_HEIGHT (WINDOW_XFRAME (w)));
5913 else
5914 return make_number (window_box_height (w));
5878} 5915}
5879 5916
5880DEFUN ("move-to-window-line", Fmove_to_window_line, Smove_to_window_line, 5917DEFUN ("move-to-window-line", Fmove_to_window_line, Smove_to_window_line,
@@ -5984,17 +6021,18 @@ struct saved_window
5984{ 6021{
5985 struct vectorlike_header header; 6022 struct vectorlike_header header;
5986 6023
5987 Lisp_Object window, buffer, start, pointm; 6024 Lisp_Object window, buffer, start, pointm, old_pointm;
5988 Lisp_Object pixel_left, pixel_top, pixel_height, pixel_width; 6025 Lisp_Object pixel_left, pixel_top, pixel_height, pixel_width;
5989 Lisp_Object left_col, top_line, total_cols, total_lines; 6026 Lisp_Object left_col, top_line, total_cols, total_lines;
5990 Lisp_Object normal_cols, normal_lines; 6027 Lisp_Object normal_cols, normal_lines;
5991 Lisp_Object hscroll, min_hscroll; 6028 Lisp_Object hscroll, min_hscroll, hscroll_whole, suspend_auto_hscroll;
5992 Lisp_Object parent, prev; 6029 Lisp_Object parent, prev;
5993 Lisp_Object start_at_line_beg; 6030 Lisp_Object start_at_line_beg;
5994 Lisp_Object display_table; 6031 Lisp_Object display_table;
5995 Lisp_Object left_margin_cols, right_margin_cols; 6032 Lisp_Object left_margin_cols, right_margin_cols;
5996 Lisp_Object left_fringe_width, right_fringe_width, fringes_outside_margins; 6033 Lisp_Object left_fringe_width, right_fringe_width, fringes_outside_margins;
5997 Lisp_Object scroll_bar_width, vertical_scroll_bar_type, dedicated; 6034 Lisp_Object scroll_bar_width, vertical_scroll_bar_type, dedicated;
6035 Lisp_Object scroll_bar_height, horizontal_scroll_bar_type;
5998 Lisp_Object combination_limit, window_parameters; 6036 Lisp_Object combination_limit, window_parameters;
5999}; 6037};
6000 6038
@@ -6022,13 +6060,359 @@ DEFUN ("window-configuration-frame", Fwindow_configuration_frame, Swindow_config
6022 return XWINDOW (SAVED_WINDOW_N (saved_windows, 0)->window)->frame; 6060 return XWINDOW (SAVED_WINDOW_N (saved_windows, 0)->window)->frame;
6023} 6061}
6024 6062
6025/* From Chong's unwind_create_frame_1. */ 6063DEFUN ("set-window-configuration", Fset_window_configuration,
6026static void 6064 Sset_window_configuration, 1, 1, 0,
6027unwind_change_frame (Lisp_Object val) 6065 doc: /* Set the configuration of windows and buffers as specified by CONFIGURATION.
6066CONFIGURATION must be a value previously returned
6067by `current-window-configuration' (which see).
6068If CONFIGURATION was made from a frame that is now deleted,
6069only frame-independent values can be restored. In this case,
6070the return value is nil. Otherwise the value is t. */)
6071 (Lisp_Object configuration)
6028{ 6072{
6029 inhibit_lisp_code = val; 6073 register struct save_window_data *data;
6074 struct Lisp_Vector *saved_windows;
6075 Lisp_Object new_current_buffer;
6076 Lisp_Object frame;
6077 struct frame *f;
6078 ptrdiff_t old_point = -1;
6079
6080 CHECK_WINDOW_CONFIGURATION (configuration);
6081
6082 data = (struct save_window_data *) XVECTOR (configuration);
6083 saved_windows = XVECTOR (data->saved_windows);
6084
6085 new_current_buffer = data->current_buffer;
6086 if (!BUFFER_LIVE_P (XBUFFER (new_current_buffer)))
6087 new_current_buffer = Qnil;
6088 else
6089 {
6090 if (XBUFFER (new_current_buffer) == current_buffer)
6091 /* The code further down "preserves point" by saving here PT in
6092 old_point and then setting it later back into PT. When the
6093 current-selected-window and the final-selected-window both show
6094 the current buffer, this suffers from the problem that the
6095 current PT is the window-point of the current-selected-window,
6096 while the final PT is the point of the final-selected-window, so
6097 this copy from one PT to the other would end up moving the
6098 window-point of the final-selected-window to the window-point of
6099 the current-selected-window. So we have to be careful which
6100 point of the current-buffer we copy into old_point. */
6101 if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer)
6102 && WINDOWP (selected_window)
6103 && EQ (XWINDOW (selected_window)->contents, new_current_buffer)
6104 && !EQ (selected_window, data->current_window))
6105 old_point = marker_position (XWINDOW (data->current_window)->pointm);
6106 else
6107 old_point = PT;
6108 else
6109 /* BUF_PT (XBUFFER (new_current_buffer)) gives us the position of
6110 point in new_current_buffer as of the last time this buffer was
6111 used. This can be non-deterministic since it can be changed by
6112 things like jit-lock by mere temporary selection of some random
6113 window that happens to show this buffer.
6114 So if possible we want this arbitrary choice of "which point" to
6115 be the one from the to-be-selected-window so as to prevent this
6116 window's cursor from being copied from another window. */
6117 if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer)
6118 /* If current_window = selected_window, its point is in BUF_PT. */
6119 && !EQ (selected_window, data->current_window))
6120 old_point = marker_position (XWINDOW (data->current_window)->pointm);
6121 else
6122 old_point = BUF_PT (XBUFFER (new_current_buffer));
6123 }
6124
6125 frame = XWINDOW (SAVED_WINDOW_N (saved_windows, 0)->window)->frame;
6126 f = XFRAME (frame);
6127
6128 /* If f is a dead frame, don't bother rebuilding its window tree.
6129 However, there is other stuff we should still try to do below. */
6130 if (FRAME_LIVE_P (f))
6131 {
6132 Lisp_Object window;
6133 Lisp_Object dead_windows = Qnil;
6134 register Lisp_Object tem, par, pers;
6135 register struct window *w;
6136 register struct saved_window *p;
6137 struct window *root_window;
6138 struct window **leaf_windows;
6139 int n_leaf_windows;
6140 ptrdiff_t k;
6141 int i, n;
6142
6143 /* Don't do this within the main loop below: This may call Lisp
6144 code and is thus potentially unsafe while input is blocked. */
6145 for (k = 0; k < saved_windows->header.size; k++)
6146 {
6147 p = SAVED_WINDOW_N (saved_windows, k);
6148 window = p->window;
6149 w = XWINDOW (window);
6150 if (BUFFERP (w->contents)
6151 && !EQ (w->contents, p->buffer)
6152 && BUFFER_LIVE_P (XBUFFER (p->buffer)))
6153 /* If a window we restore gets another buffer, record the
6154 window's old buffer. */
6155 call1 (Qrecord_window_buffer, window);
6156 }
6157
6158 /* Consider frame unofficial, temporarily. */
6159 f->official = false;
6160 /* The mouse highlighting code could get screwed up
6161 if it runs during this. */
6162 block_input ();
6163
6164 /* "Swap out" point from the selected window's buffer
6165 into the window itself. (Normally the pointm of the selected
6166 window holds garbage.) We do this now, before
6167 restoring the window contents, and prevent it from
6168 being done later on when we select a new window. */
6169 if (! NILP (XWINDOW (selected_window)->contents))
6170 {
6171 w = XWINDOW (selected_window);
6172 set_marker_both (w->pointm,
6173 w->contents,
6174 BUF_PT (XBUFFER (w->contents)),
6175 BUF_PT_BYTE (XBUFFER (w->contents)));
6176 }
6177
6178 fset_redisplay (f);
6179 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
6180
6181 /* Problem: Freeing all matrices and later allocating them again
6182 is a serious redisplay flickering problem. What we would
6183 really like to do is to free only those matrices not reused
6184 below. */
6185 root_window = XWINDOW (FRAME_ROOT_WINDOW (f));
6186 leaf_windows = alloca (count_windows (root_window)
6187 * sizeof *leaf_windows);
6188 n_leaf_windows = get_leaf_windows (root_window, leaf_windows, 0);
6189
6190 /* Kludge Alert!
6191 Mark all windows now on frame as "deleted".
6192 Restoring the new configuration "undeletes" any that are in it.
6193
6194 Save their current buffers in their height fields, since we may
6195 need it later, if a buffer saved in the configuration is now
6196 dead. */
6197 delete_all_child_windows (FRAME_ROOT_WINDOW (f));
6198
6199 for (k = 0; k < saved_windows->header.size; k++)
6200 {
6201 p = SAVED_WINDOW_N (saved_windows, k);
6202 window = p->window;
6203 w = XWINDOW (window);
6204 wset_next (w, Qnil);
6205
6206 if (!NILP (p->parent))
6207 wset_parent
6208 (w, SAVED_WINDOW_N (saved_windows, XFASTINT (p->parent))->window);
6209 else
6210 wset_parent (w, Qnil);
6211
6212 if (!NILP (p->prev))
6213 {
6214 wset_prev
6215 (w, SAVED_WINDOW_N (saved_windows, XFASTINT (p->prev))->window);
6216 wset_next (XWINDOW (w->prev), p->window);
6217 }
6218 else
6219 {
6220 wset_prev (w, Qnil);
6221 if (!NILP (w->parent))
6222 wset_combination (XWINDOW (w->parent),
6223 (XINT (p->total_cols)
6224 != XWINDOW (w->parent)->total_cols),
6225 p->window);
6226 }
6227
6228 /* If we squirreled away the buffer, restore it now. */
6229 if (BUFFERP (w->combination_limit))
6230 wset_buffer (w, w->combination_limit);
6231 w->pixel_left = XFASTINT (p->pixel_left);
6232 w->pixel_top = XFASTINT (p->pixel_top);
6233 w->pixel_width = XFASTINT (p->pixel_width);
6234 w->pixel_height = XFASTINT (p->pixel_height);
6235 w->left_col = XFASTINT (p->left_col);
6236 w->top_line = XFASTINT (p->top_line);
6237 w->total_cols = XFASTINT (p->total_cols);
6238 w->total_lines = XFASTINT (p->total_lines);
6239 wset_normal_cols (w, p->normal_cols);
6240 wset_normal_lines (w, p->normal_lines);
6241 w->hscroll = XFASTINT (p->hscroll);
6242 w->suspend_auto_hscroll = !NILP (p->suspend_auto_hscroll);
6243 w->min_hscroll = XFASTINT (p->min_hscroll);
6244 w->hscroll_whole = XFASTINT (p->hscroll_whole);
6245 wset_display_table (w, p->display_table);
6246 w->left_margin_cols = XINT (p->left_margin_cols);
6247 w->right_margin_cols = XINT (p->right_margin_cols);
6248 w->left_fringe_width = XINT (p->left_fringe_width);
6249 w->right_fringe_width = XINT (p->right_fringe_width);
6250 w->fringes_outside_margins = !NILP (p->fringes_outside_margins);
6251 w->scroll_bar_width = XINT (p->scroll_bar_width);
6252 w->scroll_bar_height = XINT (p->scroll_bar_height);
6253 wset_vertical_scroll_bar_type (w, p->vertical_scroll_bar_type);
6254 wset_horizontal_scroll_bar_type (w, p->horizontal_scroll_bar_type);
6255 wset_dedicated (w, p->dedicated);
6256 wset_combination_limit (w, p->combination_limit);
6257 /* Restore any window parameters that have been saved.
6258 Parameters that have not been saved are left alone. */
6259 for (tem = p->window_parameters; CONSP (tem); tem = XCDR (tem))
6260 {
6261 pers = XCAR (tem);
6262 if (CONSP (pers))
6263 {
6264 if (NILP (XCDR (pers)))
6265 {
6266 par = Fassq (XCAR (pers), w->window_parameters);
6267 if (CONSP (par) && !NILP (XCDR (par)))
6268 /* Reset a parameter to nil if and only if it
6269 has a non-nil association. Don't make new
6270 associations. */
6271 Fsetcdr (par, Qnil);
6272 }
6273 else
6274 /* Always restore a non-nil value. */
6275 Fset_window_parameter (window, XCAR (pers), XCDR (pers));
6276 }
6277 }
6278
6279 if (BUFFERP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer)))
6280 /* If saved buffer is alive, install it. */
6281 {
6282 wset_buffer (w, p->buffer);
6283 w->start_at_line_beg = !NILP (p->start_at_line_beg);
6284 set_marker_restricted (w->start, p->start, w->contents);
6285 set_marker_restricted (w->pointm, p->pointm, w->contents);
6286 set_marker_restricted (w->old_pointm, p->old_pointm, w->contents);
6287 /* As documented in Fcurrent_window_configuration, don't
6288 restore the location of point in the buffer which was
6289 current when the window configuration was recorded. */
6290 if (!EQ (p->buffer, new_current_buffer)
6291 && XBUFFER (p->buffer) == current_buffer)
6292 Fgoto_char (w->pointm);
6293 }
6294 else if (BUFFERP (w->contents) && BUFFER_LIVE_P (XBUFFER (w->contents)))
6295 /* Keep window's old buffer; make sure the markers are real. */
6296 {
6297 /* Set window markers at start of visible range. */
6298 if (XMARKER (w->start)->buffer == 0)
6299 set_marker_restricted_both (w->start, w->contents, 0, 0);
6300 if (XMARKER (w->pointm)->buffer == 0)
6301 set_marker_restricted_both
6302 (w->pointm, w->contents,
6303 BUF_PT (XBUFFER (w->contents)),
6304 BUF_PT_BYTE (XBUFFER (w->contents)));
6305 if (XMARKER (w->old_pointm)->buffer == 0)
6306 set_marker_restricted_both
6307 (w->old_pointm, w->contents,
6308 BUF_PT (XBUFFER (w->contents)),
6309 BUF_PT_BYTE (XBUFFER (w->contents)));
6310 w->start_at_line_beg = 1;
6311 }
6312 else if (!NILP (w->start))
6313 /* Leaf window has no live buffer, get one. */
6314 {
6315 /* Get the buffer via other_buffer_safely in order to
6316 avoid showing an unimportant buffer and, if necessary, to
6317 recreate *scratch* in the course (part of Juanma's bs-show
6318 scenario from March 2011). */
6319 wset_buffer (w, other_buffer_safely (Fcurrent_buffer ()));
6320 /* This will set the markers to beginning of visible
6321 range. */
6322 set_marker_restricted_both (w->start, w->contents, 0, 0);
6323 set_marker_restricted_both (w->pointm, w->contents, 0, 0);
6324 set_marker_restricted_both (w->old_pointm, w->contents, 0, 0);
6325 w->start_at_line_beg = 1;
6326 if (!NILP (w->dedicated))
6327 /* Record this window as dead. */
6328 dead_windows = Fcons (window, dead_windows);
6329 /* Make sure window is no more dedicated. */
6330 wset_dedicated (w, Qnil);
6331 }
6332 }
6333
6334 fset_root_window (f, data->root_window);
6335 /* Arrange *not* to restore point in the buffer that was
6336 current when the window configuration was saved. */
6337 if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer))
6338 set_marker_restricted (XWINDOW (data->current_window)->pointm,
6339 make_number (old_point),
6340 XWINDOW (data->current_window)->contents);
6341
6342 /* In the following call to `select-window', prevent "swapping out
6343 point" in the old selected window using the buffer that has
6344 been restored into it. We already swapped out that point from
6345 that window's old buffer.
6346
6347 Do not record the buffer here. We do that in a separate call
6348 to select_window below. See also Bug#16207. */
6349 select_window (data->current_window, Qt, 1);
6350 BVAR (XBUFFER (XWINDOW (selected_window)->contents),
6351 last_selected_window)
6352 = selected_window;
6353
6354 if (NILP (data->focus_frame)
6355 || (FRAMEP (data->focus_frame)
6356 && FRAME_LIVE_P (XFRAME (data->focus_frame))))
6357 Fredirect_frame_focus (frame, data->focus_frame);
6358
6359 /* Now, free glyph matrices in windows that were not reused. */
6360 for (i = n = 0; i < n_leaf_windows; ++i)
6361 {
6362 if (NILP (leaf_windows[i]->contents))
6363 free_window_matrices (leaf_windows[i]);
6364 else if (EQ (leaf_windows[i]->contents, new_current_buffer))
6365 ++n;
6366 }
6367
6368 /* Make frame official again and apply frame size changes if
6369 needed. */
6370 f->official = true;
6371 adjust_frame_size (f, -1, -1, 1, 0);
6372
6373 adjust_frame_glyphs (f);
6374 unblock_input ();
6375
6376 /* Scan dead buffer windows. */
6377 for (; CONSP (dead_windows); dead_windows = XCDR (dead_windows))
6378 {
6379 window = XCAR (dead_windows);
6380 if (WINDOW_LIVE_P (window) && !EQ (window, FRAME_ROOT_WINDOW (f)))
6381 delete_deletable_window (window);
6382 }
6383
6384 /* Record the selected window's buffer here. The window should
6385 already be the selected one from the call above. */
6386 select_window (data->current_window, Qnil, 0);
6387
6388 /* Fselect_window will have made f the selected frame, so we
6389 reselect the proper frame here. Fhandle_switch_frame will change the
6390 selected window too, but that doesn't make the call to
6391 Fselect_window above totally superfluous; it still sets f's
6392 selected window. */
6393 if (FRAME_LIVE_P (XFRAME (data->selected_frame)))
6394 do_switch_frame (data->selected_frame, 0, 0, Qnil);
6395
6396 run_window_configuration_change_hook (f);
6397 }
6398
6399 if (!NILP (new_current_buffer))
6400 {
6401 Fset_buffer (new_current_buffer);
6402 /* If the new current buffer doesn't appear in the selected
6403 window, go to its old point (see bug#12208). */
6404 if (!EQ (XWINDOW (data->current_window)->contents, new_current_buffer))
6405 Fgoto_char (make_number (old_point));
6406 }
6407
6408 Vminibuf_scroll_window = data->minibuf_scroll_window;
6409 minibuf_selected_window = data->minibuf_selected_window;
6410
6411 return (FRAME_LIVE_P (f) ? Qt : Qnil);
6030} 6412}
6031 6413
6414
6415#if 0
6032DEFUN ("set-window-configuration", Fset_window_configuration, 6416DEFUN ("set-window-configuration", Fset_window_configuration,
6033 Sset_window_configuration, 1, 1, 0, 6417 Sset_window_configuration, 1, 1, 0,
6034 doc: /* Set the configuration of windows and buffers as specified by CONFIGURATION. 6418 doc: /* Set the configuration of windows and buffers as specified by CONFIGURATION.
@@ -6137,18 +6521,18 @@ the return value is nil. Otherwise the value is t. */)
6137 call1 (Qrecord_window_buffer, window); 6521 call1 (Qrecord_window_buffer, window);
6138 } 6522 }
6139 6523
6140 /* Don't run lisp in the following segment since the frame is in a 6524 /* Consider frame unofficial, temporarily. */
6141 completely inconsistent state. See Bug#16207. */ 6525 f->official = false;
6142 record_unwind_protect (unwind_change_frame, inhibit_lisp_code);
6143 inhibit_lisp_code = Qt;
6144 /* The mouse highlighting code could get screwed up 6526 /* The mouse highlighting code could get screwed up
6145 if it runs during this. */ 6527 if it runs during this. */
6146 block_input (); 6528 block_input ();
6147 6529
6148 if (data->frame_text_width != previous_frame_text_width 6530 if (data->frame_text_width != previous_frame_text_width
6149 || data->frame_text_height != previous_frame_text_height) 6531 || data->frame_text_height != previous_frame_text_height)
6150 change_frame_size (f, data->frame_text_width, 6532 /* Make frame size fit the one in data, so window sizes restored
6151 data->frame_text_height, 0, 0, 0, 1); 6533 from data match those of the frame. */
6534 adjust_frame_size (f, data->frame_text_width,
6535 data->frame_text_height, 5, 0);
6152 6536
6153 if (data->frame_menu_bar_lines != previous_frame_menu_bar_lines) 6537 if (data->frame_menu_bar_lines != previous_frame_menu_bar_lines)
6154 { 6538 {
@@ -6245,7 +6629,9 @@ the return value is nil. Otherwise the value is t. */)
6245 wset_normal_cols (w, p->normal_cols); 6629 wset_normal_cols (w, p->normal_cols);
6246 wset_normal_lines (w, p->normal_lines); 6630 wset_normal_lines (w, p->normal_lines);
6247 w->hscroll = XFASTINT (p->hscroll); 6631 w->hscroll = XFASTINT (p->hscroll);
6632 w->suspend_auto_hscroll = !NILP (p->suspend_auto_hscroll);
6248 w->min_hscroll = XFASTINT (p->min_hscroll); 6633 w->min_hscroll = XFASTINT (p->min_hscroll);
6634 w->hscroll_whole = XFASTINT (p->hscroll_whole);
6249 wset_display_table (w, p->display_table); 6635 wset_display_table (w, p->display_table);
6250 w->left_margin_cols = XINT (p->left_margin_cols); 6636 w->left_margin_cols = XINT (p->left_margin_cols);
6251 w->right_margin_cols = XINT (p->right_margin_cols); 6637 w->right_margin_cols = XINT (p->right_margin_cols);
@@ -6253,7 +6639,9 @@ the return value is nil. Otherwise the value is t. */)
6253 w->right_fringe_width = XINT (p->right_fringe_width); 6639 w->right_fringe_width = XINT (p->right_fringe_width);
6254 w->fringes_outside_margins = !NILP (p->fringes_outside_margins); 6640 w->fringes_outside_margins = !NILP (p->fringes_outside_margins);
6255 w->scroll_bar_width = XINT (p->scroll_bar_width); 6641 w->scroll_bar_width = XINT (p->scroll_bar_width);
6642 w->scroll_bar_height = XINT (p->scroll_bar_height);
6256 wset_vertical_scroll_bar_type (w, p->vertical_scroll_bar_type); 6643 wset_vertical_scroll_bar_type (w, p->vertical_scroll_bar_type);
6644 wset_horizontal_scroll_bar_type (w, p->horizontal_scroll_bar_type);
6257 wset_dedicated (w, p->dedicated); 6645 wset_dedicated (w, p->dedicated);
6258 wset_combination_limit (w, p->combination_limit); 6646 wset_combination_limit (w, p->combination_limit);
6259 /* Restore any window parameters that have been saved. 6647 /* Restore any window parameters that have been saved.
@@ -6284,16 +6672,15 @@ the return value is nil. Otherwise the value is t. */)
6284 wset_buffer (w, p->buffer); 6672 wset_buffer (w, p->buffer);
6285 w->start_at_line_beg = !NILP (p->start_at_line_beg); 6673 w->start_at_line_beg = !NILP (p->start_at_line_beg);
6286 set_marker_restricted (w->start, p->start, w->contents); 6674 set_marker_restricted (w->start, p->start, w->contents);
6287 set_marker_restricted (w->pointm, p->pointm, 6675 set_marker_restricted (w->pointm, p->pointm, w->contents);
6288 w->contents); 6676 set_marker_restricted (w->old_pointm, p->old_pointm, w->contents);
6289
6290 /* As documented in Fcurrent_window_configuration, don't 6677 /* As documented in Fcurrent_window_configuration, don't
6291 restore the location of point in the buffer which was 6678 restore the location of point in the buffer which was
6292 current when the window configuration was recorded. */ 6679 current when the window configuration was recorded. */
6293 if (!EQ (p->buffer, new_current_buffer) 6680 if (!EQ (p->buffer, new_current_buffer)
6294 && XBUFFER (p->buffer) == current_buffer) 6681 && XBUFFER (p->buffer) == current_buffer)
6295 Fgoto_char (w->pointm); 6682 Fgoto_char (w->pointm);
6296 } 6683 }
6297 else if (BUFFERP (w->contents) && BUFFER_LIVE_P (XBUFFER (w->contents))) 6684 else if (BUFFERP (w->contents) && BUFFER_LIVE_P (XBUFFER (w->contents)))
6298 /* Keep window's old buffer; make sure the markers are real. */ 6685 /* Keep window's old buffer; make sure the markers are real. */
6299 { 6686 {
@@ -6305,20 +6692,26 @@ the return value is nil. Otherwise the value is t. */)
6305 (w->pointm, w->contents, 6692 (w->pointm, w->contents,
6306 BUF_PT (XBUFFER (w->contents)), 6693 BUF_PT (XBUFFER (w->contents)),
6307 BUF_PT_BYTE (XBUFFER (w->contents))); 6694 BUF_PT_BYTE (XBUFFER (w->contents)));
6695 if (XMARKER (w->old_pointm)->buffer == 0)
6696 set_marker_restricted_both
6697 (w->old_pointm, w->contents,
6698 BUF_PT (XBUFFER (w->contents)),
6699 BUF_PT_BYTE (XBUFFER (w->contents)));
6308 w->start_at_line_beg = 1; 6700 w->start_at_line_beg = 1;
6309 } 6701 }
6310 else if (!NILP (w->start)) 6702 else if (!NILP (w->start))
6311 /* Leaf window has no live buffer, get one. */ 6703 /* Leaf window has no live buffer, get one. */
6312 { 6704 {
6313 /* Get the buffer via other_buffer_safely in order to 6705 /* Get the buffer via other_buffer_safely in order to
6314 avoid showing an unimportant buffer and, if necessary, to 6706 avoid showing an unimportant buffer and, if necessary, to
6315 recreate *scratch* in the course (part of Juanma's bs-show 6707 recreate *scratch* in the course (part of Juanma's bs-show
6316 scenario from March 2011). */ 6708 scenario from March 2011). */
6317 wset_buffer (w, other_buffer_safely (Fcurrent_buffer ())); 6709 wset_buffer (w, other_buffer_safely (Fcurrent_buffer ()));
6318 /* This will set the markers to beginning of visible 6710 /* This will set the markers to beginning of visible
6319 range. */ 6711 range. */
6320 set_marker_restricted_both (w->start, w->contents, 0, 0); 6712 set_marker_restricted_both (w->start, w->contents, 0, 0);
6321 set_marker_restricted_both (w->pointm, w->contents, 0, 0); 6713 set_marker_restricted_both (w->pointm, w->contents, 0, 0);
6714 set_marker_restricted_both (w->old_pointm, w->contents, 0, 0);
6322 w->start_at_line_beg = 1; 6715 w->start_at_line_beg = 1;
6323 if (!NILP (w->dedicated)) 6716 if (!NILP (w->dedicated))
6324 /* Record this window as dead. */ 6717 /* Record this window as dead. */
@@ -6356,8 +6749,8 @@ the return value is nil. Otherwise the value is t. */)
6356 /* Set the frame size to the value it had before this function. */ 6749 /* Set the frame size to the value it had before this function. */
6357 if (previous_frame_text_width != FRAME_TEXT_WIDTH (f) 6750 if (previous_frame_text_width != FRAME_TEXT_WIDTH (f)
6358 || previous_frame_text_height != FRAME_TEXT_HEIGHT (f)) 6751 || previous_frame_text_height != FRAME_TEXT_HEIGHT (f))
6359 change_frame_size (f, previous_frame_text_width, 6752 adjust_frame_size (f, previous_frame_text_width,
6360 previous_frame_text_height, 0, 0, 0, 1); 6753 previous_frame_text_height, 5, 0);
6361 6754
6362 if (previous_frame_menu_bar_lines != FRAME_MENU_BAR_LINES (f)) 6755 if (previous_frame_menu_bar_lines != FRAME_MENU_BAR_LINES (f))
6363 { 6756 {
@@ -6386,9 +6779,13 @@ the return value is nil. Otherwise the value is t. */)
6386 ++n; 6779 ++n;
6387 } 6780 }
6388 6781
6782 /* Make frame official again and apply frame size changes if
6783 needed. */
6784 f->official = true;
6785 adjust_frame_size (f, -1, -1, 1, 0);
6786
6389 adjust_frame_glyphs (f); 6787 adjust_frame_glyphs (f);
6390 unblock_input (); 6788 unblock_input ();
6391 unbind_to (count, Qnil);
6392 6789
6393 /* Scan dead buffer windows. */ 6790 /* Scan dead buffer windows. */
6394 for (; CONSP (dead_windows); dead_windows = XCDR (dead_windows)) 6791 for (; CONSP (dead_windows); dead_windows = XCDR (dead_windows))
@@ -6427,6 +6824,7 @@ the return value is nil. Otherwise the value is t. */)
6427 6824
6428 return (FRAME_LIVE_P (f) ? Qt : Qnil); 6825 return (FRAME_LIVE_P (f) ? Qt : Qnil);
6429} 6826}
6827#endif
6430 6828
6431void 6829void
6432restore_window_configuration (Lisp_Object configuration) 6830restore_window_configuration (Lisp_Object configuration)
@@ -6459,6 +6857,7 @@ delete_all_child_windows (Lisp_Object window)
6459 { 6857 {
6460 unshow_buffer (w); 6858 unshow_buffer (w);
6461 unchain_marker (XMARKER (w->pointm)); 6859 unchain_marker (XMARKER (w->pointm));
6860 unchain_marker (XMARKER (w->old_pointm));
6462 unchain_marker (XMARKER (w->start)); 6861 unchain_marker (XMARKER (w->start));
6463 /* Since combination limit makes sense for an internal windows 6862 /* Since combination limit makes sense for an internal windows
6464 only, we use this slot to save the buffer for the sake of 6863 only, we use this slot to save the buffer for the sake of
@@ -6565,7 +6964,9 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
6565 p->normal_cols = w->normal_cols; 6964 p->normal_cols = w->normal_cols;
6566 p->normal_lines = w->normal_lines; 6965 p->normal_lines = w->normal_lines;
6567 XSETFASTINT (p->hscroll, w->hscroll); 6966 XSETFASTINT (p->hscroll, w->hscroll);
6967 p->suspend_auto_hscroll = w->suspend_auto_hscroll ? Qt : Qnil;
6568 XSETFASTINT (p->min_hscroll, w->min_hscroll); 6968 XSETFASTINT (p->min_hscroll, w->min_hscroll);
6969 XSETFASTINT (p->hscroll_whole, w->hscroll_whole);
6569 p->display_table = w->display_table; 6970 p->display_table = w->display_table;
6570 p->left_margin_cols = make_number (w->left_margin_cols); 6971 p->left_margin_cols = make_number (w->left_margin_cols);
6571 p->right_margin_cols = make_number (w->right_margin_cols); 6972 p->right_margin_cols = make_number (w->right_margin_cols);
@@ -6573,7 +6974,9 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
6573 p->right_fringe_width = make_number (w->right_fringe_width); 6974 p->right_fringe_width = make_number (w->right_fringe_width);
6574 p->fringes_outside_margins = w->fringes_outside_margins ? Qt : Qnil; 6975 p->fringes_outside_margins = w->fringes_outside_margins ? Qt : Qnil;
6575 p->scroll_bar_width = make_number (w->scroll_bar_width); 6976 p->scroll_bar_width = make_number (w->scroll_bar_width);
6977 p->scroll_bar_height = make_number (w->scroll_bar_height);
6576 p->vertical_scroll_bar_type = w->vertical_scroll_bar_type; 6978 p->vertical_scroll_bar_type = w->vertical_scroll_bar_type;
6979 p->horizontal_scroll_bar_type = w->horizontal_scroll_bar_type;
6577 p->dedicated = w->dedicated; 6980 p->dedicated = w->dedicated;
6578 p->combination_limit = w->combination_limit; 6981 p->combination_limit = w->combination_limit;
6579 p->window_parameters = Qnil; 6982 p->window_parameters = Qnil;
@@ -6635,9 +7038,13 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
6635 BUF_PT_BYTE (XBUFFER (w->contents))); 7038 BUF_PT_BYTE (XBUFFER (w->contents)));
6636 else 7039 else
6637 p->pointm = Fcopy_marker (w->pointm, Qnil); 7040 p->pointm = Fcopy_marker (w->pointm, Qnil);
7041 p->old_pointm = Fcopy_marker (w->old_pointm, Qnil);
6638 XMARKER (p->pointm)->insertion_type 7042 XMARKER (p->pointm)->insertion_type
6639 = !NILP (buffer_local_value /* Don't signal error if void. */ 7043 = !NILP (buffer_local_value /* Don't signal error if void. */
6640 (Qwindow_point_insertion_type, w->contents)); 7044 (Qwindow_point_insertion_type, w->contents));
7045 XMARKER (p->old_pointm)->insertion_type
7046 = !NILP (buffer_local_value /* Don't signal error if void. */
7047 (Qwindow_point_insertion_type, w->contents));
6641 7048
6642 p->start = Fcopy_marker (w->start, Qnil); 7049 p->start = Fcopy_marker (w->start, Qnil);
6643 p->start_at_line_beg = w->start_at_line_beg ? Qt : Qnil; 7050 p->start_at_line_beg = w->start_at_line_beg ? Qt : Qnil;
@@ -6645,6 +7052,7 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
6645 else 7052 else
6646 { 7053 {
6647 p->pointm = Qnil; 7054 p->pointm = Qnil;
7055 p->old_pointm = Qnil;
6648 p->start = Qnil; 7056 p->start = Qnil;
6649 p->start_at_line_beg = Qnil; 7057 p->start_at_line_beg = Qnil;
6650 } 7058 }
@@ -6714,7 +7122,6 @@ static void
6714apply_window_adjustment (struct window *w) 7122apply_window_adjustment (struct window *w)
6715{ 7123{
6716 eassert (w); 7124 eassert (w);
6717 adjust_window_margins (w);
6718 clear_glyph_matrix (w->current_matrix); 7125 clear_glyph_matrix (w->current_matrix);
6719 w->window_end_valid = 0; 7126 w->window_end_valid = 0;
6720 windows_or_buffers_changed = 30; 7127 windows_or_buffers_changed = 30;
@@ -6732,8 +7139,8 @@ set_window_margins (struct window *w, Lisp_Object left_width,
6732 Lisp_Object right_width) 7139 Lisp_Object right_width)
6733{ 7140{
6734 int left, right; 7141 int left, right;
7142 int unit = WINDOW_FRAME_COLUMN_WIDTH (w);
6735 7143
6736 /* FIXME: what about margins that are too wide? */
6737 left = (NILP (left_width) ? 0 7144 left = (NILP (left_width) ? 0
6738 : (CHECK_NATNUM (left_width), XINT (left_width))); 7145 : (CHECK_NATNUM (left_width), XINT (left_width)));
6739 right = (NILP (right_width) ? 0 7146 right = (NILP (right_width) ? 0
@@ -6741,11 +7148,23 @@ set_window_margins (struct window *w, Lisp_Object left_width,
6741 7148
6742 if (w->left_margin_cols != left || w->right_margin_cols != right) 7149 if (w->left_margin_cols != left || w->right_margin_cols != right)
6743 { 7150 {
6744 w->left_margin_cols = left; 7151 /* Don't change anything if new margins won't fit. */
6745 w->right_margin_cols = right; 7152 if ((WINDOW_PIXEL_WIDTH (w)
6746 return w; 7153 - WINDOW_FRINGES_WIDTH (w)
7154 - WINDOW_SCROLL_BAR_AREA_WIDTH (w)
7155 - (left + right) * unit)
7156 >= MIN_SAFE_WINDOW_PIXEL_WIDTH (w))
7157 {
7158 w->left_margin_cols = left;
7159 w->right_margin_cols = right;
7160
7161 return w;
7162 }
7163 else
7164 return NULL;
6747 } 7165 }
6748 return NULL; 7166 else
7167 return NULL;
6749} 7168}
6750 7169
6751DEFUN ("set-window-margins", Fset_window_margins, Sset_window_margins, 7170DEFUN ("set-window-margins", Fset_window_margins, Sset_window_margins,
@@ -6807,12 +7226,25 @@ set_window_fringes (struct window *w, Lisp_Object left_width,
6807 || w->right_fringe_width != right 7226 || w->right_fringe_width != right
6808 || w->fringes_outside_margins != outside)) 7227 || w->fringes_outside_margins != outside))
6809 { 7228 {
7229 if (left > 0 || right > 0)
7230 {
7231 /* Don't change anything if new fringes don't fit. */
7232 if ((WINDOW_PIXEL_WIDTH (w)
7233 - WINDOW_MARGINS_WIDTH (w)
7234 - WINDOW_SCROLL_BAR_AREA_WIDTH (w)
7235 - max (left, 0) - max (right, 0))
7236 < MIN_SAFE_WINDOW_PIXEL_WIDTH (w))
7237 return NULL;
7238 }
7239
6810 w->left_fringe_width = left; 7240 w->left_fringe_width = left;
6811 w->right_fringe_width = right; 7241 w->right_fringe_width = right;
6812 w->fringes_outside_margins = outside; 7242 w->fringes_outside_margins = outside;
7243
6813 return w; 7244 return w;
6814 } 7245 }
6815 return NULL; 7246 else
7247 return NULL;
6816} 7248}
6817 7249
6818DEFUN ("set-window-fringes", Fset_window_fringes, Sset_window_fringes, 7250DEFUN ("set-window-fringes", Fset_window_fringes, Sset_window_fringes,
@@ -6863,9 +7295,12 @@ Value is a list of the form (LEFT-WIDTH RIGHT-WIDTH OUTSIDE-MARGINS). */)
6863 7295
6864static struct window * 7296static struct window *
6865set_window_scroll_bars (struct window *w, Lisp_Object width, 7297set_window_scroll_bars (struct window *w, Lisp_Object width,
6866 Lisp_Object vertical_type, Lisp_Object horizontal_type) 7298 Lisp_Object vertical_type, Lisp_Object height,
7299 Lisp_Object horizontal_type)
6867{ 7300{
6868 int iwidth = (NILP (width) ? -1 : (CHECK_NATNUM (width), XINT (width))); 7301 int iwidth = (NILP (width) ? -1 : (CHECK_NATNUM (width), XINT (width)));
7302 int iheight = (NILP (height) ? -1 : (CHECK_NATNUM (height), XINT (height)));
7303 bool changed = 0;
6869 7304
6870 if (iwidth == 0) 7305 if (iwidth == 0)
6871 vertical_type = Qnil; 7306 vertical_type = Qnil;
@@ -6879,32 +7314,69 @@ set_window_scroll_bars (struct window *w, Lisp_Object width,
6879 if (w->scroll_bar_width != iwidth 7314 if (w->scroll_bar_width != iwidth
6880 || !EQ (w->vertical_scroll_bar_type, vertical_type)) 7315 || !EQ (w->vertical_scroll_bar_type, vertical_type))
6881 { 7316 {
6882 w->scroll_bar_width = iwidth; 7317 /* Don't change anything if new scroll bar won't fit. */
6883 wset_vertical_scroll_bar_type (w, vertical_type); 7318 if ((WINDOW_PIXEL_WIDTH (w)
6884 return w; 7319 - WINDOW_MARGINS_WIDTH (w)
7320 - WINDOW_FRINGES_WIDTH (w)
7321 - max (iwidth, 0))
7322 >= MIN_SAFE_WINDOW_PIXEL_WIDTH (w))
7323 {
7324 w->scroll_bar_width = iwidth;
7325 wset_vertical_scroll_bar_type (w, vertical_type);
7326 changed = 1;
7327 }
7328 }
7329
7330 if (MINI_WINDOW_P (w) || iheight == 0)
7331 horizontal_type = Qnil;
7332
7333 if (!(NILP (horizontal_type)
7334 || EQ (horizontal_type, Qbottom)
7335 || EQ (horizontal_type, Qt)))
7336 error ("Invalid type of horizontal scroll bar");
7337
7338 if (w->scroll_bar_height != iheight
7339 || !EQ (w->horizontal_scroll_bar_type, horizontal_type))
7340 {
7341 /* Don't change anything if new scroll bar won't fit. */
7342 if ((WINDOW_PIXEL_HEIGHT (w)
7343 - WINDOW_HEADER_LINE_HEIGHT (w)
7344 - WINDOW_MODE_LINE_HEIGHT (w)
7345 - max (iheight, 0))
7346 >= MIN_SAFE_WINDOW_PIXEL_HEIGHT (w))
7347 {
7348 w->scroll_bar_height = iheight;
7349 wset_horizontal_scroll_bar_type (w, horizontal_type);
7350 changed = 1;
7351 }
6885 } 7352 }
6886 return NULL; 7353
7354 return changed ? w : NULL;
6887} 7355}
6888 7356
6889DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars, 7357DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars,
6890 Sset_window_scroll_bars, 2, 4, 0, 7358 Sset_window_scroll_bars, 1, 5, 0,
6891 doc: /* Set width and type of scroll bars of window WINDOW. 7359 doc: /* Set width and type of scroll bars of window WINDOW.
6892WINDOW must be a live window and defaults to the selected one. 7360WINDOW must be a live window and defaults to the selected one.
6893 7361
6894Second parameter WIDTH specifies the pixel width for the scroll bar. 7362Second parameter WIDTH specifies the pixel width for the scroll bar.
6895Third parameter VERTICAL-TYPE specifies the type of the vertical scroll 7363Third parameter VERTICAL-TYPE specifies the type of the vertical scroll
6896bar: left, right, or nil. 7364bar: left, right, or nil. If WIDTH is nil, use the frame's scroll-bar
6897If WIDTH is nil, use the frame's scroll-bar width. 7365width. If VERTICAL-TYPE is t, use the frame's scroll-bar type.
6898If VERTICAL-TYPE is t, use the frame's scroll-bar type. 7366
6899Fourth parameter HORIZONTAL-TYPE is currently unused. 7367Fourth parameter HEIGHT specifies the pixel height for the scroll bar.
7368Fifth parameter HORIZONTAL-TYPE specifies the type of the vertical
7369scroll bar: nil, bottom, or t. If HEIGHT is nil, use the frame's
7370scroll-bar height. If HORIZONTAL-TYPE is t, use the frame's scroll-bar
7371type.
6900 7372
6901Return t if scroll bars were actually changed and nil otherwise. */) 7373Return t if scroll bars were actually changed and nil otherwise. */)
6902 (Lisp_Object window, Lisp_Object width, 7374 (Lisp_Object window, Lisp_Object width, Lisp_Object vertical_type,
6903 Lisp_Object vertical_type, Lisp_Object horizontal_type) 7375 Lisp_Object height, Lisp_Object horizontal_type)
6904{ 7376{
6905 struct window *w 7377 struct window *w
6906 = set_window_scroll_bars (decode_live_window (window), 7378 = set_window_scroll_bars (decode_live_window (window),
6907 width, vertical_type, horizontal_type); 7379 width, vertical_type, height, horizontal_type);
6908 return w ? (apply_window_adjustment (w), Qt) : Qnil; 7380 return w ? (apply_window_adjustment (w), Qt) : Qnil;
6909} 7381}
6910 7382
@@ -6914,19 +7386,20 @@ DEFUN ("window-scroll-bars", Fwindow_scroll_bars, Swindow_scroll_bars,
6914 doc: /* Get width and type of scroll bars of window WINDOW. 7386 doc: /* Get width and type of scroll bars of window WINDOW.
6915WINDOW must be a live window and defaults to the selected one. 7387WINDOW must be a live window and defaults to the selected one.
6916 7388
6917Value is a list of the form (WIDTH COLS VERTICAL-TYPE HORIZONTAL-TYPE). 7389Value is a list of the form (WIDTH COLS VERTICAL-TYPE HEIGHT LINES
6918If WIDTH is nil or TYPE is t, the window is using the frame's corresponding 7390HORIZONTAL-TYPE). If WIDTH or HEIGHT is nil or TYPE is t, the window is
6919value. */) 7391using the frame's corresponding value. */)
6920 (Lisp_Object window) 7392 (Lisp_Object window)
6921{ 7393{
6922 struct window *w = decode_live_window (window); 7394 struct window *w = decode_live_window (window);
6923 7395
6924 return list4 (make_number (WINDOW_SCROLL_BAR_AREA_WIDTH (w)), 7396 return Fcons (make_number (WINDOW_SCROLL_BAR_AREA_WIDTH (w)),
6925 make_number (WINDOW_SCROLL_BAR_COLS (w)), 7397 list5 (make_number (WINDOW_SCROLL_BAR_COLS (w)),
6926 w->vertical_scroll_bar_type, Qnil); 7398 w->vertical_scroll_bar_type,
7399 make_number (WINDOW_SCROLL_BAR_AREA_HEIGHT (w)),
7400 make_number (WINDOW_SCROLL_BAR_LINES (w)),
7401 w->horizontal_scroll_bar_type));
6927} 7402}
6928
6929
6930 7403
6931/*********************************************************************** 7404/***********************************************************************
6932 Smooth scrolling 7405 Smooth scrolling
@@ -7116,7 +7589,9 @@ compare_window_configurations (Lisp_Object configuration1,
7116 || !EQ (sw1->right_fringe_width, sw2->right_fringe_width) 7589 || !EQ (sw1->right_fringe_width, sw2->right_fringe_width)
7117 || !EQ (sw1->fringes_outside_margins, sw2->fringes_outside_margins) 7590 || !EQ (sw1->fringes_outside_margins, sw2->fringes_outside_margins)
7118 || !EQ (sw1->scroll_bar_width, sw2->scroll_bar_width) 7591 || !EQ (sw1->scroll_bar_width, sw2->scroll_bar_width)
7119 || !EQ (sw1->vertical_scroll_bar_type, sw2->vertical_scroll_bar_type)) 7592 || !EQ (sw1->scroll_bar_height, sw2->scroll_bar_height)
7593 || !EQ (sw1->vertical_scroll_bar_type, sw2->vertical_scroll_bar_type)
7594 || !EQ (sw1->horizontal_scroll_bar_type, sw2->horizontal_scroll_bar_type))
7120 return 0; 7595 return 0;
7121 } 7596 }
7122 7597
@@ -7170,6 +7645,7 @@ syms_of_window (void)
7170 DEFSYM (Qdelete_window, "delete-window"); 7645 DEFSYM (Qdelete_window, "delete-window");
7171 DEFSYM (Qwindow_resize_root_window, "window--resize-root-window"); 7646 DEFSYM (Qwindow_resize_root_window, "window--resize-root-window");
7172 DEFSYM (Qwindow_resize_root_window_vertically, "window--resize-root-window-vertically"); 7647 DEFSYM (Qwindow_resize_root_window_vertically, "window--resize-root-window-vertically");
7648 DEFSYM (Qwindow_sanitize_window_sizes, "window--sanitize-window-sizes");
7173 DEFSYM (Qwindow_pixel_to_total, "window--pixel-to-total"); 7649 DEFSYM (Qwindow_pixel_to_total, "window--pixel-to-total");
7174 DEFSYM (Qsafe, "safe"); 7650 DEFSYM (Qsafe, "safe");
7175 DEFSYM (Qdisplay_buffer, "display-buffer"); 7651 DEFSYM (Qdisplay_buffer, "display-buffer");
@@ -7396,12 +7872,14 @@ pixelwise even if this option is nil. */);
7396 defsubr (&Swindow_right_divider_width); 7872 defsubr (&Swindow_right_divider_width);
7397 defsubr (&Swindow_bottom_divider_width); 7873 defsubr (&Swindow_bottom_divider_width);
7398 defsubr (&Swindow_scroll_bar_width); 7874 defsubr (&Swindow_scroll_bar_width);
7875 defsubr (&Swindow_scroll_bar_height);
7399 defsubr (&Swindow_inside_edges); 7876 defsubr (&Swindow_inside_edges);
7400 defsubr (&Swindow_inside_pixel_edges); 7877 defsubr (&Swindow_inside_pixel_edges);
7401 defsubr (&Swindow_inside_absolute_pixel_edges); 7878 defsubr (&Swindow_inside_absolute_pixel_edges);
7402 defsubr (&Scoordinates_in_window_p); 7879 defsubr (&Scoordinates_in_window_p);
7403 defsubr (&Swindow_at); 7880 defsubr (&Swindow_at);
7404 defsubr (&Swindow_point); 7881 defsubr (&Swindow_point);
7882 defsubr (&Swindow_old_point);
7405 defsubr (&Swindow_start); 7883 defsubr (&Swindow_start);
7406 defsubr (&Swindow_end); 7884 defsubr (&Swindow_end);
7407 defsubr (&Sset_window_point); 7885 defsubr (&Sset_window_point);