Bug 610834 - New windows opened don't get painted until resized. r=fabrice
--- a/mobile/chrome/content/browser.js
+++ b/mobile/chrome/content/browser.js
@@ -382,22 +382,16 @@ var Browser = {
messageManager.addMessageListener("Browser:CertException", this);
messageManager.addMessageListener("Browser:BlockedSite", this);
messageManager.addMessageListener("Browser:ErrorPage", this);
// Broadcast a UIReady message so add-ons know we are finished with startup
let event = document.createEvent("Events");
event.initEvent("UIReady", true, false);
window.dispatchEvent(event);
-
- // If we have an opener this was not the first window opened and will not
- // receive an initial resize event. instead we fire the resize handler manually
- // Bug 610834
- if (window.opener)
- resizeHandler({ target: window });
},
_alertShown: function _alertShown() {
// ensure that the full notification still visible, even if the urlbar is floating
if (BrowserUI.isToolbarLocked())
Browser.pageScrollboxScroller.scrollTo(0, 0);
},
--- a/widget/src/android/AndroidJavaWrappers.cpp
+++ b/widget/src/android/AndroidJavaWrappers.cpp
@@ -453,16 +453,29 @@ AndroidGeckoEvent::Init(int aType)
void
AndroidGeckoEvent::Init(int x1, int y1, int x2, int y2)
{
mType = DRAW;
mRect.SetEmpty();
}
void
+AndroidGeckoEvent::Init(AndroidGeckoEvent *aResizeEvent)
+{
+ NS_ASSERTION(aResizeEvent->Type() == SIZE_CHANGED, "Init called on non-SIZE_CHANGED event");
+
+ mType = FORCED_RESIZE;
+ mTime = aResizeEvent->mTime;
+ mP0.x = aResizeEvent->mP0.x;
+ mP0.y = aResizeEvent->mP0.y;
+ mP1.x = aResizeEvent->mP1.x;
+ mP1.y = aResizeEvent->mP1.y;
+}
+
+void
AndroidGeckoSurfaceView::Init(jobject jobj)
{
NS_ASSERTION(wrapped_obj == nsnull, "Init called on non-null wrapped_obj!");
wrapped_obj = jobj;
}
int
--- a/widget/src/android/AndroidJavaWrappers.h
+++ b/widget/src/android/AndroidJavaWrappers.h
@@ -381,20 +381,24 @@ public:
Init(aType);
}
AndroidGeckoEvent(int x1, int y1, int x2, int y2) {
Init(x1, y1, x2, y2);
}
AndroidGeckoEvent(JNIEnv *jenv, jobject jobj) {
Init(jenv, jobj);
}
+ AndroidGeckoEvent(AndroidGeckoEvent *aResizeEvent) {
+ Init(aResizeEvent);
+ }
void Init(JNIEnv *jenv, jobject jobj);
void Init(int aType);
void Init(int x1, int y1, int x2, int y2);
+ void Init(AndroidGeckoEvent *aResizeEvent);
int Action() { return mAction; }
int Type() { return mType; }
int64_t Time() { return mTime; }
const nsIntPoint& P0() { return mP0; }
const nsIntPoint& P1() { return mP1; }
double Alpha() { return mAlpha; }
double Beta() { return mBeta; }
@@ -482,16 +486,17 @@ public:
SIZE_CHANGED = 8,
ACTIVITY_STOPPING = 9,
ACTIVITY_PAUSING = 10,
ACTIVITY_SHUTDOWN = 11,
LOAD_URI = 12,
SURFACE_CREATED = 13,
SURFACE_DESTROYED = 14,
GECKO_EVENT_SYNC = 15,
+ FORCED_RESIZE = 16,
dummy_java_enum_list_end
};
enum {
IME_COMPOSITION_END = 0,
IME_COMPOSITION_BEGIN = 1,
IME_SET_TEXT = 2,
IME_GET_TEXT = 3,
--- a/widget/src/android/nsAppShell.cpp
+++ b/widget/src/android/nsAppShell.cpp
@@ -69,16 +69,17 @@
using namespace mozilla;
#ifdef PR_LOGGING
PRLogModuleInfo *gWidgetLog = nsnull;
#endif
nsDeviceMotionSystem *gDeviceMotionSystem = nsnull;
nsIGeolocationUpdate *gLocationCallback = nsnull;
+nsAutoPtr<mozilla::AndroidGeckoEvent> gLastSizeChange;
nsAppShell *nsAppShell::gAppShell = nsnull;
NS_IMPL_ISUPPORTS_INHERITED1(nsAppShell, nsBaseAppShell, nsIObserver)
nsAppShell::nsAppShell()
: mQueueLock("nsAppShell.mQueueLock"),
mCondLock("nsAppShell.mCondLock"),
@@ -375,25 +376,41 @@ nsAppShell::ProcessNextNativeEvent(PRBoo
};
nsresult rv = cmdline->Init(3, const_cast<char **>(argv), nsnull, nsICommandLine::STATE_REMOTE_AUTO);
if (NS_SUCCEEDED(rv))
cmdline->Run();
nsMemory::Free(uri);
break;
}
+ case AndroidGeckoEvent::SIZE_CHANGED: {
+ // store the last resize event to dispatch it to new windows with a FORCED_RESIZE event
+ if (curEvent != gLastSizeChange) {
+ gLastSizeChange = new AndroidGeckoEvent(curEvent);
+ }
+ nsWindow::OnGlobalAndroidEvent(curEvent);
+ break;
+ }
+
default:
nsWindow::OnGlobalAndroidEvent(curEvent);
}
EVLOG("nsAppShell: -- done event %p %d", (void*)curEvent.get(), curEvent->Type());
return true;
}
+void
+nsAppShell::ResendLastResizeEvent(nsWindow* aDest) {
+ if (gLastSizeChange) {
+ nsWindow::OnGlobalAndroidEvent(gLastSizeChange);
+ }
+}
+
AndroidGeckoEvent*
nsAppShell::GetNextEvent()
{
AndroidGeckoEvent *ae = nsnull;
MutexAutoLock lock(mQueueLock);
if (mEventQueue.Length()) {
ae = mEventQueue[0];
mEventQueue.RemoveElementAt(0);
--- a/widget/src/android/nsAppShell.h
+++ b/widget/src/android/nsAppShell.h
@@ -47,16 +47,18 @@
#include "nsInterfaceHashtable.h"
namespace mozilla {
class AndroidGeckoEvent;
bool ProcessNextEvent();
void NotifyEvent();
}
+class nsWindow;
+
class nsAppShell :
public nsBaseAppShell
{
typedef mozilla::CondVar CondVar;
typedef mozilla::Mutex Mutex;
public:
static nsAppShell *gAppShell;
@@ -76,16 +78,17 @@ public:
void PostEvent(mozilla::AndroidGeckoEvent *event);
void RemoveNextEvent();
void OnResume();
nsresult AddObserver(const nsAString &aObserverKey, nsIObserver *aObserver);
void CallObserver(const nsAString &aObserverKey, const nsAString &aTopic, const nsAString &aData);
void RemoveObserver(const nsAString &aObserverKey);
void NotifyObservers(nsISupports *aSupports, const char *aTopic, const PRUnichar *aData);
+ void ResendLastResizeEvent(nsWindow* aDest);
protected:
virtual void ScheduleNativeEventCallback();
virtual ~nsAppShell();
Mutex mQueueLock;
Mutex mCondLock;
CondVar mQueueCond;
--- a/widget/src/android/nsWindow.cpp
+++ b/widget/src/android/nsWindow.cpp
@@ -443,24 +443,16 @@ nsWindow::Resize(PRInt32 aX,
PRInt32 aWidth,
PRInt32 aHeight,
PRBool aRepaint)
{
ALOG("nsWindow[%p]::Resize [%d %d %d %d] (repaint %d)", (void*)this, aX, aY, aWidth, aHeight, aRepaint);
PRBool needSizeDispatch = aWidth != mBounds.width || aHeight != mBounds.height;
- if (IsTopLevel()) {
- ALOG("... ignoring Resize sizes on toplevel window");
- aX = 0;
- aY = 0;
- aWidth = gAndroidBounds.width;
- aHeight = gAndroidBounds.height;
- }
-
mBounds.x = aX;
mBounds.y = aY;
mBounds.width = aWidth;
mBounds.height = aHeight;
if (needSizeDispatch)
OnSizeChanged(gfxIntSize(aWidth, aHeight));
@@ -581,16 +573,18 @@ nsWindow::BringToFront()
if (oldTop) {
nsGUIEvent event(PR_TRUE, NS_DEACTIVATE, oldTop);
DispatchEvent(&event);
}
nsGUIEvent event(PR_TRUE, NS_ACTIVATE, this);
DispatchEvent(&event);
+ // force a window resize
+ nsAppShell::gAppShell->ResendLastResizeEvent(this);
nsAppShell::gAppShell->PostEvent(new AndroidGeckoEvent(-1, -1, -1, -1));
}
NS_IMETHODIMP
nsWindow::GetScreenBounds(nsIntRect &aRect)
{
nsIntPoint p = WidgetToScreenOffset();
@@ -734,21 +728,29 @@ nsWindow::OnGlobalAndroidEvent(AndroidGe
if (!AndroidBridge::Bridge())
return;
nsWindow *win = TopWindow();
if (!win)
return;
switch (ae->Type()) {
+ case AndroidGeckoEvent::FORCED_RESIZE:
+ win->mBounds.width = 0;
+ win->mBounds.height = 0;
+ // also resize the children
+ for (PRUint32 i = 0; i < win->mChildren.Length(); i++) {
+ win->mChildren[i]->mBounds.width = 0;
+ win->mChildren[i]->mBounds.height = 0;
+ }
case AndroidGeckoEvent::SIZE_CHANGED: {
int nw = ae->P0().x;
int nh = ae->P0().y;
- if (nw != gAndroidBounds.width ||
+ if (ae->Type() == AndroidGeckoEvent::FORCED_RESIZE || nw != gAndroidBounds.width ||
nh != gAndroidBounds.height) {
gAndroidBounds.width = nw;
gAndroidBounds.height = nh;
// tell all the windows about the new size
for (size_t i = 0; i < gTopLevelWindows.Length(); ++i) {
if (gTopLevelWindows[i]->mIsVisible)