rdkcentral / Lightning-SDK

SDK for Lightning framework
Apache License 2.0
130 stars 69 forks source link

Widget state not working on Android TV #339

Closed MLangendijk closed 2 years ago

MLangendijk commented 2 years ago

I'm currently working on getting an app going on Android TV (through a Webview), and noticed an issue when switching focus to a Widget. Focus briefly shifts to the specified Widget, and after several milliseconds it puts focus back to the regular Page content. The same app and code works fine on both LG and Samsung televisions, so this seems isolated to Android TV.

How to reproduce

  1. Define a Widget on an App extended from Router.App static _template() { return { ...super._template(), Widgets: { Menu: { type: Menu },

  2. Attempt to focus the widget from a separate page (e.g. Home.js) --> Router.focusWidget('menu')

  3. Notice that focus shifts briefly to the Menu Widget, before shifting back to the Page

While this issue likely has a cause in the StateMachine implementation, it's in the end caused by the SDKs Router. If you feel this issue should be moved, or need more information, by all means ask away.

For reference, this was tested and confirmed to be an issue on a Sony TV from 2017 and an Nvidia Shield 2019.

MLangendijk commented 2 years ago

While debugging I noticed that they key handler was executed twice, and in this case for a key that wasn't actually handled. This resulted in the following function being executed on the Widget state:

_handleKey() {
          const restoreFocus = routerConfig.get('autoRestoreRemote')
          /**
           * The Router used to delegate focus back to the page instance on
           * every unhandled key. This is barely usefull in any situation
           * so for now we offer the option to explicity turn that behaviour off
           * so we don't don't introduce a breaking change.
           */
          if (!isBoolean(restoreFocus) || restoreFocus === true) {
            Router.focusPage()
          }

The reason the handler was executed twice, is because my Webview triggers a dispatch keydown event on the DOM; while I suspect the Canvas itself also gets the key events triggered on its own, which were not prevented from being dispatched by the webview. This caused duplicate keydown events to be triggered, resulting in the situation as described above. Removing keydown from being dispatched by the webview fixed this issue.