Window Manager Service

Overall idea

We want to be able to work with windows on a higher level than before. One important goal is to opt-in on the messages you get instead of being flooded.

The name of this service is window-manager.

BNF

Here is the grammar describing the data. Some of the following data elements are described in more detail.

This is the second version of the window-manager, version 2.

  ###
  # A grammar for listing and filtering windows
  #

  PROTOCOL ::= (COMMAND | EVENT)* ;

  COMMAND ::= GET-ACTIVE-WINDOW
            | LIST-WINDOWS
            | FILTER
            ;

  EVENT ::= LIST-WINDOWS-REPLY
          | ACTIVE-WINDOW
          | UPDATED-WINDOW
          | WINDOW-CLOSED
          | FILTER-REPLY        # Introduced in version 2
          ;

  ###
  # Commands. Sent from client.
  #

  # The default FILTER used to be INCLUDE "*".
  # After this command was introduced, the default filter is INCLUDE WINDOW-ID 0 (unknown).
  #
  # The filtering mechanism works by taking the appropriate window-id of the message and checks it.
  #   If the INCLUDE filter contains the window-id, or a window that has opened the window,
  #   and the window-id is not in the EXCLUDE filter,
  #     then send the message.
  #   Otherwise,
  #     discard the message
  #
  # INCLUDE and EXCLUDE appends to the existing filter. This is true whether these occur in the
  # same FILTER command or occur in different FILTER commands. If the CLEAR flag is present, the
  # filter will cleared before the INCLUDE and EXCLUDE appends to the filter.
  #
  # TODO: Perhaps FILTER should work on window types as well?

  FILTER ::= "<filter>"
               TAG?           # Introduced in version 2
               CLEAR?
               (INCLUDE | EXCLUDE)*
             "</filter>"
             ;

  INCLUDE ::= "<include>"
                PATTERN
              "</include>"
              ;

  EXCLUDE ::= "<exclude>"
                PATTERN
              "</exclude>"
              ;

  CLEAR ::= "<clear />" ;
  GET-ACTIVE-WINDOW ::= "<get-active-window />" ;
  LIST-WINDOWS ::= "<list-windows />" ;

  # The STRING can currently only have one value: "*", meaing all window-ids.
  # By default, the filter automatically includes windows that are opened from windows
  # in the INCLUDE filter. This can be prevented on a per-window basis by adding the
  # NOT-OPENED modifier.

  PATTERN ::= WINDOW-ID NOT-OPENED? | STRING ;

  NOT-OPENED ::= "<not-opened />" ;

  ###
  # Events. Sent from host.
  #

  # ACTIVE-WINDOW is sent whenever the active window is changed, or
  # if the COMMAND GET-ACTIVE-WINDOW is sent. In the latter case, the
  # ID might be 0, meaning the active window is unknown.

  ACTIVE-WINDOW ::= "<active-window>"
                      WINDOW-ID
                    "</active-window>"
                    ;

  #  WINDOW-LOADED is sent whenever a window has finished loading. This
  #  event happens after external resources are loaded. Note: if the page uses 
  #  scripting to dynamically change the page or load more data, this event may occur 
  #  multiple times for the same window. 

  WINDOW-LOADED ::= "<window-loaded>"
                      WINDOW-ID
                    "</window-loaded>"
                    ;
					
  LIST-WINDOWS-REPLY ::= "<list-windows-reply>"
                           WINDOW*
                         "</list-windows-reply>"
                         ;

  # This event will be sent every time there is a new window, or some window information changed.

  UPDATED-WINDOW ::= "<updated-window>"
                       WINDOW
                     "</updated-window>"
                     ;

  WINDOW-CLOSED ::= "<window-closed>"
                      WINDOW-ID
                    "</window-closed>"
                    ;

  # This event is sent as a reply to the FILTER command if the TAG was present.
  # Introduced in version 2:

  FILTER-REPLY ::= "<filter-reply>"
                     TAG
                     RESULT
                   "</filter-reply>" ;

  ###
  # Other data types
  #

  # TODO: We probably want a lot more information about each window, like URL, shortcut
  #       icon, etc.

  WINDOW ::= "<window>"
               WINDOW-ID
               TITLE
               WINDOW-TYPE
               OPENER-ID
             "</window>"
             ;

  # TODO: Some of these are obsolete, like "ad". Figure out which ones should really be present.

  WINDOW-TYPE ::= "<window-type>"
                  ( "normal"
                  | "download"
                  | "cache"
                  | "plugins"
                  | "history"
                  | "help"
                  | "mail_view"
                  | "mail_compose"
                  | "newsfeed_view"
                  | "ad"
                  | "im_view"
                  | "p2p_view"
                  | "brand_view"
                  | "print_selection"
                  | "js_console"
                  | "gadget"
                  | "controller"
                  | "info"
                  | "dialog"
                  | "thumbnail"
                  )
                  "</window-type>"
                  ;

  # The OPENER-ID is the WINDOW-ID of the window who opened the window in question,
  # or 0 if it was not opened by another window.

  OPENER-ID ::= "<opener-id>"
                  UNSIGNED
                "</opener-id>"
                ;

  TITLE ::= "<title>" TEXT "</title>" ;

  # This is the result of an operation. So far it is only used in FILTER-REPLY.
  # Introduced in version 2:
  
  RESULT ::= "<result>"
             ( "ok"               # everything went ok
             | "failed"           # failed for unknown reason
             | "parsing failed"   # data not according to BNF
             | "not supported"    # data according to BNF, but used in an unsupported way
             )
             "</result>" ;

  ###
  # Identifiers stolen from the ECMAScript debugger protocol:
  #

  WINDOW-ID ::= "<window-id>" UNSIGNED "</window-id>" ;
  UNSIGNED ::= [0-9]+ ;
  STRING ::= "<string>" TEXT "</string>" ;
  TEXT ::= BASE64-ENCODED-DATA | textual-data ;
  TAG ::= "<tag>" UNSIGNED "</tag>" ;
  BASE64-ENCODED-DATA ::= "<base64-encoded-data>" textual-data "</base64-encoded-data>" ;

Discussion

This protocol will prevent a lot of flooding from the other services, but it will on the other hand flood a bit itself. There is no way to stop it from sending ACTIVE-WINDOW messages for example.

When Opera Dragonfly is used to debug on the desktop, it probably doesn't want to use this service at all, but just have the filters automatically set to include the active window. We might cater for this later. The way to do it with the current protocol would be to retrieve the active window and put that in the include filter manually. However the active window might have changed by the time Opera Dragonfly gets to do that. Additionally, we would like Opera Dragonfly to start with a certain DOM node selected. I see no other way than adding some C++ hooks to do this when debugging locally.