Hi All!
I'm trying to make a script that opens and hides a Mac App. The target is an App like Safari where the App does not Quit even if the window is closed, and the window opens again the next time the App icon in the Dock is clicked. (Safari, Mail, Chrome, etc.)
But the script I made is a little different from what I want.
Now it is below.
if (!sf.ui.app('com.apple.Safari').mainWindow.exists) {
sf.app.launch({
path: "/Applications/Safari.app",
});
globalState.messagesIsOpen = true
throw 0
}
if (globalState.messagesIsOpen == true) {
sf.ui.app('com.apple.Safari').menuClick({
menuPath: ["Safari", "Hide Safari"],
});
globalState.messagesIsOpen = false
throw 0
}
sf.ui.app('com.apple.Safari').appActivateMainWindow();
globalState.messagesIsOpen = true;
What I want is:
(a) .Safari is not launching> Launch (& new window)… OK
(b). Safari is running and the window in the foreground> Hide… OK
(c) .Hide> Show Safari… OK
(d) .Safari is launched and is in the foreground, but there is no window> New window ... OK
(e) .Safari is running and a window is displayed, but other apps are in the foreground (Safari window behind it)> Safari is hidden once, so I have to press the button twice.
What I want to do is improve the behavior of (e), and at this time I want Safari to come to the foreground instead of being hidden by pressing the button once.
Does anyone have an idea?
- Chris Shaw @Chris_Shaw2021-09-16 23:32:55.873Z2021-09-17 00:19:34.820Z
this should do it:
const safari = sf.ui.app('com.apple.Safari'); if (!safari.isActive) { sf.app.launch({ path: "/Applications/Safari.app", }); globalState.safariIsFocused = true throw 0 }; if (safari.isActive && globalState.safariIsFocused) { safari.menuClick({ menuPath: ["Safari", "Hide Safari"], }); globalState.safariIsFocused = false throw 0 }; if (!safari.isActive && !globalState.safariIsFocused) { // if Safari is open but no window is open, then a launch command forces a new window to open // If Safari is open and a window is open it will activate the main window sf.app.launch({ path: "/Applications/Safari.app", }); globalState.safariIsFocused = true; } // This will activate the Safari window again so you don't have to press your trigger twice safari.appActivateMainWindow(); globalState.safariIsFocused = true;
- In reply toMasayoshi_Sugai⬆:Kitch Membery @Kitch2021-09-16 23:51:42.449Z2021-09-17 03:32:23.178Z
Hi @Masayoshi_Sugai,
Here is a version without having to use using globalstate. Fun stuff :-)
const appName = 'Safari'; const appRef = sf.ui.app('com.apple.Safari'); const appPath = '/Applications/Safari.app'; const isAppRunning = appRef.isRunning; const isAppFrontmost = sf.ui.frontmostApp.uiElement['Title'] === appName; const isAppWindowOpen = appRef.windows.length > 0; switch (true) { case (!isAppRunning): sf.app.launch({ path: appPath }); break case (!isAppFrontmost && isAppWindowOpen): sf.app.launch({ path: appPath }); break case ((!isAppFrontmost || isAppFrontmost) && !isAppWindowOpen): appRef.appActivate(); appRef.menuClick({ menuPath: ['File', 'New Window'] }); break case (isAppFrontmost && isAppWindowOpen): appRef.menuClick({ menuPath: [appName, `Hide ${appName}`], }); break }
Rock on!
Updated: Fixed reference to appName in line 25 and refactored. :-)
Chris Shaw @Chris_Shaw2021-09-17 00:20:06.990Z
Good one Kitch!
- MIn reply toMasayoshi_Sugai⬆:Masayoshi Sugai @Masayoshi_Sugai
Hello Chris and Kitch. Thank you for your help!
wonderful! Now I can apply it to almost all apps!
One thing, I want the EuControl App to behave in the same way, but I can't automatically open the EuControl Settings Window that was closed once while the App was running.Currently I have to manually open the window with ⌘ + 1.
Here is the script.const appName = 'EuControl';
const appRef = sf.ui.app('com.Euphonix.EuControl');
const appPath = '/Applications/EuControl.app';const isAppRunning = appRef.isRunning;
const isAppFrontmost = sf.ui.frontmostApp.uiElement['Title'] === appName;
const isAppWindowOpen = appRef.windows.length > 0;switch (true) {
case (!isAppRunning):
sf.app.launch({ path: appPath });
break
case (isAppRunning && !isAppFrontmost && isAppWindowOpen):
sf.app.launch({ path: appPath });
break
case (isAppRunning && !isAppFrontmost && !isAppWindowOpen):
appRef.appActivate();
appRef.menuClick({ menuPath: ['Window', 'EuControl Settings'] });
break
case (isAppRunning && isAppFrontmost && !isAppWindowOpen):
appRef.menuClick({ menuPath: ['Window', 'EuControl Settings'] });
break
case (isAppRunning && isAppFrontmost && isAppWindowOpen):
appRef.menuClick({
menuPath: ["EuControl", "Hide EuControl"],
});
break
}appRef.menuClick ({menuPath: ['Window','EuControl Settings']});
This doesn't seem to work, am I doing something wrong?- MMasayoshi Sugai @Masayoshi_Sugai
I solved it!
I made the following changes and it worked as expected.
from
const isAppWindowOpen = appRef.windows.length> 0;
to
const isAppWindowOpen = appRef.windows.length> 1;Thank you everyone for your help!
- In reply toMasayoshi_Sugai⬆:Nathaniel Reichman @Nathaniel_Reichman
Riffing on this, I'd love to have a command that hides all apps except Pro Tools, Dolby Atmos Renderer and Avid Control Desktop. I'll work on this later, but if someone more clever than me has this figured out, please post. Thanks!