Browse Source

Fix corner radius for macos popups

master
Jannis Weis 4 months ago
parent
commit
8f5b1b07b8
No known key found for this signature in database
GPG Key ID: 7C9D8D4B558049AB
  1. 18
      build.gradle.kts
  2. 20
      core/src/main/java/com/github/weisj/darklaf/components/border/RoundedLineBorder.java
  3. 4
      core/src/main/java/com/github/weisj/darklaf/ui/combobox/DarkComboPopup.java
  4. 4
      macos/src/main/java/com/github/weisj/darklaf/platform/macos/JNIDecorationsMacOS.java
  5. 39
      macos/src/main/java/com/github/weisj/darklaf/platform/macos/MacOSDecorationsProvider.java
  6. 7
      macos/src/main/java/com/github/weisj/darklaf/platform/macos/ui/MacOSDecorationsUtil.java
  7. 30
      macos/src/main/objcpp/Decorations.mm
  8. 31
      platform-base/src/main/java/com/github/weisj/darklaf/platform/RoundedFrame.java

18
build.gradle.kts

@ -7,7 +7,7 @@ import com.github.vlsi.gradle.publishing.dsl.simplifyXml
import com.github.vlsi.gradle.publishing.dsl.versionFromResolution
import net.ltgt.gradle.errorprone.errorprone
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
import java.util.*
import java.util.Locale
plugins {
idea
@ -96,7 +96,7 @@ allprojects {
github(
user = "weisj",
repository = "darklaf",
workflow = "libs.yml"
workflow = "libs.yml",
) {
branches = listOfNotNull(currentBranch, "master", "v$projectVersion", projectVersion)
accessToken = githubAccessToken
@ -188,7 +188,7 @@ allprojects {
configure<SigningExtension> {
useInMemoryPgpKeys(
project.stringProperty("signing.inMemoryKey")?.replace("#", "\n"),
project.stringProperty("signing.password")
project.stringProperty("signing.password"),
)
}
}
@ -213,7 +213,7 @@ allprojects {
disable(
"StringSplitter",
"InlineMeSuggester",
"MissingSummary"
"MissingSummary",
)
}
}
@ -314,16 +314,18 @@ allprojects {
description.set(
project.description
?: "A themeable Look and Feel for java swing"
?: "A themeable Look and Feel for java swing",
)
name.set(
(project.findProperty("artifact.name") as? String)
?: project.name
.replaceFirstChar {
if (it.isLowerCase()) it.titlecase(Locale.getDefault())
else it.toString()
if (it.isLowerCase()) {
it.titlecase(Locale.getDefault())
} else {
it.toString()
}
.replace("-", " ")
}.replace("-", " "),
)
url.set("https://github.com/weisJ/darklaf")
organization {

20
core/src/main/java/com/github/weisj/darklaf/components/border/RoundedLineBorder.java

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2023 Jannis Weis
* Copyright (c) 2023-2024 Jannis Weis
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction,
@ -25,8 +25,9 @@ import java.awt.*;
import javax.swing.border.Border;
import com.github.weisj.darklaf.graphics.PaintUtil;
import com.github.weisj.darklaf.platform.RoundedFrame;
public class RoundedLineBorder implements Border {
public class RoundedLineBorder implements Border, RoundedFrame {
private final Color color;
private final int arc;
@ -38,6 +39,21 @@ public class RoundedLineBorder implements Border {
this.thickness = thickness;
}
@Override
public int getRadius() {
return arc;
}
@Override
public Color getColor() {
return color;
}
@Override
public int getThickness() {
return thickness;
}
@Override
public void paintBorder(final Component c, final Graphics g, final int x, final int y, final int width,
final int height) {

4
core/src/main/java/com/github/weisj/darklaf/ui/combobox/DarkComboPopup.java

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2019-2023 Jannis Weis
* Copyright (c) 2019-2024 Jannis Weis
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction,
@ -109,7 +109,6 @@ public class DarkComboPopup extends BasicComboPopup {
protected void configurePopup() {
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
setBorderPainted(true);
setOpaque(false);
add(overlayScrollPane);
setFocusable(false);
setOpaque(true);
@ -117,6 +116,7 @@ public class DarkComboPopup extends BasicComboPopup {
@Override
public void show() {
setBackground(new Color(list.getBackground().getRGB()));
comboBox.firePopupMenuWillBecomeVisible();
setListSelection(comboBox.getSelectedIndex());
Point location = getPopupLocation();

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

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2019-2022 Jannis Weis
* Copyright (c) 2019-2024 Jannis Weis
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction,
@ -34,6 +34,8 @@ public final class JNIDecorationsMacOS {
public static native void installDecorations(final long hwnd);
public static native void installPopup(final long hwnd, final int radius, final int thickness, final int rgb);
public static native void uninstallDecorations(final long hwnd,
final boolean fullSizeContent, final boolean transparentTitleBar);

39
macos/src/main/java/com/github/weisj/darklaf/platform/macos/MacOSDecorationsProvider.java

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2019-2022 Jannis Weis
* Copyright (c) 2019-2024 Jannis Weis
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction,
@ -25,8 +25,11 @@ import java.util.Collections;
import java.util.List;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.CompoundBorder;
import com.github.weisj.darklaf.platform.*;
import com.github.weisj.darklaf.platform.macos.ui.MacOSDecorationsUtil;
import com.github.weisj.darklaf.platform.macos.ui.MacOSTitlePane;
public class MacOSDecorationsProvider implements DecorationsProvider {
@ -58,6 +61,40 @@ public class MacOSDecorationsProvider implements DecorationsProvider {
return Collections.singletonList("macos_decorations");
}
@Override
public void installPopupWindow(final Window window) {
if (!window.isDisplayable()) {
window.addNotify();
}
if (window instanceof RootPaneContainer) {
JRootPane rootPane = ((RootPaneContainer) window).getRootPane();
Border border = getOutermostBorder((JComponent) rootPane.getContentPane());
while (border instanceof CompoundBorder) {
border = ((CompoundBorder) border).getOutsideBorder();
}
if (border instanceof RoundedFrame) {
MacOSDecorationsUtil.installPopupWindow(window,
((RoundedFrame) border).getRadius(),
((RoundedFrame) border).getThickness(),
((RoundedFrame) border).getColor().getRGB());
window.repaint();
}
}
}
private static Border getOutermostBorder(final JComponent component) {
JComponent c = component;
while (c.getComponentCount() == 1 && c.getBorder() == null) {
JComponent child = (JComponent) c.getComponent(0);
if (child.getWidth() == c.getWidth() && child.getHeight() == c.getHeight()) {
c = child;
} else {
break;
}
}
return c.getBorder();
}
@Override
public boolean supportsNativeTitleLabel() {
return SystemInfo.isMacOSMojave;

7
macos/src/main/java/com/github/weisj/darklaf/platform/macos/ui/MacOSDecorationsUtil.java

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2020-2022 Jannis Weis
* Copyright (c) 2020-2024 Jannis Weis
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction,
@ -69,6 +69,11 @@ public final class MacOSDecorationsUtil {
rootPane, titleVisible, titleBarHeight, titleFontSize);
}
public static void installPopupWindow(final Window window, final int radius, final int thickness, final int rgb) {
long windowHandle = JNIDecorationsMacOS.getComponentPointer(window);
JNIDecorationsMacOS.installPopup(windowHandle, radius, thickness, radius);
}
private static void setFullSizeContent(final long windowHandle, final boolean enabled) {
if (enabled) {
JNIDecorationsMacOS.installDecorations(windowHandle);

30
macos/src/main/objcpp/Decorations.mm

@ -156,6 +156,36 @@ JNF_COCOA_ENTER(env);
JNF_COCOA_EXIT(env);
}
JNIEXPORT void JNICALL
Java_com_github_weisj_darklaf_platform_macos_JNIDecorationsMacOS_installPopup(JNIEnv *env, jclass obj, jlong hwnd, jint radius, jint borderWidth, jint borderColor) {
JNF_COCOA_ENTER(env);
NSWindow *nsWindow = OBJC(hwnd);
[JNF_RunLoop performOnMainThreadWaiting:YES withBlock:^{
nsWindow.hasShadow = YES;
nsWindow.contentView.wantsLayer = YES;
nsWindow.contentView.layer.cornerRadius = radius;
nsWindow.contentView.layer.masksToBounds = YES;
nsWindow.backgroundColor = NSColor.clearColor;
nsWindow.opaque = NO;
nsWindow.contentView.layer.borderWidth = borderWidth;
if( borderWidth > 0 ) {
CGFloat red = ((borderColor >> 16) & 0xff) / 255.;
CGFloat green = ((borderColor >> 8) & 0xff) / 255.;
CGFloat blue = (borderColor & 0xff) / 255.;
CGFloat alpha = ((borderColor >> 24) & 0xff) / 255.;
nsWindow.contentView.layer.borderColor = [[NSColor colorWithDeviceRed:red green:green blue:blue alpha:alpha] CGColor];
}
nsWindow.contentView.needsDisplay = YES;
[nsWindow.contentView.layer removeAllAnimations];
[nsWindow invalidateShadow];
}];
JNF_COCOA_EXIT(env);
}
NSRect join(NSRect r, NSButton* button) {
NSRect buttonRect = [button convertRect: [button bounds] toView: nil];
return NSUnionRect(r, buttonRect);

31
platform-base/src/main/java/com/github/weisj/darklaf/platform/RoundedFrame.java

@ -0,0 +1,31 @@
/*
* MIT License
*
* Copyright (c) 2024 Jannis Weis
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.github.weisj.darklaf.platform;
import java.awt.*;
public interface RoundedFrame {
int getRadius();
Color getColor();
int getThickness();
}
Loading…
Cancel
Save