Blame HACKING

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.