Is there a way to get the WindowUtils working on macOS?

315 views
Skip to first unread message

George Grigalashvili

unread,
Apr 26, 2021, 10:27:21 AM4/26/21
to Java Native Access
Hi, 

I was wondering if there's an implementation that would provide the similar feature of getting all open windows on macOS?

I couldn't find anything in the library to achieve this behavior so far. 

User32 user = User32.INSTANCE;
WindowUtils.getAllWindows(true);

Tres Finocchiaro

unread,
Apr 26, 2021, 10:45:15 AM4/26/21
to jna-...@googlegroups.com
While you await an answer, I've done similar tasks on Apple using the painstaking AppleScript.  This is likely the fastest solution, but also the slowest and the most unreliable.


I use a similar technique to bring focus to a Windows in my App.  Here's the code which I've recently added to do this:


(Disclaimer: This uses some classes written by a JNA contributor that  are not part of base JNA)

In regards to ALL windows, you may have to use the Accessibility API.  Apple is trying to stricten the ability for an app to control another.

https://stackoverflow.com/a/6365105/3196753

If possible, I would recommend writing an example in Swift or Objective-C and then working to get the same APIs working in JNA.  JNA's mapping to Apple classes is nowhere as robust as the Win32 stuff, so you'll have to write a lot of your own.


--
You received this message because you are subscribed to the Google Groups "Java Native Access" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jna-users+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jna-users/887d350c-f583-412d-872a-e14da173dffen%40googlegroups.com.

Daniel Widdis

unread,
Apr 26, 2021, 11:08:53 AM4/26/21
to jna-...@googlegroups.com

Yes, there is.  I’ve implemented it here.

 

https://github.com/oshi/oshi/blob/master/oshi-core/src/main/java/oshi/driver/mac/WindowInfo.java

with JNA mappings

https://github.com/oshi/oshi/blob/master/oshi-core/src/main/java/oshi/jna/platform/mac/CoreGraphics.java

 

Haven’t yet submitted this to JNA but will consider it if there’s a desire for it.

--

Durchholz, Joachim

unread,
Apr 26, 2021, 12:04:38 PM4/26/21
to jna-...@googlegroups.com

Hmm... I’d like to see this (and similar stuff) being added to contrib.

Not because I need this particular API but because I can foresee the day when I’ll have to access the Mac port of COM (which is rumored to be available once you have some Office application on the Mac).

 

I have absolutely no idea if that kind of synergy will actually happen though.

 

Regards,

Jo

 

 

Sensitivity: C2 Internal

The content of this e-mail is intended only for the confidential use of the person addressed.
If you are not the intended recipient, please notify the sender and delete this e-mail immediately.
Thank you.

Daniel Widdis

unread,
Apr 26, 2021, 11:18:03 PM4/26/21
to Java Native Access
Well, I took a look at doing this and see a few problems. I'm not sure if I want to build on the current API or deprecate it in favor of a better design.

One issue is that while purporting to be cross-platform, the current API uses the (Windows) HWND type in many places.  Granted, it's just a pointer under the hood, and the meaning is the same, but it seems confusing to interact with macOS code with a HWND type. 

A second issue is the choice of parameters to identify the window. In addition to its HWND, there are Strings for title and path of the executable, but it seems better to include the process ID than the name, to deconflict similar windows.  So they should probably be added.   

The whole WindowsUtil class (and the DesktopWindow class using Rectangle) is heavily dependent on java.awt, which in the modular world introduces a dependency for jna-platform to the java.desktop module.  (Side note:  the build script for the module-info.java class in jna-platform should add "transitive" to the java.desktop requires statement.). While that dependency may be needed, I think from a future-looking perspective and potential attempt to be more module friendly in the future, it might be preferable to segregate java.awt-based code in a different package, another vote for changing the API and deprecating this one.

In short, I can make the macOS code "fit" in the current structure but I think a better design is in order; and I'm not sure I want to put all that effort into a new design.  Anyone else is free to take this on if they'd like, or borrow code from the links I posted earlier.

George Grigalashvili

unread,
Apr 27, 2021, 3:04:53 AM4/27/21
to Java Native Access
Thank you guys for the feedback. 

