Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add System Tray workaround for Big Sur #745

Merged
merged 3 commits into from
Jan 29, 2021
Merged

Add System Tray workaround for Big Sur #745

merged 3 commits into from
Jan 29, 2021

Conversation

tresf
Copy link
Contributor

@tresf tresf commented Jan 19, 2021

Java doesn't have proper support for templated TrayIcons, a hard-requirement since Big Sur for apps that use black and white TrayIcons.

This issue was tracked and patched in JDK17 per https://bugs.openjdk.java.net/browse/JDK-8252015 (thanks @Vzor- and our JDK support provider), however the backport to JDK11 will take some time (estimated at least 3 months).

This PR adds a workaround from https://github.com/dyorgio/macos-tray-icon-fixer (Thanks @dyorgio!) which uses JNA to fix the issue prior to the backport of JDK-8252015. Note, this workaround won't work fully on Apple Silicon until the project is updated with JNA 5.7.0, which contains macOS aarch64 (arm64) support java-native-access/jna#1238.

Test results (1/29/21)

macOS JDK8 JDK11
10.15 (Catalina)
10.14 (Mojave)
10.8 (Mountain Lion) -
10.7 (Lion) -

Closes #678

Add new java attribute for system tray template icons
@klabarge
Copy link
Member

I tested the icon theming on macOS Big Sur 11.1 and this works great.

@tresf
Copy link
Contributor Author

tresf commented Jan 28, 2021

I tested the icon theming on macOS Big Sur 11.1 and this works great.

Great, however proper testing should include regression testing (e.g. Java 8 and hopefully an older macOS version) to ensure there's no breaking change.

@Vzor- I think you have the most macOS VMs laying around, can you test this out? If you need precompiled binaries, I can provide temporary download links.

@tresf
Copy link
Contributor Author

tresf commented Jan 28, 2021

Testing on macOS Mountain Lion 10.8, I get the following hard-crash:

Edit: Filed upstream bug report: dyorgio/macos-tray-icon-fixer#3

2021-01-28 15:37:19.534 java[541:2907] -[NSStatusItem button]: unrecognized selector sent to instance 0x7fb2c1cfb0f0
2021-01-28 15:37:19.535 java[541:2907] An uncaught exception was raised
2021-01-28 15:37:19.536 java[541:2907] -[NSStatusItem button]: unrecognized selector sent to instance 0x7fb2c1cfb0f0
2021-01-28 15:37:19.537 java[541:2907] (
	0   CoreFoundation                      0x00007fff8e140b06 __exceptionPreprocess + 198
	1   libobjc.A.dylib                     0x00007fff8e5553f0 objc_exception_throw + 43
	2   CoreFoundation                      0x00007fff8e1d740a -[NSObject(NSObject) doesNotRecognizeSelector:] + 186
	3   CoreFoundation                      0x00007fff8e12f02e ___forwarding___ + 414
	4   CoreFoundation                      0x00007fff8e12ee18 _CF_forwarding_prep_0 + 232
	5   jna286536894285511670.tmp           0x0000000180db5e74 ffi_call_unix64 + 76
	6   ???                                 0x00007fff57e107f8 0x0 + 140734667753464
)
2021-01-28 15:37:19.537 java[541:2907] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSStatusItem button]: unrecognized selector sent to instance 0x7fb2c1cfb0f0'
*** First throw call stack:
(
	0   CoreFoundation                      0x00007fff8e140b06 __exceptionPreprocess + 198
	1   libobjc.A.dylib                     0x00007fff8e5553f0 objc_exception_throw + 43
	2   CoreFoundation                      0x00007fff8e1d740a -[NSObject(NSObject) doesNotRecognizeSelector:] + 186
	3   CoreFoundation                      0x00007fff8e12f02e ___forwarding___ + 414
	4   CoreFoundation                      0x00007fff8e12ee18 _CF_forwarding_prep_0 + 232
	5   jna286536894285511670.tmp           0x0000000180db5e74 ffi_call_unix64 + 76
	6   ???                                 0x00007fff57e107f8 0x0 + 140734667753464
)

@tresf
Copy link
Contributor Author

tresf commented Jan 29, 2021

Tested:

macOS JDK8 JDK11
10.15 (Catalina)
10.14 (Mojave)
10.8 (Mountain Lion) -
10.7 (Lion) -

With patched from dyorgio/macos-tray-icon-fixer#3, and a fix for a race condition, this is working very well on all tests. Merging.

@tresf tresf merged commit 9785106 into master Jan 29, 2021
@tresf tresf deleted the big-sur branch January 29, 2021 19:10
@klabarge
Copy link
Member

klabarge commented Feb 23, 2021

Documenting the reflection warning that occurs when running QZ Tray with this patch.

Per @tresf this will go away once the patched jdk11 receives the system tray patch

[INFO] 2021-02-23 18:21:03,668 @ qz.ws.PrintSocketServer:?
	Server started on port(s) 8182, 8181
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by qz.utils.MacUtilities (file:/Applications/QZ%20Tray.app/qz-tray.jar) to field sun.lwawt.macosx.CFRetainedResource.ptr
WARNING: Please consider reporting this to the maintainers of qz.utils.MacUtilities
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
[WARN] 2021-02-23 18:21:50,219 @ qz.ws.PrintSocketServer:?

@tresf
Copy link
Contributor Author

tresf commented Feb 24, 2021

Per @tresf this will go away once the patched jdk11 receives the system tray patch

Correct, the warning is triggered here:

try {
Field ptrField = Class.forName("sun.lwawt.macosx.CFRetainedResource").getDeclaredField("ptr");
ptrField.setAccessible(true);
Field field = TrayIcon.class.getDeclaredField("peer");
field.setAccessible(true);
long cTrayIconAddress = ptrField.getLong(field.get(icon));

The code will stop executing the moment JDK-8252015 lands on JDK11, by checking to see if the additional boolean for template is supported. WIth this PR, we set the boolean at launch, so it will be picked up automatically when the JDK receives the feature.

/**
* Checks for presence of JDK-8252015 using reflection
*/
public static boolean jdkSupportsTemplateIcon() {
if(jdkSupportsTemplateIcon == null) {
try {
// before JDK-8252015: setNativeImage(long, long, boolean)
// after JDK-8252015: setNativeImage(long, long, boolean, boolean)
Class.forName("sun.lwawt.macosx.CTrayIcon").getDeclaredMethod("setNativeImage", long.class, long.class, boolean.class, boolean.class);
jdkSupportsTemplateIcon = true;
}
catch(ClassNotFoundException | NoSuchMethodException ignore) {
jdkSupportsTemplateIcon = false;
}
}
return jdkSupportsTemplateIcon;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

macOS 10.16/11.0 Dark mode System Tray ambiguity
2 participants