GWT/GWTP PopupDialog not always centered (due to CSS delayed rendering?)

491 views
Skip to first unread message

Johan Natt och Dag

unread,
Oct 22, 2012, 1:41:48 PM10/22/12
to gwt-pl...@googlegroups.com

Hi, 

I posted this on Stackoverflow, but there does not seem to be anyone with the skills. Very happy if someone could help out.

I am using GWT 2.4, GWTP 0.7 and Chrome 22.0.1229.94 for testing. I have struggled with this issue for days.

I use a default custom Gatekeeper. On startup the gatekeeper forces the presentation of a PopupDialog through RevealRootPopupContentEvent.fire(...). The presenter is based on PresenterWidget using a view that has extended PopupViewImpl. In an overridden onReveal() method in the presenter I center the dialog. I have noticed that the GWTP implementation of PopupViewImpl centers first synchronously and then deferred using scheduleDeferred to circumvent an IE behaviour.

In development mode and running complied on local server everything works as expected: the popup dialog is always rendered and centered correctly. I have also tested this in IE.

However, when deploying to the live web server on the Internet I notice that when I refresh using F5, sometimes the CSS is not applied before the script tries to center the dialog. This results in the measurements being wrong and the dialog is not placed in the center. Interestingly this only seems to happen now and then, typically when the browser is not fast enough in rendering all (CSS) resources before the scheduled deferred command is invoked.

So, I have already tried the following:

  1. Loading CSS using different techniques (inline CSS in the HTML file, referenced css file in HTML file, referenced css file in GWT-module as well as CssResouce). It seems inline CSS in the HTML is always rendered first. Howver, in all the other cases the problem arises.
  2. Center using Scheduler.get().scheduleDeferred as default code also does.
  3. Calling RootLayoutPanel.get().onResize() in onReveal to try to trigger some layout before centering deferred.

I notice the same behaviour in Chrome and IE so I have the feeling that it might not be a browser issue. My question is where to put my "center"-call to ensure that it is called after the all CSS has been properly applied or if there is anything else I can do to force the CSS to render?

Thanks!

Here is the onReveal code in the Presenter extending PresenterWidget:

@Override
protected void onReveal() {
   
super.onReveal();

   
// Hide loading image
    fireEvent
(new HideApplicationLoadingImageEvent());

   
// Reset message
    getView
().setStatusMessage(null);

   
// Center the popup
    getView
().center();
}

Christian Goudreau

unread,
Oct 23, 2012, 10:24:28 AM10/23/12
to gwt-pl...@googlegroups.com
Do you have the link to something that I could see the problem?

--
 
 



--
Christian Goudreau

Brandon Donnelson

unread,
Oct 23, 2012, 12:41:24 PM10/23/12
to gwt-pl...@googlegroups.com
Thanks for the detailed report. I'll see if I can help too. 

Brandon Donnelson

unread,
Oct 23, 2012, 12:42:25 PM10/23/12
to gwt-pl...@googlegroups.com

Brandon Donnelson

unread,
Oct 23, 2012, 12:56:53 PM10/23/12
to gwt-pl...@googlegroups.com
Will need more source to either replicate or investigate it in chrome dev tools. Could you provide your css or ui binder your using? 

I'm curious how your Presenters are setup in relation to. 

Maybe try this to center it:

addToPopupSlot(presenter, true);

Brandon

Johan Natt och Dag

unread,
Oct 24, 2012, 6:06:16 PM10/24/12
to gwt-pl...@googlegroups.com
Christian and Brandon, thanks a lot! I've been away to Copenhagen for two days so my answer is a bit delayed. I'll get back to you later this week with detailed information as requested. 

First: yes, correct reference to Stackoverflow (will update that issue with the final resolution ;-))

