Browse Source

Wait for jni installation to complete asynchronously. (#72)

Improve installation of decorations.
pull/77/head
Jannis Weis 5 years ago committed by GitHub
parent
commit
498b73054c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 18
      buildSrc/src/main/kotlin/MacOSSdkPathTask.gradle.kt
  2. 4
      core/src/main/java/com/github/weisj/darklaf/LafManager.java
  3. 6
      core/src/main/java/com/github/weisj/darklaf/platform/Decorations.java
  4. 21
      core/src/main/java/com/github/weisj/darklaf/ui/rootpane/DarkRootPaneUI.java
  5. 25
      macos/build.gradle.kts
  6. 4
      macos/src/main/java/com/github/weisj/darklaf/platform/macos/JNIDecorationsMacOS.java
  7. 84
      macos/src/main/objectiveCpp/JNIDecorations.mm
  8. 4
      utils/src/main/java/com/github/weisj/darklaf/util/SystemInfo.java
  9. 20
      windows/src/main/java/com/github/weisj/darklaf/platform/windows/ui/WindowsTitlePane.java

18
buildSrc/src/main/kotlin/MacOSSdkPathTask.gradle.kt

@ -0,0 +1,18 @@
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.TaskAction
import org.gradle.nativeplatform.toolchain.internal.xcode.MacOSSdkPathLocator
import java.io.File
import javax.inject.Inject
open class MacOSSdkPathTask @Inject constructor(
private val locator: MacOSSdkPathLocator
) : DefaultTask() {
@Internal
lateinit var sdkPath: File
@TaskAction
fun run() {
sdkPath = locator.find()
}
}

4
core/src/main/java/com/github/weisj/darklaf/LafManager.java

@ -192,10 +192,6 @@ public final class LafManager {
updateLafRecursively(childWindow);
}
SwingUtilities.updateComponentTreeUI(window);
//Ensure decorations are applied appropriately.
boolean wasVisible = window.isVisible();
window.dispose();
window.setVisible(wasVisible);
}
/**

6
core/src/main/java/com/github/weisj/darklaf/platform/Decorations.java

@ -44,9 +44,11 @@ public final class Decorations {
//Extend for different platforms.
boolean enableDecorations =
!PropertyValue.FALSE.equals(System.getProperty(DarkLaf.SYSTEM_PROPERTY_PREFIX + "decorations"));
if (SystemInfo.isWindows && enableDecorations) {
if (SystemInfo.isWindows10 && enableDecorations) {
//Decorations are in the Windows10 visuals. Disable for older version.
decorationsProvider = new WindowsDecorationsProvider();
} else if (SystemInfo.isMac && enableDecorations) {
} else if (SystemInfo.isMacOSYosemite && enableDecorations) {
//Compiled binary needs at least macOS 10.10 (Yosemite).
decorationsProvider = new MacOSDecorationsProvider();
} else {
decorationsProvider = new DefaultDecorationsProvider();

21
core/src/main/java/com/github/weisj/darklaf/ui/rootpane/DarkRootPaneUI.java

@ -203,27 +203,6 @@ public class DarkRootPaneUI extends BasicRootPaneUI implements HierarchyListener
if (e.getChangeFlags() == HierarchyEvent.PARENT_CHANGED) {
updateClientDecoration();
}
if (e.getChangeFlags() == HierarchyEvent.SHOWING_CHANGED) {
if (!window.isShowing()) return;
/*
* Force the window peer to relayout and repaint.
* e.g. on windows this is necessary to properly remove the title bar.
*/
Rectangle bounds = window.getBounds();
Dimension size = bounds.getSize();
Point p = bounds.getLocation();
if (window.isPreferredSizeSet()) {
size = window.getPreferredSize();
} else {
p.x += size.width / 2;
p.y += size.height / 2;
}
//Resizing triggers #reshapeNativePeer
window.setSize(size.width, size.height + 1);
window.setSize(size.width, size.height);
window.setLocation(p.x - size.width / 2,
p.y - size.height / 2);
}
}
protected void updateClientDecoration() {

25
macos/build.gradle.kts

@ -14,15 +14,32 @@ dependencies {
javaImplementation(project(":darklaf-property-loader"))
}
val macPath by tasks.registering(MacOSSdkPathTask::class)
val sdkRoot: Provider<String> get() = macPath.map { it.sdkPath.absolutePath }
fun ListProperty<String>.addJavaFrameworks() {
addAll("-framework", "JavaNativeFoundation")
add("-F")
add(sdkRoot.map { "$it/System/Library/Frameworks/JavaVM.framework/Frameworks" })
}
library {
targetMachines.addAll(machines.macOS.x86_64)
binaries.configureEach {
compileTask.get().let {
it.compilerArgs.addAll(listOf("-x", "objective-c++"))
it.source.from(file("src/main/objectiveCpp/JNIDecorations.mm"))
compileTask.get().apply {
dependsOn(macPath)
compilerArgs.addAll("-x", "objective-c++")
compilerArgs.addAll("-mmacosx-version-min=10.10")
compilerArgs.addJavaFrameworks()
source.from(file("src/main/objectiveCpp/JNIDecorations.mm"))
}
}
binaries.whenElementFinalized(CppSharedLibrary::class) {
linkTask.get().linkerArgs.addAll(listOf("-lobjc", "-framework", "AppKit"))
linkTask.get().apply {
dependsOn(macPath)
linkerArgs.addAll("-lobjc", "-framework", "AppKit")
linkerArgs.addJavaFrameworks()
}
}
}

4
macos/src/main/java/com/github/weisj/darklaf/platform/macos/JNIDecorationsMacOS.java

@ -38,9 +38,9 @@ public class JNIDecorationsMacOS {
public static native long getComponentPointer(final Window window);
public static native long retainWindow(final long hwnd);
public static native void retainWindow(final long hwnd);
public static native long releaseWindow(final long hwnd);
public static native void releaseWindow(final long hwnd);
public static native double getTitleBarHeight(final long hwnd);

84
macos/src/main/objectiveCpp/JNIDecorations.mm

@ -22,12 +22,14 @@
* SOFTWARE.
*/
#import "com_github_weisj_darklaf_platform_macos_JNIDecorationsMacOS.h"
#import <JavaNativeFoundation/JavaNativeFoundation.h>
#import <Cocoa/Cocoa.h>
#define OBJC(jl) ((id)((void*)(jl)))
#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);
if (!env || !window) return 0;
jclass class_window = env->GetObjectClass(window);
jfieldID fid_peer = env->GetFieldID(class_window, "peer", "Ljava/awt/peer/ComponentPeer;");
@ -47,87 +49,109 @@ Java_com_github_weisj_darklaf_platform_macos_JNIDecorationsMacOS_getComponentPoi
jfieldID fid_ptr = env->GetFieldID(class_platformWindow, "ptr", "J");
jlong ptr = env->GetLongField(platformWindow, fid_ptr);
return ptr;
JNF_COCOA_EXIT(env);
return 0;
}
JNIEXPORT jlong JNICALL
JNIEXPORT void JNICALL
Java_com_github_weisj_darklaf_platform_macos_JNIDecorationsMacOS_retainWindow(JNIEnv *env, jclass obj, jlong hwnd) {
NSWindow *nsWindow = OBJC(hwnd);
[nsWindow retain];
JNF_COCOA_ENTER(env);
NSWindow *nsWindow = OBJC(hwnd);
[nsWindow retain];
JNF_COCOA_EXIT(env);
}
JNIEXPORT jlong JNICALL
JNIEXPORT void JNICALL
Java_com_github_weisj_darklaf_platform_macos_JNIDecorationsMacOS_releaseWindow(JNIEnv *env, jclass obj, jlong hwnd) {
NSWindow *nsWindow = OBJC(hwnd);
//Ensure any queued operation on nsWindow is finished first.
dispatch_async(dispatch_get_main_queue(), ^{
[nsWindow release];
});
JNF_COCOA_ENTER(env);
NSWindow *nsWindow = OBJC(hwnd);
[nsWindow release];
JNF_COCOA_EXIT(env);
}
JNIEXPORT jdouble JNICALL
Java_com_github_weisj_darklaf_platform_macos_JNIDecorationsMacOS_getTitleBarHeight(JNIEnv *env, jclass obj, jlong hwnd) {
NSWindow *nsWindow = OBJC(hwnd);
NSRect frame = NSMakeRect(0.0, 0.0, 100.0, 100.0);
NSUInteger windowStyle = nsWindow.styleMask & ~NSWindowStyleMaskFullSizeContentView;
NSRect rect = [NSWindow contentRectForFrameRect:frame styleMask:windowStyle];
return (jdouble)(frame.size.height - rect.size.height);
JNF_COCOA_ENTER(env);
NSWindow *nsWindow = OBJC(hwnd);
NSRect frame = NSMakeRect(0.0, 0.0, 100.0, 100.0);
NSUInteger windowStyle = nsWindow.styleMask & ~NSWindowStyleMaskFullSizeContentView;
NSRect rect = [NSWindow contentRectForFrameRect:frame styleMask:windowStyle];
return (jdouble)(frame.size.height - rect.size.height);
JNF_COCOA_EXIT(env);
return 0;
}
JNIEXPORT jboolean JNICALL
Java_com_github_weisj_darklaf_platform_macos_JNIDecorationsMacOS_isFullscreen(JNIEnv *env, jclass obj, jlong hwnd) {
JNF_COCOA_ENTER(env);
NSWindow *nsWindow = OBJC(hwnd);
return (jboolean)(([nsWindow styleMask] & NSWindowStyleMaskFullScreen) != 0);
JNF_COCOA_EXIT(env);
return false;
}
JNIEXPORT jdouble JNICALL
Java_com_github_weisj_darklaf_platform_macos_JNIDecorationsMacOS_getTitleFontSize(JNIEnv *env, jclass obj, jlong hwnd) {
JNF_COCOA_ENTER(env);
return (jdouble)[[NSFont titleBarFontOfSize:0] pointSize];
JNF_COCOA_EXIT(env);
return 0;
}
JNIEXPORT void JNICALL
Java_com_github_weisj_darklaf_platform_macos_JNIDecorationsMacOS_setTitleEnabled(JNIEnv *env, jclass obj, jlong hwnd,
jboolean enabled) {
JNF_COCOA_ENTER(env);
NSWindow *nsWindow = OBJC(hwnd);
dispatch_async(dispatch_get_main_queue(), ^{
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^{
if (enabled) {
nsWindow.titleVisibility = NSWindowTitleVisible;
} else {
nsWindow.titleVisibility = NSWindowTitleHidden;
}
[nsWindow contentView].needsDisplay = true;
});
}];
JNF_COCOA_EXIT(env);
}
JNIEXPORT void JNICALL
Java_com_github_weisj_darklaf_platform_macos_JNIDecorationsMacOS_setDarkTheme(JNIEnv *env, jclass obj, jlong hwnd,
jboolean darkEnabled) {
NSWindow *nsWindow = OBJC(hwnd);
dispatch_async(dispatch_get_main_queue(), ^{
if (darkEnabled) {
nsWindow.appearance = [NSAppearance appearanceNamed:NSAppearanceNameDarkAqua];
} else {
nsWindow.appearance = [NSAppearance appearanceNamed:NSAppearanceNameAqua];
}
[nsWindow contentView].needsDisplay = true;
});
JNF_COCOA_ENTER(env);
NSWindow *nsWindow = OBJC(hwnd);
if(@available(macOS 10.14, *)) {
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^{
if (darkEnabled) {
nsWindow.appearance = [NSAppearance appearanceNamed:@"NSAppearanceNameDarkAqua"];
} else {
nsWindow.appearance = [NSAppearance appearanceNamed:NSAppearanceNameAqua];
}
[nsWindow contentView].needsDisplay = true;
}];
}
JNF_COCOA_EXIT(env);
}
JNIEXPORT void JNICALL
Java_com_github_weisj_darklaf_platform_macos_JNIDecorationsMacOS_installDecorations(JNIEnv *env, jclass obj, jlong hwnd) {
JNF_COCOA_ENTER(env);
NSWindow *nsWindow = OBJC(hwnd);
dispatch_async(dispatch_get_main_queue(), ^{
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^{
nsWindow.styleMask |= NSWindowStyleMaskFullSizeContentView;
nsWindow.titlebarAppearsTransparent = true;
[nsWindow contentView].needsDisplay = true;
});
}];
JNF_COCOA_EXIT(env);
}
JNIEXPORT void JNICALL
Java_com_github_weisj_darklaf_platform_macos_JNIDecorationsMacOS_uninstallDecorations(JNIEnv *env, jclass obj, jlong hwnd) {
JNF_COCOA_ENTER(env);
NSWindow *nsWindow = OBJC(hwnd);
dispatch_async(dispatch_get_main_queue(), ^{
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^{
nsWindow.styleMask &= ~NSWindowStyleMaskFullSizeContentView;
nsWindow.titlebarAppearsTransparent = false;
[nsWindow contentView].needsDisplay = true;
});
}];
JNF_COCOA_EXIT(env);
}

