Tuesday, November 27, 2012

What I Did Instead of the Xamarin Contest

So I really did intend to throw together an entry for the Xamarin contest, but realistically I didn't have time in my evenings and Saturday mornings to get anything substantial built.  In light of reality, it was nice to stumble across an article with a silly signature and post a Facebook status that escalated into a more suitably-scaled diversion.  Here's two weeks' worth of my free time:

68 74 74 70 3a 2f 2f 62 69 74 2e 6c 79 2f 57 75 65 62 63 39

Note: I failed to test on a touch device until just now, and it doesn't work.  Use a real computer.

Post your answers as comments on this entry.  Hints are available, within reason.  Enjoy!

Tuesday, November 20, 2012

Mono for Mac Scripting: Rawr!

I take it all back.  In the end, I'm unable to use Mono to script my little project on the Mac, because:
  1. I can't wait for processes to complete.  I call System.Diagnostics.Process.Start(myStartInfo).WaitForExit(), but files written by the command-line programs I'm calling aren't on disk by the time I open them for processing in the next step.  I read several places that you need to set UseShellExecute = false to have the process called directly rather than via the "open" command (which returns immediately by default), so I set this property, but it didn't help.
  2. The PNG support in libgdiplus is apparently busted.  [Link here when I bother to find the blog post/bug report again.]
Given that this was a project to script the generation of some PNGs with ImageMagick, read them in, and spit out their raw bytes....

Saturday, November 17, 2012

Serious Mono Development on the Mac: Why Not?

I've had Mono installed on my Macs for years now.  Mostly it was a novelty--occasionally I'd test some CLI or trivial Windows Forms app I'd written at work, just to see if it would run.  I wrote one quick image stitching program on the Mac for a friend's wife's blog (using GDI+, which actually worked, which in hindsight I realize is pretty impressive), but I've never done any "real" C# development on the Mac, for a few reasons:
  1. That's just wrong.
  2. I didn't have a good IDE (more on that in a bit).
  3. Compiling and running from the command line is gross.  (Yes, I know, MonoDevelop, getting to that...)
  4. I mostly wanted to do GUI stuff, the Windows Forms support was only partial, GTK sounds gross because it's not native to either .NET *or* the Mac, I didn't know any Cocoa, and Cocoa# sounded like a pretty experimental hack when I first read about it anyway.

Not So Wrong Anymore

I think I've gotten past point 1.  It comforts me somehow that Mono is now something of a commercial product thanks to Xamarin's work on MonoTouch, which presumably has positive implications for the desktop Cocoa bindings, etc.

