]> source.dussan.org Git - tigervnc.git/commitdiff
Release displays not enclosed by the window
authorHugo Lundin <hugo@lundin.dev>
Fri, 16 Jul 2021 11:26:08 +0000 (13:26 +0200)
committerHugo Lundin <hugo@lundin.dev>
Fri, 16 Jul 2021 13:43:14 +0000 (15:43 +0200)
cocoa_capture_displays it captures all displays enclosed by the
window_rect. If a set of displays were captured, but the configuration of
what monitors to use changed, a second call would only add to the set
of captured displays. Therefore, if the user enabled
FullScreenAllMonitors (all displays captured) and then disabled it (only
one display captured) they would get into a state were monitors not used
for the VNC session still were captured (which on macOS for example,
results in displays being unusable for other things).

This has now been fixed, resulting in monitors outside the window_rect
not being unnecessarily captured.

vncviewer/DesktopWindow.cxx
vncviewer/cocoa.mm

index 1278e16cb3703b8dfe6e22706ecc854d417c4229..e7f91f024cb9395b782c45505cba5f4ca6e0db28 100644 (file)
@@ -608,6 +608,11 @@ void DesktopWindow::resize(int x, int y, int w, int h)
 
     repositionWidgets();
   }
+
+  // Some systems require a grab after the window size has been changed.
+  // Otherwise they might hold on to displays, resulting in them being unusable.
+  if (fullscreen_active() && fullscreenSystemKeys)
+    grabKeyboard();
 }
 
 
index d6596d34784d7d48a2e07a8c189b9b859da1e6e0..dca1afa41f20e9c20374cfc8bb3bd3d1186ad46c 100644 (file)
@@ -56,34 +56,38 @@ int cocoa_capture_displays(Fl_Window *win)
 
   nsw = (NSWindow*)fl_xid(win);
 
-  if (!captured) {
-    CGDisplayCount count;
-    CGDirectDisplayID displays[16];
+  CGDisplayCount count;
+  CGDirectDisplayID displays[16];
 
-    int sx, sy, sw, sh;
-    rfb::Rect windows_rect, screen_rect;
+  int sx, sy, sw, sh;
+  rfb::Rect windows_rect, screen_rect;
 
-    windows_rect.setXYWH(win->x(), win->y(), win->w(), win->h());
+  windows_rect.setXYWH(win->x(), win->y(), win->w(), win->h());
 
-    if (CGGetActiveDisplayList(16, displays, &count) != kCGErrorSuccess)
-      return 1;
+  if (CGGetActiveDisplayList(16, displays, &count) != kCGErrorSuccess)
+    return 1;
 
-    if (count != (unsigned)Fl::screen_count())
-      return 1;
+  if (count != (unsigned)Fl::screen_count())
+    return 1;
 
-    for (int i = 0; i < Fl::screen_count(); i++) {
-      Fl::screen_xywh(sx, sy, sw, sh, i);
+  for (int i = 0; i < Fl::screen_count(); i++) {
+    Fl::screen_xywh(sx, sy, sw, sh, i);
 
-      screen_rect.setXYWH(sx, sy, sw, sh);
-      if (screen_rect.enclosed_by(windows_rect)) {
-        if (CGDisplayCapture(displays[i]) != kCGErrorSuccess)
-          return 1;
-      }
-    }
+    screen_rect.setXYWH(sx, sy, sw, sh);
+    if (screen_rect.enclosed_by(windows_rect)) {
+      if (CGDisplayCapture(displays[i]) != kCGErrorSuccess)
+        return 1;
 
-    captured = true;
+    } else {
+      // A display might have been captured with the previous
+      // monitor selection. In that case we don't want to keep
+      // it when its no longer inside the window_rect.
+      CGDisplayRelease(displays[i]);
+    }
   }
 
+  captured = true;
+
   if ([nsw level] == CGShieldingWindowLevel())
     return 0;