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 are still vague.
See XPToolkit for 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:
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 implemented
using a hashtable, found in nsWindow.cpp.
Frame windows store a pointer to their nsWindow at
QWL_USER in the window words. Their client window handles
are stored in the hashtable of windows.
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.
There are some kludges in place to better mimic the behaviour of Win32, so
that, for example, windows totally covered by other windows do not receive
mouseclick events.
Events
XP events are defined in nsGUIEvent.h.
They're pretty straight-forward, though with a few notes:
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.
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.
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 in the nsMenuBase class. There is also an nsMenuItem
class. In the world of XPToolkit, menus are built up at runtime using these
classes. Client applications associate menu listeners with both
menu items and menus; when menus appear or menu items are selected, messages
are dispatched to the listeners.
Yes, event handling mechansims vary wildly. But that's what makes it so fun.
How we make this work on PM:
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.
Otherwise the service should use HMQ_CURRENT.
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.
Intl work needed for MBCS input modes.
These could do with verifying.
The per-window data-structure could do with optimising
(just use a hashtable)
This design can't support images on menuitems. Current XPToolkit plans
do not include this.
nsSwitchToPMThread rerouting isn't
hooked up yet.
The code for dispatching menu events is currently in
nsWindow.cpp. It should probably be moved to nsFrameWindow.cpp.
Back to Raptor gfx | On to plugins |
---|