You're welcome to use whatever method you wish, but there are good reasons not to leap straight into using other tools as a workaround for something. For one, other forum users will come by this post one day and it'll be benefit most people not only to see how the problems we encountered were solved, but also that it was solved and allows them to utilise the solution without third-party tools that they might not have nor might not wish to install. Secondly, debugging a solution that uses a number of different technologies is harder. Lastly, having a solution that is self-contained from beginning-to-end will usually (but not always) be the most performant.
My original contribution when I came across this post was simply to highlight a C API that enumerates windows regardless of which desktop (space) they are on. I later expanded this into a JXA function as the API call returns an excess of information (most of which is useless to most people), and of a data type a lot of people wouldn't know what to do with.
It wasn't intended to solve the exact problem you put forward, but I also knew (or was very confident in my belief) that there was no other means (that doesn't require installation of third-party tools) of obtaining window data for windows that weren't on the currently-active desktop. As far as I know, this remains to be true, and if anything, more so today than it was as Apple continues to tighten its security protocols.
I knew there was something off last time I replied. I couldn't put my finger on it, or must have been half asleep, but the fact that you're getting a data dump at all was all we needed. When I started to explain about data types and casting, etc., I was sort of doing this on autopilot, partly because what I was writing holds true when thinking about the problem in the context of my own system. On Monterey, this:
ObjC.import('CoreGraphics');
$.CGWindowListCopyWindowInfo(16, 0);
returns an opaque [Object Ref]
that subsequently needs to passed to ObjC.castRefToObject()
in order to get the "data dump" that you were already getting without this. This is obviously what changed between Mojave/Catalina and later version of macOS.
Therefore, the solution is simply to remove the call to ObjC.castRefToObject()
so that this line:
return ObjC.deepUnwrap( ObjC.castRefToObject(
$.CGWindowListCopyWindowInfo(16, 0) )).filter(e =>
is now simply this:
return ObjC.deepUnwrap($.CGWindowListCopyWindowInfo(16, 0)).filter(e =>
The rest is just regular JavaScript, so can be left alone.
I'm such an idiot.