Tcl/Tk is a powerful cross-platform programming toolkit. Applications written in Tcl/Tk can run, unmodified, on a wide variety of computer platforms, including Windows, Linux and Unix, and Mac OS X. The appeal of being able to deploy an application on mutiple platforms from a single code base is very strong, and helps to explain Tcl/Tk's popularity among developers.
What an application gains in portability, however, it often loses in platform-specific features that users of a specific platform expect from their applications. These features might range from particular functionality to the general look-and-feel of the application. This is an inevitable tradeoff when developing a program on multiple platforms, and it is up to the developer to find the right balance between portability and fitting into the expectations of a specific platform's users.
Tcl/Tk developers are not exempt from this dilemma, and the challenge becomes particularly acute when they are deploying an application on Mac OS X--a platform where users have high expectations from their applications in terms of conformance with the "Mac experience." Many Tcl/Tk programmers have developed strong expertise in addressing the platform-specific demands of Windows and Linux, for instance, but the Mac may be an unfamiliar platform to them.
With a little time and attention, however, it is possible for Tcl/Tk developers to successfully target the Mac platform in a way that can preserve the portability of their applications while still addressing the expectations of Mac users as much as possible. Tcl/Tk Aqua--the native Mac port of the toolkit--is a first-class development environment on OS X, and is even now included in the latest version of Apple's operating system. As such, the Mac is a good platform for Tcl/Tk developers to add to their deployment targets, and the techniques for making their applications Mac-friendly are easy to learn.
One of the defining features of the Mac platform is a high degree of interface consistency between applications, enforced by Apple's detailed Human Interface Guidelines (HIG). Discussing the HIG in detail is beyond the scope of this document (and we encourage you to review it), but the guidelines go a long way towards defining what Mac users expect from applications on the program:
An appearance that "fits in" with other programs in Apple's Aqua windowing environment.
The ability to drag documents onto the application icon to open them.
An interface that is simple and intuitive to use, and which hides the underlying complexity of the system from the user.
The subsequent sections of this article will discuss these points in the context of a Tcl/Tk application that we ported from Linux to the Mac: tkbibtex by Peter Corke.
tkbibtex is a bibliography editing tool for the LaTeX typesetting system: it edits files in BibTeX format. It is widely used on Linux and Unix systems, though it will also run without modification on OS X and Windows as well. It must be started in a terminal session from the command-line, which is the standard method of application launching on Linux/Unix systems. Depending on how the program is installed, it can be started by typing in "tkbibtex" or "wish tkbibtex.tcl" (Wish is the interpreter program that runs Tk scripts). Starting tkbibtex in its unmodified version on the Mac by typing in "wish tkbibtex.tcl" in Terminal.app, one sees the Wish application launch, then open an empty document window for bibtex files.

We did a good deal of work rewriting portions of tkbibtex--particularly the GUI layer--to integrate more smoothly with the Mac environment, and we called the result "AquaTkbibtex." Here is a screenshot:

With this brief introduction, let's go through the differences between tkbibtex and our "aquified" version, to illustrate some of the things Tcl/Tk developers should keep in mind when including the Mac in their deployment targets.
Mac users expect their applications to blend in well with the general appearance of the Aqua environment. This includes having an application-specific icon, having the application's name in the upper-left corner of the screen, and featuring either the subtle "pinstripe" background of standard Aqua applications or the "brushed metal" look of applications such as iTunes or Safari. Out of the box, tkbibtex has none of these things. The actual application name is "Wish," referring to the Tk interpreter, and the icon--when one is presented at all--takes on the appearance of Wish, suggesting nothing about what tkbibtex does. Additionally, tkbibtex's windows do not use either the pinstripe or brushed-metal backgrounds of Mac applications: they are plain white.
These traits are illustrated in the dialog boxes that tkbibtex presents to the end-user, for instance when providing an error message:
This is a standard tk_dialog widget, which presents a brief text message to the end user, but the window looks out of place in the Aqua environment. Here is what the same dialog in AquaTkbibtex looks like:
This dialog is the tk_messageBox widget, which has been mapped to fully-native Aqua widgets by the TkAqua team. It picks up the application icon (we chose that particular icon because it suggested to us the kind of editing and research work that goes into preparing a bibliography), and includes the pinstripe background; both of these are features that Mac users expect in their applications, as part of the Mac experience. In developing the AquaTkbibtex version of this application, we replaced tk_dialog windows with tk_messageBox windows wherever possible. We also used the Tile extension, which provides native Aqua theming, including the pinstripe background, and thus replaced many of the standard Tk widgets with their Tile equivalents.
Additionally, as noted above, we updated the user menu to include the application name, and packaged the entire application with the icon shown above, so that users could launch the application by double-clicking (instead of typing commands in a shell). (Packaging and deploying Tcl/Tk Aqua application bundles is an entire topic in itself, which we cover here.)
It is important to note that these interface changes were implemented with no effect on the core functionality on tkbibtex: we made no changes to the way it parses, organizes, and saves and loads data. But Mac users expect the functionality of their applications to be delivered in a Mac-specific way.
Another feature that Mac users expect in any application that is document-based, like tkbibtex, is the ability to open files by double-clicking on them or by dragging them to the application icon. As a command-line-based tool, tkbibtex does not provide this functionality, although you can achieve something similar by typing a filename at the command line (i.e. "wish tkbibtex.tcl foo.bib"). Consequently, we focused a good deal of development time on this task.
To achieve drag-and-drop ease in opening files correctly in a Tk Aqua application, a developer needs to take two steps:
Define the application's target document and document icon in the info.plist file, which is part of a standard Mac application bundle. (The info.plist file is an XML property file that provides system-level information about a program, including its version number, its application name, the types of documents it can open, and so on.) The specific properties to define in the info.plist file are CFBundleTypeExtensions ("bib" in the case of AquaTkbibtex, for .bib files) and CFBundleTypeIconFile ("tkbibtex.icns," the icon file that is associated with .bib files). For more information about info.plist files, see here.

