Hi all,

Bug 1307820 and bug 1317604 introduced some big changes to EventDispatcher recently. I talked about these topics at the Taipei work week, but haven't sent out an email about these changes yet.

EventDispatcher is now fully unified across Gecko and Java, meaning not only can you dispatch events Gecko => Java and Java => Java like before, but you can also dispatch events Java => Gecko and Gecko => Gecko, with full callback support. "Java" here means Java code running on the Gecko/UI/background thread, and "Gecko" here means JS/native code running on the Gecko thread.

Previously, the only good way to interact with JS from Java is to use XPCOM observers and GeckoAppShell.notifyObservers. Now you can use the same EventDispatcher.dispatch call on the Java side to dispatch events to JS. On the JS side, Messaging.jsm now exports `EventDispatcher`, which is an analog of the Java EventDispatcher. For example, use `EventDispatcher.instance.registerListener` and `.unregisterListener` to register/unregister listeners on the JS side.

As part of this change, BundleEventListener is now the only supported event listener type in Java, and GeckoEventListener and NativeEventListener are both deprecated. BundleEventListener now uses org.mozilla.gecko.util.GeckoBundle instead of Bundle. GeckoBundle has mostly the same interface as Bundle, but fixes several pitfalls when using Bundle to represent JS objects [1].

In addition to the global EventDispatcher (accessible through `EventDispatcher.getInstance` in Java and `EventDispatcher.instance` in JS), each GeckoView instance now has its own independent EventDispatcher (accessible through `GeckoView.getEventDispatcher` in Java and `EventDispatcher.for` in JS [2]). Having a per-GeckoView EventDispatcher makes it a lot easier to support multiple GeckoView instances. Note that the various EventDispatcher instances are totally separate from each other, and don't interact with each other in any way.

For Fennec Java code, anything in GeckoApp or included from GeckoApp should now use the per-GeckoView EventDispatcher [3]. Everything else, including BrowserApp, should continue to use the global EventDispatcher, because the majority of existing code only cope well with the global instance.

For Fennec JS code, use `GlobalEventDispatcher` and `WindowEventDispatcher` as shortcuts if you're inside browser.js or a script included from browser.js. Outside of browser.js, use Messaging.jsm directly, or find the browser window first [4].

My slides from the Taipei work week [5] include some more explanations of the new EventDispatcher, along with code samples in Java and JS. Feel free to contact me if you have further questions. Thanks!


[1] e.g. Bundle distinguishes between int and double, whereas a JS object doesn't; GeckoBundle will automatically convert between int and double if necessary to avoid type mismatching.

[2] `EventDispatcher.for` accepts a `window` argument, which should be a global window object in a chrome JS script.

[3] GeckoApp exposes the per-GeckoView EventDispatcher through GeckoApp.getAppEventDispatcher (instance method for when you have a GeckoApp instance) or GeckoApp.getEventDispatcher (static method for when you don't have a direct GeckoApp instance).

[4] e.g. `let win = Services.wm.getMostRecentWindow("navigator:browser");` and then use `win.GlobalEventDispatcher` or `win.WindowEventDispatcher`.

[5] https://docs.google.com/presentation/d/1u9KtHjio34BOagGaDNqA7lWhTY5PEpMQ-ztl_oLn-48/edit?usp=sharing#slide=id.g194a71d8b9_1_113
mobile-firefox-dev mailing list

Reply via email to