Brian Ryner suggested that I list some tips on how people writing
or hacking on theme engines can set up their code so that it works
well when Mozilla tries to render it. Seems sane and this seems
like a decent forum to do so. First of all, a little background
on what makes Mozilla a little different from your usual Gtk
application with regards to theme handling.
Mozilla's rendering model is a little different than most Gtk
applications. First of all, most of the rendering is handled by
the layout engine and may be dispatched to the Gtk layer including
the theme code for drawing. The target for that drawing is likely
to be an offscreen drawable instead of a native window. Most Gtk
applications are written using native windows and many theme
engines as a result assume that they will be drawing only to a
native window. When Mozilla invokes the drawing calls in the
theme engines and uses its drawable as a target, an X error is the
result.
A little more explanation as to why this is a problem. There are
two different kinds of objects that you can draw to in the X
Window System. These are the Window and Pixmap.
When referring to them collectively the term Drawable is
used. The collection of raw X apis for drawing include some APIs
that can only be used on one or the other or both. For example,
you can only use XResizeWindow() on a Window
object because you can't resize a Pixmap once it's been
created like you can with a Window. Some of these calls,
like XSetWindowBackground() are actually used via various
gdk_* apis and aren't portable to a Pixmap. So
we have our first rule:
1. Avoid calls that can only use a Window or Pixmap as a
target for drawing or querying.
The biggest offender of this is the Crux
theme which included the copious use of
gdk_window_set_background. Unfortunately, we've
discovered that this code pattern has been replicated from the
Crux theme into a lot of other engines, too. These themes don't
work very well in Mozilla. So, avoid function calls that include
"window" or "pixmap" in the name. You're
bound to run into trouble.
The second thing to consider is the fact that since your theme
drawing is being targetted at a larger drawable it's going to be
drawn at a random location. There are some themes out there, like
the Mist
theme that apparently assume that if the drawable that's passed in
is of a different size than what you asked to draw that there's a
problem and quietly bail on the drawing operation. This couldn't
be farther than the truth. Apparently this code has been used in
other theme engines as well so we've got a problem with a lot of
random themes out there. So, rule number 2:
2. Don't assume that the drawable that you're going to be
drawing on is the same size as the drawing request
A final technical note about Mozilla's theme handling. If we
dispatch out to the theme engine and it causes an X Error we trap
that event and disable that particular UI element for that theme
engine. This is why with some theme engines some of the UI
elements are themed and others aren't, even when they are themed
when using other engines. This also means that we can limp along
under most circumstances even when we've got a theme that is
misbehaving.
People are always complaining that Mozilla doesn't look
"native enough". If people follow these two simple
rules, it goes a long way to helping with that problem.