When Mono on the Mac felt like an unsupported hack (I don't really know what kind of support Novell provided), I wouldn't have thought to use C# for anything but personal tinkering.  In particular, the thought of distributing a Mono app was out of the question, not because it was technically impossible, but because of point 4 and the whole packaging problem.  You can't distribute a Windows Forms app to Mac users; they'll hate and shame you.  The same probably goes for a GTK# app, with the possible exception of MonoDevelop.  So you had to develop a Cocoa# app, which felt both unsafe and unappealing.  And even if you completed one of those funky Cocoa# apps, you'd either have to somehow package it together with Mono or tell your users to go download this weird experimental Windowsy runtime platform to run your app.  Since very few users would have Mono installed by default, that would mean a huge download either way, even if your application itself were trivial.

But Mono on the Mac doesn't seem nearly so wrong now.  Even without Xamarin, C# on the Mac is probably here to stay thanks to the Unity folks.  For GUI development, MonoMac is ostensibly a decent set of Cocoa bindings that is well supported or at least has the interest of Miguel de Icaza, which goes a long way.  There's a MonoDevelop plugin with MonoMac project types, a packaging system for bundling only the assemblies used by your app, and even support for deploying to the Mac App Store.  Combine that with MonoTouch gaining traction as a real solution for iOS development, and MonoMac really doesn't sound too scary anymore.

A Real IDE

Realistically, I'm not going to do any serious coding without an IDE.  One of the things that makes .NET such a productive platform is its discoverability via IDE tools.  In C, how do you learn what you can do with a string?  Get a book?  Google "string manipulation?"  In C#, how do you learn what you can do with a string?  Type a period after the variable name or string literal.  I'm productive in typed, object-oriented, garbage-collected languages not just because of the high-level abstractions provided by the languages but because the typing system, object-orientation, and garbage collection all lend themselves to library design where all functionality pertinent to an object can be accessed via a method on that object.  This means I don't need to know an entire library before I start working with it or interrupt my workflow for an internet search every time I need to call a new method.  I do a quick Google search for a "starting point"--the main class of interest--and Intellisense my way to a working program.  This is huge.

There are other perks of an IDE, of course, like automatic syntax checking (love those red squigglies), GUI access to the file structure, streamlined builds,  and so on.  These are all things provided by IDEs like Visual Studio on Windows and XCode on the Mac.  If I'm going to do C# development on the Mac, I'm going to do it in an IDE.  And that's partly why, to date, I haven't done C# development on the Mac.

When I wrote that quick C# app on my Mac for a friend, it took longer than it should have because I was editing my program in a text editor with no syntax checking or Intellisense and compiling from the command line.  I don't remember if MonoDevelop existed at the time, but if it did, I was probably turned off for the following reasons:

  1. It's GTK.  Ugh.  Nothing against GTK *on Linux*, but this is my Mac and you're making it ugly.  Not even because GTK is especially ugly, but because you're clashing with the rest of my system.
  2. The non-native L&F leads me to expect non-native behaviors (awkward keyboard shortcuts, swapped button order in dialogs, etc.).  Basically I expect the developers to make it Mac-like only as a half-hearted afterthought.  Seriously, if you expect me to Ctrl-C for Copy on my Mac, we're done.
  3. I've used enough OSS GUI apps to keep my expectations really low.
Well, tonight I needed to script some command-line work, and I very nearly used Perl.  But I thought to myself, "Why am I doing this?  I'm going to have to go re-learn all the basics like I do every time I write a Perl script, and yes, it will be terse, but even if it takes me twice as many lines in C#, it'll take me half the time because I know C# and what I don't know or don't remember is discoverable with a good IDE, and I have this MonoDevelop thing sitting on my Mac for the Xamarin contest that I will never complete now that I'm distracted by silly code riddles (and would never have completed anyway), so let's give it a shot!

I fired up MonoDevelop and created a Console solution.  Aesthetically un-awesome, but behaviorally not unlike Visual Studio project setup.  I started typing and got some lovely code completion, with a few gotchas:
  1. Code completion is case sensitive.  Gah!  I can't tell you how many times in an evening I typed "System.io<TAB>" and ended up with "System.IndexOutOfRangeException."  Hopefully there's a setting to configure this.  If not I may submit a feature request.  They'll probably just tell me I'm spoiled by VS.
  2. In general it appears pickier than Visual Studio, especially VS 2010+, which match any text within a suggestion, not just the first word.
The syntax checking appears to be less than awesome too.  I frequently had to build before discovering I had a typo or other syntactical problem.

All that said, I think it's good enough.  Here are some things it does right:
  1. Project creation and organization is nice.
  2. Build and run works as expected, with configurable "Custom Execution Modes" for saving lists of command-line arguments and whatnot.
  3. The keyboard shortcuts are correct!  It behaves like a native Mac app for the shortcuts I use frequently, and that's enough.
Okay, that's a short list, but this is from one evening's use.  Basically, it's a real IDE that isn't so horribly un-Mac-like as to be unusable, and it lets you develop C# code on your Mac.

Better Than the Alternatives

What I realized tonight was that developing a quick C# console app in MonoDevelop was my best choice for the task at hand.  I had lots of scripting languages to choose from, but I know C# better and I have a decent environment for writing and running it, so why not?  I'm thinking about how this logic extends to real Mac GUI development.  If the Cocoa bindings are decent, MonoDevelop is an acceptable IDE (XCode is certainly nothing to write home about anyway), and C# beats the pants off of Objective-C.  There's a real developer community around the iOS stuff, and presumably there's some trickle-up to the Mac.  I don't have the time or interest to get good at Objective-C, but I could see learning enough of the Cocoa API to string a GUI to some good, sensible C# model/controller code.  Mono might actually get me developing for the Mac.

Wednesday, November 14, 2012

Swipe Gesture Overloading Considered Harmful

So both Firefox 17 and Chrome 23 interpret a two-fingered right-swipe on my RMBP trackpad as a "back" gesture.  This would be a really nifty feature if right-swipe didn't have the system-wide canonical meaning "drag the scrollable content right."  You say, "What?  No horizontal scroll gestures in Firefox and Chrome?!!"  No, it's worse than that.  You get horizontal scrolling until you can't scroll anymore, at which point your next swipe unloads the current page.  Hope it was just a page, not a client-side webapp, or you just lost your work.  Somebody fix this.

Edit: apparently this behavior is due to a misguided attempt on Firefox and Chrome's part to be good OS X citizens and implement the OS-wide "Swipe between pages" gesture, configurable in the "More Gestures" tab of the Trackpad Preference pane.  Such a gesture may make sense for, say, the Preview app, but is a truly bad idea for a "page" that may contain dynamic content.

Saturday, November 10, 2012

MacPorts vs. Homebrew: My Uneducated 2¢

For the server side of my project for the Xamarin contest, I'm trying Ruby on Rails.  Never used Ruby or Rails before, but I know how slow Java webapp development is (at least with the stack of technologies I'm familiar with) and that won't cut it.  My hope is that I can copy-paste enough code from the web to get a working Rails site going quicker than I could do the same thing in Java.  This seems like a fair test of Rails, right?

Well, the Rails installer strongly encouraged me to get Homebrew and do all my prerequisite installs that way.  All I knew about Homebrew was that it existed.  I've already installed a lot of UNIX stuff via MacPorts, which seems to work fine, so I did some quick reading about the differences.  They seem to be:

  1. Installation directory: Homebrew uses usr/lib; MacPorts uses /opt/local.
  2. Dependency resolution: Homebrew uses existing system installs where possible; MacPorts always installs the latest and greatest version of your dependencies.
  3. Notions of ownership: Homebrew wants to take over /usr/lib, which is a standard UNIX install location, and set ownership for that folder to a single user to eliminate the need for sudo; MacPorts uses a nonstandard location to avoid interfering with other installs and requires sudo for installation, making installed software available to all users.
  4. OS upgrade support: Since MacPorts is in its own little world, it's not broken by system updates; since Homebrew installs to /usr/lib and depends on system libraries, it can be.
  5. Database Management: Homebrew uses git and Sqlite to track installed apps; supposedly this makes it easier to upgrade Homebrew itself.  Or something.
  6. Coolness/Prettiness Factor:  Homebrew's website is all pretty and modern and makes everything look simple and seamless.
  7. Community: Since Homebrew is written in Ruby, all the Ruby fanboys use it and all the Ruby stuff takes for granted that you're going to be using Homebrew.  I haven't yet hit any snags where Homebrew had something I needed that MacPorts didn't, but there's a lot of pressure to conform.