4
utils/src/main/java/com/github/weisj/darklaf/util/SystemInfo.java

@ -51,6 +51,8 @@ public class SystemInfo {
protected static final String _OS_NAME;
public static boolean isMacOSMojave;
public static boolean isMacOSCatalina;
public static boolean isMacOSYosemite;
public static boolean isWindows10;
static {
_OS_NAME = OS_NAME.toLowerCase();
@ -68,6 +70,8 @@ public class SystemInfo {
isUndefined = !isX86 & !isX64;
isMacOSMojave = isMac && isOsVersionAtLeast("10.14");
isMacOSCatalina = isMac && isOsVersionAtLeast("10.15");
isMacOSYosemite = isMac && isOsVersionAtLeast("10.10");
isWindows10 = isWindows && isOsVersionAtLeast("10.0");
}
public static boolean isOsVersionAtLeast(final String version) {

20
windows/src/main/java/com/github/weisj/darklaf/platform/windows/ui/WindowsTitlePane.java

@ -214,6 +214,7 @@ public class WindowsTitlePane extends CustomTitlePane {
updateResizeBehaviour();
Color color = window.getBackground();
JNIDecorationsWindows.setBackground(windowHandle, color.getRed(), color.getGreen(), color.getBlue());
forceNativeResize();
} else {
uninstall();
return;
@ -229,13 +230,30 @@ public class WindowsTitlePane extends CustomTitlePane {
if (window instanceof Dialog) {
titleLabel.setText(((Dialog) window).getTitle());
}
determineColors();
setActive(window.isActive());
installListeners();
determineColors();
updateSystemIcon();
}
}
private void forceNativeResize() {
Rectangle bounds = window.getBounds();
Dimension size = bounds.getSize();
Point p = bounds.getLocation();
if (window.isPreferredSizeSet()) {
size = window.getPreferredSize();
} else {
p.x += size.width / 2;
p.y += size.height / 2;
}
//Resizing triggers #reshapeNativePeer
window.setSize(size.width, size.height + 1);
window.setSize(size.width, size.height);
window.setLocation(p.x - size.width / 2,
p.y - size.height / 2);
}
private void installListeners() {
if (window != null) {
windowListener = createWindowListener();

Loading…
Cancel
Save