From ca310383d43237a60a89011d287fd93a60333946 Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Sat, 3 Dec 2011 22:59:27 -0500 Subject: [PATCH] Bug 696319 - Scroll window as needed when soft keyboard is up [r=mfinkle] Send an event to scroll to the focused input field when the soft keyboard comes up. Ensure that this happens *after* the viewport change event is sent to Gecko, so that Gecko actually knows that browser viewport is smaller and doesn't just no-op the scroll request. --- mobile/android/base/GeckoAppShell.java | 6 ++++++ mobile/android/base/GeckoInputConnection.java | 4 ++++ mobile/android/base/gfx/GeckoSoftwareLayerClient.java | 10 ++++++++++ mobile/android/base/gfx/LayerClient.java | 1 + mobile/android/base/gfx/LayerController.java | 3 +++ mobile/android/base/gfx/PlaceholderLayerClient.java | 2 ++ mobile/android/chrome/content/browser.js | 4 +++- 7 files changed, 29 insertions(+), 1 deletion(-) diff --git a/mobile/android/base/GeckoAppShell.java b/mobile/android/base/GeckoAppShell.java index 7d74686efdd..761596ce85d 100644 --- a/mobile/android/base/GeckoAppShell.java +++ b/mobile/android/base/GeckoAppShell.java @@ -1572,4 +1572,10 @@ public class GeckoAppShell accessibilityManager.sendAccessibilityEvent(event); } + + public static void viewSizeChanged() { + if (mInputConnection != null && mInputConnection.isIMEEnabled()) { + sendEventToGecko(new GeckoEvent("ScrollTo:FocusedInput", "")); + } + } } diff --git a/mobile/android/base/GeckoInputConnection.java b/mobile/android/base/GeckoInputConnection.java index 5125a68f6fe..284c1aebdd5 100644 --- a/mobile/android/base/GeckoInputConnection.java +++ b/mobile/android/base/GeckoInputConnection.java @@ -911,6 +911,10 @@ public class GeckoInputConnection return false; } + public boolean isIMEEnabled() { + // make sure this picks up PASSWORD and PLUGIN states as well + return mIMEState != IME_STATE_DISABLED; + } public void notifyIME(int type, int state) { diff --git a/mobile/android/base/gfx/GeckoSoftwareLayerClient.java b/mobile/android/base/gfx/GeckoSoftwareLayerClient.java index 2018f8e2e71..17d22a1acf3 100644 --- a/mobile/android/base/gfx/GeckoSoftwareLayerClient.java +++ b/mobile/android/base/gfx/GeckoSoftwareLayerClient.java @@ -85,6 +85,7 @@ public class GeckoSoftwareLayerClient extends LayerClient implements GeckoEventL private static final long MIN_VIEWPORT_CHANGE_DELAY = 350L; private long mLastViewportChangeTime; private boolean mPendingViewportAdjust; + private boolean mViewportSizeChanged; public GeckoSoftwareLayerClient(Context context) { mContext = context; @@ -227,6 +228,11 @@ public class GeckoSoftwareLayerClient extends LayerClient implements GeckoEventL render(); } + @Override + public void viewportSizeChanged() { + mViewportSizeChanged = true; + } + @Override public void render() { adjustViewportWithThrottling(); @@ -266,6 +272,10 @@ public class GeckoSoftwareLayerClient extends LayerClient implements GeckoEventL GeckoEvent event = new GeckoEvent("Viewport:Change", viewportMetrics.toJSON()); GeckoAppShell.sendEventToGecko(event); + if (mViewportSizeChanged) { + mViewportSizeChanged = false; + GeckoAppShell.viewSizeChanged(); + } mLastViewportChangeTime = System.currentTimeMillis(); } diff --git a/mobile/android/base/gfx/LayerClient.java b/mobile/android/base/gfx/LayerClient.java index 7e5b19258fb..f7263021ce9 100644 --- a/mobile/android/base/gfx/LayerClient.java +++ b/mobile/android/base/gfx/LayerClient.java @@ -44,6 +44,7 @@ public abstract class LayerClient { private LayerController mLayerController; public abstract void geometryChanged(); + public abstract void viewportSizeChanged(); protected abstract void render(); public LayerController getLayerController() { return mLayerController; } diff --git a/mobile/android/base/gfx/LayerController.java b/mobile/android/base/gfx/LayerController.java index dfc8f4ec397..244b3d4b9c6 100644 --- a/mobile/android/base/gfx/LayerController.java +++ b/mobile/android/base/gfx/LayerController.java @@ -162,6 +162,9 @@ public class LayerController { mViewportMetrics.setSize(size); setForceRedraw(); + if (mLayerClient != null) + mLayerClient.viewportSizeChanged(); + notifyLayerClientOfGeometryChange(); mPanZoomController.geometryChanged(false); mView.requestRender(); diff --git a/mobile/android/base/gfx/PlaceholderLayerClient.java b/mobile/android/base/gfx/PlaceholderLayerClient.java index 7103a96c26b..b48eda7b7a5 100644 --- a/mobile/android/base/gfx/PlaceholderLayerClient.java +++ b/mobile/android/base/gfx/PlaceholderLayerClient.java @@ -142,6 +142,8 @@ public class PlaceholderLayerClient extends LayerClient { @Override public void geometryChanged() { /* no-op */ } @Override + public void viewportSizeChanged() { /* no-op */ } + @Override public void render() { /* no-op */ } @Override diff --git a/mobile/android/chrome/content/browser.js b/mobile/android/chrome/content/browser.js index ddb06e9cb39..c98c28d4185 100644 --- a/mobile/android/chrome/content/browser.js +++ b/mobile/android/chrome/content/browser.js @@ -518,8 +518,10 @@ var BrowserApp = { if (!doc) return; let focused = doc.activeElement; - if ((focused instanceof HTMLInputElement && focused.mozIsTextField(false)) || (focused instanceof HTMLTextAreaElement)) + if ((focused instanceof HTMLInputElement && focused.mozIsTextField(false)) || (focused instanceof HTMLTextAreaElement)) { focused.scrollIntoView(false); + BrowserApp.getTabForBrowser(aBrowser).sendViewportUpdate(); + } }, getDrawMetadata: function getDrawMetadata() {