diff --git a/app/src/common/shared/com/igalia/wolvic/VRBrowserActivity.java b/app/src/common/shared/com/igalia/wolvic/VRBrowserActivity.java index c66292c851d..cdbcca47145 100644 --- a/app/src/common/shared/com/igalia/wolvic/VRBrowserActivity.java +++ b/app/src/common/shared/com/igalia/wolvic/VRBrowserActivity.java @@ -1115,12 +1115,16 @@ void handleScrollEvent(final int aHandle, final int aDevice, final float aX, fin if (!isWidgetInputEnabled(widget)) { return; } - if (widget != null) { - float scrollDirection = mSettings.getScrollDirection() == 0 ? 1.0f : -1.0f; - MotionEventGenerator.dispatchScroll(widget, aDevice, true,aX * scrollDirection, aY * scrollDirection); - } else { - Log.e(LOGTAG, "Failed to find widget for scroll event: " + aHandle); + if (widget == null) { + if (getNavigationBar().isInVRVideo()) { + widget = getNavigationBar().getMediaControlsWidget(); + } else { + Log.e(LOGTAG, "Failed to find widget for scroll event: " + aHandle); + return; + } } + float scrollDirection = mSettings.getScrollDirection() == 0 ? 1.0f : -1.0f; + MotionEventGenerator.dispatchScroll(widget, aDevice, true,aX * scrollDirection, aY * scrollDirection); }); } diff --git a/app/src/common/shared/com/igalia/wolvic/ui/widgets/MediaControlsWidget.java b/app/src/common/shared/com/igalia/wolvic/ui/widgets/MediaControlsWidget.java index 920b7ae2130..9af6735cd11 100644 --- a/app/src/common/shared/com/igalia/wolvic/ui/widgets/MediaControlsWidget.java +++ b/app/src/common/shared/com/igalia/wolvic/ui/widgets/MediaControlsWidget.java @@ -12,6 +12,7 @@ import android.os.Looper; import android.util.AttributeSet; import android.view.LayoutInflater; +import android.view.MotionEvent; import android.view.View; import android.widget.FrameLayout; @@ -89,19 +90,9 @@ private void updateUI() { mBinding.mediaPlayButton.requestFocusFromTouch(); }); - mBinding.mediaSeekBackwardButton.setOnClickListener(v -> { - mMedia.seek(Math.max(0, mMedia.getCurrentTime() - 10.0f)); - mBinding.mediaSeekBackwardButton.requestFocusFromTouch(); - }); + mBinding.mediaSeekBackwardButton.setOnClickListener(v -> seekBackward()); - mBinding.mediaSeekForwardButton.setOnClickListener(v -> { - double t = mMedia.getCurrentTime() + 30; - if (mMedia.getDuration() > 0) { - t = Math.min(mMedia.getDuration(), t); - } - mMedia.seek(t); - mBinding.mediaSeekForwardButton.requestFocusFromTouch(); - }); + mBinding.mediaSeekForwardButton.setOnClickListener(v -> seekForward()); mBinding.mediaProjectionButton.setOnClickListener(v -> { WidgetPlacement placement = mProjectionMenu.getPlacement(); @@ -267,6 +258,36 @@ else if ((event.getX() <= 0) || (event.getX() >= v.getWidth()) || (!(event.getY( }); } + private void seekForward() { + double t = mMedia.getCurrentTime() + 30; + if (mMedia.getDuration() > 0) { + t = Math.min(mMedia.getDuration(), t); + } + mMedia.seek(t); + mBinding.mediaSeekForwardButton.requestFocusFromTouch(); + } + + private void seekBackward() { + mMedia.seek(Math.max(0, mMedia.getCurrentTime() - 10.0f)); + mBinding.mediaSeekBackwardButton.requestFocusFromTouch(); + } + + @Override + public void handleHoverEvent(MotionEvent aEvent) { + if (aEvent.getAction() == MotionEvent.ACTION_SCROLL) { + setVisible(true); + + final float aX = aEvent.getAxisValue(MotionEvent.AXIS_HSCROLL); + final float aY = aEvent.getAxisValue(MotionEvent.AXIS_VSCROLL); + + if (aX > 0) { + seekForward(); + } else { + seekBackward(); + } + } + } + @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); diff --git a/app/src/common/shared/com/igalia/wolvic/ui/widgets/NavigationBarWidget.java b/app/src/common/shared/com/igalia/wolvic/ui/widgets/NavigationBarWidget.java index 4c8b5d93084..e289336d60b 100644 --- a/app/src/common/shared/com/igalia/wolvic/ui/widgets/NavigationBarWidget.java +++ b/app/src/common/shared/com/igalia/wolvic/ui/widgets/NavigationBarWidget.java @@ -78,6 +78,7 @@ import com.igalia.wolvic.utils.UrlUtils; import java.util.ArrayList; +import java.util.Objects; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicBoolean; @@ -454,6 +455,10 @@ public void onExcludedTrackingProtectionChange(@NonNull String url, boolean excl } }; + public MediaControlsWidget getMediaControlsWidget() { + return mMediaControlsWidget; + } + @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); @@ -694,6 +699,10 @@ public void onMediaFullScreen(@NonNull WMediaSession mediaSession, boolean aFull } } + public boolean isInVRVideo() { + return Objects.requireNonNull(mViewModel.getIsInVRVideo().getValue()).get(); + } + @Override public void onKioskMode(WindowWidget aWindow, boolean isKioskMode) { mTrayViewModel.setShouldBeVisible(!isKioskMode); diff --git a/app/src/main/cpp/BrowserWorld.cpp b/app/src/main/cpp/BrowserWorld.cpp index ea97ec14e44..7bfe6d29214 100644 --- a/app/src/main/cpp/BrowserWorld.cpp +++ b/app/src/main/cpp/BrowserWorld.cpp @@ -256,6 +256,7 @@ struct BrowserWorld::State { void UpdateControllers(bool& aRelayoutWidgets); void SimulateBack(); void ClearWebXRControllerData(); + void HandleControllerScroll(Controller& controller, int handle); WidgetPtr GetWidget(int32_t aHandle) const; WidgetPtr FindWidget(const std::function& aCondition) const; bool IsParent(const Widget& aChild, const Widget& aParent) const; @@ -612,19 +613,7 @@ BrowserWorld::State::UpdateControllers(bool& aRelayoutWidgets) { controller.pointerY = theY; VRBrowser::HandleMotionEvent(handle, controller.index, jboolean(controller.focused), jboolean(pressed), controller.pointerX, controller.pointerY); } - if ((controller.scrollDeltaX != 0.0f) || controller.scrollDeltaY != 0.0f) { - if (controller.scrollStart < 0.0) { - controller.scrollStart = context->GetTimestamp(); - } - const double ctime = context->GetTimestamp(); - VRBrowser::HandleScrollEvent(controller.widget, controller.index, - ScaleScrollDelta(controller.scrollDeltaX, controller.scrollStart, ctime), - ScaleScrollDelta(controller.scrollDeltaY, controller.scrollStart, ctime)); - controller.scrollDeltaX = 0.0f; - controller.scrollDeltaY = 0.0f; - } else { - controller.scrollStart = -1.0; - } + HandleControllerScroll(controller, controller.widget); if (!pressed) { if (controller.touched) { if (!controller.wasTouched) { @@ -649,6 +638,7 @@ BrowserWorld::State::UpdateControllers(bool& aRelayoutWidgets) { } else if (wasPressed != pressed) { VRBrowser::HandleMotionEvent(0, controller.index, jboolean(controller.focused), (jboolean) pressed, 0.0f, 0.0f); } else if (vrVideo != nullptr) { + HandleControllerScroll(controller, -1); const bool togglePressed = controller.buttonState & ControllerDelegate::BUTTON_X || controller.buttonState & ControllerDelegate::BUTTON_A; const bool toggleWasPressed = controller.lastButtonState & ControllerDelegate::BUTTON_X || @@ -680,6 +670,23 @@ BrowserWorld::State::UpdateControllers(bool& aRelayoutWidgets) { } } +void +BrowserWorld::State::HandleControllerScroll(Controller& controller, int handle) { + if ((controller.scrollDeltaX != 0.0f) || controller.scrollDeltaY != 0.0f) { + if (controller.scrollStart < 0.0) { + controller.scrollStart = context->GetTimestamp(); + } + const double ctime = context->GetTimestamp(); + VRBrowser::HandleScrollEvent(handle, controller.index, + ScaleScrollDelta(controller.scrollDeltaX, controller.scrollStart, ctime), + ScaleScrollDelta(controller.scrollDeltaY, controller.scrollStart, ctime)); + controller.scrollDeltaX = 0.0f; + controller.scrollDeltaY = 0.0f; + } else { + controller.scrollStart = -1.0; + } +} + void BrowserWorld::State::ClearWebXRControllerData() { for (Controller& controller: controllers->GetControllers()) {