Ruby, iOS, and Other Development

A place to share useful code snippets, ideas, and techniques

All code in posted articles shall be considered public domain unless otherwise noted.
Comments remain the property of their authors.

2016-05-30

OS X Minutiae: DTerm, Environment Variables, and Launch Services

I've been using DTerm for years, but it recently stopped working for me. I guessed it had to do with switching my shell to zsh (from tcsh, which I'd been using since the early 1990s), and a little searching found a blog post from 2008 pointing to exactly the issues I was having and the solution: setting the SHELL environment variable to /bin/bash on launch. The post recommended launching from the commandline with env SHELL=/bin/bash TERM=dterm open /Applications/DTerm.app and, in fact, that works. My problems are solved, right?

Of course, I want DTerm to launch on login, so I either have to write a script (AppleScript or shell) to launch it and put that in my login items or dig a little further. That led me to an answer on StackExchange about setting environment variables for launched apps on OS X. I added the following block to the Info.plist:

 <key>LSEnvironment</key>
 <dict>
  <key>DISPLAY</key>
  <string>:0</string>
  <key>SHELL</key>
  <string>/bin/bash</string>
  <key>TERM</key>
  <string>dterm</string>
 </dict>

That had one effect I didn't expect, but not the one I did. I had to go into the Accessibility pane under the Privacy tab of the Security & Privacy System Preferences and explicitly authorize DTerm. DTerm offers to set it automatically at a button press and administrator authentication, but it doesn't succeed; doing it manually from System Preferences does the right thing. I was expecting adding this LSEnvironment block to make DTerm launched from a double-click work the way it does when launched with the commandline above, but it did not. More digging was required.

The "LS" part of LSEnvironment refers to Launch Services, which keeps the system aware of available apps and what sorts of documents they can handle. In looking for how to make sure Launch Services was picking up the environment variables I was setting, or at least why it wasn't, I found a (slightly outdated) hint on how to work with the Launch Services database from the commandline. The lsregister command (along with the entire LaunchServices.framework) has moved since then, and your best bet on finding it is to use locate lsregister from the commandline. I found it in /System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister but it may move in future versions of OS X. I used -dump with it to figure out what it thought was set, but what ultimately fixed things was the following:

/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -u ~/Applications/DTerm.app -apps local,network,system,user

That unregistered the app from Launch Services, and when it reregistered the LSEnvironment block was picked up. DTerm now launches from my login items and happily bahaves the way it used to.

Enjoy!

P.S. Sorry for the long absence. I can't promise to get back to posting with any regularity, but at least you know I'm not dead.

Labels: