No internet connection
  1. Home
  2. Macro and Script Help

I/O Setup New Path name field interaction broken with PT2024.10

By Forrester Savell @Forrester_Savell
    2024-12-02 23:33:30.621Z

    Title

    I/O Setup New Path name field interaction broken with PT2024.10

    What do you expect to happen when you run the script/macro?

    Creates a new bus in the I/O window

    Are you seeing an error?

    What happens when you run this script?

    With the PT2024.10 update the script can no longer access the 'name' field. New created buses just use default name.

    How were you running this script?

    I clicked the "Run Script" or "Run Macro" button in SoundFlow

    How important is this issue to you?

    5

    Details

    {
        "inputExpected": "Creates a new bus in the I/O window",
        "inputIsError": false,
        "inputWhatHappens": "With the PT2024.10 update the script can no longer access the 'name' field.  New created buses just use default name.",
        "inputHowRun": {
            "key": "-MpfwYA4I6GGlXgvp5j1",
            "title": "I clicked the \"Run Script\" or \"Run Macro\" button in SoundFlow"
        },
        "inputImportance": 5,
        "inputTitle": "I/O Setup New Path name field interaction broken with PT2024.10"
    }

    Source

    const { busWidth, num } = event.props
    
    function createBuses(createNewBus, busWidth, numberOfBuses) {
    
        sf.keyboard.press({ keys: 'left' });
        //Open I/O Window
        sf.ui.proTools.menuClick({
            menuPath: ["Setup", "I/O..."],
        });
    
        const ioWin = sf.ui.proTools.windows.whoseTitle.is('I/O Setup').first;
    
        //Select "Bus" Tab
        ioWin.radioButtons.whoseTitle.startsWith('Bus').first.elementClick();
    
        //Wait for Tab ("Active Busses" text is unique to the bus tab)
        ioWin.children.whoseRole.is("AXStaticText").whoseValue.is('Active Busses:').first.elementWaitFor();
    
        //Click 'New Path...'
        ioWin.buttons.whoseTitle.is("New Path...").first.elementClick();
    
        sf.ui.proTools.windows.whoseTitle.is("New Paths").first.elementWaitFor();
    
        const numberField = sf.ui.proTools.windows.whoseTitle.is("New Paths").first.textFields.whoseTitle.is("Number of new paths").first
    
        if (numberField.value.invalidate().value.trim() !== numberOfBuses) {
            numberField.elementClick();
    
            sf.keyboard.type({ text: numberOfBuses });
    
            var i = 0;
            while (numberField.value.invalidate().value !== numberOfBuses) {
                sf.wait({ intervalMs: 30 });
            }
        }
    
        sf.ui.proTools.windows.whoseTitle.is("New Paths").first.popupButtons.whoseDescription.is("Format").first.popupMenuSelect({
            menuPath: [busWidth]
        })
    
        log(createNewBus)
        sf.ui.proTools.windows.whoseTitle.is("New Paths").first.textFields.allItems[1].elementSetTextFieldWithAreaValue({
            value: createNewBus,
    
        })
         
        sf.ui.proTools.windows.whoseTitle.is("New Paths").first.buttons.whoseTitle.is("Create").first.elementClick();
        sf.ui.proTools.windows.whoseTitle.is("I/O Setup").first.buttons.whoseTitle.is("OK").first.elementClick();
    
        
    }
    
    
    function main() {
        //Activate Pro Tools
        sf.ui.proTools.appActivate();
        sf.ui.proTools.invalidate();
    
        let num;
        while (true) {
            const input = prompt(`Bus number?`);
    
            if (input == "null" || input == null) {
                throw 0; // Handle canceling the prompt
            }
    
            num = Number(input);
    
            if (!isNaN(num) && input.trim() !== "") {
                break; // Exit the loop if the user enters a valid number
            } else {
                alert('Please enter a valid number');
            }
        }
    
        const createNewBus = prompt(`Bus name?`);
        if (createNewBus == "null" || createNewBus == null) {
            throw 0; // Handle canceling the prompt
        }
    
        log(num.toString());
    
    
        //Get focus back
        sf.wait({ intervalMs: 100 });
        sf.ui.proTools.appActivate();
        sf.wait({ intervalMs: 50 });
        sf.ui.proTools.mainWindow.transportViewCluster.transportButtons.stopButton.elementClick();
    
    
        //Create output busses
        createBuses(createNewBus, busWidth, num.toString())
    }
    
    main()
    

    Links

    User UID: sKu19XXNXHYSdEMmZtHz8CozbdS2

    Feedback Key: sffeedback:sKu19XXNXHYSdEMmZtHz8CozbdS2:-OD8iBwTmR4vUlbyvZbc

    Feedback ZIP: KuDbazB6GsMcDuamO/ERrtjin9xYBdXXvuZz+p7jZDfyIUb6FEby7qFdXCKJUZSD5zoy2Q2yqPLiS+bjqzwHLNQrs02i4fxp4m9b7IeMUoL3jI5sTc9bKD/e66FwlpZdVgw3GsbFWQu0rG/0reSB7DuqfrrOzUP3nPalBEtQtEtDpugTcbN6NQGvxwFPVYJJYrNBOwzISAjSZDmeg/RWUYEt/lomccnMRkEHZRwzJuEcHNo5SRj7lfjop2ky2iQ/wYq5eN6iDTdcp8NdtXZw24TRNjh1gMuLRO49rzVK7DNgSJvoZxpGB4i5qdpSrv019Lc1AMAImQIzkO0+K4dqEg6khkJhUNo2wh52AzuRoyo=

    Solved in post #11, click to view
    • 12 replies

    There are 12 replies. Estimated reading time: 14 minutes

    1. F
      Forrester Savell @Forrester_Savell
        2024-12-03 00:09:03.241Z

        Solved with a sf.wait({ intervalMs: 60 }); before line 42.

        1. Kitch Membery @Kitch2024-12-03 00:56:02.868Z

          Hi @Forrester_Savell,

          Using arbitrary wait times is not a great solution here. A better approach would be to use the "elementWaitFor()" method before line 42.

          sf.ui.proTools.windows.whoseTitle.is("New Paths").first.textFields.allItems[1].elementWaitFor();
          

          Let me know if that does not work, as there may be another more robust solution. :-)

          1. FForrester Savell @Forrester_Savell
              2024-12-03 01:07:40.787Z2024-12-03 01:49:33.762Z

              Hey @Kitch

              The elementWaitFor() doesn't seem to work for me. So far the only solution I've found was the sf.wait({ intervalMs: 60 })

              Ironically this was the issue that prompted my post about Known changes documentation, but I don't think this is caused by the PT update specifically. I'm transitioning from Rosetta to Native in PT and I think the massive jump in speed has broken a bunch of scripts. Everything happens a lot faster in Native mode.
              EDIT
              I just checked in Rosetta mode, this has nothing to do with Rosetta/Native. It would appear to be a 2024.10 or Sequoia issue.

              1. FForrester Savell @Forrester_Savell
                  2024-12-03 06:02:39.264Z2024-12-03 06:09:23.704Z

                  I thought the solution might be something like what Chad added to the Create New Track script on protools 2024.10, The command is being made in stereo, not mono. (soundflow default pro tools command) However, there is no problem with the other commands that make the track. #post-8 but that didn't work.

                  If I move the

                  sf.ui.proTools.windows.whoseTitle.is("New Paths").first.textFields.allItems[1].elementSetTextFieldWithAreaValue({
                          value: createNewBus,
                   })
                  

                  to line 23, so that it renames first, then deals with numbers and Format, its working for the original simple function I wrote above.

                  However, this doesn't help if the script requires multiple buses to be added, as the +bus are made first, then the names are placed:

                  function createBusBatch(busNames, busWidth) {
                      const batchSize = 16; // Maximum number of paths that can be created at once
                      let currentIndex = 0;
                  
                      try {
                          while (currentIndex < busNames.length) {
                              // Extract a batch of bus names to process
                              const batch = busNames.slice(currentIndex, currentIndex + batchSize);
                  
                              const ioWin = sf.ui.proTools.windows.whoseTitle.is('I/O Setup').first;
                              sf.ui.proTools.invalidate();
                  
                              ioWin.buttons.whoseTitle.is("New Path...").first.elementClick();
                  
                              const newPathWin = sf.ui.proTools.windows.whoseTitle.is("New Paths").first.invalidate();
                              newPathWin.elementWaitFor();
                  
                              for (let i = 0; i < batch.length - 1; i++) {
                                  newPathWin.buttons.whoseTitle.is("Add row").first.elementClick();
                              }
                  
                              if (busWidth !== 'Mono') {
                                  for (let i = 0; i < batch.length; i++) {
                                      newPathWin.popupButtons.whoseDescription.is("Format").allItems[i].popupMenuSelect({
                                          menuPath: [busWidth],
                                      });
                                  }
                              }
                  
                              batch.forEach((busName, i) => {
                                  sf.wait({ intervalMs: 60 });
                  
                                  newPathWin.textFields.allItems[i * 2 + 1].elementSetTextFieldWithAreaValue({ value: busName });
                              });
                  
                              newPathWin.checkBoxes.whoseTitle.is("Auto-create sub paths").first.checkboxSet({ targetValue: 'Enable' });
                  
                              newPathWin.buttons.whoseTitle.is("Create").first.elementClick();
                              newPathWin.elementWaitFor({ waitType: "Disappear" });
                  
                              // Move to the next batch
                              currentIndex += batchSize;
                          }
                      } catch (error) {
                          log(`Error creating bus batch: ${error}`);
                          throw error;
                      }
                  }
                  

                  Line 31 has the sf.wait({ intervalMs: 60 }) necessary to correctly name the buses.

                  1. Kitch Membery @Kitch2024-12-03 06:49:15.475Z2024-12-03 06:56:05.745Z

                    Hi @Forrester_Savell,

                    On re-reading the script there may be a different issue here...

                    Due to changes that Apple made in Sonoma OS, popup menu calls are no longer synchronous.

                    This will cause issues when directly sequencing certain events... eg (menu -> popup menu) or (popup menu -> popup menu) etc...type actions with no wait in between.

                    Therefore, you'll now need to add implementation to ensure menus close before the next action.

                    It's important to note that when working with asynchronous tasks the fix should never be to insert an arbitrary wait (sf.wait({intervalMs:XXXX)) time, it's better to wait for a specific condition to be true rather than use arbitrary delays which might be unreliable or inefficient.

                    So for these situations, you'd need to implement a waitFor() method with a callback to ensure that each popup menu closes before moving on.

                    This approach will make your script more robust and precise, avoiding unnecessary waits or premature actions.

                    I've simplified the section of your code where you are experiencing the issue, adding a waitfor() method that waits for the popup menu to no longer have accessible children (proving the menu is closed).

                    Let me know if you need further explanation.

                    const busWidth = "Mono";
                    const createNewBus = "NEW NAME"
                    
                    sf.ui.proTools.appActivate();
                    
                    const newPathsWindow = sf.ui.proTools.windows.whoseTitle.is("New Paths").first;
                    
                    const formatPopupMenu = newPathsWindow.popupButtons.whoseDescription.is("Format").first;
                    const pathTextField = newPathsWindow.textFields.allItems[1];
                    
                    // Select bus width
                    formatPopupMenu.popupMenuSelect({ menuPath: [busWidth], });
                    
                    // Wait for the menu to close.
                    sf.waitFor({
                        // When the callback returns true within the timeout the script will continue
                        // Wait till the Popup menu no longer has accessible children. 
                        callback: () => !formatPopupMenu.invalidate().children.first.exists,
                        timeout: 2000,
                    });
                    
                    // Set "Path" name
                    pathTextField.elementSetTextFieldWithAreaValue({ value: createNewBus });
                    

                    The above script is untested as I'm on my laptop, which is on Ventura. So let me know if it works for you.

                    Rock on!

                    1. FForrester Savell @Forrester_Savell
                        2024-12-03 08:41:23.094Z

                        Thanks @Kitch, totally hear you on the arbitrary wait times.

                        I used your code verbatim (with the New Paths window open of course) but I couldn't get it to work, it didn't time-out either.
                        However I did manage to get it working using mouseClickElement()

                        const busWidth = "Mono";
                        const createNewBus = "NEW NAME";
                        
                        sf.ui.proTools.appActivate();
                        
                        const newPathsWindow = sf.ui.proTools.windows.whoseTitle.is("New Paths").first;
                        
                        const formatPopupMenu = newPathsWindow.popupButtons.whoseDescription.is("Format").first;
                        
                        const pathTextField = newPathsWindow.textFields.allItems[1];
                        
                        // Select bus width
                        formatPopupMenu.popupMenuSelect({ menuPath: [busWidth] });
                        
                        pathTextField.mouseClickElement();
                        
                        // Set "Path" name using simulated keyboard input
                        pathTextField.elementSetTextFieldWithAreaValue({
                            value: createNewBus,
                        });
                        
                        1. Kitch Membery @Kitch2024-12-03 08:43:11.948Z

                          My code may be incorrect... I'll test it tomorrow in Sonoma.

                          1. Kitch Membery @Kitch2024-12-03 08:45:23.470Z

                            Did it throw an error?

                            1. FForrester Savell @Forrester_Savell
                                2024-12-03 08:47:42.476Z

                                I preemptively posted. So I was able to get it to work with the above code.

                                No error message on your code though.

                              • Kitch Membery @Kitch2024-12-03 19:27:43.850Z

                                Hi @Forrester_Savell

                                On my Sonoma machine now and I worked out the issue here...

                                There appears to be a slight delay before the “New Paths” window becomes the frontmost window.

                                This delay is causing issues, due to the popup menu overlapping the text field you intend to modify.

                                Here's a script that should resolve this issue by waiting for the "New Paths" window to become frontmost, eliminating the need for a manual wait.

                                const busWidth = "Mono";
                                const newBusName = "NEW NAME"
                                
                                sf.ui.proTools.appActivate();
                                
                                const newPathsWindow = sf.ui.proTools.windows.whoseTitle.is("New Paths").first;
                                
                                const formatPopupMenu = newPathsWindow.popupButtons.whoseDescription.is("Format").first;
                                const pathTextField = newPathsWindow.textFields.allItems[1];
                                
                                // Select bus width
                                formatPopupMenu.popupMenuSelect({
                                    menuPath: [busWidth],
                                });
                                
                                // Wait for the Popup menu to close
                                sf.waitFor({
                                    callback: () => !formatPopupMenu.invalidate().children.first.exists,
                                    timeout: 2000,
                                }, `Failed waiting for the popup menu to close.`);
                                
                                
                                // Wait for the "New Paths" window to be frontmost
                                sf.waitFor({
                                    callback: () => sf.ui.proTools.windows.first.title.value === "New Paths",
                                    timeout: 2000,
                                }, `Failed waiting for the "New Paths" window to be in focus.`)
                                
                                // Set "Path" name
                                pathTextField.elementSetTextFieldWithAreaValue({ value: newBusName });
                                

                                Note: You may not need to wait for the popup menu to close in this instance, but I left the following code in the script as it is good practice in Sonoma+

                                // Wait for the Popup menu to close
                                sf.waitFor({
                                    callback: () => !formatPopupMenu.invalidate().children.first.exists,
                                    timeout: 2000,
                                }, `Failed waiting for the popup menu to close.`);
                                
                                ReplySolution
                                1. FForrester Savell @Forrester_Savell
                                    2024-12-03 23:35:33.982Z

                                    That's some great sleuthing @Kitch ! Works at my end too.

                                    I'd love to know how you approached solving this. I was looking at the elementDebug like you showed me on the last Zoom we had, but to no avail. What was the breadcrumb that led you to the "New Paths" window focus being the issue?

                                    1. Kitch Membery @Kitch2024-12-04 00:36:21.690Z

                                      Hi @Forrester,

                                      It may be better to walk you through my approach over a quick Zoom if you are around?

                                      Let me know and I can email you a link. :-)