views:

512

answers:

3

I need to keep a NativeWindow I am creating on top of the main window of the application.

Currently I am using alwaysInFront = true, which is not limited to the windows in the application. I can successfully synchronize the minimize/restore/move/resize actions, so the top window behaves appropriately in those cases. Even though using this option has the drawback that if I alt-tab to other application the window goes on top of the other application.

Because of the above I am trying to get it to work without using the alwaysInFront. I have tried using orderInFrontOf and orderToFront, which gets it in place but when I click an area in the main window the top one becomes hidden i.e. air makes it the top one.

I have tried capturing activate/deactivate events but it only happens on the first click, so on the second click the top window becomes hidden again. I also tried making the top window active when the main one becomes active, but that causes the main one to loose focus and I can't click on anything.

Ps. I am doing this to improve the behavior of a HTMLOverlay I am using - see http://stackoverflow.com/questions/1044927/flex-air-htmlloader-blank-pop-up-window-when-flash-content-is-loaded/1077738#1077738

A: 

Listening for Event.DEACTIVATE and calling event.preventDefault() should work. Not sure if that is what you have tried, but I have an app where that does the trick.

Theo
Thx, unfortunately that didn't work in my scenario. My guess is that in your application you were using the alwaysInFront and canceled the deactivate so it never closed, or you just wanted a window that stayed open when the main one was minimized. It seems the issue is that if I don't use the alwaysInFront option, then when air changes focus to the main window it puts it on top and I can't find a way to prevent it.
eglasius
I've found AIR's window handling to be somewhat lacking... not being able to create proper modal dialogs is sometimes a pain.
Theo
A: 

I ended up turning on/off the alwaysInFront option based on whether the main window or the top window were active i.e. if none where active I turned it off. This was additionally to what I mentioned in the question.

That way when the user switches to another application, the window doesn't go on top of the other apps. I still would prefer a solution where I don't have to use the alwaysInFront option, or even better an alternate solution to the flex loading flash in external sites issue I linked to above.

Ps. I will try to check with the owner of the HTMLOverlay to submit a patch (its an improvement, although its tied to an app that doesn't open extra windows when opening the overlay).

Update: I have committed the changes to the HTMLOverlay.

eglasius
A: 

I'm trying to do something very similar. In an AIR application, I have one large full screen window which is essentially the "desktop". I always want this window to stay behind all other windows in my app. There are, however, some items on the "desktop" window that need to be clickable.

There appears to be no clean way to force a window to maintain its position in the window ordering.

What I've settled on so far, which isn't perfect, is to make all other windows in my app use the alwaysOnTop property but bind this to a global var (ugh) that I maintain to track the overall application level active/inactive state. This way, when I switch to another app, my windows don't float above the all other app windows - they correctly move behind as expected.

Then, I have a regular (alwaysOnTop=false) window that is fully transparent as an "overlay" to the desktop window on which I can place various interactive controls. This window is OK to come forward since it's transparent and my other windows are alwaysOnTop.

Finally, and crucially, I install three event listeners on the "desktop" window as follows:

protected function onApplicationComplete(event:Event):void
{
    this.addEventListener(MouseEvent.MOUSE_DOWN, onClickHandler, true,1000,true);
    this.addEventListener(MouseEvent.CLICK, onClickHandler, true,1000,true);
    this.nativeWindow.addEventListener(Event.ACTIVATE, onActivateWindow,false,-1);
}

protected function onActivateWindow(event:Event):void
{
    trace("sent via activate to back");
    orderInBackOf(bigTransparentWindow);
}

protected function onClickHandler(event:MouseEvent):void
{
    trace("sent via click to back");
    orderInBackOf(bigTransparentWindow);
}

I'm not entirely happy with all this since there is still some occasionally noticeable flicker of objects in the overlay window - it appears that the "Desktop" window gets ordered in front of it, an update of some sort happens, and then it gets forced behind again.

Any better solutions welcome!

verveguy