Is it Possible to Identify the *Second* Window in a Desktop/Space When it is in a Different Application from the frontmost App?

EVERYTHING that I have found, both here in the KBM Forum and in Stack Exchange / Ask Different, when it comes to identifying the second window, not the frontmost window, seems to always be about people wanting to find windows in the same app. Asking about different apps seems to not cross people's minds.

But I have a situation where I want to be able to find the second window on the screen, regardless of whether it is in the same app or not. In fact, it can be pretty much guaranteed to be in a different app or I would not be asking the question.

Right now I have two kludgy workarounds:

  • Kludge One: Close the DeskSpaceID window. Identify what the frontmost app and window are now. Reopen and reposition the DeskSpaceID window. Reactivate the identified frontmost app and window.

  • Kludge Two: Click at the center of the screen to activate whatever is there, because I happen to know that the front window that I created is in the corner and does not occupy the center of the screen.

Neither of the above are truely satisfactory.

Any ideas?

That's the generic question. My specific use is that I am using windows from my DeskSpaceID app, a clone of TextEdit, to name Desktop Spaces and be able to switch between Spaces by their names. When I get to the new Desktop, the ID Window is, of course, active. I want to activate the second window on the desktop, the one that would have been active if I had changed desktops some other way than by activating the DeskSpaceID app window there.

There are various threads, here and in Stack Exchange, answering the question, "How Do I Move the Frontmost Window to the Back?", and all the working solutions only apply to windows of the same app, not interleaved windows of different apps, which is, of course, my situation.

Obviously the OS Window Manager knows what order the windows are stacked in. Is there a way to get it to tell us what that is?

2 Likes

What you call "the OS Window Manager" used to be X11 but now is Quartz, I believe. I recall that X11 had a command line utility in macOS that had a wide host of parameters for "doing things with windows." I presume Quartz has similar functionality. I tinkered with that command (in X11) about 30 years ago. I'm trying to find the equivalent command name for window management in Quartz right now.

After 10 minutes of googling, I think I found the Quartz window manager software. It's called quartz-wm. Here's the home page for that software. If I understand correctly, and I'm not sure I do, this is the open source software that Apple uses for macOS, and I'm still looking for it in Apple's macOS and/or Apple's Xcode, but it's probably just as good if you download it yourself from this site:

https://ports.macports.org/port/quartz-wm/

When I reached this page, and I saw that command with all those options for modifying the screen and its windows, I think we're on the right track.

https://www.manpagez.com/man/1/Xserver/

But I think the command for manipulating windows ends in "-wm" and I haven't found that yet. If my memory is correct, there are options in that command for moving windows forward and backward. This is what you are asking for.

I just found a thread on StackExchange which asks and answers a similar question that you have. But they are talking about other utilities, and I still haven't given up searching for a built-in macOS command.

1 Like

Thanks! You're heading in a direction that I have no familiarity with, but does sound like it could be fruitful.

XQuartz used to be installed by default on macOS until v10.8, at which time Apple removed it, but many people still like to install it, and some people need to install it because some apps require it.

I found a page online which describes the actual command I was using about 30 years ago to examine and modify windows positions (X/Y/W/H, not Z-layers.)

I tinkered with many of the commands in this chapter (30 years ago.) I really can't remember if my tinkering included windows layering or not, which is what you are after.

I think I just found the commands and parameters for determining window layers in Chapter 7, (use the navigation button on the page above to go back to Chapter 7) using a command called xlswins. I'm not sure if that command is just for reading the window order or if it can also let you change the window order. But the point is that I think this is how macOS itself processes windows, and therefore you should be able to access the same capabilities. I suspect that macOS no longer requires these utilities because it has incorporated all of the open source code into macOS directly. But these utilties are still, I believe, fully compatible and more or less equal to what macOS can do. So you may get your answers there.

You're trying to manipulate Finder windows, right? You can do that with Applescript, e.g. tell app "Finder" to set bounds of window 1 to {100,100,1000,1000}

Does this help?

No.

I can set the bounds of an app window, in most cases, but that isn't what I'm trying to do.

I need to know which app is behind the frontmost app. I have no idea whether the second app in the Desktop is Finder, TextEdit, Notes, Typora, Books, Pages, Terminal, Chrome, Keyboard Maestro, Vim, Script Editor, Xcode, or what. I want to determine what it is so that I can bring it to the front, right where it is.

Well, you can do that with the token %Application%2% but I don't think that's what you're after. The "second window" might be from the same application as the front window, right?

1 Like

Exactly. Thanks for distilling it down to the essence.

In my specific case, that's probably my answer [Oops, I spoke too soon. See below.] because I have just opened the front window and I want it to not eclipse whatever was already there, and it's pretty much guaranteed in my case to not have more than one window from the same app.

However, as you point out, the more general question becomes: Which is in front of the other, %Window%2% or %Application%2%, the second window of the front app or the front window of the second app? That's what is immediately behind the front window and will be what appears on top when the front window is closed or minimized.

