Enable "Announce the time" with Applescript - applescript

How do I enable the "Announce the time" option in the Date & Time System Preference using Applescript?

You can do this via a terminal command: defaults write
I managed to dig out the preference file that's being written to when you toggle this setting: ~/Library/Preferences/com.apple.speech.synthesis.general.prefs.plist. Note that this file may not exist on your computer; it's only created if you've toggled the "Announce the time" checkbox in System Prefs.
The key you're changing the value for is TimeAnnouncementsEnabled, which takes a boolean value of YES to turn on the announcements and NO for off. This key is inside of the dictionary TimeAnnouncementPrefs which houses the other settings related to the voice announcements. The terminal command to turn on the time announcements is:
defaults write com.apple.speech.synthesis.general.prefs TimeAnnouncementPrefs -dict TimeAnnouncementsEnabled -bool YES
To use this in an AppleScript simply do the following (to run a terminal command from AppleScript):
do shell script "defaults write com.apple.speech.synthesis.general.prefs TimeAnnouncementPrefs -dict TimeAnnouncementsEnabled -bool YES"
That should do it. The other preference keys (voice, custom rate and custom volume) will be reset to their defaults if you use the command as above. If you want to set them to non-default values you'll have to explicitly set them along with the above key value. However, since there are some nested dictionaries you'd probably need to look at using plistbuddy (which isn't installed by default AFAIK). However, if you only want to set the announcement on/off option, don't worry about it. This will set you up!

Related

What's the programmatic equivalent of "defaults read"?

When I do defaults read at the command line, I get over 6000 lines of keys. When I enumerate UserDefaults.standard.dictionaryRepresentation() in a program (non-sandboxed), I get only about 50 lines of values.
What's the Foundation version of defaults read? How do I get all the NSUserDefaults keys in a program?
defaults read without any domain argument reads all domains for the current user. UserDefaults.standard.dictionaryRepresentation() reads just the current application's domain.
I have no idea why you'd want to read all domains, but you can do it using the CFPreferences API. You start by calling CFPreferencesCopyApplicationList(kCFPreferencesCurrentUser, kCFPreferencesAnyHost) to get all of the application domains (including the global domain, kCFPreferencesAnyApplication). Note that this is deprecated without any replacement that I'm aware of. Then, you iterate through those and call CFPreferencesCopyMultiple(nil, eachAppIDInTurn, kCFPreferencesCurrentUser, kCFPreferencesAnyHost).

SSH Screen Ignoring CTRL

When I SSH into a particular server and launch screen, it ignores my CTRL+a key combo. Instead of CTRL+a c creating a new screen window, it instead acts as if I had just typed c. Other key combos fail in a similar way.
I've tried launching screen using screen -e ^jj to bind to j instead of a, but I still get the same result as above.
I tried adding a .screenrc file to my homedir that I know works on other machines, but it has no impact.
I also tried launch a zsh shell instead of bash.
Any ideas where to start to try and fix this? This basically renders screen unusable.
Thanks
screen reads commands from several configuration files during startup, as described in the FILES section of the man page or the Customizing Screen section of the User's Manual (also available, if it's installed, by typing info screen).
The files read are:
The file named by the $SYSSCREENRC environment variable (this may or may not be enabled)
/etc/screenrc
The file named by the $SCREENRC environment variable`
$HOME/.screenrc
(These interact and are searched in various ways that I don't entirely understand.)
In your particular case, based on the comments, the system on which you're running screen happens to have a /etc/screenrc file that contains an escape command that overrides the default.
A digression: in my own $HOME/.screenrc I have:
escape ^#^#
This sets the escape character to the null character, which can be entered by typing Ctrl-space. I find it easier to type, and less likely to conflict with other uses, than the default Ctrl-A. The only conflict I run into is the Emac set-mark-command function, and for that it's easy enough to type it twice.

set volume not working in xcode with applescript cocoa objc

I have an applescript xcode project in xcode 3.2 and am trying to change the system volume...however it doesn't work...it either stops the nstimer or doesnt do anything at all...
Is there a way to log the errors so that I can pinpoint the issue?
Here is my code
set newVolume to 50
set volume output volume newVolume
textName's setStringValue_(currentVolume)
set currentVolume to newVolume
obv this is a much more condense version but this literally does not work...it is inside of an NSTimer but, even when not within an NSTimer it still does not work...newVolume, currentVolume, and textName are all declared...do I need to declare something for the set volume line?
So, your actual question was simply how to log errors from AppleScriptObjC:
AppleScriptObjC will log any errors thrown in your script to the console -- just look in the bottom pane in Xcode. For instance, in your case you should see something like “«script» doesn’t understand the «aevtstvl» message.” (This isn’t terribly clear, but it’s telling you that your script sent a set volume command to a script object, which didn’t have a handler for it.) If you want to capture and log errors yourself, you can put troublesome sections inside a try/on error block, and deal with it yourself in the error handler.
If you’re feeling extra inquisitive, you can also turn on the NSScriptingDebugLogLevel preference, like this:
defaults write com.me.myapp NSScriptingDebugLogLevel 1
...and AppleScriptObjC will log information about every message sent either way across the bridge. (Set it to 0 or use defaults delete to turn it off.)
That’s error logging. Now, what you didn’t actually ask, but I’m going to answer anyway, was “How do I fix my set volume command?”
Short version: add tell current application to:
tell current application to set volume output volume 50
And yes, the range for the “new” volume parameters is 0 to 100. The old compatibility one goes from 0 to 7. (Why? The old Control Panel volume slider had 8 stops.)
Long version:
There’s a bad interaction between the default direct parameter and set volume’s handling of it. When using AppleScriptObjC, “it”, and therefore the default direct parameter, unless you say otherwise, is the current script, and set volume chokes on that. You can force “it” to be nothing by saying tell current application to. (Alternatively, you could give it an explicit direct parameter by using the old-fashioned form set volume x where x is a real number from 0 to 7. However, this doesn’t match the numbers you get from get volume settings, only lets you set the output volume, and doesn’t let you set things like “muted” correctly.)
And by the way, if your AppleScriptObjC project is sufficiently simple (in particular, if you don’t need any interface), you can write it directly in AppleScript Editor: choose File > New from Template > Cocoa-AppleScript Applet, and use the normal AppleScript on run and on open handlers, except that you can now also invoke anything from Cocoa.

How to run a script after a choice is made in a tcl tk combobox

I'm using ttk::combobox and I want to run a script each time a choice is made. But in the documentation only a -postcommand option exists, which runs the script before the choice. How can I run the script after the choice (I want to be able to know when a choice is made).
Also, the combobox is -state readonly so no choices can be made through the entry.
Bind to the <<ComboboxSelected>> virtual event, which the combobox generates every time after an item is chosen.
bind .combo <<ComboboxSelected>> {puts "chosen [%W get]"}

Change settings of a running process

I noticed that when a process starts for the first time, it statically reads some system parameter info only once and keeps it until terminated
which means,
that if there is some modification to the system parameters already read by the process, they wouldn'y reflect until the process is restarted.
e.g. Launch Notepad and type ';' key on the keyboard. Now change the input language from the langauge toolbar to Spanish. Now again hit the key ';'. Though the Input langauge has been changed to Spanish, the keys are still English (as seen by pressing ';' key).
Ideally on pressing ';' afer the input language is changed to Spanish, we should have noticed 'ñ'.
When we restart Notepad, we notice that ';' results in 'ñ' which means that the Notepad process needed to be restarted to take effect.
Is there some way where the process is not needed to be restarted to reflect the change in the Input method?
Thanks
If a process cares to, it can listen for notifications of changes to various system-wide settings. The wm_SettingChange message comes to mind.
It's a fool's errand to try to make some other process honor setting changes if it hasn't been written to do so. If a program isn't already listening for change notifications and acting upon them, you can't make it act differently.
Notepad probably isn't a good example; it's a pretty simple program, so it doesn't necessarily cover all the details that a good Windows program should.
The "answer" you gave, to refine your question, talks about changing the system's default input language with SystemParametersInfo. When you call that function, it will broadcast the wm_SettingChange message. To be notified of the change, other programs need to listen for that message; do that the same way you listen for any other window messages in your programming environment.
When you receive that message, the wParam parameter will be either spi_GetDefaultInputLang or spi_SetDefaultInputLang; I don't know which. That's you cue to call SystemParametersInfo to find out the new value of the setting. Based on what I've just read in "Languages, Locales, and Keyboard Layouts", you should call ActivateKeyboardLayout using the HKL value you get from SystemParametersInfo.
The process that changes the default input language cannot force other processes to use it. Until they choose for themselves to change their input languages, they will continue using whatever was the language when they started running. That's the distinction between the default setting and the current setting.

Resources