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

Include necessary JNF code at compile time #312

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -400,9 +400,6 @@ public HeaderButton(final Icon icon, final DarkPanelPopupUI popupUI) {
setFocus(false);
setFocusable(false);
setOpaque(false);

System.out.println(icon.getIconWidth() + " " + icon.getIconHeight());
System.out.println(getPreferredSize());
}

public void setFocus(final boolean focus) {
Expand Down
1 change: 0 additions & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ javaxAnnotations.version = 1.3.2

# MacOS Frameworks
macOSFramework.version = latest.release
javaNativeFoundation.version = 1.1.1

# Test libraries
junit.version = 5.6.2
Expand Down
39 changes: 0 additions & 39 deletions macos/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,28 +13,8 @@ moduleInfo {
stubModule("darklaf.platform.preferences")
}

val jnfConfig: Configuration by configurations.creating {
attributes {
attribute(Attribute.of("dev.nokee.architecture", String::class.java), "arm64")
}
}

dependencies {
jnfConfig(macOsFrameworks.javaNativeFoundation)
}

val nativeResourcePath = "com/github/weisj/darklaf/platform/${project.name}"

tasks.jar {
jnfConfig.asFileTree.forEach {
from(zipTree(it)) {
into("$nativeResourcePath/JavaNativeFoundation.framework")
include("JavaNativeFoundation*")
exclude("**/*.tbd")
}
}
}

library {
dependencies {
jvmImplementation(projects.darklafThemeSpec)
Expand All @@ -44,7 +24,6 @@ library {
jvmImplementation(projects.darklafPlatformDecorations)
nativeLibImplementation(macOsFrameworks.appKit)
nativeLibImplementation(macOsFrameworks.cocoa)
nativeLibImplementation(macOsFrameworks.javaNativeFoundation)
}

targetMachines.addAll(machines.macOS.x86_64, machines.macOS.architecture("arm64"))
Expand All @@ -59,28 +38,10 @@ library {
optimizedBinary()
}
linkTask.configure {
val systemFrameworks = "/System/Library/Frameworks"
val versionCurrent = "Versions/Current"
val versionA = "Versions/A"
val jnfName = "JavaNativeFoundation.framework"
linkerArgs.addAll(
"-lobjc", "-mmacosx-version-min=$minOs",
// "-framework", "AppKit",
// "-framework", "Cocoa",
// The custom JNF framework specified @rpath for searching. As we aren't actually linking
// with the dynamic library of the framework we specifically have to add the system framework
// search paths accordingly.
// First try any system provided framework (this will fail on arm64):
"-rpath", "$systemFrameworks/$jnfName/$versionCurrent",
"-rpath", "$systemFrameworks/$jnfName/$versionA",
"-rpath", "$systemFrameworks/JavaVM.framework/$versionCurrent/Frameworks/$jnfName/$versionCurrent",
"-rpath", "$systemFrameworks/JavaVM.framework/$versionA/Frameworks/$jnfName/$versionA",
// Then try the jdk provided framework (folder layout may vary. We check multiple possibilities):
"-rpath", "@executable_path/../lib/$jnfName",
"-rpath", "@executable_path/../lib/$jnfName/$versionCurrent",
"-rpath", "@executable_path/../lib/$jnfName/$versionA",
// Lastly use our bundled drop-in replacement:
"-rpath", "@loader_path/$jnfName"
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,7 @@
*/
package com.github.weisj.darklaf.platform.macos;

import java.util.Collections;
import java.util.List;

import com.github.weisj.darklaf.nativeutil.AbstractLibrary;
import com.github.weisj.darklaf.nativeutil.NativeUtil;
import com.github.weisj.darklaf.platform.SystemInfo;
import com.github.weisj.darklaf.util.LogUtil;

Expand All @@ -34,8 +30,6 @@ public class MacOSLibrary extends AbstractLibrary {
private static final String x86_64_PATH = PATH + "/libdarklaf-macos-x86-64.dylib";
private static final String arm64_PATH = PATH + "/libdarklaf-macos-arm64.dylib";

private static final String FRAMEWORK_TARGET_PATH = "JavaNativeFoundation.framework/";
private static final String FRAMEWORK_PATH = PATH + "/" + FRAMEWORK_TARGET_PATH + "JavaNativeFoundation";
private static final MacOSLibrary instance = new MacOSLibrary();

public static MacOSLibrary get() {
Expand Down Expand Up @@ -70,12 +64,6 @@ public String getLibraryPath() {
}
}

@Override
protected List<NativeUtil.Resource> getResourcePaths() {
return Collections.singletonList(
new NativeUtil.Resource(FRAMEWORK_PATH, FRAMEWORK_TARGET_PATH));
}

@Override
protected boolean canLoad() {
return ((SystemInfo.isX86Compatible && SystemInfo.isX64) || SystemInfo.isM1) && SystemInfo.isMacOSYosemite;
Expand Down
12 changes: 5 additions & 7 deletions macos/src/main/objcpp/Decorations.mm
Original file line number Diff line number Diff line change
Expand Up @@ -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 <JavaNativeFoundation/JavaNativeFoundation.h>
#import "JNFUtils.h"
#import <Cocoa/Cocoa.h>

#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);
Expand Down Expand Up @@ -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 {
Expand All @@ -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 {
Expand All @@ -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;
Expand All @@ -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 {
Expand Down
70 changes: 70 additions & 0 deletions macos/src/main/objcpp/JNFUtils.h
Original file line number Diff line number Diff line change
@@ -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 <Foundation/Foundation.h>
#import <jni.h>

__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
78 changes: 78 additions & 0 deletions macos/src/main/objcpp/JNFUtils.mm
Original file line number Diff line number Diff line change
@@ -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 <Cocoa/Cocoa.h>

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
6 changes: 2 additions & 4 deletions macos/src/main/objcpp/ThemeInfo.mm
Original file line number Diff line number Diff line change
Expand Up @@ -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 <JavaNativeFoundation/JavaNativeFoundation.h>
#import "JNFUtils.h"
#import <AppKit/AppKit.h>

#define OBJC(jl) ((id)jlong_to_ptr(jl))

#define NSRequiresAquaSystemAppearance CFSTR("NSRequiresAquaSystemAppearance")

#define KEY_APPLE_INTERFACE_STYLE @"AppleInterfaceStyle"
Expand Down Expand Up @@ -114,7 +112,7 @@ - (void)runCallback {
}

- (void)dispatchCallback {
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^{
[JNF_RunLoop performOnMainThreadWaiting:NO withBlock:^{
[self runCallback];
}];
}
Expand Down
1 change: 0 additions & 1 deletion settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ dependencyResolutionManagement {
idv("nullabilityAnnotations", "org.jetbrains:annotations")
}
create("macOsFrameworks") {
idv("javaNativeFoundation", "com.github.weisj:java-native-foundation")
idv("appKit", "dev.nokee.framework:AppKit", "macOSFramework")
idv("cocoa", "dev.nokee.framework:Cocoa", "macOSFramework")
}
Expand Down