This feature definitely should be in JNA. I was surprised to see only the Windows features working in the first place. 
The main problem with not having it is that your app immediately becomes Windows platform dependent, which is not desirable in most cases. 

@Daniel I'll give it a try to your implementation. Thank you.


Durchholz, Joachim

unread,
Apr 27, 2021, 4:31:47 AM4/27/21
to jna-...@googlegroups.com

Well, JNA is about accessing C-style APIs which have not been made accessible through the JDK in a platform-independent manner, so that’s the kind of trade-off I’d expect from a FFI like JNA: You lose platform-independence, you gain access to platform-specific APIs (and usually you’ll do some kind of platform awareness at higher levels – you don’t expect DDE to work on Mac so you offer another real-time API, for example).

 

That said, if there’s something in JNA that can be made platform-independent, or merely less platform-dependent, then yes.

I guess progress will be slow though; most developers don’t have both a Windows and a Mac development machine. So I think that independent work on both platforms, with the option of later investigating what can be merged, would be the faster option overall, and the one with earlier successes.

 

On HWND, from the perspective of an old-time GDI user here: It may be a pointer under the hood, but you can’t dereference it and you shouldn’t do calculations with it. Mapping it in Java as an opaque handle type is the right way to do it; if the equivalent Mac abstraction is indeed a pointer, then the types should be different, if it’s a handle as in Windows, then it could be a HWND – though in that case you may want to have a WindowHandle class that would be a HWND on Windows and whatever the right type is on Mac.

I find the litmus test for such things is the question “what if somebody writes a subclass that is a proxy to such a handle on another machine”? With the idea that you can do the same calls remotely as locally. Are the same calls available? If yes, make it the same type, if not, make it a different one. Is there a subset of common calls, preferably one that has a chance of being a valid abstraction? Make a common superclass for the Windows and the Mac type.

That kind of stuff.

Having some common aspect is an indicator that two classes are in fact related, but one shouldn’t unify unless it gives the caller a clear benefit.

 

Regards,

Jo

 

From: jna-...@googlegroups.com <jna-...@googlegroups.com> On Behalf Of George Grigalashvili
Sent: Dienstag, 27. April 2021 09:05
To: Java Native Access <jna-...@googlegroups.com>
Subject: [External Sender] Re: Is there a way to get the WindowUtils working on macOS?

 

Thank you guys for the feedback. 

Timothy Wall

unread,
Apr 27, 2021, 9:10:50 AM4/27/21
to jna-...@googlegroups.com
As a little background, I originally started working on JNA in order to implement transparent windows in Java, and I just happened to know how to do it on OSX, Windows, and X, so the "common" operations were "setWindowTransparency" and "setWindowMask".  Most of the other window operations were added much later and kind of tacked on to the existing minimal infrastructure.  The platforms used to share a common class for native windows via AWT, which is no longer the case.

I agree with D that any platform-specific functions should be using parameters appropriate for the platform.  I'm not sure there's enough commonality in how windows are referenced any longer to warrant a base "WindowID" class.

T.

Daniel Widdis

unread,
Apr 27, 2021, 10:54:21 AM4/27/21
to jna-...@googlegroups.com

The macOS equivalent in this case is a 64-bit integer CFNumber with its type defined as the constant kCGWindowIDCFNumberType.   In my cross-platform implementation I just use a long and document that/how it can be cast to an HWND for Windows as a native pointer peer value.  The X equivalent is an integer property (not sure if 32- or 64- bit) identified as a “Window ID”.  So “WindowID” is an appropriate class/field name, but wrapping a long might be overkill.

 

Note that an intermediate solution that I’ve done is to have my own cross-platform API and in the case of Windows, just call the existing JNA implementation and add my own features to it, thus my suggestion for a new API in JNA.   However, I also focus on an “information” library (think “read only”) so haven’t done the work of trying to implement interactive features like setting transparency, showing windows, etc.  It may be that the CoreGraphics library on macOS might not be the best approach for manipulating windows, however, and the earlier links to AppleScript or Accessibility API might be needed.

 

Dan

Reply all
Reply to author
Forward
0 new messages