Browse Source

Windows: Wrap window pointers to enforce correct checking of NULL pointers

pull/323/head
Jannis Weis 3 years ago
parent
commit
57411d725b
No known key found for this signature in database
GPG Key ID: 7C9D8D4B558049AB
  1. 4
      core/src/test/java/com/github/weisj/darklaf/core/test/PointerUtilTest.java
  2. 33
      windows/src/main/java/com/github/weisj/darklaf/platform/windows/PointerUtil.java
  3. 14
      windows/src/main/java/com/github/weisj/darklaf/platform/windows/WindowsDecorationsProvider.java
  4. 36
      windows/src/main/java/com/github/weisj/darklaf/platform/windows/ui/WindowsTitlePane.java

4
core/src/test/java/com/github/weisj/darklaf/core/test/PointerUtilTest.java

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2019-2021 Jannis Weis
* Copyright (c) 2019-2022 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,
@ -46,7 +46,7 @@ class PointerUtilTest {
Window frame = new JWindow();
frame.setAutoRequestFocus(false);
SwingUtilities.invokeAndWait(() -> frame.setVisible(true));
Assertions.assertEquals(Native.getWindowID(frame), PointerUtil.getHWND(frame));
Assertions.assertEquals(Native.getWindowID(frame), PointerUtil.getHWND(frame).value());
SwingUtilities.invokeLater(() -> {
frame.setVisible(false);
frame.dispose();

33
windows/src/main/java/com/github/weisj/darklaf/platform/windows/PointerUtil.java

@ -21,6 +21,7 @@
package com.github.weisj.darklaf.platform.windows;
import java.awt.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
@ -32,23 +33,45 @@ public final class PointerUtil {
private static final Logger LOGGER = LogUtil.getLogger(PointerUtil.class);
public static class WindowPointer {
private final long hwnd;
public WindowPointer(final long hwnd) {
this.hwnd = hwnd;
}
public boolean isValid() {
return hwnd != 0;
}
public long value() {
return hwnd;
}
@Override
public String toString() {
return String.valueOf(hwnd);
}
}
/**
* Get the window handle for the window the given component descends from.
*
* @param component the component.
* @return the handle.
*/
public static long getHWND(final Component component) {
public static WindowPointer getHWND(final Component component) {
Window window = component instanceof Window
? (Window) component
: SwingUtilities.getWindowAncestor(component);
String javaLibPath = SystemInfo.JAVA_HOME != null
? SystemInfo.JAVA_HOME + "/bin/jawt.dll"
: "jawt.dll";
long hwnd = JNIDecorationsWindows.getWindowHWND(window, javaLibPath);
if (hwnd < 0) {
LOGGER.severe("Couldn't get HWND of window (errorCode =" + hwnd + ")." + component);
try {
return new WindowPointer(JNIDecorationsWindows.getWindowHWND(window, javaLibPath));
} catch (Exception e) {
LOGGER.log(Level.SEVERE, "Couldn't get HWND of window " + component, e);
return new WindowPointer(0);
}
return hwnd;
}
}

14
windows/src/main/java/com/github/weisj/darklaf/platform/windows/WindowsDecorationsProvider.java

@ -59,14 +59,14 @@ public class WindowsDecorationsProvider implements DecorationsProvider {
if (!window.isDisplayable()) {
window.addNotify();
}
long hwnd = PointerUtil.getHWND(window);
if (hwnd > 0) {
JNIDecorationsWindows.installPopupMenuDecorations(hwnd);
PointerUtil.WindowPointer hwnd = PointerUtil.getHWND(window);
if (hwnd.isValid()) {
JNIDecorationsWindows.installPopupMenuDecorations(hwnd.value());
if (window instanceof RootPaneContainer) {
JRootPane rootPane = ((RootPaneContainer) window).getRootPane();
Color bg = rootPane != null ? rootPane.getBackground() : null;
if (bg != null) {
JNIDecorationsWindows.setBackground(hwnd, bg.getRed(), bg.getGreen(), bg.getBlue());
JNIDecorationsWindows.setBackground(hwnd.value(), bg.getRed(), bg.getGreen(), bg.getBlue());
}
}
}
@ -75,9 +75,9 @@ public class WindowsDecorationsProvider implements DecorationsProvider {
@Override
public void uninstallPopupWindow(final Window window) {
if (window.isDisplayable()) {
long hwnd = PointerUtil.getHWND(window);
if (hwnd != 0) {
JNIDecorationsWindows.uninstallDecorations(hwnd, false);
PointerUtil.WindowPointer hwnd = PointerUtil.getHWND(window);
if (hwnd.isValid()) {
JNIDecorationsWindows.uninstallDecorations(hwnd.value(), false);
}
window.dispose();
}

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

@ -94,7 +94,7 @@ public class WindowsTitlePane extends CustomTitlePane {
private Action minimizeAction;
private JLabel titleLabel;
private final Window window;
private long windowHandle;
private PointerUtil.WindowPointer windowHandle = new PointerUtil.WindowPointer(0);
private int state;
private Color inactiveBackground;
@ -190,11 +190,11 @@ public class WindowsTitlePane extends CustomTitlePane {
}
protected void uninstallDecorations(final boolean removeDecorations) {
if (windowHandle != 0) {
if (windowHandle.isValid()) {
if (removeDecorations) {
JNIDecorationsWindows.uninstallDecorations(windowHandle, decorationStyle != JRootPane.NONE);
JNIDecorationsWindows.uninstallDecorations(windowHandle.value(), decorationStyle != JRootPane.NONE);
}
windowHandle = 0;
windowHandle = new PointerUtil.WindowPointer(0);
}
}
@ -224,9 +224,9 @@ public class WindowsTitlePane extends CustomTitlePane {
@Override
public void setDecorationsStyle(final int style) {
super.setDecorationsStyle(style);
if (style == JRootPane.NONE && windowHandle != 0) {
if (style == JRootPane.NONE && windowHandle.isValid()) {
uninstall(true);
} else if (windowHandle == 0) {
} else if (!windowHandle.isValid()) {
install();
}
}
@ -236,14 +236,15 @@ public class WindowsTitlePane extends CustomTitlePane {
if (!window.isDisplayable()) return false;
if (window instanceof Dialog || window instanceof Frame) {
windowHandle = PointerUtil.getHWND(window);
if (windowHandle > 0) {
if (windowHandle.isValid()) {
LOGGER.fine("Installing decorations for window " + windowHandle);
if (!JNIDecorationsWindows.installDecorations(windowHandle)) {
if (!JNIDecorationsWindows.installDecorations(windowHandle.value())) {
LOGGER.fine("Already installed.");
}
updateResizeBehaviour();
Color color = rootPane.getBackground();
JNIDecorationsWindows.setBackground(windowHandle, color.getRed(), color.getGreen(), color.getBlue());
JNIDecorationsWindows.setBackground(windowHandle.value(), color.getRed(), color.getGreen(),
color.getBlue());
} else {
uninstall(decorationStyle != JRootPane.NONE);
return false;
@ -411,15 +412,15 @@ public class WindowsTitlePane extends CustomTitlePane {
}
private void minimize() {
JNIDecorationsWindows.minimize(windowHandle);
JNIDecorationsWindows.minimize(windowHandle.value());
}
private void maximize() {
JNIDecorationsWindows.maximize(windowHandle);
JNIDecorationsWindows.maximize(windowHandle.value());
}
private void restore() {
JNIDecorationsWindows.restore(windowHandle);
JNIDecorationsWindows.restore(windowHandle.value());
}
private void createActions() {
@ -533,7 +534,7 @@ public class WindowsTitlePane extends CustomTitlePane {
boolean res = isResizable();
if (oldResizable != res) {
oldResizable = res;
JNIDecorationsWindows.setResizable(windowHandle, res);
JNIDecorationsWindows.setResizable(windowHandle.value(), res);
}
}
@ -769,7 +770,7 @@ public class WindowsTitlePane extends CustomTitlePane {
// of the menubar.
boolean emptyMenuBar = menuBarStealer.isMenuBarEmpty();
boolean emptyContent = getDecorationStyle() == JRootPane.NONE && emptyMenuBar && title.length() == 0;
return windowHandle == 0
return !windowHandle.isValid()
|| emptyContent
|| (menuBarStealer.hasMenuBar() && !menuBarStealer.getMenuBar().isVisible());
}
@ -823,7 +824,7 @@ public class WindowsTitlePane extends CustomTitlePane {
}
protected void updateDragArea(final GraphicsConfiguration gc) {
JNIDecorationsWindows.updateValues(windowHandle,
JNIDecorationsWindows.updateValues(windowHandle.value(),
(int) Scale.scaleWidth(left, gc), (int) Scale.scaleWidth(right, gc),
(int) Scale.scaleHeight(height, gc), (int) Scale.scaleHeight(BUTTON_WIDTH, gc));
}
@ -945,7 +946,7 @@ public class WindowsTitlePane extends CustomTitlePane {
setState(frame.getExtendedState(), true);
}
if (KEY_RESIZABLE.equals(name)) {
JNIDecorationsWindows.setResizable(windowHandle, Boolean.TRUE.equals(pce.getNewValue()));
JNIDecorationsWindows.setResizable(windowHandle.value(), Boolean.TRUE.equals(pce.getNewValue()));
getRootPane().repaint();
}
} else if (PropertyKey.TITLE.equals(name)) {
@ -962,7 +963,8 @@ public class WindowsTitlePane extends CustomTitlePane {
} else if (PropertyKey.BACKGROUND.equals(name) && pce.getNewValue() instanceof Color) {
Color color = (Color) pce.getNewValue();
if (color == null) return;
JNIDecorationsWindows.setBackground(windowHandle, color.getRed(), color.getGreen(), color.getBlue());
JNIDecorationsWindows.setBackground(windowHandle.value(), color.getRed(), color.getGreen(),
color.getBlue());
}
}
}

Loading…
Cancel
Save