Browse Source

Properly handle toggling decorations on Windows.

pull/187/head
weisj 4 years ago
parent
commit
8e363503c4
  1. 6
      core/src/main/java/com/github/weisj/darklaf/ui/rootpane/DarkRootPaneUI.java
  2. 6
      core/src/test/java/ui/ComponentDemo.java
  3. 26
      windows/src/main/cpp/Decorations.cpp
  4. 2
      windows/src/main/java/com/github/weisj/darklaf/platform/windows/JNIDecorationsWindows.java
  5. 2
      windows/src/main/java/com/github/weisj/darklaf/platform/windows/WindowsDecorationsProvider.java
  6. 16
      windows/src/main/java/com/github/weisj/darklaf/platform/windows/ui/WindowsTitlePane.java

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

@ -103,14 +103,15 @@ public class DarkRootPaneUI extends BasicRootPaneUI implements HierarchyListener
public void propertyChange(final PropertyChangeEvent e) {
super.propertyChange(e);
String propertyName = e.getPropertyName();
if (PropertyKey.ANCESTOR.equals(propertyName)) {
if (PropertyKey.ANCESTOR.equals(propertyName) || KEY_NO_DECORATIONS.equals(propertyName)) {
updateWindow(rootPane.getParent());
}
}
protected int decorationsStyleFromWindow(final Window window, final int windowDecorationsStyle) {
if (DarkUIUtil.isUndecorated(window)
|| PropertyUtil.getBooleanProperty(rootPane, KEY_NO_DECORATIONS)) return JRootPane.NONE;
if (windowDecorationsStyle != JRootPane.NONE) return windowDecorationsStyle;
if (DarkUIUtil.isUndecorated(window)) return JRootPane.NONE;
if (window instanceof JFrame) return JRootPane.FRAME;
if (window instanceof JDialog) return JRootPane.PLAIN_DIALOG;
return windowDecorationsStyle;
@ -183,6 +184,7 @@ public class DarkRootPaneUI extends BasicRootPaneUI implements HierarchyListener
private void updateWindow(final Component parent) {
window = DarkUIUtil.getWindow(parent);
windowDecorationsStyle = decorationsStyleFromWindow(window, windowDecorationsStyle);
if (titlePane != null) titlePane.setDecorationsStyle(windowDecorationsStyle);
installBorder(rootPane);
}

6
core/src/test/java/ui/ComponentDemo.java

@ -206,6 +206,12 @@ public interface ComponentDemo {
dev.add(logging);
dev.add(aaPainting);
dev.add(experimentalAA);
dev.add(new JCheckBoxMenuItem("Custom Decorations") {
{
setSelected(LafManager.isDecorationsEnabled());
addActionListener(e -> LafManager.setDecorationsEnabled(isSelected()));
}
});
return dev;
}

26
windows/src/main/cpp/Decorations.cpp

@ -303,6 +303,28 @@ bool InstallDecorations(HWND handle, bool is_popup) {
return true;
}
void UninstallDecorations(WindowWrapper *wrapper, bool decorated) {
HWND handle = wrapper->window;
// Restore old window procedure.
SetWindowLongPtr(handle, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(wrapper->prev_proc));
// Restore old client area.
MARGINS margins = { 0, 0, 0, 0 };
DwmExtendFrameIntoClientArea(handle, &margins);
auto style = GetWindowLongPtr(handle, GWL_STYLE);
if (!decorated) {
style &= ~WS_THICKFRAME;
} else {
style |= WS_THICKFRAME;
}
SetWindowLongPtr(handle, GWL_STYLE, style);
UINT flags = SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED;
SetWindowPos(handle, NULL, 0, 0, 0, 0, flags);
}
// @formatter:off
LRESULT CALLBACK WindowWrapper::WindowProc(_In_ HWND hwnd, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam) {
HWND handle = reinterpret_cast<HWND>(hwnd);
@ -402,11 +424,11 @@ Java_com_github_weisj_darklaf_platform_windows_JNIDecorationsWindows_installDeco
}
JNIEXPORT void JNICALL
Java_com_github_weisj_darklaf_platform_windows_JNIDecorationsWindows_uninstallDecorations(JNIEnv *env, jclass obj, jlong hwnd) {
Java_com_github_weisj_darklaf_platform_windows_JNIDecorationsWindows_uninstallDecorations(JNIEnv *env, jclass obj, jlong hwnd, jboolean decorated) {
HWND handle = reinterpret_cast<HWND>(hwnd);
auto wrap = wrapper_map[handle];
if (wrap) {
SetWindowLongPtr(handle, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(wrap->prev_proc));
UninstallDecorations(wrap, decorated);
wrapper_map.erase(handle);
delete (wrap);
}

2
windows/src/main/java/com/github/weisj/darklaf/platform/windows/JNIDecorationsWindows.java

@ -43,7 +43,7 @@ public class JNIDecorationsWindows {
public static native boolean installDecorations(final long hwnd);
public static native void uninstallDecorations(final long hwnd);
public static native void uninstallDecorations(final long hwnd, final boolean decorated);
public static native boolean installPopupMenuDecorations(final long hwnd);
}

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

@ -76,7 +76,7 @@ public class WindowsDecorationsProvider implements DecorationsProvider {
if (window.isDisplayable()) {
long hwnd = PointerUtil.getHWND(window);
if (hwnd != 0) {
JNIDecorationsWindows.uninstallDecorations(hwnd);
JNIDecorationsWindows.uninstallDecorations(hwnd, false);
}
window.dispose();
}

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

@ -130,7 +130,7 @@ public class WindowsTitlePane extends CustomTitlePane {
this.rootPane = root;
this.window = window;
bundle = ResourceBundle.getBundle("com.github.weisj.darklaf.bundles.actions", getLocale());
setDecorationsStyle(decorationStyle);
this.decorationStyle = decorationStyle;
rootPane.addContainerListener(rootPaneContainerListener);
rootPane.getLayeredPane().addContainerListener(layeredPaneContainerListener);
state = -1;
@ -194,7 +194,7 @@ public class WindowsTitlePane extends CustomTitlePane {
protected void uninstallDecorations() {
if (windowHandle != 0) {
JNIDecorationsWindows.uninstallDecorations(windowHandle);
JNIDecorationsWindows.uninstallDecorations(windowHandle, decorationStyle != JRootPane.NONE);
windowHandle = 0;
}
rootPane.removeContainerListener(rootPaneContainerListener);
@ -224,7 +224,19 @@ public class WindowsTitlePane extends CustomTitlePane {
}
}
@Override
public void setDecorationsStyle(final int style) {
super.setDecorationsStyle(style);
if (style == JRootPane.NONE && windowHandle != 0) {
uninstall();
} else if (windowHandle == 0) {
install();
}
}
private boolean installDecorations() {
if (getDecorationStyle() == JRootPane.NONE) return false;
if (!window.isDisplayable()) return false;
if (window instanceof Dialog || window instanceof Frame) {
windowHandle = PointerUtil.getHWND(window);
if (windowHandle != 0) {

Loading…
Cancel
Save