Global.State Issue or Menu recall?
Title
Global.State Issue or Menu recall?
What do you expect to happen when you run the script/macro?
I have a script I wrote ages ago that stopped working a few months back with an updated of PT or Soundflow, I don't remember. But trying to troubleshoot it now and struggling. I read that there was a change in how info is recovered from Global state, and I've tried to fix this accordingly and no joy. But I also can't tell what exactly it is failing on as it isn't giving me an error, it just stops halfway through and doesn't export.
The idea of the script is a have clip groups on a channel named "Export", then a load of output busses after that in my project. So I select all the buses I want to export, AND the Export channel strip, then Soundflow takes the name from the Clip Group on the Export channel, copies it and uses it for the song title. It then deselects the Export channel strip and just exports the others. It iterates over all the clip groups so I can export a big session quickly.
It stops at the point I think it's trying to open the Track menu item "bounce..." I tried replacing that menu call with the keyboard shortcut and that also didn't work. Maybe that's not what is tripping it up but I see it opens the rename, copies the text, closes the rename, selects the correct tracks, then it just kind of fails with no error
Any help fixing this is much appreciated!
Are you seeing an error?
What happens when you run this script?
It stops at the point I think it's trying to open the Track menu item "bounce..." I tried replacing that menu call with the keyboard shortcut and that also didn't work. Maybe that's not what is tripping it up but I see it opens the rename, copies the text, closes the rename, selects the correct tracks, then it just kind of fails with no error
How were you running this script?
I used a keyboard shortcut within the target app
How important is this issue to you?
5
Details
{ "inputExpected": "I have a script I wrote ages ago that stopped working a few months back with an updated of PT or Soundflow, I don't remember. But trying to troubleshoot it now and struggling. I read that there was a change in how info is recovered from Global state, and I've tried to fix this accordingly and no joy. But I also can't tell what exactly it is failing on as it isn't giving me an error, it just stops halfway through and doesn't export.\n\nThe idea of the script is a have clip groups on a channel named \"Export\", then a load of output busses after that in my project. So I select all the buses I want to export, AND the Export channel strip, then Soundflow takes the name from the Clip Group on the Export channel, copies it and uses it for the song title. It then deselects the Export channel strip and just exports the others. It iterates over all the clip groups so I can export a big session quickly.\n\nIt stops at the point I think it's trying to open the Track menu item \"bounce...\" I tried replacing that menu call with the keyboard shortcut and that also didn't work. Maybe that's not what is tripping it up but I see it opens the rename, copies the text, closes the rename, selects the correct tracks, then it just kind of fails with no error\n\nAny help fixing this is much appreciated!", "inputIsError": false, "inputWhatHappens": "It stops at the point I think it's trying to open the Track menu item \"bounce...\" I tried replacing that menu call with the keyboard shortcut and that also didn't work. Maybe that's not what is tripping it up but I see it opens the rename, copies the text, closes the rename, selects the correct tracks, then it just kind of fails with no error", "inputHowRun": { "key": "-Mpfwh4RkPLb2LPwjePT", "title": "I used a keyboard shortcut within the target app" }, "inputImportance": 5, "inputTitle": "Global.State Issue or Menu recall?" }
Source
sf.ui.proTools.appActivate();
//Ensure Link Timeline and Edit Selection is ON
var TimelineEditwasLinked = sf.ui.proTools.getMenuItem('Options', 'Link Timeline and Edit Selection').isMenuChecked;
if (!TimelineEditwasLinked) {
sf.ui.proTools.menuClick({
menuPath: ["Options", "Link Timeline and Edit Selection"],
});
}
//Ensure Link Track and Edit Selection is ON
var TrackEditwasLinked = sf.ui.proTools.getMenuItem('Options', 'Link Track and Edit Selection').isMenuChecked;
if (!TrackEditwasLinked) {
sf.ui.proTools.menuClick({
menuPath: ["Options", "Link Track and Edit Selection"],
});
}
//Clear Clip Search//
sf.keyboard.press({
keys: "cmd+shift+d",
});
// Remove "Export" Track from the Selection
sf.ui.proTools.trackSelectByName({
names: sf.ui.proTools.selectedTrackNames.filter(n => n.toLowerCase().indexOf('Export'.toLowerCase()) < 0),
deselectOthers: true,
});
/// Get Selected track names to variable
globalState.selectedTracks = Array.from(sf.ui.proTools.selectedTrackNames);
//Get the selection and store it in globalState variable 'rememberedSelection'
globalState.rememberedSelection = sf.ui.proTools.selectionGet();
//Select track "EXPORT"
sf.ui.proTools.mainWindow.invalidate();
sf.ui.proTools.trackGetByName({ name: "Export", makeVisible: true }).track.trackSelect();
function PrintBuses() {
sf.ui.proTools.appActivateMainWindow();
sf.ui.proTools.menuClick({menuPath: ["Clip", "Rename..."],});
sf.keyboard.press({keys: "cmd+c"});
sf.ui.proTools.windows.whoseTitle.is("Name").first.buttons.whoseTitle.is("OK").first.elementClick();
sf.ui.proTools.trackSelectByName({ names: Array.from(globalState.selectedTracks) })
sf.ui.proTools.menuClick({menuPath: ["Track", "Bounce..."],});
sf.ui.proTools.windows.whoseTitle.is("Track Bounce").first.elementWaitFor();
sf.keyboard.press({keys: "cmd+v",});
sf.ui.proTools.windows.whoseTitle.is("Track Bounce").first.buttons.whoseTitle.is("Bounce").first.elementClick();
sf.wait({ intervalMs: 1000 });
sf.keyboard.press({keys: "return",});
sf.wait({ intervalMs: 100 });
sf.ui.proTools.waitForNoModals();
sf.ui.proTools.appActivate();
// Recall track by name using variable selectedTracks
sf.ui.proTools.trackSelectByName({ names: Array.from(globalState.selectedTracks) })
//Select track "EXPORT"
sf.ui.proTools.mainWindow.invalidate();
sf.ui.proTools.trackGetByName({ name: "Export", makeVisible: true }).track.trackSelect();
}
sf.ui.proTools.clipDoForEachSelectedClip({
action: PrintBuses,
onError: "Continue"
});
// Recall track by name using variable selectedTracks
sf.ui.proTools.trackSelectByName({ names: globalState.selectedTracks })
//Recall selection from globalState variable 'rememberedSelection'
sf.ui.proTools.selectionSet({
selectionStart: globalState.rememberedSelection.selectionStart,
selectionLength: globalState.rememberedSelection.selectionLength,
});
//Restore Link Timeline and Edit selection
if (!TimelineEditwasLinked) {
sf.ui.proTools.menuClick({
menuPath: ["Options", "Link Timeline and Edit Selection"],
});
}
//Restore Link Track and Edit selection
if (!TrackEditwasLinked) {
sf.ui.proTools.menuClick({
menuPath: ["Options", "Link Track and Edit Selection"],
});
}
Links
User UID: ViQPEeIY8QVwQ40kgvaM3cNtbH03
Feedback Key: sffeedback:ViQPEeIY8QVwQ40kgvaM3cNtbH03:-O3bT1_vAFaP1cooW2sA
Feedback ZIP: qUF9ZTlzWgUigOy7+g28b6oiz6ZtBEgpfP5LNeJmCLXTLSs9wzh5MBLC1nsjMaSOeC7a/0mCYeoAyT2nlNWemPFwr5jxoPkYKwDhVytwxA/snnoZ3OC8nXT+JuNZexDCR9KMQ8fpZXzxoT2wDJxOl76tR5kT2izm6BzSYI1kWnf4Y7QhYzLTX3U92hZqzg7hCwRBsohoLaEnDPS20MqRai3n4JTogK7BqWLf6L7ytkQQTEtbUS7WAN/N8KVzjURlUvn9cbSg9A0DUrICeeqqQq28DGjNajVLGVIBgjQ8qt7HbXoxRXLnzDpCT4yZec/nqaUUP9PRsUAfLFlJoGsLJQ==
- In reply toPete_Watson⬆:Chad Wahlbrink @Chad2024-08-23 15:30:28.959Z
Hi @Pete_Watson,
Thanks for the question.
The main issue you are running into here is that on line 51, "Track Bounce..." could not be clicked from the "Track" menu. When the tracks are selected in line 50, the menu is not updated accordingly. We can force those menus to refresh by addingsf.keyboard.press({ keys: "left" });
after line 50.
I did a quick refactor on the whole script and am sharing that below. It was working fine just by addingsf.keyboard.press({ keys: "left" });
after line 50, so if you prefer your current script, you can make that one change.
For my refactor, I swapped the global state variables for local variables. Unless you need those variables to persist between sequential runs of the script, storing the selected tracks and current selection in the global state is unnecessary. If there is a scenario I am missing, please let me know!
I also swapped the "cmd+c" and "cmd+v" keyboard simulations for UI-based automation. This is generally more stable.
sf.ui.proTools.invalidate().appActivate(); //Ensure Link Timeline and Edit Selection is ON var TimelineEditwasLinked = sf.ui.proTools.getMenuItem('Options', 'Link Timeline and Edit Selection').isMenuChecked; if (!TimelineEditwasLinked) { sf.ui.proTools.menuClick({ menuPath: ["Options", "Link Timeline and Edit Selection"], }); } //Ensure Link Track and Edit Selection is ON var TrackEditwasLinked = sf.ui.proTools.getMenuItem('Options', 'Link Track and Edit Selection').isMenuChecked; if (!TrackEditwasLinked) { sf.ui.proTools.menuClick({ menuPath: ["Options", "Link Track and Edit Selection"], }); } //Clear Clip Search// sf.keyboard.press({ keys: "cmd+shift+d", }); // Remove "Export" Track from the Selection sf.ui.proTools.trackSelectByName({ names: sf.ui.proTools.selectedTrackNames.filter(n => n.toLowerCase().indexOf('Export'.toLowerCase()) < 0), deselectOthers: true, }); /// Get Selected track names to variable let selectedTracks = sf.ui.proTools.selectedTrackNames; //Get the selection and store it in variable 'rememberedSelection' let rememberedSelection = sf.ui.proTools.selectionGet(); //Select track "EXPORT" sf.ui.proTools.mainWindow.invalidate(); sf.ui.proTools.trackGetByName({ name: "Export", makeVisible: true }).track.trackSelect(); function PrintBuses() { sf.ui.proTools.invalidate().appActivateMainWindow(); sf.ui.proTools.menuClick({ menuPath: ["Clip", "Rename..."], }); // sf.keyboard.press({keys: "cmd+c"}); // Store clip name in variable "clipName" then close clip rename window. let clipName = sf.ui.proTools.windows.whoseTitle.is("Name").first.groups.whoseTitle.is("Name").first.textFields.first.value.value; sf.ui.proTools.windows.whoseTitle.is("Name").first.buttons.whoseTitle.is("OK").first.elementClick(); sf.ui.proTools.windows.whoseTitle.is("Name").first.elementWaitFor({ waitType: "Disappear" }); sf.ui.proTools.trackSelectByName({ names: selectedTracks }); // Resetting the "Track" menu after selecting the tracks. sf.keyboard.press({ keys: "left" }); sf.ui.proTools.menuClick({ menuPath: ["Track", "Bounce..."], }); sf.ui.proTools.windows.whoseTitle.is("Track Bounce").first.elementWaitFor(); // sf.keyboard.press({keys: "cmd+v",}); // set Track Bounce name to clip name sf.ui.proTools.windows.whoseTitle.is("Track Bounce").first.textFields.first.elementSetTextFieldWithAreaValue({ value: clipName }); sf.ui.proTools.windows.whoseTitle.is("Track Bounce").first.buttons.whoseTitle.is("Bounce").first.elementClick(); sf.wait({ intervalMs: 1000 }); sf.keyboard.press({ keys: "return", }); sf.wait({ intervalMs: 100 }); sf.ui.proTools.waitForNoModals(); sf.ui.proTools.appActivate(); // Recall track by name using variable selectedTracks sf.ui.proTools.trackSelectByName({ names: selectedTracks }) // Select track "EXPORT" sf.ui.proTools.mainWindow.invalidate(); sf.ui.proTools.trackGetByName({ name: "Export", makeVisible: true }).track.trackSelect(); } sf.ui.proTools.clipDoForEachSelectedClip({ action: PrintBuses, // Commented this out so that we can see the errors thrown. // onError: "Continue" }); // Recall track by name using variable selectedTracks sf.ui.proTools.trackSelectByName({ names: selectedTracks }) //Recall selection from 'rememberedSelection' sf.ui.proTools.selectionSet({ selectionStart: rememberedSelection.selectionStart, selectionLength: rememberedSelection.selectionLength, }); //Restore Link Timeline and Edit selection if (!TimelineEditwasLinked) { sf.ui.proTools.menuClick({ menuPath: ["Options", "Link Timeline and Edit Selection"], }); } //Restore Link Track and Edit selection if (!TrackEditwasLinked) { sf.ui.proTools.menuClick({ menuPath: ["Options", "Link Track and Edit Selection"], }); }
- PIn reply toPete_Watson⬆:Pete Watson @Pete_Watson
Thanks so much - yes that works like it used to now!
Can you elaborate more on the menu not refreshing? Is this a Protools bug or new behaviour that has started to happen? I only ask as some other scripts have become temperamental so it may be the same issue, thanks
Chad Wahlbrink @Chad2024-08-27 14:18:04.340Z
Hey @Pete_Watson,
I'm glad the script is working better for you!
The Track menu not updating with track selection seems to have changed between Pro Tools 2023.12 and Pro Tools 2024.3. In 2023.12, the track menu shows all the correct options after runningsf.ui.proTools.trackSelectByName
. However, in 2024.3+, the Pro Tools menus need to be forcibly updated to reflect the current selection. I believe there were changes in Pro Tools 2024.3 to accommodate UI changes from macOS Sonoma.
For now, you can use an arbitrary key press likesf.keyboard.press({ keys: "left" });
, or if preferred, an action likesf.ui.proTools.appActivateMainWindow()
to refresh the menus in Pro Tools before using asf.ui.proTools.menuClick
command.
Here are some related posts:- PPete Watson @Pete_Watson
Hi Chad, thanks so much for that. Whilst it is now bouncing, it doesn't seem to be working the way it used to. It is now selecting all the clips on the Export track and using that selection to produce one long export range, rather than iterating through each clip name one by one. Any advice on that part as guessing that's something that got changed when you re-wrote it? Thanks
Chad Wahlbrink @Chad2024-09-05 15:55:28.958Z
Hi @Pete_Watson,
Thanks for the follow-up. Would you mind doing a quick screen recording of how the script is working on your machine? When I run the script as I understood it, it does perform the "clip-by-clip" functionality, but I may be misunderstanding your intended workflow.
https://www.loom.com/share/0956b429443648f78428fb315a7ec581?sid=bd16e7fc-50c2-4a8b-9c49-b941a1615754
Here's a quick video of how it works on my machine.Chad Wahlbrink @Chad2024-09-05 15:58:43.648Z
Also, if I use your original script and only add
sf.keyboard.press({ keys: "left" });
after line 50 (right before the menu click action), it does seem to work the same if you'd prefer to try that out:sf.ui.proTools.appActivate(); //Ensure Link Timeline and Edit Selection is ON var TimelineEditwasLinked = sf.ui.proTools.getMenuItem('Options', 'Link Timeline and Edit Selection').isMenuChecked; if (!TimelineEditwasLinked) { sf.ui.proTools.menuClick({ menuPath: ["Options", "Link Timeline and Edit Selection"], }); } //Ensure Link Track and Edit Selection is ON var TrackEditwasLinked = sf.ui.proTools.getMenuItem('Options', 'Link Track and Edit Selection').isMenuChecked; if (!TrackEditwasLinked) { sf.ui.proTools.menuClick({ menuPath: ["Options", "Link Track and Edit Selection"], }); } //Clear Clip Search// sf.keyboard.press({ keys: "cmd+shift+d", }); // Remove "Export" Track from the Selection sf.ui.proTools.trackSelectByName({ names: sf.ui.proTools.selectedTrackNames.filter(n => n.toLowerCase().indexOf('Export'.toLowerCase()) < 0), deselectOthers: true, }); /// Get Selected track names to variable globalState.selectedTracks = Array.from(sf.ui.proTools.selectedTrackNames); //Get the selection and store it in globalState variable 'rememberedSelection' globalState.rememberedSelection = sf.ui.proTools.selectionGet(); //Select track "EXPORT" sf.ui.proTools.mainWindow.invalidate(); sf.ui.proTools.trackGetByName({ name: "Export", makeVisible: true }).track.trackSelect(); function PrintBuses() { sf.ui.proTools.appActivateMainWindow(); sf.ui.proTools.menuClick({menuPath: ["Clip", "Rename..."],}); sf.keyboard.press({keys: "cmd+c"}); sf.ui.proTools.windows.whoseTitle.is("Name").first.buttons.whoseTitle.is("OK").first.elementClick(); sf.ui.proTools.trackSelectByName({ names: Array.from(globalState.selectedTracks) }) // Refresh Menus sf.keyboard.press({ keys: "left" }); sf.ui.proTools.menuClick({menuPath: ["Track", "Bounce..."],}); sf.ui.proTools.windows.whoseTitle.is("Track Bounce").first.elementWaitFor(); sf.keyboard.press({keys: "cmd+v",}); sf.ui.proTools.windows.whoseTitle.is("Track Bounce").first.buttons.whoseTitle.is("Bounce").first.elementClick(); sf.wait({ intervalMs: 1000 }); sf.keyboard.press({keys: "return",}); sf.wait({ intervalMs: 100 }); sf.ui.proTools.waitForNoModals(); sf.ui.proTools.appActivate(); // Recall track by name using variable selectedTracks sf.ui.proTools.trackSelectByName({ names: Array.from(globalState.selectedTracks) }) //Select track "EXPORT" sf.ui.proTools.mainWindow.invalidate(); sf.ui.proTools.trackGetByName({ name: "Export", makeVisible: true }).track.trackSelect(); } sf.ui.proTools.clipDoForEachSelectedClip({ action: PrintBuses, onError: "Continue" }); // Recall track by name using variable selectedTracks sf.ui.proTools.trackSelectByName({ names: globalState.selectedTracks }) //Recall selection from globalState variable 'rememberedSelection' sf.ui.proTools.selectionSet({ selectionStart: globalState.rememberedSelection.selectionStart, selectionLength: globalState.rememberedSelection.selectionLength, }); //Restore Link Timeline and Edit selection if (!TimelineEditwasLinked) { sf.ui.proTools.menuClick({ menuPath: ["Options", "Link Timeline and Edit Selection"], }); } //Restore Link Track and Edit selection if (!TrackEditwasLinked) { sf.ui.proTools.menuClick({ menuPath: ["Options", "Link Track and Edit Selection"], }); }