Oops. No. When I look at %Application%1%, %Application%2%, %Application%3%, and %Application%4%, right after I change the Desktop/Space by activating/opening a file in %Application%1%, the other three apps are not the apps stacked on that Desktop, they are the apps that I was using in the previous Desktop.

Sometimes, like with Finder and Chrome, there's repetition that confuses the issue and makes it appear that activating %Application%2% works, but for apps like Keyboard Maestro and Script Editor, it's pretty clear what's happening.

As for how to actually open the app by the token, I had some difficulty with that. What seems to work is to Open %ApplicationPath%2% with its Default app. But that's moot when it's not the app I actually want.

If I figure out how to tell what Desktop/Space an app is in, without having to open it there to find out, then I could just step through the various %Application%N% tokens until I found an app that's in the current Desktop. But that's one of he APIs that Apple removed somewhere around OS 10;6.

My hunch is that %Application%2% works fine if you're doing everthing on one Desktop, but that's not my issue.

Okay, here's another approach. Build a "stack" variable, a dictionary with 2 or 3 entries. Any time focus changes push the new app and window name onto the stack and "pop" the oldest entry off.

I like your "outside the box" thinking. It's giving me ideas. But I'm sure he'll say something like "tabs in a browser result in a different window title even though it's the same application and window."

The macOS GUI goes to great extents to hide certain parts of the GUI from apps like KM, which is why I think he needs to dig deeper and read the chapter in the book I cited which seems to be the basis upon which the macOS GUI is built.

I like this idea for the generic solution, but it seems complicated to implement for the level of annoyance that I'm trying to smooth over with this question. I would have to have a different stack for each Desktop in order to determine the most recent app on that Desktop rather than the most recent app in any Desktop, which is what %Application%2%, etc. get me. That's doable, but, as I said, complicated.

OTOH, I've been thinking about pushing and popping things in stacks lately, because I've been thinking that it would be "handy" to be able to list Desktops in Most Recently Used order. Unfortunately, the system/app list of Most Recent does not do the job, it just lists the Desktops in the order in which I first visited them after a reboot. Then the order is stagnant.

What I described in the OP as "Kluge One" started as an attempt to deal with that, because the Most Recent list is "most recently opened, not accessed, so I was trying to stack that list by closing and reopening my Desktop Workspace ID Window for each Desktop on each visit. But they don't reopen at the original position, so I have to move them, which even if automated as fast as I can do with AppleScript instead of KBM, there's still a flicker of a window in the "wrong" place. So I've been ignoring the Most Recent problem, for now.

IF I revisit the Most Recent problem and create a stack for the history, and then if I feel facil with pushing, popping, and shuffling stacks, I might go ahead and do this, at least for my most frequently used Desktops.

Thanks for helping me explore the possibilities.

Ugh, sorry I completely forgot about the desktop/spaces complication. I stopped using Spaces a long time ago and I've been smiling ever since. Good luck!

This thread and many others of mine are about my building tools to support my own (over-) use of Spaces. I currently have 45 Spaces created, of which usually about 20 to 24 are actually active. I decided to leave the other 20 existing so that I could have them when I want them (making more requires connecting a second monitor) and as a "stretch goal" in my tool building. For example, I display them in a 9x5 grid of icons which I might not have figured out if I had fewer, and I really like where that part of the design is going as a tool built out of fundamental MacOS parts.

Haven't read the entire thread, so perhaps you've obtained a solution already. If not, the JXA (JavaScript for Automation) code snippet below should—barring any idiosyncratic anomalies depending on the specific version of macOS you're using—return an array of strings, where each string has the following format:

"[${z-index}|${application-name}|${window-id}]${window-title}"
  • ${z-index}: the 1-based array index of the string item.
  • ${application-name}: the name of the application to which the window belongs. This may or may not have ".app" affixed at the end.
  • ${window-id}: the ID number of the window. This is a unique, persistent value assigned for the lifetime of the window. If the app is (Apple)scriptable, this value will typically match the value stored by the id property of the equivalent window class object belonging to the AppleScript application element representing the scriptable app.
  • ${window-title}: the title of the window. If the window has a titlebar, this is what will be displayed. However, a window without a titlebar will often still have a title.

Each of these strings pertains to a single, on-screen window. For example, from the array returned for me, the following string (excluding the bold/italicised formatting) represents the window into which I am currently typing:

"[2|Arc|1937]Is it Possible to Identify the *Second* Window in a Desktop/Space When it is in a Different Application from the frontmost App? - Questions & Suggestions - Keyboard Maestro Discourse"

From this, you can see that I'm using the Arc browser, and the title of the current tab is that of this post. Arc is one app where the window number doesn't correlate with an AppleScript id for any tab or window object, although Arc's AppleScripting implementation contains many badly-coded object references, so this may be simply be one among them. You can also see that this string item is the second item that appears in the returned array, the first being this:

