diff --git a/macos/src/main/objcpp/Decorations.mm b/macos/src/main/objcpp/Decorations.mm index cfd4708af..e9a49ac8e 100644 --- a/macos/src/main/objcpp/Decorations.mm +++ b/macos/src/main/objcpp/Decorations.mm @@ -19,11 +19,9 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #import "com_github_weisj_darklaf_platform_macos_JNIDecorationsMacOS.h" -#import +#import "JNFUtils.h" #import -#define OBJC(jl) ((id)jlong_to_ptr(jl)) - JNIEXPORT jlong JNICALL Java_com_github_weisj_darklaf_platform_macos_JNIDecorationsMacOS_getComponentPointer(JNIEnv *env, jclass cls, jobject window) { JNF_COCOA_ENTER(env); @@ -100,7 +98,7 @@ jboolean enabled) { JNF_COCOA_ENTER(env); NSWindow *nsWindow = OBJC(hwnd); - [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^{ + [JNF_RunLoop performOnMainThreadWaiting:YES withBlock:^{ if (enabled) { nsWindow.titleVisibility = NSWindowTitleVisible; } else { @@ -117,7 +115,7 @@ JNF_COCOA_ENTER(env); NSWindow *nsWindow = OBJC(hwnd); if(@available(macOS 10.14, *)) { - [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^{ + [JNF_RunLoop performOnMainThreadWaiting:YES withBlock:^{ if (darkEnabled) { nsWindow.appearance = [NSAppearance appearanceNamed:@"NSAppearanceNameDarkAqua"]; } else { @@ -133,7 +131,7 @@ Java_com_github_weisj_darklaf_platform_macos_JNIDecorationsMacOS_installDecorations(JNIEnv *env, jclass obj, jlong hwnd) { JNF_COCOA_ENTER(env); NSWindow *nsWindow = OBJC(hwnd); - [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^{ + [JNF_RunLoop performOnMainThreadWaiting:YES withBlock:^{ nsWindow.styleMask |= NSWindowStyleMaskFullSizeContentView; nsWindow.titlebarAppearsTransparent = YES; [nsWindow contentView].needsDisplay = YES; @@ -146,7 +144,7 @@ jboolean fullSizeContent, jboolean transparentTitleBar) { JNF_COCOA_ENTER(env); NSWindow *nsWindow = OBJC(hwnd); - [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^{ + [JNF_RunLoop performOnMainThreadWaiting:YES withBlock:^{ if (fullSizeContent) { nsWindow.styleMask |= NSWindowStyleMaskFullSizeContentView; } else { diff --git a/macos/src/main/objcpp/JNFUtils.h b/macos/src/main/objcpp/JNFUtils.h new file mode 100644 index 000000000..de04ae0da --- /dev/null +++ b/macos/src/main/objcpp/JNFUtils.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2008-2020 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#import +#import + +__BEGIN_DECLS + +#ifndef jlong_to_ptr +#define jlong_to_ptr(a) ((void *)(uintptr_t)(a)) +#endif + +#define OBJC(jl) ((id)jlong_to_ptr(jl)) + +#define JNF_COCOA_DURING(env) \ +@try { + +#define JNF_COCOA_HANDLE(env) \ +} @catch(NSException *localException) { \ + [JNF_Exception throwToJava:env exception:localException]; \ +} + +#define JNF_COCOA_ENTER(env) \ +@autoreleasepool { \ + @try { \ + @autoreleasepool { + +#define JNF_COCOA_EXIT(env) \ + } /*@autoreleasepool*/ \ + JNF_COCOA_HANDLE(env) \ +} /*@autoreleasepool*/ + + +@interface JNF_RunLoop : NSObject { } ++ (void)performOnMainThread:(SEL)aSelector on:(id)target withObject:(id)arg waitUntilDone:(BOOL)waitUntilDone; ++ (void)performOnMainThreadWaiting:(BOOL)waitUntilDone withBlock:(void (^)(void))block; +@end + +@interface JNF_Exception : NSException ++ (void)throwToJava:(JNIEnv *)env exception:(NSException *)exception; +@end + + +__END_DECLS diff --git a/macos/src/main/objcpp/JNFUtils.mm b/macos/src/main/objcpp/JNFUtils.mm new file mode 100644 index 000000000..83e9a0979 --- /dev/null +++ b/macos/src/main/objcpp/JNFUtils.mm @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2008-2020 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#import "JNFUtils.h" + +#import + +static NSString *AWTRunLoopMode = @"AWTRunLoopMode"; +static NSArray *sPerformModes = nil; + +@implementation JNF_RunLoop + ++ (void)initialize { + if (sPerformModes) return; + sPerformModes = [[NSArray alloc] initWithObjects:NSDefaultRunLoopMode, NSModalPanelRunLoopMode, NSEventTrackingRunLoopMode, AWTRunLoopMode, nil]; +} + ++ (void)_performDirectBlock:(void (^)(void))block { + block(); +} + ++ (void)_performCopiedBlock:(void (^)(void))newBlock { + newBlock(); + Block_release(newBlock); +} + ++ (void)performOnMainThread:(SEL)aSelector on:(id)target withObject:(id)arg waitUntilDone:(BOOL)waitUntilDone { + [target performSelectorOnMainThread:aSelector withObject:arg waitUntilDone:waitUntilDone modes:sPerformModes]; +} + ++ (void)performOnMainThreadWaiting:(BOOL)waitUntilDone withBlock:(void (^)(void))block { + if (waitUntilDone) { + [self performOnMainThread:@selector(_performDirectBlock:) on:self withObject:block waitUntilDone:YES]; + } else { + void (^newBlock)(void) = Block_copy(block); + [self performOnMainThread:@selector(_performCopiedBlock:) on:self withObject:newBlock waitUntilDone:NO]; + } +} +@end + +@implementation JNF_Exception + ++ (void)throwToJava:(JNIEnv *)env exception:(NSException *)exception { + jclass exceptionClass = env-> FindClass("java/lang/RuntimeException"); + if (!exceptionClass) return; + + const char *reason = [[NSString stringWithFormat:@"Non-Java exception raised, not handled! (Original problem: %@)", [exception reason]] UTF8String]; + if (reason == NULL) reason = "unknown"; + + env->ThrowNew(exceptionClass, reason); +} +@end diff --git a/macos/src/main/objcpp/ThemeInfo.mm b/macos/src/main/objcpp/ThemeInfo.mm index 429ece5ce..59542abca 100644 --- a/macos/src/main/objcpp/ThemeInfo.mm +++ b/macos/src/main/objcpp/ThemeInfo.mm @@ -19,11 +19,9 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #import "com_github_weisj_darklaf_platform_macos_JNIThemeInfoMacOS.h" -#import +#import "JNFUtils.h" #import -#define OBJC(jl) ((id)jlong_to_ptr(jl)) - #define NSRequiresAquaSystemAppearance CFSTR("NSRequiresAquaSystemAppearance") #define KEY_APPLE_INTERFACE_STYLE @"AppleInterfaceStyle" @@ -114,7 +112,7 @@ - (void)runCallback { } - (void)dispatchCallback { - [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^{ + [JNF_RunLoop performOnMainThreadWaiting:NO withBlock:^{ [self runCallback]; }]; }