Files
cromite/build/patches/Enable-snackbar-swipe.patch

159 lines
6.5 KiB
Diff

From: uazo <uazo@users.noreply.github.com>
Date: Mon, 18 Aug 2025 13:46:14 +0000
Subject: Enable snackbar swipe
Allows swipe of snackbar notifications
License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html
---
.../ui/messages/snackbar/SnackbarView.java | 91 ++++++++++++++++---
1 file changed, 77 insertions(+), 14 deletions(-)
diff --git a/chrome/browser/ui/messages/android/java/src/org/chromium/chrome/browser/ui/messages/snackbar/SnackbarView.java b/chrome/browser/ui/messages/android/java/src/org/chromium/chrome/browser/ui/messages/snackbar/SnackbarView.java
--- a/chrome/browser/ui/messages/android/java/src/org/chromium/chrome/browser/ui/messages/snackbar/SnackbarView.java
+++ b/chrome/browser/ui/messages/android/java/src/org/chromium/chrome/browser/ui/messages/snackbar/SnackbarView.java
@@ -9,14 +9,17 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.app.Activity;
+import android.content.Context;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.util.Pair;
+import android.view.MotionEvent;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.SurfaceView;
import android.view.View;
+import android.view.View.OnClickListener;
import android.view.View.OnLayoutChangeListener;
import android.view.ViewGroup;
import android.widget.FrameLayout;
@@ -36,6 +39,8 @@ import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarSwipeHandler.Del
import org.chromium.chrome.ui.messages.R;
import org.chromium.components.browser_ui.styles.SemanticColorUtils;
import org.chromium.components.browser_ui.widget.gesture.SwipeGestureListener;
+import org.chromium.components.browser_ui.widget.gesture.SwipeGestureListener.ScrollDirection;
+import org.chromium.components.browser_ui.widget.gesture.SwipeGestureListener.SwipeHandler;
import org.chromium.components.browser_ui.widget.text.TemplatePreservingTextView;
import org.chromium.ui.base.WindowAndroid;
import org.chromium.ui.insets.InsetObserver;
@@ -48,7 +53,7 @@ import org.chromium.ui.interpolators.Interpolators;
// TODO (jianli): Change this class and its methods back to package protected after the offline
// indicator experiment is done.
@NullMarked
-public class SnackbarView implements InsetObserver.WindowInsetObserver {
+public class SnackbarView implements InsetObserver.WindowInsetObserver, View.OnTouchListener, SwipeHandler {
private static final int MAX_LINES = 5;
private static final int DEFAULT_LINES = 2;
@@ -96,6 +101,16 @@ public class SnackbarView implements InsetObserver.WindowInsetObserver {
}
};
+ private final SwipeGestureListenerImpl mSwipeGestureListener;
+ private final OnClickListener mDismissListener;
+ private final float mHorizontalTranslationPx;
+
+ private class SwipeGestureListenerImpl extends SwipeGestureListener {
+ public SwipeGestureListenerImpl(Context context, SwipeHandler handler) {
+ super(context, handler);
+ }
+ }
+
/**
* Creates an instance of the {@link SnackbarView}.
*
@@ -151,21 +166,15 @@ public class SnackbarView implements InsetObserver.WindowInsetObserver {
adjustViewPosition();
}
});
- SwipeGestureListener swipeGestureListener =
- new SwipeGestureListener(activity, mSnackbarSwipeHandler);
-
+ mSwipeGestureListener =
+ new SwipeGestureListenerImpl(mContainerView.getContext(), this);
// Make sure clicks are not consumed by content beneath the container view.
mContainerView.setClickable(true);
- mContainerView.setOnClickListener((event) -> manager.resetSnackbarTimeout());
- mContainerView.setOnTouchListener(
- (view, event) -> {
- if (swipeGestureListener.onTouchEvent(event)) return true;
- // Disable touch inputs during animation.
- if (mIsAnimating) return true;
- mContainerView.performClick();
- return true;
- });
-
+ if (!snackbar.isTypePersistent()) {
+ mContainerView.setOnTouchListener(this);
+ }
+ mDismissListener = dismissListener;
+ mHorizontalTranslationPx = mContainerView.getResources().getDisplayMetrics().widthPixels / 3;
mSnackbarView = mContainerView.findViewById(R.id.snackbar);
mAnimationDuration =
mContainerView.getResources().getInteger(android.R.integer.config_mediumAnimTime);
@@ -311,6 +320,60 @@ public class SnackbarView implements InsetObserver.WindowInsetObserver {
return mContainerView.isShown();
}
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ return mSwipeGestureListener.onTouchEvent(event);
+ }
+
+ private boolean mSwipeStarted;
+ private float mCurrentSwipePosition;
+
+ @Override
+ public void onSwipeStarted(@ScrollDirection int direction, MotionEvent ev) {
+ mContainerView.setTranslationX(0);
+ mSwipeStarted = true;
+ }
+
+ @Override
+ public void onSwipeUpdated(MotionEvent current, float tx, float ty, float dx, float dy) {
+ if (!mSwipeStarted) return;
+ mCurrentSwipePosition = Math.abs(tx);
+ mContainerView.setTranslationX(tx);
+ }
+
+ @Override
+ public void onSwipeFinished() {
+ if (!mSwipeStarted) return;
+ mSwipeStarted = false;
+ if (mCurrentSwipePosition >= mHorizontalTranslationPx) {
+ mDismissListener.onClick(mDismissButtonView);
+ return;
+ }
+ mContainerView.setTranslationX(0);
+ }
+
+ @Override
+ public void onFling(
+ @ScrollDirection int direction,
+ MotionEvent current,
+ float tx,
+ float ty,
+ float vx,
+ float vy) {
+ if (!mSwipeStarted) return;
+ mSwipeStarted = false;
+ if (mCurrentSwipePosition >= mHorizontalTranslationPx) {
+ mDismissListener.onClick(mDismissButtonView);
+ return;
+ }
+ mContainerView.setTranslationX(0);
+ }
+
+ @Override
+ public boolean isSwipeEnabled(@ScrollDirection int direction) {
+ return direction == ScrollDirection.LEFT || direction == ScrollDirection.RIGHT;
+ }
+
void bringToFront() {
mContainerView.bringToFront();
}
--