This does exactly what I need, thank you very much for the example.
I already tried it in context of my project and it worked exactly as I imagined.
I’m so grateful for your help and help from the others. Thank you all. You definitely threw me in some new world, at least for me.
Gonna studdy this for sure, as I’d like to understand all this.
Sorry for bothering you, but I have a problem here.
The code you sent me really works. It works even after I did modifications and adjusted everything to my needs.
However, it works only if ran from script editor.
When I copy the code to keyboard maestro action “Execute apple script” it doesn’t run, or maybe it does but there’s no any error or sign of something is going on.
I tried to save the script as application then ran it from keyboard maestro.
Firstly I got the popup dialog which tells me to click Run button to run script or quit button to cancel it, and if I click run it does work with no issues.
Then I found a forum post where someone had same problem, and the fix was to not use Control modifier in key command which calls the script, that guy used the alfred, I use keyboard maestro. It really got rid of that annoying pop up, but now although the script runs, screen reader tells me that menu is openned, but I can’t go through the menu items, it acts like either menu is empty which is not, or like screen reader can’t focus on it, don’t know.
I tried all this with your original example, with no modifications and same thing happens.
Of course, the applet normally runs if I run it from desktop.
Any idea what can be causing this?
Thanks in advance.
Some news.
The keyboard maestro does shows something, I get a dialog which displays missing value, which is obviously result of script.
I didn’t see this dialog immediately, just noticed that are some hidden system dialogs as VoiceOver calls them and those were keyboard maestro dialogs.
I get now why it displays missing value as a result, but I don’t get why it works normally in cases I explained above, but not in this case.
I don’t use Keyboard Maestro or Alfred, so was not able to test with those. For an application, it sounds like it was saved with the Show Startup Screen option selected. The original script also works with osascript if you can use that, either from the Terminal or in a do shell script command, just be aware of the warning I mentioned earlier.
use framework "Foundation"
use scripting additions
-- UI item outlets
property mainWindow : missing value
property popupButton : missing value
-- script properties
property outcome : missing value
property fail : missing value
on run -- example
try
if current application's NSThread's isMainThread() as boolean then
doStuff()
else
my performSelectorOnMainThread:"doStuff" withObject:(missing value) waitUntilDone:true
end if
if fail is not missing value then error fail's errmess number fail's errnum
return outcome
on error errmess number errnum
display alert "Error " & errnum message errmess
end try
end run
-- UI stuff needs to be done on the main thread
on doStuff()
try
set mainWindow to makeWindow at {} with panel given contentSize:{0, 0} --, title:"This is a Test", styleMask:3
set menuList to getEffects()
set menuList to menuList as list -- consolidate the list
log menuList
if menuList = {} then error "Menu list is empty" number -2700 -- -2700 is a generic Applescript error
set theDefault to item 1 of menuList
set my popupButton to makePopupButton at {20, 20} given itemList:menuList --, title:theDefault
set subViewItems to {popupButton}
repeat with aSubview in subViewItems -- add subviews in key view order
(mainWindow's contentView()'s addSubview:aSubview)
end repeat
mainWindow's setInitialFirstResponder:(mainWindow's contentView) -- or whatever
mainWindow's makeKeyAndOrderFront:me
popupButton's performClick:me
mainWindow's performClose:(missing value)
on error errmess number errnum
set my fail to {errmess:errmess, errnum:errnum}
end try
end doStuff
-- Make and return a NSWindow or NSPanel.
-- Default styleMask includes title, close, and minimize buttons, and is not resizeable.
-- If no origin is given the window will be centered.
to makeWindow at (origin as list) given contentSize:contentSize as list : {400, 200}, styleMask:styleMask as integer : 15, title:title as text : "", panel:panel as boolean : false, floats:floats as boolean : false, aShadow:aShadow as boolean : true, minimumSize:minimumSize as list : {}, maximumSize:maximumSize as list : {}, backgroundColor:backgroundColor : missing value
tell current application to set theClass to item ((panel as integer) + 1) of {its NSWindow, its NSPanel}
tell (theClass's alloc()'s initWithContentRect:{{0, 0}, contentSize} styleMask:styleMask backing:2 defer:true)
if origin is {} then
tell it to |center|()
else
its setFrameOrigin:origin
end if
if title is not "" then its setTitle:title
if panel and floats then its setFloatingPanel:true
its setHasShadow:aShadow
if minimumSize is not {} then its setContentMinSize:minimumSize
if maximumSize is not {} then its setContentMaxSize:maximumSize
if backgroundColor is not missing value then its setBackgroundColor:backgroundColor
its setAutorecalculatesKeyViewLoop:true -- include added items in the key loop
return it
end tell
end makeWindow
-- Make and return a NSPopUpButton.
to makePopupButton at (origin as list) given maxWidth:maxWidth as integer : 0, itemList:itemList as list : {}, title:title as text : "", pullDown:pullDown as boolean : false, tag:tag as integer : 0, action:action as text : "popupButtonAction:", target:target : missing value
if title is "missing value" then set title to ""
if maxWidth < 0 then set maxWidth to 0 -- a maxWidth of 0 will size to fit the menu
tell (current application's NSPopUpButton's alloc()'s initWithFrame:{origin, {maxWidth, 32}} pullsDown:pullDown)
its addItemsWithTitles:itemList
if pullDown then -- initial title
its insertItemWithTitle:"" atIndex:0 -- add placeholder
its setTitle:title
else -- initial selection
if title is not "" and title is not in itemList then set title to first item of itemList
end if
its selectItemWithTitle:title -- blank title (all items deselected) if empty
if tag > 0 then its setTag:tag
if action is not in {"", "missing value"} then
if target is missing value then set target to me -- ‘me' can't be used as an optional default
its setTarget:target
its setAction:action -- see the following action handler
end if
if maxWidth is 0 then -- sizeToFit works differently for pull-down (title vs menu), so do it manually
set theSize to width of (its |menu|'s |size| as record)
if pullDown then set theSize to theSize + 10 -- adjust for checkmark space
its setFrameSize:{theSize, 25}
end if
return it
end tell
end makePopupButton
-- Perform an action when the connected popup button is pressed.
on popupButtonAction:sender
set selected to sender's titleOfSelectedItem as text
if (sender's pullsDown as boolean) then -- for pull-down
sender's setTitle:selected -- synchronizeTitleAndSelectedItem doesn't want to work
sender's sizeToFit() -- sized according to the title
end if
set my outcome to selected
-whatever
end popupButtonAction:
-- Get effects by UI scripting
on getEffects()
tell application "System Events" to tell process "Logic Pro X"
tell (window 1 whose title ends with "- Tracks")
set theParent to a reference to (UI element 1 of UI element 1 of last group of list 1 of (group 1 whose description is "Inspector"))
if not (exists theParent) then return "Parent UI element is missing"
tell theParent
set effects to {}
set theCount to (count of groups)
if theCount < 1 then return "No children found"
repeat with theItem from 1 to theCount
set counter to count of (value of (attribute "AXChildren" of group theItem))
if counter = 3 then
set beginning of effects to (description of group theItem) as string
end if
end repeat
end tell
end tell
end tell
return effects
end getEffects
When called with execute apple script from keyboard maestro, same thing as before, I get that missing value thing.
If I compile it as application it will run but still can’t go through menu items, screen reader announces it’s menu and it’s openned, but can’t do anything. Hitting escape key closes it.
I’d avoid using it like that even if it works, as there needs to be multiple such context menus, and if they run as applications, end user would have to give a permision, I mean to all of the examples to run, that’s not convenient at all.
I tried also from execute apple script action, to call this script with do shell script, but still the same: “missing value”.
I edited my previous example to include a testing property and say statements to indicate what the script will be trying to return, independent of what is running it. Note that the default when running a script in Keyboard Maestro is to ignore the result; have you set that option correctly?
An application also won’t return anything, so you would need to add whatever to get the result from the action or run handler before the application quits and do your thing there. Using preferences or the Application Scripts folder could possibly be used to add dynamic menu lists without running into permission issues.
Also, please edit your previous script to add formatting - note that you can start and end the script text with three backticks to use the forum’s formatting, which avoids the typographer’s (curly) quotes and includes a button to open it in the script editor.
I am a Keyboard Maestro user for quite some time (since Version 8).
The Dialog with the Popup Button Menu has always to run on the main thread. To ensure this save it as a .scptd (Script-Bundle -) File and call it using an AppleScript From Keyboard Maestro or use the Filepath Variant of the Execute an AppleScript Action.
The action doesn’t have support for Text based Scripts like this one. I’ve requested this as a feature to Keyboard Maestro’s Developer but I don’t really know if he implements it or not.
If you’re a FastScripts User call the saved Script-Bundle from AppleScript using FastScripts‘s AppleScript support.
Normally this should work without issues - I have quite a few Scripts with Dialogs written this way or using Shane’s Dialog Toolkit Plus and I do it this way.
Please note: This should also be done exact the same way if the dialog was created with Shane‘s Dialog Toolkit Plus Library.
Did the same as you just explained, latest keyboard maestro version, macro with trigger and single action: execute apple script.
When I run it screen reader says osa scripting not responding, and in KM display dialog I get that missing value result.
This is gonna be published for everyone, for free of course, so many blind people can use it, or anyone else, so it’s not that convenient to use both keyboard maestro and fast scripts.
However, if it works for you, then it must work here too. Yes, I copied your code with no changes, made sure it’s working by running it from script editor, then put it to keybaord maestro.
What OS version you’re on?
I have latest sonoma installed, Logic Pro is also latest version, keyboard maestro latest version too.
O yes, I’m aware of it, keyboard maestro user for long time, and I made sure to display result.
I added additional handler which deals with result, basicly just take the string from result (option I select in popup menu) then finds group whose description is string returned, and clicks open button to open the plug-in window. Again, it works from script editor, as it’s nothing complicated, but from keyboard maestro it doesn’t that is, behaves the same as I explained in my previous post.
BTW, thank you for letting me know how to format the pasted code to get that show in editor button, I wondered how you guys do it, I’ll edit my previous example.
Thank you for the suggestions. I tried saving script as bundle, but it doesn’t work. I mean the behaviour is the same, except now I just don’t get displayed anything from Keyboard Maestro. Probably Peter hasn’t implemented that yet.
However, it seems like it works for @ionah so there must be something on my machine which stops it from working.
I clearly understand the purpose and constraints of this script. I am not suggesting that every user should use FS. I was just asking if you could install a demo to see how your script behaves in that environment: it seems that there is a problem with OSAScript. Is it due to KM or Sonoma? I am trying to isolate the problem.
My macOS version is Monterey 12.7.5. This may explain why the script is working for me and not on your configuration. Is it possible for you to run this script on another Mac running Sonoma? Or maybe you could ask on the KM forum?
There is one point you didn’t answer: have you reset the accessibility permission in system settings? (You need to delete and re-import KM to make sure it is taken into account).
But before all that, can you test this revised version of @red_menace excellent script:
use framework "Foundation"
use framework "AppKit"
use scripting additions
-- UI item outlets
property thePanel : missing value
property thePopup : missing value
-- script properties
property outcome : missing value
property fail : missing value
on run
try
-- make sure LPX is open
if application "Logic Pro X" is not running then error "Logic Pro is not running" number -2700
-- build and show the menu on main thread
if current application's NSThread's isMainThread() as boolean then
displayMenu()
else
my performSelectorOnMainThread:"displayMenu" withObject:(missing value) waitUntilDone:true
end if
-- return result or display alert
if fail is not missing value then error fail's theMess number fail's theNum
return outcome
on error theMess number theNum
tell application "Logic Pro X" to display alert theMess message "Error " & theNum
end try
end run
-- UI stuff needs to be done on the main thread
on displayMenu()
try
-- build the container window
set thePanel to (current application's NSPanel's alloc()'s initWithContentRect:{{0, 0}, {400, 200}} styleMask:15 backing:2 defer:true)
tell thePanel
its |center|()
its setFloatingPanel:true
its setAutorecalculatesKeyViewLoop:true -- include added items in the key loop
end tell
-- get the list of effects in Logic Pro
set menuList to getEffects()
set menuList to menuList
if menuList = {} then error "Menu list is empty" number -2700 2700 is a generic Applescript error
-- build the pop up menu
set thePopup to (current application's NSPopUpButton's alloc()'s initWithFrame:{{20, 20}, {0, 32}} pullsDown:true)
tell thePopup
its addItemsWithTitles:({""} & menuList) -- the menu needs a first empty item because it's a pull down
its setAction:"popupButtonAction:"
set {theW, theH} to its |menu|()'s |size|() as list
its setFrameSize:{theW, 0} -- fit the menu size to its content
its setTarget:me
end tell
-- add the pop up menu to the window
(thePanel's contentView()'s addSubview:thePopup)
-- display the menu only by closing its container window
thePanel's setInitialFirstResponder:(thePanel's contentView())
thePanel's makeKeyAndOrderFront:me
thePopup's performClick:me
thePanel's performClose:(missing value)
on error errMess number errNum
set my fail to {theMess:errMess, theNum:errNum}
end try
end displayMenu
-- Perform an action when a menu item is chosen
on popupButtonAction:sender
set selected to sender's titleOfSelectedItem as text
if (sender's pullsDown as boolean) then -- for pull-down
sender's setTitle:selected -- synchronizeTitleAndSelectedItem doesn't want to work
sender's sizeToFit() -- sized according to the title
end if
set my outcome to selected
end popupButtonAction:
-- Get the list of effects by UI scripting
on getEffects()
activate application "Logic Pro X"
tell application "System Events" to tell process "Logic Pro X"
tell (window 1 whose title ends with "- Tracks")
set theParent to a reference to (UI element 1 of UI element 1 of last group of list 1 of (group 1 whose description is "Inspector"))
if not (exists theParent) then error "Parent UI element is missing" number -2700
tell theParent
set theEffects to {}
set theCount to (count of groups)
if theCount < 1 then error "No children found" number -2700
repeat with theItem from 1 to theCount
set counter to count of (value of (attribute "AXChildren" of group theItem))
if counter = 3 then
set beginning of theEffects to (description of group theItem) as string
end if
end repeat
end tell
end tell
end tell
return theEffects
end getEffects
Aha ok, got you now.
Sorry for not mentioning that, I reset accessibility permission but there was no change.
I tried this modified script and I’m still getting same output: missing value, and the behaviour is the same as I already explained.
Of course this is with keyboard maestro, from script editor it works with no issues.
However, I installed fast scripts and ran the script, and it worked perfectly.
Of course I firstly had to give it a permission, but after that it works with no issues.
I also tried it with few other cases where I’d need this custom context menu and it worked there too.
I didn’t save script as bundle then as normal script file “.scpt”, works perfectly.
Forgot to add that I already tried this script on my another machine and same behaviour. One machine is macbook pro 16 2019 version, and another one is mac mini with m2 pro chip, both running latest sonoma version.
I think you understand that KM is causing the issue.
Just to be sure: when you run the latest script in KM, the popup menu does not appear at all and you immediately get a missing value?
When you tried this last script, did you add any other statements?
Can you run your getEffects handler alone from KM and report if it gives the expected result?
Yeah seems like KM is causing this issue.
PopUp never appeared, I hear screen reader says osa scripting not responding, and I get that missing value from KM, nothing else.
getEffects() handler definitely works, already tried it from KM.
I just copied and pasted code you sent and tried it inside KM, didn’t make any modifycations.
I took same code and saved it as script, then tried that script with FS and it worked.
After it worked with fs, I then tried same with some other handlers and those examples worked with FS too.
Don’t know what else to try. I’ll gather all steps you guys recommended me and retry everything on my mac mini. I’ll report back if anything changes.
Don’t. It’s useless.
You said previously that my first script (the one who needs to click on OK button) was working. Can you confirm that it does when run from KM?
Otherwise, can you verify the KM preferences and confirm that all security settings are checked?
In preferences, under security it’s all checked except contacts.
I took that first code you sent and tried to run it without any modifycations. On first run, I got asked to give keyboard maestro a permission to run it, although the KM has permission. Anyway I reset it, but no luck, doesn’t work. In fact, nothing happens except screen reader saying osa scripting not responding when ran.
I tried that code in FS too, and it worked.
You’re right on checking everything on second machine, useless. Same behaviour.