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

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

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

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

@ -303,6 +303,28 @@ bool InstallDecorations(HWND handle, bool is_popup) {
return true; 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 // @formatter:off
LRESULT CALLBACK WindowWrapper::WindowProc(_In_ HWND hwnd, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam) { LRESULT CALLBACK WindowWrapper::WindowProc(_In_ HWND hwnd, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam) {
HWND handle = reinterpret_cast<HWND>(hwnd); HWND handle = reinterpret_cast<HWND>(hwnd);
@ -402,11 +424,11 @@ Java_com_github_weisj_darklaf_platform_windows_JNIDecorationsWindows_installDeco
} }
JNIEXPORT void JNICALL 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); HWND handle = reinterpret_cast<HWND>(hwnd);
auto wrap = wrapper_map[handle]; auto wrap = wrapper_map[handle];
if (wrap) { if (wrap) {
SetWindowLongPtr(handle, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(wrap->prev_proc)); UninstallDecorations(wrap, decorated);
wrapper_map.erase(handle); wrapper_map.erase(handle);
delete (wrap); 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 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); 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()) { if (window.isDisplayable()) {
long hwnd = PointerUtil.getHWND(window); long hwnd = PointerUtil.getHWND(window);
if (hwnd != 0) { if (hwnd != 0) {
JNIDecorationsWindows.uninstallDecorations(hwnd); JNIDecorationsWindows.uninstallDecorations(hwnd, false);
} }
window.dispose(); 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.rootPane = root;
this.window = window; this.window = window;
bundle = ResourceBundle.getBundle("com.github.weisj.darklaf.bundles.actions", getLocale()); bundle = ResourceBundle.getBundle("com.github.weisj.darklaf.bundles.actions", getLocale());
setDecorationsStyle(decorationStyle); this.decorationStyle = decorationStyle;
rootPane.addContainerListener(rootPaneContainerListener); rootPane.addContainerListener(rootPaneContainerListener);
rootPane.getLayeredPane().addContainerListener(layeredPaneContainerListener); rootPane.getLayeredPane().addContainerListener(layeredPaneContainerListener);
state = -1; state = -1;
@ -194,7 +194,7 @@ public class WindowsTitlePane extends CustomTitlePane {
protected void uninstallDecorations() { protected void uninstallDecorations() {
if (windowHandle != 0) { if (windowHandle != 0) {
JNIDecorationsWindows.uninstallDecorations(windowHandle); JNIDecorationsWindows.uninstallDecorations(windowHandle, decorationStyle != JRootPane.NONE);
windowHandle = 0; windowHandle = 0;
} }
rootPane.removeContainerListener(rootPaneContainerListener); 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() { private boolean installDecorations() {
if (getDecorationStyle() == JRootPane.NONE) return false;
if (!window.isDisplayable()) return false;
if (window instanceof Dialog || window instanceof Frame) { if (window instanceof Dialog || window instanceof Frame) {
windowHandle = PointerUtil.getHWND(window); windowHandle = PointerUtil.getHWND(window);
if (windowHandle != 0) { if (windowHandle != 0) {

Loading…
Cancel
Save