Intro...

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.

Overview
  Administrative issues
  Relevant standards and X properties
  Debugging and testing
    Debugging logs
    Adding information to the log
    Valgrind
    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 hp@redhat.com.
  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 http://developer.gnome.org/dotplan/for_maintainers.html 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.

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:
    ICCCM - http://tronche.com/gui/x/icccm/
    EWMH  - :pserver:anoncvs@pdx.freedesktop.org:/cvs
  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 :pserver:anoncvs@cvs.freedesktop.org:/cvs/icccm-extensions login
    cvs -d :pserver:anoncvs@cvs.freedesktop.org:/cvs/icccm-extensions \
      checkout wm-spec

  DO NOT GO AND READ THOSE THINGS.  THEY ARE REALLY, REALLY BORING.

  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
    xprop
  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.  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" 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 this from 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
  running
    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:
    METACITY_VERBOSE=1 METACITY_USE_LOGFILE=1 metacity --replace
  (note that METACITY_VERBOSE=1 cannot be used without
  METACITY_USE_LOGFILE=1 or metacity will crash).  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

  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 --logfile=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

  src/run-metacity.sh
    The script src/run-metacity.sh is useful to hack on the window manager. 
    It runs metacity in an Xnest. e.g.:
      CLIENTS=3 ./run-metacity.sh
    or 
      DEBUG=memprof ./run-metacity.sh
    or
      DEBUG_TEST=1 ./run-metacity-sh
    or whatever.

  metacity-message
    The tool metacity-message can be used as follows:
      metacity-message reload-theme
      metacity-message restart
      metacity-message enable-keybindings
      metacity-message disable-keybindings

  metacity-window-demo
    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.

  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:
    http://pobox.com/~hp/features.html
    rationales.txt
    doc/code-overview.txt

  It pays to read http://pobox.com/~hp/features.html 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
  http://log.ometer.com/2004-05.html.  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.
