WindowCommander Module

Introduction

The windowcommander module provides interfaces to the Opera core code to be used by the product and user interface specific code. OpWindowCommander is an API that user interface code uses to instruct core to load and display content into a window.

Diagrams

The following diagram shows a conceptual description of the WindowCommander interface:

Run doxygen to generate the diagram from the Dot sources.
WindowCommander overview.

Design principles

Listeners

The windowcommander code uses listeners heavily to allow callbacks into the code using its interfaces. The listener design principle is described here.

The burger model

See the burger model, to understand the relationship between windowcommander, core and the pi module.

Envelope of Change

API documentation

Go to the API documentation, generated with Doxygen.

WindowCommander interfaces

The OpWindowCommander and the related interfaces work as the interface between core windows and the UI. The OpWindowCommander interface allow the UI code to do operations on the core windows and the different listener interfaces enables the UI to be notified on certain events happening inside the core window.

OpWindowCommanderManager

This interface is there for managing OpWindowCommander objects. There are two ways a UI window can be created. It can be initiated from the UI, or from the core.

When the creation of a new UI window is initiated from the UI side, e.g. when the user clicks the New icon on the toolbar, the UI will need to create an OpWindowCommander object by calling GetWindowCommander on the OpWindowCommanderManager interface, then create an OpWindow to have a platform specific window to be used by the core, and finally tell the core about the new window by calling OnUiWindowCreated on the newly created OpWindowCommander.

When the creation of a new UI window is initiated from the core, the core will create an OpWindowCommander interface object for it and call CreateUiWindow on the OpUiWindowListener. The UI is responsible for creating an OpWindow and tell the core about it through OnUiWindowCreated. An example of a new UI window created from core is when opening Javascript pop-ups.

OpWindowCommanderManager also provides the functionality for authentication. The reason why this functionality is put here, is that authentication of URLs is not necessarily related to a specific window, and hence not a specific OpWindowCommander. One example is the authentication of URLs loaded by the JavaResourceHandler.

OpWindowCommanderManager doxygen documentation.

OpUiWindowListener

Listener interface on the OpWindowCommanderManager for telling the clients of the core API that the core code has either created or closed a window.

OpUiWindowListener doxygen documentation.

OpAuthenticationListener

Listener interface on the OpWindowCommanderManager for letting the UI code ask the user for login name and password to be used for authentication.

OpAuthenticationListener doxygen documentation.

OpWindowCommander

As mentioned earlier, OpWindowCommander acts as the interface between a core window and the UI. It supports several methods for operating on the window including: opening urls, start/stop loading, history navigation, setting/retrieving statuses/modes, text selection, search, etc. A set of listeners facilitates signalling the UI that certain events occur inside the Opera core.

OpWindowCommander doxygen documentation.

OpLoadingListener

The OpLoadingListener can be implemented to keep track of loading progress through: OnStartLoading, OnLoadingProgress, and OnLoadingFinished. OnUrlChanged will be called if the core changes the url loaded in the window. E.g. due to a redirect or refresh. Also, OpLoadingListener has a method for letting the UI ask for username/password for authentication. For authentication of URLs directly related to a window, this interface is used for authentication, not the OpAuthenticationListener in the OpWindowCommanderManager described earlier.

OpLoadingListener doxygen documentation.

OpHistoryListener

This listener interface is not in use. Will probably be removed.

OpHistoryListener doxygen documentation.

OpErrorListener

This interface is currently not in use.

OpErrorListener doxygen documentation.

OpDocumentListener

The largest listener interface on OpWindowCommander is the OpDocumentListener. The methods can be categorized into:

OpDocumentListener doxygen documentation.

OpAccessKeyListener

Access keys are single keys assigned to a document element as a way of giving this element focus as described in the html spec. The OpAccessKeyListener interface on the OpWindowCommander is used to tell the UI that access keys are added or removed. Adding happens during parsing of a document as the accesskey attributes are parsed or if the accesskey attribute is changed through DOM. Removal can happen if the attribute is removed or altered through DOM.

OpAccessKeyListener doxygen documentation.

OpLinkListener

A listener interface offering two methods: OnAlternateCssAvailable and OnLinkElementAvailable. Both are called when a document has finished loading.

OpLinkListener doxygen documentation.

OpPrintingListener

This interface is for keeping track of printing status. The core calls OnPrintStatus when printing starts, for each page printed, when printing is finished, and if the printing has been aborted.

OpPrintingListener doxygen documentation.

OpMenuListener

This one is used for telling the UI that the user has right-clicked on the document. The UI should open a context menu depending on what was under the mouse pointer (or whichever input device was used). Currently supported contexts are: document, link, image, text-selection, and mail-to. There is currently no support for different window types, so Quick currently accesses the core Window directly to decide upon different context menus (this will have to be changed).

