Display Variable from Repeat loop in a Floating Window - applescript

I have an applescript that captures a counter in another application. This works fine but I'd like to output the results to another floating window and have it update with each loop. Does anyone know of a way to do this? Complete newb.
Thanks
EDIT:
My code is:
tell application "System Events"
tell process "MIDI Editor"
with timeout of 0 seconds
repeat
set barCount to value of text field "Main Counter" of group "Counter Display Cluster" of window "Edit: kjhsdf" of application process "MIDI Editor" of application "System Events"
delay 0.01
end repeat
end timeout
end tell
end tell
(Not sure why that last end tell keeps breaking out of the code block!)
So its barCount that I want to mirror in real time in another window

From the Script Editor you can use some AppleScriptObjC to programmatically create a non-modal window with a text field that can be updated. In the example below I am using a repeating timer instead of an AppleScript repeat statement, as tight loops like that will block the user interface. Save the script as an application, with the option set to stay open.
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Cocoa"
use scripting additions
property WindowFrame : {{200, 600}, {150, 50}} -- window location and size
property TextFrame : {{10, 10}, {130, 30}} -- window size minus 20
property mainWindow : missing value
property textField : missing value
property timer : missing value
on run -- example
setup()
update()
set my timer to current application's NSTimer's timerWithTimeInterval:0.25 target:me selector:"update" userInfo:(missing value) repeats:true
current application's NSRunLoop's mainRunLoop's addTimer:timer forMode:(current application's NSDefaultRunLoopMode)
end run
to update() -- update text field
set barCount to ""
with timeout of 0.5 seconds
tell application "System Events" to tell process "MIDI Editor"
set barCount to value of text field "Main Counter" of group "Counter Display Cluster" of window "Edit: kjhsdf"
end tell
end timeout
textField's setStringValue:(barCount as text)
end update
to setup() -- create UI objects
tell (current application's NSTextField's alloc's initWithFrame:TextFrame)
set my textField to it
its setFont:(current application's NSFont's fontWithName:"Menlo" |size|:18)
its setBordered:false
its setDrawsBackground:false
its setSelectable:false
end tell
tell (current application's NSWindow's alloc's initWithContentRect:WindowFrame styleMask:1 backing:(current application's NSBackingStoreBuffered) defer:true)
set my mainWindow to it
its setAllowsConcurrentViewDrawing:true
its setHasShadow:true
its setTitle:"Progress"
its setLevel:(current application's NSFloatingWindowLevel)
its (contentView's addSubview:textField)
its setFrameAutosaveName:"Update Window" -- keep window position
its setFrameUsingName:"Update Window"
its makeKeyAndOrderFront:me
end tell
end setup

Related

How to get Application Name To Call from PID in Mac AppleScript

There is a script that lets you resize any app in mac. This is the code:
set theApp to "Application Name"
set appHeight to 1080
set appWidth to 1920
tell application "Finder"
set screenResolution to bounds of window of desktop
end tell
set screenWidth to item 3 of screenResolution
set screenHeight to item 4 of screenResolution
tell application theApp
activate
reopen
set yAxis to (screenHeight - appHeight) / 2 as integer
set xAxis to (screenWidth - appWidth) / 2 as integer
set the bounds of the first window to {xAxis, yAxis, appWidth + xAxis, appHeight + yAxis}
end tell
I want to change the size of a java application opened by a launcher. When I insert the name of any app, it works. However when I insert the name of the app that I want to resize it doesn't work. I know the process id of the app that I want to resize. Is there a way I can change this line set theApp to "Application Name" to use PID instead of Application name?
Thanks.
Not all apps are AppleScript scriptable and some that are do not support the bounds property, they use position property and size property. Also, sometimes you'll need System Events to position and size an app's window.
I use a keyboard shortcut assigned in FastScripts with the following example AppleScript code to automatically adjust the frontmost app's window. You can adjust the code to suite your needs.
If the frontmost app can't use the bounds property it silently errors, and then System Events does it.
tell application "System Events"
set frontmostProcess to name of process 1 whose frontmost is true
end tell
try
tell application frontmostProcess
set bounds of window 1 to {0, 22, 1136, 844}
end tell
on error
tell application "System Events" to tell application process frontmostProcess
set position of window 1 to {0, 22}
set size of window 1 to {1136, 822}
end tell
end try
Note: I am not affiliated with the developer of FastScript, just a satisfied user. It's also free for the first ten keyboard shortcuts.

AppleScript to focus on a window in Preview app

Im trying to do some manipulation with preview using Automator. I have several windows open in preview, two of which are of interest. One is named "Markup Badges.png" one is called "Screenshot.png"
I want to set the focus to "Screenshot.png", copy the image and close the window, then I want to close the "Markup Badges.png" window.
I am having a lot of trouble getting this to work.
As part of my experimenting I have created two scripts trying to get the windows in focus, so I can then perform additional actions on them
Script 1:
on run {input, parameters}
tell application "Preview"
set visible of every window whose visible is true to false
end tel
tell application "Preview"
try
set theWindow to 1st window whose name begins with "Screenshot.png"
set index of theWindow to 1
activate
end try
end tell
-- stuff
delay 1
tell application "Preview"
set visible of every window whose visible is false to true
end tell
return input
end run
Script 2:
on run {input, parameters}
tell application "Preview"
set visible of every window whose visible is true to false
end tell
tell application "Preview"
try
set theWindow to 1st window whose name begins with "Markup Badges.png"
set index of theWindow to 1
activate
end try
end tell
-- stuff
delay 1
tell application "Preview"
set visible of every window whose visible is false to true
end tell
return input
end run
If I run Script 1 on its own, it does what I expect, Screenshot.png window is shown and has focus.
If I run Script 2 on its own, it does what I expect, Markup Badges.png window is shown and has focus.
If I run both scripts (play button in automator, Script 1 runs, followed by script 2) then script 2 does not work as it does on its own. The window is shown, but it does not have focus meaning I cannot send any keypresses to the window.
Any help appreciated
I found changing the code to the below fixed the problem.
on run {input, parameters}
tell application "Preview"
set visible of every window whose visible is true to false
end tell
tell application "Preview"
try
set theWindow to 1st window whose name begins with "Markup Badges.png"
set index of theWindow to 1
activate
tell application "System Events" to tell process "Preview" to perform action "AXRaise" of window 1
end try
end tell
-- stuff
delay 1
tell application "Preview"
set visible of every window whose visible is false to true
end tell
return input
end run

HOW TO: display a check mark, disable a menu item, refresh a menubar

I am trying to set up some simple services on a Mac using a menubar/status script with applescript.
After having read the web up and down, bearing in mind I am new to scripting, it seems I have reached my limit and I need some help...
First, I want to display a check mark next to a menuItem on a condition. In my example the condition is the display resolution between 720p and 1080p.
I have set up the menubar adapted from an existing script (some of which I do not fully understand) as follows:
use AppleScript version "2.7"
use scripting additions
use framework "Foundation"
use framework "AppKit"
property aStatusItem : missing value
on init()
set aBar to {"Reset Display", "1080p", "720p", "Open Monitor Preferences...", "", "External Monitor: active", "Quit"}
set aStatusItem to current application's NSStatusBar's systemStatusBar()'s statusItemWithLength:(current application's NSVariableStatusItemLength)
aStatusItem's setTitle:"FTV"
aStatusItem's setHighlightMode:true
aStatusItem's setMenu:(createMenu(aBar) of me)
end init
on createMenu(aList)
set myDisplay to ChkDisplay()
set aMenu to current application's NSMenu's alloc()'s init()
set aCount to 1
repeat with i in aList
set j to contents of i
if j is not equal to "" then
set aMenuItem to (current application's NSMenuItem's alloc()'s initWithTitle:j action:"actionHandler:" keyEquivalent:"")
else
set aMenuItem to (current application's NSMenuItem's separatorItem())
end if
if j = myDisplay then (aMenuItem's setState:NSOnState)
(aMenuItem's setTarget:me)
(aMenuItem's setTag:aCount)
(aMenu's addItem:aMenuItem)
if j is not equal to "" then set aCount to aCount + 1
end repeat
return aMenu
end createMenu
The handler to check the display resolution:
on ChkDisplay()
tell application "System Preferences"
reveal anchor "displaysDisplayTab" of pane id "com.apple.preference.displays"
end tell
tell application "System Events"
set myDisplay to "720p"
tell table 1 of scroll area 1 of tab group 1 of window "Philips FTV" of process "System Preferences"
if selected of row 1 then set myDisplay to "1080p"
end tell
end tell
tell application "System Preferences" to quit
return myDisplay
end ChkDisplay
Basically I want the check mark to move from 720p to 1080p depending on which of the resolution is active. The 720p and 1080p item, if clicked, will also set the display resolution.
The code I have return an error: NSOnState is not defined... and there I am lost.
The second issue I have is to find a way to:
a) "grey out" (disable) a menuItem (in this case, the item "External Monitor: active"
b) to have the item change to "External Monitor: missing" on a condition
I have tried: NSMenuItem highlight:false and NSMenuItem enabled:false and both returned and error.
In addition, I don't know how to refresh the menu and/or a menu item.
Any help or pointers will be greatly appreciated.
I thank anyone in advance for the time (s)he will spend on my thinking about those questions!
Final Solution
For issue #1, displaying a check mark next to a menu item, thanks to #CJK help, I have found some working code:
replace if j = myDisplay then (aMenuItem's setState:NSOnState) by either
if j = myDisplay then (aMenuItem's setState:1)
or
if j = myDisplay then (aMenuItem's setState:NSOnState)
I have also been able to display any image next to a menu item with NSimage (do not hesitate to ask me if need be)
As regards issue #2, enabling/disabling a menu item, I also have found a working code:
in the createMenu(aList) handler, you need to add the second line before the repeat loop:
set aMenu to current application's NSMenu's alloc()'s init()
aMenu's setAutoenablesItems:false
then in the repeat loop, to enable/disable a menu item:
(aMenuItem's setEnabled:false)
**Finally to refresh the menu items, ** I put the code aMenu's removeAllItems() in createMenu(aList) handler and call the handler when I want to refresh. It seems by removing on run/ end run at the beginning of the script, everything works fine!

Selecting Pop Up Menu Buttons in AppleScript

I want to automate clicking a specific pop down menu's item.
For Example, I want to change the Value of "Message receive Sound" to something else. How can I do this with AppleScript? And how can I do this with other pop down menus in AppleScript?
(To open the iMessage Settings menu, shown in the image, type CMD COMMA, once you open iMessage)
Note: I have successfully done this Automator, I just want to do it in applescript.
It's called GUI scripting. You have to identify the reference to the UI element(s).
GUI scripting strongly depends on the system version. If an update changes the UI structure the script will brake.
This selects the sound "Popcorn" in the sound popup menu. It's for El Capitan. In systems < 10.11 the UI elements may be different and the process name might be "iChat"
tell application "System Events"
tell process "Messages"
set frontmost to true
if not (exists (1st window whose value of attribute "AXIdentifier" is "MessagesPreferencesWindow")) then
keystroke "," using command down
repeat until exists (1st window whose value of attribute "AXIdentifier" is "MessagesPreferencesWindow")
delay 0.1
end repeat
end if
tell (1st window whose value of attribute "AXIdentifier" is "MessagesPreferencesWindow")
tell pop up button 4 of group 1
click
delay 0.2
click menu item "Popcorn" of menu 1
end tell
end tell
end tell
end tell

Applescript - Bring window to foreground

I have an application with several windows opened at the same time.
I'd like to bring a specific window to foreground (I know its title).
At the moment I'm using a combination of keys to achieve this task but I'd like to try something different since I'm experiencing some problems with this approach.
tell application "System Events"
set frontmost of process "appIT" to true
keystroke "1" using command down
delay 0.2
end tell
This is possible by using the "AXRaise" action, except on certain window (applications that use X11 for example).
Try this.
set theTitle to "some title"
tell application "System Events"
tell process "appIT"
set frontmost to true
perform action "AXRaise" of (windows whose title is theTitle)
end tell
end tell
If your application is scriptable and allows setting the index of a window, you can do the following (based on an answer in How do I make a Safari window active using AppleScript (elegantly)?)
to raiseWindow of theApplicationName for theName
tell the application named theApplicationName
activate
set theWindow to the first item of ¬
(get the windows whose name is theName)
if index of theWindow is not 1 then
set index to 1
set visible to false
set visible to true
end if
end tell
end raiseWindow
The toggling of the visibility is necessary to deal with some weirdness that occurs with switching applications. If you don't toggle the visibility, the window won't be the first when you switch away from and back to the application. Unfortunately, this toggling shrinks the window to the dock then restores it, a very dramatic UI disruption.
Here's another way I've found to deal with the weirdness:
to raiseWindow2 of theApplicationName for theName
tell the application named theApplicationName
activate
set theWindow to the first item of ¬
(get the windows whose name is theName)
if the index of theWindow is not 1 then
set the index of theWindow to 2
tell application "System Events" to ¬
tell application process theApplicationName to ¬
keystroke "`" using command down
end if
end tell
end raiseWindow2
I don't think System Events can change the front window of a process. Of course you can close the front window until the window you want is on top. That's not really a solution though as you probably don't want to close windows. Really though the only way you could achieve this is if the application itself is apple-scriptable and allows you to do this.

Resources