5.0 Changes that will affect macro's and extensions

Posted by shanec on 2008-07-11 13:23

Hello everyone,
We're well into the cycle on 5.0 and I thought I would take a moment to mention some of the under-the-hood changes that will be happening.

One of the often requested features is the ability to have multiple windows open, or to move tabs to different locations in the UI. I'm not making any promises on those actually making it into 5.0, but we are devoting time to some structural issues that prevent the ability to do this in 4.x.

One significant item is that we're removing a lot of our usage of observers and moving them into DOM events. Observers and notifications are global to the application, whereas DOM events are local to the window's DOM. Early on we had always designed for a single main window, and the observer system was an easy way to communicate things like a new buffer being opened, or one being closed.

Here's an example of what you would do in Komodo 4.0 to watch for the current buffer being changed (ie. switching to a different file in the editor tabs).

var obs = {
  observe: function(subject, topic, data) {
    if (topic=="current_view_changed") {
      // do something
      var view = subject;
    }
  }
};
var observerSvc = Components.classes["@mozilla.org/observer-service;1"].
                        getService(Components.interfaces.nsIObserverService);
observerSvc.addObserver(obs, "current_view_changed",false);
// remember to removeObserver later or risk leaks

And here is how you will do it in Komodo 5.0:

function viewChanged(event) {
   var view = event.originalTarget;
}
window.addEventListener("current_view_changed", viewChanged, false);
// remember to removeEventListener later or risk leaks

We will likely be able to have automatic compatibility for macro's that are using the new observer functionality in 4.4. Anyone who has written macros that use the observer service directly will have to change, as will any extensions that observe on any of our notifications. More details on this will be provided in the future.

So how will this help in the future to provide more flexible UI? We isolate events into the window they happen in, allowing for multiple main windows that only receive events that are important to them. This is essentially what Firefox does in a bunch of places. While this doesn't solve the issue of actually implementing coherent multi-window support or the ability to move UI elements around, it does make it possible to go down that road at some point.

If any macro/extension authors have thoughts around this, we'd be happy to hear from you.

Regards,
Shane

dafi | Sat, 2008-07-12 00:29

Related to Notifications document only the "View notifications" (the UI layer) paragraph requires modification.
I suppose the other notifications continue to use the observer approach.

--
dafi
Enhance KomodoEdit with MoreKomodo

dafi | Sat, 2008-07-12 01:59

Should be useful to "re-route" listener to existing observer code.

My humble approach is shown below, it uses only one listener for all view events.

var gTestKomodo5 = {
    observe : function(subject, topic, data) {
        switch (topic) {
            case "current_view_changed":
                // ...
                break;
            case "current_view_encoding_changed":
                // ...
                break;
            // ...
            // ...
        }
    },
   
    listenerToObserver : function(event) {
        var subject = event.originalTarget;
        var topic = event.type;
        var data = null;
        this.observe(subject, topic, data);
    }
}

window.addEventListener("current_view_changed", function(event) {gTestKomodo5.listenerToObserver(event);}, false);
window.addEventListener("current_view_encoding_changed", function(event) {gTestKomodo5.listenerToObserver(event);}, false);
window.addEventListener("current_view_linecol_changed", function(event) {gTestKomodo5.listenerToObserver(event);}, false);

shanec
ActiveState Staff
Sat, 2008-07-12 09:58

Observers have different arguments than event handlers.

void observe(nsISupports subject, string topic, wstring data);
(see http://mxr.mozilla.org/mozilla/source/xpcom/ds/nsIObserver.idl)

vs.

void handleEvent(in nsIDOMEvent event);
(see http://mxr.mozilla.org/mozilla/source/dom/public/idl/events/nsIDOMEventL...)

So it is not a direct translation the way you're looking at it. I suppose you could do the following, but you loose some capability (such as canceling an event, etc):

window.addEventListener("current_view_changed", function(event) {gTestKomodo5.listenerToObserver(event.originalTarget, "current_view_changed", "");}, false);

shanec
ActiveState Staff
Sat, 2008-07-12 10:00

I obviously didn't digest your code, yes it would work.

dafi | Sat, 2008-07-12 10:08

My code was intended only for existing extensions to modify only a few of lines of code.
Actually using observer you don't need to cancel events.

BTW You are right

best regards,

davide

ericp
ActiveState Staff
Sun, 2008-07-20 15:41

Events are one-to-one in terms of windows. So when an event is fired,
only the objects that are listening on that event, and by default are
in the same window as the event source, will receive it. When you
convert an event into a notification like that, objects on other windows
will respond to that event. Chances are, you don't want that to happen.

For example, if you transfer a 'current_view_changed' event to a notification,
all open windows will display the new view, for example, when you only
want this to happen only in the window where the current view changed.

We're tracking all the changes, and will document how to deal with them.