"[1|Script Editor|6972]Untitled 242.scpt"

This reflects the fact that I am executing the JXA code below from within Script Editor, having clicked away from this browser window and into the specific Script Editor document containing the code for testing. That is to say, when I execute the code, the Script Editor window is at the front, and this Arc window sits just behind, hence the returned array contains the Script Editor window as its first element, and this Arc window as its second element.

The array returned by the code below reflects the z-ordered arrangement of on-screen windows, ordered front-to-back. Thus, the %{z-index} represents the positional index of the item in the array as well as the position in the front-to-back ordering of all on-screen windows (which is equivalent to the order of most recently-active):

((O = "") => {
	ObjC.import('CoreGraphics');

	Ref.prototype.deref = function(Ω = this){
	  try { Ω = ObjC.castRefToObject(this); }
	  finally { return  ObjC.deepUnwrap(Ω); }
	}

	let Wᵢ = $.CGWindowListCopyWindowInfo(
	    $.kCGWindowListOptionOnScreenOnly,
	    $.kCGNullWindowID).deref().filter(
	    (_w) => _w.kCGWindowLayer==0).map(
	    (_w, index) => `[${ 1 + index }|${
	            _w.kCGWindowOwnerName }|${
	            _w.kCGWindowNumber    }]${
	            _w.kCGWindowName      }`);

	return O ? Wᵢ : Wᵢ.join('\n');
})([]);

Bear in mind that it is a JavaScript array that is returned. If you'd prefer it to return a unary string value, with each array item placed on a new line, then replace in the final line the pair of square brackets ([]) with a pair of double quotes (""). This will produce a string similar to the following:

"[1|Script Editor|6972]Untitled 242.scpt
[2|Arc|1937]Is it Possible to Identify the *Second* Window in a Desktop/Space When it is in a Different Application from the frontmost App? - Questions & Suggestions - Keyboard Maestro Discourse
[3|Music|5968]Music
[4|iTerm.app|247]-fish — /dev/ttys004
[5|Script Editor|6908]Library
[6|Shortcuts|6644]QuickLook Contents of Folder
[7|Finder|5602]osa
[8|Finder|4271]Pictures
[9|Shortcuts|6313]All Shortcuts
[10|iTerm.app|248]~/#/o/ascr
[11|Session|6269]Session
[12|VLC|5606]VLC media player
[13|Usenapp|5101]
[14|iTerm.app|246]~/L/M/c/#/o/ascr
[15|Telegram|4652]Telegram
[16|Signal|4651]Signal
[17|Terminal.app|195]~ — ttys000 — 60×41"

System version: 12.6.3 (Monterey)
1 Like

Thanks @CJK, this may be useful for several things I've been banging on.

First, I want to doublecheck that the "on-screen windows" this refers to are windows in a single Desktop Workspace, not all windows open on the system.

I tripped over the token %Application%2% which is the previously active application, but it doesn't care about Spaces or Desktops, so activating that app can pop you to somewhere unexpected.

If it's only the windows in the current Desktop/Space, then it could solve a problem asked frequently here and on Stack Exchange / Ask Different -- "How do you move a window to the back?". It looks to me like for your list of 17 apps, you could "simply" build a snapshot of the current list of windows and then activate them in the order "1, 17, 16, 15, ... 3, 2" which would move #1 to the bottom of the list.

My immediate need i sto reduce the annoyance of using a relatively large window as an ID for the Desktop/Space, activating it to move to that Space. That puts the ID window in the front, covering at least some of what had been in front. When I am popping back and forth between a couple of Desktops, I want my work in front, not the name of the Desktop.

For now I've been using a kludge of simply clicking just outside the ID window. Since I keep them all in the lower left corner, a click 3px to the right and 3px up from that window's upper right corner does a mostly adequate job. Not superb, but mostly adequate.

If that continues to have an annoyance factor, I'll look into your solution. It might be fun. [I did some work with Acrobat JavaScript about 20 years ago. I prototyped being able to set a Status value for Comments in a PDF for my own editorial purposes and then Acrobat Engineering implemented some of it (although they didn't address moving comments from one PDF to another). If you possibly still have a copy of Acrobat 6, you can find my name in the credits.]

That's something I didnt investigate specifically, but the code snippet I shared above as it currently stands will, I believe, return all windows across all desktop spaces. However, I'll have a look to see if any of the properties returned against each window include one denoting its desktop space. Hopefully, I'll get back to you in under two months this time.

I have heard (but not used it) that from the introduction of Spaces (OSX 10.3??) through OSX 10.9 there was a public API that gave that information. However it was deprecated and not replaced by anything. IOW, Apple now keeps that to themselves with Private APIs. This may not be entirely accurate, it's what I remember reading and I don't remember the source(s), probable people pontificating in comments on Ask Different or Stack Overflow.

If you can find a way to access that info, it would be useful for so much more than my original question in this thread.