diff --git a/README.md b/README.md index 7f69a650..30735f32 100644 --- a/README.md +++ b/README.md @@ -133,6 +133,8 @@ Alpha. Expect API breakages. | setMinimumSize | ❌ | ❌ | ❌ | | setMaximumSize | ❌ | ❌ | ❌ | | setResizable | ❌ | ❌ | ❌ | +| bringToFront | ✅ | ❌ | ❌ | +| isFront | ✅ | ✅ | ❌ | ### Events @@ -226,6 +228,35 @@ Run examples without building (use version from the table above): ./script/run.py --jwm-version ``` +### Local JAR + +Generate & install a local .jar file: + +``` +./script/install.py +``` + +This outputs `target/jwm-0.0.0-SNAPSHOT.jar` for use in testing (e.g. `io.github.humbleui/jwm {:local/root "..."}` if using deps.edn) + +### MacOS + +Before running the build, ensure you've installed: +* XCode Developer Tools (`xcode-select --install`) +* Ninja (`brew install ninja`) +* Python 3 (`brew install python`) + +### Debugging + +Set `JWM_VERBOSE` in process env to see extra log output when running locally. + +``` bash +# Mac / Linux +export JWM_VERBOSE=true + +# Windows +set JWM_VERBOSE=true +``` + # Contributing PRs & issue reports are welcome! diff --git a/examples/dashboard/java/PanelScreens.java b/examples/dashboard/java/PanelScreens.java index 378f8ef3..aff2a92c 100644 --- a/examples/dashboard/java/PanelScreens.java +++ b/examples/dashboard/java/PanelScreens.java @@ -20,6 +20,8 @@ public PanelScreens(Window window) { titleStyles = new Options("Default", "Hidden", "Transparent", "Unified", "Unified Compact", "Unified Transparent", "Unified Compact Transparent"); } else if (Platform.X11 == Platform.CURRENT) { titleStyles = new Options("Default", "Hidden"); + } else if (Platform.WINDOWS == Platform.CURRENT) { + titleStyles = new Options("Default", "Hidden"); } } @@ -66,6 +68,14 @@ public void setTitleStyle(String style) { case "Hidden" -> w.setTitlebarVisible(false); } + } else if (Platform.WINDOWS == Platform.CURRENT) { + WindowWin32 w = (WindowWin32) window; + switch (style) { + case "Default" -> + w.setTitlebarVisible(true); + case "Hidden" -> + w.setTitlebarVisible(false); + } } } diff --git a/windows/cc/WindowWin32.cc b/windows/cc/WindowWin32.cc index 36937e7d..fcc3af6c 100644 --- a/windows/cc/WindowWin32.cc +++ b/windows/cc/WindowWin32.cc @@ -70,6 +70,19 @@ void jwm::WindowWin32::setTitle(const std::wstring& title) { SetWindowTextW(_hWnd, title.c_str()); } +void jwm::WindowWin32::setTitlebarVisible(bool isVisible) { + JWM_VERBOSE("Set titlebar visible=" << isVisible << " for window 0x" << this); + if (isVisible == true) { + LONG_PTR lStyle = GetWindowLongPtr(_hWnd, GWL_STYLE); + lStyle |= (WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU); + SetWindowLongPtr(_hWnd, GWL_STYLE, lStyle); + } else { + LONG_PTR lStyle = GetWindowLongPtr(_hWnd, GWL_STYLE); + lStyle &= ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU); + SetWindowLongPtr(_hWnd, GWL_STYLE, lStyle); + } +} + void jwm::WindowWin32::setIcon(const std::wstring& iconPath) { JWM_VERBOSE("Set window icon '" << iconPath << "'"); // width / height of 0 along with LR_DEFAULTSIZE tells windows to load the default icon size. @@ -656,6 +669,15 @@ LRESULT jwm::WindowWin32::processEvent(UINT uMsg, WPARAM wParam, LPARAM lParam) dispatch(classes::EventWindowFocusOut::kInstance); break; + case WM_STYLECHANGED: { + IRect rect = getWindowRect(); + int windowWidth = rect.getWidth(); + int windowHeight = rect.getHeight(); + JWM_VERBOSE("StyleChanged event" + << "window w=" << windowWidth << " h=" << windowHeight); + setContentSize(windowWidth, windowHeight); + return 0; + } case WM_CLOSE: JWM_VERBOSE("Event close"); @@ -1013,6 +1035,12 @@ extern "C" JNIEXPORT void JNICALL Java_io_github_humbleui_jwm_WindowWin32__1nSet env->ReleaseStringChars(title, titleStr); } +extern "C" JNIEXPORT void JNICALL Java_io_github_humbleui_jwm_WindowWin32__1nSetTitlebarVisible + (JNIEnv* env, jobject obj, jboolean isVisible) { + jwm::WindowWin32* instance = reinterpret_cast(jwm::classes::Native::fromJava(env, obj)); + instance->setTitlebarVisible(isVisible); +} + extern "C" JNIEXPORT void JNICALL Java_io_github_humbleui_jwm_WindowWin32__1nSetIcon (JNIEnv* env, jobject obj, jstring iconPath) { jwm::WindowWin32* instance = reinterpret_cast(jwm::classes::Native::fromJava(env, obj)); diff --git a/windows/cc/WindowWin32.hh b/windows/cc/WindowWin32.hh index f5ca97e2..4b3a91b3 100644 --- a/windows/cc/WindowWin32.hh +++ b/windows/cc/WindowWin32.hh @@ -51,6 +51,7 @@ namespace jwm { void unmarkText(); void setImeEnabled(bool enabled); void setTitle(const std::wstring& title); + void setTitlebarVisible(bool isVisible); void setIcon(const std::wstring& iconPath); void setOpacity(float opacity); float getOpacity(); diff --git a/windows/java/WindowWin32.java b/windows/java/WindowWin32.java index 1379268e..5548c638 100644 --- a/windows/java/WindowWin32.java +++ b/windows/java/WindowWin32.java @@ -68,7 +68,6 @@ public Window setTitle(String title) { return this; } - @Override public Window setIcon(File icon){ assert _onUIThread() : "Should be run on UI thread"; @@ -78,7 +77,9 @@ public Window setIcon(File icon){ @Override public Window setTitlebarVisible(boolean value) { - throw new UnsupportedOperationException("impl me!"); + assert _onUIThread(); + _nSetTitlebarVisible(value); + return this; } @Override @@ -225,6 +226,7 @@ public Window winSetParent(long hwnd) { @ApiStatus.Internal public native void _nSetWindowSize(int width, int height); @ApiStatus.Internal public native void _nSetContentSize(int width, int height); @ApiStatus.Internal public native void _nSetTitle(String title); + @ApiStatus.Internal public native void _nSetTitlebarVisible(boolean isVisible); @ApiStatus.Internal public native void _nSetIcon(String iconPath); @ApiStatus.Internal public native void _nSetVisible(boolean isVisible); @ApiStatus.Internal public native void _nSetOpacity(float opacity);