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.
The following diagram shows a conceptual description of the WindowCommander interface:
The windowcommander code uses listeners heavily to allow callbacks into the code using its interfaces. The listener design principle is described here.
See the burger model, to understand the relationship between windowcommander, core and the pi module.
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.
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.
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.
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.
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.
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.
This listener interface is not in use. Will probably be removed.
OpHistoryListener doxygen documentation.
This interface is currently not in use.
OpErrorListener doxygen documentation.
The largest listener interface on OpWindowCommander is the OpDocumentListener. The methods can be categorized into:
OpDocumentListener doxygen documentation.
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.
A listener interface offering two methods: OnAlternateCssAvailable and OnLinkElementAvailable. Both are called when a document has finished loading.
OpLinkListener doxygen documentation.
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.
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.
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.
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.
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.
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.
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.
OpTvWindowListener doxygen documentation.
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.
OOM is usually handled by windowcommander directly. See previous chapter.
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:
or:
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.
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.
Negligible.
The windowcommander module is too simple and stupid for caching.
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.
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.
No tuning. Memory usage increases with each window created. The UI may limit memory usage by limiting the number of simultaneous open windows.
No memory tests.
Make a full-blown web browser UI using windowcommander.
The overall idea is that windowcommander should deal with memory allocation as little as possible on its own.
Get rid of shared temp buffer usage?
No tutorials yet.