Commit ff635bad authored by Jasper St. Pierre's avatar Jasper St. Pierre

Clean up the source tree

Remove a lot of old, unmaintained files
parent 43a409de
Havoc Pennington <>
Metacity Standards Compliance
1) Introduction
2) EWMH Compliance
a. Root Window Properties
b. Root Window Messages
c. Application Window Properties
d. Window Manager Protocols
3) ICCCM Compliance
1) Introduction
This document details metacity compliance with the relevent standards.
The format of this document is as follows:
[-/+?] Hint Name/Feature Name (Version number)
The first character indicates the level of compliance as follows:
- none
/ partial
+ complete
? unknown
The title indicates a feature or a hint in the specification, and the
version number indicates the minimum version of the specification
supported by metacity. Later versions may be supported if no
incompatible changes have been made in the specification.
2) EWMH Compliance
The EWMH, or Extended Window Manager Hints is a
developed standard to support a number of conventions for
communication between the window manager and clients. It builds on
and extends the ICCCM (See Section 3). A copy of the current EWMH
standard is available at
a. Root Window Properties
Metacity does not implement large desktops, so this is kept set to
the screen size.
Metacity does not implement viewports, so this is a constant (0,0).
Metacity does not read or set this property, but it does not use
virtual roots to implement virtual desktops, so it complies with the
b. Root Window Messages
Metacity supports this message, but the specification is unclear on
the layout of the detail value, and as such it is #if 0'd in the code
Metacity will raise or lower windows in response to this message,
but the sibling restack modes are not supported, and it is currently
#if 0'd in the code.
c. Application Window Properties
+ _NET_WM_NAME (1.3)
Metacity does not set this property, but metacity will never display
a name different from _NET_WM_NAME
Metacity does not set this property, but metacity will never display
a name different from _NET_WM_NAME
/ _NET_WM_STATE (1.3)
This property is read and updated according to the specification,
but see caveat below.
Metacity does not recognize separate vertical and horizontal
maximization states. Currently metacity will do a two-dimensional
maximization if either property is set.
Metacity doesn't implement viewports so _NET_WM_STATE_STICKY is
Metacity keeps this hint up to date. The code is somewhat crufty
and should be rewritten, though it is functional.
+ _NET_WM_STRUT (1.3)
Metacity uses this property to draw minimize/restore animations
+ _NET_WM_ICON (1.3)
+ _NET_WM_PID (1.3)
Metacity does not read or set this property. However, metacity
never manages iconified windows, and so has no need to do so.
Metacity uses this property to prevent applications from stealing
focus if supported by the toolkit.
If set in response to a _NET_REQUEST_FRAME_EXTENTS message received
prior to the window being mapped, this may be an estimate. This is,
however, expressly allowed by the specification.
d. Window Manager Protocols
+ _NET_WM_PING (1.3)
3) ICCCM Compliance
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
Window managers have a few ways in which they are significantly different
from other applications. This file, combined with the code overview in
doc/code-overview.txt, should hopefully provide a series of relatively
quick pointers (hopefully only a few minutes each) to some of the places
one can look to orient themselves and get started. Some of this will be
general to window managers on X, much will be specific to Metacity, and
there's probably some information that's common to programs in general but
is nonetheless useful.
Administrative issues
Minimal Building/Testing Environment
Relevant standards and X properties
Debugging and testing
Debugging logs
Adding information to the log
Testing Utilities
Technical gotchas to keep in mind
Other important reading
Extra reading
Ideas for tasks to work on
Administrative issues
Don't commit substantive code in here without asking
Adding translations, no-brainer typo fixes, etc. is fine.
The code could use cleanup in a lot of places, feel free to do so.
See for
information on how to make a release. The only difference from those
instructions is that the minor version number of a Metacity release
should always be a number from the Fibonacci sequence.
Minimal Building/Testing Environment
You do not need to _install_ a development version of Metacity to
build, run and test it; you can run it from some temporary
directory. Also, you do not need to build all of Gnome in order to
build a development version of Metacity -- odds are, you may be able
to build metacity from CVS without building any other modules.
As long as you have gtk+ >= 3.0 and GIO >= 2.25.10 with your distro
(gtk+ >= 2.6 if you manually revert the change from bug 348633), you
should be able to install your distro's development packages
(e.g. gtk2-devel, glib-devel, startup-notification-devel on
Fedora; also, remember to install the gnome-common package which is
needed for building cvs versions of Gnome modules like Metacity) as
well as the standard development tools (gcc, autoconf, automake,
pkg-config, intltool, and libtool) and be ready to build and test
Metacity. Steps to do so:
$ svn checkout metacity
$ cd metacity
$ ./ --prefix /usr
$ make
$ ./src/metacity --replace
Again, note that you do not need to run 'make install'.
Relevant standards and X properties
There are two documents that describe some basics about how window
managers should behave: the ICCCM (Inter-Client Communication Conventions
Manual) and EWMH (Extended Window Manager Hints). You can find these at
the following locations:
The ICCCM is usually available in RPM or DEB format as well. There is
actually an online version of the EWMH, but it is almost always woefully
out of date. Just get it from cvs with these commands (the backslash
means include the stuff from the next line):
cvs -d login
cvs -d \
checkout wm-spec
If you do, you'll probably end up catching up on your sleep instead of
hacking on Metacity. ;-) Instead, just look at the table of contents and
glance at a page or two to get an idea of what's in there. Then only
refer to it if you see something weird in the code and you don't know
what it is but has some funny looking name like you see in one of those
two documents.
You can refer to the COMPLIANCE file for additional information on these
specifications and Metacity's compliance therewith.
One of the major things those documents cover that are useful to learn
about immediately are X properties. The right way to learn about those,
though, is through hand on experimentation with the xprop command (and
then look up things you find from xprop in those two manuals if you're
curious enough). First, try running
in a terminal and click on one of the windows on your screen. That gives
you the x properties for that window. Look through them and get a basic
idea of what's there for kicks. Note that you can get rid of some of the
verboseness by grepping out the _NET_WM_ICON stuff, i.e.
xprop | grep -v _NET_WM_ICON
Next, try running
xprop -root
in a terminal. There's all the properties of the root window (which you
can think of as the "main" Xserver window). You can also manually
specify individual windows that you want the properties of with
xprop -id <id>
if you know the id of the window in question. You can get the id of a
given window by either running xwininfo, e.g.
xwininfo | grep "Window id" | cut -f 4 -d ' '
or by looking at the _NET_CLIENT_STACKING property of the root
window. Finally, it can also be useful to add "-spy" (without the
quotes) to the xprop command to get it to continually monitor that
window and report any changes to you.
Debugging information
Trying to run a window manager under a typical debugger, such as gdb,
unfortunately just doesn't work very well. So, we have to resort to
other methods.
Debugging logs
First, note that you can start a new version of metacity to replace the
existing one by running
metacity --replace
(which also comes in handy in the form "./src/metacity --replace" when
trying to quickly test a small change while hacking on metacity without
doing a full "make install", though I'm going off topic...) This will
allow you to see any warnings printed at the terminal. Sometimes it's
useful to have these directed to a logfile instead, which you can do by
METACITY_USE_LOGFILE=1 metacity --replace
The logfile it uses will be printed in the terminal. Sometimes, it's
useful to get more information than just warnings. You can set
METACITY_VERBOSE to do that, like so:
(note that METACITY_VERBOSE=1 can be problematic without
METACITY_USE_LOGFILE=1; avoid it unless running in from something that
won't be managed by the new Metacity--see bug 305091 for more details).
There are also other flags, such as METACITY_DEBUG, most of which I
haven't tried and don't know what they do. Go to the source code
directory and run
grep "METACITY_" * | grep getenv
to find out what the other ones are.
Adding information to the log
Since we can't single step with a debugger, we often have to fall back to
the primitive method of getting information we want to know: adding
"print" statements. Metacity has a fairly structured way to do this,
using the functions meta_warning, meta_topic, and meta_verbose. All
three have the same basic format as printf, except that meta_topic also
takes a leading enumeration parameter to specify the type of message
being shown (makes it easier for grepping in a verbose log). You'll find
tons of examples in the source code if you need them; just do a quick
grep or look in most any file. Note that meta_topic and meta_verbose
messages only appear if verbosity is turned on. I tend to frequently add
temporary meta_warning statements (or switch meta_topic or meta_verbose
ones to meta_warning ones) and then undo the changes once I've learned
the info that I needed.
There is also a meta_print_backtrace (which again is only active if
verbosity is turned on) that can also be useful if you want to learn how
a particular line of code gets called. And, of course, there's always
g_assert if you want to make sure some section isn't executed (or isn't
executed under certain conditions).
Valgrind is awesome for finding memory leaks or corruption and
uninitialized variables. But I also tend to use it in a non-traditional
way as a partial substitute for a normal debugger: it can provide me with
a stack trace of where metacity is crashing if I made a change that
caused it to do so, which is one of the major uses of debuggers. (And,
what makes it cooler than a debugger is that there will also often be
warnings pinpointing the cause of the crash from either some kind of
simple memory corruption or an uninitialized variable). Sometimes, when
I merely want to know what is calling a particular function I'll just
throw in an "int i; printf("%d\n", i);" just because valgrind will give
me a full stacktrace whenever it sees that uninitialized variable being
used (yes, I could use meta_print_backtrace, but that means I have to
turn verbosity on).
To run metacity under valgrind, use options typical for any Gnome
program, such as
valgrind --log-file=metacity.log --tool=memcheck --num-callers=48 \
--leak-check=yes --leak-resolution=high --show-reachable=yes \
./src/metacity --replace
where, again, the backslashes mean to join all the stuff on the following
line with the previous one.
However, there is a downside. Things run a little bit slowly, and it
appears that you'll need about 1.5GB of ram, which unfortunately prevents
most people from trying this.
Testing Utilities
The script src/ is useful to hack on the window manager.
It runs metacity in an Xnest. e.g.:
DEBUG=memprof ./
DEBUG_TEST=1 ./run-metacity-sh
or whatever.
The tool metacity-message can be used as follows:
metacity-message reload-theme
metacity-message restart
metacity-message enable-keybindings
metacity-message disable-keybindings
The first of these is useful for testing themes, the second is just
another way (besides the --restart flag to metacity itself) of
restarting metacity, and the third is useful for testing Metacity when
running it under an Xnest (typically, the Metacity under the Xnest
wouldn't get keybinding notifications--making keyboard navigation not
work--but if you disable the keybindings for the global Metacity then
the Metacity under the Xnest can then get those keybinding notifications).
metacity-window-demo is good for trying behavior of various kinds
of window without launching a full desktop.
Technical gotchas to keep in mind
Files that include gdk.h or gtk.h are not supposed to include
display.h or window.h or other core files. Files in the core
(display.[hc], window.[hc]) are not supposed to include gdk.h or
gtk.h. Reasons:
"Basically you don't want GDK most of the time. It adds
abstractions that cause problems, because they aren't designed to
be used in a WM where we do weird stuff (display grabs, and just
being the WM). At best GDK adds inefficiency, at worst it breaks
things in weird ways where you have to be a GDK guru to figure
them out. Owen also told me that they didn't want to start adding
a lot of hacks to GDK to let a WM use it; we both agreed back in
the mists of time that metacity would only use it for the "UI"
bits as it does.
Having the split in the source code contains and makes very clear
the interface between the WM and GDK/GTK. This keeps people from
introducing extra GDK/GTK usage when it isn't needed or
appropriate. Also, it speeds up the compilation a bit, though this
was perhaps more relevant 5 years ago than it is now.
There was also a very old worry that the GDK stuff might have to
be in a separate process to work right; that turned out to be
untrue. Though who knows what issues the CM will introduce."
Remember that strings stored in X properties are not in UTF-8, and they
have to end up in UTF-8 before we try putting them through Pango.
If you make any X request involving a client window, you have to
meta_error_trap_push() around the call; this is not necessary for X
requests on the frame windows.
Remember that not all windows have frames, and window->frame can be NULL.
Other important reading & where to get started
Extra reading
There are some other important things to read to get oriented as well.
These are:
It pays to read in order
to understand the philosophy of Metacity.
The rationales.txt file has two things: (1) a list of design choices with
links in the form of bugzilla bugs that discuss the issue, and (2) a list
outstanding bug categories, each of which is tracked by a particular
tracker bug in bugzilla from which you can find several closely related
bug reports.
doc/code-overview.txt provides a fairly good overview of the code,
including coverage of the function of the various files, the main
structures and their relationships, and places to start looking in the
code tailored to general categories of tasks.
Ideas for tasks to work on
There are a variety of things you could work on in the code. You may
have ideas of your own, but in case you don't, let me provide a list of
ideas you could choose from:
If you're ambitious, there's a list of things Havoc made that he'd really
like to see tackled, which you can find at Be sure to double check with someone
to make sure the item is still relevant if you're interested in one of
these. Another place to look for ideas, of course, is bugzilla. One can
just do queries and look for things that look fixable.
However, perhaps the best way of getting ideas of related tasks to work
on, is to look at the second half of the rationales.txt file, which tries
to group bugs by type.
Tomas Frydrych
Email: tf linux intel com
Userid: tomasf
Owen Taylor
Email: otaylor redhat com
Userid: otaylor
Currently active maintainers
Elijah Newren
Email: newren gmail com
Userid: newren
- Usually won't touch the theme bugs (isn't interested) or the
compositor (until open source nvidia drivers are up to snuff).
Tends to be most interested in libwnck/gtk interactions, focus
issues, constraints problems, and raising/stacking, but works on
just about anything other than themes and the compositor.
Thomas Thurman
Email: thomas thurman org uk
Userid: tthurman
- Responsible for all theme bugs and the compositor (thank goodness
Thomas got involved, eh?). I'm sure he'll replace this sentence
with his interests when he reads it. ;-)
Semi-active maintainers
Havoc Pennington
Email: hp redhat com
Userid: hp
- Original author. Doesn't patch metacity anymore, but is active in
answering questions, responding to bugs, providing very helpful
suggestions and insight, and even assisting with debugging.
Important historical figureheads
Rob Adams (readams readams net)
- Was the main maintainer of metacity for a while; particular areas
of focus included xinerama, placement, and an older version of the
constraints code. Still responds to bugs every once in a while.
Søren Sandmann (sandmann redhat com)
- Wrote most of the current compositing manager code + libcm
The original codebase named "Metacity" is not a meta-City as in an
urban center, but rather Meta-ness as in the state of being
meta. i.e. metacity : meta as opacity : opaque. Also it may have
something to do with the Meta key on UNIX keyboards.
Since then, it has been renamed mutter after a rebase on top of
clutter as a compositing manager.
You need GTK+ 2.2. For startup notification to work you need
libstartup-notification at or on the
GNOME ftp site.
You need Clutter 1.0. You need gobject-introspection 0.6.3.
Report new bugs on Please check for
duplicates, *especially* if you are reporting a feature request.
Please do *not* add "me too!" or "yes I really want this!" comments to
feature requests in bugzilla. Please read prior to adding any kind of flame
about missing features or misfeatures.
Feel free to send patches too; Metacity is relatively small and
simple, so if you find a bug or want to add a feature it should be
pretty easy. Send me mail, or put the patch in bugzilla.
See the HACKING file for some notes on hacking Mutter.
- Uses GTK+ 2.0 for drawing window frames. This means colors, fonts,
etc. come from GTK+ theme.
- Does not expose the concept of "window manager" to the user. Some
of the features in the GNOME control panel and other parts of the
desktop happen to be implemented in metacity, such as changing your
window border theme, or changing your window navigation shortcuts,
but the user doesn't need to know this.
- Includes only the window manager; does not try to be a desktop
environment. The pager, configuration, etc. are all separate and
modular. The "libwnck" library (which I also wrote) is available
for writing metacity extensions, pagers, and so on. (But libwnck
isn't metacity specific, or GNOME-dependent; it requires only GTK,
and should work with KWin, fvwm2, and other EWMH-compliant WMs.)
- Has a simple theme system and a couple of extra themes come with it.
Change themes via gsettings:
gsettings set org.gnome.desktop.wm.preferences theme Crux
gsettings set org.gnome.desktop.wm.preferences theme Gorilla
gsettings set org.gnome.desktop.wm.preferences theme Atlanta
gsettings set org.gnome.desktop.wm.preferences theme Bright
See theme-format.txt for docs on the theme format. Use
metacity-theme-viewer to preview themes.
- Change number of workspaces via gsettings:
gsettings set org.gnome.desktop.wm.preferences num-workspaces 5
Can also change workspaces from GNOME 2 pager.
- Change focus mode:
gsettings set org.gnome.desktop.wm.preferences focus-mode mouse
gsettings set org.gnome.desktop.wm.preferences focus-mode sloppy
gsettings set org.gnome.desktop.wm.preferences focus-mode click
- Global keybinding defaults include:
Alt-Tab forward cycle window focus
Alt-Shift-Tab backward cycle focus
Alt-Ctrl-Tab forward cycle focus among panels
Alt-Ctrl-Shift-Tab backward cycle focus among panels
Alt-Escape cycle window focus without a popup thingy
Ctrl-Alt-Left Arrow previous workspace
Ctrl-Alt-Right Arrow next workspace
Ctrl-Alt-D minimize/unminimize all, to show desktop
Change keybindings for example:
gsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-1 '[<Alt>F1]'
Also try the GNOME keyboard shortcuts control panel.
- Window keybindings:
Alt-space window menu
Mnemonics work in the menu. That is, Alt-space then underlined
letter in the menu item works.
Choose Move from menu, and arrow keys to move the window.
While moving, hold down Control to move slower, and
Shift to snap to edges.
Choose Resize from menu, and nothing happens yet, but
eventually I might implement something.
Keybindings for things like maximize window, vertical maximize,
etc. can be bound, but may not all exist by default. See
- Window mouse bindings:
Clicking anywhere on frame with button 1 will raise/focus window
If you click a window control, such as the close button, then the
control will activate on button release if you are still over it
on release (as with most GUI toolkits)
If you click and drag borders with button 1 it resizes the window
If you click and drag the titlebar with button 1 it moves the
If you click anywhere on the frame with button 2 it lowers the
If you click anywhere on the frame with button 3 it shows the
window menu.
If you hold down Super (windows key) and click inside a window, it
will move the window (buttons 1 and 2) or show menu (button 3).
Or you can configure a different modifier for this.
If you pick up a window with button 1 and then switch workspaces
the window will come with you to the new workspace, this is
a feature copied from Enlightenment.
If you hold down Shift while moving a window, the window snaps
to edges of other windows and the screen.
- Session management:
Mutter connects to the session manager and will set itself up to
be respawned. It theoretically restores sizes/positions/workspace
for session-aware applications.
- Mutter implements much of the EWMH window manager specification
from, as well as the older ICCCM. Please refer to
the COMPLIANCE file for information on mutter compliance with
these standards.
- Uses Pango to render text, so has cool i18n capabilities.
Supports UTF-8 window titles and such.
- There are simple animations for actions such as minimization,
to help users see what is happening. Should probably
have a few more of these and make them nicer.
- if you have the proper X setup, set the GDK_USE_XFT=1
environment variable to get antialiased window titles.
- considers the panel when placing windows and maximizing
- handles the window manager selection from the ICCCM. Will exit if
another WM claims it, and can claim it from another WM if you pass
the --replace argument. So if you're running another
ICCCM-compliant WM, you can run "mutter --replace" to replace it
with Metacity.
- does basic colormap handling
- and much more! well, maybe not a lot more.
You can write a mutter "plugin" such as a pager, window list, icon
box, task menu, or even things like "window matching" using the
Extended Window Manager Hints. See for the
EWMH specification. An easy-to-use library called "libwnck" is
available that uses the EWMH and is specifically designed for writing
WM accessories.
You might be interested in existing accessories such as "Devil's Pie"
by Ross Burton, which add features to Mutter (or other
EWMH-compliant WMs).
See bugzilla:
Q: Will you add my feature?
A: If it makes sense to turn on unconditionally, or is genuinely a
harmless preference that I would not be embarrassed to put in a
simple, uncluttered, user-friendly configuration dialog.
If the only rationale for your feature is that other window
managers have it, or that you are personally used to it, or
something like that, then I will not be impressed. Metacity is
firmly in the "choose good defaults" camp rather than the "offer 6
equally broken ways to do it, and let the user pick one" camp.
This is part of a "no crackrock" policy, despite some exceptions
I'm mildly embarrassed about. For example, multiple workspaces
probably constitute crackrock, they confuse most users and really
are not that useful if you have a decent tasklist and so on. But I
am too used to them to turn them off. Or alternatively
iconification/tasklist is crack, and workspaces/pager are good. But
having both is certainly a bit wrong. Sloppy focus is probably
crackrock too.
But don't think unlimited crack is OK just because I slipped up a
little. No slippery slope here.
Don't let this discourage patches and fixes - I love those. ;-)
Just be prepared to hear the above objections if your patch adds
some crack-ridden configuration option.
Q: Will Mutter be part of GNOME?
A: It is not officially part of GNOME as of GNOME 2.27. We are
hoping to have mutter officially included as of GNOME 2.28.
Q: Why does Mutter remember the workspace/position of some apps
but not others across logout/login?
A: Mutter only stores sizes/positions for apps that are session
managed. As far as I can determine, there is no way to attempt to
remember workspace/position for non-session-aware apps without
causing a lot of weird effects.
The reason is that you don't know which non-SM-aware apps were
launched by the session. When you initially log in, Metacity sees a
bunch of new windows appear. But it can't distinguish between
windows that were stored in your session, or windows you just
launched after logging in. If Metacity tried to guess that a window
was from the session, it could e.g. end up maximizing a dialog, or
put a window you just launched on another desktop or in a weird
place. And in fact I see a lot of bugs like this in window managers
that try to handle non-session-aware apps.
However, for session-aware apps, Mutter can tell that the
application instance is from the session and thus restore it
reliably, assuming the app properly restores the windows it had
open on session save.
So the correct way to fix the situation is to make apps
session-aware. libSM has come with X for years, it's very
standardized, it's shared by GNOME and KDE - even twm is
session-aware. So anyone who won't take a patch to add SM is more
archaic than twm - and you should flame them. ;-)
Docs on session management:
See also the ICCCM section on SM. For GNOME apps, use the
GnomeClient object. For a simple example of using libSM directly,
twm/session.c in the twm source code is pretty easy to understand.
Q: How about adding viewports in addition to workspaces?
A: I could conceivably be convinced to use viewports _instead_ of
workspaces, though currently I'm not thinking that. But I don't
think it makes any sense to have both; it's just confusing. They
are functionally equivalent.
You may think this means that you won't have certain keybindings,
or something like that. This is a misconception. The only
_fundamental_ difference between viewports and workspaces is that
with viewports, windows can "overlap" and appear partially on