Now, just for experiencing the end user situation, try experimenting by visiting and refreshing ("F5") the following "site": http://www.festivitas.se/f/. I'll get back to you with the source, but, here, some of it is explained:
1. I've overloaded the center() method, replicated it and added a Window.alert("Deferred centering") in the "deferred event" for testing purpose.
1. I've removed 99% of the CSS for testing so it might look ugly. Disregard that. The "9x9" images and the popup dialog background are removed. In the base html file there's internal CSS in a <style> clause, specifying the background image and a "loading image".
2. The "loading image" is, interestingly  always correctly removed. It is removed by firing an event in the onReveal() method before the "center the popup dialog" is called.  (I'll get back to you with the exact source code).
3. In the CssResource there is a background = "blue", overriding the background image in step 1.

Now, if you see what I see (occasionally) when pressing F5 (use "Esc" to dismiss the dialog for "faster" testing) you will notice that:
a) the background is not always switched from image to plain dark blue before the "alert" dialog appears. However, the loading image always disappears.
b) the (basic GWT-styled) button "Logga in" is, sometimes (synchronized with a), not styled at all when the "alert" dialog appears. The styling is GWT basic styling from the module's inherited "Clean" theme.
c) a few images (the "flags") are not shown (which affect the size of the dialog and thus the centering)

As said, I'll get back to you with the "relevant" parts of the source code you ask for.

Thanks for your help!

/Johan

Johan Natt och Dag

unread,
Oct 27, 2012, 11:17:23 AM10/27/12
to gwt-pl...@googlegroups.com

Hi again,

Here is some code and explanation of how my application is designed.

The default place is defined in the gin module (extending AbstractPresenterModule):

    bindConstant().annotatedWith(DefaultPlace.class).to(NameTokens.newsPage);

A default gate keeper is defined in the ginjector

    @DefaultGatekeeper
    FestivitasPortalGatekeeper getFestivitasPortalGatekeeper();

Then, the place manager:

public class FPlaceManager extends PlaceManagerImpl {
    private final PlaceRequest defaultPlaceRequest;
    private final LoginPopupPresenter loginPopupPresenter;

    @Inject
    public FPlaceManager(
            final EventBus eventBus,
            final TokenFormatter tokenFormatter,
            LoginPopupPresenter loginPopupPresenter,
            @DefaultPlace String defaultNameToken,
            final LoggerPopupPresenter loggerPopupPresenter) {
        super(eventBus, tokenFormatter);

        this.defaultPlaceRequest = new PlaceRequest(defaultNameToken);
        this.loginPopupPresenter = loginPopupPresenter;
        eventBus.addHandler(ShowPortalEvent.TYPE, new ShowPortalEvent.ShowPortalHandler() {

            @Override
            public void onShowPortal(ShowPortalEvent event) {
                // Reveal the default place
                revealDefaultPlace();
                // Allow animations
                AnimationsEnabledEvent.fire(FPlaceManager.this, true);
            }
        });

        /**
         * Take proper action when application loading image shall be removed.
         */
        eventBus.addHandler(HideApplicationLoadingImageEvent.TYPE, new HideApplicationLoadingImageHandler() {

            @Override
            public void onHideApplicationLoadingImage(
                    HideApplicationLoadingImageEvent event) {
                Element loadingElement = DOM.getElementById("applicationLoadingImage");
                if (loadingElement != null)
                    DOM.removeChild(RootPanel.getBodyElement(), DOM.getElementById("applicationLoadingImage"));
            }
        });
    }

    @Override
    public void revealDefaultPlace() {
        // Reveal the default presenter.
        // The actual default is defined in {@link FModule} using a NameToken.

        // Pass false as second parameter to prevent another token to be
        // inserted into the browser history.
        // TODO: Show the place the user prefers, i.e. place when logged out or a custom start page.
        revealPlace( defaultPlaceRequest, false);

    }

    @Override
    public void revealUnauthorizedPlace(String unauthorizedHistoryToken) {
        // If not authorized, show login dialog
        RevealRootPopupContentEvent.fire(this, loginPopupPresenter);
    }
}

