The Mozilla
Organization
Our Mission
Who We Are
Getting Involved
Community
Editorials
What's New
Development
Roadmap
Module Owners
Blue Sky
Projects
Status
Tools
Products
Source Code
Binaries
Documentation
License Terms
Bug Reports
Search
Feedback


Raptor Widget

Files in mozilla/widget/src/os2/
(not yet checked in to mozilla.org cvs)

This is the cross-platform window library. Most of the files and classes (eg. nsEntryField) are small subclasses of the base OS/2 window class, nsWindow. Note that the widgets are grounded in an XP class, nsBaseWidget. The hierarchy looks like this:

       nsISupports
         |
         +---nsIWidget
               |
               +---nsBaseWidget
                     |
                     +---nsWindow
                           |
                           +---nsEntryField   (for example)

The future - XPToolkit

There are several incomplete sections in this library (eg. printing). They are being left incomplete because their future is unclear. Mozilla is adopting a system of drawn widgets; there will be a place for native widgets, but the details remain unclear.

See XPToolkit for much, much more.

Managing message queues

In order to do interesting things like create windows, a thread needs to have a HMQ. There are three places in the mozilla code where, independently, PM function is neeed: here, in libwidget; in nsTimerOS2, and in the plevent library. Here is the way in which message queues are to be managed:

  1. When a service needs a message queue, it should first test for there being one for the current thread, using WinQueryQueueInfo.
  2. If there is no queue, create one.
    Otherwise the service should use HMQ_CURRENT.
  3. The service should take no action to destroy any queue it creates.
  4. The exception to this rule is the nsAppShell class. It is the job of nsAppShell to destroy the message queue and shut down PM.
    This a valid thing to do because by the time the nsAppShell shuts down, it is no longer processing its message queue, and so the services which may be using will have stopped working anyhow.

nsTimer does not yet comply to this scheme.

Toolkits and thread management

Not all mozilla threads are PM threads. Some functions in the OS/2 API demand that they are called from PM threads. Indeed, some functions must be called in specific PM threads. So there needs to be a method of re-routing function calls.

This mechanism is contained in the nsToolkit class. Each widget created has a reference to an nsToolkit, which is associated with a thread. There's a set of routines for calling methods (using a callback interface, SwitchToPMThread, which nsWindow implements) and a convenience equivalent of WinSendMsg which doesn't require the caller to be a PM thread.

That said, mozilla isn't too promiscuous in the thread-creation department. Plans for this version seem to be limited to one UI thread plus some more netlib threads (more info). But if things ever change, we will be ready.

HWND basics

nsWindow.cpp is more-or-less an encapsulation of the basic window management sections of the OS/2 API.

All windows are subclassed into a simple window procedure, the nsWindow for that window is looked up, and the ProcessMessage method called.

The HWND to nsWindow mapping is currently done by sticking a pointer in one of the window words. This isn't done consistently at the moment: while most windows use QWL_USER, windows created for the nsCanvas class use QWL_USER + 4. This is because the window may be used as a plugin, the specification for which says that QWL_USER is free for the plugin to use.

This is horrible: it requires a check on the window class on each message received by each mozilla-created window. So:

Switch to using a static hashtable to look up nsWindows.

The resizing and moving code is a bit non-obvious and probably contains a few bugs: as in the graphics library, the coordinate system has the origin in the top-left. Because the height of the window is an oft-requested quanitity, the window rectangle (in XP space) is cached in the object. This is updated in the dispatch routines for the PM notification messages as opposed to the site of the Resize method. There's some interesting code (which is, as yet, uncalled) to batch window repositions.

Events

XP events are defined in nsGUIEvent.h. They're pretty straight-forward, though with a few notes:

  • The keycodes (see nsKeyEvent) are occasionally ambiguous; there's a global function in nsWindow.h to convert from a WM_CHAR to the keycode.
  • Menu events are incomplete (see below)
  • No-one really knows when NS_SIZE and NS_MOVE events should be generated. OS/2's funky coordinate system doesn't help matters, and we could probably do better.

There are a bunch of methods in nsWindow.cpp which deal with setting up for and dispatching events to interested parties.

nsLookAndFeel

The nsILookAndFeel interface is meant to wrap up various platform-specific things, including various system colours.

There are some rather weird entries which have appeared relatively recently, which are used when laying out and aligning form elements.

These could do with checking out!

If components look `a bit wrong', adjusting a value in here is probably the way to go (but see above).

Tooltips

Because Win32 has tooltips built in to the API, tooltips are built in to the nsIWidget interface. The code to manage tooltips is in the nsTooltipManager.cpp file. Note that this doesn't have anything to do with displaying tooltips -- it just sends a notification to the window, which can then act as it likes.

The per-window data-structure could do with optimising (just use a hashtable)

This could well be subsumed into XP code.

Menus

There are separate classes for menu bars, pull-down menus, and popup menus, which all share code.

Stop menu classes from deriving from nsWindow. They'll need to find a toolkit and inherit from nsSwitchToPMThread for threading to work properly.
Make nsMenuItem better. There needs to be a way of wrapping up an existing menu item (ie. construct from HWND and item ID). This will allow the nsMenuEvent to contain one.

There's much menu functionality to come in the way of ticks, greying, images, accelerators and so on.

Dialog windows

Dialogs aren't, at the moment -- they're just frame windows with a dialog border and a light grey-filled client. This shows up when you create button controls: there's a thin white border around them, which isn't normally present in dialogs.

The problem with using dialogs lies in coordinate systems. A dialog is one window, whose area is made up of a 'client area', a dialog border, and a titlebar. The origin of the client area depends on system settings, but isn't (0,0). This makes it very difficult to draw into dialogs: mozilla expects to be able to draw or lay out controls from the origin over the size of the window.

In practice, the white line doesn't look that bad, and it'll probably go away when the XPToolkit arrives.


Back to Raptor gfx On to plugins



Copyright © 1998 The Mozilla Organization.