From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: David PONCE Newsgroups: gmane.emacs.devel Subject: Subject: w32 mouse wheel handling Date: Fri, 23 May 2003 16:47:59 +0200 (CEST) Sender: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Message-ID: <25058549.1053701279594.JavaMail.www@wwinf0601> Reply-To: david.ponce@wanadoo.fr NNTP-Posting-Host: main.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 7bit X-Trace: main.gmane.org 1053701597 32019 80.91.224.249 (23 May 2003 14:53:17 GMT) X-Complaints-To: usenet@main.gmane.org NNTP-Posting-Date: Fri, 23 May 2003 14:53:17 +0000 (UTC) Original-X-From: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Fri May 23 16:53:14 2003 Return-path: Original-Received: from quimby.gnus.org ([80.91.224.244]) by main.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 19JDto-0008BW-00 for ; Fri, 23 May 2003 16:52:00 +0200 Original-Received: from monty-python.gnu.org ([199.232.76.173]) by quimby.gnus.org with esmtp (Exim 3.12 #1 (Debian)) id 19JE5b-0003Em-00 for ; Fri, 23 May 2003 17:04:11 +0200 Original-Received: from localhost ([127.0.0.1] helo=monty-python.gnu.org) by monty-python.gnu.org with esmtp (Exim 4.20) id 19JDuo-0003kz-5N for emacs-devel@quimby.gnus.org; Fri, 23 May 2003 10:53:02 -0400 Original-Received: from list by monty-python.gnu.org with tmda-scanned (Exim 4.20) id 19JDtH-0002xZ-96 for emacs-devel@gnu.org; Fri, 23 May 2003 10:51:27 -0400 Original-Received: from mail by monty-python.gnu.org with spam-scanned (Exim 4.20) id 19JDry-0002T5-49 for emacs-devel@gnu.org; Fri, 23 May 2003 10:50:11 -0400 Original-Received: from smtp3.wanadoo.fr ([193.252.22.25] helo=mwinf0602.wanadoo.fr) by monty-python.gnu.org with esmtp (Exim 4.20) id 19JDpz-0000Yl-N2 for emacs-devel@gnu.org; Fri, 23 May 2003 10:48:03 -0400 Original-Received: from wwinf0601 (wwinf0601 [172.22.137.28]) by mwinf0602.wanadoo.fr (SMTP Server) with ESMTP id A018454001CB for ; Fri, 23 May 2003 16:47:59 +0200 (CEST) Original-To: emacs-devel X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1b5 Precedence: list List-Id: Emacs development discussions. List-Help: List-Post: List-Subscribe: , List-Archive: List-Unsubscribe: , Errors-To: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Xref: main.gmane.org gmane.emacs.devel:14137 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:14137 Hi All, With latest CVS version of NT Emacs (and 21.3.1 too) , I noticed a scroll performance problem with relatively big files, when using the mouse wheel and there is a header line displayed. I use: GNU Emacs 21.3.50.1 (i386-mingw-nt4.0.1381) of 2003-05-23 on EBAT311 configured using `configure --with-gcc (3.2)' on Windows NT4 SP6a Workstation. Here is a small test case, editing the Emacs src/ChangeLog file: emacs -q -no-site-file M-x mouse-wheel-mode C-x C-f emacs/src/ChangeLog Using the mouse wheel to scroll up/down works as expected. Then setup a very basic header line: M-: (setq header-line-format "TEST") Now use again the mouse wheel to scroll up/down: you should notice an important performance degradation! After some investigation, I discovered that, when there is an header line, mouse wheel events seems to be queued by Emacs, instead of being processed as they appears. Then, while Emacs process the queue of mouse-wheel events, it eats a lot of CPU and the display isn't refreshed, so the observed slow down. Someone else observed that too? I must admit that I didn't found why, when there is an header line, mouse wheel events are deferred. Another annoying thing with the way mouse wheel events are handled in NT Emacs, is that it is impossible to directly bind commands to scroll up or down events, nor to bind commands to mouse wheel events on the mode line or header line only, like in X. For example, I can't do something like this ;-) (global-set-key [mode-line mouse-4] 'mode-line-unbury-buffer) (global-set-key [mode-line mouse-5] 'mode-line-bury-buffer) I submit you the following patch to handle mouse wheel events in NT Emacs like in X, that is as mouse click events. Scrolling the wheel up produces mouse-4 events, and scrolling the wheel down produces mouse-5 events, eventually prefixed by header or mode line depending on the mouse location :-) Finally, handling all mouse events in an uniform way seems to have fixed the performance problem mentioned above :-) What do you think? Sincerely, David Index: src/keyboard.c =================================================================== RCS file: /cvsroot/emacs/emacs/src/keyboard.c,v retrieving revision 1.744 diff -c -r1.744 keyboard.c *** src/keyboard.c 15 May 2003 21:20:52 -0000 1.744 --- src/keyboard.c 23 May 2003 11:26:39 -0000 *************** *** 5517,5523 **** } } #endif /* WINDOWSNT */ ! #if defined(WINDOWSNT) || defined(MAC_OSX) case MOUSE_WHEEL_EVENT: { enum window_part part; --- 5517,5523 ---- } } #endif /* WINDOWSNT */ ! #if defined(MAC_OSX) case MOUSE_WHEEL_EVENT: { enum window_part part; *************** *** 5589,5595 **** Qnil)))); } } ! #endif /* WINDOWSNT || MAC_OSX */ case DRAG_N_DROP_EVENT: { --- 5589,5595 ---- Qnil)))); } } ! #endif /* MAC_OSX */ case DRAG_N_DROP_EVENT: { Index: src/w32term.c =================================================================== RCS file: /cvsroot/emacs/emacs/src/w32term.c,v retrieving revision 1.188 diff -c -r1.188 w32term.c *** src/w32term.c 4 Apr 2003 21:15:53 -0000 1.188 --- src/w32term.c 23 May 2003 11:26:40 -0000 *************** *** 2913,2920 **** struct frame *f; { POINT p; ! result->kind = MOUSE_WHEEL_EVENT; ! result->code = (short) HIWORD (msg->msg.wParam); result->timestamp = msg->msg.time; result->modifiers = msg->dwModifiers; p.x = LOWORD (msg->msg.lParam); --- 2913,2920 ---- struct frame *f; { POINT p; ! result->kind = MOUSE_CLICK_EVENT; ! result->code = ( GET_WHEEL_DELTA_WPARAM (msg->msg.wParam) < 0 )? 4 : 3; result->timestamp = msg->msg.time; result->modifiers = msg->dwModifiers; p.x = LOWORD (msg->msg.lParam); *************** *** 4385,4410 **** } case WM_MOUSEWHEEL: ! if (dpyinfo->grabbed && last_mouse_frame ! && FRAME_LIVE_P (last_mouse_frame)) ! f = last_mouse_frame; ! else ! f = x_window_to_frame (dpyinfo, msg.msg.hwnd); ! ! if (f) ! { ! if ((!dpyinfo->w32_focus_frame ! || f == dpyinfo->w32_focus_frame) ! && (numchars >= 1)) ! { ! construct_mouse_wheel (bufp, &msg, f); ! bufp++; ! count++; ! numchars--; ! } ! } ! break; ! case WM_DROPFILES: f = x_window_to_frame (dpyinfo, msg.msg.hwnd); --- 4385,4475 ---- } case WM_MOUSEWHEEL: ! { ! /* Convert each Windows mouse wheel event in a couple of ! Emacs mouse click down/up events. Scrolling the wheel up ! is associated to mouse button 4 and scrolling the wheel ! down to the mouse button 5. */ ! int button; ! int up; ! ! up = msg.dwModifiers & up_modifier; ! ! if (dpyinfo->grabbed && last_mouse_frame ! && FRAME_LIVE_P (last_mouse_frame)) ! f = last_mouse_frame; ! else ! f = x_window_to_frame (dpyinfo, msg.msg.hwnd); ! ! if (f) ! { ! Lisp_Object window; ! POINT p; ! int x, y; ! ! p.x = LOWORD (msg.msg.lParam); ! p.y = HIWORD (msg.msg.lParam); ! ScreenToClient (msg.msg.hwnd, &p); ! x = XFASTINT (p.x); ! y = XFASTINT (p.y); ! ! window = window_from_coordinates (f, x, y, 0, 0); ! ! /* Ignore mouse wheel events not in a window. */ ! if (!WINDOWP(window)) ! break; ! ! if ((!dpyinfo->w32_focus_frame ! || f == dpyinfo->w32_focus_frame) ! && (numchars >= 1)) ! { ! if ( !up ) ! { ! /* Emit an Emacs mouse down message. */ ! msg.dwModifiers |= down_modifier; ! construct_mouse_wheel (bufp, &msg, f); ! bufp++; ! count++; ! numchars--; ! ! /* Push a simulated WM_MOUSEWHEEL up message. */ ! msg.dwModifiers &= ~down_modifier; ! msg.dwModifiers |= up_modifier; ! prepend_msg (&msg); ! } ! else ! { ! /* Emit an Emacs mouse up message. */ ! construct_mouse_wheel (bufp, &msg, f); ! bufp++; ! count++; ! numchars--; ! } ! } ! } ! ! button = ( GET_WHEEL_DELTA_WPARAM (msg.msg.wParam) < 0 )? 4 : 3; ! ! if (up) ! { ! dpyinfo->grabbed &= ~ (1 << button); ! } ! else ! { ! dpyinfo->grabbed |= (1 << button); ! last_mouse_frame = f; ! /* Ignore any mouse motion that happened ! before this event; any subsequent mouse-movement ! Emacs events should reflect only motion after ! the ButtonPress. */ ! if (f != 0) ! f->mouse_moved = 0; ! ! last_tool_bar_item = -1; ! } ! } ! break; ! case WM_DROPFILES: f = x_window_to_frame (dpyinfo, msg.msg.hwnd);