Browse Source

Merge branch 'release/1.10.x'

rdb 4 years ago
parent
commit
b817e19ab6

+ 18 - 4
direct/src/dist/commands.py

@@ -99,10 +99,13 @@ PACKAGE_DATA_DIRS = {
 
 
 # Some dependencies have extra directories that need to be scanned for DLLs.
 # Some dependencies have extra directories that need to be scanned for DLLs.
 # This dictionary maps wheel basenames (ie. the part of the .whl basename
 # This dictionary maps wheel basenames (ie. the part of the .whl basename
-# before the first hyphen) to a list of directories inside the .whl.
+# before the first hyphen) to a list of tuples, the first value being the
+# directory inside the wheel, the second being which wheel to look in (or
+# None to look in its own wheel).
 
 
 PACKAGE_LIB_DIRS = {
 PACKAGE_LIB_DIRS = {
-    'scipy':  ['scipy/extra-dll'],
+    'scipy':  [('scipy/extra-dll', None)],
+    'PyQt5':  [('PyQt5/Qt5/bin', 'PyQt5_Qt5')],
 }
 }
 
 
 SITE_PY = u"""
 SITE_PY = u"""
@@ -610,6 +613,12 @@ class build_apps(setuptools.Command):
                     # by default.  Switch it up if FMOD is not included.
                     # by default.  Switch it up if FMOD is not included.
                     if value not in self.plugins and value == 'p3fmod_audio' and 'p3openal_audio' in self.plugins:
                     if value not in self.plugins and value == 'p3fmod_audio' and 'p3openal_audio' in self.plugins:
                         self.warn("Missing audio plugin p3fmod_audio referenced in PRC data, replacing with p3openal_audio")
                         self.warn("Missing audio plugin p3fmod_audio referenced in PRC data, replacing with p3openal_audio")
+                        value = 'p3openal_audio'
+
+                if var == 'aux-display':
+                    # Silently remove aux-display lines for missing plugins.
+                    if value not in self.plugins:
+                        continue
 
 
                 for plugin in check_plugins:
                 for plugin in check_plugins:
                     if plugin in value and plugin not in self.plugins:
                     if plugin in value and plugin not in self.plugins:
@@ -662,8 +671,13 @@ class build_apps(setuptools.Command):
                     # Also look for more specific per-package cases, defined in
                     # Also look for more specific per-package cases, defined in
                     # PACKAGE_LIB_DIRS at the top of this file.
                     # PACKAGE_LIB_DIRS at the top of this file.
                     extra_dirs = PACKAGE_LIB_DIRS.get(whl_name, [])
                     extra_dirs = PACKAGE_LIB_DIRS.get(whl_name, [])
-                    for extra_dir in extra_dirs:
-                        search_path.append(os.path.join(whl, extra_dir.replace('/', os.path.sep)))
+                    for extra_dir, search_in in extra_dirs:
+                        if not search_in:
+                            search_path.append(os.path.join(whl, extra_dir.replace('/', os.path.sep)))
+                        else:
+                            for whl2 in wheelpaths:
+                                if os.path.basename(whl2).startswith(search_in + '-'):
+                                    search_path.append(os.path.join(whl2, extra_dir.replace('/', os.path.sep)))
 
 
             return search_path
             return search_path
 
 

+ 9 - 2
makepanda/makewheel.py

@@ -404,6 +404,7 @@ class WheelFile(object):
 
 
             # Now add dependencies.  On macOS, fix @loader_path references.
             # Now add dependencies.  On macOS, fix @loader_path references.
             if sys.platform == "darwin":
             if sys.platform == "darwin":
+                is_unsigned = subprocess.call(['codesign', '-d', temp.name], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
                 if source_path.endswith('deploy-stubw'):
                 if source_path.endswith('deploy-stubw'):
                     deps_path = '@executable_path/../Frameworks'
                     deps_path = '@executable_path/../Frameworks'
                 else:
                 else:
@@ -452,9 +453,15 @@ class WheelFile(object):
                     subprocess.call(["install_name_tool", "-change", dep, new_dep, temp.name])
                     subprocess.call(["install_name_tool", "-change", dep, new_dep, temp.name])
                     remove_signature = True
                     remove_signature = True
 
 
-                # Remove the codesign signature if we modified the library.
-                if remove_signature:
+                # Replace the codesign signature if we modified the library.
+                if self.platform.endswith("_arm64") and (is_unsigned or remove_signature):
+                    subprocess.call(["codesign", "-f", "-s", "-", temp.name])
+                elif remove_signature and not is_unsigned:
+                    if GetVerbose():
+                        print("Removing code signature from {0}".format(source_path))
                     subprocess.call(["codesign", "--remove-signature", temp.name])
                     subprocess.call(["codesign", "--remove-signature", temp.name])
+                    if self.platform.endswith("_universal2"):
+                        subprocess.call(["codesign", "-a", "arm64", "-s", "-", temp.name])
             else:
             else:
                 # On other unixes, we just add dependencies normally.
                 # On other unixes, we just add dependencies normally.
                 for dep in deps:
                 for dep in deps:

+ 1 - 1
panda/src/cocoadisplay/cocoaGraphicsWindow.h

@@ -68,7 +68,7 @@ protected:
   virtual void close_window();
   virtual void close_window();
   virtual bool open_window();
   virtual bool open_window();
 
 
-  CGDisplayModeRef find_display_mode(int width, int height);
+  CFMutableArrayRef find_display_modes(int width, int height);
   bool do_switch_fullscreen(CGDisplayModeRef mode);
   bool do_switch_fullscreen(CGDisplayModeRef mode);
 
 
   virtual void mouse_mode_absolute();
   virtual void mouse_mode_absolute();

+ 90 - 53
panda/src/cocoadisplay/cocoaGraphicsWindow.mm

@@ -628,18 +628,32 @@ open_window() {
 
 
   if (_properties.get_fullscreen()) {
   if (_properties.get_fullscreen()) {
     // Change the display mode.
     // Change the display mode.
-    CGDisplayModeRef mode;
-    mode = find_display_mode(_properties.get_x_size(),
-                             _properties.get_y_size());
+    CFMutableArrayRef modes;
+
+    modes = find_display_modes(_properties.get_x_size(),
+                               _properties.get_y_size());
+
+    if (CFArrayGetCount(modes) > 0) {
+      bool switched = false;
+      for (CFIndex i = 0; i < CFArrayGetCount(modes); i++) {
+        CGDisplayModeRef mode = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
+        if (do_switch_fullscreen(mode)) {
+          switched = true;
+          break;
+        }
+      }
+      CFRelease(modes);
 
 
-    if (mode == NULL) {
-      cocoadisplay_cat.error()
-        << "Could not find a suitable display mode!\n";
-      return false;
+      if (!switched) {
+        cocoadisplay_cat.error()
+          << "Failed to change display mode.\n";
+        return false;
+      }
 
 
-    } else if (!do_switch_fullscreen(mode)) {
+    } else {
       cocoadisplay_cat.error()
       cocoadisplay_cat.error()
-        << "Failed to change display mode.\n";
+        << "Could not find a suitable display mode!\n";
+      CFRelease(modes);
       return false;
       return false;
     }
     }
   }
   }
@@ -787,38 +801,48 @@ set_properties_now(WindowProperties &properties) {
           height = _properties.get_y_size();
           height = _properties.get_y_size();
         }
         }
 
 
-        CGDisplayModeRef mode;
-        mode = find_display_mode(width, height);
-
-        if (mode == NULL) {
-          cocoadisplay_cat.error()
-            << "Could not find a suitable display mode with size " << width
-            << "x" << height << "!\n";
+        CFMutableArrayRef modes = find_display_modes(width, height);
 
 
-        } else if (do_switch_fullscreen(mode)) {
-          if (_window != nil) {
-            // For some reason, setting the style mask makes it give up its
-            // first-responder status.
-            if ([_window respondsToSelector:@selector(setStyleMask:)]) {
-              [_window setStyleMask:NSBorderlessWindowMask];
+        if (CFArrayGetCount(modes) > 0) {
+          bool switched = false;
+          for (CFIndex i = 0; i < CFArrayGetCount(modes); i++) {
+            CGDisplayModeRef mode = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
+            if (do_switch_fullscreen(mode)) {
+              switched = true;
+              break;
             }
             }
-            [_window makeFirstResponder:_view];
-            [_window setLevel:NSMainMenuWindowLevel+1];
-            [_window makeKeyAndOrderFront:nil];
           }
           }
 
 
-          // We've already set the size property this way; clear it.
-          properties.clear_size();
-          _properties.set_size(width, height);
-          properties.clear_origin();
-          _properties.set_origin(0, 0);
-          properties.clear_fullscreen();
-          _properties.set_fullscreen(true);
+          if (switched) {
+            if (_window != nil) {
+              // For some reason, setting the style mask makes it give up its
+              // first-responder status.
+              if ([_window respondsToSelector:@selector(setStyleMask:)]) {
+                [_window setStyleMask:NSBorderlessWindowMask];
+              }
+              [_window makeFirstResponder:_view];
+              [_window setLevel:NSMainMenuWindowLevel+1];
+              [_window makeKeyAndOrderFront:nil];
+            }
 
 
+            // We've already set the size property this way; clear it.
+            properties.clear_size();
+            _properties.set_size(width, height);
+            properties.clear_origin();
+            _properties.set_origin(0, 0);
+            properties.clear_fullscreen();
+            _properties.set_fullscreen(true);
+
+          } else {
+            cocoadisplay_cat.error()
+              << "Failed to change display mode.\n";
+          }
         } else {
         } else {
           cocoadisplay_cat.error()
           cocoadisplay_cat.error()
-            << "Failed to change display mode.\n";
+            << "Could not find a suitable display mode with size " << width
+            << "x" << height << "!\n";
         }
         }
+        CFRelease(modes);
 
 
       } else {
       } else {
         do_switch_fullscreen(NULL);
         do_switch_fullscreen(NULL);
@@ -864,22 +888,33 @@ set_properties_now(WindowProperties &properties) {
       properties.clear_size();
       properties.clear_size();
 
 
     } else {
     } else {
-      CGDisplayModeRef mode = find_display_mode(width, height);
-
-      if (mode == NULL) {
-        cocoadisplay_cat.error()
-          << "Could not find a suitable display mode with size " << width
-          << "x" << height << "!\n";
+      CFMutableArrayRef modes = find_display_modes(width, height);
+
+      if (CFArrayGetCount(modes) > 0) {
+        bool switched = false;
+        for (CFIndex i = 0; i < CFArrayGetCount(modes); i++) {
+          CGDisplayModeRef mode = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
+          if (do_switch_fullscreen(mode)) {
+            switched = true;
+            break;
+          }
+        }
 
 
-      } else if (do_switch_fullscreen(mode)) {
-        // Yay!  Our resolution has changed.
-        _properties.set_size(width, height);
-        properties.clear_size();
+        if (switched) {
+          // Yay!  Our resolution has changed.
+          _properties.set_size(width, height);
+          properties.clear_size();
+        } else {
+          cocoadisplay_cat.error()
+            << "Failed to change display mode.\n";
+        }
 
 
       } else {
       } else {
         cocoadisplay_cat.error()
         cocoadisplay_cat.error()
-          << "Failed to change display mode.\n";
+          << "Could not find a suitable display mode with size " << width
+          << "x" << height << "!\n";
       }
       }
+      CFRelease(modes);
     }
     }
   }
   }
 
 
