Skip to content

Commit

Permalink
Mac: Handle "Displays have separate Spaces"
Browse files Browse the repository at this point in the history
- Using JNI, detect whether "Displays have separate Spaces" is enabled
  in the system settings, and don't try to enable multi-screen spanning
  if so.  (Otherwise, if the viewer tries to create a multi-screen
  window, only the part of the window on the primary display will be
  visible.  If there is a vertical scrollbar, it will be inaccessible,
  and if there is a horizontal scrollbar, it will be incorrectly sized.)

- To be safe, also don't try to enable multi-screen spanning if the
  TurboVNC Helper is unavailable (which means that the state of
  "Displays have separate Spaces" cannot be determined.)

- Modify the description of the Span parameter on macOS to document the
  need to disable "Displays have separate Spaces" in order to use
  multi-screen spanning.
  • Loading branch information
dcommander committed Jan 10, 2025
1 parent c113222 commit 2152fb0
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 11 deletions.
6 changes: 6 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ and CVE-2024-31083) from the xorg-server 21.1.x code base.
a TurboVNC session if the initial resolution of any of the screens in the
session matched one of the default X RandR modes.

5. Fixed an issue in the Mac TurboVNC Viewer whereby the viewer window did not
display a vertical scrollbar, and the horizontal scrollbar was incorrectly
sized, if multi-screen spanning was enabled, the scaled remote desktop was
larger than the viewer window, and "Displays have separate Spaces" was enabled
in the system settings.


3.1.3
=====
Expand Down
7 changes: 5 additions & 2 deletions java/com/turbovnc/rfb/Helper.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* Copyright (C) 2015, 2017-2018, 2020-2022 D. R. Commander.
* All Rights Reserved.
/* Copyright (C) 2015, 2017-2018, 2020-2022, 2025 D. R. Commander.
* All Rights Reserved.
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -53,6 +53,9 @@ private static synchronized void printMissingFeatures() {
if (Utils.osEID())
vlog.info(" - Extended input device support");
if (Utils.isX11()) {
vlog.info(" - Multi-screen spanning in full-screen mode");
}
if (Utils.isMac()) {
vlog.info(" - Multi-screen spanning");
}
if (Utils.isWindows())
Expand Down
12 changes: 8 additions & 4 deletions java/com/turbovnc/rfb/Params.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (C) 2012-2018, 2020-2024 D. R. Commander. All Rights Reserved.
/* Copyright (C) 2012-2018, 2020-2025 D. R. Commander. All Rights Reserved.
* Copyright (C) 2021 Steffen Kieß
* Copyright (C) 2011-2012, 2016 Brian P. Hinz
* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
Expand Down Expand Up @@ -795,9 +795,13 @@ public void save(String node) {

"When using automatic desktop resizing, \"Auto\" has the same effect as " +
"\"Primary\" when in windowed mode and the same effect as \"All\" when in " +
"full-screen mode. Due to general issues with spanning windows across " +
"multiple monitors in X11, this parameter does not work on Un*x/X11 " +
"platforms except in full-screen mode.", SpanParameter.AUTO);
"full-screen mode." +
(Utils.isX11() ? " Due to general issues with spanning windows across " +
"multiple monitors in X11, this parameter has no effect on Un*x/X11 " +
"platforms except in full-screen mode." : "") +
(Utils.isMac() ? " This parameter has no effect on macOS unless " +
"\"Displays have separate Spaces\" is disabled in the system settings." :
""), SpanParameter.AUTO);

public BoolParameter toolbar =
new BoolParameter("Toolbar", this, true,
Expand Down
8 changes: 7 additions & 1 deletion java/com/turbovnc/rfb/Utils.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (C) 2012, 2015, 2018, 2020, 2022-2024 D. R. Commander.
/* Copyright (C) 2012, 2015, 2018, 2020, 2022-2025 D. R. Commander.
* All Rights Reserved.
* Copyright (C) 2012 Brian P. Hinz
*
Expand Down Expand Up @@ -57,6 +57,12 @@ public static boolean osGrab() {
return !isMac();
}

private static native boolean displaysHaveSeparateSpaces();

public static boolean displaysHaveSeparateSpacesHelper() {
return isMac() && (!Helper.isAvailable() || displaysHaveSeparateSpaces());
}

public static boolean getBooleanProperty(String key, boolean def) {
String prop = System.getProperty(key, def ? "True" : "False");
if (prop != null && prop.length() > 0) {
Expand Down
8 changes: 6 additions & 2 deletions java/com/turbovnc/vncviewer/CConn.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (C) 2011-2024 D. R. Commander. All Rights Reserved.
/* Copyright (C) 2011-2025 D. R. Commander. All Rights Reserved.
* Copyright (C) 2021 Steffen Kieß
* Copyright 2009-2011, 2016-2019 Pierre Ossman <[email protected]>
* for Cendio AB
Expand Down Expand Up @@ -1367,7 +1367,11 @@ public Rectangle getSpannedSize() {
// under X11 except for full-screen windows, and even then, the
// appropriate WM hints must be set using C.)
(Utils.isX11() &&
(!params.fullScreen.get() || !Helper.isAvailable()))) {
(!params.fullScreen.get() || !Helper.isAvailable())) ||
// We're using macOS, and "Displays have separate Spaces" is enabled in
// the system settings (or the state of "Displays have separate Spaces"
// cannot be determined because the helper library isn't available.)
(Utils.isMac() && Utils.displaysHaveSeparateSpacesHelper())) {
span = primary;
viewport.leftMon = viewport.rightMon = viewport.topMon =
viewport.bottomMon = primaryID;
Expand Down
20 changes: 20 additions & 0 deletions unix/vncviewer/com_turbovnc_rfb_Utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include <jni.h>
/* Header for class com_turbovnc_rfb_Utils */

#ifndef _Included_com_turbovnc_rfb_Utils
#define _Included_com_turbovnc_rfb_Utils
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_turbovnc_rfb_Utils
* Method: displaysHaveSeparateSpaces
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_com_turbovnc_rfb_Utils_displaysHaveSeparateSpaces
(JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif
12 changes: 10 additions & 2 deletions unix/vncviewer/turbovnchelper.m
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* Copyright (C) 2015-2017, 2019, 2021-2022 D. R. Commander.
* All Rights Reserved.
/* Copyright (C) 2015-2017, 2019, 2021-2022, 2025 D. R. Commander.
* All Rights Reserved.
* Copyright 2014, 2017 Pierre Ossman for Cendio AB
*
* This is free software; you can redistribute it and/or modify
Expand Down Expand Up @@ -48,6 +48,7 @@
#include <string.h>
#include <dlfcn.h>
#include <unistd.h>
#include "com_turbovnc_rfb_Utils.h"
#include "com_turbovnc_vncviewer_Viewport.h"
#include <Cocoa/Cocoa.h>
#import <Carbon/Carbon.h>
Expand Down Expand Up @@ -380,3 +381,10 @@ - (void)newSendEvent:(NSEvent *)event
bailout:
return;
}


JNIEXPORT jboolean JNICALL Java_com_turbovnc_rfb_Utils_displaysHaveSeparateSpaces
(JNIEnv *env, jobject obj)
{
return (jboolean)[NSScreen screensHaveSeparateSpaces];
}

0 comments on commit 2152fb0

Please sign in to comment.