Browse Source

windisplay: fix issues with losing mouse cursor confinement

Fixes #727
Fixes #729
rdb 6 years ago
parent
commit
8b241b8c18

+ 57 - 21
panda/src/windisplay/winGraphicsWindow.cxx

@@ -430,26 +430,8 @@ set_properties_now(WindowProperties &properties) {
         break;
         break;
 
 
       case WindowProperties::M_confined:
       case WindowProperties::M_confined:
-        {
-          RECT clip;
-
-          if (!GetWindowRect(_hWnd, &clip)) {
-            windisplay_cat.warning()
-                << "GetWindowRect() failed in set_properties_now.  Cannot confine cursor.\n";
-          } else {
-            windisplay_cat.info()
-                    << "ClipCursor() to " << clip.left << "," << clip.top << " to "
-                    << clip.right << "," << clip.bottom << endl;
-
-            GetClipCursor(&_mouse_unconfined_cliprect);
-            if (!ClipCursor(&clip)) {
-              windisplay_cat.warning()
-                      << "ClipCursor() failed in set_properties_now.  Ignoring.\n";
-            } else {
-              _properties.set_mouse_mode(WindowProperties::M_confined);
-              windisplay_cat.info() << "Confining cursor to window\n";
-            }
-          }
+        if (confine_cursor()) {
+          _properties.set_mouse_mode(WindowProperties::M_confined);
         }
         }
         break;
         break;
       }
       }
@@ -772,6 +754,12 @@ do_reshape_request(int x_origin, int y_origin, bool has_origin,
                  view_rect.bottom - view_rect.top,
                  view_rect.bottom - view_rect.top,
                  flags);
                  flags);
 
 
+    // If we are in confined mode, we must update the clip region.
+    if (_properties.has_mouse_mode() &&
+        _properties.get_mouse_mode() == WindowProperties::M_confined) {
+      confine_cursor();
+    }
+
     handle_reshape();
     handle_reshape();
     return true;
     return true;
   }
   }
@@ -944,6 +932,12 @@ do_windowed_switch() {
                metrics.width, metrics.height,
                metrics.width, metrics.height,
                SWP_FRAMECHANGED | SWP_SHOWWINDOW);
                SWP_FRAMECHANGED | SWP_SHOWWINDOW);
 
 
+  // If we had a confined cursor, we must reconfine it now.
+  if (_properties.has_mouse_mode() &&
+      _properties.get_mouse_mode() == WindowProperties::M_confined) {
+    confine_cursor();
+  }
+
   return true;
   return true;
 }
 }
 
 
@@ -1309,6 +1303,31 @@ track_mouse_leaving(HWND hwnd) {
   _tracking_mouse_leaving = true;
   _tracking_mouse_leaving = true;
 }
 }
 
 
+/**
+ * Confines the mouse cursor to the window.
+ */
+bool WinGraphicsWindow::
+confine_cursor() {
+  RECT clip;
+  if (!GetWindowRect(_hWnd, &clip)) {
+    windisplay_cat.warning()
+      << "GetWindowRect() failed, cannot confine cursor.\n";
+    return false;
+  } else {
+    windisplay_cat.info()
+      << "ClipCursor() to " << clip.left << "," << clip.top << " to "
+      << clip.right << "," << clip.bottom << endl;
+
+    if (!ClipCursor(&clip)) {
+      windisplay_cat.warning()
+        << "Failed to confine cursor to window.\n";
+      return false;
+    } else {
+      return true;
+    }
+  }
+}
+
 /**
 /**
  * Attempts to set this window as the "focus" window, so that keyboard events
  * Attempts to set this window as the "focus" window, so that keyboard events
  * come here.
  * come here.
@@ -1482,6 +1501,14 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
             SetWindowPos(_hWnd, HWND_TOP, 0,0,0,0, SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOOWNERZORDER);
             SetWindowPos(_hWnd, HWND_TOP, 0,0,0,0, SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOOWNERZORDER);
             fullscreen_restored(properties);
             fullscreen_restored(properties);
           }
           }
+
+        // If we had a confined cursor, we must reconfine it upon activation.
+        if (_properties.has_mouse_mode() &&
+            _properties.get_mouse_mode() == WindowProperties::M_confined) {
+          if (!confine_cursor()) {
+            properties.set_mouse_mode(WindowProperties::M_absolute);
+          }
+        }
       }
       }
     else
     else
       {
       {
@@ -1516,7 +1543,16 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
     break;
     break;
 
 
   case WM_EXITSIZEMOVE:
   case WM_EXITSIZEMOVE:
-    // handle_reshape();
+    if (windisplay_cat.is_debug()) {
+      windisplay_cat.debug()
+        << "WM_EXITSIZEMOVE: " << hwnd << ", " << wparam << "\n";
+    }
+
+    // If we had a confined cursor, we must reconfine it upon a resize.
+    if (_properties.has_mouse_mode() &&
+        _properties.get_mouse_mode() == WindowProperties::M_confined) {
+      confine_cursor();
+    }
     break;
     break;
 
 
   case WM_WINDOWPOSCHANGED:
   case WM_WINDOWPOSCHANGED:

+ 1 - 1
panda/src/windisplay/winGraphicsWindow.h

@@ -134,7 +134,7 @@ private:
   void initialize_input_devices();
   void initialize_input_devices();
   void handle_raw_input(HRAWINPUT hraw);
   void handle_raw_input(HRAWINPUT hraw);
   void track_mouse_leaving(HWND hwnd);
   void track_mouse_leaving(HWND hwnd);
-
+  bool confine_cursor();
   void set_focus();
   void set_focus();
 
 
   static void process_1_event();
   static void process_1_event();