Regression r3722: Grid + Wobbly Windows: Pointer position way off, if snapping off gridded windows and Grid's "Snap Windows Back To Original Size" option is disabled

Bug #1184381 reported by MC Return on 2013-05-26
This bug affects 1 person
Affects Status Importance Assigned to Milestone

Bug Description

MC Return (mc-return) on 2013-05-26
Changed in compiz:
assignee: nobody → MC Return (mc-return)
status: New → In Progress
status: In Progress → Confirmed
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...

MC Return (mc-return) on 2013-06-15
Changed in compiz:
milestone: none →
importance: Undecided → Medium
MC Return (mc-return) wrote :

Hey, Sami.
First of all thanks a lot for helping with debugging this and your detailed report.

TBH, I wanted to approach this issue this way:

if (wobblyIsEnabled)

I just have to see how to best extract the isWobblyEnabled information... as I am not sure how to best do it.

What do you think about that (simple) solution ?

Sami Jaktholm (sjakthol) wrote :

I think that's a hack which should be avoided. It'll be extra code to maintain and might cause issues in the future. This is basically the same as not blocking the window movement at all and just restoring the size.

A second hack would be to force the cube to be loaded before grid.

Both of these hacks only hide the problem without really fixing anything. I don't like either.

MC Return (mc-return) wrote :

Sami, okay - agreed that it would be a hack and that a hack is nothing good ;)

The problem is just that you said yourself that "the real fix is a whole lot bigger project" and I am not sure if we really have enough time for that.
Of course I am also happy, if you want to eliminate this bug, because you already did this big junk of investigation of the real cause...

Do you want to take on this bug ?

Changed in compiz:
assignee: MC Return (mc-return) → nobody
status: Confirmed → Triaged
Sami Jaktholm (sjakthol) wrote :

I have thought of that but I haven't came up with anything that would work with the current wrapsystem architecture.

So I'm not up for the task either.

Sami Jaktholm (sjakthol) on 2013-07-14
tags: added: grid
MC Return (mc-return) on 2013-07-24
Changed in compiz:
milestone: →
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers