Merge lp:~smspillaz/compiz-core/compiz-core.work_923683 into lp:compiz-core

Proposed by Sam Spilsbury on 2012-02-28
Status: Superseded
Proposed branch: lp:~smspillaz/compiz-core/compiz-core.work_923683
Merge into: lp:compiz-core
Diff against target: 1439 lines (+277/-573)
10 files modified
include/core/window.h (+2/-2)
plugins/composite/src/window.cpp (+16/-16)
plugins/decor/src/decor.cpp (+15/-15)
plugins/move/src/move.cpp (+12/-12)
plugins/opengl/src/window.cpp (+2/-2)
src/event.cpp (+1/-1)
src/privatewindow.h (+7/-10)
src/screen.cpp (+2/-0)
src/window.cpp (+216/-511)
src/windowgeometry.cpp (+4/-4)
To merge this branch: bzr merge lp:~smspillaz/compiz-core/compiz-core.work_923683
Reviewer Review Type Date Requested Status
Daniel van Vugt 2012-02-28 Needs Fixing on 2012-02-28
Sam Spilsbury Pending
Alan Griffiths 2012-02-28 Pending
Review via email: mp+94918@code.launchpad.net

This proposal supersedes a proposal from 2012-02-26.

This proposal has been superseded by a proposal from 2012-02-28.

Description of the change

A lot of the work that I've wanted to do in order to properly fix this, but in a far more condensed form. (bug 923683). Proposing early so that ~vanvugt will see it :)

Always use the asynchronous codepaths in core. This commit changes the following:

 * CompWindow::move is now just a wrapper around CompWindow::configureXWindow
 * CompWindow::configureXWindow will always call through to moveNotify
 * moveNotify is only ever called pre-request to the server in the case of
   managed windows (SubstructureRedirectMask guaruntees they will end up in
   the right place) and post ConfigureNotify for override redirect windows
 * resizeNotify is always called post ConfigureNotify regardless of whether
   or not the window is managed or not
 * composite and opengl now use the geometry last sent to the server in order
   to compute display matrices and window positions as well as damage regions
 * decor now also does the above
 * const correctness in include/core/window.h
 * removed priv->width and priv->height , which was just redundant data used for
   window shading and honestly, is a ticking time bomb for future maintainers.
 * CompWindow::syncPosition is now deprecated and a no-op
 * Removed the majority of PrivateWindow::updateFrameWindow - this function had a lot
   of redundant code which PrivateWindow::reconfigureXWindow had anyways - the big work
   there was to send synthetic ConfigureNotify events to ourselves to notify about windows
   moving within frame windows that don't move themselves. Its safer to use reconfigureXWindow
   in this case and probably more sane too. We should look into removing the other update* functions.

Caveats:

 0) There are no tests yet
 1) Window movement performance will regress with this branch. This is *probably* due to the fact that for every slight movement, we send a full ConfigureWindow request to the X Server and it has to post back to us a full ConfigureNotify, for pretty much every pixel the window moves. In the case that we're not doing compositing thats fine, but in every other case its *super* chatty and largely unnecessary. This can probably be optimized a lot, but that will require work to gather up requests that we want to send to the X server - combine them (eg, merging the stack of requests based on the change mask and using the latest values where appropriate). Thats a lot of work and probably not appropriate in this branch
 2) The diff is a little big
 3) No tests
 4) Window shading is more than likely going to break again, mostly because I haven't tested it yet, but also because shading does some strange things and manipulated geometry values in strange ways
 5) No tests

Testing plan?

I would imagine here that the PendingConfigureRequests object can probably be split out into something testable, as can the logic to strip flags from frame window geometry and client window geometry updates.

To post a comment you must log in.
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal
Download full text (10.3 KiB)

The diff is big and scary, but its not too complicated. I'll explain each separate part

1 === modified file 'include/core/window.h'
2 --- include/core/window.h 2012-01-20 15:20:44 +0000
3 +++ include/core/window.h 2012-01-31 17:12:59 +0000
4 @@ -398,9 +398,9 @@
5
6 bool hasUnmapReference ();
7
8 - bool resize (XWindowAttributes);
9 + bool resize (const XWindowAttributes &);
10
11 - bool resize (Geometry);
12 + bool resize (const Geometry &);
13
14 bool resize (int x, int y, int width, int height,
15 int border = 0);

const correctness

31 int x1, x2, y1, y2;
32
33 - CompWindow::Geometry geom = priv->window->geometry ();
34 - CompWindowExtents output = priv->window->output ();
35 + const CompWindow::Geometry &geom = priv->window->serverGeometry ();
36 + const CompWindowExtents &output = priv->window->output ();

more const correctness

35 + const CompWindow::Geometry &geom = priv->window->serverGeometry ();
36 + const CompWindowExtents &output = priv->window->output ();

Lots of this - in paint code we want to use serverFoo because it was the last thing sent to the server. And this is always guarunteed to come back to us.

166 - unsigned int width = window->size ().width ();
167 - unsigned int height = window->size ().height ();
168 + unsigned int width = window->geometry ().width ();
169 + unsigned int height = window->geometry ().height ();

CompWindow::size was just returning CompSize (priv->width, priv->height) which was just redundant data which should be removed. Replaced it with geometry () for clarity

299 + void move (int dx, int dy, bool sync);
300 + bool resize (int dx, int dy, int dwidth, int dheight, int dborder);
301 + bool resize (const CompWindow::Geometry &g);
302 + bool resize (const XWindowAttributes &attrib);
303 +

