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!

———————————————-
Update: This has been fixed in AIR 2.5

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;
}
 

11 Responses to Adobe AIR Non-Transparent Window Bugs Part 2: Maximize

  1. Neobox75 says:

    Same problem… :(

  2. Oliver Goldman says:

    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. 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.

  4. Steven Sacks says:

    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.

  5. Loïc Fougeray says:

    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.

  6. djandrew says:

    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.

  7. jeff spicer says:

    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;
    }

  8. jeff spicer says:

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

  9. sravanthi says:

    Hi Jeff,
    Great workaround thank u

  10. Elliot Geno says:

    Yeah, the redraw issues on resize are deplorable. Resizing on the lower right is not that bad, however the top left is most noticeable in my application. I'm curious about changing the stage.align to the opposite corner while resizing. Im going to see if it helps.

Leave a Reply

Set your Twitter account name in your settings to use the TwitterBar Section.