21 Replies Latest reply on Aug 9, 2011 10:56 AM by Flex harUI

    Popup / Dialog positioning for a subapplication

    Green Goby

      We are loading sub applications into our parent application using separate ApplicationDomains but using the same Security Domain.

       

      When we use an Alert, the alert is centered on the sub application, not the parent application.  Is there any way to get a Popup to center on the parent application instead?

       

      We have a widgets style dashboard and some of the widgets are really small.  So, when they do a popup, it is often off the edge of the screen.

       

      We copied this code from Alert.as to put in our dialog class, as it seemed like it was on the right track, but it always seems to go into the "else"

       

              if (!this._parentSprite)

              {

                      //Below for Flex 4 - also taken from Alert.as.            

                  var sm:ISystemManager = ISystemManager(FlexGlobals.topLevelApplication.systemManager);

          // no types so no dependencies

          var mp:Object = sm.getImplementation("mx.managers.IMarshallPlanSystemManager");

          if (mp && mp.useSWFBridge()) {

                      this._parentSprite = Sprite(sm.getSandboxRoot());

                      }

                  else {

                      this._parentSprite = Sprite(FlexGlobals.topLevelApplication);

                      }

              }

      We just want a way to use the parent application as the centering.  Thanks in advance for any help.
      Irv

        • 1. Re: Popup / Dialog positioning for a subapplication
          Flex harUI Adobe Employee

          Did you use -includes=mx.managers.systemClasses.MarshallingSupport for both

          apps?  And SWFLoader with loadForCompatibility to load the sub app?

          • 2. Re: Popup / Dialog positioning for a subapplication
            Green Goby Level 1

            Yes, we have MarshallingSupport in both apps.  As I mentioned, we are using separate ApplicationDomains but the same SecurityDomain.  Using separate ApplicationDomains is the equivalent of loadForCompatibility.  So, we are a multi-versioned application, but not a Sandboxed application.  I see the bridge request come across, and it dims the whole screen over the parent application, but calling centerPopup does not center it over the whole application, just over the subapplication.

             

            According to the documentation, we are seeing everything listed there except the second one, that I have highlighted.  That is not working.  In looking at the code in PopUpManagerImpl, I don't see how that second item would actually work:

             

            Pop-up controls in multi-versioned applications

            When a sub-application launches a pop-up control, it floats over the entire application, and can be dragged anywhere on the stage. Pop-up controls are created in the sub-application’s application domain and passed to the main application's PopUpManager. Pop-up controls cannot be strongly-typed as IUIComponent, so they are marshaled from the sub-application to the main application for display.

            Pop-up windows behave as follows in a multi-versioned sub-application (these behaviors are the same for single-versioned sub-applications):

            • Launching a modal dialog box dims the entire application, not just the sub-application that launched it

            • Centering a pop-up centers it over the entire application, not just the sub-application

            • Dragging pop-up controls works over the entire application, not just the sub-application

            • Focus shifts to the pop-up when you first launch a pop-up from the sub-application

               

            • 3. Re: Popup / Dialog positioning for a subapplication
              Flex harUI Adobe Employee

              LoadForCompatibility has subtle differences than using a separate AppDom in

              some cases, so I would recommend using it instead of custom LoaderContexts.

              Also note that there is lots of glue in SWFLoader, so make sure you are

              using it and not the lower level flash.display.Loader.

               

              It might be that the parent app needs to have the shared managers like

              PopUpManager force-linked in.

              http://help.adobe.com/en_US/flex/using/WS2db454920e96a9e51e63e3d11c0bf69084-

              7f0c.html

               

              What are you passing into PopUpManager?  See if Alert centers and examine

              what it does.

              • 4. Re: Popup / Dialog positioning for a subapplication
                Green Goby Level 1

                Can you detail out what subtle differences you are referring to, as we have not witnessed anything different nor have seen anything in the documentation.  I will try using loadForCompatibility, but when I looked at the sources, it just seemed to be setting a new ApplicationDomain so we did that directly.

                 

                Alert behaves the same way our code is behaving.  As I mentioned before, it is behaving exactly as the multi-versioned application is supposed to behave EXCEPT the centering.  All of our other code behaves exactly as a multi-versioned app would behave. 

                 

                Yes, we are very familiar with the page you sent, that is part of the page I put in my text.  Yes, we are using SWFLoader.

                 

                This is a very large application over 15 developers have built over the past 1.5 years.  It has 14 different sub applications in it loaded and unloaded at various times. They are on different versions of the flex SDK, all is working fine except this centering behavior. 

                 

                I am stepping through the code in PopupManagerImpl and I am not seeing how this would center, but I'll keep digging.  As we have in the past, hopefully we can find out where it is going wrong in the PopupManagerImpl and I'll have more details tomorrow.

                 

                The parent container it has listed in the PopupManagerImpl after the bridge events is coming from the parent container, so I think it is setup properly.

                • 5. Re: Popup / Dialog positioning for a subapplication
                  Green Goby Level 1

                  When you use the PopUpManager, you can't pass in null for the parent, so the subapplication must pass in something.  I have tried passing in the parent application, but that throws all sorts of errors in the parent application.  So, the "highest" component I have found I can use is the subapplication itself.

                   

                  This is where the problem comes in.

                   

                  Looking at these lines in PopUpManagerIml, starting on line 557:

                   

                   

                                                   // The appWidth may smaller than parentWidth if the application is

                                  // clipped by the parent application.

                                  x = Math.max(0, (Math.min(appWidth, parentWidth) - popUp.width) / 2);

                                  y = Math.max(0, (Math.min(appHeight, parentHeight) - popUp.height) / 2);


                                  pt = new Point(clippingOffset.x, clippingOffset.y);

                                  pt = popUpParent.localToGlobal(pt);

                                  pt = popUp.parent.globalToLocal(pt);

                                  popUp.move(Math.round(x) + pt.x, Math.round(y) + pt.y);

                   

                   

                  The problem starts with those Math.mins in there.  In a subapplication situation, the parentWidth will always be less than the appWidth, meaning the parent width will always be used to set the offset.  In a normal application, this is fine, as you can set the parent to the main applicaiton.  However, in a multi-versioned app, you can't seem to set it to anything in the outer app (as far as I can tell)  Then, that clippingOffset is always set relative to the parent.  So, the parent that is passed in is very importan.  So, if you want to center the popup on the parent application, and not the subapplication, I have not found a way to do that.
                  Just to prove this out, I took out the parentWidth, parentHeight and the offset, and it worked perfectly.   So, we could set our own PopUpManagerImpl in our subapplications, but we don't really want to do that.
                  So, back to my original question, is there anything else I can pass in for the parent of the popup from with the subapplication to make this actually center on the outer application?  Given the code as it is (in 4.1 at least), I am not seeing how we can do this....
                  • 6. Re: Popup / Dialog positioning for a subapplication
                    Flex harUI Adobe Employee

                    The code in Alert is using systemManager.getSandboxRoot().  Give that a try.

                    • 7. Re: Popup / Dialog positioning for a subapplication
                      Flex harUI Adobe Employee

                      The most important is that if you use the same SWFLoader to load another

                      app, you have to use a brand new LoaderContext otherwise things may not work

                      correctly.

                       

                      Alert should be using sandboxRoot if you have linked MarshallingSupport into

                      the apps.

                      • 8. Re: Popup / Dialog positioning for a subapplication
                        Green Goby Level 1

                        As I mentioned earlier, we are using the same code (copied) that is in Alert, and Alert doesn't work right either.

                         

                        We are not sharing SWFLoaders or LoaderContexts.  Brand new one each time.

                         

                        I'll write up a small program to demonstrate this behavior and post that later.

                        • 9. Re: Popup / Dialog positioning for a subapplication
                          Green Goby Level 1

                          Also, when using getSandboxRoot(), we get the following error:

                           

                          stack trace=TypeError: Error #1009: Cannot access a property or method of a null object reference.

                          [trace] at mx.accessibility::AccImpl$/http://www.adobe.com/2006/flex/mx/internal::getDefinition()[E:\dev\4.x\frameworks\projects \framework\src\mx\accessibility\AccImpl.as:248]

                          [trace] at mx.accessibility::UIComponentAccProps()[E:\dev\4.x\frameworks\projects\framework\src\mx\a ccessibility\UIComponentAccProps.as:120]

                          [trace] at mx.accessibility::UIComponentAccProps$/http://www.adobe.com/2006/flex/mx/internal::createAccessibilityImplementation()[E:\dev\4.x \frameworks\projects\framework\src\mx\accessibility\UIComponentAccProps.as:76]

                          [trace] at mx.core::UIComponent/initializeAccessibility()[E:\dev\4.x\frameworks\projects\framework\s rc\mx\core\UIComponent.as:7400]

                          [trace] at mx.core::UIComponent/initialize()[E:\dev\4.x\frameworks\projects\framework\src\mx\core\UI Component.as:7355]

                          [trace] at mx.core::Container/initialize()[E:\dev\4.x\frameworks\projects\framework\src\mx\core\Cont ainer.as:3129]

                          [trace] at mx.managers.systemClasses::ChildManager/childAdded()[E:\dev\4.x\frameworks\projects\frame work\src\mx\managers\systemClasses\ChildManager.as:189]

                          [trace] at mx.managers::SystemManager/http://www.adobe.com/2006/flex/mx/internal::rawChildren_addChildAt()[E:\dev\4.x\frameworks \projects\framework\src\mx\managers\SystemManager.as:1963]

                          [trace] at mx.managers::SystemManager/addChildAt()[E:\dev\4.x\frameworks\projects\framework\src\mx\m anagers\SystemManager.as:1595]

                          [trace] at mx.managers::SystemManager/addChild()[E:\dev\4.x\frameworks\projects\framework\src\mx\man agers\SystemManager.as:1578]

                          [trace] at mx.managers::PopUpManagerImpl/addPopUp()[C:\view\isalisbu_olr_ss2\png\apps\olr\ui\src\mai n\flex\mx\managers\PopUpManagerImpl.as:346]

                          [trace] at mx.managers::PopUpManager$/addPopUp()[E:\dev\4.x\frameworks\projects\framework\src\mx\man agers\PopUpManager.as:193]

                          [trace] at com.paychex.framework.controls::Dialog/show()[C:\view\isalisbu_olr_ss2\png\apps\olr\ui\sr c\main\flex\com\paychex\framework\controls\Dialog.as:75]

                          [trace] at com.paychex.framework.containers::ActionAreaDialog/show()[N:\Hudson\workspace\PNG_UIFrame work_v03_RC\hapnv022_PNG_UIFramework_v03_RC\soa_suite\png\framework\flex\ui-component\src\ com\paychex\framework\containers\ActionAreaDialog.as:61]

                          [trace] at Function/<anonymous>()[N:\Hudson\workspace\PNG_UIFramework_v03_RC\hapnv022_PNG_UIFramewor k_v03_RC\soa_suite\png\framework\flex\ui-bulb\src\com\paychex\framework\bulbs\DialogContro llerBulb.as:297]

                          [trace] at Function/http://adobe.com/AS3/2006/builtin::call()

                          [trace] at Function/<anonymous>()[N:\Hudson\workspace\PNG_UIFramework_v03_RC\hapnv022_PNG_UIFramewor k_v03_RC\soa_suite\png\framework\flex\ui-bulb\src\com\paychex\framework\bulbcore\DynamicBu lbHelper.as:61]

                          [trace] at Function/http://adobe.com/AS3/2006/builtin::call()

                          [trace] at Function/<anonymous>()[N:\Hudson\workspace\PNG_UIFramework_v03_RC\hapnv022_PNG_UIFramewor k_v03_RC\soa_suite\png\framework\flex\ui-bulb\src\com\paychex\framework\bulbcore\Juicer.as :975]

                          [trace] at Function/http://adobe.com/AS3/2006/builtin::call()

                          [trace] at WiringHelper/wiringLoadSuccess()[N:\Hudson\workspace\PNG_UIFramework_v03_RC\hapnv022_PNG_ UIFramework_v03_RC\soa_suite\png\framework\flex\ui-bulb\src\com\paychex\framework\bulbcore \WiringHelper.as:42]

                          [trace] at Function/http://adobe.com/AS3/2006/builtin::apply()

                          [trace] at com.paychex.framework.util::DelayedInvoker/timerHandler()[N:\Hudson\workspace\PNG_UIFrame work_v03_RC\hapnv022_PNG_UIFramework_v03_RC\soa_suite\png\framework\flex\ui-core\src\com\p aychex\framework\util\DelayedInvoker.as:46]

                          [trace] at flash.utils::Timer/_timerDispatch()

                          [trace]

                           

                          In watching the code from alert, it never gets into the code that uses getSandboxRoot.  We are using the same security domain (trusted code) so we are not a sandboxed app, we are a mutli-versioned app (load for compatiblity / different application domain)

                           

                          I'll work on a snippet of code that is easier to discuss that demonstrates the problem.

                          • 10. Re: Popup / Dialog positioning for a subapplication
                            Flex harUI Adobe Employee

                            Hmm.  There might have been an issue with accessibility in 4.1.  Try turning

                            it off.  It is probably best if you can post a simple test case.

                            • 11. Re: Popup / Dialog positioning for a subapplication
                              Green Goby Level 1

                              I haven't tried the accessibility stuff yet, but here is a simple example that demonstrates the problem.  The outer app loads an inner app to the right.  The inner app has a button that launches an Alert box.  The Alert box is positioned over the right inner app, but can be moved over the whole app.  So, it all behaves as a multi versioned app, except the center doesn't center over the outer app.

                               

                              Inner app:

                               

                               

                              <?xml version="1.0"?>

                              <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" width="100%" height="100%">

                                <fx:Script><![CDATA[

                                  import mx.controls.Alert;

                                  import mx.managers.systemClasses.MarshallingSupport; MarshallingSupport;

                                  ]]></fx:Script>

                                <s:Button click="Alert.show('Hello, world')" label="Say Hello"/>

                              </s:Application>

                               

                              Outer app:
                              <?xml version="1.0"?>
                              <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" width="800" height="600">
                                <fx:Script><![CDATA[
                                  import mx.controls.SWFLoader;
                                  import mx.managers.systemClasses.MarshallingSupport; MarshallingSupport;

                                  function showSubApp() : void {
                                    var loader:SWFLoader = new SWFLoader();
                                    loader.loadForCompatibility = true;
                                    loader.trustContent = true;
                                    loader.percentHeight = 50;
                                    loader.percentWidth = 50;
                                    mainPanel.addElement( loader );
                                    loader.load( "../Inner/Inner.swf" );
                                  }
                                  ]]></fx:Script>
                                <s:Group id="mainPanel" width="100%" height="100%">
                                  <s:layout>
                                    <s:HorizontalLayout/>
                                  </s:layout>
                                  <s:Group width="50%" height="50%">
                                    <s:Button click="showSubApp()" label="Load Sub App"/>
                                  </s:Group>
                                </s:Group>
                              </s:Application>
                              • 12. Re: Popup / Dialog positioning for a subapplication
                                Green Goby Level 1

                                If I turn off accessibility, and I use getSandboxRoot as the parent, it works with 4.1  This is good news. 

                                 

                                The bad news is that this code is in our framework and has to work both in subapps and in regular apps.  So, the code from Alert that we copied:

                                 

                                                var sm:ISystemManager = ISystemManager(FlexGlobals.topLevelApplication.systemManager);

                                                // no types so no dependencies

                                                var mp:Object = sm.getImplementation("mx.managers.IMarshallPlanSystemManager");

                                                // this._parentSprite = Sprite(sm.getSandboxRoot());

                                                if (mp && mp.useSWFBridge()) {

                                                    this._parentSprite = Sprite(sm.getSandboxRoot());

                                                }

                                                else {

                                                    this._parentSprite = Sprite(FlexGlobals.topLevelApplication);

                                                }

                                does not work, as it does not get into the "if" block.  If I force it to use the sandbox root, it works perfectly.
                                So, being that this code doesn't work that we copied from Alert, is there a better way to write this if block?
                                Also, I am not sure we'll be able to turn off accessibility, but it is at least a start.

                                • 13. Re: Popup / Dialog positioning for a subapplication
                                  Flex harUI Adobe Employee

                                  I'm not quite sure of your configurations, but are there situation where passing getSandboxRoot() would not work?

                                   

                                  Alex Harui

                                  Flex SDK Developer

                                  Adobe Systems Inc.

                                  Blog: http://blogs.adobe.com/aharui

                                  • 14. Re: Popup / Dialog positioning for a subapplication
                                    Green Goby Level 1

                                    I was wondering the same thing, and it looks like getSandboxRoot() will always work for us, so I think we'll be good to go there, assuming we can turn off accessibility.  Do you happen to know if the accessibility bug is fixed in 4.5?  I can't easily test in our environment right now.

                                     

                                    Do you know why Alert didn't just use that?

                                    • 15. Re: Popup / Dialog positioning for a subapplication
                                      Flex harUI Adobe Employee

                                      I tried your test case.  You are getting tripped up by this bug

                                      https://bugs.adobe.com/jira/browse/SDK-30598

                                       

                                      I added the following workaround to the inner app

                                       

                                      private function registerMPFix():void

                                      {

                                      systemManager.registerImplementation("mx.managers.IMarshallPlanSystemManage

                                      r",

                                                        

                                      systemManager.getImplementation("mx.managers::IMarshalSystemManager"));

                                      }

                                       

                                      Which is called from creationComplete.  Then the alert centers.

                                       

                                       

                                      I am not getting accessibilty errors in my 4.1 build, and the line numbers

                                      you reported are not matching up.  Are you on a pre-release build?  What is

                                      the build numbers after the 4.1.

                                       

                                      Your example did not force link PopUpManager into the main app which is

                                      required.

                                      1 person found this helpful
                                      • 16. Re: Popup / Dialog positioning for a subapplication
                                        Green Goby Level 1

                                        That does seem like that bug is affecting that code.  We are always using getSandBoxRoot() now (no if statement) so I think we are good there. 

                                         

                                        We do have PopupManager coming in to the outer app in our real app.  That was an oversight on the example code, sorry.

                                         

                                        My flex 4.1 is:

                                         

                                        <?xml version="1.0"?>

                                        <flex-sdk-description>

                                        <name>Flex 4.1</name>

                                        <version>4.1.0</version>

                                        <build>16076</build>

                                        </flex-sdk-description>

                                         

                                        When I turned off accessibility, it worked, so if there is another workaround that would be great.  We are not willing to turn off accessibility for our app at this time, so we cannot fix this bug in our application.
                                        Thanks for your help.

                                        • 17. Re: Popup / Dialog positioning for a subapplication
                                          Flex harUI Adobe Employee

                                          What platform and version of player or AIR?  Do you have a screen reader

                                          installed?

                                          • 18. Re: Popup / Dialog positioning for a subapplication
                                            Green Goby Level 1

                                            We are not using air, but the flash player we are testing with is WIN 10,3,181,14, Debug Player

                                             

                                            I do not have a screen reader installed.

                                            • 19. Re: Popup / Dialog positioning for a subapplication
                                              Flex harUI Adobe Employee

                                              I haven't had a chance to try this on Windows yet.  If I haven't posted an

                                              update my Monday night, post a reminder.

                                              • 20. Re: Popup / Dialog positioning for a subapplication
                                                Flex harUI Adobe Employee

                                                OK, I get the error on Windows.  I will try to find time to find a

                                                workaround.  It isn't fixed in 4.5 as far as I can tell.

                                                • 21. Re: Popup / Dialog positioning for a subapplication
                                                  Flex harUI Adobe Employee

                                                  The workaround is to assign the modulefactory of the popup.

                                                   

                                                          private function popIt():void

                                                          {

                                                              var pop:MyPopUp = new MyPopUp();

                                                              pop.moduleFactory = this.moduleFactory;

                                                              PopUpManager.addPopUp(pop, systemManager.getSandboxRoot());

                                                              PopUpManager.centerPopUp(pop);

                                                          }