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 .
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 ). 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 . Everything else,
including BrowserApp, should continue to use the global EventDispatcher,
because the majority of existing code only cope well with the global
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 .
My slides from the Taipei work week  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!
 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.
 `EventDispatcher.for` accepts a `window` argument, which should be a
global window object in a chrome JS script.
 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).
 e.g. `let win =
Services.wm.getMostRecentWindow("navigator:browser");` and then use
`win.GlobalEventDispatcher` or `win.WindowEventDispatcher`.
mobile-firefox-dev mailing list