No internet connection
  1. Home
  2. How to

How to ensure that All Groups are suspended

I was wondering how to ensure that All groups are suspended. I got as far as ensuring the Goups Window is open an clicking "Suspend All Groups" but trying to set to 'Enable' doesn't seem to work if Suspend All groups is already enabled - if it is I want the script to do nothing.

here's what I've come up with so far

sf.ui.proTools.groupsEnsureGroupListIsVisible();


var groupListPopup = sf.ui.proTools.groupsOpenListPopupMenu().popupMenu;
groupListPopup.menuClickPopupMenu({
    menuPath: ["Suspend All Groups"],
    targetValue: 'Enable'
});
Solved in post #2, click to view
  • 19 replies

There are 19 replies. Estimated reading time: 26 minutes

  1. It appears to work - almost - here, in that if Suspend All Groups is already enabled, the script doesn't click it.
    However, the script only knows that Suspend All Groups is already enabled after it has opened the popup menu. It doesn't care to dismiss the popup menu afterwards if it didn't need to click it (which you can argue is kind-of a bug).

    You can work around this by inserting an appActivateMainWindow call after the popup call though, which then in the case where the groups are already suspended, will just trigger a short flicker of the popup menu.

    So in total, your script would be:

    sf.ui.proTools.groupsEnsureGroupListIsVisible();
    
    
    var groupListPopup = sf.ui.proTools.groupsOpenListPopupMenu().popupMenu;
    groupListPopup.menuClickPopupMenu({
        menuPath: ["Suspend All Groups"],
        targetValue: 'Enable'
    });
    
    sf.ui.proTools.appActivateMainWindow();
    
    Reply1 LikeSolution
    1. In reply toChris_Shaw:

      Perfect!
      Thanks again!

      1. In reply toChris_Shaw:

        Follow up question.
        I would like to query the status of Suspend All Groups and store it's state into a variable before turning it on or off so that when my script completes I can return Suspend All Groups to the state it was in before the script was run.

        1. Then you'd do like this:

          The menuClickPopupMenu action returns a property menuWasClicked that tells you whether or not the action needed to click the menu item to get to the desired targetValue.

          Inside the finally block I'm then checking to see, if the menu was clicked, it should be clicked again, this time disregarding any targetValue.

          The try/finally block is there to make sure that even if the script fails inside the try block, it's always gonna run the finally block, and so even upon a failure, the Suspend state should be returned to normal.

          sf.ui.proTools.groupsEnsureGroupListIsVisible();
          
          var groupListPopup = sf.ui.proTools.groupsOpenListPopupMenu().popupMenu;
          var menuWasClicked = groupListPopup.menuClickPopupMenu({
              menuPath: ["Suspend All Groups"],
              targetValue: 'Enable'
          }).menuWasClicked;
          sf.ui.proTools.appActivateMainWindow();
          
          try {
              //Do something with groups suspended...
          
          } finally {
              if (menuWasClicked) {
                  groupListPopup.menuClickPopupMenu({
                      menuPath: ["Suspend All Groups"]
                  });
              }
          }
          
          1. Note, this can be made into a reusable function, which is probably how I would use it:

            
            function doWithGroupsSuspended(callback) {
                sf.ui.proTools.groupsEnsureGroupListIsVisible();
            
                var groupListPopup = sf.ui.proTools.groupsOpenListPopupMenu().popupMenu;
                var menuWasClicked = groupListPopup.menuClickPopupMenu({
                    menuPath: ["Suspend All Groups"],
                    targetValue: 'Enable'
                }).menuWasClicked;
                sf.ui.proTools.appActivateMainWindow();
            
                try {
                    callback();
                } finally {
                    if (menuWasClicked) {
                        groupListPopup.menuClickPopupMenu({
                            menuPath: ["Suspend All Groups"]
                        });
                    }
                }
            }
            
            doWithGroupsSuspended(function(){
                //Do stuff here...
            
            });
            
            
            1. Off to JavaScript school to wrap my head around this. :)
              Thanks!

              1. Haha yea :)

                If I haven't already linked you there, make sure to check this:
                https://soundflow.org/docs/how-to/custom-commands/javascript-resources

            2. In reply tochrscheuer:
              Jack Green @Jack_Green
                2022-10-28 16:49:20.869Z

                So im trying to adapt this to work with the Link Track and Edit Selection option in the options menu. I want to make sure it's enabled but then return it to its original state. Ive tried to adapt your code but fear i have made a mess of it...

                var trackClipLink = sf.ui.proTools.menuClick ({"Options"});
                var menuWasClicked = trackClipLink.menuClick({
                    menuPath: ["Link Track and Edit Selection"],
                    targetValue: 'Enable'
                }).menuWasClicked;
                sf.ui.proTools.appActivateMainWindow();
                
                try {
                    //Do something with groups suspended...
                
                } finally {
                    if (menuWasClicked) {
                        groupListPopup.menuClickPopupMenu({
                            menuPath: ["Suspend All Groups"]
                        });
                    }
                }
                
                
                

                Thanks

                Jack !

            3. In reply toChris_Shaw:

              Hmm, I'm getting an error when trying to implement either of these two methods.
              I'm just inserting a simple sf.ui.proTools.menuClick({ menuPath: ["Edit", "Copy"], function where you have //Do stuff here... in the script
              It works fine when the script is executed with Suspend All Groups inactive but if Suspend All groups is active when the script is run it throws "kAXErrorInvalidUIElement" error at the groupListPopup.menuClickPopupMenu line under the finally routine.

              1. Kitch Membery @Kitch2020-11-10 22:40:43.012Z

                Hi @chrscheuer,

                I've been trying to use the doWithGroupsSuspended callback function as a part of a larger script;

                function doWithGroupsSuspended(callback) {
                    sf.ui.proTools.groupsEnsureGroupListIsVisible();
                
                    var groupListPopup = sf.ui.proTools.groupsOpenListPopupMenu().popupMenu;
                    var menuWasClicked = groupListPopup.menuClickPopupMenu({
                        menuPath: ["Suspend All Groups"],
                        targetValue: 'Enable'
                    }).menuWasClicked;
                    sf.ui.proTools.appActivateMainWindow();
                
                    try {
                        callback();
                    } finally {
                        if (menuWasClicked) {
                            groupListPopup.menuClickPopupMenu({
                                menuPath: ["Suspend All Groups"],
                            });
                        }
                    }
                }
                
                doWithGroupsSuspended(function () {
                    log('Test Log');
                });
                

                But I get this error;

                
                10.11.2020 14:27:55.63 <info> [Backend]: #Key: ctrl+x  (7) -> TEST SCRIPT [ckhci226h0005wq10g46xe1kp]
                
                10.11.2020 14:27:55.63 <info> [Backend]: >> Command: TEST SCRIPT [user:ckgsisa950009c110xlamn0jq:ckh3rxrhz000aw610yf08ycy2#ckh3rcyxr0005w610trwlwksj]
                
                10.11.2020 14:27:55.71 <info> [Backend]: Clicking with mouse here: 219, 1112
                
                10.11.2020 14:27:55.86 <info> [Backend]: PopupMenu full role:AXMenu
                
                10.11.2020 14:27:55.86 <info> [Backend]: Clicking popup menu element: Suspend All Groups
                
                10.11.2020 14:27:56.28 <info> [Backend]: Clicking with mouse here: 72, 30
                
                10.11.2020 14:27:56.31 <info> [Backend]: [LOG] Test
                
                10.11.2020 14:27:57.06 <info> [Backend]: Logging unknown error in action (02) ClickPopupMenuAction: kAXErrorInvalidUIElement
                Logging unknown error in action (02) RunCommandAction: Setup: Track Name to Comments: Line 117
                !! Command Error: TEST SCRIPT [user:ckgsisa950009c110xlamn0jq:ckh3rxrhz000aw610yf08ycy2#ckh3rcyxr0005w610trwlwksj]:
                kAXErrorInvalidUIElement (Setup: Track Name to Comments: Line 117)
                    SoundFlow.Shortcuts.AXUIElementException: kAXErrorInvalidUIElement
                   at SoundFlow.Shortcuts.AXUIElement.GetSubElements(String) + 0x1a5
                   at SoundFlow.Shortcuts.AXUIElement.GetPopupMenuPathRecursive(String[], List`1, Boolean&, Boolean) + 0x447
                   at SoundFlow.Shortcuts.AXUIElement.GetPopupMenuPath(Boolean, String[]) + 0x4f
                   at SoundFlow.Shortcuts.Automation.Actions.ClickPopupMenuAction.<Execute>d__16.MoveNext() + 0x69
                --- End of stack trace from previous location where exception was thrown ---
                   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x1c
                   at sfbackend!<BaseAddress>+0x168260b
                   at sfbackend!<BaseAddress>+0x1682546
                   at SoundFlow.Shortcuts.Automation.AutoAction`1.<Run>d__20.MoveNext() + 0x317
                
                << Command: TEST SCRIPT [user:ckgsisa950009c110xlamn0jq:ckh3rxrhz000aw610yf08ycy2#ckh3rcyxr0005w610trwlwksj]
                

                Any thoughts on how to get around this?

                Note: The error only occurs when "Suspend All Groups" is checked in the "Groups List Popup Menu" prior to running the script.

                Thanks in advance!

                1. Kitch Membery @Kitch2020-11-10 23:05:51.308Z

                  I think I've figured it out. I'll report back with my workaround asap :-)

                  1. In reply toKitch:
                    Kitch Membery @Kitch2020-11-10 23:10:35.177Z2020-11-10 23:25:45.071Z

                    Boom! Fixed with some menu filtering :-)

                    function doWithGroupsSuspended(callback) {
                        sf.ui.proTools.groupsEnsureGroupListIsVisible();
                    
                        const groupListPopup = sf.ui.proTools.mainWindow.groupListPopupButton;
                        var menuWasClicked = groupListPopup.popupMenuFetchAllItems().menuItems
                            .filter(menuItem => menuItem.element.isMenuChecked)
                            .filter(checkedItems => checkedItems.names.includes('Suspend All Groups')).length === 1;
                    
                        sf.ui.proTools.appActivateMainWindow();
                    
                        if (!menuWasClicked) {
                            groupListPopup.popupMenuSelect({ menuPath: ["Suspend All Groups"], });
                        }
                    
                        try {
                            callback();
                        } finally {
                            if (!menuWasClicked) {
                                groupListPopup.popupMenuSelect({ menuPath: ["Suspend All Groups"], });
                            }
                        }
                    }
                    
                    doWithGroupsSuspended(function () {
                        log('Test Log');
                    });
                    
                2. In reply toChris_Shaw:

                  Hey @Kitch , @Chris_Shaw and @chrscheuer ! Just resurrecting this thread to see if I can implement it in to my macros..
                  Basically I want to do what Chris suggested, which is to Suspend All Groups (IF not already suspended), run the macro, then return Group status to the state it was before running.
                  I see this as javascript here, but I'm a macro builder and hoping someone could break it in to 1 or 2 pieces of code I can put at the beginning and ending of my action chain. If that's possible that would be ideal!
                  If not, here is the script version of my macros. Maybe we can just implement the code correctly in here?
                  Script one:

                  
                  sf.ui.proTools.mainWindow.elementRaise();
                  
                  /* //Calling command "Set Views: Edit Window - Main Area" from package "Kitch's Command Template Collection" (installed from user/pkg/version "uOwKfD26NbWKAWotin3dmnSne7B3/ckdt68led0000yz10dsi5hqgy/cklua4ezl0005gw10s4qp897s")
                  sf.soundflow.runCommand({
                      commandId: 'user:cky89mb710006mx10pbwr4gzx:ckdt9nmjb0005jw103ityzq5i',
                      props: {
                          viewInsertsAE: "Enable",
                          viewInsertsFJ: "Enable",
                          viewSendsAE: "Enable",
                          viewSendsFJ: "Enable",
                      }
                  }); */
                  
                  //Calling command "!Remove Inactive Inserts ONLY" from package "Default Package"
                  sf.soundflow.runCommand({
                      commandId: 'package:ckyhvbsc10004tg10x77xsc1s',
                      props: {}
                  });
                  
                  /* //Calling command "Set Views: Edit Window - Main Area" from package "Kitch's Command Template Collection" (installed from user/pkg/version "uOwKfD26NbWKAWotin3dmnSne7B3/ckdt68led0000yz10dsi5hqgy/cklua4ezl0005gw10s4qp897s")
                  sf.soundflow.runCommand({
                      commandId: 'user:cky89mb710006mx10pbwr4gzx:ckdt9nmjb0005jw103ityzq5i',
                      props: {
                          viewInsertsAE: "Disable",
                          viewInsertsFJ: "Disable",
                          viewSendsAE: "Disable",
                          viewSendsFJ: "Disable",
                      }
                  }); */
                  
                  

                  SCRIPT 2:

                  
                  sf.ui.proTools.mainWindow.elementRaise();
                  
                  /* //Calling command "Set Views: Edit Window - Main Area" from package "Kitch's Command Template Collection" (installed from user/pkg/version "uOwKfD26NbWKAWotin3dmnSne7B3/ckdt68led0000yz10dsi5hqgy/cklua4ezl0005gw10s4qp897s")
                  sf.soundflow.runCommand({
                      commandId: 'user:cky89mb710006mx10pbwr4gzx:ckdt9nmjb0005jw103ityzq5i',
                      props: {
                          viewInsertsAE: "Enable",
                          viewInsertsFJ: "Enable",
                          viewSendsAE: "Enable",
                          viewSendsFJ: "Enable",
                      }
                  }); */
                  
                  //Calling command "!Remove Inactive SENDS " from package "Default Package"
                  sf.soundflow.runCommand({
                      commandId: 'package:ckyhvcbiz0005tg101ttt6xeg',
                      props: {}
                  });
                  
                  /* //Calling command "Set Views: Edit Window - Main Area" from package "Kitch's Command Template Collection" (installed from user/pkg/version "uOwKfD26NbWKAWotin3dmnSne7B3/ckdt68led0000yz10dsi5hqgy/cklua4ezl0005gw10s4qp897s")
                  sf.soundflow.runCommand({
                      commandId: 'user:cky89mb710006mx10pbwr4gzx:ckdt9nmjb0005jw103ityzq5i',
                      props: {
                          viewInsertsAE: "Disable",
                          viewInsertsFJ: "Disable",
                          viewSendsAE: "Disable",
                          viewSendsFJ: "Disable",
                      }
                  }); */
                  
                  
                  1. Kitch Membery @Kitch2022-04-17 19:11:44.839Z

                    Hi @Brett_Ryan_Stewart,

                    I think I have a function that does this already... I'll take a look and get back to you. :-)

                    1. Kitch Membery @Kitch2022-04-17 19:22:24.993Z

                      Hi Brett_Ryan_Stewart,

                      Untested, but this should do the trick...

                      function doWithGroupsSuspended(callback) {
                          sf.ui.proTools.groupsEnsureGroupListIsVisible();
                      
                          const groupListPopup = sf.ui.proTools.mainWindow.groupListPopupButton;
                          var menuWasClicked = groupListPopup.popupMenuFetchAllItems().menuItems
                              .filter(menuItem => menuItem.element.isMenuChecked)
                              .filter(checkedItems => checkedItems.names.includes('Suspend All Groups')).length === 1;
                      
                          sf.ui.proTools.appActivateMainWindow();
                      
                          if (!menuWasClicked) {
                              //Toggle Suspend All Groups via Groups List Popup menu.
                              groupListPopup.popupMenuSelect({ menuPath: ["Suspend All Groups"], });
                      
                              //Toggle Suspend All Groups with Keyboard Shortcut
                              //sf.keyboard.press({ keys: "cmd+shift+g", });
                          }
                      
                          try {
                              callback();
                          } finally {
                              if (!menuWasClicked) {
                                  //Toggle Suspend All Groups via Groups List Popup menu.
                                  groupListPopup.popupMenuSelect({ menuPath: ["Suspend All Groups"], });
                      
                                  //Toggle Suspend All Groups with Keyboard Shortcut
                                  //sf.keyboard.press({ keys: "cmd+shift+g", });
                              }
                          }
                      }
                      
                      function main() {
                          sf.ui.proTools.mainWindow.elementRaise();
                      
                          /* //Calling command "Set Views: Edit Window - Main Area" from package "Kitch's Command Template Collection" (installed from user/pkg/version "uOwKfD26NbWKAWotin3dmnSne7B3/ckdt68led0000yz10dsi5hqgy/cklua4ezl0005gw10s4qp897s")
                          sf.soundflow.runCommand({
                              commandId: 'user:cky89mb710006mx10pbwr4gzx:ckdt9nmjb0005jw103ityzq5i',
                              props: {
                                  viewInsertsAE: "Enable",
                                  viewInsertsFJ: "Enable",
                                  viewSendsAE: "Enable",
                                  viewSendsFJ: "Enable",
                              }
                          }); */
                      
                          //Calling command "!Remove Inactive Inserts ONLY" from package "Default Package"
                          sf.soundflow.runCommand({
                              commandId: 'package:ckyhvbsc10004tg10x77xsc1s',
                              props: {}
                          });
                      
                          /* //Calling command "Set Views: Edit Window - Main Area" from package "Kitch's Command Template Collection" (installed from user/pkg/version "uOwKfD26NbWKAWotin3dmnSne7B3/ckdt68led0000yz10dsi5hqgy/cklua4ezl0005gw10s4qp897s")
                          sf.soundflow.runCommand({
                              commandId: 'user:cky89mb710006mx10pbwr4gzx:ckdt9nmjb0005jw103ityzq5i',
                              props: {
                                  viewInsertsAE: "Disable",
                                  viewInsertsFJ: "Disable",
                                  viewSendsAE: "Disable",
                                  viewSendsFJ: "Disable",
                              }
                          }); */
                      
                      }
                      
                      doWithGroupsSuspended(() => {
                          main();
                      });
                      

                      You can apply this to your other script by replacing the contents of the main function with your code.

                      Essentially what it does is runs all the code before the try section of the doWithGroupsSuspended then runs the callback (which is the main function), then finally once it completes that runs the finally block of the doWithGroupsSuspended function.

                      I hope that helps.

                      Rock on!

                      1. @Kitch you're a wiz! Thank you, it's working great. What can be added to change the track height in Edit window to make all Insert / Send slots visible?

                        This full command is intended to remove all inactive plugins from selected tracks, but it's not working unless the track(s) is at a height where all slots are visible vertically.

                        This is the script so far:

                        function doWithGroupsSuspended(callback) {
                            sf.ui.proTools.groupsEnsureGroupListIsVisible();
                        
                            const groupListPopup = sf.ui.proTools.mainWindow.groupListPopupButton;
                            var menuWasClicked = groupListPopup.popupMenuFetchAllItems().menuItems
                                .filter(menuItem => menuItem.element.isMenuChecked)
                                .filter(checkedItems => checkedItems.names.includes('Suspend All Groups')).length === 1;
                        
                            sf.ui.proTools.appActivateMainWindow();
                        
                            if (!menuWasClicked) {
                                //Toggle Suspend All Groups via Groups List Popup menu.
                                groupListPopup.popupMenuSelect({ menuPath: ["Suspend All Groups"], });
                        
                                //Toggle Suspend All Groups with Keyboard Shortcut
                                //sf.keyboard.press({ keys: "cmd+shift+g", });
                            }
                        
                            try {
                                callback();
                            } finally {
                                if (!menuWasClicked) {
                                    //Toggle Suspend All Groups via Groups List Popup menu.
                                    groupListPopup.popupMenuSelect({ menuPath: ["Suspend All Groups"], });
                        
                                    //Toggle Suspend All Groups with Keyboard Shortcut
                                    //sf.keyboard.press({ keys: "cmd+shift+g", });
                                }
                            }
                        }
                        
                        function main() {
                            sf.ui.proTools.mainWindow.elementRaise();
                        
                            /* //Calling command "Set Views: Edit Window - Main Area" from package "Kitch's Command Template Collection" (installed from user/pkg/version "uOwKfD26NbWKAWotin3dmnSne7B3/ckdt68led0000yz10dsi5hqgy/cklua4ezl0005gw10s4qp897s")
                            sf.soundflow.runCommand({
                                commandId: 'user:cky89mb710006mx10pbwr4gzx:ckdt9nmjb0005jw103ityzq5i',
                                props: {
                                    viewInsertsAE: "Enable",
                                    viewInsertsFJ: "Enable",
                                    viewSendsAE: "Enable",
                                    viewSendsFJ: "Enable",
                                }
                            }); */
                        
                            //Calling command "!Remove Inactive Inserts ONLY" from package "Default Package"
                            sf.soundflow.runCommand({
                                commandId: 'package:ckyhvbsc10004tg10x77xsc1s',
                                props: {}
                            });
                        
                            /* //Calling command "Set Views: Edit Window - Main Area" from package "Kitch's Command Template Collection" (installed from user/pkg/version "uOwKfD26NbWKAWotin3dmnSne7B3/ckdt68led0000yz10dsi5hqgy/cklua4ezl0005gw10s4qp897s")
                            sf.soundflow.runCommand({
                                commandId: 'user:cky89mb710006mx10pbwr4gzx:ckdt9nmjb0005jw103ityzq5i',
                                props: {
                                    viewInsertsAE: "Disable",
                                    viewInsertsFJ: "Disable",
                                    viewSendsAE: "Disable",
                                    viewSendsFJ: "Disable",
                                }
                            }); */
                        
                        }
                        
                        doWithGroupsSuspended(() => {
                            main();
                        });
                        
                        1. Kitch Membery @Kitch2022-04-21 09:54:12.126Z

                          Hi @Brett_Ryan_Stewart,

                          You can use a function like this to set all the track heights to medium :-)

                          function setTrackHeight(height) {
                              sf.ui.proTools.appActivateMainWindow();
                          
                              var f = sf.ui.proTools.selectedTrack.frame;
                              var popupMenu = sf.ui.proTools.selectedTrack.popupMenuOpenFromElement({
                                  relativePosition: { x: f.w - 10, y: 5 },
                                  isOption: true,
                                  //isShift: true,
                              }).popupMenu;
                              popupMenu.menuClickPopupMenu({
                                  menuPath: [height]
                              });
                          }
                          
                          setTrackHeight("medium");
                          
                          1. awesome thanks!!

                    2. J
                      In reply toChris_Shaw:

                      Hey guys, thanks for this post! I'm trying to use this with PT Studio 2024.6.0, to have a Suspend Groups button on my Stream Deck, but no luck here. Any chance you could revisit the code for it? Thank you!