diff options
| author | Martin Rudalics | 2014-07-27 15:21:30 +0200 |
|---|---|---|
| committer | Martin Rudalics | 2014-07-27 15:21:30 +0200 |
| commit | 3477e27021dbe9366c3c1aaba80feb72f1138b29 (patch) | |
| tree | c1ebfb6695e8d7f90ddad1a5bfaaf353be677514 /src/xterm.c | |
| parent | 11fb71017b03f01a7e9e2db24973e756a41e16ec (diff) | |
| download | emacs-3477e27021dbe9366c3c1aaba80feb72f1138b29.tar.gz emacs-3477e27021dbe9366c3c1aaba80feb72f1138b29.zip | |
Complete pixelwise frame/window resizing, add horizontal scrollbar support.
* frame.el (frame-notice-user-settings): Rewrite using
frame-initial-frame-tool-bar-height.
* menu-bar.el (menu-bar-horizontal-scroll-bar)
(menu-bar-no-horizontal-scroll-bar): New functions.
(menu-bar-showhide-scroll-bar-menu): Add bindings for horizontal
scroll bars.
* scroll-bar.el (scroll-bar-lines)
(set-horizontal-scroll-bar-mode)
(get-horizontal-scroll-bar-mode, horizontal-scroll-bar-mode)
(scroll-bar-horizontal-drag-1, scroll-bar-horizontal-drag)
(scroll-bar-toolkit-horizontal-scroll): New functions.
(horizontal-scroll-bar-mode)
(previous-horizontal-scroll-bar-mode)
(horizontal-scroll-bar-mode-explicit): New variables.
(horizontal-scroll-bar-mode): New option.
(toggle-horizontal-scroll-bar): Do something.
(top-level): Bind horizontal-scroll-bar mouse-1.
* startup.el (tool-bar-originally-present): Remove variable.
(command-line): Don't set tool-bar-originally-present.
* window.el (window-min-height): Update doc-string.
(window--dump-frame): Dump horizontal scroll bar values.
(window--min-size-1): Handle minibuffer window separately.
Count in margins and horizontal scroll bar. Return safe value
iff IGNORE equals 'safe.
(frame-windows-min-size): New function (used by frame resizing
routines).
(fit-frame-to-buffer, fit-window-to-buffer): Count in horizontal
scroll bars.
(window--sanitize-window-sizes): New function.
(window-split-min-size): Remove.
(split-window): Count divider-width. Don't use
`window-split-min-size' any more. Reword error messages.
Sanitize windows sizes after splitting.
* buffer.h (struct buffer): New fields scroll_bar_height and
horizontal_scroll_bar_type.
* buffer.c (bset_scroll_bar_height)
(bset_horizontal_scroll_bar_type): New functions.
(Fbuffer_swap_text): Handle old_pointm field.
(init_buffer_once): Set defaults for scroll_bar_height and
horizontal_scroll_bar_type.
(syms_of_buffer): New variables scroll_bar_height and
horizontal_scroll_bar_type.
* dispextern.h (window_part): Rename ON_SCROLL_BAR to
ON_VERTICAL_SCROLL_BAR. Add ON_HORIZONTAL_SCROLL_BAR.
(set_vertical_scroll_bar): Remove prototype.
(x_change_tool_bar_height): Add prototype.
* dispnew.c (adjust_frame_glyphs_for_frame_redisplay)
(window_to_frame_vpos, update_frame_1, scrolling, init_display):
Use FRAME_TOTAL_COLS and FRAME_TOTAL_LINES instead of FRAME_COLS
and FRAME_LINES.
(adjust_frame_glyphs_for_window_redisplay): Rearrange lines.
(update_window): Start mode_line_row->y after horizontal scroll
bar.
(change_frame_size_1): Call adjust_frame_size.
(init_display): When changing the size of a tty frame do not
pass height of menu bar.
(Qframe_windows_min_size): New symbol.
* frame.h (struct frame): List tool bar fields after menu bar
fields. Add official, total_lines, horizontal_scroll_bars,
config_scroll_bar_height and config_scroll_bar_lines fields.
(FRAME_HAS_HORIZONTAL_SCROLL_BARS)
(FRAME_CONFIG_SCROLL_BAR_HEIGHT, FRAME_CONFIG_SCROLL_BAR_LINES)
(FRAME_SCROLL_BAR_AREA_HEIGHT, FRAME_SCROLL_BAR_COLS)
(FRAME_SCROLL_BAR_LINES, FRAME_TOTAL_LINES, SET_FRAME_LINES)
(FRAME_WINDOWS_HEIGHT): New macros.
(SET_FRAME_HEIGHT, FRAME_TEXT_LINES_TO_PIXEL_HEIGHT)
(FRAME_PIXEL_Y_TO_LINE, FRAME_PIXEL_HEIGHT_TO_TEXT_LINES)
(FRAME_TEXT_TO_PIXEL_HEIGHT): Separately count top margin and
horizontal scroll bar.
(frame_inhibit_resize, adjust_frame_size)
(frame_windows_min_size): Add declarations.
(Qscroll_bar_height, Qhorizontal_scroll_bars)
(x_set_scroll_bar_default_height, x_set_left_fringe)
(x_set_right_fringe, x_set_vertical_scroll_bars)
(x_set_horizontal_scroll_bars, x_set_scroll_bar_width)
(x_set_scroll_bar_height): Add external declarations.
* frame.c: (frame_inhibit_resize, frame_windows_min_size)
(adjust_frame_size): New functions.
(make_frame): Initial horizontal_scroll_bars field. Use
SET_FRAME_LINES. Don't allow horizontal scroll bar in
minibuffer window.
(make_initial_frame, make_terminal_frame): No horizontal scroll
bar in initial and terminal frames. Use adjust_frame_size.
(Fframe_total_cols): Fix doc-string.
(Fframe_total_lines, Fscroll_bar_height): New Lisp functions.
(Fset_frame_height, Fset_frame_width, Fset_frame_size): Rewrite
using adjust_frame_size.
(Qscroll_bar_height, Qhorizontal_scroll_bars)
(Qframe_windows_min_size): New symbols.
(x_set_frame_parameters): Remove call of check_frame_size.
(x_report_frame_params): Return scroll_bar_height value.
(x_set_left_fringe, x_set_right_fringe): New functions.
(adjust_frame_height, x_set_internal_border_width)
(x_set_fringe_width): Remove.
(x_set_internal_border_width, x_set_vertical_scroll_bars)
(x_set_scroll_bar_width, x_set_right_divider_width)
(x_set_bottom_divider_width): Rewrite using adjust_frame_size.
(x_set_horizontal_scroll_bars, x_set_scroll_bar_height): New
functions.
(x_figure_window_size): Rewrite to make frame display the
expected number of lines.
(Vdefault_frame_scroll_bars): Rewrite doc-string.
(Vdefault_frame_horizontal_scroll_bars)
(Vframe_initial_frame_tool_bar_height)
(frame_inhibit_implied_resize): New variables.
* fringe.c (compute_fringe_widths): Remove.
* gtkutil.h (YG_SB_MIN, YG_SB_MAX, YG_SB_RANGE): Define.
(xg_create_horizontal_scroll_bar)
(xg_update_horizontal_scrollbar_pos)
(xg_set_toolkit_horizontal_scroll_bar_thumb)
(xg_get_default_scrollbar_height)
(xg_clear_under_internal_border): Extern.
* gtkutil.c (xg_frame_resized): Don't call
do_pending_window_change.
(xg_frame_set_char_size): Use adjust_frame_size.
(style_changed_cb): Call update_theme_scrollbar_height and
x_set_scroll_bar_default_height.
(x_wm_set_size_hint): Don't call check_frame_size.
(update_theme_scrollbar_height)
(xg_get_default_scrollbar_height)
(xg_create_horizontal_scroll_bar)
(xg_update_horizontal_scrollbar_pos)
(xg_set_toolkit_horizontal_scroll_bar_thumb): New functions.
(xg_create_scroll_bar): Set horizontal slot of bar.
(xg_initialize): Call update_theme_scrollbar_height.
(xg_clear_under_internal_border): No more static.
* insdel.c (adjust_suspend_auto_hscroll): New function.
(adjust_markers_for_delete, adjust_markers_for_insert)
(adjust_markers_for_replace): Call adjust_suspend_auto_hscroll.
* keyboard.c (readable_events, discard_mouse_events)
(make_lispy_event): Handle horizontal scroll bar click events.
(Fsuspend_emacs): When changing the size of a tty frame do not
pass height of menu bar.
(Qbefore_handle, Qhorizontal_handle, Qafter_handle, Qleft)
(Qright, Qleftmost, Qrightmost): New symbols.
* menu.c (Fx_popup_dialog): Use FRAME_TOTAL_LINES instead of
FRAME_LINES.
* minibuf.c (read_minibuf): Initialize suspend_auto_hscroll.
* nsfns.m (x_set_internal_border_width): New function.
* nsterm.m (ns_draw_fringe_bitmap, ns_set_vertical_scroll_bar):
Remove extended fringe code.
(x_set_window_size, x_new_font): Don't call
compute_fringe_widths.
* term.c (Fresume_tty): When changing the size of a tty frame do
not pass height of menu bar.
(clear_tty_hooks, set_tty_hooks): Clear
horizontal_scroll_bar_hook.
(init_tty): Frame has no horizontal scroll bars.
* termhooks.h (enum scroll_bar_part): Add scroll_bar_move_ratio,
scroll_bar_before_handle, scroll_bar_horizontal_handle,
scroll_bar_after_handle, scroll_bar_left_arrow,
scroll_bar_right_arrow, scroll_bar_to_leftmost and
scroll_bar_to_rightmost entries.
(enum event_kind): Add HORIZONTAL_SCROLL_BAR_CLICK_EVENT
(struct terminal): Add set_horizontal_scroll_bar_hook.
* w32console.c (initialize_w32_display): Clear
horizontal_scroll_bar_hook.
* w32fns.c (x_set_mouse_color): Use FRAME_W32_DISPLAY instead of
FRAME_X_DISPLAY.
(x_clear_under_internal_border, x_set_internal_border_width):
New functions.
(x_set_menu_bar_lines): Rewrite using frame_inhibit_resize. Set
windows_or_buffers_changed when adding the menu bar.
(x_set_tool_bar_lines): Rewrite using adjust_frame_size.
(x_change_tool_bar_height, x_set_scroll_bar_default_height)
(w32_createhscrollbar): New functions.
(w32_createscrollbar): Rename to w32_createvscrollbar.
(w32_createwindow): Init WND_HSCROLLBAR_INDEX.
(w32_name_of_message): Replace WM_EMACS_CREATESCROLLBAR by
WM_EMACS_CREATEVSCROLLBAR and WM_EMACS_CREATEHSCROLLBAR. Add
WM_EMACS_SHOWCURSOR.
(w32_wnd_proc): Handle WM_HSCROLL case. In WM_WINDOWPOSCHANGING
case do not artificially impose WM size hints. Handle
WM_EMACS_SHOWCURSOR case. Replace WM_EMACS_CREATESCROLLBAR case
by WM_EMACS_CREATEVSCROLLBAR and WM_EMACS_CREATEHSCROLLBAR
cases.
(my_create_tip_window): Replace WND_SCROLLBAR_INDEX by
WND_VSCROLLBAR_INDEX and WND_HSCROLLBAR_INDEX.
(unwind_create_frame_1): Remove.
(Fx_create_frame): Make both scrollbars the system standard
width and height. Use official field of frame structure to
inhibit running window-configuration-change-hook.
(x_create_tip_frame): Call SET_FRAME_LINES and change_frame_size
pixelwise. Handle frame's official field.
(w32_frame_parm_handlers): Remove x_set_fringe_width
entries. Add x_set_scroll_bar_height,
x_set_horizontal_scroll_bars, x_set_left_fringe and
x_set_right_fringe.
* w32inevt.c (resize_event, maybe_generate_resize_event): Do not
pass height of menu bar to change_frame_size.
* w32menu.c (set_frame_menubar): Rewrite using
frame_inhibit_resize.
* w32term.h (struct w32_display_info): Add
horizontal_scroll_bar_cursor and cursor_display_counter.
(struct scroll_bar): Add horizontal.
(HORIZONTAL_SCROLL_BAR_INSIDE_HEIGHT)
(HORIZONTAL_SCROLL_BAR_LEFT_RANGE)
(HORIZONTAL_SCROLL_BAR_INSIDE_WIDTH)
(HORIZONTAL_SCROLL_BAR_LEFT_BORDER)
(HORIZONTAL_SCROLL_BAR_RIGHT_BORDER)
(HORIZONTAL_SCROLL_BAR_TOP_BORDER)
(HORIZONTAL_SCROLL_BAR_BOTTOM_BORDER)
(HORIZONTAL_SCROLL_BAR_MIN_HANDLE): New macros.
(WM_EMACS_CREATEVSCROLLBAR, WM_EMACS_CREATEHSCROLLBAR): Define
instead of WM_EMACS_CREATESCROLLBAR.
(WND_VSCROLLBAR_INDEX, WND_HSCROLLBAR_INDEX): Define instead of
WND_SCROLLBAR_INDEX.
* w32term.c (horizontal_scroll_bar_min_handle)
(horizontal_scroll_bar_left_border)
(horizontal_scroll_bar_right_border): New integers.
(x_set_frame_alpha): Replace x_highlight_frame by
w32_focus_frame.
(x_window_to_scroll_bar): New argument "type". Update callers
accordingly.
(w32_set_horizontal_scroll_bar_thumb)
(x_horizontal_scroll_bar_report_motion)
(w32_set_horizontal_scroll_bar)
(w32_horizontal_scroll_bar_handle_click)
(x_horizontal_scroll_bar_report_motion): New functions.
(w32_mouse_position): Discriminate horizontal and vertical
scrollbar cases.
(my_create_scrollbar): Replace with two new functions
my_create_vscrollbar and my_create_hscrollbar.
(x_scroll_bar_create): New argument "horizontal". Update
callers accordingly.
(x_scroll_bar_remove, w32_condemn_scroll_bars)
(w32_redeem_scroll_bar, x_scroll_bar_clear): Handle horizontal
scroll bar case.
(w32_read_socket): Handle WM_HSCROLL cae.
(x_new_font): Don't recompute fringe widths. Use
frame_inhibit_resize. Calculate new menu bar height iff we
build without toolkit. Always clear under internal border.
(x_set_window_size): Don't check frame size or recompute
fringes. Reset fullscreen status before applying sizes. Always
resize as requested by pixelwise argument. Don't call
do_pending_window_change.
(x_wm_set_size_hint): Add call for FRAME_SCROLL_BAR_AREA_HEIGHT.
(w32_initialize_display_info): Initialize dpyinfo's
horizontal_scroll_bar_cursor entry.
(w32_create_terminal): Add set_horizontal_scroll_bar_hook.
(w32_initialize): Init horizontal_scroll_bar_min_handle and
horizontal_scroll_bar_left_border.
(w32fullscreen_hook): Intermittently resize window to normal
when switching from fullscreen to maximized state.
(run_window_configuration_change_hook): Don't run it if frame is
not official yet.
(unwind_change_frame): Remove.
(Fset_window_configuration): Rewrite using frame's official field.
* widget.c (set_frame_size): Don't call compute_fringe_widths.
(EmacsFrameSetCharSize): Obey frame_inhibit_resize.
* window.h (struct window): New fields old_pointm,
horizontal_scroll_bar, horizontal_scroll_bar_type, hscroll_whole,
scroll_bar_height and suspend_auto_hscroll.
(wset_horizontal_scroll_bar, wset_horizontal_scroll_bar_type):
New functions.
(sanitize_window_sizes): Extern.
(MINI_NON_ONLY_WINDOW_P, MINI_ONLY_WINDOW_P, WINDOW_PSEUDO_P)
(WINDOW_TOPMOST_P, WINDOW_HAS_HORIZONTAL_SCROLL_BAR)
(WINDOW_CONFIG_SCROLL_BAR_HEIGHT)
(WINDOW_CONFIG_SCROLL_BAR_LINES)
(WINDOW_SCROLL_BAR_LINES, WINDOW_SCROLL_BAR_AREA_HEIGHT): New
macros.
(WINDOW_LEFT_FRINGE_COLS, WINDOW_RIGHT_FRINGE_COLS)
(WINDOW_FRINGE_COLS, WINDOW_FRINGE_EXTENDED_P): Remove macros.
(WINDOW_VERTICAL_SCROLL_BAR_TYPE)
(WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT)
(WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT)
(WINDOW_HAS_VERTICAL_SCROLL_BAR): Minor rewrite.
(WINDOW_BOX_HEIGHT_NO_MODE_LINE, WINDOW_BOX_TEXT_HEIGHT)
(WINDOW_SCROLL_BAR_AREA_Y): Count in scroll bar height.
* window.c (wset_old_pointm, Fwindow_scroll_bar_height)
(Fwindow_old_point, sanitize_window_sizes): New functions.
(Qwindow_sanitize_window_sizes): New symbol.
(window_body_height): Count in horizontal scroll bar.
(set_window_hscroll, Fscroll_left, Fscroll_right): Set
suspend_auto_hscroll slot.
(Fwindow_inside_edges): Count fringes pixelwise.
(coordinates_in_window, Fcoordinates_in_window_p): Consider
horizontal scroll bar.
(check_frame_size, adjust_window_margins): Remove functions and
corresponding calls.
(set_window_buffer): Initialize old_pointm and horizontal scroll
bars.
(temp_output_buffer_show): Reset hscroll related fields.
Initialize old_pointm.
(make_parent_window): Initialize old_pointm.
(make_window): Initialize old_pointm, horizontal scroll bar type,
and scroll bar height.
(resize_frame_windows): Don't count top margin in new sizes.
Don't use safe sizes when shrinking a frame; let the window
manager do the clipping.
(Fsplit_window_internal): Inherit horizontal scroll bar type and
height.
(Fdelete_window_internal): Unchain old_pointm marker.
(window_scroll_pixel_based, Fscroll_other_window): Adjust
old_pointm.
(Fwindow_text_width, Fwindow_text_height): New argument
"pixelwise".
(struct saved_window): New fields, old_pointm, hscroll_whole,
suspend_auto_hscroll, scroll_bar_height and
horizontal_scroll_bar_type.
(Fset_window_configuration, save_window_save): Set new fields of
saved_window.
(apply_window_adjustment): Don't call adjust_window_margins.
(set_window_margins): Don't change margins if new sizes don't
fit into window.
(set_window_scroll_bars): New argument "horizontal_type".
Handle horizontal scroll bars. Don't change scroll bars if they
don't fit into window.
(Fset_window_scroll_bars): New argument "horizontal_type".
(Fwindow_scroll_bars): Return values for horizontal scroll bars.
(compare_window_configurations): Compare horizontal scroll bar
settings.
* xdisp.c (window_text_bottom_y, window_box_height): Count in
horizontal scroll bar height.
(pixel_to_glyph_coords, init_xdisp): Use FRAME_TOTAL_LINES
instead of FRAME_LINES.
(remember_mouse_glyph): Case ON_SCROLL_BAR changed to
ON_VERTICAL_SCROLL_BAR.
(with_echo_area_buffer): Initialize old_pointm.
(with_echo_area_buffer_unwind_data): Store old_pointm values in
vector.
(unwind_with_echo_area_buffer): Handle old_pointm.
(update_tool_bar): Set do_update when the tool bar window has at
least one line (since this is what the user sets).
(MAX_FRAME_TOOL_BAR_HEIGHT): Remove macro.
(redisplay_tool_bar): Return early when toolbar has zero lines.
Call x_change_tool_bar_height. Don't use max_tool_bar_height.
(hscroll_window_tree): Handle suspension of auto_hscroll and
old_pointm.
(set_horizontal_scroll_bar): New function.
(redisplay_window): Set ignore_mouse_drag_p when tool bar has
more than one line. Handle horizontal scroll bars.
(note_mouse_highlight): Handle horizontal scrol bars.
(expose_frame): Set dimensions of XRectangle from frame's text
sizes.
(Vvoid_text_area_pointer): Update doc-string.
* xfns.c (x_set_menu_bar_lines): Use adjust_frame_size.
(x_change_tool_bar_height, x_set_scroll_bar_default_height)
(x_set_internal_border_width): New functions.
(x_set_tool_bar_lines): Call x_change_tool_bar_height.
(unwind_create_frame_1): Remove.
(Fx_create_frame): Handle horizontal scroll bars. Use official
field of frame structure to inhibit running
window-configuration-change-hook.
(x_create_tip_frame): Call SET_FRAME_LINES and change_frame_size
pixelwise. Handle frame's official field.
(x_frame_parm_handlers): Add x_set_scroll_bar_height,
x_set_horizontal_scroll_bars, x_set_left_fringe,
x_set_right_fringe.
* xmenu.c (update_frame_menubar, free_frame_menubar): Use
adjust_frame_size.
* xterm.h (struct x_display_info): Add
horizontal_scroll_bar_cursor and Xatom_Horizontal_Scrollbar
slots.
(struct scroll_bar): Add horizontal slot.
(HORIZONTAL_SCROLL_BAR_INSIDE_HEIGHT)
(HORIZONTAL_SCROLL_BAR_LEFT_RANGE)
(HORIZONTAL_SCROLL_BAR_INSIDE_WIDTH): New macros.
(HORIZONTAL_SCROLL_BAR_LEFT_BORDER)
(HORIZONTAL_SCROLL_BAR_RIGHT_BORDER)
(HORIZONTAL_SCROLL_BAR_TOP_BORDER)
(HORIZONTAL_SCROLL_BAR_BOTTOM_BORDER)
(HORIZONTAL_SCROLL_BAR_MIN_HANDLE): Define.
(x_clear_under_internal_border): Remove.
* xterm.c (XTmouse_position): Handle horizontal scroll bars.
(x_window_to_scroll_bar): New argument TYPE. Update callers.
(x_send_scroll_bar_event, x_scroll_bar_create): New arguments
HORIZONTAL. Update callers.
(horizontal_action_hook_id): New action hook id.
(x_horizontal_scroll_bar_to_input_event)
(x_create_horizontal_toolkit_scroll_bar)
(xt_horizontal_action_hook)
(x_set_toolkit_horizontal_scroll_bar_thumb)
(XTset_horizontal_scroll_bar, x_net_wm_state)
(x_horizontal_scroll_bar_report_motion): New functions.
(xg_scroll_callback, x_scroll_bar_handle_click): Handle
horizontal scroll bars.
(SCROLL_BAR_HORIZONTAL_NAME): Define.
(XTset_vertical_scroll_bar): Attempt to clear areas not covered
by scroll bar.
(XTcondemn_scroll_bars, XTredeem_scroll_bar): Rewrite. Handle
horizontal scroll bars.
(handle_one_xevent): Handle horizontal scroll bar events. Call
x_net_wm_state.
(x_set_window_size_1, x_wm_set_size_hint): Don't call
check_frame_size.
(x_set_window_size): Don't call check_frame_size and
do_pending_window_change.
(x_term_init): Init horizontal_scroll_bar_cursor display info.
(x_create_terminal): Add set_horizontal_scroll_bar_hook.
(x_scroll_bar_set_handle): Add some checks when calling
x_clear_area.
Diffstat (limited to 'src/xterm.c')
| -rw-r--r-- | src/xterm.c | 1068 |
1 files changed, 919 insertions, 149 deletions
diff --git a/src/xterm.c b/src/xterm.c index 85835a2c7c5..b4eba7fcf82 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -246,11 +246,15 @@ static void x_clip_to_row (struct window *, struct glyph_row *, | |||
| 246 | static void x_flush (struct frame *f); | 246 | static void x_flush (struct frame *f); |
| 247 | static void x_update_begin (struct frame *); | 247 | static void x_update_begin (struct frame *); |
| 248 | static void x_update_window_begin (struct window *); | 248 | static void x_update_window_begin (struct window *); |
| 249 | static struct scroll_bar *x_window_to_scroll_bar (Display *, Window); | 249 | static struct scroll_bar *x_window_to_scroll_bar (Display *, Window, int); |
| 250 | static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *, | 250 | static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *, |
| 251 | enum scroll_bar_part *, | 251 | enum scroll_bar_part *, |
| 252 | Lisp_Object *, Lisp_Object *, | 252 | Lisp_Object *, Lisp_Object *, |
| 253 | Time *); | 253 | Time *); |
| 254 | static void x_horizontal_scroll_bar_report_motion (struct frame **, Lisp_Object *, | ||
| 255 | enum scroll_bar_part *, | ||
| 256 | Lisp_Object *, Lisp_Object *, | ||
| 257 | Time *); | ||
| 254 | static int x_handle_net_wm_state (struct frame *, const XPropertyEvent *); | 258 | static int x_handle_net_wm_state (struct frame *, const XPropertyEvent *); |
| 255 | static void x_check_fullscreen (struct frame *); | 259 | static void x_check_fullscreen (struct frame *); |
| 256 | static void x_check_expected_move (struct frame *, int, int); | 260 | static void x_check_expected_move (struct frame *, int, int); |
| @@ -268,6 +272,7 @@ static void x_wm_set_window_state (struct frame *, int); | |||
| 268 | static void x_wm_set_icon_pixmap (struct frame *, ptrdiff_t); | 272 | static void x_wm_set_icon_pixmap (struct frame *, ptrdiff_t); |
| 269 | static void x_initialize (void); | 273 | static void x_initialize (void); |
| 270 | 274 | ||
| 275 | static int get_current_wm_state (struct frame *, Window, int *, int *); | ||
| 271 | 276 | ||
| 272 | /* Flush display of frame F. */ | 277 | /* Flush display of frame F. */ |
| 273 | 278 | ||
| @@ -634,10 +639,8 @@ XTframe_up_to_date (struct frame *f) | |||
| 634 | } | 639 | } |
| 635 | 640 | ||
| 636 | 641 | ||
| 637 | /* Clear under internal border if any for non-toolkit builds. */ | 642 | /* Clear under internal border if any (GTK has its own version). */ |
| 638 | 643 | #ifndef USE_GTK | |
| 639 | |||
| 640 | #if !defined USE_X_TOOLKIT && !defined USE_GTK | ||
| 641 | void | 644 | void |
| 642 | x_clear_under_internal_border (struct frame *f) | 645 | x_clear_under_internal_border (struct frame *f) |
| 643 | { | 646 | { |
| @@ -3974,7 +3977,14 @@ XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window, | |||
| 3974 | block_input (); | 3977 | block_input (); |
| 3975 | 3978 | ||
| 3976 | if (dpyinfo->last_mouse_scroll_bar && insist == 0) | 3979 | if (dpyinfo->last_mouse_scroll_bar && insist == 0) |
| 3977 | x_scroll_bar_report_motion (fp, bar_window, part, x, y, timestamp); | 3980 | { |
| 3981 | struct scroll_bar *bar = dpyinfo->last_mouse_scroll_bar; | ||
| 3982 | |||
| 3983 | if (bar->horizontal) | ||
| 3984 | x_horizontal_scroll_bar_report_motion (fp, bar_window, part, x, y, timestamp); | ||
| 3985 | else | ||
| 3986 | x_scroll_bar_report_motion (fp, bar_window, part, x, y, timestamp); | ||
| 3987 | } | ||
| 3978 | else | 3988 | else |
| 3979 | { | 3989 | { |
| 3980 | Window root; | 3990 | Window root; |
| @@ -4118,7 +4128,7 @@ XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window, | |||
| 4118 | { | 4128 | { |
| 4119 | struct scroll_bar *bar; | 4129 | struct scroll_bar *bar; |
| 4120 | 4130 | ||
| 4121 | bar = x_window_to_scroll_bar (FRAME_X_DISPLAY (*fp), win); | 4131 | bar = x_window_to_scroll_bar (FRAME_X_DISPLAY (*fp), win, 2); |
| 4122 | 4132 | ||
| 4123 | if (bar) | 4133 | if (bar) |
| 4124 | { | 4134 | { |
| @@ -4173,7 +4183,7 @@ XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window, | |||
| 4173 | bits. */ | 4183 | bits. */ |
| 4174 | 4184 | ||
| 4175 | static struct scroll_bar * | 4185 | static struct scroll_bar * |
| 4176 | x_window_to_scroll_bar (Display *display, Window window_id) | 4186 | x_window_to_scroll_bar (Display *display, Window window_id, int type) |
| 4177 | { | 4187 | { |
| 4178 | Lisp_Object tail, frame; | 4188 | Lisp_Object tail, frame; |
| 4179 | 4189 | ||
| @@ -4198,8 +4208,11 @@ x_window_to_scroll_bar (Display *display, Window window_id) | |||
| 4198 | condemned = Qnil, | 4208 | condemned = Qnil, |
| 4199 | ! NILP (bar)); | 4209 | ! NILP (bar)); |
| 4200 | bar = XSCROLL_BAR (bar)->next) | 4210 | bar = XSCROLL_BAR (bar)->next) |
| 4201 | if (XSCROLL_BAR (bar)->x_window == window_id && | 4211 | if (XSCROLL_BAR (bar)->x_window == window_id |
| 4202 | FRAME_X_DISPLAY (XFRAME (frame)) == display) | 4212 | && FRAME_X_DISPLAY (XFRAME (frame)) == display |
| 4213 | && (type = 2 | ||
| 4214 | || (type == 1 && XSCROLL_BAR (bar)->horizontal) | ||
| 4215 | || (type == 0 && !XSCROLL_BAR (bar)->horizontal))) | ||
| 4203 | return XSCROLL_BAR (bar); | 4216 | return XSCROLL_BAR (bar); |
| 4204 | } | 4217 | } |
| 4205 | 4218 | ||
| @@ -4237,7 +4250,7 @@ x_window_to_menu_bar (Window window) | |||
| 4237 | 4250 | ||
| 4238 | #ifdef USE_TOOLKIT_SCROLL_BARS | 4251 | #ifdef USE_TOOLKIT_SCROLL_BARS |
| 4239 | 4252 | ||
| 4240 | static void x_send_scroll_bar_event (Lisp_Object, int, int, int); | 4253 | static void x_send_scroll_bar_event (Lisp_Object, int, int, int, bool); |
| 4241 | 4254 | ||
| 4242 | /* Lisp window being scrolled. Set when starting to interact with | 4255 | /* Lisp window being scrolled. Set when starting to interact with |
| 4243 | a toolkit scroll bar, reset to nil when ending the interaction. */ | 4256 | a toolkit scroll bar, reset to nil when ending the interaction. */ |
| @@ -4251,6 +4264,7 @@ static Lisp_Object window_being_scrolled; | |||
| 4251 | /* Id of action hook installed for scroll bars. */ | 4264 | /* Id of action hook installed for scroll bars. */ |
| 4252 | 4265 | ||
| 4253 | static XtActionHookId action_hook_id; | 4266 | static XtActionHookId action_hook_id; |
| 4267 | static XtActionHookId horizontal_action_hook_id; | ||
| 4254 | 4268 | ||
| 4255 | static Boolean xaw3d_arrow_scroll; | 4269 | static Boolean xaw3d_arrow_scroll; |
| 4256 | 4270 | ||
| @@ -4288,7 +4302,7 @@ xt_action_hook (Widget widget, XtPointer client_data, String action_name, | |||
| 4288 | struct scroll_bar *bar; | 4302 | struct scroll_bar *bar; |
| 4289 | 4303 | ||
| 4290 | x_send_scroll_bar_event (window_being_scrolled, | 4304 | x_send_scroll_bar_event (window_being_scrolled, |
| 4291 | scroll_bar_end_scroll, 0, 0); | 4305 | scroll_bar_end_scroll, 0, 0, 0); |
| 4292 | w = XWINDOW (window_being_scrolled); | 4306 | w = XWINDOW (window_being_scrolled); |
| 4293 | bar = XSCROLL_BAR (w->vertical_scroll_bar); | 4307 | bar = XSCROLL_BAR (w->vertical_scroll_bar); |
| 4294 | 4308 | ||
| @@ -4306,6 +4320,49 @@ xt_action_hook (Widget widget, XtPointer client_data, String action_name, | |||
| 4306 | toolkit_scroll_bar_interaction = 0; | 4320 | toolkit_scroll_bar_interaction = 0; |
| 4307 | } | 4321 | } |
| 4308 | } | 4322 | } |
| 4323 | |||
| 4324 | |||
| 4325 | static void | ||
| 4326 | xt_horizontal_action_hook (Widget widget, XtPointer client_data, String action_name, | ||
| 4327 | XEvent *event, String *params, Cardinal *num_params) | ||
| 4328 | { | ||
| 4329 | int scroll_bar_p; | ||
| 4330 | const char *end_action; | ||
| 4331 | |||
| 4332 | #ifdef USE_MOTIF | ||
| 4333 | scroll_bar_p = XmIsScrollBar (widget); | ||
| 4334 | end_action = "Release"; | ||
| 4335 | #else /* !USE_MOTIF i.e. use Xaw */ | ||
| 4336 | scroll_bar_p = XtIsSubclass (widget, scrollbarWidgetClass); | ||
| 4337 | end_action = "EndScroll"; | ||
| 4338 | #endif /* USE_MOTIF */ | ||
| 4339 | |||
| 4340 | if (scroll_bar_p | ||
| 4341 | && strcmp (action_name, end_action) == 0 | ||
| 4342 | && WINDOWP (window_being_scrolled)) | ||
| 4343 | { | ||
| 4344 | struct window *w; | ||
| 4345 | struct scroll_bar *bar; | ||
| 4346 | |||
| 4347 | x_send_scroll_bar_event (window_being_scrolled, | ||
| 4348 | scroll_bar_end_scroll, 0, 0, 1); | ||
| 4349 | w = XWINDOW (window_being_scrolled); | ||
| 4350 | bar = XSCROLL_BAR (w->horizontal_scroll_bar); | ||
| 4351 | |||
| 4352 | if (bar->dragging != -1) | ||
| 4353 | { | ||
| 4354 | bar->dragging = -1; | ||
| 4355 | /* The thumb size is incorrect while dragging: fix it. */ | ||
| 4356 | set_horizontal_scroll_bar (w); | ||
| 4357 | } | ||
| 4358 | window_being_scrolled = Qnil; | ||
| 4359 | #if defined (USE_LUCID) | ||
| 4360 | bar->last_seen_part = scroll_bar_nowhere; | ||
| 4361 | #endif | ||
| 4362 | /* Xt timeouts no longer needed. */ | ||
| 4363 | toolkit_scroll_bar_interaction = 0; | ||
| 4364 | } | ||
| 4365 | } | ||
| 4309 | #endif /* not USE_GTK */ | 4366 | #endif /* not USE_GTK */ |
| 4310 | 4367 | ||
| 4311 | /* Send a client message with message type Xatom_Scrollbar for a | 4368 | /* Send a client message with message type Xatom_Scrollbar for a |
| @@ -4314,7 +4371,7 @@ xt_action_hook (Widget widget, XtPointer client_data, String action_name, | |||
| 4314 | amount to scroll of a whole of WHOLE. */ | 4371 | amount to scroll of a whole of WHOLE. */ |
| 4315 | 4372 | ||
| 4316 | static void | 4373 | static void |
| 4317 | x_send_scroll_bar_event (Lisp_Object window, int part, int portion, int whole) | 4374 | x_send_scroll_bar_event (Lisp_Object window, int part, int portion, int whole, bool horizontal) |
| 4318 | { | 4375 | { |
| 4319 | XEvent event; | 4376 | XEvent event; |
| 4320 | XClientMessageEvent *ev = &event.xclient; | 4377 | XClientMessageEvent *ev = &event.xclient; |
| @@ -4329,7 +4386,9 @@ x_send_scroll_bar_event (Lisp_Object window, int part, int portion, int whole) | |||
| 4329 | 4386 | ||
| 4330 | /* Construct a ClientMessage event to send to the frame. */ | 4387 | /* Construct a ClientMessage event to send to the frame. */ |
| 4331 | ev->type = ClientMessage; | 4388 | ev->type = ClientMessage; |
| 4332 | ev->message_type = FRAME_DISPLAY_INFO (f)->Xatom_Scrollbar; | 4389 | ev->message_type = (horizontal |
| 4390 | ? FRAME_DISPLAY_INFO (f)->Xatom_Horizontal_Scrollbar | ||
| 4391 | : FRAME_DISPLAY_INFO (f)->Xatom_Scrollbar); | ||
| 4333 | ev->display = FRAME_X_DISPLAY (f); | 4392 | ev->display = FRAME_X_DISPLAY (f); |
| 4334 | ev->window = FRAME_X_WINDOW (f); | 4393 | ev->window = FRAME_X_WINDOW (f); |
| 4335 | ev->format = 32; | 4394 | ev->format = 32; |
| @@ -4394,6 +4453,41 @@ x_scroll_bar_to_input_event (const XEvent *event, | |||
| 4394 | ievent->modifiers = 0; | 4453 | ievent->modifiers = 0; |
| 4395 | } | 4454 | } |
| 4396 | 4455 | ||
| 4456 | /* Transform a horizontal scroll bar ClientMessage EVENT to an Emacs | ||
| 4457 | input event in *IEVENT. */ | ||
| 4458 | |||
| 4459 | static void | ||
| 4460 | x_horizontal_scroll_bar_to_input_event (const XEvent *event, | ||
| 4461 | struct input_event *ievent) | ||
| 4462 | { | ||
| 4463 | const XClientMessageEvent *ev = &event->xclient; | ||
| 4464 | Lisp_Object window; | ||
| 4465 | struct window *w; | ||
| 4466 | |||
| 4467 | /* See the comment in the function above. */ | ||
| 4468 | intptr_t iw0 = ev->data.l[0]; | ||
| 4469 | intptr_t iw1 = ev->data.l[1]; | ||
| 4470 | intptr_t iw = (iw0 << 31 << 1) + (iw1 & 0xffffffffu); | ||
| 4471 | w = (struct window *) iw; | ||
| 4472 | |||
| 4473 | XSETWINDOW (window, w); | ||
| 4474 | |||
| 4475 | ievent->kind = HORIZONTAL_SCROLL_BAR_CLICK_EVENT; | ||
| 4476 | ievent->frame_or_window = window; | ||
| 4477 | ievent->arg = Qnil; | ||
| 4478 | #ifdef USE_GTK | ||
| 4479 | ievent->timestamp = CurrentTime; | ||
| 4480 | #else | ||
| 4481 | ievent->timestamp = | ||
| 4482 | XtLastTimestampProcessed (FRAME_X_DISPLAY (XFRAME (w->frame))); | ||
| 4483 | #endif | ||
| 4484 | ievent->code = 0; | ||
| 4485 | ievent->part = ev->data.l[2]; | ||
| 4486 | ievent->x = make_number (ev->data.l[3]); | ||
| 4487 | ievent->y = make_number (ev->data.l[4]); | ||
| 4488 | ievent->modifiers = 0; | ||
| 4489 | } | ||
| 4490 | |||
| 4397 | 4491 | ||
| 4398 | #ifdef USE_MOTIF | 4492 | #ifdef USE_MOTIF |
| 4399 | 4493 | ||
| @@ -4401,7 +4495,6 @@ x_scroll_bar_to_input_event (const XEvent *event, | |||
| 4401 | 4495 | ||
| 4402 | #define XM_SB_MAX 10000000 | 4496 | #define XM_SB_MAX 10000000 |
| 4403 | 4497 | ||
| 4404 | |||
| 4405 | /* Scroll bar callback for Motif scroll bars. WIDGET is the scroll | 4498 | /* Scroll bar callback for Motif scroll bars. WIDGET is the scroll |
| 4406 | bar widget. CLIENT_DATA is a pointer to the scroll_bar structure. | 4499 | bar widget. CLIENT_DATA is a pointer to the scroll_bar structure. |
| 4407 | CALL_DATA is a pointer to a XmScrollBarCallbackStruct. */ | 4500 | CALL_DATA is a pointer to a XmScrollBarCallbackStruct. */ |
| @@ -4412,51 +4505,65 @@ xm_scroll_callback (Widget widget, XtPointer client_data, XtPointer call_data) | |||
| 4412 | struct scroll_bar *bar = client_data; | 4505 | struct scroll_bar *bar = client_data; |
| 4413 | XmScrollBarCallbackStruct *cs = call_data; | 4506 | XmScrollBarCallbackStruct *cs = call_data; |
| 4414 | int part = -1, whole = 0, portion = 0; | 4507 | int part = -1, whole = 0, portion = 0; |
| 4508 | int horizontal = bar->horizontal; | ||
| 4415 | 4509 | ||
| 4416 | switch (cs->reason) | 4510 | switch (cs->reason) |
| 4417 | { | 4511 | { |
| 4418 | case XmCR_DECREMENT: | 4512 | case XmCR_DECREMENT: |
| 4419 | bar->dragging = -1; | 4513 | bar->dragging = -1; |
| 4420 | part = scroll_bar_up_arrow; | 4514 | part = horizontal ? scroll_bar_left_arrow : scroll_bar_up_arrow; |
| 4421 | break; | 4515 | break; |
| 4422 | 4516 | ||
| 4423 | case XmCR_INCREMENT: | 4517 | case XmCR_INCREMENT: |
| 4424 | bar->dragging = -1; | 4518 | bar->dragging = -1; |
| 4425 | part = scroll_bar_down_arrow; | 4519 | part = horizontal ? scroll_bar_right_arrow : scroll_bar_down_arrow; |
| 4426 | break; | 4520 | break; |
| 4427 | 4521 | ||
| 4428 | case XmCR_PAGE_DECREMENT: | 4522 | case XmCR_PAGE_DECREMENT: |
| 4429 | bar->dragging = -1; | 4523 | bar->dragging = -1; |
| 4430 | part = scroll_bar_above_handle; | 4524 | part = horizontal ? scroll_bar_before_handle : scroll_bar_above_handle; |
| 4431 | break; | 4525 | break; |
| 4432 | 4526 | ||
| 4433 | case XmCR_PAGE_INCREMENT: | 4527 | case XmCR_PAGE_INCREMENT: |
| 4434 | bar->dragging = -1; | 4528 | bar->dragging = -1; |
| 4435 | part = scroll_bar_below_handle; | 4529 | part = horizontal ? scroll_bar_after_handle : scroll_bar_below_handle; |
| 4436 | break; | 4530 | break; |
| 4437 | 4531 | ||
| 4438 | case XmCR_TO_TOP: | 4532 | case XmCR_TO_TOP: |
| 4439 | bar->dragging = -1; | 4533 | bar->dragging = -1; |
| 4440 | part = scroll_bar_to_top; | 4534 | part = horizontal ? scroll_bar_to_leftmost : scroll_bar_to_top; |
| 4441 | break; | 4535 | break; |
| 4442 | 4536 | ||
| 4443 | case XmCR_TO_BOTTOM: | 4537 | case XmCR_TO_BOTTOM: |
| 4444 | bar->dragging = -1; | 4538 | bar->dragging = -1; |
| 4445 | part = scroll_bar_to_bottom; | 4539 | part = horizontal ? scroll_bar_to_rightmost : scroll_bar_to_bottom; |
| 4446 | break; | 4540 | break; |
| 4447 | 4541 | ||
| 4448 | case XmCR_DRAG: | 4542 | case XmCR_DRAG: |
| 4449 | { | 4543 | { |
| 4450 | int slider_size; | 4544 | int slider_size; |
| 4451 | 4545 | ||
| 4452 | /* Get the slider size. */ | ||
| 4453 | block_input (); | 4546 | block_input (); |
| 4454 | XtVaGetValues (widget, XmNsliderSize, &slider_size, NULL); | 4547 | XtVaGetValues (widget, XmNsliderSize, &slider_size, NULL); |
| 4455 | unblock_input (); | 4548 | unblock_input (); |
| 4456 | 4549 | ||
| 4457 | whole = XM_SB_MAX - slider_size; | 4550 | if (horizontal) |
| 4458 | portion = min (cs->value, whole); | 4551 | { |
| 4459 | part = scroll_bar_handle; | 4552 | whole = bar->whole; |
| 4553 | portion = (((float) cs->value | ||
| 4554 | / (XM_SB_MAX - slider_size)) | ||
| 4555 | * (whole | ||
| 4556 | - ((float) slider_size / XM_SB_MAX) * whole)); | ||
| 4557 | portion = max (0, portion); | ||
| 4558 | part = scroll_bar_horizontal_handle; | ||
| 4559 | } | ||
| 4560 | else | ||
| 4561 | { | ||
| 4562 | whole = XM_SB_MAX - slider_size; | ||
| 4563 | portion = min (cs->value, whole); | ||
| 4564 | part = scroll_bar_handle; | ||
| 4565 | } | ||
| 4566 | |||
| 4460 | bar->dragging = cs->value; | 4567 | bar->dragging = cs->value; |
| 4461 | } | 4568 | } |
| 4462 | break; | 4569 | break; |
| @@ -4468,7 +4575,7 @@ xm_scroll_callback (Widget widget, XtPointer client_data, XtPointer call_data) | |||
| 4468 | if (part >= 0) | 4575 | if (part >= 0) |
| 4469 | { | 4576 | { |
| 4470 | window_being_scrolled = bar->window; | 4577 | window_being_scrolled = bar->window; |
| 4471 | x_send_scroll_bar_event (bar->window, part, portion, whole); | 4578 | x_send_scroll_bar_event (bar->window, part, portion, whole, bar->horizontal); |
| 4472 | } | 4579 | } |
| 4473 | } | 4580 | } |
| 4474 | 4581 | ||
| @@ -4497,27 +4604,42 @@ xg_scroll_callback (GtkRange *range, | |||
| 4497 | if (FRAME_DISPLAY_INFO (f)->grabbed != 0 | 4604 | if (FRAME_DISPLAY_INFO (f)->grabbed != 0 |
| 4498 | && FRAME_DISPLAY_INFO (f)->grabbed < (1 << 4)) | 4605 | && FRAME_DISPLAY_INFO (f)->grabbed < (1 << 4)) |
| 4499 | { | 4606 | { |
| 4500 | part = scroll_bar_handle; | 4607 | if (bar->horizontal) |
| 4501 | whole = gtk_adjustment_get_upper (adj) - | 4608 | { |
| 4502 | gtk_adjustment_get_page_size (adj); | 4609 | part = scroll_bar_horizontal_handle; |
| 4503 | portion = min ((int)value, whole); | 4610 | whole = (int)(gtk_adjustment_get_upper (adj) - |
| 4504 | bar->dragging = portion; | 4611 | gtk_adjustment_get_page_size (adj)); |
| 4505 | } | 4612 | portion = min ((int)value, whole); |
| 4613 | bar->dragging = portion; | ||
| 4614 | } | ||
| 4615 | else | ||
| 4616 | { | ||
| 4617 | part = scroll_bar_handle; | ||
| 4618 | whole = gtk_adjustment_get_upper (adj) - | ||
| 4619 | gtk_adjustment_get_page_size (adj); | ||
| 4620 | portion = min ((int)value, whole); | ||
| 4621 | bar->dragging = portion; | ||
| 4622 | } | ||
| 4623 | } | ||
| 4506 | break; | 4624 | break; |
| 4507 | case GTK_SCROLL_STEP_BACKWARD: | 4625 | case GTK_SCROLL_STEP_BACKWARD: |
| 4508 | part = scroll_bar_up_arrow; | 4626 | part = (bar->horizontal |
| 4627 | ? scroll_bar_left_arrow : scroll_bar_up_arrow); | ||
| 4509 | bar->dragging = -1; | 4628 | bar->dragging = -1; |
| 4510 | break; | 4629 | break; |
| 4511 | case GTK_SCROLL_STEP_FORWARD: | 4630 | case GTK_SCROLL_STEP_FORWARD: |
| 4512 | part = scroll_bar_down_arrow; | 4631 | part = (bar->horizontal |
| 4632 | ? scroll_bar_right_arrow : scroll_bar_down_arrow); | ||
| 4513 | bar->dragging = -1; | 4633 | bar->dragging = -1; |
| 4514 | break; | 4634 | break; |
| 4515 | case GTK_SCROLL_PAGE_BACKWARD: | 4635 | case GTK_SCROLL_PAGE_BACKWARD: |
| 4516 | part = scroll_bar_above_handle; | 4636 | part = (bar->horizontal |
| 4637 | ? scroll_bar_before_handle : scroll_bar_above_handle); | ||
| 4517 | bar->dragging = -1; | 4638 | bar->dragging = -1; |
| 4518 | break; | 4639 | break; |
| 4519 | case GTK_SCROLL_PAGE_FORWARD: | 4640 | case GTK_SCROLL_PAGE_FORWARD: |
| 4520 | part = scroll_bar_below_handle; | 4641 | part = (bar->horizontal |
| 4642 | ? scroll_bar_after_handle : scroll_bar_below_handle); | ||
| 4521 | bar->dragging = -1; | 4643 | bar->dragging = -1; |
| 4522 | break; | 4644 | break; |
| 4523 | } | 4645 | } |
| @@ -4525,7 +4647,7 @@ xg_scroll_callback (GtkRange *range, | |||
| 4525 | if (part >= 0) | 4647 | if (part >= 0) |
| 4526 | { | 4648 | { |
| 4527 | window_being_scrolled = bar->window; | 4649 | window_being_scrolled = bar->window; |
| 4528 | x_send_scroll_bar_event (bar->window, part, portion, whole); | 4650 | x_send_scroll_bar_event (bar->window, part, portion, whole, bar->horizontal); |
| 4529 | } | 4651 | } |
| 4530 | 4652 | ||
| 4531 | return FALSE; | 4653 | return FALSE; |
| @@ -4543,7 +4665,7 @@ xg_end_scroll_callback (GtkWidget *widget, | |||
| 4543 | if (WINDOWP (window_being_scrolled)) | 4665 | if (WINDOWP (window_being_scrolled)) |
| 4544 | { | 4666 | { |
| 4545 | x_send_scroll_bar_event (window_being_scrolled, | 4667 | x_send_scroll_bar_event (window_being_scrolled, |
| 4546 | scroll_bar_end_scroll, 0, 0); | 4668 | scroll_bar_end_scroll, 0, 0, bar->horizontal); |
| 4547 | window_being_scrolled = Qnil; | 4669 | window_being_scrolled = Qnil; |
| 4548 | } | 4670 | } |
| 4549 | 4671 | ||
| @@ -4567,29 +4689,27 @@ xaw_jump_callback (Widget widget, XtPointer client_data, XtPointer call_data) | |||
| 4567 | float shown; | 4689 | float shown; |
| 4568 | int whole, portion, height; | 4690 | int whole, portion, height; |
| 4569 | enum scroll_bar_part part; | 4691 | enum scroll_bar_part part; |
| 4692 | int horizontal = bar->horizontal; | ||
| 4570 | 4693 | ||
| 4571 | /* Get the size of the thumb, a value between 0 and 1. */ | 4694 | /* Get the size of the thumb, a value between 0 and 1. */ |
| 4572 | block_input (); | 4695 | block_input (); |
| 4573 | XtVaGetValues (widget, XtNshown, &shown, XtNheight, &height, NULL); | 4696 | XtVaGetValues (widget, XtNshown, &shown, XtNheight, &height, NULL); |
| 4574 | unblock_input (); | 4697 | unblock_input (); |
| 4575 | 4698 | ||
| 4576 | whole = 10000000; | 4699 | if (horizontal) |
| 4577 | portion = shown < 1 ? top * whole : 0; | 4700 | { |
| 4578 | 4701 | whole = bar->whole; | |
| 4579 | if (shown < 1 && (eabs (top + shown - 1) < 1.0f / height)) | 4702 | portion = (top * (whole - (shown * whole))) / (1 - shown); |
| 4580 | /* Some derivatives of Xaw refuse to shrink the thumb when you reach | 4703 | portion = max (0, portion); |
| 4581 | the bottom, so we force the scrolling whenever we see that we're | 4704 | part = scroll_bar_horizontal_handle; |
| 4582 | too close to the bottom (in x_set_toolkit_scroll_bar_thumb | 4705 | } |
| 4583 | we try to ensure that we always stay two pixels away from the | ||
| 4584 | bottom). */ | ||
| 4585 | part = scroll_bar_down_arrow; | ||
| 4586 | else | 4706 | else |
| 4587 | part = scroll_bar_handle; | 4707 | part = scroll_bar_handle; |
| 4588 | 4708 | ||
| 4589 | window_being_scrolled = bar->window; | 4709 | window_being_scrolled = bar->window; |
| 4590 | bar->dragging = portion; | 4710 | bar->dragging = portion; |
| 4591 | bar->last_seen_part = part; | 4711 | bar->last_seen_part = part; |
| 4592 | x_send_scroll_bar_event (bar->window, part, portion, whole); | 4712 | x_send_scroll_bar_event (bar->window, part, portion, whole, bar->horizontal); |
| 4593 | } | 4713 | } |
| 4594 | 4714 | ||
| 4595 | 4715 | ||
| @@ -4628,12 +4748,13 @@ xaw_scroll_callback (Widget widget, XtPointer client_data, XtPointer call_data) | |||
| 4628 | window_being_scrolled = bar->window; | 4748 | window_being_scrolled = bar->window; |
| 4629 | bar->dragging = -1; | 4749 | bar->dragging = -1; |
| 4630 | bar->last_seen_part = part; | 4750 | bar->last_seen_part = part; |
| 4631 | x_send_scroll_bar_event (bar->window, part, position, height); | 4751 | x_send_scroll_bar_event (bar->window, part, position, height, bar->horizontal); |
| 4632 | } | 4752 | } |
| 4633 | 4753 | ||
| 4634 | #endif /* not USE_GTK and not USE_MOTIF */ | 4754 | #endif /* not USE_GTK and not USE_MOTIF */ |
| 4635 | 4755 | ||
| 4636 | #define SCROLL_BAR_NAME "verticalScrollBar" | 4756 | #define SCROLL_BAR_NAME "verticalScrollBar" |
| 4757 | #define SCROLL_BAR_HORIZONTAL_NAME "horizontalScrollBar" | ||
| 4637 | 4758 | ||
| 4638 | /* Create the widget for scroll bar BAR on frame F. Record the widget | 4759 | /* Create the widget for scroll bar BAR on frame F. Record the widget |
| 4639 | and X window of the scroll bar in BAR. */ | 4760 | and X window of the scroll bar in BAR. */ |
| @@ -4651,6 +4772,18 @@ x_create_toolkit_scroll_bar (struct frame *f, struct scroll_bar *bar) | |||
| 4651 | unblock_input (); | 4772 | unblock_input (); |
| 4652 | } | 4773 | } |
| 4653 | 4774 | ||
| 4775 | static void | ||
| 4776 | x_create_horizontal_toolkit_scroll_bar (struct frame *f, struct scroll_bar *bar) | ||
| 4777 | { | ||
| 4778 | const char *scroll_bar_name = SCROLL_BAR_HORIZONTAL_NAME; | ||
| 4779 | |||
| 4780 | block_input (); | ||
| 4781 | xg_create_horizontal_scroll_bar (f, bar, G_CALLBACK (xg_scroll_callback), | ||
| 4782 | G_CALLBACK (xg_end_scroll_callback), | ||
| 4783 | scroll_bar_name); | ||
| 4784 | unblock_input (); | ||
| 4785 | } | ||
| 4786 | |||
| 4654 | #else /* not USE_GTK */ | 4787 | #else /* not USE_GTK */ |
| 4655 | 4788 | ||
| 4656 | static void | 4789 | static void |
| @@ -4846,6 +4979,208 @@ x_create_toolkit_scroll_bar (struct frame *f, struct scroll_bar *bar) | |||
| 4846 | SET_SCROLL_BAR_X_WIDGET (bar, widget); | 4979 | SET_SCROLL_BAR_X_WIDGET (bar, widget); |
| 4847 | xwindow = XtWindow (widget); | 4980 | xwindow = XtWindow (widget); |
| 4848 | bar->x_window = xwindow; | 4981 | bar->x_window = xwindow; |
| 4982 | bar->whole = 1; | ||
| 4983 | bar->horizontal = 0; | ||
| 4984 | |||
| 4985 | unblock_input (); | ||
| 4986 | } | ||
| 4987 | |||
| 4988 | static void | ||
| 4989 | x_create_horizontal_toolkit_scroll_bar (struct frame *f, struct scroll_bar *bar) | ||
| 4990 | { | ||
| 4991 | Window xwindow; | ||
| 4992 | Widget widget; | ||
| 4993 | Arg av[20]; | ||
| 4994 | int ac = 0; | ||
| 4995 | const char *scroll_bar_name = SCROLL_BAR_HORIZONTAL_NAME; | ||
| 4996 | unsigned long pixel; | ||
| 4997 | |||
| 4998 | block_input (); | ||
| 4999 | |||
| 5000 | #ifdef USE_MOTIF | ||
| 5001 | /* Set resources. Create the widget. */ | ||
| 5002 | XtSetArg (av[ac], XtNmappedWhenManaged, False); ++ac; | ||
| 5003 | XtSetArg (av[ac], XmNminimum, 0); ++ac; | ||
| 5004 | XtSetArg (av[ac], XmNmaximum, XM_SB_MAX); ++ac; | ||
| 5005 | XtSetArg (av[ac], XmNorientation, XmHORIZONTAL); ++ac; | ||
| 5006 | XtSetArg (av[ac], XmNprocessingDirection, XmMAX_ON_RIGHT), ++ac; | ||
| 5007 | XtSetArg (av[ac], XmNincrement, 1); ++ac; | ||
| 5008 | XtSetArg (av[ac], XmNpageIncrement, 1); ++ac; | ||
| 5009 | |||
| 5010 | pixel = f->output_data.x->scroll_bar_foreground_pixel; | ||
| 5011 | if (pixel != -1) | ||
| 5012 | { | ||
| 5013 | XtSetArg (av[ac], XmNforeground, pixel); | ||
| 5014 | ++ac; | ||
| 5015 | } | ||
| 5016 | |||
| 5017 | pixel = f->output_data.x->scroll_bar_background_pixel; | ||
| 5018 | if (pixel != -1) | ||
| 5019 | { | ||
| 5020 | XtSetArg (av[ac], XmNbackground, pixel); | ||
| 5021 | ++ac; | ||
| 5022 | } | ||
| 5023 | |||
| 5024 | widget = XmCreateScrollBar (f->output_data.x->edit_widget, | ||
| 5025 | (char *) scroll_bar_name, av, ac); | ||
| 5026 | |||
| 5027 | /* Add one callback for everything that can happen. */ | ||
| 5028 | XtAddCallback (widget, XmNdecrementCallback, xm_scroll_callback, | ||
| 5029 | (XtPointer) bar); | ||
| 5030 | XtAddCallback (widget, XmNdragCallback, xm_scroll_callback, | ||
| 5031 | (XtPointer) bar); | ||
| 5032 | XtAddCallback (widget, XmNincrementCallback, xm_scroll_callback, | ||
| 5033 | (XtPointer) bar); | ||
| 5034 | XtAddCallback (widget, XmNpageDecrementCallback, xm_scroll_callback, | ||
| 5035 | (XtPointer) bar); | ||
| 5036 | XtAddCallback (widget, XmNpageIncrementCallback, xm_scroll_callback, | ||
| 5037 | (XtPointer) bar); | ||
| 5038 | XtAddCallback (widget, XmNtoBottomCallback, xm_scroll_callback, | ||
| 5039 | (XtPointer) bar); | ||
| 5040 | XtAddCallback (widget, XmNtoTopCallback, xm_scroll_callback, | ||
| 5041 | (XtPointer) bar); | ||
| 5042 | |||
| 5043 | /* Realize the widget. Only after that is the X window created. */ | ||
| 5044 | XtRealizeWidget (widget); | ||
| 5045 | |||
| 5046 | /* Set the cursor to an arrow. I didn't find a resource to do that. | ||
| 5047 | And I'm wondering why it hasn't an arrow cursor by default. */ | ||
| 5048 | XDefineCursor (XtDisplay (widget), XtWindow (widget), | ||
| 5049 | f->output_data.x->nontext_cursor); | ||
| 5050 | |||
| 5051 | #else /* !USE_MOTIF i.e. use Xaw */ | ||
| 5052 | |||
| 5053 | /* Set resources. Create the widget. The background of the | ||
| 5054 | Xaw3d scroll bar widget is a little bit light for my taste. | ||
| 5055 | We don't alter it here to let users change it according | ||
| 5056 | to their taste with `emacs*verticalScrollBar.background: xxx'. */ | ||
| 5057 | XtSetArg (av[ac], XtNmappedWhenManaged, False); ++ac; | ||
| 5058 | XtSetArg (av[ac], XtNorientation, XtorientHorizontal); ++ac; | ||
| 5059 | /* For smoother scrolling with Xaw3d -sm */ | ||
| 5060 | /* XtSetArg (av[ac], XtNpickTop, True); ++ac; */ | ||
| 5061 | |||
| 5062 | pixel = f->output_data.x->scroll_bar_foreground_pixel; | ||
| 5063 | if (pixel != -1) | ||
| 5064 | { | ||
| 5065 | XtSetArg (av[ac], XtNforeground, pixel); | ||
| 5066 | ++ac; | ||
| 5067 | } | ||
| 5068 | |||
| 5069 | pixel = f->output_data.x->scroll_bar_background_pixel; | ||
| 5070 | if (pixel != -1) | ||
| 5071 | { | ||
| 5072 | XtSetArg (av[ac], XtNbackground, pixel); | ||
| 5073 | ++ac; | ||
| 5074 | } | ||
| 5075 | |||
| 5076 | /* Top/bottom shadow colors. */ | ||
| 5077 | |||
| 5078 | /* Allocate them, if necessary. */ | ||
| 5079 | if (f->output_data.x->scroll_bar_top_shadow_pixel == -1) | ||
| 5080 | { | ||
| 5081 | pixel = f->output_data.x->scroll_bar_background_pixel; | ||
| 5082 | if (pixel != -1) | ||
| 5083 | { | ||
| 5084 | if (!x_alloc_lighter_color (f, FRAME_X_DISPLAY (f), | ||
| 5085 | FRAME_X_COLORMAP (f), | ||
| 5086 | &pixel, 1.2, 0x8000)) | ||
| 5087 | pixel = -1; | ||
| 5088 | f->output_data.x->scroll_bar_top_shadow_pixel = pixel; | ||
| 5089 | } | ||
| 5090 | } | ||
| 5091 | if (f->output_data.x->scroll_bar_bottom_shadow_pixel == -1) | ||
| 5092 | { | ||
| 5093 | pixel = f->output_data.x->scroll_bar_background_pixel; | ||
| 5094 | if (pixel != -1) | ||
| 5095 | { | ||
| 5096 | if (!x_alloc_lighter_color (f, FRAME_X_DISPLAY (f), | ||
| 5097 | FRAME_X_COLORMAP (f), | ||
| 5098 | &pixel, 0.6, 0x4000)) | ||
| 5099 | pixel = -1; | ||
| 5100 | f->output_data.x->scroll_bar_bottom_shadow_pixel = pixel; | ||
| 5101 | } | ||
| 5102 | } | ||
| 5103 | |||
| 5104 | #ifdef XtNbeNiceToColormap | ||
| 5105 | /* Tell the toolkit about them. */ | ||
| 5106 | if (f->output_data.x->scroll_bar_top_shadow_pixel == -1 | ||
| 5107 | || f->output_data.x->scroll_bar_bottom_shadow_pixel == -1) | ||
| 5108 | /* We tried to allocate a color for the top/bottom shadow, and | ||
| 5109 | failed, so tell Xaw3d to use dithering instead. */ | ||
| 5110 | /* But only if we have a small colormap. Xaw3d can allocate nice | ||
| 5111 | colors itself. */ | ||
| 5112 | { | ||
| 5113 | XtSetArg (av[ac], XtNbeNiceToColormap, | ||
| 5114 | DefaultDepthOfScreen (FRAME_X_SCREEN (f)) < 16); | ||
| 5115 | ++ac; | ||
| 5116 | } | ||
| 5117 | else | ||
| 5118 | /* Tell what colors Xaw3d should use for the top/bottom shadow, to | ||
| 5119 | be more consistent with other emacs 3d colors, and since Xaw3d is | ||
| 5120 | not good at dealing with allocation failure. */ | ||
| 5121 | { | ||
| 5122 | /* This tells Xaw3d to use real colors instead of dithering for | ||
| 5123 | the shadows. */ | ||
| 5124 | XtSetArg (av[ac], XtNbeNiceToColormap, False); | ||
| 5125 | ++ac; | ||
| 5126 | |||
| 5127 | /* Specify the colors. */ | ||
| 5128 | pixel = f->output_data.x->scroll_bar_top_shadow_pixel; | ||
| 5129 | if (pixel != -1) | ||
| 5130 | { | ||
| 5131 | XtSetArg (av[ac], XtNtopShadowPixel, pixel); | ||
| 5132 | ++ac; | ||
| 5133 | } | ||
| 5134 | pixel = f->output_data.x->scroll_bar_bottom_shadow_pixel; | ||
| 5135 | if (pixel != -1) | ||
| 5136 | { | ||
| 5137 | XtSetArg (av[ac], XtNbottomShadowPixel, pixel); | ||
| 5138 | ++ac; | ||
| 5139 | } | ||
| 5140 | } | ||
| 5141 | #endif | ||
| 5142 | |||
| 5143 | widget = XtCreateWidget (scroll_bar_name, scrollbarWidgetClass, | ||
| 5144 | f->output_data.x->edit_widget, av, ac); | ||
| 5145 | |||
| 5146 | { | ||
| 5147 | char const *initial = ""; | ||
| 5148 | char const *val = initial; | ||
| 5149 | XtVaGetValues (widget, XtNscrollVCursor, (XtPointer) &val, | ||
| 5150 | #ifdef XtNarrowScrollbars | ||
| 5151 | XtNarrowScrollbars, (XtPointer) &xaw3d_arrow_scroll, | ||
| 5152 | #endif | ||
| 5153 | XtNpickTop, (XtPointer) &xaw3d_pick_top, NULL); | ||
| 5154 | if (xaw3d_arrow_scroll || val == initial) | ||
| 5155 | { /* ARROW_SCROLL */ | ||
| 5156 | xaw3d_arrow_scroll = True; | ||
| 5157 | /* Isn't that just a personal preference ? --Stef */ | ||
| 5158 | XtVaSetValues (widget, XtNcursorName, "top_left_arrow", NULL); | ||
| 5159 | } | ||
| 5160 | } | ||
| 5161 | |||
| 5162 | /* Define callbacks. */ | ||
| 5163 | XtAddCallback (widget, XtNjumpProc, xaw_jump_callback, (XtPointer) bar); | ||
| 5164 | XtAddCallback (widget, XtNscrollProc, xaw_scroll_callback, | ||
| 5165 | (XtPointer) bar); | ||
| 5166 | |||
| 5167 | /* Realize the widget. Only after that is the X window created. */ | ||
| 5168 | XtRealizeWidget (widget); | ||
| 5169 | |||
| 5170 | #endif /* !USE_MOTIF */ | ||
| 5171 | |||
| 5172 | /* Install an action hook that lets us detect when the user | ||
| 5173 | finishes interacting with a scroll bar. */ | ||
| 5174 | if (horizontal_action_hook_id == 0) | ||
| 5175 | horizontal_action_hook_id | ||
| 5176 | = XtAppAddActionHook (Xt_app_con, xt_horizontal_action_hook, 0); | ||
| 5177 | |||
| 5178 | /* Remember X window and widget in the scroll bar vector. */ | ||
| 5179 | SET_SCROLL_BAR_X_WIDGET (bar, widget); | ||
| 5180 | xwindow = XtWindow (widget); | ||
| 5181 | bar->x_window = xwindow; | ||
| 5182 | bar->whole = 1; | ||
| 5183 | bar->horizontal = 1; | ||
| 4849 | 5184 | ||
| 4850 | unblock_input (); | 5185 | unblock_input (); |
| 4851 | } | 5186 | } |
| @@ -4862,6 +5197,12 @@ x_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, int portion, int positio | |||
| 4862 | xg_set_toolkit_scroll_bar_thumb (bar, portion, position, whole); | 5197 | xg_set_toolkit_scroll_bar_thumb (bar, portion, position, whole); |
| 4863 | } | 5198 | } |
| 4864 | 5199 | ||
| 5200 | static void | ||
| 5201 | x_set_toolkit_horizontal_scroll_bar_thumb (struct scroll_bar *bar, int portion, int position, int whole) | ||
| 5202 | { | ||
| 5203 | xg_set_toolkit_horizontal_scroll_bar_thumb (bar, portion, position, whole); | ||
| 5204 | } | ||
| 5205 | |||
| 4865 | #else /* not USE_GTK */ | 5206 | #else /* not USE_GTK */ |
| 4866 | static void | 5207 | static void |
| 4867 | x_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, int portion, int position, | 5208 | x_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, int portion, int position, |
| @@ -4974,6 +5315,89 @@ x_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, int portion, int positio | |||
| 4974 | 5315 | ||
| 4975 | unblock_input (); | 5316 | unblock_input (); |
| 4976 | } | 5317 | } |
| 5318 | |||
| 5319 | static void | ||
| 5320 | x_set_toolkit_horizontal_scroll_bar_thumb (struct scroll_bar *bar, int portion, int position, | ||
| 5321 | int whole) | ||
| 5322 | { | ||
| 5323 | struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); | ||
| 5324 | Widget widget = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar); | ||
| 5325 | float top, shown; | ||
| 5326 | |||
| 5327 | block_input (); | ||
| 5328 | |||
| 5329 | #ifdef USE_MOTIF | ||
| 5330 | bar->whole = whole; | ||
| 5331 | shown = (float) portion / whole; | ||
| 5332 | top = (float) position / (whole - portion); | ||
| 5333 | { | ||
| 5334 | int size = clip_to_bounds (1, shown * XM_SB_MAX, XM_SB_MAX); | ||
| 5335 | int value = clip_to_bounds (0, top * (XM_SB_MAX - size), XM_SB_MAX - size); | ||
| 5336 | |||
| 5337 | XmScrollBarSetValues (widget, value, size, 0, 0, False); | ||
| 5338 | } | ||
| 5339 | #else /* !USE_MOTIF i.e. use Xaw */ | ||
| 5340 | bar->whole = whole; | ||
| 5341 | if (whole == 0) | ||
| 5342 | top = 0, shown = 1; | ||
| 5343 | else | ||
| 5344 | { | ||
| 5345 | top = (float) position / whole; | ||
| 5346 | shown = (float) portion / whole; | ||
| 5347 | } | ||
| 5348 | |||
| 5349 | { | ||
| 5350 | float old_top, old_shown; | ||
| 5351 | Dimension height; | ||
| 5352 | XtVaGetValues (widget, | ||
| 5353 | XtNtopOfThumb, &old_top, | ||
| 5354 | XtNshown, &old_shown, | ||
| 5355 | XtNheight, &height, | ||
| 5356 | NULL); | ||
| 5357 | |||
| 5358 | #if 0 | ||
| 5359 | /* Massage the top+shown values. */ | ||
| 5360 | if (bar->dragging == -1 || bar->last_seen_part == scroll_bar_down_arrow) | ||
| 5361 | top = max (0, min (1, top)); | ||
| 5362 | else | ||
| 5363 | top = old_top; | ||
| 5364 | #if ! defined (HAVE_XAW3D) | ||
| 5365 | /* With Xaw, 'top' values too closer to 1.0 may | ||
| 5366 | cause the thumb to disappear. Fix that. */ | ||
| 5367 | top = min (top, 0.99f); | ||
| 5368 | #endif | ||
| 5369 | /* Keep two pixels available for moving the thumb down. */ | ||
| 5370 | shown = max (0, min (1 - top - (2.0f / height), shown)); | ||
| 5371 | #if ! defined (HAVE_XAW3D) | ||
| 5372 | /* Likewise with too small 'shown'. */ | ||
| 5373 | shown = max (shown, 0.01f); | ||
| 5374 | #endif | ||
| 5375 | #endif | ||
| 5376 | |||
| 5377 | /* If the call to XawScrollbarSetThumb below doesn't seem to | ||
| 5378 | work, check that 'NARROWPROTO' is defined in src/config.h. | ||
| 5379 | If this is not so, most likely you need to fix configure. */ | ||
| 5380 | XawScrollbarSetThumb (widget, top, shown); | ||
| 5381 | #if 0 | ||
| 5382 | if (top != old_top || shown != old_shown) | ||
| 5383 | { | ||
| 5384 | if (bar->dragging == -1) | ||
| 5385 | XawScrollbarSetThumb (widget, top, shown); | ||
| 5386 | else | ||
| 5387 | { | ||
| 5388 | /* Try to make the scrolling a tad smoother. */ | ||
| 5389 | if (!xaw3d_pick_top) | ||
| 5390 | shown = min (shown, old_shown); | ||
| 5391 | |||
| 5392 | XawScrollbarSetThumb (widget, top, shown); | ||
| 5393 | } | ||
| 5394 | } | ||
| 5395 | #endif | ||
| 5396 | } | ||
| 5397 | #endif /* !USE_MOTIF */ | ||
| 5398 | |||
| 5399 | unblock_input (); | ||
| 5400 | } | ||
| 4977 | #endif /* not USE_GTK */ | 5401 | #endif /* not USE_GTK */ |
| 4978 | 5402 | ||
| 4979 | #endif /* USE_TOOLKIT_SCROLL_BARS */ | 5403 | #endif /* USE_TOOLKIT_SCROLL_BARS */ |
| @@ -4990,7 +5414,7 @@ x_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, int portion, int positio | |||
| 4990 | scroll bar. */ | 5414 | scroll bar. */ |
| 4991 | 5415 | ||
| 4992 | static struct scroll_bar * | 5416 | static struct scroll_bar * |
| 4993 | x_scroll_bar_create (struct window *w, int top, int left, int width, int height) | 5417 | x_scroll_bar_create (struct window *w, int top, int left, int width, int height, bool horizontal) |
| 4994 | { | 5418 | { |
| 4995 | struct frame *f = XFRAME (w->frame); | 5419 | struct frame *f = XFRAME (w->frame); |
| 4996 | struct scroll_bar *bar | 5420 | struct scroll_bar *bar |
| @@ -5000,7 +5424,10 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height) | |||
| 5000 | block_input (); | 5424 | block_input (); |
| 5001 | 5425 | ||
| 5002 | #ifdef USE_TOOLKIT_SCROLL_BARS | 5426 | #ifdef USE_TOOLKIT_SCROLL_BARS |
| 5003 | x_create_toolkit_scroll_bar (f, bar); | 5427 | if (horizontal) |
| 5428 | x_create_horizontal_toolkit_scroll_bar (f, bar); | ||
| 5429 | else | ||
| 5430 | x_create_toolkit_scroll_bar (f, bar); | ||
| 5004 | #else /* not USE_TOOLKIT_SCROLL_BARS */ | 5431 | #else /* not USE_TOOLKIT_SCROLL_BARS */ |
| 5005 | { | 5432 | { |
| 5006 | XSetWindowAttributes a; | 5433 | XSetWindowAttributes a; |
| @@ -5063,8 +5490,12 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height) | |||
| 5063 | #ifdef USE_TOOLKIT_SCROLL_BARS | 5490 | #ifdef USE_TOOLKIT_SCROLL_BARS |
| 5064 | { | 5491 | { |
| 5065 | #ifdef USE_GTK | 5492 | #ifdef USE_GTK |
| 5066 | xg_update_scrollbar_pos (f, bar->x_window, top, | 5493 | if (horizontal) |
| 5067 | left,width, max (height, 1)); | 5494 | xg_update_horizontal_scrollbar_pos (f, bar->x_window, top, |
| 5495 | left, width, max (height, 1)); | ||
| 5496 | else | ||
| 5497 | xg_update_scrollbar_pos (f, bar->x_window, top, | ||
| 5498 | left, width, max (height, 1)); | ||
| 5068 | #else /* not USE_GTK */ | 5499 | #else /* not USE_GTK */ |
| 5069 | Widget scroll_bar = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar); | 5500 | Widget scroll_bar = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar); |
| 5070 | XtConfigureWidget (scroll_bar, left, top, width, max (height, 1), 0); | 5501 | XtConfigureWidget (scroll_bar, left, top, width, max (height, 1), 0); |
| @@ -5148,7 +5579,7 @@ x_scroll_bar_set_handle (struct scroll_bar *bar, int start, int end, int rebuild | |||
| 5148 | 5579 | ||
| 5149 | /* Draw the empty space above the handle. Note that we can't clear | 5580 | /* Draw the empty space above the handle. Note that we can't clear |
| 5150 | zero-height areas; that means "clear to end of window." */ | 5581 | zero-height areas; that means "clear to end of window." */ |
| 5151 | if (start > 0) | 5582 | if ((inside_width > 0) && (start > 0)) |
| 5152 | x_clear_area (FRAME_X_DISPLAY (f), w, | 5583 | x_clear_area (FRAME_X_DISPLAY (f), w, |
| 5153 | VERTICAL_SCROLL_BAR_LEFT_BORDER, | 5584 | VERTICAL_SCROLL_BAR_LEFT_BORDER, |
| 5154 | VERTICAL_SCROLL_BAR_TOP_BORDER, | 5585 | VERTICAL_SCROLL_BAR_TOP_BORDER, |
| @@ -5173,7 +5604,7 @@ x_scroll_bar_set_handle (struct scroll_bar *bar, int start, int end, int rebuild | |||
| 5173 | 5604 | ||
| 5174 | /* Draw the empty space below the handle. Note that we can't | 5605 | /* Draw the empty space below the handle. Note that we can't |
| 5175 | clear zero-height areas; that means "clear to end of window." */ | 5606 | clear zero-height areas; that means "clear to end of window." */ |
| 5176 | if (end < inside_height) | 5607 | if ((inside_width > 0) && (end < inside_height)) |
| 5177 | x_clear_area (FRAME_X_DISPLAY (f), w, | 5608 | x_clear_area (FRAME_X_DISPLAY (f), w, |
| 5178 | VERTICAL_SCROLL_BAR_LEFT_BORDER, | 5609 | VERTICAL_SCROLL_BAR_LEFT_BORDER, |
| 5179 | VERTICAL_SCROLL_BAR_TOP_BORDER + end, | 5610 | VERTICAL_SCROLL_BAR_TOP_BORDER + end, |
| @@ -5205,7 +5636,10 @@ x_scroll_bar_remove (struct scroll_bar *bar) | |||
| 5205 | #endif | 5636 | #endif |
| 5206 | 5637 | ||
| 5207 | /* Dissociate this scroll bar from its window. */ | 5638 | /* Dissociate this scroll bar from its window. */ |
| 5208 | wset_vertical_scroll_bar (XWINDOW (bar->window), Qnil); | 5639 | if (bar->horizontal) |
| 5640 | wset_horizontal_scroll_bar (XWINDOW (bar->window), Qnil); | ||
| 5641 | else | ||
| 5642 | wset_vertical_scroll_bar (XWINDOW (bar->window), Qnil); | ||
| 5209 | 5643 | ||
| 5210 | unblock_input (); | 5644 | unblock_input (); |
| 5211 | } | 5645 | } |
| @@ -5229,8 +5663,6 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio | |||
| 5229 | window_box (w, ANY_AREA, 0, &window_y, 0, &window_height); | 5663 | window_box (w, ANY_AREA, 0, &window_y, 0, &window_height); |
| 5230 | top = window_y; | 5664 | top = window_y; |
| 5231 | height = window_height; | 5665 | height = window_height; |
| 5232 | |||
| 5233 | /* Compute the left edge and the width of the scroll bar area. */ | ||
| 5234 | left = WINDOW_SCROLL_BAR_AREA_X (w); | 5666 | left = WINDOW_SCROLL_BAR_AREA_X (w); |
| 5235 | width = WINDOW_SCROLL_BAR_AREA_WIDTH (w); | 5667 | width = WINDOW_SCROLL_BAR_AREA_WIDTH (w); |
| 5236 | 5668 | ||
| @@ -5245,7 +5677,7 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio | |||
| 5245 | unblock_input (); | 5677 | unblock_input (); |
| 5246 | } | 5678 | } |
| 5247 | 5679 | ||
| 5248 | bar = x_scroll_bar_create (w, top, left, width, max (height, 1)); | 5680 | bar = x_scroll_bar_create (w, top, left, width, max (height, 1), 0); |
| 5249 | } | 5681 | } |
| 5250 | else | 5682 | else |
| 5251 | { | 5683 | { |
| @@ -5334,6 +5766,138 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio | |||
| 5334 | } | 5766 | } |
| 5335 | 5767 | ||
| 5336 | 5768 | ||
| 5769 | static void | ||
| 5770 | XTset_horizontal_scroll_bar (struct window *w, int portion, int whole, int position) | ||
| 5771 | { | ||
| 5772 | struct frame *f = XFRAME (w->frame); | ||
| 5773 | Lisp_Object barobj; | ||
| 5774 | struct scroll_bar *bar; | ||
| 5775 | int top, height, left, width; | ||
| 5776 | int window_x, window_width; | ||
| 5777 | int pixel_width = WINDOW_PIXEL_WIDTH (w); | ||
| 5778 | |||
| 5779 | /* Get window dimensions. */ | ||
| 5780 | window_box (w, ANY_AREA, &window_x, 0, &window_width, 0); | ||
| 5781 | left = window_x; | ||
| 5782 | width = window_width; | ||
| 5783 | top = WINDOW_SCROLL_BAR_AREA_Y (w); | ||
| 5784 | height = WINDOW_SCROLL_BAR_AREA_HEIGHT (w); | ||
| 5785 | |||
| 5786 | /* Does the scroll bar exist yet? */ | ||
| 5787 | if (NILP (w->horizontal_scroll_bar)) | ||
| 5788 | { | ||
| 5789 | if (width > 0 && height > 0) | ||
| 5790 | { | ||
| 5791 | block_input (); | ||
| 5792 | |||
| 5793 | /* Clear also part between window_width and | ||
| 5794 | WINDOW_PIXEL_WIDTH. */ | ||
| 5795 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | ||
| 5796 | left, top, pixel_width, height); | ||
| 5797 | unblock_input (); | ||
| 5798 | } | ||
| 5799 | |||
| 5800 | bar = x_scroll_bar_create (w, top, left, width, height, 1); | ||
| 5801 | } | ||
| 5802 | else | ||
| 5803 | { | ||
| 5804 | /* It may just need to be moved and resized. */ | ||
| 5805 | unsigned int mask = 0; | ||
| 5806 | |||
| 5807 | bar = XSCROLL_BAR (w->horizontal_scroll_bar); | ||
| 5808 | |||
| 5809 | block_input (); | ||
| 5810 | |||
| 5811 | if (left != bar->left) | ||
| 5812 | mask |= CWX; | ||
| 5813 | if (top != bar->top) | ||
| 5814 | mask |= CWY; | ||
| 5815 | if (width != bar->width) | ||
| 5816 | mask |= CWWidth; | ||
| 5817 | if (height != bar->height) | ||
| 5818 | mask |= CWHeight; | ||
| 5819 | |||
| 5820 | #ifdef USE_TOOLKIT_SCROLL_BARS | ||
| 5821 | /* Move/size the scroll bar widget. */ | ||
| 5822 | if (mask) | ||
| 5823 | { | ||
| 5824 | /* Since toolkit scroll bars are smaller than the space reserved | ||
| 5825 | for them on the frame, we have to clear "under" them. */ | ||
| 5826 | if (width > 0 && height > 0) | ||
| 5827 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | ||
| 5828 | WINDOW_LEFT_EDGE_X (w), top, | ||
| 5829 | pixel_width - WINDOW_RIGHT_DIVIDER_WIDTH (w), height); | ||
| 5830 | #ifdef USE_GTK | ||
| 5831 | xg_update_horizontal_scrollbar_pos (f, bar->x_window, top, left, | ||
| 5832 | width, height); | ||
| 5833 | #else /* not USE_GTK */ | ||
| 5834 | XtConfigureWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar), | ||
| 5835 | left, top, width, height, 0); | ||
| 5836 | #endif /* not USE_GTK */ | ||
| 5837 | } | ||
| 5838 | #else /* not USE_TOOLKIT_SCROLL_BARS */ | ||
| 5839 | |||
| 5840 | /* Clear areas not covered by the scroll bar because it's not as | ||
| 5841 | wide as the area reserved for it. This makes sure a | ||
| 5842 | previous mode line display is cleared after C-x 2 C-x 1, for | ||
| 5843 | example. */ | ||
| 5844 | { | ||
| 5845 | int area_height = WINDOW_CONFIG_SCROLL_BAR_HEIGHT (w); | ||
| 5846 | int rest = area_height - height; | ||
| 5847 | if (rest > 0 && width > 0) | ||
| 5848 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | ||
| 5849 | left, top, width, rest); | ||
| 5850 | } | ||
| 5851 | |||
| 5852 | /* Move/size the scroll bar window. */ | ||
| 5853 | if (mask) | ||
| 5854 | { | ||
| 5855 | XWindowChanges wc; | ||
| 5856 | |||
| 5857 | wc.x = left; | ||
| 5858 | wc.y = top; | ||
| 5859 | wc.width = width; | ||
| 5860 | wc.height = height; | ||
| 5861 | XConfigureWindow (FRAME_X_DISPLAY (f), bar->x_window, | ||
| 5862 | mask, &wc); | ||
| 5863 | } | ||
| 5864 | |||
| 5865 | #endif /* not USE_TOOLKIT_SCROLL_BARS */ | ||
| 5866 | |||
| 5867 | /* Remember new settings. */ | ||
| 5868 | bar->left = left; | ||
| 5869 | bar->top = top; | ||
| 5870 | bar->width = width; | ||
| 5871 | bar->height = height; | ||
| 5872 | |||
| 5873 | unblock_input (); | ||
| 5874 | } | ||
| 5875 | |||
| 5876 | #ifdef USE_TOOLKIT_SCROLL_BARS | ||
| 5877 | x_set_toolkit_horizontal_scroll_bar_thumb (bar, portion, position, whole); | ||
| 5878 | #else /* not USE_TOOLKIT_SCROLL_BARS */ | ||
| 5879 | /* Set the scroll bar's current state, unless we're currently being | ||
| 5880 | dragged. */ | ||
| 5881 | if (bar->dragging == -1) | ||
| 5882 | { | ||
| 5883 | int left_range = HORIZONTAL_SCROLL_BAR_LEFT_RANGE (f, width); | ||
| 5884 | |||
| 5885 | if (whole == 0) | ||
| 5886 | x_scroll_bar_set_handle (bar, 0, left_range, 0); | ||
| 5887 | else | ||
| 5888 | { | ||
| 5889 | int start = ((double) position * left_range) / whole; | ||
| 5890 | int end = ((double) (position + portion) * left_range) / whole; | ||
| 5891 | x_scroll_bar_set_handle (bar, start, end, 0); | ||
| 5892 | } | ||
| 5893 | } | ||
| 5894 | #endif /* not USE_TOOLKIT_SCROLL_BARS */ | ||
| 5895 | |||
| 5896 | XSETVECTOR (barobj, bar); | ||
| 5897 | wset_horizontal_scroll_bar (w, barobj); | ||
| 5898 | } | ||
| 5899 | |||
| 5900 | |||
| 5337 | /* The following three hooks are used when we're doing a thorough | 5901 | /* The following three hooks are used when we're doing a thorough |
| 5338 | redisplay of the frame. We don't explicitly know which scroll bars | 5902 | redisplay of the frame. We don't explicitly know which scroll bars |
| 5339 | are going to be deleted, because keeping track of when windows go | 5903 | are going to be deleted, because keeping track of when windows go |
| @@ -5349,17 +5913,22 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio | |||
| 5349 | static void | 5913 | static void |
| 5350 | XTcondemn_scroll_bars (struct frame *frame) | 5914 | XTcondemn_scroll_bars (struct frame *frame) |
| 5351 | { | 5915 | { |
| 5352 | /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */ | 5916 | if (!NILP (FRAME_SCROLL_BARS (frame))) |
| 5353 | while (! NILP (FRAME_SCROLL_BARS (frame))) | ||
| 5354 | { | 5917 | { |
| 5355 | Lisp_Object bar; | 5918 | if (!NILP (FRAME_CONDEMNED_SCROLL_BARS (frame))) |
| 5356 | bar = FRAME_SCROLL_BARS (frame); | 5919 | { |
| 5357 | fset_scroll_bars (frame, XSCROLL_BAR (bar)->next); | 5920 | /* Prepend scrollbars to already condemned ones. */ |
| 5358 | XSCROLL_BAR (bar)->next = FRAME_CONDEMNED_SCROLL_BARS (frame); | 5921 | Lisp_Object last = FRAME_SCROLL_BARS (frame); |
| 5359 | XSCROLL_BAR (bar)->prev = Qnil; | 5922 | |
| 5360 | if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame))) | 5923 | while (!NILP (XSCROLL_BAR (last)->next)) |
| 5361 | XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame))->prev = bar; | 5924 | last = XSCROLL_BAR (last)->next; |
| 5362 | fset_condemned_scroll_bars (frame, bar); | 5925 | |
| 5926 | XSCROLL_BAR (last)->next = FRAME_CONDEMNED_SCROLL_BARS (frame); | ||
| 5927 | XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame))->prev = last; | ||
| 5928 | } | ||
| 5929 | |||
| 5930 | fset_condemned_scroll_bars (frame, FRAME_SCROLL_BARS (frame)); | ||
| 5931 | fset_scroll_bars (frame, Qnil); | ||
| 5363 | } | 5932 | } |
| 5364 | } | 5933 | } |
| 5365 | 5934 | ||
| @@ -5368,47 +5937,84 @@ XTcondemn_scroll_bars (struct frame *frame) | |||
| 5368 | Note that WINDOW isn't necessarily condemned at all. */ | 5937 | Note that WINDOW isn't necessarily condemned at all. */ |
| 5369 | 5938 | ||
| 5370 | static void | 5939 | static void |
| 5371 | XTredeem_scroll_bar (struct window *window) | 5940 | XTredeem_scroll_bar (struct window *w) |
| 5372 | { | 5941 | { |
| 5373 | struct scroll_bar *bar; | 5942 | struct scroll_bar *bar; |
| 5374 | struct frame *f; | ||
| 5375 | Lisp_Object barobj; | 5943 | Lisp_Object barobj; |
| 5944 | struct frame *f; | ||
| 5376 | 5945 | ||
| 5377 | /* We can't redeem this window's scroll bar if it doesn't have one. */ | 5946 | /* We can't redeem this window's scroll bar if it doesn't have one. */ |
| 5378 | if (NILP (window->vertical_scroll_bar)) | 5947 | if (NILP (w->vertical_scroll_bar) && NILP (w->horizontal_scroll_bar)) |
| 5379 | emacs_abort (); | 5948 | emacs_abort (); |
| 5380 | 5949 | ||
| 5381 | bar = XSCROLL_BAR (window->vertical_scroll_bar); | 5950 | if (!NILP (w->vertical_scroll_bar) && WINDOW_HAS_VERTICAL_SCROLL_BAR (w)) |
| 5382 | |||
| 5383 | /* Unlink it from the condemned list. */ | ||
| 5384 | f = XFRAME (WINDOW_FRAME (window)); | ||
| 5385 | if (NILP (bar->prev)) | ||
| 5386 | { | 5951 | { |
| 5387 | /* If the prev pointer is nil, it must be the first in one of | 5952 | bar = XSCROLL_BAR (w->vertical_scroll_bar); |
| 5388 | the lists. */ | 5953 | /* Unlink it from the condemned list. */ |
| 5389 | if (EQ (FRAME_SCROLL_BARS (f), window->vertical_scroll_bar)) | 5954 | f = XFRAME (WINDOW_FRAME (w)); |
| 5390 | /* It's not condemned. Everything's fine. */ | 5955 | if (NILP (bar->prev)) |
| 5391 | return; | 5956 | { |
| 5392 | else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f), | 5957 | /* If the prev pointer is nil, it must be the first in one of |
| 5393 | window->vertical_scroll_bar)) | 5958 | the lists. */ |
| 5394 | fset_condemned_scroll_bars (f, bar->next); | 5959 | if (EQ (FRAME_SCROLL_BARS (f), w->vertical_scroll_bar)) |
| 5960 | /* It's not condemned. Everything's fine. */ | ||
| 5961 | goto horizontal; | ||
| 5962 | else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f), | ||
| 5963 | w->vertical_scroll_bar)) | ||
| 5964 | fset_condemned_scroll_bars (f, bar->next); | ||
| 5965 | else | ||
| 5966 | /* If its prev pointer is nil, it must be at the front of | ||
| 5967 | one or the other! */ | ||
| 5968 | emacs_abort (); | ||
| 5969 | } | ||
| 5395 | else | 5970 | else |
| 5396 | /* If its prev pointer is nil, it must be at the front of | 5971 | XSCROLL_BAR (bar->prev)->next = bar->next; |
| 5397 | one or the other! */ | 5972 | |
| 5398 | emacs_abort (); | 5973 | if (! NILP (bar->next)) |
| 5974 | XSCROLL_BAR (bar->next)->prev = bar->prev; | ||
| 5975 | |||
| 5976 | bar->next = FRAME_SCROLL_BARS (f); | ||
| 5977 | bar->prev = Qnil; | ||
| 5978 | XSETVECTOR (barobj, bar); | ||
| 5979 | fset_scroll_bars (f, barobj); | ||
| 5980 | if (! NILP (bar->next)) | ||
| 5981 | XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar); | ||
| 5399 | } | 5982 | } |
| 5400 | else | ||
| 5401 | XSCROLL_BAR (bar->prev)->next = bar->next; | ||
| 5402 | 5983 | ||
| 5403 | if (! NILP (bar->next)) | 5984 | horizontal: |
| 5404 | XSCROLL_BAR (bar->next)->prev = bar->prev; | 5985 | if (!NILP (w->horizontal_scroll_bar) && WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w)) |
| 5986 | { | ||
| 5987 | bar = XSCROLL_BAR (w->horizontal_scroll_bar); | ||
| 5988 | /* Unlink it from the condemned list. */ | ||
| 5989 | f = XFRAME (WINDOW_FRAME (w)); | ||
| 5990 | if (NILP (bar->prev)) | ||
| 5991 | { | ||
| 5992 | /* If the prev pointer is nil, it must be the first in one of | ||
| 5993 | the lists. */ | ||
| 5994 | if (EQ (FRAME_SCROLL_BARS (f), w->horizontal_scroll_bar)) | ||
| 5995 | /* It's not condemned. Everything's fine. */ | ||
| 5996 | return; | ||
| 5997 | else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f), | ||
| 5998 | w->horizontal_scroll_bar)) | ||
| 5999 | fset_condemned_scroll_bars (f, bar->next); | ||
| 6000 | else | ||
| 6001 | /* If its prev pointer is nil, it must be at the front of | ||
| 6002 | one or the other! */ | ||
| 6003 | emacs_abort (); | ||
| 6004 | } | ||
| 6005 | else | ||
| 6006 | XSCROLL_BAR (bar->prev)->next = bar->next; | ||
| 5405 | 6007 | ||
| 5406 | bar->next = FRAME_SCROLL_BARS (f); | 6008 | if (! NILP (bar->next)) |
| 5407 | bar->prev = Qnil; | 6009 | XSCROLL_BAR (bar->next)->prev = bar->prev; |
| 5408 | XSETVECTOR (barobj, bar); | 6010 | |
| 5409 | fset_scroll_bars (f, barobj); | 6011 | bar->next = FRAME_SCROLL_BARS (f); |
| 5410 | if (! NILP (bar->next)) | 6012 | bar->prev = Qnil; |
| 5411 | XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar); | 6013 | XSETVECTOR (barobj, bar); |
| 6014 | fset_scroll_bars (f, barobj); | ||
| 6015 | if (! NILP (bar->next)) | ||
| 6016 | XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar); | ||
| 6017 | } | ||
| 5412 | } | 6018 | } |
| 5413 | 6019 | ||
| 5414 | /* Remove all scroll bars on FRAME that haven't been saved since the | 6020 | /* Remove all scroll bars on FRAME that haven't been saved since the |
| @@ -5493,7 +6099,9 @@ x_scroll_bar_handle_click (struct scroll_bar *bar, | |||
| 5493 | if (! WINDOWP (bar->window)) | 6099 | if (! WINDOWP (bar->window)) |
| 5494 | emacs_abort (); | 6100 | emacs_abort (); |
| 5495 | 6101 | ||
| 5496 | emacs_event->kind = SCROLL_BAR_CLICK_EVENT; | 6102 | emacs_event->kind = (bar->horizontal |
| 6103 | ? HORIZONTAL_SCROLL_BAR_CLICK_EVENT | ||
| 6104 | : SCROLL_BAR_CLICK_EVENT); | ||
| 5497 | emacs_event->code = event->xbutton.button - Button1; | 6105 | emacs_event->code = event->xbutton.button - Button1; |
| 5498 | emacs_event->modifiers | 6106 | emacs_event->modifiers |
| 5499 | = (x_x_to_emacs_modifiers (FRAME_DISPLAY_INFO | 6107 | = (x_x_to_emacs_modifiers (FRAME_DISPLAY_INFO |
| @@ -5505,36 +6113,68 @@ x_scroll_bar_handle_click (struct scroll_bar *bar, | |||
| 5505 | emacs_event->frame_or_window = bar->window; | 6113 | emacs_event->frame_or_window = bar->window; |
| 5506 | emacs_event->arg = Qnil; | 6114 | emacs_event->arg = Qnil; |
| 5507 | emacs_event->timestamp = event->xbutton.time; | 6115 | emacs_event->timestamp = event->xbutton.time; |
| 5508 | { | 6116 | if (bar->horizontal) |
| 5509 | int top_range | 6117 | { |
| 5510 | = VERTICAL_SCROLL_BAR_TOP_RANGE (f, bar->height); | 6118 | int left_range |
| 5511 | int y = event->xbutton.y - VERTICAL_SCROLL_BAR_TOP_BORDER; | 6119 | = HORIZONTAL_SCROLL_BAR_LEFT_RANGE (f, bar->width); |
| 6120 | int x = event->xbutton.x - HORIZONTAL_SCROLL_BAR_LEFT_BORDER; | ||
| 5512 | 6121 | ||
| 5513 | if (y < 0) y = 0; | 6122 | if (x < 0) x = 0; |
| 5514 | if (y > top_range) y = top_range; | 6123 | if (x > left_range) x = left_range; |
| 5515 | 6124 | ||
| 5516 | if (y < bar->start) | 6125 | if (x < bar->start) |
| 5517 | emacs_event->part = scroll_bar_above_handle; | 6126 | emacs_event->part = scroll_bar_before_handle; |
| 5518 | else if (y < bar->end + VERTICAL_SCROLL_BAR_MIN_HANDLE) | 6127 | else if (x < bar->end + HORIZONTAL_SCROLL_BAR_MIN_HANDLE) |
| 5519 | emacs_event->part = scroll_bar_handle; | 6128 | emacs_event->part = scroll_bar_horizontal_handle; |
| 5520 | else | 6129 | else |
| 5521 | emacs_event->part = scroll_bar_below_handle; | 6130 | emacs_event->part = scroll_bar_after_handle; |
| 5522 | 6131 | ||
| 5523 | #ifndef USE_TOOLKIT_SCROLL_BARS | 6132 | #ifndef USE_TOOLKIT_SCROLL_BARS |
| 5524 | /* If the user has released the handle, set it to its final position. */ | 6133 | /* If the user has released the handle, set it to its final position. */ |
| 5525 | if (event->type == ButtonRelease && bar->dragging != -1) | 6134 | if (event->type == ButtonRelease && bar->dragging != -1) |
| 5526 | { | 6135 | { |
| 5527 | int new_start = y - bar->dragging; | 6136 | int new_start = - bar->dragging; |
| 5528 | int new_end = new_start + bar->end - bar->start; | 6137 | int new_end = new_start + bar->end - bar->start; |
| 5529 | 6138 | ||
| 5530 | x_scroll_bar_set_handle (bar, new_start, new_end, 0); | 6139 | x_scroll_bar_set_handle (bar, new_start, new_end, 0); |
| 5531 | bar->dragging = -1; | 6140 | bar->dragging = -1; |
| 5532 | } | 6141 | } |
| 5533 | #endif | 6142 | #endif |
| 5534 | 6143 | ||
| 5535 | XSETINT (emacs_event->x, y); | 6144 | XSETINT (emacs_event->x, left_range); |
| 5536 | XSETINT (emacs_event->y, top_range); | 6145 | XSETINT (emacs_event->y, x); |
| 5537 | } | 6146 | } |
| 6147 | else | ||
| 6148 | { | ||
| 6149 | int top_range | ||
| 6150 | = VERTICAL_SCROLL_BAR_TOP_RANGE (f, bar->height); | ||
| 6151 | int y = event->xbutton.y - VERTICAL_SCROLL_BAR_TOP_BORDER; | ||
| 6152 | |||
| 6153 | if (y < 0) y = 0; | ||
| 6154 | if (y > top_range) y = top_range; | ||
| 6155 | |||
| 6156 | if (y < bar->start) | ||
| 6157 | emacs_event->part = scroll_bar_above_handle; | ||
| 6158 | else if (y < bar->end + VERTICAL_SCROLL_BAR_MIN_HANDLE) | ||
| 6159 | emacs_event->part = scroll_bar_handle; | ||
| 6160 | else | ||
| 6161 | emacs_event->part = scroll_bar_below_handle; | ||
| 6162 | |||
| 6163 | #ifndef USE_TOOLKIT_SCROLL_BARS | ||
| 6164 | /* If the user has released the handle, set it to its final position. */ | ||
| 6165 | if (event->type == ButtonRelease && bar->dragging != -1) | ||
| 6166 | { | ||
| 6167 | int new_start = y - bar->dragging; | ||
| 6168 | int new_end = new_start + bar->end - bar->start; | ||
| 6169 | |||
| 6170 | x_scroll_bar_set_handle (bar, new_start, new_end, 0); | ||
| 6171 | bar->dragging = -1; | ||
| 6172 | } | ||
| 6173 | #endif | ||
| 6174 | |||
| 6175 | XSETINT (emacs_event->x, y); | ||
| 6176 | XSETINT (emacs_event->y, top_range); | ||
| 6177 | } | ||
| 5538 | } | 6178 | } |
| 5539 | 6179 | ||
| 5540 | #ifndef USE_TOOLKIT_SCROLL_BARS | 6180 | #ifndef USE_TOOLKIT_SCROLL_BARS |
| @@ -5641,6 +6281,75 @@ x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window, | |||
| 5641 | } | 6281 | } |
| 5642 | 6282 | ||
| 5643 | 6283 | ||
| 6284 | /* Return information to the user about the current position of the mouse | ||
| 6285 | on the scroll bar. */ | ||
| 6286 | |||
| 6287 | static void | ||
| 6288 | x_horizontal_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window, | ||
| 6289 | enum scroll_bar_part *part, Lisp_Object *x, | ||
| 6290 | Lisp_Object *y, Time *timestamp) | ||
| 6291 | { | ||
| 6292 | struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp); | ||
| 6293 | struct scroll_bar *bar = dpyinfo->last_mouse_scroll_bar; | ||
| 6294 | Window w = bar->x_window; | ||
| 6295 | struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); | ||
| 6296 | int win_x, win_y; | ||
| 6297 | Window dummy_window; | ||
| 6298 | int dummy_coord; | ||
| 6299 | unsigned int dummy_mask; | ||
| 6300 | |||
| 6301 | block_input (); | ||
| 6302 | |||
| 6303 | /* Get the mouse's position relative to the scroll bar window, and | ||
| 6304 | report that. */ | ||
| 6305 | if (XQueryPointer (FRAME_X_DISPLAY (f), w, | ||
| 6306 | |||
| 6307 | /* Root, child, root x and root y. */ | ||
| 6308 | &dummy_window, &dummy_window, | ||
| 6309 | &dummy_coord, &dummy_coord, | ||
| 6310 | |||
| 6311 | /* Position relative to scroll bar. */ | ||
| 6312 | &win_x, &win_y, | ||
| 6313 | |||
| 6314 | /* Mouse buttons and modifier keys. */ | ||
| 6315 | &dummy_mask)) | ||
| 6316 | { | ||
| 6317 | int left_range = HORIZONTAL_SCROLL_BAR_LEFT_RANGE (f, bar->width); | ||
| 6318 | |||
| 6319 | win_x -= HORIZONTAL_SCROLL_BAR_LEFT_BORDER; | ||
| 6320 | |||
| 6321 | if (bar->dragging != -1) | ||
| 6322 | win_x -= bar->dragging; | ||
| 6323 | |||
| 6324 | if (win_x < 0) | ||
| 6325 | win_x = 0; | ||
| 6326 | if (win_x > left_range) | ||
| 6327 | win_x = left_range; | ||
| 6328 | |||
| 6329 | *fp = f; | ||
| 6330 | *bar_window = bar->window; | ||
| 6331 | |||
| 6332 | if (bar->dragging != -1) | ||
| 6333 | *part = scroll_bar_horizontal_handle; | ||
| 6334 | else if (win_x < bar->start) | ||
| 6335 | *part = scroll_bar_before_handle; | ||
| 6336 | else if (win_x < bar->end + HORIZONTAL_SCROLL_BAR_MIN_HANDLE) | ||
| 6337 | *part = scroll_bar_handle; | ||
| 6338 | else | ||
| 6339 | *part = scroll_bar_after_handle; | ||
| 6340 | |||
| 6341 | XSETINT (*y, win_x); | ||
| 6342 | XSETINT (*x, left_range); | ||
| 6343 | |||
| 6344 | f->mouse_moved = 0; | ||
| 6345 | dpyinfo->last_mouse_scroll_bar = NULL; | ||
| 6346 | *timestamp = dpyinfo->last_mouse_movement_time; | ||
| 6347 | } | ||
| 6348 | |||
| 6349 | unblock_input (); | ||
| 6350 | } | ||
| 6351 | |||
| 6352 | |||
| 5644 | /* The screen has been cleared so we may have changed foreground or | 6353 | /* The screen has been cleared so we may have changed foreground or |
| 5645 | background colors, and the scroll bars may need to be redrawn. | 6354 | background colors, and the scroll bars may need to be redrawn. |
| 5646 | Clear out the scroll bars, and ask for expose events, so we can | 6355 | Clear out the scroll bars, and ask for expose events, so we can |
| @@ -5783,6 +6492,35 @@ static void xembed_send_message (struct frame *f, Time, | |||
| 5783 | enum xembed_message, | 6492 | enum xembed_message, |
| 5784 | long detail, long data1, long data2); | 6493 | long detail, long data1, long data2); |
| 5785 | 6494 | ||
| 6495 | static void | ||
| 6496 | x_net_wm_state (struct frame *f, Window window) | ||
| 6497 | { | ||
| 6498 | int value = FULLSCREEN_NONE; | ||
| 6499 | Lisp_Object lval = Qnil; | ||
| 6500 | int sticky = 0; | ||
| 6501 | |||
| 6502 | (void)get_current_wm_state (f, window, &value, &sticky); | ||
| 6503 | |||
| 6504 | switch (value) | ||
| 6505 | { | ||
| 6506 | case FULLSCREEN_WIDTH: | ||
| 6507 | lval = Qfullwidth; | ||
| 6508 | break; | ||
| 6509 | case FULLSCREEN_HEIGHT: | ||
| 6510 | lval = Qfullheight; | ||
| 6511 | break; | ||
| 6512 | case FULLSCREEN_BOTH: | ||
| 6513 | lval = Qfullboth; | ||
| 6514 | break; | ||
| 6515 | case FULLSCREEN_MAXIMIZED: | ||
| 6516 | lval = Qmaximized; | ||
| 6517 | break; | ||
| 6518 | } | ||
| 6519 | |||
| 6520 | store_frame_param (f, Qfullscreen, lval); | ||
| 6521 | /** store_frame_param (f, Qsticky, sticky ? Qt : Qnil); **/ | ||
| 6522 | } | ||
| 6523 | |||
| 5786 | /* Handles the XEvent EVENT on display DPYINFO. | 6524 | /* Handles the XEvent EVENT on display DPYINFO. |
| 5787 | 6525 | ||
| 5788 | *FINISH is X_EVENT_GOTO_OUT if caller should stop reading events. | 6526 | *FINISH is X_EVENT_GOTO_OUT if caller should stop reading events. |
| @@ -5980,6 +6718,12 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 5980 | *finish = X_EVENT_GOTO_OUT; | 6718 | *finish = X_EVENT_GOTO_OUT; |
| 5981 | goto done; | 6719 | goto done; |
| 5982 | } | 6720 | } |
| 6721 | else if (event->xclient.message_type == dpyinfo->Xatom_Horizontal_Scrollbar) | ||
| 6722 | { | ||
| 6723 | x_horizontal_scroll_bar_to_input_event (event, &inev.ie); | ||
| 6724 | *finish = X_EVENT_GOTO_OUT; | ||
| 6725 | goto done; | ||
| 6726 | } | ||
| 5983 | #endif /* USE_TOOLKIT_SCROLL_BARS */ | 6727 | #endif /* USE_TOOLKIT_SCROLL_BARS */ |
| 5984 | 6728 | ||
| 5985 | /* XEmbed messages from the embedder (if any). */ | 6729 | /* XEmbed messages from the embedder (if any). */ |
| @@ -6131,7 +6875,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 6131 | goto OTHER; | 6875 | goto OTHER; |
| 6132 | #else /* not USE_TOOLKIT_SCROLL_BARS */ | 6876 | #else /* not USE_TOOLKIT_SCROLL_BARS */ |
| 6133 | bar = x_window_to_scroll_bar (event->xexpose.display, | 6877 | bar = x_window_to_scroll_bar (event->xexpose.display, |
| 6134 | event->xexpose.window); | 6878 | event->xexpose.window, 2); |
| 6135 | 6879 | ||
| 6136 | if (bar) | 6880 | if (bar) |
| 6137 | x_scroll_bar_expose (bar, event); | 6881 | x_scroll_bar_expose (bar, event); |
| @@ -6695,7 +7439,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 6695 | #ifndef USE_TOOLKIT_SCROLL_BARS | 7439 | #ifndef USE_TOOLKIT_SCROLL_BARS |
| 6696 | struct scroll_bar *bar | 7440 | struct scroll_bar *bar |
| 6697 | = x_window_to_scroll_bar (event->xmotion.display, | 7441 | = x_window_to_scroll_bar (event->xmotion.display, |
| 6698 | event->xmotion.window); | 7442 | event->xmotion.window, 2); |
| 6699 | 7443 | ||
| 6700 | if (bar) | 7444 | if (bar) |
| 6701 | x_scroll_bar_note_movement (bar, &event->xmotion); | 7445 | x_scroll_bar_note_movement (bar, &event->xmotion); |
| @@ -6728,6 +7472,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 6728 | #endif | 7472 | #endif |
| 6729 | if (f) | 7473 | if (f) |
| 6730 | { | 7474 | { |
| 7475 | x_net_wm_state (f, event->xconfigure.window); | ||
| 7476 | |||
| 6731 | #ifndef USE_X_TOOLKIT | 7477 | #ifndef USE_X_TOOLKIT |
| 6732 | #ifndef USE_GTK | 7478 | #ifndef USE_GTK |
| 6733 | int width = FRAME_PIXEL_TO_TEXT_WIDTH (f, event->xconfigure.width); | 7479 | int width = FRAME_PIXEL_TO_TEXT_WIDTH (f, event->xconfigure.width); |
| @@ -6838,7 +7584,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 6838 | { | 7584 | { |
| 6839 | struct scroll_bar *bar | 7585 | struct scroll_bar *bar |
| 6840 | = x_window_to_scroll_bar (event->xbutton.display, | 7586 | = x_window_to_scroll_bar (event->xbutton.display, |
| 6841 | event->xbutton.window); | 7587 | event->xbutton.window, 2); |
| 6842 | 7588 | ||
| 6843 | #ifdef USE_TOOLKIT_SCROLL_BARS | 7589 | #ifdef USE_TOOLKIT_SCROLL_BARS |
| 6844 | /* Make the "Ctrl-Mouse-2 splits window" work for toolkit | 7590 | /* Make the "Ctrl-Mouse-2 splits window" work for toolkit |
| @@ -7824,10 +8570,10 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset) | |||
| 7824 | FRAME_COLUMN_WIDTH (f) = font->average_width; | 8570 | FRAME_COLUMN_WIDTH (f) = font->average_width; |
| 7825 | FRAME_LINE_HEIGHT (f) = FONT_HEIGHT (font); | 8571 | FRAME_LINE_HEIGHT (f) = FONT_HEIGHT (font); |
| 7826 | 8572 | ||
| 7827 | FRAME_TOOL_BAR_HEIGHT (f) = FRAME_TOOL_BAR_LINES (f) * FRAME_LINE_HEIGHT (f); | 8573 | #ifndef USE_X_TOOLKIT \ |
| 8574 | /** FRAME_TOOL_BAR_HEIGHT (f) = FRAME_TOOL_BAR_LINES (f) * FRAME_LINE_HEIGHT (f); **/ | ||
| 7828 | FRAME_MENU_BAR_HEIGHT (f) = FRAME_MENU_BAR_LINES (f) * FRAME_LINE_HEIGHT (f); | 8575 | FRAME_MENU_BAR_HEIGHT (f) = FRAME_MENU_BAR_LINES (f) * FRAME_LINE_HEIGHT (f); |
| 7829 | 8576 | #endif | |
| 7830 | compute_fringe_widths (f, 1); | ||
| 7831 | 8577 | ||
| 7832 | /* Compute character columns occupied by scrollbar. | 8578 | /* Compute character columns occupied by scrollbar. |
| 7833 | 8579 | ||
| @@ -8658,7 +9404,7 @@ x_wait_for_event (struct frame *f, int eventtype) | |||
| 8658 | } | 9404 | } |
| 8659 | 9405 | ||
| 8660 | 9406 | ||
| 8661 | /* Change the size of frame F's X window to COLS/ROWS in the case F | 9407 | /* Change the size of frame F's X window to WIDTH/HEIGHT in the case F |
| 8662 | doesn't have a widget. If CHANGE_GRAVITY is 1, we change to | 9408 | doesn't have a widget. If CHANGE_GRAVITY is 1, we change to |
| 8663 | top-left-corner window gravity for this size change and subsequent | 9409 | top-left-corner window gravity for this size change and subsequent |
| 8664 | size changes. Otherwise we leave the window gravity unchanged. */ | 9410 | size changes. Otherwise we leave the window gravity unchanged. */ |
| @@ -8668,23 +9414,39 @@ x_set_window_size_1 (struct frame *f, int change_gravity, int width, int height, | |||
| 8668 | { | 9414 | { |
| 8669 | int pixelwidth, pixelheight; | 9415 | int pixelwidth, pixelheight; |
| 8670 | 9416 | ||
| 8671 | check_frame_size (f, &width, &height, pixelwise); | 9417 | /** if (pixelwise) **/ |
| 8672 | 9418 | /** { **/ | |
| 8673 | compute_fringe_widths (f, 0); | 9419 | /** pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width); **/ |
| 8674 | 9420 | /** pixelheight = FRAME_TEXT_TO_PIXEL_HEIGHT (f, height); **/ | |
| 8675 | pixelwidth = ((pixelwise | 9421 | /** } **/ |
| 8676 | ? FRAME_TEXT_TO_PIXEL_WIDTH (f, width) | 9422 | /** else **/ |
| 8677 | : FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width)) | 9423 | /** { **/ |
| 8678 | + FRAME_TOOLBAR_WIDTH (f)); | 9424 | /** pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width); **/ |
| 9425 | /** pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height); **/ | ||
| 9426 | /** } **/ | ||
| 9427 | |||
| 9428 | /** FRAME_TOOL_BAR_HEIGHT (f) = FRAME_TOOLBAR_HEIGHT (f); **/ | ||
| 9429 | pixelwidth = (pixelwise | ||
| 9430 | ? FRAME_TEXT_TO_PIXEL_WIDTH (f, width) | ||
| 9431 | : FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width)); | ||
| 8679 | pixelheight = ((pixelwise | 9432 | pixelheight = ((pixelwise |
| 8680 | ? FRAME_TEXT_TO_PIXEL_HEIGHT (f, height) | 9433 | ? FRAME_TEXT_TO_PIXEL_HEIGHT (f, height) |
| 8681 | : FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height)) | 9434 | : FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height))); |
| 8682 | + FRAME_MENUBAR_HEIGHT (f) | 9435 | |
| 8683 | + FRAME_TOOLBAR_HEIGHT (f)); | 9436 | /** pixelwidth = ((pixelwise ? width : (width * FRAME_COLUMN_WIDTH (f))) **/ |
| 9437 | /** + FRAME_SCROLL_BAR_AREA_WIDTH (f) **/ | ||
| 9438 | /** + FRAME_TOTAL_FRINGE_WIDTH (f) **/ | ||
| 9439 | /** + 2 * FRAME_INTERNAL_BORDER_WIDTH (f)); **/ | ||
| 9440 | |||
| 9441 | /** pixelheight = ((pixelwise ? height : (height * FRAME_LINE_HEIGHT (f))) **/ | ||
| 9442 | /** + FRAME_TOOLBAR_HEIGHT (f) **/ | ||
| 9443 | /** + FRAME_SCROLL_BAR_AREA_HEIGHT (f) **/ | ||
| 9444 | /** + 2 * FRAME_INTERNAL_BORDER_WIDTH (f)); **/ | ||
| 9445 | |||
| 8684 | if (change_gravity) f->win_gravity = NorthWestGravity; | 9446 | if (change_gravity) f->win_gravity = NorthWestGravity; |
| 8685 | x_wm_set_size_hint (f, 0, 0); | 9447 | x_wm_set_size_hint (f, 0, 0); |
| 8686 | XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), | 9448 | XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), |
| 8687 | pixelwidth, pixelheight); | 9449 | pixelwidth, pixelheight + FRAME_MENUBAR_HEIGHT (f)); |
| 8688 | 9450 | ||
| 8689 | 9451 | ||
| 8690 | /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to | 9452 | /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to |
| @@ -8714,7 +9476,7 @@ x_set_window_size_1 (struct frame *f, int change_gravity, int width, int height, | |||
| 8714 | x_wait_for_event (f, ConfigureNotify); | 9476 | x_wait_for_event (f, ConfigureNotify); |
| 8715 | else | 9477 | else |
| 8716 | { | 9478 | { |
| 8717 | change_frame_size (f, width, height, 0, 1, 0, 1); | 9479 | change_frame_size (f, pixelwidth, pixelheight, 0, 1, 0, 1); |
| 8718 | x_sync (f); | 9480 | x_sync (f); |
| 8719 | } | 9481 | } |
| 8720 | } | 9482 | } |
| @@ -8730,8 +9492,9 @@ x_set_window_size (struct frame *f, int change_gravity, int width, int height, b | |||
| 8730 | { | 9492 | { |
| 8731 | block_input (); | 9493 | block_input (); |
| 8732 | 9494 | ||
| 8733 | check_frame_size (f, &width, &height, pixelwise); | 9495 | /* The following breaks our calculations. If it's really needed, |
| 8734 | 9496 | think of something else. */ | |
| 9497 | #if 0 | ||
| 8735 | if (NILP (tip_frame) || XFRAME (tip_frame) != f) | 9498 | if (NILP (tip_frame) || XFRAME (tip_frame) != f) |
| 8736 | { | 9499 | { |
| 8737 | int text_width, text_height; | 9500 | int text_width, text_height; |
| @@ -8754,6 +9517,7 @@ x_set_window_size (struct frame *f, int change_gravity, int width, int height, b | |||
| 8754 | 9517 | ||
| 8755 | change_frame_size (f, text_width, text_height, 0, 1, 0, 1); | 9518 | change_frame_size (f, text_width, text_height, 0, 1, 0, 1); |
| 8756 | } | 9519 | } |
| 9520 | #endif | ||
| 8757 | 9521 | ||
| 8758 | #ifdef USE_GTK | 9522 | #ifdef USE_GTK |
| 8759 | if (FRAME_GTK_WIDGET (f)) | 9523 | if (FRAME_GTK_WIDGET (f)) |
| @@ -8767,9 +9531,7 @@ x_set_window_size (struct frame *f, int change_gravity, int width, int height, b | |||
| 8767 | #else /* not USE_GTK */ | 9531 | #else /* not USE_GTK */ |
| 8768 | 9532 | ||
| 8769 | x_set_window_size_1 (f, change_gravity, width, height, pixelwise); | 9533 | x_set_window_size_1 (f, change_gravity, width, height, pixelwise); |
| 8770 | #if !defined USE_X_TOOLKIT | ||
| 8771 | x_clear_under_internal_border (f); | 9534 | x_clear_under_internal_border (f); |
| 8772 | #endif | ||
| 8773 | 9535 | ||
| 8774 | #endif /* not USE_GTK */ | 9536 | #endif /* not USE_GTK */ |
| 8775 | 9537 | ||
| @@ -8783,6 +9545,8 @@ x_set_window_size (struct frame *f, int change_gravity, int width, int height, b | |||
| 8783 | cancel_mouse_face (f); | 9545 | cancel_mouse_face (f); |
| 8784 | 9546 | ||
| 8785 | unblock_input (); | 9547 | unblock_input (); |
| 9548 | |||
| 9549 | do_pending_window_change (0); | ||
| 8786 | } | 9550 | } |
| 8787 | 9551 | ||
| 8788 | /* Move the mouse to position pixel PIX_X, PIX_Y relative to frame F. */ | 9552 | /* Move the mouse to position pixel PIX_X, PIX_Y relative to frame F. */ |
| @@ -9419,6 +10183,9 @@ x_wm_set_size_hint (struct frame *f, long flags, bool user_position) | |||
| 9419 | XSizeHints size_hints; | 10183 | XSizeHints size_hints; |
| 9420 | Window window = FRAME_OUTER_WINDOW (f); | 10184 | Window window = FRAME_OUTER_WINDOW (f); |
| 9421 | 10185 | ||
| 10186 | if (!window) | ||
| 10187 | return; | ||
| 10188 | |||
| 9422 | #ifdef USE_X_TOOLKIT | 10189 | #ifdef USE_X_TOOLKIT |
| 9423 | if (f->output_data.x->widget) | 10190 | if (f->output_data.x->widget) |
| 9424 | { | 10191 | { |
| @@ -9452,8 +10219,6 @@ x_wm_set_size_hint (struct frame *f, long flags, bool user_position) | |||
| 9452 | base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0); | 10219 | base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0); |
| 9453 | base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0); | 10220 | base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0); |
| 9454 | 10221 | ||
| 9455 | check_frame_size (f, &min_cols, &min_rows, 0); | ||
| 9456 | |||
| 9457 | if (frame_resize_pixelwise) | 10222 | if (frame_resize_pixelwise) |
| 9458 | /* Needed to prevent a bad protocol error crash when making the | 10223 | /* Needed to prevent a bad protocol error crash when making the |
| 9459 | frame size very small. */ | 10224 | frame size very small. */ |
| @@ -10079,6 +10844,9 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) | |||
| 10079 | dpyinfo->vertical_scroll_bar_cursor | 10844 | dpyinfo->vertical_scroll_bar_cursor |
| 10080 | = XCreateFontCursor (dpyinfo->display, XC_sb_v_double_arrow); | 10845 | = XCreateFontCursor (dpyinfo->display, XC_sb_v_double_arrow); |
| 10081 | 10846 | ||
| 10847 | dpyinfo->horizontal_scroll_bar_cursor | ||
| 10848 | = XCreateFontCursor (dpyinfo->display, XC_sb_h_double_arrow); | ||
| 10849 | |||
| 10082 | xrdb = x_load_resources (dpyinfo->display, xrm_option, | 10850 | xrdb = x_load_resources (dpyinfo->display, xrm_option, |
| 10083 | resource_name, EMACS_CLASS); | 10851 | resource_name, EMACS_CLASS); |
| 10084 | #ifdef HAVE_XRMSETDATABASE | 10852 | #ifdef HAVE_XRMSETDATABASE |
| @@ -10214,6 +10982,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) | |||
| 10214 | ATOM_REFS_INIT ("DONE", Xatom_DONE) | 10982 | ATOM_REFS_INIT ("DONE", Xatom_DONE) |
| 10215 | ATOM_REFS_INIT ("PAGE", Xatom_PAGE) | 10983 | ATOM_REFS_INIT ("PAGE", Xatom_PAGE) |
| 10216 | ATOM_REFS_INIT ("SCROLLBAR", Xatom_Scrollbar) | 10984 | ATOM_REFS_INIT ("SCROLLBAR", Xatom_Scrollbar) |
| 10985 | ATOM_REFS_INIT ("HORIZONTAL_SCROLLBAR", Xatom_Horizontal_Scrollbar) | ||
| 10217 | ATOM_REFS_INIT ("_XEMBED", Xatom_XEMBED) | 10986 | ATOM_REFS_INIT ("_XEMBED", Xatom_XEMBED) |
| 10218 | /* EWMH */ | 10987 | /* EWMH */ |
| 10219 | ATOM_REFS_INIT ("_NET_WM_STATE", Xatom_net_wm_state) | 10988 | ATOM_REFS_INIT ("_NET_WM_STATE", Xatom_net_wm_state) |
| @@ -10602,6 +11371,7 @@ x_create_terminal (struct x_display_info *dpyinfo) | |||
| 10602 | terminal->popup_dialog_hook = xw_popup_dialog; | 11371 | terminal->popup_dialog_hook = xw_popup_dialog; |
| 10603 | #endif | 11372 | #endif |
| 10604 | terminal->set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar; | 11373 | terminal->set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar; |
| 11374 | terminal->set_horizontal_scroll_bar_hook = XTset_horizontal_scroll_bar; | ||
| 10605 | terminal->condemn_scroll_bars_hook = XTcondemn_scroll_bars; | 11375 | terminal->condemn_scroll_bars_hook = XTcondemn_scroll_bars; |
| 10606 | terminal->redeem_scroll_bar_hook = XTredeem_scroll_bar; | 11376 | terminal->redeem_scroll_bar_hook = XTredeem_scroll_bar; |
| 10607 | terminal->judge_scroll_bars_hook = XTjudge_scroll_bars; | 11377 | terminal->judge_scroll_bars_hook = XTjudge_scroll_bars; |