Skip to content
This repository has been archived by the owner on Jul 22, 2024. It is now read-only.

Commit

Permalink
Improved focus handling (#608)
Browse files Browse the repository at this point in the history
* Improved focus handling

* Added focus change events when clicked outside a widget

* Check if motion event is in pressed state

* Hanlding of clicking on the env. Better handling of focus in listview.
  • Loading branch information
keianhzo authored and MortimerGoro committed Oct 10, 2018
1 parent 93ece9d commit 0ad0545
Show file tree
Hide file tree
Showing 19 changed files with 277 additions and 146 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class MotionEventGenerator {
static class Device {
int mDevice;
Widget mPreviousWidget = null;
Widget mTouchStartWidget = null;
boolean mWasPressed;
long mDownTime;
MotionEvent.PointerProperties mProperties[];
Expand Down Expand Up @@ -78,28 +79,30 @@ static void dispatch(Widget aWidget, int aDevice, boolean aPressed, float aX, fl
device.mCoords[0].pressure = 0.0f;
}
}
if ((device.mPreviousWidget != null) && (device.mPreviousWidget != aWidget)) {
if (!aPressed && (device.mPreviousWidget != null) && (device.mPreviousWidget != aWidget)) {
if (device.mWasPressed) {
generateEvent(device.mPreviousWidget, device, MotionEvent.ACTION_CANCEL, false);
device.mWasPressed = false;
}
generateEvent(device.mPreviousWidget, device, MotionEvent.ACTION_HOVER_EXIT, true);
device.mPreviousWidget = null;
}
if (aWidget == null) {
device.mPreviousWidget = null;
return;
}
if (aWidget != device.mPreviousWidget) {
if (aWidget != device.mPreviousWidget && !aPressed) {
generateEvent(aWidget, device, MotionEvent.ACTION_HOVER_ENTER, true);
}
if (aPressed && !device.mWasPressed) {
device.mDownTime = SystemClock.uptimeMillis();
device.mWasPressed = true;
generateEvent(aWidget, device, MotionEvent.ACTION_HOVER_EXIT, true);
generateEvent(aWidget, device, MotionEvent.ACTION_DOWN, false);
device.mTouchStartWidget = aWidget;
} else if (!aPressed && device.mWasPressed) {
device.mWasPressed = false;
generateEvent(aWidget, device, MotionEvent.ACTION_UP, false);
generateEvent(device.mTouchStartWidget, device, MotionEvent.ACTION_UP, false);
generateEvent(aWidget, device, MotionEvent.ACTION_HOVER_ENTER, true);
} else if (moving && aPressed) {
generateEvent(aWidget, device, MotionEvent.ACTION_MOVE, false);
Expand Down
51 changes: 38 additions & 13 deletions app/src/common/shared/org/mozilla/vrbrowser/VRBrowserActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import android.support.annotation.Keep;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
Expand Down Expand Up @@ -81,14 +82,16 @@ public void run() {
Handler mHandler = new Handler();
Runnable mAudioUpdateRunnable;
BrowserWidget mBrowserWidget;
RootWidget mRootWidget;
KeyboardWidget mKeyboard;
NavigationBarWidget mNavigationBar;
CrashDialogWidget mCrashDialog;
TopBarWidget mTopBar;
TrayWidget mTray;
PermissionDelegate mPermissionDelegate;
LinkedList<WidgetManagerDelegate.Listener> mWidgetEventListeners;
LinkedList<WidgetManagerDelegate.PermissionListener> mPermissionListeners;
LinkedList<UpdateListener> mWidgetUpdateListeners;
LinkedList<PermissionListener> mPermissionListeners;
LinkedList<FocusChangeListener> mFocusChangeListeners;
LinkedList<Runnable> mBackHandlers;
private boolean mIsPresentingImmersive = false;
private Thread mUiThread;
Expand All @@ -114,17 +117,19 @@ protected void onCreate(Bundle savedInstanceState) {
mLastGesture = NoGesture;
super.onCreate(savedInstanceState);

mWidgetEventListeners = new LinkedList<>();
mWidgetUpdateListeners = new LinkedList<>();
mPermissionListeners = new LinkedList<>();
mFocusChangeListeners = new LinkedList<>();
mBackHandlers = new LinkedList<>();

mWidgets = new HashMap<>();
mWidgetContainer = new FrameLayout(this);
mWidgetContainer.getViewTreeObserver().addOnGlobalFocusChangeListener(new ViewTreeObserver.OnGlobalFocusChangeListener() {
@Override
public void onGlobalFocusChanged(View oldFocus, View newFocus) {
if (mKeyboard != null) {
mKeyboard.updateFocusedView(newFocus);
Log.d(LOGTAG, "======> OnGlobalFocusChangeListener: old(" + oldFocus + ") new(" + newFocus + ")");
for (FocusChangeListener listener: mFocusChangeListeners) {
listener.onGlobalFocusChanged(oldFocus, newFocus);
}
}
});
Expand Down Expand Up @@ -187,10 +192,13 @@ protected void initializeWorld() {
mTopBar = new TopBarWidget(this);
mTopBar.setBrowserWidget(mBrowserWidget);

// Empty widget just for handling focus on empty space
mRootWidget = new RootWidget(this);

// Create Tray
mTray = new TrayWidget(this);

addWidgets(Arrays.<Widget>asList(mBrowserWidget, mNavigationBar, mKeyboard, mTray));
addWidgets(Arrays.<Widget>asList(mRootWidget, mBrowserWidget, mNavigationBar, mKeyboard, mTray));
}

@Override
Expand Down Expand Up @@ -418,7 +426,12 @@ void handleMotionEvent(final int aHandle, final int aDevice, final boolean aPres
@Override
public void run() {
Widget widget = mWidgets.get(aHandle);
MotionEventGenerator.dispatch(widget, aDevice, aPressed, aX, aY);
if (widget == null) {
MotionEventGenerator.dispatch(mRootWidget, aDevice, aPressed, aX, aY);

} else {
MotionEventGenerator.dispatch(widget, aDevice, aPressed, aX, aY);
}
}
});
}
Expand Down Expand Up @@ -685,7 +698,7 @@ public void run() {
view.setVisibility(visible ? View.VISIBLE : View.GONE);
}

for (WidgetManagerDelegate.Listener listener: mWidgetEventListeners) {
for (UpdateListener listener: mWidgetUpdateListeners) {
listener.onWidgetUpdate(aWidget);
}

Expand Down Expand Up @@ -725,15 +738,15 @@ public void run() {
}

@Override
public void addListener(WidgetManagerDelegate.Listener aListener) {
if (!mWidgetEventListeners.contains(aListener)) {
mWidgetEventListeners.add(aListener);
public void addUpdateListener(UpdateListener aUpdateListener) {
if (!mWidgetUpdateListeners.contains(aUpdateListener)) {
mWidgetUpdateListeners.add(aUpdateListener);
}
}

@Override
public void removeListener(WidgetManagerDelegate.Listener aListener) {
mWidgetEventListeners.remove(aListener);
public void removeUpdateListener(UpdateListener aUpdateListener) {
mWidgetUpdateListeners.remove(aUpdateListener);
}

@Override
Expand All @@ -748,6 +761,18 @@ public void removePermissionListener(PermissionListener aListener) {
mPermissionListeners.remove(aListener);
}

@Override
public void addFocusChangeListener(FocusChangeListener aListener) {
if (!mFocusChangeListeners.contains(aListener)) {
mFocusChangeListeners.add(aListener);
}
}

@Override
public void removeFocusChangeListener(FocusChangeListener aListener) {
mFocusChangeListeners.remove(aListener);
}

@Override
public void pushBackHandler(Runnable aRunnable) {
mBackHandlers.addLast(aRunnable);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,37 @@
package org.mozilla.vrbrowser;

import android.support.annotation.Nullable;
import android.support.annotation.NonNull;
import android.view.View;

public interface WidgetManagerDelegate {
interface Listener {
interface UpdateListener {
void onWidgetUpdate(Widget aWidget);
}
interface PermissionListener {
void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults);
}
interface FocusChangeListener {
void onGlobalFocusChanged(View oldFocus, View newFocus);
}
int newWidgetHandle();
void addWidget(Widget aWidget);
void updateWidget(Widget aWidget);
void removeWidget(Widget aWidget);
void startWidgetResize(Widget aWidget);
void finishWidgetResize(Widget aWidget);
void addListener(WidgetManagerDelegate.Listener aListener);
void removeListener(WidgetManagerDelegate.Listener aListener);
void pushBackHandler(Runnable aRunnable);
void popBackHandler(Runnable aRunnable);
void addWidget(@NonNull Widget aWidget);
void updateWidget(@NonNull Widget aWidget);
void removeWidget(@NonNull Widget aWidget);
void startWidgetResize(@NonNull Widget aWidget);
void finishWidgetResize(@NonNull Widget aWidget);
void addUpdateListener(@NonNull UpdateListener aUpdateListener);
void removeUpdateListener(@NonNull UpdateListener aUpdateListener);
void pushBackHandler(@NonNull Runnable aRunnable);
void popBackHandler(@NonNull Runnable aRunnable);
void fadeOutWorld();
void fadeInWorld();
void setTrayVisible(boolean visible);
void setBrowserSize(float targetWidth, float targetHeight);
void keyboardDismissed();
void updateEnvironment();
void updatePointerColor();
void addPermissionListener(PermissionListener aListener);
void removePermissionListener(PermissionListener aListener);
void addPermissionListener(@NonNull PermissionListener aListener);
void removePermissionListener(@NonNull PermissionListener aListener);
void addFocusChangeListener(@NonNull FocusChangeListener aListener);
void removeFocusChangeListener(@NonNull FocusChangeListener aListener);
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public BrowserWidget(Context aContext, int aSessionId) {
mWidgetManager = (WidgetManagerDelegate) aContext;
SessionStore.get().addSessionChangeListener(this);
SessionStore.get().addPromptListener(this);
setFocusableInTouchMode(true);
setFocusable(true);
GeckoSession session = SessionStore.get().getSession(mSessionId);
if (session != null) {
session.getTextInput().setView(this);
Expand Down Expand Up @@ -140,8 +140,9 @@ public WidgetPlacement getPlacement() {

@Override
public void handleTouchEvent(MotionEvent aEvent) {
if (aEvent.getActionMasked() == MotionEvent.ACTION_DOWN) {
if (aEvent.getActionMasked() == MotionEvent.ACTION_UP) {
requestFocus();
requestFocusFromTouch();
}
GeckoSession session = SessionStore.get().getSession(mSessionId);
if (session == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -332,15 +332,15 @@ protected void initializeWidgetPlacement(WidgetPlacement aPlacement) {
}

private void showRestartDialog() {
hide();

UIWidget widget = getChild(mRestartDialogHandle);
if (widget == null) {
widget = createChild(RestartDialogWidget.class, false);
mRestartDialogHandle = widget.getHandle();
}

widget.show();

hide();
}

private CompoundButton.OnCheckedChangeListener mRemoteDebuggingListener = new CompoundButton.OnCheckedChangeListener() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,14 @@
import org.mozilla.geckoview.GeckoSession;
import org.mozilla.vrbrowser.R;
import org.mozilla.vrbrowser.SessionStore;
import org.mozilla.vrbrowser.Widget;
import org.mozilla.vrbrowser.WidgetManagerDelegate;
import org.mozilla.vrbrowser.WidgetPlacement;
import org.mozilla.vrbrowser.telemetry.TelemetryWrapper;


public class KeyboardWidget extends UIWidget implements CustomKeyboardView.OnKeyboardActionListener, GeckoSession.TextInputDelegate {
public class KeyboardWidget extends UIWidget implements CustomKeyboardView.OnKeyboardActionListener,
GeckoSession.TextInputDelegate, WidgetManagerDelegate.FocusChangeListener {

private static final String LOGTAG = "VRB";

Expand Down Expand Up @@ -80,6 +83,8 @@ public KeyboardWidget(Context aContext, AttributeSet aAttrs, int aDefStyle) {
private void initialize(Context aContext) {
inflate(aContext, R.layout.keyboard, this);

mWidgetManager.addFocusChangeListener(this);

mKeyboardview = findViewById(R.id.keyboard);
mPopupKeyboardview = findViewById(R.id.popupKeyboard);
mVoiceInput = findViewById(R.id.keyboard_microphone);
Expand Down Expand Up @@ -177,6 +182,7 @@ public void run() {

@Override
public void releaseWidget() {
mWidgetManager.removeFocusChangeListener(this);
SessionStore.get().removeTextInputListener(this);
mBrowserWidget = null;
super.releaseWidget();
Expand Down Expand Up @@ -599,4 +605,11 @@ public void updateCursorAnchorInfo(@NonNull GeckoSession session, @NonNull Curso
public void notifyAutoFill(GeckoSession session, int notification, int virtualId) {

}

// FocusChangeListener

@Override
public void onGlobalFocusChanged(View oldFocus, View newFocus) {
updateFocusedView(newFocus);
}
}
Loading

0 comments on commit 0ad0545

Please sign in to comment.