How to make application written using AppleScript to open the dialog each time the icon is clicked?

149 views Asked by At

I'm writing an applescript application that would say time every 5 mins. This will be in an infinite loop. My requirement is, although it is running 24x7 since start, next time when I click application icon, it should show the dialog to get user input via one of the 3 buttons.

I have 3 buttons.

  • Pause Notifications
  • Notifications ON
  • Notification OFF

When the code is in infinite loop, and I click the application icon, the dialog prompt doesn't come up to get the user input via above 3 buttons. How to fix that?

global isSoundEnabled, isNotifEnabled

on run
    set isSoundEnabled to true
    set isNotifEnabled to true
    
    set theDialogText to "The curent date and time is " & (current date) & "."
    display dialog theDialogText buttons {"Pause", "Notif ON", "Notif OFF"} default button "Notif ON" cancel button "Pause" with icon caution
    
    if result = {button returned:"Notif ON"} then
        set isSoundEnabled to true
        set isNotifEnabled to true
        loop()
    else if result = {button returned:"Notif OFF"} then
        set isSoundEnabled to false
        set isNotifEnabled to false
    end if
end run

on loop()
    repeat while true
        set min to getMin()
        get min as integer
        #if (min mod 5) = 0 then
        if (min / 5) > 1 then
            set timee to getTimeInHoursAndMinutes()
            if isNotifEnabled then
                display notification timee
            end if
            if isSoundEnabled then
                say timee
            end if
            #delay 60
            #if isSoundEnabled is not 
        end if
        #exit repeat
    end repeat
end loop

I haven't added getTimeInHoursAndMinutes() and getMin() implementation on purpose as it doesn't much value.

1

There are 1 answers

3
red_menace On

The application user interface (menus, etc) will be blocked if you don’t give the system time to process events, so you want to avoid long repeat loops. The standard dialogs are modal, so you also normally can't do other things while they are being shown.

Repeatedly showing the standard dialogs can also be intrusive, since the current application will switch if activating the application (to show the dialog), or the Dock icon will start bouncing if you don't. Some AppleScriptObjc could be used for other types of notifications, but for this example I stayed with the standard dialogs.

I did cheat a little in the following script by using some AppleScriptObjC for the speech synthesizer, since it can speak in the background (while a dialog is shown). I've also avoided using notifications, since those need to be allowed in the System Preferences.

The bottom line is that when saving an app as stay open, the idle and reopen handlers can be used - the idle handler is repeatedly called after the run handler finishes (it uses a timer), and the reopen handler is called when the app is double-clicked (or the Dock icon clicked), so you can avoid locking up the UI. For example:

use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "AppKit" -- for the speech synthesizer
use scripting additions

global isSoundEnabled, isNotifEnabled, defaultButton

on run -- initial setup
    set isSoundEnabled to true
    set isNotifEnabled to true
    set defaultButton to "Notif OFF" -- the default is set opposite the current setting
    getSettings()
end run

to getSettings()
    set theDialogText to "The curent date and time is " & (current date) & "."
    tell me to activate
    set theButton to button returned of (display dialog theDialogText buttons {"Quit", "Notif ON", "Notif OFF"} default button defaultButton with icon caution giving up after 10)
    if theButton is "Notif ON" then
        set isSoundEnabled to true
        set isNotifEnabled to true
        set defaultButton to "Notif OFF"
    else if theButton is "Notif OFF" then
        set isSoundEnabled to false
        set isNotifEnabled to false
        set defaultButton to "Notif ON"
    end if
end getSettings

on reopen -- application double-clicked or dock icon clicked
    getSettings()
end reopen

on idle -- after the run handler completes, is called repeatedly
    set giveup to 5 -- dialog will self-dismiss, although timing will be a little off if manually dismissed 
    set theTime to time string of (current date)
    if isSoundEnabled then -- AppleScriptObjC is used to speak in the background
        (current application's NSSpeechSynthesizer's alloc's initWithVoice:(missing value))'s startSpeakingString:theTime
    end if
    if isNotifEnabled then
        tell me to activate
        display dialog "The current time is " & theTime with title "Current time" buttons {"OK"} giving up after 5
    end if
    return 300 - giveup -- the number of seconds for next idle run (less the dialog giveup time)
end idle