@@ -1101,8 +1136,8 @@ set_properties_now(WindowProperties &properties) {
  * Returns an appropriate CGDisplayModeRef for the given width and height, or
  * Returns an appropriate CGDisplayModeRef for the given width and height, or
  * NULL if none was found.
  * NULL if none was found.
  */
  */
-CGDisplayModeRef CocoaGraphicsWindow::
-find_display_mode(int width, int height) {
+CFMutableArrayRef CocoaGraphicsWindow::
+find_display_modes(int width, int height) {
   CFDictionaryRef options = NULL;
   CFDictionaryRef options = NULL;
   // On macOS 10.15+ (Catalina), we want to select the display mode with the
   // On macOS 10.15+ (Catalina), we want to select the display mode with the
   // samescaling factor as the current view to avoid cropping or scaling issues.
   // samescaling factor as the current view to avoid cropping or scaling issues.
@@ -1122,6 +1157,9 @@ find_display_mode(int width, int height) {
                                  &kCFTypeDictionaryValueCallBacks);
                                  &kCFTypeDictionaryValueCallBacks);
   }
   }
 #endif
 #endif
+  CFMutableArrayRef valid_modes;
+  valid_modes = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+
   CFArrayRef modes = CGDisplayCopyAllDisplayModes(_display, options);
   CFArrayRef modes = CGDisplayCopyAllDisplayModes(_display, options);
   if (options != NULL) {
   if (options != NULL) {
     CFRelease(options);
     CFRelease(options);
@@ -1141,7 +1179,9 @@ find_display_mode(int width, int height) {
   if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_14 &&
   if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_14 &&
       CGDisplayModeGetWidth(mode) == width &&
       CGDisplayModeGetWidth(mode) == width &&
       CGDisplayModeGetHeight(mode) == height) {
       CGDisplayModeGetHeight(mode) == height) {
-    return mode;
+    CFArrayAppendValue(valid_modes, mode);
+    CGDisplayModeRelease(mode);
+    return valid_modes;
   }
   }
 
 
   current_pixel_encoding = CGDisplayModeCopyPixelEncoding(mode);
   current_pixel_encoding = CGDisplayModeCopyPixelEncoding(mode);
@@ -1172,17 +1212,14 @@ find_display_mode(int width, int height) {
 #endif
 #endif
         CFStringCompare(pixel_encoding, current_pixel_encoding, 0) == kCFCompareEqualTo) {
         CFStringCompare(pixel_encoding, current_pixel_encoding, 0) == kCFCompareEqualTo) {
 
 
-      CFRetain(mode);
-      CFRelease(pixel_encoding);
-      CFRelease(current_pixel_encoding);
-      CFRelease(modes);
-      return mode;
+      CFArrayAppendValue(valid_modes, mode);
     }
     }
