emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Subject: w32 mouse wheel handling


From: David PONCE
Subject: Subject: w32 mouse wheel handling
Date: Fri, 23 May 2003 16:47:59 +0200 (CEST)

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);
  





reply via email to

[Prev in Thread] Current Thread [Next in Thread]