The LoginPopupPresenter extends PresenterWidget and has an overridden onBind (with super.onBind() and then registration of some click handlers) and the overridden onReveal (code as in original post).

In the LoginPopupView I have, for testing purposes, overridden the center() method as such:

@Override
public void center() {
    // TODO Auto-generated method stub
    super.center();

    // We center again in a deferred command to solve a bug in IE where newly
    // created window are sometimes not centered.
    Scheduler.get().scheduleDeferred(new Command() {
      @Override
      public void execute() {
        Window.alert("Deferred centering");
        asPopupPanel().center();
        // 
      }
    });
}

So, the presenter that is to be displayed when first visiting the site is the loginPopupPresenter (due to the gate keeper), which, certainly, it is. However, the CSS is not always completely rendered before the onReveal() code is fired. And the question is how this can be?

Is there any more code needed?

Message has been deleted
Message has been deleted
Message has been deleted

Johan Natt och Dag

unread,
Oct 27, 2012, 6:08:46 PM10/27/12
to gwt-pl...@googlegroups.com
Twice has my follow-up message been deleted from the thread. Quite annoying. Probably because I try to attached the code. Here is the text. Please let me know how I can share the code in the message thread without Google deleting the message automatically without notice.

I have been able to reproduce the problem. Attached is a stripped down project.

I have deployed it to http://www.festivitas.se/gwtptest/GWTPTest.html. Visit the site and repeat hitting Esc->F5 until the border around the "Log in" button is not drawn before the Chrome popup dialog appears.

It demonstrates that the CSS is sometime not rendered before the onReveal() code is executed.

Johan Natt och Dag

unread,
Oct 27, 2012, 6:10:10 PM10/27/12
to gwt-pl...@googlegroups.com
Testing attaching code again. This time I deleted the whole war folder.
GWTPTest.zip

Christian Goudreau

unread,
Oct 30, 2012, 1:31:38 PM10/30/12
to gwt-pl...@googlegroups.com
I don't know why it's beging deleted, in any case, I just approved them all.

On Sat, Oct 27, 2012 at 12:20 PM, Johan Natt och Dag <johan.na...@gmail.com> wrote:
I have been able to replicate the problem in a stripped down project. The source code is attached.

I have deployed it to my server. Visit http://www.festivitas.se/gwtptest/GWTPTest.html and keep pressing Esc->F5 until you notice that the border around the "Log in" button is not visible behind the Chrome popup dialog.

This demonstrates that sometimes the CSS is not completely rendered before the onReveal() code is reached.

--
 
 



--
Christian Goudreau

Johan Natt och Dag

unread,
Oct 30, 2012, 1:53:59 PM10/30/12
to gwt-pl...@googlegroups.com

Thanks, but I succeeded after deleting the war folder so I am quite sure it is beacuse there where javascript files in the war folder. Smart filtering ;-).

--
 
 

Christian Goudreau

unread,
Oct 30, 2012, 2:14:29 PM10/30/12
to gwt-pl...@googlegroups.com
Ha ha, glad to hear! That kind of problems are the awful one, you don't find any problems until you do something like trying to reimport everything from scratch which is often the last thing we do... after several days of debugging.

Johan Natt och Dag

unread,
Oct 30, 2012, 2:36:25 PM10/30/12
to gwt-pl...@googlegroups.com

Hm, it seems we now discuss different things ;o)... I was talking about the failed attempt to uploading code to the thread. I succeeded uploading after deleting the war folder containing JavaScript code. The original problem that is the subject of the thread unfortunately still exists as demonstrated in the uploaded code and the instructions in the post to which I first tried to attach the code.

--
 
 

Brandon Donnelson

unread,
Oct 31, 2012, 1:40:27 PM10/31/12
to gwt-pl...@googlegroups.com
I'm going to look at the issue and see if I can help resolve it too ;)

Brandon Donnelson