Added PrivateWindow::move and PrivateWindow::resize - to be called whenever a new position / size comes back from the server. (cut'n'paste code from CompWindow::move and CompWindow::resize

335 -
336 - gettimeofday (&lastConfigureRequest, NULL);
337 - /* Flush any changes made to serverFrameGeometry or serverGeometry to the server
338 - * since there is a race condition where geometries will go out-of-sync with
339 - * window movement */
340 -
341 - window->syncPosition ();
342 -
343 - if (serverInput.left || serverInput.right || serverInput.top || serverInput.bottom)
344 - {
345 - int bw = serverGeometry.border () * 2;
346 -
347 - xwc.x = serverGeometry.x () - serverInput.left;
348 - xwc.y = serverGeometry.y () - serverInput.top;
349 - xwc.width = serverGeometry.width () + serverInput.left + serverInput.right + bw;
350 - if (shaded)
351 - xwc.height = serverInput.top + serverInput.bottom + bw;
352 - else
353 - xwc.height = serverGeometry.height () + serverInput.top + serverInput.bottom + bw;
354 -
355 - if (shaded)
356 - height = serverInput.top + serverInput.bottom;
357 -
358 - if (serverFrameGeometry.x () == xwc.x)
359 - valueMask &= ~(CWX);
360 - else
361 - serverFrameGeometry.setX (xwc.x);
362 -
*snip*
616 - XMoveResizeWindow (screen->dpy (), id, 0, 0,
617 - serverGeometry.width (), serverGeometry.height ());
618 - window->sendConfigureNotify ();
619 - window->windowNotify (CompWindowNotifyFrameUpdate...

Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

824 -
825 - if (!pendingConfigures.pending ())
826 - {
827 - /* Tell plugins its ok to start doing stupid things again but
828 - * obviously FIXME */
829 - CompOption::Vector options;
830 - CompOption::Value v;
831 -
832 - options.push_back (CompOption ("window", CompOption::TypeInt));
833 - v.set ((int) id);
834 - options.back ().set (v);
835 - options.push_back (CompOption ("active", CompOption::TypeInt));
836 - v.set ((int) 0);
837 - options.back ().set (v);
838 -
839 - /* Notify other plugins that it is unsafe to change geometry or serverGeometry
840 - * FIXME: That API should not be accessible to plugins, this is a hack to avoid
841 - * breaking ABI */
842 -
843 - screen->handleCompizEvent ("core", "lock_position", options);
844 - }

DIE

924 -bool
925 -PrivateWindow::checkClear ()
926 -{
927 - if (pendingConfigures.pending ())
928 - {
929 - /* FIXME: This is a hack to avoid performance regressions
930 - * and must be removed in 0.9.6 */
931 - compLogMessage ("core", CompLogLevelWarn, "failed to receive ConfigureNotify event on 0x%x\n",
932 - id);
933 - pendingConfigures.dump ();
934 - pendingConfigures.clear ();
935 - }
936 -
937 - return false;
938 -}
939 -
940 void
941 compiz::X11::PendingEventQueue::add (PendingEvent::Ptr p)
942 {
943 @@ -2454,21 +2148,6 @@
944 mValueMask (valueMask),
945 mXwc (*xwc)
946 {
947 - CompOption::Vector options;
948 - CompOption::Value v;
949 -
950 - options.push_back (CompOption ("window", CompOption::TypeInt));
951 - v.set ((int) w);
952 - options.back ().set (v);
953 - options.push_back (CompOption ("active", CompOption::TypeInt));
954 - v.set ((int) 1);
955 - options.back ().set (v);
956 -
957 - /* Notify other plugins that it is unsafe to change geometry or serverGeometry
958 - * FIXME: That API should not be accessible to plugins, this is a hack to avoid
959 - * breaking ABI */
960 -
961 - screen->handleCompizEvent ("core", "lock_position", options);
962 }

DIE

Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

GOOD IN THEORY:

* Most of the description sounds like steps in the right direction.

* Simplified: Replacing 559 lines of code with 247.

UNSURE ABOUT THE THEORY:

* "composite and opengl now use the geometry last sent to the server"
This should give maximum performance, sure, but what if (for some reason) the server rejects the configure request as being somehow invalid? Would you ever encounter that, like moving a window to an invalid location?
For stability and correctness (which should be the primary goal right now) don't we want "composite and opengl now use the geometry last received from the server"?

* Caveat #1 is not really a caveat. It's the right (intended) design. But if you want to see a (buggy) example of how to solve the chattiness look at the timer code here:
https://code.launchpad.net/~vanvugt/compiz-core/fix-764330-trunk/+merge/86497
This was slightly buggy though as it broke keyboatrd-initiated moves (incorrect pointer warp). Simple to fix, probably.

* Still no XFlush's to ensure XConfigureWindow happens immediately. Or are there adequate XSyncs already?

BAD IN THEORY:

* The diff is too big for a mere mortal (who hasn't worked on all the code before) to fully load into their mental interpreter and evaluate its theoretical correctness. Please read that sentence again; it's important.

GOOD IN PRACTICE:

* Window movement is smooth and predictable, but not really better than in oneiric.

BAD IN PRACTICE:

* The bug introduced is worse than the bug being fixed; Window contents offset from the frame/decorations whenever a window is created or maximized.

* All that code, but we still haven't reduced the lag below oneiric-levels. Still not as good as Gnome Shell.

CONCLUSION:

The theory is mostly good but there is at least one serious bug that needs fixing. We probably shouldn't risk 0.9.7.0 any more with large changes like this. We should aim to get this code into a later release when it's more stable, not 0.9.7.0.

review: Needs Fixing
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal
Download full text (3.2 KiB)

> GOOD IN THEORY:
>
> * Most of the description sounds like steps in the right direction.
>
> * Simplified: Replacing 559 lines of code with 247.
>
>
> UNSURE ABOUT THE THEORY:
>
> * "composite and opengl now use the geometry last sent to the server"
> This should give maximum performance, sure, but what if (for some reason) the
> server rejects the configure request as being somehow invalid? Would you ever
> encounter that, like moving a window to an invalid location?
> For stability and correctness (which should be the primary goal right now)
> don't we want "composite and opengl now use the geometry last received from
> the server"?

See http://tronche.com/gui/x/xlib/window/XConfigureWindow.html

Since we have SubstructureRedirectMask, it is guarunteed that any ConfigureWindow request we make on a child of the root window is guarunteed to end up in that position (hence the event tracker).

The only error cases I can think of is where you ask for a window to be of a size < 0 or > MAXSHORT. Ideally we should check for that case.

>
> * Caveat #1 is not really a caveat. It's the right (intended) design. But if
> you want to see a (buggy) example of how to solve the chattiness look at the
> timer code here:
> https://code.launchpad.net/~vanvugt/compiz-core/fix-764330-trunk/+merge/86497
> This was slightly buggy though as it broke keyboatrd-initiated moves
> (incorrect pointer warp). Simple to fix, probably.
>

There are some optimizations that can be done here - for example, if a window is grabbed, you can withold sending positions to the server until it is ungrabbed, or there is some other reason why you would want to do that. When that happens you can send it all at once.

> * Still no XFlush's to ensure XConfigureWindow happens immediately. Or are
> there adequate XSyncs already?

The GLib mainloop work introduced an XFlush as soon as we have finished dispatching the X event source.

>
>
> BAD IN THEORY:
>
> * The diff is too big for a mere mortal (who hasn't worked on all the code
> before) to fully load into their mental interpreter and evaluate its
> theoretical correctness. Please read that sentence again; it's important.

Indeed. The good thing is that its mostly all deletion and consolidation.

>
>
> GOOD IN PRACTICE:
>
> * Window movement is smooth and predictable, but not really better than in
> oneiric.
>
>
> BAD IN PRACTICE:
>
> * The bug introduced is worse than the bug being fixed; Window contents offset
> from the frame/decorations whenever a window is created or maximized.

Alright. I haven't seen this yet, but I have an idea of what might cause it. Will have a look into it when I get some time.

>
> * All that code, but we still haven't reduced the lag below oneiric-levels.
> Still not as good as Gnome Shell.

This will be fixed once the chattyness goes away. (as above). Watch your X.org CPU usage as you move windows - it skyrockets because at the moment we flood it with requests.

>
>
> CONCLUSION:
>
> The theory is mostly good but there is at least one serious bug that needs
> fixing. We probably shouldn't risk 0.9.7.0 any more with large changes like
> this. We should aim to get this code into a later r...

Read more...

Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal

OK, I'm still wading through the changes. But I feel like a rant...

1307 CompSize
1308 CompWindow::size () const
1309 {
1310 - return CompSize (priv->width + priv->geometry.border () * 2,
1311 - priv->height + priv->geometry.border () * 2);
1312 + return CompSize (priv->geometry.width () + priv->geometry.border () * 2,
1313 + priv->geometry.height () + priv->geometry.border () * 2);
1314 }

As a change this doesn't look too bad - but it ignores a horrid design!

1. Chained operations like "priv->geometry.width ()" imply too muck knowledge of the details of "priv".
   That is "priv->width ()" would reflect less coupling.

2. You're tracing the path "priv->geometry..." many times, which suggests that the logic belongs in "geometry".
   "return priv->geometry.size ()" or "return CompSize(priv->geometry)" would reflect better coherence.

So, assuming (because borders may be optional?) that there's an unambiguous mapping from CompWindow::Geometry:

a. Add a constructor to CompSize: "explicit CompSize(CompWindow::Geometry const& g) : mWidth(g.width () + g.border () * 2) ..."
b. Add an inline method "CompSize PrivateWindow::size () const { return CompSize(priv->geometry); }"
c. Rewrite the above as "CompSize CompWindow::size () const { "return priv->size ()"; }"

Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal

264 - /* been shaded */
265 + /* been shaded
266 if (w->priv->height == 0)
267 {
268 if (w->id () == priv->activeWindow)
269 w->moveInputFocusTo ();
270 - }
271 + }*/

Comments are not for storing old versions of the code - that's what we use bzr for. ;)

review: Needs Fixing
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal

There's a lot of "<blah>.width () + <blah>.border () * 2" and "<blah>.height () + <blah>.border () * 2" around. Surely CompWindow::Geometry could have a "widthWithBorders" method - or maybe a free function?

I'm tempted by

template<Typename T>
inline int heightWithBorders(T const& blah) { return blah.height () + blah.border () * 2; }

Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

> OK, I'm still wading through the changes. But I feel like a rant...
>
> 1307 CompSize
> 1308 CompWindow::size () const
> 1309 {
> 1310 - return CompSize (priv->width + priv->geometry.border () * 2,
> 1311 - priv->height + priv->geometry.border () * 2);
> 1312 + return CompSize (priv->geometry.width () + priv->geometry.border ()
> * 2,
> 1313 + priv->geometry.height () + priv->geometry.border () * 2);
> 1314 }
>
> As a change this doesn't look too bad - but it ignores a horrid design!
>
> 1. Chained operations like "priv->geometry.width ()" imply too muck knowledge
> of the details of "priv".
> That is "priv->width ()" would reflect less coupling.

Probably, although priv is just a private member with implementation details, I don't really see this as a large design problem.

>
> 2. You're tracing the path "priv->geometry..." many times, which suggests that
> the logic belongs in "geometry".
> "return priv->geometry.size ()" or "return CompSize(priv->geometry)" would
> reflect better coherence.
>
> So, assuming (because borders may be optional?) that there's an unambiguous
> mapping from CompWindow::Geometry:
>
> a. Add a constructor to CompSize: "explicit CompSize(CompWindow::Geometry
> const& g) : mWidth(g.width () + g.border () * 2) ..."
> b. Add an inline method "CompSize PrivateWindow::size () const { return
> CompSize(priv->geometry); }"
> c. Rewrite the above as "CompSize CompWindow::size () const { "return
> priv->size ()"; }"

+1 for all three

Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

> 264 - /* been shaded */
> 265 + /* been shaded
> 266 if (w->priv->height == 0)
> 267 {
> 268 if (w->id () == priv->activeWindow)
> 269 w->moveInputFocusTo ();
> 270 - }
> 271 + }*/
>
> Comments are not for storing old versions of the code - that's what we use bzr
> for. ;)

Indeed, this is a small portion of the code and I'm not yet sure what to do with it. When I get around to revisiting this section (when I actually get time to look at this again, wanted to get it up for review early) I'll see what can be done.

Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

> There's a lot of "<blah>.width () + <blah>.border () * 2" and "<blah>.height
> () + <blah>.border () * 2" around. Surely CompWindow::Geometry could have a
> "widthWithBorders" method - or maybe a free function?
>
> I'm tempted by
>
> template<Typename T>
> inline int heightWithBorders(T const& blah) { return blah.height () +
> blah.border () * 2; }

I'm not really sure ?

The complexity here comes from a legacy part of the X Server coming into play - a window could have fixed dimentions, but also specify a "border" which would be exclusive of the fixed dimentions, so you'd have to take this into account for all positioning operations (Xterm comes to mind here).

I definitely agree that geom.width () + geom.border () * 2 feels fragile and indeed, that has tripped me up many times before. Maybe a default parameter with a bitflag makes sense here, eg IncludeBorder , IncludeBorderFirst , IncludeBorderSecond (as it is on both sides)

Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

I'll note that the above isn't *really* all that relevant to this merge though, but good things to keep in mind in any case. I'd rather not see the diff get any better except for adding tests.

Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Please resubmit for target branch lp:compiz-core (0.9.7)

review: Resubmit
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal

A lot of the above is about making the code better (which the proposal doesn't attempt). However, in a previous version I pointed out that:

> 264 - /* been shaded */
> 265 + /* been shaded
> 266 if (w->priv->height == 0)
> 267 {
> 268 if (w->id () == priv->activeWindow)
> 269 w->moveInputFocusTo ();
> 270 - }
> 271 + }*/
>
> Comments are not for storing old versions of the code - that's what we use bzr for. ;)

I still think that needs fixing.

review: Needs Fixing
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

Alright, I've updated this so that there's no distorted windows on decoration size change. Was (ironically) a race condition.

Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

For the sake of not making this diff any bigger, I'm not going to introduce unit tests here.

As for testing this I'd say the following is appropriate:

 * Add testcase for PendingConfigureEvent
 * Add testcase for rectsToRegion (serverGeometry should really be DI'd here)

Notes for the future:

 * As alan has said - the whole priv->geometry ().width () + priv->geometry ().border () * 2 is /really/ awkward and error prone, but we need it to support windows like xterm that still use this (stupid, legacy) attribute on their windows. I would say that the role of compiz::window::Geometry should thus be expanded somewhat
   - it should also encapsulate priv->region and really, geometry::x and friends should be made with reference to that. Ideally we'll store two regions, one with borders and one without. That sucks, since its a little memory hungry, but at least the cost is only really born whenever those regions need to be updated (::translate on a region with one rectangle is basically free, slightly more complicated on regions with multiple rects (eg, shaped window). The default should be to return the size /without/ borders, and have a default-parameter enum to get the size with borders.

Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Unfortunately still fails basic testing. The same bug remains;

* The bug introduced is worse than the bug being fixed; Window contents offset from the frame/decorations whenever a window is created or maximized.

review: Needs Fixing
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Also... I would have thought/hoped that a simplified/stable solution would eliminate "serverGeometry" completely.

        /**
        * Geometry retrieved from the
         * last ConfigureNotify event received
         */
        Geometry & geometry () const;

        /**
         * Geometry last sent to the server
         */
        Geometry & serverGeometry () const;

I understand why we have, and why we might want, serverGeometry. However it is an optimization which only makes sense to attempt if the code is stable and bug-free to begin with.

While serious bugs remain, I think the first goal should be to simplify the logic down to just using "geometry" and remove or stub "serverGeometry".

Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

> Also... I would have thought/hoped that a simplified/stable solution would
> eliminate "serverGeometry" completely.
>
> /**
> * Geometry retrieved from the
> * last ConfigureNotify event received
> */
> Geometry & geometry () const;
>
> /**
> * Geometry last sent to the server
> */
> Geometry & serverGeometry () const;
>
> I understand why we have, and why we might want, serverGeometry. However it is
> an optimization which only makes sense to attempt if the code is stable and
> bug-free to begin with.
>
> While serious bugs remain, I think the first goal should be to simplify the
> logic down to just using "geometry" and remove or stub "serverGeometry".

There are some usescases for when we need to know what the last /received/ geometry from the server is. That's why the whole geometry/serverGeometry thing exists.

Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

Also, I'm not seeing this offset problem - could you give me some steps to reproduce it ?

Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

> > Also... I would have thought/hoped that a simplified/stable solution would
> > eliminate "serverGeometry" completely.
> >
> > /**
> > * Geometry retrieved from the
> > * last ConfigureNotify event received
> > */
> > Geometry & geometry () const;
> >
> > /**
> > * Geometry last sent to the server
> > */
> > Geometry & serverGeometry () const;
> >
> > I understand why we have, and why we might want, serverGeometry. However it
> is
> > an optimization which only makes sense to attempt if the code is stable and
> > bug-free to begin with.
> >
> > While serious bugs remain, I think the first goal should be to simplify the
> > logic down to just using "geometry" and remove or stub "serverGeometry".
>
>
> There are some usescases for when we need to know what the last /received/
> geometry from the server is. That's why the whole geometry/serverGeometry
> thing exists.

Hmm, we could make it so that serverGeometry is returned for managed windows and geometry is returned for override redirect windows on the public API. That of course means that we have to break the public API and update all the plugins.

Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

The practical problem:

Just start compiz --replace composite opengl move resize decor
and gtk-window-decorator --replace
Then every window will have its contents horizontally shifted around 15 pixels from the correct location relative to its decorations. The shift occurs whenever a window is created, maximized or restored. The shift goes away (corrects itself) when you start moving the window. On a positive note, the lag *appears* totally fixed and dragging windows is performing as well as Gnome Shell now.

The theoretical problem:

You can ignore my comments about geometry/serverGeometry for now. They are insignificant compared to the above bug. And besides, the use of both geometry and serverGeometry now appears to be yielding the desired reduction in lag.

Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Screenshot of the bug introduced by this branch:
https://launchpadlibrarian.net/92172452/shift.png

Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

Alright, I'll have another look into it ? (Not seeing it here :( )

Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

And it gets worse:
* The usual lag has come back. I have no idea how or why it was fixed when I ran it the first time.
* When dragging windows around, the area of desktop recently exposed flashes white.

So there is no improvement in performance and 2 serious regressions introduced :(

Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

    //XSynchronize (dpy, TRUE);

:) Haven't merged your other branch

Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Yikes. That would be another regression to be missing:
src/screen.cpp: XSynchronize (dpy, synchronousX ? True : False);

Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Perhaps remember to pull from trunk more often.

Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

where trunk == lp:compiz-core

Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Why doesn't the removal of XSynchronize show up in the below diff? It's obvious if I merge the branch myself. Maybe LaunchPad needs a kick to update the below diff?

Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

I think the horizontal shift bug is coming from upstream lp:compiz-core, and is exposed moreso by this branch. I can reproduce the same kind of horizontal shift jitter using just lp:compiz-core and resizing a window rapidly.

Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal

> The default should be to return the size /without/ borders,
> and have a default-parameter enum to get the size with borders.

There are very few designs where default parameters are better than multiple functions. This isn't one.

auto sizeWithoutBorders = geometry.size();
auto sizeWithBorders = geometry.sizeWithBorders(); // not geometry.size(::compiz::geometry::WithBorders);

Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

OK, the horizontal shifting bug does not seem to be caused by this branch. Just made worse by this branch.

Sam, please review that nasty issue first: bug 928173.

Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

This branch will incidentally help with a lot of the resizing issues, so I think it should be merged first.

Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

I would prefer not to approve this branch so long as the offset/shift bug is as bad as it is. If absolutely necessary, we could release without a fix for bug 928173 because it is hidden by the default Ubuntu config. But introducing this branch makes the bug unacceptably worse, as the screenshot showed.

Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

To clarify, "unacceptably worse" means that the bug will no longer be hidden in Ubuntu and will occur on every new window that opens. At least on my machine (and presumably others).

Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

.... I'm still not even seeing this issue.

I can look into resizing tonight if you really think that this is a blocker.

Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

I think I may have confused the situation by suggesting the regression introduced by this branch is bug 928173. The symptoms are actually slightly different. It's only a theory that it's the same bug, because the size of the horizontal offset looks similar.

The bug I see with this branch would be worthy of a new bug report (a critical regression) that I don't want to log. And we won't have to log that bug so long as it's fixed before this branch is merged.

Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

On Wed, 8 Feb 2012, Daniel van Vugt wrote:

> I think I may have confused the situation by suggesting the regression introduced by this branch is bug 928173. The symptoms are actually slightly different. It's only a theory that it's the same bug, because the size of the horizontal offset looks similar.
>
> The bug I see with this branch would be worthy of a new bug report (a critical regression) that I don't want to log. And we won't have to log that bug so long as it's fixed before this branch is merged.
> --
> https://code.launchpad.net/~smspillaz/compiz-core/compiz-core.work_923683/+merge/91654
> You are the owner of lp:~smspillaz/compiz-core/compiz-core.work_923683.
>

Alright.

I am looking into the decor plugin for a way to resolve this.

Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Despite the success of the fix for #928173: lp:~smspillaz/compiz-core/compiz-core.decor_928173
the offset bug introduced by this branch persists.

This confirms that the horizontal offset/shift problems introduced (or exposed) by this branch are certainly not the same as bug 928173.

review: Needs Fixing
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

I still can't even observe this problem that you're referring to :(

Can you specify, exactly what windows this occurs on and /exact/ steps to reproduce it ?

Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Steps to reproduce the issue:

1. Start with an exact clone of lp:compiz-core
2. Merge in lp:~smspillaz/compiz-core/compiz-core.work_923683
3. Build and install it.
4. Run compiz --replace composite opengl move resize decor
5. Run gtk-window-decorator --replace

Now every window will be corrupted. Not just the existing ones, but any new ones you open too. The corruption persists during window resizing, but vanishes as soon as you move a window.

Here is a new screenshot:
https://launchpadlibrarian.net/92390683/shifted2.png

Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

Is the window itself shifted (eg are the input regions correctly lined up) or is it just the image that is shifted ?

Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

The window itself is shifted. The input regions correctly line up with the image still.

However, it looks like the damage events are not shifted. This causes some redraw problems.

Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

Can you post the xwininfo -all of the window, xwininfo -all -id of the parent and xwininfo -all -parent of the parent of that ?

Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Attachments sent via email. This is interesting though;

$ diff correct.xwininfo shifted.xwininfo
11c11
< 0x2c03ca7 (has no name): () 1x1+-1+-1 +45+69
---
> 0x2c03ca7 (has no name): () 1x1+-1+-1 +34+69
13c13
< Absolute upper-left X: 46
---
> Absolute upper-left X: 35
31,32c31,32
< Corners: +46+70 -1232+70 -1232-720 +46-720
< -geometry 80x24+35+41
---
> Corners: +35+70 -1243+70 -1243-720 +35-720
> -geometry 80x24+34+41

It looks like geometry/serverGeometry might be out of sync.

Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

And why do I have so many 1x1 pixel windows?! I swear occasionally I see them on screen too.

Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

On Sun, 12 Feb 2012, Daniel van Vugt wrote:

> And why do I have so many 1x1 pixel windows?!

Applications use them as a means of doing IPC. Gtk+ is a serial offender
here.

> I swear occasionally I see them on screen too.

Under what circumstances?

> --
> https://code.launchpad.net/~smspillaz/compiz-core/compiz-core.work_923683/+merge/91654
> You are the owner of lp:~smspillaz/compiz-core/compiz-core.work_923683.
>

Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

On Sun, 12 Feb 2012, Daniel van Vugt wrote:

The frame window is in the wrong position. This means that serverGeometry
isn't the last thing sent to the server. serverGeometry is still writable
in this branch, so it could be $evilplugin doing the wrong thing here.

I don't want to spend any more time on this until wednesday. So I'll pick
it up then.

(compiz run with --debug will have some logs which can confirm this btw)

Incidentally, you don't see any of those "unmatched ConfigureNotify"
warnings do you? They're all gone here but they indicate the first sign of
trouble.

> Attachments sent via email. This is interesting though;
>
> $ diff correct.xwininfo shifted.xwininfo
> 11c11
> < 0x2c03ca7 (has no name): () 1x1+-1+-1 +45+69
> ---
>> 0x2c03ca7 (has no name): () 1x1+-1+-1 +34+69
> 13c13
> < Absolute upper-left X: 46
> ---
>> Absolute upper-left X: 35
> 31,32c31,32
> < Corners: +46+70 -1232+70 -1232-720 +46-720
> < -geometry 80x24+35+41
> ---
>> Corners: +35+70 -1243+70 -1243-720 +35-720
>> -geometry 80x24+34+41
>
> It looks like geometry/serverGeometry might be out of sync.
> --
> https://code.launchpad.net/~smspillaz/compiz-core/compiz-core.work_923683/+merge/91654
> You are the owner of lp:~smspillaz/compiz-core/compiz-core.work_923683.
>

Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

It's random and very rare. But sometimes I see 1-pixel windows (with shadow). Can't ever seem to get xwininfo for them. Sometimes I also get very large white anonymous windows blocking my view. But it's all very hard to reproduce. And off-topic.

Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Correct. I did stop getting "Warn: failed to receive ConfigureNotify event on ..." when using this branch.

Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

Well, you should stop getting "failed to receive" since I've removed the timeout which checks for unmatched events :) (A necessary hack coming up to the oneiric release).

I'm more interested in warnings that say "unmatched ConfigureNotify"

Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

Could you have a look again to see if the issue is still occurring for you ? I've just re-synced with trunk, so it may be fixed.

Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

OK, I found the issue. Its actually a bug that's been in the code for quite some time which would cause the client to not move within the frame when the frame was updated until the client position itself was updated.

Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

There's still one more issue here though to do with override redirect windows not getting their paint regions updated, so that needs to be looked into as well. And tests.

review: Needs Fixing
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

^ Those fix the offset issue confirmed here (was finally able to reproduce it with qtcreator)

Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

1. Confirmed the shifted window regression is now fixed. Seems to work without any obvious bugs now.

2. I'm not entirely sure about replacing geometry with serverGeometry. I thought it would be a good idea to do the opposite. There would be a slight performance penalty, but using just "geometry" would guarantee that compiz always agrees with the actual server geometry, instead of guessing/assuming that serverGeometry is accepted by the server (which does not always seem to be true, hence bug 886192).

3. There are two instances of double semicolons ";;" in this proposal.

4. I suspect this proposal will conflict just slightly with the proposal for bug 940139. But it should be minor.

5. NEW REGRESSION:
375 - XSynchronize (dpy, synchronousX ? True : False);
376 +// priv->connection = XGetXCBConnection (priv->dpy);

6. Why always two spaces before "* 2" ?

review: Needs Fixing
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

> 2. I'm not entirely sure about replacing geometry with serverGeometry. I
> thought it would be a good idea to do the opposite. There would be a slight
> performance penalty, but using just "geometry" would guarantee that compiz
> always agrees with the actual server geometry, instead of guessing/assuming
> that serverGeometry is accepted by the server (which does not always seem to
> be true, hence bug 886192).
>

serverGeometry will always be "accepted" by the server as long as the window is managed and the requested window geometry will not generate a BadValue error (eg, 0 < 1 < MAXINT) (eg, it is not override redirect and it is a child of a window for which we have a SubstructureRedirectMask.

Bug 886192 is not an example of this. In fact, the behaviour exhibited by bug 886192 is primarily /because/ we use the geometry last received from the server rather than geometry last sent, and the latency of which explains the reason why the window movement lags the cursor, because the server is "catching up".

The only case where you can't guaruntee that a similar update for geometry is going to be delivered by the server for serverGeometry as stored on XConfigureWindow is either in the case that A) Another client has SubstructureRedirectMask on the root window or a parent window owned by compiz and in that case compiz shouldn't even touch that window at all or B) override redirect windows, and as you can see in the code, we /always/ use geometry for override redirect windows in placement sensitive operations. Incidentally, override redirect windows are why getting window stacking right is such a nightmare, but thats a topic for another day.

> 3. There are two instances of double semicolons ";;" in this proposal.

Fix
>
> 4. I suspect this proposal will conflict just slightly with the proposal for
> bug 940139. But it should be minor.

Yes, fixable

>
> 5. NEW REGRESSION:
> 375 - XSynchronize (dpy, synchronousX ? True : False);
> 376 +// priv->connection = XGetXCBConnection (priv->dpy);

Please elaborate further on why this is a regression.

>
> 6. Why always two spaces before "* 2" ?

Most likely copy-and-paste errors

Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

#5 is a regression because it will make "--sync" be ignored. Line 375 is important and should not be deleted.

review: Needs Fixing
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

On Mon, 27 Feb 2012, Daniel van Vugt wrote:

> Review: Needs Fixing
>
> #5 is a regression because it will make "--sync" be ignored. Line 375 is important and should not be deleted.

Thank you. Fixing.

> --
> https://code.launchpad.net/~smspillaz/compiz-core/compiz-core.work_923683/+merge/94683
> You are the owner of lp:~smspillaz/compiz-core/compiz-core.work_923683.
>

Mikkel Kamstrup Erlandsen (kamstrup) wrote : Posted in a previous version of this proposal

> > #5 is a regression because it will make "--sync" be ignored. Line 375 is
> important and should not be deleted.
>
> Thank you. Fixing.

Be sure to add a comment there explaining why that call needs to be there - this review demonstrates that it should have been there in the first place :-)

Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Comments are good. Though the string "synchronousX" is unique so its use should be quite clear already without a comment.

Daniel van Vugt (vanvugt) wrote :

Looks like a mistake:

710 - if (x2 > priv->width)
711 - x2 = priv->width;
712 - if (y2 > priv->height)
713 - y2 = priv->height;
714 + if (x2 > priv->serverGeometry.width ())
715 + x2 = priv->serverGeometry.height (); <====== width?
716 + if (y2 > priv->serverGeometry.width ()) <====== height?
717 + y2 = priv->serverGeometry.height ();

review: Needs Fixing
2992. By Sam Spilsbury on 2012-02-28

Fix silly typo

Daniel van Vugt (vanvugt) wrote :

Also, there seems to be a HUGE performance regression when moving windows with this new branch. Try running under callgrind. With lp:compiz-core it's nice and fast. However with this branch it is painfully slow moving windows.

About 75% of the time is spent in:
  775,164,942 /home/dan/bzr/compiz-core/sam/plugins/move/src/move.cpp:moveHandleMotionEvent(CompScreen*, int, int) [/home/dan/sam/lib/compiz/libmove.so]
  772,734,309 /home/dan/bzr/compiz-core/sam/src/window.cpp:CompWindow::configureXWindow(unsigned int, XWindowChanges*) [/home/dan/sam/lib/libcompiz_core.so.0.9.7.0]
  771,062,144 /home/dan/bzr/compiz-core/sam/src/window.cpp:CompWindow::move(int, int, bool) [/home/dan/sam/lib/libcompiz_core.so.0.9.7.0]
  636,443,803 /home/dan/bzr/compiz-core/sam/src/window.cpp:CompWindow::moveNotify(int, int, bool) [/home/dan/sam/lib/libcompiz_core.so.0.9.7.0]
  636,266,731 /home/dan/bzr/compiz-core/sam/plugins/decor/src/decor.cpp:DecorWindow::moveNotify(int, int, bool) [/home/dan/sam/lib/compiz/libdecor.so]

review: Needs Fixing
Daniel van Vugt (vanvugt) wrote :

The main paths causing this massive performance regression are:

70% of the time:
CompWindow::move
DecorWindow::moveNotify
DecorWindow::computeShadowRegion

18% of the time:
CompWindow::move
CompWindow::configureXWindow
PrivateWindow::reconfigureXWindow

Daniel van Vugt (vanvugt) wrote :

I also recommend "kcachegrind" to display callgrind output in a pretty graphical way.

Daniel van Vugt (vanvugt) wrote :

Try using valgrind/callgrind to simulate a slow machine. You will see a monumental difference in performance when dragging windows. Even my i7 (running callgrind) can't keep up with dragging windows using this branch. But it is almost perfectly fluid without this branch.

Maybe it is the fact that all motion events are getting though now. But regardless, people with slow-to-regular machines will be noticeably impacted. We need a fix before accepting this.

Daniel van Vugt (vanvugt) wrote :

From what I can tell, the problem is that moveNotify is called much more often with this branch. However moveNotify is far too expensive to call so often, mostly due to DecorWindow::moveNotify.

Does DecorWindow::moveNotify really need to computeShadowRegion on EVERY window whenever a single window moves?

2993. By Sam Spilsbury on 2012-02-28

Merge lp:compiz-core

2994. By Sam Spilsbury on 2012-02-29

Use reference

2995. By Sam Spilsbury on 2012-04-03

Merge trunk

2996. By Sam Spilsbury on 2012-04-04

Removed a lot of width () / height () + border () * 2 sillyness, replace with
more sturdy abstraction

2997. By Sam Spilsbury on 2012-04-05

Fix LP #932520 - Update regions correctly when sending geometry updates

Use information last sent to server to determine window regions and shape
regions, update regions for resizing when we send the information to the server
as the shape rectangles will be correct anyways (even though it costs us a
round trip).

2998. By Sam Spilsbury on 2012-04-05

Replace instances of geometry with serverGeoemtry where appropriate

2999. By Sam Spilsbury on 2012-04-05

Merge lp:compiz-core

3000. By Sam Spilsbury on 2012-04-07

Fix typoo

3001. By Sam Spilsbury on 2012-04-11

Merge trunk

3002. By Sam Spilsbury on 2012-04-11

Remove abi breaks

3003. By Sam Spilsbury on 2012-04-11

Don't break abi

3004. By Sam Spilsbury on 2012-04-11

Use geometry last sent to server to calculate damage rects

3005. By Sam Spilsbury on 2012-04-11

Use server side rects for calculating clip regions

3006. By Sam Spilsbury on 2012-04-12

Use serverGeometry

3007. By Sam Spilsbury on 2012-04-12

Damage the screen when windows are resized

3008. By Sam Spilsbury on 2012-04-12

Style issue

3009. By Sam Spilsbury on 2012-04-14

Merged trunk and fixed a number of problems with resize synchronization

3010. By Sam Spilsbury on 2012-04-14

Send resize notification immediately for windows that aren't override redirect

3011. By Sam Spilsbury on 2012-04-14

Fix jumping around on resize because we were rebinding way too much at the wrong time.

Only rebind on paints.

3012. By Sam Spilsbury on 2012-04-14

Don't not update decorations when we're grabbed for resizing

3013. By Sam Spilsbury on 2012-04-14

Null check

3014. By Sam Spilsbury on 2012-04-15

resize: unconditionally finish the resize operation when releasing the button

3015. By Sam Spilsbury on 2012-04-16

Merge trunk

3016. By Sam Spilsbury on 2012-04-16

Don't send a moveNotify and resizeNotify if the window was moved and resized

3017. By Sam Spilsbury on 2012-04-16

Cleanup wobbly model update code

3018. By Sam Spilsbury on 2012-04-17

Ensure that override redirect windows get their regions set correctly.
Also they can't have input extents.

3019. By Sam Spilsbury on 2012-04-18

Force all override redirect windows to use geometry last received from
server. Force all managed windows to use geometry last sent.

The difference between geometry and server* is now moot and can be
removed in a future release

3020. By Sam Spilsbury on 2012-04-18

Clean some cruft

3021. By Sam Spilsbury on 2012-04-18

Update decoration matrix of shaded windows

3022. By Sam Spilsbury on 2012-04-18

Send a resizeNotify to indicate to plugins when map operations have completed

3023. By Sam Spilsbury on 2012-04-18

Merge lp:compiz-core

3024. By Sam Spilsbury on 2012-04-18

Don't notify plugins of unreparent in the right place

3025. By Sam Spilsbury on 2012-04-18

Merged lp:~vanvugt/compiz-core/compiz-core/fix-981703-properly

3026. By Sam Spilsbury on 2012-04-18

updateState is bitwise, so never clobber it

3027. By Sam Spilsbury on 2012-04-18

Base decision to send notifications to plugins on absolute position
changes

3028. By Sam Spilsbury on 2012-04-19

Don't set height = 0 if the window still has a pixmap

3029. By Sam Spilsbury on 2012-04-19

Remove some unnecessary cahgnes in the wobbly plugin

3030. By Sam Spilsbury on 2012-04-19

Merge lp:compiz-core

3031. By Sam Spilsbury on 2012-04-19

Now that geometry and serverGeometry both return the same thing, the changes
in client code don't make any sense to keep

3032. By Sam Spilsbury on 2012-04-20

Fix logic errors

3033. By Sam Spilsbury on 2012-04-20

!= 0 not necessary

3034. By Sam Spilsbury on 2012-04-23

Merge lp:compiz-core

Unmerged revisions

3034. By Sam Spilsbury on 2012-04-23

Merge lp:compiz-core

3033. By Sam Spilsbury on 2012-04-20

!= 0 not necessary

3032. By Sam Spilsbury on 2012-04-20

Fix logic errors

3031. By Sam Spilsbury on 2012-04-19

Now that geometry and serverGeometry both return the same thing, the changes
in client code don't make any sense to keep

3030. By Sam Spilsbury on 2012-04-19

Merge lp:compiz-core

3029. By Sam Spilsbury on 2012-04-19

Remove some unnecessary cahgnes in the wobbly plugin

3028. By Sam Spilsbury on 2012-04-19

Don't set height = 0 if the window still has a pixmap

3027. By Sam Spilsbury on 2012-04-18

Base decision to send notifications to plugins on absolute position
changes

3026. By Sam Spilsbury on 2012-04-18

updateState is bitwise, so never clobber it

3025. By Sam Spilsbury on 2012-04-18

Merged lp:~vanvugt/compiz-core/compiz-core/fix-981703-properly

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'include/core/window.h'
2--- include/core/window.h 2012-02-16 09:55:06 +0000
3+++ include/core/window.h 2012-02-28 07:58:17 +0000
4@@ -406,9 +406,9 @@
5
6 bool hasUnmapReference ();
7
8- bool resize (XWindowAttributes);
9+ bool resize (const XWindowAttributes &);
10
11- bool resize (Geometry);
12+ bool resize (const Geometry &);
13
14 bool resize (int x, int y, int width, int height,
15 int border = 0);
16
17=== modified file 'plugins/composite/src/window.cpp'
18--- plugins/composite/src/window.cpp 2012-02-01 17:49:07 +0000
19+++ plugins/composite/src/window.cpp 2012-02-28 07:58:17 +0000
20@@ -250,7 +250,7 @@
21
22 if (x2 > x1 && y2 > y1)
23 {
24- CompWindow::Geometry geom = priv->window->geometry ();
25+ CompWindow::Geometry geom = priv->window->serverGeometry ();
26
27 x1 += geom.x () + geom.border ();
28 y1 += geom.y () + geom.border ();
29@@ -272,20 +272,20 @@
30 {
31 int x1, x2, y1, y2;
32
33- CompWindow::Geometry geom = priv->window->geometry ();
34- CompWindowExtents output = priv->window->output ();
35+ const CompWindow::Geometry &geom = priv->window->serverGeometry ();
36+ const CompWindowExtents &output = priv->window->output ();
37
38 /* top */
39 x1 = -output.left - geom.border ();
40 y1 = -output.top - geom.border ();
41- x2 = priv->window->size ().width () + output.right - geom.border ();
42+ x2 = priv->window->serverGeometry ().width () + geom.border () + output.right;
43 y2 = -geom.border ();
44
45 if (x1 < x2 && y1 < y2)
46 addDamageRect (CompRect (x1, y1, x2 - x1, y2 - y1));
47
48 /* bottom */
49- y1 = priv->window->size ().height () - geom.border ();
50+ y1 = priv->window->serverGeometry ().height () + geom.border ();
51 y2 = y1 + output.bottom - geom.border ();
52
53 if (x1 < x2 && y1 < y2)
54@@ -295,13 +295,13 @@
55 x1 = -output.left - geom.border ();
56 y1 = -geom.border ();
57 x2 = -geom.border ();
58- y2 = priv->window->size ().height () - geom.border ();
59+ y2 = priv->window->serverGeometry ().height () - geom.border ();
60
61 if (x1 < x2 && y1 < y2)
62 addDamageRect (CompRect (x1, y1, x2 - x1, y2 - y1));
63
64 /* right */
65- x1 = priv->window->size ().width () - geom.border ();
66+ x1 = priv->window->serverGeometry ().width () - geom.border ();
67 x2 = x1 + output.right - geom.border ();
68
69 if (x1 < x2 && y1 < y2)
70@@ -322,7 +322,7 @@
71 x = rect.x ();
72 y = rect.y ();
73
74- CompWindow::Geometry geom = priv->window->geometry ();
75+ const CompWindow::Geometry &geom = priv->window->serverGeometry ();
76 x += geom.x () + geom.border ();
77 y += geom.y () + geom.border ();
78
79@@ -341,16 +341,16 @@
80 if (priv->window->shaded () || force ||
81 (priv->window->isViewable ()))
82 {
83- int border = priv->window->geometry ().border ();
84+ int border = priv->window->serverGeometry ().border ();
85
86 int x1 = -MAX (priv->window->output ().left,
87 priv->window->input ().left) - border;
88 int y1 = -MAX (priv->window->output ().top,
89 priv->window->input ().top) - border;
90- int x2 = priv->window->size ().width () +
91+ int x2 = priv->window->serverGeometry ().width () +
92 MAX (priv->window->output ().right,
93 priv->window->input ().right) ;
94- int y2 = priv->window->size ().height () +
95+ int y2 = priv->window->serverGeometry ().height () +
96 MAX (priv->window->output ().bottom,
97 priv->window->input ().bottom) ;
98 CompRect r (x1, y1, x2 - x1, y2 - y1);
99@@ -410,7 +410,7 @@
100
101 if (!w->damageRect (initial, CompRect (x, y, width, height)))
102 {
103- CompWindow::Geometry geom = w->priv->window->geometry ();
104+ CompWindow::Geometry geom = w->priv->window->serverGeometry ();
105
106 x += geom.x () + geom.border ();
107 y += geom.y () + geom.border ();
108@@ -622,14 +622,14 @@
109 {
110 int x, y, x1, x2, y1, y2;
111
112- x = window->geometry ().x ();
113- y = window->geometry ().y ();
114+ x = window->serverGeometry ().x ();
115+ y = window->serverGeometry ().y ();
116
117 x1 = x - window->output ().left - dx;
118 y1 = y - window->output ().top - dy;
119- x2 = x + window->size ().width () +
120+ x2 = x + window->serverGeometry ().width () +
121 window->output ().right - dx;
122- y2 = y + window->size ().height () +
123+ y2 = y + window->serverGeometry ().height () +
124 window->output ().bottom - dy;
125
126 cScreen->damageRegion (CompRegion (CompRect (x1, y1, x2 - x1, y2 - y1)));
127
128=== modified file 'plugins/decor/src/decor.cpp'
129--- plugins/decor/src/decor.cpp 2012-02-27 09:58:19 +0000
130+++ plugins/decor/src/decor.cpp 2012-02-28 07:58:17 +0000
131@@ -91,7 +91,7 @@
132 void
133 DecorWindow::computeShadowRegion ()
134 {
135- shadowRegion = CompRegion (window->outputRect ());
136+ shadowRegion = CompRegion (window->serverOutputRect ());
137
138 if (window->type () == CompWindowTypeDropdownMenuMask ||
139 window->type () == CompWindowTypePopupMenuMask)
140@@ -141,11 +141,11 @@
141 if (window->type () == CompWindowTypeDropdownMenuMask &&
142 shadowRegion == CompRegionRef (window->outputRect ().region ()))
143 {
144- CompRect area (window->outputRect ().x1 (),
145- window->outputRect ().y1 (),
146- window->outputRect ().width (),
147- window->inputRect ().y1 () -
148- window->outputRect ().y1 ());
149+ CompRect area (window->serverOutputRect ().x1 (),
150+ window->serverOutputRect ().y1 (),
151+ window->serverOutputRect ().width (),
152+ window->serverInputRect ().y1 () -
153+ window->serverOutputRect ().y1 ());
154
155 shadowRegion -= area;
156 }
157@@ -1072,8 +1072,8 @@
158 for (i = 0; i < wd->nQuad; i++)
159 {
160 int x, y;
161- unsigned int width = window->size ().width ();
162- unsigned int height = window->size ().height ();
163+ unsigned int width = window->geometry ().width ();
164+ unsigned int height = window->geometry ().height ();
165
166 if (window->shaded ())
167 height = 0;
168@@ -1082,8 +1082,8 @@
169 &x1, &y1, &x2, &y2, &sx, &sy);
170
171 /* Translate by x and y points of this window */
172- x = window->geometry ().x ();
173- y = window->geometry ().y ();
174+ x = window->serverGeometry ().x ();
175+ y = window->serverGeometry ().y ();
176
177 wd->quad[i].box.x1 = x1 + x;
178 wd->quad[i].box.y1 = y1 + y;
179@@ -1111,8 +1111,8 @@
180 bool
181 DecorWindow::checkSize (const Decoration::Ptr &decoration)
182 {
183- return (decoration->minWidth <= (int) window->size ().width () &&
184- decoration->minHeight <= (int) window->size ().height ());
185+ return (decoration->minWidth <= (int) window->geometry ().width () &&
186+ decoration->minHeight <= (int) window->geometry ().height ());
187 }
188
189 /*
190@@ -2124,8 +2124,8 @@
191 {
192 int x, y;
193
194- x = window->geometry (). x ();
195- y = window->geometry (). y ();
196+ x = window->serverGeometry (). x ();
197+ y = window->serverGeometry (). y ();
198
199 region += frameRegion.translated (x - wd->decor->input.left,
200 y - wd->decor->input.top);
201@@ -2146,7 +2146,7 @@
202 void
203 DecorWindow::updateWindowRegions ()
204 {
205- const CompRect &input (window->inputRect ());
206+ const CompRect &input (window->serverInputRect ());
207
208 if (regions.size () != gWindow->textures ().size ())
209 regions.resize (gWindow->textures ().size ());
210
211=== modified file 'plugins/move/src/move.cpp'
212--- plugins/move/src/move.cpp 2012-02-16 05:31:28 +0000
213+++ plugins/move/src/move.cpp 2012-02-28 07:58:17 +0000
214@@ -138,8 +138,8 @@
215 {
216 int xRoot, yRoot;
217
218- xRoot = w->geometry ().x () + (w->size ().width () / 2);
219- yRoot = w->geometry ().y () + (w->size ().height () / 2);
220+ xRoot = w->serverGeometry ().x () + (w->size ().width () / 2);
221+ yRoot = w->serverGeometry ().y () + (w->size ().height () / 2);
222
223 s->warpPointer (xRoot - pointerX, yRoot - pointerY);
224 }
225@@ -169,8 +169,8 @@
226 if (ms->w)
227 {
228 if (state & CompAction::StateCancel)
229- ms->w->move (ms->savedX - ms->w->geometry ().x (),
230- ms->savedY - ms->w->geometry ().y (), false);
231+ ms->w->move (ms->savedX - ms->w->serverGeometry ().x (),
232+ ms->savedY - ms->w->serverGeometry ().y (), false);
233
234 ms->w->syncPosition ();
235
236@@ -314,12 +314,12 @@
237
238 w = ms->w;
239
240- wX = w->geometry ().x ();
241- wY = w->geometry ().y ();
242- wWidth = w->geometry ().width () +
243- w->geometry ().border () * 2;
244- wHeight = w->geometry ().height () +
245- w->geometry ().border () * 2;
246+ wX = w->serverGeometry ().x ();
247+ wY = w->serverGeometry ().y ();
248+ wWidth = w->serverGeometry ().width () +
249+ w->serverGeometry ().border () * 2;
250+ wHeight = w->serverGeometry ().height () +
251+ w->serverGeometry ().border () * 2;
252
253 ms->x += xRoot - lastPointerX;
254 ms->y += yRoot - lastPointerY;
255@@ -484,8 +484,8 @@
256
257 if (dx || dy)
258 {
259- w->move (wX + dx - w->geometry ().x (),
260- wY + dy - w->geometry ().y (), false);
261+ w->move (wX + dx - w->serverGeometry ().x (),
262+ wY + dy - w->serverGeometry ().y (), false);
263
264 if (!ms->optionGetLazyPositioning ())
265 w->syncPosition ();
266
267=== modified file 'plugins/opengl/src/window.cpp'
268--- plugins/opengl/src/window.cpp 2011-03-11 12:15:30 +0000
269+++ plugins/opengl/src/window.cpp 2012-02-28 07:58:17 +0000
270@@ -76,7 +76,7 @@
271 void
272 PrivateGLWindow::setWindowMatrix ()
273 {
274- CompRect input (window->inputRect ());
275+ CompRect input (window->serverInputRect ());
276
277 if (textures.size () != matrices.size ())
278 matrices.resize (textures.size ());
279@@ -344,7 +344,7 @@
280 void
281 PrivateGLWindow::updateWindowRegions ()
282 {
283- CompRect input (window->inputRect ());
284+ CompRect input (window->serverInputRect ());
285
286 if (regions.size () != textures.size ())
287 regions.resize (textures.size ());
288
289=== modified file 'src/event.cpp'
290--- src/event.cpp 2012-02-22 05:13:00 +0000
291+++ src/event.cpp 2012-02-28 07:58:17 +0000
292@@ -1249,7 +1249,7 @@
293 }
294
295 /* been shaded */
296- if (w->priv->height == 0)
297+ if (w->shaded ())
298 {
299 if (w->id () == priv->activeWindow)
300 w->moveInputFocusTo ();
301
302=== modified file 'src/privatewindow.h'
303--- src/privatewindow.h 2012-02-14 14:37:04 +0000
304+++ src/privatewindow.h 2012-02-28 07:58:17 +0000
305@@ -34,7 +34,6 @@
306 #include <core/timer.h>
307 #include "privatescreen.h"
308
309-
310 typedef CompWindowExtents CompFullscreenMonitorSet;
311
312 class PrivateWindow {
313@@ -167,6 +166,11 @@
314
315 bool handleSyncAlarm ();
316
317+ void move (int dx, int dy, bool sync);
318+ bool resize (int dx, int dy, int dwidth, int dheight, int dborder);
319+ bool resize (const CompWindow::Geometry &g);
320+ bool resize (const XWindowAttributes &attrib);
321+
322 void configure (XConfigureEvent *ce);
323
324 void configureFrame (XConfigureEvent *ce);
325@@ -207,8 +211,6 @@
326
327 void readIconHint ();
328
329- bool checkClear ();
330-
331 public:
332
333 PrivateWindow *priv;
334@@ -240,13 +242,8 @@
335 XSizeHints sizeHints;
336 XWMHints *hints;
337
338- struct timeval lastGeometryUpdate;
339- struct timeval lastConfigureRequest;
340-
341 bool inputHint;
342 bool alpha;
343- int width;
344- int height;
345 CompRegion region;
346 CompRegion inputRegion;
347 CompRegion frameRegion;
348@@ -289,8 +286,6 @@
349 typedef std::pair <XWindowChanges, unsigned int> XWCValueMask;
350
351 compiz::X11::PendingEventQueue pendingConfigures;
352- CompTimer mClearCheckTimeout;
353- bool pendingPositionUpdates;
354
355 char *startupId;
356 char *resName;
357@@ -326,6 +321,8 @@
358
359 bool closeRequests;
360 Time lastCloseRequestTime;
361+
362+ bool nextMoveImmediate;
363 };
364
365 class CoreWindow
366
367=== modified file 'src/screen.cpp'
368--- src/screen.cpp 2012-02-24 12:18:12 +0000
369+++ src/screen.cpp 2012-02-28 07:58:17 +0000
370@@ -4536,6 +4536,8 @@
371 return false;
372 }
373
374+ /* Use synchronous behaviour when running with --sync, useful
375+ * for getting stacktraces when X Errors occurr */
376 XSynchronize (dpy, synchronousX ? True : False);
377
378 snprintf (displayString, 255, "DISPLAY=%s",
379
380=== modified file 'src/window.cpp'
381--- src/window.cpp 2012-02-20 02:30:34 +0000
382+++ src/window.cpp 2012-02-28 07:58:17 +0000
383@@ -75,8 +75,8 @@
384 PrivateWindow::isInvisible() const
385 {
386 return attrib.map_state != IsViewable ||
387- attrib.x + width + output.right <= 0 ||
388- attrib.y + height + output.bottom <= 0 ||
389+ attrib.x + geometry.width () + output.right <= 0 ||
390+ attrib.y + geometry.height () + output.bottom <= 0 ||
391 attrib.x - output.left >= (int) screen->width () ||
392 attrib.y - output.top >= (int) screen->height ();
393 }
394@@ -808,292 +808,14 @@
395 if (!serverFrame)
396 return;
397
398-
399- gettimeofday (&lastConfigureRequest, NULL);
400- /* Flush any changes made to serverFrameGeometry or serverGeometry to the server
401- * since there is a race condition where geometries will go out-of-sync with
402- * window movement */
403-
404- window->syncPosition ();
405-
406- if (serverInput.left || serverInput.right || serverInput.top || serverInput.bottom)
407- {
408- int bw = serverGeometry.border () * 2;
409-
410- xwc.x = serverGeometry.x () - serverInput.left;
411- xwc.y = serverGeometry.y () - serverInput.top;
412- xwc.width = serverGeometry.width () + serverInput.left + serverInput.right + bw;
413- if (shaded)
414- xwc.height = serverInput.top + serverInput.bottom + bw;
415- else
416- xwc.height = serverGeometry.height () + serverInput.top + serverInput.bottom + bw;
417-
418- if (shaded)
419- height = serverInput.top + serverInput.bottom;
420-
421- if (serverFrameGeometry.x () == xwc.x)
422- valueMask &= ~(CWX);
423- else
424- serverFrameGeometry.setX (xwc.x);
425-
426- if (serverFrameGeometry.y () == xwc.y)
427- valueMask &= ~(CWY);
428- else
429- serverFrameGeometry.setY (xwc.y);
430-
431- if (serverFrameGeometry.width () == xwc.width)
432- valueMask &= ~(CWWidth);
433- else
434- serverFrameGeometry.setWidth (xwc.width);
435-
436- if (serverFrameGeometry.height () == xwc.height)
437- valueMask &= ~(CWHeight);
438- else
439- serverFrameGeometry.setHeight (xwc.height);
440-
441- /* Geometry is the same, so we're not going to get a ConfigureNotify
442- * event when the window is configured, which means that other plugins
443- * won't know that the client, frame and wrapper windows got shifted
444- * around (and might result in display corruption, eg in OpenGL */
445- if (valueMask == 0)
446- {
447- XConfigureEvent xev;
448- XWindowAttributes attrib;
449- unsigned int nchildren = 0;
450- Window rootRet = 0, parentRet = 0;
451- Window *children = NULL;
452-
453- xev.type = ConfigureNotify;
454- xev.event = screen->root ();
455- xev.window = priv->serverFrame;
456-
457- XGrabServer (screen->dpy ());
458-
459- if (XGetWindowAttributes (screen->dpy (), priv->serverFrame, &attrib))
460- {
461- xev.x = attrib.x;
462- xev.y = attrib.y;
463- xev.width = attrib.width;
464- xev.height = attrib.height;
465- xev.border_width = attrib.border_width;
466- xev.above = None;
467-
468- /* We need to ensure that the stacking order is
469- * based on the current server stacking order so
470- * find the sibling to this window's frame in the
471- * server side stack and stack above that */
472- XQueryTree (screen->dpy (), screen->root (), &rootRet, &parentRet, &children, &nchildren);
473-
474- if (nchildren)
475- {
476- for (unsigned int i = 0; i < nchildren; i++)
477- {
478- if (i + 1 == nchildren ||
479- children[i + 1] == ROOTPARENT (window))
480- {
481- xev.above = children[i];
482- break;
483- }
484- }
485- }
486-
487- if (children)
488- XFree (children);
489-
490- if (!xev.above)
491- xev.above = (window->serverPrev) ? ROOTPARENT (window->serverPrev) : None;
492-
493- xev.override_redirect = priv->attrib.override_redirect;
494-
495- }
496-
497- compiz::X11::PendingEvent::Ptr pc =
498- boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
499- new compiz::X11::PendingConfigureEvent (
500- screen->dpy (), serverFrame, valueMask, &xwc)));
501-
502- pendingConfigures.add (pc);
503- if (priv->mClearCheckTimeout.active ())
504- priv->mClearCheckTimeout.stop ();
505- priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
506- 2000, 2500);
507-
508- XSendEvent (screen->dpy (), screen->root (), false,
509- SubstructureNotifyMask, (XEvent *) &xev);
510-
511- XUngrabServer (screen->dpy ());
512- XSync (screen->dpy (), false);
513- }
514- else
515- {
516- compiz::X11::PendingEvent::Ptr pc =
517- boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
518- new compiz::X11::PendingConfigureEvent (
519- screen->dpy (), serverFrame, valueMask, &xwc)));
520-
521- pendingConfigures.add (pc);
522- if (priv->mClearCheckTimeout.active ())
523- priv->mClearCheckTimeout.stop ();
524- priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
525- 2000, 2500);
526- XConfigureWindow (screen->dpy (), serverFrame, valueMask, &xwc);
527- }
528-
529- if (shaded)
530- {
531- XUnmapWindow (screen->dpy (), wrapper);
532- }
533- else
534- {
535- XMapWindow (screen->dpy (), wrapper);
536- XMoveResizeWindow (screen->dpy (), wrapper, serverInput.left, serverInput.top,
537- serverGeometry.width (), serverGeometry.height ());
538- }
539- XMoveResizeWindow (screen->dpy (), id, 0, 0,
540- serverGeometry.width (), serverGeometry.height ());
541- window->sendConfigureNotify ();
542- window->windowNotify (CompWindowNotifyFrameUpdate);
543- }
544- else
545- {
546- int bw = serverGeometry.border () * 2;
547-
548- xwc.x = serverGeometry.x ();
549- xwc.y = serverGeometry.y ();
550- xwc.width = serverGeometry.width () + bw;
551-
552- /* FIXME: It doesn't make much sense to allow undecorated windows to be
553- * shaded */
554- if (shaded)
555- xwc.height = bw;
556- else
557- xwc.height = serverGeometry.height () + bw;
558-
559- if (serverFrameGeometry.x () == xwc.x)
560- valueMask &= ~(CWX);
561- else
562- serverFrameGeometry.setX (xwc.x);
563-
564- if (serverFrameGeometry.y () == xwc.y)
565- valueMask &= ~(CWY);
566- else
567- serverFrameGeometry.setY (xwc.y);
568-
569- if (serverFrameGeometry.width () == xwc.width)
570- valueMask &= ~(CWWidth);
571- else
572- serverFrameGeometry.setWidth (xwc.width);
573-
574- if (serverFrameGeometry.height () == xwc.height)
575- valueMask &= ~(CWHeight);
576- else
577- serverFrameGeometry.setHeight (xwc.height);
578-
579- /* Geometry is the same, so we're not going to get a ConfigureNotify
580- * event when the window is configured, which means that other plugins
581- * won't know that the client, frame and wrapper windows got shifted
582- * around (and might result in display corruption, eg in OpenGL */
583- if (valueMask == 0)
584- {
585- XConfigureEvent xev;
586- XWindowAttributes attrib;
587- unsigned int nchildren = 0;
588- Window rootRet = 0, parentRet = 0;
589- Window *children = NULL;
590-
591- xev.type = ConfigureNotify;
592- xev.event = screen->root ();
593- xev.window = priv->serverFrame;
594-
595- XGrabServer (screen->dpy ());
596-
597- if (XGetWindowAttributes (screen->dpy (), priv->serverFrame, &attrib))
598- {
599- xev.x = attrib.x;
600- xev.y = attrib.y;
601- xev.width = attrib.width;
602- xev.height = attrib.height;
603- xev.border_width = attrib.border_width;
604- xev.above = None;
605-
606- /* We need to ensure that the stacking order is
607- * based on the current server stacking order so
608- * find the sibling to this window's frame in the
609- * server side stack and stack above that */
610- XQueryTree (screen->dpy (), screen->root (), &rootRet, &parentRet, &children, &nchildren);
611-
612- if (nchildren)
613- {
614- for (unsigned int i = 0; i < nchildren; i++)
615- {
616- if (i + 1 == nchildren ||
617- children[i + 1] == ROOTPARENT (window))
618- {
619- xev.above = children[i];
620- break;
621- }
622- }
623- }
624-
625- if (children)
626- XFree (children);
627-
628- if (!xev.above)
629- xev.above = (window->serverPrev) ? ROOTPARENT (window->serverPrev) : None;
630-
631- xev.override_redirect = priv->attrib.override_redirect;
632-
633- }
634-
635- compiz::X11::PendingEvent::Ptr pc =
636- boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
637- new compiz::X11::PendingConfigureEvent (
638- screen->dpy (), serverFrame, valueMask, &xwc)));
639-
640- pendingConfigures.add (pc);
641- if (priv->mClearCheckTimeout.active ())
642- priv->mClearCheckTimeout.stop ();
643- priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
644- 2000, 2500);
645-
646- XSendEvent (screen->dpy (), screen->root (), false,
647- SubstructureNotifyMask, (XEvent *) &xev);
648-
649- XUngrabServer (screen->dpy ());
650- XSync (screen->dpy (), false);
651- }
652- else
653- {
654- compiz::X11::PendingEvent::Ptr pc =
655- boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
656- new compiz::X11::PendingConfigureEvent (
657- screen->dpy (), serverFrame, valueMask, &xwc)));
658-
659- pendingConfigures.add (pc);
660- if (priv->mClearCheckTimeout.active ())
661- priv->mClearCheckTimeout.stop ();
662- priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
663- 2000, 2500);
664-
665- XConfigureWindow (screen->dpy (), serverFrame, valueMask, &xwc);
666- }
667-
668- if (shaded)
669- {
670- XUnmapWindow (screen->dpy (), wrapper);
671- }
672- else
673- {
674- XMapWindow (screen->dpy (), wrapper);
675- XMoveResizeWindow (screen->dpy (), wrapper, 0, 0,
676- serverGeometry.width (), serverGeometry.height ());
677- }
678-
679- XMoveResizeWindow (screen->dpy (), id, 0, 0,
680- serverGeometry.width (), serverGeometry.height ());
681- window->sendConfigureNotify ();
682- window->windowNotify (CompWindowNotifyFrameUpdate);
683- }
684+ xwc.x = serverGeometry.x ();
685+ xwc.y = serverGeometry.y ();
686+ xwc.width = serverGeometry.width ();
687+ xwc.height = serverGeometry.height ();
688+ xwc.border_width = serverGeometry.border ();
689+
690+ window->configureXWindow (valueMask, &xwc);
691+ window->windowNotify (CompWindowNotifyFrameUpdate);
692 window->recalcActions ();
693 }
694
695@@ -1136,8 +858,8 @@
696
697 for (unsigned int i = 0; i < n; i++)
698 {
699- x1 = rects[i].x + priv->geometry.border ();
700- y1 = rects[i].y + priv->geometry.border ();
701+ x1 = rects[i].x + priv->serverGeometry.border ();
702+ y1 = rects[i].y + priv->serverGeometry.border ();
703 x2 = x1 + rects[i].width;
704 y2 = y1 + rects[i].height;
705
706@@ -1145,17 +867,17 @@
707 x1 = 0;
708 if (y1 < 0)
709 y1 = 0;
710- if (x2 > priv->width)
711- x2 = priv->width;
712- if (y2 > priv->height)
713- y2 = priv->height;
714+ if (x2 > priv->serverGeometry.width ())
715+ x2 = priv->serverGeometry.height ();
716+ if (y2 > priv->serverGeometry.width ())
717+ y2 = priv->serverGeometry.height ();
718
719 if (y1 < y2 && x1 < x2)
720 {
721- x1 += priv->geometry.x ();
722- y1 += priv->geometry.y ();
723- x2 += priv->geometry.x ();
724- y2 += priv->geometry.y ();
725+ x1 += priv->serverGeometry.x ();
726+ y1 += priv->serverGeometry.y ();
727+ x2 += priv->serverGeometry.x ();
728+ y2 += priv->serverGeometry.y ();
729
730 ret += CompRect (x1, y1, x2 - x1, y2 - y1);
731 }
732@@ -1183,17 +905,19 @@
733 {
734 int order;
735
736+ /* We should update the server here */
737+ XSync (screen->dpy (), false);
738+
739 boundingShapeRects = XShapeGetRectangles (screen->dpy (), priv->id,
740 ShapeBounding, &nBounding, &order);
741 inputShapeRects = XShapeGetRectangles (screen->dpy (), priv->id,
742 ShapeInput, &nInput, &order);
743-
744 }
745
746- r.x = -priv->geometry.border ();
747- r.y = -priv->geometry.border ();
748- r.width = priv->width + priv->geometry.border ();
749- r.height = priv->height + priv->geometry.border ();
750+ r.x = -priv->serverGeometry.border ();
751+ r.y = -priv->serverGeometry.border ();
752+ r.width = priv->serverGeometry.width () + priv->serverGeometry.border ();
753+ r.height = priv->serverGeometry.height () + priv->serverGeometry.border ();
754
755 if (nBounding < 1)
756 {
757@@ -1726,7 +1450,7 @@
758 priv->attrib.map_state = IsUnmapped;
759 priv->invisible = true;
760
761- if (priv->shaded && priv->height)
762+ if (priv->shaded)
763 {
764 priv->updateFrameWindow ();
765 }
766@@ -1794,7 +1518,7 @@
767 }
768
769 bool
770-CompWindow::resize (XWindowAttributes attr)
771+CompWindow::resize (const XWindowAttributes &attr)
772 {
773 return resize (Geometry (attr.x, attr.y, attr.width, attr.height,
774 attr.border_width));
775@@ -1811,7 +1535,7 @@
776 }
777
778 bool
779-CompWindow::resize (CompWindow::Geometry gm)
780+PrivateWindow::resize (const CompWindow::Geometry &gm)
781 {
782 /* Input extents are now the last thing sent
783 * from the server. This might not work in some
784@@ -1828,12 +1552,8 @@
785 priv->geometry.height () != gm.height () ||
786 priv->geometry.border () != gm.border ())
787 {
788- int pw, ph;
789 int dx, dy, dwidth, dheight;
790
791- pw = gm.width () + gm.border () * 2;
792- ph = gm.height () + gm.border () * 2;
793-
794 dx = gm.x () - priv->geometry.x ();
795 dy = gm.y () - priv->geometry.y ();
796 dwidth = gm.width () - priv->geometry.width ();
797@@ -1843,37 +1563,60 @@
798 gm.width (), gm.height (),
799 gm.border ());
800
801- priv->width = pw;
802- priv->height = ph;
803+ if (priv->attrib.override_redirect)
804+ {
805+ priv->serverGeometry = priv->geometry;
806+ priv->serverFrameGeometry = priv->frameGeometry;
807+ }
808
809 if (priv->mapNum)
810 priv->updateRegion ();
811
812- resizeNotify (dx, dy, dwidth, dheight);
813+ window->resizeNotify (dx, dy, dwidth, dheight);
814
815 priv->invisible = priv->isInvisible ();
816 }
817 else if (priv->geometry.x () != gm.x () || priv->geometry.y () != gm.y ())
818 {
819- int dx, dy;
820-
821- dx = gm.x () - priv->geometry.x ();
822- dy = gm.y () - priv->geometry.y ();
823-
824- priv->geometry.setX (gm.x ());
825- priv->geometry.setY (gm.y ());
826-
827- priv->region.translate (dx, dy);
828- priv->inputRegion.translate (dx, dy);
829- if (!priv->frameRegion.isEmpty ())
830- priv->frameRegion.translate (dx, dy);
831-
832- priv->invisible = priv->isInvisible ();
833-
834- moveNotify (dx, dy, true);
835+ move (gm.x () - priv->geometry.x (),
836+ gm.y () - priv->geometry.y (), true);
837 }
838
839- updateFrameRegion ();
840+ window->updateFrameRegion ();
841+
842+ return true;
843+}
844+
845+bool
846+PrivateWindow::resize (const XWindowAttributes &attr)
847+{
848+ return resize (CompWindow::Geometry (attr.x, attr.y, attr.width, attr.height,
849+ attr.border_width));
850+}
851+
852+bool
853+PrivateWindow::resize (int x,
854+ int y,
855+ int width,
856+ int height,
857+ int border)
858+{
859+ return resize (CompWindow::Geometry (x, y, width, height, border));
860+}
861+
862+bool
863+CompWindow::resize (const CompWindow::Geometry &gm)
864+{
865+ XWindowChanges xwc = XWINDOWCHANGES_INIT;
866+ unsigned int valueMask = CWX | CWY | CWWidth | CWHeight | CWBorderWidth;
867+
868+ xwc.x = gm.x ();
869+ xwc.y = gm.y ();
870+ xwc.width = gm.width ();
871+ xwc.height = gm.height ();
872+ xwc.border_width = gm.border ();
873+
874+ configureXWindow (valueMask, &xwc);
875
876 return true;
877 }
878@@ -2041,13 +1784,7 @@
879 ce->border_width);
880 else
881 {
882- if (ce->override_redirect)
883- {
884- priv->serverGeometry.set (ce->x, ce->y, ce->width, ce->height,
885- ce->border_width);
886- }
887-
888- window->resize (ce->x, ce->y, ce->width, ce->height, ce->border_width);
889+ resize (ce->x, ce->y, ce->width, ce->height, ce->border_width);
890 }
891
892 if (ce->event == screen->root ())
893@@ -2128,7 +1865,7 @@
894 if (priv->syncWait)
895 priv->syncGeometry.set (x, y, width, height, ce->border_width);
896 else
897- window->resize (x, y, width, height, ce->border_width);
898+ resize (x, y, width, height, ce->border_width);
899
900 if (priv->restack (ce->above))
901 priv->updatePassiveButtonGrabs ();
902@@ -2137,27 +1874,6 @@
903
904 if (above)
905 above->priv->updatePassiveButtonGrabs ();
906-
907- if (!pendingConfigures.pending ())
908- {
909- /* Tell plugins its ok to start doing stupid things again but
910- * obviously FIXME */
911- CompOption::Vector options;
912- CompOption::Value v;
913-
914- options.push_back (CompOption ("window", CompOption::TypeInt));
915- v.set ((int) id);
916- options.back ().set (v);
917- options.push_back (CompOption ("active", CompOption::TypeInt));
918- v.set ((int) 0);
919- options.back ().set (v);
920-
921- /* Notify other plugins that it is unsafe to change geometry or serverGeometry
922- * FIXME: That API should not be accessible to plugins, this is a hack to avoid
923- * breaking ABI */
924-
925- screen->handleCompizEvent ("core", "lock_position", options);
926- }
927 }
928
929 void
930@@ -2180,23 +1896,34 @@
931 {
932 if (dx || dy)
933 {
934- gettimeofday (&priv->lastGeometryUpdate, NULL);
935-
936- /* Don't allow window movement to overwrite working geometries
937- * last received from the server if we know there are pending
938- * ConfigureNotify events on this window. That's a clunky workaround
939- * and a FIXME in any case, however, until we can break the API
940- * and remove CompWindow::move, this will need to be the case */
941-
942- if (!priv->pendingConfigures.pending ())
943+ XWindowChanges xwc = XWINDOWCHANGES_INIT;
944+ unsigned int valueMask = CWX | CWY;
945+
946+ xwc.x = priv->serverGeometry.x () + dx;
947+ xwc.y = priv->serverGeometry.y () + dy;
948+
949+ priv->nextMoveImmediate = immediate;
950+
951+ configureXWindow (valueMask, &xwc);
952+ }
953+}
954+
955+void
956+PrivateWindow::move (int dx,
957+ int dy,
958+ bool immediate)
959+{
960+ if (dx || dy)
961+ {
962+ priv->geometry.setX (priv->geometry.x () + dx);
963+ priv->geometry.setY (priv->geometry.y () + dy);
964+ priv->frameGeometry.setX (priv->frameGeometry.x () + dx);
965+ priv->frameGeometry.setY (priv->frameGeometry.y () + dy);
966+
967+ if (priv->attrib.override_redirect)
968 {
969- priv->geometry.setX (priv->geometry.x () + dx);
970- priv->geometry.setY (priv->geometry.y () + dy);
971- priv->frameGeometry.setX (priv->frameGeometry.x () + dx);
972- priv->frameGeometry.setY (priv->frameGeometry.y () + dy);
973-
974- priv->pendingPositionUpdates = true;
975-
976+ priv->serverGeometry = priv->geometry;
977+ priv->serverFrameGeometry = priv->frameGeometry;
978 priv->region.translate (dx, dy);
979 priv->inputRegion.translate (dx, dy);
980 if (!priv->frameRegion.isEmpty ())
981@@ -2204,19 +1931,7 @@
982
983 priv->invisible = priv->isInvisible ();
984
985- moveNotify (dx, dy, immediate);
986- }
987- else
988- {
989- XWindowChanges xwc = XWINDOWCHANGES_INIT;
990- unsigned int valueMask = CWX | CWY;
991- compLogMessage ("core", CompLogLevelDebug, "pending configure notifies on 0x%x, "\
992- "moving window asyncrhonously!", (unsigned int) priv->serverId);
993-
994- xwc.x = priv->serverGeometry.x () + dx;
995- xwc.y = priv->serverGeometry.y () + dy;
996-
997- configureXWindow (valueMask, &xwc);
998+ window->moveNotify (dx, dy, true);
999 }
1000 }
1001 }
1002@@ -2227,22 +1942,6 @@
1003 return !mEvents.empty ();
1004 }
1005
1006-bool
1007-PrivateWindow::checkClear ()
1008-{
1009- if (pendingConfigures.pending ())
1010- {
1011- /* FIXME: This is a hack to avoid performance regressions
1012- * and must be removed in 0.9.6 */
1013- compLogMessage ("core", CompLogLevelWarn, "failed to receive ConfigureNotify event on 0x%x\n",
1014- id);
1015- pendingConfigures.dump ();
1016- pendingConfigures.clear ();
1017- }
1018-
1019- return false;
1020-}
1021-
1022 void
1023 compiz::X11::PendingEventQueue::add (PendingEvent::Ptr p)
1024 {
1025@@ -2464,21 +2163,6 @@
1026 mValueMask (valueMask),
1027 mXwc (*xwc)
1028 {
1029- CompOption::Vector options;
1030- CompOption::Value v;
1031-
1032- options.push_back (CompOption ("window", CompOption::TypeInt));
1033- v.set ((int) w);
1034- options.back ().set (v);
1035- options.push_back (CompOption ("active", CompOption::TypeInt));
1036- v.set ((int) 1);
1037- options.back ().set (v);
1038-
1039- /* Notify other plugins that it is unsafe to change geometry or serverGeometry
1040- * FIXME: That API should not be accessible to plugins, this is a hack to avoid
1041- * breaking ABI */
1042-
1043- screen->handleCompizEvent ("core", "lock_position", options);
1044 }
1045
1046 compiz::X11::PendingConfigureEvent::~PendingConfigureEvent ()
1047@@ -2488,57 +2172,6 @@
1048 void
1049 CompWindow::syncPosition ()
1050 {
1051- gettimeofday (&priv->lastConfigureRequest, NULL);
1052-
1053- unsigned int valueMask = CWX | CWY;
1054- XWindowChanges xwc = XWINDOWCHANGES_INIT;
1055-
1056- if (priv->pendingPositionUpdates && !priv->pendingConfigures.pending ())
1057- {
1058- if (priv->serverFrameGeometry.x () == priv->frameGeometry.x ())
1059- valueMask &= ~(CWX);
1060- if (priv->serverFrameGeometry.y () == priv->frameGeometry.y ())
1061- valueMask &= ~(CWY);
1062-
1063- /* Because CompWindow::move can update the geometry last
1064- * received from the server, we must indicate that no values
1065- * changed, because when the ConfigureNotify comes around
1066- * the values are going to be the same. That's obviously
1067- * broken behaviour and worthy of a FIXME, but requires
1068- * larger changes to the window movement system. */
1069- if (valueMask)
1070- {
1071- priv->serverGeometry.setX (priv->geometry.x ());
1072- priv->serverGeometry.setY (priv->geometry.y ());
1073- priv->serverFrameGeometry.setX (priv->frameGeometry.x ());
1074- priv->serverFrameGeometry.setY (priv->frameGeometry.y ());
1075-
1076- xwc.x = priv->serverFrameGeometry.x ();
1077- xwc.y = priv->serverFrameGeometry.y ();
1078-
1079- compiz::X11::PendingEvent::Ptr pc =
1080- boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
1081- new compiz::X11::PendingConfigureEvent (
1082- screen->dpy (), priv->serverFrame, 0, &xwc)));
1083-
1084- priv->pendingConfigures.add (pc);
1085-
1086- /* Got 3 seconds to get its stuff together */
1087- if (priv->mClearCheckTimeout.active ())
1088- priv->mClearCheckTimeout.stop ();
1089- priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
1090- 2000, 2500);
1091- XConfigureWindow (screen->dpy (), ROOTPARENT (this), valueMask, &xwc);
1092-
1093- if (priv->serverFrame)
1094- {
1095- XMoveWindow (screen->dpy (), priv->wrapper,
1096- priv->serverInput.left, priv->serverInput.top);
1097- sendConfigureNotify ();
1098- }
1099- }
1100- priv->pendingPositionUpdates = false;
1101- }
1102 }
1103
1104 bool
1105@@ -3360,14 +2993,23 @@
1106 {
1107 unsigned int frameValueMask = 0;
1108
1109- /* Immediately sync window position
1110- * if plugins were updating w->geometry () directly
1111- * in order to avoid a race condition */
1112-
1113- window->syncPosition ();
1114+ if (id == screen->root ())
1115+ {
1116+ compLogMessage ("core", CompLogLevelWarn, "attempted to reconfigure root window");
1117+ return;
1118+ }
1119
1120 /* Remove redundant bits */
1121
1122+ xwc->x = valueMask & CWX ? xwc->x : serverGeometry.x ();
1123+ xwc->y = valueMask & CWY ? xwc->y : serverGeometry.y ();
1124+ xwc->width = valueMask & CWWidth ? xwc->width : serverGeometry.width ();
1125+ xwc->height = valueMask & CWHeight ? xwc->height : serverGeometry.height ();
1126+ xwc->border_width = valueMask & CWBorderWidth ? xwc->border_width : serverGeometry.border ();
1127+
1128+ /* FIXME: This is a total fallacy for the reparenting case
1129+ * at least since the client doesn't actually move here, it only
1130+ * moves within the frame */
1131 if (valueMask & CWX && serverGeometry.x () == xwc->x)
1132 valueMask &= ~(CWX);
1133
1134@@ -3434,18 +3076,15 @@
1135 compLogMessage ("core", CompLogLevelWarn, "restack_mode not Above");
1136 }
1137
1138- frameValueMask = valueMask;
1139+ frameValueMask = CWX | CWY | CWWidth | CWHeight | (valueMask & (CWStackMode | CWSibling));
1140
1141- if (frameValueMask & CWX &&
1142- serverFrameGeometry.x () == xwc->x - serverGeometry.border () - serverInput.left)
1143+ if (serverFrameGeometry.x () == xwc->x - serverGeometry.border () - serverInput.left)
1144 frameValueMask &= ~(CWX);
1145
1146- if (frameValueMask & CWY &&
1147- serverFrameGeometry.y () == xwc->y - serverGeometry.border () - serverInput.top)
1148+ if (serverFrameGeometry.y () == xwc->y - serverGeometry.border () - serverInput.top)
1149 frameValueMask &= ~(CWY);
1150
1151- if (frameValueMask & CWWidth &&
1152- serverFrameGeometry.width () == xwc->width + serverGeometry.border () * 2
1153+ if (serverFrameGeometry.width () == xwc->width + serverGeometry.border () * 2
1154 + serverInput.left + serverInput.right)
1155 frameValueMask &= ~(CWWidth);
1156
1157@@ -3455,19 +3094,76 @@
1158
1159 if (shaded)
1160 {
1161- if (frameValueMask & CWHeight &&
1162- serverFrameGeometry.height () == serverGeometry.border () * 2
1163+ if (serverFrameGeometry.height () == serverGeometry.border () * 2
1164 + serverInput.top + serverInput.bottom)
1165 frameValueMask &= ~(CWHeight);
1166 }
1167 else
1168 {
1169- if (frameValueMask & CWHeight &&
1170- serverFrameGeometry.height () == xwc->height + serverGeometry.border () * 2
1171+ if (serverFrameGeometry.height () == xwc->height + serverGeometry.border () * 2
1172 + serverInput.top + serverInput.bottom)
1173 frameValueMask &= ~(CWHeight);
1174 }
1175
1176+ /* Don't allow anything that might generate a BadValue */
1177+ if (valueMask & CWWidth && !xwc->width)
1178+ {
1179+ compLogMessage ("core", CompLogLevelWarn, "Attempted to set < 1 width on a window");
1180+ xwc->width = 1;
1181+ }
1182+
1183+ if (valueMask & CWHeight && !xwc->height)
1184+ {
1185+ compLogMessage ("core", CompLogLevelWarn, "Attempted to set < 1 height on a window");
1186+ xwc->height = 1;
1187+ }
1188+
1189+ if (valueMask & CWStackMode &&
1190+ ((xwc->stack_mode != TopIf) && (xwc->stack_mode != BottomIf) && (xwc->stack_mode != Opposite) &&
1191+ (xwc->stack_mode != Above) && (xwc->stack_mode != Below)))
1192+ {
1193+ compLogMessage ("core", CompLogLevelWarn, "Invalid stack mode %i", xwc->stack_mode);
1194+ valueMask &= ~(CWStackMode | CWSibling);
1195+ }
1196+
1197+ /* Don't allow anything that might cause a BadMatch error */
1198+
1199+ if (valueMask & CWSibling && !(valueMask & CWStackMode))
1200+ {
1201+ compLogMessage ("core", CompLogLevelWarn, "Didn't specify a CWStackMode for CWSibling");
1202+ valueMask &= ~CWSibling;
1203+ }
1204+
1205+ if (valueMask & CWSibling && xwc->sibling == (serverFrame ? serverFrame : id))
1206+ {
1207+ compLogMessage ("core", CompLogLevelWarn, "Can't restack a window relative to itself");
1208+ valueMask &= ~CWSibling;
1209+ }
1210+
1211+ if (valueMask & CWBorderWidth && attrib.c_class == InputOnly)
1212+ {
1213+ compLogMessage ("core", CompLogLevelWarn, "Cannot set border_width of an input_only window");
1214+ valueMask &= ~CWBorderWidth;
1215+ }
1216+
1217+ if (valueMask & CWSibling)
1218+ {
1219+ CompWindow *sibling = screen->findTopLevelWindow (xwc->sibling);
1220+
1221+ if (!sibling)
1222+ {
1223+ compLogMessage ("core", CompLogLevelWarn, "Attempted to restack relative to 0x%x which is "\
1224+ "not a child of the root window or a window compiz owns", static_cast <unsigned int> (xwc->sibling));
1225+ valueMask &= ~(CWSibling | CWStackMode);
1226+ }
1227+ else if (sibling->frame () && xwc->sibling != sibling->frame ())
1228+ {
1229+ compLogMessage ("core", CompLogLevelWarn, "Attempted to restack relative to 0x%x which is "\
1230+ "not a child of the root window", static_cast <unsigned int> (xwc->sibling));
1231+ valueMask &= ~(CWSibling | CWStackMode);
1232+ }
1233+ }
1234+
1235 /* Can't set the border width of frame windows */
1236 frameValueMask &= ~(CWBorderWidth);
1237
1238@@ -3494,11 +3190,8 @@
1239 + serverInput.top + serverInput.bottom);
1240 }
1241
1242-
1243 if (serverFrame)
1244 {
1245- gettimeofday (&lastConfigureRequest, NULL);
1246-
1247 if (frameValueMask)
1248 {
1249 XWindowChanges wc = *xwc;
1250@@ -3514,15 +3207,20 @@
1251 screen->dpy (), priv->serverFrame, frameValueMask, &wc)));
1252
1253 pendingConfigures.add (pc);
1254- if (priv->mClearCheckTimeout.active ())
1255- priv->mClearCheckTimeout.stop ();
1256- priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
1257- 2000, 2500);
1258
1259 XConfigureWindow (screen->dpy (), serverFrame, frameValueMask, &wc);
1260 }
1261+
1262 valueMask &= ~(CWSibling | CWStackMode);
1263
1264+ /* If the frame has changed position (eg, serverInput.top
1265+ * or serverInput.left have changed) then we also need to
1266+ * update the client and wrapper position */
1267+ if (!(valueMask & CWX))
1268+ valueMask |= frameValueMask & CWX;
1269+ if (!(valueMask & CWY))
1270+ valueMask |= frameValueMask & CWY;
1271+
1272 if (valueMask)
1273 {
1274 xwc->x = serverInput.left;
1275@@ -3710,6 +3408,9 @@
1276 CompWindow::configureXWindow (unsigned int valueMask,
1277 XWindowChanges *xwc)
1278 {
1279+ int dx = valueMask & CWX ? xwc->x - priv->serverGeometry.x () : 0;
1280+ int dy = valueMask & CWY ? xwc->y - priv->serverGeometry.y () : 0;
1281+
1282 if (priv->managed && (valueMask & (CWSibling | CWStackMode)))
1283 {
1284 CompWindowList transients;
1285@@ -3764,6 +3465,16 @@
1286 {
1287 priv->reconfigureXWindow (valueMask, xwc);
1288 }
1289+
1290+ if (!overrideRedirect () && (dx || dy))
1291+ {
1292+ priv->region.translate (dx, dy);
1293+ priv->inputRegion.translate (dx, dy);
1294+ if (!priv->frameRegion.isEmpty ())
1295+ priv->frameRegion.translate (dx, dy);
1296+ moveNotify (dx, dy, priv->nextMoveImmediate);
1297+ priv->nextMoveImmediate = true;
1298+ }
1299 }
1300
1301 int
1302@@ -4315,10 +4026,6 @@
1303 screen->dpy (), serverFrame, valueMask, &lxwc)));
1304
1305 pendingConfigures.add (pc);
1306- if (priv->mClearCheckTimeout.active ())
1307- priv->mClearCheckTimeout.stop ();
1308- priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
1309- 2000, 2500);
1310 }
1311
1312 /* Below with no sibling puts the window at the bottom
1313@@ -5489,7 +5196,7 @@
1314 m = priv->geometry.x () + offX;
1315 if (m - priv->input.left < (int) s->width () - vWidth)
1316 rv.setX (offX + vWidth);
1317- else if (m + priv->width + priv->input.right > vWidth)
1318+ else if (m + priv->geometry.width () + priv->input.right > vWidth)
1319 rv.setX (offX - vWidth);
1320 else
1321 rv.setX (offX);
1322@@ -5504,7 +5211,7 @@
1323 m = priv->geometry.y () + offY;
1324 if (m - priv->input.top < (int) s->height () - vHeight)
1325 rv.setY (offY + vHeight);
1326- else if (m + priv->height + priv->input.bottom > vHeight)
1327+ else if (m + priv->geometry.height () + priv->input.bottom > vHeight)
1328 rv.setY (offY - vHeight);
1329 else
1330 rv.setY (offY);
1331@@ -6080,7 +5787,7 @@
1332
1333 if (m - priv->output.left < (int) screen->width () - vWidth)
1334 wx = tx + vWidth;
1335- else if (m + priv->width + priv->output.right > vWidth)
1336+ else if (m + priv->geometry.width () + priv->output.right > vWidth)
1337 wx = tx - vWidth;
1338 }
1339
1340@@ -6090,7 +5797,7 @@
1341
1342 if (m - priv->output.top < (int) screen->height () - vHeight)
1343 wy = ty + vHeight;
1344- else if (m + priv->height + priv->output.bottom > vHeight)
1345+ else if (m + priv->geometry.height () + priv->output.bottom > vHeight)
1346 wy = ty - vHeight;
1347 }
1348
1349@@ -6316,9 +6023,6 @@
1350 priv->serverFrameGeometry = priv->frameGeometry = priv->syncGeometry
1351 = priv->geometry = priv->serverGeometry;
1352
1353- priv->width = priv->attrib.width + priv->attrib.border_width * 2;
1354- priv->height = priv->attrib.height + priv->attrib.border_width * 2;
1355-
1356 priv->sizeHints.flags = 0;
1357
1358 priv->recalcNormalHints ();
1359@@ -6340,8 +6044,7 @@
1360
1361 if (priv->attrib.c_class != InputOnly)
1362 {
1363- priv->region = CompRegion (priv->attrib.x, priv->attrib.y,
1364- priv->width, priv->height);
1365+ priv->region = CompRegion (priv->serverGeometry);
1366 priv->inputRegion = priv->region;
1367
1368 /* need to check for DisplayModal state on all windows */
1369@@ -6586,8 +6289,6 @@
1370 hints (NULL),
1371 inputHint (true),
1372 alpha (false),
1373- width (0),
1374- height (0),
1375 region (),
1376 wmType (0),
1377 type (CompWindowTypeUnknownMask),
1378@@ -6622,7 +6323,6 @@
1379 pendingUnmaps (0),
1380 pendingMaps (0),
1381 pendingConfigures (screen->dpy ()),
1382- pendingPositionUpdates (false),
1383
1384 startupId (0),
1385 resName (0),
1386@@ -6824,8 +6524,8 @@
1387 priv->frameRegion &= CompRegion (r);
1388 }
1389
1390- x = priv->geometry.x () - priv->input.left;
1391- y = priv->geometry.y () - priv->input.top;
1392+ x = priv->serverGeometry.x () - priv->input.left;
1393+ y = priv->serverGeometry.y () - priv->input.top;
1394
1395 XShapeCombineRegion (screen->dpy (), priv->serverFrame,
1396 ShapeBounding, -x, -y,
1397@@ -6866,6 +6566,11 @@
1398
1399 priv->updateSize ();
1400 priv->updateFrameWindow ();
1401+
1402+ /* Always send a moveNotify
1403+ * whenever the frame extents update
1404+ * so that plugins can re-position appropriately */
1405+ moveNotify (0, 0, true);
1406 }
1407
1408 /* Use b for _NET_WM_FRAME_EXTENTS here because
1409
1410=== modified file 'src/windowgeometry.cpp'
1411--- src/windowgeometry.cpp 2012-01-23 05:44:19 +0000
1412+++ src/windowgeometry.cpp 2012-02-28 07:58:17 +0000
1413@@ -61,22 +61,22 @@
1414 int
1415 CompWindow::width () const
1416 {
1417- return priv->width +
1418+ return priv->geometry.width () +
1419 priv->geometry.border () * 2;
1420 }
1421
1422 int
1423 CompWindow::height () const
1424 {
1425- return priv->height +
1426+ return priv->geometry.height () +
1427 priv->geometry.border () * 2;;
1428 }
1429
1430 CompSize
1431 CompWindow::size () const
1432 {
1433- return CompSize (priv->width + priv->geometry.border () * 2,
1434- priv->height + priv->geometry.border () * 2);
1435+ return CompSize (priv->geometry.width () + priv->geometry.border () * 2,
1436+ priv->geometry.height () + priv->geometry.border () * 2);
1437 }
1438
1439 int

Subscribers

People subscribed via source and target branches