Browse Source

Capture all displays inside the viewport (macOS)

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.
tags/v1.11.90
Hugo Lundin 2 years ago
parent
commit
2289342de7
3 changed files with 27 additions and 20 deletions
  1. 2
    2
      vncviewer/DesktopWindow.cxx
  2. 4
    2
      vncviewer/cocoa.h
  3. 21
    16
      vncviewer/cocoa.mm

+ 2
- 2
vncviewer/DesktopWindow.cxx View 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())

+ 4
- 2
vncviewer/cocoa.h View File

@@ -19,8 +19,10 @@
#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;


+ 21
- 16
vncviewer/cocoa.mm View 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;

Loading…
Cancel
Save