unread,
Oct 31, 2012, 1:46:50 PM10/31/12
to gwt-pl...@googlegroups.com
Hmmm... I see each time the dialog displays before the border is drawn. Looking into it. 

Brandon Donnelson

unread,
Oct 31, 2012, 1:53:59 PM10/31/12
to gwt-pl...@googlegroups.com
Is there a reason why your using gwtp .6? 

Brandon Donnelson

unread,
Oct 31, 2012, 3:02:23 PM10/31/12
to gwt-pl...@googlegroups.com
I see the GWTP eclipse plugin has a few libs that could be updated and I'll do that too soon.

Brandon Donnelson

unread,
Oct 31, 2012, 3:15:37 PM10/31/12
to gwt-pl...@googlegroups.com
I replicated it, now to start digging. :)

Message has been deleted

Johan Natt och Dag

unread,
Oct 31, 2012, 4:44:55 PM10/31/12
to gwt-pl...@googlegroups.com
Thanks for looking into it! 

Correct. I had no reason using 0.6. In my actual project I am using 0.7 When creating the stripped down project I used the the GWTP eclipse plugin which generates a project with 0.6. 

I experience the same behaviour with 0.6 and 0.7.

Brandon Donnelson

unread,
Oct 31, 2012, 5:06:43 PM10/31/12
to gwt-pl...@googlegroups.com
Thats what I was wondering. I noticed the same behavior in .6 and .7. I'm looking at the popup methods now. :)

Johan Natt och Dag

unread,
Oct 31, 2012, 5:17:39 PM10/31/12
to gwt-pl...@googlegroups.com
Great. I also migrated the test project. 
Attached.
GWTPTest_GWTP0.7.zip

Johan Natt och Dag

unread,
Oct 31, 2012, 5:18:27 PM10/31/12
to gwt-pl...@googlegroups.com
Great. I also migrated the test project. 
Attached.

On Wednesday, 31 October 2012 20:15:37 UTC+1, Brandon Donnelson wrote:
GWTPTest_GWTP0.7.zip

Brandon Donnelson

unread,
Oct 31, 2012, 7:13:23 PM10/31/12
to gwt-pl...@googlegroups.com
I've investigated all the playing parts. So far the PopupPanelmpl.doCenter() second call is suspect, and maybe before that is called it could check to see if the panel is already in the center. Although this looks like its the only logic that we are doing differently than would would normally happen with a popup panel displaying with the gwt toolkit. I've noticed a few other issues with the popup panel in gwt issues, but I don't see anything related. I've run out of time today to change the center() method code. The other option is to do is add a new root panel event with absolute positioning and/or maybe some other feature logic that would give more controls higher up. 

Brandon 

Johan Natt och Dag

unread,
Nov 6, 2012, 3:53:49 PM11/6/12
to gwt-pl...@googlegroups.com
Hi Brandon,

Thanks a lot for analysing this. Unfortunately, I am not sure I understand how this would have an effect on the CSS rendering before the centering occurs. I think the main problem is that the popup is visible without any CSS applied (and that there is some code running depending on the CSS being rendered). Perhaps this is a GWT problem, rather than a GWTP problem, but I am unable to analyse this fully because I do not use GWTP to understand the inner workings of GWTP ;-).

I tried the following (with respect to the test project):
  1. Removed the Window.alert() from the deferred command's execute method
  2. Added a Window.alert() after RevealRootPopupContentEvent.fire(this, loginPopupPresenter) in ClientPlaceManager.revealUnauthorizedPlace(..).
In this case the popup is always shown before the alert. Thus, the event is dispatched and the popup is shown before the alert. However, the CSS is not always rendered. Sometimes no CSS is rendered at all (there is just a text in the center saying "Log in"), sometimes only basic Chrome CSS is rendered. Of course, in many cases the full GWT CSS is rendered.

