FixingCompizBugs
Dev Week -- Fixing bugs in compiz -- smspillaz -- Fri, Jul 15th, 2011
Toggle line numbers
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> https://bugs.launchpad.net/ubuntu/+source/compiz
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://git.compiz.org 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 http://bazaar.launchpad.net/~compiz-team/compiz-core/0.9.5/files
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> http://bazaar.launchpad.net/~compiz-team/compiz-core/0.9.5/view/head:/src/event.cpp#L984
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> http://tronche.com/gui/x/xlib/events/client-communication/selection.html
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: http://tronche.com/gui/x/icccm/ and here: http://standards.freedesktop.org/wm-spec/wm-spec-1.3.html
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)