Futurescale, Inc. PureMVC Home

The PureMVC Framework Code at the Speed of Thought


Over 10 years of community discussion and knowledge are maintained here as a read-only archive.

New discussions should be taken up in issues on the appropriate projects at https://github.com/PureMVC

Pages: 1 [2]
Print
Author Topic: Desktop Citizen Event.CLOSING  (Read 12725 times)
Ondina
Sr. Member
****
Posts: 86


View Profile Email
« Reply #15 on: March 28, 2009, 03:14:22 »

When I have to work on a web project I also need a second monitor.
After reading your answer I tried it out with 2 monitors.

The key for detecting the monitors is :

Screen.getScreensForRectangle()

"Returns the (possibly empty) set of Screens that intersect the provided rectangle."


protected function onResize( event:NativeWindowBoundsEvent ):void
{
      var screens:Array = Screen.getScreensForRectangle( event.target.bounds );   
      var screen:Screen;
      if( screens.length == 1 ) { 
            Alert.show("FIRST monitor");
            screen = screens[0];                                             
    }else if( screens.length == 2 ) { 
         Alert.show("SECOND monitor");                                     
         screen = screens[1];                                             
   }   
...
}

So far so good, but I'm not sure how to use it yet.

Maybe there should be an additional attribute “screens” in that DesktopCitizen.xml?

I'll let you know as soon as I find a solution.

--

Apropos your presentation at FITC Toronto, will it be recorded?

Ondina
Logged

~ Ondina ~
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #16 on: April 01, 2009, 04:00:39 »

Thanks for researching this Ondina. I think it might be useful for us to have at least an automatic function to bring the window back onto screen 1 if screen 2 isn't there and the app is fully within the bounds of screen 2. But if its only partially offscreen, we may not want to. Imagine you've resized the app so it takes up all of screen 2 and only extends partway onto screen 1 and that's how you like it.

I do hope they'll record and make available the FITC talk, but I'm not sure. I'll see.

-=Cliff>
Logged
Ondina
Sr. Member
****
Posts: 86


View Profile Email
« Reply #17 on: April 02, 2009, 04:31:06 »

Hi Cliff

Here is how I solved the positioning of the window when using 2 monitors.

:
  private var windowRectangle:Rectangle;
  private var isOnSecondMonitor:Boolean = false;

   protected function onResize( event:NativeWindowBoundsEvent ):void
   {
windowRectangle = event.afterBounds;
detectScreens();
if ( windowMetricsProxy.displayState == NativeWindowDisplayState.NORMAL ){
windowMetricsProxy.bounds = windowRectangle;
sendNotification( WINDOW_SHOW );
}
  }
  protected function detectScreens():void
  {
var screens:Array = Screen.getScreensForRectangle(windowRectangle);   
var screen:Screen;
var screenIndex:uint = screens.length - 1;
if( screens.length == 1 ){ 
   screen = screens[screenIndex]; 
if( screen.bounds.x > 0 ){
isOnSecondMonitor = true;
trace("window is on SECOND monitor");   
}else{
isOnSecondMonitor = false; 
trace("window is on FIRST monitor");
}
keepOnScreen(screen.bounds);
}                                                                    
else{ 
screen = screens[screenIndex];       
trace("window is on both monitors ( do nothing )");
}  
  }
  protected function keepOnScreen( screen:Rectangle ):void
  {
var rightMargin:Number = screen.x + screen.width + 1;
var bottomFactor:Number = 84;
if( !isOnSecondMonitor ){
if( windowRectangle.left < 0 ){
windowRectangle.offset( -windowRectangle.left, 0 );
}
}
if( isOnSecondMonitor ){
  if( windowRectangle.right > rightMargin ){
windowRectangle.offset( -(windowRectangle.right-rightMargin), 0 );
}
}
if( windowRectangle.top < 0 ){
windowRectangle.offset( 0, -windowRectangle.top );
}
if( windowRectangle.bottom > screen.bottom ){
windowRectangle.offset( 0, -(windowRectangle.bottom-screen.bottom-bottomFactor) );
}
  }

That's far from being perfect, but it's a start.

I couldn't test it on more than 2 monitors, but I think little changes to the code would make it work on multiple monitors as well.

The bottomFactor, you'll see in my code, is an ugly thing. I didn't know how to get the height of the (MS Windows) taskbar for the first monitor. The second monitor doesn't have a taskbar.

There was this post
http://forums.puremvc.org/index.php?topic=1145.0
about DesktopCitizen and a Window object opening from the main mxml.

That made me think about how would DesktopCitizen remember the position of that Window object. I don't know the answer yet, but I think it's worth finding a solution, since there might be a need for having Windows objects opening together with the WindowedApplication.

Enjoy the Spring,
Ondina
« Last Edit: April 02, 2009, 04:45:43 by Ondina » Logged

~ Ondina ~
Ondina
Sr. Member
****
Posts: 86


View Profile Email
« Reply #18 on: April 02, 2009, 06:34:52 »

I don't know if I was the only one in the world who was wondering where the Mozilla Firefox has gone while trying to launch it – a (long) time ago.
It appeared on the taskbar, but it wouldn't launch.
Anything else ( even IE ) worked fine.

I was sure it was a bug or who knows maybe a virus.
Or maybe MS Windows wouldn't like Firefox anymore.
Lots of stupid scenarios, you know...

It took me a while to realize that I had Firefox on my second monitor the other day, and now the monitor was closed. My Firefox was there!

So I thought, if that would happen to others too while opening an AIR Application managed by the DesktopCitizen, it would be nice to tell the user where the window is, just in case there are multiple monitors available.

