Looking for implementation advice from someone familiar with the internal workings of JWM <-> HumbleUI;
I'd like to "bring a window to top" in Windows, including stealing application focus if another application is on top. There is an existing implementation of window/set-visible, but it only works if the HumbleUI application already has toplevel OS focus.
src - https://github.com/HumbleUI/HumbleUI/blob/main/src/io/github/humbleui/window.clj#L128
----------
To get the behavior I want, I expect to add a function to humbleui.window.
It'll assumedly call into https://github.com/HumbleUI/JWM/blob/main/windows/cc/WindowWin32.cc ; probably jwm::WindowWin32::focus()
If ::focus() doesn't work, then I'll add a new method with some magic win API incantations (ref https://stackoverflow.com/questions/916259/win32-bring-a-window-to-top )
-----------
Does the above plan track? Anything I should try or do differently?
Latest commit adds the feature on Windows via abuse of the AttachThreadInput. It ain't pretty but it works; lets my app popup from the background via alt+space trigger (think launcher program behavior)
Working snippet based off the latest commit --
(defn toggle-open!
[]
(let [$window @*window
foreground-hwnd (.getForegroundWindow $window)
app-in-foreground? (= (.getWindowThreadProcessId $window foreground-hwnd)
(.getCurrentThreadId $window))]
(log/debug (or (and app-in-foreground? "Toggling app to closed state")
"Toggling app to open state!"))
(window/set-visible $window (not app-in-foreground?))
(when-not app-in-foreground?
(window/steal-focus $window)
(window/restore $window)
(window/focus $window))))Tried some approaches but couldn't get .focus() to do OS level "steal focused app" behavior. I'm falling back to my second plan; update JWM with the magic SendMessage WinAPI calls that will produce the correct behavior. Now reading over JWM code to understand structure & how to compile a local .jar
--------
Some context: I'm building a 'native' desktop app in Clojure. I've written versions in ClojureFX and Membrane but the code / architecture felt complex & unpleasant.
HumbleUI has felt the best so far; responsibilities are decomplected in an understandable way. CljFX is comparatively a hot mess. Membrane has some really cool ideas but it's also immature with hard-to-understand src.
Given the pre-alpha release state of HumbleUI, I expect this will be a rocky path. Even then, it still seems the best option for a homegrown Clojure desktop app in 2023.
Let me know if you have any questions!
Took a while to grok JWM but some progress. https://github.com/HumbleUI/JWM/pull/266
I need to add another commit; though it's nasty, using AttachThreadInput of the JWM thread onto the Windows foreground thread is looking like the only way to correctly steal application focus
setVisible is only for hiding/unhiding window
As I understand it
Window.java has .focus(), just add it to the window.clj
I’m not sure if it’s working under Windows, but theoretically that’s where that code should go
.focus() is probably it -- I'll check this out until it's working on my local machine and raise a small PR if appropriate