+    CFRelease(pixel_encoding);
   }
   }
 
 
   CFRelease(current_pixel_encoding);
   CFRelease(current_pixel_encoding);
   CFRelease(modes);
   CFRelease(modes);
-  return NULL;
+  return valid_modes;
 }
 }
 
 
 /**
 /**

+ 68 - 43
panda/src/windisplay/winGraphicsWindow.cxx

@@ -302,32 +302,34 @@ set_properties_now(WindowProperties &properties) {
     // When switching undecorated mode, Windows will keep the window at the
     // When switching undecorated mode, Windows will keep the window at the
     // current outer size, whereas we want to keep it with the configured
     // current outer size, whereas we want to keep it with the configured
     // inner size.  Store the current size and origin.
     // inner size.  Store the current size and origin.
-    LPoint2i top_left = _properties.get_origin();
-    LPoint2i bottom_right = top_left + _properties.get_size();
-
-    DWORD window_style = make_style(_properties);
-    DWORD current_style = GetWindowLong(_hWnd, GWL_STYLE);
-    SetWindowLong(_hWnd, GWL_STYLE, window_style);
-
-    // If we switched to/from undecorated, calculate the new size.
-    if (((window_style ^ current_style) & WS_CAPTION) != 0) {
-      RECT view_rect;
-      SetRect(&view_rect, top_left[0], top_left[1],
-              bottom_right[0], bottom_right[1]);
-      WINDOWINFO wi;
-      GetWindowInfo(_hWnd, &wi);
-      AdjustWindowRectEx(&view_rect, wi.dwStyle, FALSE, wi.dwExStyle);
-
-      SetWindowPos(_hWnd, HWND_NOTOPMOST, view_rect.left, view_rect.top,
-                   view_rect.right - view_rect.left,
-                   view_rect.bottom - view_rect.top,
-                   SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED |
-                   SWP_NOSENDCHANGING | SWP_SHOWWINDOW);
-    } else {
-      // We need to call this to ensure that the style change takes effect.
-      SetWindowPos(_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0,
-                   SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE |
-                   SWP_FRAMECHANGED | SWP_NOSENDCHANGING | SWP_SHOWWINDOW);
+    if (_parent_window_handle == nullptr) {
+      LPoint2i top_left = _properties.get_origin();
+      LPoint2i bottom_right = top_left + _properties.get_size();
+
+      DWORD window_style = make_style(_properties);
+      DWORD current_style = GetWindowLong(_hWnd, GWL_STYLE);
+      SetWindowLong(_hWnd, GWL_STYLE, window_style);
+
+      // If we switched to/from undecorated, calculate the new size.
+      if (((window_style ^ current_style) & WS_CAPTION) != 0) {
+        RECT view_rect;
+        SetRect(&view_rect, top_left[0], top_left[1],
+                bottom_right[0], bottom_right[1]);
+        WINDOWINFO wi;
+        GetWindowInfo(_hWnd, &wi);
+        AdjustWindowRectEx(&view_rect, wi.dwStyle, FALSE, wi.dwExStyle);
+
+        SetWindowPos(_hWnd, HWND_NOTOPMOST, view_rect.left, view_rect.top,
+                     view_rect.right - view_rect.left,
+                     view_rect.bottom - view_rect.top,
+                     SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED |
+                     SWP_NOSENDCHANGING | SWP_SHOWWINDOW);
+      } else {
+        // We need to call this to ensure that the style change takes effect.
+        SetWindowPos(_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0,
+                     SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE |
+                     SWP_FRAMECHANGED | SWP_NOSENDCHANGING | SWP_SHOWWINDOW);
+      }
     }
     }
   }
   }
 
 
@@ -464,7 +466,9 @@ set_properties_now(WindowProperties &properties) {
         // Fall through
         // Fall through
 
 
       case WindowProperties::M_confined:
       case WindowProperties::M_confined:
-        if (confine_cursor()) {
+        // If we are not the foreground window, we defer confining the cursor
+        // until we are.
+        if (GetForegroundWindow() != _hWnd || confine_cursor()) {
           _properties.set_mouse_mode(properties.get_mouse_mode());
           _properties.set_mouse_mode(properties.get_mouse_mode());
         }
         }
         break;
         break;
@@ -505,6 +509,11 @@ close_window() {
   set_cursor_out_of_window();
   set_cursor_out_of_window();
   DestroyWindow(_hWnd);
   DestroyWindow(_hWnd);
 
 
+  if (_properties.has_mouse_mode() &&
+      _properties.get_mouse_mode() != WindowProperties::M_absolute) {
+    ClipCursor(nullptr);
+  }
+
   if (is_fullscreen()) {
   if (is_fullscreen()) {
     // revert to default display mode.
     // revert to default display mode.
     do_fullscreen_disable();
     do_fullscreen_disable();
@@ -797,7 +806,7 @@ do_reshape_request(int x_origin, int y_origin, bool has_origin,
     GetWindowInfo(_hWnd, &wi);
     GetWindowInfo(_hWnd, &wi);
     AdjustWindowRectEx(&view_rect, wi.dwStyle, FALSE, wi.dwExStyle);
     AdjustWindowRectEx(&view_rect, wi.dwStyle, FALSE, wi.dwExStyle);
 
 
-    UINT flags = SWP_NOZORDER | SWP_NOSENDCHANGING;
+    UINT flags = SWP_NOZORDER | SWP_NOSENDCHANGING | SWP_NOACTIVATE;
 
 
     if (has_origin) {
     if (has_origin) {
       x_origin = view_rect.left;
       x_origin = view_rect.left;
@@ -813,12 +822,6 @@ 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;
   }
   }
@@ -868,6 +871,28 @@ handle_reshape() {
     return;
     return;
   }
   }
 
 
+  // If we are in confined mode, we must update the clip region.  However,
+  // we ony do that if the cursor in currently inside the window, to properly
+  // handle the case where someone is resizing the window straight after
+  // switching to it (you can do this if you press the start menu key to
+  // deactive the window, and then trying to resize it)
+  if (_properties.has_mouse_mode() &&
+      _properties.get_mouse_mode() != WindowProperties::M_absolute &&
+      _hWnd == GetForegroundWindow()) {
+
+    POINT cpos;
+    if (GetCursorPos(&cpos) && PtInRect(&view_rect, cpos)) {
+      windisplay_cat.info()
+        << "ClipCursor() to " << view_rect.left << "," << view_rect.top
+        << " to " << view_rect.right << "," << view_rect.bottom << endl;
+
+      if (!ClipCursor(&view_rect)) {
+        windisplay_cat.warning()
+          << "Failed to re-confine cursor to window.\n";
+      }
+    }
+  }
+
   WindowProperties properties;
   WindowProperties properties;
   properties.set_size((view_rect.right - view_rect.left),
   properties.set_size((view_rect.right - view_rect.left),
                       (view_rect.bottom - view_rect.top));
                       (view_rect.bottom - view_rect.top));
@@ -1008,7 +1033,7 @@ do_windowed_switch() {
 
 
   // If we had a confined cursor, we must reconfine it now.
   // If we had a confined cursor, we must reconfine it now.
   if (_properties.has_mouse_mode() &&
   if (_properties.has_mouse_mode() &&
-      _properties.get_mouse_mode() == WindowProperties::M_confined) {
+      _properties.get_mouse_mode() != WindowProperties::M_absolute) {
     confine_cursor();
     confine_cursor();
   }
   }
 
 
@@ -1049,12 +1074,12 @@ make_style(const WindowProperties &properties) {
 
 
   if (properties.get_fullscreen()) {
   if (properties.get_fullscreen()) {
     window_style |= WS_POPUP | WS_SYSMENU;
     window_style |= WS_POPUP | WS_SYSMENU;
-  } else {
-    if (_parent_window_handle) {
-      window_style |= WS_CHILD;
-    } else {
-      window_style |= WS_POPUP;
-    }
+  }
+  else if (_parent_window_handle) {
+    window_style |= WS_CHILD;
+  }
+  else {
+    window_style |= WS_POPUP;
 
 
     if (!properties.get_undecorated()) {
     if (!properties.get_undecorated()) {
       window_style |= (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX);
       window_style |= (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX);
@@ -1585,7 +1610,7 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
 
 
         // If we had a confined cursor, we must reconfine it upon activation.
         // If we had a confined cursor, we must reconfine it upon activation.
         if (_properties.has_mouse_mode() &&
         if (_properties.has_mouse_mode() &&
-            _properties.get_mouse_mode() == WindowProperties::M_confined) {
+            _properties.get_mouse_mode() != WindowProperties::M_absolute) {
           if (!confine_cursor()) {
           if (!confine_cursor()) {
             properties.set_mouse_mode(WindowProperties::M_absolute);
             properties.set_mouse_mode(WindowProperties::M_absolute);
           }
           }
@@ -1631,7 +1656,7 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
 
 
     // If we had a confined cursor, we must reconfine it upon a resize.
     // If we had a confined cursor, we must reconfine it upon a resize.
     if (_properties.has_mouse_mode() &&
     if (_properties.has_mouse_mode() &&
-        _properties.get_mouse_mode() == WindowProperties::M_confined) {
+        _properties.get_mouse_mode() != WindowProperties::M_absolute) {
       confine_cursor();
       confine_cursor();
     }
     }
     break;
     break;