The best article I found comparing the two this one by Ted Wise.  I also read one slightly scary story about MacPorts.

After some reading, here were my thoughts:
  1. MacPorts sounds a lot less problematic, especially when it comes to OS upgrades.
  2. Having to download less for Homebrew sounds nice for installations at home over a not-super-fast cable internet connection.
  3. Git and Sqlite are cool, but I guess I don't really care how things are stored so long as the installs are seamless.
  4. I'm already using MacPorts, and I don't know what happens when I start mixing the systems.  I suppose everything's fine so long as I don't install the same package from both, but what about dependencies that get sucked in?  Plus, if I use both systems, I have to decide which to use for every package I install.
  5. While I don't *like* Homebrew's notions of ownership, I'm the only user of my system and I guess I don't care what it does so long as none of my existing stuff breaks and Homebrew does its thing right.  The Homebrew page assures you that's how it'll go.
  6. It would be nice to be doing things the "default" way for all the Ruby stuff.
  7. I already have stuff in /usr/lib that I've built and installed from source.  I *think* Homebrew is supposed to leave that stuff alone so long as you don't try to install the same package via Homebrew.  But I wasn't sure.
In short, I saw pros and cons for installing Homebrew but definitely didn't want to switch to it wholesale.  I decided to try things the "no-nag" way to appease the Ruby folks and install my Ruby dependencies via Homebrew.

Upon installing, Homebrew warned me that I was using MacPorts and that I should probably rename, if not delete, my MacPorts install directory.  Uh-oh.  I hoped this was only necessary if Homebrew and MacPorts installed conflicting versions of the same library, and I was going to keep my Homebrew installs to a minimum, so I proceeded.  But the Homebrew installer also encouraged me to run "brew doctor" to list all the potential problems with my system.  It complained about all the stuff in /usr/lib and then about some library from my Mono install.  And I thought, y'know, this MacPorts-all-in-its-own-world thing is starting to sound pretty nice.  So I uninstalled Homebrew using this script, installed the Ruby/Rails dependencies via MacPorts, and went on my merry way.

So.  MacPorts for me.

Thursday, November 8, 2012

Xamarin is Cool

I've been distracted from my Retina MBP setup series by several side projects.  In addition to a very disappointing Facebook ad campaign for Reverse Remote and the setup of the flamingtortoise.com domain, I've been planning an application I will never write for this contestXamarin is cool for so many reasons.  I actually read about them on Miguel de Icaza's blog as they were starting up (right after the spin-off from Novell/Attachmate) and applied for a developer position listed as "telecommute."  What could be cooler than developing for a cool platform like the iPhone in a real language like C# in your pajamas, right?  I got as far as a phone interview with the CEO, but no luck.  Still, some pretty cool technology.  I'm reading up on the best RAD tools for MonoTouch and web development to see if I can get a bare-bones app thrown together in a few weeks of evenings and Saturday mornings.  Probably won't happen, but I may carry the idea to completion at my own pace anyway, just for the heck of it.  If it's good, I may try to publish it.

Flaming Tortoise Enterprises

So most of my work is for the federal government, writing apps used by at most a few hundred people working under confidentiality agreements.  A lot of what I've written is pretty nice, if I do say so myself, but I have very little to show for it except the skills I've gained over the last eleven years.  All the public software I've written is linked to in the sidebar.  The only remotely commercial item is Reverse Remote, my iPhone app, which now has a fancy-schmancy marketing webpage thanks to WordPress and the Grizzly theme.  You should go there, buy my app, and read my very first blog post on the flamingtortoise.com blog.  Honestly this post is mostly about getting Google to index the new site.

Friday, October 26, 2012

macopen, a Bash Script to Open and Edit Linux Files on Your Mac Using SSH/OSXFuse/sshfs and OS X's 'open' Command

Note: a user on the textmate IRC channel mentioned rmate, which already does much of what I was trying to accomplish.  It appears to be TextMate-specific though.

Okay it's late and I don't have time for a long description, but this is my first true "hack" and I need to post about it quickly.

Do you ever find yourself logged into a remote UNIX machine from your Mac via SSH, wishing you could say (for instance) "TextMate foo.txt" and have foo.txt from the remote filesystem open in TextMate just like it would in an X Window app?  Turns out this isn't all that hard to set up.  There are good tools for mounting remote filesystems via SSH; all that's missing is a way to auto-mount them and launch Mac apps from the remote end.  I considered writing a fancy server until I realized everything was already there with a reverse SSH connection.  So I wrote a script that logs *back* into my Mac from the remote machine, mounts the remote filesystem via OSXFuse and sshfs, and launches the file via OS X's "open" command.

To make it work, install OSXFuse and SSHFS, both available for download from this page.  Then enable remote login on your Mac and configure your Mac and the remote machines for password-less SSH using ssh-keygen as described here.  Then download the macopen script, install it on the remote machine, and enjoy.

There are some rough edges, but I'll work those out over time.  Note that the machines have to be able to route to one another, so no NAT support right now.  I read a little about SSH tunneling/reverse SSH, which might be able to help when your Mac is behind NAT.

I'm not really a UNIX/shell scripting guy, so probably I'm doing all sorts of things wrong.  This is the longest bash script I've ever written, if that's any indication.  So feel free to fork, clean it up, issue pull requests, and what-have-you.

Good luck!

Tuesday, October 23, 2012

Replacing DragThing (Setting Up a Retina MacBook Pro for Multi-Platform Development, Part 3)

I am a big fan of DragThing.  I've owned a copy since probably Mac OS 8, and it's the first app I install on every new Mac I buy.  It sits unobtrusively at the bottom of my screen, pinned as a drawer...

My Main DragThing Dock, Shown as Drawer

waiting for me to hover, click a tab, or drag a file onto an app icon...

My Main DragThing Dock, Responding to Dragged File

or (maybe most importantly for me) hit the user-defined key chord for a commonly-used app:

DragThing Item Hot Key Editor

But it does cost money, and for my new work PC I didn't want to rack up requests for nonessential utilities.  After all, I use it primarily as an app launcher, and there are other ways to launch apps on OS X.

So I'm trying an experiment.  Rather than pinning the Dock to the right side of my screen, removing almost all the icons, and and setting it to auto-hide, I'm going to try using it.  I find it awkward and obtrusive sitting there at the bottom of my screen with its poorly-defined boundaries, but maybe I'll get used to it.  I can't put anywhere near all my apps in it, but I can add some favorites.  I can't define tabbed layers with app categories that automatically open when a file is dragged onto them, but maybe there are other ways to skin that cat.  It's nice at least that my Downloads folder is more readily accessible (now that downloading to one's desktop is out of fashion), and now when Dock icons bounce it seems like part of my standard UI rather than a weird annoyance from out of nowhere.

So anyway, here is my RMBP Dock, about one month in:

My Retina MacBook Pro's Dock

I've got all the essentials, plus a few non-essentials I'm vaguely afraid to remove or I keep there for completeness or aesthetic reasons.

What I find is that I use the Dock for "in-between" apps--ones I launch semi-frequently that I don't feel warrant their own key chords (more on this next).  For apps that didn't make the cut for the Dock, I'm experimenting with various launchers but will probably stick with QuickSilver because I need it for hot keys and its "power user" features give me feelings of superiority.

Non-Dock App Launching Options in OS X

There are plenty of ways to launch apps in OS X without the Dock.  Here a few.

Option 1: The Finder

The classic way to launch a Mac application is simply to double-click the app's icon in the Finder:

The Applications Folder
The Applications Folder is for You (Kind of)!
The idea of navigating to the app's icon in the Finder isn't as foreign to longtime Mac users as it is to Windows users.  In Classic Mac OS, your hard drive was your own and you were free to put your apps (which were, in general, entirely self-contained) anywhere you saw fit.  There was no off-limits Program Files directory that only installers were allowed to touch.  The application icon was both the representation of the executable file in the filesystem and the default interface for launching the executable.  Things got a bit scarier with the UNIXification of Mac OS, and after some bad app upgrade experiences in the early days of OS X I'm very leery of reorganizing my Applications directory (which is a shame).  But Apple still clearly considers the Finder acceptable interface for launching applications and provides a prominent link to the Applications folder in the Finder's sidebar.

The Finder is my last-resort app launcher because it just takes too many clicks or awkward keystrokes to get from working in an application to selecting an app icon.  With the keyboard, I can Command+Tab to the Finder (minimum two keystrokes), type Command+Shift+A (a very awkward key chord that forces me to leave home row) to open the Applications folder, and then start typing the application name (hoping I don't make any typos).  With luck, I get the correct icon selected and can type Command+O to open it.  This is silly; I might as well use the mouse.  But mousing to a Finder window means first getting (usually) several layers of application windows out of the way (I suppose I could use Exposé) to get to an open Finder window or the desktop, then double-clicking my way to the correct folder.  This is slow and annoying.

Option 2: Spotlight

If an application appears as a hit in a Spotlight search, you can launch it by clicking the appropriate menu item or selecting it with cursor keys and hitting Return.  I really want a solution that's either all mouse or all keyboard, so clicking a menu option that appears after typing isn't great.  And I dislike using the cursor keys because I can't use them reliably without leaving home row.  But Spotlight works okay if the desired application is the top hit: Command+Space to pop up the search box, type the first few characters in the app's name, and hit Return (no cursor keys) to launch the top hit.

Launching Applications from Spotlight

Option 3: Launchpad

With OS X Lion, Apple introduced the iOS- (or maybe System 7.5)-inspired Launchpad app, a secondary interface for app launching.  I can click its icon in the dock or launch it via F4 on the RMBP (no need to hold the "fn" key).

My OS X Launchpad

It's pretty, but it doesn't hold any more icons on a single screen than the Dock, so it doesn't really make more apps accessible graphically.  What's more, even though they're smaller, icons in the Dock are easier targets thanks to Fitts's Law.  Launchpad has a search feature that will narrow down the list of apps as you type, so it's decent for keyboard control, but really no better than Spotlight, which is easier (for me) to access from the keyboard and makes the top hit just as keyboard-accessible.  As in Spotlight, selecting the non-top hit requires use of the cursor keys.

Third-Party App Launching Options

There is no shortage of third-party application launchers for the Mac.  I don't know why this is such a popular category for Mac apps, but it is and has been for decades.  Even back when I first heard about DragThing, there were several full-featured alternatives.  These days, some favorites appear to be:
LaunchBar looks very nice, and if I were a new Mac user in the market for a full-featured, commercial app launcher, I'd give it a serious look.  But the point of my search was to find something free, so I only tried free launchers.  I've installed Alfred, QuickSilver, Namely, and Chuck.  I never got around to trying the last three, not because they're any less compelling than the others, but because I'd already settled into a groove when I first read about them.  Below are my thoughts on the apps I did try.

Chuck

Chuck is a nice, simple, free app available on the Mac App Store.  You can set it to start up at login and summons it with a user-definable hotkey.  It's this:

Chuck Launching Firefox
That's pretty much it.  You pull it up, you type a few characters from the name of your app, and you hit Return to launch your app.  Hitting Command-F instead will reveal the app in the Finder.  There are a few preferences, but basically that's Chuck.  It's lean and mean and nice for what it is.  It offers potentially two advantages over Spotlight for app launching: the list contains just apps, and you can use abbreviations that omit intermediate characters for apps (e.g. "ffx" for Firefox).  Nice app, but I want something a little beefier.

Namely

Namely is... a whole lot like Chuck:

Namely Launching Firefox
Nothing wrong with that; I just don't have much more to say about it.  Good, single-purpose app.  Not quite full-featured enough for my tastes.

Alfred

Alfred is gorgeous.  Behold:

Alfred Launching Apps

Like Chuck and Namely, it's a background app that listens for a user-defined hotkey (by default Option+Space) and displays a floating search box with the top hits for your search.  Hitting Return launches the top hit, and--learn a lesson, Apple--there are keyboard shortcuts for the next six!  There are also all sorts of little goodies, like a built-in calculator:

Alfred as a Calculator
(I recently discovered that Spotlight does this too--cool!)

This would be my ideal app launcher if the PowerPack were free.  The PowerPack has the one DragThing feature I'm most eager to replace: user-assignable hotkeys for applications.  If I were seeking a beautiful, less-is-more app launcher for a new personal Mac, I'd get Alfred and buy the PowerPack.  But this whole experiment is about finding what I can get for free, so...

QuickSilver

I guess QuickSilver was all the rage about six years ago and I missed it because my app-launching needs were taken care of.  In 2007 the main developer, Nicholas Jitkoff, actually ceased development to work on Google Quick Search Box.  He open-sourced the code, but OS upgrades repeatedly broke compatibility and there wasn't much serious development for several years.  But now it's on GitHub with an active developer community, and I read good reviews so I tried it out.

Like Alfred, QuickSilver's primary UI is a floating search window launched with a hotkey.  Here's the default appearance:

QuickSilver Launching Firefox

I've hit Ctrl+Space and typed "f."  Firefox is the top suggestion; others are shown in the list below.  The second pane on the right is the default action.  If I hit Return, the default action will be executed on the selected item.  For applications and files, the default action is "Open"; there are also other types of search results you can configure to appear in the list.

To execute an action other than the default, you can hit Tab to highlight the Action pane and use the cursor keys to highlight another action:

QuickSilver Actions

Some actions take an additional argument:

QuickSilver Arguments

The previous two images hint at the "power user" features that QuickSilver is known for.  It has a plugin system for adding actions of all sorts, in particular app-specific actions that expose functionality of Apple-provided and third-party apps via QuickSilver's interface:

QuickSilver Plugins
More importantly for me on a practical level, though, is the "Triggers" interface:

QuickSilver Custom Triggers
Ah, there they are.  My app hotkeys.  So QuickSilver wins.  Realistically, I will probably rarely, if ever, use more than a few hotkeys and the occasional Ctrl+Space+<app name>+Return.  And I could get the latter effect from Spotlight with a Command+Space.  But QuickSilver provides the best overall package at my at-work price point ($0), so that's what I'll be using most.  I wish it were as pretty as Alfred; I wish it supported keyboard shortcuts for the top several hits; I wish it didn't have a creepy alchemical symbol for a logo; but it gets the job done.

Side Note: Good Software is Worth Money; Good Free Software is a Gift

I want to make it clear that QuickSilver is only my top choice among the free apps I tried.  In general I'm not opposed to paying for good software--at home I'm still using DragThing, and apps like Alfred (with PowerPack) and LaunchPad seem well worth the money.  But it does amaze me how much great freeware there is for the Mac, and QuickSilver is an excellent piece of software.  It has probably hundreds to thousands of hours of development time in it, and it is worth real money.  That the developer chose to give it away for free is charity on his part, and I greatly appreciate it.  Thanks, Nicholas Jitkoff.  And thanks to all the other QuickSilver developers who have taken over the code base.  I'll be discussing other free apps in future posts, some of which are best-in-class and some of which are "best-in-class-for-free."  I want to encourage readers to:
  1. Appreciate and be thankful for the free apps and
  2. Don't snub the commercial ones.  Developers need to eat.

Saturday, October 13, 2012

Finding Good, Free Mac Software (Setting Up a Retina MacBook Pro for Multi-Platform Development, Part 2)

As I mentioned in the introduction, lately at work I've been on a low-budget Mac software shopping spree for a Retina MacBook Pro.  I'll talk about specific apps in future posts, but first I'll discuss finding good Mac software.

(If you're impatient, go to thriftmac, by far the best curated list of Mac freeware I've found.  For my rants and raves, read on.)

There's (Probably) a (Beautiful, Free) App for That

I've used Macs personally since 1995 and Windows professionally since 2001.  There is undeniably more freeware and low-cost software for available for Windows machines than for Macs.  But I'm not convinced there's actually more *good* software.  This is a bit subjective, but I find that when I search for a free Windows utility to accomplish this or that task, most of my time is spent filtering the list to the one or two apps that don't completely embarrass themselves.  On the Mac there may only be three apps that even try, but chances are that two of them will be serious solutions and they will all look and feel better than their Windows counterparts.  Consider, for example, the case of WinDirStat and GrandPerspective:
WinDirStat
WinDirStat


GrandPerspective
GrandPerspective


Enough said.

I attribute these differences to the fact that Mac developers are snobs.  They choose to work on and develop for a minority platform because they believe it's better.  They're keenly aware of what makes a Mac app a Mac app, and they make sure their own creations live up to their expectations.  Windows, on the other hand, is what people use and develop for by default.  So you get way more apps that are written simply to accomplish a certain task without consideration of how best to accomplish that task or present that functionality to the user.  That's how you end up with this UI:

Bulk Rename Utility
Bulk Rename Utility

(Incidentally, Bulk Rename Utility is actually pretty handy if you can figure out how to use it.)

So all that was just to say that there *is* good Mac software out there, and you generally have to do less sifting to find it... unless you're searching on the Mac App Store.

The Mac App Store is Horrible

The Mac App Store is horrible as a discovery tool.  Suppose I launch it with a general question like, "what are the most popular free Mac apps for developers?"  Here's the first screen I see:

Mac App Store Main Screen
App Store Main Screen
This screen is full of items Apple chooses to feature.  Obviously it's not going to be developer-focused, but it amazes me what mediocre software makes it into this list considering what serious apps are on the store.  Whatever.  Apple can feature what it wants so long as I can find what I'm looking for.  So I click "Categories" and choose "Developer Tools."  Here's that page:

Mac App Store Developer Tools
App Store Developer Tools
There are some featured apps at the top, followed by a list of the most recently released/updated apps.  Apple seems to try to feature a variety of application types, so don't expect to find "the standard tools" in the featured apps list; think of it more like, "oh, here's a neat little app that does X and has a pretty UI."  Except for XCode, which will probably always be there.  The release-date sorting gives new app some exposure but also gives Mac users the impression that Mac applications are primarily trivial, version-0.1, one-trick-ponies thrown together by first-time developers in desperate need of a graphic designer.  Honestly, if I didn't know better, this list would turn me off to Mac software.

But I know there's some amazing software out there, and some (though by no means all) of it is on the App Store, so I keep looking.  Clicking the "See All" link takes me to a page that looks promising because I can page through all apps in the category and I can sort!  But look:

Mac App Store Developer Tools "Sort By" Options
Developer Tools "Sort By" Options
That's right.  I can sort by Name or Release Date.  Uh, rating maybe?  Number of downloads?

So I look around some more.  Back on the Developer Tools page, I click the "Developer Tools Apps" header on the "featured" section.  That gets me a different list, sorted by who-knows-what (there's no "Sort By" option), but apparently featuring highly-rated apps.  Lovely.  I wish I knew the algorithm, but this gets me somewhere at least.  But I start clicking through apps and realize that many of these are very special-purpose.  Maybe they're "good" apps, but the fact that a fully-featured text editor like BBEdit shows up halfway down the list after ~30 clipboard managers strikes me as unintuitive.  For all I know, my Top 10 developer apps are scattered across the first five pages because there are fifty really popular color pickers apps.  And I have to process that many pages of color picker apps to find them.  Gah.  But okay, I'll give it a try.  I click the "Next" link at the bottom of the page and... it does nothing.  The App Store says I'm seeing page 1 of 5 (items 1-180 of 798), but I can't navigate to Page 2.  Awesome.

So I try another of Apple's curated lists.  The Developer Tools page has a link in its sidebar to "Top Free" developer apps.  I click that.   I get a page with 68 apps that I can supposedly sort by "Name" or "Bestsellers":

Mac App Store Top Free Developer Apps
Top Free Developer Apps


Changing the sort option appears to do nothing.  But this is at least a small enough list to scan through.  Note that all I have to go on here are the app name, developer name, rating, and icon.  No description of what the app does, so if that's not obvious from the name, I have to click each icon individually to get the app's description.  Many I don't click simply because the icon is ugly (I'm a Mac snob, after all) and the name doesn't immediately interest me.  I may be missing good apps I'd download if there were any descriptive text whatsoever in this display.

There is no Page 2.  I don't know Apple's selection algorithm for this page, but it seems better than the sort options available on the "All Developer Apps" page.  I wish I could go to that page and sort by this algorithm.

If you know the exact functionality you're looking for, you might think to search for it via the Search box in the upper right.  Let's try that.  I'll enter "Text Editor."  Here's what I get:

Mac App Store Text Editors
Text Editors
This is actually almost decent.  If I knew or could control what metadata were being searched, I could eliminate a lot of false hits, in which case I might prefer to search by "Most Popular" or "Customer Rating" rather than "Relevance."  But what's the first hit for "text editor" when I sort by "Customer Rating"?  Pablo Draw.  Of course.

And since I'm shopping on a budget, what I really want is the top free text editors, not the top text editors.  How do I get that list?  It looks like I can't.

What's really frustrating is that there are a lot of great Mac apps on the store.  Unfortunately, the best way to find them is to hear about them elsewhere and then follow a direct link to the store from the developer's website or search for the app by name in the App Store.  That's kind of sad.

Google Beats the App Store for Functionality-Specific Searches

 If you know what functionality you want in an app, the best way to find the "best" app is to Google "best Mac app for X."  This will usually take you to a blog post or article comparing several competitors, with links to the developers' sites.  Full-blown comparison reviews with screenshots are what usually get me to my desired app the fastest.  As noted above, the best app is not always on the App Store (for several reasons, many of which are Apple's fault), and even if it is, you'll find it quicker this way.

Use Curated Lists From Sources You Trust

Comparison reviews are great if you're looking for a specific type of app (say, "FTP Client.")  But if you just want to load up a new Mac with some good software, maybe discovering app categories that you didn't even know about, ask a Mac person.  This is how I discovered several of my go-to apps.  But these days I don't know many avid (no pun intended) Mac users, and my own knowledge of what's out there is a bit out of date.  So I Googled for things like "Top 10 must-have Mac apps" or "Best Mac apps for developers" and found some good lists.  These will usually point you to polished, mature, feature-rich apps, many offering functionality you wouldn't have thought to look for.

Go to thriftmac, Now!

By far the best up-to-date, curated list of Mac freeware I found was thriftmac.  The site is clean and user-friendly, not overrun with ads, jam-packed with good software, and focused on giving *good* software the exposure it deserves.  As the site's author says, "No crapware."  I clicked through every category, read descriptions, and clicked through to the developer sites for probably half of the linked apps.  This site is wonderful.  Thank you, Mark Rogers.

That's All for Now

As promised, future posts will discuss what Mac apps I've settled on and why, plus what else I've done to set up my RMBP for multi-platform development on Mac OS X Mountain Lion, Windows 8, and Linux.  Stay tuned!

Thursday, October 11, 2012

Setting Up a Retina MacBook Pro for Multi-Platform Development, Part 1: Introduction

I've spent the last eleven years at work developing on Windows XP.  It's... okay.  I used to loathe Microsoft, but now the relationship is more complicated.  Given my choice of any development platform and environment in the world, I would pick C#/.NET and Visual Studio.  On the other hand, in eleven years,Windows hasn't grown on me at all.  I know a lot more than I once did about Windows XP and probably more than the average consumer knows, but I still don't feel comfortable with it, and I certainly don't like it.

I bought Vista Ultimate to run at home via Boot Camp, and it seemed to offer few advantages over XP with a *lot* of rough edges and security-related annoyances.  From what I've seen, Windows 7 is nicer, but at heart I'm a Mac guy (specifically, a "Classic Mac" guy who has mostly come to terms with OS X but still mourns the death of BeOS).

So imagine my delight when I was told I could get a Mac for my next work computer!  These days, this really makes a lot of sense even for pure Windows development: Apple makes really nice hardware, and a Mac plus Boot Camp or virtualization software makes a fine PC.  It makes even more sense for web development, where more platforms and browsers to test on make for a better webapp.  It makes yet more sense if you're regularly connecting to Linux systems, because the command-line environment is true UNIX with all the standard goodies (including an ssh client), the Terminal app is a real GUI program that follows reasonable UI guidelines and integrates with other apps, and there's a great free native X11 implementation.  It makes even more sense if you have lots of clients with iPads and there's a chance you'll need to get into native iOS development, where OS X is the only authorized development platform.  Finally, in my case, it makes me more productive (or at least makes me *feel* more productive), and more happy, simply because it's a Mac.

I was pretty shocked to find out I'd be allowed to get not just any Mac but a Retina MacBook Pro.  These are pretty amazing machines all around, but the display is really something else.  Just like an iPhone 3GS seems perfectly fine until you spend some time with the screen on a 4S, the Retina MBP has ruined me for "normal" screens forever.  The biggest downside is that not every app is retina-ready, and the pixel-doubled graphics you get for non-retina apps are so perfectly pixellated, they look worse than they would on a fuzzier, standard-resolution screen, especially when they're juxtaposed with everything else on the display.

Of course, I need to run Windows for my Windows-specific development, and I'm doing it in a virtual machine so I don't have to dual-boot.  Windows 8 is RTM, and Iowa State has a site license, so I asked whether I could try that rather than Windows 7.  My boss said to give it a go and just fall back on a Windows 7 VM for anything that doesn't work in 8.

Since I can technically get all my current work done on an XP machine with existing software licenses, I didn't want to run up a large bill for Mac-specific software.  At home, I have a lot of handy shareware/commercial Mac apps I've bought over the years to customize this or that aspect of my system, notably DragThing, which has been my Dock replacement since before there was a Dock.  It's been fun to be forced to live without some things to see what can be done with built-in functionality and freeware/open source software.

So the next several posts will be documentation of my experiences turning a 15" Retina MacBook Pro into a multi-platform, Andrew-friendly development machine on a budget.  I'll probably talk mostly about the Mac side, but I'll also have some things to say about Windows 8, specifically its support for HiDPI displays and how it integrates with OS X when run under Parallels 8.

Friday, June 15, 2012

About "about:about"

I just learned about "about:about", which (in current versions of Firefox and Chrome, at least) gives you a menu of all the "about:" pages (which in Chrome are actually chrome:// pages).  How lovely!  Here's the blog post that mentioned it.

Tuesday, June 5, 2012

Cache OpenLayers Tiles With Web SQL Database

(Note: this post has been edited to reflect the current state of OpenLayers and my code.)

As of this edit, there's an open pull request to provide a pluggable offline cache system for OpenLayers.  A few months ago, there was only a single CacheRead/CacheWrite implementation using localstorage.  I needed Web SQL Database support because localstorage currently maxes out at 5MB on iOS (with ungraceful failures), whereas Web SQL Database will grow to 50MB with user confirmation.

ahocevar's pull request for the initial implementation indicated that adding backends for other databases would be as easy as providing a different implementation for OpenLayers.Control.CacheWrite.cache and OpenLayers.Control.CacheRead.fetch.  This is true...ish.  Because Web SQL Database is asynchronous (apparently no vendor ever implemented the synchronous API, at least on mobile), there are a lot of gotchas.  Rather than list them all here, I'll link again to my comment on the current pull request, where I note a few.

I got a public github account and committed some code before being asked for an OpenLayers Contributors License Agreement and learning that my university really has no process for approving things like that.  But since this blog post had already linked to my modified CacheWrite and CacheRead controls, I'm leaving the links live.  I've also committed my latest versions, which fix some bugs.  Feel free to use this code as a guide for OpenLayers caching code, but don't submit it verbatim to OpenLayers until I get a CLA.  Thanks!

Note that this code (and all OpenLayers caching code) is affected by an OpenLayers bug that allows slightly different URLs to be calculated for essentially the same tiles, leading to cache misses that should be hits.  Be my guest and fix this bug to make caching work more reliably!  (Read the issue comments to understand what the fix requires.)

Be aware that this code doesn't properly notify on "cachefull" situations.  At least on iOS, I found that there was no way to distinguish between a quota error and a unique constraint violation.  That is, inserts that fail due to exceeding the disk quota are reported as constraint violations.  I think this is a bug in Safari, but probably one that will never be fixed now that Web SQL Database is deprecated.

Happy coding!

Split OpenLayers Polygons with JSTS

Update: I've put several months of development into our app since this post was first published, with probably a couple weeks' extra work into the SplitPolygon tool.  Our tool is now production quality, but I won't post it here until I get word from our legal department on an OpenLayers CLA.  I'm leaving the old code up, but be warned that it's more like demo quality.  In particular, note that because this version doesn't split edges of "unaffected" polygons adjacent to affected polygons, split polygons may not merge cleanly back with their neighbors.  Also, because Mobile Safari likes to terminate long-running tasks without warning, I did significant rework to break tasks into the smallest pieces I could without modifying JSTS itself, and running the pieces on timers.  This was nice for other reasons, as it allowed me to display progress updates, etc.  Anyway, hopefully I'll get the real version posted... someday.

So I've got a half-baked SplitPolygon control for OpenLayers that's good enough for our use in a project here at work but not ready for submission back to OpenLayers (if they'd even accept a control with an external dependency), and I thought I should find some way to share it for others trying to do the same thing.  It seems like the typical route is one's personal "code blog."  So I made this lovely personal code blog, where I will share such thing(s).

Here's the SplitPolygon code.  It's just the OpenLayers Split Control, slightly mangled to handle polygons instead of polylines.  The Split control will technically handle any OpenLayers.Geometry with a "split" method, but as of OpenLayers 2.12, only polylines have this method.

It depends on the excellent JSTS, a JavaScript port of Martin Davis's JTS Topology Suite by the illustrious Björn Harrtell, who (through his employer, SWECO Position AB), for a very reasonable fee, ported the critical Polygonizer.  The logic in the considerSplit function is ripped from a desktop application we wrote for the USDA.

The tool works through the supplied layer and splits all eligible features with the provided polyline.  The polyline can be arbitrarily complex, with self-intersections and other goodness.   It can split a single polygon into several pieces.  I put some code in to limit the splits to visible features because that was a requirement for our app.

Because we're using it on touch devices, which can't use CTRL-Z and ESC for undo and cancel, it adds two links to the map (one for undo and one for cancel).

I commented out some code we weren't using, and I mostly ignored parts of it that I didn't understand.  So this might serve as a base for your own tool but probably shouldn't be taken as-is.

Hope this helps!