diff options
author | Martin Rudalics <rudalics@gmx.at> | 2014-07-27 15:21:30 +0200 |
---|---|---|
committer | Martin Rudalics <rudalics@gmx.at> | 2014-07-27 15:21:30 +0200 |
commit | 3477e27021dbe9366c3c1aaba80feb72f1138b29 (patch) | |
tree | c1ebfb6695e8d7f90ddad1a5bfaaf353be677514 /src/w32term.c | |
parent | 11fb71017b03f01a7e9e2db24973e756a41e16ec (diff) | |
download | emacs-3477e27021dbe9366c3c1aaba80feb72f1138b29.tar.gz emacs-3477e27021dbe9366c3c1aaba80feb72f1138b29.tar.bz2 emacs-3477e27021dbe9366c3c1aaba80feb72f1138b29.zip |
Complete pixelwise frame/window resizing, add horizontal scrollbar support.
* frame.el (frame-notice-user-settings): Rewrite using
frame-initial-frame-tool-bar-height.
* menu-bar.el (menu-bar-horizontal-scroll-bar)
(menu-bar-no-horizontal-scroll-bar): New functions.
(menu-bar-showhide-scroll-bar-menu): Add bindings for horizontal
scroll bars.
* scroll-bar.el (scroll-bar-lines)
(set-horizontal-scroll-bar-mode)
(get-horizontal-scroll-bar-mode, horizontal-scroll-bar-mode)
(scroll-bar-horizontal-drag-1, scroll-bar-horizontal-drag)
(scroll-bar-toolkit-horizontal-scroll): New functions.
(horizontal-scroll-bar-mode)
(previous-horizontal-scroll-bar-mode)
(horizontal-scroll-bar-mode-explicit): New variables.
(horizontal-scroll-bar-mode): New option.
(toggle-horizontal-scroll-bar): Do something.
(top-level): Bind horizontal-scroll-bar mouse-1.
* startup.el (tool-bar-originally-present): Remove variable.
(command-line): Don't set tool-bar-originally-present.
* window.el (window-min-height): Update doc-string.
(window--dump-frame): Dump horizontal scroll bar values.
(window--min-size-1): Handle minibuffer window separately.
Count in margins and horizontal scroll bar. Return safe value
iff IGNORE equals 'safe.
(frame-windows-min-size): New function (used by frame resizing
routines).
(fit-frame-to-buffer, fit-window-to-buffer): Count in horizontal
scroll bars.
(window--sanitize-window-sizes): New function.
(window-split-min-size): Remove.
(split-window): Count divider-width. Don't use
`window-split-min-size' any more. Reword error messages.
Sanitize windows sizes after splitting.
* buffer.h (struct buffer): New fields scroll_bar_height and
horizontal_scroll_bar_type.
* buffer.c (bset_scroll_bar_height)
(bset_horizontal_scroll_bar_type): New functions.
(Fbuffer_swap_text): Handle old_pointm field.
(init_buffer_once): Set defaults for scroll_bar_height and
horizontal_scroll_bar_type.
(syms_of_buffer): New variables scroll_bar_height and
horizontal_scroll_bar_type.
* dispextern.h (window_part): Rename ON_SCROLL_BAR to
ON_VERTICAL_SCROLL_BAR. Add ON_HORIZONTAL_SCROLL_BAR.
(set_vertical_scroll_bar): Remove prototype.
(x_change_tool_bar_height): Add prototype.
* dispnew.c (adjust_frame_glyphs_for_frame_redisplay)
(window_to_frame_vpos, update_frame_1, scrolling, init_display):
Use FRAME_TOTAL_COLS and FRAME_TOTAL_LINES instead of FRAME_COLS
and FRAME_LINES.
(adjust_frame_glyphs_for_window_redisplay): Rearrange lines.
(update_window): Start mode_line_row->y after horizontal scroll
bar.
(change_frame_size_1): Call adjust_frame_size.
(init_display): When changing the size of a tty frame do not
pass height of menu bar.
(Qframe_windows_min_size): New symbol.
* frame.h (struct frame): List tool bar fields after menu bar
fields. Add official, total_lines, horizontal_scroll_bars,
config_scroll_bar_height and config_scroll_bar_lines fields.
(FRAME_HAS_HORIZONTAL_SCROLL_BARS)
(FRAME_CONFIG_SCROLL_BAR_HEIGHT, FRAME_CONFIG_SCROLL_BAR_LINES)
(FRAME_SCROLL_BAR_AREA_HEIGHT, FRAME_SCROLL_BAR_COLS)
(FRAME_SCROLL_BAR_LINES, FRAME_TOTAL_LINES, SET_FRAME_LINES)
(FRAME_WINDOWS_HEIGHT): New macros.
(SET_FRAME_HEIGHT, FRAME_TEXT_LINES_TO_PIXEL_HEIGHT)
(FRAME_PIXEL_Y_TO_LINE, FRAME_PIXEL_HEIGHT_TO_TEXT_LINES)
(FRAME_TEXT_TO_PIXEL_HEIGHT): Separately count top margin and
horizontal scroll bar.
(frame_inhibit_resize, adjust_frame_size)
(frame_windows_min_size): Add declarations.
(Qscroll_bar_height, Qhorizontal_scroll_bars)
(x_set_scroll_bar_default_height, x_set_left_fringe)
(x_set_right_fringe, x_set_vertical_scroll_bars)
(x_set_horizontal_scroll_bars, x_set_scroll_bar_width)
(x_set_scroll_bar_height): Add external declarations.
* frame.c: (frame_inhibit_resize, frame_windows_min_size)
(adjust_frame_size): New functions.
(make_frame): Initial horizontal_scroll_bars field. Use
SET_FRAME_LINES. Don't allow horizontal scroll bar in
minibuffer window.
(make_initial_frame, make_terminal_frame): No horizontal scroll
bar in initial and terminal frames. Use adjust_frame_size.
(Fframe_total_cols): Fix doc-string.
(Fframe_total_lines, Fscroll_bar_height): New Lisp functions.
(Fset_frame_height, Fset_frame_width, Fset_frame_size): Rewrite
using adjust_frame_size.
(Qscroll_bar_height, Qhorizontal_scroll_bars)
(Qframe_windows_min_size): New symbols.
(x_set_frame_parameters): Remove call of check_frame_size.
(x_report_frame_params): Return scroll_bar_height value.
(x_set_left_fringe, x_set_right_fringe): New functions.
(adjust_frame_height, x_set_internal_border_width)
(x_set_fringe_width): Remove.
(x_set_internal_border_width, x_set_vertical_scroll_bars)
(x_set_scroll_bar_width, x_set_right_divider_width)
(x_set_bottom_divider_width): Rewrite using adjust_frame_size.
(x_set_horizontal_scroll_bars, x_set_scroll_bar_height): New
functions.
(x_figure_window_size): Rewrite to make frame display the
expected number of lines.
(Vdefault_frame_scroll_bars): Rewrite doc-string.
(Vdefault_frame_horizontal_scroll_bars)
(Vframe_initial_frame_tool_bar_height)
(frame_inhibit_implied_resize): New variables.
* fringe.c (compute_fringe_widths): Remove.
* gtkutil.h (YG_SB_MIN, YG_SB_MAX, YG_SB_RANGE): Define.
(xg_create_horizontal_scroll_bar)
(xg_update_horizontal_scrollbar_pos)
(xg_set_toolkit_horizontal_scroll_bar_thumb)
(xg_get_default_scrollbar_height)
(xg_clear_under_internal_border): Extern.
* gtkutil.c (xg_frame_resized): Don't call
do_pending_window_change.
(xg_frame_set_char_size): Use adjust_frame_size.
(style_changed_cb): Call update_theme_scrollbar_height and
x_set_scroll_bar_default_height.
(x_wm_set_size_hint): Don't call check_frame_size.
(update_theme_scrollbar_height)
(xg_get_default_scrollbar_height)
(xg_create_horizontal_scroll_bar)
(xg_update_horizontal_scrollbar_pos)
(xg_set_toolkit_horizontal_scroll_bar_thumb): New functions.
(xg_create_scroll_bar): Set horizontal slot of bar.
(xg_initialize): Call update_theme_scrollbar_height.
(xg_clear_under_internal_border): No more static.
* insdel.c (adjust_suspend_auto_hscroll): New function.
(adjust_markers_for_delete, adjust_markers_for_insert)
(adjust_markers_for_replace): Call adjust_suspend_auto_hscroll.
* keyboard.c (readable_events, discard_mouse_events)
(make_lispy_event): Handle horizontal scroll bar click events.
(Fsuspend_emacs): When changing the size of a tty frame do not
pass height of menu bar.
(Qbefore_handle, Qhorizontal_handle, Qafter_handle, Qleft)
(Qright, Qleftmost, Qrightmost): New symbols.
* menu.c (Fx_popup_dialog): Use FRAME_TOTAL_LINES instead of
FRAME_LINES.
* minibuf.c (read_minibuf): Initialize suspend_auto_hscroll.
* nsfns.m (x_set_internal_border_width): New function.
* nsterm.m (ns_draw_fringe_bitmap, ns_set_vertical_scroll_bar):
Remove extended fringe code.
(x_set_window_size, x_new_font): Don't call
compute_fringe_widths.
* term.c (Fresume_tty): When changing the size of a tty frame do
not pass height of menu bar.
(clear_tty_hooks, set_tty_hooks): Clear
horizontal_scroll_bar_hook.
(init_tty): Frame has no horizontal scroll bars.
* termhooks.h (enum scroll_bar_part): Add scroll_bar_move_ratio,
scroll_bar_before_handle, scroll_bar_horizontal_handle,
scroll_bar_after_handle, scroll_bar_left_arrow,
scroll_bar_right_arrow, scroll_bar_to_leftmost and
scroll_bar_to_rightmost entries.
(enum event_kind): Add HORIZONTAL_SCROLL_BAR_CLICK_EVENT
(struct terminal): Add set_horizontal_scroll_bar_hook.
* w32console.c (initialize_w32_display): Clear
horizontal_scroll_bar_hook.
* w32fns.c (x_set_mouse_color): Use FRAME_W32_DISPLAY instead of
FRAME_X_DISPLAY.
(x_clear_under_internal_border, x_set_internal_border_width):
New functions.
(x_set_menu_bar_lines): Rewrite using frame_inhibit_resize. Set
windows_or_buffers_changed when adding the menu bar.
(x_set_tool_bar_lines): Rewrite using adjust_frame_size.
(x_change_tool_bar_height, x_set_scroll_bar_default_height)
(w32_createhscrollbar): New functions.
(w32_createscrollbar): Rename to w32_createvscrollbar.
(w32_createwindow): Init WND_HSCROLLBAR_INDEX.
(w32_name_of_message): Replace WM_EMACS_CREATESCROLLBAR by
WM_EMACS_CREATEVSCROLLBAR and WM_EMACS_CREATEHSCROLLBAR. Add
WM_EMACS_SHOWCURSOR.
(w32_wnd_proc): Handle WM_HSCROLL case. In WM_WINDOWPOSCHANGING
case do not artificially impose WM size hints. Handle
WM_EMACS_SHOWCURSOR case. Replace WM_EMACS_CREATESCROLLBAR case
by WM_EMACS_CREATEVSCROLLBAR and WM_EMACS_CREATEHSCROLLBAR
cases.
(my_create_tip_window): Replace WND_SCROLLBAR_INDEX by
WND_VSCROLLBAR_INDEX and WND_HSCROLLBAR_INDEX.
(unwind_create_frame_1): Remove.
(Fx_create_frame): Make both scrollbars the system standard
width and height. Use official field of frame structure to
inhibit running window-configuration-change-hook.
(x_create_tip_frame): Call SET_FRAME_LINES and change_frame_size
pixelwise. Handle frame's official field.
(w32_frame_parm_handlers): Remove x_set_fringe_width
entries. Add x_set_scroll_bar_height,
x_set_horizontal_scroll_bars, x_set_left_fringe and
x_set_right_fringe.
* w32inevt.c (resize_event, maybe_generate_resize_event): Do not
pass height of menu bar to change_frame_size.
* w32menu.c (set_frame_menubar): Rewrite using
frame_inhibit_resize.
* w32term.h (struct w32_display_info): Add
horizontal_scroll_bar_cursor and cursor_display_counter.
(struct scroll_bar): Add horizontal.
(HORIZONTAL_SCROLL_BAR_INSIDE_HEIGHT)
(HORIZONTAL_SCROLL_BAR_LEFT_RANGE)
(HORIZONTAL_SCROLL_BAR_INSIDE_WIDTH)
(HORIZONTAL_SCROLL_BAR_LEFT_BORDER)
(HORIZONTAL_SCROLL_BAR_RIGHT_BORDER)
(HORIZONTAL_SCROLL_BAR_TOP_BORDER)
(HORIZONTAL_SCROLL_BAR_BOTTOM_BORDER)
(HORIZONTAL_SCROLL_BAR_MIN_HANDLE): New macros.
(WM_EMACS_CREATEVSCROLLBAR, WM_EMACS_CREATEHSCROLLBAR): Define
instead of WM_EMACS_CREATESCROLLBAR.
(WND_VSCROLLBAR_INDEX, WND_HSCROLLBAR_INDEX): Define instead of
WND_SCROLLBAR_INDEX.
* w32term.c (horizontal_scroll_bar_min_handle)
(horizontal_scroll_bar_left_border)
(horizontal_scroll_bar_right_border): New integers.
(x_set_frame_alpha): Replace x_highlight_frame by
w32_focus_frame.
(x_window_to_scroll_bar): New argument "type". Update callers
accordingly.
(w32_set_horizontal_scroll_bar_thumb)
(x_horizontal_scroll_bar_report_motion)
(w32_set_horizontal_scroll_bar)
(w32_horizontal_scroll_bar_handle_click)
(x_horizontal_scroll_bar_report_motion): New functions.
(w32_mouse_position): Discriminate horizontal and vertical
scrollbar cases.
(my_create_scrollbar): Replace with two new functions
my_create_vscrollbar and my_create_hscrollbar.
(x_scroll_bar_create): New argument "horizontal". Update
callers accordingly.
(x_scroll_bar_remove, w32_condemn_scroll_bars)
(w32_redeem_scroll_bar, x_scroll_bar_clear): Handle horizontal
scroll bar case.
(w32_read_socket): Handle WM_HSCROLL cae.
(x_new_font): Don't recompute fringe widths. Use
frame_inhibit_resize. Calculate new menu bar height iff we
build without toolkit. Always clear under internal border.
(x_set_window_size): Don't check frame size or recompute
fringes. Reset fullscreen status before applying sizes. Always
resize as requested by pixelwise argument. Don't call
do_pending_window_change.
(x_wm_set_size_hint): Add call for FRAME_SCROLL_BAR_AREA_HEIGHT.
(w32_initialize_display_info): Initialize dpyinfo's
horizontal_scroll_bar_cursor entry.
(w32_create_terminal): Add set_horizontal_scroll_bar_hook.
(w32_initialize): Init horizontal_scroll_bar_min_handle and
horizontal_scroll_bar_left_border.
(w32fullscreen_hook): Intermittently resize window to normal
when switching from fullscreen to maximized state.
(run_window_configuration_change_hook): Don't run it if frame is
not official yet.
(unwind_change_frame): Remove.
(Fset_window_configuration): Rewrite using frame's official field.
* widget.c (set_frame_size): Don't call compute_fringe_widths.
(EmacsFrameSetCharSize): Obey frame_inhibit_resize.
* window.h (struct window): New fields old_pointm,
horizontal_scroll_bar, horizontal_scroll_bar_type, hscroll_whole,
scroll_bar_height and suspend_auto_hscroll.
(wset_horizontal_scroll_bar, wset_horizontal_scroll_bar_type):
New functions.
(sanitize_window_sizes): Extern.
(MINI_NON_ONLY_WINDOW_P, MINI_ONLY_WINDOW_P, WINDOW_PSEUDO_P)
(WINDOW_TOPMOST_P, WINDOW_HAS_HORIZONTAL_SCROLL_BAR)
(WINDOW_CONFIG_SCROLL_BAR_HEIGHT)
(WINDOW_CONFIG_SCROLL_BAR_LINES)
(WINDOW_SCROLL_BAR_LINES, WINDOW_SCROLL_BAR_AREA_HEIGHT): New
macros.
(WINDOW_LEFT_FRINGE_COLS, WINDOW_RIGHT_FRINGE_COLS)
(WINDOW_FRINGE_COLS, WINDOW_FRINGE_EXTENDED_P): Remove macros.
(WINDOW_VERTICAL_SCROLL_BAR_TYPE)
(WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT)
(WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT)
(WINDOW_HAS_VERTICAL_SCROLL_BAR): Minor rewrite.
(WINDOW_BOX_HEIGHT_NO_MODE_LINE, WINDOW_BOX_TEXT_HEIGHT)
(WINDOW_SCROLL_BAR_AREA_Y): Count in scroll bar height.
* window.c (wset_old_pointm, Fwindow_scroll_bar_height)
(Fwindow_old_point, sanitize_window_sizes): New functions.
(Qwindow_sanitize_window_sizes): New symbol.
(window_body_height): Count in horizontal scroll bar.
(set_window_hscroll, Fscroll_left, Fscroll_right): Set
suspend_auto_hscroll slot.
(Fwindow_inside_edges): Count fringes pixelwise.
(coordinates_in_window, Fcoordinates_in_window_p): Consider
horizontal scroll bar.
(check_frame_size, adjust_window_margins): Remove functions and
corresponding calls.
(set_window_buffer): Initialize old_pointm and horizontal scroll
bars.
(temp_output_buffer_show): Reset hscroll related fields.
Initialize old_pointm.
(make_parent_window): Initialize old_pointm.
(make_window): Initialize old_pointm, horizontal scroll bar type,
and scroll bar height.
(resize_frame_windows): Don't count top margin in new sizes.
Don't use safe sizes when shrinking a frame; let the window
manager do the clipping.
(Fsplit_window_internal): Inherit horizontal scroll bar type and
height.
(Fdelete_window_internal): Unchain old_pointm marker.
(window_scroll_pixel_based, Fscroll_other_window): Adjust
old_pointm.
(Fwindow_text_width, Fwindow_text_height): New argument
"pixelwise".
(struct saved_window): New fields, old_pointm, hscroll_whole,
suspend_auto_hscroll, scroll_bar_height and
horizontal_scroll_bar_type.
(Fset_window_configuration, save_window_save): Set new fields of
saved_window.
(apply_window_adjustment): Don't call adjust_window_margins.
(set_window_margins): Don't change margins if new sizes don't
fit into window.
(set_window_scroll_bars): New argument "horizontal_type".
Handle horizontal scroll bars. Don't change scroll bars if they
don't fit into window.
(Fset_window_scroll_bars): New argument "horizontal_type".
(Fwindow_scroll_bars): Return values for horizontal scroll bars.
(compare_window_configurations): Compare horizontal scroll bar
settings.
* xdisp.c (window_text_bottom_y, window_box_height): Count in
horizontal scroll bar height.
(pixel_to_glyph_coords, init_xdisp): Use FRAME_TOTAL_LINES
instead of FRAME_LINES.
(remember_mouse_glyph): Case ON_SCROLL_BAR changed to
ON_VERTICAL_SCROLL_BAR.
(with_echo_area_buffer): Initialize old_pointm.
(with_echo_area_buffer_unwind_data): Store old_pointm values in
vector.
(unwind_with_echo_area_buffer): Handle old_pointm.
(update_tool_bar): Set do_update when the tool bar window has at
least one line (since this is what the user sets).
(MAX_FRAME_TOOL_BAR_HEIGHT): Remove macro.
(redisplay_tool_bar): Return early when toolbar has zero lines.
Call x_change_tool_bar_height. Don't use max_tool_bar_height.
(hscroll_window_tree): Handle suspension of auto_hscroll and
old_pointm.
(set_horizontal_scroll_bar): New function.
(redisplay_window): Set ignore_mouse_drag_p when tool bar has
more than one line. Handle horizontal scroll bars.
(note_mouse_highlight): Handle horizontal scrol bars.
(expose_frame): Set dimensions of XRectangle from frame's text
sizes.
(Vvoid_text_area_pointer): Update doc-string.
* xfns.c (x_set_menu_bar_lines): Use adjust_frame_size.
(x_change_tool_bar_height, x_set_scroll_bar_default_height)
(x_set_internal_border_width): New functions.
(x_set_tool_bar_lines): Call x_change_tool_bar_height.
(unwind_create_frame_1): Remove.
(Fx_create_frame): Handle horizontal scroll bars. Use official
field of frame structure to inhibit running
window-configuration-change-hook.
(x_create_tip_frame): Call SET_FRAME_LINES and change_frame_size
pixelwise. Handle frame's official field.
(x_frame_parm_handlers): Add x_set_scroll_bar_height,
x_set_horizontal_scroll_bars, x_set_left_fringe,
x_set_right_fringe.
* xmenu.c (update_frame_menubar, free_frame_menubar): Use
adjust_frame_size.
* xterm.h (struct x_display_info): Add
horizontal_scroll_bar_cursor and Xatom_Horizontal_Scrollbar
slots.
(struct scroll_bar): Add horizontal slot.
(HORIZONTAL_SCROLL_BAR_INSIDE_HEIGHT)
(HORIZONTAL_SCROLL_BAR_LEFT_RANGE)
(HORIZONTAL_SCROLL_BAR_INSIDE_WIDTH): New macros.
(HORIZONTAL_SCROLL_BAR_LEFT_BORDER)
(HORIZONTAL_SCROLL_BAR_RIGHT_BORDER)
(HORIZONTAL_SCROLL_BAR_TOP_BORDER)
(HORIZONTAL_SCROLL_BAR_BOTTOM_BORDER)
(HORIZONTAL_SCROLL_BAR_MIN_HANDLE): Define.
(x_clear_under_internal_border): Remove.
* xterm.c (XTmouse_position): Handle horizontal scroll bars.
(x_window_to_scroll_bar): New argument TYPE. Update callers.
(x_send_scroll_bar_event, x_scroll_bar_create): New arguments
HORIZONTAL. Update callers.
(horizontal_action_hook_id): New action hook id.
(x_horizontal_scroll_bar_to_input_event)
(x_create_horizontal_toolkit_scroll_bar)
(xt_horizontal_action_hook)
(x_set_toolkit_horizontal_scroll_bar_thumb)
(XTset_horizontal_scroll_bar, x_net_wm_state)
(x_horizontal_scroll_bar_report_motion): New functions.
(xg_scroll_callback, x_scroll_bar_handle_click): Handle
horizontal scroll bars.
(SCROLL_BAR_HORIZONTAL_NAME): Define.
(XTset_vertical_scroll_bar): Attempt to clear areas not covered
by scroll bar.
(XTcondemn_scroll_bars, XTredeem_scroll_bar): Rewrite. Handle
horizontal scroll bars.
(handle_one_xevent): Handle horizontal scroll bar events. Call
x_net_wm_state.
(x_set_window_size_1, x_wm_set_size_hint): Don't call
check_frame_size.
(x_set_window_size): Don't call check_frame_size and
do_pending_window_change.
(x_term_init): Init horizontal_scroll_bar_cursor display info.
(x_create_terminal): Add set_horizontal_scroll_bar_hook.
(x_scroll_bar_set_handle): Add some checks when calling
x_clear_area.
Diffstat (limited to 'src/w32term.c')
-rw-r--r-- | src/w32term.c | 615 |
1 files changed, 489 insertions, 126 deletions
diff --git a/src/w32term.c b/src/w32term.c index fd902ee7cd5..dfda29fb903 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -158,8 +158,11 @@ DWORD dwMainThreadId = 0; HANDLE hMainThread = NULL; int vertical_scroll_bar_min_handle; +int horizontal_scroll_bar_min_handle; int vertical_scroll_bar_top_border; int vertical_scroll_bar_bottom_border; +int horizontal_scroll_bar_left_border; +int horizontal_scroll_bar_right_border; int last_scroll_bar_drag_pos; @@ -455,7 +458,7 @@ x_set_frame_alpha (struct frame *f) if (!pfnSetLayeredWindowAttributes) return; - if (dpyinfo->x_highlight_frame == f) + if (dpyinfo->w32_focus_frame == f) alpha = f->alpha[0]; else alpha = f->alpha[1]; @@ -3337,11 +3340,15 @@ note_mouse_movement (struct frame *frame, MSG *msg) Mouse Face ************************************************************************/ -static struct scroll_bar *x_window_to_scroll_bar (Window); +static struct scroll_bar *x_window_to_scroll_bar (Window, int); static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *, enum scroll_bar_part *, Lisp_Object *, Lisp_Object *, unsigned long *); +static void x_horizontal_scroll_bar_report_motion (struct frame **, Lisp_Object *, + enum scroll_bar_part *, + Lisp_Object *, Lisp_Object *, + unsigned long *); static void x_check_fullscreen (struct frame *); static void @@ -3349,6 +3356,7 @@ w32_define_cursor (Window window, Cursor cursor) { PostMessage (window, WM_EMACS_SETCURSOR, (WPARAM) cursor, 0); } + /* Return the current position of the mouse. *fp should be a frame which indicates which display to ask about. @@ -3380,7 +3388,14 @@ w32_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window, block_input (); if (dpyinfo->last_mouse_scroll_bar && insist == 0) - x_scroll_bar_report_motion (fp, bar_window, part, x, y, time); + { + struct scroll_bar *bar = dpyinfo->last_mouse_scroll_bar; + + if (bar->horizontal) + x_horizontal_scroll_bar_report_motion (fp, bar_window, part, x, y, time); + else + x_scroll_bar_report_motion (fp, bar_window, part, x, y, time); + } else { POINT pt; @@ -3408,7 +3423,7 @@ w32_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window, if (! f1) { struct scroll_bar *bar - = x_window_to_scroll_bar (WindowFromPoint (pt)); + = x_window_to_scroll_bar (WindowFromPoint (pt), 2); if (bar) f1 = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); @@ -3475,12 +3490,12 @@ w32_handle_tool_bar_click (struct frame *f, struct input_event *button_event) /* Scroll bar support. */ -/* Given a window ID, find the struct scroll_bar which manages it. - This can be called in GC, so we have to make sure to strip off mark - bits. */ +/* Given a window ID, find the struct scroll_bar which manages it + vertically. This can be called in GC, so we have to make sure to + strip off mark bits. */ static struct scroll_bar * -x_window_to_scroll_bar (Window window_id) +x_window_to_scroll_bar (Window window_id, int type) { Lisp_Object tail, frame; @@ -3498,7 +3513,10 @@ x_window_to_scroll_bar (Window window_id) condemned = Qnil, ! NILP (bar)); bar = XSCROLL_BAR (bar)->next) - if (SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar)) == window_id) + if (SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar)) == window_id + && (type = 2 + || (type == 1 && XSCROLL_BAR (bar)->horizontal) + || (type == 0 && !XSCROLL_BAR (bar)->horizontal))) return XSCROLL_BAR (bar); } @@ -3507,7 +3525,7 @@ x_window_to_scroll_bar (Window window_id) -/* Set the thumb size and position of scroll bar BAR. We are currently +/* Set the thumb size and position of vertical scroll bar BAR. We are currently displaying PORTION out of a whole WHOLE, and our position POSITION. */ static void @@ -3581,16 +3599,49 @@ w32_set_scroll_bar_thumb (struct scroll_bar *bar, unblock_input (); } +/* Set the thumb size and position of horizontal scroll bar BAR. We are currently + displaying PORTION out of a whole WHOLE, and our position POSITION. */ + +static void +w32_set_horizontal_scroll_bar_thumb (struct scroll_bar *bar, + int portion, int position, int whole) +{ + Window w = SCROLL_BAR_W32_WINDOW (bar); + SCROLLINFO si; + + block_input (); + + si.cbSize = sizeof (si); + si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE; + si.nMin = 0; + si.nMax = whole; + /* Allow nPage to be one larger than nPos so we don't allow to scroll + an already fully visible buffer. */ + si.nPage = min (portion, si.nMax) + 1; + si.nPos = min (position, si.nMax); + SetScrollInfo (w, SB_CTL, &si, TRUE); + + unblock_input (); +} + /************************************************************************ Scroll bars, general ************************************************************************/ static HWND -my_create_scrollbar (struct frame * f, struct scroll_bar * bar) +my_create_vscrollbar (struct frame * f, struct scroll_bar * bar) +{ + return (HWND) SendMessage (FRAME_W32_WINDOW (f), + WM_EMACS_CREATEVSCROLLBAR, (WPARAM) f, + (LPARAM) bar); +} + +static HWND +my_create_hscrollbar (struct frame * f, struct scroll_bar * bar) { return (HWND) SendMessage (FRAME_W32_WINDOW (f), - WM_EMACS_CREATESCROLLBAR, (WPARAM) f, + WM_EMACS_CREATEHSCROLLBAR, (WPARAM) f, (LPARAM) bar); } @@ -3660,7 +3711,7 @@ my_bring_window_to_top (HWND hwnd) scroll bar. */ static struct scroll_bar * -x_scroll_bar_create (struct window *w, int top, int left, int width, int height) +x_scroll_bar_create (struct window *w, int left, int top, int width, int height, bool horizontal) { struct frame *f = XFRAME (WINDOW_FRAME (w)); HWND hwnd; @@ -3679,16 +3730,24 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height) bar->start = 0; bar->end = 0; bar->dragging = 0; + bar->horizontal = horizontal; /* Requires geometry to be set before call to create the real window */ - hwnd = my_create_scrollbar (f, bar); + if (horizontal) + hwnd = my_create_hscrollbar (f, bar); + else + hwnd = my_create_vscrollbar (f, bar); si.cbSize = sizeof (si); si.fMask = SIF_ALL; si.nMin = 0; - si.nMax = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height) - + VERTICAL_SCROLL_BAR_MIN_HANDLE; + if (horizontal) + si.nMax = HORIZONTAL_SCROLL_BAR_LEFT_RANGE (f, width) + + HORIZONTAL_SCROLL_BAR_MIN_HANDLE; + else + si.nMax = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height) + + VERTICAL_SCROLL_BAR_MIN_HANDLE; si.nPage = si.nMax; si.nPos = 0; @@ -3724,15 +3783,18 @@ x_scroll_bar_remove (struct scroll_bar *bar) my_destroy_window (f, SCROLL_BAR_W32_WINDOW (bar)); /* Dissociate this scroll bar from its window. */ - wset_vertical_scroll_bar (XWINDOW (bar->window), Qnil); + if (bar->horizontal) + wset_horizontal_scroll_bar (XWINDOW (bar->window), Qnil); + else + wset_vertical_scroll_bar (XWINDOW (bar->window), Qnil); unblock_input (); } -/* Set the handle of the vertical scroll bar for WINDOW to indicate - that we are displaying PORTION characters out of a total of WHOLE - characters, starting at POSITION. If WINDOW has no scroll bar, - create one. */ +/* Set the handle of the vertical scroll bar for WINDOW to indicate that + we are displaying PORTION characters out of a total of WHOLE + characters, starting at POSITION. If WINDOW has no vertical scroll + bar, create one. */ static void w32_set_vertical_scroll_bar (struct window *w, int portion, int whole, int position) @@ -3765,7 +3827,7 @@ w32_set_vertical_scroll_bar (struct window *w, } unblock_input (); - bar = x_scroll_bar_create (w, top, left, width, height); + bar = x_scroll_bar_create (w, left, top, width, height, 0); } else { @@ -3829,6 +3891,106 @@ w32_set_vertical_scroll_bar (struct window *w, wset_vertical_scroll_bar (w, barobj); } +/* Set the handle of the horizontal scroll bar for WINDOW to indicate + that we are displaying PORTION characters out of a total of WHOLE + characters, starting at POSITION. If WINDOW has no horizontal scroll + bar, create one. */ +static void +w32_set_horizontal_scroll_bar (struct window *w, + int portion, int whole, int position) +{ + struct frame *f = XFRAME (w->frame); + Lisp_Object barobj; + struct scroll_bar *bar; + int top, height, left, width; + int window_x, window_width; + int clear_left = WINDOW_LEFT_EDGE_X (w); + int clear_width = WINDOW_PIXEL_WIDTH (w) - WINDOW_RIGHT_DIVIDER_WIDTH (w); + + /* Get window dimensions. */ + window_box (w, ANY_AREA, &window_x, 0, &window_width, 0); + left = window_x; + height = WINDOW_SCROLL_BAR_AREA_HEIGHT (w); + width = window_width; + top = WINDOW_SCROLL_BAR_AREA_Y (w); + + /* Does the scroll bar exist yet? */ + if (NILP (w->horizontal_scroll_bar)) + { + HDC hdc; + block_input (); + if (width > 0 && height > 0) + { + hdc = get_frame_dc (f); + w32_clear_area (f, hdc, clear_left, top, clear_width, height); + release_frame_dc (f, hdc); + } + unblock_input (); + + bar = x_scroll_bar_create (w, left, top, width, height, 1); + } + else + { + /* It may just need to be moved and resized. */ + HWND hwnd; + + bar = XSCROLL_BAR (w->horizontal_scroll_bar); + hwnd = SCROLL_BAR_W32_WINDOW (bar); + + /* If already correctly positioned, do nothing. */ + if (bar->left == left && bar->top == top + && bar->width == width && bar->height == height) + { + /* Redraw after clear_frame. */ + if (!my_show_window (f, hwnd, SW_NORMAL)) + InvalidateRect (hwnd, NULL, FALSE); + } + else + { + HDC hdc; + SCROLLINFO si; + + block_input (); + if (width && height) + { + hdc = get_frame_dc (f); + /* Since Windows scroll bars are smaller than the space reserved + for them on the frame, we have to clear "under" them. */ + w32_clear_area (f, hdc, clear_left, top, clear_width, height); + release_frame_dc (f, hdc); + } + /* Make sure scroll bar is "visible" before moving, to ensure the + area of the parent window now exposed will be refreshed. */ + my_show_window (f, hwnd, SW_HIDE); + MoveWindow (hwnd, left, top, width, max (height, 1), TRUE); + + /* +++ SetScrollInfo +++ */ + si.cbSize = sizeof (si); + si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE; + si.nMin = 0; + si.nMax = whole; + si.nPage = min (portion, si.nMax) + 1; + si.nPos = min (position, si.nMax); + SetScrollInfo (hwnd, SB_CTL, &si, FALSE); + + my_show_window (f, hwnd, SW_NORMAL); + /* InvalidateRect (w, NULL, FALSE); */ + + /* Remember new settings. */ + bar->left = left; + bar->top = top; + bar->width = width; + bar->height = height; + + unblock_input (); + } + } + + w32_set_horizontal_scroll_bar_thumb (bar, portion, position, whole); + XSETVECTOR (barobj, bar); + wset_horizontal_scroll_bar (w, barobj); +} + /* The following three hooks are used when we're doing a thorough redisplay of the frame. We don't explicitly know which scroll bars @@ -3845,17 +4007,22 @@ w32_set_vertical_scroll_bar (struct window *w, static void w32_condemn_scroll_bars (struct frame *frame) { - /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */ - while (! NILP (FRAME_SCROLL_BARS (frame))) + if (!NILP (FRAME_SCROLL_BARS (frame))) { - Lisp_Object bar; - bar = FRAME_SCROLL_BARS (frame); - fset_scroll_bars (frame, XSCROLL_BAR (bar)->next); - XSCROLL_BAR (bar)->next = FRAME_CONDEMNED_SCROLL_BARS (frame); - XSCROLL_BAR (bar)->prev = Qnil; - if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame))) - XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame))->prev = bar; - fset_condemned_scroll_bars (frame, bar); + if (!NILP (FRAME_CONDEMNED_SCROLL_BARS (frame))) + { + /* Prepend scrollbars to already condemned ones. */ + Lisp_Object last = FRAME_SCROLL_BARS (frame); + + while (!NILP (XSCROLL_BAR (last)->next)) + last = XSCROLL_BAR (last)->next; + + XSCROLL_BAR (last)->next = FRAME_CONDEMNED_SCROLL_BARS (frame); + XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame))->prev = last; + } + + fset_condemned_scroll_bars (frame, FRAME_SCROLL_BARS (frame)); + fset_scroll_bars (frame, Qnil); } } @@ -3864,47 +4031,84 @@ w32_condemn_scroll_bars (struct frame *frame) Note that WINDOW isn't necessarily condemned at all. */ static void -w32_redeem_scroll_bar (struct window *window) +w32_redeem_scroll_bar (struct window *w) { struct scroll_bar *bar; Lisp_Object barobj; struct frame *f; /* We can't redeem this window's scroll bar if it doesn't have one. */ - if (NILP (window->vertical_scroll_bar)) + if (NILP (w->vertical_scroll_bar) && NILP (w->horizontal_scroll_bar)) emacs_abort (); - bar = XSCROLL_BAR (window->vertical_scroll_bar); - - /* Unlink it from the condemned list. */ - f = XFRAME (WINDOW_FRAME (window)); - if (NILP (bar->prev)) + if (!NILP (w->vertical_scroll_bar) && WINDOW_HAS_VERTICAL_SCROLL_BAR (w)) { - /* If the prev pointer is nil, it must be the first in one of - the lists. */ - if (EQ (FRAME_SCROLL_BARS (f), window->vertical_scroll_bar)) - /* It's not condemned. Everything's fine. */ - return; - else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f), - window->vertical_scroll_bar)) - fset_condemned_scroll_bars (f, bar->next); + bar = XSCROLL_BAR (w->vertical_scroll_bar); + /* Unlink it from the condemned list. */ + f = XFRAME (WINDOW_FRAME (w)); + if (NILP (bar->prev)) + { + /* If the prev pointer is nil, it must be the first in one of + the lists. */ + if (EQ (FRAME_SCROLL_BARS (f), w->vertical_scroll_bar)) + /* It's not condemned. Everything's fine. */ + goto horizontal; + else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f), + w->vertical_scroll_bar)) + fset_condemned_scroll_bars (f, bar->next); + else + /* If its prev pointer is nil, it must be at the front of + one or the other! */ + emacs_abort (); + } else - /* If its prev pointer is nil, it must be at the front of - one or the other! */ - emacs_abort (); + XSCROLL_BAR (bar->prev)->next = bar->next; + + if (! NILP (bar->next)) + XSCROLL_BAR (bar->next)->prev = bar->prev; + + bar->next = FRAME_SCROLL_BARS (f); + bar->prev = Qnil; + XSETVECTOR (barobj, bar); + fset_scroll_bars (f, barobj); + if (! NILP (bar->next)) + XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar); } - else - XSCROLL_BAR (bar->prev)->next = bar->next; - if (! NILP (bar->next)) - XSCROLL_BAR (bar->next)->prev = bar->prev; + horizontal: + if (!NILP (w->horizontal_scroll_bar) && WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w)) + { + bar = XSCROLL_BAR (w->horizontal_scroll_bar); + /* Unlink it from the condemned list. */ + f = XFRAME (WINDOW_FRAME (w)); + if (NILP (bar->prev)) + { + /* If the prev pointer is nil, it must be the first in one of + the lists. */ + if (EQ (FRAME_SCROLL_BARS (f), w->horizontal_scroll_bar)) + /* It's not condemned. Everything's fine. */ + return; + else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f), + w->horizontal_scroll_bar)) + fset_condemned_scroll_bars (f, bar->next); + else + /* If its prev pointer is nil, it must be at the front of + one or the other! */ + emacs_abort (); + } + else + XSCROLL_BAR (bar->prev)->next = bar->next; - bar->next = FRAME_SCROLL_BARS (f); - bar->prev = Qnil; - XSETVECTOR (barobj, bar); - fset_scroll_bars (f, barobj); - if (! NILP (bar->next)) - XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar); + if (! NILP (bar->next)) + XSCROLL_BAR (bar->next)->prev = bar->prev; + + bar->next = FRAME_SCROLL_BARS (f); + bar->prev = Qnil; + XSETVECTOR (barobj, bar); + fset_scroll_bars (f, barobj); + if (! NILP (bar->next)) + XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar); + } } /* Remove all scroll bars on FRAME that haven't been saved since the @@ -3935,8 +4139,9 @@ w32_judge_scroll_bars (struct frame *f) and they should get garbage-collected. */ } -/* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind - is set to something other than NO_EVENT, it is enqueued. +/* Handle a mouse click on the vertical scroll bar BAR. If + *EMACS_EVENT's kind is set to something other than NO_EVENT, it is + enqueued. This may be called from a signal handler, so we have to ignore GC mark bits. */ @@ -4043,9 +4248,120 @@ w32_scroll_bar_handle_click (struct scroll_bar *bar, W32Msg *msg, } } -/* Return information to the user about the current position of the mouse - on the scroll bar. */ +/* Handle a mouse click on the horizontal scroll bar BAR. If + *EMACS_EVENT's kind is set to something other than NO_EVENT, it is + enqueued. + + This may be called from a signal handler, so we have to ignore GC + mark bits. */ +static int +w32_horizontal_scroll_bar_handle_click (struct scroll_bar *bar, W32Msg *msg, + struct input_event *emacs_event) +{ + if (! WINDOWP (bar->window)) + emacs_abort (); + + emacs_event->kind = HORIZONTAL_SCROLL_BAR_CLICK_EVENT; + emacs_event->code = 0; + /* not really meaningful to distinguish left/right */ + emacs_event->modifiers = msg->dwModifiers; + emacs_event->frame_or_window = bar->window; + emacs_event->arg = Qnil; + emacs_event->timestamp = msg->msg.time; + + { + int left_range = HORIZONTAL_SCROLL_BAR_LEFT_RANGE (f, bar->width); + int x; + int dragging = bar->dragging; + SCROLLINFO si; + + si.cbSize = sizeof (si); + si.fMask = SIF_POS; + + GetScrollInfo ((HWND) msg->msg.lParam, SB_CTL, &si); + x = si.nPos; + + bar->dragging = 0; + FRAME_DISPLAY_INFO (f)->last_mouse_scroll_bar_pos = msg->msg.wParam; + + switch (LOWORD (msg->msg.wParam)) + { + case SB_LINELEFT: + emacs_event->part = scroll_bar_left_arrow; + break; + case SB_LINERIGHT: + emacs_event->part = scroll_bar_right_arrow; + break; + case SB_PAGELEFT: + emacs_event->part = scroll_bar_before_handle; + break; + case SB_PAGERIGHT: + emacs_event->part = scroll_bar_after_handle; + break; + case SB_LEFT: + emacs_event->part = scroll_bar_horizontal_handle; + x = 0; + break; + case SB_RIGHT: + emacs_event->part = scroll_bar_horizontal_handle; + x = left_range; + break; + case SB_THUMBTRACK: + case SB_THUMBPOSITION: + if (HORIZONTAL_SCROLL_BAR_LEFT_RANGE (f, bar->width) <= 0xffff) + x = HIWORD (msg->msg.wParam); + bar->dragging = 1; + emacs_event->part = scroll_bar_horizontal_handle; + + /* "Silently" update current position. */ + { + SCROLLINFO si; + + si.cbSize = sizeof (si); + si.fMask = SIF_POS; + si.nPos = min (x, XWINDOW (bar->window)->hscroll_whole - 1); + /* Remember apparent position (we actually lag behind the real + position, so don't set that directly). */ + last_scroll_bar_drag_pos = x; + + SetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, FALSE); + } + break; + case SB_ENDSCROLL: + /* If this is the end of a drag sequence, then reset the scroll + handle size to normal and do a final redraw. Otherwise do + nothing. */ + if (dragging) + { + SCROLLINFO si; + int start = bar->start; + int end = bar->end; + + si.cbSize = sizeof (si); +/** si.fMask = SIF_PAGE | SIF_POS; **/ + si.fMask = SIF_POS; +/** si.nPage = end - start + HORIZONTAL_SCROLL_BAR_MIN_HANDLE; **/ + si.nPos = min (last_scroll_bar_drag_pos, + XWINDOW (bar->window)->hscroll_whole - 1); +/** si.nPos = last_scroll_bar_drag_pos; **/ + SetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, TRUE); + } + /* fall through */ + default: + emacs_event->kind = NO_EVENT; + return FALSE; + } + + XSETINT (emacs_event->x, x); + XSETINT (emacs_event->y, left_range); + + return TRUE; + } +} + +/* Return information to the user about the current position of the mouse + on the vertical scroll bar. */ static void x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window, enum scroll_bar_part *part, @@ -4100,6 +4416,62 @@ x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window, unblock_input (); } +/* Return information to the user about the current position of the mouse + on the horizontal scroll bar. */ +static void +x_horizontal_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window, + enum scroll_bar_part *part, + Lisp_Object *x, Lisp_Object *y, + unsigned long *time) +{ + struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp); + struct scroll_bar *bar = dpyinfo->last_mouse_scroll_bar; + Window w = SCROLL_BAR_W32_WINDOW (bar); + struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); + int pos; + int left_range = HORIZONTAL_SCROLL_BAR_LEFT_RANGE (f, bar->width); + SCROLLINFO si; + + block_input (); + + *fp = f; + *bar_window = bar->window; + + si.cbSize = sizeof (si); + si.fMask = SIF_POS | SIF_PAGE | SIF_RANGE; + + GetScrollInfo (w, SB_CTL, &si); + pos = si.nPos; + left_range = si.nMax - si.nPage + 1; + + switch (LOWORD (dpyinfo->last_mouse_scroll_bar_pos)) + { + case SB_THUMBPOSITION: + case SB_THUMBTRACK: + *part = scroll_bar_handle; + if (HORIZONTAL_SCROLL_BAR_LEFT_RANGE (f, bar->width) <= 0xffff) + pos = HIWORD (dpyinfo->last_mouse_scroll_bar_pos); + break; + case SB_LINERIGHT: + *part = scroll_bar_handle; + pos++; + break; + default: + *part = scroll_bar_handle; + break; + } + + XSETINT (*y, pos); + XSETINT (*x, left_range); + + f->mouse_moved = 0; + dpyinfo->last_mouse_scroll_bar = NULL; + + *time = dpyinfo->last_mouse_movement_time; + + unblock_input (); +} + /* The screen has been cleared so we may have changed foreground or background colors, and the scroll bars may need to be redrawn. @@ -4114,7 +4486,8 @@ x_scroll_bar_clear (struct frame *f) /* We can have scroll bars even if this is 0, if we just turned off scroll bar mode. But in that case we should not clear them. */ - if (FRAME_HAS_VERTICAL_SCROLL_BARS (f)) + if (FRAME_HAS_VERTICAL_SCROLL_BARS (f) + || FRAME_HAS_HORIZONTAL_SCROLL_BARS (f)) for (bar = FRAME_SCROLL_BARS (f); VECTORP (bar); bar = XSCROLL_BAR (bar)->next) { @@ -4589,10 +4962,20 @@ w32_read_socket (struct terminal *terminal, construct_drag_n_drop (&inev, &msg, f); break; + case WM_HSCROLL: + { + struct scroll_bar *bar = + x_window_to_scroll_bar ((HWND)msg.msg.lParam, 1); + + if (bar) + w32_horizontal_scroll_bar_handle_click (bar, &msg, &inev); + break; + } + case WM_VSCROLL: { struct scroll_bar *bar = - x_window_to_scroll_bar ((HWND)msg.msg.lParam); + x_window_to_scroll_bar ((HWND)msg.msg.lParam, 0); if (bar) w32_scroll_bar_handle_click (bar, &msg, &inev); @@ -4787,10 +5170,6 @@ w32_read_socket (struct terminal *terminal, change_frame_size (f, text_width, text_height, 0, 1, 0, 1); SET_FRAME_GARBAGED (f); cancel_mouse_face (f); - /* 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; } } @@ -5430,8 +5809,6 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset) FRAME_COLUMN_WIDTH (f) = unit = font->average_width; FRAME_LINE_HEIGHT (f) = font->height; - compute_fringe_widths (f, 1); - /* Compute number of scrollbar columns. */ unit = FRAME_COLUMN_WIDTH (f); if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0) @@ -5451,8 +5828,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_COLUMN_WIDTH (f), - FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 1); + adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f), + FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3, 0); } /* X version sets font of input methods here also. */ @@ -5649,6 +6026,7 @@ w32fullscreen_hook (struct frame *f) HWND hwnd = FRAME_W32_WINDOW(f); DWORD dwStyle = GetWindowLong (hwnd, GWL_STYLE); RECT rect; + enum fullscreen_type prev_fsmode = FRAME_PREV_FSMODE (f); block_input(); f->want_fullscreen &= ~FULLSCREEN_WAIT; @@ -5670,7 +6048,14 @@ w32fullscreen_hook (struct frame *f) if (f->want_fullscreen == FULLSCREEN_NONE) ShowWindow (hwnd, SW_SHOWNORMAL); else if (f->want_fullscreen == FULLSCREEN_MAXIMIZED) - ShowWindow (hwnd, SW_MAXIMIZE); + { + if (prev_fsmode == FULLSCREEN_BOTH || prev_fsmode == FULLSCREEN_WIDTH + || prev_fsmode == FULLSCREEN_HEIGHT) + /* Make window normal since otherwise the subsequent + maximization might fail in some cases. */ + ShowWindow (hwnd, SW_SHOWNORMAL); + ShowWindow (hwnd, SW_MAXIMIZE); + } else if (f->want_fullscreen == FULLSCREEN_BOTH) { w32_fullscreen_rect (hwnd, f->want_fullscreen, @@ -5705,70 +6090,40 @@ void x_set_window_size (struct frame *f, int change_gravity, int width, int height, bool pixelwise) { int pixelwidth, pixelheight; + RECT rect; block_input (); - check_frame_size (f, &width, &height, pixelwise); - - compute_fringe_widths (f, 0); - - if (frame_resize_pixelwise) + if (pixelwise) { - 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); - } + pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width); + pixelheight = FRAME_TEXT_TO_PIXEL_HEIGHT (f, height); } else { - /* If we don't resize frames pixelwise, round sizes to multiples - of character sizes here. Otherwise, when enforcing size hints - while processing WM_WINDOWPOSCHANGING in w32_wnd_proc, we might - clip our frame rectangle to a multiple of the frame's character - size and subsequently lose our mode line or scroll bar. - Bug#16923 could be one possible consequence of this. Carefully - reverse-engineer what WM_WINDOWPOSCHANGING does here since - otherwise we might make our frame too small, see Bug#17077. */ - int unit_width = FRAME_COLUMN_WIDTH (f); - int unit_height = FRAME_LINE_HEIGHT (f); - - pixelwidth = (((((pixelwise ? width : (width * FRAME_COLUMN_WIDTH (f))) - + FRAME_TOTAL_FRINGE_WIDTH (f)) - / unit_width) * unit_width) - + FRAME_SCROLL_BAR_AREA_WIDTH (f) - + 2 * FRAME_INTERNAL_BORDER_WIDTH (f)); - - pixelheight = ((((pixelwise ? height : (height * FRAME_LINE_HEIGHT (f))) - / unit_height) * unit_height) - + 2 * FRAME_INTERNAL_BORDER_WIDTH (f)); + 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); - { - RECT rect; + f->want_fullscreen = FULLSCREEN_NONE; + w32fullscreen_hook (f); - rect.left = rect.top = 0; - rect.right = pixelwidth; - rect.bottom = pixelheight; + rect.left = rect.top = 0; + rect.right = pixelwidth; + rect.bottom = pixelheight; - AdjustWindowRect (&rect, f->output_data.w32->dwStyle, - FRAME_EXTERNAL_MENU_BAR (f)); + AdjustWindowRect (&rect, f->output_data.w32->dwStyle, + FRAME_EXTERNAL_MENU_BAR (f)); - my_set_window_pos (FRAME_W32_WINDOW (f), - NULL, - 0, 0, - rect.right - rect.left, - rect.bottom - rect.top, - SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); - } + my_set_window_pos (FRAME_W32_WINDOW (f), + NULL, + 0, 0, + rect.right - rect.left, + rect.bottom - rect.top, + SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); /* If w32_enable_frame_resize_hack is non-nil, immediately apply the new pixel sizes to the frame and its subwindows. @@ -5817,6 +6172,8 @@ x_set_window_size (struct frame *f, int change_gravity, int width, int height, b } unblock_input (); + + do_pending_window_change (0); } /* Mouse warping. */ @@ -6156,7 +6513,8 @@ 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, FRAME_SCROLL_BAR_AREA_WIDTH (f)); + SetWindowLong (window, WND_VSCROLLBAR_INDEX, FRAME_SCROLL_BAR_AREA_WIDTH (f)); + SetWindowLong (window, WND_HSCROLLBAR_INDEX, FRAME_SCROLL_BAR_AREA_HEIGHT (f)); leave_crit (); } @@ -6243,6 +6601,7 @@ w32_initialize_display_info (Lisp_Object display_name) dpyinfo->smallest_font_height = 1; dpyinfo->smallest_char_width = 1; dpyinfo->vertical_scroll_bar_cursor = w32_load_cursor (IDC_ARROW); + dpyinfo->horizontal_scroll_bar_cursor = w32_load_cursor (IDC_ARROW); /* TODO: dpyinfo->gray */ reset_mouse_highlight (&dpyinfo->mouse_highlight); @@ -6363,6 +6722,7 @@ w32_create_terminal (struct w32_display_info *dpyinfo) terminal->menu_show_hook = w32_menu_show; terminal->popup_dialog_hook = w32_popup_dialog; terminal->set_vertical_scroll_bar_hook = w32_set_vertical_scroll_bar; + terminal->set_horizontal_scroll_bar_hook = w32_set_horizontal_scroll_bar; terminal->condemn_scroll_bars_hook = w32_condemn_scroll_bars; terminal->redeem_scroll_bar_hook = w32_redeem_scroll_bar; terminal->judge_scroll_bars_hook = w32_judge_scroll_bars; @@ -6595,13 +6955,16 @@ w32_initialize (void) #undef LOAD_PROC - /* Ensure scrollbar handle is at least 5 pixels. */ + /* Ensure scrollbar handles are at least 5 pixels. */ vertical_scroll_bar_min_handle = 5; + horizontal_scroll_bar_min_handle = 5; /* For either kind of scroll bar, take account of the arrows; these effectively form the border of the main scroll bar range. */ vertical_scroll_bar_top_border = vertical_scroll_bar_bottom_border = GetSystemMetrics (SM_CYVSCROLL); + horizontal_scroll_bar_left_border = horizontal_scroll_bar_right_border + = GetSystemMetrics (SM_CYHSCROLL); } } |