Code by Kevin
   


About
Code by Kevin: Programming, code, business, and other pursuits

Your Host
Kevin Walzer, software developer.

Home

Subscribe to RSS Feed
Get a syndicated feed of my weblog.

Archives
2010
2009
2008
2007
2006

Categories
Business
Software
General

        home
Sat, 10 Jul 2010

QuickWho 3.0: When to rewrite an app

I've just released version 3.0 of QuickWho, my application for obtaining registration information for Internet domains. This new version is the most thorough rewrite of an application that I've ever done, so I wanted to discuss a bit about the new version and its changes.

Earlier versions of QuickWho were basically GUI wrappers, or front-ends, for the command line "whois" tool that ships with Mac OS X. A user would type in a domain name in the search field, QuickWho would send the query to whois, and then display the text output in the main window. I tried, with the user interface, to add some features that were not directly present in the command-line tool, such as the ability to select a specific whois server to query; the ability to call QuickWho via AppleScript; and the ability to save and print the textual output for later review.

However, despite these additional features, at its foundation QuickWho remained a simple wrapper for the whois program that offered little functionality not found in the command-line tool or in other GUI applications (such as Apple's own Network Utility, which ships for free with OS X). It simply didn't offer much value for the money I was charging for it, even after I lowered the price to $12.95. Reviews of the program, and its sales, reflected this lack of value.

As a result, I decided to make the new version of QuickWho substantially different from the older ones. It would offer more information than a simple dump of whois output. It would be easier to use and better integrated into OS X so it could be incorporated into different workflows. After looking at a number of possible features and technologies to support these features, here is the core mix of the new QuickWho:

  • Distills basic whois data to an at-a-glance list, with both domain information and geographic information about the domain. This is done through a mix of approaches: the Python pywhois library, for basic information about the domain; the "dig" command-line program, to get the main IP address for the domain; and the pwhois domain information server, which retrieves geographic information about the domain (city/state/country, latitude, longitute) based on the IP address. The raw whois data can also be displayed; this can be configured in the preferences. The result is that more precise, accurate whois data is delivered.

  • Displays the text data as rich text with clickable URL's for domain names and e-mail addresses, to facilitate e-mailing or displaying domain information in a browser.

  • Displays map information from the domain, based on Yahoo! web services and the PyYahooMaps library. This can be useful for gathering more information about the domain.

  • More robust AppleScript support and complete integration with the OS X Services menu, so QuickWho can both return whois data to other applications and access the functionality of other applications from the Services menu.

I've come to re-evaluate my long-standing belief that you should never rewrite an application from scratch, which Joel Spolsky eloquently articulated. If a program is at a dead end and cannot do what you want it to, you may have no choice but to rewrite large portions of it, even the entire thing. With QuickWho, I rewrote major portions of the user interface (removing the tree view, developing and customizing the rich text view, adding the image display) and completely re-implemented the whois query, as well as the alogorithms to print the data (since it now included an image as well as text).

With these changes, I'm restoring the price of QuickWho to its previous level of $24.95. I believe the program now does far more than the simple command-line whois tool, and previous versions of QuickWho: it offers a richer array of information about specific domains, in an easier-to-read format.

If you need to do frequent searches of domain information via "whois," then QuickWho 3.0 is a useful tool that can increase your productivity. It's definitely worth a look.

[/software] permanent link

Thu, 17 Jun 2010

Simplicity vs. power

A big part of my design philosophy as a Mac developer is to harness the underlying power of the Unix command-line tools that reside beneath the Mac's shiny Aqua surface. This means that I attempt to expose the functionality of these tools with an easy-to-use graphical interface. As I do this, however, I am often faced with a conflict between simplicity--making the tool intuitive to use through the GUI--and power--allowing the user to access as much of the tool's functionality as possible through the GUI.

That conflict is not an easy one to negotiate. If you don't expose enough of the program's functionality, you run the risk of "dumbing it down"--making it less useful than it should be. A GUI tool that provides only a simple wrapper to the tool's most basic functionality doesn't offer a lot of value to the user. On the other hand, if the GUI tool attempts to access every single command-line switch from the program, you run the risk of burying the user in an avalanche of configuration options and preference settings, and overwhelming all but the most advanced users--who many not need the convenience of a GUI tool at all.

Sometimes finding the right balance between simplicity and power is straightforward. In both PortAuthority and Phynchronicity, the command-line tools that power my applications offer a managable range of functions--installing, updating, deleting, searching, and getting information about Unix software--that can easily be encompassed in a GUI. In the case of both of these programs, the GUI itself handles some functions (especially searching the list of software packages) and dispatches other functions directly to the command-line tool as required. My programs offer a more pleasant user experience over the command-line tool without sacrificing any essential or advanced functionality.

In other cases it's harder to find the right balance between simplicity and power. This conflict is especially acute in my network monitoring tool, PacketStream. PacketStream is a user interface for tcpdump, an enormously powerful but complex network monitoring tool. The documentation for PacketStream outlines a stunning range of options, which, in the hands of a power user, results in the ability to monitor network traffic with incredible precision. It's hard for a GUI to capture all of that power without becoming equally complex to use. (Some GUI tools for tcpdump, such as WireShark, are unabashedly complicated to use.) The challenge for me is to identify the most common uses for tcpdump and provide access to a range of functions in PacketStream, without turning the program into something as complicated as tcpdump itself.

It's still a work in progress, and I've been guided by my own instincts and user input. The earliest version of PacketStream just provided a simple wrapper for tcpdump with no options beyond which network interface it listened to (Airport, Ethernet, etc.). Over the past couple of years, I've added the ability to listen on specific network ports for certain types of traffic (such as http, e-mail, etc.), and to display the contents of packets; these are command-line switches to tcpdump options. I've also added, at the GUI level, the ability to save and print network output, and to call PacketStream via AppleScript and the Mac Services menu. These aren't hooks into tcpdump itself, but they do make the program more integrated into the Mac's GUI environment, and allow it to cooperate with other programs. Finally, I've also added some basic documentation on tcpdump itself, to assist users in understanding how PacketStream works under the hood.

I've also removed some features, or at least moved them out of the GUI, in the interest of making the program simpler without sacrificing power. Adding Keychain support allows you to type a password once and then store the password in the system keychain: some users have complained about having to type a password everything they launch a search. I've also added functionality that automatically sets the correct network interface to listen on. In these cases there's a lot of code working to make the program more effortless to the user, with less configuration required; I've been able to increase the program's simplicity with no adverse effect on its power.

Certainly my design decisions with PacketStream aren't for everyone. One review of the program, undoubtedly by a power user of tcpdump, complained that PacketStream is too simple, little more than a worthless GUI wrapper for tcpdump's most basic functions. I don't agree with this assessment, as there is a considerable amount of work in PacketStream to make accessing tcpdump seem effortless, but there it's certainly true that PacketStream doesn't provide access to every feature of tcpdump. Nonetheless, PacketStream is one of my better-selling programs, so at least some users are finding that it provides a good mix of simplicity and power.

My long-term goal for PacketStream is to improve both its simplicity and its power, by making the interface more and more effortless to use, even as I gradually expose more of tcpdump's functionality. Making power seem effortless is the design philosophy of most good Mac software, and I will continue to move PacketStream--and all my other programs--in that direction.

[/general] permanent link

Thu, 03 Jun 2010

Packaging vs. developing, or mainstream vs. cutting-edge

As a developer primarily using scripting languages (Tcl/Tk and Python), I have multiple options for setting up my development environment: I can use the versions of the languages bundled with OS X; I can use one of several freely available binary installers for the languages; or I can build my own.

The drawback of using the bundled versions with OS X is that they tend to be out of date; Apple only updates its scripting languages with a new release of OS X. As a result, the version of Tcl/Tk available on my machine is 8.4, which is a couple of years out of date.

Binary installers--from ActiveState for Tcl and Python, or the official Python website--are very convenient, but you trade that convenience for control over your development environment. It's difficult to do non-standard or cutting-edge stuff with the standard pre-packaged distribution. My work with Tk-Cocoa and 64-bit, for instance, is too cutting-edge for these distributions; in fact, a lot of my work with Tk-Cocoa and extensions is being incorporated into the next generation of ActiveState's Tcl/Tk installer.

As a result, I'm left to the final option of the developer--"rolling my own," or building my own stuff from source. That's actually fine in most cases. I have complete control over my environment, and I'm able to focus on what I need to do. The drawback is that if I want to incorporate something outside of my usual development environment, I have a lot of work to do because I have to build it myself.

Recently, though, I found myself turning to pre-packaged distributions for a project--and greatly appreciating the convenience they offer.

I have packaged up a Mac build of a popular Python-based card game, PySolFC. PySolFC is a complex package that builds on many components, including the Python PyGame library and the Python Image Library (PIL)--themselves both highly complex Python extension libraries that also build on many external libraries. I've tried to build both PyGame and PIL myself from source many times, in order to integrate them into my custom Python builds, but my efforts haven't worked: both PyGame and PIL have too many moving parts, and something always breaks. I tried again, this time using MacPorts to build the dependencies, but that didn't work either: some of the MacPorts packages were out of date or were incompatible with each other.

Finally, after several hours of frustration, I decided to try the binary installers from ActiveState, both Python and Tcl/Tk. I moved my own builds out of the way and installed the ActiveState packages. ActiveState also provides various extension packages for Python and Tcl, and I used this method to install PIL. Finally, I used a binary installer of PyGame provided by the PyGame developers. Then, I ran the build of PySolFC using the py2app tool. The build worked out of the box. Total time spent using the binary tools: about an hour.

In this case, I definitely appreciate the convenience that the binary packages offer. The complexities of building a library like PIL become someone else's headache (just as these are my headaches if it's my own software that I'm working on). I wanted a working build of PySolFC; the binary packages, which provide the foundation for PySolFC, make it easy to build.

This process has given me some definite insight into the differences between being a developer of my own software and a packager of someone else's. In my own software, I want to push the limits of my toolset. That's why I'm working with Tk-Cocoa now, before it is mainstream, and also why I'm working with 64-bit applications. When you are working on the leading edge, sometimes things are difficult: for instance, I have to use the older, less capable bundlebuilder tool to wrap my 64-bit Python applications, because py2app doesn't yet handle 64-bit programs gracefully. (py2app is more powerful than bundlebuilder, scanning your application and mapping out dependencies as well as building application bundles, and as a result requires more changes to integrate successfully with 64-bit builds; bundlebuilder simply copies code libraries that you specify into an application bundle, and knows nothing about different kinds of builds.) The current maintainer of py2app, Ronald Oussoren, is also the maintainer of Python on the Mac and the maintainer of the PyObjC Cocoa-Python library. Needless to say, he's stretched pretty thin, and hasn't had time to update py2app in some time.

As an application developer, I want to push the limits, but as an application packager, I just want something that works, that has been thoroughly tested and debugged. Using the ActiveState binary installers for Python and Tcl/Tk, and py2app, I was able to efficiently build PySolFC. The built program doesn't reflect the cutting edge of Tcl/Tk or Python--it's not built on Cocoa, nor is it 64-bit capable--but it works great, and just as importantly, it was easy to build. I definitely appreciate the convenience offered by the binary installers!

Finally, since I release a great deal of my own work as open-source, I'm helping to contribute to the next generation of stable binary packages. ActiveState's beta build of Tk-Cocoa now includes some of my libraries. When this beta version (actually Tk 8.6) is finally released in the next year or so, hopefully the cutting-edge advances it includes will become more mainstream.

[/general] permanent link

Mon, 31 May 2010

Tk-Cocoa is the best cross-platform toolkit for the Mac

I'd like to make a bold claim: Tk-Cocoa is now, in terms of its platform-specific integration, the best cross-platform toolkit for OS X.

With the release of tclservices, Tk-Cocoa now has a range of core features and extensions that no other cross-platform GUI toolkit can match. In other words, Tk-Cocoa provides fuller access to Mac-specific technologies--the features and user experience that help define the Mac--than any other toolkit.

Here's how I support this claim:

  • Services: With the tclservices package, Tk-Cocoa allows Tk applications to be both providers and consumers of services via the Services menu. No other toolkit--not wxWidgets, not Qt, not Gtk, not Java--supports this. Java allows Mac applications to access the Services menu, but provides no simple mechanism for providing them.

  • AppleScript: With its built-in AppleScript support via the "do script" command, Tk-Cocoa allows any Tk application to provide AppleScript support that goes beyond opening documents, launching the application, and so on. No other toolkit--not wxWidgets, not Qt, not Gtk, not Java--supports this.

  • Mac-specific window styles: Tk-Cocoa provides, via its core features and extension packages, access to such features as sheets and drawers. Qt provides full access to Mac-specific window styles, while Java provides access to sheets. Neither wxWidgets nor Gtk provide this.

  • Displaying Mac-native icons: Tk-Cocoa provides, via core features and extension packages, the ability to display Mac-native icons in an aplication. Qt and Java support this; wxWidgets and Gtk do not.

Does this mean that Tk-Cocoa is superior to these other toolkits? No, certainly not. Tk still lacks some significant features, most notably platform-native printing and a modern HTML library like WebKit. But if you're looking for platform-native integration, no other cross-platform toolkit offers as much specific support for these features as Tk-Cocoa.

I hope this brief discussion may persuade other developers to take a closer look at what Tk-Cocoa provides.

[/general] permanent link

Tclservices 1.0

I've released version 1.0 of tclservices, a Tcl/Tk library that provides access to the Mac's Services menu, allowing Tcl/Tk applications built against the Cocoa frameworks (Tk-Cocoa) to function as both providers and consumers of services. (Tk-Carbon is not supported.) With tclservices, Tcl/Tk applications can send data to other applications via the Services menu, and can also provide functionality that can be accessed from the Services menu. This package adds yet another aspect of platform-native integration that can improve Tk applications on the Mac.

[/software] permanent link

Tue, 25 May 2010

PacketStream 3.3

I've released version 3.3 of PacketStream, my network monitoring tool for OS X. This is a fairly major update. PacketStream now supports AppleScript and Services (both as a provider of a service, and able to access the Services menu); it also supports Keychain integration, which means that it's no longer necessary to type in your password each time you launch a new network scan. The other major new feature is a preference item to display the actual contents of packet data in the PacketStream data view.

All in all, this release puts more monitoring power at your fingertips, and also greatly improves the application's ease-of-use and integration with OS X. I strongly recommend that you upgrade, and if you aren't currently a registered user, it's a great time to give PacketStream a try.

[/software] permanent link

Sun, 25 Apr 2010

Reconsidering "good enough"

Sometimes, good enough isn't good enough.

A few months ago I suggested that perfection wasn't the ideal goal in software; instead I championed "good enough," a strategy that lets you get a product out the door that does most of what needs to be done.

"Good enough" is indeed useful for shipping products, but I've come to the conclusion that perfection isn't such a bad goal after all--if you define "perfection" as a long-term goal that you strive for over multiple product releases. Even if you don't reach perfection, you still improve.

The reason I'm re-considering the goal of "good enough" is that I'm still quite unhappy with some of the additions I've made to my programming toolkit--specifically, integration of Tcl/Tk with drag-and-drop on the Mac, and accessing the Services menu from Tcl/Tk applications. You can drag files and text to my Tk applications, and they provide a service that can be accessed from the Services menu. But that's a one-way street; currently, you can't drag items from a Tk application to other applications, and you can't access the Services menu from my Tk programs. This feels incomplete to me.

So, over the past month or so, I've been working on improvements in these areas. I've gotten a working implementation of Tk applications as a "drag source" committed to TkDND's source code archive, and I've completely rewritten my Tcl Services package to properly integrate with Cocoa's Services API, both in sending data to Tk applications and accessing the Services menu from Tk applications; in the case of the Tcl Services package, it's a rare instance where a complete re-write makes sense. In fact, after a bit more stress-testing of the Tcl Services package in my own programs, I plan to add it to my growing list of Tcl extensions that provide integration of Tcl/Tk with various aspects of the Cocoa API.

I still don't feel compelled to revisit AppleScript support and printing support in my programs; there, the current implementation is truly "good enough," in that it satisfies all my current and projected use cases, and where a re-write would represent a huge amount of work with only a marginal improvement in the functionality offered by my current packages.

Look for these new improvements in new releases of my apps in the near future.

[/business] permanent link

Sat, 10 Apr 2010

Manpower, PacketStream, QuickWho

I've released minor updates to Manpower, PacketStream, and QuickWho. All of these updates incorporate the library bug fix that I outlined here. If you use any of these programs, this is a recommended update.

[/software] permanent link

Thu, 08 Apr 2010

Windowlist 1.3

I've done another update of my windowlist package, which implements a Mac-standard "window" menu in Tcl/Tk applications. This version, 1.3, fixes some additional bugs in the package that cropped up when I attempted to integrate it with my macdrawer package.

Because all of my applications make use of the windowlist package, look for another round of bug fix updates shortly.

[/software] permanent link

Wed, 31 Mar 2010

Is Tcl/Tk dying?

A hardy perennial among Tcl/Tk developers is hand-wringing over the language and toolkit's standing relative to other languages and toolkits. At one time Tcl/Tk was one of the most widely-used programming combinations around, but in recent years it seems to have lost some popularity and mindshare among programmers and companies. Tcl/Tk developer Mark Roseman has posted an amusing satire about this question. David Welton has also recently posted a more serious consideration of this question. His analysis, which focuses on both the technical and cultural reasons for this erosion in popularity, is astute.

Still, even after acknowledging the relative decline of Tcl's mindshare and community size, I still have to believe that it's little more than an inconvenience--not a fatal liability--because the core language and toolkit are still being actively developed.

Make no mistake: Tcl/Tk's small community and mindshare are definitely an inconvenience. In Perl or Python, if you're looking for a library or extension package, it's more likely that someone, somewhere has done it already, because their communities are larger. In Tcl/Tk, you often have to do it yourself. In some instances, the functionality I'm looking for is quite difficult to implement (such as SSH support) or is already fully available in another language (such as RSS parsing); in these cases, I may turn to a language that already supports them, such as Python. And even when I do undertake an extension project, such as adding drawers and sheets, I'm often completely on my own because no one else in the community has the expertise or time to offer insight or assistance. Most of my recent posts on the Tcl-Mac mailing list go unanswered because they involve rather complex questions about the integration of Tk and its underlying Cocoa implementation. In fact, it's not an exaggeration to say that the number of active developers of the Tcl-Mac community (contributing to the language's core or with widely-used extensions) can be counted on one hand.

But these problems are an inconvenience--not a showstopper. I am usually able, eventually, to work out any problems I encounter in developing Tk extensions. And, more importantly, Tcl and Tk are getting development where it counts most. While the releases and improvements don't come as frequently as some other languages, they do come--and there are real improvements. Of course, many of these improvements are undertaken by the scrappy core team of Tcl/Tk developers. Some of them, however, are the result of corporate sponsorship, which contradicts those who say that Tcl's mindshare is withering.

In fact, I am heavily dependent on the Tcl/Tk improvement sponsored by a single company: Apple. Apple has twice sponsored ports of Tk to run on top of its native GUI frameworks: first Carbon in 2001, and then Cocoa in 2009. Even though the core Tk-Mac community is small even by Tcl/Tk standards, Tk itself is so widely used on the Mac (by Python, Ruby, etc.) that Apple wanted it as a first-class cross-platform GUI library. That support by Apple, especially by sponsoring a Cocoa version of Tk, ensures the toolkit's future on the platform and is the major reason I continue to develop my Mac-only apps in Tk instead of another toolkit.

I feel very confident in Tcl/Tk's future, and am not troubled by its small community. It would be nice if it had a larger community, but as long as the language continues to evolve and grow, then I will continue to stick with it.

[/general] permanent link

Fri, 26 Mar 2010

Application, not platform

I was trying to think today of the last time I received a complaint about the user interfaces of my programs. The last time I can remember was last August, when NameFind received some pretty harsh criticism during a MacZot promotion. This was right before I began the big push to migrate my applications to Tk-Cocoa, to improve the UI style of the applications, and to improve their integration with Mac-specific technologies. The only integration issue I'm still dealing with is a fuller implementation of drag-and-drop, which I'm working on as part of an update to NameFind.

I think those changes have paid off quite nicely. I still get complaints about the price of my applications, I still get complaints about crashes because of third-party extensions on Snow Leopard, and I still get complaints about specific features and functionality--but I don't get complaints about look-and-feel, platform-integration issues. Even if my programs are not perfect in this regard, they're good enough.

So what now?

For the past couple of years, at least, I've focused more on platform integration than on features in my programs. In other words, I've focused on improving and refining the user experience rather than offering lots of new functionality. This isn't a bad strategy. But I think now the time has come to shift the balance back toward development of application features, rather than improving the platform I use to develop my programs. While those platform improvements can be rolled into every one of my programs, they can't be applied in an across-the-board way to the problems that each program is designed to solve.

I've already started moving in this direction. Updates to QuickWho and Manpower included some common features--AppleScript and Services support, most prominently--but also some differences, including price adjustments to different levels. By contrast, my update of PacketStream had more application-specific changes, no price change, and no integration with AppleScript or Services, because such features don't really make sense in this application's domain.

NameFind, next on the update list, will get some application-specific changes, and also one big remaining platform feature that I'm working on at the same time: drag-and-drop. And the last two the last two current applications on the update cycle, PortAuthority and Phynchronicity, will likely get more application-specific changes. At that point, I'll be ready to work on some entirely new applications, which I've been planning for a couple of years but postponed because of my need to work on the platform level, rather than the application level.

It's my hope that as I'm moving my application focus to a different level, I'll be moving my sales to a different level as well.

[/business] permanent link

Sat, 20 Mar 2010

Which file search alogrithm?

I'm working on an update to NameFind, and I'm revisiting one of its central design features: the algorithm it uses to search the file system for files with specific names.

From its inception, NameFind has been designed to use the Unix "find" command-line tool. The find tool is very simple in its approach: it recursively scans or crawls the file system by directory, looking for file names that match the search parameters passed to it. It is very accurate, it's real-time (meaning there's no out-of-date information returned by the search), and it does exactly what it's designed to do: find files by name. The drawback to find is that while it's very fast for small searches (of a single directory or directory tree), it is quite slow for full file-system searches. It's not unusual for a full file-system search for a file name to take 15-20 minutes, and even to cause NameFind to appear to lock up while it's waiting for the search to complete.

User complaints about NameFind have tended to focus on its speed and responsiveness, and so I've tried to find ways to speed up the search process, or at least make it feel more responsive. This is leading me to look at other search algorithms as well. Unfortunately, though, these other algorithms have drawbacks of their own.

By far the fastest tool for searching the file system is the "locate" command. Locate works similarly to find, searching for file names that match a particular search term. It does so by scanning an index rather than recursively trawling the file system: as a result, it is much, much faster. However, the database that locate uses is updated, by default, only once a week; the obvious danger here is that its output may be outdated. It may list things that have been deleted and miss things that have been added since the last time the database was updated. As a result, while its speed is a huge plus, its accuracy is not. And while it is possible to update the locate database manually, it is a lengthy process, and doing so would detract from the user experience I'm trying to offer with NameFind.

A third search option is "mdfind," which the Mac's command-line interface to the Spotlight search system. I originally wrote NameFind as an alternative to Spotlight because I did not find Spotlight's features especially useful for searching for specific files in specific directories. mdfind does have command-line switches for searching in specific directories for specific file names, and its output is faster than "find" because its search is based on a database search, not a real-time directory crawl; unlike locate, the Spotlight database is continually updated in real time. However, mdfind does have problems with accuracy, or at least relevancy. Spotlight, and therefore mdfind, indexes based on file content as well as file name and other data; it may return hits based on the search term being contained within the file's content, instead of its name. Spotlight also does not index certain kinds of data by default (system/hidden files, application bundles, etc.). Finally, while the built-in version of Spotlight translates its raw search output into user-friendly titles and icons, the command-line mdfind tool returns raw search data (instead of an e-mail message, it returns something like "/Users/kevin/Library/Mail/POP-kevin@11.1.1.1111/Deleted Messages.mbox/Messages/718453.emlx"). Looking more closely at mdfind, I'm reminded of why I didn't use it from the start.

Looking at all of these alternatives, none of them is perfect. But, despite its speed drawbacks, the find tool is best suited for my design goal: to find files by name. NameFind is especially useful and fast if I'm trying to search a single directory or two with a lot of files in it; for shallow directory searches, it's better suited than any of the alternatives. It's not as good for a full-system search; while I can probably tune up its responsiveness a bit so it doesn't feel so sluggish, I can't speed up the actual search process itself. Nonetheless, I am going to retain "find" as the engine that powers NameFind.

[/general] permanent link

Sun, 14 Mar 2010

PacketStream 3.1

I've just released a significant update to PacketStream, my network-monitoring GUI for OS X. The most significant new feature is that PacketStream now automatically queries the system for the active network interface, so manual configuration of this functionality is no longer necessary. (This had been a confusing point to some users.) The program also now includes more than 30 specific network filters to monitor specific types of network traffic; the documentation has been updated to reference the expanded network parts. The application also includes various other UI improvements and bug fixes. If you use PacketStream, the new version is a useful upgrade; if you haven't tried it, please do so. I think you'll be surprised at how easy it is to monitor network traffic over your Mac.

[/software] permanent link

Updates for QuickWho, Manpower

I've released version 2.2 of QuickWho and version 3.2 of Manpower. These are mainly bugfix releases; they fix a potentially serious UI glitch with sheet windows, and also add some new support options to the help menu, including a link to the Code by Kevin user forum. If you use either program, please upgrade to the latest version.

[/software] permanent link

Updates for windowlist and macsheet

I've released updates to my macsheet and windowlist open-source Tcl/Tk extension packages. The macsheet package implements "sheet"-style custom dialogs for Tk-Cocoa on OS X, while the windowlist package implements a Mac-standard "window" menu for window management.

Version 1.1 of macsheet fixes a potentially serious UI glitch in which the sheet window may be incorrectly rendered depending on whether it was invoked from a menu or a button/keyboard shortcut. The main macsheet command now includes a "source" parameter to indicate how the command was invoked.

Version 1.2 of windowlist now offers a complete implementation of the standard "window" menu on OS X. The package raises and minimizes windows, and also implements standard keyboard shortcuts for minimizing (Command-M), hiding (Command-W) and re-opening (click on Dock) the main window.

Both packages are available under Tcl/Tk's standard BSD-style open-source license.

[/software] permanent link

Wed, 24 Feb 2010

Pricing

Readers of this blog will notice that I've lowered prices on two of my products recently. You should not, however, assume that I'm going to lower prices across the board as I release new products.

In the past I've tended to charge the same prices for all of my programs; once I set a price point for one product, the rest went to that price point as well. But I've found this actually isn't the smartest way to set prices, since it's more rooted in a desire to be consistent than in finding the right pricing balance between my product and the market. This year I've decided to be a bit smarter about pricing; I'm trying to better align my prices with the market, and back this decision up with actual sales data. My previous sales data told me that Manpower sold better at a lower price point, so the decision to lower the price of that program was easy. QuickWho sold very poorly at a higher price point, and the jury is still out on whether the new lower price point is the optimal one.

Some products, of course, are selling quite well at their current price point, and I see no reason to lower those particular prices.

[/business] permanent link

Manpower 3.1

I've released version 3.1 of Manpower, the GUI for viewing man pages on OS X. Version 3.1 is a pretty big update, building on 3.0's transition to 64-bit capabilities and Cocoa. 3.1 includes support for AppleScript and Services; it also includes a long-requested feature, the ability to bookmark specific man pages. I've also added the ability to input and display a single man page, which is something that probably should have been part of the application from the beginning. With these new features, I strongly believe that Manpower is the most complete GUI tool for browsing and viewing man pages on OS X.

As part of the new release, I've also lowered Manpower's price a bit, from $24.95 to $19.95. This is motivated by a couple of factors. First, most of Manpower's competitors are free. While I believe Manpower's feature set surpasses any of its competitors and is well worth paying for, I can't completely ignore the market, and $24.95 may be a bit high for this particular niche. I also have actual data to support this change: Manpower was originally priced at $19.95 when it was first released two years ago, and it sold better at that price point than at a higher price point. So, I'm hopeful that the lower price will prompt you to take a closer look.

[/software] permanent link

Wed, 10 Feb 2010

Macdrawer

I'm pleased to announce the release of the macdrawer package for Tk on Mac OS X.

This package implements Mac-native "drawer" windows for Tk. "Drawer" windows are windows are attached to the side of a toplevel window, and whose visibility can be toggled with a button. Drawers contain frequently accessed controls that do not need to be visible at all times.

The package is available at http://tk-components.sourceforge.net and is licensed under Tcl's BSD-style license. Both file releases and SVN downloads are available. In addition to source code, the packages include demo scripts and man pages.

This extension requires Tk-Cocoa to run; it is not compatible with the older version of Tk based on the Mac's Carbon framework. Tk 8.6 for the Mac is based on Cocoa, and a backport of Tk-Cocoa to 8.5 is available at http://github.com/das/tcltk/tree/de-carbon-8-5.

[/software] permanent link

Mon, 01 Feb 2010

New user forum

I've added a user forum section to the Code by Kevin website. This is a place for users of my products to post questions and suggestions about these products, the website, and other related subjects. I hope that users of my software will find the forum site a useful resource.

The forum is here: http://www.codebykevin.com/forum/. Enjoy.

[/business] permanent link

Sun, 31 Jan 2010

The perfect is the enemy of revenue

Even though I've made a great deal of progress over the past year in enhancing the native integration of my programs on the Mac, I'm not entirely satisfied. My programs can now support text and files dragged to them, but you can't drag text from them to other applications. They can now be called from AppleScript, and they support the Services menu, but you can't access the Services menu from within my programs. And while my programs can now print with nice, "sheet"-style dialogs, they don't print using Cocoa API's.

The question before me: is it better to release software that doesn't support these nice features in their entirety, or would it have been better for me to wait until the features worked perfectly?

This is actually a dilemma that all software developers wrestle with. Marissa Mayer, Google's vice president of search and user experience, favors an incremental release process and continuous improvement. Apple, by contrast, favors "insanely great" products that are little gems of perfection. Many indie developers in the Mac community tend to embrace the Apple view of things. In the words of Brent Simmons, "You make beautiful hardware and software--you create an experience so new and compelling that people lust for these things."

In practice, and also in philosophy, I tend to come down more on the other side--releasing even if it ain't perfect. This doesn't mean I ship programs that fail to work as advertised, that are glaringly buggy, or that lack any useful features. Some proponents of "release early, release often" see no problem with releasing stuff that crashes--hey, it's a chance to identify bugs!

However, I do embrace Voltaire's maxim that "the perfect is the enemy of the good." In software terms, this translates to, "the perfect is the enemy of the released product." There's no opportunity for a perfect product to make money if it's not in released form. In terms of my products, this means that I'd rather partially implement the easy part of a useful feature than delay release indefinitely for a complete, perfect implementation.

This has been my approach with drag-and-drop, AppleScript support, Services, and printing. The parts that I implemented were the relatively easy parts--and even those aren't easy. Drag-and-drop took several weeks, and a good deal of collaboration with the original creator of the TkDND extension, to implement dragging to a Tk window. Dragging text out of a Tk window is much, much harder because of technical conflicts between Tk and the underlying Cocoa foundation. I had no idea how long it might take to work through these conflicts, or even if I had the skill to do so. So I decided to move ahead with what I had.

AppleScript support is another incomplete, difficult feature to implement. My Python programs actually have the hooks in place to provide extensive AppleScript support--implementing AppleScript commands that other applications can call--through the excellent appscript Python library. However, my Tcl applications can't provide the same level of support because the standard Tcl library for AppleScript support, TclAE, will need an extensive rewrite to support 64-bit--a rewrite I currently lack the skills to undertake. Instead, if I want to offer AppleScript support, I'll have to use Tcl's built-in "do script" AppleScript command--which means I'll have to implement raw Tcl commands that other applications can call via AppleScript. Functional, but hardly perfect.

Services is yet another feature where the implementation isn't as perfect as I'd like. For technical reasons similar to the issues with drag-and-drop, my Tcl and Python programs can't access the Services menu from within the application itself. And they can only export Services functionality because I discovered a handy tool called ThisService, which allows you to create Services from scripting languages. I'm using the AppleScript support my programs are implementing to add the Services functionality as well. (I tried to create a Cocoa extension that would hook into the Mac's Services functionality, but was not successful--again, technical conflicts between Cocoa and Tcl that I could not work through.) While I feel my solution using the ThisService tool and AppleScript was elegant and actually quite clever, it's certainly not perfect.

Finally, printing. It would be nice to support native printing. Yet the Mac's built-in command-line interface to printing is so adequate for my needs that it's hard to muster too much worry about the lack of Cocoa-native printing in my programs.

My thinking about these issues is guided by more than just my desire to earn revenue by shipping products. It's also guided by the Unix philosophy of programming, which I've written about before. The key idea I'm taking away from the Unix philosophy is "keep it simple, stupid." If I can adequately implement a feature that is effective if imperfect, it's better to go that route than wait indefinitely for perfection. It's hard to say, at this point, if I'll ever perfectly implement drag-and-drop, AppleScript, Services, or printing in my programs. In 2010, my goal is to release commercial products, not open-source libraries. That means building on what I have; it's good enough. Waiting for perfection means waiting for revenue.

[/business] permanent link

Thu, 21 Jan 2010

QuickWho 2.1 released

I've released version 2.1 of QuickWho, my domain-search GUI for OS X. The big new feature in this release is support for AppleScript and Services, opening up possiblities for inter-appliction communication between QuickWho and other apps. The other big feature is that QuickWho is now a fully 64-bit application; I solved the build issues that previously prevented this from happening. This version also incorporates much of the work I've done recently in Tk itself for a better UI, and also includes a good deal of under-the-hood optimization to reduce the application's size and startup time.

One other major change: I've lowered the price for QuickWho from $24.95 to $12.95. Previous versions of QuickWho haven't sold very much, and what sales I did receive most often came when I ran a discount campaign. I think this fact shows that the market judged QuickWho to be overpriced at $24.95, especially when you compare its relative simplicity to some of my other, better-selling programs that also have a $24.95 price tag (such as PortAuthority). I still believe that QuickWho's polish, documentation, and its system-wide integration via AppleScript and Services make it a superior alternative to command-line and freeware tools--it offers value that is worth paying for. But I think $12.95 is a more accurate reflection of its value.

[/software] permanent link

Tue, 12 Jan 2010

Postmortem on 2009, and looking forward in 2010

At the end of 2008, I posted a blog entry on what I learned that year. I didn't have time to do anything similar at the end of 2009, so I'm carrying it over into 2010. Which is appropriate, given that I am now more interested in looking forward than looking back.

2009 was mostly a transitional year, in which most of the lessons of 2008 provided irrelevant. In 2008 I talked a lot about the importance of marketing. Regardless of my marketing strategy, the Great Recession kept sales down, down, down. I also complained about the difficulty of learning Cocoa and swore I'd never do it. But most of my technological work in 2009 was spent in learning various aspects of Cocoa and applying it to Tk, which itself was ported to Cocoa by Daniel Steffen. And finally, I said I'd add a lot of new products; instead I revived one I previously discontinued, and released incremental updates of everything else. (The single biggest upgrade of all my apps was moving them from Tk-Carbon to Tk-Cocoa and 64-bit capability, as well as UI freshening.)

I now enter 2010 a much stronger developer than I was a year ago: I can delve into lower-level technologies when necessary (Cocoa), while still taking advantage of the rapid development features of my primary programming languages. My toolbox is much richer than it was a year ago, and with drag-and-drop, native icons, custom dock icons, sheet windows, and AppleScript and Services support, my programs will be much better Mac citizens: these are real improvements in usability, functionality, and the user experience.

Now that I've greatly broadened my development skills, however, it's now time to begin applying it to my programs in a substantial way. The first task, of course, is to integrate these new features into my programs in appropriate ways. The next task is to explore opportunities for new applications, opportunities that my new skills now make available. I have lots of ideas, and lots of interests: the challenge will be to translate those ideas into products that users find compelling enough to pay for.

I want to improve my sales in 2010 as much as I improved my development skills in 20009. I think I'm finally in a position to do that. Sales really surged in the last two months of 2009, to the point where sales finished at the same level as 2008--a pleasant surprise, given how slowly the year started. There's still a lot of room for improvement, but like a last-place football team that wins its last four games, I've gained some momentum. I attribute the sales spike to moving my applications to Cocoa: some of the user feedback I've gotten suggests this has made a big difference.

As far as marketing, my product mix, and pricing, I've gathered some data about what works and what doesn't, and will keep working on that as the year goes on.

Bottom line: despite the difficulties of the past year, I feel more optimistic about my software business than ever before. I'll be working hard to bring cool and useful products to the table in 2010.

[/business] permanent link

Finally, drag and drop in Tk

This is a bit late, but I'm pleased to announce the long-awaited availability of TkDND on the Mac. This package allows you to drag files and text from other Mac applications to Tk applications. This basic GUI functionality has been a sore omission from Tk on the Mac, but George Petasis (with some assistance from myself) has done a major update of the package, including Mac support. I'm looking forward to integrating this essential library into my applications.

[/software] permanent link

Inter-application communication on OS X: AppleScript and Services

One of the nicest features of Mac OS X is the operating system's support for inter-application communication. Of course, OS X's Unix underpinnings do a great deal in this respect, but the application level also provides many useful features as well. Specifically, OS X includes AppleScript and Services.

AppleScript is the Mac's system scripting language, allowing different applications that support AppleScript to communicate with each other, exchange data, and more. AppleScript can be used to combine applications in unusual and unique ways, leveraging the strengths of each application to build complex workflows. It's not unusual to see AppleScript-based workflows that combine Microsoft Word, Adobe InDesign, and the FileMaker database to create elaborate publications, for instance. And AppleScript hooks into the lower levels of OS X as well, with a Unix-level command-line tool. No other scripting language touches as many aspects of the Mac as AppleScript. My applications make extensive use of AppleScript internally to communicate with various aspects of the OS.

Services are a smaller, but still powerful, aspect of OS X. Services allow an application to expose part of its functionality to other applications, which can then be accessed from a system-wide menu. In accessing Services, you might highlight some text in TextEdit, select "Search with Google" from the Services menu, and then watch Safari fire up and run the selected term in the Google site. You can't really chain Services together into complex workflows the way you can with AppleScript--but, on the other hand, Services are just a menu click away.

Most professional-level applications on OS X support AppleScript and Services to at least some degree. Not only is it a sign of the application's polish and integration with the Mac OS, it's just an added dimension of usability, of utility. My own applications have lacked this dimension, and that My own applications have not done so. As I've given this more thought, I've come to regard this as a pretty serious omission. How much more useful would NameFind be if you could highlight a search term and launch a search for a filename with that term in a specific directory? Or if you could write an AppleScript that would search for a particular software package in both PortAuthority and Phynchronicity?

I've spent the last few weeks exploring ways to add AppleScript and Services support for my programs, and after some trial and error, I think I have the hooks in place to provide basic support for both. It will take some time--and imagination--to figure out what types of functionality to export via AppleScript and Services, but that's the fun part. And, once I'm finished, my applications will be better Mac OS citizens.

[/software] permanent link