Title
Error thrown on trying to click Track Title
What do you expect to happen when you run the script/macro?
Supposed to move selection to the next track in either mix or edit window. Then click on the track name to attention the track in EUCON.
When I run the script it does this but throws an error message and does not complete the script (dismissing the track rename window that comes up).
Are you seeing an error?
This is the error I get. I happens at the same line in either the mix or edit windows.
Logging error in action (01) ClickButtonAction: Error invoking AXElement: kAXErrorCannotComplete
!! Command Error: SELECT NEXT TRACK FULL [user:ck08xanhn0007p610i48im7ck:cm8ahcbld0000kd10vktqn5hi]:
Error invoking AXElement: kAXErrorCannotComplete (SELECT NEXT TRACK FULL: Line 26)
SoundFlow.Shortcuts.AXUIElementException: kAXErrorCannotComplete
at SoundFlow.Shortcuts.AXUIElement.DoAction(String action) + 0x98
at SoundFlow.Shortcuts.Automation.Actions.ClickButtonAction.d__11.MoveNext() + 0x7c
What happens when you run this script?
gave all the info already
How were you running this script?
Other
How important is this issue to you?
5
Details
{ "inputExpected": "Supposed to move selection to the next track in either mix or edit window. Then click on the track name to attention the track in EUCON.\n\nWhen I run the script it does this but throws an error message and does not complete the script (dismissing the track rename window that comes up).", "inputIsError": true, "inputError": "This is the error I get. I happens at the same line in either the mix or edit windows. \n\nLogging error in action (01) ClickButtonAction: Error invoking AXElement: kAXErrorCannotComplete\n!! Command Error: SELECT NEXT TRACK FULL [user:ck08xanhn0007p610i48im7ck:cm8ahcbld0000kd10vktqn5hi]:\nError invoking AXElement: kAXErrorCannotComplete (SELECT NEXT TRACK FULL: Line 26)\n SoundFlow.Shortcuts.AXUIElementException: kAXErrorCannotComplete\n at SoundFlow.Shortcuts.AXUIElement.DoAction(String action) + 0x98\n at SoundFlow.Shortcuts.Automation.Actions.ClickButtonAction.d__11.MoveNext() + 0x7c\n", "inputWhatHappens": "gave all the info already", "inputHowRun": { "key": "-MpfwoFyZNOpBC3X5xGI", "title": "Other" }, "inputImportance": 5, "inputTitle": "Error thrown on trying to click Track Title" }
Source
sf.ui.proTools.appActivateMainWindow();
const sup = sf.ui.proTools
var allTracks = sup.trackGetVisibleTracks().names;
var allTracksCount = allTracks.length
var selTracks = sup.trackGetSelectedTracks().names;
var currentTrack = selTracks[0]
for (var i = 0; i < allTracksCount; i++) {
if (allTracks[i].indexOf(currentTrack) == 0)
break;
}
i = i + 1;
if (i > allTracksCount - 1) { throw 0 }
sup.trackSelectByName({
names: [allTracks[i]]
});
//Get the current window name
const focusedWindow = sf.ui.proTools.focusedWindow.title.invalidate().value.split(" ", 1)[0].slice(0, -1);
// If Mix Window is Frontmost
if (focusedWindow == 'Mix') {
let trackName = sf.ui.proTools.selectedTrack.normalizedTrackName;
// Click on Track Name in the Mix Window
sf.ui.proTools.mixWindow.groups.whoseTitle.startsWith(trackName).first.popupButtons.whoseTitle.startsWith('Track name').first.elementClick();
}
// Else - Edit Window is front Most
else if (focusedWindow == 'Edit') {
let trackName = sf.ui.proTools.selectedTrack.normalizedTrackName;
sf.ui.proTools.mixWindow.groups.whoseTitle.startsWith(trackName).first.popupButtons.whoseTitle.startsWith('Track name').first.elementClick();
}
sf.ui.proTools.children.whoseRole.is("AXWindow").first.getElement("AXTitleUIElement").elementWaitFor();
sf.ui.proTools.children.whoseRole.is("AXWindow").first.buttons.whoseTitle.is("OK").first.elementClick();
Links
User UID: yesbmwLVy0dRQLFNZzxo8kQx4ri2
Feedback Key: sffeedback:yesbmwLVy0dRQLFNZzxo8kQx4ri2:-OLQIehWZoDfOyfpx5GK
Feedback ZIP: gaDUnhNDMFQn2xFB50I8xXNwApjHc7xeSDrO5oSYoazg8SxbKyyl1K68qo8zxhr3Gbj4dup/38ltFnaVpynaEJdMNpnMQIWpyqib+ptU8qt9pUhsIWlboyD7h5wyvhaXfXIswBbsBPGLRjZ/PH10QL/7zkVI8U1m5A4vDmcilZFloOk22Q9+kGgleudS/UL+IxmUvHnwMg5VYCPpA179X54ivGkkbmOZgJhvVrfsPjLIx+m35ADfDdr7DKFMEQp3psDQHUWQPhPoZH5KgxxYpNJs5f4BfjkKHhzHNV1pKPlqVmregu/9AFXVN+tszs8wx/X7f74VWSBXe3JaqqFLHw==
- Ben Rubin @Ben_Rubin
Error will happen on either line 26 or 32 depending on the frontmost window.
Im sure this a clunky way to do this so open to any alternatives from our resident SF geniuses.
My ultimate goal is to get the next track in pro tools attentioned in EUCON by just running a script launched from an Avid Dock touchstrip.
Ben Rubin @Ben_Rubin
@Kitch, @samuel_henriques, @Chris_Shaw, any thoughts on this one?
🙏
- In reply toBen_Rubin⬆:
Kitch Membery @Kitch2025-03-17 20:25:37.717Z
Hi @Ben_Rubin
Does running a script like this attention the track in EUCON?
const focusTrackName = "Audio 1"; // Change this name to a track in your session. sf.app.proTools.selectTracksByName({ trackNames: [focusTrackName] });
Let me know, and if so, it should be pretty simple. :-)
Chris Shaw @Chris_Shaw2025-03-17 22:46:23.118Z
In order for a track to be selected in Eucon (depending on preferences) the title button has to be clicked. I've come up with a semi robust solution but I think you could do better :)
- In reply toBen_Rubin⬆:
Chris Shaw @Chris_Shaw2025-03-17 22:44:48.473Z
I'm assuming that you have "Attention most recently click DAW area" set to "Track Name" to attention the track in Econ (Which requires the track title to be clicked - not just selected).
You can simplify the script significantly and still have it work in the Edit or Mix windows.
When usingelementClick()
you have to setasyncSwallow
totrue
otherwise it fails.
The downside to this is that if you re-trigger the script rapidly it causes the track rename window to appear or cause a timeout error. I've included a routine to check for a rename window and dismiss it if it appears.
But still, rapid triggering results in inconsistent behavior.
@Kitch will probably have a more robust solution./*** * Selects and attentions track in Eucon. * If no parameter is specified it will select next track * @param {'next' | 'previous'| null} [nextOrPrevious] */ function selectAndAttentionNextOrPreviousTracK(nextOrPrevious) { sf.ui.proTools.mainWindow.invalidate() sf.ui.proTools.appActivate(); const visibleTracks = sf.ui.proTools.visibleTrackNames; const currentTrackName = sf.ui.proTools.selectedTrackNames[0] const nextTrackDelta = nextOrPrevious == "next" || nextOrPrevious == null ? 1 : -1; const nextTrackIndex = visibleTracks.indexOf(currentTrackName) + nextTrackDelta // Bail if trying to select track outside of array start or end if (nextTrackIndex == visibleTracks.length || nextTrackIndex < 0) throw 0; const nextTrackName = visibleTracks[nextTrackIndex] const nextTrackTitleButton = sf.ui.proTools.trackGetByName({ name: nextTrackName }).track.titleButton nextTrackTitleButton.elementClick({ asyncSwallow: true, }) const trackRenameWindow = sf.ui.proTools.windows.whoseTitle.is(nextTrackName).first sf.waitFor({ callback: () => trackRenameWindow.exists, timeout:150, onError:"Continue" }) if (trackRenameWindow.exists) { trackRenameWindow.buttons.whoseTitle.is("OK").first.elementClick() trackRenameWindow.elementWaitFor({ waitType: "Disappear" }) } } selectAndAttentionNextOrPreviousTracK('next')
Ben Rubin @Ben_Rubin
This seems to be working for me, @Chris_Shaw. Thanks so much! Def interested if @kitch can streamline or improve in any way. I dont think the P/; solution works for me since it doesnt work in the Mix Window.
Kitch Membery @Kitch2025-03-18 09:23:34.421Z
Hi @Ben_Rubin & @Chris_Shaw,
Let me know if this script attentions tracks via EUCON as expected. (Fingers crossed.)
/** * @param {object} obj * @param {'next'|'previous'} obj.direction */ function navigateTracks({ direction } = { direction: "next" }) { const visibleTrackNames = sf.ui.proTools.visibleTrackNames; const selectedTrackName = sf.ui.proTools.selectedTrack.normalizedTrackName; const delta = direction === "next" ? 1 : -1; const targetTrackIndex = visibleTrackNames.indexOf(selectedTrackName) + delta; if (targetTrackIndex < 0 || targetTrackIndex >= visibleTrackNames.length) return; const targetTrackName = visibleTrackNames[targetTrackIndex]; sf.app.proTools.selectTracksByName({ trackNames: [targetTrackName] }); try { const tracklistview = sf.ui.proTools.mainWindow.trackListView; const rows = tracklistview.childrenByRole("AXRow"); let trackSelector = null; for (let i = 0; i < rows.length; i++) { const row = rows[i]; const cells = row.childrenByRole("AXCell").allItems; if (cells.length > 1) { const button = cells[1].buttons.first; if (button && button.title.value.replace(/^Open\. /, "") === targetTrackName) { trackSelector = button; break; } } } if (trackSelector) { trackSelector.elementClick(); } } catch (err) { } } navigateTracks({ direction: "next" });
And, to navigate to the previous track, change the call to...
navigateTracks({ direction: "previous" });
Rock on!
Chris Shaw @Chris_Shaw2025-03-18 16:06:05.803Z
It didn't work on my end. (SO close!)
I added this below line 37log("Clicking")
to see if it was finding the selected track and the script didn't log anything.
I then changed line 30 to :
if (button && button.title.value.startsWith("Selected.")) {
This change then logged "Clicking"; so the element is being found. The element is clicked but is then de-selected so the track isn't attentioned in EuconKitch Membery @Kitch2025-03-18 16:13:34.655Z
Bummer!!! Back to the drawing board.
Thanks for checking @Chris_Shaw
Chris Shaw @Chris_Shaw2025-03-18 16:29:51.127Z
Success!
This works:/** * @param {object} obj * @param {'next'|'previous'} obj.direction */ function navigateTracks({ direction } = { direction: "next" }) { const tracks = () => sf.app.proTools.tracks.invalidate().allItems; const visibleTrackNames = sf.ui.proTools.visibleTrackNames; const selectedTrackName = sf.ui.proTools.selectedTrack.normalizedTrackName; const delta = direction === "next" ? 1 : -1; const targetTrackIndex = visibleTrackNames.indexOf(selectedTrackName) + delta; if (targetTrackIndex < 0 || targetTrackIndex >= visibleTrackNames.length) return; const targetTrackName = visibleTrackNames[targetTrackIndex]; const targetTrackHeader =sf.ui.proTools.trackGetByName({name:targetTrackName}).track targetTrackHeader.trackScrollToView() targetTrackHeader.titleButton.mouseClickElement({ anchor:"TopLeft", relativePosition:{x:5,y:5} }) } navigateTracks({ direction: "next" });
Chris Shaw @Chris_Shaw2025-03-18 16:35:16.944Z
I wonder if there is a bug with
elementClick()
ing the title button? PT is treating it as a double click and opens the rename window.- In reply toChris_Shaw⬆:
Ben Rubin @Ben_Rubin
This also works great for me. Thanks much, 🙏🙏🙏
- In reply toChris_Shaw⬆:
Kitch Membery @Kitch2025-03-18 16:52:48.042Z
Nice one @Chris_Shaw.
Can you try this script that uses the
trackSelectByName
method to select a track.../** * @param {object} obj * @param {'next'|'previous'} obj.direction */ function navigateTracks({ direction } = { direction: "next" }) { const visibleTrackNames = sf.ui.proTools.visibleTrackNames; const selectedTrackName = sf.ui.proTools.selectedTrack.normalizedTrackName; const delta = direction === "next" ? 1 : -1; const targetTrackIndex = visibleTrackNames.indexOf(selectedTrackName) + delta; if (targetTrackIndex < 0 || targetTrackIndex >= visibleTrackNames.length) return; const targetTrackName = visibleTrackNames[targetTrackIndex]; sf.ui.proTools.trackSelectByName({names:[targetTrackName]}); } navigateTracks({ direction: "next" });
Kitch Membery @Kitch2025-03-18 16:56:27.378Z
I'd say it won't work, but it's worth testing to avoid the use of a mouse click.
Chris Shaw @Chris_Shaw2025-03-18 17:31:30.120Z
It selects the track but it doesn't attention the track. It seems only a click will do it.
Kitch Membery @Kitch2025-03-18 17:32:22.151Z
Figured as much. Thanks! :-)
- In reply toBen_Rubin⬆:
Kitch Membery @Kitch2025-03-18 00:16:10.613Z
This works for me on the Avid Control (iPad app) through EUCON...
/** * @param {object} obj * @param {'next'|'previous'} obj.direction */ function navigateTracks({ direction } = { direction: "next" }) { sf.ui.proTools.appActivateMainWindow(); sf.ui.proTools.mainWindow.invalidate(); const visibleTrackNames = sf.ui.proTools.visibleTrackNames; const selectedTrackName = sf.ui.proTools.selectedTrack.normalizedTrackName; const delta = { "next": +1, "previous": -1, }[direction]; const targetTrackIndex = visibleTrackNames.indexOf(selectedTrackName) + delta; const targetTrackName = visibleTrackNames[targetTrackIndex]; if (!targetTrackName) throw 0 sf.app.proTools.selectTracksByName({ trackNames: [targetTrackName] }); }
With the following calls...
// Next track navigateTracks({ direction: "next" });
&
// Previous track navigateTracks({ direction: "previous" });
Let me know if it works for you. :-)
Chris Shaw @Chris_Shaw2025-03-18 02:55:19.174Z
I think the confusing issue here is the difference in Eucon parlance between "selected" and "attentioned".
Selecting a track can be done either physically or programmatically. A track is attentioned by either clicking a track header element with a mouse or selecting it using a button on a Eucon surface.
To see this in action, in Eucon preferences, set 'Track name' as an attention click area:In your AVID Control app, at the very top of the display select 'Channel', then select the Pan display which will show the pan settings on an attentioned track.
If you switch track inPT by using the 'p' and ';' keys you'll notice that the attentioned track pan display in the AVID Control app does not change. Programmatically selecting a track does not change the display either. But if you select a track by clicking on it's title button with the mouse the channel pan display changes to the track you just clicked.
So the script needs to click the track title button in order to attention the selected track.Chris Shaw @Chris_Shaw2025-03-18 02:59:40.734Z
I think the easiest way to get around this is to use 'Edit selection move up/down' in EuCon prefs and just use the 'p' and ';' keys: