|
Packit |
5e0819 |
Intro...
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
Window managers have a few ways in which they are significantly different
|
|
Packit |
5e0819 |
from other applications. This file, combined with the code overview in
|
|
Packit |
5e0819 |
doc/code-overview.txt, should hopefully provide a series of relatively
|
|
Packit |
5e0819 |
quick pointers (hopefully only a few minutes each) to some of the places
|
|
Packit |
5e0819 |
one can look to orient themselves and get started. Some of this will be
|
|
Packit |
5e0819 |
general to window managers on X, much will be specific to Metacity, and
|
|
Packit |
5e0819 |
there's probably some information that's common to programs in general but
|
|
Packit |
5e0819 |
is nonetheless useful.
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
Overview
|
|
Packit |
5e0819 |
Administrative issues
|
|
Packit |
5e0819 |
Minimal Building/Testing Environment
|
|
Packit |
5e0819 |
Relevant standards and X properties
|
|
Packit |
5e0819 |
Debugging and testing
|
|
Packit |
5e0819 |
Debugging logs
|
|
Packit |
5e0819 |
Adding information to the log
|
|
Packit |
5e0819 |
Valgrind
|
|
Packit |
5e0819 |
Testing Utilities
|
|
Packit |
5e0819 |
Technical gotchas to keep in mind
|
|
Packit |
5e0819 |
Other important reading
|
|
Packit |
5e0819 |
Extra reading
|
|
Packit |
5e0819 |
Ideas for tasks to work on
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
Administrative issues
|
|
Packit |
5e0819 |
Don't commit substantive code in here without asking hp@redhat.com.
|
|
Packit |
5e0819 |
Adding translations, no-brainer typo fixes, etc. is fine.
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
The code could use cleanup in a lot of places, feel free to do so.
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
See http://developer.gnome.org/dotplan/for_maintainers.html for
|
|
Packit |
5e0819 |
information on how to make a release. The only difference from those
|
|
Packit |
5e0819 |
instructions is that the minor version number of a Metacity release
|
|
Packit |
5e0819 |
should always be a number from the Fibonacci sequence.
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
Minimal Building/Testing Environment
|
|
Packit |
5e0819 |
You do not need to _install_ a development version of Metacity to
|
|
Packit |
5e0819 |
build, run and test it; you can run it from some temporary
|
|
Packit |
5e0819 |
directory. Also, you do not need to build all of Gnome in order to
|
|
Packit |
5e0819 |
build a development version of Metacity -- odds are, you may be able
|
|
Packit |
5e0819 |
to build metacity from CVS without building any other modules.
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
As long as you have gtk+ >= 2.10 and GIO >= 2.25.10 with your distro
|
|
Packit |
5e0819 |
(gtk+ >= 2.6 if you manually revert the change from bug 348633), you
|
|
Packit |
5e0819 |
should be able to install your distro's development packages
|
|
Packit |
5e0819 |
(e.g. gtk2-devel, glib-devel, startup-notification-devel on
|
|
Packit |
5e0819 |
Fedora; also, remember to install the gnome-common package which is
|
|
Packit |
5e0819 |
needed for building cvs versions of Gnome modules like Metacity) as
|
|
Packit |
5e0819 |
well as the standard development tools (gcc, autoconf, automake,
|
|
Packit |
5e0819 |
pkg-config, intltool, and libtool) and be ready to build and test
|
|
Packit |
5e0819 |
Metacity. Steps to do so:
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
$ svn checkout http://svn.gnome.org/svn/metacity/trunk metacity
|
|
Packit |
5e0819 |
$ cd metacity
|
|
Packit |
5e0819 |
$ ./autogen.sh --prefix /usr
|
|
Packit |
5e0819 |
$ make
|
|
Packit |
5e0819 |
$ ./src/metacity --replace
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
Again, note that you do not need to run 'make install'.
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
Relevant standards and X properties
|
|
Packit |
5e0819 |
There are two documents that describe some basics about how window
|
|
Packit |
5e0819 |
managers should behave: the ICCCM (Inter-Client Communication Conventions
|
|
Packit |
5e0819 |
Manual) and EWMH (Extended Window Manager Hints). You can find these at
|
|
Packit |
5e0819 |
the following locations:
|
|
Packit |
5e0819 |
ICCCM - http://tronche.com/gui/x/icccm/
|
|
Packit |
5e0819 |
EWMH - :pserver:anoncvs@pdx.freedesktop.org:/cvs
|
|
Packit |
5e0819 |
The ICCCM is usually available in RPM or DEB format as well. There is
|
|
Packit |
5e0819 |
actually an online version of the EWMH, but it is almost always woefully
|
|
Packit |
5e0819 |
out of date. Just get it from cvs with these commands (the backslash
|
|
Packit |
5e0819 |
means include the stuff from the next line):
|
|
Packit |
5e0819 |
cvs -d :pserver:anoncvs@cvs.freedesktop.org:/cvs/icccm-extensions login
|
|
Packit |
5e0819 |
cvs -d :pserver:anoncvs@cvs.freedesktop.org:/cvs/icccm-extensions \
|
|
Packit |
5e0819 |
checkout wm-spec
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
DO NOT GO AND READ THOSE THINGS. THEY ARE REALLY, REALLY BORING.
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
If you do, you'll probably end up catching up on your sleep instead of
|
|
Packit |
5e0819 |
hacking on Metacity. ;-) Instead, just look at the table of contents and
|
|
Packit |
5e0819 |
glance at a page or two to get an idea of what's in there. Then only
|
|
Packit |
5e0819 |
refer to it if you see something weird in the code and you don't know
|
|
Packit |
5e0819 |
what it is but has some funny looking name like you see in one of those
|
|
Packit |
5e0819 |
two documents.
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
You can refer to the COMPLIANCE file for additional information on these
|
|
Packit |
5e0819 |
specifications and Metacity's compliance therewith.
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
One of the major things those documents cover that are useful to learn
|
|
Packit |
5e0819 |
about immediately are X properties. The right way to learn about those,
|
|
Packit |
5e0819 |
though, is through hand on experimentation with the xprop command (and
|
|
Packit |
5e0819 |
then look up things you find from xprop in those two manuals if you're
|
|
Packit |
5e0819 |
curious enough). First, try running
|
|
Packit |
5e0819 |
xprop
|
|
Packit |
5e0819 |
in a terminal and click on one of the windows on your screen. That gives
|
|
Packit |
5e0819 |
you the x properties for that window. Look through them and get a basic
|
|
Packit |
5e0819 |
idea of what's there for kicks. Note that you can get rid of some of the
|
|
Packit |
5e0819 |
verboseness by grepping out the _NET_WM_ICON stuff, i.e.
|
|
Packit |
5e0819 |
xprop | grep -v _NET_WM_ICON
|
|
Packit |
5e0819 |
Next, try running
|
|
Packit |
5e0819 |
xprop -root
|
|
Packit |
5e0819 |
in a terminal. There's all the properties of the root window (which you
|
|
Packit |
5e0819 |
can think of as the "main" Xserver window). You can also manually
|
|
Packit |
5e0819 |
specify individual windows that you want the properties of with
|
|
Packit |
5e0819 |
xprop -id <id>
|
|
Packit |
5e0819 |
if you know the id of the window in question. You can get the id of a
|
|
Packit |
5e0819 |
given window by either running xwininfo, e.g.
|
|
Packit |
5e0819 |
xwininfo | grep "Window id" | cut -f 4 -d ' '
|
|
Packit |
5e0819 |
or by looking at the _NET_CLIENT_STACKING property of the root
|
|
Packit |
5e0819 |
window. Finally, it can also be useful to add "-spy" (without the
|
|
Packit |
5e0819 |
quotes) to the xprop command to get it to continually monitor that
|
|
Packit |
5e0819 |
window and report any changes to you.
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
Debugging information
|
|
Packit |
5e0819 |
Trying to run a window manager under a typical debugger, such as gdb,
|
|
Packit |
5e0819 |
unfortunately just doesn't work very well. So, we have to resort to
|
|
Packit |
5e0819 |
other methods.
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
Debugging logs
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
First, note that you can start a new version of metacity to replace the
|
|
Packit |
5e0819 |
existing one by running
|
|
Packit |
5e0819 |
metacity --replace
|
|
Packit |
5e0819 |
(which also comes in handy in the form "./src/metacity --replace" when
|
|
Packit |
5e0819 |
trying to quickly test a small change while hacking on metacity without
|
|
Packit |
5e0819 |
doing a full "make install", though I'm going off topic...) This will
|
|
Packit |
5e0819 |
allow you to see any warnings printed at the terminal. Sometimes it's
|
|
Packit |
5e0819 |
useful to have these directed to a logfile instead, which you can do by
|
|
Packit |
5e0819 |
running
|
|
Packit |
5e0819 |
METACITY_USE_LOGFILE=1 metacity --replace
|
|
Packit |
5e0819 |
The logfile it uses will be printed in the terminal. Sometimes, it's
|
|
Packit |
5e0819 |
useful to get more information than just warnings. You can set
|
|
Packit |
5e0819 |
METACITY_VERBOSE to do that, like so:
|
|
Packit |
5e0819 |
METACITY_VERBOSE=1 METACITY_USE_LOGFILE=1 metacity --replace
|
|
Packit |
5e0819 |
(note that METACITY_VERBOSE=1 can be problematic without
|
|
Packit |
5e0819 |
METACITY_USE_LOGFILE=1; avoid it unless running in from something that
|
|
Packit |
5e0819 |
won't be managed by the new Metacity--see bug 305091 for more details).
|
|
Packit |
5e0819 |
There are also other flags, such as METACITY_DEBUG, most of which I
|
|
Packit |
5e0819 |
haven't tried and don't know what they do. Go to the source code
|
|
Packit |
5e0819 |
directory and run
|
|
Packit |
5e0819 |
grep "METACITY_" * | grep getenv
|
|
Packit |
5e0819 |
to find out what the other ones are.
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
Adding information to the log
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
Since we can't single step with a debugger, we often have to fall back to
|
|
Packit |
5e0819 |
the primitive method of getting information we want to know: adding
|
|
Packit |
5e0819 |
"print" statements. Metacity has a fairly structured way to do this,
|
|
Packit |
5e0819 |
using the functions meta_warning, meta_topic, and meta_verbose. All
|
|
Packit |
5e0819 |
three have the same basic format as printf, except that meta_topic also
|
|
Packit |
5e0819 |
takes a leading enumeration parameter to specify the type of message
|
|
Packit |
5e0819 |
being shown (makes it easier for grepping in a verbose log). You'll find
|
|
Packit |
5e0819 |
tons of examples in the source code if you need them; just do a quick
|
|
Packit |
5e0819 |
grep or look in most any file. Note that meta_topic and meta_verbose
|
|
Packit |
5e0819 |
messages only appear if verbosity is turned on. I tend to frequently add
|
|
Packit |
5e0819 |
temporary meta_warning statements (or switch meta_topic or meta_verbose
|
|
Packit |
5e0819 |
ones to meta_warning ones) and then undo the changes once I've learned
|
|
Packit |
5e0819 |
the info that I needed.
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
There is also a meta_print_backtrace (which again is only active if
|
|
Packit |
5e0819 |
verbosity is turned on) that can also be useful if you want to learn how
|
|
Packit |
5e0819 |
a particular line of code gets called. And, of course, there's always
|
|
Packit |
5e0819 |
g_assert if you want to make sure some section isn't executed (or isn't
|
|
Packit |
5e0819 |
executed under certain conditions).
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
Valgrind
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
Valgrind is awesome for finding memory leaks or corruption and
|
|
Packit |
5e0819 |
uninitialized variables. But I also tend to use it in a non-traditional
|
|
Packit |
5e0819 |
way as a partial substitute for a normal debugger: it can provide me with
|
|
Packit |
5e0819 |
a stack trace of where metacity is crashing if I made a change that
|
|
Packit |
5e0819 |
caused it to do so, which is one of the major uses of debuggers. (And,
|
|
Packit |
5e0819 |
what makes it cooler than a debugger is that there will also often be
|
|
Packit |
5e0819 |
warnings pinpointing the cause of the crash from either some kind of
|
|
Packit |
5e0819 |
simple memory corruption or an uninitialized variable). Sometimes, when
|
|
Packit |
5e0819 |
I merely want to know what is calling a particular function I'll just
|
|
Packit |
5e0819 |
throw in an "int i; printf("%d\n", i);" just because valgrind will give
|
|
Packit |
5e0819 |
me a full stacktrace whenever it sees that uninitialized variable being
|
|
Packit |
5e0819 |
used (yes, I could use meta_print_backtrace, but that means I have to
|
|
Packit |
5e0819 |
turn verbosity on).
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
To run metacity under valgrind, use options typical for any Gnome
|
|
Packit |
5e0819 |
program, such as
|
|
Packit |
5e0819 |
valgrind --log-file=metacity.log --tool=memcheck --num-callers=48 \
|
|
Packit |
5e0819 |
--leak-check=yes --leak-resolution=high --show-reachable=yes \
|
|
Packit |
5e0819 |
./src/metacity --replace
|
|
Packit |
5e0819 |
where, again, the backslashes mean to join all the stuff on the following
|
|
Packit |
5e0819 |
line with the previous one.
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
However, there is a downside. Things run a little bit slowly, and it
|
|
Packit |
5e0819 |
appears that you'll need about 1.5GB of ram, which unfortunately prevents
|
|
Packit |
5e0819 |
most people from trying this.
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
Testing Utilities
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
metacity-message
|
|
Packit |
5e0819 |
The tool metacity-message can be used as follows:
|
|
Packit |
5e0819 |
metacity-message reload-theme
|
|
Packit |
5e0819 |
metacity-message restart
|
|
Packit |
5e0819 |
metacity-message enable-keybindings
|
|
Packit |
5e0819 |
metacity-message disable-keybindings
|
|
Packit |
5e0819 |
The first of these is useful for testing themes, the second is just
|
|
Packit |
5e0819 |
another way (besides the --restart flag to metacity itself) of
|
|
Packit |
5e0819 |
restarting metacity, and the third is useful for testing Metacity when
|
|
Packit |
5e0819 |
running it under an Xnest (typically, the Metacity under the Xnest
|
|
Packit |
5e0819 |
wouldn't get keybinding notifications--making keyboard navigation not
|
|
Packit |
5e0819 |
work--but if you disable the keybindings for the global Metacity then
|
|
Packit |
5e0819 |
the Metacity under the Xnest can then get those keybinding notifications).
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
metacity-window-demo
|
|
Packit |
5e0819 |
metacity-window-demo is good for trying behavior of various kinds
|
|
Packit |
5e0819 |
of window without launching a full desktop.
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
Technical gotchas to keep in mind
|
|
Packit |
5e0819 |
Files that include gdk.h or gtk.h are not supposed to include
|
|
Packit |
5e0819 |
display.h or window.h or other core files. Files in the core
|
|
Packit |
5e0819 |
(display.[hc], window.[hc]) are not supposed to include gdk.h or
|
|
Packit |
5e0819 |
gtk.h. Reasons:
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
"Basically you don't want GDK most of the time. It adds
|
|
Packit |
5e0819 |
abstractions that cause problems, because they aren't designed to
|
|
Packit |
5e0819 |
be used in a WM where we do weird stuff (display grabs, and just
|
|
Packit |
5e0819 |
being the WM). At best GDK adds inefficiency, at worst it breaks
|
|
Packit |
5e0819 |
things in weird ways where you have to be a GDK guru to figure
|
|
Packit |
5e0819 |
them out. Owen also told me that they didn't want to start adding
|
|
Packit |
5e0819 |
a lot of hacks to GDK to let a WM use it; we both agreed back in
|
|
Packit |
5e0819 |
the mists of time that metacity would only use it for the "UI"
|
|
Packit |
5e0819 |
bits as it does.
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
Having the split in the source code contains and makes very clear
|
|
Packit |
5e0819 |
the interface between the WM and GDK/GTK. This keeps people from
|
|
Packit |
5e0819 |
introducing extra GDK/GTK usage when it isn't needed or
|
|
Packit |
5e0819 |
appropriate. Also, it speeds up the compilation a bit, though this
|
|
Packit |
5e0819 |
was perhaps more relevant 5 years ago than it is now.
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
There was also a very old worry that the GDK stuff might have to
|
|
Packit |
5e0819 |
be in a separate process to work right; that turned out to be
|
|
Packit |
5e0819 |
untrue. Though who knows what issues the CM will introduce."
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
Remember that strings stored in X properties are not in UTF-8, and they
|
|
Packit |
5e0819 |
have to end up in UTF-8 before we try putting them through Pango.
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
If you make any X request involving a client window, you have to
|
|
Packit |
5e0819 |
meta_error_trap_push() around the call; this is not necessary for X
|
|
Packit |
5e0819 |
requests on the frame windows.
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
Remember that not all windows have frames, and window->frame can be NULL.
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
Other important reading & where to get started
|
|
Packit |
5e0819 |
Extra reading
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
There are some other important things to read to get oriented as well.
|
|
Packit |
5e0819 |
These are:
|
|
Packit |
5e0819 |
http://pobox.com/~hp/features.html
|
|
Packit |
5e0819 |
rationales.txt
|
|
Packit |
5e0819 |
doc/code-overview.txt
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
It pays to read http://pobox.com/~hp/features.html in order
|
|
Packit |
5e0819 |
to understand the philosophy of Metacity.
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
The rationales.txt file has two things: (1) a list of design choices with
|
|
Packit |
5e0819 |
links in the form of bugzilla bugs that discuss the issue, and (2) a list
|
|
Packit |
5e0819 |
outstanding bug categories, each of which is tracked by a particular
|
|
Packit |
5e0819 |
tracker bug in bugzilla from which you can find several closely related
|
|
Packit |
5e0819 |
bug reports.
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
doc/code-overview.txt provides a fairly good overview of the code,
|
|
Packit |
5e0819 |
including coverage of the function of the various files, the main
|
|
Packit |
5e0819 |
structures and their relationships, and places to start looking in the
|
|
Packit |
5e0819 |
code tailored to general categories of tasks.
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
Ideas for tasks to work on
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
There are a variety of things you could work on in the code. You may
|
|
Packit |
5e0819 |
have ideas of your own, but in case you don't, let me provide a list of
|
|
Packit |
5e0819 |
ideas you could choose from:
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
If you're ambitious, there's a list of things Havoc made that he'd really
|
|
Packit |
5e0819 |
like to see tackled, which you can find at
|
|
Packit |
5e0819 |
http://log.ometer.com/2004-05.html. Be sure to double check with someone
|
|
Packit |
5e0819 |
to make sure the item is still relevant if you're interested in one of
|
|
Packit |
5e0819 |
these. Another place to look for ideas, of course, is bugzilla. One can
|
|
Packit |
5e0819 |
just do queries and look for things that look fixable.
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
However, perhaps the best way of getting ideas of related tasks to work
|
|
Packit |
5e0819 |
on, is to look at the second half of the rationales.txt file, which tries
|
|
Packit |
5e0819 |
to group bugs by type.
|