aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorMartin Rudalics2014-07-27 15:21:30 +0200
committerMartin Rudalics2014-07-27 15:21:30 +0200
commit3477e27021dbe9366c3c1aaba80feb72f1138b29 (patch)
treec1ebfb6695e8d7f90ddad1a5bfaaf353be677514 /lisp
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 'lisp')
-rw-r--r--lisp/ChangeLog36
-rw-r--r--lisp/frame.el77
-rw-r--r--lisp/menu-bar.el36
-rw-r--r--lisp/scroll-bar.el236
-rw-r--r--lisp/startup.el15
-rw-r--r--lisp/window.el104
6 files changed, 363 insertions, 141 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 454dc823ef7..3f97396ca02 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,39 @@
12014-07-27 Martin Rudalics <rudalics@gmx.at>
2
3 * frame.el (frame-notice-user-settings): Rewrite using
4 frame-initial-frame-tool-bar-height.
5 * menu-bar.el (menu-bar-horizontal-scroll-bar)
6 (menu-bar-no-horizontal-scroll-bar): New functions.
7 (menu-bar-showhide-scroll-bar-menu): Add bindings for horizontal
8 scroll bars.
9 * scroll-bar.el (scroll-bar-lines)
10 (set-horizontal-scroll-bar-mode)
11 (get-horizontal-scroll-bar-mode, horizontal-scroll-bar-mode)
12 (scroll-bar-horizontal-drag-1, scroll-bar-horizontal-drag)
13 (scroll-bar-toolkit-horizontal-scroll): New functions.
14 (horizontal-scroll-bar-mode)
15 (previous-horizontal-scroll-bar-mode)
16 (horizontal-scroll-bar-mode-explicit): New variables.
17 (horizontal-scroll-bar-mode): New option.
18 (toggle-horizontal-scroll-bar): Do something.
19 (top-level): Bind horizontal-scroll-bar mouse-1.
20 * startup.el (tool-bar-originally-present): Remove variable.
21 (command-line): Don't set tool-bar-originally-present.
22 * window.el (window-min-height): Update doc-string.
23 (window--dump-frame): Dump horizontal scroll bar values.
24 (window--min-size-1): Handle minibuffer window separately.
25 Count in margins and horizontal scroll bar. Return safe value
26 iff IGNORE equals 'safe.
27 (frame-windows-min-size): New function (used by frame resizing
28 routines).
29 (fit-frame-to-buffer, fit-window-to-buffer): Count in horizontal
30 scroll bars.
31 (window--sanitize-window-sizes): New function.
32 (window-split-min-size): Remove.
33 (split-window): Count divider-width. Don't use
34 `window-split-min-size' any more. Reword error messages.
35 Sanitize windows sizes after splitting.
36
12014-07-27 Thien-Thi Nguyen <ttn@gnu.org> 372014-07-27 Thien-Thi Nguyen <ttn@gnu.org>
2 38
3 Use `defvar-local' more. 39 Use `defvar-local' more.
diff --git a/lisp/frame.el b/lisp/frame.el
index 9a170134e3d..d3e84d21024 100644
--- a/lisp/frame.el
+++ b/lisp/frame.el
@@ -256,60 +256,43 @@ there (in decreasing order of priority)."
256 ;; If the initial frame is still around, apply initial-frame-alist 256 ;; If the initial frame is still around, apply initial-frame-alist
257 ;; and default-frame-alist to it. 257 ;; and default-frame-alist to it.
258 (when (frame-live-p frame-initial-frame) 258 (when (frame-live-p frame-initial-frame)
259
260 ;; When tool-bar has been switched off, correct the frame size 259 ;; When tool-bar has been switched off, correct the frame size
261 ;; by the lines added in x-create-frame for the tool-bar and 260 ;; by the lines added in x-create-frame for the tool-bar and
262 ;; switch `tool-bar-mode' off. 261 ;; switch `tool-bar-mode' off.
263 (when (display-graphic-p) 262 (when (display-graphic-p)
264 (let ((tool-bar-lines (or (assq 'tool-bar-lines initial-frame-alist) 263 (let ((tool-bar-lines
265 (assq 'tool-bar-lines window-system-frame-alist) 264 (or (assq 'tool-bar-lines initial-frame-alist)
266 (assq 'tool-bar-lines default-frame-alist)))) 265 (assq 'tool-bar-lines window-system-frame-alist)
267 (when (and tool-bar-originally-present 266 (assq 'tool-bar-lines default-frame-alist))))
268 (or (null tool-bar-lines) 267 ;; Shrink frame by its initial tool bar height iff either zero
269 (null (cdr tool-bar-lines)) 268 ;; tool bar lines have been requested in one of the frame's
270 (eq 0 (cdr tool-bar-lines)))) 269 ;; alists or tool bar mode has been turned off explicitly in
271 (let* ((char-height (frame-char-height frame-initial-frame)) 270 ;; the user's init file.
272 (image-height tool-bar-images-pixel-height) 271 (when (and tool-bar-lines
273 (margin (cond ((and (consp tool-bar-button-margin) 272 (> frame-initial-frame-tool-bar-height 0)
274 (integerp (cdr tool-bar-button-margin)) 273 (or (not tool-bar-mode)
275 (> tool-bar-button-margin 0)) 274 (null (cdr tool-bar-lines))
276 (cdr tool-bar-button-margin)) 275 (eq 0 (cdr tool-bar-lines))))
277 ((and (integerp tool-bar-button-margin) 276 (set-frame-height
278 (> tool-bar-button-margin 0)) 277 frame-initial-frame (- (frame-text-height frame-initial-frame)
279 tool-bar-button-margin) 278 frame-initial-frame-tool-bar-height)
280 (t 0))) 279 nil t)
281 (relief (if (and (integerp tool-bar-button-relief) 280 (let* ((initial-top
282 (> tool-bar-button-relief 0)) 281 (cdr (assq 'top frame-initial-geometry-arguments)))
283 tool-bar-button-relief 3))
284 (lines (/ (+ image-height
285 (* 2 margin)
286 (* 2 relief)
287 (1- char-height))
288 char-height))
289 (height (frame-parameter frame-initial-frame 'height))
290 (newparms (list (cons 'height (- height lines))))
291 (initial-top (cdr (assq 'top
292 frame-initial-geometry-arguments)))
293 (top (frame-parameter frame-initial-frame 'top))) 282 (top (frame-parameter frame-initial-frame 'top)))
294 (when (and (consp initial-top) (eq '- (car initial-top))) 283 (when (and (consp initial-top) (eq '- (car initial-top)))
295 (let ((adjusted-top 284 (let ((adjusted-top
296 (cond ((and (consp top) 285 (cond
297 (eq '+ (car top))) 286 ((and (consp top) (eq '+ (car top)))
298 (list '+ 287 (list '+ (+ (cadr top)
299 (+ (cadr top) 288 frame-initial-frame-tool-bar-height)))
300 (* lines char-height)))) 289 ((and (consp top) (eq '- (car top)))
301 ((and (consp top) 290 (list '- (- (cadr top)
302 (eq '- (car top))) 291 frame-initial-frame-tool-bar-height)))
303 (list '- 292 (t (+ top frame-initial-frame-tool-bar-height)))))
304 (- (cadr top) 293 (modify-frame-parameters
305 (* lines char-height)))) 294 frame-initial-frame '((top . adjusted-top))))))
306 (t (+ top (* lines char-height)))))) 295 (tool-bar-mode -1))))
307 (setq newparms
308 (append newparms
309 `((top . ,adjusted-top))
310 nil))))
311 (modify-frame-parameters frame-initial-frame newparms)
312 (tool-bar-mode -1)))))
313 296
314 ;; The initial frame we create above always has a minibuffer. 297 ;; The initial frame we create above always has a minibuffer.
315 ;; If the user wants to remove it, or make it a minibuffer-only 298 ;; If the user wants to remove it, or make it a minibuffer-only
diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el
index c816488c6d1..5ad4bed49b8 100644
--- a/lisp/menu-bar.el
+++ b/lisp/menu-bar.el
@@ -887,8 +887,35 @@ by \"Save Options\" in Custom buffers.")
887 (interactive) 887 (interactive)
888 (customize-set-variable 'scroll-bar-mode nil)) 888 (customize-set-variable 'scroll-bar-mode nil))
889 889
890(defun menu-bar-horizontal-scroll-bar ()
891 "Display horizontal scroll bars on each window."
892 (interactive)
893 (customize-set-variable 'horizontal-scroll-bar-mode t))
894
895(defun menu-bar-no-horizontal-scroll-bar ()
896 "Turn off horizontal scroll bars."
897 (interactive)
898 (customize-set-variable 'horizontal-scroll-bar-mode nil))
899
890(defvar menu-bar-showhide-scroll-bar-menu 900(defvar menu-bar-showhide-scroll-bar-menu
891 (let ((menu (make-sparse-keymap "Scroll-bar"))) 901 (let ((menu (make-sparse-keymap "Scroll-bar")))
902 (bindings--define-key menu [horizontal]
903 '(menu-item "Horizontal"
904 menu-bar-horizontal-scroll-bar
905 :help "Horizontal scroll bar"
906 :visible (display-graphic-p)
907 :button (:radio . (eq (cdr (assq 'horizontal-scroll-bars
908 (frame-parameters)))
909 t))))
910
911 (bindings--define-key menu [none-horizontal]
912 '(menu-item "None-horizontal"
913 menu-bar-no-horizontal-scroll-bar
914 :help "Turn off horizontal scroll bars"
915 :visible (display-graphic-p)
916 :button (:radio . (eq (cdr (assq 'horizontal-scroll-bars
917 (frame-parameters)))
918 nil))))
892 919
893 (bindings--define-key menu [right] 920 (bindings--define-key menu [right]
894 '(menu-item "On the Right" 921 '(menu-item "On the Right"
@@ -896,7 +923,8 @@ by \"Save Options\" in Custom buffers.")
896 :help "Scroll-bar on the right side" 923 :help "Scroll-bar on the right side"
897 :visible (display-graphic-p) 924 :visible (display-graphic-p)
898 :button (:radio . (eq (cdr (assq 'vertical-scroll-bars 925 :button (:radio . (eq (cdr (assq 'vertical-scroll-bars
899 (frame-parameters))) 'right)))) 926 (frame-parameters)))
927 'right))))
900 928
901 (bindings--define-key menu [left] 929 (bindings--define-key menu [left]
902 '(menu-item "On the Left" 930 '(menu-item "On the Left"
@@ -904,7 +932,8 @@ by \"Save Options\" in Custom buffers.")
904 :help "Scroll-bar on the left side" 932 :help "Scroll-bar on the left side"
905 :visible (display-graphic-p) 933 :visible (display-graphic-p)
906 :button (:radio . (eq (cdr (assq 'vertical-scroll-bars 934 :button (:radio . (eq (cdr (assq 'vertical-scroll-bars
907 (frame-parameters))) 'left)))) 935 (frame-parameters)))
936 'left))))
908 937
909 (bindings--define-key menu [none] 938 (bindings--define-key menu [none]
910 '(menu-item "None" 939 '(menu-item "None"
@@ -912,7 +941,8 @@ by \"Save Options\" in Custom buffers.")
912 :help "Turn off scroll-bar" 941 :help "Turn off scroll-bar"
913 :visible (display-graphic-p) 942 :visible (display-graphic-p)
914 :button (:radio . (eq (cdr (assq 'vertical-scroll-bars 943 :button (:radio . (eq (cdr (assq 'vertical-scroll-bars
915 (frame-parameters))) nil)))) 944 (frame-parameters)))
945 nil))))
916 menu)) 946 menu))
917 947
918(defun menu-bar-frame-for-menubar () 948(defun menu-bar-frame-for-menubar ()
diff --git a/lisp/scroll-bar.el b/lisp/scroll-bar.el
index 2990e8e5ffa..09f30d5d3f0 100644
--- a/lisp/scroll-bar.el
+++ b/lisp/scroll-bar.el
@@ -70,16 +70,36 @@ SIDE must be the symbol `left' or `right'."
70 (frame-char-width))) 70 (frame-char-width)))
71 (0)))) 71 (0))))
72 72
73(defun scroll-bar-lines ()
74 "Return the height, measured in lines, of the horizontal scrollbar."
75 (let* ((wsb (window-scroll-bars))
76 (htype (nth 5 wsb))
77 (lines (nth 4 wsb)))
78 (cond
79 (htype lines)
80 ((frame-parameter nil 'horizontal-scroll-bars)
81 ;; nil means it's a non-toolkit scroll bar (which is currently
82 ;; impossible), and its width in columns is 14 pixels rounded up.
83 (ceiling (or (frame-parameter nil 'scroll-bar-height) 14)
84 (frame-char-width)))
85 (0))))
86
73 87
74;;;; Helpful functions for enabling and disabling scroll bars. 88;;;; Helpful functions for enabling and disabling scroll bars.
75 89
76(defvar scroll-bar-mode) 90(defvar scroll-bar-mode)
91(defvar horizontal-scroll-bar-mode)
77(defvar previous-scroll-bar-mode nil) 92(defvar previous-scroll-bar-mode nil)
93(defvar previous-horizontal-scroll-bar-mode nil)
78 94
79(defvar scroll-bar-mode-explicit nil 95(defvar scroll-bar-mode-explicit nil
80 "Non-nil means `set-scroll-bar-mode' should really do something. 96 "Non-nil means `set-scroll-bar-mode' should really do something.
81This is nil while loading `scroll-bar.el', and t afterward.") 97This is nil while loading `scroll-bar.el', and t afterward.")
82 98
99(defvar horizontal-scroll-bar-mode-explicit nil
100 "Non-nil means `set-horizontal-scroll-bar-mode' should really do something.
101This is nil while loading `scroll-bar.el', and t afterward.")
102
83(defun set-scroll-bar-mode (value) 103(defun set-scroll-bar-mode (value)
84 "Set the scroll bar mode to VALUE and put the new value into effect. 104 "Set the scroll bar mode to VALUE and put the new value into effect.
85See the `scroll-bar-mode' variable for possible values to use." 105See the `scroll-bar-mode' variable for possible values to use."
@@ -92,6 +112,18 @@ See the `scroll-bar-mode' variable for possible values to use."
92 (modify-all-frames-parameters (list (cons 'vertical-scroll-bars 112 (modify-all-frames-parameters (list (cons 'vertical-scroll-bars
93 scroll-bar-mode))))) 113 scroll-bar-mode)))))
94 114
115(defun set-horizontal-scroll-bar-mode (value)
116 "Set the horizontal scroll bar mode to VALUE and put the new value into effect.
117See the `horizontal-scroll-bar-mode' variable for possible values to use."
118 (if horizontal-scroll-bar-mode
119 (setq previous-horizontal-scroll-bar-mode horizontal-scroll-bar-mode))
120
121 (setq horizontal-scroll-bar-mode value)
122
123 (when horizontal-scroll-bar-mode-explicit
124 (modify-all-frames-parameters (list (cons 'horizontal-scroll-bars
125 horizontal-scroll-bar-mode)))))
126
95(defcustom scroll-bar-mode default-frame-scroll-bars 127(defcustom scroll-bar-mode default-frame-scroll-bars
96 "Specify whether to have vertical scroll bars, and on which side. 128 "Specify whether to have vertical scroll bars, and on which side.
97Possible values are nil (no scroll bars), `left' (scroll bars on left) 129Possible values are nil (no scroll bars), `left' (scroll bars on left)
@@ -108,14 +140,32 @@ Setting the variable with a customization buffer also takes effect."
108 :initialize 'custom-initialize-default 140 :initialize 'custom-initialize-default
109 :set (lambda (_sym val) (set-scroll-bar-mode val))) 141 :set (lambda (_sym val) (set-scroll-bar-mode val)))
110 142
143(defcustom horizontal-scroll-bar-mode default-frame-horizontal-scroll-bars
144 "Specify whether to have horizontal scroll bars, and on which side.
145To set this variable in a Lisp program, use `set-horizontal-scroll-bar-mode'
146to make it take real effect.
147Setting the variable with a customization buffer also takes effect."
148 :type '(choice (const :tag "none (nil)" nil)
149 (const t))
150 :group 'frames
151 ;; The default value for :initialize would try to use :set
152 ;; when processing the file in cus-dep.el.
153 :initialize 'custom-initialize-default
154 :set (lambda (_sym val) (set-horizontal-scroll-bar-mode val)))
155
111;; We just set scroll-bar-mode, but that was the default. 156;; We just set scroll-bar-mode, but that was the default.
112;; If it is set again, that is for real. 157;; If it is set again, that is for real.
113(setq scroll-bar-mode-explicit t) 158(setq scroll-bar-mode-explicit t)
159(setq horizontal-scroll-bar-mode-explicit t)
114 160
115(defun get-scroll-bar-mode () 161(defun get-scroll-bar-mode ()
116 (declare (gv-setter set-scroll-bar-mode)) 162 (declare (gv-setter set-scroll-bar-mode))
117 scroll-bar-mode) 163 scroll-bar-mode)
118 164
165(defun get-horizontal-scroll-bar-mode ()
166 (declare (gv-setter set-horizontal-scroll-bar-mode))
167 horizontal-scroll-bar-mode)
168
119(define-minor-mode scroll-bar-mode 169(define-minor-mode scroll-bar-mode
120 "Toggle vertical scroll bars on all frames (Scroll Bar mode). 170 "Toggle vertical scroll bars on all frames (Scroll Bar mode).
121With a prefix argument ARG, enable Scroll Bar mode if ARG is 171With a prefix argument ARG, enable Scroll Bar mode if ARG is
@@ -126,8 +176,21 @@ This command applies to all frames that exist and frames to be
126created in the future." 176created in the future."
127 :variable ((get-scroll-bar-mode) 177 :variable ((get-scroll-bar-mode)
128 . (lambda (v) (set-scroll-bar-mode 178 . (lambda (v) (set-scroll-bar-mode
129 (if v (or previous-scroll-bar-mode 179 (if v (or previous-scroll-bar-mode
130 default-frame-scroll-bars)))))) 180 default-frame-scroll-bars))))))
181
182(define-minor-mode horizontal-scroll-bar-mode
183 "Toggle horizontal scroll bars on all frames (Horizontal Scroll Bar mode).
184With a prefix argument ARG, enable Horizontal Scroll Bar mode if
185ARG is positive, and disable it otherwise. If called from Lisp,
186enable the mode if ARG is omitted or nil.
187
188This command applies to all frames that exist and frames to be
189created in the future."
190 :variable ((get-horizontal-scroll-bar-mode)
191 . (lambda (v) (set-horizontal-scroll-bar-mode
192 (if v (or previous-scroll-bar-mode
193 default-frame-horizontal-scroll-bars))))))
131 194
132(defun toggle-scroll-bar (arg) 195(defun toggle-scroll-bar (arg)
133 "Toggle whether or not the selected frame has vertical scroll bars. 196 "Toggle whether or not the selected frame has vertical scroll bars.
@@ -147,12 +210,21 @@ when they are turned on; if it is nil, they go on the left."
147 (if (> arg 0) 210 (if (> arg 0)
148 (or scroll-bar-mode default-frame-scroll-bars)))))) 211 (or scroll-bar-mode default-frame-scroll-bars))))))
149 212
150(defun toggle-horizontal-scroll-bar (_arg) 213(defun toggle-horizontal-scroll-bar (arg)
151 "Toggle whether or not the selected frame has horizontal scroll bars. 214 "Toggle whether or not the selected frame has horizontal scroll bars.
152With arg, turn horizontal scroll bars on if and only if arg is positive. 215With arg, turn horizontal scroll bars on if and only if arg is positive."
153Horizontal scroll bars aren't implemented yet."
154 (interactive "P") 216 (interactive "P")
155 (error "Horizontal scroll bars aren't implemented yet")) 217 (if (null arg)
218 (setq arg
219 (if (cdr (assq 'horizontal-scroll-bars
220 (frame-parameters (selected-frame))))
221 -1 1))
222 (setq arg (prefix-numeric-value arg)))
223 (modify-frame-parameters
224 (selected-frame)
225 (list (cons 'horizontal-scroll-bars
226 (if (> arg 0)
227 (or horizontal-scroll-bar-mode default-frame-horizontal-scroll-bars))))))
156 228
157;;;; Buffer navigation using the scroll bar. 229;;;; Buffer navigation using the scroll bar.
158 230
@@ -249,6 +321,45 @@ If you click outside the slider, the window scrolls to bring the slider there."
249 (with-current-buffer (window-buffer window) 321 (with-current-buffer (window-buffer window)
250 (setq point-before-scroll before-scroll)))) 322 (setq point-before-scroll before-scroll))))
251 323
324;; Scroll the window to the proper position for EVENT.
325(defun scroll-bar-horizontal-drag-1 (event)
326 (let* ((start-position (event-start event))
327 (window (nth 0 start-position))
328 (portion-whole (nth 2 start-position))
329 (unit (frame-char-width (window-frame window))))
330 (set-window-hscroll
331 window (/ (1- (+ (car portion-whole) unit)) unit))))
332
333(defun scroll-bar-horizontal-drag (event)
334 "Scroll the window horizontally by dragging the scroll bar slider.
335If you click outside the slider, the window scrolls to bring the slider there."
336 (interactive "e")
337 (let* (done
338 (echo-keystrokes 0)
339 (end-position (event-end event))
340 (window (nth 0 end-position))
341 (before-scroll))
342 (with-current-buffer (window-buffer window)
343 (setq before-scroll point-before-scroll))
344 (save-selected-window
345 (select-window window)
346 (setq before-scroll
347 (or before-scroll (point))))
348 (scroll-bar-horizontal-drag-1 event)
349 (track-mouse
350 (while (not done)
351 (setq event (read-event))
352 (if (eq (car-safe event) 'mouse-movement)
353 (setq event (read-event)))
354 (cond ((eq (car-safe event) 'scroll-bar-movement)
355 (scroll-bar-horizontal-drag-1 event))
356 (t
357 ;; Exit when we get the drag event; ignore that event.
358 (setq done t)))))
359 (sit-for 0)
360 (with-current-buffer (window-buffer window)
361 (setq point-before-scroll before-scroll))))
362
252(defun scroll-bar-scroll-down (event) 363(defun scroll-bar-scroll-down (event)
253 "Scroll the window's top line down to the location of the scroll bar click. 364 "Scroll the window's top line down to the location of the scroll bar click.
254EVENT should be a scroll bar click." 365EVENT should be a scroll bar click."
@@ -300,47 +411,92 @@ EVENT should be a scroll bar click."
300 (window (nth 0 end-position)) 411 (window (nth 0 end-position))
301 (part (nth 4 end-position)) 412 (part (nth 4 end-position))
302 before-scroll) 413 before-scroll)
303 (cond ((eq part 'end-scroll)) 414 (cond
304 (t 415 ((eq part 'end-scroll))
305 (with-current-buffer (window-buffer window) 416 (t
306 (setq before-scroll point-before-scroll)) 417 (with-current-buffer (window-buffer window)
307 (save-selected-window 418 (setq before-scroll point-before-scroll))
308 (select-window window) 419 (save-selected-window
309 (setq before-scroll (or before-scroll (point))) 420 (select-window window)
310 (cond ((eq part 'above-handle) 421 (setq before-scroll (or before-scroll (point)))
311 (scroll-up '-)) 422 (cond
312 ((eq part 'below-handle) 423 ((eq part 'above-handle)
313 (scroll-up nil)) 424 (scroll-up '-))
314 ((eq part 'ratio) 425 ((eq part 'below-handle)
315 (let* ((portion-whole (nth 2 end-position)) 426 (scroll-up nil))
316 (lines (scroll-bar-scale portion-whole 427 ((eq part 'ratio)
317 (1- (window-height))))) 428 (let* ((portion-whole (nth 2 end-position))
318 (scroll-up (cond ((not (zerop lines)) lines) 429 (lines (scroll-bar-scale portion-whole
319 ((< (car portion-whole) 0) -1) 430 (1- (window-height)))))
320 (t 1))))) 431 (scroll-up (cond ((not (zerop lines)) lines)
321 ((eq part 'up) 432 ((< (car portion-whole) 0) -1)
322 (scroll-up -1)) 433 (t 1)))))
323 ((eq part 'down) 434 ((eq part 'up)
324 (scroll-up 1)) 435 (scroll-up -1))
325 ((eq part 'top) 436 ((eq part 'down)
326 (set-window-start window (point-min))) 437 (scroll-up 1))
327 ((eq part 'bottom) 438 ((eq part 'top)
328 (goto-char (point-max)) 439 (set-window-start window (point-min)))
329 (recenter)) 440 ((eq part 'bottom)
330 ((eq part 'handle) 441 (goto-char (point-max))
331 (scroll-bar-drag-1 event)))) 442 (recenter))
332 (sit-for 0) 443 ((eq part 'handle)
333 (with-current-buffer (window-buffer window) 444 (scroll-bar-drag-1 event))))
334 (setq point-before-scroll before-scroll)))))) 445 (sit-for 0)
335 446 (with-current-buffer (window-buffer window)
447 (setq point-before-scroll before-scroll))))))
336 448
449(defun scroll-bar-toolkit-horizontal-scroll (event)
450 (interactive "e")
451 (let* ((end-position (event-end event))
452 (window (nth 0 end-position))
453 (part (nth 4 end-position))
454 before-scroll)
455 (cond
456 ((eq part 'end-scroll))
457 (t
458 (with-current-buffer (window-buffer window)
459 (setq before-scroll point-before-scroll))
460 (save-selected-window
461 (select-window window)
462 (setq before-scroll (or before-scroll (point)))
463 (cond
464 ((eq part 'before-handle)
465 (scroll-right 4))
466 ((eq part 'after-handle)
467 (scroll-left 4))
468 ((eq part 'ratio)
469 (let* ((portion-whole (nth 2 end-position))
470 (columns (scroll-bar-scale portion-whole
471 (1- (window-width)))))
472 (scroll-right
473 (cond
474 ((not (zerop columns))
475 columns)
476 ((< (car portion-whole) 0) -1)
477 (t 1)))))
478 ((eq part 'left)
479 (scroll-right 1))
480 ((eq part 'right)
481 (scroll-left 1))
482 ((eq part 'leftmost)
483 (goto-char (line-beginning-position)))
484 ((eq part 'rightmost)
485 (goto-char (line-end-position)))
486 ((eq part 'horizontal-handle)
487 (scroll-bar-horizontal-drag-1 event))))
488 (sit-for 0)
489 (with-current-buffer (window-buffer window)
490 (setq point-before-scroll before-scroll))))))
337 491
338;;;; Bindings. 492;;;; Bindings.
339 493
340;; For now, we'll set things up to work like xterm. 494;; For now, we'll set things up to work like xterm.
341(cond ((and (boundp 'x-toolkit-scroll-bars) x-toolkit-scroll-bars) 495(cond ((and (boundp 'x-toolkit-scroll-bars) x-toolkit-scroll-bars)
342 (global-set-key [vertical-scroll-bar mouse-1] 496 (global-set-key [vertical-scroll-bar mouse-1]
343 'scroll-bar-toolkit-scroll)) 497 'scroll-bar-toolkit-scroll)
498 (global-set-key [horizontal-scroll-bar mouse-1]
499 'scroll-bar-toolkit-horizontal-scroll))
344 (t 500 (t
345 (global-set-key [vertical-scroll-bar mouse-1] 501 (global-set-key [vertical-scroll-bar mouse-1]
346 'scroll-bar-scroll-up) 502 'scroll-bar-scroll-up)
diff --git a/lisp/startup.el b/lisp/startup.el
index d984e6269ae..144d732272f 100644
--- a/lisp/startup.el
+++ b/lisp/startup.el
@@ -719,9 +719,6 @@ It is the default value of the variable `top-level'."
719(defconst tool-bar-images-pixel-height 24 719(defconst tool-bar-images-pixel-height 24
720 "Height in pixels of images in the tool-bar.") 720 "Height in pixels of images in the tool-bar.")
721 721
722(defvar tool-bar-originally-present nil
723 "Non-nil if tool-bars are present before user and site init files are read.")
724
725(defvar handle-args-function-alist '((nil . tty-handle-args)) 722(defvar handle-args-function-alist '((nil . tty-handle-args))
726 "Functions for processing window-system dependent command-line arguments. 723 "Functions for processing window-system dependent command-line arguments.
727Window system startup files should add their own function to this 724Window system startup files should add their own function to this
@@ -1042,18 +1039,6 @@ please check its value")
1042 (or (eq initial-window-system 'pc) 1039 (or (eq initial-window-system 'pc)
1043 (tty-register-default-colors)) 1040 (tty-register-default-colors))
1044 1041
1045 ;; Record whether the tool-bar is present before the user and site
1046 ;; init files are processed. frame-notice-user-settings uses this
1047 ;; to determine if the tool-bar has been disabled by the init files,
1048 ;; and the frame needs to be resized.
1049 (when (fboundp 'frame-notice-user-settings)
1050 (let ((tool-bar-lines (or (assq 'tool-bar-lines initial-frame-alist)
1051 (assq 'tool-bar-lines default-frame-alist))))
1052 (setq tool-bar-originally-present
1053 (and tool-bar-lines
1054 (cdr tool-bar-lines)
1055 (not (eq 0 (cdr tool-bar-lines)))))))
1056
1057 (let ((old-scalable-fonts-allowed scalable-fonts-allowed) 1042 (let ((old-scalable-fonts-allowed scalable-fonts-allowed)
1058 (old-face-ignored-fonts face-ignored-fonts)) 1043 (old-face-ignored-fonts face-ignored-fonts))
1059 1044
diff --git a/lisp/window.el b/lisp/window.el
index e1c79659773..a7dcd9a6612 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -378,9 +378,9 @@ Anything less might crash Emacs.")
378(defcustom window-min-height 4 378(defcustom window-min-height 4
379 "The minimum total height, in lines, of any window. 379 "The minimum total height, in lines, of any window.
380The value has to accommodate one text line, a mode and header 380The value has to accommodate one text line, a mode and header
381line, and a bottom divider, if present. A value less than 381line, a horizontal scroll bar and a bottom divider, if present.
382`window-safe-min-height' is ignored. The value of this variable 382A value less than `window-safe-min-height' is ignored. The value
383is honored when windows are resized or split. 383of this variable is honored when windows are resized or split.
384 384
385Applications should never rebind this variable. To resize a 385Applications should never rebind this variable. To resize a
386window to a height less than the one specified here, an 386window to a height less than the one specified here, an
@@ -1137,11 +1137,12 @@ dumping to it."
1137 (format "frame text pixel: %s x %s cols/lines: %s x %s\n" 1137 (format "frame text pixel: %s x %s cols/lines: %s x %s\n"
1138 (frame-text-width frame) (frame-text-height frame) 1138 (frame-text-width frame) (frame-text-height frame)
1139 (frame-text-cols frame) (frame-text-lines frame)) 1139 (frame-text-cols frame) (frame-text-lines frame))
1140 (format "tool: %s scroll: %s fringe: %s border: %s right: %s bottom: %s\n\n" 1140 (format "tool: %s scroll: %s/%s fringe: %s border: %s right: %s bottom: %s\n\n"
1141 (if (fboundp 'tool-bar-height) 1141 (if (fboundp 'tool-bar-height)
1142 (tool-bar-height frame t) 1142 (tool-bar-height frame t)
1143 "0") 1143 "0")
1144 (frame-scroll-bar-width frame) 1144 (frame-scroll-bar-width frame)
1145 (frame-scroll-bar-height frame)
1145 (frame-fringe-width frame) 1146 (frame-fringe-width frame)
1146 (frame-border-width frame) 1147 (frame-border-width frame)
1147 (frame-right-divider-width frame) 1148 (frame-right-divider-width frame)
@@ -1262,12 +1263,14 @@ of WINDOW."
1262 value) 1263 value)
1263 (with-current-buffer (window-buffer window) 1264 (with-current-buffer (window-buffer window)
1264 (cond 1265 (cond
1266 ((window-minibuffer-p window)
1267 (if pixelwise (frame-char-height (window-frame window)) 1))
1265 ((and (not (window--size-ignore-p window ignore)) 1268 ((and (not (window--size-ignore-p window ignore))
1266 (window-size-fixed-p window horizontal)) 1269 (window-size-fixed-p window horizontal))
1267 ;; The minimum size of a fixed size window is its size. 1270 ;; The minimum size of a fixed size window is its size.
1268 (window-size window horizontal pixelwise)) 1271 (window-size window horizontal pixelwise))
1269 ((or (eq ignore 'safe) (eq ignore window)) 1272 ((eq ignore 'safe)
1270 ;; If IGNORE equals `safe' or WINDOW return the safe values. 1273 ;; If IGNORE equals `safe' return the safe value.
1271 (window-safe-min-size window horizontal pixelwise)) 1274 (window-safe-min-size window horizontal pixelwise))
1272 (horizontal 1275 (horizontal
1273 ;; For the minimum width of a window take fringes and 1276 ;; For the minimum width of a window take fringes and
@@ -1278,8 +1281,11 @@ of WINDOW."
1278 ;; `window-min-width'. 1281 ;; `window-min-width'.
1279 (let* ((char-size (frame-char-size window t)) 1282 (let* ((char-size (frame-char-size window t))
1280 (fringes (window-fringes window)) 1283 (fringes (window-fringes window))
1284 (margins (window-margins window))
1281 (pixel-width 1285 (pixel-width
1282 (+ (window-safe-min-size window t t) 1286 (+ (window-safe-min-size window t t)
1287 (* (or (car margins) 0) char-size)
1288 (* (or (cdr margins) 0) char-size)
1283 (car fringes) (cadr fringes) 1289 (car fringes) (cadr fringes)
1284 (window-scroll-bar-width window) 1290 (window-scroll-bar-width window)
1285 (window-right-divider-width window)))) 1291 (window-right-divider-width window))))
@@ -1301,6 +1307,7 @@ of WINDOW."
1301 (pixel-height 1307 (pixel-height
1302 (+ (window-safe-min-size window nil t) 1308 (+ (window-safe-min-size window nil t)
1303 (window-header-line-height window) 1309 (window-header-line-height window)
1310 (window-scroll-bar-height window)
1304 (window-mode-line-height window) 1311 (window-mode-line-height window)
1305 (window-bottom-divider-width window)))) 1312 (window-bottom-divider-width window))))
1306 (if pixelwise 1313 (if pixelwise
@@ -1508,6 +1515,18 @@ by which WINDOW can be shrunk."
1508 (window--min-delta-1 1515 (window--min-delta-1
1509 window (- size minimum) horizontal ignore trail noup pixelwise))))) 1516 window (- size minimum) horizontal ignore trail noup pixelwise)))))
1510 1517
1518(defun frame-windows-min-size (&optional frame horizontal pixelwise)
1519 "Return minimum number of lines of FRAME's windows.
1520HORIZONTAL non-nil means return number of columns of FRAME's
1521windows. PIXELWISE non-nil means return sizes in pixels."
1522 (setq frame (window-normalize-frame frame))
1523 (let* ((root (frame-root-window frame))
1524 (mini (window-next-sibling root)))
1525 (+ (window-min-size root horizontal nil pixelwise)
1526 (if (and mini (not horizontal))
1527 (window-min-size mini horizontal nil pixelwise)
1528 0))))
1529
1511(defun window--max-delta-1 (window delta &optional horizontal ignore trail noup pixelwise) 1530(defun window--max-delta-1 (window delta &optional horizontal ignore trail noup pixelwise)
1512 "Internal function of `window-max-delta'." 1531 "Internal function of `window-max-delta'."
1513 (if (not (window-parent window)) 1532 (if (not (window-parent window))
@@ -2984,6 +3003,28 @@ routines."
2984 pixel-delta 3003 pixel-delta
2985 (/ pixel-delta (frame-char-height frame))))) 3004 (/ pixel-delta (frame-char-height frame)))))
2986 3005
3006(defun window--sanitize-window-sizes (frame horizontal)
3007 "Assert that all windows on FRAME are large enough.
3008If necessary and possible, make sure that every window on frame
3009FRAME has its minimum height. Optional argument HORIZONTAL
3010non-nil means to make sure that every window on frame FRAME has
3011its minimum width. The minimumm height/width of a window is the
3012respective value returned by `window-min-size' for that window.
3013
3014Return t if all windows were resized appropriately. Return nil
3015if at least one window could not be resized as requested, which
3016may happen when the FRAME is not large enough to accomodate it."
3017 (let ((value t))
3018 (walk-window-tree
3019 (lambda (window)
3020 (let ((delta (- (window-min-size window horizontal nil t)
3021 (window-size window horizontal t))))
3022 (when (> delta 0)
3023 (if (window-resizable-p window delta horizontal nil t)
3024 (window-resize window delta horizontal nil t)
3025 (setq value nil))))))
3026 value))
3027
2987(defun adjust-window-trailing-edge (window delta &optional horizontal pixelwise) 3028(defun adjust-window-trailing-edge (window delta &optional horizontal pixelwise)
2988 "Move WINDOW's bottom edge by DELTA lines. 3029 "Move WINDOW's bottom edge by DELTA lines.
2989Optional argument HORIZONTAL non-nil means move WINDOW's right 3030Optional argument HORIZONTAL non-nil means move WINDOW's right
@@ -4241,20 +4282,6 @@ showing BUFFER-OR-NAME."
4241 ;; If a window doesn't show BUFFER, unrecord BUFFER in it. 4282 ;; If a window doesn't show BUFFER, unrecord BUFFER in it.
4242 (unrecord-window-buffer window buffer))))) 4283 (unrecord-window-buffer window buffer)))))
4243 4284
4244;;; Splitting windows.
4245(defun window-split-min-size (&optional horizontal pixelwise)
4246 "Return minimum height of any window when splitting windows.
4247Optional argument HORIZONTAL non-nil means return minimum width."
4248 (cond
4249 (pixelwise
4250 (if horizontal
4251 (window-min-pixel-width)
4252 (window-min-pixel-height)))
4253 (horizontal
4254 (max window-min-width window-safe-min-width))
4255 (t
4256 (max window-min-height window-safe-min-height))))
4257
4258(defun split-window (&optional window size side pixelwise) 4285(defun split-window (&optional window size side pixelwise)
4259 "Make a new window adjacent to WINDOW. 4286 "Make a new window adjacent to WINDOW.
4260WINDOW must be a valid window and defaults to the selected one. 4287WINDOW must be a valid window and defaults to the selected one.
@@ -4318,6 +4345,9 @@ frame. The selected window is not changed by this function."
4318 (pixel-size 4345 (pixel-size
4319 (when (numberp size) 4346 (when (numberp size)
4320 (window--size-to-pixel window size horizontal pixelwise t))) 4347 (window--size-to-pixel window size horizontal pixelwise t)))
4348 (divider-width (if horizontal
4349 (frame-right-divider-width frame)
4350 (frame-bottom-divider-width frame)))
4321 atom-root) 4351 atom-root)
4322 (window--check frame) 4352 (window--check frame)
4323 (catch 'done 4353 (catch 'done
@@ -4419,19 +4449,14 @@ frame. The selected window is not changed by this function."
4419 (cond 4449 (cond
4420 (resize 4450 (resize
4421 ;; SIZE unspecified, resizing. 4451 ;; SIZE unspecified, resizing.
4422 (when (and (not (window-sizable-p 4452 (unless (window-sizable-p
4423 parent (- new-pixel-size) horizontal nil t)) 4453 parent (- new-pixel-size divider-width) horizontal nil t)
4424 ;; Try again with minimum split size. 4454 (error "Window %s too small for splitting (1)" parent)))
4425 (setq new-pixel-size 4455 ((> (+ new-pixel-size divider-width
4426 (max new-pixel-size 4456 (window-min-size window horizontal nil t))
4427 (window-split-min-size horizontal t)))
4428 (not (window-sizable-p
4429 parent (- new-pixel-size) horizontal nil t)))
4430 (error "Window %s too small for splitting 1" parent)))
4431 ((> (+ new-pixel-size (window-min-size window horizontal nil t))
4432 old-pixel-size) 4457 old-pixel-size)
4433 ;; SIZE unspecified, no resizing. 4458 ;; SIZE unspecified, no resizing.
4434 (error "Window %s too small for splitting 2" window)))) 4459 (error "Window %s too small for splitting (2)" window))))
4435 ((and (>= pixel-size 0) 4460 ((and (>= pixel-size 0)
4436 (or (>= pixel-size old-pixel-size) 4461 (or (>= pixel-size old-pixel-size)
4437 (< new-pixel-size 4462 (< new-pixel-size
@@ -4439,19 +4464,19 @@ frame. The selected window is not changed by this function."
4439 ;; SIZE specified as new size of old window. If the new size 4464 ;; SIZE specified as new size of old window. If the new size
4440 ;; is larger than the old size or the size of the new window 4465 ;; is larger than the old size or the size of the new window
4441 ;; would be less than the safe minimum, signal an error. 4466 ;; would be less than the safe minimum, signal an error.
4442 (error "Window %s too small for splitting 3" window)) 4467 (error "Window %s too small for splitting (3)" window))
4443 (resize 4468 (resize
4444 ;; SIZE specified, resizing. 4469 ;; SIZE specified, resizing.
4445 (unless (window-sizable-p 4470 (unless (window-sizable-p
4446 parent (- new-pixel-size) horizontal nil t) 4471 parent (- new-pixel-size divider-width) horizontal nil t)
4447 ;; If we cannot resize the parent give up. 4472 ;; If we cannot resize the parent give up.
4448 (error "Window %s too small for splitting 4" parent))) 4473 (error "Window %s too small for splitting (4)" parent)))
4449 ((or (< new-pixel-size 4474 ((or (< new-pixel-size
4450 (window-safe-min-pixel-size window horizontal)) 4475 (window-safe-min-pixel-size window horizontal))
4451 (< (- old-pixel-size new-pixel-size) 4476 (< (- old-pixel-size new-pixel-size)
4452 (window-safe-min-pixel-size window horizontal))) 4477 (window-safe-min-pixel-size window horizontal)))
4453 ;; SIZE specification violates minimum size restrictions. 4478 ;; SIZE specification violates minimum size restrictions.
4454 (error "Window %s too small for splitting 5" window))) 4479 (error "Window %s too small for splitting (5)" window)))
4455 4480
4456 (window--resize-reset frame horizontal) 4481 (window--resize-reset frame horizontal)
4457 4482
@@ -4522,6 +4547,9 @@ frame. The selected window is not changed by this function."
4522 (set-window-parameter (window-parent new) 'window-atom t)) 4547 (set-window-parameter (window-parent new) 'window-atom t))
4523 (set-window-parameter new 'window-atom t))) 4548 (set-window-parameter new 'window-atom t)))
4524 4549
4550 ;; Sanitize sizes.
4551 (window--sanitize-window-sizes frame horizontal)
4552
4525 (run-window-configuration-change-hook frame) 4553 (run-window-configuration-change-hook frame)
4526 (run-window-scroll-functions new) 4554 (run-window-scroll-functions new)
4527 (window--check frame) 4555 (window--check frame)
@@ -7116,7 +7144,10 @@ FRAME."
7116 (value (window-text-pixel-size 7144 (value (window-text-pixel-size
7117 nil t t workarea-width workarea-height t)) 7145 nil t t workarea-width workarea-height t))
7118 (width (+ (car value) (window-right-divider-width))) 7146 (width (+ (car value) (window-right-divider-width)))
7119 (height (+ (cdr value) (window-bottom-divider-width)))) 7147 (height
7148 (+ (cdr value)
7149 (window-bottom-divider-width)
7150 (nth 3 (window-scroll-bars)))))
7120 ;; Don't change height or width when the window's size is fixed 7151 ;; Don't change height or width when the window's size is fixed
7121 ;; in either direction or ONLY forbids it. 7152 ;; in either direction or ONLY forbids it.
7122 (cond 7153 (cond
@@ -7275,6 +7306,7 @@ accessible position."
7275 ;; height. Its width remains fixed. 7306 ;; height. Its width remains fixed.
7276 (setq height (+ (cdr (window-text-pixel-size 7307 (setq height (+ (cdr (window-text-pixel-size
7277 nil nil t nil (frame-pixel-height) t)) 7308 nil nil t nil (frame-pixel-height) t))
7309 (nth 3 (window-scroll-bars window))
7278 (window-bottom-divider-width))) 7310 (window-bottom-divider-width)))
7279 ;; Round height. 7311 ;; Round height.
7280 (unless pixelwise 7312 (unless pixelwise