[Remoting Android] Use floating point coords for rendering the cursor
Currently we use integer coords when calculating cursor position and rendering the cursor so the pixels we are locking the cursor to are very apparent when the zoom level is increased. This CL makes the client use floating point coords for rendering the cursor so that the position finer-grained than a pixel. BUG=638307 Review-Url: https://codereview.chromium.org/2255663002 Cr-Commit-Position: refs/heads/master@{#412909}
This commit is contained in:
remoting
android
java
client
@ -5,7 +5,7 @@
|
||||
package org.chromium.chromoting;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.PointF;
|
||||
import android.text.InputType;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.SurfaceView;
|
||||
@ -140,7 +140,7 @@ public abstract class AbstractDesktopView extends SurfaceView {
|
||||
}
|
||||
|
||||
/** Triggers a brief animation to indicate the existence and location of an input event. */
|
||||
public abstract void showInputFeedback(InputFeedbackType feedbackToShow, Point pos);
|
||||
public abstract void showInputFeedback(InputFeedbackType feedbackToShow, PointF pos);
|
||||
|
||||
/**
|
||||
* Informs the view that its transformation matrix (for rendering the remote desktop bitmap)
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
package org.chromium.chromoting;
|
||||
|
||||
import android.graphics.Point;
|
||||
import android.graphics.PointF;
|
||||
import android.view.SurfaceHolder;
|
||||
|
||||
import org.chromium.chromoting.jni.Client;
|
||||
@ -38,7 +38,7 @@ public class GlDesktopView extends AbstractDesktopView implements SurfaceHolder.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showInputFeedback(InputFeedbackType feedbackToShow, Point pos) {
|
||||
public void showInputFeedback(InputFeedbackType feedbackToShow, PointF pos) {
|
||||
float diameter = getFeedbackRadius(feedbackToShow) * 2.0f;
|
||||
if (diameter <= 0.0f) {
|
||||
return;
|
||||
@ -60,7 +60,7 @@ public class GlDesktopView extends AbstractDesktopView implements SurfaceHolder.
|
||||
|
||||
@Override
|
||||
public void cursorMoved() {
|
||||
Point cursorPosition = mRenderData.getCursorPosition();
|
||||
PointF cursorPosition = mRenderData.getCursorPosition();
|
||||
mDisplay.cursorPixelPositionChanged(cursorPosition.x, cursorPosition.y);
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
package org.chromium.chromoting;
|
||||
|
||||
import android.graphics.Point;
|
||||
import android.graphics.PointF;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
@ -35,35 +35,35 @@ public final class InputEventSender {
|
||||
mPressedTextKeys = new TreeSet<>();
|
||||
}
|
||||
|
||||
public void sendMouseEvent(Point pos, int button, boolean down) {
|
||||
public void sendMouseEvent(PointF pos, int button, boolean down) {
|
||||
Preconditions.isTrue(button == InputStub.BUTTON_UNDEFINED
|
||||
|| button == InputStub.BUTTON_LEFT
|
||||
|| button == InputStub.BUTTON_MIDDLE
|
||||
|| button == InputStub.BUTTON_RIGHT);
|
||||
mInjector.sendMouseEvent(pos.x, pos.y, button, down);
|
||||
mInjector.sendMouseEvent((int) pos.x, (int) pos.y, button, down);
|
||||
}
|
||||
|
||||
public void sendMouseDown(Point pos, int button) {
|
||||
public void sendMouseDown(PointF pos, int button) {
|
||||
sendMouseEvent(pos, button, true);
|
||||
}
|
||||
|
||||
public void sendMouseUp(Point pos, int button) {
|
||||
public void sendMouseUp(PointF pos, int button) {
|
||||
sendMouseEvent(pos, button, false);
|
||||
}
|
||||
|
||||
public void sendMouseClick(Point pos, int button) {
|
||||
public void sendMouseClick(PointF pos, int button) {
|
||||
sendMouseDown(pos, button);
|
||||
sendMouseUp(pos, button);
|
||||
}
|
||||
|
||||
public void sendCursorMove(Point pos) {
|
||||
public void sendCursorMove(PointF pos) {
|
||||
sendMouseUp(pos, InputStub.BUTTON_UNDEFINED);
|
||||
}
|
||||
|
||||
// TODO(zijiehe): This function will be eventually removed after {@link InputStrategyInterface}
|
||||
// has been deprecated.
|
||||
public void sendCursorMove(int x, int y) {
|
||||
sendCursorMove(new Point(x, y));
|
||||
public void sendCursorMove(float x, float y) {
|
||||
sendCursorMove(new PointF(x, y));
|
||||
}
|
||||
|
||||
public void sendMouseWheelEvent(float distanceX, float distanceY) {
|
||||
|
@ -5,7 +5,7 @@
|
||||
package org.chromium.chromoting;
|
||||
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.PointF;
|
||||
|
||||
/**
|
||||
* This class stores data that needs to be accessed on both the display thread and the
|
||||
@ -27,15 +27,15 @@ public class RenderData {
|
||||
* Specifies the position, in image coordinates, at which the cursor image will be drawn.
|
||||
* This will normally be at the location of the most recently injected motion event.
|
||||
*/
|
||||
private Point mCursorPosition = new Point();
|
||||
private PointF mCursorPosition = new PointF();
|
||||
|
||||
/**
|
||||
* Returns the position of the rendered cursor.
|
||||
*
|
||||
* @return A point representing the current position.
|
||||
*/
|
||||
public Point getCursorPosition() {
|
||||
return new Point(mCursorPosition);
|
||||
public PointF getCursorPosition() {
|
||||
return new PointF(mCursorPosition.x, mCursorPosition.y);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -45,7 +45,7 @@ public class RenderData {
|
||||
* @param newY The new value of the y coordinate
|
||||
* @return True if the cursor position has changed.
|
||||
*/
|
||||
public boolean setCursorPosition(int newX, int newY) {
|
||||
public boolean setCursorPosition(float newX, float newY) {
|
||||
boolean cursorMoved = false;
|
||||
if (newX != mCursorPosition.x) {
|
||||
mCursorPosition.x = newX;
|
||||
|
@ -5,7 +5,7 @@
|
||||
package org.chromium.chromoting;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.PointF;
|
||||
import android.os.SystemClock;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.ViewConfiguration;
|
||||
@ -30,7 +30,7 @@ public class SimulatedTouchInputStrategy implements InputStrategyInterface {
|
||||
/**
|
||||
* Stores the position of the last left button single tap processed.
|
||||
*/
|
||||
private Point mLastTapPoint;
|
||||
private PointF mLastTapPoint;
|
||||
|
||||
/**
|
||||
* The maximum distance, in pixels, between two points in order for them to be considered a
|
||||
@ -84,7 +84,7 @@ public class SimulatedTouchInputStrategy implements InputStrategyInterface {
|
||||
|
||||
@Override
|
||||
public boolean onTap(int button) {
|
||||
Point currentTapPoint = getCursorPosition();
|
||||
PointF currentTapPoint = getCursorPosition();
|
||||
if (button == InputStub.BUTTON_LEFT) {
|
||||
// Left clicks are handled a little differently than the events for other buttons.
|
||||
// This is needed because translating touch events to mouse events has a problem with
|
||||
@ -96,7 +96,7 @@ public class SimulatedTouchInputStrategy implements InputStrategyInterface {
|
||||
// attempting a double tap, we use the original event's location for that second tap.
|
||||
long tapInterval = SystemClock.uptimeMillis() - mLastTapTimeInMs;
|
||||
if (isDoubleTap(currentTapPoint.x, currentTapPoint.y, tapInterval)) {
|
||||
currentTapPoint = new Point(mLastTapPoint);
|
||||
currentTapPoint = new PointF(mLastTapPoint.x, mLastTapPoint.y);
|
||||
mLastTapPoint = null;
|
||||
mLastTapTimeInMs = 0;
|
||||
} else {
|
||||
@ -153,13 +153,13 @@ public class SimulatedTouchInputStrategy implements InputStrategyInterface {
|
||||
return false;
|
||||
}
|
||||
|
||||
private Point getCursorPosition() {
|
||||
private PointF getCursorPosition() {
|
||||
synchronized (mRenderData) {
|
||||
return mRenderData.getCursorPosition();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isDoubleTap(int currentX, int currentY, long tapInterval) {
|
||||
private boolean isDoubleTap(float currentX, float currentY, long tapInterval) {
|
||||
if (tapInterval > mDoubleTapDurationInMs || mLastTapPoint == null) {
|
||||
return false;
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ package org.chromium.chromoting;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.view.GestureDetector;
|
||||
@ -397,7 +396,7 @@ public class TouchInputHandler {
|
||||
// If we are in an indirect mode, then we want to keep the cursor centered, if possible, as
|
||||
// the viewport moves.
|
||||
if (mInputStrategy.isIndirectInputMode()) {
|
||||
moveCursor((int) newPos.x, (int) newPos.y);
|
||||
moveCursor(newPos.x, newPos.y);
|
||||
}
|
||||
|
||||
mDesktopCanvas.repositionImage(true);
|
||||
@ -406,15 +405,15 @@ public class TouchInputHandler {
|
||||
/** Moves the cursor to the specified position on the screen. */
|
||||
private void moveCursorToScreenPoint(float screenX, float screenY) {
|
||||
float[] imagePoint = mapScreenPointToImagePoint(screenX, screenY);
|
||||
moveCursor((int) imagePoint[0], (int) imagePoint[1]);
|
||||
moveCursor(imagePoint[0], imagePoint[1]);
|
||||
}
|
||||
|
||||
/** Moves the cursor to the specified position on the remote host. */
|
||||
private void moveCursor(int newX, int newY) {
|
||||
private void moveCursor(float newX, float newY) {
|
||||
synchronized (mRenderData) {
|
||||
boolean cursorMoved = mRenderData.setCursorPosition(newX, newY);
|
||||
if (cursorMoved) {
|
||||
mInputStrategy.injectCursorMoveEvent(newX, newY);
|
||||
mInputStrategy.injectCursorMoveEvent((int) newX, (int) newY);
|
||||
}
|
||||
}
|
||||
mViewer.cursorMoved();
|
||||
@ -595,7 +594,7 @@ public class TouchInputHandler {
|
||||
}
|
||||
|
||||
if (mInputStrategy.onTap(button)) {
|
||||
Point pos;
|
||||
PointF pos;
|
||||
synchronized (mRenderData) {
|
||||
pos = mRenderData.getCursorPosition();
|
||||
}
|
||||
@ -620,7 +619,7 @@ public class TouchInputHandler {
|
||||
}
|
||||
|
||||
if (mInputStrategy.onPressAndHold(button)) {
|
||||
Point pos;
|
||||
PointF pos;
|
||||
synchronized (mRenderData) {
|
||||
pos = mRenderData.getCursorPosition();
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
package org.chromium.chromoting;
|
||||
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.PointF;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import java.util.LinkedList;
|
||||
@ -80,7 +80,7 @@ public class TouchInputStrategy implements InputStrategyInterface {
|
||||
MotionEvent downEvent = mQueuedEvents.peek();
|
||||
assert downEvent.getActionMasked() == MotionEvent.ACTION_DOWN;
|
||||
|
||||
mInjector.sendMouseClick(new Point((int) downEvent.getX(), (int) downEvent.getY()),
|
||||
mInjector.sendMouseClick(new PointF(downEvent.getX(), downEvent.getY()),
|
||||
InputStub.BUTTON_RIGHT);
|
||||
clearQueuedEvents();
|
||||
return true;
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
package org.chromium.chromoting;
|
||||
|
||||
import android.graphics.Point;
|
||||
import android.graphics.PointF;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
/**
|
||||
@ -76,7 +76,7 @@ public class TrackpadInputStrategy implements InputStrategyInterface {
|
||||
return true;
|
||||
}
|
||||
|
||||
private Point getCursorPosition() {
|
||||
private PointF getCursorPosition() {
|
||||
synchronized (mRenderData) {
|
||||
return mRenderData.getCursorPosition();
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ public class GlDisplay {
|
||||
}
|
||||
|
||||
/** Moves the cursor to the corresponding location on the desktop. */
|
||||
public void cursorPixelPositionChanged(int x, int y) {
|
||||
public void cursorPixelPositionChanged(float x, float y) {
|
||||
if (mNativeJniGlDisplay != 0) {
|
||||
nativeOnCursorPixelPositionChanged(mNativeJniGlDisplay, x, y);
|
||||
}
|
||||
@ -140,7 +140,7 @@ public class GlDisplay {
|
||||
* Shows the cursor input feedback animation with the given diameter at the given desktop
|
||||
* location.
|
||||
*/
|
||||
public void showCursorInputFeedback(int x, int y, float diameter) {
|
||||
public void showCursorInputFeedback(float x, float y, float diameter) {
|
||||
if (mNativeJniGlDisplay != 0) {
|
||||
nativeOnCursorInputFeedback(mNativeJniGlDisplay, x, y, diameter);
|
||||
}
|
||||
@ -168,9 +168,9 @@ public class GlDisplay {
|
||||
private native void nativeOnPixelTransformationChanged(long nativeJniGlDisplayHandler,
|
||||
float[] matrix);
|
||||
private native void nativeOnCursorPixelPositionChanged(long nativeJniGlDisplayHandler,
|
||||
int x, int y);
|
||||
float x, float y);
|
||||
private native void nativeOnCursorInputFeedback(long nativeJniGlDisplayHandler,
|
||||
int x, int y, float diameter);
|
||||
float x, float y, float diameter);
|
||||
private native void nativeOnCursorVisibilityChanged(long nativeJniGlDisplayHandler,
|
||||
boolean visible);
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ void GlCursor::SetCursorShape(const protocol::CursorShapeInfo& cursor_shape) {
|
||||
SetCursorPosition(cursor_x_, cursor_y_);
|
||||
}
|
||||
|
||||
void GlCursor::SetCursorPosition(int x, int y) {
|
||||
void GlCursor::SetCursorPosition(float x, float y) {
|
||||
cursor_x_ = x;
|
||||
cursor_y_ = y;
|
||||
if (!current_cursor_data_) {
|
||||
|
@ -30,7 +30,7 @@ class GlCursor {
|
||||
|
||||
// Sets the cursor hotspot positions. Does nothing if the cursor shape or the
|
||||
// canvas size has not been set.
|
||||
void SetCursorPosition(int x, int y);
|
||||
void SetCursorPosition(float x, float y);
|
||||
|
||||
// Draw() will do nothing if cursor is not visible.
|
||||
void SetCursorVisible(bool visible);
|
||||
@ -56,8 +56,8 @@ class GlCursor {
|
||||
int current_cursor_hotspot_x_ = 0;
|
||||
int current_cursor_hotspot_y_ = 0;
|
||||
|
||||
int cursor_x_ = 0;
|
||||
int cursor_y_ = 0;
|
||||
float cursor_x_ = 0;
|
||||
float cursor_y_ = 0;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(GlCursor);
|
||||
};
|
||||
|
@ -36,7 +36,7 @@ void GlCursorFeedback::SetCanvas(GlCanvas* canvas) {
|
||||
GlCursorFeedbackTexture::kTextureWidth, 0);
|
||||
}
|
||||
|
||||
void GlCursorFeedback::StartAnimation(int x, int y, float diameter) {
|
||||
void GlCursorFeedback::StartAnimation(float x, float y, float diameter) {
|
||||
cursor_x_ = x;
|
||||
cursor_y_ = y;
|
||||
max_diameter_ = diameter;
|
||||
|
@ -28,7 +28,7 @@ class GlCursorFeedback {
|
||||
// If |canvas| is nullptr, nothing will happen when calling Draw().
|
||||
void SetCanvas(GlCanvas* canvas);
|
||||
|
||||
void StartAnimation(int x, int y, float diameter);
|
||||
void StartAnimation(float x, float y, float diameter);
|
||||
|
||||
// Returns true if animation is not finished, false otherwise. Does nothing
|
||||
// if the animation has stopped.
|
||||
|
@ -43,13 +43,13 @@ void GlRenderer::OnPixelTransformationChanged(
|
||||
RequestRender();
|
||||
}
|
||||
|
||||
void GlRenderer::OnCursorMoved(int x, int y) {
|
||||
void GlRenderer::OnCursorMoved(float x, float y) {
|
||||
DCHECK(thread_checker_.CalledOnValidThread());
|
||||
cursor_.SetCursorPosition(x, y);
|
||||
RequestRender();
|
||||
}
|
||||
|
||||
void GlRenderer::OnCursorInputFeedback(int x, int y, float diameter) {
|
||||
void GlRenderer::OnCursorInputFeedback(float x, float y, float diameter) {
|
||||
DCHECK(thread_checker_.CalledOnValidThread());
|
||||
cursor_feedback_.StartAnimation(x, y, diameter);
|
||||
RequestRender();
|
||||
|
@ -62,9 +62,9 @@ class GlRenderer {
|
||||
// and the top-left corner will be (m2, m5) in pixel coordinates.
|
||||
void OnPixelTransformationChanged(const std::array<float, 9>& matrix);
|
||||
|
||||
void OnCursorMoved(int x, int y);
|
||||
void OnCursorMoved(float x, float y);
|
||||
|
||||
void OnCursorInputFeedback(int x, int y, float diameter);
|
||||
void OnCursorInputFeedback(float x, float y, float diameter);
|
||||
|
||||
void OnCursorVisibilityChanged(bool visible);
|
||||
|
||||
|
@ -115,8 +115,8 @@ void JniGlDisplayHandler::OnPixelTransformationChanged(
|
||||
void JniGlDisplayHandler::OnCursorPixelPositionChanged(
|
||||
JNIEnv* env,
|
||||
const base::android::JavaParamRef<jobject>& caller,
|
||||
int x,
|
||||
int y) {
|
||||
float x,
|
||||
float y) {
|
||||
DCHECK(runtime_->ui_task_runner()->BelongsToCurrentThread());
|
||||
ui_task_poster_->AddTask(base::Bind(&GlRenderer::OnCursorMoved,
|
||||
renderer_.GetWeakPtr(), x, y));
|
||||
@ -134,8 +134,8 @@ void JniGlDisplayHandler::OnCursorVisibilityChanged(
|
||||
void JniGlDisplayHandler::OnCursorInputFeedback(
|
||||
JNIEnv* env,
|
||||
const base::android::JavaParamRef<jobject>& caller,
|
||||
int x,
|
||||
int y,
|
||||
float x,
|
||||
float y,
|
||||
float diameter) {
|
||||
DCHECK(runtime_->ui_task_runner()->BelongsToCurrentThread());
|
||||
ui_task_poster_->AddTask(base::Bind(&GlRenderer::OnCursorInputFeedback,
|
||||
|
@ -68,8 +68,8 @@ class JniGlDisplayHandler : public DisplayUpdaterFactory,
|
||||
void OnCursorPixelPositionChanged(
|
||||
JNIEnv* env,
|
||||
const base::android::JavaParamRef<jobject>& caller,
|
||||
int x,
|
||||
int y);
|
||||
float x,
|
||||
float y);
|
||||
|
||||
void OnCursorVisibilityChanged(
|
||||
JNIEnv* env,
|
||||
@ -79,8 +79,8 @@ class JniGlDisplayHandler : public DisplayUpdaterFactory,
|
||||
void OnCursorInputFeedback(
|
||||
JNIEnv* env,
|
||||
const base::android::JavaParamRef<jobject>& caller,
|
||||
int x,
|
||||
int y,
|
||||
float x,
|
||||
float y,
|
||||
float diameter);
|
||||
|
||||
private:
|
||||
|
Reference in New Issue
Block a user