summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Rudalics <rudalics@gmx.at>2013-11-30 10:25:31 +0100
committerMartin Rudalics <rudalics@gmx.at>2013-11-30 10:25:31 +0100
commit880e615853d4074937795850b279338720618431 (patch)
tree9ff3cbd92ec5963cf80315a4fb912ed73dc89be3 /src
parent3e2fb4db3f517dd051cd35c742355c492e085333 (diff)
downloademacs-880e615853d4074937795850b279338720618431.tar.gz
Support resizing frames and windows pixelwise.
* dispextern.h (enum window_part): Add ON_SCROLL_BAR, ON_RIGHT_DIVIDER and ON_BOTTOM_DIVIDER. (struct glyph_matrix): Replace window_left_col and window_top_line by window_pixel_left and window_pixel_top. (WINDOW_WANTS_MODELINE_P, WINDOW_WANTS_HEADER_LINE_P): Minor rewrite. (enum face_id): Add WINDOW_DIVIDER_FACE_ID. (draw_window_divider, move_it_to, x_draw_right_divider) (x_draw_bottom_divider, change_frame_size): Add or fix declarations. * dispnew.c (change_frame_size_1): Change prototype. (adjust_glyph_matrix, required_matrix_width) (adjust_frame_glyphs_for_window_redisplay): Use pixel values instead of lines and columns. (marginal_area_string): Use WINDOW_FRINGES_WIDTH instead of WINDOW_TOTAL_FRINGE_WIDTH. (handle_window_change_signal, do_pending_window_change) (init_display): Adjusts calls of change_frame_size. (change_frame_size, change_frame_size_1): Handle pixelwise changes. * frame.c (Qright_divider_width, Qbottom_divider_width): New Lisp objects. (set_menu_bar_lines_1, set_menu_bar_lines, make_frame) (make_terminal_frame, Fmake_terminal_frame, Fframe_parameters) (x_set_internal_border_width, x_set_vertical_scroll_bars) (x_set_scroll_bar_width, x_figure_window_size): Handle pixel values. (set_frame_param): New function. (Fframe_text_cols, Fframe_text_lines, Fframe_total_cols) (Fframe_text_width, Fframe_text_height, Fscroll_bar_width) (Ffringe_width, Fborder_width, Fright_divider_width) (Fbottom_divider_width): New functions, defsubr them. (Fset_frame_height, Fset_frame_width, Fset_frame_size): New argument pixelwise. (struct frame_parm_table): New members Qright_divider_width and Qbottom_divider_width. (x_set_frame_parameters): Handle parameters for pixelwise sizes. (x_report_frame_params): Handle Qright_divider_width and Qbottom_divider_width. (x_set_right_divider_width, x_set_bottom_divider_width): New functions. (frame_resize_pixelwise): New option. * frame.h (struct frame): Add tool_bar_height, menu_bar_height, new_pixelwise, right_divider_width and bottom_divider_width; remove total_lines; rename text_lines, text_cols, new_text_lines and new_text_cols to text_height, text_width, new_height and new_width respectively. (FRAME_LINES, FRAME_COLS): Rename to FRAME_TEXT_HEIGHT and FRAME_TEXT_WIDTH respectively. (FRAME_MENU_BAR_HEIGHT, FRAME_TOOL_BAR_HEIGHT) (FRAME_RIGHT_DIVIDER_WIDTH, FRAME_BOTTOM_DIVIDER_WIDTH) (FRAME_TEXT_TO_PIXEL_WIDTH, FRAME_PIXEL_TO_TEXT_WIDTH): New macros. (FRAME_TOP_MARGIN_HEIGHT, FRAME_LEFT_SCROLL_BAR_AREA_WIDTH) (FRAME_RIGHT_SCROLL_BAR_AREA_WIDTH, FRAME_SCROLL_BAR_AREA_WIDTH) (SET_FRAME_COLS, SET_FRAME_WIDTH, SET_FRAME_HEIGHT) (FRAME_TEXT_COLS_TO_PIXEL_WIDTH, FRAME_PIXEL_WIDTH_TO_TEXT_COLS) (FRAME_TEXT_COLS_TO_PIXEL_WIDTH): Rewrite macros. (FRAME_TOTAL_COLS_ARG): Remove macro. * fringe.c (draw_fringe_bitmap_1): Handle right divder. * gtkutil.c (xg_frame_resized, xg_frame_set_char_size) (x_wm_set_size_hint): Handle frame pixel sizes. * indent.c (compute_motion, Fcompute_motion): Call window_body_width instead of window_body_cols. * keyboard.c (Qright_divider, Qbottom_divider): New symbols. (make_lispy_position): Handle right and bottom dividers. (Fsuspend_emacs): Pixelize call of change_frame_size. * keyboard.h: Extern Qright_divider, Qbottom_divider. * lisp.h: Extern set_frame_param. * nsfns.m (x_set_tool_bar_lines): Pixelize call of x_set_window_size. (Fx_create_frame): Add entry for vertical_drag_cursor. Pixelize call of change_frame_size. * nsterm.h (struct ns_output): Add vertical_drag_cursor. * nsterm.m (ns_update_window_end): Optionally draw right divider. (x_set_window_size): Add argument pixelwise. Call check_frame_size and change_frame_size with pixelwise zero. (ns_draw_window_divider): New function. (ns_redisplay_interface): Add ns_draw_window_divider. (updateFrameSize:): Call change_frame_size with pixelwise zero. (x_new_font): Call x_set_window_size with pixelwise zero. * print.c (print_object): For a window print its sequence number again. * term.c (Fresume_tty): Pixelize call of change_frame_size. * w32fns.c (x_set_mouse_color): Handle vertical drag cursor. (x_set_menu_bar_lines, x_set_tool_bar_lines): Calculate pixelwise. (w32_createwindow): Use scroll bar area width. (w32_wnd_proc): Handle bottom divider width. For WM_WINDOWPOSCHANGING return zero if we resize pixelwise. (Fx_create_frame): Default divider width parameters. Caclulate sizes pixelwise. Add vertical drag cursor support. (x_create_tip_frame): Default divider widths to zero. Pixelize call to change_frame_size. (Fx_show_tip): Add handling of divider widths. Pixelize window position and sizes. (Fw32_frame_rect): New function. (frame_parm_handler w32_frame_parm_handlers): Add divider widths. (Vx_window_vertical_drag_shape): Add variable. * w32inevt.c (resize_event, maybe_generate_resize_event): Pixelize change_frame_size calls. * w32menu.c (set_frame_menubar): Pixelize x_set_window_size call. * w32term.c (w32_draw_window_divider): New function. (x_update_window_end): Handle right divider. (w32_draw_fringe_bitmap, x_scroll_run) (w32_set_vertical_scroll_bar): Pixelize scrollbar widths. (w32_read_socket): Handle SIZE_MAXIMIZED separately. Calculate new frame sizes pixelwise. (x_new_font): Pixelize call to x_set_window_size. (x_check_fullscreen): Pixelize call to change_frame_size. (x_set_window_size_1, x_set_window_size): New argument pixelwise. Calculate pixelwise. (x_wm_set_size_hint): Use scroll bar area width. (w32_redisplay_interface): Add w32_draw_window_divider. * w32term.h (struct w32_output): Add vertical drag cursor. * widget.c (set_frame_size, update_wm_hints) (EmacsFrameResize, EmacsFrameSetValues): Pixelize calls of change_frame_size. (EmacsFrameSetCharSize): Pixelize call of x_set_window_size. * window.c (sequence_number): Restore. (Fwindow_pixel_width, Fwindow_pixel_height) (Fwindow_mode_line_height, Fwindow_header_line_height) (window_pixel_to_total, Frun_window_scroll_functions) (Fset_window_new_pixel, window_resize_apply_total) (Fwindow_resize_apply_total): New functions. (window_body_height, window_body_width): Rename from window_body_lines. New argument PIXELWISE. Calculate pixelwise. (Fwindow_body_height, Fwindow_body_width): New argument PIXELWISE. (coordinates_in_window, window_relative_x_coord): Use window's pixel width instead of total width. (replace_window, recombine_windows): Initialize pixel values. (resize_root_window, resize_frame_windows, grow_mini_window) (shrink_mini_window): New argument PIXELWISE. Calculate pixelwise. (Fdelete_other_windows_internal, adjust_window_margins) (window_resize_check, window_resize_apply) (Fdelete_window_internal, Fresize_mini_window_internal) (Fwindow_text_width, Fwindow_text_height): Calculate pixelwise. (check_frame_size): Rename arguments. New argument PIXELWISE. Calculate pixelwise. (set_window_buffer): Make samebuf bool. Run configuration change hook only if buffer changed. (Fset_window_buffer): Rewrite doc-string. (make_window): Initialize new_pixel slot. (Fwindow_resize_apply): Check pixel size of root window. (Fsplit_window_internal): Call 2nd argument pixel_size. Calculate pixelwise. (Fscroll_left, Fscroll_right): Call window_body_width instead of window_body_cols. (save_window_data): New slots frame_text_width, frame_text_height, frame_menu_bar_height, frame_tool_bar_height. (saved_window): New slots pixel_left, pixel_top, pixel_height, pixel_width. (Fcurrent_window_configuration, Fset_window_configuration) (save_window_save, compare_window_configurations): Handle new slots in save_window_data and saved_window. (Fset_window_scroll_bars): Fix doc-string. (window_resize_pixelwise): New variable. (coordinates_in_window, Fcoordinates_in_window_p): Handle dividers. (make_parent_window): Adjust sequence_number. (Fwindow_right_divider_width, Fwindow_bottom_divider_width): New functions. * window.h (struct window): New members new_pixel, pixel_left, pixel_top, pixel_width, pixel_height. Restore sequence_number. (wset_new_pixel): New function. (WINDOW_PIXEL_WIDTH, WINDOW_PIXEL_HEIGHT) (MIN_SAFE_WINDOW_PIXEL_WIDTH, MIN_SAFE_WINDOW_PIXEL_HEIGHT) (WINDOW_LEFT_PIXEL_EDGE, WINDOW_RIGHT_PIXEL_EDGE) (WINDOW_TOP_PIXEL_EDGE, WINDOW_BOTTOM_PIXEL_EDGE) (WINDOW_BOTTOMMOST_P, WINDOW_BOX_LEFT_PIXEL_EDGE) (WINDOW_BOX_RIGHT_PIXEL_EDGE, WINDOW_MARGINS_COLS) (WINDOW_MARGINS_WIDTH, WINDOW_RIGHT_DIVIDER_WIDTH) (WINDOW_BOTTOM_DIVIDER_WIDTH): New macros. (WINDOW_TOTAL_FRINGE_WIDTH): Rename to WINDOW_FRINGES_WIDTH. (WINDOW_TOTAL_WIDTH, WINDOW_TOTAL_HEIGHT): Remove macros. (WINDOW_RIGHT_EDGE_X, WINDOW_LEFT_EDGE_X, WINDOW_TOP_EDGE_Y) (WINDOW_BOTTOM_EDGE_Y, WINDOW_FULL_WIDTH_P, WINDOW_LEFTMOST_P) (WINDOW_RIGHTMOST_P, WINDOW_BOX_LEFT_EDGE_X) (WINDOW_BOX_RIGHT_EDGE_X, WINDOW_FRINGE_COLS) (WINDOW_BOX_HEIGHT_NO_MODE_LINE, WINDOW_BOX_TEXT_HEIGHT): Rewrite. (resize_frame_windows, grow_mini_window, shrink_mini_window) (window_body_width, check_frame_size): Adapt external declarations. * xdisp.c (last_max_ascent): New integer. (window_text_bottom_y): Handle bottom divider. (window_box_width, window_box_height): Calculate pixelwise. (get_glyph_string_clip_rects): Handle right divider. (remember_mouse_glyph): When windows are resized pixelwise proceed with width and height set to 1. (init_iterator): Use WINDOW_PIXEL_WIDTH instead of WINDOW_TOTAL_WIDTH. (move_it_to): Calculate and return maximum x position encountered. (Fwindow_text_pixel_size): New function. (resize_mini_window, update_tool_bar): Calculate pixelwise. (tool_bar_lines_needed): Rename to tool_bar_height. Calculate pixelwise. (Ftool_bar_lines_needed): Rename to Ftool_bar_height. Calculate pixelwise. (redisplay_tool_bar): Calculate pixelwise. (redisplay_window): Calculate pixelwise. Handle dividers. (draw_glyphs, x_clear_end_of_line, note_mouse_highlight) (x_draw_vertical_border): Handle dividers. (define_frame_cursor1): Handle vertical drag cursor. (x_draw_right_divider, x_draw_bottom_divider): New functions. (expose_window): Calculate pixelwise. Handle dividers. (init_xdisp): Initialize pixel values. * xfaces.c (Qwindow_divider): New face. (realize_basic_faces): Realize it. * xfns.c (x_set_mouse_color): Handle vertical_drag_cursor. (x_set_menu_bar_lines, x_set_tool_bar_lines): Calculate pixelwise. (x_set_scroll_bar_default_width): Default actual width to 16. (Fx_create_frame): Set sizes pixelwise. (x_create_tip_frame): Default divider widths to zero. Pixelize call of change_frame_size. (Fx_show_tip): Handle divider widths. Initial pixel position and sizes. (frame_parm_handler x_frame_parm_handlers): Add divider widths. (Vx_window_vertical_drag_shape): New option. * xmenu.c (free_frame_menubar): Pixelize call of x_set_window_size. * xterm.c (x_draw_window_divider): New function. (x_update_window_end): Optionally draw right divider. (x_draw_fringe_bitmap, x_scroll_run, x_scroll_bar_create) (XTset_vertical_scroll_bar): Use scroll bar pixel width. (handle_one_xevent, x_new_font): Calculate pixelwise. (x_set_window_size_1, x_set_window_size): New argument pixelwise. Calculate pixelwise. (x_wm_set_size_hint): Pixelize call of check_frame_size. (struct x_redisplay_interface): Add x_draw_window_divider. * xterm.h (struct x_output): Add vertical_drag_cursor. * cus-start.el (frame-resize-pixelwise) (window-resize-pixelwise): New entries. * emacs-lisp/debug.el (debug): Use window-total-height instead of window-total-size. * frame.el (tool-bar-lines-needed): Defalias to tool-bar-height. * help.el (describe-bindings-internal): Call help-buffer (temp-buffer-max-width): New option. (resize-temp-buffer-window, help-window-setup) (with-help-window): Rewrite. * mouse.el (mouse-drag-line): Rewrite. Add key bindings for dragging dividers. * window.el (frame-char-size, window-min-pixel-height) (window-safe-min-pixel-height, window-safe-min-pixel-width) (window-min-pixel-width, window-safe-min-pixel-size) (window-combination-p, window-safe-min-size) (window-resizable-p, window--size-to-pixel) (window--pixel-to-size, window--resize-apply-p): New functions. (window-safe-min-height): Fix doc-string. (window-size, window-min-size, window--min-size-1) (window-sizable, window-sizable-p, window--min-delta-1) (window-min-delta, window--max-delta-1, window-max-delta) (window--resizable, window--resizable-p, window-resizable) (window-full-height-p, window-full-width-p, window-at-side-p) (window--in-direction-2, window-in-direction) (window--resize-reset-1, window--resize-mini-window) (window-resize, window-resize-no-error) (window--resize-child-windows-normal) (window--resize-child-windows, window--resize-siblings) (window--resize-this-window, window--resize-root-window) (window--resize-root-window-vertically) (adjust-window-trailing-edge, enlarge-window, shrink-window) (maximize-window, minimize-window, delete-window) (quit-restore-window, window-split-min-size, split-window) (balance-windows-2, balance-windows) (balance-windows-area-adjust, balance-windows-area) (window--state-get-1, window-state-get, window--state-put-1) (window--state-put-2, window-state-put) (display-buffer-record-window, window--display-buffer): Make functions handle pixelwise sizing of windows. (display-buffer--action-function-custom-type) (display-buffer-fallback-action): Add display-buffer-in-previous-window. (display-buffer-use-some-window): Resize window to height it had before. (fit-window-to-buffer-horizontally): New option. (fit-frame-to-buffer): Describe new values. (fit-frame-to-buffer-bottom-margin): Replace with fit-frame-to-buffer-margins. (window--sanitize-margin): New function. (fit-frame-to-buffer, fit-window-to-buffer): Rewrite completely using window-text-pixel-size.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog240
-rw-r--r--src/dispextern.h73
-rw-r--r--src/dispnew.c160
-rw-r--r--src/frame.c352
-rw-r--r--src/frame.h211
-rw-r--r--src/fringe.c4
-rw-r--r--src/gtkutil.c25
-rw-r--r--src/indent.c4
-rw-r--r--src/keyboard.c19
-rw-r--r--src/keyboard.h1
-rw-r--r--src/lisp.h1
-rw-r--r--src/nsfns.m5
-rw-r--r--src/nsterm.h1
-rw-r--r--src/nsterm.m40
-rw-r--r--src/print.c5
-rw-r--r--src/term.c2
-rw-r--r--src/w32fns.c155
-rw-r--r--src/w32inevt.c6
-rw-r--r--src/w32menu.c2
-rw-r--r--src/w32term.c140
-rw-r--r--src/w32term.h3
-rw-r--r--src/widget.c12
-rw-r--r--src/window.c1113
-rw-r--r--src/window.h318
-rw-r--r--src/xdisp.c463
-rw-r--r--src/xfaces.c3
-rw-r--r--src/xfns.c72
-rw-r--r--src/xmenu.c2
-rw-r--r--src/xterm.c86
-rw-r--r--src/xterm.h3
30 files changed, 2652 insertions, 869 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 058597586e5..addfb838b47 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,243 @@
+2013-12-01 Martin Rudalics <rudalics@gmx.at>
+
+ Support resizing frames and windows pixelwise.
+ * dispextern.h (enum window_part): Add ON_SCROLL_BAR,
+ ON_RIGHT_DIVIDER and ON_BOTTOM_DIVIDER.
+ (struct glyph_matrix): Replace window_left_col and
+ window_top_line by window_pixel_left and window_pixel_top.
+ (WINDOW_WANTS_MODELINE_P, WINDOW_WANTS_HEADER_LINE_P): Minor
+ rewrite.
+ (enum face_id): Add WINDOW_DIVIDER_FACE_ID.
+ (draw_window_divider, move_it_to, x_draw_right_divider)
+ (x_draw_bottom_divider, change_frame_size): Add or fix
+ declarations.
+ * dispnew.c (change_frame_size_1): Change prototype.
+ (adjust_glyph_matrix, required_matrix_width)
+ (adjust_frame_glyphs_for_window_redisplay): Use pixel
+ values instead of lines and columns.
+ (marginal_area_string): Use WINDOW_FRINGES_WIDTH instead of
+ WINDOW_TOTAL_FRINGE_WIDTH.
+ (handle_window_change_signal, do_pending_window_change)
+ (init_display): Adjusts calls of change_frame_size.
+ (change_frame_size, change_frame_size_1): Handle pixelwise
+ changes.
+ * frame.c (Qright_divider_width, Qbottom_divider_width): New
+ Lisp objects.
+ (set_menu_bar_lines_1, set_menu_bar_lines, make_frame)
+ (make_terminal_frame, Fmake_terminal_frame, Fframe_parameters)
+ (x_set_internal_border_width, x_set_vertical_scroll_bars)
+ (x_set_scroll_bar_width, x_figure_window_size): Handle pixel
+ values.
+ (set_frame_param): New function.
+ (Fframe_text_cols, Fframe_text_lines, Fframe_total_cols)
+ (Fframe_text_width, Fframe_text_height, Fscroll_bar_width)
+ (Ffringe_width, Fborder_width, Fright_divider_width)
+ (Fbottom_divider_width): New functions, defsubr them.
+ (Fset_frame_height, Fset_frame_width, Fset_frame_size): New
+ argument pixelwise.
+ (struct frame_parm_table): New members Qright_divider_width and
+ Qbottom_divider_width.
+ (x_set_frame_parameters): Handle parameters for pixelwise sizes.
+ (x_report_frame_params): Handle Qright_divider_width and
+ Qbottom_divider_width.
+ (x_set_right_divider_width, x_set_bottom_divider_width): New
+ functions.
+ (frame_resize_pixelwise): New option.
+ * frame.h (struct frame): Add tool_bar_height, menu_bar_height,
+ new_pixelwise, right_divider_width and bottom_divider_width;
+ remove total_lines; rename text_lines, text_cols, new_text_lines
+ and new_text_cols to text_height, text_width, new_height and
+ new_width respectively.
+ (FRAME_LINES, FRAME_COLS): Rename to FRAME_TEXT_HEIGHT and
+ FRAME_TEXT_WIDTH respectively.
+ (FRAME_MENU_BAR_HEIGHT, FRAME_TOOL_BAR_HEIGHT)
+ (FRAME_RIGHT_DIVIDER_WIDTH, FRAME_BOTTOM_DIVIDER_WIDTH)
+ (FRAME_TEXT_TO_PIXEL_WIDTH, FRAME_PIXEL_TO_TEXT_WIDTH): New
+ macros.
+ (FRAME_TOP_MARGIN_HEIGHT, FRAME_LEFT_SCROLL_BAR_AREA_WIDTH)
+ (FRAME_RIGHT_SCROLL_BAR_AREA_WIDTH, FRAME_SCROLL_BAR_AREA_WIDTH)
+ (SET_FRAME_COLS, SET_FRAME_WIDTH, SET_FRAME_HEIGHT)
+ (FRAME_TEXT_COLS_TO_PIXEL_WIDTH, FRAME_PIXEL_WIDTH_TO_TEXT_COLS)
+ (FRAME_TEXT_COLS_TO_PIXEL_WIDTH): Rewrite macros.
+ (FRAME_TOTAL_COLS_ARG): Remove macro.
+ * fringe.c (draw_fringe_bitmap_1): Handle right divder.
+ * gtkutil.c (xg_frame_resized, xg_frame_set_char_size)
+ (x_wm_set_size_hint): Handle frame pixel sizes.
+ * indent.c (compute_motion, Fcompute_motion): Call
+ window_body_width instead of window_body_cols.
+ * keyboard.c (Qright_divider, Qbottom_divider): New symbols.
+ (make_lispy_position): Handle right and bottom dividers.
+ (Fsuspend_emacs): Pixelize call of change_frame_size.
+ * keyboard.h: Extern Qright_divider, Qbottom_divider.
+ * lisp.h: Extern set_frame_param.
+ * nsfns.m (x_set_tool_bar_lines): Pixelize call of
+ x_set_window_size.
+ (Fx_create_frame): Add entry for vertical_drag_cursor. Pixelize
+ call of change_frame_size.
+ * nsterm.h (struct ns_output): Add vertical_drag_cursor.
+ * nsterm.m (ns_update_window_end): Optionally draw right
+ divider.
+ (x_set_window_size): Add argument pixelwise. Call
+ check_frame_size and change_frame_size with pixelwise zero.
+ (ns_draw_window_divider): New function.
+ (ns_redisplay_interface): Add ns_draw_window_divider.
+ (updateFrameSize:): Call change_frame_size with pixelwise zero.
+ (x_new_font): Call x_set_window_size with pixelwise zero.
+ * print.c (print_object): For a window print its sequence
+ number again.
+ * term.c (Fresume_tty): Pixelize call of change_frame_size.
+ * w32fns.c (x_set_mouse_color): Handle vertical drag cursor.
+ (x_set_menu_bar_lines, x_set_tool_bar_lines): Calculate pixelwise.
+ (w32_createwindow): Use scroll bar area width.
+ (w32_wnd_proc): Handle bottom divider width. For
+ WM_WINDOWPOSCHANGING return zero if we resize pixelwise.
+ (Fx_create_frame): Default divider width parameters. Caclulate
+ sizes pixelwise. Add vertical drag cursor support.
+ (x_create_tip_frame): Default divider widths to zero. Pixelize
+ call to change_frame_size.
+ (Fx_show_tip): Add handling of divider widths. Pixelize window
+ position and sizes.
+ (Fw32_frame_rect): New function.
+ (frame_parm_handler w32_frame_parm_handlers): Add divider
+ widths.
+ (Vx_window_vertical_drag_shape): Add variable.
+ * w32inevt.c (resize_event, maybe_generate_resize_event):
+ Pixelize change_frame_size calls.
+ * w32menu.c (set_frame_menubar): Pixelize x_set_window_size
+ call.
+ * w32term.c (w32_draw_window_divider): New function.
+ (x_update_window_end): Handle right divider.
+ (w32_draw_fringe_bitmap, x_scroll_run)
+ (w32_set_vertical_scroll_bar): Pixelize scrollbar widths.
+ (w32_read_socket): Handle SIZE_MAXIMIZED separately. Calculate
+ new frame sizes pixelwise.
+ (x_new_font): Pixelize call to x_set_window_size.
+ (x_check_fullscreen): Pixelize call to change_frame_size.
+ (x_set_window_size_1, x_set_window_size): New argument
+ pixelwise. Calculate pixelwise.
+ (x_wm_set_size_hint): Use scroll bar area width.
+ (w32_redisplay_interface): Add w32_draw_window_divider.
+ * w32term.h (struct w32_output): Add vertical drag cursor.
+ * widget.c (set_frame_size, update_wm_hints)
+ (EmacsFrameResize, EmacsFrameSetValues): Pixelize calls of
+ change_frame_size.
+ (EmacsFrameSetCharSize): Pixelize call of x_set_window_size.
+ * window.c (sequence_number): Restore.
+ (Fwindow_pixel_width, Fwindow_pixel_height)
+ (Fwindow_mode_line_height, Fwindow_header_line_height)
+ (window_pixel_to_total, Frun_window_scroll_functions)
+ (Fset_window_new_pixel, window_resize_apply_total)
+ (Fwindow_resize_apply_total): New functions.
+ (window_body_height, window_body_width): Rename from
+ window_body_lines. New argument PIXELWISE. Calculate
+ pixelwise.
+ (Fwindow_body_height, Fwindow_body_width): New argument
+ PIXELWISE.
+ (coordinates_in_window, window_relative_x_coord): Use window's
+ pixel width instead of total width.
+ (replace_window, recombine_windows): Initialize pixel values.
+ (resize_root_window, resize_frame_windows, grow_mini_window)
+ (shrink_mini_window): New argument PIXELWISE. Calculate
+ pixelwise.
+ (Fdelete_other_windows_internal, adjust_window_margins)
+ (window_resize_check, window_resize_apply)
+ (Fdelete_window_internal, Fresize_mini_window_internal)
+ (Fwindow_text_width, Fwindow_text_height): Calculate pixelwise.
+ (check_frame_size): Rename arguments. New argument PIXELWISE.
+ Calculate pixelwise.
+ (set_window_buffer): Make samebuf bool. Run configuration change
+ hook only if buffer changed.
+ (Fset_window_buffer): Rewrite doc-string.
+ (make_window): Initialize new_pixel slot.
+ (Fwindow_resize_apply): Check pixel size of root window.
+ (Fsplit_window_internal): Call 2nd argument pixel_size.
+ Calculate pixelwise.
+ (Fscroll_left, Fscroll_right): Call window_body_width instead of
+ window_body_cols.
+ (save_window_data): New slots frame_text_width,
+ frame_text_height, frame_menu_bar_height, frame_tool_bar_height.
+ (saved_window): New slots pixel_left, pixel_top, pixel_height,
+ pixel_width.
+ (Fcurrent_window_configuration, Fset_window_configuration)
+ (save_window_save, compare_window_configurations): Handle new
+ slots in save_window_data and saved_window.
+ (Fset_window_scroll_bars): Fix doc-string.
+ (window_resize_pixelwise): New variable.
+ (coordinates_in_window, Fcoordinates_in_window_p): Handle
+ dividers.
+ (make_parent_window): Adjust sequence_number.
+ (Fwindow_right_divider_width, Fwindow_bottom_divider_width): New
+ functions.
+ * window.h (struct window): New members new_pixel, pixel_left,
+ pixel_top, pixel_width, pixel_height. Restore sequence_number.
+ (wset_new_pixel): New function.
+ (WINDOW_PIXEL_WIDTH, WINDOW_PIXEL_HEIGHT)
+ (MIN_SAFE_WINDOW_PIXEL_WIDTH, MIN_SAFE_WINDOW_PIXEL_HEIGHT)
+ (WINDOW_LEFT_PIXEL_EDGE, WINDOW_RIGHT_PIXEL_EDGE)
+ (WINDOW_TOP_PIXEL_EDGE, WINDOW_BOTTOM_PIXEL_EDGE)
+ (WINDOW_BOTTOMMOST_P, WINDOW_BOX_LEFT_PIXEL_EDGE)
+ (WINDOW_BOX_RIGHT_PIXEL_EDGE, WINDOW_MARGINS_COLS)
+ (WINDOW_MARGINS_WIDTH, WINDOW_RIGHT_DIVIDER_WIDTH)
+ (WINDOW_BOTTOM_DIVIDER_WIDTH): New macros.
+ (WINDOW_TOTAL_FRINGE_WIDTH): Rename to WINDOW_FRINGES_WIDTH.
+ (WINDOW_TOTAL_WIDTH, WINDOW_TOTAL_HEIGHT): Remove macros.
+ (WINDOW_RIGHT_EDGE_X, WINDOW_LEFT_EDGE_X, WINDOW_TOP_EDGE_Y)
+ (WINDOW_BOTTOM_EDGE_Y, WINDOW_FULL_WIDTH_P, WINDOW_LEFTMOST_P)
+ (WINDOW_RIGHTMOST_P, WINDOW_BOX_LEFT_EDGE_X)
+ (WINDOW_BOX_RIGHT_EDGE_X, WINDOW_FRINGE_COLS)
+ (WINDOW_BOX_HEIGHT_NO_MODE_LINE, WINDOW_BOX_TEXT_HEIGHT):
+ Rewrite.
+ (resize_frame_windows, grow_mini_window, shrink_mini_window)
+ (window_body_width, check_frame_size): Adapt external declarations.
+ * xdisp.c (last_max_ascent): New integer.
+ (window_text_bottom_y): Handle bottom divider.
+ (window_box_width, window_box_height): Calculate pixelwise.
+ (get_glyph_string_clip_rects): Handle right divider.
+ (remember_mouse_glyph): When windows are resized pixelwise
+ proceed with width and height set to 1.
+ (init_iterator): Use WINDOW_PIXEL_WIDTH instead of
+ WINDOW_TOTAL_WIDTH.
+ (move_it_to): Calculate and return maximum x position
+ encountered.
+ (Fwindow_text_pixel_size): New function.
+ (resize_mini_window, update_tool_bar): Calculate pixelwise.
+ (tool_bar_lines_needed): Rename to tool_bar_height. Calculate
+ pixelwise.
+ (Ftool_bar_lines_needed): Rename to Ftool_bar_height. Calculate
+ pixelwise.
+ (redisplay_tool_bar): Calculate pixelwise.
+ (redisplay_window): Calculate pixelwise. Handle dividers.
+ (draw_glyphs, x_clear_end_of_line, note_mouse_highlight)
+ (x_draw_vertical_border): Handle dividers.
+ (define_frame_cursor1): Handle vertical drag cursor.
+ (x_draw_right_divider, x_draw_bottom_divider): New functions.
+ (expose_window): Calculate pixelwise. Handle dividers.
+ (init_xdisp): Initialize pixel values.
+ * xfaces.c (Qwindow_divider): New face.
+ (realize_basic_faces): Realize it.
+ * xfns.c (x_set_mouse_color): Handle vertical_drag_cursor.
+ (x_set_menu_bar_lines, x_set_tool_bar_lines): Calculate pixelwise.
+ (x_set_scroll_bar_default_width): Default actual width to 16.
+ (Fx_create_frame): Set sizes pixelwise.
+ (x_create_tip_frame): Default divider widths to zero. Pixelize
+ call of change_frame_size.
+ (Fx_show_tip): Handle divider widths. Initial pixel position
+ and sizes.
+ (frame_parm_handler x_frame_parm_handlers): Add divider widths.
+ (Vx_window_vertical_drag_shape): New option.
+ * xmenu.c (free_frame_menubar): Pixelize call of
+ x_set_window_size.
+ * xterm.c (x_draw_window_divider): New function.
+ (x_update_window_end): Optionally draw right divider.
+ (x_draw_fringe_bitmap, x_scroll_run, x_scroll_bar_create)
+ (XTset_vertical_scroll_bar): Use scroll bar pixel width.
+ (handle_one_xevent, x_new_font): Calculate pixelwise.
+ (x_set_window_size_1, x_set_window_size): New argument
+ pixelwise. Calculate pixelwise.
+ (x_wm_set_size_hint): Pixelize call of check_frame_size.
+ (struct x_redisplay_interface): Add x_draw_window_divider.
+ * xterm.h (struct x_output): Add vertical_drag_cursor.
+
2013-11-30 Stefan Monnier <monnier@iro.umontreal.ca>
* xdisp.c (redisplay_internal): Don't call set_window_update_flags.
diff --git a/src/dispextern.h b/src/dispextern.h
index 6f162316242..fb2053476b0 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -118,7 +118,9 @@ enum window_part
ON_RIGHT_FRINGE,
ON_LEFT_MARGIN,
ON_RIGHT_MARGIN,
- ON_SCROLL_BAR
+ ON_SCROLL_BAR,
+ ON_RIGHT_DIVIDER,
+ ON_BOTTOM_DIVIDER
};
/* Number of bits allocated to store fringe bitmap numbers. */
@@ -667,7 +669,7 @@ struct glyph_pool
glyph memory, which is allocated in the form of a glyph_pool structure.
Glyph rows in such a window matrix are slices of frame matrix rows.
- 2. Free-standing window glyph matrices managing their own glyph
+ 3. Free-standing window glyph matrices managing their own glyph
storage. This form is used in window-based redisplay which
includes variable width and height fonts etc.
@@ -704,12 +706,12 @@ struct glyph_matrix
int matrix_w, matrix_h;
/* If this structure describes a window matrix of window W,
- window_left_col is the value of W->left_col, window_top_line the
- value of W->top_line, window_height and window_width are width and
- height of W, as returned by window_box, and window_vscroll is the
- value of W->vscroll at the time the matrix was last adjusted.
+ window_pixel_left is the value of W->pixel_left, window_pixel_top
+ the value of W->pixel_top, window_height and window_width are width
+ and height of W, as returned by window_box, and window_vscroll is
+ the value of W->vscroll at the time the matrix was last adjusted.
Only set for window-based redisplay. */
- int window_left_col, window_top_line;
+ int window_pixel_left, window_pixel_top;
int window_height, window_width;
int window_vscroll;
@@ -722,7 +724,7 @@ struct glyph_matrix
which do their own scrolling. */
unsigned no_scrolling_p : 1;
- /* Non-zero means window displayed in this matrix has a top mode
+ /* Non-zero means window displayed in this matrix has a header
line. */
unsigned header_line_p : 1;
@@ -1460,28 +1462,40 @@ struct glyph_string
#define DESIRED_HEADER_LINE_HEIGHT(W) \
MATRIX_HEADER_LINE_HEIGHT ((W)->desired_matrix)
-/* Value is non-zero if window W wants a mode line. */
+/* PXW: The height checks below serve to show at least one text line
+ instead of a mode- and/or header line when a window gets very small.
+ But (1) the check fails when the mode- or header-line is taller than
+ the associated frame's line height and (2) we don't care much about
+ text visibility anyway when shrinking a frame containing a toolbar.
-#define WINDOW_WANTS_MODELINE_P(W) \
- (!MINI_WINDOW_P ((W)) \
- && !(W)->pseudo_window_p \
- && FRAME_WANTS_MODELINE_P (XFRAME (WINDOW_FRAME ((W)))) \
- && BUFFERP ((W)->contents) \
- && !NILP (BVAR (XBUFFER ((W)->contents), mode_line_format)) \
- && WINDOW_TOTAL_LINES (W) > 1)
+ So maybe these checks should be removed and any clipping left to the
+ window manager. */
-/* Value is true if window W wants a header line. */
-
-#define WINDOW_WANTS_HEADER_LINE_P(W) \
+/* Value is non-zero if window W wants a mode line and is large enough
+ to accomodate it. */
+#define WINDOW_WANTS_MODELINE_P(W) \
(BUFFERP ((W)->contents) \
- ? (!MINI_WINDOW_P ((W)) \
+ ? (!MINI_WINDOW_P (W) \
&& !(W)->pseudo_window_p \
- && FRAME_WANTS_MODELINE_P (XFRAME (WINDOW_FRAME ((W)))) \
- && !NILP (BVAR (XBUFFER ((W)->contents), header_line_format)) \
- && WINDOW_TOTAL_LINES (W) > \
- (1 + !NILP (BVAR (XBUFFER ((W)->contents), mode_line_format)))) \
+ && FRAME_WANTS_MODELINE_P (XFRAME (WINDOW_FRAME (W))) \
+ && !NILP (BVAR (XBUFFER ((W)->contents), mode_line_format)) \
+ && WINDOW_PIXEL_HEIGHT (W) > WINDOW_FRAME_LINE_HEIGHT (W)) \
: 0)
+/* Value is non-zero if window W wants a header line and is large enough
+ to accomodate it. */
+#define WINDOW_WANTS_HEADER_LINE_P(W) \
+ (BUFFERP ((W)->contents) \
+ ? (!MINI_WINDOW_P (W) \
+ && !(W)->pseudo_window_p \
+ && FRAME_WANTS_MODELINE_P (XFRAME (WINDOW_FRAME (W))) \
+ && !NILP (BVAR (XBUFFER ((W)->contents), header_line_format)) \
+ && (WINDOW_PIXEL_HEIGHT (W) \
+ > (WINDOW_WANTS_MODELINE_P (W) \
+ ? (2 * WINDOW_FRAME_LINE_HEIGHT (W)) \
+ : WINDOW_FRAME_LINE_HEIGHT (W)))) \
+ : 0)
+
/* Return proper value to be used as baseline offset of font that has
ASCENT and DESCENT to draw characters by the font at the vertical
center of the line of frame F.
@@ -1751,6 +1765,7 @@ enum face_id
MOUSE_FACE_ID,
MENU_FACE_ID,
VERTICAL_BORDER_FACE_ID,
+ WINDOW_DIVIDER_FACE_ID,
BASIC_FACE_ID_SENTINEL
};
@@ -2850,6 +2865,10 @@ struct redisplay_interface
void (*draw_vertical_window_border) (struct window *w,
int x, int y_0, int y_1);
+/* Draw window divider for window W from (X_0, Y_0) to (X_1, ,Y_1). */
+ void (*draw_window_divider) (struct window *w,
+ int x_0, int x_1, int y_0, int y_1);
+
/* Shift display of frame F to make room for inserted glyphs.
The area at pixel (X,Y) of width WIDTH and height HEIGHT is
shifted right by SHIFT_BY pixels. */
@@ -3167,6 +3186,7 @@ int window_box_left_offset (struct window *, enum glyph_row_area);
int window_box_right (struct window *, enum glyph_row_area);
int window_box_right_offset (struct window *, enum glyph_row_area);
int estimate_mode_line_height (struct frame *, enum face_id);
+int move_it_to (struct it *, ptrdiff_t, int, int, int, int);
void pixel_to_glyph_coords (struct frame *, int, int, int *, int *,
NativeRectangle *, int);
void remember_mouse_glyph (struct frame *, int, int, NativeRectangle *);
@@ -3178,7 +3198,6 @@ void init_iterator (struct it *, struct window *, ptrdiff_t,
void init_iterator_to_row_start (struct it *, struct window *,
struct glyph_row *);
void start_display (struct it *, struct window *, struct text_pos);
-void move_it_to (struct it *, ptrdiff_t, int, int, int, int);
void move_it_vertically (struct it *, int);
void move_it_vertically_backward (struct it *, int);
void move_it_by_lines (struct it *, ptrdiff_t);
@@ -3235,6 +3254,8 @@ extern void display_and_set_cursor (struct window *, bool, int, int, int, int);
extern void x_update_cursor (struct frame *, bool);
extern void x_clear_cursor (struct window *);
extern void x_draw_vertical_border (struct window *w);
+extern void x_draw_right_divider (struct window *w);
+extern void x_draw_bottom_divider (struct window *w);
extern int get_glyph_string_clip_rects (struct glyph_string *,
NativeRectangle *, int);
@@ -3464,7 +3485,7 @@ void clear_glyph_row (struct glyph_row *);
void prepare_desired_row (struct glyph_row *);
void update_single_window (struct window *, bool);
void do_pending_window_change (bool);
-void change_frame_size (struct frame *, int, int, bool, bool, bool);
+void change_frame_size (struct frame *, int, int, bool, bool, bool, bool);
void init_display (void);
void syms_of_display (void);
extern Lisp_Object Qredisplay_dont_pause;
diff --git a/src/dispnew.c b/src/dispnew.c
index b68cc2e54f8..94929600286 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -72,7 +72,7 @@ struct dim
static void update_frame_line (struct frame *, int);
static int required_matrix_height (struct window *);
static int required_matrix_width (struct window *);
-static void change_frame_size_1 (struct frame *, int, int, bool, bool, bool);
+static void change_frame_size_1 (struct frame *, int, int, bool, bool, bool, bool);
static void increment_row_positions (struct glyph_row *, ptrdiff_t, ptrdiff_t);
static void build_frame_matrix_from_window_tree (struct glyph_matrix *,
struct window *);
@@ -401,8 +401,8 @@ adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y
if (!marginal_areas_changed_p
&& !XFRAME (w->frame)->fonts_changed
&& !header_line_changed_p
- && matrix->window_left_col == WINDOW_LEFT_EDGE_COL (w)
- && matrix->window_top_line == WINDOW_TOP_EDGE_LINE (w)
+ && matrix->window_pixel_left == WINDOW_LEFT_PIXEL_EDGE (w)
+ && matrix->window_pixel_top == WINDOW_TOP_PIXEL_EDGE (w)
&& matrix->window_height == window_height
&& matrix->window_vscroll == w->vscroll
&& matrix->window_width == window_width)
@@ -543,8 +543,8 @@ adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y
&& !header_line_changed_p
&& new_rows == 0
&& dim.width == matrix->matrix_w
- && matrix->window_left_col == WINDOW_LEFT_EDGE_COL (w)
- && matrix->window_top_line == WINDOW_TOP_EDGE_LINE (w)
+ && matrix->window_pixel_left == WINDOW_LEFT_PIXEL_EDGE (w)
+ && matrix->window_pixel_top == WINDOW_TOP_PIXEL_EDGE (w)
&& matrix->window_width == window_width)
{
/* Find the last row in the window. */
@@ -591,8 +591,8 @@ adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y
was last adjusted. This is used to optimize redisplay above. */
if (w)
{
- matrix->window_left_col = WINDOW_LEFT_EDGE_COL (w);
- matrix->window_top_line = WINDOW_TOP_EDGE_LINE (w);
+ matrix->window_pixel_left = WINDOW_LEFT_PIXEL_EDGE (w);
+ matrix->window_pixel_top = WINDOW_TOP_PIXEL_EDGE (w);
matrix->window_height = window_height;
matrix->window_width = window_width;
matrix->window_vscroll = w->vscroll;
@@ -1661,6 +1661,7 @@ required_matrix_height (struct window *w)
{
int ch_height = FRAME_SMALLEST_FONT_HEIGHT (f);
int window_pixel_height = window_box_height (w) + eabs (w->vscroll);
+
return (((window_pixel_height + ch_height - 1)
/ ch_height) * w->nrows_scale_factor
/* One partially visible line at the top and
@@ -1685,10 +1686,9 @@ required_matrix_width (struct window *w)
if (FRAME_WINDOW_P (f))
{
int ch_width = FRAME_SMALLEST_CHAR_WIDTH (f);
- int window_pixel_width = WINDOW_TOTAL_WIDTH (w);
/* Compute number of glyphs needed in a glyph row. */
- return (((window_pixel_width + ch_width - 1)
+ return (((WINDOW_PIXEL_WIDTH (w) + ch_width - 1)
/ ch_width) * w->ncols_scale_factor
/* 2 partially visible columns in the text area. */
+ 2
@@ -1978,6 +1978,10 @@ adjust_frame_glyphs_for_frame_redisplay (struct frame *f)
/* Size of frame matrices must equal size of frame. Note
that we are called for X frames with window widths NOT equal
to the frame width (from CHANGE_FRAME_SIZE_1). */
+ if (matrix_dim.width != FRAME_COLS (f)
+ || matrix_dim.height != FRAME_LINES (f))
+ return;
+
eassert (matrix_dim.width == FRAME_COLS (f)
&& matrix_dim.height == FRAME_LINES (f));
@@ -2047,10 +2051,14 @@ adjust_frame_glyphs_for_window_redisplay (struct frame *f)
/* Set window dimensions to frame dimensions and allocate or
adjust glyph matrices of W. */
- w->top_line = 0;
+ w->pixel_left = 0;
w->left_col = 0;
- w->total_lines = FRAME_MENU_BAR_LINES (f);
+ w->pixel_top = 0;
+ w->top_line = 0;
+ w->pixel_width = FRAME_PIXEL_WIDTH (f);
w->total_cols = FRAME_TOTAL_COLS (f);
+ w->pixel_height = FRAME_MENU_BAR_HEIGHT (f);
+ w->total_lines = FRAME_MENU_BAR_LINES (f);
allocate_matrices_for_window_redisplay (w);
}
#endif
@@ -2072,10 +2080,15 @@ adjust_frame_glyphs_for_window_redisplay (struct frame *f)
else
w = XWINDOW (f->tool_bar_window);
- w->top_line = FRAME_MENU_BAR_LINES (f);
+ w->pixel_left = 0;
w->left_col = 0;
- w->total_lines = FRAME_TOOL_BAR_LINES (f);
+ w->pixel_top = FRAME_MENU_BAR_HEIGHT (f);
+ w->top_line = FRAME_MENU_BAR_LINES (f);
+ w->pixel_width = (FRAME_PIXEL_WIDTH (f)
+ - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
w->total_cols = FRAME_TOTAL_COLS (f);
+ w->pixel_height = FRAME_TOOL_BAR_HEIGHT (f);
+ w->total_lines = FRAME_TOOL_BAR_LINES (f);
allocate_matrices_for_window_redisplay (w);
}
#endif
@@ -5275,7 +5288,7 @@ marginal_area_string (struct window *w, enum window_part part,
if (area == RIGHT_MARGIN_AREA)
x0 = ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
? WINDOW_LEFT_FRINGE_WIDTH (w)
- : WINDOW_TOTAL_FRINGE_WIDTH (w))
+ : WINDOW_FRINGES_WIDTH (w))
+ window_box_width (w, LEFT_MARGIN_AREA)
+ window_box_width (w, TEXT_AREA));
else
@@ -5367,7 +5380,7 @@ handle_window_change_signal (int sig)
/* Record the new sizes, but don't reallocate the data
structures now. Let that be done later outside of the
signal handler. */
- change_frame_size (XFRAME (frame), height, width, 0, 1, 0);
+ change_frame_size (XFRAME (frame), width, height, 0, 1, 0, 0);
}
}
}
@@ -5401,17 +5414,21 @@ do_pending_window_change (bool safe)
{
struct frame *f = XFRAME (frame);
- if (f->new_text_lines != 0 || f->new_text_cols != 0)
- change_frame_size (f, f->new_text_lines, f->new_text_cols,
- 0, 0, safe);
+ if (f->new_height != 0 || f->new_width != 0)
+ change_frame_size (f, f->new_width, f->new_height,
+ 0, 0, safe, f->new_pixelwise);
}
}
}
-
/* Change the frame height and/or width. Values may be given as zero to
indicate no change is to take place.
+ new_height and new_width refer to the text portion of the frame. It
+ doesn't matter for new_height, since text and total portion are the
+ same in that case. But new_width must be enlarged to get the total
+ width of the frame.
+
If DELAY, assume we're being called from a signal handler, and
queue the change for later - perhaps the next redisplay.
Since this tries to resize windows, we can't call it
@@ -5421,8 +5438,8 @@ do_pending_window_change (bool safe)
safe to change frame sizes while a redisplay is in progress. */
void
-change_frame_size (struct frame *f, int newheight, int newwidth,
- bool pretend, bool delay, bool safe)
+change_frame_size (struct frame *f, int new_width, int new_height,
+ bool pretend, bool delay, bool safe, bool pixelwise)
{
Lisp_Object tail, frame;
@@ -5433,55 +5450,72 @@ change_frame_size (struct frame *f, int newheight, int newwidth,
ttys. */
FOR_EACH_FRAME (tail, frame)
if (! FRAME_WINDOW_P (XFRAME (frame)))
- change_frame_size_1 (XFRAME (frame), newheight, newwidth,
- pretend, delay, safe);
+ change_frame_size_1 (XFRAME (frame), new_width, new_height,
+ pretend, delay, safe, pixelwise);
}
else
- change_frame_size_1 (f, newheight, newwidth, pretend, delay, safe);
+ change_frame_size_1 (f, new_width, new_height, pretend, delay, safe,
+ pixelwise);
}
static void
-change_frame_size_1 (struct frame *f, int newheight, int newwidth,
- bool pretend, bool delay, bool safe)
+change_frame_size_1 (struct frame *f, int new_width, int new_height,
+ bool pretend, bool delay, bool safe, bool pixelwise)
{
- int new_frame_total_cols;
+ int new_text_width, new_text_height, new_root_width;
+ int old_root_width = (FRAME_PIXEL_WIDTH (f)
+ - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
+ int new_cols, new_lines;
ptrdiff_t count = SPECPDL_INDEX ();
/* If we can't deal with the change now, queue it for later. */
if (delay || (redisplaying_p && !safe))
{
- f->new_text_lines = newheight;
- f->new_text_cols = newwidth;
+ f->new_width = new_width;
+ f->new_height = new_height;
+ f->new_pixelwise = pixelwise;
delayed_size_change = 1;
return;
}
/* This size-change overrides any pending one for this frame. */
- f->new_text_lines = 0;
- f->new_text_cols = 0;
+ f->new_height = 0;
+ f->new_width = 0;
+ f->new_pixelwise = 0;
/* If an argument is zero, set it to the current value. */
- if (newheight == 0)
- newheight = FRAME_LINES (f);
- if (newwidth == 0)
- newwidth = FRAME_COLS (f);
+ if (pixelwise)
+ {
+ new_text_width = (new_width == 0) ? FRAME_TEXT_WIDTH (f) : new_width;
+ new_text_height = (new_height == 0) ? FRAME_TEXT_HEIGHT (f) : new_height;
+ new_cols = new_text_width / FRAME_COLUMN_WIDTH (f);
+ new_lines = new_text_height / FRAME_LINE_HEIGHT (f);
+ }
+ else
+ {
+ new_cols = (new_width == 0) ? FRAME_COLS (f) : new_width;
+ new_lines = (new_height == 0) ? FRAME_LINES (f) : new_height;
+ new_text_width = new_cols * FRAME_COLUMN_WIDTH (f);
+ new_text_height = new_lines * FRAME_LINE_HEIGHT (f);
+ }
/* Compute width of windows in F. */
/* Round up to the smallest acceptable size. */
- check_frame_size (f, &newheight, &newwidth);
-
- /* This is the width of the frame with vertical scroll bars and fringe
- columns. Do this after rounding - see discussion of bug#9723. */
- new_frame_total_cols = FRAME_TOTAL_COLS_ARG (f, newwidth);
-
+ check_frame_size (f, &new_text_width, &new_text_height, 1);
+
+ /* This is the width of the frame without vertical scroll bars and
+ fringe columns. Do this after rounding - see discussion of
+ bug#9723. */
+ new_root_width = (new_text_width
+ /* PXM: Use the configured scrollbar width !?? */
+ + FRAME_SCROLL_BAR_AREA_WIDTH (f)
+ + FRAME_TOTAL_FRINGE_WIDTH (f));
/* If we're not changing the frame size, quit now. */
/* Frame width may be unchanged but the text portion may change, for
example, fullscreen and remove/add scroll bar. */
- if (newheight == FRAME_LINES (f)
- /* Text portion unchanged? */
- && newwidth == FRAME_COLS (f)
- /* Frame width unchanged? */
- && new_frame_total_cols == FRAME_TOTAL_COLS (f))
+ if (new_text_height == FRAME_TEXT_HEIGHT (f)
+ && new_text_width == FRAME_TEXT_WIDTH (f)
+ && new_root_width == old_root_width)
return;
block_input ();
@@ -5490,36 +5524,44 @@ change_frame_size_1 (struct frame *f, int newheight, int newwidth,
/* We only can set screen dimensions to certain values supported
by our video hardware. Try to find the smallest size greater
or equal to the requested dimensions. */
- dos_set_window_size (&newheight, &newwidth);
+ dos_set_window_size (&new_lines, &new_cols);
#endif
- if (newheight != FRAME_LINES (f))
+ if (new_text_height != FRAME_TEXT_HEIGHT (f))
{
- resize_frame_windows (f, newheight, 0);
+ resize_frame_windows (f, new_text_height, 0, 1);
/* MSDOS frames cannot PRETEND, as they change frame size by
manipulating video hardware. */
if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f))
- FrameRows (FRAME_TTY (f)) = newheight;
+ FrameRows (FRAME_TTY (f)) = new_height;
}
- if (new_frame_total_cols != FRAME_TOTAL_COLS (f))
+ if (new_text_width != FRAME_TEXT_WIDTH (f)
+ || new_root_width != old_root_width)
{
- resize_frame_windows (f, new_frame_total_cols, 1);
+ resize_frame_windows (f, new_root_width, 1, 1);
/* MSDOS frames cannot PRETEND, as they change frame size by
manipulating video hardware. */
if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f))
- FrameCols (FRAME_TTY (f)) = newwidth;
+ FrameCols (FRAME_TTY (f)) = new_cols;
#if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
if (WINDOWP (f->tool_bar_window))
- XWINDOW (f->tool_bar_window)->total_cols = newwidth;
+ {
+ XWINDOW (f->tool_bar_window)->total_cols = new_cols;
+ XWINDOW (f->tool_bar_window)->pixel_width = new_root_width;
+ }
#endif
}
- FRAME_LINES (f) = newheight;
- SET_FRAME_COLS (f, newwidth);
+ SET_FRAME_COLS (f, new_cols);
+ FRAME_LINES (f) = new_lines;
+ FRAME_TEXT_WIDTH (f) = new_text_width;
+ FRAME_TEXT_HEIGHT (f) = new_text_height;
+ FRAME_PIXEL_WIDTH (f) = FRAME_TEXT_TO_PIXEL_WIDTH (f, new_text_width);
+ FRAME_PIXEL_HEIGHT (f) = FRAME_TEXT_TO_PIXEL_HEIGHT (f, new_text_height);
{
struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
@@ -5546,8 +5588,6 @@ change_frame_size_1 (struct frame *f, int newheight, int newwidth,
unbind_to (count, Qnil);
}
-
-
/***********************************************************************
Terminal Related Lisp Functions
@@ -6076,8 +6116,8 @@ init_display (void)
#endif
t->display_info.tty->top_frame = selected_frame;
change_frame_size (XFRAME (selected_frame),
- FrameRows (t->display_info.tty),
- FrameCols (t->display_info.tty), 0, 0, 1);
+ FrameCols (t->display_info.tty),
+ FrameRows (t->display_info.tty), 0, 0, 1, 0);
/* Delete the initial terminal. */
if (--initial_terminal->reference_count == 0
diff --git a/src/frame.c b/src/frame.c
index 35e7ff1fbb4..df41822f916 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -78,6 +78,7 @@ Lisp_Object Qleft, Qright;
Lisp_Object Qicon_left, Qicon_top, Qicon_type, Qicon_name;
Lisp_Object Qtooltip;
Lisp_Object Qinternal_border_width;
+Lisp_Object Qright_divider_width, Qbottom_divider_width;
Lisp_Object Qmouse_color;
Lisp_Object Qminibuffer;
Lisp_Object Qscroll_bar_width, Qvertical_scroll_bars;
@@ -197,9 +198,12 @@ static void
set_menu_bar_lines_1 (Lisp_Object window, int n)
{
struct window *w = XWINDOW (window);
+ struct frame *f = XFRAME (WINDOW_FRAME (w));
w->top_line += n;
+ w->pixel_top += n * FRAME_LINE_HEIGHT (f);
w->total_lines -= n;
+ w->pixel_height -= n * FRAME_LINE_HEIGHT (f);
/* Handle just the top child in a vertical split. */
if (WINDOW_VERTICAL_COMBINATION_P (w))
@@ -236,6 +240,7 @@ set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
windows_or_buffers_changed = 14;
FRAME_WINDOW_SIZES_CHANGED (f) = 1;
FRAME_MENU_BAR_LINES (f) = nlines;
+ FRAME_MENU_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f);
set_menu_bar_lines_1 (f->root_window, nlines - olines);
adjust_frame_glyphs (f);
}
@@ -325,6 +330,7 @@ make_frame (bool mini_p)
{
Lisp_Object frame;
register struct frame *f;
+ register struct window *rw, *mw;
register Lisp_Object root_window;
register Lisp_Object mini_window;
@@ -350,23 +356,25 @@ make_frame (bool mini_p)
#endif
root_window = make_window ();
+ rw = XWINDOW (root_window);
if (mini_p)
{
mini_window = make_window ();
- wset_next (XWINDOW (root_window), mini_window);
- wset_prev (XWINDOW (mini_window), root_window);
- XWINDOW (mini_window)->mini = 1;
- wset_frame (XWINDOW (mini_window), frame);
+ mw = XWINDOW (mini_window);
+ wset_next (rw, mini_window);
+ wset_prev (mw, root_window);
+ mw->mini = 1;
+ wset_frame (mw, frame);
fset_minibuffer_window (f, mini_window);
}
else
{
mini_window = Qnil;
- wset_next (XWINDOW (root_window), Qnil);
+ wset_next (rw, Qnil);
fset_minibuffer_window (f, Qnil);
}
- wset_frame (XWINDOW (root_window), frame);
+ wset_frame (rw, frame);
/* 10 is arbitrary,
just so that there is "something there."
@@ -374,15 +382,22 @@ make_frame (bool mini_p)
SET_FRAME_COLS (f, 10);
FRAME_LINES (f) = 10;
+ SET_FRAME_WIDTH (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f));
+ SET_FRAME_HEIGHT (f, FRAME_LINES (f) * FRAME_LINE_HEIGHT (f));
- XWINDOW (root_window)->total_cols = 10;
- XWINDOW (root_window)->total_lines = mini_p ? 9 : 10;
+ rw->total_cols = 10;
+ rw->pixel_width = rw->total_cols * FRAME_COLUMN_WIDTH (f);
+ rw->total_lines = mini_p ? 9 : 10;
+ rw->pixel_height = rw->total_lines * FRAME_LINE_HEIGHT (f);
if (mini_p)
{
- XWINDOW (mini_window)->total_cols = 10;
- XWINDOW (mini_window)->top_line = 9;
- XWINDOW (mini_window)->total_lines = 1;
+ mw->top_line = rw->total_lines;
+ mw->pixel_top = rw->pixel_height;
+ mw->total_cols = rw->total_cols;
+ mw->pixel_width = rw->pixel_width;
+ mw->total_lines = 1;
+ mw->pixel_height = FRAME_LINE_HEIGHT (f);
}
/* Choose a buffer for the frame's root window. */
@@ -603,7 +618,8 @@ make_terminal_frame (struct terminal *terminal)
#endif /* not MSDOS */
FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
- FRAME_MENU_BAR_LINES(f) = NILP (Vmenu_bar_mode) ? 0 : 1;
+ FRAME_MENU_BAR_LINES (f) = NILP (Vmenu_bar_mode) ? 0 : 1;
+ FRAME_MENU_BAR_HEIGHT (f) = FRAME_MENU_BAR_LINES (f) * FRAME_LINE_HEIGHT (f);
/* Set the top frame to the newly created frame. */
if (FRAMEP (FRAME_TTY (f)->top_frame)
@@ -723,7 +739,7 @@ affects all frames on the same terminal device. */)
{
int width, height;
get_tty_size (fileno (FRAME_TTY (f)->input), &width, &height);
- change_frame_size (f, height, width, 0, 0, 0);
+ change_frame_size (f, width, height, 0, 0, 0, 0);
}
adjust_frame_glyphs (f);
@@ -2012,6 +2028,18 @@ set_term_frame_name (struct frame *f, Lisp_Object name)
}
void
+set_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val)
+{
+ register Lisp_Object old_alist_elt;
+
+ old_alist_elt = Fassq (prop, f->param_alist);
+ if (EQ (old_alist_elt, Qnil))
+ fset_param_alist (f, Fcons (Fcons (prop, val), f->param_alist));
+ else
+ Fsetcdr (old_alist_elt, val);
+}
+
+void
store_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val)
{
register Lisp_Object old_alist_elt;
@@ -2164,9 +2192,17 @@ If FRAME is omitted or nil, return information on the currently selected frame.
:"tty"));
}
store_in_alist (&alist, Qname, f->name);
- height = (f->new_text_lines ? f->new_text_lines : FRAME_LINES (f));
+ height = (f->new_height
+ ? (f->new_pixelwise
+ ? (f->new_height / FRAME_LINE_HEIGHT (f))
+ : f->new_height)
+ : FRAME_LINES (f));
store_in_alist (&alist, Qheight, make_number (height));
- width = (f->new_text_cols ? f->new_text_cols : FRAME_COLS (f));
+ width = (f->new_width
+ ? (f->new_pixelwise
+ ? (f->new_width / FRAME_COLUMN_WIDTH (f))
+ : f->new_width)
+ : FRAME_COLS (f));
store_in_alist (&alist, Qwidth, make_number (width));
store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
store_in_alist (&alist, Qminibuffer,
@@ -2437,80 +2473,180 @@ is used. */)
#endif
return make_number (0);
}
+
+DEFUN ("frame-text-cols", Fframe_text_cols, Sframe_text_cols, 0, 1, 0,
+ doc: /* Return width in columns of FRAME's text area. */)
+ (Lisp_Object frame)
+{
+ return make_number (FRAME_COLS (decode_any_frame (frame)));
+}
+
+DEFUN ("frame-text-lines", Fframe_text_lines, Sframe_text_lines, 0, 1, 0,
+ doc: /* Return height in lines of FRAME's text area. */)
+ (Lisp_Object frame)
+{
+ return make_number (FRAME_LINES (decode_any_frame (frame)));
+}
+
+DEFUN ("frame-total-cols", Fframe_total_cols, Sframe_total_cols, 0, 1, 0,
+ doc: /* Return total columns of FRAME. */)
+ (Lisp_Object frame)
+{
+ return make_number (FRAME_TOTAL_COLS (decode_any_frame (frame)));
+}
+
+DEFUN ("frame-text-width", Fframe_text_width, Sframe_text_width, 0, 1, 0,
+ doc: /* Return text area width of FRAME in pixels. */)
+ (Lisp_Object frame)
+{
+ return make_number (FRAME_TEXT_WIDTH (decode_any_frame (frame)));
+}
+
+DEFUN ("frame-text-height", Fframe_text_height, Sframe_text_height, 0, 1, 0,
+ doc: /* Return text area height of FRAME in pixels. */)
+ (Lisp_Object frame)
+{
+ return make_number (FRAME_TEXT_HEIGHT (decode_any_frame (frame)));
+}
+
+DEFUN ("frame-scroll-bar-width", Fscroll_bar_width, Sscroll_bar_width, 0, 1, 0,
+ doc: /* Return scroll bar width of FRAME in pixels. */)
+ (Lisp_Object frame)
+{
+ return make_number (decode_any_frame (frame)->scroll_bar_actual_width);
+}
+
+DEFUN ("frame-fringe-width", Ffringe_width, Sfringe_width, 0, 1, 0,
+ doc: /* Return fringe width of FRAME in pixels. */)
+ (Lisp_Object frame)
+{
+ return make_number (FRAME_TOTAL_FRINGE_WIDTH (decode_any_frame (frame)));
+}
+
+DEFUN ("frame-border-width", Fborder_width, Sborder_width, 0, 1, 0,
+ doc: /* Return border width of FRAME in pixels. */)
+ (Lisp_Object frame)
+{
+ return make_number (FRAME_INTERNAL_BORDER_WIDTH (decode_any_frame (frame)));
+}
+
+DEFUN ("frame-right-divider-width", Fright_divider_width, Sright_divider_width, 0, 1, 0,
+ doc: /* Return width (in pixels) of vertical window dividers on FRAME. */)
+ (Lisp_Object frame)
+{
+ return make_number (FRAME_RIGHT_DIVIDER_WIDTH (decode_any_frame (frame)));
+}
+
+DEFUN ("frame-bottom-divider-width", Fbottom_divider_width, Sbottom_divider_width, 0, 1, 0,
+ doc: /* Return width (in pixels) of horizontal window dividers on FRAME. */)
+ (Lisp_Object frame)
+{
+ return make_number (FRAME_BOTTOM_DIVIDER_WIDTH (decode_any_frame (frame)));
+}
-DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
- doc: /* Specify that the frame FRAME has LINES lines.
-If FRAME is nil, the selected frame is used. Optional third arg
-non-nil means that redisplay should use LINES lines but that the
-idea of the actual height of the frame should not be changed. */)
- (Lisp_Object frame, Lisp_Object lines, Lisp_Object pretend)
+DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 4, 0,
+ doc: /* Specify that the frame FRAME has HEIGHT text lines.
+Optional third arg PRETEND non-nil means that redisplay should use
+HEIGHT lines but that the idea of the actual height of the frame should
+not be changed. Optional fourth argument PIXELWISE non-nil means that
+FRAME should be HEIGHT pixels high. */)
+ (Lisp_Object frame, Lisp_Object height, Lisp_Object pretend, Lisp_Object pixelwise)
{
register struct frame *f = decode_live_frame (frame);
- CHECK_TYPE_RANGED_INTEGER (int, lines);
+ CHECK_TYPE_RANGED_INTEGER (int, height);
/* I think this should be done with a hook. */
#ifdef HAVE_WINDOW_SYSTEM
if (FRAME_WINDOW_P (f))
{
- if (XINT (lines) != FRAME_LINES (f))
- x_set_window_size (f, 1, FRAME_COLS (f), XINT (lines));
- do_pending_window_change (0);
+ if (NILP (pixelwise))
+ {
+ if (XINT (height) != FRAME_LINES (f))
+ x_set_window_size (f, 1, FRAME_COLS (f), XINT (height), 0);
+
+ do_pending_window_change (0);
+ }
+ else if (XINT (height) != FRAME_TEXT_HEIGHT (f))
+ {
+ x_set_window_size (f, 1, FRAME_TEXT_WIDTH (f), XINT (height), 1);
+ do_pending_window_change (0);
+ }
}
else
#endif
- change_frame_size (f, XINT (lines), 0, !NILP (pretend), 0, 0);
+ change_frame_size (f, 0, XINT (height), !NILP (pretend), 0, 0,
+ NILP (pixelwise) ? 0 : 1);
return Qnil;
}
-DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
- doc: /* Specify that the frame FRAME has COLS columns.
-If FRAME is nil, the selected frame is used. Optional third arg
-non-nil means that redisplay should use COLS columns but that the
-idea of the actual width of the frame should not be changed. */)
- (Lisp_Object frame, Lisp_Object cols, Lisp_Object pretend)
+DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 4, 0,
+ doc: /* Specify that the frame FRAME has WIDTH columns.
+Optional third arg PRETEND non-nil means that redisplay should use WIDTH
+columns but that the idea of the actual width of the frame should not
+be changed. Optional fourth argument PIXELWISE non-nil means that FRAME
+should be WIDTH pixels wide. */)
+ (Lisp_Object frame, Lisp_Object width, Lisp_Object pretend, Lisp_Object pixelwise)
{
register struct frame *f = decode_live_frame (frame);
- CHECK_TYPE_RANGED_INTEGER (int, cols);
+ CHECK_TYPE_RANGED_INTEGER (int, width);
/* I think this should be done with a hook. */
#ifdef HAVE_WINDOW_SYSTEM
if (FRAME_WINDOW_P (f))
{
- if (XINT (cols) != FRAME_COLS (f))
- x_set_window_size (f, 1, XINT (cols), FRAME_LINES (f));
- do_pending_window_change (0);
+ if (NILP (pixelwise))
+ {
+ if (XINT (width) != FRAME_COLS (f))
+ x_set_window_size (f, 1, XINT (width), FRAME_LINES (f), 0);
+
+ do_pending_window_change (0);
+ }
+ else if (XINT (width) != FRAME_TEXT_WIDTH (f))
+ {
+ x_set_window_size (f, 1, XINT (width), FRAME_TEXT_HEIGHT (f), 1);
+ do_pending_window_change (0);
+ }
}
else
#endif
- change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0, 0);
+ change_frame_size (f, XINT (width), 0, !NILP (pretend), 0, 0,
+ NILP (pixelwise) ? 0 : 1);
return Qnil;
}
-DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
- doc: /* Sets size of FRAME to COLS by ROWS, measured in characters.
-If FRAME is nil, the selected frame is used. */)
- (Lisp_Object frame, Lisp_Object cols, Lisp_Object rows)
+DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 4, 0,
+ doc: /* Sets size of FRAME to WIDTH by HEIGHT, measured in characters.
+Optional argument PIXELWISE non-nil means to measure in pixels. */)
+ (Lisp_Object frame, Lisp_Object width, Lisp_Object height, Lisp_Object pixelwise)
{
register struct frame *f = decode_live_frame (frame);
- CHECK_TYPE_RANGED_INTEGER (int, cols);
- CHECK_TYPE_RANGED_INTEGER (int, rows);
+ CHECK_TYPE_RANGED_INTEGER (int, width);
+ CHECK_TYPE_RANGED_INTEGER (int, height);
/* I think this should be done with a hook. */
#ifdef HAVE_WINDOW_SYSTEM
if (FRAME_WINDOW_P (f))
{
- if (XINT (rows) != FRAME_LINES (f)
- || XINT (cols) != FRAME_COLS (f)
- || f->new_text_lines || f->new_text_cols)
- x_set_window_size (f, 1, XINT (cols), XINT (rows));
- do_pending_window_change (0);
+ if (!NILP (pixelwise)
+ ? (XINT (width) != FRAME_TEXT_WIDTH (f)
+ || XINT (height) != FRAME_TEXT_HEIGHT (f)
+ || f->new_height || f->new_width)
+ : (XINT (width) != FRAME_COLS (f)
+ || XINT (height) != FRAME_LINES (f)
+ || f->new_height || f->new_width))
+ {
+ x_set_window_size (f, 1, XINT (width), XINT (height),
+ NILP (pixelwise) ? 0 : 1);
+ do_pending_window_change (0);
+ }
}
else
#endif
- change_frame_size (f, XINT (rows), XINT (cols), 0, 0, 0);
+ change_frame_size (f, XINT (width), XINT (height), 0, 0, 0,
+ NILP (pixelwise) ? 0 : 1);
return Qnil;
}
@@ -2569,6 +2705,8 @@ static const struct frame_parm_table frame_parms[] =
{"icon-name", &Qicon_name},
{"icon-type", &Qicon_type},
{"internal-border-width", &Qinternal_border_width},
+ {"right-divider-width", &Qright_divider_width},
+ {"bottom-divider-width", &Qbottom_divider_width},
{"menu-bar-lines", &Qmenu_bar_lines},
{"mouse-color", &Qmouse_color},
{"name", &Qname},
@@ -2703,8 +2841,16 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist)
icon_left = icon_top = Qunbound;
/* Provide default values for HEIGHT and WIDTH. */
- width = (f->new_text_cols ? f->new_text_cols : FRAME_COLS (f));
- height = (f->new_text_lines ? f->new_text_lines : FRAME_LINES (f));
+ width = (f->new_width
+ ? (f->new_pixelwise
+ ? (f->new_width / FRAME_COLUMN_WIDTH (f))
+ : f->new_width)
+ : FRAME_COLS (f));
+ height = (f->new_height
+ ? (f->new_pixelwise
+ ? (f->new_height / FRAME_LINE_HEIGHT (f))
+ : f->new_height)
+ : FRAME_LINES (f));
/* Process foreground_color and background_color before anything else.
They are independent of other properties, but other properties (e.g.,
@@ -2830,15 +2976,16 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist)
{
Lisp_Object frame;
- check_frame_size (f, &height, &width);
+ /* Make this 1, eventually. */
+ check_frame_size (f, &width, &height, 0);
XSETFRAME (frame, f);
if (size_changed
&& (width != FRAME_COLS (f)
|| height != FRAME_LINES (f)
- || f->new_text_lines || f->new_text_cols))
- Fset_frame_size (frame, make_number (width), make_number (height));
+ || f->new_height || f->new_width))
+ Fset_frame_size (frame, make_number (width), make_number (height), Qnil);
if ((!NILP (left) || !NILP (top))
&& ! (left_no_change && top_no_change)
@@ -2946,6 +3093,10 @@ x_report_frame_params (struct frame *f, Lisp_Object *alistptr)
make_number (f->border_width));
store_in_alist (alistptr, Qinternal_border_width,
make_number (FRAME_INTERNAL_BORDER_WIDTH (f)));
+ store_in_alist (alistptr, Qright_divider_width,
+ make_number (FRAME_RIGHT_DIVIDER_WIDTH (f)));
+ store_in_alist (alistptr, Qbottom_divider_width,
+ make_number (FRAME_BOTTOM_DIVIDER_WIDTH (f)));
store_in_alist (alistptr, Qleft_fringe,
make_number (FRAME_LEFT_FRINGE_WIDTH (f)));
store_in_alist (alistptr, Qright_fringe,
@@ -3278,7 +3429,53 @@ x_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldva
if (FRAME_X_WINDOW (f) != 0)
{
- x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
+ x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 1);
+ SET_FRAME_GARBAGED (f);
+ do_pending_window_change (0);
+ }
+ else
+ SET_FRAME_GARBAGED (f);
+}
+
+void
+x_set_right_divider_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+ int old = FRAME_RIGHT_DIVIDER_WIDTH (f);
+
+ CHECK_TYPE_RANGED_INTEGER (int, arg);
+ FRAME_RIGHT_DIVIDER_WIDTH (f) = XINT (arg);
+ if (FRAME_RIGHT_DIVIDER_WIDTH (f) < 0)
+ FRAME_RIGHT_DIVIDER_WIDTH (f) = 0;
+
+ if (FRAME_RIGHT_DIVIDER_WIDTH (f) == old)
+ return;
+
+ if (FRAME_X_WINDOW (f) != 0)
+ {
+ x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 1);
+ SET_FRAME_GARBAGED (f);
+ do_pending_window_change (0);
+ }
+ else
+ SET_FRAME_GARBAGED (f);
+}
+
+void
+x_set_bottom_divider_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+ int old = FRAME_BOTTOM_DIVIDER_WIDTH (f);
+
+ CHECK_TYPE_RANGED_INTEGER (int, arg);
+ FRAME_BOTTOM_DIVIDER_WIDTH (f) = XINT (arg);
+ if (FRAME_BOTTOM_DIVIDER_WIDTH (f) < 0)
+ FRAME_BOTTOM_DIVIDER_WIDTH (f) = 0;
+
+ if (FRAME_BOTTOM_DIVIDER_WIDTH (f) == old)
+ return;
+
+ if (FRAME_X_WINDOW (f) != 0)
+ {
+ x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 1);
SET_FRAME_GARBAGED (f);
do_pending_window_change (0);
}
@@ -3344,7 +3541,8 @@ x_set_vertical_scroll_bars (struct frame *f, Lisp_Object arg, Lisp_Object oldval
However, if the window hasn't been created yet, we shouldn't
call x_set_window_size. */
if (FRAME_X_WINDOW (f))
- x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
+ x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f),
+ FRAME_TEXT_HEIGHT (f), 1);
do_pending_window_change (0);
}
}
@@ -3352,27 +3550,29 @@ x_set_vertical_scroll_bars (struct frame *f, Lisp_Object arg, Lisp_Object oldval
void
x_set_scroll_bar_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
{
- int wid = FRAME_COLUMN_WIDTH (f);
+ int unit = FRAME_COLUMN_WIDTH (f);
if (NILP (arg))
{
x_set_scroll_bar_default_width (f);
if (FRAME_X_WINDOW (f))
- x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
+ x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f),
+ FRAME_TEXT_HEIGHT (f), 1);
do_pending_window_change (0);
}
else if (RANGED_INTEGERP (1, arg, INT_MAX)
&& XFASTINT (arg) != FRAME_CONFIG_SCROLL_BAR_WIDTH (f))
{
FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = XFASTINT (arg);
- FRAME_CONFIG_SCROLL_BAR_COLS (f) = (XFASTINT (arg) + wid-1) / wid;
+ FRAME_CONFIG_SCROLL_BAR_COLS (f) = (XFASTINT (arg) + unit - 1) / unit;
if (FRAME_X_WINDOW (f))
- x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
+ x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f),
+ FRAME_TEXT_HEIGHT (f), 1);
do_pending_window_change (0);
}
- change_frame_size (f, 0, FRAME_COLS (f), 0, 0, 0);
+ change_frame_size (f, 0, 0, 0, 0, 0, 1);
XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.hpos = 0;
XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.x = 0;
}
@@ -3985,17 +4185,20 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p)
/* Default values if we fall through.
Actually, if that happens we should get
window manager prompting. */
+ SET_FRAME_WIDTH (f, DEFAULT_COLS * FRAME_COLUMN_WIDTH (f));
SET_FRAME_COLS (f, DEFAULT_COLS);
+ SET_FRAME_HEIGHT (f, DEFAULT_ROWS * FRAME_LINE_HEIGHT (f));
FRAME_LINES (f) = DEFAULT_ROWS;
+
/* Window managers expect that if program-specified
positions are not (0,0), they're intentional, not defaults. */
f->top_pos = 0;
f->left_pos = 0;
- /* Ensure that old new_text_cols and new_text_lines will not override the
+ /* Ensure that old new_width and new_height will not override the
values set here. */
/* ++KFS: This was specific to W32, but seems ok for all platforms */
- f->new_text_cols = f->new_text_lines = 0;
+ f->new_width = f->new_height = f->new_pixelwise = 0;
tem0 = x_get_arg (dpyinfo, parms, Qheight, 0, 0, RES_TYPE_NUMBER);
tem1 = x_get_arg (dpyinfo, parms, Qwidth, 0, 0, RES_TYPE_NUMBER);
@@ -4036,7 +4239,7 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p)
change the frame size. This is done so that users can create
tall Emacs frames without having to guess how tall the tool-bar
will get. */
- if (toolbar_p && FRAME_TOOL_BAR_LINES (f))
+ if (toolbar_p && FRAME_TOOL_BAR_HEIGHT (f))
{
int margin, relief, bar_height;
@@ -4052,14 +4255,15 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p)
else
margin = 0;
+ /* PXW: We should be able to not round here. */
bar_height = DEFAULT_TOOL_BAR_IMAGE_HEIGHT + 2 * margin + 2 * relief;
FRAME_LINES (f) += (bar_height + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
}
compute_fringe_widths (f, 0);
- FRAME_PIXEL_WIDTH (f) = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, FRAME_COLS (f));
- FRAME_PIXEL_HEIGHT (f) = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, FRAME_LINES (f));
+ SET_FRAME_WIDTH (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f));
+ SET_FRAME_HEIGHT(f, FRAME_LINES (f) * FRAME_LINE_HEIGHT (f));
tem0 = x_get_arg (dpyinfo, parms, Qtop, 0, 0, RES_TYPE_NUMBER);
tem1 = x_get_arg (dpyinfo, parms, Qleft, 0, 0, RES_TYPE_NUMBER);
@@ -4512,6 +4716,12 @@ handles focus, since there is no way in general for Emacs to find out
automatically. See also `mouse-autoselect-window'. */);
focus_follows_mouse = 0;
+ DEFVAR_BOOL ("frame-resize-pixelwise", frame_resize_pixelwise,
+ doc: /* Non-nil means frames are resized pixelwise.
+If this is nil, resizing a frame will round sizes to the frame's
+current values of `frame-char-height' and `frame-char-width'. */);
+ frame_resize_pixelwise = 0;
+
staticpro (&Vframe_list);
defsubr (&Sframep);
@@ -4551,6 +4761,16 @@ automatically. See also `mouse-autoselect-window'. */);
defsubr (&Sframe_char_width);
defsubr (&Sframe_pixel_height);
defsubr (&Sframe_pixel_width);
+ defsubr (&Sframe_text_cols);
+ defsubr (&Sframe_text_lines);
+ defsubr (&Sframe_total_cols);
+ defsubr (&Sframe_text_width);
+ defsubr (&Sframe_text_height);
+ defsubr (&Sscroll_bar_width);
+ defsubr (&Sfringe_width);
+ defsubr (&Sborder_width);
+ defsubr (&Sright_divider_width);
+ defsubr (&Sbottom_divider_width);
defsubr (&Stool_bar_pixel_width);
defsubr (&Sset_frame_height);
defsubr (&Sset_frame_width);
diff --git a/src/frame.h b/src/frame.h
index 657ef489590..4a0ff461f6d 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -220,6 +220,9 @@ struct frame
/* Margin at the top of the frame. Used to display the tool-bar. */
int tool_bar_lines;
+ /* Pixel height of tool bar. */
+ int tool_bar_height;
+
int n_tool_bar_rows;
int n_tool_bar_items;
@@ -236,23 +239,36 @@ struct frame
/* Cost of deleting n lines on this frame. */
int *delete_n_lines_cost;
- /* Size of this frame, excluding fringes, scroll bars etc.,
- in units of canonical characters. */
- int text_lines, text_cols;
+ /* Text width of this frame (excluding fringes, scroll bars and
+ internal border width) and text height (excluding internal border
+ width) in units of canonical characters. */
+ int text_cols, text_lines;
+
+ /* Total width of this frame (including fringes and scroll bars) in
+ units of canonical characters. */
+ int total_cols;
+
+ /* Text width of this frame (excluding fringes, scroll bars and
+ internal border width) and text height (excluding internal border
+ width) in pixels. */
+ int text_width, text_height;
- /* Total size of this frame (i.e. its native window), in units of
- canonical characters. */
- int total_lines, total_cols;
+ /* New text height and width for pending size change. 0 if no change
+ pending. These value represent pixels or canoncial character units
+ according to the value of new_pixelwise and correlate to the the
+ text width/height of the frame. */
+ int new_width, new_height;
- /* New text height and width for pending size change.
- 0 if no change pending. */
- int new_text_lines, new_text_cols;
+ /* Whether new_height and new_width shall be interpreted
+ in pixels. */
+ bool new_pixelwise;
/* Pixel position of the frame window (x and y offsets in root window). */
int left_pos, top_pos;
- /* Size of the frame window in pixels. */
- int pixel_height, pixel_width;
+ /* Size of the frame window (including internal border widths) in
+ pixels. */
+ int pixel_width, pixel_height;
/* These many pixels are the difference between the outer window (i.e. the
left and top of the window manager decoration) and FRAME_X_WINDOW. */
@@ -272,6 +288,10 @@ struct frame
a highlighting is displayed inside the internal border. */
int internal_border_width;
+ /* Width of borders between this frame's windows. */
+ int right_divider_width;
+ int bottom_divider_width;
+
/* Canonical X unit. Width of default font, in pixels. */
int column_width;
@@ -322,6 +342,9 @@ struct frame
/* Number of lines of menu bar. */
int menu_bar_lines;
+ /* Pixel height of menubar. */
+ int menu_bar_height;
+
#if defined (HAVE_X_WINDOWS)
/* Used by x_wait_for_event when watching for an X event on this frame. */
int wait_event_type;
@@ -658,20 +681,28 @@ default_pixels_per_inch_y (void)
(WINDOWP (f->minibuffer_window) \
&& XFRAME (XWINDOW (f->minibuffer_window)->frame) == f)
+/* Pixel width of frame F. */
+#define FRAME_PIXEL_WIDTH(f) ((f)->pixel_width)
+
/* Pixel height of frame F, including non-toolkit menu bar and
non-toolkit tool bar lines. */
#define FRAME_PIXEL_HEIGHT(f) ((f)->pixel_height)
-/* Pixel width of frame F. */
-#define FRAME_PIXEL_WIDTH(f) ((f)->pixel_width)
+/* Width of frame F, measured in canonical character columns,
+ not including scroll bars if any. */
+#define FRAME_COLS(f) (f)->text_cols
/* Height of frame F, measured in canonical lines, including
non-toolkit menu bar and non-toolkit tool bar lines. */
#define FRAME_LINES(f) (f)->text_lines
-/* Width of frame F, measured in canonical character columns,
- not including scroll bars if any. */
-#define FRAME_COLS(f) (f)->text_cols
+/* Width of frame F, measured in pixels not including the width for
+ fringes, scroll bar, and internal borders. */
+#define FRAME_TEXT_WIDTH(f) (f)->text_width
+
+/* Height of frame F, measured in pixels not including the height
+ for internal borders. */
+#define FRAME_TEXT_HEIGHT(f) (f)->text_height
/* Number of lines of frame F used for menu bar.
This is relevant on terminal frames and on
@@ -679,6 +710,9 @@ default_pixels_per_inch_y (void)
These lines are counted in FRAME_LINES. */
#define FRAME_MENU_BAR_LINES(f) (f)->menu_bar_lines
+/* Pixel height of frame F's menu bar. */
+#define FRAME_MENU_BAR_HEIGHT(f) (f)->menu_bar_height
+
/* Nonzero if this frame should display a tool bar
in a way that does not use any text lines. */
#if defined (USE_GTK) || defined (HAVE_NS)
@@ -688,19 +722,18 @@ default_pixels_per_inch_y (void)
#endif
/* Number of lines of frame F used for the tool-bar. */
-
#define FRAME_TOOL_BAR_LINES(f) (f)->tool_bar_lines
+/* Pixel height of frame F's tool-bar. */
+#define FRAME_TOOL_BAR_HEIGHT(f) (f)->tool_bar_height
/* Lines above the top-most window in frame F. */
-
#define FRAME_TOP_MARGIN(F) \
(FRAME_MENU_BAR_LINES (F) + FRAME_TOOL_BAR_LINES (F))
-/* Pixel height of the top margin above. */
-
-#define FRAME_TOP_MARGIN_HEIGHT(f) \
- (FRAME_TOP_MARGIN (f) * FRAME_LINE_HEIGHT (f))
+/* Pixel height of frame F's top margin. */
+#define FRAME_TOP_MARGIN_HEIGHT(F) \
+ (FRAME_MENU_BAR_HEIGHT (F) + FRAME_TOOL_BAR_HEIGHT (F))
/* Nonzero if this frame should display a menu bar
in a way that does not use any text lines. */
@@ -788,7 +821,7 @@ default_pixels_per_inch_y (void)
#define FRAME_LEFT_SCROLL_BAR_AREA_WIDTH(f) \
(FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f) \
- ? (FRAME_CONFIG_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f)) \
+ ? FRAME_CONFIG_SCROLL_BAR_WIDTH (f) \
: 0)
/* Width of a scroll bar in frame F, measured in columns (characters),
@@ -804,7 +837,7 @@ default_pixels_per_inch_y (void)
#define FRAME_RIGHT_SCROLL_BAR_AREA_WIDTH(f) \
(FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f) \
- ? (FRAME_CONFIG_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f)) \
+ ? FRAME_CONFIG_SCROLL_BAR_WIDTH (f) \
: 0)
/* Actual width of a scroll bar in frame F, measured in columns. */
@@ -818,29 +851,36 @@ default_pixels_per_inch_y (void)
#define FRAME_SCROLL_BAR_AREA_WIDTH(f) \
(FRAME_HAS_VERTICAL_SCROLL_BARS (f) \
- ? (FRAME_CONFIG_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f)) \
+ ? FRAME_CONFIG_SCROLL_BAR_WIDTH (f) \
: 0)
/* Total width of frame F, in columns (characters),
including the width used by scroll bars if any. */
-
#define FRAME_TOTAL_COLS(f) ((f)->total_cols)
-/* Set the width of frame F to VAL.
- VAL is the width of a full-frame window,
- not including scroll bars and fringes. */
-
-#define SET_FRAME_COLS(f, val) \
- (FRAME_COLS (f) = (val), \
- (f)->total_cols = FRAME_TOTAL_COLS_ARG (f, FRAME_COLS (f)))
-
-/* Given a value WIDTH for frame F's nominal width,
- return the value that FRAME_TOTAL_COLS should have. */
-
-#define FRAME_TOTAL_COLS_ARG(f, width) \
- ((width) \
- + FRAME_SCROLL_BAR_COLS (f) \
- + FRAME_FRINGE_COLS (f))
+/* Set the character widths of frame F. WIDTH specifies a nominal
+ character text width. */
+#define SET_FRAME_COLS(f, width) \
+ ((f)->text_cols = (width), \
+ (f)->total_cols = ((width) \
+ + FRAME_SCROLL_BAR_COLS (f) \
+ + FRAME_FRINGE_COLS (f)))
+
+/* Set the pixel widths of frame F. WIDTH specifies a nominal pixel
+ text width. */
+#define SET_FRAME_WIDTH(f, width) \
+ ((f)->text_width = (width), \
+ (f)->pixel_width = ((width) \
+ + FRAME_SCROLL_BAR_AREA_WIDTH (f) \
+ + FRAME_TOTAL_FRINGE_WIDTH (f) \
+ + 2 * FRAME_INTERNAL_BORDER_WIDTH (f)))
+
+/* Set the pixel heights of frame F. HEIGHT specifies a nominal pixel
+ text width. */
+#define SET_FRAME_HEIGHT(f, height) \
+ ((f)->text_height = (height), \
+ (f)->pixel_height = ((height) \
+ + 2 * FRAME_INTERNAL_BORDER_WIDTH (f)))
/* Maximum + 1 legitimate value for FRAME_CURSOR_X. */
@@ -1004,11 +1044,13 @@ extern Lisp_Object Vframe_list;
#define FRAME_TOTAL_FRINGE_WIDTH(F) \
(FRAME_LEFT_FRINGE_WIDTH (F) + FRAME_RIGHT_FRINGE_WIDTH (F))
-
/* Pixel-width of internal border lines */
-
#define FRAME_INTERNAL_BORDER_WIDTH(F) ((F)->internal_border_width)
+/* Pixel-size of window border lines */
+#define FRAME_RIGHT_DIVIDER_WIDTH(F) ((F)->right_divider_width)
+#define FRAME_BOTTOM_DIVIDER_WIDTH(F) ((F)->bottom_divider_width)
+
#else /* not HAVE_WINDOW_SYSTEM */
#define FRAME_FRINGE_COLS(F) 0
@@ -1016,11 +1058,10 @@ extern Lisp_Object Vframe_list;
#define FRAME_LEFT_FRINGE_WIDTH(F) 0
#define FRAME_RIGHT_FRINGE_WIDTH(F) 0
#define FRAME_INTERNAL_BORDER_WIDTH(F) 0
+#define FRAME_RIGHT_DIVIDER_WIDTH(F) 0
+#define FRAME_BOTTOM_DIVIDER_WIDTH(F) 0
#endif /* not HAVE_WINDOW_SYSTEM */
-
-
-
/***********************************************************************
Conversion between canonical units and pixels
@@ -1077,58 +1118,81 @@ extern Lisp_Object Vframe_list;
Return the upper/left pixel position of the character cell on frame F
at ROW/COL. */
-#define FRAME_LINE_TO_PIXEL_Y(f, row) \
+#define FRAME_LINE_TO_PIXEL_Y(f, row) \
(((row) < FRAME_TOP_MARGIN (f) ? 0 : FRAME_INTERNAL_BORDER_WIDTH (f)) \
+ (row) * FRAME_LINE_HEIGHT (f))
-#define FRAME_COL_TO_PIXEL_X(f, col) \
- (FRAME_INTERNAL_BORDER_WIDTH (f) \
+#define FRAME_COL_TO_PIXEL_X(f, col) \
+ (FRAME_INTERNAL_BORDER_WIDTH (f) \
+ (col) * FRAME_COLUMN_WIDTH (f))
/* Return the pixel width/height of frame F if it has
COLS columns/LINES rows. */
#define FRAME_TEXT_COLS_TO_PIXEL_WIDTH(f, cols) \
- (FRAME_COL_TO_PIXEL_X (f, cols) \
- + (f)->scroll_bar_actual_width \
- + FRAME_TOTAL_FRINGE_WIDTH (f) \
+ (FRAME_COL_TO_PIXEL_X (f, cols) \
+ + FRAME_SCROLL_BAR_AREA_WIDTH (f) \
+ + FRAME_TOTAL_FRINGE_WIDTH (f) \
+ FRAME_INTERNAL_BORDER_WIDTH (f))
#define FRAME_TEXT_LINES_TO_PIXEL_HEIGHT(f, lines) \
- ((lines) * FRAME_LINE_HEIGHT (f) \
+ ((lines) * FRAME_LINE_HEIGHT (f) \
+ 2 * FRAME_INTERNAL_BORDER_WIDTH (f))
-
/* Return the row/column (zero-based) of the character cell containing
the pixel on FRAME at Y/X. */
-#define FRAME_PIXEL_Y_TO_LINE(f, y) \
- (((y) < FRAME_TOP_MARGIN_HEIGHT (f) \
- ? (y) \
+#define FRAME_PIXEL_Y_TO_LINE(f, y) \
+ (((y) < FRAME_TOP_MARGIN_HEIGHT (f) \
+ ? (y) \
: ((y) < FRAME_TOP_MARGIN_HEIGHT (f) + FRAME_INTERNAL_BORDER_WIDTH (f) \
? (y) - (FRAME_TOP_MARGIN_HEIGHT (f) + FRAME_INTERNAL_BORDER_WIDTH (f) \
- /* Arrange for the division to round down. */ \
- + FRAME_LINE_HEIGHT (f) - 1) \
- : (y) - FRAME_INTERNAL_BORDER_WIDTH (f))) \
+ /* Arrange for the division to round down. */ \
+ + FRAME_LINE_HEIGHT (f) - 1) \
+ : (y) - FRAME_INTERNAL_BORDER_WIDTH (f))) \
/ FRAME_LINE_HEIGHT (f))
-#define FRAME_PIXEL_X_TO_COL(f, x) \
+#define FRAME_PIXEL_X_TO_COL(f, x) \
(((x) - FRAME_INTERNAL_BORDER_WIDTH (f)) \
/ FRAME_COLUMN_WIDTH (f))
/* How many columns/rows of text can we fit in WIDTH/HEIGHT pixels on
frame F? */
-#define FRAME_PIXEL_WIDTH_TO_TEXT_COLS(f, width) \
- (FRAME_PIXEL_X_TO_COL (f, ((width) \
- - FRAME_INTERNAL_BORDER_WIDTH (f) \
- - FRAME_TOTAL_FRINGE_WIDTH (f) \
- - (f)->scroll_bar_actual_width)))
+#define FRAME_PIXEL_WIDTH_TO_TEXT_COLS(f, width) \
+ (FRAME_PIXEL_X_TO_COL (f, ((width) \
+ - FRAME_INTERNAL_BORDER_WIDTH (f) \
+ - FRAME_TOTAL_FRINGE_WIDTH (f) \
+ - FRAME_SCROLL_BAR_AREA_WIDTH (f)))) \
-#define FRAME_PIXEL_HEIGHT_TO_TEXT_LINES(f, height) \
- (FRAME_PIXEL_Y_TO_LINE (f, ((height) \
+#define FRAME_PIXEL_HEIGHT_TO_TEXT_LINES(f, height) \
+ (FRAME_PIXEL_Y_TO_LINE (f, ((height) \
- FRAME_INTERNAL_BORDER_WIDTH (f))))
+/* Return the pixel width/height of frame F with a text size of
+ width/heigh. */
+
+#define FRAME_TEXT_TO_PIXEL_WIDTH(f, width) \
+ ((width) \
+ + FRAME_SCROLL_BAR_AREA_WIDTH (f) \
+ + FRAME_TOTAL_FRINGE_WIDTH (f) \
+ + 2 * FRAME_INTERNAL_BORDER_WIDTH (f))
+
+#define FRAME_TEXT_TO_PIXEL_HEIGHT(f, height) \
+ ((height) + 2 * FRAME_INTERNAL_BORDER_WIDTH (f))
+
+/* Return the text width/height of frame F with a pixel size of
+ width/heigh. */
+
+#define FRAME_PIXEL_TO_TEXT_WIDTH(f, width) \
+ ((width) \
+ - FRAME_SCROLL_BAR_AREA_WIDTH (f) \
+ - FRAME_TOTAL_FRINGE_WIDTH (f) \
+ - 2 * FRAME_INTERNAL_BORDER_WIDTH (f))
+
+#define FRAME_PIXEL_TO_TEXT_HEIGHT(f, height) \
+ ((height) - 2 * FRAME_INTERNAL_BORDER_WIDTH (f))
+
/* Value is the smallest width of any character in any font on frame F. */
#define FRAME_SMALLEST_CHAR_WIDTH(f) \
@@ -1151,6 +1215,7 @@ extern Lisp_Object Qfont;
extern Lisp_Object Qbackground_color, Qforeground_color;
extern Lisp_Object Qicon, Qicon_name, Qicon_type, Qicon_left, Qicon_top;
extern Lisp_Object Qinternal_border_width;
+extern Lisp_Object Qright_divider_width, Qbottom_divider_width;
extern Lisp_Object Qtooltip;
extern Lisp_Object Qmenu_bar_lines, Qtool_bar_lines, Qtool_bar_position;
extern Lisp_Object Qmouse_color;
@@ -1214,6 +1279,10 @@ extern void x_set_fringe_width (struct frame *, Lisp_Object, Lisp_Object);
extern void x_set_border_width (struct frame *, Lisp_Object, Lisp_Object);
extern void x_set_internal_border_width (struct frame *, Lisp_Object,
Lisp_Object);
+extern void x_set_right_divider_width (struct frame *, Lisp_Object,
+ Lisp_Object);
+extern void x_set_bottom_divider_width (struct frame *, Lisp_Object,
+ Lisp_Object);
extern void x_set_visibility (struct frame *, Lisp_Object, Lisp_Object);
extern void x_set_autoraise (struct frame *, Lisp_Object, Lisp_Object);
extern void x_set_autolower (struct frame *, Lisp_Object, Lisp_Object);
@@ -1237,7 +1306,7 @@ extern Lisp_Object display_x_get_resource (Display_Info *,
extern void set_frame_menubar (struct frame *f, bool first_time, bool deep_p);
extern void x_set_window_size (struct frame *f, int change_grav,
- int cols, int rows);
+ int width, int height, bool pixelwise);
extern Lisp_Object x_get_focus_frame (struct frame *);
extern void x_set_mouse_position (struct frame *f, int h, int v);
extern void x_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y);
@@ -1246,9 +1315,7 @@ extern void x_make_frame_invisible (struct frame *f);
extern void x_iconify_frame (struct frame *f);
extern void x_set_frame_alpha (struct frame *f);
extern void x_set_menu_bar_lines (struct frame *, Lisp_Object, Lisp_Object);
-extern void x_set_tool_bar_lines (struct frame *f,
- Lisp_Object value,
- Lisp_Object oldval);
+extern void x_set_tool_bar_lines (struct frame *, Lisp_Object, Lisp_Object);
extern void x_activate_menubar (struct frame *);
extern void x_real_positions (struct frame *, int *, int *);
extern void free_frame_menubar (struct frame *);
diff --git a/src/fringe.c b/src/fringe.c
index 9c77e6557f4..db4f92d6ce4 100644
--- a/src/fringe.c
+++ b/src/fringe.c
@@ -659,6 +659,10 @@ draw_fringe_bitmap_1 (struct window *w, struct glyph_row *row, int left_p, int o
{
/* If W has a vertical border to its left, don't draw over it. */
wd -= ((!WINDOW_LEFTMOST_P (w)
+ /* This could be wrong when we allow window local
+ right dividers - but the window on the left is hard
+ to get. */
+ && !FRAME_RIGHT_DIVIDER_WIDTH (f)
&& !WINDOW_HAS_VERTICAL_SCROLL_BAR (w)
/* But don't reduce the fringe width if the window
has a left margin, because that means we are not
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 192b64a7e62..d30a68a4193 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -904,7 +904,7 @@ xg_clear_under_internal_border (struct frame *f)
void
xg_frame_resized (struct frame *f, int pixelwidth, int pixelheight)
{
- int rows, columns;
+ int width, height;
if (pixelwidth == -1 && pixelheight == -1)
{
@@ -916,11 +916,11 @@ xg_frame_resized (struct frame *f, int pixelwidth, int pixelheight)
}
- rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, pixelheight);
- columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pixelwidth);
+ width = FRAME_PIXEL_TO_TEXT_WIDTH (f, pixelwidth);
+ height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixelheight);
- if (columns != FRAME_COLS (f)
- || rows != FRAME_LINES (f)
+ if (width != FRAME_TEXT_WIDTH (f)
+ || height != FRAME_TEXT_HEIGHT (f)
|| pixelwidth != FRAME_PIXEL_WIDTH (f)
|| pixelheight != FRAME_PIXEL_HEIGHT (f))
{
@@ -928,7 +928,7 @@ xg_frame_resized (struct frame *f, int pixelwidth, int pixelheight)
FRAME_PIXEL_HEIGHT (f) = pixelheight;
xg_clear_under_internal_border (f);
- change_frame_size (f, rows, columns, 0, 1, 0);
+ change_frame_size (f, width, height, 0, 1, 0, 1);
SET_FRAME_GARBAGED (f);
cancel_mouse_face (f);
}
@@ -938,11 +938,10 @@ xg_frame_resized (struct frame *f, int pixelwidth, int pixelheight)
COLUMNS/ROWS is the size the edit area shall have after the resize. */
void
-xg_frame_set_char_size (struct frame *f, int cols, int rows)
+xg_frame_set_char_size (struct frame *f, int width, int height)
{
- int pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows)
- + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f);
int pixelwidth;
+ int pixelheight = FRAME_TEXT_TO_PIXEL_HEIGHT (f, height);
if (FRAME_PIXEL_HEIGHT (f) == 0)
return;
@@ -959,9 +958,7 @@ xg_frame_set_char_size (struct frame *f, int cols, int rows)
/* FRAME_TEXT_COLS_TO_PIXEL_WIDTH uses scroll_bar_actual_width, so call it
after calculating that value. */
- pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, cols)
- + FRAME_TOOLBAR_WIDTH (f);
-
+ pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width);
/* Do this before resize, as we don't know yet if we will be resized. */
xg_clear_under_internal_border (f);
@@ -991,7 +988,7 @@ xg_frame_set_char_size (struct frame *f, int cols, int rows)
}
else
{
- change_frame_size (f, rows, cols, 0, 1, 0);
+ change_frame_size (f, width, height, 0, 1, 0, 1);
FRAME_PIXEL_WIDTH (f) = pixelwidth;
FRAME_PIXEL_HEIGHT (f) = pixelheight;
}
@@ -1381,7 +1378,7 @@ x_wm_set_size_hint (struct frame *f, long int flags, bool user_position)
base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 1)
+ FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f);
- check_frame_size (f, &min_rows, &min_cols);
+ check_frame_size (f, &min_cols, &min_rows, 0);
if (min_cols > 0) --min_cols; /* We used one col in base_width = ... 1); */
if (min_rows > 0) --min_rows; /* We used one row in base_height = ... 1); */
diff --git a/src/indent.c b/src/indent.c
index 891b42788ed..502611b534a 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -1146,7 +1146,7 @@ compute_motion (ptrdiff_t from, ptrdiff_t frombyte, EMACS_INT fromvpos,
/* Negative width means use all available text columns. */
if (width < 0)
{
- width = window_body_cols (win);
+ width = window_body_width (win, 0);
/* We must make room for continuation marks if we don't have fringes. */
#ifdef HAVE_WINDOW_SYSTEM
if (!FRAME_WINDOW_P (XFRAME (win->frame)))
@@ -1756,7 +1756,7 @@ visible section of the buffer, and pass LINE and COL as TOPOS. */)
? window_internal_height (w)
: XINT (XCDR (topos))),
(NILP (topos)
- ? (window_body_cols (w)
+ ? (window_body_width (w, 0)
- (
#ifdef HAVE_WINDOW_SYSTEM
FRAME_WINDOW_P (XFRAME (w->frame)) ? 0 :
diff --git a/src/keyboard.c b/src/keyboard.c
index 2e16a872190..b50c06b4154 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -347,6 +347,7 @@ static Lisp_Object Qmodifier_cache;
/* Symbols to use for parts of windows. */
Lisp_Object Qmode_line;
Lisp_Object Qvertical_line;
+Lisp_Object Qright_divider, Qbottom_divider;
static Lisp_Object Qvertical_scroll_bar;
Lisp_Object Qmenu_bar;
@@ -5302,6 +5303,20 @@ make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y,
dy = yret = wy;
}
/* Nothing special for part == ON_SCROLL_BAR. */
+ else if (part == ON_RIGHT_DIVIDER)
+ {
+ posn = Qright_divider;
+ width = WINDOW_RIGHT_DIVIDER_WIDTH (w);
+ dx = xret = wx;
+ dy = yret = wy;
+ }
+ else if (part == ON_BOTTOM_DIVIDER)
+ {
+ posn = Qbottom_divider;
+ width = WINDOW_BOTTOM_DIVIDER_WIDTH (w);
+ dx = xret = wx;
+ dy = yret = wy;
+ }
/* For clicks in the text area, fringes, or margins, call
buffer_posn_from_coords to extract TEXTPOS, the buffer
@@ -10142,7 +10157,7 @@ On such systems, Emacs starts a subshell instead of suspending. */)
with a window system; but suspend should be disabled in that case. */
get_tty_size (fileno (CURTTY ()->input), &width, &height);
if (width != old_width || height != old_height)
- change_frame_size (SELECTED_FRAME (), height, width, 0, 0, 0);
+ change_frame_size (SELECTED_FRAME (), width, height, 0, 0, 0, 0);
/* Run suspend-resume-hook. */
hook = intern ("suspend-resume-hook");
@@ -10978,6 +10993,8 @@ syms_of_keyboard (void)
DEFSYM (Qvertical_line, "vertical-line");
DEFSYM (Qvertical_scroll_bar, "vertical-scroll-bar");
DEFSYM (Qmenu_bar, "menu-bar");
+ DEFSYM (Qright_divider, "right-divider");
+ DEFSYM (Qbottom_divider, "bottom-divider");
DEFSYM (Qmouse_fixup_help_message, "mouse-fixup-help-message");
diff --git a/src/keyboard.h b/src/keyboard.h
index b8aad959dd9..a1aa59fe988 100644
--- a/src/keyboard.h
+++ b/src/keyboard.h
@@ -457,6 +457,7 @@ extern Lisp_Object Qhelp_echo;
/* Symbols to use for non-text mouse positions. */
extern Lisp_Object Qmode_line, Qvertical_line, Qheader_line;
+extern Lisp_Object Qright_divider, Qbottom_divider;
/* True while doing kbd input. */
extern bool waiting_for_input;
diff --git a/src/lisp.h b/src/lisp.h
index 52b20b73ae1..60cbc98daf8 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4042,6 +4042,7 @@ extern void syms_of_indent (void);
/* Defined in frame.c. */
extern Lisp_Object Qonly, Qnone;
extern Lisp_Object Qvisible;
+extern void set_frame_param (struct frame *, Lisp_Object, Lisp_Object);
extern void store_frame_param (struct frame *, Lisp_Object, Lisp_Object);
extern void store_in_alist (Lisp_Object *, Lisp_Object, Lisp_Object);
extern Lisp_Object do_switch_frame (Lisp_Object, int, int, Lisp_Object);
diff --git a/src/nsfns.m b/src/nsfns.m
index ee6020f2b43..550e625c424 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -703,7 +703,7 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
}
}
- x_set_window_size (f, 0, f->text_cols, f->text_lines);
+ x_set_window_size (f, 0, f->text_cols, f->text_lines, 0);
}
@@ -1266,6 +1266,7 @@ This function is an internal primitive--use `make-frame' instead. */)
f->output_data.ns->hand_cursor = [NSCursor pointingHandCursor];
f->output_data.ns->hourglass_cursor = [NSCursor disappearingItemCursor];
f->output_data.ns->horizontal_drag_cursor = [NSCursor resizeLeftRightCursor];
+ f->output_data.ns->vertical_drag_cursor = [NSCursor resizeUpDownCursor];
FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor
= [NSCursor arrowCursor];
f->output_data.ns->current_pointer = f->output_data.ns->text_cursor;
@@ -1303,7 +1304,7 @@ This function is an internal primitive--use `make-frame' instead. */)
SET_FRAME_COLS (f, 0);
FRAME_LINES (f) = 0;
- change_frame_size (f, height, width, 1, 0, 0);
+ change_frame_size (f, width, height, 1, 0, 0, 0);
if (! f->output_data.ns->explicit_parent)
{
diff --git a/src/nsterm.h b/src/nsterm.h
index 22a8aec9436..0f22350156e 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -654,6 +654,7 @@ struct ns_output
Cursor hand_cursor;
Cursor hourglass_cursor;
Cursor horizontal_drag_cursor;
+ Cursor vertical_drag_cursor;
/* NS-specific */
Cursor current_pointer;
diff --git a/src/nsterm.m b/src/nsterm.m
index d995bfa835b..7121366527b 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -771,7 +771,12 @@ ns_update_window_end (struct window *w, bool cursor_on_p,
w->output_cursor.x, w->output_cursor.y);
if (draw_window_fringes (w, 1))
- x_draw_vertical_border (w);
+ {
+ if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
+ x_draw_right_divider (w);
+ else
+ x_draw_vertical_border (w);
+ }
unblock_input ();
}
@@ -1235,7 +1240,7 @@ x_set_offset (struct frame *f, int xoff, int yoff, int change_grav)
void
-x_set_window_size (struct frame *f, int change_grav, int cols, int rows)
+x_set_window_size (struct frame *f, int change_grav, int cols, int rows, bool pixelwise)
/* --------------------------------------------------------------------------
Adjust window pixel size based on given character grid size
Impl is a bit more complex than other terms, need to do some
@@ -1257,7 +1262,7 @@ x_set_window_size (struct frame *f, int change_grav, int cols, int rows)
block_input ();
- check_frame_size (f, &rows, &cols);
+ check_frame_size (f, &cols, &rows, 0);
f->scroll_bar_actual_width = NS_SCROLL_BAR_WIDTH (f);
compute_fringe_widths (f, 0);
@@ -1316,7 +1321,7 @@ x_set_window_size (struct frame *f, int change_grav, int cols, int rows)
[view setBoundsOrigin: origin];
}
- change_frame_size (f, rows, cols, 0, 1, 0); /* pretend, delay, safe */
+ change_frame_size (f, cols, rows, 0, 1, 0, 0); /* pretend, delay, safe */
FRAME_PIXEL_WIDTH (f) = pixelwidth;
FRAME_PIXEL_HEIGHT (f) = pixelheight;
/* SET_FRAME_GARBAGED (f); // this short-circuits expose call in drawRect */
@@ -2504,6 +2509,28 @@ ns_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
}
+static void
+ns_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
+/* --------------------------------------------------------------------------
+ External (RIF): Draw a window divider.
+ -------------------------------------------------------------------------- */
+{
+ struct frame *f = XFRAME (WINDOW_FRAME (w));
+ struct face *face;
+ NSRect r = NSMakeRect (x0, y0, x1-x0, y1-y0);
+
+ NSTRACE (ns_draw_window_divider);
+
+ face = FACE_FROM_ID (f, WINDOW_DIVIDER_FACE_ID);
+ if (face)
+ [ns_lookup_indexed_color(face->foreground, f) set];
+
+ ns_focus (f, &r, 1);
+ NSRectFill(r);
+ ns_unfocus (f);
+}
+
+
void
show_hourglass (struct atimer *timer)
{
@@ -4017,6 +4044,7 @@ static struct redisplay_interface ns_redisplay_interface =
ns_clear_frame_area,
ns_draw_window_cursor,
ns_draw_vertical_window_border,
+ ns_draw_window_divider,
ns_shift_glyphs_for_insert
};
@@ -5657,7 +5685,7 @@ not_in_argv (NSString *arg)
FRAME_PIXEL_WIDTH (emacsframe) = neww;
FRAME_PIXEL_HEIGHT (emacsframe) = newh;
- change_frame_size (emacsframe, rows, cols, 0, delay, 0);
+ change_frame_size (emacsframe, cols, rows, 0, delay, 0, 0);
SET_FRAME_GARBAGED (emacsframe);
cancel_mouse_face (emacsframe);
@@ -7330,7 +7358,7 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
/* Now make the frame display the given font. */
if (FRAME_NS_WINDOW (f) != 0)
- x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
+ x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f), 0);
return font_object;
}
diff --git a/src/print.c b/src/print.c
index e3c56a6de62..80e010ee0f5 100644
--- a/src/print.c
+++ b/src/print.c
@@ -1766,8 +1766,9 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
}
else if (WINDOWP (obj))
{
- void *ptr = XWINDOW (obj);
- int len = sprintf (buf, "#<window %p", ptr);
+ int len;
+ strout ("#<window ", -1, -1, printcharfun);
+ len = sprintf (buf, "%d", XWINDOW (obj)->sequence_number);
strout (buf, len, len, printcharfun);
if (BUFFERP (XWINDOW (obj)->contents))
{
diff --git a/src/term.c b/src/term.c
index 877d43b89d9..4d900020ce6 100644
--- a/src/term.c
+++ b/src/term.c
@@ -2407,7 +2407,7 @@ frame's terminal). */)
was suspended. */
get_tty_size (fileno (t->display_info.tty->input), &width, &height);
if (width != old_width || height != old_height)
- change_frame_size (f, height, width, 0, 0, 0);
+ change_frame_size (f, width, height, 0, 0, 0, 0);
SET_FRAME_VISIBLE (XFRAME (t->display_info.tty->top_frame), 1);
}
diff --git a/src/w32fns.c b/src/w32fns.c
index 403a7ba0d6a..975d3f95e67 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -1383,6 +1383,17 @@ x_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
horizontal_drag_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f), XC_sb_h_double_arrow);
+ if (!NILP (Vx_window_vertical_drag_shape))
+ {
+ CHECK_NUMBER (Vx_window_vertical_drag_shape);
+ vertical_drag_cursor
+ = XCreateFontCursor (FRAME_X_DISPLAY (f),
+ XINT (Vx_window_vertical_drag_shape));
+ }
+ else
+ vertical_drag_cursor
+ = XCreateFontCursor (FRAME_X_DISPLAY (f), XC_sb_v_double_arrow);
+
/* Check and report errors with the above calls. */
x_check_errors (FRAME_W32_DISPLAY (f), "can't set cursor shape: %s");
x_uncatch_errors (FRAME_W32_DISPLAY (f), count);
@@ -1623,6 +1634,7 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
nlines = 0;
FRAME_MENU_BAR_LINES (f) = 0;
+ FRAME_MENU_BAR_HEIGHT (f) = 0;
if (nlines)
FRAME_EXTERNAL_MENU_BAR (f) = 1;
else
@@ -1634,7 +1646,7 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
/* Adjust the frame size so that the client (text) dimensions
remain the same. This depends on FRAME_EXTERNAL_MENU_BAR being
set correctly. */
- x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
+ x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 1);
do_pending_window_change (0);
}
adjust_frame_glyphs (f);
@@ -1642,16 +1654,17 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
/* Set the number of lines used for the tool bar of frame F to VALUE.
- VALUE not an integer, or < 0 means set the lines to zero. OLDVAL
- is the old number of tool bar lines. This function changes the
- height of all windows on frame F to match the new tool bar height.
- The frame's height doesn't change. */
+ VALUE not an integer, or < 0 means set the lines to zero. OLDVAL is
+ the old number of tool bar lines (and is unused). This function may
+ change the height of all windows on frame F to match the new tool bar
+ height. By design, the frame's height doesn't change (but maybe it
+ should if we don't get enough space otherwise). */
void
x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
{
int delta, nlines, root_height;
- Lisp_Object root_window;
+ int unit = FRAME_LINE_HEIGHT (f);
/* Treat tool bars like menu bars. */
if (FRAME_MINIBUF_ONLY_P (f))
@@ -1666,19 +1679,25 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
/* Make sure we redisplay all windows in this frame. */
windows_or_buffers_changed = 23;
- delta = nlines - FRAME_TOOL_BAR_LINES (f);
+ /* DELTA is in pixels now. */
+ delta = (nlines - FRAME_TOOL_BAR_LINES (f)) * unit;
- /* Don't resize the tool-bar to more than we have room for. */
- root_window = FRAME_ROOT_WINDOW (f);
- root_height = WINDOW_TOTAL_LINES (XWINDOW (root_window));
- if (root_height - delta < 1)
+ /* Don't resize the tool-bar to more than we have room for. FIXME:
+ This must use window_sizable eventually !!!!!!!!!!!! */
+ if (delta > 0)
{
- delta = root_height - 1;
- nlines = FRAME_TOOL_BAR_LINES (f) + delta;
+ root_height = WINDOW_PIXEL_HEIGHT (XWINDOW (FRAME_ROOT_WINDOW (f)));
+ if (root_height - delta < unit)
+ {
+ delta = root_height - unit;
+ nlines = (root_height / unit) + min (1, (root_height % unit));
+ }
}
FRAME_TOOL_BAR_LINES (f) = nlines;
- resize_frame_windows (f, FRAME_LINES (f), 0);
+ FRAME_TOOL_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f);
+ ++windows_or_buffers_changed;
+ resize_frame_windows (f, FRAME_TEXT_HEIGHT (f), 0, 1);
adjust_frame_glyphs (f);
/* We also have to make sure that the internal border at the top of
@@ -1687,7 +1706,7 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
below the tool bar if one is displayed, but is below the menu bar
if there isn't a tool bar. The tool bar draws into the area
below the menu bar. */
- if (FRAME_W32_WINDOW (f) && FRAME_TOOL_BAR_LINES (f) == 0)
+ if (FRAME_W32_WINDOW (f) && FRAME_TOOL_BAR_HEIGHT (f) == 0)
{
clear_frame (f);
clear_current_matrices (f);
@@ -1700,7 +1719,7 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
{
int height = FRAME_INTERNAL_BORDER_WIDTH (f);
int width = FRAME_PIXEL_WIDTH (f);
- int y = nlines * FRAME_LINE_HEIGHT (f);
+ int y = nlines * unit;
block_input ();
{
@@ -1948,7 +1967,7 @@ w32_createwindow (struct frame *f)
SetWindowLong (hwnd, WND_FONTWIDTH_INDEX, FRAME_COLUMN_WIDTH (f));
SetWindowLong (hwnd, WND_LINEHEIGHT_INDEX, FRAME_LINE_HEIGHT (f));
SetWindowLong (hwnd, WND_BORDER_INDEX, FRAME_INTERNAL_BORDER_WIDTH (f));
- SetWindowLong (hwnd, WND_SCROLLBAR_INDEX, f->scroll_bar_actual_width);
+ SetWindowLong (hwnd, WND_SCROLLBAR_INDEX, FRAME_SCROLL_BAR_AREA_WIDTH (f));
SetWindowLong (hwnd, WND_BACKGROUND_INDEX, FRAME_BACKGROUND_PIXEL (f));
/* Enable drag-n-drop. */
@@ -3224,6 +3243,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
- WINDOW_RIGHT_MARGIN_WIDTH (w)
- WINDOW_RIGHT_FRINGE_WIDTH (w));
form.rcArea.bottom = (WINDOW_BOTTOM_EDGE_Y (w)
+ - WINDOW_BOTTOM_DIVIDER_WIDTH (w)
- w32_system_caret_mode_height);
/* Punt if the window was deleted behind our back. */
@@ -3773,7 +3793,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
case WM_WINDOWPOSCHANGING:
/* Don't restrict the sizing of tip frames. */
- if (hwnd == tip_window)
+ if (frame_resize_pixelwise || hwnd == tip_window)
return 0;
/* Don't restrict the sizing of fullscreened frames, allowing them to be
@@ -4452,6 +4472,10 @@ This function is an internal primitive--use `make-frame' instead. */)
/* Default internalBorderWidth to 0 on Windows to match other programs. */
x_default_parameter (f, parameters, Qinternal_border_width, make_number (0),
"internalBorderWidth", "InternalBorder", RES_TYPE_NUMBER);
+ x_default_parameter (f, parameters, Qright_divider_width, make_number (0),
+ NULL, NULL, RES_TYPE_NUMBER);
+ x_default_parameter (f, parameters, Qbottom_divider_width, make_number (0),
+ NULL, NULL, RES_TYPE_NUMBER);
x_default_parameter (f, parameters, Qvertical_scroll_bars, Qright,
"verticalScrollBars", "ScrollBars", RES_TYPE_SYMBOL);
@@ -4481,6 +4505,20 @@ This function is an internal primitive--use `make-frame' instead. */)
happen. */
init_frame_faces (f);
+ /* PXW: This is a duplicate from below. We have to do it here since
+ otherwise x_set_tool_bar_lines will work with the character sizes
+ installed by init_frame_faces while the frame's pixel size is still
+ calculated from a character size of 1 and we subsequently hit the
+ eassert (height >= 0) assertion in window_box_height. The
+ non-pixelwise code apparently worked around this because it had one
+ frame line vs one toolbar line which left us with a zero root
+ window height which was obviously wrong as well ... */
+ width = FRAME_TEXT_WIDTH (f);
+ height = FRAME_TEXT_HEIGHT (f);
+ FRAME_TEXT_HEIGHT (f) = 0;
+ SET_FRAME_WIDTH (f, 0);
+ change_frame_size (f, width, height, 1, 0, 0, 1);
+
/* The X resources controlling the menu-bar and tool-bar are
processed specially at startup, and reflected in the mode
variables; ignore them here. */
@@ -4509,6 +4547,7 @@ This function is an internal primitive--use `make-frame' instead. */)
f->output_data.w32->hand_cursor = w32_load_cursor (IDC_HAND);
f->output_data.w32->hourglass_cursor = w32_load_cursor (IDC_WAIT);
f->output_data.w32->horizontal_drag_cursor = w32_load_cursor (IDC_SIZEWE);
+ f->output_data.w32->vertical_drag_cursor = w32_load_cursor (IDC_SIZENS);
f->output_data.w32->current_cursor = f->output_data.w32->nontext_cursor;
@@ -4546,12 +4585,11 @@ This function is an internal primitive--use `make-frame' instead. */)
/* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
Change will not be effected unless different from the current
FRAME_LINES (f). */
- width = FRAME_COLS (f);
- height = FRAME_LINES (f);
-
- FRAME_LINES (f) = 0;
- SET_FRAME_COLS (f, 0);
- change_frame_size (f, height, width, 1, 0, 0);
+ width = FRAME_TEXT_WIDTH (f);
+ height = FRAME_TEXT_HEIGHT (f);
+ FRAME_TEXT_HEIGHT (f) = 0;
+ SET_FRAME_WIDTH (f, 0);
+ change_frame_size (f, width, height, 1, 0, 0, 1);
/* Tell the server what size and position, etc, we want, and how
badly we want them. This should be done after we have the menu
@@ -5689,6 +5727,10 @@ x_create_tip_frame (struct w32_display_info *dpyinfo,
x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
"internalBorderWidth", "internalBorderWidth",
RES_TYPE_NUMBER);
+ x_default_parameter (f, parms, Qright_divider_width, make_number (0),
+ NULL, NULL, RES_TYPE_NUMBER);
+ x_default_parameter (f, parms, Qbottom_divider_width, make_number (0),
+ NULL, NULL, RES_TYPE_NUMBER);
/* Also do the stuff which must be set before the window exists. */
x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
@@ -5733,14 +5775,14 @@ x_create_tip_frame (struct w32_display_info *dpyinfo,
x_default_parameter (f, parms, Qcursor_type, Qbox,
"cursorType", "CursorType", RES_TYPE_SYMBOL);
- /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
- Change will not be effected unless different from the current
- FRAME_LINES (f). */
+ /* Dimensions, especially FRAME_LINES (f), must be done via
+ change_frame_size. Change will not be effected unless different
+ from the current FRAME_LINES (f). */
width = FRAME_COLS (f);
height = FRAME_LINES (f);
FRAME_LINES (f) = 0;
SET_FRAME_COLS (f, 0);
- change_frame_size (f, height, width, 1, 0, 0);
+ change_frame_size (f, width, height, 1, 0, 0, 0);
/* Add `tooltip' frame parameter's default value. */
if (NILP (Fframe_parameter (frame, Qtooltip)))
@@ -5998,6 +6040,10 @@ Text larger than the specified size is clipped. */)
parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
if (NILP (Fassq (Qinternal_border_width, parms)))
parms = Fcons (Fcons (Qinternal_border_width, make_number (3)), parms);
+ if (NILP (Fassq (Qright_divider_width, parms)))
+ parms = Fcons (Fcons (Qright_divider_width, make_number (0)), parms);
+ if (NILP (Fassq (Qbottom_divider_width, parms)))
+ parms = Fcons (Fcons (Qbottom_divider_width, make_number (0)), parms);
if (NILP (Fassq (Qborder_width, parms)))
parms = Fcons (Fcons (Qborder_width, make_number (1)), parms);
if (NILP (Fassq (Qborder_color, parms)))
@@ -6019,6 +6065,8 @@ Text larger than the specified size is clipped. */)
w = XWINDOW (FRAME_ROOT_WINDOW (f));
w->left_col = 0;
w->top_line = 0;
+ w->pixel_left = 0;
+ w->pixel_top = 0;
if (CONSP (Vx_max_tooltip_size)
&& INTEGERP (XCAR (Vx_max_tooltip_size))
@@ -6035,6 +6083,9 @@ Text larger than the specified size is clipped. */)
w->total_lines = 40;
}
+ w->pixel_width = w->total_cols * FRAME_COLUMN_WIDTH (f);
+ w->pixel_height = w->total_lines * FRAME_LINE_HEIGHT (f);
+
FRAME_TOTAL_COLS (f) = WINDOW_TOTAL_COLS (w);
adjust_frame_glyphs (f);
w->pseudo_window_p = 1;
@@ -6100,11 +6151,17 @@ Text larger than the specified size is clipped. */)
width of the frame. */
if (seen_reversed_p)
{
- /* w->total_cols and FRAME_TOTAL_COLS want the width in columns,
+ /* PXW: Why do we do the pixel-to-cols conversion only if
+ seen_reversed_p holds? Don't we have to set other fields of
+ the window/frame stucture ?
+
+ w->total_cols and FRAME_TOTAL_COLS want the width in columns,
not in pixels. */
+ w->pixel_width = width;
width /= WINDOW_FRAME_COLUMN_WIDTH (w);
w->total_cols = width;
FRAME_TOTAL_COLS (f) = width;
+ SET_FRAME_WIDTH (f, width);
adjust_frame_glyphs (f);
w->pseudo_window_p = 1;
clear_glyph_matrix (w->desired_matrix);
@@ -6134,16 +6191,15 @@ Text larger than the specified size is clipped. */)
}
}
- /* Round up the height to an integral multiple of FRAME_LINE_HEIGHT. */
- if (height % FRAME_LINE_HEIGHT (f) != 0)
- height += FRAME_LINE_HEIGHT (f) - height % FRAME_LINE_HEIGHT (f);
/* Add the frame's internal border to the width and height the w32
window should have. */
height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
width += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
/* Move the tooltip window where the mouse pointer is. Resize and
- show it. */
+ show it.
+
+ PXW: This should use the frame's pixel coordinates. */
compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
{
@@ -6919,6 +6975,29 @@ This is a direct interface to the Windows API FindWindow function. */)
return Qt;
}
+DEFUN ("w32-frame-rect", Fw32_frame_rect, Sw32_frame_rect, 0, 2, 0,
+ doc: /* Return boundary rectangle of FRAME in screen coordinates.
+FRAME must be a live frame and defaults to the selected one.
+
+The boundary rectangle is a list of four elements, specifying the left,
+top, right and bottom screen coordinates of FRAME including menu and
+title bar and decorations. Optional argument CLIENT non-nil means to
+return the boundaries of the client rectangle which excludes menu and
+title bar and decorations. */)
+ (Lisp_Object frame, Lisp_Object client)
+{
+ struct frame *f = decode_live_frame (frame);
+ RECT rect;
+
+ if (!NILP (client))
+ GetClientRect (FRAME_W32_WINDOW (f), &rect);
+ else
+ GetWindowRect (FRAME_W32_WINDOW (f), &rect);
+
+ return list4 (make_number (rect.left), make_number (rect.top),
+ make_number (rect.right), make_number (rect.bottom));
+}
+
DEFUN ("w32-battery-status", Fw32_battery_status, Sw32_battery_status, 0, 0, 0,
doc: /* Get power status information from Windows system.
@@ -7510,6 +7589,8 @@ frame_parm_handler w32_frame_parm_handlers[] =
x_set_icon_name,
x_set_icon_type,
x_set_internal_border_width,
+ x_set_right_divider_width,
+ x_set_bottom_divider_width,
x_set_menu_bar_lines,
x_set_mouse_color,
x_explicitly_set_name,
@@ -7761,6 +7842,13 @@ or when you set the mouse color. */);
This variable takes effect when you create a new frame
or when you set the mouse color. */);
Vx_window_horizontal_drag_shape = Qnil;
+
+ DEFVAR_LISP ("x-window-vertical-drag-cursor",
+ Vx_window_vertical_drag_shape,
+ doc: /* Pointer shape to use for indicating a window can be dragged vertically.
+This variable takes effect when you create a new frame
+or when you set the mouse color. */);
+ Vx_window_vertical_drag_shape = Qnil;
#endif
DEFVAR_LISP ("x-cursor-fore-pixel", Vx_cursor_fore_pixel,
@@ -7853,6 +7941,7 @@ only be necessary if the default setting causes problems. */);
defsubr (&Sw32_reconstruct_hot_key);
defsubr (&Sw32_toggle_lock_key);
defsubr (&Sw32_window_exists_p);
+ defsubr (&Sw32_frame_rect);
defsubr (&Sw32_battery_status);
#ifdef WINDOWSNT
diff --git a/src/w32inevt.c b/src/w32inevt.c
index a157cb5c1df..d4c96bd9b8a 100644
--- a/src/w32inevt.c
+++ b/src/w32inevt.c
@@ -587,7 +587,7 @@ resize_event (WINDOW_BUFFER_SIZE_RECORD *event)
{
struct frame *f = get_frame ();
- change_frame_size (f, event->dwSize.Y, event->dwSize.X, 0, 1, 0);
+ change_frame_size (f, event->dwSize.X, event->dwSize.Y, 0, 1, 0, 0);
SET_FRAME_GARBAGED (f);
}
@@ -602,9 +602,9 @@ maybe_generate_resize_event (void)
/* It is okay to call this unconditionally, since it will do nothing
if the size hasn't actually changed. */
change_frame_size (f,
- 1 + info.srWindow.Bottom - info.srWindow.Top,
1 + info.srWindow.Right - info.srWindow.Left,
- 0, 0, 0);
+ 1 + info.srWindow.Bottom - info.srWindow.Top,
+ 0, 0, 0, 0);
}
#if HAVE_W32NOTIFY
diff --git a/src/w32menu.c b/src/w32menu.c
index b846a3f999c..4f8e8dbef05 100644
--- a/src/w32menu.c
+++ b/src/w32menu.c
@@ -505,7 +505,7 @@ set_frame_menubar (struct frame *f, bool first_time, bool deep_p)
/* Force the window size to be recomputed so that the frame's text
area remains the same, if menubar has just been created. */
if (old_widget == NULL)
- x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
+ x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 1);
}
unblock_input ();
diff --git a/src/w32term.c b/src/w32term.c
index 90cc204239e..38b297810b1 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -180,7 +180,7 @@ void x_lower_frame (struct frame *);
void x_scroll_bar_clear (struct frame *);
void x_wm_set_size_hint (struct frame *, long, bool);
void x_raise_frame (struct frame *);
-void x_set_window_size (struct frame *, int, int, int);
+void x_set_window_size (struct frame *, int, int, int, bool);
void x_wm_set_window_state (struct frame *, int);
void x_wm_set_icon_pixmap (struct frame *, int);
static void w32_initialize (void);
@@ -621,6 +621,32 @@ w32_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
}
+/* Draw a window divider from (x0, y0) to (x1, y1) */
+
+static void
+w32_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
+{
+ struct frame *f = XFRAME (WINDOW_FRAME (w));
+ RECT r;
+ HDC hdc;
+ struct face *face;
+
+ r.left = x0;
+ r.right = x1;
+ r.top = y0;
+ r.bottom = y1;
+
+ hdc = get_frame_dc (f);
+ face = FACE_FROM_ID (f, WINDOW_DIVIDER_FACE_ID);
+ if (face)
+ w32_fill_rect (f, hdc, face->foreground, &r);
+ else
+ w32_fill_rect (f, hdc, FRAME_FOREGROUND_PIXEL (f), &r);
+
+ release_frame_dc (f, hdc);
+}
+
+
/* End update of window W.
Draw vertical borders between horizontally adjacent windows, and
@@ -648,7 +674,12 @@ x_update_window_end (struct window *w, bool cursor_on_p,
w->output_cursor.x, w->output_cursor.y);
if (draw_window_fringes (w, 1))
- x_draw_vertical_border (w);
+ {
+ if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
+ x_draw_right_divider (w);
+ else
+ x_draw_vertical_border (w);
+ }
unblock_input ();
}
@@ -777,8 +808,7 @@ w32_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
if (sb_width > 0)
{
int bar_area_x = WINDOW_SCROLL_BAR_AREA_X (w);
- int bar_area_width = (WINDOW_CONFIG_SCROLL_BAR_COLS (w)
- * FRAME_COLUMN_WIDTH (f));
+ int bar_area_width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
if (bx < 0)
{
@@ -2675,8 +2705,7 @@ x_scroll_run (struct window *w, struct run *run)
if (sb_width > 0)
{
int bar_area_x = WINDOW_SCROLL_BAR_AREA_X (w);
- int bar_area_width = (WINDOW_CONFIG_SCROLL_BAR_COLS (w)
- * FRAME_COLUMN_WIDTH (f));
+ int bar_area_width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
if (bar_area_x + bar_area_width == x)
{
@@ -3740,7 +3769,7 @@ w32_set_vertical_scroll_bar (struct window *w,
/* Get window dimensions. */
window_box (w, ANY_AREA, 0, &window_y, 0, &window_height);
top = window_y;
- width = WINDOW_CONFIG_SCROLL_BAR_COLS (w) * FRAME_COLUMN_WIDTH (f);
+ width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
height = window_height;
/* Compute the left edge of the scroll bar area. */
@@ -4681,6 +4710,47 @@ w32_read_socket (struct terminal *terminal,
break;
case SIZE_MAXIMIZED:
+ {
+ bool iconified = FRAME_ICONIFIED_P (f);
+
+ SET_FRAME_VISIBLE (f, 1);
+ SET_FRAME_ICONIFIED (f, 0);
+
+ /* wait_reading_process_output will notice this
+ and update the frame's display structures. */
+ SET_FRAME_GARBAGED (f);
+
+ if (iconified)
+ {
+ int x, y;
+
+ /* Reset top and left positions of the Window
+ here since Windows sends a WM_MOVE message
+ BEFORE telling us the Window is minimized
+ when the Window is iconified, with 3000,3000
+ as the co-ords. */
+ x_real_positions (f, &x, &y);
+ f->left_pos = x;
+ f->top_pos = y;
+
+ inev.kind = DEICONIFY_EVENT;
+ XSETFRAME (inev.frame_or_window, f);
+ }
+ else if (! NILP (Vframe_list)
+ && ! NILP (XCDR (Vframe_list)))
+ /* Force a redisplay sooner or later
+ to update the frame titles
+ in case this is the second frame. */
+ record_asynch_buffer_change ();
+ }
+
+ if (get_frame_param (f, Qfullscreen) == Qnil)
+ set_frame_param (f, Qfullscreen, Qmaximized);
+ else if (get_frame_param (f, Qfullscreen) != Qmaximized)
+ set_frame_param (f, Qmaximized, Qmaximized);
+
+ break;
+
case SIZE_RESTORED:
{
bool iconified = FRAME_ICONIFIED_P (f);
@@ -4712,6 +4782,12 @@ w32_read_socket (struct terminal *terminal,
in case this is the second frame. */
record_asynch_buffer_change ();
}
+
+ if (get_frame_param (f, Qfullscreen) == Qmaximized)
+ set_frame_param (f, Qfullscreen, Qnil);
+ else if (get_frame_param (f, Qmaximized) != Qnil)
+ set_frame_param (f, Qmaximized, Qnil);
+
break;
}
}
@@ -4719,16 +4795,14 @@ w32_read_socket (struct terminal *terminal,
if (f && !FRAME_ICONIFIED_P (f) && msg.msg.wParam != SIZE_MINIMIZED)
{
RECT rect;
- int rows;
- int columns;
- int width;
- int height;
+ int rows, columns, width, height, text_width, text_height;
GetClientRect (msg.msg.hwnd, &rect);
height = rect.bottom - rect.top;
width = rect.right - rect.left;
-
+ text_width = FRAME_PIXEL_TO_TEXT_WIDTH (f, width);
+ text_height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, height);
rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, height);
columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, width);
@@ -4738,16 +4812,18 @@ w32_read_socket (struct terminal *terminal,
not changed, the font size may have changed, so we need
to check the pixel dimensions as well. */
- if (columns != FRAME_COLS (f)
- || rows != FRAME_LINES (f)
- || width != FRAME_PIXEL_WIDTH (f)
- || height != FRAME_PIXEL_HEIGHT (f))
+ if (width != FRAME_PIXEL_WIDTH (f)
+ || height != FRAME_PIXEL_HEIGHT (f)
+ || text_width != FRAME_TEXT_WIDTH (f)
+ || text_height != FRAME_TEXT_HEIGHT (f))
{
- change_frame_size (f, rows, columns, 0, 1, 0);
+ change_frame_size (f, text_width, text_height, 0, 1, 0, 1);
SET_FRAME_GARBAGED (f);
cancel_mouse_face (f);
- FRAME_PIXEL_WIDTH (f) = width;
- FRAME_PIXEL_HEIGHT (f) = height;
+ /* Do we want to set these here ???? */
+/** FRAME_PIXEL_WIDTH (f) = width; **/
+/** FRAME_TEXT_WIDTH (f) = text_width; **/
+/** FRAME_PIXEL_HEIGHT (f) = height; **/
f->win_gravity = NorthWestGravity;
}
}
@@ -5404,7 +5480,8 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
doing it because it's done in Fx_show_tip, and it leads to
problems because the tip frame has no widget. */
if (NILP (tip_frame) || XFRAME (tip_frame) != f)
- x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
+ x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f),
+ FRAME_TEXT_HEIGHT (f), 1);
}
/* X version sets font of input methods here also. */
@@ -5542,7 +5619,7 @@ x_check_fullscreen (struct frame *f)
when setting WM manager hints. */
if (FRAME_COLS (f) != width || FRAME_LINES (f) != height)
{
- change_frame_size (f, height, width, 0, 1, 0);
+ change_frame_size (f, width, height, 0, 1, 0, 0);
SET_FRAME_GARBAGED (f);
cancel_mouse_face (f);
@@ -5606,20 +5683,28 @@ w32fullscreen_hook (struct frame *f)
Otherwise we leave the window gravity unchanged. */
void
-x_set_window_size (struct frame *f, int change_gravity, int cols, int rows)
+x_set_window_size (struct frame *f, int change_gravity, int width, int height, bool pixelwise)
{
int pixelwidth, pixelheight;
block_input ();
- check_frame_size (f, &rows, &cols);
+ check_frame_size (f, &width, &height, pixelwise);
f->scroll_bar_actual_width
= FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f);
compute_fringe_widths (f, 0);
- pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, cols);
- pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows);
+ if (pixelwise)
+ {
+ pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width);
+ pixelheight = FRAME_TEXT_TO_PIXEL_HEIGHT (f, height);
+ }
+ else
+ {
+ pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width);
+ pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height);
+ }
f->win_gravity = NorthWestGravity;
x_wm_set_size_hint (f, (long) 0, 0);
@@ -5670,7 +5755,7 @@ x_set_window_size (struct frame *f, int change_gravity, int cols, int rows)
We pass 1 for DELAY since we can't run Lisp code inside of
a BLOCK_INPUT. */
- change_frame_size (f, rows, cols, 0, 1, 0);
+ change_frame_size (f, width, height, 0, 1, 0, 0);
FRAME_PIXEL_WIDTH (f) = pixelwidth;
FRAME_PIXEL_HEIGHT (f) = pixelheight;
@@ -6051,7 +6136,7 @@ x_wm_set_size_hint (struct frame *f, long flags, bool user_position)
SetWindowLong (window, WND_FONTWIDTH_INDEX, FRAME_COLUMN_WIDTH (f));
SetWindowLong (window, WND_LINEHEIGHT_INDEX, FRAME_LINE_HEIGHT (f));
SetWindowLong (window, WND_BORDER_INDEX, FRAME_INTERNAL_BORDER_WIDTH (f));
- SetWindowLong (window, WND_SCROLLBAR_INDEX, f->scroll_bar_actual_width);
+ SetWindowLong (window, WND_SCROLLBAR_INDEX, FRAME_SCROLL_BAR_AREA_WIDTH (f));
leave_crit ();
}
@@ -6191,6 +6276,7 @@ static struct redisplay_interface w32_redisplay_interface =
w32_clear_frame_area,
w32_draw_window_cursor,
w32_draw_vertical_window_border,
+ w32_draw_window_divider,
w32_shift_glyphs_for_insert
};
diff --git a/src/w32term.h b/src/w32term.h
index 6825e3cd546..779b37e63a8 100644
--- a/src/w32term.h
+++ b/src/w32term.h
@@ -230,7 +230,7 @@ extern struct w32_display_info *w32_term_init (Lisp_Object,
extern int w32_defined_color (struct frame *f, const char *color,
XColor *color_def, int alloc);
extern void x_set_window_size (struct frame *f, int change_grav,
- int cols, int rows);
+ int width, int height, bool pixelwise);
extern int x_display_pixel_height (struct w32_display_info *);
extern int x_display_pixel_width (struct w32_display_info *);
extern Lisp_Object x_get_focus_frame (struct frame *);
@@ -349,6 +349,7 @@ struct w32_output
Cursor hand_cursor;
Cursor hourglass_cursor;
Cursor horizontal_drag_cursor;
+ Cursor vertical_drag_cursor;
/* Non-zero means hourglass cursor is currently displayed. */
unsigned hourglass_p : 1;
diff --git a/src/widget.c b/src/widget.c
index d6469d7eec5..89b43fdae76 100644
--- a/src/widget.c
+++ b/src/widget.c
@@ -412,7 +412,7 @@ set_frame_size (EmacsFrame ew)
#if 0 /* This can run Lisp code, and it is dangerous to give
out the frame to Lisp code before it officially exists.
This is handled in Fx_create_frame so not needed here. */
- change_frame_size (f, h, w, 1, 0, 0);
+ change_frame_size (f, w, h, 1, 0, 0, 0);
#endif
char_to_pixel_size (ew, w, h, &pixel_width, &pixel_height);
ew->core.width = pixel_width;
@@ -467,7 +467,7 @@ update_wm_hints (EmacsFrame ew)
if (! wmshell) return;
#if 0
- check_frame_size (ew->emacs_frame.frame, &min_rows, &min_cols);
+ check_frame_size (ew->emacs_frame.frame, &min_cols, &min_rows, 0);
#endif
pixel_to_char_size (ew, ew->core.width, ew->core.height,
@@ -681,7 +681,7 @@ EmacsFrameResize (Widget widget)
|| ew->core.width != FRAME_PIXEL_WIDTH (f)
|| ew->core.height + x->menubar_height != FRAME_PIXEL_HEIGHT (f))
{
- change_frame_size (f, rows, columns, 0, 1, 0);
+ change_frame_size (f, columns, rows, 0, 1, 0, 0);
update_wm_hints (ew);
update_various_frame_slots (ew);
@@ -735,8 +735,8 @@ EmacsFrameSetValues (Widget cur_widget, Widget req_widget, Widget new_widget, Ar
new->core.width = pixel_width;
new->core.height = pixel_height;
- change_frame_size (new->emacs_frame.frame, char_height, char_width,
- 1, 0, 0);
+ change_frame_size (new->emacs_frame.frame, char_width, char_height,
+ 1, 0, 0, 0);
needs_a_refresh = True;
}
@@ -798,7 +798,7 @@ EmacsFrameSetCharSize (Widget widget, int columns, int rows)
EmacsFrame ew = (EmacsFrame) widget;
struct frame *f = ew->emacs_frame.frame;
- x_set_window_size (f, 0, columns, rows);
+ x_set_window_size (f, 0, columns, rows, 0);
}
diff --git a/src/window.c b/src/window.c
index 89fcb490412..e73c50fc3a1 100644
--- a/src/window.c
+++ b/src/window.c
@@ -51,6 +51,7 @@ static Lisp_Object Qrecord_window_buffer;
static Lisp_Object Qwindow_deletable_p, Qdelete_window, Qdisplay_buffer;
static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window;
static Lisp_Object Qwindow_resize_root_window, Qwindow_resize_root_window_vertically;
+static Lisp_Object Qwindow_pixel_to_total;
static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command;
static Lisp_Object Qsafe, Qabove, Qbelow, Qwindow_size, Qclone_of;
@@ -74,6 +75,7 @@ static int foreach_window_1 (struct window *,
static Lisp_Object window_list_1 (Lisp_Object, Lisp_Object, Lisp_Object);
static int window_resize_check (struct window *, bool);
static void window_resize_apply (struct window *, bool);
+static void window_resize_apply_total (struct window *, bool);
static Lisp_Object select_window (Lisp_Object, Lisp_Object, int);
static void select_window_1 (Lisp_Object, bool);
@@ -112,6 +114,9 @@ Lisp_Object minibuf_selected_window;
/* Hook run at end of temp_output_buffer_show. */
static Lisp_Object Qtemp_buffer_show_hook;
+/* Incremented for each window created. */
+static int sequence_number;
+
/* Nonzero after init_window_once has finished. */
static int window_initialized;
@@ -675,6 +680,31 @@ selected one. */)
return make_number (decode_live_window (window)->use_time);
}
+DEFUN ("window-pixel-width", Fwindow_pixel_width, Swindow_pixel_width, 0, 1, 0,
+ doc: /* Return the pixel width of window WINDOW.
+WINDOW must be a valid window and defaults to the selected one.
+
+The return value includes the fringes and margins of WINDOW as well as
+any vertical dividers or scroll bars belonging to WINDOW. If WINDOW is
+an internal window, its pixel width is the width of the screen areas
+spanned by its children. */)
+ (Lisp_Object window)
+{
+ return make_number (decode_valid_window (window)->pixel_width);
+}
+
+DEFUN ("window-pixel-height", Fwindow_pixel_height, Swindow_pixel_height, 0, 1, 0,
+ doc: /* Return the pixel height of window WINDOW.
+WINDOW must be a valid window and defaults to the selected one.
+
+The return value includes the mode line and header line, if any. If
+WINDOW is an internal window, its pixel height is the height of the
+screen areas spanned by its children. */)
+ (Lisp_Object window)
+{
+ return make_number (decode_valid_window (window)->pixel_height);
+}
+
DEFUN ("window-total-height", Fwindow_total_height, Swindow_total_height, 0, 1, 0,
doc: /* Return the total height, in lines, of window WINDOW.
WINDOW must be a valid window and defaults to the selected one.
@@ -732,6 +762,30 @@ WINDOW must be a valid window and defaults to the selected one. */)
return decode_valid_window (window)->new_normal;
}
+DEFUN ("window-new-pixel", Fwindow_new_pixel, Swindow_new_pixel, 0, 1, 0,
+ doc: /* Return new pixel size of window WINDOW.
+WINDOW must be a valid window and defaults to the selected one. */)
+ (Lisp_Object window)
+{
+ return decode_valid_window (window)->new_pixel;
+}
+
+DEFUN ("window-pixel-left", Fwindow_pixel_left, Swindow_pixel_left, 0, 1, 0,
+ doc: /* Return left pixel edge of window WINDOW.
+WINDOW must be a valid window and defaults to the selected one. */)
+ (Lisp_Object window)
+{
+ return make_number (decode_valid_window (window)->pixel_left);
+}
+
+DEFUN ("window-pixel-top", Fwindow_pixel_top, Swindow_pixel_top, 0, 1, 0,
+ doc: /* Return top pixel edge of window WINDOW.
+WINDOW must be a valid window and defaults to the selected one. */)
+ (Lisp_Object window)
+{
+ return make_number (decode_valid_window (window)->pixel_top);
+}
+
DEFUN ("window-left-column", Fwindow_left_column, Swindow_left_column, 0, 1, 0,
doc: /* Return left column of window WINDOW.
This is the distance, in columns, between the left edge of WINDOW and
@@ -760,75 +814,118 @@ WINDOW must be a valid window and defaults to the selected one. */)
header line of W. */
static int
-window_body_lines (struct window *w)
+window_body_height (struct window *w, bool pixelwise)
{
- int height = w->total_lines;
-
- if (!MINI_WINDOW_P (w))
- {
- if (WINDOW_WANTS_MODELINE_P (w))
- --height;
- if (WINDOW_WANTS_HEADER_LINE_P (w))
- --height;
- }
+ int pixels = (w->pixel_height
+ - WINDOW_BOTTOM_DIVIDER_WIDTH (w)
+ - WINDOW_HEADER_LINE_HEIGHT (w)
+ - WINDOW_MODE_LINE_HEIGHT (w));
+ int unit = FRAME_LINE_HEIGHT (WINDOW_XFRAME (w));
- return height;
+ return pixelwise ? pixels : ((pixels + unit - 1) / unit);
}
/* Return the number of columns of W's body. Don't count columns
occupied by the scroll bar or the vertical bar separating W from its
right sibling. On window-systems don't count fringes or display
margins either. */
-
int
-window_body_cols (struct window *w)
+window_body_width (struct window *w, bool pixelwise)
{
struct frame *f = XFRAME (WINDOW_FRAME (w));
- int width = w->total_cols;
- if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
- /* Scroll bars occupy a few columns. */
- width -= WINDOW_CONFIG_SCROLL_BAR_COLS (w);
- else if (!FRAME_WINDOW_P (f)
- && !WINDOW_RIGHTMOST_P (w) && !WINDOW_FULL_WIDTH_P (w))
- /* The column of `|' characters separating side-by-side windows
- occupies one column only. */
- width -= 1;
+ int pixels = (w->pixel_width
+ - WINDOW_RIGHT_DIVIDER_WIDTH (w)
+ - (WINDOW_HAS_VERTICAL_SCROLL_BAR (w)
+ ? WINDOW_SCROLL_BAR_AREA_WIDTH (w)
+ : ((!FRAME_WINDOW_P (f)
+ && !WINDOW_RIGHTMOST_P (w)
+ && !WINDOW_RIGHT_DIVIDER_WIDTH (w)
+ && !WINDOW_FULL_WIDTH_P (w))
+ /* According to Eli this is either 1 or 0. */
+ ? 1 : 0))
+ - WINDOW_MARGINS_WIDTH (w)
+ - (FRAME_WINDOW_P (f)
+ ? WINDOW_FRINGES_WIDTH (w)
+ : 0));
+ int unit = FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w));
+
+ return pixelwise ? pixels : ((pixels + unit - 1) / unit);
+}
+
+DEFUN ("window-body-height", Fwindow_body_height, Swindow_body_height, 0, 2, 0,
+ doc: /* Return the height, in lines, of WINDOW's text area.
+WINDOW must be a live window and defaults to the selected one.
- /* Display margins cannot be used for normal text. */
- width -= WINDOW_LEFT_MARGIN_COLS (w) + WINDOW_RIGHT_MARGIN_COLS (w);
+Optional argument PIXELWISE non-nil means return the height in pixels.
- if (FRAME_WINDOW_P (f))
- /* On window-systems, fringes cannot be used for normal text. */
- width -= WINDOW_FRINGE_COLS (w);
+The returned height does not include the mode line or header line. On a
+graphical display, the height is expressed as an integer multiple of the
+default character height if PIXELWISE is nil.
- return width;
+If PIXELWISE is nil and a line at the bottom of the text area is only
+partially visible, that counts as a whole line; to exclude
+partially-visible lines, use `window-text-height'. */)
+ (Lisp_Object window, Lisp_Object pixelwise)
+{
+ return make_number (window_body_height (decode_live_window (window),
+ NILP (pixelwise) ? 0 : 1));
}
-DEFUN ("window-body-height", Fwindow_body_height, Swindow_body_height, 0, 1, 0,
- doc: /* Return the height, in lines, of WINDOW's text area.
+DEFUN ("window-body-width", Fwindow_body_width, Swindow_body_width, 0, 2, 0,
+ doc: /* Return the width, in columns, of WINDOW's text area.
WINDOW must be a live window and defaults to the selected one.
-The returned height does not include the mode line or header line.
-On a graphical display, the height is expressed as an integer multiple
-of the default character height. If a line at the bottom of the text
-area is only partially visible, that counts as a whole line; to
-exclude partially-visible lines, use `window-text-height'. */)
+Optional argument PIXELWISE non-nil means return the width in pixels.
+
+The return value does not include any vertical dividers, fringe or
+marginal areas, or scroll bars. On a graphical display, the width is
+expressed as an integer multiple of the default character width if
+PIXELWISE is nil.
+
+If PIXELWISE is nil and a column at the right of the text area is only
+partially visible, that counts as a whole column; to exclude
+partially-visible columns, use `window-text-width'. */)
+ (Lisp_Object window, Lisp_Object pixelwise)
+{
+ return make_number (window_body_width (decode_live_window (window),
+ NILP (pixelwise) ? 0 : 1));
+}
+
+DEFUN ("window-mode-line-height", Fwindow_mode_line_height,
+ Swindow_mode_line_height, 0, 1, 0,
+ doc: /* Return the height in pixel of WINDOW's mode-line.
+WINDOW must be a live window and defaults to the selected one. */)
(Lisp_Object window)
{
- return make_number (window_body_lines (decode_live_window (window)));
+ return (make_number (WINDOW_MODE_LINE_HEIGHT (decode_live_window (window))));
}
-DEFUN ("window-body-width", Fwindow_body_width, Swindow_body_width, 0, 1, 0,
- doc: /* Return the width, in columns, of WINDOW's text area.
-WINDOW must be a live window and defaults to the selected one.
+DEFUN ("window-header-line-height", Fwindow_header_line_height,
+ Swindow_header_line_height, 0, 1, 0,
+ doc: /* Return the height in pixel of WINDOW's header-line.
+WINDOW must be a live window and defaults to the selected one. */)
+ (Lisp_Object window)
+{
+ return (make_number (WINDOW_HEADER_LINE_HEIGHT (decode_live_window (window))));
+}
-The return value does not include any vertical dividers, fringe or
-marginal areas, or scroll bars. On a graphical display, the width is
-expressed as an integer multiple of the default character width. */)
+DEFUN ("window-right-divider-width", Fwindow_right_divider_width,
+ Swindow_right_divider_width, 0, 1, 0,
+ doc: /* Return the width of WINDOW's right divider.
+WINDOW must be a live window and defaults to the selected one. */)
(Lisp_Object window)
{
- return make_number (window_body_cols (decode_live_window (window)));
+ return (make_number (WINDOW_RIGHT_DIVIDER_WIDTH (decode_live_window (window))));
+}
+
+DEFUN ("window-bottom-divider-width", Fwindow_bottom_divider_width,
+ Swindow_bottom_divider_width, 0, 1, 0,
+ doc: /* Return the width of WINDOW's bottom divider.
+WINDOW must be a live window and defaults to the selected one. */)
+ (Lisp_Object window)
+{
+ return (make_number (WINDOW_BOTTOM_DIVIDER_WIDTH (decode_live_window (window))));
}
DEFUN ("window-hscroll", Fwindow_hscroll, Swindow_hscroll, 0, 1, 0,
@@ -1078,11 +1175,15 @@ display margins, fringes, header line, and/or mode line. */)
/* Test if the character at column X, row Y is within window W.
If it is not, return ON_NOTHING;
+ if it is on the window's vertical divider, return
+ ON_RIGHT_DIVIDER;
+ if it is on the window's horizontal divider, return
+ ON_BOTTOM_DIVIDER;
if it is in the window's text area, return ON_TEXT;
if it is on the window's modeline, return ON_MODE_LINE;
if it is on the border between the window and its right sibling,
- return ON_VERTICAL_BORDER.
- if it is on a scroll bar, return ON_SCROLL_BAR.
+ return ON_VERTICAL_BORDER;
+ if it is on a scroll bar, return ON_SCROLL_BAR;
if it is on the window's top line, return ON_HEADER_LINE;
if it is in left or right fringe of the window,
return ON_LEFT_FRINGE or ON_RIGHT_FRINGE;
@@ -1110,13 +1211,28 @@ coordinates_in_window (register struct window *w, int x, int y)
if (y < top_y || y >= bottom_y || x < left_x || x >= right_x)
return ON_NOTHING;
- /* On the mode line or header line? */
- if ((WINDOW_WANTS_MODELINE_P (w)
- && y >= bottom_y - CURRENT_MODE_LINE_HEIGHT (w)
- && (part = ON_MODE_LINE))
- || (WINDOW_WANTS_HEADER_LINE_P (w)
- && y < top_y + CURRENT_HEADER_LINE_HEIGHT (w)
- && (part = ON_HEADER_LINE)))
+ /* On vertical window divider (which prevails horizontal
+ dividers) ? */
+ if (!WINDOW_RIGHTMOST_P (w)
+ && WINDOW_RIGHT_DIVIDER_WIDTH (w)
+ && x >= right_x - WINDOW_RIGHT_DIVIDER_WIDTH (w)
+ && x <= right_x)
+ return ON_RIGHT_DIVIDER;
+ /* On the horizontal window divider? */
+ else if (WINDOW_BOTTOM_DIVIDER_WIDTH (w)
+ && y >= (bottom_y - WINDOW_BOTTOM_DIVIDER_WIDTH (w))
+ && y <= bottom_y)
+ return ON_BOTTOM_DIVIDER;
+ /* On the mode or header line? */
+ else if ((WINDOW_WANTS_MODELINE_P (w)
+ && y >= (bottom_y
+ - CURRENT_MODE_LINE_HEIGHT (w)
+ - WINDOW_BOTTOM_DIVIDER_WIDTH (w))
+ && y <= bottom_y - WINDOW_BOTTOM_DIVIDER_WIDTH (w)
+ && (part = ON_MODE_LINE))
+ || (WINDOW_WANTS_HEADER_LINE_P (w)
+ && y < top_y + CURRENT_HEADER_LINE_HEIGHT (w)
+ && (part = ON_HEADER_LINE)))
{
/* If it's under/over the scroll bar portion of the mode/header
line, say it's on the vertical line. That's to be able to
@@ -1139,7 +1255,7 @@ coordinates_in_window (register struct window *w, int x, int y)
if (w->pseudo_window_p)
{
left_x = 0;
- right_x = WINDOW_TOTAL_WIDTH (w) - 1;
+ right_x = WINDOW_PIXEL_WIDTH (w) - 1;
}
else
{
@@ -1169,6 +1285,8 @@ coordinates_in_window (register struct window *w, int x, int y)
terminals, the vertical line's x coordinate is right_x. */
else if (!w->pseudo_window_p
&& !WINDOW_RIGHTMOST_P (w)
+ /* Why check ux if we are not the rightmost window ? Also
+ shouldn't a pseudo window always be rightmost ? */
&& x > right_x - ux)
return ON_VERTICAL_BORDER;
@@ -1224,7 +1342,7 @@ window_relative_x_coord (struct window *w, enum window_part part, int x)
case ON_RIGHT_MARGIN:
return (x + 1
- ((w->pseudo_window_p)
- ? WINDOW_TOTAL_WIDTH (w)
+ ? WINDOW_PIXEL_WIDTH (w)
: WINDOW_BOX_RIGHT_EDGE_X (w))
+ window_box_width (w, RIGHT_MARGIN_AREA)
+ ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
@@ -1309,6 +1427,12 @@ If they are in the windows's left or right marginal areas, `left-margin'\n\
/* Historically we are supposed to return nil in this case. */
return Qnil;
+ case ON_RIGHT_DIVIDER:
+ return Qright_divider;
+
+ case ON_BOTTOM_DIVIDER:
+ return Qbottom_divider;
+
default:
emacs_abort ();
}
@@ -2002,6 +2126,10 @@ replace_window (Lisp_Object old, Lisp_Object new, int setflag)
if (setflag)
{
+ n->pixel_left = o->pixel_left;
+ n->pixel_top = o->pixel_top;
+ n->pixel_width = o->pixel_width;
+ n->pixel_height = o->pixel_height;
n->left_col = o->left_col;
n->top_line = o->top_line;
n->total_cols = o->total_cols;
@@ -2082,13 +2210,13 @@ recombine_windows (Lisp_Object window)
wset_parent (c, parent);
if (horflag)
- wset_normal_cols (c,
- make_float ((double) c->total_cols
- / (double) p->total_cols));
+ wset_normal_cols
+ (c, make_float ((double) c->pixel_width
+ / (double) p->pixel_width));
else
- wset_normal_lines (c,
- make_float ((double) c->total_lines
- / (double) p->total_lines));
+ wset_normal_lines
+ (c, make_float ((double) c->pixel_height
+ / (double) p->pixel_height));
if (NILP (c->next))
{
@@ -2719,9 +2847,16 @@ selected frame and no others. */)
}
static Lisp_Object
-resize_root_window (Lisp_Object window, Lisp_Object delta, Lisp_Object horizontal, Lisp_Object ignore)
+resize_root_window (Lisp_Object window, Lisp_Object delta, Lisp_Object horizontal, Lisp_Object ignore, Lisp_Object pixelwise)
+{
+ return call5 (Qwindow_resize_root_window, window, delta, horizontal, ignore, pixelwise);
+}
+
+
+static Lisp_Object
+window_pixel_to_total (Lisp_Object frame, Lisp_Object horizontal)
{
- return call4 (Qwindow_resize_root_window, window, delta, horizontal, ignore);
+ return call2(Qwindow_pixel_to_total, frame, horizontal);
}
@@ -2785,8 +2920,8 @@ window-start value is reasonable when this function is called. */)
{
startpos = marker_position (w->start);
startbyte = marker_byte_position (w->start);
- top = WINDOW_TOP_EDGE_LINE (w)
- - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w)));
+ top = (WINDOW_TOP_EDGE_LINE (w)
+ - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w))));
/* Make sure WINDOW is the frame's selected window. */
if (!EQ (window, FRAME_SELECTED_WINDOW (f)))
{
@@ -2852,16 +2987,23 @@ window-start value is reasonable when this function is called. */)
if (!WINDOW_LEAF_P (w))
{
/* Resize child windows vertically. */
- XSETINT (delta, r->total_lines - w->total_lines);
+ XSETINT (delta, r->pixel_height - w->pixel_height);
+ w->pixel_top = r->pixel_top;
w->top_line = r->top_line;
- resize_root_window (window, delta, Qnil, Qnil);
+ resize_root_window (window, delta, Qnil, Qnil, Qt);
if (window_resize_check (w, 0))
- window_resize_apply (w, 0);
+ {
+ window_resize_apply (w, 0);
+ window_pixel_to_total (w->frame, Qnil);
+ }
else
{
- resize_root_window (window, delta, Qnil, Qt);
+ resize_root_window (window, delta, Qnil, Qt, Qt);
if (window_resize_check (w, 0))
- window_resize_apply (w, 0);
+ {
+ window_resize_apply (w, 0);
+ window_pixel_to_total (w->frame, Qnil);
+ }
else
resize_failed = 1;
}
@@ -2870,15 +3012,22 @@ window-start value is reasonable when this function is called. */)
if (!resize_failed)
{
w->left_col = r->left_col;
- XSETINT (delta, r->total_cols - w->total_cols);
- resize_root_window (window, delta, Qt, Qnil);
+ w->pixel_left = r->pixel_left;
+ XSETINT (delta, r->pixel_width - w->pixel_width);
+ resize_root_window (window, delta, Qt, Qnil, Qt);
if (window_resize_check (w, 1))
- window_resize_apply (w, 1);
+ {
+ window_resize_apply (w, 1);
+ window_pixel_to_total (w->frame, Qt);
+ }
else
{
- resize_root_window (window, delta, Qt, Qt);
+ resize_root_window (window, delta, Qt, Qt, Qt);
if (window_resize_check (w, 1))
- window_resize_apply (w, 1);
+ {
+ window_resize_apply (w, 1);
+ window_pixel_to_total (w->frame, Qt);
+ }
else
resize_failed = 1;
}
@@ -2987,27 +3136,46 @@ replace_buffer_in_windows_safely (Lisp_Object buffer)
}
}
-/* If *ROWS or *COLS are too small a size for FRAME, set them to the
- minimum allowable size. */
+/* If *HEIGHT or *WIDTH are too small a size for FRAME, set them to the
+ minimum allowable size. PIXELWISE means interpret these as pixel
+ sizes. */
void
-check_frame_size (struct frame *frame, int *rows, int *cols)
+check_frame_size (struct frame *frame, int *width, int *height, bool pixelwise)
{
/* For height, we have to see:
how many windows the frame has at minimum (one or two),
and whether it has a menu bar or other special stuff at the top. */
- int min_height
- = ((FRAME_MINIBUF_ONLY_P (frame) || ! FRAME_HAS_MINIBUF_P (frame))
- ? MIN_SAFE_WINDOW_HEIGHT
- : 2 * MIN_SAFE_WINDOW_HEIGHT);
+ if (pixelwise)
+ {
+ int min_height = MIN_SAFE_WINDOW_HEIGHT * FRAME_LINE_HEIGHT (frame);
+ int min_width = MIN_SAFE_WINDOW_WIDTH * FRAME_COLUMN_WIDTH (frame);
- if (FRAME_TOP_MARGIN (frame) > 0)
- min_height += FRAME_TOP_MARGIN (frame);
+ if (!FRAME_MINIBUF_ONLY_P (frame) && FRAME_HAS_MINIBUF_P (frame))
+ min_height = 2 * min_height;
- if (*rows < min_height)
- *rows = min_height;
- if (*cols < MIN_SAFE_WINDOW_WIDTH)
- *cols = MIN_SAFE_WINDOW_WIDTH;
+ min_height += FRAME_TOP_MARGIN_HEIGHT (frame);
+
+ if (*height < min_height)
+ *height = min_height;
+ if (*width < min_width)
+ *width = min_width;
+ }
+ else
+ {
+ int min_height
+ = ((FRAME_MINIBUF_ONLY_P (frame) || ! FRAME_HAS_MINIBUF_P (frame))
+ ? MIN_SAFE_WINDOW_HEIGHT
+ : 2 * MIN_SAFE_WINDOW_HEIGHT);
+
+ if (FRAME_TOP_MARGIN (frame) > 0)
+ min_height += FRAME_TOP_MARGIN (frame);
+
+ if (*height < min_height)
+ *height = min_height;
+ if (*width < MIN_SAFE_WINDOW_WIDTH)
+ *width = MIN_SAFE_WINDOW_WIDTH;
+ }
}
/* Adjust the margins of window W if text area is too small.
@@ -3017,31 +3185,37 @@ check_frame_size (struct frame *frame, int *rows, int *cols)
static int
adjust_window_margins (struct window *w)
{
- int box_cols = (WINDOW_TOTAL_COLS (w)
- - WINDOW_FRINGE_COLS (w)
- - WINDOW_SCROLL_BAR_COLS (w));
- int margin_cols = (WINDOW_LEFT_MARGIN_COLS (w)
- + WINDOW_RIGHT_MARGIN_COLS (w));
+ int box_width = (WINDOW_PIXEL_WIDTH (w)
+ - WINDOW_FRINGES_WIDTH (w)
+ - WINDOW_SCROLL_BAR_AREA_WIDTH (w));
+ int margin_width = WINDOW_MARGINS_WIDTH (w);
- if (box_cols - margin_cols >= MIN_SAFE_WINDOW_WIDTH)
+ if (box_width - margin_width >= MIN_SAFE_WINDOW_PIXEL_WIDTH (w))
return 1;
- if (margin_cols < 0 || box_cols < MIN_SAFE_WINDOW_WIDTH)
+ if (margin_width < 0 || box_width < MIN_SAFE_WINDOW_PIXEL_WIDTH (w))
return 0;
-
- /* Window's text area is too narrow, but reducing the window
- margins will fix that. */
- margin_cols = box_cols - MIN_SAFE_WINDOW_WIDTH;
- if (WINDOW_RIGHT_MARGIN_COLS (w) > 0)
+ else
+ /* Window's text area is too narrow, but reducing the window
+ margins will fix that. */
{
- if (WINDOW_LEFT_MARGIN_COLS (w) > 0)
- w->left_margin_cols = w->right_margin_cols = margin_cols / 2;
+ int unit = WINDOW_FRAME_COLUMN_WIDTH (w);
+
+ margin_width = box_width - MIN_SAFE_WINDOW_PIXEL_WIDTH (w);
+
+ if (WINDOW_RIGHT_MARGIN_WIDTH (w) > 0)
+ {
+ if (WINDOW_LEFT_MARGIN_WIDTH (w) > 0)
+ w->left_margin_cols = w->right_margin_cols =
+ margin_width / (2 * unit);
+ else
+ w->right_margin_cols = margin_width / unit;
+ }
else
- w->right_margin_cols = margin_cols;
+ w->left_margin_cols = margin_width / unit;
+
+ return 1;
}
- else
- w->left_margin_cols = margin_cols;
- return 1;
}
/* The following three routines are needed for running a window's
@@ -3126,11 +3300,23 @@ If FRAME is omitted or nil, it defaults to the selected frame. */)
return Qnil;
}
-/* Make WINDOW display BUFFER as its contents. RUN_HOOKS_P non-zero
- means it's allowed to run hooks. See make_frame for a case where
- it's not allowed. KEEP_MARGINS_P non-zero means that the current
- margins, fringes, and scroll-bar settings of the window are not
- reset from the buffer's local settings. */
+DEFUN ("run-window-scroll-functions", Frun_window_scroll_functions,
+ Srun_window_scroll_functions, 0, 1, 0,
+ doc: /* Run `window-scroll-functions' for WINDOW.
+If WINDOW is omitted or nil, it defaults to the selected window. */)
+ (Lisp_Object window)
+{
+ if (! NILP (Vwindow_scroll_functions))
+ run_hook_with_args_2 (Qwindow_scroll_functions, window,
+ Fmarker_position (decode_live_window (window)->start));
+ return Qnil;
+}
+
+/* Make WINDOW display BUFFER. RUN_HOOKS_P non-zero means it's allowed
+ to run hooks. See make_frame for a case where it's not allowed.
+ KEEP_MARGINS_P non-zero means that the current margins, fringes, and
+ scroll-bar settings of the window are not reset from the buffer's
+ local settings. */
void
set_window_buffer (Lisp_Object window, Lisp_Object buffer,
@@ -3139,7 +3325,7 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer,
struct window *w = XWINDOW (window);
struct buffer *b = XBUFFER (buffer);
ptrdiff_t count = SPECPDL_INDEX ();
- int samebuf = EQ (buffer, w->contents);
+ bool samebuf = EQ (buffer, w->contents);
wset_buffer (w, buffer);
@@ -3209,14 +3395,15 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer,
if (! NILP (Vwindow_scroll_functions))
run_hook_with_args_2 (Qwindow_scroll_functions, window,
Fmarker_position (w->start));
- run_window_configuration_change_hook (XFRAME (WINDOW_FRAME (w)));
+ if (!samebuf)
+ run_window_configuration_change_hook (XFRAME (WINDOW_FRAME (w)));
}
unbind_to (count, Qnil);
}
DEFUN ("set-window-buffer", Fset_window_buffer, Sset_window_buffer, 2, 3, 0,
- doc: /* Make WINDOW display BUFFER-OR-NAME as its contents.
+ doc: /* Make WINDOW display BUFFER-OR-NAME.
WINDOW must be a live window and defaults to the selected one.
BUFFER-OR-NAME must be a buffer or the name of an existing buffer.
@@ -3388,6 +3575,8 @@ make_parent_window (Lisp_Object window, bool horflag)
adjust_window_count (p, 1);
XSETWINDOW (parent, p);
+ p->sequence_number = ++sequence_number;
+
replace_window (window, parent, 1);
wset_next (o, Qnil);
@@ -3416,6 +3605,7 @@ make_window (void)
wset_normal_cols (w, make_float (1.0));
wset_new_total (w, make_number (0));
wset_new_normal (w, make_number (0));
+ wset_new_pixel (w, make_number (0));
wset_start (w, Fmake_marker ());
wset_pointm (w, Fmake_marker ());
wset_vertical_scroll_bar_type (w, Qt);
@@ -3433,6 +3623,7 @@ make_window (void)
w->phys_cursor_type = NO_CURSOR;
w->phys_cursor_width = -1;
#endif
+ w->sequence_number = ++sequence_number;
w->scroll_bar_width = -1;
w->column_number_displayed = -1;
@@ -3443,6 +3634,28 @@ make_window (void)
return window;
}
+DEFUN ("set-window-new-pixel", Fset_window_new_pixel, Sset_window_new_pixel, 2, 3, 0,
+ doc: /* Set new pixel size of WINDOW to SIZE.
+WINDOW must be a valid window and defaults to the selected one.
+Return SIZE.
+
+Optional argument ADD non-nil means add SIZE to the new pixel size of
+WINDOW and return the sum.
+
+Note: This function does not operate on any child windows of WINDOW. */)
+ (Lisp_Object window, Lisp_Object size, Lisp_Object add)
+{
+ struct window *w = decode_valid_window (window);
+
+ CHECK_NUMBER (size);
+ if (NILP (add))
+ wset_new_pixel (w, size);
+ else
+ wset_new_pixel (w, make_number (XINT (w->new_pixel) + XINT (size)));
+
+ return w->new_pixel;
+}
+
DEFUN ("set-window-new-total", Fset_window_new_total, Sset_window_new_total, 2, 3, 0,
doc: /* Set new total size of WINDOW to SIZE.
WINDOW must be a valid window and defaults to the selected one.
@@ -3477,8 +3690,8 @@ Note: This function does not operate on any child windows of WINDOW. */)
return size;
}
-/* Return 1 if setting w->total_lines (w->total_cols if HORFLAG is
- non-zero) to w->new_total would result in correct heights (widths)
+/* Return 1 if setting w->pixel_height (w->pixel_width if HORFLAG is
+ non-zero) to w->new_pixel would result in correct heights (widths)
for window W and recursively all child windows of W.
Note: This function does not check any of `window-fixed-size-p',
@@ -3487,6 +3700,7 @@ Note: This function does not operate on any child windows of WINDOW. */)
static int
window_resize_check (struct window *w, bool horflag)
{
+ struct frame *f = XFRAME (w->frame);
struct window *c;
if (WINDOW_VERTICAL_COMBINATION_P (w))
@@ -3498,26 +3712,31 @@ window_resize_check (struct window *w, bool horflag)
{
while (c)
{
- if ((XINT (c->new_total) != XINT (w->new_total))
+ if (XINT (c->new_pixel) != XINT (w->new_pixel)
|| !window_resize_check (c, horflag))
return 0;
+
c = NILP (c->next) ? 0 : XWINDOW (c->next);
}
+
return 1;
}
else
/* The sum of the heights of the child windows of W must equal
W's height. */
{
- int sum_of_sizes = 0;
+ int sum_of_pixels = 0;
+
while (c)
{
if (!window_resize_check (c, horflag))
return 0;
- sum_of_sizes = sum_of_sizes + XINT (c->new_total);
+
+ sum_of_pixels = sum_of_pixels + XINT (c->new_pixel);
c = NILP (c->next) ? 0 : XWINDOW (c->next);
}
- return (sum_of_sizes == XINT (w->new_total));
+
+ return (sum_of_pixels == XINT (w->new_pixel));
}
}
else if (WINDOW_HORIZONTAL_COMBINATION_P (w))
@@ -3528,26 +3747,31 @@ window_resize_check (struct window *w, bool horflag)
/* The sum of the widths of the child windows of W must equal W's
width. */
{
- int sum_of_sizes = 0;
+ int sum_of_pixels = 0;
+
while (c)
{
if (!window_resize_check (c, horflag))
return 0;
- sum_of_sizes = sum_of_sizes + XINT (c->new_total);
+
+ sum_of_pixels = sum_of_pixels + XINT (c->new_pixel);
c = NILP (c->next) ? 0 : XWINDOW (c->next);
}
- return (sum_of_sizes == XINT (w->new_total));
+
+ return (sum_of_pixels == XINT (w->new_pixel));
}
else
/* All child windows of W must have the same height as W. */
{
while (c)
{
- if ((XINT (c->new_total) != XINT (w->new_total))
+ if (XINT (c->new_pixel) != XINT (w->new_pixel)
|| !window_resize_check (c, horflag))
return 0;
+
c = NILP (c->next) ? 0 : XWINDOW (c->next);
}
+
return 1;
}
}
@@ -3555,12 +3779,111 @@ window_resize_check (struct window *w, bool horflag)
/* A leaf window. Make sure it's not too small. The following
hardcodes the values of `window-safe-min-width' (2) and
`window-safe-min-height' (1) which are defined in window.el. */
- return XINT (w->new_total) >= (horflag ? 2 : 1);
+ return (XINT (w->new_pixel) >= (horflag
+ ? (2 * FRAME_COLUMN_WIDTH (f))
+ : FRAME_LINE_HEIGHT (f)));
}
-/* Set w->total_lines (w->total_cols if HORIZONTAL is non-zero) to
- w->new_total for window W and recursively all child windows of W.
- Also calculate and assign the new vertical (horizontal) start
+static int
+window_resize_total_check (struct window *w, int horflag)
+{
+ struct frame *f = XFRAME (w->frame);
+ struct window *c;
+
+ if (WINDOW_VERTICAL_COMBINATION_P (w))
+ /* W is a vertical combination. */
+ {
+ c = XWINDOW (w->contents);
+ if (horflag)
+ /* All child windows of W must have the same width as W. */
+ {
+ while (c)
+ {
+ if (XINT (c->new_pixel) != XINT (w->new_pixel)
+/** || XINT (c->new_total != XINT (w->new_total)) **/
+ || !window_resize_check (c, horflag))
+ return 0;
+
+ c = NILP (c->next) ? 0 : XWINDOW (c->next);
+ }
+
+ return 1;
+ }
+ else
+ /* The sum of the heights of the child windows of W must equal
+ W's height. */
+ {
+ int sum_of_pixels = 0, sum_of_totals = 0;
+
+ while (c)
+ {
+ if (!window_resize_check (c, horflag))
+ return 0;
+
+ sum_of_pixels = sum_of_pixels + XINT (c->new_pixel);
+/** sum_of_totals = sum_of_totals + XINT (c->new_total); **/
+ c = NILP (c->next) ? 0 : XWINDOW (c->next);
+ }
+
+ return (sum_of_pixels == XINT (w->new_pixel)
+/** && sum_of_totals == XINT (w->new_total) **/
+ );
+ }
+ }
+ else if (WINDOW_HORIZONTAL_COMBINATION_P (w))
+ /* W is a horizontal combination. */
+ {
+ c = XWINDOW (w->contents);
+ if (horflag)
+ /* The sum of the widths of the child windows of W must equal W's
+ width. */
+ {
+ int sum_of_pixels = 0, sum_of_totals = 0;
+
+ while (c)
+ {
+ if (!window_resize_check (c, horflag))
+ return 0;
+
+ sum_of_pixels = sum_of_pixels + XINT (c->new_pixel);
+ sum_of_totals = sum_of_totals + XINT (c->new_total);
+ c = NILP (c->next) ? 0 : XWINDOW (c->next);
+ }
+
+ return (sum_of_pixels == XINT (w->new_pixel)
+/** && sum_of_totals == XINT (w->new_total) **/
+ );
+ }
+ else
+ /* All child windows of W must have the same height as W. */
+ {
+ while (c)
+ {
+ if (XINT (c->new_pixel) != XINT (w->new_pixel)
+/** || XINT (c->new_total) != XINT (w->new_total) **/
+ || !window_resize_check (c, horflag))
+ return 0;
+
+ c = NILP (c->next) ? 0 : XWINDOW (c->next);
+ }
+
+ return 1;
+ }
+ }
+ else
+ /* A leaf window. Make sure it's not too small. The following
+ hardcodes the values of `window-safe-min-width' (2) and
+ `window-safe-min-height' (1) which are defined in window.el. */
+ return (XINT (w->new_pixel) >= (horflag
+ ? (2 * FRAME_COLUMN_WIDTH (f))
+ : FRAME_LINE_HEIGHT (f))
+/** && XINT (w->new_total) >= (horflag ? 2 : 1) **/
+ );
+}
+
+/* Set w->pixel_height (w->pixel_height if HORIZONTAL is non-zero) to
+ w->new_pixel for window W and recursively all child windows of W.
+ Also calculate and assign the new vertical (horizontal) pixel start
positions of each of these windows.
This function does not perform any error checks. Make sure you have
@@ -3569,25 +3892,30 @@ static void
window_resize_apply (struct window *w, bool horflag)
{
struct window *c;
- int pos;
+ int edge;
+ int unit = (horflag
+ ? FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w))
+ : FRAME_LINE_HEIGHT (WINDOW_XFRAME (w)));
/* Note: Assigning new_normal requires that the new total size of the
parent window has been set *before*. */
if (horflag)
{
- w->total_cols = XFASTINT (w->new_total);
+ w->pixel_width = XFASTINT (w->new_pixel);
+ w->total_cols = w->pixel_width / unit;
if (NUMBERP (w->new_normal))
wset_normal_cols (w, w->new_normal);
- pos = w->left_col;
+ edge = w->pixel_left;
}
else
{
- w->total_lines = XFASTINT (w->new_total);
+ w->pixel_height = XFASTINT (w->new_pixel);
+ w->total_lines = w->pixel_height / unit;
if (NUMBERP (w->new_normal))
wset_normal_lines (w, w->new_normal);
- pos = w->top_line;
+ edge = w->pixel_top;
}
if (WINDOW_VERTICAL_COMBINATION_P (w))
@@ -3597,12 +3925,19 @@ window_resize_apply (struct window *w, bool horflag)
while (c)
{
if (horflag)
- c->left_col = pos;
+ {
+ c->pixel_left = edge;
+ c->left_col = edge / unit;
+ }
else
- c->top_line = pos;
+ {
+ c->pixel_top = edge;
+ c->top_line = edge / unit;
+ }
window_resize_apply (c, horflag);
if (!horflag)
- pos = pos + c->total_lines;
+ edge = edge + c->pixel_height;
+
c = NILP (c->next) ? 0 : XWINDOW (c->next);
}
}
@@ -3613,12 +3948,20 @@ window_resize_apply (struct window *w, bool horflag)
while (c)
{
if (horflag)
- c->left_col = pos;
+ {
+ c->pixel_left = edge;
+ c->left_col = edge / unit;
+ }
else
- c->top_line = pos;
+ {
+ c->pixel_top = edge;
+ c->top_line = edge / unit;
+ }
+
window_resize_apply (c, horflag);
if (horflag)
- pos = pos + c->total_cols;
+ edge = edge + c->pixel_width;
+
c = NILP (c->next) ? 0 : XWINDOW (c->next);
}
}
@@ -3628,6 +3971,67 @@ window_resize_apply (struct window *w, bool horflag)
}
+/* Set w->total_lines (w->total_cols if HORIZONTAL is non-zero) to
+ w->new_total for window W and recursively all child windows of W.
+ Also calculate and assign the new vertical (horizontal) start
+ positions of each of these windows. */
+static void
+window_resize_apply_total (struct window *w, bool horflag)
+{
+ struct window *c;
+ int edge;
+
+ /* Note: Assigning new_normal requires that the new total size of the
+ parent window has been set *before*. */
+ if (horflag)
+ {
+ w->total_cols = XFASTINT (w->new_total);
+ edge = w->left_col;
+ }
+ else
+ {
+ w->total_lines = XFASTINT (w->new_total);
+ edge = w->top_line;
+ }
+
+ if (WINDOW_VERTICAL_COMBINATION_P (w))
+ /* W is a vertical combination. */
+ {
+ c = XWINDOW (w->contents);
+ while (c)
+ {
+ if (horflag)
+ c->left_col = edge;
+ else
+ c->top_line = edge;
+
+ window_resize_apply_total (c, horflag);
+ if (!horflag)
+ edge = edge + c->total_lines;
+
+ c = NILP (c->next) ? 0 : XWINDOW (c->next);
+ }
+ }
+ else if (WINDOW_HORIZONTAL_COMBINATION_P (w))
+ /* W is a horizontal combination. */
+ {
+ c = XWINDOW (w->contents);
+ while (c)
+ {
+ if (horflag)
+ c->left_col = edge;
+ else
+ c->top_line = edge;
+
+ window_resize_apply_total (c, horflag);
+ if (horflag)
+ edge = edge + c->total_cols;
+
+ c = NILP (c->next) ? 0 : XWINDOW (c->next);
+ }
+ }
+}
+
DEFUN ("window-resize-apply", Fwindow_resize_apply, Swindow_resize_apply, 0, 2, 0,
doc: /* Apply requested size values for window-tree of FRAME.
If FRAME is omitted or nil, it defaults to the selected frame.
@@ -3649,8 +4053,8 @@ be applied on the Elisp level. */)
bool horflag = !NILP (horizontal);
if (!window_resize_check (r, horflag)
- || (XINT (r->new_total)
- != (horflag ? r->total_cols : r->total_lines)))
+ || (XINT (r->new_pixel)
+ != (horflag ? r->pixel_width : r->pixel_height)))
return Qnil;
block_input ();
@@ -3662,7 +4066,31 @@ be applied on the Elisp level. */)
adjust_frame_glyphs (f);
unblock_input ();
- run_window_configuration_change_hook (f);
+ return Qt;
+}
+
+
+DEFUN ("window-resize-apply-total", Fwindow_resize_apply_total, Swindow_resize_apply_total, 0, 2, 0,
+ doc: /* Apply requested total size values for window-tree of FRAME.
+If FRAME is omitted or nil, it defaults to the selected frame.
+
+This function does not assign pixel or normal size values. You should
+have run `window-resize-apply' before running this.
+
+Optional argument HORIZONTAL omitted or nil means apply requested
+height values. HORIZONTAL non-nil means apply requested width
+values. */)
+ (Lisp_Object frame, Lisp_Object horizontal)
+{
+ struct frame *f = decode_live_frame (frame);
+ struct window *r = XWINDOW (FRAME_ROOT_WINDOW (f));
+
+ block_input ();
+ /* Necessary when deleting the top-/or leftmost window. */
+ r->left_col = 0;
+ r->top_line = FRAME_TOP_MARGIN (f);
+ window_resize_apply_total (r, !NILP (horizontal));
+ unblock_input ();
return Qt;
}
@@ -3670,59 +4098,107 @@ be applied on the Elisp level. */)
/* Resize frame F's windows when number of lines of F is set to SIZE.
HORFLAG 1 means resize windows when number of columns of F is set to
- SIZE.
+ SIZE. PIXELWISE 1 means to interpret SIZE as pixels.
This function can delete all windows but the selected one in order to
satisfy the request. The result will be meaningful if and only if
F's windows have meaningful sizes when you call this. */
void
-resize_frame_windows (struct frame *f, int size, bool horflag)
+resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
{
Lisp_Object root = f->root_window;
struct window *r = XWINDOW (root);
Lisp_Object mini = f->minibuffer_window;
struct window *m;
+ /* old_size is the old size of the frame's root window. */
+ int old_size = horflag ? r->total_cols : r->total_lines;
+ int old_pixel_size = horflag ? r->pixel_width : r->pixel_height;
/* new_size is the new size of the frame's root window. */
- int new_size = (horflag
- ? size
- : (size
- - FRAME_TOP_MARGIN (f)
- - ((FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
- ? 1 : 0)));
+ int new_size, new_pixel_size;
+
+ if (pixelwise)
+ {
+ new_pixel_size
+ = (horflag
+ ? size
+ : (size
+ - FRAME_TOP_MARGIN_HEIGHT (f)
+ - ((FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
+ ? FRAME_LINE_HEIGHT (f) : 0)));
+ new_size = new_pixel_size / (horflag
+ ? FRAME_COLUMN_WIDTH (f)
+ : FRAME_LINE_HEIGHT (f));
+ }
+ else
+ {
+ new_size= (horflag
+ ? size
+ : (size
+ - FRAME_TOP_MARGIN (f)
+ - ((FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
+ ? 1 : 0)));
+ new_pixel_size = new_size * (horflag
+ ? FRAME_COLUMN_WIDTH (f)
+ : FRAME_LINE_HEIGHT (f));
+ }
r->top_line = FRAME_TOP_MARGIN (f);
- if (WINDOW_LEAF_P (r))
+ r->pixel_top = FRAME_TOP_MARGIN_HEIGHT (f);
+
+ if (new_pixel_size == old_pixel_size)
+ return;
+ else if (WINDOW_LEAF_P (r))
/* For a leaf root window just set the size. */
if (horflag)
- r->total_cols = new_size;
+ {
+ r->total_cols = new_size;
+ r->pixel_width = new_pixel_size;
+ }
else
- r->total_lines = new_size;
+ {
+ r->total_lines = new_size;
+ r->pixel_height = new_pixel_size;
+ }
else
{
- /* old_size is the old size of the frame's root window. */
- int old_size = horflag ? r->total_cols : r->total_lines;
Lisp_Object delta;
- XSETINT (delta, new_size - old_size);
+ if (pixelwise)
+ XSETINT (delta, new_pixel_size - old_pixel_size);
+ else
+ XSETINT (delta, new_size - old_size);
+
/* Try a "normal" resize first. */
- resize_root_window (root, delta, horflag ? Qt : Qnil, Qnil);
+ resize_root_window (root, delta, horflag ? Qt : Qnil, Qnil,
+ pixelwise ? Qt : Qnil);
if (window_resize_check (r, horflag)
- && new_size == XINT (r->new_total))
- window_resize_apply (r, horflag);
+ && new_pixel_size == XINT (r->new_pixel))
+ {
+ window_resize_apply (r, horflag);
+ window_pixel_to_total (r->frame, horflag ? Qt : Qnil);
+ }
else
{
/* Try with "reasonable" minimum sizes next. */
- resize_root_window (root, delta, horflag ? Qt : Qnil, Qt);
+ resize_root_window (root, delta, horflag ? Qt : Qnil, Qt,
+ pixelwise ? Qt : Qnil);
if (window_resize_check (r, horflag)
- && new_size == XINT (r->new_total))
- window_resize_apply (r, horflag);
+ && new_pixel_size == XINT (r->new_pixel))
+ {
+ window_resize_apply (r, horflag);
+ window_pixel_to_total (r->frame, horflag ? Qt : Qnil);
+ }
else
{
/* Finally, try with "safe" minimum sizes. */
- resize_root_window (root, delta, horflag ? Qt : Qnil, Qsafe);
+ resize_root_window (root, delta, horflag ? Qt : Qnil, Qsafe,
+ pixelwise ? Qt : Qnil);
if (window_resize_check (r, horflag)
- && new_size == XINT (r->new_total))
- window_resize_apply (r, horflag);
+ && new_pixel_size == XINT (r->new_pixel))
+ {
+ window_resize_apply (r, horflag);
+ window_pixel_to_total (r->frame, horflag ? Qt : Qnil);
+ }
else
{
/* We lost. Delete all windows but the frame's
@@ -3730,9 +4206,15 @@ resize_frame_windows (struct frame *f, int size, bool horflag)
root = f->selected_window;
Fdelete_other_windows_internal (root, Qnil);
if (horflag)
- XWINDOW (root)->total_cols = new_size;
+ {
+ XWINDOW (root)->total_cols = new_size;
+ XWINDOW (root)->pixel_width = new_pixel_size;
+ }
else
- XWINDOW (root)->total_lines = new_size;
+ {
+ XWINDOW (root)->total_lines = new_size;
+ XWINDOW (root)->pixel_height = new_pixel_size;
+ }
}
}
}
@@ -3742,12 +4224,17 @@ resize_frame_windows (struct frame *f, int size, bool horflag)
{
m = XWINDOW (mini);
if (horflag)
- m->total_cols = size;
+ {
+ m->total_cols = size;
+ m->pixel_width = new_pixel_size;
+ }
else
{
/* Are we sure we always want 1 line here? */
m->total_lines = 1;
+ m->pixel_height = FRAME_LINE_HEIGHT (f);
m->top_line = r->top_line + r->total_lines;
+ m->pixel_top = r->pixel_top + r->pixel_height;
}
}
@@ -3757,27 +4244,27 @@ resize_frame_windows (struct frame *f, int size, bool horflag)
DEFUN ("split-window-internal", Fsplit_window_internal, Ssplit_window_internal, 4, 4, 0,
doc: /* Split window OLD.
-Second argument TOTAL-SIZE specifies the number of lines or columns of the
+Second argument PIXEL-SIZE specifies the number of pixels of the
new window. In any case TOTAL-SIZE must be a positive integer.
Third argument SIDE nil (or `below') specifies that the new window shall
be located below WINDOW. SIDE `above' means the new window shall be
-located above WINDOW. In both cases TOTAL-SIZE specifies the number of
-lines of the new window including space reserved for the mode and/or
+located above WINDOW. In both cases PIXEL-SIZE specifies the pixel
+height of the new window including space reserved for the mode and/or
header line.
SIDE t (or `right') specifies that the new window shall be located on
the right side of WINDOW. SIDE `left' means the new window shall be
-located on the left of WINDOW. In both cases TOTAL-SIZE specifies the
-number of columns of the new window including space reserved for fringes
-and the scrollbar or a divider column.
+located on the left of WINDOW. In both cases PIXEL-SIZE specifies the
+width of the new window including space reserved for fringes and the
+scrollbar or a divider column.
Fourth argument NORMAL-SIZE specifies the normal size of the new window
according to the SIDE argument.
-The new total and normal sizes of all involved windows must have been
+The new pixel and normal sizes of all involved windows must have been
set correctly. See the code of `split-window' for how this is done. */)
- (Lisp_Object old, Lisp_Object total_size, Lisp_Object side, Lisp_Object normal_size)
+ (Lisp_Object old, Lisp_Object pixel_size, Lisp_Object side, Lisp_Object normal_size)
{
/* OLD (*o) is the window we have to split. (*p) is either OLD's
parent window or an internal window we have to install as OLD's new
@@ -3786,19 +4273,24 @@ set correctly. See the code of `split-window' for how this is done. */)
NEW (*n) is the new window created with some parameters taken from
REFERENCE (*r). */
register Lisp_Object new, frame, reference;
- register struct window *o, *p, *n, *r;
+ register struct window *o, *p, *n, *r, *c;
struct frame *f;
bool horflag
/* HORFLAG is 1 when we split side-by-side, 0 otherwise. */
= EQ (side, Qt) || EQ (side, Qleft) || EQ (side, Qright);
- int combination_limit = 0;
+ int combination_limit = 0, sum = 0;
+ int total_size;
CHECK_WINDOW (old);
o = XWINDOW (old);
frame = WINDOW_FRAME (o);
f = XFRAME (frame);
- CHECK_NUMBER (total_size);
+ CHECK_NUMBER (pixel_size);
+ total_size
+ = XINT (pixel_size) / (horflag
+ ? FRAME_COLUMN_WIDTH (f)
+ : FRAME_LINE_HEIGHT (f));
/* Set combination_limit to 1 if we have to make a new parent window.
We do that if either `window-combination-limit' is t, or OLD has no
@@ -3822,7 +4314,7 @@ set correctly. See the code of `split-window' for how this is done. */)
/* The following bugs are caught by `split-window'. */
if (MINI_WINDOW_P (o))
error ("Attempt to split minibuffer window");
- else if (XINT (total_size) < (horflag ? 2 : 1))
+ else if (total_size < (horflag ? 2 : 1))
error ("Size of new window too small (after split)");
else if (!combination_limit && !NILP (Vwindow_combination_resize))
/* `window-combination-resize' non-nil means try to resize OLD's siblings
@@ -3830,22 +4322,21 @@ set correctly. See the code of `split-window' for how this is done. */)
{
p = XWINDOW (o->parent);
/* Temporarily pretend we split the parent window. */
- wset_new_total
- (p, make_number ((horflag ? p->total_cols : p->total_lines)
- - XINT (total_size)));
+ wset_new_pixel
+ (p, make_number ((horflag ? p->pixel_width : p->pixel_height)
+ - XINT (pixel_size)));
if (!window_resize_check (p, horflag))
error ("Window sizes don't fit");
else
/* Undo the temporary pretension. */
- wset_new_total (p, make_number
- (horflag ? p->total_cols : p->total_lines));
+ wset_new_pixel (p, make_number (horflag ? p->pixel_width : p->pixel_height));
}
else
{
if (!window_resize_check (o, horflag))
error ("Resizing old window failed");
- else if (XINT (total_size) + XINT (o->new_total)
- != (horflag ? o->total_cols : o->total_lines))
+ else if (XINT (pixel_size) + XINT (o->new_pixel)
+ != (horflag ? o->pixel_width : o->pixel_height))
error ("Sum of sizes of old and new window don't fit");
}
@@ -3865,8 +4356,10 @@ set correctly. See the code of `split-window' for how this is done. */)
that its children get merged into another window. */
wset_combination_limit (p, Qt);
/* These get applied below. */
- wset_new_total (p, make_number
- (horflag ? o->total_cols : o->total_lines));
+ wset_new_pixel
+ (p, make_number (horflag ? o->pixel_width : o->pixel_height));
+ wset_new_total
+ (p, make_number (horflag ? o->total_cols : o->total_lines));
wset_new_normal (p, new_normal);
}
else
@@ -3913,18 +4406,33 @@ set correctly. See the code of `split-window' for how this is done. */)
/* Directly assign orthogonal coordinates and sizes. */
if (horflag)
{
+ n->pixel_top = o->pixel_top;
n->top_line = o->top_line;
+ n->pixel_height = o->pixel_height;
n->total_lines = o->total_lines;
}
else
{
+ n->pixel_left = o->pixel_left;
n->left_col = o->left_col;
+ n->pixel_width = o->pixel_width;
n->total_cols = o->total_cols;
}
/* Iso-coordinates and sizes are assigned by window_resize_apply,
get them ready here. */
- wset_new_total (n, total_size);
+ wset_new_pixel (n, pixel_size);
+ c = XWINDOW (p->contents);
+ while (c)
+ {
+ if (c != n)
+ sum = sum + XINT (c->new_total);
+ c = NILP (c->next) ? 0 : XWINDOW (c->next);
+ }
+ wset_new_total (n, make_number ((horflag
+ ? p->total_cols
+ : p->total_lines)
+ - sum));
wset_new_normal (n, normal_size);
block_input ();
@@ -4003,15 +4511,14 @@ Signal an error when WINDOW is the only window on its frame. */)
}
if (window_resize_check (r, horflag)
- && (XINT (r->new_total)
- == (horflag ? r->total_cols : r->total_lines)))
+ && (XINT (r->new_pixel)
+ == (horflag ? r->pixel_width : r->pixel_height)))
/* We can delete WINDOW now. */
{
/* Block input. */
block_input ();
window_resize_apply (p, horflag);
-
/* If this window is referred to by the dpyinfo's mouse
highlight, invalidate that slot to be safe (Bug#9904). */
if (!FRAME_INITIAL_P (f))
@@ -4122,55 +4629,74 @@ Signal an error when WINDOW is the only window on its frame. */)
/* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we
can. */
void
-grow_mini_window (struct window *w, int delta)
+grow_mini_window (struct window *w, int delta, bool pixelwise)
{
struct frame *f = XFRAME (w->frame);
struct window *r;
- Lisp_Object root, value;
+ Lisp_Object root, height;
+ int line_height, pixel_height;
eassert (MINI_WINDOW_P (w));
eassert (delta >= 0);
- root = FRAME_ROOT_WINDOW (f);
- r = XWINDOW (root);
- value = call2 (Qwindow_resize_root_window_vertically,
- root, make_number (- delta));
- if (INTEGERP (value) && window_resize_check (r, 0))
+ if (delta > 0)
{
- block_input ();
- window_resize_apply (r, 0);
+ root = FRAME_ROOT_WINDOW (f);
+ r = XWINDOW (root);
+ height = call3 (Qwindow_resize_root_window_vertically,
+ root, make_number (- delta), pixelwise ? Qt : Qnil);
+ if (INTEGERP (height) && window_resize_check (r, 0))
+ {
+ block_input ();
+ window_resize_apply (r, 0);
- /* Grow the mini-window. */
- w->top_line = r->top_line + r->total_lines;
- w->total_lines -= XINT (value);
- /* Enforce full redisplay of the frame. */
- /* FIXME: Shouldn't window--resize-root-window-vertically do it? */
- fset_redisplay (f);
- adjust_frame_glyphs (f);
- unblock_input ();
+ if (pixelwise)
+ {
+ pixel_height = -XINT (height);
+ line_height = pixel_height / FRAME_LINE_HEIGHT (f);
+ }
+ else
+ {
+ line_height = -XINT (height);
+ pixel_height = line_height * FRAME_LINE_HEIGHT (f);
+ }
+
+ /* Grow the mini-window. */
+ w->pixel_top = r->pixel_top + r->pixel_height;
+ w->top_line = r->top_line + r->total_lines;
+ w->pixel_height += pixel_height;
+ w->total_lines += line_height;
+
+ /* Enforce full redisplay of the frame. */
+ /* FIXME: Shouldn't window--resize-root-window-vertically do it? */
+ fset_redisplay (f);
+ adjust_frame_glyphs (f);
+ unblock_input ();
+ }
}
}
-
-/* Shrink mini-window W. */
+/* Shrink mini-window W to one line. */
void
-shrink_mini_window (struct window *w)
+shrink_mini_window (struct window *w, bool pixelwise)
{
struct frame *f = XFRAME (w->frame);
struct window *r;
- Lisp_Object root, value;
- EMACS_INT size;
+ Lisp_Object root, delta;
+ EMACS_INT height, unit;
eassert (MINI_WINDOW_P (w));
- size = w->total_lines;
- if (size > 1)
+ height = pixelwise ? w->pixel_height : w->total_lines;
+ unit = pixelwise ? FRAME_LINE_HEIGHT (f) : 1;
+ if (height > unit)
{
root = FRAME_ROOT_WINDOW (f);
r = XWINDOW (root);
- value = call2 (Qwindow_resize_root_window_vertically,
- root, make_number (size - 1));
- if (INTEGERP (value) && window_resize_check (r, 0))
+ delta = call3 (Qwindow_resize_root_window_vertically,
+ root, make_number (height - unit),
+ pixelwise ? Qt : Qnil);
+ if (INTEGERP (delta) && window_resize_check (r, 0))
{
block_input ();
window_resize_apply (r, 0);
@@ -4178,6 +4704,8 @@ shrink_mini_window (struct window *w)
/* Shrink the mini-window. */
w->top_line = r->top_line + r->total_lines;
w->total_lines = 1;
+ w->pixel_top = r->pixel_top + r->pixel_height;
+ w->pixel_height = FRAME_LINE_HEIGHT (f);
/* Enforce full redisplay of the frame. */
/* FIXME: Shouldn't window--resize-root-window-vertically do it? */
fset_redisplay (f);
@@ -4209,26 +4737,27 @@ DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal, Sresize_mini
error ("Cannot resize a minibuffer-only frame");
r = XWINDOW (FRAME_ROOT_WINDOW (f));
- height = r->total_lines + w->total_lines;
+ height = r->pixel_height + w->pixel_height;
if (window_resize_check (r, 0)
- && XINT (w->new_total) > 0
- && height == XINT (r->new_total) + XINT (w->new_total))
+ && XINT (w->new_pixel) > 0
+ && height == XINT (r->new_pixel) + XINT (w->new_pixel))
{
block_input ();
window_resize_apply (r, 0);
w->total_lines = XFASTINT (w->new_total);
w->top_line = r->top_line + r->total_lines;
+ w->pixel_height = XFASTINT (w->new_pixel);
+ w->pixel_top = r->pixel_top + r->pixel_height;
windows_or_buffers_changed = 36;
FRAME_WINDOW_SIZES_CHANGED (f) = 1;
adjust_frame_glyphs (f);
unblock_input ();
-
- run_window_configuration_change_hook (f);
return Qt;
}
- else error ("Failed to resize minibuffer window");
+ else
+ error ("Failed to resize minibuffer window");
}
/* Mark window cursors off for all windows in the window tree rooted
@@ -4990,7 +5519,7 @@ by this function. This happens in an interactive call. */)
{
struct window *w = XWINDOW (selected_window);
EMACS_INT requested_arg = (NILP (arg)
- ? window_body_cols (w) - 2
+ ? window_body_width (w, 0) - 2
: XINT (Fprefix_numeric_value (arg)));
Lisp_Object result = set_window_hscroll (w, w->hscroll + requested_arg);
@@ -5013,7 +5542,7 @@ by this function. This happens in an interactive call. */)
{
struct window *w = XWINDOW (selected_window);
EMACS_INT requested_arg = (NILP (arg)
- ? window_body_cols (w) - 2
+ ? window_body_width (w, 0) - 2
: XINT (Fprefix_numeric_value (arg)));
Lisp_Object result = set_window_hscroll (w, w->hscroll - requested_arg);
@@ -5287,22 +5816,36 @@ and redisplay normally--don't erase and redraw the frame. */)
return Qnil;
}
-DEFUN ("window-text-height", Fwindow_text_height, Swindow_text_height,
+DEFUN ("window-text-width", Fwindow_text_width, Swindow_text_width,
0, 1, 0,
- doc: /* Return the height in lines of the text display area of WINDOW.
+ doc: /* Return the width in columns of the text display area of WINDOW.
WINDOW must be a live window and defaults to the selected one.
-The returned height does not include the mode line, any header line,
-nor any partial-height lines at the bottom of the text area. */)
+The returned width does not include dividers, scrollbars, margins,
+fringes, nor any partial-width columns at the right of the text
+area. */)
(Lisp_Object window)
{
struct window *w = decode_live_window (window);
- int pixel_height = window_box_height (w);
- int line_height = pixel_height / FRAME_LINE_HEIGHT (XFRAME (w->frame));
- return make_number (line_height);
+
+ return make_number (window_box_width (w, TEXT_AREA)
+ / FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w)));
}
+DEFUN ("window-text-height", Fwindow_text_height, Swindow_text_height,
+ 0, 1, 0,
+ doc: /* Return the height in lines of the text display area of WINDOW.
+WINDOW must be a live window and defaults to the selected one.
+The returned height does not include dividers, the mode line, any header
+line, nor any partial-height lines at the bottom of the text area. */)
+ (Lisp_Object window)
+{
+ struct window *w = decode_live_window (window);
+
+ return make_number (window_box_height (w)
+ / FRAME_LINE_HEIGHT (WINDOW_XFRAME (w)));
+}
DEFUN ("move-to-window-line", Fmove_to_window_line, Smove_to_window_line,
1, 1, "P",
@@ -5395,9 +5938,15 @@ struct save_window_data
/* All fields above are traced by the GC.
From `frame-cols' down, the fields are ignored by the GC. */
-
- int frame_cols, frame_lines, frame_menu_bar_lines;
- int frame_tool_bar_lines;
+ /* We should be able to do without the following two. */
+ int frame_cols, frame_lines;
+ /* These two should get eventually replaced by their pixelized
+ counterparts. */
+ int frame_menu_bar_lines, frame_tool_bar_lines;
+ int frame_text_width, frame_text_height;
+ /* These are currently unused. We need them as soon as we pixelize
+ them. */
+ int frame_menu_bar_height, frame_tool_bar_height;
};
/* This is saved as a Lisp_Vector */
@@ -5406,6 +5955,7 @@ struct saved_window
struct vectorlike_header header;
Lisp_Object window, buffer, start, pointm, mark;
+ Lisp_Object pixel_left, pixel_top, pixel_height, pixel_width;
Lisp_Object left_col, top_line, total_cols, total_lines;
Lisp_Object normal_cols, normal_lines;
Lisp_Object hscroll, min_hscroll;
@@ -5526,6 +6076,10 @@ the return value is nil. Otherwise the value is t. */)
made, we change the frame to the size specified in the
configuration, restore the configuration, and then resize it
back. We keep track of the prevailing height in these variables. */
+ int previous_frame_text_height = FRAME_TEXT_HEIGHT (f);
+ int previous_frame_text_width = FRAME_TEXT_WIDTH (f);
+ int previous_frame_menu_bar_height = FRAME_MENU_BAR_HEIGHT (f);
+ int previous_frame_tool_bar_height = FRAME_TOOL_BAR_HEIGHT (f);
int previous_frame_lines = FRAME_LINES (f);
int previous_frame_cols = FRAME_COLS (f);
int previous_frame_menu_bar_lines = FRAME_MENU_BAR_LINES (f);
@@ -5550,12 +6104,12 @@ the return value is nil. Otherwise the value is t. */)
if it runs during this. */
block_input ();
- if (data->frame_lines != previous_frame_lines
- || data->frame_cols != previous_frame_cols)
- change_frame_size (f, data->frame_lines,
- data->frame_cols, 0, 0, 0);
- if (data->frame_menu_bar_lines
- != previous_frame_menu_bar_lines)
+ if (data->frame_text_width != previous_frame_text_width
+ || data->frame_text_height != previous_frame_text_height)
+ change_frame_size (f, data->frame_text_width,
+ data->frame_text_height, 0, 0, 0, 1);
+
+ if (data->frame_menu_bar_lines != previous_frame_menu_bar_lines)
{
#ifdef HAVE_WINDOW_SYSTEM
if (FRAME_WINDOW_P (f))
@@ -5567,8 +6121,7 @@ the return value is nil. Otherwise the value is t. */)
make_number (0));
}
#ifdef HAVE_WINDOW_SYSTEM
- if (data->frame_tool_bar_lines
- != previous_frame_tool_bar_lines)
+ if (data->frame_tool_bar_lines != previous_frame_tool_bar_lines)
x_set_tool_bar_lines (f, make_number (data->frame_tool_bar_lines),
make_number (0));
#endif
@@ -5640,6 +6193,10 @@ the return value is nil. Otherwise the value is t. */)
/* If we squirreled away the buffer, restore it now. */
if (BUFFERP (w->combination_limit))
wset_buffer (w, w->combination_limit);
+ w->pixel_left = XFASTINT (p->pixel_left);
+ w->pixel_top = XFASTINT (p->pixel_top);
+ w->pixel_width = XFASTINT (p->pixel_width);
+ w->pixel_height = XFASTINT (p->pixel_height);
w->left_col = XFASTINT (p->left_col);
w->top_line = XFASTINT (p->top_line);
w->total_cols = XFASTINT (p->total_cols);
@@ -5745,11 +6302,12 @@ the return value is nil. Otherwise the value is t. */)
&& FRAME_LIVE_P (XFRAME (data->focus_frame))))
Fredirect_frame_focus (frame, data->focus_frame);
- /* Set the screen height to the value it had before this function. */
- if (previous_frame_lines != FRAME_LINES (f)
- || previous_frame_cols != FRAME_COLS (f))
- change_frame_size (f, previous_frame_lines, previous_frame_cols,
- 0, 0, 0);
+ /* Set the frame size to the value it had before this function. */
+ if (previous_frame_text_width != FRAME_TEXT_WIDTH (f)
+ || previous_frame_text_height != FRAME_TEXT_HEIGHT (f))
+ change_frame_size (f, previous_frame_text_width,
+ previous_frame_text_height, 0, 0, 0, 1);
+
if (previous_frame_menu_bar_lines != FRAME_MENU_BAR_LINES (f))
{
#ifdef HAVE_WINDOW_SYSTEM
@@ -5954,6 +6512,10 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
wset_temslot (w, make_number (i)); i++;
p->window = window;
p->buffer = (WINDOW_LEAF_P (w) ? w->contents : Qnil);
+ p->pixel_left = make_number (w->pixel_left);
+ p->pixel_top = make_number (w->pixel_top);
+ p->pixel_width = make_number (w->pixel_width);
+ p->pixel_height = make_number (w->pixel_height);
p->left_col = make_number (w->left_col);
p->top_line = make_number (w->top_line);
p->total_cols = make_number (w->total_cols);
@@ -6093,6 +6655,10 @@ saved by this function. */)
data->frame_lines = FRAME_LINES (f);
data->frame_menu_bar_lines = FRAME_MENU_BAR_LINES (f);
data->frame_tool_bar_lines = FRAME_TOOL_BAR_LINES (f);
+ data->frame_text_width = FRAME_TEXT_WIDTH (f);
+ data->frame_text_height = FRAME_TEXT_HEIGHT (f);
+ data->frame_menu_bar_height = FRAME_MENU_BAR_HEIGHT (f);
+ data->frame_tool_bar_height = FRAME_TOOL_BAR_HEIGHT (f);
data->selected_frame = selected_frame;
data->current_window = FRAME_SELECTED_WINDOW (f);
XSETBUFFER (data->current_buffer, current_buffer);
@@ -6179,8 +6745,10 @@ as nil. */)
(Lisp_Object window)
{
struct window *w = decode_live_window (window);
- return Fcons (w->left_margin_cols ? make_number (w->left_margin_cols) : Qnil,
- w->right_margin_cols ? make_number (w->right_margin_cols) : Qnil);
+ return Fcons (w->left_margin_cols
+ ? make_number (w->left_margin_cols) : Qnil,
+ w->right_margin_cols
+ ? make_number (w->right_margin_cols) : Qnil);
}
@@ -6290,15 +6858,14 @@ DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars,
doc: /* Set width and type of scroll bars of window WINDOW.
WINDOW must be a live window and defaults to the selected one.
-Second parameter WIDTH specifies the pixel width for the scroll bar;
-this is automatically adjusted to a multiple of the frame column width.
+Second parameter WIDTH specifies the pixel width for the scroll bar.
Third parameter VERTICAL-TYPE specifies the type of the vertical scroll
bar: left, right, or nil.
If WIDTH is nil, use the frame's scroll-bar width.
If VERTICAL-TYPE is t, use the frame's scroll-bar type.
Fourth parameter HORIZONTAL-TYPE is currently unused.
-Return t if scroll bars was actually changed and nil otherwise. */)
+Return t if scroll bars were actually changed and nil otherwise. */)
(Lisp_Object window, Lisp_Object width,
Lisp_Object vertical_type, Lisp_Object horizontal_type)
{
@@ -6493,6 +7060,10 @@ compare_window_configurations (Lisp_Object configuration1,
!= EQ (d2->current_window, sw2->window)
/* Windows' buffers must match. */
|| !EQ (sw1->buffer, sw2->buffer)
+ || !EQ (sw1->pixel_left, sw2->pixel_left)
+ || !EQ (sw1->pixel_top, sw2->pixel_top)
+ || !EQ (sw1->pixel_height, sw2->pixel_height)
+ || !EQ (sw1->pixel_width, sw2->pixel_width)
|| !EQ (sw1->left_col, sw2->left_col)
|| !EQ (sw1->top_line, sw2->top_line)
|| !EQ (sw1->total_cols, sw2->total_cols)
@@ -6571,6 +7142,7 @@ syms_of_window (void)
DEFSYM (Qdelete_window, "delete-window");
DEFSYM (Qwindow_resize_root_window, "window--resize-root-window");
DEFSYM (Qwindow_resize_root_window_vertically, "window--resize-root-window-vertically");
+ DEFSYM (Qwindow_pixel_to_total, "window--pixel-to-total");
DEFSYM (Qsafe, "safe");
DEFSYM (Qdisplay_buffer, "display-buffer");
DEFSYM (Qreplace_buffer_in_windows, "replace-buffer-in-windows");
@@ -6729,6 +7301,18 @@ Parameters not saved by `current-window-configuration' or
respectively are not installed by `window-state-put'. */);
Vwindow_persistent_parameters = list1 (Fcons (Qclone_of, Qt));
+ DEFVAR_BOOL ("window-resize-pixelwise", window_resize_pixelwise,
+ doc: /* Non-nil means resizing windows works pixelwise.
+Functions currently affected by this option are `split-window',
+`maximize-window', `minimize-window', `fit-window-to-buffer' and
+`fit-frame-to-buffer' and all functions symmetrically resizing a
+parent window.
+
+Note that when a frame's pixel size is not a multiple of the
+frame's character size, at least one window may get resized
+pixelwise even if this option is nil. */);
+ window_resize_pixelwise = 0;
+
defsubr (&Sselected_window);
defsubr (&Sminibuffer_window);
defsubr (&Swindow_minibuffer_p);
@@ -6751,16 +7335,23 @@ respectively are not installed by `window-state-put'. */);
defsubr (&Swindow_combination_limit);
defsubr (&Sset_window_combination_limit);
defsubr (&Swindow_use_time);
- defsubr (&Swindow_top_line);
- defsubr (&Swindow_left_column);
- defsubr (&Swindow_total_height);
+ defsubr (&Swindow_pixel_width);
+ defsubr (&Swindow_pixel_height);
defsubr (&Swindow_total_width);
+ defsubr (&Swindow_total_height);
defsubr (&Swindow_normal_size);
+ defsubr (&Swindow_new_pixel);
defsubr (&Swindow_new_total);
defsubr (&Swindow_new_normal);
+ defsubr (&Swindow_pixel_left);
+ defsubr (&Swindow_pixel_top);
+ defsubr (&Swindow_left_column);
+ defsubr (&Swindow_top_line);
+ defsubr (&Sset_window_new_pixel);
defsubr (&Sset_window_new_total);
defsubr (&Sset_window_new_normal);
defsubr (&Swindow_resize_apply);
+ defsubr (&Swindow_resize_apply_total);
defsubr (&Swindow_body_height);
defsubr (&Swindow_body_width);
defsubr (&Swindow_hscroll);
@@ -6770,6 +7361,10 @@ respectively are not installed by `window-state-put'. */);
defsubr (&Swindow_edges);
defsubr (&Swindow_pixel_edges);
defsubr (&Swindow_absolute_pixel_edges);
+ defsubr (&Swindow_mode_line_height);
+ defsubr (&Swindow_header_line_height);
+ defsubr (&Swindow_right_divider_width);
+ defsubr (&Swindow_bottom_divider_width);
defsubr (&Swindow_inside_edges);
defsubr (&Swindow_inside_pixel_edges);
defsubr (&Swindow_inside_absolute_pixel_edges);
@@ -6792,6 +7387,7 @@ respectively are not installed by `window-state-put'. */);
defsubr (&Sresize_mini_window_internal);
defsubr (&Sset_window_buffer);
defsubr (&Srun_window_configuration_change_hook);
+ defsubr (&Srun_window_scroll_functions);
defsubr (&Sselect_window);
defsubr (&Sforce_window_update);
defsubr (&Ssplit_window_internal);
@@ -6803,6 +7399,7 @@ respectively are not installed by `window-state-put'. */);
defsubr (&Sscroll_other_window);
defsubr (&Sminibuffer_selected_window);
defsubr (&Srecenter);
+ defsubr (&Swindow_text_width);
defsubr (&Swindow_text_height);
defsubr (&Smove_to_window_line);
defsubr (&Swindow_configuration_p);
diff --git a/src/window.h b/src/window.h
index 555c386d7bd..b91161f4d32 100644
--- a/src/window.h
+++ b/src/window.h
@@ -111,6 +111,7 @@ struct window
to something beyond an integer, so C int can't be used here. */
Lisp_Object new_total;
Lisp_Object new_normal;
+ Lisp_Object new_pixel;
/* May be buffer, window, or nil. */
Lisp_Object contents;
@@ -180,14 +181,26 @@ struct window
/* Number saying how recently window was selected. */
int use_time;
+ /* Unique number of window assigned when it was created. */
+ int sequence_number;
+
+ /* The upper left corner pixel coordinates of this window, as
+ integers relative to upper left corner of frame = 0, 0. */
+ int pixel_left;
+ int pixel_top;
+
/* The upper left corner coordinates of this window,
relative to upper left corner of frame = 0, 0. */
int left_col;
int top_line;
+ /* The pixel size of the window. */
+ int pixel_width;
+ int pixel_height;
+
/* The size of the window. */
- int total_lines;
int total_cols;
+ int total_lines;
/* Number of columns display within the window is scrolled to the left. */
ptrdiff_t hscroll;
@@ -356,31 +369,43 @@ wset_frame (struct window *w, Lisp_Object val)
{
w->frame = val;
}
+
INLINE void
wset_next (struct window *w, Lisp_Object val)
{
w->next = val;
}
+
INLINE void
wset_prev (struct window *w, Lisp_Object val)
{
w->prev = val;
}
+
INLINE void
wset_redisplay_end_trigger (struct window *w, Lisp_Object val)
{
w->redisplay_end_trigger = val;
}
+
+INLINE void
+wset_new_pixel (struct window *w, Lisp_Object val)
+{
+ w->new_pixel = val;
+}
+
INLINE void
wset_vertical_scroll_bar (struct window *w, Lisp_Object val)
{
w->vertical_scroll_bar = val;
}
+
INLINE void
wset_prev_buffers (struct window *w, Lisp_Object val)
{
w->prev_buffers = val;
}
+
INLINE void
wset_next_buffers (struct window *w, Lisp_Object val)
{
@@ -446,38 +471,44 @@ wset_next_buffers (struct window *w, Lisp_Object val)
#define WINDOW_FRAME_LINE_HEIGHT(W) \
(FRAME_LINE_HEIGHT (WINDOW_XFRAME ((W))))
-/* Return the width of window W in canonical column units.
+/* Return the pixel width of window W.
This includes scroll bars and fringes. */
+#define WINDOW_PIXEL_WIDTH(W) (W)->pixel_width
+/* Return the pixel height of window W.
+ This includes header and mode lines, if any. */
+#define WINDOW_PIXEL_HEIGHT(W) (W)->pixel_height
+
+/* Return the width of window W in canonical column units.
+ This includes scroll bars and fringes.
+ This value is adjusted such that the sum of the widths of all child
+ windows equals the width of their parent window. */
#define WINDOW_TOTAL_COLS(W) (W)->total_cols
/* Return the height of window W in canonical line units.
- This includes header and mode lines, if any. */
-
+ This includes header and mode lines, if any.
+ This value is adjusted such that the sum of the heights of all child
+ windows equals the height of their parent window. */
#define WINDOW_TOTAL_LINES(W) (W)->total_lines
-/* Return the total pixel width of window W. */
-
-#define WINDOW_TOTAL_WIDTH(W) \
- (WINDOW_TOTAL_COLS (W) * WINDOW_FRAME_COLUMN_WIDTH (W))
-
-/* Return the total pixel height of window W. */
-
-#define WINDOW_TOTAL_HEIGHT(W) \
- (WINDOW_TOTAL_LINES (W) * WINDOW_FRAME_LINE_HEIGHT (W))
-
-/* For HORFLAG non-zero the total number of columns of window W. Otherwise
- the total number of lines of W. */
-
-#define WINDOW_TOTAL_SIZE(w, horflag) \
- (horflag ? WINDOW_TOTAL_COLS (w) : WINDOW_TOTAL_LINES (w))
-
/* The smallest acceptable dimensions for a window. Anything smaller
might crash Emacs. */
+#define MIN_SAFE_WINDOW_WIDTH (2)
+
+#define MIN_SAFE_WINDOW_PIXEL_WIDTH(W) \
+ (2 * WINDOW_FRAME_COLUMN_WIDTH (W))
-#define MIN_SAFE_WINDOW_WIDTH (2)
#define MIN_SAFE_WINDOW_HEIGHT (1)
+#define MIN_SAFE_WINDOW_PIXEL_HEIGHT(W) \
+ (WINDOW_FRAME_LINE_HEIGHT (W))
+
+/* Width of right divider of window W. */
+#define WINDOW_RIGHT_DIVIDER_WIDTH(W) \
+ ((WINDOW_RIGHTMOST_P (W) || MINI_WINDOW_P (W)) \
+ ? 0 \
+ : FRAME_RIGHT_DIVIDER_WIDTH (WINDOW_XFRAME (W)))
+
/* Return the canonical frame column at which window W starts.
This includes a left-hand scroll bar, if any. */
@@ -500,20 +531,37 @@ wset_next_buffers (struct window *w, Lisp_Object val)
#define WINDOW_BOTTOM_EDGE_LINE(W) \
(WINDOW_TOP_EDGE_LINE (W) + WINDOW_TOTAL_LINES (W))
+/* Return the left pixel edge at which window W starts.
+ This includes a left-hand scroll bar, if any. */
+#define WINDOW_LEFT_PIXEL_EDGE(W) (W)->pixel_left
+
+/* Return the right pixel edge before which window W ends.
+ This includes a right-hand scroll bar, if any. */
+#define WINDOW_RIGHT_PIXEL_EDGE(W) \
+ (WINDOW_LEFT_PIXEL_EDGE (W) + WINDOW_PIXEL_WIDTH (W))
+
+/* Return the top pixel edge at which window W starts.
+ This includes a header line, if any. */
+#define WINDOW_TOP_PIXEL_EDGE(W) (W)->pixel_top
+
+/* Return the bottom pixel edge before which window W ends.
+ This includes a mode line, if any. */
+#define WINDOW_BOTTOM_PIXEL_EDGE(W) \
+ (WINDOW_TOP_PIXEL_EDGE (W) + WINDOW_PIXEL_HEIGHT (W))
/* Return the frame x-position at which window W starts.
This includes a left-hand scroll bar, if any. */
#define WINDOW_LEFT_EDGE_X(W) \
(FRAME_INTERNAL_BORDER_WIDTH (WINDOW_XFRAME (W)) \
- + WINDOW_LEFT_EDGE_COL (W) * WINDOW_FRAME_COLUMN_WIDTH (W))
+ + WINDOW_LEFT_PIXEL_EDGE (W))
/* Return the frame x- position before which window W ends.
This includes a right-hand scroll bar, if any. */
#define WINDOW_RIGHT_EDGE_X(W) \
(FRAME_INTERNAL_BORDER_WIDTH (WINDOW_XFRAME (W)) \
- + WINDOW_RIGHT_EDGE_COL (W) * WINDOW_FRAME_COLUMN_WIDTH (W))
+ + WINDOW_RIGHT_PIXEL_EDGE (W))
/* 1 if W is a menu bar window. */
@@ -536,37 +584,45 @@ wset_next_buffers (struct window *w, Lisp_Object val)
#endif
/* Return the frame y-position at which window W starts.
- This includes a header line, if any. */
+ This includes a header line, if any.
+ PXW: With a menu or tool bar this is not symmetric to the _X values
+ since it _does_ include the internal border width. */
#define WINDOW_TOP_EDGE_Y(W) \
(((WINDOW_MENU_BAR_P (W) || WINDOW_TOOL_BAR_P (W)) \
? 0 : FRAME_INTERNAL_BORDER_WIDTH (WINDOW_XFRAME (W))) \
- + WINDOW_TOP_EDGE_LINE (W) * WINDOW_FRAME_LINE_HEIGHT (W))
+ + WINDOW_TOP_PIXEL_EDGE (W))
/* Return the frame y-position before which window W ends.
This includes a mode line, if any. */
-
-#define WINDOW_BOTTOM_EDGE_Y(W) \
- (((WINDOW_MENU_BAR_P (W) || WINDOW_TOOL_BAR_P (W)) \
+#define WINDOW_BOTTOM_EDGE_Y(W) \
+ (((WINDOW_MENU_BAR_P (W) || WINDOW_TOOL_BAR_P (W)) \
? 0 : FRAME_INTERNAL_BORDER_WIDTH (WINDOW_XFRAME (W))) \
- + WINDOW_BOTTOM_EDGE_LINE (W) * WINDOW_FRAME_LINE_HEIGHT (W))
-
+ + WINDOW_BOTTOM_PIXEL_EDGE (W))
/* 1 if window W takes up the full width of its frame. */
-
-#define WINDOW_FULL_WIDTH_P(W) \
- (WINDOW_TOTAL_COLS (W) == FRAME_TOTAL_COLS (WINDOW_XFRAME (W)))
+#define WINDOW_FULL_WIDTH_P(W) \
+ (WINDOW_PIXEL_WIDTH (W) \
+ == (WINDOW_PIXEL_WIDTH \
+ (XWINDOW (FRAME_ROOT_WINDOW (WINDOW_XFRAME (W)))))) \
/* 1 if window W's has no other windows to its left in its frame. */
#define WINDOW_LEFTMOST_P(W) \
- (WINDOW_LEFT_EDGE_COL (W) == 0)
+ (WINDOW_LEFT_PIXEL_EDGE (W) == 0)
/* 1 if window W's has no other windows to its right in its frame. */
-
-#define WINDOW_RIGHTMOST_P(W) \
- (WINDOW_RIGHT_EDGE_COL (W) == FRAME_TOTAL_COLS (WINDOW_XFRAME (W)))
-
+#define WINDOW_RIGHTMOST_P(W) \
+ (WINDOW_RIGHT_PIXEL_EDGE (W) \
+ == (WINDOW_RIGHT_PIXEL_EDGE \
+ (XWINDOW (FRAME_ROOT_WINDOW (WINDOW_XFRAME (W)))))) \
+
+/* 1 if window W's has no other windows below it in its frame
+ (the minibuffer window is not counted in this respect). */
+#define WINDOW_BOTTOMMOST_P(W) \
+ (WINDOW_BOTTOM_PIXEL_EDGE (W) \
+ == (WINDOW_BOTTOM_PIXEL_EDGE \
+ (XWINDOW (FRAME_ROOT_WINDOW (WINDOW_XFRAME (W)))))) \
/* Return the frame column at which the text (or left fringe) in
window W starts. This is different from the `LEFT_EDGE' because it
@@ -576,6 +632,13 @@ wset_next_buffers (struct window *w, Lisp_Object val)
(WINDOW_LEFT_EDGE_COL (W) \
+ WINDOW_LEFT_SCROLL_BAR_COLS (W))
+/* Return the pixel value where the text (or left fringe) in
+ window W starts. This is different from the `LEFT_EDGE' because it
+ does not include a left-hand scroll bar if any. */
+#define WINDOW_BOX_LEFT_PIXEL_EDGE(W) \
+ (WINDOW_LEFT_PIXEL_EDGE (W) \
+ + WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (W))
+
/* Return the window column before which the text in window W ends.
This is different from WINDOW_RIGHT_EDGE_COL because it does not
include a scroll bar or window-separating line on the right edge. */
@@ -584,59 +647,72 @@ wset_next_buffers (struct window *w, Lisp_Object val)
(WINDOW_RIGHT_EDGE_COL (W) \
- WINDOW_RIGHT_SCROLL_BAR_COLS (W))
+/* Return the pixel value before which the text in window W ends. This
+ is different from the `RIGHT_EDGE' because it does not include a
+ right-hand scroll bar or window-separating line on the right
+ edge. */
+#define WINDOW_BOX_RIGHT_PIXEL_EDGE(W) \
+ (WINDOW_RIGHT_PIXEL_EDGE (W) \
+ - WINDOW_RIGHT_DIVIDER_WIDTH (W) \
+ - WINDOW_RIGHT_SCROLL_BAR_AREA_WIDTH (W))
/* Return the frame position at which the text (or left fringe) in
window W starts. This is different from the `LEFT_EDGE' because it
does not include a left-hand scroll bar if any. */
-
-#define WINDOW_BOX_LEFT_EDGE_X(W) \
+#define WINDOW_BOX_LEFT_EDGE_X(W) \
(FRAME_INTERNAL_BORDER_WIDTH (WINDOW_XFRAME (W)) \
- + WINDOW_BOX_LEFT_EDGE_COL (W) * WINDOW_FRAME_COLUMN_WIDTH (W))
+ + WINDOW_BOX_LEFT_PIXEL_EDGE (W))
/* Return the window column before which the text in window W ends.
This is different from WINDOW_RIGHT_EDGE_COL because it does not
include a scroll bar or window-separating line on the right edge. */
-
-#define WINDOW_BOX_RIGHT_EDGE_X(W) \
+#define WINDOW_BOX_RIGHT_EDGE_X(W) \
(FRAME_INTERNAL_BORDER_WIDTH (WINDOW_XFRAME (W)) \
- + WINDOW_BOX_RIGHT_EDGE_COL (W) * WINDOW_FRAME_COLUMN_WIDTH (W))
-
-
-/* Width of left margin area in columns. */
+ + WINDOW_BOX_RIGHT_PIXEL_EDGE (W))
+/* Widths of marginal areas in columns. */
#define WINDOW_LEFT_MARGIN_COLS(W) (W->left_margin_cols)
-/* Width of right marginal area in columns. */
-
#define WINDOW_RIGHT_MARGIN_COLS(W) (W->right_margin_cols)
-/* Width of left margin area in pixels. */
+#define WINDOW_MARGINS_COLS(W) \
+ (WINDOW_LEFT_MARGIN_COLS (W) \
+ + WINDOW_RIGHT_MARGIN_COLS (W))
+/* Widths of marginal areas in pixels. */
#define WINDOW_LEFT_MARGIN_WIDTH(W) \
(W->left_margin_cols * WINDOW_FRAME_COLUMN_WIDTH (W))
-/* Width of right marginal area in pixels. */
-
-#define WINDOW_RIGHT_MARGIN_WIDTH(W) \
+#define WINDOW_RIGHT_MARGIN_WIDTH(W) \
(W->right_margin_cols * WINDOW_FRAME_COLUMN_WIDTH (W))
-/* Total width of fringes reserved for drawing truncation bitmaps,
- continuation bitmaps and alike. The width is in canonical char
- units of the frame. This must currently be the case because window
- sizes aren't pixel values. If it weren't the case, we wouldn't be
- able to split windows horizontally nicely. */
+#define WINDOW_MARGINS_WIDTH(W) \
+ (WINDOW_LEFT_MARGIN_WIDTH (W) \
+ + WINDOW_RIGHT_MARGIN_WIDTH (W))
+/* Pixel-widths of fringes. */
+#define WINDOW_LEFT_FRINGE_WIDTH(W) \
+ (W->left_fringe_width >= 0 \
+ ? W->left_fringe_width \
+ : FRAME_LEFT_FRINGE_WIDTH (WINDOW_XFRAME (W)))
+
+#define WINDOW_RIGHT_FRINGE_WIDTH(W) \
+ (W->right_fringe_width >= 0 \
+ ? W->right_fringe_width \
+ : FRAME_RIGHT_FRINGE_WIDTH (WINDOW_XFRAME (W)))
+
+#define WINDOW_FRINGES_WIDTH(W) \
+ (WINDOW_LEFT_FRINGE_WIDTH (W) + WINDOW_RIGHT_FRINGE_WIDTH (W))
+
+/* Widths of fringes in columns. */
#define WINDOW_FRINGE_COLS(W) \
((W->left_fringe_width >= 0 \
&& W->right_fringe_width >= 0) \
- ? ((W->left_fringe_width \
- + W->right_fringe_width \
+ ? ((WINDOW_FRINGES_WIDTH (W) \
+ WINDOW_FRAME_COLUMN_WIDTH (W) - 1) \
/ WINDOW_FRAME_COLUMN_WIDTH (W)) \
: FRAME_FRINGE_COLS (WINDOW_XFRAME (W)))
-/* Column-width of the left and right fringe. */
-
#define WINDOW_LEFT_FRINGE_COLS(W) \
((WINDOW_LEFT_FRINGE_WIDTH ((W)) \
+ WINDOW_FRAME_COLUMN_WIDTH (W) - 1) \
@@ -647,29 +723,12 @@ wset_next_buffers (struct window *w, Lisp_Object val)
+ WINDOW_FRAME_COLUMN_WIDTH (W) - 1) \
/ WINDOW_FRAME_COLUMN_WIDTH (W))
-/* Pixel-width of the left and right fringe. */
-
-#define WINDOW_LEFT_FRINGE_WIDTH(W) \
- (W->left_fringe_width >= 0 ? W->left_fringe_width \
- : FRAME_LEFT_FRINGE_WIDTH (WINDOW_XFRAME (W)))
-
-#define WINDOW_RIGHT_FRINGE_WIDTH(W) \
- (W->right_fringe_width >= 0 ? W->right_fringe_width \
- : FRAME_RIGHT_FRINGE_WIDTH (WINDOW_XFRAME (W)))
-
-/* Total width of fringes in pixels. */
-
-#define WINDOW_TOTAL_FRINGE_WIDTH(W) \
- (WINDOW_LEFT_FRINGE_WIDTH (W) + WINDOW_RIGHT_FRINGE_WIDTH (W))
-
/* Are fringes outside display margins in window W. */
-
#define WINDOW_HAS_FRINGES_OUTSIDE_MARGINS(W) \
((W)->fringes_outside_margins)
/* Say whether scroll bars are currently enabled for window W,
and which side they are on. */
-
#define WINDOW_VERTICAL_SCROLL_BAR_TYPE(w) \
(EQ (w->vertical_scroll_bar_type, Qt) \
? FRAME_VERTICAL_SCROLL_BAR_TYPE (WINDOW_XFRAME (w)) \
@@ -697,15 +756,14 @@ wset_next_buffers (struct window *w, Lisp_Object val)
/* Width that a scroll bar in window W should have, if there is one.
Measured in pixels. If scroll bars are turned off, this is still
nonzero. */
-
#define WINDOW_CONFIG_SCROLL_BAR_WIDTH(w) \
- (w->scroll_bar_width >= 0 ? w->scroll_bar_width \
+ (w->scroll_bar_width >= 0 \
+ ? w->scroll_bar_width \
: FRAME_CONFIG_SCROLL_BAR_WIDTH (WINDOW_XFRAME (w)))
/* Width that a scroll bar in window W should have, if there is one.
Measured in columns (characters). If scroll bars are turned off,
this is still nonzero. */
-
#define WINDOW_CONFIG_SCROLL_BAR_COLS(w) \
(w->scroll_bar_width >= 0 \
? ((w->scroll_bar_width \
@@ -713,65 +771,64 @@ wset_next_buffers (struct window *w, Lisp_Object val)
/ WINDOW_FRAME_COLUMN_WIDTH (w)) \
: FRAME_CONFIG_SCROLL_BAR_COLS (WINDOW_XFRAME (w)))
-/* Width of a scroll bar in window W, measured in columns (characters),
- but only if scroll bars are on the left. If scroll bars are on
- the right in this frame, or there are no scroll bars, value is 0. */
-
+/* Width of left scroll bar in window W, measured in columns
+ (characters). If scroll bars are on the right in this frame, or
+ there are no scroll bars, value is 0. */
#define WINDOW_LEFT_SCROLL_BAR_COLS(w) \
(WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w) \
? (WINDOW_CONFIG_SCROLL_BAR_COLS (w)) \
: 0)
-/* Width of a left scroll bar area in window W , measured in pixels. */
-
-#define WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH(w) \
- (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w) \
- ? (WINDOW_CONFIG_SCROLL_BAR_COLS (w) * WINDOW_FRAME_COLUMN_WIDTH (w)) \
- : 0)
-
-/* Width of a scroll bar in window W, measured in columns (characters),
- but only if scroll bars are on the right. If scroll bars are on
- the left in this frame, or there are no scroll bars, value is 0. */
-
+/* Width of right scroll bar in window W, measured in columns
+ (characters). If scroll bars are on the left in this frame, or there
+ are no scroll bars, value is 0. */
#define WINDOW_RIGHT_SCROLL_BAR_COLS(w) \
(WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w) \
? WINDOW_CONFIG_SCROLL_BAR_COLS (w) \
: 0)
-/* Width of a left scroll bar area in window W , measured in pixels. */
-
-#define WINDOW_RIGHT_SCROLL_BAR_AREA_WIDTH(w) \
- (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w) \
- ? (WINDOW_CONFIG_SCROLL_BAR_COLS (w) * WINDOW_FRAME_COLUMN_WIDTH (w)) \
- : 0)
-
-
-/* Actual width of a scroll bar in window W, measured in columns. */
-
+/* Width of a scroll bar in window W, measured in columns. */
#define WINDOW_SCROLL_BAR_COLS(w) \
(WINDOW_HAS_VERTICAL_SCROLL_BAR (w) \
? WINDOW_CONFIG_SCROLL_BAR_COLS (w) \
: 0)
-/* Width of a left scroll bar area in window W , measured in pixels. */
+/* Width of a left scroll bar area in window W, measured in pixels. */
+#define WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH(w) \
+ (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w) \
+ ? WINDOW_CONFIG_SCROLL_BAR_WIDTH (w) \
+ : 0)
-#define WINDOW_SCROLL_BAR_AREA_WIDTH(w) \
- (WINDOW_HAS_VERTICAL_SCROLL_BAR (w) \
- ? (WINDOW_CONFIG_SCROLL_BAR_COLS (w) * WINDOW_FRAME_COLUMN_WIDTH (w)) \
+/* Width of a right scroll bar area in window W, measured in pixels. */
+#define WINDOW_RIGHT_SCROLL_BAR_AREA_WIDTH(w) \
+ (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w) \
+ ? WINDOW_CONFIG_SCROLL_BAR_WIDTH (w) \
: 0)
+/* Width of scroll bar area in window W, measured in pixels. */
+#define WINDOW_SCROLL_BAR_AREA_WIDTH(w) \
+ (WINDOW_HAS_VERTICAL_SCROLL_BAR (w) \
+ ? WINDOW_CONFIG_SCROLL_BAR_WIDTH (w) \
+ : 0)
/* Return the frame position where the scroll bar of window W starts. */
-
#define WINDOW_SCROLL_BAR_AREA_X(W) \
(WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (W) \
? WINDOW_BOX_RIGHT_EDGE_X (W) \
: WINDOW_LEFT_EDGE_X (W))
+/* Width of bottom divider of window W. */
+#define WINDOW_BOTTOM_DIVIDER_WIDTH(W) \
+ (((WINDOW_BOTTOMMOST_P (W) \
+ && NILP ((XWINDOW (FRAME_ROOT_WINDOW \
+ (WINDOW_XFRAME (W))))->next)) \
+ || EQ ((W)->prev, FRAME_ROOT_WINDOW (WINDOW_XFRAME (W))) \
+ || (W)->pseudo_window_p) \
+ ? 0 \
+ : FRAME_BOTTOM_DIVIDER_WIDTH (WINDOW_XFRAME (W)))
/* Height in pixels, and in lines, of the mode line.
May be zero if W doesn't have a mode line. */
-
#define WINDOW_MODE_LINE_HEIGHT(W) \
(WINDOW_WANTS_MODELINE_P ((W)) \
? CURRENT_MODE_LINE_HEIGHT (W) \
@@ -782,7 +839,6 @@ wset_next_buffers (struct window *w, Lisp_Object val)
/* Height in pixels, and in lines, of the header line.
Zero if W doesn't have a header line. */
-
#define WINDOW_HEADER_LINE_HEIGHT(W) \
(WINDOW_WANTS_HEADER_LINE_P ((W)) \
? CURRENT_HEADER_LINE_HEIGHT (W) \
@@ -791,43 +847,38 @@ wset_next_buffers (struct window *w, Lisp_Object val)
#define WINDOW_HEADER_LINE_LINES(W) \
(!! WINDOW_WANTS_HEADER_LINE_P ((W)))
-/* Pixel height of window W without mode line. */
-
+/* Pixel height of window W without mode line and bottom divider. */
#define WINDOW_BOX_HEIGHT_NO_MODE_LINE(W) \
- (WINDOW_TOTAL_HEIGHT ((W)) \
+ (WINDOW_PIXEL_HEIGHT ((W)) \
+ - WINDOW_BOTTOM_DIVIDER_WIDTH (W) \
- WINDOW_MODE_LINE_HEIGHT ((W)))
-/* Pixel height of window W without mode and header line. */
-
+/* Pixel height of window W without mode and header line and bottom
+ divider. */
#define WINDOW_BOX_TEXT_HEIGHT(W) \
- (WINDOW_TOTAL_HEIGHT ((W)) \
+ (WINDOW_PIXEL_HEIGHT ((W)) \
+ - WINDOW_BOTTOM_DIVIDER_WIDTH (W) \
- WINDOW_MODE_LINE_HEIGHT ((W)) \
- WINDOW_HEADER_LINE_HEIGHT ((W)))
-
/* Convert window W relative pixel X to frame pixel coordinates. */
-
#define WINDOW_TO_FRAME_PIXEL_X(W, X) \
((X) + WINDOW_BOX_LEFT_EDGE_X ((W)))
/* Convert window W relative pixel Y to frame pixel coordinates. */
-
#define WINDOW_TO_FRAME_PIXEL_Y(W, Y) \
((Y) + WINDOW_TOP_EDGE_Y ((W)))
/* Convert frame relative pixel X to window relative pixel X. */
-
#define FRAME_TO_WINDOW_PIXEL_X(W, X) \
((X) - WINDOW_BOX_LEFT_EDGE_X ((W)))
/* Convert frame relative pixel Y to window relative pixel Y. */
-
#define FRAME_TO_WINDOW_PIXEL_Y(W, Y) \
((Y) - WINDOW_TOP_EDGE_Y ((W)))
/* Convert a text area relative x-position in window W to frame X
pixel coordinates. */
-
#define WINDOW_TEXT_TO_FRAME_PIXEL_X(W, X) \
(window_box_left ((W), TEXT_AREA) + (X))
@@ -873,18 +924,17 @@ extern Lisp_Object minibuf_selected_window;
extern Lisp_Object make_window (void);
extern Lisp_Object window_from_coordinates (struct frame *, int, int,
enum window_part *, bool);
-extern void resize_frame_windows (struct frame *, int, bool);
+extern void resize_frame_windows (struct frame *, int, bool, bool);
extern void restore_window_configuration (Lisp_Object);
extern void delete_all_child_windows (Lisp_Object);
-extern void grow_mini_window (struct window *, int);
-extern void shrink_mini_window (struct window *);
+extern void grow_mini_window (struct window *, int, bool);
+extern void shrink_mini_window (struct window *, bool);
extern int window_relative_x_coord (struct window *, enum window_part, int);
void run_window_configuration_change_hook (struct frame *f);
-/* Make WINDOW display BUFFER as its contents. RUN_HOOKS_P non-zero
- means it's allowed to run hooks. See make_frame for a case where
- it's not allowed. */
+/* Make WINDOW display BUFFER. RUN_HOOKS_P non-zero means it's allowed
+ to run hooks. See make_frame for a case where it's not allowed. */
void set_window_buffer (Lisp_Object window, Lisp_Object buffer,
bool run_hooks_p, bool keep_margins_p);
@@ -932,7 +982,7 @@ extern void redisplay_other_windows (void);
/* If *ROWS or *COLS are too small a size for FRAME, set them to the
minimum allowable size. */
-extern void check_frame_size (struct frame *frame, int *rows, int *cols);
+extern void check_frame_size (struct frame *frame, int *width, int *height, bool pixelwise);
/* Return a pointer to the glyph W's physical cursor is on. Value is
null if W's current matrix is invalid, so that no meaningful glyph
@@ -968,7 +1018,7 @@ extern struct window *decode_any_window (Lisp_Object);
extern bool compare_window_configurations (Lisp_Object, Lisp_Object, bool);
extern void mark_window_cursors_off (struct window *);
extern int window_internal_height (struct window *);
-extern int window_body_cols (struct window *w);
+extern int window_body_width (struct window *w, bool);
extern void temp_output_buffer_show (Lisp_Object);
extern void replace_buffer_in_windows (Lisp_Object);
extern void replace_buffer_in_windows_safely (Lisp_Object);
diff --git a/src/xdisp.c b/src/xdisp.c
index 28da6bffb92..8e2c18f6891 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -570,7 +570,7 @@ static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
/* Ascent and height of the last line processed by move_it_to. */
-static int last_height;
+static int last_max_ascent, last_height;
/* Non-zero if there's a help-echo in the echo area. */
@@ -998,10 +998,13 @@ static int coords_in_mouse_face_p (struct window *, int, int);
int
window_text_bottom_y (struct window *w)
{
- int height = WINDOW_TOTAL_HEIGHT (w);
+ int height = WINDOW_PIXEL_HEIGHT (w);
+
+ height -= WINDOW_BOTTOM_DIVIDER_WIDTH (w);
if (WINDOW_WANTS_MODELINE_P (w))
height -= CURRENT_MODE_LINE_HEIGHT (w);
+
return height;
}
@@ -1012,32 +1015,23 @@ window_text_bottom_y (struct window *w)
int
window_box_width (struct window *w, enum glyph_row_area area)
{
- int cols = w->total_cols;
- int pixels = 0;
+ int pixels = w->pixel_width;
if (!w->pseudo_window_p)
{
- cols -= WINDOW_SCROLL_BAR_COLS (w);
+ pixels -= WINDOW_SCROLL_BAR_AREA_WIDTH (w);
+ pixels -= WINDOW_RIGHT_DIVIDER_WIDTH (w);
if (area == TEXT_AREA)
- {
- cols -= max (0, w->left_margin_cols);
- cols -= max (0, w->right_margin_cols);
- pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
- }
+ pixels -= (WINDOW_MARGINS_WIDTH (w)
+ + WINDOW_FRINGES_WIDTH (w));
else if (area == LEFT_MARGIN_AREA)
- {
- cols = max (0, w->left_margin_cols);
- pixels = 0;
- }
+ pixels = WINDOW_LEFT_MARGIN_WIDTH (w);
else if (area == RIGHT_MARGIN_AREA)
- {
- cols = max (0, w->right_margin_cols);
- pixels = 0;
- }
+ pixels = WINDOW_RIGHT_MARGIN_WIDTH (w);
}
- return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
+ return pixels;
}
@@ -1048,10 +1042,12 @@ int
window_box_height (struct window *w)
{
struct frame *f = XFRAME (w->frame);
- int height = WINDOW_TOTAL_HEIGHT (w);
+ int height = WINDOW_PIXEL_HEIGHT (w);
eassert (height >= 0);
+ height -= WINDOW_BOTTOM_DIVIDER_WIDTH (w);
+
/* Note: the code below that determines the mode-line/header-line
height is essentially the same as that contained in the macro
CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
@@ -1910,6 +1906,8 @@ pixel_to_glyph_coords (struct frame *f, register int pix_x, register int pix_y,
FRAME_COLUMN_WIDTH (f) - 1,
FRAME_LINE_HEIGHT (f) - 1);
+ /* PXW: Should we clip pixelized before converting to
+ columns/lines ? */
if (!noclip)
{
if (pix_x < 0)
@@ -2050,7 +2048,10 @@ get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int
{
/* Draw full-width. X coordinates are relative to S->w->left_col. */
r.x = WINDOW_LEFT_EDGE_X (s->w);
- r.width = WINDOW_TOTAL_WIDTH (s->w);
+ if (s->row->mode_line_p)
+ r.width = WINDOW_PIXEL_WIDTH (s->w) - WINDOW_RIGHT_DIVIDER_WIDTH (s->w);
+ else
+ r.width = WINDOW_PIXEL_WIDTH (s->w);
/* Unless displaying a mode or menu bar line, which are always
fully visible, clip to the visible part of the row. */
@@ -2318,9 +2319,14 @@ remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
/* Try to determine frame pixel position and size of the glyph under
frame pixel coordinates X/Y on frame F. */
- if (!f->glyphs_initialized_p
- || (window = window_from_coordinates (f, gx, gy, &part, 0),
- NILP (window)))
+ if (window_resize_pixelwise)
+ {
+ width = height = 1;
+ goto virtual_glyph;
+ }
+ else if (!f->glyphs_initialized_p
+ || (window = window_from_coordinates (f, gx, gy, &part, 0),
+ NILP (window)))
{
width = FRAME_SMALLEST_CHAR_WIDTH (f);
height = FRAME_SMALLEST_FONT_HEIGHT (f);
@@ -2478,6 +2484,7 @@ remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
goto store_rect;
}
+ pixelwise:
gx += WINDOW_LEFT_EDGE_X (w);
gy += WINDOW_TOP_EDGE_Y (w);
@@ -2807,6 +2814,7 @@ init_iterator (struct it *it, struct window *w,
&& ((!NILP (Vtruncate_partial_width_windows)
&& !INTEGERP (Vtruncate_partial_width_windows))
|| (INTEGERP (Vtruncate_partial_width_windows)
+ /* PXW: Shall we do something about this ? */
&& (WINDOW_TOTAL_COLS (it->w)
< XINT (Vtruncate_partial_width_windows))))))
it->line_wrap = TRUNCATE;
@@ -2866,7 +2874,7 @@ init_iterator (struct it *it, struct window *w,
{
/* Mode lines, menu bar in terminal frames. */
it->first_visible_x = 0;
- it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
+ it->last_visible_x = WINDOW_PIXEL_WIDTH (w);
}
else
{
@@ -8843,13 +8851,17 @@ move_it_in_display_line (struct it *it,
If TO_CHARPOS is in invisible text, e.g. a truncated part of a
screen line, this function will set IT to the next position that is
- displayed to the right of TO_CHARPOS on the screen. */
+ displayed to the right of TO_CHARPOS on the screen.
-void
+ Return the maximum pixel length of any line scanned but never more
+ than it.last_visible_x. */
+
+int
move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos, int op)
{
enum move_it_result skip, skip2 = MOVE_X_REACHED;
int line_height, line_start_x = 0, reached = 0;
+ int max_current_x = 0;
void *backup_data = NULL;
for (;;)
@@ -8980,6 +8992,9 @@ move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos
if (to_y >= it->current_y
&& to_y < it->current_y + line_height)
{
+ if (to_y > it->current_y)
+ max_current_x = max (it->current_x, max_current_x);
+
/* When word-wrap is on, TO_X may lie past the end
of a wrapped line. Then it->current is the
character on the next line, so backtrack to the
@@ -8992,12 +9007,16 @@ move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos
skip = move_it_in_display_line_to
(it, -1, prev_x, MOVE_TO_X);
}
+
reached = 6;
}
}
if (reached)
- break;
+ {
+ max_current_x = max (it->current_x, max_current_x);
+ break;
+ }
}
else if (BUFFERP (it->object)
&& (it->method == GET_FROM_BUFFER
@@ -9017,15 +9036,18 @@ move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos
switch (skip)
{
case MOVE_POS_MATCH_OR_ZV:
+ max_current_x = max (it->current_x, max_current_x);
reached = 8;
goto out;
case MOVE_NEWLINE_OR_CR:
+ max_current_x = max (it->current_x, max_current_x);
set_iterator_to_next (it, 1);
it->continuation_lines_width = 0;
break;
case MOVE_LINE_TRUNCATED:
+ max_current_x = it->last_visible_x;
it->continuation_lines_width = 0;
reseat_at_next_visible_line_start (it, 0);
if ((op & MOVE_TO_POS) != 0
@@ -9037,6 +9059,7 @@ move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos
break;
case MOVE_LINE_CONTINUED:
+ max_current_x = it->last_visible_x;
/* For continued lines ending in a tab, some of the glyphs
associated with the tab are displayed on the current
line. Since it->current_x does not include these glyphs,
@@ -9072,6 +9095,7 @@ move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos
it->current_y += it->max_ascent + it->max_descent;
++it->vpos;
last_height = it->max_ascent + it->max_descent;
+ last_max_ascent = it->max_ascent;
it->max_ascent = it->max_descent = 0;
}
@@ -9098,12 +9122,15 @@ move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos
it->current_y += it->max_ascent + it->max_descent;
++it->vpos;
last_height = it->max_ascent + it->max_descent;
+ last_max_ascent = it->max_ascent;
}
if (backup_data)
bidi_unshelve_cache (backup_data, 1);
TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
+
+ return max_current_x;
}
@@ -9451,6 +9478,145 @@ in_display_vector_p (struct it *it)
&& it->dpvec + it->current.dpvec_index != it->dpend);
}
+DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_size, 0, 6, 0,
+ doc: /* Return the size of the text of WINDOW's buffer in pixels.
+WINDOW must be a live window and defaults to the selected one. The
+return value is a cons of the maximum pixel-width of any text line and
+the maximum pixel-height of all text lines.
+
+The optional argument FROM, if non-nil, specifies the first text
+position and defaults to the minimum accessible position of the buffer.
+If FROM is t, use the minimum accessible position that is not a newline
+character. TO, if non-nil, specifies the last text position and
+defaults to the maximum accessible position of the buffer. If TO is t,
+use the maximum accessible position that is not a newline character.
+
+The optional argument X_LIMIT, if non-nil, specifies the maximum text
+width that can be returned. X_LIMIT nil or omitted, means to use the
+pixel-width of WINDOW's body; use this if you do not intend to change
+the width of WINDOW. Use the maximum width WINDOW may assume if you
+intend to change WINDOW's width.
+
+The optional argument Y_LIMIT, if non-nil, specifies the maximum text
+height that can be returned. Text lines whose y-coordinate is beyond
+Y_LIMIT are ignored. Since calculating the text height of a large
+buffer can take some time, it makes sense to specify this argument if
+the size of the buffer is unknown.
+
+Optional argument MODE_AND_HEADER_LINE nil or omitted means do not
+include the height of the mode- or header-line of WINDOW in the return
+value. If it is either the symbol `mode-line' or `header-line', include
+only the height of that line, if present, in the return value. If t,
+include the height of any of these lines in the return value. */)
+ (Lisp_Object window, Lisp_Object from, Lisp_Object to, Lisp_Object x_limit, Lisp_Object y_limit,
+ Lisp_Object mode_and_header_line)
+{
+ struct window *w = decode_live_window (window);
+ Lisp_Object buf, value;
+ struct buffer *b;
+ struct it it;
+ struct buffer *old_buffer = NULL;
+ ptrdiff_t start, end, pos;
+ struct text_pos startp, endp;
+ void *itdata = NULL;
+ int c, max_y = -1, x = 0, y = 0;
+
+ buf = w->contents;
+ CHECK_BUFFER (buf);
+ b = XBUFFER (buf);
+
+ if (b != current_buffer)
+ {
+ old_buffer = current_buffer;
+ set_buffer_internal (b);
+ }
+
+ if (NILP (from))
+ start = BEGV;
+ else if (EQ (from, Qt))
+ {
+ start = pos = BEGV;
+ while ((pos++ < ZV) && (c = FETCH_CHAR (pos))
+ && (c == ' ' || c == '\t' || c == '\n' || c == '\r'))
+ start = pos;
+ while ((pos-- > BEGV) && (c = FETCH_CHAR (pos)) && (c == ' ' || c == '\t'))
+ start = pos;
+ }
+ else
+ {
+ CHECK_NUMBER_COERCE_MARKER (from);
+ start = min (max (XINT (from), BEGV), ZV);
+ }
+
+ if (NILP (to))
+ end = ZV;
+ else if (EQ (to, Qt))
+ {
+ end = pos = ZV;
+ while ((pos-- > BEGV) && (c = FETCH_CHAR (pos))
+ && (c == ' ' || c == '\t' || c == '\n' || c == '\r'))
+ end = pos;
+ while ((pos++ < ZV) && (c = FETCH_CHAR (pos)) && (c == ' ' || c == '\t'))
+ end = pos;
+ }
+ else
+ {
+ CHECK_NUMBER_COERCE_MARKER (to);
+ end = max (start, min (XINT (to), ZV));
+ }
+
+ if (!NILP (y_limit))
+ {
+ CHECK_NUMBER (y_limit);
+ max_y = XINT (y_limit);
+ }
+
+ itdata = bidi_shelve_cache ();
+ SET_TEXT_POS (startp, start, CHAR_TO_BYTE (start));
+ start_display (&it, w, startp);
+
+ /** move_it_vertically_backward (&it, 0); **/
+ if (NILP (x_limit))
+ x = move_it_to (&it, end, -1, max_y, -1, MOVE_TO_POS | MOVE_TO_Y);
+ else
+ {
+ CHECK_NUMBER (x_limit);
+ it.last_visible_x = XINT (x_limit);
+ /* Actually, we never want move_it_to stop at to_x. But to make
+ sure that move_it_in_display_line_to always moves far enough,
+ we set it to INT_MAX and specify MOVE_TO_X. */
+ x = move_it_to (&it, end, INT_MAX, max_y, -1,
+ MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
+ }
+
+ if (start == end)
+ y = it.current_y;
+ else
+ {
+ /* Count last line. */
+ last_height = 0;
+ y = line_bottom_y (&it); /* - y; */
+ }
+
+ if (!EQ (mode_and_header_line, Qheader_line)
+ && !EQ (mode_and_header_line, Qt))
+ /* Do not count the header-line which was counted automatically by
+ start_display. */
+ y = y - WINDOW_HEADER_LINE_HEIGHT (w);
+
+ if (EQ (mode_and_header_line, Qmode_line)
+ || EQ (mode_and_header_line, Qt))
+ /* Do count the mode-line which is not included automatically by
+ start_display. */
+ y = y + WINDOW_MODE_LINE_HEIGHT (w);
+
+ bidi_unshelve_cache (itdata, 0);
+
+ if (old_buffer)
+ set_buffer_internal (old_buffer);
+
+ return Fcons (make_number (x), make_number (y));
+}
/***********************************************************************
Messages
@@ -10447,11 +10613,10 @@ resize_mini_window (struct window *w, int exact_p)
if (!FRAME_MINIBUF_ONLY_P (f))
{
struct it it;
- struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
- int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
- int height;
- EMACS_INT max_height;
+ int total_height = (WINDOW_PIXEL_HEIGHT (XWINDOW (FRAME_ROOT_WINDOW (f)))
+ + WINDOW_PIXEL_HEIGHT (w));
int unit = FRAME_LINE_HEIGHT (f);
+ int height, max_height;
struct text_pos start;
struct buffer *old_current_buffer = NULL;
@@ -10465,18 +10630,18 @@ resize_mini_window (struct window *w, int exact_p)
/* Compute the max. number of lines specified by the user. */
if (FLOATP (Vmax_mini_window_height))
- max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
+ max_height = XFLOATINT (Vmax_mini_window_height) * total_height;
else if (INTEGERP (Vmax_mini_window_height))
- max_height = XINT (Vmax_mini_window_height);
+ max_height = XINT (Vmax_mini_window_height) * unit;
else
max_height = total_height / 4;
/* Correct that max. height if it's bogus. */
- max_height = clip_to_bounds (1, max_height, total_height);
+ max_height = clip_to_bounds (unit, max_height, total_height);
/* Find out the height of the text in the window. */
if (it.line_wrap == TRUNCATE)
- height = 1;
+ height = unit;
else
{
last_height = 0;
@@ -10486,7 +10651,6 @@ resize_mini_window (struct window *w, int exact_p)
else
height = it.current_y + it.max_ascent + it.max_descent;
height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
- height = (height + unit - 1) / unit;
}
/* Compute a suitable window start. */
@@ -10494,7 +10658,7 @@ resize_mini_window (struct window *w, int exact_p)
{
height = max_height;
init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
- move_it_vertically_backward (&it, (height - 1) * unit);
+ move_it_vertically_backward (&it, height);
start = it.current.pos;
}
else
@@ -10505,49 +10669,49 @@ resize_mini_window (struct window *w, int exact_p)
{
/* Let it grow only, until we display an empty message, in which
case the window shrinks again. */
- if (height > WINDOW_TOTAL_LINES (w))
+ if (height > WINDOW_PIXEL_HEIGHT (w))
{
- int old_height = WINDOW_TOTAL_LINES (w);
+ int old_height = WINDOW_PIXEL_HEIGHT (w);
FRAME_WINDOWS_FROZEN (f) = 1;
- grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
- window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
+ grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), 1);
+ window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
}
- else if (height < WINDOW_TOTAL_LINES (w)
+ else if (height < WINDOW_PIXEL_HEIGHT (w)
&& (exact_p || BEGV == ZV))
{
- int old_height = WINDOW_TOTAL_LINES (w);
+ int old_height = WINDOW_PIXEL_HEIGHT (w);
FRAME_WINDOWS_FROZEN (f) = 0;
- shrink_mini_window (w);
- window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
+ shrink_mini_window (w, 1);
+ window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
}
}
else
{
/* Always resize to exact size needed. */
- if (height > WINDOW_TOTAL_LINES (w))
+ if (height > WINDOW_PIXEL_HEIGHT (w))
{
- int old_height = WINDOW_TOTAL_LINES (w);
+ int old_height = WINDOW_PIXEL_HEIGHT (w);
FRAME_WINDOWS_FROZEN (f) = 1;
- grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
- window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
+ grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), 1);
+ window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
}
- else if (height < WINDOW_TOTAL_LINES (w))
+ else if (height < WINDOW_PIXEL_HEIGHT (w))
{
- int old_height = WINDOW_TOTAL_LINES (w);
+ int old_height = WINDOW_PIXEL_HEIGHT (w);
FRAME_WINDOWS_FROZEN (f) = 0;
- shrink_mini_window (w);
+ shrink_mini_window (w, 1);
if (height)
{
FRAME_WINDOWS_FROZEN (f) = 1;
- grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
+ grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), 1);
}
- window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
+ window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
}
}
@@ -11501,8 +11665,8 @@ update_tool_bar (struct frame *f, int save_match_data)
#if defined (USE_GTK) || defined (HAVE_NS)
int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
#else
- int do_update = WINDOWP (f->tool_bar_window)
- && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
+ int do_update = (WINDOWP (f->tool_bar_window)
+ && WINDOW_PIXEL_HEIGHT (XWINDOW (f->tool_bar_window)) > 0);
#endif
if (do_update)
@@ -11884,7 +12048,8 @@ display_tool_bar_line (struct it *it, int height)
}
-/* Max tool-bar height. */
+/* Max tool-bar height. Basically, this is what makes all other windows
+ disappear when the frame gets too small. Rethink this! */
#define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
@@ -11894,11 +12059,11 @@ display_tool_bar_line (struct it *it, int height)
returned in *N_ROWS if non-NULL. */
static int
-tool_bar_lines_needed (struct frame *f, int *n_rows)
+tool_bar_height (struct frame *f, int *n_rows, bool pixelwise)
{
struct window *w = XWINDOW (f->tool_bar_window);
struct it it;
- /* tool_bar_lines_needed is called from redisplay_tool_bar after building
+ /* tool_bar_height is called from redisplay_tool_bar after building
the desired matrix, so use (unused) mode-line row as temporary row to
avoid destroying the first tool-bar row. */
struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
@@ -11907,6 +12072,7 @@ tool_bar_lines_needed (struct frame *f, int *n_rows)
F->desired_tool_bar_string in the tool-bar window of frame F. */
init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
it.first_visible_x = 0;
+ /* PXW: Use FRAME_PIXEL_WIDTH (f) here ? */
it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
it.paragraph_embedding = L2R;
@@ -11923,7 +12089,10 @@ tool_bar_lines_needed (struct frame *f, int *n_rows)
if (n_rows)
*n_rows = it.vpos > 0 ? it.vpos : -1;
- return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
+ if (pixelwise)
+ return it.current_y;
+ else
+ return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
}
#endif /* !USE_GTK && !HAVE_NS */
@@ -11932,30 +12101,30 @@ tool_bar_lines_needed (struct frame *f, int *n_rows)
EXFUN (Ftool_bar_lines_needed, 1) ATTRIBUTE_CONST;
#endif
-DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
- 0, 1, 0,
+DEFUN ("tool-bar-height", Ftool_bar_height, Stool_bar_height,
+ 0, 2, 0,
doc: /* Return the number of lines occupied by the tool bar of FRAME.
-If FRAME is nil or omitted, use the selected frame. */)
- (Lisp_Object frame)
+If FRAME is nil or omitted, use the selected frame. Optional argument
+PIXELWISE non-nil means return the height of the tool bar inpixels. */)
+ (Lisp_Object frame, Lisp_Object pixelwise)
{
- int nlines = 0;
-#if ! defined (USE_GTK) && ! defined (HAVE_NS)
struct frame *f = decode_any_frame (frame);
- struct window *w;
+ int height = 0;
+#if ! defined (USE_GTK) && ! defined (HAVE_NS)
if (WINDOWP (f->tool_bar_window)
- && (w = XWINDOW (f->tool_bar_window),
- WINDOW_TOTAL_LINES (w) > 0))
+ && WINDOW_PIXEL_HEIGHT (XWINDOW (f->tool_bar_window)) > 0)
{
update_tool_bar (f, 1);
if (f->n_tool_bar_items)
{
build_desired_tool_bar_string (f);
- nlines = tool_bar_lines_needed (f, NULL);
+ height = tool_bar_height (f, NULL, NILP (pixelwise) ? 0 : 1);
}
}
#endif
- return make_number (nlines);
+
+ return make_number (height);
}
@@ -11983,13 +12152,13 @@ redisplay_tool_bar (struct frame *f)
can turn off tool-bars by specifying tool-bar-lines zero. */
if (!WINDOWP (f->tool_bar_window)
|| (w = XWINDOW (f->tool_bar_window),
- WINDOW_TOTAL_LINES (w) == 0))
+ WINDOW_PIXEL_HEIGHT (w) == 0))
return 0;
/* Set up an iterator for the tool-bar window. */
init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
it.first_visible_x = 0;
- it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
+ it.last_visible_x = WINDOW_PIXEL_WIDTH (w);
row = it.glyph_row;
/* Build a string that represents the contents of the tool-bar. */
@@ -12006,24 +12175,22 @@ redisplay_tool_bar (struct frame *f)
if (f->n_tool_bar_rows == 0)
{
- int nlines;
+ int new_height = tool_bar_height (f, &f->n_tool_bar_rows, 1);
- if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
- nlines != WINDOW_TOTAL_LINES (w)))
+ if (new_height != WINDOW_PIXEL_HEIGHT (w))
{
Lisp_Object frame;
- int old_height = WINDOW_TOTAL_LINES (w);
+ int new_lines = ((new_height + FRAME_LINE_HEIGHT (f) - 1)
+ / FRAME_LINE_HEIGHT (f));
XSETFRAME (frame, f);
Fmodify_frame_parameters (frame,
list1 (Fcons (Qtool_bar_lines,
- make_number (nlines))));
- if (WINDOW_TOTAL_LINES (w) != old_height)
- {
- clear_glyph_matrix (w->desired_matrix);
- f->fonts_changed = 1;
- return 1;
- }
+ make_number (new_lines))));
+ /* Always do that now. */
+ clear_glyph_matrix (w->desired_matrix);
+ f->fonts_changed = 1;
+ return 1;
}
}
@@ -12072,6 +12239,7 @@ redisplay_tool_bar (struct frame *f)
if (!NILP (Vauto_resize_tool_bars))
{
+ /* Do we really allow the toolbar to occupy the whole frame? */
int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
int change_height_p = 0;
@@ -12102,29 +12270,29 @@ redisplay_tool_bar (struct frame *f)
if (change_height_p)
{
Lisp_Object frame;
- int old_height = WINDOW_TOTAL_LINES (w);
int nrows;
- int nlines = tool_bar_lines_needed (f, &nrows);
+ int new_height = tool_bar_height (f, &nrows, 1);
change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
&& !f->minimize_tool_bar_window_p)
- ? (nlines > old_height)
- : (nlines != old_height));
+ ? (new_height > WINDOW_PIXEL_HEIGHT (w))
+ : (new_height != WINDOW_PIXEL_HEIGHT (w)));
f->minimize_tool_bar_window_p = 0;
if (change_height_p)
{
+ int new_lines = ((new_height + FRAME_LINE_HEIGHT (f) - 1)
+ / FRAME_LINE_HEIGHT (f));
+
XSETFRAME (frame, f);
Fmodify_frame_parameters (frame,
list1 (Fcons (Qtool_bar_lines,
- make_number (nlines))));
- if (WINDOW_TOTAL_LINES (w) != old_height)
- {
- clear_glyph_matrix (w->desired_matrix);
- f->n_tool_bar_rows = nrows;
- f->fonts_changed = 1;
- return 1;
- }
+ make_number (new_lines))));
+ /* Always do that now. */
+ clear_glyph_matrix (w->desired_matrix);
+ f->n_tool_bar_rows = nrows;
+ f->fonts_changed = 1;
+ return 1;
}
}
}
@@ -13323,6 +13491,8 @@ redisplay_internal (void)
PT == w->last_point
/* Make sure the cursor was last displayed
in this window. Otherwise we have to reposition it. */
+
+ /* PXW: Must be pixelized, probably. */
&& 0 <= w->cursor.vpos
&& w->cursor.vpos < WINDOW_TOTAL_LINES (w))
{
@@ -14926,6 +15096,7 @@ compute_window_start_on_continuation_line (struct window *w)
/* If the line start is "too far" away from the window start,
say it takes too much time to compute a new window start. */
if (CHARPOS (start_pos) - IT_CHARPOS (it)
+ /* PXW: Do we need upper bounds here ? */
< WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
{
int min_distance, distance;
@@ -16220,7 +16391,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
redisplay_tool_bar (f);
#else
if (WINDOWP (f->tool_bar_window)
- && (FRAME_TOOL_BAR_LINES (f) > 0
+ && (FRAME_TOOL_BAR_HEIGHT (f) > 0
|| !NILP (Vauto_resize_tool_bars))
&& redisplay_tool_bar (f))
ignore_mouse_drag_p = 1;
@@ -16238,10 +16409,18 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
update_begin (f);
block_input ();
if (draw_window_fringes (w, 1))
- x_draw_vertical_border (w);
+ {
+ if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
+ x_draw_right_divider (w);
+ else
+ x_draw_vertical_border (w);
+ }
unblock_input ();
update_end (f);
}
+
+ if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
+ x_draw_bottom_divider (w);
#endif /* HAVE_WINDOW_SYSTEM */
/* We go to this label, with fonts_changed set, if it is
@@ -20544,6 +20723,7 @@ display_menu_bar (struct window *w)
eassert (!FRAME_WINDOW_P (f));
init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
it.first_visible_x = 0;
+ /* PXW: Use FRAME_PIXEL_WIDTH (f) here ? */
it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
#elif defined (HAVE_X_WINDOWS) /* X without toolkit. */
if (FRAME_WINDOW_P (f))
@@ -20555,6 +20735,7 @@ display_menu_bar (struct window *w)
init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
MENU_FACE_ID);
it.first_visible_x = 0;
+ /* PXW: Use FRAME_PIXEL_WIDTH (f) here ? */
it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
}
else
@@ -23929,7 +24110,8 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row,
/* X is relative to the left edge of W, without scroll bars
or fringes. */
area_left = WINDOW_LEFT_EDGE_X (w);
- last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
+ last_x = (WINDOW_LEFT_EDGE_X (w) + WINDOW_PIXEL_WIDTH (w)
+ - (row->mode_line_p ? WINDOW_RIGHT_DIVIDER_WIDTH (w) : 0));
}
else
{
@@ -25967,7 +26149,8 @@ x_clear_end_of_line (struct window *w, struct glyph_row *updated_row,
f = XFRAME (w->frame);
if (updated_row->full_width_p)
- max_x = WINDOW_TOTAL_WIDTH (w);
+ max_x = (WINDOW_PIXEL_WIDTH (w)
+ - (updated_row->mode_line_p ? WINDOW_RIGHT_DIVIDER_WIDTH (w) : 0));
else
max_x = window_box_width (w, updated_area);
max_y = window_text_bottom_y (w);
@@ -27811,6 +27994,8 @@ define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
cursor = FRAME_X_OUTPUT (f)->text_cursor;
else if (EQ (pointer, intern ("hdrag")))
cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
+ else if (EQ (pointer, intern ("nhdrag")))
+ cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
#ifdef HAVE_X_WINDOWS
else if (EQ (pointer, intern ("vdrag")))
cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
@@ -28224,6 +28409,16 @@ note_mouse_highlight (struct frame *f, int x, int y)
cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
help_echo_string = build_string ("drag-mouse-1: resize");
}
+ else if (part == ON_RIGHT_DIVIDER)
+ {
+ cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
+ help_echo_string = build_string ("drag-mouse-1: resize");
+ }
+ else if (part == ON_BOTTOM_DIVIDER)
+ {
+ cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
+ help_echo_string = build_string ("drag-mouse-1: resize");
+ }
else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
|| part == ON_SCROLL_BAR)
cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
@@ -28864,7 +29059,7 @@ x_draw_vertical_border (struct window *w)
do it for frames with vertical scroll bars because either the
right scroll bar of a window, or the left scroll bar of its
neighbor will suffice as a border. */
- if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
+ if (FRAME_HAS_VERTICAL_SCROLL_BARS (f) || FRAME_RIGHT_DIVIDER_WIDTH (f))
return;
/* Note: It is necessary to redraw both the left and the right
@@ -28883,6 +29078,7 @@ x_draw_vertical_border (struct window *w)
FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
}
+
if (!WINDOW_LEFTMOST_P (w)
&& !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
{
@@ -28899,6 +29095,44 @@ x_draw_vertical_border (struct window *w)
}
+/* Draw window dividers for window W. */
+
+void
+x_draw_right_divider (struct window *w)
+{
+ struct frame *f = WINDOW_XFRAME (w);
+
+ if (w->mini || w->pseudo_window_p)
+ return;
+ else if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
+ {
+ int x0 = WINDOW_RIGHT_EDGE_X (w) - WINDOW_RIGHT_DIVIDER_WIDTH (w);
+ int x1 = WINDOW_RIGHT_EDGE_X (w);
+ int y0 = WINDOW_TOP_EDGE_Y (w);
+ int y1 = WINDOW_BOTTOM_EDGE_Y (w);
+
+ FRAME_RIF (f)->draw_window_divider (w, x0, x1, y0, y1);
+ }
+}
+
+void
+x_draw_bottom_divider (struct window *w)
+{
+ struct frame *f = XFRAME (WINDOW_FRAME (w));
+
+ if (w->mini || w->pseudo_window_p)
+ return;
+ else if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
+ {
+ int x0 = WINDOW_LEFT_EDGE_X (w);
+ int x1 = WINDOW_RIGHT_EDGE_X (w);
+ int y0 = WINDOW_BOTTOM_EDGE_Y (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
+ int y1 = WINDOW_BOTTOM_EDGE_Y (w);
+
+ FRAME_RIF (f)->draw_window_divider (w, x0, x1, y0, y1);
+ }
+}
+
/* Redraw the part of window W intersection rectangle FR. Pixel
coordinates in FR are frame-relative. Call this function with
input blocked. Value is non-zero if the exposure overwrites
@@ -28930,8 +29164,8 @@ expose_window (struct window *w, XRectangle *fr)
/* Frame-relative pixel rectangle of W. */
wr.x = WINDOW_LEFT_EDGE_X (w);
wr.y = WINDOW_TOP_EDGE_Y (w);
- wr.width = WINDOW_TOTAL_WIDTH (w);
- wr.height = WINDOW_TOTAL_HEIGHT (w);
+ wr.width = WINDOW_PIXEL_WIDTH (w);
+ wr.height = WINDOW_PIXEL_HEIGHT (w);
if (x_intersect_rectangles (fr, &wr, &r))
{
@@ -29027,7 +29261,13 @@ expose_window (struct window *w, XRectangle *fr)
fr);
/* Draw border between windows. */
- x_draw_vertical_border (w);
+ if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
+ x_draw_right_divider (w);
+ else
+ x_draw_vertical_border (w);
+
+ if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
+ x_draw_bottom_divider (w);
/* Turn the cursor on again. */
if (cursor_cleared_p
@@ -29245,13 +29485,14 @@ syms_of_xdisp (void)
defsubr (&Strace_to_stderr);
#endif
#ifdef HAVE_WINDOW_SYSTEM
- defsubr (&Stool_bar_lines_needed);
+ defsubr (&Stool_bar_height);
defsubr (&Slookup_image_map);
#endif
defsubr (&Sline_pixel_height);
defsubr (&Sformat_mode_line);
defsubr (&Sinvisible_p);
defsubr (&Scurrent_bidi_paragraph_direction);
+ defsubr (&Swindow_text_pixel_size);
defsubr (&Smove_point_visually);
DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
@@ -29879,12 +30120,18 @@ init_xdisp (void)
echo_area_window = minibuf_window;
r->top_line = FRAME_TOP_MARGIN (f);
- r->total_lines = FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f);
+ r->pixel_top = r->top_line * FRAME_LINE_HEIGHT (f);
r->total_cols = FRAME_COLS (f);
+ r->pixel_width = r->total_cols * FRAME_COLUMN_WIDTH (f);
+ r->total_lines = FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f);
+ r->pixel_height = r->total_lines * FRAME_LINE_HEIGHT (f);
m->top_line = FRAME_LINES (f) - 1;
- m->total_lines = 1;
+ m->pixel_top = m->top_line * FRAME_LINE_HEIGHT (f);
m->total_cols = FRAME_COLS (f);
+ m->pixel_width = m->total_cols * FRAME_COLUMN_WIDTH (f);
+ m->total_lines = 1;
+ m->pixel_height = m->total_lines * FRAME_LINE_HEIGHT (f);
scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
scratch_glyph_row.glyphs[TEXT_AREA + 1]
diff --git a/src/xfaces.c b/src/xfaces.c
index b9ddddfd9e2..b6e0abc2f96 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -323,6 +323,7 @@ Lisp_Object Qheader_line, Qscroll_bar, Qcursor;
static Lisp_Object Qborder, Qmouse, Qmenu;
Lisp_Object Qmode_line_inactive;
static Lisp_Object Qvertical_border;
+static Lisp_Object Qwindow_divider;
/* The symbol `face-alias'. A symbols having that property is an
alias for another face. Value of the property is the name of
@@ -5246,6 +5247,7 @@ realize_basic_faces (struct frame *f)
realize_named_face (f, Qmouse, MOUSE_FACE_ID);
realize_named_face (f, Qmenu, MENU_FACE_ID);
realize_named_face (f, Qvertical_border, VERTICAL_BORDER_FACE_ID);
+ realize_named_face (f, Qwindow_divider, WINDOW_DIVIDER_FACE_ID);
/* Reflect changes in the `menu' face in menu bars. */
if (FRAME_FACE_CACHE (f)->menu_face_changed_p)
@@ -6448,6 +6450,7 @@ syms_of_xfaces (void)
DEFSYM (Qmouse, "mouse");
DEFSYM (Qmode_line_inactive, "mode-line-inactive");
DEFSYM (Qvertical_border, "vertical-border");
+ DEFSYM (Qwindow_divider, "window-divider");
DEFSYM (Qtty_color_desc, "tty-color-desc");
DEFSYM (Qtty_color_standard_values, "tty-color-standard-values");
DEFSYM (Qtty_color_by_index, "tty-color-by-index");
diff --git a/src/xfns.c b/src/xfns.c
index 46f377042f6..bd4a6a62db6 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -612,7 +612,7 @@ x_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
struct x_output *x = f->output_data.x;
Display *dpy = FRAME_X_DISPLAY (f);
Cursor cursor, nontext_cursor, mode_cursor, hand_cursor;
- Cursor hourglass_cursor, horizontal_drag_cursor;
+ Cursor hourglass_cursor, horizontal_drag_cursor, vertical_drag_cursor;
unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
unsigned long mask_color = FRAME_BACKGROUND_PIXEL (f);
@@ -688,6 +688,16 @@ x_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
horizontal_drag_cursor
= XCreateFontCursor (dpy, XC_sb_h_double_arrow);
+ if (!NILP (Vx_window_vertical_drag_shape))
+ {
+ CHECK_NUMBER (Vx_window_vertical_drag_shape);
+ vertical_drag_cursor
+ = XCreateFontCursor (dpy, XINT (Vx_window_vertical_drag_shape));
+ }
+ else
+ vertical_drag_cursor
+ = XCreateFontCursor (dpy, XC_sb_v_double_arrow);
+
/* Check and report errors with the above calls. */
x_check_errors (dpy, "can't set cursor shape: %s");
x_uncatch_errors ();
@@ -745,6 +755,11 @@ x_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
XFreeCursor (dpy, x->horizontal_drag_cursor);
x->horizontal_drag_cursor = horizontal_drag_cursor;
+ if (vertical_drag_cursor != x->vertical_drag_cursor
+ && x->vertical_drag_cursor != 0)
+ XFreeCursor (dpy, x->vertical_drag_cursor);
+ x->vertical_drag_cursor = vertical_drag_cursor;
+
XFlush (dpy);
unblock_input ();
@@ -963,6 +978,7 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
FRAME_MENU_BAR_LINES (f) = 0;
+ FRAME_MENU_BAR_HEIGHT (f) = 0;
if (nlines)
{
FRAME_EXTERNAL_MENU_BAR (f) = 1;
@@ -980,7 +996,8 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
}
#else /* not USE_X_TOOLKIT && not USE_GTK */
FRAME_MENU_BAR_LINES (f) = nlines;
- resize_frame_windows (f, FRAME_LINES (f), 0);
+ FRAME_MENU_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f);
+ resize_frame_windows (f, FRAME_LINES (f), 0, 0);
/* If the menu bar height gets changed, the internal border below
the top margin has to be cleared. Also, if the menu bar gets
@@ -993,7 +1010,7 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
int y;
/* height can be zero here. */
- if (height > 0 && width > 0)
+ if (FRAME_X_WINDOW (f) && height > 0 && width > 0)
{
y = FRAME_TOP_MARGIN_HEIGHT (f);
@@ -1051,6 +1068,7 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
#ifdef USE_GTK
FRAME_TOOL_BAR_LINES (f) = 0;
+ FRAME_TOOL_BAR_HEIGHT (f) = 0;
if (nlines)
{
FRAME_EXTERNAL_TOOL_BAR (f) = 1;
@@ -1083,7 +1101,8 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
}
FRAME_TOOL_BAR_LINES (f) = nlines;
- resize_frame_windows (f, FRAME_LINES (f), 0);
+ FRAME_TOOL_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f);
+ resize_frame_windows (f, FRAME_LINES (f), 0, 0);
adjust_frame_glyphs (f);
/* We also have to make sure that the internal border at the top of
@@ -1092,7 +1111,7 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
below the tool bar if one is displayed, but is below the menu bar
if there isn't a tool bar. The tool bar draws into the area
below the menu bar. */
- if (FRAME_X_WINDOW (f) && FRAME_TOOL_BAR_LINES (f) == 0)
+ if (FRAME_X_WINDOW (f) && FRAME_TOOL_BAR_HEIGHT (f) == 0)
{
clear_frame (f);
clear_current_matrices (f);
@@ -1471,13 +1490,13 @@ x_set_scroll_bar_default_width (struct frame *f)
FRAME_CONFIG_SCROLL_BAR_COLS (f) = (minw + wid - 1) / wid;
FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = minw;
#else
- /* Make the actual width at least 14 pixels and a multiple of a
+ /* Make the actual width 16 pixels and a multiple of a
character width. */
- FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
+ FRAME_CONFIG_SCROLL_BAR_COLS (f) = (16 + wid - 1) / wid;
/* Use all of that space (aside from required margins) for the
scroll bar. */
- FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = 0;
+ FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = 16;
#endif
}
@@ -3130,12 +3149,11 @@ This function is an internal primitive--use `make-frame' instead. */)
/* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
Change will not be effected unless different from the current
FRAME_LINES (f). */
- width = FRAME_COLS (f);
- height = FRAME_LINES (f);
-
- SET_FRAME_COLS (f, 0);
- FRAME_LINES (f) = 0;
- change_frame_size (f, height, width, 1, 0, 0);
+ width = FRAME_TEXT_WIDTH (f);
+ height = FRAME_TEXT_HEIGHT (f);
+ FRAME_TEXT_HEIGHT (f) = 0;
+ SET_FRAME_WIDTH (f, 0);
+ change_frame_size (f, width, height, 1, 0, 0, 1);
#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
/* Create the menu bar. */
@@ -4918,6 +4936,10 @@ x_create_tip_frame (struct x_display_info *dpyinfo,
x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
"internalBorderWidth", "internalBorderWidth",
RES_TYPE_NUMBER);
+ x_default_parameter (f, parms, Qright_divider_width, make_number (0),
+ NULL, NULL, RES_TYPE_NUMBER);
+ x_default_parameter (f, parms, Qbottom_divider_width, make_number (0),
+ NULL, NULL, RES_TYPE_NUMBER);
/* Also do the stuff which must be set before the window exists. */
x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
@@ -5000,7 +5022,7 @@ x_create_tip_frame (struct x_display_info *dpyinfo,
height = FRAME_LINES (f);
SET_FRAME_COLS (f, 0);
FRAME_LINES (f) = 0;
- change_frame_size (f, height, width, 1, 0, 0);
+ change_frame_size (f, width, height, 1, 0, 0, 0);
/* Add `tooltip' frame parameter's default value. */
if (NILP (Fframe_parameter (frame, Qtooltip)))
@@ -5260,6 +5282,10 @@ Text larger than the specified size is clipped. */)
parms = Fcons (Fcons (Qinternal_border_width, make_number (3)), parms);
if (NILP (Fassq (Qborder_width, parms)))
parms = Fcons (Fcons (Qborder_width, make_number (1)), parms);
+ if (NILP (Fassq (Qbottom_divider_width, parms)))
+ parms = Fcons (Fcons (Qbottom_divider_width, make_number (0)), parms);
+ if (NILP (Fassq (Qright_divider_width, parms)))
+ parms = Fcons (Fcons (Qright_divider_width, make_number (0)), parms);
if (NILP (Fassq (Qborder_color, parms)))
parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
if (NILP (Fassq (Qbackground_color, parms)))
@@ -5275,6 +5301,8 @@ Text larger than the specified size is clipped. */)
w = XWINDOW (FRAME_ROOT_WINDOW (f));
w->left_col = 0;
w->top_line = 0;
+ w->pixel_left = 0;
+ w->pixel_top = 0;
if (CONSP (Vx_max_tooltip_size)
&& RANGED_INTEGERP (1, XCAR (Vx_max_tooltip_size), INT_MAX)
@@ -5289,6 +5317,9 @@ Text larger than the specified size is clipped. */)
w->total_lines = 40;
}
+ w->pixel_width = w->total_cols * FRAME_COLUMN_WIDTH (f);
+ w->pixel_height = w->total_lines * FRAME_LINE_HEIGHT (f);
+
FRAME_TOTAL_COLS (f) = w->total_cols;
adjust_frame_glyphs (f);
w->pseudo_window_p = 1;
@@ -5355,9 +5386,11 @@ Text larger than the specified size is clipped. */)
{
/* w->total_cols and FRAME_TOTAL_COLS want the width in columns,
not in pixels. */
+ w->pixel_width = width;
width /= WINDOW_FRAME_COLUMN_WIDTH (w);
w->total_cols = width;
FRAME_TOTAL_COLS (f) = width;
+ SET_FRAME_WIDTH (f, width);
adjust_frame_glyphs (f);
clear_glyph_matrix (w->desired_matrix);
clear_glyph_matrix (w->current_matrix);
@@ -5958,6 +5991,8 @@ frame_parm_handler x_frame_parm_handlers[] =
x_set_icon_name,
x_set_icon_type,
x_set_internal_border_width,
+ x_set_right_divider_width,
+ x_set_bottom_divider_width,
x_set_menu_bar_lines,
x_set_mouse_color,
x_explicitly_set_name,
@@ -6041,6 +6076,13 @@ This variable takes effect when you create a new frame
or when you set the mouse color. */);
Vx_window_horizontal_drag_shape = Qnil;
+ DEFVAR_LISP ("x-window-vertical-drag-cursor",
+ Vx_window_vertical_drag_shape,
+ doc: /* Pointer shape to use for indicating a window can be dragged vertically.
+This variable takes effect when you create a new frame
+or when you set the mouse color. */);
+ Vx_window_vertical_drag_shape = Qnil;
+
DEFVAR_LISP ("x-cursor-fore-pixel", Vx_cursor_fore_pixel,
doc: /* A string indicating the foreground color of the cursor box. */);
Vx_cursor_fore_pixel = Qnil;
diff --git a/src/xmenu.c b/src/xmenu.c
index cdc63cbaa96..d587610fdd7 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -1168,7 +1168,7 @@ free_frame_menubar (struct frame *f)
if (x1 == 0 && y1 == 0)
XtVaSetValues (f->output_data.x->widget, XtNx, x0, XtNy, y0, NULL);
#endif
- x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
+ x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 1);
}
unblock_input ();
}
diff --git a/src/xterm.c b/src/xterm.c
index e80212a6adb..46419aed154 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -214,7 +214,7 @@ enum xembed_message
};
static bool x_alloc_nearest_color_1 (Display *, Colormap, XColor *);
-static void x_set_window_size_1 (struct frame *, int, int, int);
+static void x_set_window_size_1 (struct frame *, int, int, int, bool);
static void x_raise_frame (struct frame *);
static void x_lower_frame (struct frame *);
static const XColor *x_color_cells (Display *, int *);
@@ -509,6 +509,23 @@ x_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
f->output_data.x->normal_gc, x, y0, x, y1);
}
+/* Draw a window divider from (x0,y0) to (x1,y1) */
+
+static void
+x_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
+{
+ struct frame *f = XFRAME (WINDOW_FRAME (w));
+ struct face *face;
+
+ face = FACE_FROM_ID (f, WINDOW_DIVIDER_FACE_ID);
+ if (face)
+ XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->normal_gc,
+ face->foreground);
+
+ XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+ f->output_data.x->normal_gc, x0, y0, x1 - x0, y1 - y0);
+}
+
/* End update of window W.
Draw vertical borders between horizontally adjacent windows, and
@@ -536,7 +553,12 @@ x_update_window_end (struct window *w, bool cursor_on_p,
w->output_cursor.x, w->output_cursor.y);
if (draw_window_fringes (w, 1))
- x_draw_vertical_border (w);
+ {
+ if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
+ x_draw_right_divider (w);
+ else
+ x_draw_vertical_border (w);
+ }
unblock_input ();
}
@@ -658,8 +680,7 @@ x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fring
if (sb_width > 0)
{
int bar_area_x = WINDOW_SCROLL_BAR_AREA_X (w);
- int bar_area_width = (WINDOW_CONFIG_SCROLL_BAR_COLS (w)
- * FRAME_COLUMN_WIDTH (f));
+ int bar_area_width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
if (bx < 0)
{
@@ -3121,8 +3142,7 @@ x_scroll_run (struct window *w, struct run *run)
if (sb_width > 0)
{
int bar_area_x = WINDOW_SCROLL_BAR_AREA_X (w);
- int bar_area_width = (WINDOW_CONFIG_SCROLL_BAR_COLS (w)
- * FRAME_COLUMN_WIDTH (f));
+ int bar_area_width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
if (bar_area_x + bar_area_width == x)
{
@@ -4945,7 +4965,7 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height)
/* Clear the area of W that will serve as a scroll bar. This is
for the case that a window has been split horizontally. In
this case, no clear_frame is generated to reduce flickering. */
- if (width > 0 && height > 0)
+ if (width > 0 && window_box_height (w) > 0)
x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
left, top, width, window_box_height (w));
@@ -5156,7 +5176,7 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio
/* Get window dimensions. */
window_box (w, ANY_AREA, 0, &window_y, 0, &window_height);
top = window_y;
- width = WINDOW_CONFIG_SCROLL_BAR_COLS (w) * FRAME_COLUMN_WIDTH (f);
+ width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
height = window_height;
/* Compute the left edge of the scroll bar area. */
@@ -5203,7 +5223,7 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio
unblock_input ();
}
- bar = x_scroll_bar_create (w, top, sb_left, sb_width, height);
+ bar = x_scroll_bar_create (w, top, sb_left, sb_width, max (height, 1));
}
else
{
@@ -5254,7 +5274,7 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio
previous mode line display is cleared after C-x 2 C-x 1, for
example. */
{
- int area_width = WINDOW_CONFIG_SCROLL_BAR_COLS (w) * FRAME_COLUMN_WIDTH (f);
+ int area_width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
int rest = area_width - sb_width;
if (rest > 0 && height > 0)
{
@@ -6722,8 +6742,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
{
#ifndef USE_X_TOOLKIT
#ifndef USE_GTK
- int rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, event->xconfigure.height);
- int columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, event->xconfigure.width);
+ int width = FRAME_PIXEL_TO_TEXT_WIDTH (f, event->xconfigure.width);
+ int height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, event->xconfigure.height);
/* In the toolkit version, change_frame_size
is called by the code that handles resizing
@@ -6732,12 +6752,12 @@ handle_one_xevent (struct x_display_info *dpyinfo,
/* Even if the number of character rows and columns has
not changed, the font size may have changed, so we need
to check the pixel dimensions as well. */
- if (columns != FRAME_COLS (f)
- || rows != FRAME_LINES (f)
+ if (width != FRAME_TEXT_WIDTH (f)
+ || height != FRAME_TEXT_HEIGHT (f)
|| event->xconfigure.width != FRAME_PIXEL_WIDTH (f)
|| event->xconfigure.height != FRAME_PIXEL_HEIGHT (f))
{
- change_frame_size (f, rows, columns, 0, 1, 0);
+ change_frame_size (f, width, height, 0, 1, 0, 1);
SET_FRAME_GARBAGED (f);
cancel_mouse_face (f);
}
@@ -7822,12 +7842,15 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0)
{
int wid = FRAME_COLUMN_WIDTH (f);
+
FRAME_CONFIG_SCROLL_BAR_COLS (f)
= (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + wid-1) / wid;
}
else
{
int wid = FRAME_COLUMN_WIDTH (f);
+
+ FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = 14;
FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
}
@@ -7837,7 +7860,7 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
doing it because it's done in Fx_show_tip, and it leads to
problems because the tip frame has no widget. */
if (NILP (tip_frame) || XFRAME (tip_frame) != f)
- x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
+ x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 1);
}
#ifdef HAVE_X_I18N
@@ -8652,11 +8675,11 @@ x_wait_for_event (struct frame *f, int eventtype)
size changes. Otherwise we leave the window gravity unchanged. */
static void
-x_set_window_size_1 (struct frame *f, int change_gravity, int cols, int rows)
+x_set_window_size_1 (struct frame *f, int change_gravity, int width, int height, bool pixelwise)
{
int pixelwidth, pixelheight;
- check_frame_size (f, &rows, &cols);
+ check_frame_size (f, &width, &height, pixelwise);
f->scroll_bar_actual_width
= (!FRAME_HAS_VERTICAL_SCROLL_BARS (f)
? 0
@@ -8664,9 +8687,11 @@ x_set_window_size_1 (struct frame *f, int change_gravity, int cols, int rows)
compute_fringe_widths (f, 0);
- pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, cols)
+ pixelwidth =
+ (pixelwise ? width : FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width))
+ FRAME_TOOLBAR_WIDTH (f);
- pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows)
+ pixelheight =
+ (pixelwise ? height : FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height))
+ FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f);
if (change_gravity) f->win_gravity = NorthWestGravity;
@@ -8702,7 +8727,7 @@ x_set_window_size_1 (struct frame *f, int change_gravity, int cols, int rows)
x_wait_for_event (f, ConfigureNotify);
else
{
- change_frame_size (f, rows, cols, 0, 1, 0);
+ change_frame_size (f, width, height, 0, 1, 0, 1);
FRAME_PIXEL_WIDTH (f) = pixelwidth;
FRAME_PIXEL_HEIGHT (f) = pixelheight;
x_sync (f);
@@ -8716,17 +8741,17 @@ x_set_window_size_1 (struct frame *f, int change_gravity, int cols, int rows)
Otherwise we leave the window gravity unchanged. */
void
-x_set_window_size (struct frame *f, int change_gravity, int cols, int rows)
+x_set_window_size (struct frame *f, int change_gravity, int width, int height, bool pixelwise)
{
block_input ();
if (NILP (tip_frame) || XFRAME (tip_frame) != f)
{
- int r, c;
+ int r, c, text_width, text_height;
/* When the frame is maximized/fullscreen or running under for
example Xmonad, x_set_window_size_1 will be a no-op.
- In that case, the right thing to do is extend rows/cols to
+ In that case, the right thing to do is extend rows/width to
the current frame size. We do that first if x_set_window_size_1
turns out to not be a no-op (there is no way to know).
The size will be adjusted again if the frame gets a
@@ -8737,23 +8762,25 @@ x_set_window_size (struct frame *f, int change_gravity, int cols, int rows)
is however. */
pixelh -= FRAME_MENUBAR_HEIGHT (f);
#endif
+ text_width = FRAME_PIXEL_TO_TEXT_WIDTH (f, FRAME_PIXEL_WIDTH (f));
+ text_height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixelh);
r = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, pixelh);
/* Update f->scroll_bar_actual_width because it is used in
FRAME_PIXEL_WIDTH_TO_TEXT_COLS. */
f->scroll_bar_actual_width
= FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f);
c = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, FRAME_PIXEL_WIDTH (f));
- change_frame_size (f, r, c, 0, 1, 0);
+ change_frame_size (f, text_width, text_height, 0, 1, 0, 1);
}
#ifdef USE_GTK
if (FRAME_GTK_WIDGET (f))
- xg_frame_set_char_size (f, cols, rows);
+ xg_frame_set_char_size (f, width, height);
else
- x_set_window_size_1 (f, change_gravity, cols, rows);
+ x_set_window_size_1 (f, change_gravity, width, height, pixelwise);
#else /* not USE_GTK */
- x_set_window_size_1 (f, change_gravity, cols, rows);
+ x_set_window_size_1 (f, change_gravity, width, height, pixelwise);
#endif /* not USE_GTK */
@@ -9439,7 +9466,7 @@ x_wm_set_size_hint (struct frame *f, long flags, bool user_position)
base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0);
base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0);
- check_frame_size (f, &min_rows, &min_cols);
+ check_frame_size (f, &min_cols, &min_rows, 0);
/* The window manager uses the base width hints to calculate the
current number of rows and columns in the frame while
@@ -10352,6 +10379,7 @@ static struct redisplay_interface x_redisplay_interface =
x_clear_frame_area,
x_draw_window_cursor,
x_draw_vertical_window_border,
+ x_draw_window_divider,
x_shift_glyphs_for_insert
};
diff --git a/src/xterm.h b/src/xterm.h
index 89676e873ae..88a0ae787aa 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -549,6 +549,7 @@ struct x_output
Cursor hand_cursor;
Cursor hourglass_cursor;
Cursor horizontal_drag_cursor;
+ Cursor vertical_drag_cursor;
Cursor current_cursor;
/* Window whose cursor is hourglass_cursor. This window is temporarily
@@ -930,7 +931,7 @@ extern void x_check_errors (Display *, const char *)
extern bool x_had_errors_p (Display *);
extern void x_uncatch_errors (void);
extern void x_clear_errors (Display *);
-extern void x_set_window_size (struct frame *, int, int, int);
+extern void x_set_window_size (struct frame *, int, int, int, bool);
extern void x_set_mouse_position (struct frame *, int, int);
extern void x_set_mouse_pixel_position (struct frame *, int, int);
extern void xembed_request_focus (struct frame *);