Adobe AIR Non-Transparent Window Bugs Part 2: Maximize

February 4th, 2010 by Steven Sacks

Maximized AIR windows on Windows XP are positioned at -4,-4 and the width and height add 8 pixels to compensate. On Windows 7, this is doubled, so the position is -8,-8 and the width and height add 16 pixels to compensate. This works fine with transparent AIR windows.

Note: This behavior is not documented, and I hope they add it to the AIR documentation.

However, when you maximize a non-transparent non-system chrome window in AIR, the window is drawn 1 pixel in on all edges, so you can see the desktop as a 1 pixel border around the window. Additionally, the window is positioned at 1,1 instead of -4,-4 in Windows XP and -8,-8 in Windows 7, and the window is cropped to 1 pixel less than the visible bounds on width and height, which means 10 pixels are being cropped in Windows XP and 18 pixels are being cropped in Windows 7.

Here's a screenshot of what the window top and bottom look like when normal:
Normal AIR Window
Normal AIR Window Bottom

And this is what it looks like when it's maximized (I cropped out the middle to fit the blog):
Maximized AIR Window
Maximized AIR Window Bottom

As you can see from the maximized image, the window is incorrectly rendered. There are two primary issues.

The NativeWindowBoundsEvent says it's positioned at -4,-4 / -8,-8, but it's actually positioned at 1,1.

The NativeWindowBoundsEvent width and height are correct at +8 for Windows XP and +16 for Windows 7. But, because the window is cropped at 2 pixels less width and height than the window is drawn at, on Windows XP the window is cropped by 10 pixels, and on Windows 7 the window is cropped by 18 pixels.

Here are screenshots where you can see the 1 pixel border on Windows XP and Windows 7. I made the desktop bright red (#FF0000) so you can clearly see the borders. There's also another bug with Windows XP that I'll go into below.

Windows XP
Windows XP

Windows 7
Windows 7

If you look at the Windows XP one, you can see that native window controls are being drawn (this happens in Windows 7, as well). This happens sometimes when you maximize from a normal state on a non-transparent window. There's nothing reliable that causes it, but it does happen sometimes. This is the first time I've been able to take a screenshot of it. What's weird is rolling over the graphics in the window hides the controls but you can still click on them. What's weirder is that if you click on the native control to restore the window (go back to normal), AIR doesn't fire a state change event!

There's one more issue with non-transparent AIR windows. It's the same bug that the CS4 suite of software has when the windows are maximized. When you have two monitors and your CS4 application is maximized (like Flash or Photoshop) and you drag a window across the right edge of the application, you see ugly ghosting of the window you're dragging.

Windows XP Edge Bug

See all that ugly blue? That was me dragging the FlexBuilder window around. The blue is the color of the title bar of the native window. Any window will cause that, though. On AIR, the problem is even worse because that 1 pixel border on the top and bottom also suffer from the ghosting.

I don't know why, but CS4 and AIR both have the same exact issue.

Here's what it looks like in Flash CS4 and Photoshop CS4:

Flash CS4
Windows XP Edge Bug

Photoshop CS4
Windows XP Edge Bug

The ghosting goes away if you change state, like minimizing then restoring or clicking the restore button. This only happens when the window is maximized.

Please, please, please fix this in AIR (and CS5)!

Added to Adobe Bugs on Feb 8th

Update: Workaround

While there's no way to deal with the 1 pixel border or the ugly ghosting that happens, I have figured out a straightforward workaround for the resize. Because you cannot move Mac windows to negative y positions (AFAIK), this if statement will only happen on windows.

private function onResize(event:NativeWindowBoundsEvent):void
{
	var offset:int;
	if ((event.afterBounds.x == -4 && event.afterBounds.y == -4) || (event.afterBounds.x == -8 && event.afterBounds.y == -8)) offset = event.afterBounds.x * -2;
	width = event.afterBounds.width - offset;
	height = event.afterBounds.height - offset;
}

Posted in AIR, Adobe, Bugs

9 Responses

  1. Neobox75

    Same problem… :(

  2. Oliver Goldman

    Thanks for the detailed write-up. If you'd be so kind as to submit this through our public bug reporting mechanism at http://www.adobe.com/go/wish, we'd be happy to investigate.

    regards,
    Oliver Goldman
    Adobe AIR engineering

  3. Steven Sacks

    Already did!

  4. Yann Graufogel

    Take care, you're workaround doesn't deal with the taskbar size (width or height depending on the user configuration).
    So need to add in the calculation some of the Screen.mainScreen.visibleBounds properties.

    regards.

  5. Steven Sacks

    A maximized window already takes into account the visibleBounds.

    This is an onResize event listener and uses the afterBounds property. No additional calculation required. My code is fully tested on all platforms.

  6. Loïc Fougeray

    Hi, you're talking about non-transparent windows but i'm worling with a transparent one and a custom chrome and i'm having similar problems.

    Since the window is move to -4,-4 (-8,-8) and sized to compensate some of the chrome is cut off.
    First it's not looking great but the bigger problem is it's not actually cut off, it's just outside of the screen so if you bring mutliple screens you can see the borders of your chrome on those (you can see it behind windows 7 taskbar wich is transparent too).

    For the moment the only solution i see is creating a custom maximize/restore capability and thuse loosing the native system one.

  7. djandrew

    The work around seems to be broken in the latest version of AIR (2.0.2). A white 1 pixel border shows on dynamically created non-transparent windows that are maximized on Windows 7.

  8. jeff spicer

    i've not used AIR2 yet. if there are problems, this might be a solution. It's the same principal, just with more code. The difference is that it subracts the offset from an invisible maximized window, whether the offset is 4 or 5 or whatever.

    private function maximizeNativeWindow():void
    {
    //AIR's maximize feature is off by 4 pixels, top and left.
    if (Capabilities.os.search("Windows") > -1)
    {
    var rect:Rectangle = getScreenRect();

    rect.width = rect.width + 2 * rect.x; //rect.x is a negative number. we're subtracting from the width and height.
    rect.height = rect.height + 2 * rect.y;
    rect.x = 0;
    rect.y = 4;

    this.nativeWindow.x = rect.x;
    this.nativeWindow.y = rect.y;
    this.nativeWindow.width = rect.width;
    this.nativeWindow.height = rect.height;
    }
    if (Capabilities.os.search("Mac") > -1)
    {
    this.nativeWindow.maximize();
    }
    }

    private function getScreenRect():Rectangle
    {
    var options:NativeWindowInitOptions = new NativeWindowInitOptions()
    options.systemChrome=NativeWindowSystemChrome.NONE;
    options.transparent=true;
    var tmpWindow:NativeWindow = new NativeWindow(options);
    tmpWindow.maximize();
    var rect:Rectangle = tmpWindow.bounds.clone();
    tmpWindow.close();
    return rect;
    }

  9. jeff spicer

    edit: that ought to say rect.y = 0;

Leave a Comment

Please note: Comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.

About Steven Sacks

I am a professional Flash developer with over 13 years of programming experience. I have consulted for high-profile agencies and companies in San Francisco, Los Angeles, Atlanta and New York, and developed numerous award-winning websites and rich internet applications for clients including Adobe, Fox Sports, FX Networks, Anheuser-Busch, GE, DirecTV, ESPN, The Weather Channel, Home Depot, and Coca-Cola.

I am the author of the open-source Gaia Framework for Adobe Flash, which dramatically reduces development time and makes developing Flash sites much easier.