OpMenuListener doxygen documentation.

TransferManager interfaces

The TransferManager interfaces support downloading URLs and keeping track of the size and the estimated time remaining of a given URL. The OpTransferManager keeps a collection of OpTransferItem objects which can be used to start, stop, and continue loading of URLs. This functionality is used for implementing downloading of URLs in Opera through the transfer panel, but could also be used in other parts of the code where download functionality is needed.

OpTransferManager

The OpTransferManager is a container keeping track of the OpTransferItems currently existing. The clients of the OpTransferManager calls the OpTransferManager to create new OpTransferItem objects, and they are responsible for releasing them when they are no longer used. Clients can keep track of added OpTransferItems by implementing the OpTransferManagerListener interface.

OpTransferManager doxygen documentation.

OpTransferManagerListener

A listener interface which can be implemented and set on the OpTransferManager to keep control of added OpTransferItems. E.g. in the TransferPanel of Quick, this listener is implemented to add UI elements to the transfer panel representing the items being downloaded.

OpTransferManagerListener doxygen documentation.

OpTransferItem

For each transfer/download, an OpTransferItem is created by calling GetTransferItem in the OpTransferManager. Each transfer item can start, stop, and resume a transfer.

OpTransferItem doxygen documentation.

OpTransferListener

It is possible to track the progress of an OpTransferItem by implementing the OpTransferListener interface and set a listener implementation object on the OpTransferItem. The OpTransferListener implementation is notified regularly about the current status of the transfer through the OnProgress method.

OpTransferListener doxygen documentation.

OpTv interfaces

OpTv

OpTv doxygen documentation.

OpTvWindowListener

OpTvWindowListener doxygen documentation.

Memory handling

Used OOM policies

In most cases, since the windowcommander methods are called directly by UI/product/platform code, the implementation of the virtual methods in the module handles OOM situations without further propagation, by calling MemoryManager::RaiseCondition() directly. There are however also some methods that return OP_STATUS values to the caller instead. The LEAVE mechanism is only used during module initialization.

Who is handling OOM?

OOM is usually handled by windowcommander directly. See previous chapter.

Description of flow

As a thin layer between core and UI code, the windowcommander module is fairly simple, and so is its code flow. It typically goes like this:

  1. The user does something in the UI (e.g. click a "Back in history" button)
  2. UI code calls a method in windowcommander (e.g. OpWindowCommander::Previous())
  3. windowcommander does the right stuff in core (e.g. Window::SetHistoryPrev())
  4. Core does its stuff and returns, with an error code if something went wrong. Normally, if an OOM error occured, this will be dealt with internally in windowcommander, and the UI code will at best be told that something went wrong. In many cases, what core was told to do by the UI is carried out asynchronously, and one or several listener method calls may be called later to notify the UI about progress and result.

or:

  1. Something happened in core that the UI should be made aware of (e.g. the document title changed)
  2. Core calls a listener method class in windowcommander (e.g. OpDocumentListener::OnTitleChanged())
  3. The implementation of OpDocumentListener in the UI code does its stuff.

Heap memory usage

In general the windowcommander module itself doesn't allocate memory at many sites. The transfer manager code allocates some pieces here and there though. A few OpWindowCommander methods also allocate some. There is e.g. a method that allocates and creates an image (OpBitmap). Another method allocates a string containing all text on the clipboard. The memory from both these potentially fairly large memory allocations are sent to the UI code, which takes over ownership. Lifespan is not documented.

Stack memory usage

Negligible. Worst-case scenario is when the UI calls a method in windowcommander, which calls a method in core, which calls a listener method defined in windowcommander, ending up back in the UI code.

Static memory usage

Negligible.

Caching and freeing memory

The windowcommander module is too simple and stupid for caching.

Freeing memory on exit

The UI code is responsible for deleting all OpWindowCommander objects (including those created by core and passed via OpUiWindowListener::CreateUiWindow()), by calling OpWindowCommanderManager::ReleaseWindowCommander() on each object. Other data allocated (OpBitmap, clipboard text) with ownership transferred to UI code must also be deleted by UI code. The rest of the memory used by windowcommander is deleted automatically at module shutdown.

Temp buffers

OpWindowCommander::GetSelectedLinkInfo() uses a temp buffer. We should consider fixing that, although the risk for the temp buffer to already be in use, is close to none.

Memory tuning

No tuning. Memory usage increases with each window created. The UI may limit memory usage by limiting the number of simultaneous open windows.

Tests

No memory tests.

Coverage

Make a full-blown web browser UI using windowcommander.

Design choices

The overall idea is that windowcommander should deal with memory allocation as little as possible on its own.

Suggestions of improvements

Get rid of shared temp buffer usage?

Tutorials

No tutorials yet.