Dev Week -- Fixing bugs in compiz -- smspillaz -- Fri, Jul 15th, 2011

   1 [16:00] <smspillaz> lovely, we're ready to start
   2 [16:01] <smspillaz> hey everyone, you may have heard of me before, you may have seen my funky hair or youthful appearance :) I'm Sam Spilsbury, the current maintainer of compiz, the compositing window manager behind unity
   3 [16:01] <smspillaz> last UDW I gave a session on how to write plugins for this wonderful window manager
   4 [16:02] <smspillaz> today I'm going to give you a session on how it works and how you can fix the little odd corner cases within it
   5 [16:02] <smspillaz> so agenda:
   6 [16:02] <smspillaz> 1. What is compiz and how does it work
   7 [16:02] <smspillaz> 2. Gimmeh teh code
   8 [16:02] <smspillaz> 3. Where is everything in the code?
   9 [16:02] <smspillaz> 4. How can I get fixes to you
  10 [16:03] <smspillaz> fantastic, okay, item one, what is compiz and how does it work
  11 [16:03] <smspillaz> so you've probably all heard of compiz as the bit of magic on the system that provides all of the bling, best known for things like wobbly windows, spinnan cubez ;-) etc
  12 [16:03] <smspillaz> or drawing fire on the screen
  13 [16:04] <smspillaz> however, compiz is also responsible for a lot of other stuff too
  14 [16:04] <smspillaz> for example, even when your screen is idling and you've just got some windows up
  15 [16:04] <smspillaz> compiz is drawing the entire contents of those windows to the screen
  16 [16:05] <smspillaz> or when you grab a titlebar to move a window, compiz is handling the grab of the titlebar, the moving of the window and the placement of the window
  17 [16:05] <smspillaz> it also handles resizing windows, focus stealing prevention, tiling windows
  18 [16:05] <smspillaz> drawing the window borders on windows
  19 [16:05] <smspillaz> basically, if it ends up on your screen, compiz is probably doing some work somewhere
  20 [16:06] <smspillaz> so, because of that, we call compiz a "compositing window manager" because it "composites" windows on screen as well as determining how they behave
  21 [16:06] <smspillaz> and because of that, there's a lot of scope for things to go /wrong/ too
  22 [16:06] <smspillaz> (especially in the land of X11 window managers)
  23 [16:06] <smspillaz> for example, if a window is placed off screen, that's a compiz bug
  24 [16:07] <smspillaz> or if movement makes the window jump a little, compiz bug
  25 [16:07] <smspillaz> or if windows jump around when maximized and the resolution is too low for that window
  26 [16:07] <smspillaz> compiz bug
  27 [16:07] <smspillaz> so the kind of bugs that you do get in compiz aren't all complicated graphical ones where the effects don't work
  28 [16:07] <smspillaz> it can even be small window management related things
  29 [16:08] <smspillaz> so there's lots of scope for bugs to fix
  30 [16:08] <smspillaz> and luckily, these window management ones are not too tricky to fix
  31 [16:08] <smspillaz> so as for how it works
  32 [16:09] <smspillaz> so basically compiz' main job is to communicate with the X Server (or X11) on your system to find out the contents of windows and what properties and hints the application has set on them, and then combine them with user input in order to implement a set of rules for how windows behave on screen
  33 [16:09] <smspillaz> usually problems happen in one of three places
  34 [16:10] <smspillaz> first, in communication with the X server
  35 [16:10] <smspillaz> second, the process of turning that communication and user input produces something which is not correct
  36 [16:10] <smspillaz> or third, actual graphical problems
  37 [16:10] <smspillaz> 3) is a realm that is rather complicated and that we won't look into
  38 [16:11] <smspillaz> 1) is also quite complicated, but for new contributors, it can be worked out fairly quickly (though you should ping marnanel or me if you plan to work in this area)
  39 [16:11] <smspillaz> and 2) is where the easy wins lie
  40 [16:12] <smspillaz> so now you ask, how do I find the bugs in compiz
  41 [16:12] <smspillaz> basically, they're all on launchpad
  42 [16:12] <smspillaz> right now, all of the bugs are filed against the compiz package on launchpad
  43 [16:13] <smspillaz> however, a few days ago, I mirrored all of our components (incl. plugins, settings, everything) to launchpad too in separate launchpad projects
  44 [16:13] <smspillaz> so now as we're sorting through the bug queue, I'll be assigning bugs against that larger package to the smaller components, eg, core, plugins, settings
  45 [16:13] <smspillaz> lets have a look now at the bugs filed against the compiz package on ubuntu
  46 [16:14] <smspillaz>
  47 [16:14] <smspillaz> here's the algorithm I use to sort "that looks nasty" from "easy win"
  48 [16:15] <smspillaz> anything regarding visual glitches? (corruption, blank windows)
  49 [16:15] <smspillaz> that's probably something quite nasty
  50 [16:15] <smspillaz> something like "compiz does this when it should do this"
  51 [16:16] <smspillaz> eg "places transient dialogs behind currently focused window"
  52 [16:16] <smspillaz> that's an easy win
  53 [16:16] <smspillaz> the next thing to determine if its easy is to find out if there's a reproducible test case
  54 [16:16] <smspillaz> usually the reporter would have said something about that
  55 [16:16] <smspillaz> if it's not reproducible easily, then its not going to be easy to fix
  56 [16:17] <smspillaz> because often fixing the bugs requires a very close tracing of what's going on
  57 [16:17] <smspillaz> usually I find that if a bug can't generally be reproduced then I ask the bug reporter to show an application which is triggering the problem or a screencast of what's going on
  58 [16:18] <smspillaz> reproduction is 90% of the way to fixing it
  59 [16:18] <smspillaz> anything about compiz crashing with SIGSEGV can contingently be easy wins
  60 [16:18] <smspillaz> have a look at the stacktrace that apport gives you
  61 [16:19] <smspillaz> if it's full of things like "??" then it's not useful
  62 [16:19] <smspillaz> if it has references to "nux::" in it, then it is probably a bug in untiy or nux and not in compiz (though this should be mostly resolved by apports heuristics)
  63 [16:20] <smspillaz> however, if it's got references to things like "PluginScreen::doBlahBlahBlah" then you're good
  64 [16:20] <smspillaz> especially if the stacktrace ends within compiz itself
  65 [16:20] <smspillaz> ok, now you're probably asking me "where do I get all of this stuff! I want to get my hands dirty hackign on this!"
  66 [16:21] <smspillaz> well, compiz is hosted upstream at git:// and also mirrored in launchpad at lp:compiz-core
  67 [16:21] <smspillaz> if you're used to working with launchpad, then I'd suggest using launchpad as it has some rather powerful features
  68 [16:21] <smspillaz> usually we try to keep the ABI/API of upstream compiz in sync with what downstream ubuntu is shipping
  69 [16:21] <smspillaz> that way, if you build core, you also don't have to rebuild plugins
  70 [16:22] <smspillaz> however, in the rare circumstance that this is the case, you'll need to rebuild some of the other standard components
  71 [16:22] <smspillaz> so, that being lp:compiz-core lp:compiz-plugins-main lp:libcompizconfig lp:compizconfig-python lp:ccsm
  72 [16:23] <smspillaz> for each of those, it's as easy as doing something like mkdir build; cd build; cmake ..; make && make install
  73 [16:23] <smspillaz> (compiz uses the cmake buildsystem)
  74 [16:24] <smspillaz> if there's a break in the API/ABI you'll also need to rebuild unity
  75 [16:24] <smspillaz> (that's lp:unity)
  76 [16:24] <smspillaz> (same instructions_)
  77 [16:24] <smspillaz> a small protip: since the window manager is a fairly core part of your system, its nice to have a working one if you're hacking on compiz and have happened to break things
  78 [16:25] <smspillaz> so you can install cmake-curses-gui and run ccmake .. and change the CMAKE_INSTALL_PREFIX to something that is not in the system $PATH
  79 [16:25] <smspillaz> for example, I keep mine in ~/Applications/Compiz
  80 [16:26] <smspillaz> (so you need to adjust your PKG_CONFIG_PATH LD_LIBRARY_PATH LD_RUN_PATH XDG_DATA_DIRS PATH and PYTHONPATH to reflect that change)
  81 [16:26] <smspillaz> in order that I don't get carpal tunnel syndrome, I usually just keep a script in my ~/.bashrc with a function to export those variables correctly
  82 [16:27] <smspillaz> so now that you've got the source code, where is everything
  83 [16:27] <smspillaz> well, if we have a look into
  84 [16:27] <smspillaz> you'll see there is quite a lot there
  85 [16:27] <smspillaz> (and this is just for core, but that's where all the bugs lie anyways)
  86 [16:28] <smspillaz> so first of all, you can ignore cmake/ po/ xslt/ metadata/ images/ legacy/ (I should really remove that)
  87 [16:28] <smspillaz> those are all either there for building compiz or default settings
  88 [16:29] <smspillaz> gtk/ is where the GTK-Window-Decorator lives and kde/ is where the KDE4-Window-Decorator lives
  89 [16:29] <smspillaz> basically in compiz, window borders, titlebars, menus etc are handled in a bit of a special way
  90 [16:29] <smspillaz> there's a process called a "decorator" which runs outside of compiz and actually draws the contents of the window borders
  91 [16:30] <smspillaz> (there's a good reason for this, and that is that it is not a good idea to mix toolkits and window managers)
  92 [16:30] <smspillaz> so part of the titlebars are handled by compiz and part of them are handled by the decorators
  93 [16:31] <smspillaz> basically, what the decorators do is talk with compiz' decor plugin over X11 window properties using the protocol defined in libdecoration
  94 [16:32] <smspillaz> they specify the geometry of the backing input window for the decorations as well as a pixmap which is the contents of that decoration
  95 [16:32] <smspillaz> (they work independently to figure out the contents of every single window decoration)
  96 [16:32] <smspillaz> they also handle all the input events on the backing input window for the decoration and tell compiz when to start moving and resizing windows
  97 [16:33] <smspillaz> so that's the decorators in a nutshell
  98 [16:33] <smspillaz> as for plugins/
  99 [16:33] <smspillaz> surprisingly, a lot of stuff in compiz is handled by plugins
 100 [16:33] <smspillaz> for example, moving a window by dragging it's titlebar or alt-drag is handled in a plugin
 101 [16:33] <smspillaz> or resizing a window in the same way also in a plugin
 102 [16:34] <smspillaz> the alt-tab switcher is in a plugin
 103 [16:34] <smspillaz> even rendering using OpenGL is in a plugin
 104 [16:34] <smspillaz> the compiz end of window titlebars and frames are also in a plugin
 105 [16:35] <smspillaz> the way those plugins work is fairly simple, they take some user interaction and modify the state of the window system based on it
 106 [16:35] <smspillaz> but the real magic of compiz happens within core
 107 [16:35] <smspillaz> which is that subdirectory named /src
 108 [16:35] <smspillaz> core is both a lovely and scary place
 109 [16:35] <smspillaz> lovely because you can see all the hard-set policy of compiz
 110 [16:36] <smspillaz> scary because this is where communication with X11 happens and a lot of it isn't pretty
 111 [16:36] <smspillaz> most of core is separated out into separate files so you can see what's going on
 112 [16:37] <smspillaz> action.cpp is the file which handles the dispatching "compiz events" (eg ctrl-alt-left to move desktops) on X11 input events
 113 [16:37] <smspillaz> event.cpp is where we handle X11 events and change state based on policy
 114 [16:38] <smspillaz> most of that happens in this gigantic function here
 115 [16:38] <smspillaz>
 116 [16:38] <smspillaz> I'll run through them breifly
 117 [16:38] <smspillaz> basically, we have to dispatch "actions" on key and button events (also also enter/leave events for edge windows)
 118 [16:39] <smspillaz> there are also a number events that we only get because we're the window manager
 119 [16:39] <smspillaz> so SelectionRequest and SelectionClear are basically two special events which exist when another window manager or compositing manager wishes to take over from us
 120 [16:40] <smspillaz> sections are explained here
 121 [16:40] <smspillaz>
 122 [16:40] <smspillaz> they aren't really of all that much concern to compiz
 123 [16:41] <smspillaz> the next is ConfigureRequest (will come back to ConfigureNotify in a second)
 124 [16:41] <smspillaz> basically, in X11, we can set an event mask which stops all other application from being able to resize windows except us
 125 [16:41] <smspillaz> (that being the magical SubstructureRedirectMask)
 126 [16:41] <smspillaz> we do this on what's called the root window
 127 [16:42] <smspillaz> which is the topmostlevel window in the window heirarchy
 128 [16:42] <smspillaz> all windows are children of the root window
 129 [16:42] <smspillaz> by selecting SubstructureRedirectMask on the root window, we are telling X11 that no client which is a direct child of this window should be able to resize itself
 130 [16:42] <smspillaz> or move itself
 131 [16:42] <smspillaz> or change its stack position
 132 [16:43] <smspillaz> when that happens, compiz gets a ConfigureRequest event
 133 [16:43] <smspillaz> at which point, compiz decided whether to allow the window to move, resize, or restack itself
 134 [16:43] <smspillaz> (in most cases, it will just go straight through, however we may need to adjust the request a little so that windows don't go above, eg, panels)
 135 [16:44] <smspillaz> by calling XConfigureWindow on the window, we override the substructureredirectmask and change the size,position,stacking of the window ourselves, usually what the application wanted
 136 [16:44] <smspillaz> MapRequest is another important event
 137 [16:45] <smspillaz> it happens when a window attempts to display itself
 138 [16:45] <smspillaz> (using XMapWindow)
 139 [16:45] <smspillaz> in that case, we need to set its initial position and also some properties on the window
 140 [16:45] <smspillaz> then there are the "Notifies"
 141 [16:46] <smspillaz> so ConfigureNotify happens whenever the size,position,stacking of a window *actually* changes
 142 [16:47] <smspillaz> this is usually in response to us changing the size,position,stacking of the window ourselves, but watch out, because some windows are "override redirect" and will be able to change their positions anyways regardless of our SubstructureRedirectMask
 143 [16:47] <smspillaz> there is also FocusIn and FocusOut which we use to handle focus stealing prevention
 144 [16:47] <smspillaz> so once compiz processes these events, where do they actually go?
 145 [16:48] <smspillaz> well, for any request that tries to *change* the size,position,stacking of a window, that's all handled in a function called CompWindow::moveResize
 146 [16:49] <smspillaz> for any request that tries to create a new window, that's all in ::processMap
 147 [16:49] <smspillaz> once a window *is* resized, restacked or moved, that's handled in CompWindow PrivateWindow::configure
 148 [16:49] <smspillaz> err
 149 [16:49] <smspillaz> PrivateWindow::configure
 150 [16:49] <smspillaz> or PrivateWindow::configureFrame if it is a normal toplevel window
 151 [16:49] <smspillaz> (eg reparented)
 152 [16:50] <smspillaz> in response to a window being mapped, we've got CompWindow::map and CompWindow::unmap for UnmapNotfy
 153 [16:50] <smspillaz> CreateNotify creates a new CompWindow
 154 [16:50] <smspillaz> now finally there is this big block called PropertyNotify
 155 [16:50] <smspillaz> in there are handlers for a whole bunch of changes to window properties known as "atoms"
 156 [16:51] <smspillaz> basically, applications set hints on windows for how they're supposed to operate
 157 [16:51] <smspillaz> that's all specified in a standared known as the Inter Client Communications Conventions Manual and the Extended Window Manager Hints
 158 [16:52] <smspillaz> here: and here:
 159 [16:52] <smspillaz> protip: unless you want your brain to explode, I would NOT read those all at once
 160 [16:52] <smspillaz> rather, if you hit a bit of the code which deals with a particular property, go look in those manuals
 161 [16:52] <smspillaz> since those explain what that property does
 162 [16:53] <smspillaz> for example, when a window changes state we get a property notify for _NET_WM_STATE (Atoms::winState)
 163 [16:53] <smspillaz> the relevant section in the manual specifies what each state is supposed to mean
 164 [16:53] <smspillaz> that's pretty much how compiz operates as a window manager
 165 [16:53] <smspillaz> the logic controlling how each request and event handler is supposed to work is all implemented in window.cpp and screen.cpp
 166 [16:54] <smspillaz> screen.cpp is the "toplevel" object handling the window management context
 167 [16:54] <smspillaz> and window.cpp is for each window
 168 [16:54] <smspillaz> ok, now how to make your stuff rock
 169 [16:54] <smspillaz> once you've tracked down the bug, and fixed it in the implementation section or the communication section you can create a launchpad branch merge proposal
 170 [16:55] <smspillaz> not that compiz is an upstream project as such you do not need to sign the contributor agreement for it
 171 [16:55] <smspillaz> *note
 172 [16:55] <smspillaz> merge propose your branch to lp:compiz-core
 173 [16:55] <smspillaz> or if you're working on a plugin outside of core lp:compiz-$whatever-plugin
 174 [16:55] <smspillaz> (don't merge propose to lp:compiz-plugins-main or lp:compiz-plugins-extra)
 175 [16:56] <smspillaz> once that's done, the launcher team and the other compiz maintainers will look over it
 176 [16:56] <smspillaz> and approve and merge it if its good
 177 [16:56] <smspillaz> happy bug fixing!
 178 [16:56] <smspillaz> Now is the time to hit me with questions
 179 [16:56] <smspillaz> (and not pet bugs)
 180 [16:56] <smspillaz> !q
 181 [16:57] <smspillaz> ok, we had a question and ClassBot isn't picking it up
 182 [16:57] <smspillaz> QUESTION: (App writing) What's the best way to resize a ui  file defined gtk window before showing it (getting dimensions  from preferences before display), so Compiz will put in in a  good place. Seems like the window size defined in the ui file  is the only one compiz looks at.
 183 [16:57] <smspillaz> so this is more of an app developers question
 184 [16:57] <smspillaz> but basically, compiz places windows in the "least used space possible"
 185 [16:58] <smspillaz> so if you want to get a good position, you should make the size of the application in the ui file the actual size that you plan to use
 186 [16:59] <smspillaz> you can also modify the win_gravity hint
 187 [16:59] <smspillaz> that will make a window more likely to be placed in a certain area of the screen by default
 188 [16:59] <smspillaz> have a look at the section called "window geometry" in the Extended Window Manager Hints
 189 [17:00] <smspillaz> okay, that's it
 190 [17:00] <smspillaz> back to work for me :P)

MeetingLogs/devweek1107/FixingCompizBugs (last edited 2011-07-18 08:30:15 by dholbach)