Code by Kevin, Programming, code, business, and other pursuits
Kevin Walzer, software developer.
Subscribe to RSS Feed
Get a syndicated feed of my weblog.
Site design: Skeleton
TextSweep is no longer in the Mac App Store.
I've tried four times to get the new version, 2.0, approved, and after an initial rejection that reflected some silly oversights on my part, I've hit a more difficult obstacle: the App Store version freezes when files are dragged to the main window, while the non-App-Store version does not.
The difference between the two--the app sandbox, which is required for the MAS version--seems to be the obvious place to look for issues. I've disabled the sandbox for the version downloaded from my website because I want to support the Sparkle app updating tool for that version, and Sparkle is incompatible with the sandbox.
After doing some further digging, I've narrowed it down to one of two issues, both intractable. The likeliest cause is that the sandbox does not play well with groups of dragged files, as Apple discusses here: "Although you can support dragging file paths, in general, you should avoid doing so unless you are certain that the destination app will never be run in an app sandbox." Removing drag-and-drop support from TextSweep would make using it so cumbersome it hardly seems worth the effort.
Another, less likely candidate is a long-standing bug in Tk that leads to hangups and freezes at random moments; this is a result of the complex and fragile integration between Tk and Cocoa, which works somewhat differently at processing user events than Tk does. (Carbon integrated far better with Tk in this fashion.) When I force-quit TextSweep because it hangs, this is what I'm actually seeing (though I suspect it was triggered by the sandbox not handling groups of dragged files gracefully). This bug has proven impossible to fix, so if I can't work around it, I'm basically stuck.
Either way, the non-sandboxed version works just fine, and so it's just a simple matter of supporting that version: done. I've removed the existing MAS version of TextSweep, and will not be submitting any more MAS updates.
If you are a user of the MAS version of TextSweep and would like to update to version 2.0 at no cost, please contact me and I will be glad to assist you. My apologies for the difficulty.Sat, 28 Dec 2013
Now, TextSweep is the last app still under review. I'm hoping it will be approved in the coming week.Thu, 19 Dec 2013 Wed, 18 Dec 2013
I don't hear from customers as much as I used to.
Even a few years ago, when I developed a new app or released an update to an existing app, I'd get a lot of e-mails from customers about it. They might be reporting a bug, requesting help with something that was unclear, or suggesting a new feature. Regardless of the circumstances, the communication, the interaction, was very valuable. It made me feel my apps were useful, and gave me a sense of connection to the folks using them.
I'd also send out announcements of new products to new customers, since I had a large database of customer e-mail addresses; back then I fulfilled serial numbers manually, after getting a notification from Paypal. Occasionally these messages would also include requests for feedback on specific questions. Again, the feedback was enormously useful.
Over the past couple of years that's changed. I still hear from a customer or two when I do a new release, but the volume is far less than it used to be. Most of the time, when I get a confirmation of a customer purchase, I never hear from the customer. (The ones I do hear from today are the ones I've heard from a lot in the past.) And in many cases (i.e. the Mac App Store) I don't know who my customers are at all.
I don't know if this is just a factor of the reduced sales of my apps or the changing landscape of the app market on Mac OS X; probably it's a bit of both. But it's not a development I'm happy about. Connection with customers gives me a real sense of purpose with my apps, and I miss that.Fri, 13 Dec 2013
Today I'm releasing updated versions of my apps and unveiling a redesigned website, in what I feel is the most significant transition for my software business in four years (since my apps were ported to run on Cocoa).
As noted over the past several months, I've been working to modernize the user experience that my apps offer, both in terms of new hardware on the Mac (Retina Display) and their general fit with the Mac platform. These new apps offer a resolution-independent UI, a more muted design, support new features of OS X (fullscreen and sudden termination, among others); they also offer improved performance and other functional enhancements. Their under-the-hood organization has also been simplified to make updates a smoother process.
The website redesign reflects the evolution of the apps toward a cooler, more muted appearance. The website has also been re-tooled a bit under the hood for easier, simpler maintenance and updates.
Of the apps, all six have been released from my website, I've posted announcements of them to Mac download sites, and three are waiting for review at the Mac App Store. (I didn't want to hold up the release of my apps because of Apple's review process; the App Store versions will simply have to come when they come.) One app I had previously decided to discontinue has been revived--NameFind, because I still use it frequently, and because I'm personally fond of it. The other apps I discontinued had little constituency any more, and I had less personal investment in their functionality.
What value does a more muted appearance, better performance, and simpler internal design offer to my customers? For one, it means that my apps provide a smoother working experience with the latest version of OS X than before (even though the apps are somewhat less native overall, trading an NSToolbar for a simpler toolbar layout that can be configured more extensively in my toolkit of choice, Tk). I've made my apps 10.9 only to ensure they support the latest features. It also means that the apps now have a strong foundation for updates; I can focus on refining app features rather than re-architecting and re-designing the apps at a foundational level.
While it's my hope that these apps enjoy better sales, I've been trying for so long to grow my software business only to see its sales gradually decline that I have adjusted my expectations. The Mac software landscape has changed in the past few years; paradoxically, as the user base has grown because of the influx of iOS developers, it has become harder for an indie developer to stand out, to make a living. Over the past year or two I've seen so many talented developers---developers far better than me--throw in the towel on product development and shift over to contracting for other companies. It's not easy. I don't depend on my app sales for my living, so I don't have to make the choice to focus on something else I enjoy less, but I empathize with those who do.
So what's the theme of "reinvention"? It means I've streamlined my app lineup, from one I had planned to grow to a dozen or more apps to a smaller one (six, with possibly one or two more if I can find a specific niche to target). Downsizing my sales expectations, downsizing my app portfolio: these have been my focus this year. Overall my sales are down a bit from last year, and are significantly down from a few years ago. But even as I downsize my app portfolio and watch my sales taper off, the apps themselves are better than ever. I'm proud of them.
The flailing around I've done over the past few years--trying and failing at Windows development, doing a large amount of open-source development, releasing a commercial iPhone app that sold not at all, briefly hanging out a shingle as a software consultant before realizing that working as a software developer for someone other than myself has no appeal whatsoever--has left me where I am now: a Mac developer who earns some revenue from Mac apps, and an iPhone/mobile developer who targets the platform for branding/strategic reasons (my publishing business) rather than as a revenue stream. In both cases I am producing quality work, better than I ever have, even as the money has declined. 2013 was the year I spent coming to terms with this paradox, and it will guide me into 2014 and beyond.Fri, 08 Nov 2013
After my recent discussion of finding the right mass of customers, and given the ambitious task I've set of doing major updates of all my apps, I've also taken on another difficult task: deciding how many apps to move forward with.
I have one steadily-selling app (PortAuthority), and several others that sell in volumes ranging from modest to non-existent. PortAuthority is not far enough ahead of the rest to sustain my software business by itself; instead, it accounts for about half my sales overall, while a cluster of my other apps accounts for the other half. Of that cluster, several apps show up in modest numbers individually, and some contribute only a sale or two per year.
I've been very reluctant to decide to drop any of my apps, since I've invested a good deal of effort into each of them, and all solve problems I've had at one time or another. However, the scale of the app updates I'm undertaking is rather large, and I simply don't have time to invest in that level of work for an individual app that isn't selling. So, today I took a hard look at sales numbers, and have decided to drop three apps from my lineup: my file renaming app FileMorph; my file search app NameFind; and my UI for Fink, Phynchronicity.
None of these apps have sold more than a couple of licenses per year over the last few years. Phynchronicity got some nice attention when it was first released in 2007, and was a solid seller for a few years. But its sales in recent years have dropped to near zero. By contrast, NameFind and FileMorph never took off at all and only registered sales when accompanied by heavy promotion and discounting. All three apps are in crowded markets with a major incumbent or lots of competition, and it was just hard for them to get any sustained tractions. (By contrast, PortAuthority is the major established incumbent in its market niche, and no other competitor has been able to gain traction.)
Somewhat to my surprise, other apps such as QuickWho and TextSweep have found modest, but steady, sales on the Mac App Store. These apps, along with Manpower, are not stellar performers individually, but each contributes to an average monthly sales total that is about equal to PortAuthority. In contrast to the apps I'm dropping, these apps are in more focused niches and don't seem to have a lot of competition; for a small but sufficiently large number of users, these apps fulfill a need. Apps of this kind also really benefit from being in the Mac App Store; while the App Store is crowded, it offers such a huge potential market of Mac users that it's easier to reach the small number of users who might be interested in my apps.
Reviewing my sales numbers and deciding to drop some slow sellers accomplishes two things for me. One, it will allow me to better focus my efforts. It's easier to update five apps than eight, especially when one of the apps, Phynchronicity, would require significantly more time to update than the rest. Second, this review pretty much answers the question I posed previously: I'm having more success targeting narrow niches, where there isn't much competition, rather than large niches. This also means that any new apps I develop will be geared to smaller niches rather than large ones, and will focus on being included in the Mac App Store. Except for PortAuthority, my non-Mac-App-Store sales are pretty negligible. (PacketStream, my Mac network monitor, cannot be in the Mac App Store, and its sales numbers just made the cut--but it sells far less than PortAuthority.)
This has been a useful and productive process. I'll be able to finish updating my remaining apps fairly quickly, and I'll be able to do incremental updates much more frequently with a smaller number of apps; this has been a real challenge for me in recent years. And I'll be very careful before deciding to add any new apps, as well.Thu, 31 Oct 2013
I've spent the last few days updating and tweaking my server installation, which happens to be OS X Server running on an iMac in my office. I've posted some observations about Mavericks Server here. Brief summary: Mavericks Server is a powerful, inexpensive, easy-to-use server platform that, in its current incarnation, offers the smoothest upgrade experience of any Mac server I've ever installed. Check out the link for more details.Fri, 11 Oct 2013
As I discuss plans to keep my prices at the higher end of the "indie-shareware-utility" market (around $30) to keep slightly better revenue in the face of low unit sales, this also prompts me to consider why my sales are pretty modest, and lower than a few years ago.
There are two common reasons for low sales: you're in a crowded market and it's hard to get noticed; or you're in a niche market that only a few people care about. Either way, it's hard to get a critical mass of customers. In discussing my app strategy on various mailing lists such as the MacSB group, the advice most other folks give me focuses on the latter: in general my apps provide nice graphical user interfaces to command-line utilities, and the most frequent users of such utilities are people who do not want or need GUI's--hence my potential customer base is pretty small. Because it's hard to reach a big enough group of customers in niche markets, developers like Marco Arment advise against developing "niche" apps.
Fair enough. An obvious alternative strategy is to target larger app markets with more potential customers. But the obvious challenge here is that there is more competition in larger markets, and it's harder to get noticed. This is especially so today in light of the Mac App Store; it seems pretty clear that the Mac App Store has attracted more developers into the Mac orbit. It's hard to prove definitively, but my overall sales dropped quite a bit after the Mac App Store opened up. Because there's more competition in the Mac space, there are developers like Justin Williams who advise against targeting larger categories because they are too crowded.
Well. If small niches are too small, and large niches are too crowded, what's left?
I think the best solution is to be realistic about your prospects: reaching customers is hard, and now it's harder than ever. Paradoxically, as the Mac app market gets bigger and more crowded, the chances of any individual developer standing out and earning high sales is reduced. (In this respect the Mac market is becoming more like the Windows market.) I think this is one reason why a lot of Mac developers focus more on contract app development for the Mac and iPhone market rather than on trying to make and sell individual apps to end users. If they develop individual apps, they are more apt to be portfolio pieces than serious products with a large customer base.
If it's a given that your app is likely to be a modest seller and that any chance of breaking out of the pack is going to rely on factors beyond your control, what's left is to follow your muse: make apps that address some need that you see, perhaps something that scratches your own itch, and make them as good as you can, regardless of whether it targets a large or small niche. You are much more likely to create an app that reduces pain for someone else, and therefore is worth paying for, if you are reducing your own pain in the process. It's always a risk that your app will only have an audience of one, but if you make it awesome, and put a little business sense behind it in terms of marketing and presentation, it's likely that you'll reach at least a few other users who will give you money.
Let's face it: This may require you do to something else for your living. But then again, that's always been the case. And if you make an awesome app that others give you money for, you still have a chance, however slim, to be one of the exceptions.
If one lowers prices, that needs to be offset by a corresponding increase in sales volume sufficient to offset the lower price. Otherwise, you're simply left with less revenue.
Because the lower prices didn't really move the needle on sales, I have little choice but to restore the older prices if revenue is to remain consistent.
I've tried this trick enough that I don't see much point in trying it again in the future. I may run promotional prices in the future; I have done so in the past in partnership with MacZot, MacUpdate, and Bits du Jour, but these were usually one-day or one-week promotions that provided a nice short-term boost in sales. As for my own discounts, though...I think that's done.Mon, 23 Sep 2013
In a previous entry I outlined an update roadmap for my apps that focused on taking a step back from native UI integration and more on under-the-hood integration between my cross-platform development framework (Tcl/Tk) and OS X. I'm about done with applying this strategy to PacketStream. Because the changes to PacketStream are going to serve as a template for the rest of the app updates as well, I wanted to take some time to discuss them in detail.
Less native UI integration
I am moving away from the extensive wrapping of native widgets in favor of a modified approach that makes use of Tk's native foundation but also takes advantage of Tk's flexibility with configuring appearance. For instance, in place of a native NSToolbar that cannot be easily configured from Tk, I've opted for the standard Tk approach of setting up a group of toolbuttons within a frame using a custom font to display icons, and using Tk to style both the buttons and their tooltips. This is simpler to set up and also is snappier in performance; the NSToolbar approach was harder to configure, slower to load and, for some reason, subject to flickering, especially in displaying tooltips. Note that this approach still makes use of under-the-hood native integration; I had to write a custom library calling Core Text functions to load the icon font. But this approach has the advantage of allowing me to use font icons, which are resolution independent and naturally friendly to Retina displays, rather than native bitmaps, which are not Retina friendly without considerable rigamorole. Bottom line: My UI is now easier to set up, runs better, and supports emerging hardware features on the Mac platform (Retina support).
The screen shots below illustrate the older and newer layout of PacketStream.
Greater integration under the hood
I'm taking a step forward toward better integration under the hood. One good example on this is how I call external processes that need escalated privileges, such as running tcpdump (the network monitoring tool that powers PacketStream). If someone is launching tcpdump from the command line, they'll do so by calling "sudo tcpdump"; sudo is a command that gives "superuser" privileges to the user launching tcpdump. Native GUI apps use a somewhat different process that presents an "authorization" dialog to the user (such as a software installer); I have, however, been unable to get this approach to play nicely with the design of my Tcl apps, and so have resorted to presenting a dialog that calls for the user's password and pipes it under the hood to "sudo." This approach has served me well for several years, but as I have continued to research the question, I've come to the conclusion that using the user's "sudo" password in this fashion presents a security risk because the password is transmitted, under the hood, in plain text. I finally devised a solution that allows me to make use of the native authorization dialog based on the work of another Mac developer, Ian Waldham, and that's what I'm rolling out in my applications now. It's more secure, provides very clean integration, and, in my testing, allows my app to perform better as well. Bottom line: Improved under-the-hood integration provides better performance and security.
The screenshots below illustrate the older and newer, more secure, native authorization dialog.
More muted look and feel
One reason for moving away from wrapping of native widgets such as the NSToolbar is that they are not very configurable--it is hard to modify their appearance to keep up with evolving UI trends on the Mac. This may be subjective, but it matters; my apps making use of the native Cocoa toolbar look dated compared to other apps running on recent versions of OS X, which are more muted in color. It's not just a matter of changing icons; it's also matter of overall color schemes, the size of buttons and their layout, and more. Switching to a more Tk-centric approach (which uses native components such as Cocoa buttons and frames, but which does not lock you into structured Cocoa widgets such as the toolbar) gives me more flexibility to keep up with these UI styles. As a result, if you look at the screenshots above, you see a big difference in the old and new version of PacketStream. The old version is more authentically native, but now looks stuck in a time warp. The new version, while it looks somewhat less native in its overall layout, nonetheless does not look out of place because it picks up current styles with color, icon format, and more. Similarly, if you look at the icons below, you'll see a big difference in the old and new versions. Bottom line: It's important to use an app structure that lets you readily modify the general look of the app to keep up with evolving UI trends.
The screenshots below illustrate the older and newer, more muted, icon style.
I'm going to hold off on releasing the new version of PacketStream because I want it to be of a piece with my other apps; I'm hoping to have all of the new apps ready for release, along with a website makeover, early in 2014. But I wanted to give some concrete evidence of the direction these apps are taking. I'm happy with the progress thus far.Thu, 29 Aug 2013
Maintaining and updating several applications at once isn't a simple process, especially if you don't have as much time as you'd prefer. After putting out point updates of a couple of my apps that implemented some of the work I've been doing this year, and planning to roll out similar incremental releases of my other apps, I've decided to hold off on any further incremental releases and just update everything in one big bang. This is definitely a case of mission creep, as my plans are now evolving in the direction of a complete user interface (UI) refresh of my apps, many revisions in their under-the-hood features, and revisions of their branding, but I think it's the best course to pursue.
In general terms, here's what the changes portend for my apps:
Why all these changes? Declining sales are one reason; I'm not satisfied with the way my apps have sold in recent years and I think it's time to try some major changes. But, apart from that, I also want to put the apps on a platform for continued evolution. That's a necessary task. I think they've gone as far as they can go in their current configuration and more than minor tweaking is required to get them ready for their next five years of life. That's the larger purpose of this project, even if sales don't revive to a dramatically higher level.
I realize that until I release them, these changes are just vaporware. My goal is to have them out after the new year, but time will tell.Sat, 03 Aug 2013
The new versions will support a vastly improved update experience going forward by integrating Sparkle support, the popular framework for app updates that is still used by hundreds of apps that are downloaded from outside the Mac App Store. Sparkle does not have any obvious hooks that would enable it to be directly integrated into Tcl/Tk applications, but I was able to integrate the framework's functionality by adapting the Sparkle Helper App by Marco Schuh to my own projects. (To see the source code for my Sparkle Helper app, go to http://sourceforge.net/p/tk-components/code/134/tree/.) My own homegrown updating system has had some hard-to-track bugs in recent versions of my apps, and I just decided to abandon it in favor of Sparkle.
Other than Sparkle integration, both apps feature bug fixes and other improvements (PacketStream gets a more responsive display; NameFind has better Growl integration). I've also lowered the price of the apps a bit, from $30 to $20, in hopes that this will invite more folks to give them a try.
As always, upgrades are free to registered users. And these are just the first round of updates I have planned for these apps. As we enter the second half of 2013, I'm moving ahead with rolling out some of the work I've done on different levels of Mac integration in my apps. Sparkle support is a good example of this, but it's not the only one.Wed, 03 Jul 2013
A few months ago I decided against using Perl as a desktop development language, as a result of some limitations I had run into in updating and deploying some Perl libraries. I have had a bit of free time this week to revisit the problem, and happily, I've found a solution. As a result, Perl is now back in my toolbox, and I look forward to working on some new apps in the language in the near future.Tue, 02 Jul 2013
I've scratched another small itch in my app development by creating a Cocoa-style popover window for my Tcl/Tk apps.
After looking at the Cocoa docs for NSPopover, I concluded that it isn't feasible to implement such a window natively in Tcl/Tk by implementing some kind of integration at the Objective-C level--there's no way to place Tk child views in the genuine NSPopover. However, Tk provides enough hooks to implement something reasonably close in look and behavior.
I've posted some sample code implementing the popover window here. It's not really feasible to make this a general package, but the sample code should be easy enough to adapt for individual Tk apps.Sun, 02 Jun 2013
I've released version 1.1 of my "fullscreen" open-source library for Tcl/Tk apps on the Mac. This package adds native a "fullscreen" button to Tk windows on Mac OS X 10.7 and later. This release, which is a fairly major under-the-hood rewrite, fixes a major bug with window geometry when the app took fullscreen status (widgets such as buttons would not respond to mouse clicks but instead the click would register a few pixels underneath the widget). For more information, and to download, see http://opensource.codebykevin.com/native.html. Thanks to Andrew Stein for the bug report.Sat, 18 May 2013
Earlier this month I talked about recent changes in UI fashion on OS X, away from bright colors and icons toward a more muted look. This general trend is going to help guide me as I do a significant round of updates on my apps.
I wanted to talk about a related topic as I decide how to update my apps, in terms of how they integrate with OS X. I've always believed that a high level of OS integration is very important in my apps even though I develop using a cross-platform toolkit. The question is, what type of OS-level integration is the most important--visual integration, integration under the hood, or some combination of the two? Until very recently, even though I do strive to integrate with the OS on several different fronts, my answer to this question would have focused on visual integration. Most of my work in recent years has focused on visual integration: native toolbars, printing dialogs, manipulation of the Dock icon, a status icon in the menubar, and more. And my apps have done well on this front.
Yet I am beginning to wonder if the time I've spent on visual integration has been well-spent. In terms of functionality, my apps have advanced at a much slower pace than their visual fidelity to Mac UI conventions. And the increasing pace of change and complexity in Mac UI conventions--especially to support Retina displays--mean that I will have to spend yet more time on UI integration, at the expense of other features.
I'll be honest: I'm getting a bit tired of this treadmill. So I'm starting to look in another direction for an example of how to proceed, NeoOffice, a Mac-optimized version of the open-source OpenOffice office suite, developed for the past decade by Patrick Luby and Ed Peterlin.
A bit of background: OpenOffice is essentially a cross-platform, open-source clone of Microsoft Office. It was originally developed as a commercial product, was bought and open-sourced by Sun Microsystems, and then became a fully independent, open-source project after Sun was acquired by Oracle, the database company. A large community of volunteers and some professional developers maintain OpenOffice and several variants, including LibreOffice (which forked from OpenOffice after it was acquired by Oracle and before Oracle divested the project) and NeoOffice.
NeoOffice came into being because, back in 2003, OpenOffice only ran as a Unix-style X11 application on the Mac: powerful and functional, but not integrated in any way whatsoever. Patrick Luby and Ed Peterlin have gradually enhanced the OpenOffice code base with Mac optimizations, to the point where their version is far superior on the Mac to standard OpenOffice (which now runs natively, but has no special Mac optimizations beyond running as a standard app and not in the X11 environment). They have chosen a different, incompatible open-source license for NeoOffice (GPL) so their code changes cannot be merged back into the standard OpenOffice code suite.
A list of differences between NeoOffice and OpenOffice is instructive. The most recent version of NeoOffice supports the new Mac fullscreen mode introduced in 10.7; supports the Mac document "Versions" feature introduced in 10.7; is much faster than OpenOffice because it uses the latest Mac text-rendering framework, Core Text; supports OS X Services; and more. OpenOffice supports none of these features.
This high degree of OS-level integration may not be immediately apparent if one looks at a screenshot of NeoOffice, such as below, because NeoOffice does not invest heavily in visual integration with Mac UI conventions:
The icons fit reasonably well with the Mac, but toolbars are definitely not native, and the general UI design--i.e. putting tons of buttons in a toolbar--does not follow Mac-optimized guidelines either. While the under-the-hood integration is superior, the visual integration of NeoOffice from a design standpoint is little different from the other variants of OpenOffice. In response to user questions about the UI, the NeoOffice developers have said that, because of limited resources, rewriting the UI of NeoOffice is not in their plans; they prefer to focus on under-the-hood integration, application performance, and so on.
What I find very interesting about NeoOffice is that its under-the-hood integration with the OS is not just better than OpenOffice; it is also arguably better than Microsoft Office's. Microsoft Office 2011 does not support the "Versions" feature either, and I suspect it still uses the same older text-rendering engine that OpenOffice does. Microsoft Office 2011 is, from a general performance standpoint, much slower, less snappy, more sluggish, than NeoOffice, as well.
In terms of visual integration, however, Microsoft Office far surpasses NeoOffice, using a native toolbar, native search field, and, in general, an overall design that well adheres to Mac UI guidelines. Microsoft has taken its "Ribbon" UI concept and, rather than doing a straight port of it from Windows, has implemented in a way that makes sense on the Mac:
Microsoft is to be commended for its work in visual integration. It also goes without saying that Microsoft Office is very powerful. However, as one who uses both Microsoft Office and NeoOffice frequently, I have to suggest that Microsoft's superior visual integration does not offset its sluggishness. I find that NeoOffice is generally easier to use, despite its lack of visual integration. (In fairness, one significant under-the-hood area where Microsoft Office does greatly surpass NeoOffice is in its support for AppleScript, but I don't make much use of this feature.)
So what lessons am I drawing from this discussion? An important one is that I have come to conclude that perfect visual integration is overrated. The likely overhead of continuing to provide a high level of visual integration in my own apps, i.e. to comply with Retina display requirements, does not seem worth it if the apps are sluggish and slow--a complaint I've increasingly heard in the past year or so, which also coincides with an unexpected decline in sales. I want to have reasonable visual integration, but it has to be done in a manner that is easily maintained and allows me to focus on other kinds of optimization and integration as well.
The NeoOffice developers recognize their limits, and are focusing on the types of optimizations and integrations that will give them the most bang for their buck. And I say "buck" literally; the developers earn their living from NeoOffice work, charging an annual $10 download fee to get the app from their website and a year's worth of updates. They have enough users that this is feasible from a business standpoint, and they manage this in spite of the competition from the free OpenOffice variants, such as LibreOffice and the original OpenOffice.
So I will work to maintain a reasonable level of visual integration--I fully intend to support Retina displays--but this will be done in a way that allows me to use my limited time for other, arguably more important, optimizations and integrations. I want my apps to be fast and pleasant to use, and I want them to integrate with the OS in ways other than just visually. They have a ways to go on that front, but I'm taking my first steps in that direction.
One Tcl/Tk app I like for its clean, basic UI is WaveSurfer, an open source tool for sound visualization and manipulation. Its UI is very simple, providing a visual representation of a sound's waveform, with a single set of toolbar buttons that get out of the user's way:
The lack of a standard Mac "unified toolbar" here is not problematic for me, and I imagine the overhead of adding one to the app's UI design would not be worth it for the developer. This app gets its job done in a clean, simple way, and, as with NeoOffice, I'm taking instruction from it for the future development of my own apps.Fri, 17 May 2013
I'm pleased to announce three new Tk-Cocoa integration packages for Mac OS X.
Fullscreen: This package adds native a "fullscreen" button to Tk windows on Mac OS X 10.7 and later. The package adds the fullscreen button that, when pressed, will smoothly animate the window to fullscreen status. The window can be restored to its previous state by clicking the upper right-hand part of the screen and locating the button in the menubar. This package has no relationship to the standard Tk command "wm attributes $w -fullscreen 1," which also implements a fullscreen window and tracks its state internally through Tk. Under OS X, the "wm attributes" command uses different API's and its state can be tracked and configured via Tk. The "::fullscreen::fullscreen" only adds the fullscreen button to the window, and does not track the window's state; setting the window to fullscreen state is triggered by the user. The benefit of this command is that it provides better integration with modern Mac API's.
I've been wanting to implement something like this ever since OS X 10.7 "Lion" came out; I think the fullscreen button is a neat, and useful, effect if you want to immerse yourself in a single app. I could never figure out how to integrate the functionality into Tk's core, especially in a way that played well with existing Tk commands, but the functionality itself is very simple and, once I decided to implement it as an extension library, everything came together quickly.
TclGrowl: This package implements native support for the Growl desktop notification system on OS X. It provides Tcl support via a SWIG wrapper for the gntp-send library, which implements Growl's custom network protocol.
Growl is a popular third-party notification for the Mac, and in the past year or so it has been modernized to play well with recent Mac technologies for Lion and later, such as sandboxing and the Mac App Store. Various Tcl bindings for Growl have been deployed over the years, including more than one written by me, but these older packages are either obsolete (Growl has undergone significant internal changes) or, at a minimum, incompatible with one or more modern Mac features (the Mac App Store has made it much harder to use AppleScript to glue together various applications; my last Growl binding was based on Growl's AppleScript API). I found a third-party library written primarily for Linux, gntp-send, that implemented Growl's notification protocol, and developed a Tcl binding for it. This approach brings Tcl's Growl bindings up to date and sidesteps the limitations of AppleScript, so it's a useful addition to the toolbox.
TkWebView is perhaps the most significant of these packages, as it displays HTML content using the exact same engine as Safari. I posted a query on the Tcl-Mac mailing list about four years ago asking if anyone could provide some guidance in integrating Tcl/Tk with WebKit, and Daniel Steffen, my predecessor as Tk's maintainer on the Mac, threw together a very basic implementation. It was a bit unstable (though that was more because of WebKit bugs on OS X 10.5 rather than in Daniel's code), and so I set it aside. In the past year I came back to the code, added some additional logic to it that would allow the package to serve nicely as a viewer for local HTML content, and polished it up enough for release. This new package supersedes an earlier, pure-Tcl package also called "TkWebView," that I put together based on some truly ancient (mid-1990s) Tk code, and I have removed the older package from my website.
These packages all scratch long-standing itches for me, and should improve the integration of any modern Tk app on OS X. I know they will mine. For more information, and to download them, visit my open-source site.Thu, 09 May 2013
As I mentioned a couple of months ago, I'm in the middle of a large group of updates to my Mac apps. As I've delved into these updates (which focus on implementing libraries and frameworks that will improve all of my apps), I've come to the conclusion that it's time to update their user interface.
The last significant UI update to the apps came in 2011, when I implemented a native Cocoa toolbar for my programs, which, in my view, made them better integrated with OS X. At that point, I was taking a lot of UI inspiration from apps like NetNewsWire, the leading RSS reader for OS X, and which influenced a large number of Mac apps over the years.
Here's a screenshot of NetNewsWire:
Note the clean three-pane interface, the large, easy-to-understand icons in the toolbar, and other details.
And here's my implementation of this interface style in Manpower, my man page reader for OS X:
Note the three-pane interface, the large toolbar icons, and so on. By way of contrast, see this blog entry for some before-and-after comparisons of my apps with an older UI design and the new UI design using the native Cocoa toolbar.
I was very proud of this UI design when I completed it. However, I'm not as happy with it anymore. Several significant changes have come about in the Mac ecosystem, just since 2011: Apple's introduction of high-resolution Retina display technology in its MacBook Pro machines; and the increasing influence of iOS interface design on the Mac UI.
In terms of the Retina display, it has twice the pixel density of standard monitors, so that means that standard images look pixellated when displayed on it; Apple has implemented several API's and best practices to make images look sharp on the high-resolution machines. This requires to make several changes to their applications to work well with the Retina display, including bundling higher-resolution images with their applications.
In terms of iOS UI design, this is reflected in Apple's moving to a much more subdued color and icon scheme in the applications deployed on OS X since 10.7, Lion; buttons are muted, icons are smaller in size and monochrome in layout, and so on. Consider the Mail app in Lion:
What this means for my own apps is that their bright, large-icon interfaces now look somewhat dated, and they also need to be updated to support Retina displays.
A significant part of the work I'll be doing over the next several months is implementing these UI updates, and I've spent a significant amount of time in recent weeks mulling over options on how to proceed on these updates. These updates will require changes under the hood (code) and in the visuals and layout of the apps; it's much more than a simple matter of swapping out images.
While I haven't made a final decision about this yet, one approach I'm actively researching is based on my work on my iPhone apps: using font icons instead of actual image files for icons. A "font icon" is a font character that actually renders an icon image rather than a letter or number; it's a very recent development in web design, and it can translate fairly easily into desktop apps. Font icons offer several advantages over regular images. The most important one is that they are resolution independent, meaning that they scale up and down automatically with the resolution of the computer screen; this will greatly simplify the process of supporting the Retina display. Another advantage of font icons is that they are most commonly designed in the simple, muted style that is now the prevailing mode in both iOS and Mac UI design; this means that they will fit in better. Finally, there are several free, high-quality, open-source font icon sets that I can choose from; this will make the process of modernizing the appearance of my apps much smoother.
I don't have any mockups or other screen shots of my apps with a new UI design to share yet; I'm still very early in the process. But I will share more in coming weeks as I hit specific milestones in UI design. It's also important to note that a UI overhaul is not the only thing my apps will have as new features; I'm working on other framework/library improvements that will make my apps more pleasant to use, and each app will also have app-specific improvements as well.
Given the size of the task I've taken on for myself, it's likely that I will work for much of the rest of this year on these updates, and do a large-scale release of all of them, rather than rolling them out one by one. I've previously said that I want to do more frequent releases of my apps, and it's likely that I won't be following that advice here; but I don't see another way to proceed. In any event, keep watching this space for more updates.Fri, 12 Apr 2013
Most of my work with scripting languages has been with Tcl and Python. Both are powerful languages, work well on OS X, have nice support for the Tk GUI toolkit, and well-defined libraries for deploying desktop apps in an easy-to-install fashion for end users.
Partly out of a desire for a new challenge, and partly to access a different range of capabilities than Python and Tcl offer, I've tried two different languages: Ruby and Perl. Ruby, while a powerful language and with excellent Tk bindings, proved to be a disappointment for reasons outlined here: poor desktop deployment tools for OS X. In that same blog entry, I added that I would be giving Perl a try next.
My time with Perl has been less of a disappointment than Ruby--I enjoy the language and have made it a part of my software business, particularly with enhancing my websites and providing the server side of one of my iPhone apps. I don't regret learning the language. But I've found Perl to be less effective as a desktop development language.
Perl's support for the Tk framework, which is one reason I decided to try it, is quirky and less robust than I expected. Perl's native support for Tk is primarily maintained by ActiveState, an excellent software company that provides commercial support for many scripting languages and which earns a good deal of income from its developer tools. While ActiveState's Perl Tkx module is open-source, it seems to work best with ActiveState's own proprietary tools; it has less of a constituency among developers who use Perl's open-source deployment tools, such as pp. Trying to wrap simple Perl scripts, I've had unexpected results (such as the script linking to the first version of Tk it finds on my system, even though it wasn't built against that version; or crashing unexpectedly when it finds a different version of Tk). Unexpected results aren't necessarily a surprise, but significantly, I've also been able to find little online discussion of the issues I've found; my queries to mailing lists on some of these issues have gone unanswered. That's a bad sign.
As a result, I have decided to stick with my current development languages, Tcl and Python; both have better community support for desktop Mac deployment, and troubleshooting, than either Perl or Ruby.Wed, 20 Mar 2013
I've joined the ranks of developers running promotional screencasts of their apps on their website. The first screencast, for PacketStream, is below.
Screencasts can range in quality from the strictly bare-bones--someone recording a session of an app running on their machine while narrating over an echo into the computer's built-in mike--to highly sophisticated videos with lots of animation, special effects, slick background tracks, and more. It was the latter type, produced by MacUpdate in support of a promotion for FileMorph, which inspired me to give screencasting a try.
The result of my efforts is somewhere between rank amateur and highly slick commercial production--I wanted something with a little polish but don't have the budget for uber-slick--and I'm reasonably pleased with it. My toolset, similar to what I use with my own software, was mainly open-source software (Audacity for mixing the soundtrack, Avidemux for editing the video, and ffmpeg for post-processing for upload to YouTube). I tried a couple of commercial Mac tools on a demo basis; while these tools seemed quite powerful, their learning curve was a bit steep, as was their cost. The open-source toolchain fit both my budget, and my brain, better.
I plan to do screencasts for all my apps over the coming year, and now that I have an idea of how the process works, I think it will be a bit simpler to proceed. I'm looking forward to it.Fri, 15 Mar 2013
After spending a few months working on mobile apps, I am now back working on Mac desktop apps in earnest. The challenge when working on multiple apps, as I do, is how to prioritize updates in such a way that I can actually ship releases at semi-regular intervals.
It's easy to develop a long laundry list of new things to add to an app--it's hard to exhaust that list. Even if an app is fairly mature, it's easy to identify small improvements to make or bugs to fix. However, limiting the scope of such changes is necessary to keep the update treadmill in check; some changes can be deferred until a later release.
Historically, in my apps I've tended to alternate between app-specific changes and improvements--new features for a single app--and more general framework improvements, which can be implemented across all my apps. A rewrite of an app's underlying engine for improved speed is an app-specific improvement. Implementing a Cocoa-based toolbar integrated from Tk is a framework improvement that can be rolled into every app.
At present I'm working more in the framework mode. I have a large list of app-specific improvements to add, but I would like to add some of the framework features first--these will improve all of my apps in meaningful ways. Shifting afterward to more app-specific features and improvements will allow for more than a single release per year. Looking back last year, I see that I tended to combine both library and app-specific features into larger, monolithic releases, and that reduced the frequency of my app updates. Making more regular releases seems to be a better way to keep your apps in the public eye. So, that's what I plan to do this year.Wed, 06 Mar 2013
I've consolidated all my open-source code packages into a separate subdomain, with a different look-and-feel, to make them easier to access and download. The new site is http://opensource.codebykevin.com. Please check it out.Thu, 17 Jan 2013
In response to customer feedback, I've implemented a search engine for all of the sites I maintain, including http://www.wordtechcommunications.com and http://www.codebykevin.com based on some clever code documented at Build a Search Engine in PERL. My own code was heavily modified, but this example was exceptionally helpful in helping me get started.
I've also implemented a similar feature at my blogs using the find plugin for Blosxom by Fletcher Penney. This plugin, unlike the other search engine I developed, is a drop-in module that required no configuration on my part. It works beautifully.
Both search tools enhance the usability of my sites, and both are written in a programming language I'm having fun learning: Perl. Perl is well-suited for website programming, and I look forward to doing more with it.