Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import android.content.res.Configuration;
import android.text.Editable;
import android.util.AttributeSet;
import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
Expand Down Expand Up @@ -59,6 +60,7 @@ public class FermataWebView extends WebView
private WebBrowserAddon addon;
private FermataWebClient webClient;
private FermataChromeClient chrome;
private boolean keyNavigation;

public FermataWebView(Context context) {
this(context, null);
Expand Down Expand Up @@ -239,12 +241,50 @@ protected void pageLoaded(String uri) {
});
}

@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if ((event.getAction() == KeyEvent.ACTION_DOWN) && isNavigationKey(event.getKeyCode())) {
onKeyNavigation();
}
return super.dispatchKeyEvent(event);
}

@Override
public boolean dispatchGenericMotionEvent(MotionEvent event) {
// Some rotary controllers turn as scroll events rather than keys
if ((event.getAction() == MotionEvent.ACTION_SCROLL) &&
event.isFromSource(InputDevice.SOURCE_ROTARY_ENCODER)) {
onKeyNavigation();
}
return super.dispatchGenericMotionEvent(event);
}

private static boolean isNavigationKey(int code) {
return switch (code) {
case KeyEvent.KEYCODE_DPAD_UP, KeyEvent.KEYCODE_DPAD_DOWN, KeyEvent.KEYCODE_DPAD_LEFT,
KeyEvent.KEYCODE_DPAD_RIGHT, KeyEvent.KEYCODE_DPAD_CENTER, KeyEvent.KEYCODE_TAB,
KeyEvent.KEYCODE_NAVIGATE_NEXT, KeyEvent.KEYCODE_NAVIGATE_PREVIOUS -> true;
default -> false;
};
}

// The highlight is for key navigation (D-pad, rotary controller): add it on the first such input.
// It then stays for this view's lifetime, as the same controller keeps being used.
private void onKeyNavigation() {
if (keyNavigation) return;
keyNavigation = true;
addFocusHighlight();
}

protected void addFocusHighlight() {
if (!keyNavigation) return;
evaluateJavascript("""
(function() {
if (document.getElementById('fermata-focus')) return;
var style = document.createElement('style');
style.innerHTML = ':focus {outline: 2px solid blue !important; border-radius: 5px;}';
document.head.appendChild(style);
style.id = 'fermata-focus';
style.textContent = ':focus-visible {outline: 2px solid blue !important; border-radius: 5px;}';
(document.head || document.documentElement).appendChild(style);
})()""", null);
}

Expand Down
Loading