Hey Rajeev :) Would you take a look at this patch, implementing Joel's suggestion for keeping DialogBox on the screen?
Instead of trying to decide whether a PopupPanel is being positioned off the edge, we check whether the user is dragging it off the screen, and ignore the drag if the pointer has left the visible window area. We use a WindowResizeListener to make sure we always know how wide the window is. Also, in the PopupPanel class, we remove the check that prevents placing a popup offscreen -- if a developer wants to programmatically put it off screen, that's OK. Seems to work right in RTL and LTR modes on all major browsers. Thanks! -- Alex Rudnick swe, gwt, atl --~--~---------~--~----~------------~-------~--~----~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~----------~----~----~----~------~----~------~--~---
Index: user/src/com/google/gwt/user/client/ui/DialogBox.java =================================================================== --- user/src/com/google/gwt/user/client/ui/DialogBox.java (revision 3717) +++ user/src/com/google/gwt/user/client/ui/DialogBox.java (working copy) @@ -15,9 +15,12 @@ */ package com.google.gwt.user.client.ui; +import com.google.gwt.dom.client.Document; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Event; +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.WindowResizeListener; /** * A form of popup that has a caption area at the top and can be dragged by the @@ -69,6 +72,10 @@ private boolean dragging; private int dragStartX, dragStartY; private MouseListenerCollection mouseListeners = new MouseListenerCollection(); + private WindowResizeListener resizeListener; + private int windowWidth; + private int clientLeft; + private int clientTop; /** * Creates an empty dialog box. It should not be shown until its child widget @@ -114,6 +121,10 @@ // Set the style name setStyleName(DEFAULT_STYLENAME); sinkEvents(Event.MOUSEEVENTS); + + windowWidth = Window.getClientWidth(); + clientLeft = Document.get().getBodyOffsetLeft(); + clientTop = Document.get().getBodyOffsetTop(); } public String getHTML() { @@ -125,6 +136,12 @@ } @Override + public void hide() { + Window.removeWindowResizeListener(resizeListener); + super.hide(); + } + + @Override public void onBrowserEvent(Event event) { super.onBrowserEvent(event); @@ -178,6 +195,14 @@ if (dragging) { int absX = x + getAbsoluteLeft(); int absY = y + getAbsoluteTop(); + + // if the mouse is off the sceen to the left, right, or top, don't + // move the dialog box. This would let users lose dialog boxes, which + // would be bad for modal popups. + if (absX < clientLeft || absX >= windowWidth || absY < clientTop) { + return; + } + setPopupPosition(absX - dragStartX, absY - dragStartY); } } @@ -212,6 +237,20 @@ } @Override + public void show() { + if (resizeListener == null) { + resizeListener = new WindowResizeListener() { + @Override + public void onWindowResized(int width, int height) { + windowWidth = width; + } + }; + } + Window.addWindowResizeListener(resizeListener); + super.show(); + } + + @Override protected void doAttachChildren() { super.doAttachChildren(); Index: user/src/com/google/gwt/user/client/ui/PopupPanel.java =================================================================== --- user/src/com/google/gwt/user/client/ui/PopupPanel.java (revision 3717) +++ user/src/com/google/gwt/user/client/ui/PopupPanel.java (working copy) @@ -573,17 +573,6 @@ * @param top the top position, in pixels */ public void setPopupPosition(int left, int top) { - // Keep the popup within the browser's client area, so that they can't get - // 'lost' and become impossible to interact with. Note that we don't attempt - // to keep popups pegged to the bottom and right edges, as they will then - // cause scrollbars to appear, so the user can't lose them. - if (left < 0) { - left = 0; - } - if (top < 0) { - top = 0; - } - // Save the position of the popup leftPosition = left; topPosition = top;