To: vim-dev@vim.org Subject: patch 5.5a.14 Fcc: outbox From: Bram Moolenaar ------------ Bending the term 'bug fix' a bit... Patch 5.5a.14 Problem: Athena, Motif and GTK: The mouse scroll wheel doesn't work. Solution: Interpret a click of the wheel as a key press of the or keys. Default behavior is to scroll three lines, or a full page when Shift is used. Files: src/edit.c, src/ex_getln.c, src/gui.c, src/gui_gtk_x11.c, src/gui_x11.c, src/keymap.h, src/message.c, src/misc1.c, src/misc2.c, src/normal.c, src/proto/normal.pro, src/vim.h, runtime/doc/scroll.txt *** ../vim-5.5a.13/src/edit.c Wed Sep 1 18:02:55 1999 --- src/edit.c Thu Sep 9 17:06:23 1999 *************** *** 129,134 **** --- 129,135 ---- static int ins_bs __ARGS((int c, int mode, int *inserted_space_p)); #ifdef USE_MOUSE static void ins_mouse __ARGS((int c)); + static void ins_mousescroll __ARGS((int up)); #endif static void ins_left __ARGS((void)); static void ins_home __ARGS((void)); *************** *** 849,854 **** --- 850,865 ---- case K_IGNORE: break; + + /* Default action for scroll wheel up: scroll up */ + case K_MOUSEDOWN: + ins_mousescroll(FALSE); + break; + + /* Default action for scroll wheel down: scroll down */ + case K_MOUSEUP: + ins_mousescroll(TRUE); + break; #endif #ifdef USE_GUI *************** *** 5092,5097 **** --- 5103,5129 ---- /* redraw status lines (in case another window became active) */ redraw_statuslines(); } + + static void + ins_mousescroll(up) + int up; + { + FPOS tpos; + + undisplay_dollar(); + tpos = curwin->w_cursor; + if (mod_mask & MOD_MASK_SHIFT) + scroll_redraw(up, (long)(curwin->w_botline - curwin->w_topline)); + else + scroll_redraw(up, 3L); + if (!equal(curwin->w_cursor, tpos)) + { + start_arrow(&tpos); + # ifdef CINDENT + can_cindent = TRUE; + # endif + } + } #endif #ifdef USE_GUI *************** *** 5121,5129 **** if (gui_do_horiz_scroll()) { start_arrow(&tpos); ! #ifdef CINDENT can_cindent = TRUE; ! #endif } } #endif --- 5153,5161 ---- if (gui_do_horiz_scroll()) { start_arrow(&tpos); ! # ifdef CINDENT can_cindent = TRUE; ! # endif } } #endif *** ../vim-5.5a.13/src/ex_getln.c Mon Aug 30 10:40:50 1999 --- src/ex_getln.c Thu Sep 9 17:06:26 1999 *************** *** 858,863 **** --- 858,869 ---- ccline.cmdspos += i; } goto cmdline_not_changed; + + /* Mouse scroll wheel: ignored here */ + case K_MOUSEDOWN: + case K_MOUSEUP: + goto cmdline_not_changed; + #endif /* USE_MOUSE */ #ifdef USE_GUI *** ../vim-5.5a.13/src/gui.c Mon Aug 30 10:40:59 1999 --- src/gui.c Thu Sep 9 17:05:52 1999 *************** *** 1817,1822 **** --- 1817,1823 ---- * the given properties. * button --- may be any of MOUSE_LEFT, MOUSE_MIDDLE, MOUSE_RIGHT, * MOUSE_DRAG, or MOUSE_RELEASE. + * MOUSE_4 and MOUSE_5 are used for a scroll wheel. * x, y --- Coordinates of mouse in pixels. * repeated_click --- TRUE if this click comes only a short time after a * previous click. *************** *** 1838,1849 **** static int num_clicks = 1; char_u string[6]; int row, col; - #ifdef USE_CLIPBOARD - int checkfor; int did_clip = FALSE; /* If a clipboard selection is in progress, handle it */ if (clipboard.state == SELECT_IN_PROGRESS) { --- 1839,1880 ---- static int num_clicks = 1; char_u string[6]; int row, col; #ifdef USE_CLIPBOARD int checkfor; int did_clip = FALSE; + #endif + + /* + * Scrolling may happen at any time, also while a selection is present. + */ + if (button == MOUSE_4 || button == MOUSE_5) + { + /* Don't put events in the input queue now. */ + if (hold_gui_events) + return; + string[3] = CSI; + string[4] = KS_EXTRA; + string[5] = button == MOUSE_4 ? KE_MOUSEDOWN : KE_MOUSEUP; + if (modifiers == 0) + add_to_input_buf(string + 3, 3); + else + { + string[0] = CSI; + string[1] = KS_MODIFIER; + string[2] = 0; + if (modifiers & MOUSE_SHIFT) + string[2] |= MOD_MASK_SHIFT; + if (modifiers & MOUSE_CTRL) + string[2] |= MOD_MASK_CTRL; + if (modifiers & MOUSE_ALT) + string[2] |= MOD_MASK_ALT; + add_to_input_buf(string, 6); + } + return; + } + + #ifdef USE_CLIPBOARD /* If a clipboard selection is in progress, handle it */ if (clipboard.state == SELECT_IN_PROGRESS) { *** ../vim-5.5a.13/src/gui_gtk_x11.c Mon Aug 30 10:40:53 1999 --- src/gui_gtk_x11.c Thu Sep 9 15:20:51 1999 *************** *** 2642,2648 **** mouse_click_timer = gtk_timeout_add(p_mouset, mouse_click_timer_cb, &mouse_timed_out); ! switch (event->button) { case 1: button = MOUSE_LEFT; break; --- 2642,2649 ---- mouse_click_timer = gtk_timeout_add(p_mouset, mouse_click_timer_cb, &mouse_timed_out); ! switch (event->button) ! { case 1: button = MOUSE_LEFT; break; *************** *** 2651,2656 **** --- 2652,2663 ---- break; case 3: button = MOUSE_RIGHT; + break; + case 4: + button = MOUSE_4; + break; + case 5: + button = MOUSE_5; break; default: return FALSE; /* Unknown button */ *** ../vim-5.5a.13/src/gui_x11.c Mon Aug 30 10:40:54 1999 --- src/gui_x11.c Thu Sep 9 13:20:19 1999 *************** *** 792,797 **** --- 795,802 ---- case Button1: button = MOUSE_LEFT; break; case Button2: button = MOUSE_MIDDLE; break; case Button3: button = MOUSE_RIGHT; break; + case Button4: button = MOUSE_4; break; + case Button5: button = MOUSE_5; break; default: return; /* Unknown button */ } *** ../vim-5.5a.13/src/keymap.h Mon Aug 30 10:40:47 1999 --- src/keymap.h Thu Sep 9 17:06:35 1999 *************** *** 200,206 **** KE_S_XF1, /* extra vt100 shifted function keys for xterm */ KE_S_XF2, KE_S_XF3, ! KE_S_XF4 }; /* --- 200,209 ---- KE_S_XF1, /* extra vt100 shifted function keys for xterm */ KE_S_XF2, KE_S_XF3, ! KE_S_XF4, ! ! KE_MOUSEDOWN, /* scroll wheel pseudo-button Down */ ! KE_MOUSEUP /* scroll wheel pseudo-button Up */ }; /* *************** *** 362,367 **** --- 365,373 ---- #define K_IGNORE TERMCAP2KEY(KS_EXTRA, KE_IGNORE) #define K_SNIFF TERMCAP2KEY(KS_EXTRA, KE_SNIFF) + + #define K_MOUSEDOWN TERMCAP2KEY(KS_EXTRA, KE_MOUSEDOWN) + #define K_MOUSEUP TERMCAP2KEY(KS_EXTRA, KE_MOUSEUP) /* Bits for modifier mask */ /* 0x01 cannot be used, because the modifier must be 0x02 or higher */ *** ../vim-5.5a.13/src/message.c Mon Aug 30 10:40:58 1999 --- src/message.c Thu Sep 9 17:06:40 1999 *************** *** 589,594 **** --- 589,595 ---- || c == K_LEFTDRAG || c == K_LEFTRELEASE || c == K_MIDDLEDRAG || c == K_MIDDLERELEASE || c == K_RIGHTDRAG || c == K_RIGHTRELEASE + || c == K_MOUSEDOWN || c == K_MOUSEUP || c == K_IGNORE || (!mouse_has(MOUSE_RETURN) && (c == K_LEFTMOUSE || *** ../vim-5.5a.13/src/misc1.c Mon Aug 30 10:40:51 1999 --- src/misc1.c Thu Sep 9 17:06:43 1999 *************** *** 2056,2061 **** --- 2056,2063 ---- || n == K_RIGHTMOUSE || n == K_RIGHTDRAG || n == K_RIGHTRELEASE + || n == K_MOUSEDOWN + || n == K_MOUSEUP # ifdef USE_GUI || n == K_SCROLLBAR || n == K_HORIZ_SCROLLBAR *** ../vim-5.5a.13/src/misc2.c Mon Aug 30 10:40:52 1999 --- src/misc2.c Thu Sep 9 17:06:50 1999 *************** *** 1422,1427 **** --- 1422,1429 ---- {K_RIGHTMOUSE, (char_u *)"RightMouse"}, {K_RIGHTDRAG, (char_u *)"RightDrag"}, {K_RIGHTRELEASE, (char_u *)"RightRelease"}, + {K_MOUSEDOWN, (char_u *)"MouseDown"}, + {K_MOUSEUP, (char_u *)"MouseUp"}, {K_ZERO, (char_u *)"Nul"}, {0, NULL} }; *** ../vim-5.5a.13/src/normal.c Mon Aug 30 10:40:58 1999 --- src/normal.c Thu Sep 9 17:07:00 1999 *************** *** 1180,1185 **** --- 1180,1198 ---- case K_IGNORE: break; + + /* Mouse scroll wheel: default action is to scroll three lines, or one + * page when Shift is used. */ + case K_MOUSEUP: + flag = TRUE; + case K_MOUSEDOWN: + if (mod_mask & MOD_MASK_SHIFT) + ca.count1 = curwin->w_botline - curwin->w_topline; + else + ca.count1 = 3; + ca.count0 = ca.count1; + nv_scroll_line(&ca, flag); + break; #endif #ifdef USE_GUI *************** *** 2860,2865 **** --- 2873,2879 ---- K_LEFTMOUSE, K_LEFTDRAG, K_LEFTRELEASE, K_MIDDLEMOUSE, K_MIDDLEDRAG, K_MIDDLERELEASE, K_RIGHTMOUSE, K_RIGHTDRAG, K_RIGHTRELEASE, + K_MOUSEDOWN, K_MOUSEUP, 0}; #endif *************** *** 3274,3290 **** */ static void nv_scroll_line(cap, is_ctrl_e) ! CMDARG *cap; ! int is_ctrl_e; /* TRUE for CTRL-E command */ { - linenr_t prev_topline = curwin->w_topline; - if (checkclearop(cap->oap)) return; ! if (is_ctrl_e) ! scrollup(cap->count1); else ! scrolldown(cap->count1); if (p_so) { cursor_correct(); --- 3288,3316 ---- */ static void nv_scroll_line(cap, is_ctrl_e) ! CMDARG *cap; ! int is_ctrl_e; /* TRUE for CTRL-E command */ { if (checkclearop(cap->oap)) return; ! scroll_redraw(is_ctrl_e, cap->count1); ! } ! ! /* ! * Scroll "count" lines up or down, and redraw. ! */ ! void ! scroll_redraw(up, count) ! int up; ! long count; ! { ! linenr_t prev_topline = curwin->w_topline; ! linenr_t prev_lnum = curwin->w_cursor.lnum; ! ! if (up) ! scrollup(count); else ! scrolldown(count); if (p_so) { cursor_correct(); *************** *** 3294,3306 **** * first line of the buffer is already on the screen */ if (curwin->w_topline == prev_topline) { ! if (is_ctrl_e) cursor_down(1L, FALSE); else if (prev_topline != 1L) cursor_up(1L, FALSE); } } ! coladvance(curwin->w_curswant); update_screen(VALID); } --- 3320,3333 ---- * first line of the buffer is already on the screen */ if (curwin->w_topline == prev_topline) { ! if (up) cursor_down(1L, FALSE); else if (prev_topline != 1L) cursor_up(1L, FALSE); } } ! if (curwin->w_cursor.lnum != prev_lnum) ! coladvance(curwin->w_curswant); update_screen(VALID); } *** ../vim-5.5a.13/src/proto/normal.pro Mon Aug 30 10:40:39 1999 --- src/proto/normal.pro Thu Sep 9 14:45:32 1999 *************** *** 12,16 **** --- 12,17 ---- void pop_showcmd __ARGS((void)); void do_check_scrollbind __ARGS((int check)); void check_scrollbind __ARGS((linenr_t topline_diff, long leftcol_diff)); + void scroll_redraw __ARGS((int up, long count)); void start_selection __ARGS((void)); void may_start_select __ARGS((int c)); *** ../vim-5.5a.13/src/vim.h Mon Aug 30 10:40:48 1999 --- src/vim.h Thu Sep 9 17:13:43 1999 *************** *** 886,891 **** --- 886,895 ---- # define MOUSE_ALT 0x08 # define MOUSE_CTRL 0x10 + /* mouse buttons that are handled like a key press */ + # define MOUSE_4 0x100 /* scroll wheel down */ + # define MOUSE_5 0x200 /* scroll wheel up */ + /* 0x20 is reserved by xterm */ # define MOUSE_DRAG_XTERM 0x40 *** ../vim-5.5a.13/runtime/doc/scroll.txt Mon Aug 30 10:41:12 1999 --- runtime/doc/scroll.txt Thu Sep 9 17:02:59 1999 *************** *** 1,4 **** ! *scroll.txt* For Vim version 5.5a. Last change: 1999 Mar 31 VIM REFERENCE MANUAL by Bram Moolenaar --- 1,4 ---- ! *scroll.txt* For Vim version 5.5a. Last change: 1999 Sep 09 VIM REFERENCE MANUAL by Bram Moolenaar *************** *** 19,24 **** --- 19,25 ---- 3. Scrolling relative to cursor |scroll-cursor| 4. Scrolling horizontally |scroll-horizontal| 5. Scrolling synchronously |scroll-binding| + 6. Scrolling with a mouse wheel |scroll-mouse-wheel| ============================================================================== 1. Scrolling downwards *scroll-down* *************** *** 195,199 **** --- 196,237 ---- window which has the cursor focus. However, when using the vertical scrollbar of a window which doesn't have the cursor focus, 'scrollbind' is ignored. This allows quick adjustment of the relative offset of 'scrollbind' windows. + + ============================================================================== + 6. Scrolling with a mouse wheel *scroll-mouse-wheel* + + When your mouse has a scroll wheel, it should work with Vim in the GUI. How + it works depends on your system. + + For the Win32 GUI the scroll action is hard coded. It works just like + dragging the scrollbar of the current window. How many lines are scrolled + depends on your mouse driver. If the scroll action causes input focus + problems, see |intellimouse-wheel-problems|. + + For the X11 GUIs (Motif, Athena and GTK) scrolling the wheel generates key + presses and . The default action for these keys are: + scroll three lines down. ** + scroll a full page down. ** + scroll three lines up. ** + scroll a full page up. ** + This should work in all modes, except when editing the command line. + + You can modify this behavior by mapping the keys. For example, to make the + scroll wheel move one line or half a page in Normal mode: + > map + > map + > map + > map + You can also use Alt and Ctrl modifiers. + + This only works when Vim gets the scroll wheel events, of course. You can + check if this works with the "xev" program. + + When using Xfree86, the /etc/XF86Config file should have the correct entry for + your mouse. For FreeBSD, this entry works for a Logitech scrollmouse: + > Protocol "MouseMan" + > Device "/dev/psm0" + > ZAxisMapping 4 5 + See the Xfree86 documentation for information. vim:tw=78:ts=8:sw=8: *** ../vim-5.5a.13/src/version.c Thu Sep 9 17:16:27 1999 --- src/version.c Thu Sep 9 17:15:51 1999 *************** *** 420,420 **** --- 420,421 ---- { /* Add new patch number below this line */ + 14, -- Mynd you, m00se bites Kan be pretty nasti ... "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD --/-/---- Bram Moolenaar ---- Bram@moolenaar.net ---- Bram@vim.org ---\-\-- \ \ www.vim.org/iccf www.moolenaar.net www.vim.org / /