Comment 1 for bug 1184381

Revision history for this message
Sami Jaktholm (sjakthol) wrote :

I've debugged this a bit and this seems to be quite a complicated issue.

The reason causing this is that wobbly doesn't receive the moveNotify of grid blocking the window movement. Wobbly only sees the window moving forward and draws it where the window had been moved (if you let the wobbling settle by holding the pointer still, the window returns back to the original location). In reality the window moves backwards a moment later but wobbly doesn't know that.

Once it's time to snap off the window, it will move even further away from the pointer. At some point the place the window is drawn becomes the real location of the window (I don't know at which point or why but it certainly seems so).

Now, why doesn't wobbly get the moveNotify from grid moving the window? When window is originally moved, moveNotifies are sent properly in following order: Wobbly, Animation, Grid, Decor, GL, Composite.

When the last moveNotify is called, the execution returns back to GridWindow::moveNotify. It then calls CompWindow::move, which in turn sends moveNotify to following plugins in this order: Decor, GL, Composite.

The first three plugins aren't notified about new the movement at all. This is due to the nature of the wrap system: it can only handle events one at a time.

The wrapped methods are chained together. This is achieved by incrementing an index for a list of interested interfaces. Once an interface is found, the corresponding method is invoked. This method then calls the controller method (e.g. CompWindow::moveNotify) which increments the index until second interface is found, calls it and so on.

When the end is reached, this all goes reverse. The last function returns, the controller restores the index to what it was before the last function was called and returns to the second to last function. This continues until the first call to the controller returns back to it's invoker (e.g. CompWindow::move).

This is where the problem lies. Once the reversing reaches grid the current interface index for moveNotify is pointing at GridWindow::moveNotify. When it calls CompWindow::move that initiates a new moveNotify the search for interested interfaces start at the middle of the list. The ones at the beginning are completely ignored!

So basically whether this works or not is determined by the order the plugins are loaded. If grid is loaded after wobbly, it works a bit better. However, it doesn't really look that nice. You can see it via following steps:
1) Run compiz with "compiz --replace core composite opengl decor move resize wobbly grid"
2) Corner grid the window with keyboard
3) Click on the resize border to reset the grid state
4) Corner grid the window with keyboard again
5) Drag the window off the edge.

OR change the order the plugins are loaded in CCSM so that wobbly loads before grid.

That's just a workaround - the real fix is a whole lot bigger project...