Hi I think I have asked this before with no answer. But I see the option to make the red button "Quit App Under Cursor." But that quits the app even if I have 10 windows open. Is there some way (any way at all!) to have the red button close windows as usual if another window is open. But to quit the app when hitting the red button on the last window of an app.
So essentially, instead of an option to make the red button "Quit app under cursor" it would "Quit the app under cursor (only on the last window)."
Alternatively, can better touch tool auto-quit apps that are sitting in my dock without any windows open? Or any other app for that matter.
I have tried Quitter (only works for 10 apps) and I have tried RedQuits which mostly works but sometimes quits apps with multiple windows open. I was hoping BTT had some way to do this!
I wish I could say I have. Redquits is the only thing available right now and it hasn’t been updated in a long time. BTT almost has it. I just wish they’d modify it to only quit an app when closing the last window.
What other functions/options are available and attached to the red button or attached to whatever is under the cursor? I currently don't have BTT installed so can't check, and perhaps there's a way to achieve it that's not immediately obvious.
Not heard of either, but I'm assuming these run in the background and listen for messages sent by the system whenever an instance of a window is destroyed. That's something one can create themselves, in the form of a stay open AppleScript application. It would operate under the same principle (and not in a stupid that uses repeat loops or polling), by listening to system messages, so it would have to remain running. It's not going to be as efficient as an application written in Swift or Objective-C, but since loads of stuff now is written with JavaScript frameworks that rape your system for all their memory, it'll probably appear reasonably modest, save for any memory leaks which one has no control over with AppleScript (if this occurs, it means you'd need to restart the application whenever it becomes less responsive). It would also be hanging around on the dock, which might or might be annoying.
Yeah the only other options for the red button under "Window Interaction" is to minimize, zoom, fullscreen, etc.
As to RedQuits specifically, yeah I believe it does run in the background. It doesn't quit an app when you close a window, unless it's the last window of that app. It's just a little finicky and hasn't been updated in so long. So I thought it'd be nice if BTT implemented this functionality.
Ok, I don't if there is anyone left who still wants this as a functionality but I figured it out thanks to another user in the forum who showed me the majority of the solution.
So what do you need
In btt create two named triggers name them closea and quitb.
closea - closes the window under the cursor
quitb - quits the app under cursor
create a trigger when left click the red X button - > run a real javascript
Wow, thanks so much for your answer. I'm really glad I could solve this using just BTT without any other 3rd party app. Your script worked well for me most of the time, but in cases where hovered_app was present in both the app name and the window name, it was counting it multiple times, preventing it from quitting the last window.
I updated the code as below, and now it's working as expected for me. P.S. You can exclude apps that are not supposed to be quit (so they can keep working in the background) in Advanced Conditions, e.g. NOT (hovered_element_details CONTAINS "<AXApplication: \"BetterTouchTool\">"
(async ()=> {
const window_list = await callBTT('get_string_variable', {variable_name:'visible_window_list'} );
const hovered_element = await callBTT('get_string_variable', {variable_name:'hovered_element_details'} );
const hovered_app = hovered_element.split('<AXApplication: "')[1].split('"')[0];
// Split window_list into lines and extract the first part before the separator '-'
const window_list_lines = window_list.split('\n').map(line => line.split(' - ')[0]).join('\n');
let rgexp = new RegExp(hovered_app, 'g');
let count = (window_list_lines.match(rgexp) || []).length;
if (count == 1){
await callBTT('trigger_named', {trigger_name: 'quitb'});
} else {
await callBTT('trigger_named', {trigger_name: 'closea'});
}
returnToBTT("done");
})();
For some reason it doesn't work for me to call the named triggers. If I click the red x-button nothing happens. I have a different solution which removes the need to create named triggers and merges everything into a single trigger:
Create trigger Leftclick Red Window Button with the action If Java Script Returns True. The JavaScript is:
try this on apps on the secondary monitor, it does not work, it quits app even if it has multiple windows, for the named triggers way, red button just doesnt respond and does absolutely nothing to apps on secondary monitor. If there is a solution, please help!
To be honest I gave up on this as on many other things where I tried to force macos to behave how I expect and just accepted the mac-way. I just use cmd-q (works also in alttab) or quit it from the dock.
I agree with you, i also have tried to manipulate a lot of things to work my way but it always leads to multiple issues but this function has made my life so much easier. I just exclude apps which i dont want to quit even after closing last window and havent faced any problem whatsoever. But i have recently started using secondary monitor and just noticed that this is not applicable for windows outside of the main monitor. @jonny33 Haven't you faced this problem?
I think it's some kind of a bug on MacOS. I noticed that if my app is on a secondary monitored maximized and I click on the red button nothing happens, but if the window is smaller and the red button is slightly lower than when maximized it's working.
I discovered another issue. It doesn't seem to work with fullscreen windows.
I tried to debug it by running the script from inside the BTT-window to check the output and it seems that at least for the BTT-window the variable visible_window_list contains two BTT-windows although only one is open. If the BTT-window is not fullscreen then visible_window_list contains only one window and it works as expected.
Then I adjusted my script such that it wouldn't check if an app has only one window open to quit but two. This fixed the fullscreen-window bug which confirms my finding that for some reason fullscreen-windows have two windows stored in visible_window_list although only one is open.
Does anybody know how to check from inside javascript if the active window is fullscreen?
hmm interesting, i was not able to fix this through javascript but applescript atleast solved this bug where secondary monitor windows werent working:
"tell application "System Events"
-- Get the name of the frontmost application
set frontAppName to name of the first process whose frontmost is true
try
-- Get the process for the frontmost application
set appProcess to first process whose name is frontAppName
-- Count the windows of the application
set windowCount to count of windows of appProcess
if windowCount = 1 then
-- If only one window is open, quit the application
do shell script "osascript -e 'tell application \"" & frontAppName & "\" to quit'"
else if windowCount > 1 then
-- If more than one window is open, close the front window using osascript
do shell script "osascript -e 'tell application \"" & frontAppName & "\" to close front window'"
end if
on error errMsg
-- Handle errors silently (optional)
end try
end tell
"
But the fullscreen window not quitting is not being fixed even by this, because as you stated when app is in fullscreen the windows detected are 2 instead of one because macOS creates a virtual extra window when app is in fullscreen, trying to solve this.