| Code by Kevin | |||||
|
Subscribe to RSS Feed 2010 2009 2008 2007 2006 Categories Business Software General |
home
Mon, 01 Feb 2010 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. 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 a 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. Thu, 21 Jan 2010I'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. 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. 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.
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. Fri, 11 Dec 2009I'm pleased to announce the release of three Mac-platform-native Tk-extensions that build on the Cocoa frameworks to integrate with the new Cocoa-based version of Tk for the Mac. Macsheet This package implements Mac-native "sheet" windows for Tk. "Sheet" windows are dialogs or toplevel windows that slide down from the top of a Mac toplevel window, and then slide back up when they are dismissed. Tk on the Mac has long supported the "sheet" effect for system dialogs, such as tk_messageBox, when a "-parent" option is passed to the call. The macsheet package adds the ability to create customized dialogs or windows with a similar effect. Tkdock The tkdock package allows a Tcl/Tk application to manipulate the Dock icon. The package allows an application to change its icon on the OS X Dock while running; it also allows the application to set a badge label to the Dock. Tkmacicon The tkmacicon package renders platform-native icons on OS X as Tk images. The ::tkmacicon::retrieveicon command takes three arguments: a file path or file extension, width, and height. If a file path is specified, then the package will return the specific icon for that file as defined by the Mac OS, in the width and height specified in the arguments. If a file extension is specified, then the package will return the specific icon for that file type as defined by the Mac OS, in the width and height specified in the arguments. Specifying the file extension rather than the actual file can yield faster performance for large numbers of files. All three packages are available at http://tk-components.sourceforge.net/ and are 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. These extensions require Tk-Cocoa to run; they are 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. Thu, 26 Nov 2009
More progress on adding features to Tk-Cocoa
First, the good news... Drag-and-drop. I'm making some good progress on my project to port TkDND to OS X: I've successfully gotten Tk widgets to recognize files and strings of text that are dragged to it. I still have to do some work on integrating my code with TkDND itself, which will take some time--but the hardest part is over. I won't be implementing drags from Tk windows to other Mac windows or the Finder/desktop, because that's considerably more complicated. Even with this limitation, being able to drag files and text directly to Tk windows will be a big improvement in usability and Mac-native integration. Custom sheets. Tk has long supported "sheets"--dialogs that slide down from the window--with standard system dialogs, file choosers, and so on. It hasn't supported custom dialogs that a programmer may choose to implement, such as a password dialog. With just a couple of days of work, I've got a decent implementation put together. The slide-down of custom dialogs isn't as smooth as system dialogs (because of some differences in how Tk draws windows and how Cocoa manages the "sheet" effect), but it's good enough for my requirements--and again, a nice improvement in usability and integration. I've gotten the Cocoa-level code working fine; I have to add some additional script-level code (based on the prototype code I've been hacking on) to make the package complete. Next, the bad news... Native Cocoa printing/dialogs. I've decided not to attempt to develop a Tk extension that provides system-native (Cocoa-based) printing. The command-line tools to support printing on OS X are superb, as I've discussed before, and native printing dialogs simply won't offer a huge improvement over what I am already doing. My one serious motivation for exploring native printing was the inability of the command-line tools to print HTML well. I've been using an open-source tool called HTMLDoc to generate a PDF file from HTML, which I can then print via the command-line. HTMLDoc does a good job, but it is a large program, and because it is licensed under the GPL, I have to include the source code for the program with my applications; the combination of these two things greatly increases the size of my applications. However, more recently I've run across a command-line tool called wkpdf--a Cocoa-native WebKit (HTML)-to-PDF tool that uses the Cocoa frameworks for the conversion. It's much smaller than HTMLDoc and works a bit better, to boot, so this solves my HTML-printing problem. As a result, I have no real need for a Cocoa-native printing solution, and won't be pursuing this. Finally, on the to-do list... Dock icons and native Mac icons. I've developed several packages in the past year to integrate native Mac icons in my applications, to modify the Dock icon of my programs, and to add a badge to the Dock icon. Some of these I've released as open-source, and some I haven't. I plan to do a bit more work on expanding and polishing the capabilities of these extensions; then I will do a big release of them. It's my hope that others will find my work on these projects beneficial, but I'm doing them first and foremost to improve the capabilities of my commercial applications: that's why I have to pick and choose among the many possibilities for (unpaid) open-source work that I run across. I've been working on these projects for several weeks now, and eventually I need to get back to working on applications that users pay for. After this round of projects is done, my applications will have several new capabilities, which will make them more pleasant to use. Thu, 19 Nov 2009One of the most comical aspects of my programs over the years has been my repeated gear-shifting over how to display help documentation in my applications. Apart from the other reasons I've discussed--dissatisfaction with Apple's built-in help viewer chief among them--part of the issue has been my continuing search for a suitable HTML renderer. Tk offers several different approaches, but none are optimal. For the past couple of years I've been using my own html display package, tkwebview. It's an updated version of an ancient Tk package (mid-1990s vintage), built on Tk's text widget, that can parse and display basic HTML. This package has the virtue of simplicity, being composed entirely of scripts, and it doesn't require any additional compilation. However, it's rather slow to render HTML, and when an HTML pages has numerous images, its scrolling performance is noticeably slow and jerky. (An unavoidable limitation of Tk's text widget.) As a result, earlier this year I examined two other HTML rendering packages, both of which are written in C and require compilation: TkHTML 2 by D. Richard Hipp, and its successor, TkHTML 3 by Dan Kennedy. TkHTML 2 is a fast, lightweight renderer for basic HTML. Over the years it has been widely adopted, documented, and supported by Tcl/Tk developers, which means that it is fairly easy to adopt and use in applications. The main problem with TkHTML 2 is that it is rather old (last updated in 2002), only supports basic HTML with no support for more recent web advances such as Cascading Style Sheets (CSS), and is hard to build, at least on the Mac. (A colloquial term for this is called "bit-rot," meaning that the code has not kept up with its environment.) TkHTML 3 is an ambitious attempt to provide a more modern HTML rendering widget for Tk that supports both CSS and JavaScript. It underwent intensive development from 2005-2007, and in that time, an impressive, nearly full-featured, TkHTML-based browser (HV3) was one result. However, development on TkHTML 3 has come to a complete halt, and the widget has not gained widespread use among Tcl/Tk developers. It is considerably more complex than TkHTML 2, and no common set of best practices for incorporating the widget into an application has emerged (in sharp contrast to TkHTML 2). After evaluating both options, I finally opted to use TkHTML 2; George Petasis, the author of several widely-used Tk extensions including TkDND, assisted me in getting it built for OS X. While TkHTML 2 is essentially obsolete, it is sufficient for my modest needs: it displays basic HTML, much faster than my earlier text-widget-based package did. It provides everything I need, and nothing more. It would be nice to take advantage of TkHTML 3's features, but I would be largely on uncharted ground: I'm not aware of any simple TkTHML 3-based help viewers out there, just the enormous HV3 browser (which is overkill for my needs). Another, intriguing possibility down the road is to tap into the Cocoa-native WebKit frameworks on OS X. Daniel Steffen put together a sample project that embeds a Cocoa WebKit view inside a Tk widget. Very cool. However, at present, this method does not allow fine-grained control of the HTML view from Tk; all of that is turned over to Cocoa. For instance, I want to be able to control whether a page is displayed in the web view or loaded into an external browser; WebKit provides hooks for this, but it's not clear to me whether they can be controlled from Tk or not. As a result, I won't be integrating WebKit into my applications anytime soon, although that may be a longer-term project after my other projects--and new applications--are released. The blogging has been quiet lately, and work on new applications is on the back burner right now, but I'm plenty busy. I'm working on some low-level Tk infrastructure projects to fill in some serious gaps in the toolkit's functionality. The first project is porting TkDND to run on OS X. TkDND is a Tk extension that provides platform-native drag and drop capabilities to Tk windows. While this package has been in existence in one form or another for nearly a decade, it's never been supported on the Mac, just Windows and Unix. With Tk finally running on Cocoa, I've decided to add TkDND to the Mac. I'm making good progress on implementing "drop" support--dragging files, text, and URL/bookmarks from the Finder and other applications to a Tk window. "Drag" support--dragging text and other elements from a Tk window to the desktop, for instance--is proving much harder, and I may not implement that feature. (This feature is also missing from TkDND on Unix.) Drag and drop is the most important project. After this is done, I plan to look at implementing Mac sheets for windows other than dialogs in Tk (dialogs, such as message notifications and saving/opening files, already work as sheets); native (Cocoa-based) Mac printing; and providing additional methods to access native Mac icons in Tk. All of these projects will be released as open-source when they're finished. It's common for unpaid, open-source programming to originate from the developer's desire to "scratch an itch"; that's true in my case. Sheets, drag-and-drop, and native printing are all features that I've wanted in my own applications for a long time. Until this year my programming skills in C/Objective-C/Cocoa were not equal to the task. I'm still no expert in Cocoa or Tk at the C level, indeed I still have much to learn, but now I feel competent to take on these projects. When they're done, they will make my Tk applications much more pleasant to use. |
||||