]> source.dussan.org Git - tigervnc.git/commitdiff
Capture all displays inside the viewport (macOS)
authorHugo Lundin <hugo@lundin.dev>
Tue, 13 Jul 2021 11:07:41 +0000 (13:07 +0200)
committerHugo Lundin <hugo@lundin.dev>
Fri, 16 Jul 2021 07:44:59 +0000 (09:44 +0200)
It was only possible to capture either the current, or all displays
previously. This could become an issue if you want to show a vnc session
over only a selected set of displays, because then we only want to
capture those displays.

The solution in the commit was chosen because it handles all cases - by
looking at what monitors are enclosed by the viewport the implementation
is independent on any configuration, but instead captures the monitors
actually being used.

vncviewer/DesktopWindow.cxx
vncviewer/cocoa.h
vncviewer/cocoa.mm

index dddd74d7151a57511c3c448160a4d629690e21ef..1278e16cb3703b8dfe6e22706ecc854d417c4229 100644 (file)
@@ -932,7 +932,7 @@ void DesktopWindow::grabKeyboard()
 #elif defined(__APPLE__)
   int ret;
   
-  ret = cocoa_capture_display(this, fullScreenAllMonitors);
+  ret = cocoa_capture_displays(this);
   if (ret != 0) {
     vlog.error(_("Failure grabbing keyboard"));
     return;
@@ -988,7 +988,7 @@ void DesktopWindow::ungrabKeyboard()
 #if defined(WIN32)
   win32_disable_lowlevel_keyboard(fl_xid(this));
 #elif defined(__APPLE__)
-  cocoa_release_display(this);
+  cocoa_release_displays(this);
 #else
   // FLTK has a grab so lets not mess with it
   if (Fl::grab())
index 98e5fafd40e054c7cc5f8e7daacb03bceaa4c982..083400383e216111b79871cd2289cef3b044c5e2 100644 (file)
 #ifndef __VNCVIEWER_COCOA_H__
 #define __VNCVIEWER_COCOA_H__
 
-int cocoa_capture_display(Fl_Window *win, bool all_displays);
-void cocoa_release_display(Fl_Window *win);
+class Fl_Window;
+
+int cocoa_capture_displays(Fl_Window *win);
+void cocoa_release_displays(Fl_Window *win);
 
 typedef struct CGColorSpace *CGColorSpaceRef;
 
index c3fe98e532a4ab56f3036d55e4fab1e6dcb240a7..d6596d34784d7d48a2e07a8c189b9b859da1e6e0 100644 (file)
@@ -35,6 +35,7 @@
 #define XK_XKB_KEYS
 #include <rfb/keysymdef.h>
 #include <rfb/XF86keysym.h>
+#include <rfb/Rect.h>
 
 #include "keysym2ucs.h"
 
@@ -49,31 +50,35 @@ const int kVK_Menu = 0x6E;
 
 static bool captured = false;
 
-int cocoa_capture_display(Fl_Window *win, bool all_displays)
+int cocoa_capture_displays(Fl_Window *win)
 {
   NSWindow *nsw;
 
   nsw = (NSWindow*)fl_xid(win);
 
   if (!captured) {
-    if (all_displays) {
-      if (CGCaptureAllDisplays() != kCGErrorSuccess)
-        return 1;
-    } else {
-      CGDirectDisplayID displays[16];
-      CGDisplayCount count;
-      int index;
+    CGDisplayCount count;
+    CGDirectDisplayID displays[16];
 
-      if (CGGetActiveDisplayList(16, displays, &count) != kCGErrorSuccess)
-        return 1;
+    int sx, sy, sw, sh;
+    rfb::Rect windows_rect, screen_rect;
 
-      if (count != (unsigned)Fl::screen_count())
-        return 1;
+    windows_rect.setXYWH(win->x(), win->y(), win->w(), win->h());
 
-      index = Fl::screen_num(win->x(), win->y(), win->w(), win->h());
+    if (CGGetActiveDisplayList(16, displays, &count) != kCGErrorSuccess)
+      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);
 
-      if (CGDisplayCapture(displays[index]) != 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;
@@ -87,7 +92,7 @@ int cocoa_capture_display(Fl_Window *win, bool all_displays)
   return 0;
 }
 
-void cocoa_release_display(Fl_Window *win)
+void cocoa_release_displays(Fl_Window *win)
 {
   NSWindow *nsw;
   int newlevel;