Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(161)

Unified Diff: content/public/android/java/src/org/chromium/content/browser/WebActionMode.java

Issue 1242613002: [Android] Supporting floating select ActionModes for web content (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/public/android/java/src/org/chromium/content/browser/WebActionMode.java
diff --git a/content/public/android/java/src/org/chromium/content/browser/WebActionMode.java b/content/public/android/java/src/org/chromium/content/browser/WebActionMode.java
index befbb81b1f5279794a6f65c0b750c90474912206..6c0008954994aea0ef1a6e4c5bb443bef58b7883 100644
--- a/content/public/android/java/src/org/chromium/content/browser/WebActionMode.java
+++ b/content/public/android/java/src/org/chromium/content/browser/WebActionMode.java
@@ -4,7 +4,10 @@
package org.chromium.content.browser;
+import android.annotation.TargetApi;
+import android.os.Build;
import android.view.ActionMode;
+import android.view.View;
import org.chromium.base.Log;
@@ -12,18 +15,36 @@ import org.chromium.base.Log;
* An ActionMode for in-page web content selection. This class wraps an ActionMode created
* by the associated View, providing modified interaction with that ActionMode.
*/
+@TargetApi(Build.VERSION_CODES.M)
public class WebActionMode {
- private static final String TAG = "cr.SelectActionMode";
+ private static final String TAG = "cr.WebActionMode";
protected final ActionMode mActionMode;
+ private final View mView;
+ private boolean mHidden;
+ private boolean mPendingInvalidateContentRect;
+
+ // Self-repeating task that repeatedly hides the ActionMode. This is
+ // required because ActionMode only exposes a temporary hide routine.
+ private final Runnable mRepeatingHideRunnable;
/**
* Constructs a SelectActionMode instance wrapping a concrete ActionMode.
* @param actionMode the wrapped ActionMode.
*/
- public WebActionMode(ActionMode actionMode) {
+ public WebActionMode(ActionMode actionMode, View view) {
assert actionMode != null;
+ assert view != null;
mActionMode = actionMode;
+ mView = view;
+ mRepeatingHideRunnable = new Runnable() {
+ @Override
+ public void run() {
+ assert mHidden;
+ mView.postDelayed(mRepeatingHideRunnable, ActionMode.DEFAULT_HIDE_DURATION - 1);
+ hideTemporarily(ActionMode.DEFAULT_HIDE_DURATION);
+ }
+ };
}
/**
@@ -35,8 +56,17 @@ public class WebActionMode {
/**
* @see ActionMode#invalidate()
+ * Note that invalidation will also reset visibility state. The caller
+ * should account for this when making subsequent visibility updates.
*/
public void invalidate() {
+ if (mHidden) {
+ assert canHide();
+ mHidden = false;
+ mView.removeCallbacks(mRepeatingHideRunnable);
+ mPendingInvalidateContentRect = false;
+ }
+
// Try/catch necessary for framework bug, crbug.com/446717.
try {
mActionMode.invalidate();
@@ -48,5 +78,65 @@ public class WebActionMode {
/**
* @see ActionMode#invalidateContentRect()
*/
- public void invalidateContentRect() {}
+ public void invalidateContentRect() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ if (mHidden) {
+ mPendingInvalidateContentRect = true;
+ } else {
+ mPendingInvalidateContentRect = false;
+ mActionMode.invalidateContentRect();
+ }
+ }
+ }
+
+ /**
+ * @see ActionMode#onWindowFocusChanged()
+ */
+ public void onWindowFocusChanged(boolean hasWindowFocus) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ mActionMode.onWindowFocusChanged(hasWindowFocus);
+ }
+ }
+
+ /**
+ * Hide or reveal the ActionMode. Note that this only has visible
+ * side-effects if the underlying ActionMode supports hiding.
+ * @param hide whether to hide or show the ActionMode.
+ */
+ public void hide(boolean hide) {
+ if (!canHide()) return;
+ if (mHidden == hide) return;
+ mHidden = hide;
+ if (mHidden) {
+ mRepeatingHideRunnable.run();
+ } else {
+ mHidden = false;
+ mView.removeCallbacks(mRepeatingHideRunnable);
+ // Delay the reveal slightly as there could be trailing content
+ // rect invalidations soon after showing (which would temporarily
+ // hide the ActionMode yet again).
+ hideTemporarily(300);
aurimas (slooooooooow) 2015/08/20 22:20:16 How did we pick this number? Can we pull this cons
jdduke (slow) 2015/08/20 23:13:14 It's somewhat arbitrary, 300 ms should ensure we g
+ if (mPendingInvalidateContentRect) {
+ mPendingInvalidateContentRect = false;
+ invalidateContentRect();
+ }
+ }
+ }
+
+ /**
+ * @see ActionMode#hide(long)
+ */
+ private void hideTemporarily(long duration) {
+ assert canHide();
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ mActionMode.hide(duration);
+ }
+ }
+
+ private boolean canHide() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ return mActionMode.getType() == ActionMode.TYPE_FLOATING;
+ }
+ return false;
+ }
}

Powered by Google App Engine
This is Rietveld 408576698