So, the widget is displayed without CSS and there is code running while this is happening. Therefore I start wondering if there is any way to check if CSS has been rendered? Somehow, the CSS should be processed before the widget is displayed so that there is also no "flickering" of CSS, i.e., first comes an unstyled widget and then comes the styled widget. Is this possible to do or is this an underlying problem with the browsers? If it is, how to circumvent it? Is the second option something like that - could you elaborate that suggestion?

Thanks!

/Johan

Brandon Donnelson

unread,
Nov 6, 2012, 5:10:57 PM11/6/12
to gwt-pl...@googlegroups.com
You have some great points. While I see what's happening, I haven't figured out the solution to the issue yet. I think we could process the popup differently in GWTP possibly so css is not rendered after the onReveal. I like your ideas above. One idea I had might be to attachment to dom earlier or possibly check computed style, if everything is finished before on reveal. One of my thoughts on work around is give more control of the popup, so maybe the centering could be delayed for a split second, not ideal, but could possibly help with custom things that popup. I'd like to drill it more and discover some other possibilities and even the solution.

This week, I'm working on the build system of GWTP from transferring it to github, which I'm nearly finished and over the hump. I also took care of another nagging issue with the gwtp eclipse plugin falling behind. Once I get over the github transfer hump some time this week, I'll take another crack at this. I know we can get this to work as expected :)

Have a good day,
Brandon Donnelson


--
 
 

Christian Goudreau

unread,
Nov 6, 2012, 5:13:34 PM11/6/12
to gwt-pl...@googlegroups.com
Could it be linked to the fact that GWTP will reveal the first presenter, than it's parents until the root is attached to the dom? Meaning that the first time it's revealed, you could end up in a race condition.

but well, using onReveal should make sure that everything is attached to the dom before hand, so maybe I'm just thinking out loud for nothing.

--
 
 



--
Christian Goudreau

Brandon Donnelson

unread,
Nov 7, 2012, 12:58:20 PM11/7/12
to gwt-pl...@googlegroups.com
I've been wondering about the timing of the popup getting attached to the dom which is done just before centering. I think typically popups are attached to the dom, and then when needed they are centered and set visible, but I could be wrong. But since on reveal also attaches then center happens might cause the issue with timing. There is also a deferred center happening just after the first center, which cause the recenter if the css shows up a split second later the popup jumps. I wonder about the timing of the css after the dom attachment and wonder if I could use onAttach before centering. 

I didn't notice a racing happening. I think its a timing issue of attachment and rendering the popup. It may have more to do with the gwt implementation of the popup than we have to do. But I think we could control the way it pops up, maybe by delaying center after attaching to the dom. But I'm not sure yet. 

Brandon

Brandon Donnelson

unread,
Nov 7, 2012, 1:00:22 PM11/7/12
to gwt-pl...@googlegroups.com
I suppose what I just said could be stated as a race condition :)

Johan Natt och Dag

unread,
Jul 2, 2015, 2:04:38 PM7/2/15
to gwt-pl...@googlegroups.com, brandon....@arcbees.com
Time flies... ;-)
I cannot recreate the problem anymore - not even with the exact same source code. I guess the problem was not in GWTP at all as suggested byyou Brandon.
Nevertheless, I post this reply used to show everyone else that this is not a problem any more.

Christian Goudreau

unread,
Jul 2, 2015, 3:27:09 PM7/2/15
to gwt-pl...@googlegroups.com
Thanks Johan! Times fly indeed! On top of that, I think that the mechanism has completely changed since the time you had that problem :D

Christian Goudreau | CEO - PDG

--
You received this message because you are subscribed to the Google Groups "GWTP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gwt-platform...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Richard Wallis

unread,
Jul 2, 2015, 3:34:29 PM7/2/15
to gwt-pl...@googlegroups.com, brandon....@arcbees.com
The Popup positioning race condition was fixed in GWTP 1.4.

There's a new positioning mechanism which works by passing a PopupPositioner (which provides the left and top offsets) to the view.

Reply all
Reply to author
Forward
0 new messages