Macro to make closing a window behave like closing a window on Windows OS

On macOS, when I close the front app’s window, the app often remains in focus regardless if there is an active window or not.

On Windows OS, closing a window moves focus back to the previously active app’s window. I'm so used to this behavior and would like a macro that can do this.

macOS behavior:
I have 2 active windows open for LibreOffice Calc, test1.ods and test2.ods.
I have Chrome browser open with 2 tabs, tab1 and tab2.
I navigate from Chrome tab2 to LibreOffice test1.ods.
From test1.ods, I press CMD+W to close test1.ods.
Focus is switched to test2.ods
From test2.ods, I press CMD+W to close test2.ods
Focus remains on LibreOffice without an active window.

Desired behavior: I would like a KM macro that does this (like Windows OS):
I have 2 active windows open for LibreOffice Calc, test1.ods and test2.ods.
I have Chrome browser open with 2 tabs, tab1 and tab2.
I navigate from Chrome tab2 to LibreOffice test1.ods.
From test1.ods, I press CMD+W to close test1.ods.
Focus is switched to Chrome tab2.
From Chrome tab2, I press CMD+W to close tab2.
Focus is switched to Chrome tab1.
From Chrome tab1, I press CMD+W to close tab1.
Focus is switched to LibreOffice test2.ods.

You could try a macro whose trigger is CMD+W and executes the following actions:

Manipulate a Window > Close the Front Window in Front Application

Activate Last Application

If you want it to only apply to certain apps (like Libreoffice), make sure you set Available In at the top of the macro appropriately.

Try this:

Test for ChrisQ.kmmacros (2.5 KB)

I think you'll also need to check the window count in the frontmost application before switching—if there's still an open window, the macro shouldn't switch. You could check if the text token %WindowName%0% is empty, I think—if it is, there is no frontmost active window, so you could switch.

-rob.

1 Like

Does not seem to work for applications that have 1 window with multiple tabs like Chrome and BBEdit. CMD+W closes the tab/document, but it should not switch to previous app unless the current app has no active window. I can’t seem to work out the logic to this problem :frowning:

Did you try what I recommended? Add an IF action that checks to see if the %WindowName%0% token is empty. If it is, close the window. If it's not, end the macro because there are still windows in the frontmost app.

-rob.

This is going to be very difficult to do completely because the two OS's work differently.

In Windows, each window is effectively an instance of an application -- it works how you like because the "stack" contains interleaved instances of the different applications. Close the top instance and the next one down is the active one, regardless of what the app may be.

In macOS, each window is a "child" of an application and while you can interleave the windows of different apps the apps themselves remain in position in the "stack" -- close the frontmost window of appA and appA remains active, even if a window from appB was immediately behind it.

You can get close with "when I close the only open window of an app, active the next app in the stack" -- but then even you'll have manage exceptions since some apps will Quit when you close their last window and the "next app in the stack" will now be the behind the one you actually want activated.

IMO this is one of those cases where you are better off embracing the Mac way rather than fighting to make it like Windows...

2 Likes

I'd forgotten about that; you'd need to have a long list of "quit when last window closed" apps, and only switch apps if the one whose last window you're about to close isn't in the list. Doable, though I'm not sure how long the list is—but it keeps getting longer, unfortunately.

-rob.

Thanks all for your responses.

@griffman, yes, I also try %WindowName%0% is empty, but still did not get the desired results.

@Nige_S, thanks for the detail explanation on how macOS and WindowsOS handle windows. Now that I know this is not so easy to do, I will succumb to macOS’s way of handling windows.

Actually, I just had a thought on how this could work. Lemme experiment for a bit…

-rob.

1 Like

That may or may not work. But you can get the actual count of windows of the frontmost app using the WINDOWCOUNT() Function, so you could try that instead:

Activating the previous app when you close the last window of the current app is pretty easy -- but it is difficult to detect when you are in a situation where windows are stacked like:

appA window1
appB window1
appA window2
appB window2

...so you can act appropriately. The best detector is actually you :wink: so if you are prepared to manually trigger a macro when the situation demands we may be able to do something.

Unless @griffman comes up with something cool, of course -- he does have a habit of doing that!

1 Like

Just to clarify, while it does remain active, it will also pull forward the background window, even if it was interleaved before you closed the frontmost window. I would think this would be the expected behavior; @ChrisQ stated he wants to switch to the other app only when no additional windows remain.

And if that's the case, then I think this macro works, and handles apps that quit when you close their last window, and those that don't.

NOTE: I assigned the macro to Control-W, for easier testing. You can set it to Command-W to replace the built-in close shortcut, if you wish (and if it works as expected :)).

Download Macro(s): Switch Apps on Last Window Close.kmmacros (40 KB)

Macro screenshot

Macro notes
  • Macros are always disabled when imported into the Keyboard Maestro Editor.
    • The user must ensure the macro is enabled.
    • The user must also ensure the macro's parent macro-group is enabled.
System information
  • macOS 15.7.3
  • Keyboard Maestro v11.0.4

It first saves the current app name, then checks the window count. As long as there's at least one open window, it closes it. There's some simple logic there to check the one condition I'm aware of that will break this: If you try to close a document with unsaved changes.

The macro could be written to pause and handle that situation, but I took the easy way out for sake of speed: The macro just tells you to fix the problem then quits :).

Assuming there's nothing to save, the macro closes the window. It then checks the window count again, and if it's zero, it checks to see if the active app changed. If it did, there's nothing to do. If it didn't, then it switches to the last active application.

Excluding oddball onscreen non-save dialogs on window close, I think (with lots of emphasis on that word) this should work as expected for any situation. Please let me know if I'm wrong and have overlooked something stupid (quite possible).

-rob.

1 Like

That's a change in behaviour from what was stated in the opening post. I don't think this:

...contradicts that, but I'm going solely on the use of the phrase "no active window" rather than "no open window" (emphasis mine).

It's difficult to emulate full Windows behaviour.

You're thinking the same as me for the "after last window closes" scenario, but I'd add a wrinkle -- you also need to special-case Finder's window count to allow for the Desktop, always open and counted as a window.

There is another edge case where you can have

appA window1
appB -- no windows open!
appC window1

...and you close appA's window, activating appB when you wanted appC. Without stepping out to AppleScript I think the easiest way to handle that is to collect a list of running apps at the start (which will be in index order) then use the "Use Variable" Action to frontmost each in turn until you get to an app that has open windows.

1 Like

Ah, yes, we totally read that in different ways. I read "active" as "open."

Good point.

Couldn't you just use the %Application%n% token to step back one by one, stopping at the first one where WINDOWCOUNT() isn't zero?

-rob.

Something like (omitting Finder special-case for brevity):

Whether that's more readable than, say:

...depends on what you're used to, I guess.

I do get the heebies when iterating over an array that gets changed on each iteration, which is what happens in the first example -- I've got that wrong more times than I care to remember, which is why my default would be the static list approach of the second example.

Another "gotcha" to consider in approach to this problem -- some apps, FileMaker in my case, spawn a window when activated without an existing window. These are generally in the "Would you like to open..." style of things and have set titles so could also be special-cased -- but that means even more work/complexity...

2 Likes

Enlightenment … :slight_smile: