Reflection: I was too lazy — too lazy to check the official docs for how to minimize to the tray. As it turns out, AIR had this designed in all along. See the official AIR document DEV_GUIDE_FLASH, <Chapter 13: Taskbar icons>. Let me study it now, and put together a Chinese doc along the way to atone.

Overview: About taskbar icons

Many operating systems provide a taskbar where applications can display a small icon representing themselves. ADOBE AIR exposes an interface for interacting with an application’s taskbar icon through the NativeApplication.nativeApplication.icon property. AIR creates the NativeApplication.nativeApplication.icon object automatically. The type of this object is either SystemTrayIcon or DockIcon, depending on the operating system.

You can use the NativeApplication.supportsDockIcon and NativeApplication.supportsSystemTrayIcon properties to determine which InteractiveIcon subclasses AIR supports on the current operating system. The InteractiveIcon base class provides the width, height and bitmaps properties for changing the images used for the icon. However, accessing the DockIcon or SystemTrayIcon properties on the wrong operating system will throw a runtime error. To set or change the image used for an icon, just create an array containing one or more images and assign it to the NativeApplication.nativeApplication.icon.bitmaps property. Taskbar icons can be different sizes on different operating systems. To avoid images being displayed at an incorrect scaled size, you can add multiple image sizes to the bitmap array. If you provide more than one image, AIR picks the one closest to the current taskbar display size and only scales it when necessary. The following example sets a taskbar icon using two images: NativeApplication.nativeApplication.icon.bitmaps = [bmp16x16.bitmapData, bmp128x128.bitmapData]; To change the icon’s image, define an array containing the new image and assign it to the bitmaps property. You can update the icon in response to EnterFrame or Timer events. To remove the icon from the notification area (on Windows), or restore the default icon appearance (on Mac OS X), set bitmaps to an empty array: NativeApplication.nativeApplication.icon.bitmaps = [];

Dock icons

AIR supports dock icons when NativeApplication.supportsDockIcon is true. The NativeApplication.nativeApplication.icon property represents the application on the dock (not the window dock icon). Note: On Mac OS X, AIR does not support changing a window icon on the dock. Likewise, changes to the application dock icon only apply while the application is running — when the application exits, the icon reverts to its default appearance.

Dock icon menu

We can add commands to the standard dock menu by creating a NativeMenu object containing those commands and assigning it to the NativeApplication.nativeApplication.icon.menu property. The items in the menu appear above the standard dock icon menu items. Bouncing the dock You can bounce the dock icon by calling the NativeApplication.nativeApplication.icon.bounce() method. If you set the bounce() priority parameter to informational, the icon bounces once. If you set it to critical, the icon bounces until the user activates the application. The priority constant parameters are declared in the NotificationType class. Note: The icon does not bounce when the application is already active.

Dock icon events

When the dock icon is clicked, the NativeApplication object dispatches an invoke event. If the application is not running, the system starts it. Otherwise, the invoke event is delivered to the running application instance.

System tray icons

AIR supports system tray icons when NativeApplication.supportsSystemTrayIcon is true, currently only on Windows. On Windows, system tray icons are displayed in the taskbar notification area. No icon is displayed by default. To display an icon, assign an array containing BitmapData objects to the icon’s bitmaps property. To change the icon’s image, assign an array containing the new image to bitmaps. To remove the icon, set bitmaps to an empty array.

System tray icon menu

You can add a menu to the system tray icon (the operating system does not provide a default menu) by creating a NativeMenu object and assigning it to the NativeApplication.nativeApplication.icon.menu property. Right-clicking the icon gives access to the system tray icon menu.

System tray icon tooltip

Add a tooltip to an icon by setting the tooltip property: NativeApplication.nativeApplication.icon.tooltip = "Application name";

System tray icon events

The SystemTrayIcon object referenced from the NativeApplication.nativeApplication.icon property dispatches a ScreenMouseEvent for click, mouseDown, mouseUp, rightClick, rightMouseDown and rightMouseUp. We can use these events, together with the icon menu, to let users interact with the application when it has no visible window.

Example: Creating a windowless application

The following example creates an AIR application with a system tray icon but no visible window. The system tray icon has a menu with just one command to exit the program. package { import flash.display.Loader; import flash.display.NativeMenu; import flash.display.NativeMenuItem; import flash.display.NativeWindow; import flash.display.Sprite; import flash.desktop.SystemTrayIcon; import flash.events.Event; import flash.net.URLRequest; import flash.desktop.NativeApplication; public class SysTrayApp extends Sprite { public function SysTrayApp():void{ NativeApplication.nativeApplication.autoExit = false; var icon:Loader = new Loader(); var iconMenu:NativeMenu = new NativeMenu(); var exitCommand:NativeMenuItem = iconMenu.addItem(new NativeMenuItem(“Exit”)); exitCommand.addEventListener(Event.SELECT, function(event:Event):void { NativeApplication.nativeApplication.icon.bitmaps = []; NativeApplication.nativeApplication.exit(); }); if (NativeApplication.supportsSystemTrayIcon) { NativeApplication.nativeApplication.autoExit = false; icon.contentLoaderInfo.addEventListener(Event.COMPLETE, iconLoadComplete); icon.load(new URLRequest(“icons/AIRApp_16.png”)); var systray:SystemTrayIcon = NativeApplication.nativeApplication.icon as SystemTrayIcon; systray.tooltip = “AIR application”; systray.menu = iconMenu; } if (NativeApplication.supportsDockIcon){ icon.contentLoaderInfo.addEventListener(Event.COMPLETE,iconLoadComplete); icon.load(new URLRequest(“icons/AIRApp_128.png”)); var dock:DockIcon = NativeApplication.nativeApplication.icon as DockIcon; dock.menu = iconMenu; } } stage.nativeWindow.close(); } private function iconLoadComplete(event:Event):void { NativeApplication.nativeApplication.icon.bitmaps = [event.target.content.bitmapData]; } } } Note: This example requires image files named AIRApp_16.png and AIRApp_128.png in the application’s icons subdirectory. (You can find the example icon files in the AIR SDK — copy them into your project folder to test.)

Window taskbar icons and buttons

Highlighting a taskbar window icon

When a window is in the background, we can notify the user that an event associated with that window has occurred. On Mac OS X, we can notify the user by bouncing the application dock icon. On Windows, we can call the notifyUser() method of a NativeWindow instance to highlight the window’s taskbar button (window notification). The type parameter passed to the method determines how urgent the notification is:

  • NotificationType.CRITICAL: The window icon flashes until the user brings the window to the foreground.
  • NotificationType.INFORMATIONAL: The window icon changes color and is highlighted.

The following highlights a window’s taskbar button: stage.nativeWindow.notifyUser(NotificationType.CRITICAL); Calling the NativeWindow.notifyUser() method on an operating system that does not support window-level notifications has no effect. Use the NativeWindow.supportsNotification property to determine whether window notification is supported.

Creating windows with no taskbar button or icon

On Windows, windows created with the utility or lightweight type do not appear in the taskbar. Invisible windows also do not appear in the taskbar. Because the initial window must be of type normal, to create an application with no window buttons appearing in the taskbar we must close the initial window or make it invisible. To close all windows in an application without ending the program, you need to set the NativeApplication object’s autoExit property to false before closing the last window. To simply keep the initial window from being visible when it appears, add false to the element in the application descriptor file. (Do not set the visible property to true or call the window’s activate() method.) In new windows opened by the application, set the type property of the NativeWindowInitOption object passed to the window constructor to NativeWindowType.UTILITY or NativeWindowType.LIGHTWEIGHT. On Mac OS X, minimized windows are displayed on the dock. We can prevent the minimized icon from being displayed by hiding the window instead of minimizing it. The following example listens for a nativeWindowDisplayState change event and cancels it when the window is minimized, replacing it with handling that sets the window’s visible property to false. private function preventMinimize(event:NativeWindowDisplayStateEvent):void{ if(event.afterDisplayState == NativeWindowDisplayState.MINIMIZED){ event.preventDefault(); event.target.visible = false; } } If a window is minimized to the Mac OS X dock, after setting the visible property to false the dock icon is not removed, and the user can still click the icon to bring the window back.