No internet connection
  1. Home
  2. How to

How to make a toggle button for show/hide applications

By Brian Sloss @Bsloss
    2020-05-23 00:51:45.223Z2020-05-24 20:41:19.564Z

    Hey, so I am trying to make a button that toggles Soundminer between open and hidden. Here is the code I have pulled together, it will open Soundminer, but it will not hide soundminer once open. I am very amateur at writing code so please bear with me. Also, I couldn't get the code to paste without looking very sloppy, my bad.

    if (sf.ui.soundminer.mainWindow.isFocused) {
    
        sf.ui.app('com.soundminer.smv5Pro').menuClick({
            menuPath: ["Soundminer v5Pro", "Hide Soundminer"],
        });
    
    }
    
    else {
    
        sf.app.launch({
            path: "/Applications/Soundminer v5Pro.app",
        });
    
    }
    
    

    I got this function to work with UAD console, it toggles between open and hidden UAD console. Here's the code for that. Maybe there's a more elegant way of doing this? Thanks in advance for your help.

    if (sf.ui.app('com.uaudio.ua_mixer_engine').windows.whoseTitle.is('Console*').first.isFocused) {
    
        sf.ui.app('com.uaudio.console').menuClick({
            menuPath: ["Console", "Hide Console"],
        });
    }
    
    else {
    
        sf.app.launch({
            path: "/Applications/Universal Audio/Console.app",
        });
    }
    
    
    Solved in post #7, click to view
    • 26 replies

    There are 26 replies. Estimated reading time: 18 minutes

    1. Kitch Membery @Kitch2020-05-23 09:54:19.963Z

      Hi Brian,

      I too had an issue with using "isFocused"

      The link below may help you (possibly).
      https://forum.soundflow.org/-1759#post-2

      I don't have Soundminer but you could try this to see if it works;

      if (sf.ui.soundminer.focusedWindow.title.value.indexOf('Soundminer') === 0) {
          sf.ui.app('com.soundminer.smv5Pro').menuClick({
              menuPath: ["Soundminer v5Pro", "Hide Soundminer"],
          });
      } else {
          sf.app.launch({
              path: "/Applications/Soundminer v5Pro.app",
          });
      }
      

      Oh... And the way to paste code into a forum post is to put a line of three back ticks ```` , then on the next line add the code you want to display, follwed by another line of 3 back ticks ``` The "back tick" key is the key below the Escape key on a mac keyboard.

      Hope that helps.

      1. BBrian Sloss @Bsloss
          2020-05-24 08:06:30.479Z

          Thank you for your help! This code seems to only close soundminer once open, but won't open it. I will see if I can come up with a solution based on these suggestions. Thanks again!

          -Brian

          1. Kitch Membery @Kitch2020-05-24 08:21:45.589Z

            Sorry that did not work... If only I had soundminer to trouble shoot it. . @Dustin_Harris may be able to help you with this, as I think he has a few soundminer script in is collection, and is an absolute champion! :-)

            1. Dustin Harris @Dustin_Harris
                2020-05-24 13:56:30.578Z

                Hi @Bsloss and @Kitch!
                Kitch: your if statement is always triggering whether Soundminer is hidden or not... I guess the window status still exists but the OS is doing some tomfoolery? I'll see if I can come up with something :)

                1. Dustin Harris @Dustin_Harris
                    2020-05-24 14:33:14.258Z

                    Alright. I think I have something here. They key was finding a condition that was true when SM5 was hidden but false when it wasn't. Turns out it's a bit of a hack but something that satisfies that condition is the menu command Smv5 Pro>Show All.

                    This is working for me, with the condition that is it assigned a trigger running on ALL APPS.

                    if (!sf.ui.soundminer.exists) {
                    
                        sf.app.launch({
                            path: "/Applications/Soundminer v5Pro.app",
                        });
                        throw 0;
                    }
                    
                    
                    if (sf.ui.soundminer.getMenuItem('Soundminer v5Pro', 'Show All').isEnabled) {
                    
                        sf.ui.app('com.soundminer.smv5Pro').appActivate();
                    
                    
                    } else {
                    
                    
                        sf.ui.app('com.soundminer.smv5Pro').menuClick({
                            menuPath: ["Soundminer v5Pro", "Hide Soundminer"],
                        });
                    
                    
                    }
                    

                    Maybe @Kitch can turn this info into something more elegant as my knowledge of Javascript is younger than my SoundFlow subscription ;)

                    Reply2 LikesSolution
                    1. Kitch Membery @Kitch2020-05-24 14:54:35.525Z

                      Nice one Dustin!

                      1. In reply toDustin_Harris:
                        BBrian Sloss @Bsloss
                          2020-05-24 20:59:32.917Z

                          This works for me too! Sometimes the button needs to be pressed twice if I click it quickly, but it works. Thank you guys!

                          1. In reply toDustin_Harris:
                            Miguel Carrascal @Miguel_Carrascal
                              2020-09-29 15:53:04.048Z

                              Thanks so much for the script, Dustin.
                              I'd love to see how you wrote the script to work on ALL APPS (not just Soundminer) – as I'd like a Stream Deck trigger that does precisely that.
                              Thanks so much, in advance!

                              1. Dustin Harris @Dustin_Harris
                                  2020-09-29 15:58:24.664Z

                                  Hi @Miguel_Carrascal! Do you mean you want to be able to show/hide other apps, not just SoundMiner?
                                  Thanks!
                                  -D

                                  1. Miguel Carrascal @Miguel_Carrascal
                                      2020-09-29 16:08:31.041Z

                                      Hi Dustin!
                                      Thanks so much for the prompt response.
                                      Yes, that is correct. Toggle Button to show/hide other apps.
                                      To give you a bit of context:
                                      – I currently have a Deck where my favorite apps launch when their corresponding Stream Deck key is pressed.
                                      – I'd like to have a Toggle Button that when triggered, allows me to Show/Hide whichever app I choose from the aforementioned deck.
                                      – Ideally: I'd also like to have a "Quit App" trigger that does essentially the same, but instead of toggling between show/hide, it just quits the app when pressing their corresponding Stream Deck key.
                                      I am a complete noob when it comes to coding; your patience is very much appreciated.
                                      Let me know if this makes sense or if you'd like me to rephrase/be more specific.
                                      Thanks so much!
                                      -MCR

                                      1. Dustin Harris @Dustin_Harris
                                          2020-09-29 20:16:05.415Z

                                          OK, so to make this work for any app, you need to do some 'investagating' into the app's bundle identifier. You can do this by selecting the app icon in the applications folder, then right clicking on the icon and selecting 'show package contents'

                                          then navigating to contents folder to find the info.plist file. copy this to your desktop and open it with any plist editor you may have (I use Xcode) or failing that, a text editor.

                                          what you're looking for here is the Bundle Identifier, which is what SoundFlow uses to find the program.

                                          I'm using iBooks as an example here so as you can see it's listed as 'com.apple.iBooksX'
                                          make note of that and use it for the first variable below.

                                          Next, close those finder windows and once again click on the application icon that you want to create the script for. Hit Option-Command-C to copy the application PATH to the clipboard, and paste it (in quotes) to the 2nd variable in the script below.

                                          Here's the script with me again using iBooks as an example:

                                          let bundleIdentifier = "com.apple.iBooksX" //the value of the Bundle Identifier from the Info.plist for iBooks
                                          
                                          let appLocaton = "/System/Applications/Books.app" //Get this value by selecting the app icon, hit "option-command-c", then paste the result inside the quotes
                                          
                                          
                                          
                                          if (!sf.ui.app(bundleIdentifier).exists) {
                                          
                                              sf.app.launch({path: appLocaton})
                                              throw 0;
                                          }
                                          
                                          if (sf.ui.app(bundleIdentifier).getMenuItem('Books', 'Show All').isEnabled) { //These Menus names need to be figured out by going into the app and looking at their names
                                          
                                              sf.ui.app(bundleIdentifier).appActivate()
                                          
                                          
                                          } else {
                                          
                                              sf.ui.app(bundleIdentifier).menuClick({
                                                  menuPath: ["Books", "Hide Books"],
                                              });
                                          
                                          }
                                          

                                          please note that my application path is /System/Applications/ because I'm running on 10.15 Catalina, but the option-command-c copy should give you the right path no matter where your application is.

                                          Hope this helps!

                          2. In reply toBsloss:
                            Miguel Carrascal @Miguel_Carrascal
                              2020-09-29 21:30:47.119Z

                              Hi Dustin –
                              Thanks so much for this! I'm a bit dumbfounded because I tried the script with Google Chrome and it worked the first couple of instances I tried it, and then, all of a sudden, it didn't.
                              To clarify: the first portion of the script works like a charm every time [Launch Application + Show Application]. It is the "Hide" (Application) functionality that doesn't seem to work – though, as I mentioned, it worked for a couple of minutes before it stopped.

                              Take a look at my script below:

                              if (!sf.ui.app("com.google.Chrome").exists) {
                              
                                  sf.app.launch({path: "/Applications/Google Chrome.app"})
                                  throw 0;
                              }
                              
                              if (sf.ui.app("com.google.Chrome").getMenuItem('Chrome', 'Show All').isEnabled) { 
                              
                                  sf.ui.app("com.google.Chrome").appActivate()
                              
                              
                              } else {
                              
                                  sf.ui.app("com.google.Chrome").menuClick({
                                      menuPath: ["Chrome", "Hide Google Chrome"],
                                  });
                              
                              }
                              
                              

                              Am I missing something? Did I write part of the script incorrectly? I'm quite positive the Bundle Identifier and app PATH are both correct.

                              Thanks again so much for putting this together. Really appreciate your help with everything.
                              Best,
                              -MCR

                              1. Dustin Harris @Dustin_Harris
                                  2020-09-30 01:47:07.499Z

                                  Heyya! I tried it and it's working for me, as long as I don't try to show and hide it too quickly... AKA if I hide it and wait for a couple of seconds, then show it, wait a couple of seconds, etc... it works fine for me (google chrome). Also, your code looks spot on.
                                  If its still not working, try starting Sound Flow and see if it works again?

                                  -D

                                  1. Kitch Membery @Kitch2020-09-30 11:18:07.645Z

                                    @Dustin_Harris, @Bsloss & @Miguel_Carrascal,

                                    Gentlemen... I finally got to the bottom of this bizare behavior.

                                    Here is a script to open and toggle show/hide Chrome. Without having to trigger the script twice. (I hope) :-)

                                    const application = sf.ui.app("com.google.Chrome");
                                    
                                    if (!sf.ui.app("com.google.Chrome").exists) {
                                        sf.app.launch({path: "/Applications/Google Chrome.app"})
                                        throw 0;
                                    } else if (sf.ui.frontmostApp.value["Parent"]['Title'].value === "Chrome") {
                                        application.getMenuItem("Chrome", "Hide Google Chrome").elementClick();
                                    } else {
                                        application.appActivateMainWindow();
                                    }
                                    

                                    Rock on!!!

                                    1. Dustin Harris @Dustin_Harris
                                        2020-09-30 14:07:23.118Z

                                        @Kitch this works a treat! I can also mash the buttons as fast as I can and it shows/hides each time. Excellent discovery!

                                        1. Miguel Carrascal @Miguel_Carrascal
                                            2020-09-30 15:20:08.848Z

                                            @Kitch Amazing! That seemed to do the trick. Thank you so much!
                                            @Dustin_Harris Thanks so much for all your help as well.
                                            I've got one last issue, I was hoping you guys would be kind enough to shine a light on. Now that Show/Hide Toggle works for all the apps I wrote Scripts for, the only one that gives me trouble is Pro Tools. When I use the trigger to Hide it, I get the following pop-up (SoundFlow):

                                            See script below:

                                            const application = sf.ui.app("com.avid.ProTools");
                                            
                                            if (!sf.ui.app("com.avid.ProTools").exists) {
                                                sf.app.launch({path: "/Applications/Pro Tools.app"})
                                                throw 0;
                                            } else if (sf.ui.frontmostApp.value["Parent"]['Title'].value === "Pro Tools") {
                                                application.getMenuItem("Pro tools", "Hide Pro Tools | Ultimate").elementClick();
                                            } else {
                                                application.appActivateMainWindow();
                                            }
                                            

                                            I have a feeling that it might have something to do with having vertical line in the command "Hide Pro Tools | Ultimate", but I might be completely wrong. Any thoughts?
                                            Thanks again, so much. You guys rock!

                                            1. Dustin Harris @Dustin_Harris
                                                2020-09-30 15:50:34.963Z

                                                there is a 'tools' in line 7 that should be 'Tools' :)

                                                1. Miguel Carrascal @Miguel_Carrascal
                                                    2020-09-30 16:01:46.191Z

                                                    I guess there's a reason why I don't code...thanks @Dustin_Harris for pointing out quite the egregious oversight on my part.
                                                    It now works fine.

                                                    Quick tip I discovered while doing some research yesterday. To easily find any app's BUNDLE IDENTIFIER:

                                                    – Open Terminal and run this command:

                                                    osascript -e 'id of app "Name of App"'

                                                    – The "Name of App" is replaced with the name of the app as it appears when hovering over its Dock icon.

                                                    For Excel, for example, it'd be:
                                                    osascript -e 'id of app "Microsoft Excel"'

                                                    I just thought it was a nice little trick for noobs like myself.
                                                    Thanks again for being so patient and for all your help.
                                                    Best,
                                                    -MCR

                                                    1. Dustin Harris @Dustin_Harris
                                                        2020-09-30 16:05:28.873Z

                                                        It happens to all coders, so it just means you’re MORE of a coder now ;)

                                                        And that’s an awesome tip about the bundle identifier!

                                                        1. Dustin Harris @Dustin_Harris
                                                            2020-09-30 16:11:16.381Z

                                                            You just gave me a soundflow idea that I can piggyback off of part of @Kitch 's addition to the script!

                                                            log(sf.ui.frontmostApp.activeBundleID);
                                                            

                                                            This will return the bundleID of whatever the focused app on the system is :)

                                                            1. Miguel Carrascal @Miguel_Carrascal
                                                                2020-09-30 16:46:42.782Z

                                                                Nice! Super-helpful.
                                                                Thanks again!

                                                          • Kitch Membery @Kitch2020-09-30 17:33:25.847Z

                                                            Rock on!

                                                  • In reply toBsloss:
                                                    Daniel Dettwiler @Daniel_Dettwiler
                                                      2022-02-07 18:10:06.785Z

                                                      Forgive me, if I bring this up rather than making a new post, I am new here, not sure whats better.

                                                      Anyway, I seem to not be able to adapt this script to safari.

                                                      I can open it with the button on the deck, but not hide it by pressing a 2nd time. While with Crhome that works. I like the idea of having Programm-Launch Buttons that then show hide the software by pressing them again.

                                                      Here is my code:

                                                      const application = sf.ui.app("com.apple.safari");
                                                      
                                                      if (!sf.ui.app("com.apple.safari").exists) {
                                                          sf.app.launch({path: "/Applications/Safari.app"})
                                                          throw 0;
                                                      } else if (sf.ui.frontmostApp.value["Parent"]['Title'].value === "Safari") {
                                                          application.getMenuItem("Safari", "Safari ausblenden").elementClick();
                                                      } else {
                                                          application.appActivateMainWindow();
                                                      }
                                                      

                                                      Thanks for any help..

                                                      1. Reuven Amiel @Reuven_Amiel
                                                          2022-08-18 16:11:57.641Z

                                                          Can you Hide and Show for Example Soundflow and other apps on a Tablet?

                                                          1. Daniel Dettwiler @Daniel_Dettwiler
                                                              2022-08-19 17:58:40.428Z

                                                              I have them on a Stream Deck, not on a Tablet, but I guess that would behave the same way.
                                                              I can show / hide Chrome as example and also some other apps. Safari can be opened but not closed while Apple Mail I can not even open. I think that the command lines to be entered are different on my swiss german Mac OS, and I am too stupid to get those command lines.

                                                              What would be great, would be a little app, in which you can choose all software installed and press one of it and it would tell the exact name that would need to be entered in the SF Script.

                                                              1. Reuven Amiel @Reuven_Amiel
                                                                  2022-08-19 19:59:59.160Z

                                                                  Awesome Daniel..will check it and report! thank you!