Index: remoting/android/java/src/org/chromium/chromoting/DesktopCanvas.java |
diff --git a/remoting/android/java/src/org/chromium/chromoting/DesktopCanvas.java b/remoting/android/java/src/org/chromium/chromoting/DesktopCanvas.java |
index 778c395267e875f75548e8ff8aa6acc33aa484e0..2cc913d79301d30d85f9fbd142c61015f4d8371d 100644 |
--- a/remoting/android/java/src/org/chromium/chromoting/DesktopCanvas.java |
+++ b/remoting/android/java/src/org/chromium/chromoting/DesktopCanvas.java |
@@ -58,6 +58,18 @@ public class DesktopCanvas { |
*/ |
private RectF mVisibleImagePadding = new RectF(); |
+ /** |
+ * Tracks whether to adjust the viewport to account for System UI. If false, the viewport |
+ * center is the center of the screen. If true, then System UI offsets will be used to |
+ * adjust the position of the viewport to ensure the cursor is visible. |
+ */ |
+ private boolean mAdjustViewportForSystemUi = false; |
+ |
+ /** |
+ * Represents the amount of space, in pixels, to adjust the cursor center along the y-axis. |
+ */ |
+ private float mCursorOffsetScreenY = 0.0f; |
+ |
public DesktopCanvas(RenderStub renderStub, RenderData renderData) { |
mRenderStub = renderStub; |
mRenderData = renderData; |
@@ -122,13 +134,35 @@ public class DesktopCanvas { |
*/ |
public void setSystemUiOffsetValues(int left, int top, int right, int bottom) { |
mSystemUiScreenSize.set(left, top, right, bottom); |
+ |
+ if (mAdjustViewportForSystemUi) { |
+ // Adjust the cursor position to ensure it's visible when large System UI (defined as |
+ // 1/3 or more of the total screen size) is displayed. This is typically the Soft |
+ // Keyboard. Without this change, it is difficult for users to enter text into edit |
+ // controls which are located bottom of the screen and may not be able to view their |
+ // cursor at all. |
+ if (bottom > (mRenderData.screenHeight / 3)) { |
+ // Center the cursor within the viewable area (not obscured by System UI). |
+ mCursorOffsetScreenY = (((float) mRenderData.screenHeight - bottom) / 2.0f); |
+ } else { |
+ mCursorOffsetScreenY = 0.0f; |
+ } |
+ |
+ // Apply the cursor offset. |
+ setCursorPosition(mCursorPosition.x, mCursorPosition.y); |
+ } |
} |
/** Called to indicate that no System UI is visible. */ |
public void clearSystemUiOffsets() { |
+ mCursorOffsetScreenY = 0.0f; |
mSystemUiScreenSize.setEmpty(); |
} |
+ public void adjustViewportForSystemUi(boolean adjustViewportForSystemUi) { |
+ mAdjustViewportForSystemUi = adjustViewportForSystemUi; |
+ } |
+ |
/** Resizes the image by zooming it such that the image is displayed without borders. */ |
public void resizeImageToFitScreen() { |
// Protect against being called before the image has been initialized. |
@@ -220,9 +254,10 @@ public class DesktopCanvas { |
mRenderData.transform.mapPoints(viewportPosition); |
float viewportTransX = ((float) mRenderData.screenWidth / 2) - viewportPosition[0]; |
- float viewportTransY = ((float) mRenderData.screenHeight / 2) - viewportPosition[1]; |
+ float viewportTransY = |
+ ((float) mRenderData.screenHeight / 2) - viewportPosition[1] - mCursorOffsetScreenY; |
- // Translate the image so the viewport center is displayed in the middle of the screen. |
+ // Translate the image to move the viewport to the expected screen location. |
mRenderData.transform.postTranslate(viewportTransX, viewportTransY); |
updateVisibleImagePadding(); |
@@ -263,9 +298,10 @@ public class DesktopCanvas { |
// the desktop image from 'snapping' back to pre-System UI state. |
RectF systemUiOverlap = getSystemUiOverlap(); |
float[] padding = {Math.max(mVisibleImagePadding.left, systemUiOverlap.left), |
- Math.max(mVisibleImagePadding.top, systemUiOverlap.top), |
+ Math.max(mVisibleImagePadding.top + mCursorOffsetScreenY, systemUiOverlap.top), |
Math.max(mVisibleImagePadding.right, systemUiOverlap.right), |
- Math.max(mVisibleImagePadding.bottom, systemUiOverlap.bottom)}; |
+ Math.max(mVisibleImagePadding.bottom - mCursorOffsetScreenY, |
+ systemUiOverlap.bottom)}; |
Matrix screenToImage = new Matrix(); |
mRenderData.transform.invert(screenToImage); |
screenToImage.mapVectors(padding); |
@@ -325,9 +361,10 @@ public class DesktopCanvas { |
// Note: Ignore negative padding (clamp to 0) since that means no overlap exists. |
PointF letterboxPadding = getLetterboxPadding(); |
return new RectF(Math.max(mSystemUiScreenSize.left - letterboxPadding.x, 0.0f), |
- Math.max(mSystemUiScreenSize.top - letterboxPadding.y, 0.0f), |
+ Math.max(mSystemUiScreenSize.top - letterboxPadding.y + mCursorOffsetScreenY, 0.0f), |
Math.max(mSystemUiScreenSize.right - letterboxPadding.x, 0.0f), |
- Math.max(mSystemUiScreenSize.bottom - letterboxPadding.y, 0.0f)); |
+ Math.max(mSystemUiScreenSize.bottom - letterboxPadding.y - mCursorOffsetScreenY, |
+ 0.0f)); |
} |
/** |