So when the application is on the second monitor I send a notification to the ApplicationMediator, that will change the title of the WindowedApplication:
“MyTitle -> Second Monitor”, and that's what the user would see on the taskbar.

In the code from my previous post I would do that:
if( screen.bounds.x > 0 ){
  isOnSecondMonitor = true;
  trace("window is on SECOND monitor");
  sendNotification(SET_APP_TITLE, "Second Monitor");
}
and in the ApplicationMediator
case WindowMediator.SET_APP_TITLE:
   app.title = " ->"+note.getBody() as String;
break;
Logged

~ Ondina ~
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #19 on: April 02, 2009, 07:32:00 »

Maybe shorten that to 'MyApp 2nd Monitor" since taskbar button text gets shortened.

You're right, some apps are smart enough to move themselves to the first monitor to avoid this problem of 'where is my app' and some don't. You have to right click on the taskbar button, select 'Move' and use arrow keys to move it onscreen. I prefer the intelligent behavior of repositioning it if the other monitor isn't there, because clearly if I launched the app and don't have the second monitor, I'll be moving it. Or, as you were, be confused and think somethings wrong.

Also, on the bottomFactor, don't assume the taskbar is on the bottom (or top of the screen.

I have an 'L' shaped desk with my extra monitor in the corner, and laptops on either side. I have a Belkin Flip that let's both laptops share the monitor. The laptop on the left has the taskbar vertically aligned on the left side of its screen, and the extra monitor extends the desktop to. The right.

The right side laptop mirrors this with its taskbar vertically aligned on the right side of Its screen with the extra monitor extending the desktop to the left.

An edge case to be sure, but then I'm an edgy bloke. :)

-=Cliff> 
Logged
Ondina
Sr. Member
****
Posts: 86


View Profile Email
« Reply #20 on: April 02, 2009, 08:36:41 »

some apps are smart enough to move themselves to the first monitor

Those apps might have a way to communicate with the OS ??
Or do you know how to let an AIR app be aware of the absence of the others monitors?

I couldn't find a way of knowing if the other monitor is there by the time the application starts.

I only know that the application “is” on the second monitor, even if it's Nirvana:)

That's why I tried to change the application's title as a warning for the user.

Also, on the bottomFactor, don't assume the taskbar is on the bottom (or top of the screen.

Hmm, you are right!
That might complicate the repositioning on the right and on the left as well, as I did it in my code.

The right side laptop mirrors this with its taskbar vertically aligned on the right side of Its screen with the extra monitor extending the desktop to the left.

Are the extra monitors considered to be the 2nd and 3rd ... monitors, or I should ask where does  DesktopCitizen open  the app the first time (default).

Well well, so many scenarios... why did I start playing around with DesktopCitizen? :)

P.S. Maybe  changing the SystemTrayIcon (adding an item “Back to 1st Screen” or something) would be an acceptable compromise ?
« Last Edit: April 02, 2009, 11:30:24 by Ondina » Logged

~ Ondina ~
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #21 on: April 02, 2009, 04:46:12 »

Is the measured stage size different if the second monitor is off? I was suprised when it was able to cope with the second screen when I wrote it. It appeared that the stage rectangle was simply large enough to encompas them both without knowing that there was another monitor per se. So I'm imagining that when my second monitor is gone, the stage bounds shrink to the size of the first screen. If so it should be as easy as detecting if the window lies within the stage bounds or not.

-=Cliff>
Logged
Ondina
Sr. Member
****
Posts: 86


View Profile Email
« Reply #22 on: April 03, 2009, 03:32:01 »

So I'm imagining that when my second monitor is gone, the stage bounds shrink to the size of the first screen.

That doesn't happen.

Look at my tracings. By the way my second monitor is smaller than the main monitor.

App starts on the first Monitor:

screens.length : 1
window is on FIRST monitor
screen.bounds (x=0, y=0, w=1280, h=1024)
event.afterBounds (x=293, y=192, w=719, h=619)
stage.nativeWindow.bounds (x=293, y=192, w=719, h=619)

I move the window, so it intersects the second monitor:

screens.length : 2
window is on both monitors ( do nothing )
screen.bounds (x=1280, y=0, w=1024, h=768)
event.afterBounds (x=904, y=125, w=719, h=619)
stage.nativeWindow.bounds (x=293, y=192, w=719, h=619)

Now the window is on the second monitor:

screens.length : 1
window is  on SECOND monitor
screen.bounds (x=1280, y=0, w=1024, h=768)
event.afterBounds (x=1465, y=57, w=719, h=619)
stage.nativeWindow.bounds (x=904, y=125, w=719, h=619)

Here the window is minimized:

screens.length : 0
window is minimized

When you just move the App, the stage.nativeWindow.bounds change their x and y values, not the size. Only the screen.bounds reflect the monitor's size.
And only the event.afterBounds rectangle shows the real position of the Application on the screen.

So even if you unplug your 2nd monitor, the above tracings will be the same.
If the App was on the second monitor last time you opened it, it will still be there when you start your App again, even if your second monitor is gone. If you then activate your second monitor, the App is still there (2nd Monitor), waiting for you :)

I don't know what would happen, if the MS Windows settings for the Dual Display changed, meaning that you'd have only one monitor defined in the settings and you tried the above. I don't want to try this on my computer, but I think it would be the same:
you would know that your App is NOT on the main monitor - eventually as in my code that it is on the second monitor, but you wouldn't know if other monitors are there or not.

So until you'll find an “edgy”   ;)  solution, I will just notify the user about the Application being on other monitors through the  App Title and add an item to the SystemTrayIcon, that will let them take the App back on the main monitor.
Logged

~ Ondina ~
Pages: 1 [2]
Print