Define a procedure supported by Tk Aqua for translating documents "clicked" in the Aqua environment into command-line arguments. This procedure is called ::tk::mac::OpenDocument, and we associated it with the document-opening procedure defined by tkbibtex itself, "bibparse". In this procedure, the file name is passed to the bibparse procedure as an argument, and the file is loaded into the display. (See the source code to AquaTkbibtex, which you can download here, for more detail.)
With these two steps implemented, end users can open a .bib file by double-clicking it or by dragging the file to the AquaTkbibtex icon. Either way, the application will launch with the specified file open--standard Mac behavior.
While the Mac platform has attracted a growing number of hackers who are interested in the underlying Unix foundation, the majority of end users are drawn instead by the elegance and ease-of-use of the Mac's graphical interface. As such, they want their applications to hide the underlying complexity of the system. One way we revised tktibtex to provide this ease of use was in the print dialog box.
In the Unix environment, when a user selects "print" from the menu, tkbibtex presents a dialog that asks the user to input the print command manually, just as the user would if printing from the terminal. Here is a screenshot:

This is not "llpr"; this command is actually the standard "lpr" command, found on most Unix systems, preceded by a "pipe" symbol. tkbibtex writes the file output and then "pipes" that output to the lpr command, which prints the data on the user's default printer. Even we found this confusing initially, and had to dig into the tkbibtex code to figure out that the first character is the pipe symbol. (Setting the command simply to "lpr," as many seasoned Unix users would do, would result in an error message.) If an experienced Unix hacker finds this command confusing, it will appear downright cryptic to the average Mac user. Moreover, the average Mac user may be confused as to why he or she cannot select a printer for the output, as the standard Mac print dialog box allows.
We chose to address this complexity by hiding the print command from the user and by displaying output being sent to the user's default printer in a floating window. Here is what the new interface looks like:
The underlying code first runs the standard Unix "lpstat" command, to get the default printer, which is then displayed in the resulting dialog after the user selects "print" from the menu. When the user hits "print," the print output is sent to the default printer via the "lpr" command. We hard-coded the print commands into AquaTkbibtex, knowing that these commands are present on all versions of Mac OS X that can run AquaTkbibtex. (Admittedly, hard-coding a command is not recommended if you are targeting multiple platforms.)
By presenting the printer interface in this fashion, end users can see data being sent to the output printer, and do not have to worry about defining command-line arguments and parameters. This is the type of interface that Mac users expect.
These are just a few of the things to consider in targeting the Mac platform for deployment of Tcl/Tk applications. We understand that not every idea here will be useful or feasible; in specific instances preserving portability will doubtless outweight the benefits that are gained by implementing Mac-specific features. However, if you consider Mac interface guidelines in deploying your application, you will be able to make decisions that strike a good balance between portability--the hallmark of Tcl/Tk programs--and the user experience that Mac enthusasists demand.
| Copyright (C) 2006 Kevin Walzer. All rights reserved. All trademarks and copyrights are the properties of their respective holders. |