This is the mail archive of the cygwin-xfree mailing list for the Cygwin XFree86 project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch 3/7] Cygwin/X: Improve mouse tracking for moving/resizing undecorated windows


In -multiwindow mode, tell Windows we wish to capture the mouse when a button
is down.  This causes Windows to continue to send movement events for the mouse
even if the mouse pointer moves outside the window frame.

This helps greatly with undecorated windows which have regions you can grab
to move (e.g. gmplayer, xine control panels) or resize (e.g. Songbird) the
window, as it means the window continues to receive the mouse motion even if the
mouse pointer  moves out of the window (which presumably happens if we don't
manage to update the window fast enough to track the mouse pointer)

Consolidate the multiple instances of the code to start the mouse position
polling timer into a new function winStartMousePolling(), and use that to
restart the polling timer when we release the mouse.

Also, start the timer on WM_SHOW, so that xeyes will track the mouse position
when it is first shown, even if the mouse doesn't enter it's window
(You probably need focus-stealing turned off to see this problem)

---
 xserver/hw/xwin/winmultiwindowwndproc.c |   59 ++++++++++++++++++++------------
 1 file changed, 37 insertions(+), 22 deletions(-)

Index: xorg-server-1.5.3/xserver/hw/xwin/winmultiwindowwndproc.c
===================================================================
--- xorg-server-1.5.3.orig/xserver/hw/xwin/winmultiwindowwndproc.c	2009-01-07 22:46:22.312500000 +0000
+++ xorg-server-1.5.3/xserver/hw/xwin/winmultiwindowwndproc.c	2009-01-07 23:32:32.640625000 +0000
@@ -303,6 +303,20 @@
   }
 }
 
+static
+void winStartMousePolling(winPrivScreenPtr s_pScreenPriv)
+{
+  /*
+   * Timer to poll mouse position.  This is needed to make
+   * programs like xeyes follow the mouse properly when the
+   * mouse pointer is outside of any X window.
+   */
+  if (g_uipMousePollingTimerID == 0)
+    g_uipMousePollingTimerID = SetTimer (s_pScreenPriv->hwndScreen,
+					 WIN_POLLING_MOUSE_TIMER_ID,
+					 MOUSE_POLLING_INTERVAL,
+					 NULL);
+}
 
 /*
  * winTopLevelWindowProc - Window procedure for all top-level Windows windows.
@@ -580,15 +594,8 @@
 	  ShowCursor (TRUE);
 	}
 
-      /*
-       * Timer to poll mouse events.  This is needed to make
-       * programs like xeyes follow the mouse properly.
-       */
-      if (g_uipMousePollingTimerID == 0)
-	g_uipMousePollingTimerID = SetTimer (s_pScreenPriv->hwndScreen,
-					     WIN_POLLING_MOUSE_TIMER_ID,
-					     MOUSE_POLLING_INTERVAL,
-					     NULL);
+      winStartMousePolling(s_pScreenPriv);
+
       break;
 
     case WM_MOUSELEAVE:
@@ -604,15 +611,8 @@
 	  ShowCursor (TRUE);
 	}
 
-      /*
-       * Timer to poll mouse events.  This is needed to make
-       * programs like xeyes follow the mouse properly.
-       */
-      if (g_uipMousePollingTimerID == 0)
-	g_uipMousePollingTimerID = SetTimer (s_pScreenPriv->hwndScreen,
-					     WIN_POLLING_MOUSE_TIMER_ID,
-					     MOUSE_POLLING_INTERVAL,
-					     NULL);
+      winStartMousePolling(s_pScreenPriv);
+
       return 0;
 
     case WM_LBUTTONDBLCLK:
@@ -620,12 +620,15 @@
       if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
 	break;
       g_fButton[0] = TRUE;
+      SetCapture(hwnd);
       return winMouseButtonsHandle (s_pScreen, ButtonPress, Button1, wParam);
-      
+
     case WM_LBUTTONUP:
       if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
 	break;
       g_fButton[0] = FALSE;
+      ReleaseCapture();
+      winStartMousePolling(s_pScreenPriv);
       return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button1, wParam);
 
     case WM_MBUTTONDBLCLK:
@@ -633,35 +636,45 @@
       if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
 	break;
       g_fButton[1] = TRUE;
+      SetCapture(hwnd);
       return winMouseButtonsHandle (s_pScreen, ButtonPress, Button2, wParam);
-      
+
     case WM_MBUTTONUP:
       if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
 	break;
       g_fButton[1] = FALSE;
+      ReleaseCapture();
+      winStartMousePolling(s_pScreenPriv);
       return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button2, wParam);
-      
+
     case WM_RBUTTONDBLCLK:
     case WM_RBUTTONDOWN:
       if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
 	break;
       g_fButton[2] = TRUE;
+      SetCapture(hwnd);
       return winMouseButtonsHandle (s_pScreen, ButtonPress, Button3, wParam);
-      
+
     case WM_RBUTTONUP:
       if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
 	break;
       g_fButton[2] = FALSE;
+      ReleaseCapture();
+      winStartMousePolling(s_pScreenPriv);
       return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button3, wParam);
 
     case WM_XBUTTONDBLCLK:
     case WM_XBUTTONDOWN:
       if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
 	break;
+	SetCapture(hwnd);
       return winMouseButtonsHandle (s_pScreen, ButtonPress, HIWORD(wParam) + 5, wParam);
+
     case WM_XBUTTONUP:
       if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
 	break;
+      ReleaseCapture();
+      winStartMousePolling(s_pScreenPriv);
       return winMouseButtonsHandle (s_pScreen, ButtonRelease, HIWORD(wParam) + 5, wParam);
 
     case WM_MOUSEWHEEL:
@@ -908,6 +921,8 @@
       if (fWMMsgInitialized)
 	winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg);
 
+      winStartMousePolling(s_pScreenPriv);
+
       return 0;
 
     case WM_SIZING:

-- 


--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://x.cygwin.com/docs/
FAQ:                   http://x.cygwin.com/docs/faq/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]