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

Proposed by Sam Spilsbury
Status: Superseded
Proposed branch: lp:~smspillaz/compiz-core/compiz-core.work_923683
Merge into: lp:compiz-core
Prerequisite: lp:~smspillaz/compiz-core/compiz-core.fix_969101
Diff against target: 2780 lines (+584/-844)
21 files modified
plugins/composite/src/window.cpp (+19/-39)
plugins/decor/src/decor.cpp (+80/-59)
plugins/decor/src/decor.h (+4/-3)
plugins/move/src/move.cpp (+10/-12)
plugins/opengl/src/paint.cpp (+11/-18)
plugins/opengl/src/privates.h (+7/-1)
plugins/opengl/src/window.cpp (+39/-17)
plugins/place/src/constrain-to-workarea/src/constrain-to-workarea.cpp (+4/-6)
plugins/place/src/place.cpp (+19/-24)
plugins/resize/src/resize.cpp (+8/-18)
plugins/resize/src/resize.h (+0/-2)
plugins/wobbly/src/wobbly.cpp (+37/-40)
plugins/wobbly/src/wobbly.h (+2/-0)
src/actions.cpp (+2/-2)
src/event.cpp (+1/-1)
src/privatewindow.h (+7/-8)
src/screen.cpp (+4/-2)
src/window.cpp (+274/-545)
src/window/geometry/include/core/windowgeometry.h (+6/-0)
src/window/geometry/tests/window-geometry/src/test-window-geometry.cpp (+10/-0)
src/windowgeometry.cpp (+40/-47)
To merge this branch: bzr merge lp:~smspillaz/compiz-core/compiz-core.work_923683
Reviewer Review Type Date Requested Status
Daniel van Vugt Needs Fixing
Sam Spilsbury Pending
Alan Griffiths Pending
Review via email: mp+102504@code.launchpad.net

This proposal supersedes a proposal from 2012-04-18.

This proposal has been superseded by a proposal from 2012-04-19.

Description of the change

Resubmitted now that lp:~smspillaz/compiz-core/compiz-core.fix_969108.2 and lp:~smspillaz/compiz-core/compiz-core.fix_969101 are active

Note: you'll get funny behaviour around window edges unless you use lp:~smspillaz/compiz-snap-plugin/compiz-snap-plugin.work_923683 . The snap plugin was using the interfaces incorrectly.

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.
Revision history for this message
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...

Revision history for this message
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

Revision history for this message
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
Revision history for this message
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...

Revision history for this message
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 ()"; }"

Revision history for this message
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
Revision history for this message
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; }

Revision history for this message
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

Revision history for this message
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.

Revision history for this message
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)

Revision history for this message
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.

Revision history for this message
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: Needs Resubmitting
Revision history for this message
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
Revision history for this message
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.

Revision history for this message
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.

Revision history for this message
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
Revision history for this message
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".

Revision history for this message
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.

Revision history for this message
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 ?

Revision history for this message
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.

Revision history for this message
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.

Revision history for this message
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

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

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

Revision history for this message
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 :(

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

    //XSynchronize (dpy, TRUE);

:) Haven't merged your other branch

Revision history for this message
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);

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

Perhaps remember to pull from trunk more often.

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

where trunk == lp:compiz-core

Revision history for this message
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?

Revision history for this message
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.

Revision history for this message
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);

Revision history for this message
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.

Revision history for this message
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.

Revision history for this message
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.

Revision history for this message
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).

Revision history for this message
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.

Revision history for this message
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.

Revision history for this message
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.

Revision history for this message
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
Revision history for this message
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 ?

Revision history for this message
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

Revision history for this message
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 ?

Revision history for this message
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.

Revision history for this message
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 ?

Revision history for this message
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.

Revision history for this message
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.

Revision history for this message
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.
>

Revision history for this message
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.
>

Revision history for this message
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.

Revision history for this message
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.

Revision history for this message
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"

Revision history for this message
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.

Revision history for this message
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.

Revision history for this message
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
Revision history for this message
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)

Revision history for this message
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
Revision history for this message
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

Revision history for this message
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
Revision history for this message
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.
>

Revision history for this message
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 :-)

Revision history for this message
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.

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

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
Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

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
Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

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

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

Hmm, I would imagine this is the throttling of motion events that we mentioned earlier. I think in lp:compiz-core we would have just spent all that time in CompWindow::move although I'll conceed that configureXWindow is a bit more of an ... involved function (although I haven't noticed any *noticable* performance problems).

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

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

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

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.

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

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?

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

One small caveat is that I haven't merged lp:compiz-core into this one today, which includes the region fixes.

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

Yes it does. There are some optimizations we can do there to make it only compute regions on certain windows. I've done them before, so its not too hard. Not for this branch.

> 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.

So I think there are three optimizations which can be applied here, all of which are quite involved, so I'll need to put them in separate branches.

Firstly, we need to throttle motion events, so they aren't dispatched spuriously. That's easy enough to do.

The second which is a bit more complicated is to also throttle dispatch of serverGeometry updates / moveNotify / XConfigureWindow as well. There are some plugins which need immediate move notify updates but probably not immediate move notify updates 1000 times a second.

Another optimization is to only call XConfigureWindow when we actually need to update the server side position and not necessarily all the time. This does mean that serverGeometry will be "ahead" of whats being sent to the server, but that's OK since we can just flush the changes on demand (and besides, its meant to be ahead, which is why its there).

Incidentally, I'm not able to get such high readings in callgrind for window movement, but I guess this is a case-by-case thing.

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

Window movement accounts for all my CPU because that's all I am testing since I noticed the problem;
  Start compiz
  Move windows around lots
  Stop compiz

With this branch I see movement account for 60-80% of compiz' time and is incredibly slow and stuttering. Without this branch, it only uses maximum 20% of compiz' time and is visually much smoother.

Revision history for this message
Daniel van Vugt (vanvugt) : Posted in a previous version of this proposal
review: Needs Fixing
Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

I merged lp:compiz-core from today. Could you give it another try and let me know how it goes ?

Also some thoughts on those optimizations would be nice :)

Currently I'm testing using the entire unity stack, but I can reduce it down to just compiz and a basic set of plugins.

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

I was already testing this branch merged with the latest lp:compiz-core (including yesterday's optimizations) all along. Which makes the regression from this branch more worrying.

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

tOn Tue, 28 Feb 2012, Daniel van Vugt wrote:

> I was already testing this branch merged with the latest lp:compiz-core (including yesterday's optimizations) all along. Which makes the regression from this branch more worrying.
> --
> https://code.launchpad.net/~smspillaz/compiz-core/compiz-core.work_923683/+merge/94923
> You are the owner of lp:~smspillaz/compiz-core/compiz-core.work_923683.
>

OK, well, I know there are some code paths which can be slow, so lets look
at optimizing. Do you have any thoughts about the ideas I raised ?

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

I don't have the encyclopaedic knowledge of CompWindow or the time to research your suggestions right now. So no comment.

But I'm happy to test/profile any further additions to this proposal... tomorrow.

(Daniel logs off)

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

I don't see anything obviously wrong, but would like to hear the results of Daniel's profiling.

review: Abstain
Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Tested revision 2994. Moving windows is still so slow it's unusable (under valgrind). We should fix this because it's a good indication that the same would occur in the wild on a slow machine.

compiz is spending 70% of it's CPU in or below moveHandleMotionEvent. The two main CPU hogs are:

(73% of the 70%)
moveHandleMotionEvent
CompWindow::move
DecorWindow::moveNotify
DecorWindow::computeShadowRegion

(16% of the 70%)
moveHandleMotionEvent
CompWindow::move
CompWindow::configureXWindow
PrivateWindow::reconfigureXWindow

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

And no, combining this branch with lp:~smspillaz/compiz-core/compiz-core.optimization-inlining
does not solve or change the performance problem.

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

Indeed, that's not meant to completely fix it, but it does fix some hotspots and other inefficiencies I observed :)

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

I'm concerned that the code still looks "fragile" (to use Sam's word). For example:

50 + y1 = geom.height () + geom.border ();
...
59 + y2 = geom.height () - geom.border ();

It isn't explicit why border is added in one case and subtracted in the other. I suspect that there's an abstraction missing (or at least suitably named functions that derive the appropriate result from geom). Something like "internalHeight = internalHeight(geom)" is much easier to follow.

I've not tested the latest version enough to be confident in it. Will aim to do so on Thursday.

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

> I'm concerned that the code still looks "fragile" (to use Sam's word). For
> example:
>
> 50 + y1 = geom.height () + geom.border ();
> ...
> 59 + y2 = geom.height () - geom.border ();
>
> It isn't explicit why border is added in one case and subtracted in the other.
> I suspect that there's an abstraction missing (or at least suitably named
> functions that derive the appropriate result from geom). Something like
> "internalHeight = internalHeight(geom)" is much easier to follow.
>
> I've not tested the latest version enough to be confident in it. Will aim to
> do so on Thursday.

Ack, I'll add something like that to compiz::window::Geometry

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal
Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Tested this branch by itself and merged with lp:~smspillaz/compiz-core/compiz-core.fix_969108.2

By itself, this branch still makes window movement unacceptably slow. With the other branch designed to make movement more efficient, windows now often don't move at all when dragged.

Unfortunately performance is getting worse, not better.

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

Its probably a small typo during refactoring. Please don't panic

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

I got this branch performing somewhat better by combining it with:
https://code.launchpad.net/~vanvugt/compiz-core/lastMotionTime/+merge/100742

However I would say still noticeably slower than lp:compiz-core. :(

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

Confirmed the performance problems with this branch do seem to be fixed by:
https://code.launchpad.net/~smspillaz/compiz-core/compiz-core.fix_969101/+merge/100270

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

Please resubmit with prerequisite:
lp:~smspillaz/compiz-core/compiz-core.fix_969101

review: Needs Resubmitting
Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

This branch does appear to fix bug 862430.

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

I was so close to approving and merging this today. But in final testing I noticed it triggers window border/shadow artefacts when resizing. They are easiest to see in Normal resize mode, but still happen much less noticeably in Rectangle resize mode too.

Just put a Nautilus window in front of a large white window and resize the Nautilus window rapidly from its top-right corner. Ugly artefacts will be left on the window behind.

I actually suspect the resize plugin being to blame for this, because I have encountered similar bugs with it before. And read that the GLES branch seems to have too.

However right now, it's being triggered by this branch. So I can't approve it just yet.

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

I can't reproduce the same resize artefacts with my experimental branch, only with this one.

Perhaps we didn't notice the artefacts before because they are the result of the latest compiz-core commit r3086 combining with this branch...

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

Resubmitted again.

LP #923520 is also fixed in this branch. I'm not sure if the artefacts are fixed "for good" but I can't reproduce them anymore since fixing that one.

(I cannot remove that fix from this branch, since its actually dependent on the fact that we can update window regions before sending geometry to the server, which wouldn't be possible in core at the moment)

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

> (I cannot remove that fix from this branch, since its actually dependent on
> the fact that we can update window regions before sending geometry to the
> server, which wouldn't be possible in core at the moment)

Clarifying ambiguous words: I can't separate out that fix.

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

Typo : bug 932520

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

The intent has always looked sensible. The latest code looks the tidiest. And I've been running it all morning without noticing anything untoward.

review: Approve
Revision history for this message
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal

Probably a reason not to merge, but running with "wobbly windows", and dragging a window across others there are repaint issues on the "behind" windows that don't resolve until the moved window is released.

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

> Probably a reason not to merge, but running with "wobbly windows", and
> dragging a window across others there are repaint issues on the "behind"
> windows that don't resolve until the moved window is released.

That should be "Probably /not/ a reason not to merge"

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

> Probably a reason not to merge, but running with "wobbly windows", and
> dragging a window across others there are repaint issues on the "behind"
> windows that don't resolve until the moved window is released.

I'll resolve this anyhow since it could impact other plugins.

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

Please remove the ABI changes (include/core/window.h at least). I agree they're nice changes, but we can't change the ABI.

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

Also, when I maximize and restore a window, it moves left by about 1 pixel each time. So I don't think we can declare this branch as having fixed bug 892012.

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

And confirmed the regression with wobbly windows this branch introduces. Although not officially enabled by default, enough people do use wobbly windows for us to want to avoid introducing such a regression.

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

Confirmed the flicker bug 862430 is fixed. So that's some good news.

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

Both issues fixed, please re-review.

Will look into the 1px shift later.

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

Confirm wobbly windows fixed. They are rather cute!

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

I'm still testing the various bugs, and want to continue testing for tomorrow at least.

So far I can't see any regressions. And the 1px movement issue is actually not related to this branch, so forget that for now.

Once I'm happy it runs OK and further fixes are not required, then I'll start reviewing the code again in detail.

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

I sense a slight performance regression when moving windows compared to trunk. Trunk is slightly smoother. But it's only noticeable when running under callgrind and only slight.

I have confirmed 3 of the 4 bugs are fixed, and the other 1 I can't reproduce.

All good so far. But I won't review the rather large diff in detail tonight.

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

Only problem I've seen today is that when I replace the graphics stack all windows end up in 1st workspace. I don't think that is this branch - but haven't got to the bottom of it yet.

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

* priv->frameRegion -= infiniteRegion
  should be:
  priv->frameRegion = emptyRegion;

* Gererally speaking, x1 + width != x2
  That's an off-by-one mistake. It should usually be: x1 + width - 1 == x2
  However I can't prove that's causing any problems right now and it's not new in this branch.

* Regression: The resize artefacts reported on 5 April are still present. I thought they were meant to be fixed?

I really really don't want to see any more revisions of this branch. But the regression is kind of a problem.

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

Thanks, the regression is now fixed (or at least worked around by damageScreen).

And after 10 weeks(!) of revisions on this branch, I'm sure I'm not the only one who is fed up looking at it.

As far as I can tell, it fixes all the bugs linked to it. And there are no visible regressions now. Let's land it, and move on.

review: Approve
Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

As above.

review: Approve
Revision history for this message
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal

LGTM

review: Approve
Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

REGRESSION:
When resizing a window's top or left edges, the opposite edge jitters about (in Normal resize move). I know I mentioned this bug yesterday but I only just realized it's a regression that's unique to this branch.

Sounds like that's the cause of the resize artefacts too. So if we fix the regression then we can remove the damageScreen workaround from the resize plugin.

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

And please wait till Monday at least before proposing any new revisions. It would ruin my weekend to see this branch come up in weekend email :)

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

Make that Tuesday. You're meant to have Monday off, I believe :)

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

> And please wait till Monday at least before proposing any new revisions. It
> would ruin my weekend to see this branch come up in weekend email :)

Nobody is making you look at this ...........................................

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

Okay.

Normal resize mode was not something I was planning on supporting in precise. Nevertheless, I've merged in some work I did a few weeks ago to essentially fix it up so that there's no tearing and windows don't appear to jump around when you resize them.

There is still a race condition in the window decorators where pixmaps can be freed server side before they are bound by the decorator. Getting around that race condition requires some synchronization protocol which I've prototyped and works fine with gtk-window-decorator (no fail to bind errors \o/). However, I don't want to push up the size of the diff anymore. So I've put that work in another branch (lp:~smspillaz/compiz-core/compiz-core.decor_synchronization).

The damageScreen call in DecorWindow::resizeNotify is, while unfortunate, necessary for now at least. There are some race conditions to do with bindPixmapToTexture where the returned size can differ from the actual texture size in the middle of a resize op. As such, damageScreen for now.

I hope this is the last revision we need to do of this.

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

Contains a trivial conflict in src/window.cpp, but simple to fix and carry on testing.

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

Breaks with wobby windows - moving windows distorted, semi-maximized windows placed wrongly

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

Regression: Vertically maximizing a window while wobbly is enabled causes it to over-shoot either the top or bottom of the screen, instead of fitting to the top and bottom.

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

Erm, I think we both just said the same thing :)

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

> Erm, I think we both just said the same thing :)

Maybe we're both right?

;)

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

Issues with the wobbly plugin fixed.

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

That being said, please keep in mind that for ubuntu we really don't care about plugins and options that we don't enable by default. All upgraders get their settings reset.

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

[Still using wobbly of course] largely fixed.

If I drag to LHS (say) the orange highlight looks fine, but the window first paints and wobbles a few pixels to left before jumping to the correct position.

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

The glitch with wobbly is minor (and now doesn't happen consistently) other issues appear fixed.

review: Approve
Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Regression: Weirdly, this branch (r3017) causes a regression of bug 981703. So Alan's fix wasn't the root cause, just a trigger. But we knew that already.

Also contains conflicts.

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

Regression #2: This branch causes artefacts/gaps in the switcher window. Screenshot emailed to smspillaz.

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

Regressions fixed.

The big change in this branch is here:

 CompWindow::Geometry &
 CompWindow::serverGeometry () const
 {
- return priv->serverGeometry;
+ return priv->attrib.override_redirect ? priv->geometry : priv->serverGeometry;
 }

 CompWindow::Geometry &
 CompWindow::geometry () const
 {
- return priv->geometry;
+ return priv->attrib.override_redirect ? priv->geometry : priv->serverGeometry;
 }

We're now making all calls to both geometry () and serverGeometry () for managed windows return geometry last sent to server. The reason is that for managed windows, configureXWindow can never fail, so the geometry last sent is always the most up to date and the most accurate.

Override redirect windows cant be configured so we used the geometry last received from the server from that.

In my testing, this fixed practically all the flakiness.

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

I have no reason to believe it is doing the wrong thing, but expressions like the following don't parse easily:

2706 + return CompRect (geometry ().xMinusBorder () - priv->border.left,
2707 + geometry ().yMinusBorder () - priv->border.top,

why are we subtracting a border from "*MinusBorder"? why isn't that what "MinusBorder" does?

2708 + geometry ().widthIncBorders () +
2709 priv->border.left + priv->border.right,
2711 + geometry ().heightIncBorders () +
2712 priv->border.top + priv->border.bottom);

why are we adding borders to "*IncBorders"? why isn't that what "IncBorders" does?

(I suspect it's a naming thing, or a missing abstraction.)

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

Regression: Window is offset from its decorations (vertically this time).
Test case : Open a terminal, minimize it, restore it using switcher.
Outcome : Window is offset vertically from its decorations.

I've emailed a screenshot to smpsillaz.

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

The branch also contains more complex conflicts now that need fixing.

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

Regression #2: Shading is very broken. Windows shade/unshade without their decorations changing (until the window is moved). And often I can't unshade windows at all.

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

Lines 2537..2547: This is the same as Alan's branch and ideally shouldn't be in this one too. I will reintroduce that code to trunk soon, when my new fix for bug 981703 is merged.

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

And I spy more pointless "-= infiniteRegion" statements.

review: Needs Fixing
Revision history for this message
Sam Spilsbury (smspillaz) wrote :

Regressions fixed.

Alan - now that server* is effectively no longer necessary, we can proceed to bulk-rename things in the next series when we get all the code in one place. Wdyt ?

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

Not seen any problems over the last couple of hours. Will have a look at the code tomorrow (unless there are more changes by then - in which case I might swear).

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Regression #1: Windows lose their borders (and most shadows) during shading animation. Try this with a Terminal so it's more visible.

Regression #2: "failed to bind pixmap to texture" warnings and flashing white decorations during resize are now much more common in this branch than with trunk. Annoyingly so.

Regression #3: Moving wobbly windows in expo (esp. between workspaces) jump a significant distance after the wobble.

Regression #4: Vertically maximized wobbly windows sometimes jump up/down by one pixel after the wobble, making the bottom border visible/invisible. Try Alt+dragging a vertically maximized window up a little, and sometimes it will move up ~1px. Normally the borders of semi-maximized windows overlap adjacent workspaces by 1px. That's a bug in trunk too, but this regression makes it worse (2px) and unpredictable.

I dare say it might be time to start again, using multiple smaller proposals rather than this one big one. I don't believe a single large proposal is the only way to solve the four related bugs.

review: Needs Fixing
Revision history for this message
Sam Spilsbury (smspillaz) wrote :

> Regression #1: Windows lose their borders (and most shadows) during shading
> animation. Try this with a Terminal so it's more visible.

Insignificant.

>
> Regression #2: "failed to bind pixmap to texture" warnings and flashing white
> decorations during resize are now much more common in this branch than with
> trunk. Annoyingly so.

I'm not supporting normal resize mode. See my previous comments as to the flashing white borders and the solution to that.

>
> Regression #3: Moving wobbly windows in expo (esp. between workspaces) jump a
> significant distance after the wobble.

This is the only one worth attention. I will look into it.

>
> Regression #4: Vertically maximized wobbly windows sometimes jump up/down by
> one pixel after the wobble, making the bottom border visible/invisible. Try
> Alt+dragging a vertically maximized window up a little, and sometimes it will
> move up ~1px. Normally the borders of semi-maximized windows overlap adjacent
> workspaces by 1px. That's a bug in trunk too, but this regression makes it
> worse (2px) and unpredictable.

Why is this a bad thing ? Why does this justify rejecting this branch. This feels very insignificant.

>
> I dare say it might be time to start again, using multiple smaller proposals
> rather than this one big one. I don't believe a single large proposal is the
> only way to solve the four related bugs.

Not possible.

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Please don't say something's impossible. It will only motivate me (or other people) to prove you wrong, and that would be a duplication of effort and waste of resources.

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

Everyone is getting fed up with this branch.

IMO the prop-review cycle is getting in the way. This sort of problem is better addressed by a pairing session. (Not so easy when not co-located, but still possible.)

3028. By Sam Spilsbury

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

3029. By Sam Spilsbury

Remove some unnecessary cahgnes in the wobbly plugin

3030. By Sam Spilsbury

Merge lp:compiz-core

3031. By Sam Spilsbury

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

Fix logic errors

3033. By Sam Spilsbury

!= 0 not necessary

3034. By Sam Spilsbury

Merge lp:compiz-core

Unmerged revisions

3034. By Sam Spilsbury

Merge lp:compiz-core

3033. By Sam Spilsbury

!= 0 not necessary

3032. By Sam Spilsbury

Fix logic errors

3031. By Sam Spilsbury

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

Merge lp:compiz-core

3029. By Sam Spilsbury

Remove some unnecessary cahgnes in the wobbly plugin

3028. By Sam Spilsbury

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

3027. By Sam Spilsbury

Base decision to send notifications to plugins on absolute position
changes

3026. By Sam Spilsbury

updateState is bitwise, so never clobber it

3025. By Sam Spilsbury

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 'plugins/composite/src/window.cpp'
2--- plugins/composite/src/window.cpp 2012-03-22 17:00:51 +0000
3+++ plugins/composite/src/window.cpp 2012-04-18 12:32:31 +0000
4@@ -128,6 +128,9 @@
5 /* We have to grab the server here to make sure that window
6 is mapped when getting the window pixmap */
7 XGrabServer (screen->dpy ());
8+
9+ /* Flush changes to the server and wait for it to process them */
10+ XSync (screen->dpy (), false);
11 XGetWindowAttributes (screen->dpy (),
12 ROOTPARENT (priv->window), &attr);
13 if (attr.map_state != IsViewable)
14@@ -250,7 +253,7 @@
15
16 if (x2 > x1 && y2 > y1)
17 {
18- CompWindow::Geometry geom = priv->window->geometry ();
19+ const CompWindow::Geometry &geom = priv->window->serverGeometry ();
20
21 x1 += geom.x () + geom.border ();
22 y1 += geom.y () + geom.border ();
23@@ -272,20 +275,20 @@
24 {
25 int x1, x2, y1, y2;
26
27- CompWindow::Geometry geom = priv->window->geometry ();
28- CompWindowExtents output = priv->window->output ();
29+ const CompWindow::Geometry &geom = priv->window->serverGeometry ();
30+ const CompWindowExtents &output = priv->window->output ();
31
32 /* top */
33 x1 = -output.left - geom.border ();
34 y1 = -output.top - geom.border ();
35- x2 = priv->window->size ().width () + output.right - geom.border ();
36+ x2 = geom.width () + geom.border () + output.right;
37 y2 = -geom.border ();
38
39 if (x1 < x2 && y1 < y2)
40 addDamageRect (CompRect (x1, y1, x2 - x1, y2 - y1));
41
42 /* bottom */
43- y1 = priv->window->size ().height () - geom.border ();
44+ y1 = geom.height () + geom.border ();
45 y2 = y1 + output.bottom - geom.border ();
46
47 if (x1 < x2 && y1 < y2)
48@@ -295,13 +298,13 @@
49 x1 = -output.left - geom.border ();
50 y1 = -geom.border ();
51 x2 = -geom.border ();
52- y2 = priv->window->size ().height () - geom.border ();
53+ y2 = geom.height () - geom.border ();
54
55 if (x1 < x2 && y1 < y2)
56 addDamageRect (CompRect (x1, y1, x2 - x1, y2 - y1));
57
58 /* right */
59- x1 = priv->window->size ().width () - geom.border ();
60+ x1 = geom.width () - geom.border ();
61 x2 = x1 + output.right - geom.border ();
62
63 if (x1 < x2 && y1 < y2)
64@@ -322,7 +325,7 @@
65 x = rect.x ();
66 y = rect.y ();
67
68- CompWindow::Geometry geom = priv->window->geometry ();
69+ const CompWindow::Geometry &geom = priv->window->serverGeometry ();
70 x += geom.x () + geom.border ();
71 y += geom.y () + geom.border ();
72
73@@ -341,16 +344,16 @@
74 if (priv->window->shaded () || force ||
75 (priv->window->isViewable ()))
76 {
77- int border = priv->window->geometry ().border ();
78+ int border = priv->window->serverGeometry ().border ();
79
80 int x1 = -MAX (priv->window->output ().left,
81 priv->window->input ().left) - border;
82 int y1 = -MAX (priv->window->output ().top,
83 priv->window->input ().top) - border;
84- int x2 = priv->window->size ().width () +
85+ int x2 = priv->window->serverGeometry ().width () +
86 MAX (priv->window->output ().right,
87 priv->window->input ().right) ;
88- int y2 = priv->window->size ().height () +
89+ int y2 = priv->window->serverGeometry ().height () +
90 MAX (priv->window->output ().bottom,
91 priv->window->input ().bottom) ;
92 CompRect r (x1, y1, x2 - x1, y2 - y1);
93@@ -410,7 +413,7 @@
94
95 if (!w->damageRect (initial, CompRect (x, y, width, height)))
96 {
97- CompWindow::Geometry geom = w->priv->window->geometry ();
98+ CompWindow::Geometry geom = w->priv->window->serverGeometry ();
99
100 x += geom.x () + geom.border ();
101 y += geom.y () + geom.border ();
102@@ -557,10 +560,6 @@
103 {
104 window->resizeNotify (dx, dy, dwidth, dheight);
105
106- Pixmap pixmap = None;
107- CompSize size = CompSize ();
108-
109-
110 if (window->shaded () || (window->isViewable ()))
111 {
112 int x, y, x1, x2, y1, y2;
113@@ -578,25 +577,6 @@
114 cScreen->damageRegion (CompRegion (CompRect (x1, y1, x2 - x1, y2 - y1)));
115 }
116
117- if (window->mapNum () && redirected)
118- {
119- unsigned int actualWidth, actualHeight, ui;
120- Window root;
121- Status result;
122- int i;
123-
124- pixmap = XCompositeNameWindowPixmap (screen->dpy (), ROOTPARENT (window));
125- result = XGetGeometry (screen->dpy (), pixmap, &root, &i, &i,
126- &actualWidth, &actualHeight, &ui, &ui);
127- size = CompSize (actualWidth, actualHeight);
128- if (!result || actualWidth != (unsigned int) window->size ().width () ||
129- actualHeight != (unsigned int) window->size ().height ())
130- {
131- XFreePixmap (screen->dpy (), pixmap);
132- return;
133- }
134- }
135-
136 if (((!window->mapNum () && window->isViewable ()) ||
137 window->state () & CompWindowStateHiddenMask) && window->hasUnmapReference ())
138 {
139@@ -622,14 +602,14 @@
140 {
141 int x, y, x1, x2, y1, y2;
142
143- x = window->geometry ().x ();
144- y = window->geometry ().y ();
145+ x = window->serverGeometry ().x ();
146+ y = window->serverGeometry ().y ();
147
148 x1 = x - window->output ().left - dx;
149 y1 = y - window->output ().top - dy;
150- x2 = x + window->size ().width () +
151+ x2 = x + window->serverGeometry ().width () +
152 window->output ().right - dx;
153- y2 = y + window->size ().height () +
154+ y2 = y + window->serverGeometry ().height () +
155 window->output ().bottom - dy;
156
157 cScreen->damageRegion (CompRegion (CompRect (x1, y1, x2 - x1, y2 - y1)));
158
159=== modified file 'plugins/decor/src/decor.cpp'
160--- plugins/decor/src/decor.cpp 2012-04-17 04:05:07 +0000
161+++ plugins/decor/src/decor.cpp 2012-04-18 12:32:31 +0000
162@@ -223,30 +223,38 @@
163
164 const CompRegion *preg = NULL;
165
166- if ((mask & (PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK |
167- PAINT_WINDOW_WITH_OFFSET_MASK)))
168- preg = &region;
169- else if (mask & PAINT_WINDOW_TRANSFORMED_MASK)
170- preg = &infiniteRegion;
171- else
172+ if (mClipGroup)
173 {
174- tmpRegion = mOutputRegion;
175- tmpRegion &= region;
176-
177- if (tmpRegion.isEmpty ())
178+ if ((mask & (PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK |
179+ PAINT_WINDOW_WITH_OFFSET_MASK)))
180 preg = &region;
181+ else if (mask & PAINT_WINDOW_TRANSFORMED_MASK)
182+ preg = &infiniteRegion;
183 else
184- preg = &shadowRegion;
185+ {
186+ tmpRegion = mOutputRegion;
187+ tmpRegion &= region;
188+
189+ if (tmpRegion.isEmpty ())
190+ preg = &region;
191+ else
192+ preg = &shadowRegion;
193+ }
194+
195+ /* In case some plugin needs to paint us with an offset region */
196+ if (preg->isEmpty ())
197+ preg = &region;
198 }
199-
200- /* In case some plugin needs to paint us with an offset region */
201- if (preg->isEmpty ())
202+ else
203 preg = &region;
204
205 const CompRegion &reg (*preg);
206
207 gWindow->geometry ().reset ();
208
209+ if (updateMatrix)
210+ updateDecorationScale ();
211+
212 for (int i = 0; i < wd->nQuad; i++)
213 {
214 box.setGeometry (wd->quad[i].box.x1,
215@@ -275,6 +283,9 @@
216 if (gWindow->textures ().empty ())
217 return;
218
219+ if (updateMatrix)
220+ updateDecorationScale ();
221+
222 if (gWindow->textures ().size () == 1)
223 {
224 ml[0] = gWindow->matrices ()[0];
225@@ -1017,6 +1028,8 @@
226 wd->quad[i].box.y1 * wd->quad[i].matrix.yy +
227 wd->quad[i].box.x1 * wd->quad[i].matrix.yx;
228 }
229+
230+ updateMatrix = false;
231 }
232
233 /*
234@@ -1043,8 +1056,8 @@
235 for (i = 0; i < wd->nQuad; i++)
236 {
237 int x, y;
238- unsigned int width = window->size ().width ();
239- unsigned int height = window->size ().height ();
240+ unsigned int width = window->geometry ().width ();
241+ unsigned int height = window->geometry ().height ();
242
243 if (window->shaded ())
244 height = 0;
245@@ -1060,6 +1073,7 @@
246 wd->quad[i].box.y1 = y1 + y;
247 wd->quad[i].box.x2 = x2 + x;
248 wd->quad[i].box.y2 = y2 + y;
249+
250 wd->quad[i].sx = sx;
251 wd->quad[i].sy = sy;
252 }
253@@ -1082,8 +1096,8 @@
254 bool
255 DecorWindow::checkSize (const Decoration::Ptr &decoration)
256 {
257- return (decoration->minWidth <= (int) window->size ().width () &&
258- decoration->minHeight <= (int) window->size ().height ());
259+ return (decoration->minWidth <= (int) window->serverGeometry ().width () &&
260+ decoration->minHeight <= (int) window->serverGeometry ().height ());
261 }
262
263 /*
264@@ -1502,7 +1516,7 @@
265 */
266 if (decoration)
267 {
268- wd = WindowDecoration::create (decoration);
269+ wd = WindowDecoration::create ( decoration);
270 if (!wd)
271 return false;
272
273@@ -1523,6 +1537,9 @@
274 if (decorate)
275 updateFrame ();
276 window->updateWindowOutputExtents ();
277+
278+ updateReg = true;
279+ updateMatrix = true;
280 mOutputRegion = CompRegion (window->outputRect ());
281 updateGroupShadows ();
282 if (dScreen->cmActive)
283@@ -1537,8 +1554,7 @@
284 /* Undecorated windows need to have the
285 * input and output frame removed and the
286 * frame window geometry reset */
287- if (decorate)
288- updateFrame ();
289+ updateFrame ();
290
291 memset (&emptyExtents, 0, sizeof (CompWindowExtents));
292
293@@ -1687,7 +1703,6 @@
294 XRectangle rects[4];
295 int x, y, width, height;
296 CompWindow::Geometry server = window->serverGeometry ();
297- int bw = server.border () * 2;
298 CompWindowExtents input;
299 CompWindowExtents border;
300 Window parent;
301@@ -1714,8 +1729,8 @@
302
303 x = window->border ().left - border.left;
304 y = window->border ().top - border.top;
305- width = server.width () + input.left + input.right + bw;
306- height = server.height ()+ input.top + input.bottom + bw;
307+ width = server.widthIncBorders () + input.left + input.right;
308+ height = server.heightIncBorders ()+ input.top + input.bottom ;
309
310 /* Non switcher windows are rooted relative to the frame window of the client
311 * and switchers need to be offset by the window geometry of the client */
312@@ -1854,7 +1869,6 @@
313 XRectangle rects[4];
314 int x, y, width, height;
315 CompWindow::Geometry server = window->serverGeometry ();
316- int bw = server.border () * 2;
317 CompWindowExtents input;
318
319 /* Determine frame extents */
320@@ -1865,8 +1879,8 @@
321
322 x = window->input ().left - input.left;
323 y = window->input ().top - input.top;
324- width = server.width () + input.left + input.right + bw;
325- height = server.height ()+ input.top + input.bottom + bw;
326+ width = server.widthIncBorders () + input.left + input.right;
327+ height = server.heightIncBorders ()+ input.top + input.bottom;
328
329 if (window->shaded ())
330 height = input.top + input.bottom;
331@@ -2097,8 +2111,8 @@
332 {
333 int x, y;
334
335- x = window->geometry (). x ();
336- y = window->geometry (). y ();
337+ x = window->serverGeometry (). x ();
338+ y = window->serverGeometry (). y ();
339
340 region += frameRegion.translated (x - wd->decor->input.left,
341 y - wd->decor->input.top);
342@@ -2108,7 +2122,9 @@
343 region += infiniteRegion;
344 }
345 }
346+
347 updateReg = true;
348+ updateMatrix = true;
349 }
350
351 /*
352@@ -2119,7 +2135,7 @@
353 void
354 DecorWindow::updateWindowRegions ()
355 {
356- const CompRect &input (window->inputRect ());
357+ const CompRect &input (window->serverInputRect ());
358
359 if (regions.size () != gWindow->textures ().size ())
360 regions.resize (gWindow->textures ().size ());
361@@ -2130,6 +2146,7 @@
362 regions[i].translate (input.x (), input.y ());
363 regions[i] &= window->frameRegion ();
364 }
365+
366 updateReg = false;
367 }
368
369@@ -2368,7 +2385,13 @@
370 if (w)
371 {
372 DECOR_WINDOW (w);
373- dw->updateDecoration ();
374+
375+ if (dw->wd && dw->wd->decor)
376+ {
377+ if ((dw->wd->decor->minWidth < w->serverGeometry ().width () ||
378+ dw->wd->decor->minHeight < w->serverGeometry ().height ()))
379+ dw->updateDecoration ();
380+ }
381
382 dw->update (true);
383 }
384@@ -2703,10 +2726,10 @@
385 wd->quad[i].box.x2 += dx;
386 wd->quad[i].box.y2 += dy;
387 }
388-
389- setDecorationMatrices ();
390 }
391+
392 updateReg = true;
393+ updateMatrix = true;
394
395 mInputRegion.translate (dx, dy);
396 mOutputRegion.translate (dx, dy);
397@@ -2717,30 +2740,18 @@
398 window->moveNotify (dx, dy, immediate);
399 }
400
401-/*
402- * DecorWindow::resizeTimeout
403- *
404- * Called from the timeout on ::resizeNotify,
405- * set the shading and unshading bits and also
406- * updates the decoration. See the comment
407- * in ::resizeNotify as to why the timeout
408- * is necessary here
409- *
410- */
411-bool
412-DecorWindow::resizeTimeout ()
413-{
414- if (shading || unshading)
415- {
416- shading = false;
417- unshading = false;
418-
419- updateDecoration ();
420- }
421-
422- if (!window->hasUnmapReference ())
423- update (true);
424- return false;
425+void
426+DecorWindow::grabNotify (int x, int y, unsigned int state, unsigned int mask)
427+{
428+ window->grabNotify (x, y, state, mask);
429+}
430+
431+void
432+DecorWindow::ungrabNotify ()
433+{
434+ update (true);
435+
436+ window->ungrabNotify ();
437 }
438
439 /*
440@@ -2754,6 +2765,11 @@
441 void
442 DecorWindow::resizeNotify (int dx, int dy, int dwidth, int dheight)
443 {
444+ if (shading || unshading)
445+ {
446+ shading = false;
447+ unshading = false;
448+ }
449 /* FIXME: we should not need a timer for calling decorWindowUpdate,
450 and only call updateWindowDecorationScale if decorWindowUpdate
451 returns false. Unfortunately, decorWindowUpdate may call
452@@ -2761,8 +2777,7 @@
453 we never should call a wrapped function that's currently
454 processed, we need the timer for the moment. updateWindowOutputExtents
455 should be fixed so that it does not emit a resize notification. */
456- resizeUpdate.start (boost::bind (&DecorWindow::resizeTimeout, this), 0);
457- updateDecorationScale ();
458+ updateMatrix = true;
459 updateReg = true;
460
461 mInputRegion = CompRegion (window->inputRect ());
462@@ -2770,7 +2785,12 @@
463 if (dScreen->cmActive && mClipGroup)
464 updateGroupShadows ();
465
466+ updateReg = true;
467+
468 window->resizeNotify (dx, dy, dwidth, dheight);
469+
470+ /* FIXME: remove */
471+ CompositeScreen::get (screen)->damageScreen ();
472 }
473
474
475@@ -3008,6 +3028,7 @@
476 pixmapFailed (false),
477 regions (),
478 updateReg (true),
479+ updateMatrix (true),
480 unshading (false),
481 shading (false),
482 isSwitcher (false),
483
484=== modified file 'plugins/decor/src/decor.h'
485--- plugins/decor/src/decor.h 2012-03-30 14:29:18 +0000
486+++ plugins/decor/src/decor.h 2012-04-18 12:32:31 +0000
487@@ -159,7 +159,7 @@
488
489 class WindowDecoration {
490 public:
491- static WindowDecoration * create (const Decoration::Ptr &);
492+ static WindowDecoration * create (const Decoration::Ptr &d);
493 static void destroy (WindowDecoration *);
494
495 public:
496@@ -245,13 +245,13 @@
497 void getOutputExtents (CompWindowExtents&);
498 void resizeNotify (int, int, int, int);
499 void moveNotify (int, int, bool);
500+ void grabNotify (int x, int y, unsigned int state, unsigned int mask);
501+ void ungrabNotify ();
502 void stateChangeNotify (unsigned int);
503 void updateFrameRegion (CompRegion &region);
504
505 bool damageRect (bool, const CompRect &);
506
507- void computeShadowRegion ();
508-
509 bool glDraw (const GLMatrix &, GLFragment::Attrib &,
510 const CompRegion &, unsigned int);
511 void glDecorate (const GLMatrix &, GLFragment::Attrib &,
512@@ -322,6 +322,7 @@
513
514 CompRegion::Vector regions;
515 bool updateReg;
516+ bool updateMatrix;
517
518 CompTimer resizeUpdate;
519 CompTimer moveUpdate;
520
521=== modified file 'plugins/move/src/move.cpp'
522--- plugins/move/src/move.cpp 2012-02-16 05:31:28 +0000
523+++ plugins/move/src/move.cpp 2012-04-18 12:32:31 +0000
524@@ -138,8 +138,8 @@
525 {
526 int xRoot, yRoot;
527
528- xRoot = w->geometry ().x () + (w->size ().width () / 2);
529- yRoot = w->geometry ().y () + (w->size ().height () / 2);
530+ xRoot = w->serverGeometry ().x () + (w->size ().width () / 2);
531+ yRoot = w->serverGeometry ().y () + (w->size ().height () / 2);
532
533 s->warpPointer (xRoot - pointerX, yRoot - pointerY);
534 }
535@@ -169,8 +169,8 @@
536 if (ms->w)
537 {
538 if (state & CompAction::StateCancel)
539- ms->w->move (ms->savedX - ms->w->geometry ().x (),
540- ms->savedY - ms->w->geometry ().y (), false);
541+ ms->w->move (ms->savedX - ms->w->serverGeometry ().x (),
542+ ms->savedY - ms->w->serverGeometry ().y (), false);
543
544 ms->w->syncPosition ();
545
546@@ -314,12 +314,10 @@
547
548 w = ms->w;
549
550- wX = w->geometry ().x ();
551- wY = w->geometry ().y ();
552- wWidth = w->geometry ().width () +
553- w->geometry ().border () * 2;
554- wHeight = w->geometry ().height () +
555- w->geometry ().border () * 2;
556+ wX = w->serverGeometry ().x ();
557+ wY = w->serverGeometry ().y ();
558+ wWidth = w->serverGeometry ().widthIncBorders ();
559+ wHeight = w->serverGeometry ().heightIncBorders ();
560
561 ms->x += xRoot - lastPointerX;
562 ms->y += yRoot - lastPointerY;
563@@ -484,8 +482,8 @@
564
565 if (dx || dy)
566 {
567- w->move (wX + dx - w->geometry ().x (),
568- wY + dy - w->geometry ().y (), false);
569+ w->move (wX + dx - w->serverGeometry ().x (),
570+ wY + dy - w->serverGeometry ().y (), false);
571
572 if (!ms->optionGetLazyPositioning ())
573 w->syncPosition ();
574
575=== modified file 'plugins/opengl/src/paint.cpp'
576--- plugins/opengl/src/paint.cpp 2012-03-19 09:19:04 +0000
577+++ plugins/opengl/src/paint.cpp 2012-04-18 12:32:31 +0000
578@@ -1194,7 +1194,7 @@
579 !priv->cWindow->damaged ())
580 return true;
581
582- if (priv->textures.empty () && !bind ())
583+ if (textures ().empty () && !bind ())
584 return false;
585
586 if (mask & PAINT_WINDOW_TRANSLUCENT_MASK)
587@@ -1210,26 +1210,19 @@
588 //
589 priv->gScreen->setTexEnvMode (GL_REPLACE);
590
591- if (priv->textures.size () == 1)
592+ if (priv->updateState & PrivateGLWindow::UpdateMatrix)
593+ priv->setWindowMatrix ();
594+
595+ if (priv->updateState & PrivateGLWindow::UpdateRegion)
596+ priv->updateWindowRegions ();
597+
598+ for (unsigned int i = 0; i < textures ().size (); i++)
599 {
600- ml[0] = priv->matrices[0];
601+ ml[0] = priv->matrices[i];
602 priv->geometry.reset ();
603- glAddGeometry (ml, priv->window->region (), reg);
604+ glAddGeometry (ml, priv->regions[i], reg);
605 if (priv->geometry.vCount)
606- glDrawTexture (priv->textures[0], fragment, mask);
607- }
608- else
609- {
610- if (priv->updateReg)
611- priv->updateWindowRegions ();
612- for (unsigned int i = 0; i < priv->textures.size (); i++)
613- {
614- ml[0] = priv->matrices[i];
615- priv->geometry.reset ();
616- glAddGeometry (ml, priv->regions[i], reg);
617- if (priv->geometry.vCount)
618- glDrawTexture (priv->textures[i], fragment, mask);
619- }
620+ glDrawTexture (textures ()[i], fragment, mask);
621 }
622
623 return true;
624
625=== modified file 'plugins/opengl/src/privates.h'
626--- plugins/opengl/src/privates.h 2012-02-08 10:54:35 +0000
627+++ plugins/opengl/src/privates.h 2012-04-18 12:32:31 +0000
628@@ -134,6 +134,11 @@
629 public CompositeWindowInterface
630 {
631 public:
632+
633+ static const unsigned int UpdateRegion = 1 << 0;
634+ static const unsigned int UpdateMatrix = 1 << 1;
635+
636+ public:
637 PrivateGLWindow (CompWindow *w, GLWindow *gw);
638 ~PrivateGLWindow ();
639
640@@ -153,7 +158,8 @@
641 GLTexture::List textures;
642 GLTexture::MatrixList matrices;
643 CompRegion::Vector regions;
644- bool updateReg;
645+ unsigned int updateState;
646+ bool needsRebind;
647
648 CompRegion clip;
649
650
651=== modified file 'plugins/opengl/src/window.cpp'
652--- plugins/opengl/src/window.cpp 2012-03-22 17:00:51 +0000
653+++ plugins/opengl/src/window.cpp 2012-04-18 12:32:31 +0000
654@@ -54,7 +54,8 @@
655 gScreen (GLScreen::get (screen)),
656 textures (),
657 regions (),
658- updateReg (true),
659+ updateState (UpdateRegion | UpdateMatrix),
660+ needsRebind (true),
661 clip (),
662 bindFailed (false),
663 geometry (),
664@@ -87,28 +88,41 @@
665 matrices[i].x0 -= (input.x () * matrices[i].xx);
666 matrices[i].y0 -= (input.y () * matrices[i].yy);
667 }
668+
669+ updateState &= ~(UpdateMatrix);
670 }
671
672 bool
673 GLWindow::bind ()
674 {
675 if ((!priv->cWindow->pixmap () && !priv->cWindow->bind ()))
676- return false;
677+ {
678+ if (!priv->textures.empty ())
679+ {
680+ /* Getting a new pixmap failed, recycle the old texture */
681+ priv->needsRebind = false;
682+ return true;
683+ }
684+ }
685
686- priv->textures =
687+ GLTexture::List textures =
688 GLTexture::bindPixmapToTexture (priv->cWindow->pixmap (),
689 priv->cWindow->size ().width (),
690 priv->cWindow->size ().height (),
691 priv->window->depth ());
692- if (priv->textures.empty ())
693+ if (textures.empty ())
694 {
695 compLogMessage ("opengl", CompLogLevelInfo,
696 "Couldn't bind redirected window 0x%x to "
697 "texture\n", (int) priv->window->id ());
698 }
699+ else
700+ {
701+ priv->textures = textures;
702+ priv->needsRebind = false;
703+ }
704
705- priv->setWindowMatrix ();
706- priv->updateReg = true;
707+ priv->updateState |= PrivateGLWindow::UpdateRegion | PrivateGLWindow::UpdateMatrix;
708
709 return true;
710 }
711@@ -116,12 +130,12 @@
712 void
713 GLWindow::release ()
714 {
715- priv->textures.clear ();
716-
717+ /* Release the pixmap but don't release
718+ * the texture (yet) */
719 if (priv->cWindow->pixmap ())
720- {
721 priv->cWindow->release ();
722- }
723+
724+ priv->needsRebind = true;
725 }
726
727 bool
728@@ -180,8 +194,7 @@
729 PrivateGLWindow::resizeNotify (int dx, int dy, int dwidth, int dheight)
730 {
731 window->resizeNotify (dx, dy, dwidth, dheight);
732- setWindowMatrix ();
733- updateReg = true;
734+ updateState |= PrivateGLWindow::UpdateMatrix | PrivateGLWindow::UpdateRegion;
735 if (!window->hasUnmapReference ())
736 gWindow->release ();
737 }
738@@ -190,8 +203,10 @@
739 PrivateGLWindow::moveNotify (int dx, int dy, bool now)
740 {
741 window->moveNotify (dx, dy, now);
742- updateReg = true;
743- setWindowMatrix ();
744+ updateState |= PrivateGLWindow::UpdateMatrix;
745+
746+ foreach (CompRegion &r, regions)
747+ r.translate (dx, dy);
748 }
749
750 void
751@@ -298,6 +313,13 @@
752 const GLTexture::List &
753 GLWindow::textures () const
754 {
755+ static const GLTexture::List emptyList;
756+
757+ /* No pixmap backs this window, let
758+ * users know that the window needs rebinding */
759+ if (priv->needsRebind)
760+ return emptyList;
761+
762 return priv->textures;
763 }
764
765@@ -338,13 +360,13 @@
766 PrivateGLWindow::updateFrameRegion (CompRegion &region)
767 {
768 window->updateFrameRegion (region);
769- updateReg = true;
770+ updateState |= PrivateGLWindow::UpdateRegion;
771 }
772
773 void
774 PrivateGLWindow::updateWindowRegions ()
775 {
776- CompRect input (window->inputRect ());
777+ CompRect input (window->serverInputRect ());
778
779 if (regions.size () != textures.size ())
780 regions.resize (textures.size ());
781@@ -354,7 +376,7 @@
782 regions[i].translate (input.x (), input.y ());
783 regions[i] &= window->region ();
784 }
785- updateReg = false;
786+ updateState &= ~(UpdateRegion);
787 }
788
789 unsigned int
790
791=== modified file 'plugins/place/src/constrain-to-workarea/src/constrain-to-workarea.cpp'
792--- plugins/place/src/constrain-to-workarea/src/constrain-to-workarea.cpp 2012-01-20 06:13:07 +0000
793+++ plugins/place/src/constrain-to-workarea/src/constrain-to-workarea.cpp 2012-04-18 12:32:31 +0000
794@@ -61,13 +61,11 @@
795 }
796
797 left = x - border.left;
798- right = left + g.width () + (border.left +
799- border.right +
800- 2 * g.border ());
801+ right = left + g.widthIncBorders () + (border.left +
802+ border.right);
803 top = y - border.top;
804- bottom = top + g.height () + (border.top +
805- border.bottom +
806- 2 * g.border ());
807+ bottom = top + g.heightIncBorders () + (border.top +
808+ border.bottom);
809
810 if ((right - left) > workArea.width ())
811 {
812
813=== modified file 'plugins/place/src/place.cpp'
814--- plugins/place/src/place.cpp 2012-02-02 17:01:15 +0000
815+++ plugins/place/src/place.cpp 2012-04-18 12:32:31 +0000
816@@ -343,37 +343,36 @@
817 CompWindow::Geometry geom;
818 int output;
819
820+ geom.set (xwc->x, xwc->y, xwc->width, xwc->height,
821+ window->serverGeometry ().border ());
822+
823 if (clampToViewport)
824 {
825 /* left, right, top, bottom target coordinates, clamed to viewport
826 * sizes as we don't need to validate movements to other viewports;
827 * we are only interested in inner-viewport movements */
828
829- x = xwc->x % screen->width ();
830- if ((x + xwc->width) < 0)
831+ x = geom.x () % screen->width ();
832+ if ((geom.x2 ()) < 0)
833 x += screen->width ();
834
835- y = xwc->y % screen->height ();
836- if ((y + xwc->height) < 0)
837+ y = geom.y () % screen->height ();
838+ if ((geom.y2 ()) < 0)
839 y += screen->height ();
840 }
841 else
842 {
843- x = xwc->x;
844- y = xwc->y;
845+ x = geom.x ();
846+ y = geom.y ();
847 }
848
849 left = x - window->border ().left;
850- right = left + xwc->width + (window->border ().left +
851- window->border ().right +
852- 2 * window->serverGeometry ().border ());
853+ right = left + geom.widthIncBorders () + (window->border ().left +
854+ window->border ().right);
855 top = y - window->border ().top;
856- bottom = top + xwc->height + (window->border ().top +
857- window->border ().bottom +
858- 2 * window->serverGeometry ().border ());
859+ bottom = top + geom.heightIncBorders () + (window->border ().top +
860+ window->border ().bottom);
861
862- geom.set (xwc->x, xwc->y, xwc->width, xwc->height,
863- window->serverGeometry ().border ());
864 output = screen->outputDeviceForGeometry (geom);
865 workArea = screen->getWorkareaForOutput (output);
866
867@@ -746,10 +745,8 @@
868 {
869 if (PlaceScreen::get (screen)->getPointerPosition (pos))
870 {
871- unsigned int dx = (window->serverGeometry ().width () / 2) -
872- window->serverGeometry ().border ();
873- unsigned int dy = (window->serverGeometry ().height () / 2) -
874- window->serverGeometry ().border ();
875+ unsigned int dx = (window->serverGeometry ().widthIncBorders () / 2);
876+ unsigned int dy = (window->serverGeometry ().heightIncBorders () / 2);
877 pos -= CompPoint (dx, dy);
878 }
879 else
880@@ -1200,14 +1197,12 @@
881
882 extents.left = pos.x () - window->border ().left;
883 extents.top = pos.y () - window->border ().top;
884- extents.right = extents.left + window->serverWidth () +
885+ extents.right = extents.left + window->serverGeometry ().heightIncBorders () +
886 (window->border ().left +
887- window->border ().right +
888- 2 * window->serverGeometry ().border ());
889- extents.bottom = extents.top + window->serverHeight () +
890+ window->border ().right);
891+ extents.bottom = extents.top + window->serverGeometry ().widthIncBorders () +
892 (window->border ().top +
893- window->border ().bottom +
894- 2 * window->serverGeometry ().border ());
895+ window->border ().bottom);
896
897 delta = workArea.right () - extents.right;
898 if (delta < 0)
899
900=== modified file 'plugins/resize/src/resize.cpp'
901--- plugins/resize/src/resize.cpp 2012-02-16 05:31:28 +0000
902+++ plugins/resize/src/resize.cpp 2012-04-18 12:32:31 +0000
903@@ -56,7 +56,7 @@
904 void
905 ResizeWindow::getStretchScale (BoxPtr pBox, float *xScale, float *yScale)
906 {
907- CompRect rect (window->borderRect ());
908+ CompRect rect (window->serverBorderRect ());
909
910 *xScale = (rect.width ()) ? (pBox->x2 - pBox->x1) /
911 (float) rect.width () : 1.0f;
912@@ -642,8 +642,7 @@
913 w->configureXWindow (mask, &xwc);
914 }
915
916- if (!(mask & (CWWidth | CWHeight)))
917- rs->finishResizing ();
918+ rs->finishResizing ();
919
920 if (rs->grabIndex)
921 {
922@@ -1467,10 +1466,10 @@
923 getPaintRectangle (&box);
924 damageRectangle (&box);
925
926- box.x1 = w->outputRect ().x ();
927- box.y1 = w->outputRect ().y ();
928- box.x2 = box.x1 + w->outputRect ().width ();
929- box.y2 = box.y1 + w->outputRect ().height ();
930+ box.x1 = w->serverOutputRect ().x ();
931+ box.y1 = w->serverOutputRect ().y ();
932+ box.x2 = box.x1 + w->serverOutputRect ().width ();
933+ box.y2 = box.y1 + w->serverOutputRect ().height ();
934
935 damageRectangle (&box);
936 }
937@@ -1510,15 +1509,6 @@
938 }
939
940 void
941-ResizeWindow::resizeNotify (int dx, int dy, int dwidth, int dheight)
942-{
943- window->resizeNotify (dx, dy, dwidth, dheight);
944-
945- if (rScreen->w == window && !rScreen->grabIndex)
946- rScreen->finishResizing ();
947-}
948-
949-void
950 ResizeScreen::glPaintRectangle (const GLScreenPaintAttrib &sAttrib,
951 const GLMatrix &transform,
952 CompOutput *output,
953@@ -1649,8 +1639,8 @@
954 rScreen->getPaintRectangle (&box);
955 getStretchScale (&box, &xScale, &yScale);
956
957- x = window->geometry (). x ();
958- y = window->geometry (). y ();
959+ x = window->serverGeometry (). x ();
960+ y = window->serverGeometry (). y ();
961
962 xOrigin = x - window->border ().left;
963 yOrigin = y - window->border ().top;
964
965=== modified file 'plugins/resize/src/resize.h'
966--- plugins/resize/src/resize.h 2012-02-09 07:48:57 +0000
967+++ plugins/resize/src/resize.h 2012-04-18 12:32:31 +0000
968@@ -162,8 +162,6 @@
969 ResizeWindow (CompWindow *w);
970 ~ResizeWindow ();
971
972- void resizeNotify (int, int, int, int);
973-
974 bool damageRect (bool, const CompRect &);
975
976 bool glPaint (const GLWindowPaintAttrib &, const GLMatrix &,
977
978=== modified file 'plugins/wobbly/src/wobbly.cpp'
979--- plugins/wobbly/src/wobbly.cpp 2011-03-14 16:12:45 +0000
980+++ plugins/wobbly/src/wobbly.cpp 2012-04-18 12:32:31 +0000
981@@ -71,9 +71,9 @@
982 }
983 else if (!p->invisible () && (p->type () & SNAP_WINDOW_TYPE))
984 {
985- s = p->geometry ().y () - p->border ().top -
986+ s = p->serverGeometry ().y () - p->border ().top -
987 window->output ().top;
988- e = p->geometry ().y () + p->height () + p->border ().bottom +
989+ e = p->serverGeometry ().y () + p->height () + p->border ().bottom +
990 window->output ().bottom;
991 }
992 else
993@@ -102,7 +102,7 @@
994 if (p->mapNum () && p->struts ())
995 v = p->struts ()->left.x + p->struts ()->left.width;
996 else
997- v = p->geometry ().x () + p->width () +
998+ v = p->serverGeometry ().x () + p->width () +
999 p->border ().right;
1000
1001 if (v <= x)
1002@@ -179,9 +179,9 @@
1003 }
1004 else if (!p->invisible () && (p->type () & SNAP_WINDOW_TYPE))
1005 {
1006- s = p->geometry ().y () - p->border ().top -
1007+ s = p->serverGeometry ().y () - p->border ().top -
1008 window->output ().top;
1009- e = p->geometry ().y () + p->height () + p->border ().bottom +
1010+ e = p->serverGeometry ().y () + p->height () + p->border ().bottom +
1011 window->output ().bottom;
1012 }
1013 else
1014@@ -210,7 +210,7 @@
1015 if (p->mapNum () && p->struts ())
1016 v = p->struts ()->right.x;
1017 else
1018- v = p->geometry ().x () - p->border ().left;
1019+ v = p->serverGeometry ().x () - p->border ().left;
1020
1021 if (v >= x)
1022 {
1023@@ -286,9 +286,9 @@
1024 }
1025 else if (!p->invisible () && (p->type () & SNAP_WINDOW_TYPE))
1026 {
1027- s = p->geometry ().x () - p->border ().left -
1028+ s = p->serverGeometry ().x () - p->border ().left -
1029 window->output ().left;
1030- e = p->geometry ().x () + p->width () + p->border ().right +
1031+ e = p->serverGeometry ().x () + p->width () + p->border ().right +
1032 window->output ().right;
1033 }
1034 else
1035@@ -317,7 +317,7 @@
1036 if (p->mapNum () && p->struts ())
1037 v = p->struts ()->top.y + p->struts ()->top.height;
1038 else
1039- v = p->geometry ().y () + p->height () + p->border ().bottom;
1040+ v = p->serverGeometry ().y () + p->height () + p->border ().bottom;
1041
1042 if (v <= y)
1043 {
1044@@ -393,9 +393,9 @@
1045 }
1046 else if (!p->invisible () && (p->type () & SNAP_WINDOW_TYPE))
1047 {
1048- s = p->geometry ().x () - p->border ().left -
1049+ s = p->serverGeometry ().x () - p->border ().left -
1050 window->output ().left;
1051- e = p->geometry ().x () + p->width () + p->border ().right +
1052+ e = p->serverGeometry ().x () + p->width () + p->border ().right +
1053 window->output ().right;
1054 }
1055 else
1056@@ -424,7 +424,7 @@
1057 if (p->mapNum () && p->struts ())
1058 v = p->struts ()->bottom.y;
1059 else
1060- v = p->geometry ().y () - p->border ().top;
1061+ v = p->serverGeometry ().y () - p->border ().top;
1062
1063 if (v >= y)
1064 {
1065@@ -1251,7 +1251,7 @@
1066 if (!model)
1067 {
1068 unsigned int edgeMask = 0;
1069- CompRect outRect (window->outputRect ());
1070+ CompRect outRect (window->serverOutputRect ());
1071
1072 if (window->type () & CompWindowTypeNormalMask)
1073 edgeMask = WestEdgeMask | EastEdgeMask | NorthEdgeMask |
1074@@ -1311,7 +1311,7 @@
1075 if (window->width () == 1 && window->height () == 1)
1076 return false;
1077
1078- CompWindow::Geometry &geom = window->geometry ();
1079+ CompWindow::Geometry &geom = window->serverGeometry ();
1080
1081 /* avoid fullscreen windows */
1082 if (geom.x () <= 0 &&
1083@@ -1406,23 +1406,16 @@
1084 }
1085 }
1086 }
1087- else
1088+ else if (ww->dropGeometry == w->serverGeometry ())
1089 {
1090 ww->model = 0;
1091
1092- if (w->geometry ().x () == w->serverX () &&
1093- w->geometry ().y () == w->serverY ())
1094- {
1095- w->move (model->topLeft.x +
1096- w->output ().left -
1097- w->geometry ().x (),
1098- model->topLeft.y +
1099- w->output ().top -
1100- w->geometry ().y (),
1101- true);
1102- w->syncPosition ();
1103- }
1104-
1105+ XWindowChanges xwc;
1106+
1107+ xwc.x = model->topLeft.x + w->output ().left;
1108+ xwc.y = model->topLeft.y + w->output ().top;
1109+
1110+ w->configureXWindow (CWX | CWY, &xwc);
1111 ww->model = model;
1112 }
1113
1114@@ -1448,9 +1441,9 @@
1115 else
1116 cw->addDamage ();
1117
1118- int wx = w->geometry ().x ();
1119- int wy = w->geometry ().y ();
1120- int borderWidth = w->geometry ().border ();
1121+ int wx = w->serverGeometry ().x ();
1122+ int wy = w->serverGeometry ().y ();
1123+ int borderWidth = w->serverGeometry ().border ();
1124
1125 // Damage a box that's 1-pixel larger on each side
1126 // to prevent artifacts
1127@@ -1578,7 +1571,7 @@
1128 }
1129 }
1130
1131- CompRect outRect (window->outputRect ());
1132+ CompRect outRect (window->serverOutputRect ());
1133 wx = outRect.x ();
1134 wy = outRect.y ();
1135 width = outRect.width ();
1136@@ -1772,7 +1765,7 @@
1137
1138 if (ww->isWobblyWin () && ww->ensureModel ())
1139 {
1140- CompRect outRect (w->outputRect ());
1141+ CompRect outRect (w->serverOutputRect ());
1142
1143 ww->model->setMiddleAnchor (outRect.x (), outRect.y (),
1144 outRect.width (), outRect.height ());
1145@@ -1901,7 +1894,7 @@
1146 switch (focusEffect) {
1147 case WobblyOptions::FocusEffectShiver:
1148 {
1149- CompRect outRect (w->outputRect ());
1150+ CompRect outRect (w->serverOutputRect ());
1151
1152 ww->model->adjustObjectsForShiver (outRect.x (),
1153 outRect.y (),
1154@@ -1977,7 +1970,7 @@
1155 wScreen->optionGetMapWindowMatch ().evaluate (window) &&
1156 ensureModel ())
1157 {
1158- CompRect outRect (window->outputRect ());
1159+ CompRect outRect (window->serverOutputRect ());
1160
1161 model->initObjects (outRect.x (), outRect.y (),
1162 outRect.width (), outRect.height ());
1163@@ -2006,7 +1999,7 @@
1164 int dwidth,
1165 int dheight)
1166 {
1167- CompRect outRect (window->outputRect ());
1168+ CompRect outRect (window->serverOutputRect ());
1169
1170 if (wScreen->optionGetMaximizeEffect () &&
1171 isWobblyWin () &&
1172@@ -2128,10 +2121,12 @@
1173 {
1174 wScreen->grabMask = mask;
1175 wScreen->grabWindow = window;
1176+ dropGeometry = CompWindow::Geometry (0, 0, 0, 0, 0);
1177 }
1178 wScreen->moveWindow = false;
1179
1180- if ((mask & CompWindowGrabButtonMask) &&
1181+ if (mask & (CompWindowGrabButtonMask) &&
1182+ mask & (CompWindowGrabMoveMask) &&
1183 wScreen->optionGetMoveWindowMatch ().evaluate (window) &&
1184 isWobblyWin ())
1185 {
1186@@ -2144,7 +2139,7 @@
1187
1188 if (wScreen->optionGetMaximizeEffect ())
1189 {
1190- CompRect outRect (window->outputRect ());
1191+ CompRect outRect (window->serverOutputRect ());
1192
1193 if (window->state () & MAXIMIZE_STATE)
1194 {
1195@@ -2192,7 +2187,7 @@
1196 if (wScreen->yConstrained)
1197 {
1198 int output =
1199- ::screen->outputDeviceForGeometry (window->geometry ());
1200+ ::screen->outputDeviceForGeometry (window->serverGeometry ());
1201 wScreen->constraintBox =
1202 &::screen->outputDevs ()[output].workArea ();
1203 }
1204@@ -2252,7 +2247,7 @@
1205 if (wScreen->optionGetMaximizeEffect () &&
1206 (state & MAXIMIZE_STATE))
1207 {
1208- CompRect outRect (window->outputRect ());
1209+ CompRect outRect (window->serverOutputRect ());
1210
1211 model->addEdgeAnchors (outRect.x (), outRect.y (),
1212 outRect.width (), outRect.height ());
1213@@ -2262,6 +2257,8 @@
1214 }
1215
1216 grabbed = false;
1217+
1218+ dropGeometry = window->serverGeometry ();
1219 }
1220
1221 window->ungrabNotify ();
1222
1223=== modified file 'plugins/wobbly/src/wobbly.h'
1224--- plugins/wobbly/src/wobbly.h 2009-12-25 19:50:25 +0000
1225+++ plugins/wobbly/src/wobbly.h 2012-04-18 12:32:31 +0000
1226@@ -300,6 +300,8 @@
1227 bool grabbed;
1228 bool velocity;
1229 unsigned int state;
1230+
1231+ CompWindow::Geometry dropGeometry;
1232 };
1233
1234 class WobblyPluginVTable :
1235
1236=== modified file 'src/actions.cpp'
1237--- src/actions.cpp 2012-01-31 14:52:20 +0000
1238+++ src/actions.cpp 2012-04-18 12:32:31 +0000
1239@@ -201,9 +201,9 @@
1240 time = CompOption::getIntOptionNamed (options, "time", CurrentTime);
1241 button = CompOption::getIntOptionNamed (options, "button", 0);
1242 x = CompOption::getIntOptionNamed (options, "x",
1243- w->geometry ().x ());
1244+ w->serverGeometry ().x ());
1245 y = CompOption::getIntOptionNamed (options, "y",
1246- w->geometry ().y ());
1247+ w->serverGeometry ().y ());
1248
1249 screen->toolkitAction (Atoms::toolkitActionWindowMenu,
1250 time, w->id (), button, x, y);
1251
1252=== modified file 'src/event.cpp'
1253--- src/event.cpp 2012-04-04 03:11:55 +0000
1254+++ src/event.cpp 2012-04-18 12:32:31 +0000
1255@@ -1251,7 +1251,7 @@
1256 }
1257
1258 /* been shaded */
1259- if (w->priv->height == 0)
1260+ if (w->shaded ())
1261 {
1262 if (w->id () == priv->activeWindow)
1263 w->moveInputFocusTo ();
1264
1265=== modified file 'src/privatewindow.h'
1266--- src/privatewindow.h 2012-03-02 18:02:07 +0000
1267+++ src/privatewindow.h 2012-04-18 12:32:31 +0000
1268@@ -34,7 +34,6 @@
1269 #include <core/timer.h>
1270 #include "privatescreen.h"
1271
1272-
1273 typedef CompWindowExtents CompFullscreenMonitorSet;
1274
1275 class PrivateWindow {
1276@@ -167,6 +166,11 @@
1277
1278 bool handleSyncAlarm ();
1279
1280+ void move (int dx, int dy, bool sync);
1281+ bool resize (int dx, int dy, int dwidth, int dheight, int dborder);
1282+ bool resize (const CompWindow::Geometry &g);
1283+ bool resize (const XWindowAttributes &attrib);
1284+
1285 void configure (XConfigureEvent *ce);
1286
1287 void configureFrame (XConfigureEvent *ce);
1288@@ -241,13 +245,8 @@
1289 XSizeHints sizeHints;
1290 XWMHints *hints;
1291
1292- struct timeval lastGeometryUpdate;
1293- struct timeval lastConfigureRequest;
1294-
1295 bool inputHint;
1296 bool alpha;
1297- int width;
1298- int height;
1299 CompRegion region;
1300 CompRegion inputRegion;
1301 CompRegion frameRegion;
1302@@ -290,8 +289,6 @@
1303 typedef std::pair <XWindowChanges, unsigned int> XWCValueMask;
1304
1305 compiz::X11::PendingEventQueue pendingConfigures;
1306- CompTimer mClearCheckTimeout;
1307- bool pendingPositionUpdates;
1308
1309 char *startupId;
1310 char *resName;
1311@@ -327,6 +324,8 @@
1312
1313 bool closeRequests;
1314 Time lastCloseRequestTime;
1315+
1316+ bool nextMoveImmediate;
1317 };
1318
1319 #endif
1320
1321=== modified file 'src/screen.cpp'
1322--- src/screen.cpp 2012-03-30 06:26:33 +0000
1323+++ src/screen.cpp 2012-04-18 12:32:31 +0000
1324@@ -4060,8 +4060,8 @@
1325 CompRect rect (gm);
1326 int offset;
1327
1328- rect.setWidth (rect.width () + (gm.border () * 2));
1329- rect.setHeight (rect.height () + (gm.border () * 2));
1330+ rect.setWidth (gm.widthIncBorders ());
1331+ rect.setHeight (gm.heightIncBorders ());
1332
1333 offset = rect.centerX () < 0 ? -1 : 0;
1334 viewport.setX (priv->vp.x () + ((rect.centerX () / width ()) + offset) %
1335@@ -4657,6 +4657,8 @@
1336 return false;
1337 }
1338
1339+ /* Use synchronous behaviour when running with --sync, useful
1340+ * for getting stacktraces when X Errors occurr */
1341 XSynchronize (dpy, synchronousX ? True : False);
1342
1343 snprintf (displayString, 255, "DISPLAY=%s",
1344
1345=== modified file 'src/window.cpp'
1346--- src/window.cpp 2012-04-16 09:44:13 +0000
1347+++ src/window.cpp 2012-04-18 12:32:31 +0000
1348@@ -77,8 +77,8 @@
1349 PrivateWindow::isInvisible() const
1350 {
1351 return attrib.map_state != IsViewable ||
1352- attrib.x + width + output.right <= 0 ||
1353- attrib.y + height + output.bottom <= 0 ||
1354+ attrib.x + geometry.width () + output.right <= 0 ||
1355+ attrib.y + geometry.height () + output.bottom <= 0 ||
1356 attrib.x - output.left >= (int) screen->width () ||
1357 attrib.y - output.top >= (int) screen->height ();
1358 }
1359@@ -810,292 +810,14 @@
1360 if (!serverFrame)
1361 return;
1362
1363-
1364- gettimeofday (&lastConfigureRequest, NULL);
1365- /* Flush any changes made to serverFrameGeometry or serverGeometry to the server
1366- * since there is a race condition where geometries will go out-of-sync with
1367- * window movement */
1368-
1369- window->syncPosition ();
1370-
1371- if (serverInput.left || serverInput.right || serverInput.top || serverInput.bottom)
1372- {
1373- int bw = serverGeometry.border () * 2;
1374-
1375- xwc.x = serverGeometry.x () - serverInput.left;
1376- xwc.y = serverGeometry.y () - serverInput.top;
1377- xwc.width = serverGeometry.width () + serverInput.left + serverInput.right + bw;
1378- if (shaded)
1379- xwc.height = serverInput.top + serverInput.bottom + bw;
1380- else
1381- xwc.height = serverGeometry.height () + serverInput.top + serverInput.bottom + bw;
1382-
1383- if (shaded)
1384- height = serverInput.top + serverInput.bottom;
1385-
1386- if (serverFrameGeometry.x () == xwc.x)
1387- valueMask &= ~(CWX);
1388- else
1389- serverFrameGeometry.setX (xwc.x);
1390-
1391- if (serverFrameGeometry.y () == xwc.y)
1392- valueMask &= ~(CWY);
1393- else
1394- serverFrameGeometry.setY (xwc.y);
1395-
1396- if (serverFrameGeometry.width () == xwc.width)
1397- valueMask &= ~(CWWidth);
1398- else
1399- serverFrameGeometry.setWidth (xwc.width);
1400-
1401- if (serverFrameGeometry.height () == xwc.height)
1402- valueMask &= ~(CWHeight);
1403- else
1404- serverFrameGeometry.setHeight (xwc.height);
1405-
1406- /* Geometry is the same, so we're not going to get a ConfigureNotify
1407- * event when the window is configured, which means that other plugins
1408- * won't know that the client, frame and wrapper windows got shifted
1409- * around (and might result in display corruption, eg in OpenGL */
1410- if (valueMask == 0)
1411- {
1412- XConfigureEvent xev;
1413- XWindowAttributes attrib;
1414- unsigned int nchildren = 0;
1415- Window rootRet = 0, parentRet = 0;
1416- Window *children = NULL;
1417-
1418- xev.type = ConfigureNotify;
1419- xev.event = screen->root ();
1420- xev.window = priv->serverFrame;
1421-
1422- XGrabServer (screen->dpy ());
1423-
1424- if (XGetWindowAttributes (screen->dpy (), priv->serverFrame, &attrib))
1425- {
1426- xev.x = attrib.x;
1427- xev.y = attrib.y;
1428- xev.width = attrib.width;
1429- xev.height = attrib.height;
1430- xev.border_width = attrib.border_width;
1431- xev.above = None;
1432-
1433- /* We need to ensure that the stacking order is
1434- * based on the current server stacking order so
1435- * find the sibling to this window's frame in the
1436- * server side stack and stack above that */
1437- XQueryTree (screen->dpy (), screen->root (), &rootRet, &parentRet, &children, &nchildren);
1438-
1439- if (nchildren)
1440- {
1441- for (unsigned int i = 0; i < nchildren; i++)
1442- {
1443- if (i + 1 == nchildren ||
1444- children[i + 1] == ROOTPARENT (window))
1445- {
1446- xev.above = children[i];
1447- break;
1448- }
1449- }
1450- }
1451-
1452- if (children)
1453- XFree (children);
1454-
1455- if (!xev.above)
1456- xev.above = (window->serverPrev) ? ROOTPARENT (window->serverPrev) : None;
1457-
1458- xev.override_redirect = priv->attrib.override_redirect;
1459-
1460- }
1461-
1462- compiz::X11::PendingEvent::Ptr pc =
1463- boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
1464- new compiz::X11::PendingConfigureEvent (
1465- screen->dpy (), serverFrame, valueMask, &xwc)));
1466-
1467- pendingConfigures.add (pc);
1468- if (priv->mClearCheckTimeout.active ())
1469- priv->mClearCheckTimeout.stop ();
1470- priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
1471- 2000, 2500);
1472-
1473- XSendEvent (screen->dpy (), screen->root (), false,
1474- SubstructureNotifyMask, (XEvent *) &xev);
1475-
1476- XUngrabServer (screen->dpy ());
1477- XSync (screen->dpy (), false);
1478- }
1479- else
1480- {
1481- compiz::X11::PendingEvent::Ptr pc =
1482- boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
1483- new compiz::X11::PendingConfigureEvent (
1484- screen->dpy (), serverFrame, valueMask, &xwc)));
1485-
1486- pendingConfigures.add (pc);
1487- if (priv->mClearCheckTimeout.active ())
1488- priv->mClearCheckTimeout.stop ();
1489- priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
1490- 2000, 2500);
1491- XConfigureWindow (screen->dpy (), serverFrame, valueMask, &xwc);
1492- }
1493-
1494- if (shaded)
1495- {
1496- XUnmapWindow (screen->dpy (), wrapper);
1497- }
1498- else
1499- {
1500- XMapWindow (screen->dpy (), wrapper);
1501- XMoveResizeWindow (screen->dpy (), wrapper, serverInput.left, serverInput.top,
1502- serverGeometry.width (), serverGeometry.height ());
1503- }
1504- XMoveResizeWindow (screen->dpy (), id, 0, 0,
1505- serverGeometry.width (), serverGeometry.height ());
1506- window->sendConfigureNotify ();
1507- window->windowNotify (CompWindowNotifyFrameUpdate);
1508- }
1509- else
1510- {
1511- int bw = serverGeometry.border () * 2;
1512-
1513- xwc.x = serverGeometry.x ();
1514- xwc.y = serverGeometry.y ();
1515- xwc.width = serverGeometry.width () + bw;
1516-
1517- /* FIXME: It doesn't make much sense to allow undecorated windows to be
1518- * shaded */
1519- if (shaded)
1520- xwc.height = bw;
1521- else
1522- xwc.height = serverGeometry.height () + bw;
1523-
1524- if (serverFrameGeometry.x () == xwc.x)
1525- valueMask &= ~(CWX);
1526- else
1527- serverFrameGeometry.setX (xwc.x);
1528-
1529- if (serverFrameGeometry.y () == xwc.y)
1530- valueMask &= ~(CWY);
1531- else
1532- serverFrameGeometry.setY (xwc.y);
1533-
1534- if (serverFrameGeometry.width () == xwc.width)
1535- valueMask &= ~(CWWidth);
1536- else
1537- serverFrameGeometry.setWidth (xwc.width);
1538-
1539- if (serverFrameGeometry.height () == xwc.height)
1540- valueMask &= ~(CWHeight);
1541- else
1542- serverFrameGeometry.setHeight (xwc.height);
1543-
1544- /* Geometry is the same, so we're not going to get a ConfigureNotify
1545- * event when the window is configured, which means that other plugins
1546- * won't know that the client, frame and wrapper windows got shifted
1547- * around (and might result in display corruption, eg in OpenGL */
1548- if (valueMask == 0)
1549- {
1550- XConfigureEvent xev;
1551- XWindowAttributes attrib;
1552- unsigned int nchildren = 0;
1553- Window rootRet = 0, parentRet = 0;
1554- Window *children = NULL;
1555-
1556- xev.type = ConfigureNotify;
1557- xev.event = screen->root ();
1558- xev.window = priv->serverFrame;
1559-
1560- XGrabServer (screen->dpy ());
1561-
1562- if (XGetWindowAttributes (screen->dpy (), priv->serverFrame, &attrib))
1563- {
1564- xev.x = attrib.x;
1565- xev.y = attrib.y;
1566- xev.width = attrib.width;
1567- xev.height = attrib.height;
1568- xev.border_width = attrib.border_width;
1569- xev.above = None;
1570-
1571- /* We need to ensure that the stacking order is
1572- * based on the current server stacking order so
1573- * find the sibling to this window's frame in the
1574- * server side stack and stack above that */
1575- XQueryTree (screen->dpy (), screen->root (), &rootRet, &parentRet, &children, &nchildren);
1576-
1577- if (nchildren)
1578- {
1579- for (unsigned int i = 0; i < nchildren; i++)
1580- {
1581- if (i + 1 == nchildren ||
1582- children[i + 1] == ROOTPARENT (window))
1583- {
1584- xev.above = children[i];
1585- break;
1586- }
1587- }
1588- }
1589-
1590- if (children)
1591- XFree (children);
1592-
1593- if (!xev.above)
1594- xev.above = (window->serverPrev) ? ROOTPARENT (window->serverPrev) : None;
1595-
1596- xev.override_redirect = priv->attrib.override_redirect;
1597-
1598- }
1599-
1600- compiz::X11::PendingEvent::Ptr pc =
1601- boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
1602- new compiz::X11::PendingConfigureEvent (
1603- screen->dpy (), serverFrame, valueMask, &xwc)));
1604-
1605- pendingConfigures.add (pc);
1606- if (priv->mClearCheckTimeout.active ())
1607- priv->mClearCheckTimeout.stop ();
1608- priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
1609- 2000, 2500);
1610-
1611- XSendEvent (screen->dpy (), screen->root (), false,
1612- SubstructureNotifyMask, (XEvent *) &xev);
1613-
1614- XUngrabServer (screen->dpy ());
1615- XSync (screen->dpy (), false);
1616- }
1617- else
1618- {
1619- compiz::X11::PendingEvent::Ptr pc =
1620- boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
1621- new compiz::X11::PendingConfigureEvent (
1622- screen->dpy (), serverFrame, valueMask, &xwc)));
1623-
1624- pendingConfigures.add (pc);
1625- if (priv->mClearCheckTimeout.active ())
1626- priv->mClearCheckTimeout.stop ();
1627- priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
1628- 2000, 2500);
1629-
1630- XConfigureWindow (screen->dpy (), serverFrame, valueMask, &xwc);
1631- }
1632-
1633- if (shaded)
1634- {
1635- XUnmapWindow (screen->dpy (), wrapper);
1636- }
1637- else
1638- {
1639- XMapWindow (screen->dpy (), wrapper);
1640- XMoveResizeWindow (screen->dpy (), wrapper, 0, 0,
1641- serverGeometry.width (), serverGeometry.height ());
1642- }
1643-
1644- XMoveResizeWindow (screen->dpy (), id, 0, 0,
1645- serverGeometry.width (), serverGeometry.height ());
1646- window->sendConfigureNotify ();
1647- window->windowNotify (CompWindowNotifyFrameUpdate);
1648- }
1649+ xwc.x = serverGeometry.x ();
1650+ xwc.y = serverGeometry.y ();
1651+ xwc.width = serverGeometry.width ();
1652+ xwc.height = serverGeometry.height ();
1653+ xwc.border_width = serverGeometry.border ();
1654+
1655+ window->configureXWindow (valueMask, &xwc);
1656+ window->windowNotify (CompWindowNotifyFrameUpdate);
1657 window->recalcActions ();
1658 }
1659
1660@@ -1135,11 +857,12 @@
1661 {
1662 CompRegion ret;
1663 int x1, x2, y1, y2;
1664+ const CompWindow::Geometry &geom = attrib.override_redirect ? priv->geometry : priv->serverGeometry;
1665
1666 for (unsigned int i = 0; i < n; i++)
1667 {
1668- x1 = rects[i].x + priv->geometry.border ();
1669- y1 = rects[i].y + priv->geometry.border ();
1670+ x1 = rects[i].x + geom.border ();
1671+ y1 = rects[i].y + geom.border ();
1672 x2 = x1 + rects[i].width;
1673 y2 = y1 + rects[i].height;
1674
1675@@ -1147,17 +870,17 @@
1676 x1 = 0;
1677 if (y1 < 0)
1678 y1 = 0;
1679- if (x2 > priv->width)
1680- x2 = priv->width;
1681- if (y2 > priv->height)
1682- y2 = priv->height;
1683+ if (x2 > geom.width ())
1684+ x2 = geom.width ();
1685+ if (y2 > geom.height ())
1686+ y2 = geom.height ();
1687
1688 if (y1 < y2 && x1 < x2)
1689 {
1690- x1 += priv->geometry.x ();
1691- y1 += priv->geometry.y ();
1692- x2 += priv->geometry.x ();
1693- y2 += priv->geometry.y ();
1694+ x1 += geom.x ();
1695+ y1 += geom.y ();
1696+ x2 += geom.x ();
1697+ y2 += geom.y ();
1698
1699 ret += CompRect (x1, y1, x2 - x1, y2 - y1);
1700 }
1701@@ -1177,25 +900,27 @@
1702 XRectangle r, *boundingShapeRects = NULL;
1703 XRectangle *inputShapeRects = NULL;
1704 int nBounding = 0, nInput = 0;
1705+ const CompWindow::Geometry &geom = attrib.override_redirect ? priv->geometry : priv->serverGeometry;
1706
1707- priv->region = CompRegion ();
1708- priv->inputRegion = CompRegion ();
1709+ priv->region = priv->inputRegion = CompRegion ();
1710
1711 if (screen->XShape ())
1712 {
1713 int order;
1714
1715+ /* We should update the server here */
1716+ XSync (screen->dpy (), false);
1717+
1718 boundingShapeRects = XShapeGetRectangles (screen->dpy (), priv->id,
1719 ShapeBounding, &nBounding, &order);
1720 inputShapeRects = XShapeGetRectangles (screen->dpy (), priv->id,
1721 ShapeInput, &nInput, &order);
1722-
1723 }
1724
1725- r.x = -priv->geometry.border ();
1726- r.y = -priv->geometry.border ();
1727- r.width = priv->width + priv->geometry.border ();
1728- r.height = priv->height + priv->geometry.border ();
1729+ r.x = -geom.border ();
1730+ r.y = -geom.border ();
1731+ r.width = geom.widthIncBorders ();
1732+ r.height = geom.heightIncBorders ();
1733
1734 if (nBounding < 1)
1735 {
1736@@ -1661,6 +1386,9 @@
1737 }
1738
1739 windowNotify (CompWindowNotifyMap);
1740+ /* Send a resizeNotify to plugins to indicate
1741+ * that the map is complete */
1742+ resizeNotify (0, 0, 0, 0);
1743 }
1744
1745 void
1746@@ -1729,7 +1457,7 @@
1747 priv->attrib.map_state = IsUnmapped;
1748 priv->invisible = true;
1749
1750- if (priv->shaded && priv->height)
1751+ if (priv->shaded)
1752 {
1753 priv->updateFrameWindow ();
1754 }
1755@@ -1814,7 +1542,7 @@
1756 }
1757
1758 bool
1759-CompWindow::resize (CompWindow::Geometry gm)
1760+PrivateWindow::resize (const CompWindow::Geometry &gm)
1761 {
1762 /* Input extents are now the last thing sent
1763 * from the server. This might not work in some
1764@@ -1831,12 +1559,8 @@
1765 priv->geometry.height () != gm.height () ||
1766 priv->geometry.border () != gm.border ())
1767 {
1768- int pw, ph;
1769 int dx, dy, dwidth, dheight;
1770
1771- pw = gm.width () + gm.border () * 2;
1772- ph = gm.height () + gm.border () * 2;
1773-
1774 dx = gm.x () - priv->geometry.x ();
1775 dy = gm.y () - priv->geometry.y ();
1776 dwidth = gm.width () - priv->geometry.width ();
1777@@ -1846,37 +1570,58 @@
1778 gm.width (), gm.height (),
1779 gm.border ());
1780
1781- priv->width = pw;
1782- priv->height = ph;
1783-
1784- if (priv->mapNum)
1785- priv->updateRegion ();
1786-
1787- resizeNotify (dx, dy, dwidth, dheight);
1788-
1789 priv->invisible = priv->isInvisible ();
1790+
1791+ if (priv->attrib.override_redirect)
1792+ {
1793+ priv->serverGeometry = priv->geometry;
1794+ priv->serverFrameGeometry = priv->frameGeometry;
1795+
1796+ if (priv->mapNum)
1797+ priv->updateRegion ();
1798+
1799+ window->resizeNotify (dx, dy, dwidth, dheight);
1800+ }
1801 }
1802 else if (priv->geometry.x () != gm.x () || priv->geometry.y () != gm.y ())
1803 {
1804- int dx, dy;
1805-
1806- dx = gm.x () - priv->geometry.x ();
1807- dy = gm.y () - priv->geometry.y ();
1808-
1809- priv->geometry.setX (gm.x ());
1810- priv->geometry.setY (gm.y ());
1811-
1812- priv->region.translate (dx, dy);
1813- priv->inputRegion.translate (dx, dy);
1814- if (!priv->frameRegion.isEmpty ())
1815- priv->frameRegion.translate (dx, dy);
1816-
1817- priv->invisible = priv->isInvisible ();
1818-
1819- moveNotify (dx, dy, true);
1820+ move (gm.x () - priv->geometry.x (),
1821+ gm.y () - priv->geometry.y (), true);
1822 }
1823
1824- updateFrameRegion ();
1825+ return true;
1826+}
1827+
1828+bool
1829+PrivateWindow::resize (const XWindowAttributes &attr)
1830+{
1831+ return resize (CompWindow::Geometry (attr.x, attr.y, attr.width, attr.height,
1832+ attr.border_width));
1833+}
1834+
1835+bool
1836+PrivateWindow::resize (int x,
1837+ int y,
1838+ int width,
1839+ int height,
1840+ int border)
1841+{
1842+ return resize (CompWindow::Geometry (x, y, width, height, border));
1843+}
1844+
1845+bool
1846+CompWindow::resize (CompWindow::Geometry gm)
1847+{
1848+ XWindowChanges xwc = XWINDOWCHANGES_INIT;
1849+ unsigned int valueMask = CWX | CWY | CWWidth | CWHeight | CWBorderWidth;
1850+
1851+ xwc.x = gm.x ();
1852+ xwc.y = gm.y ();
1853+ xwc.width = gm.width ();
1854+ xwc.height = gm.height ();
1855+ xwc.border_width = gm.border ();
1856+
1857+ configureXWindow (valueMask, &xwc);
1858
1859 return true;
1860 }
1861@@ -2044,13 +1789,7 @@
1862 ce->border_width);
1863 else
1864 {
1865- if (ce->override_redirect)
1866- {
1867- priv->serverGeometry.set (ce->x, ce->y, ce->width, ce->height,
1868- ce->border_width);
1869- }
1870-
1871- window->resize (ce->x, ce->y, ce->width, ce->height, ce->border_width);
1872+ resize (ce->x, ce->y, ce->width, ce->height, ce->border_width);
1873 }
1874
1875 if (ce->event == screen->root ())
1876@@ -2120,9 +1859,9 @@
1877 * windows since we didn't resize them
1878 * on configureXWindow */
1879 if (priv->shaded)
1880- height = priv->serverGeometry.height () - priv->serverGeometry.border () * 2 - priv->serverInput.top - priv->serverInput.bottom;
1881+ height = priv->serverGeometry.heightIncBorders () - priv->serverInput.top - priv->serverInput.bottom;
1882 else
1883- height = ce->height - priv->serverGeometry.border () * 2 - priv->serverInput.top - priv->serverInput.bottom;
1884+ height = ce->height + priv->serverGeometry.border () * 2 - priv->serverInput.top - priv->serverInput.bottom;
1885
1886 /* set the frame geometry */
1887 priv->frameGeometry.set (ce->x, ce->y, ce->width, ce->height, ce->border_width);
1888@@ -2131,7 +1870,7 @@
1889 if (priv->syncWait)
1890 priv->syncGeometry.set (x, y, width, height, ce->border_width);
1891 else
1892- window->resize (x, y, width, height, ce->border_width);
1893+ resize (x, y, width, height, ce->border_width);
1894
1895 if (priv->restack (ce->above))
1896 priv->updatePassiveButtonGrabs ();
1897@@ -2140,27 +1879,6 @@
1898
1899 if (above)
1900 above->priv->updatePassiveButtonGrabs ();
1901-
1902- if (!pendingConfigures.pending ())
1903- {
1904- /* Tell plugins its ok to start doing stupid things again but
1905- * obviously FIXME */
1906- CompOption::Vector options;
1907- CompOption::Value v;
1908-
1909- options.push_back (CompOption ("window", CompOption::TypeInt));
1910- v.set ((int) id);
1911- options.back ().set (v);
1912- options.push_back (CompOption ("active", CompOption::TypeInt));
1913- v.set ((int) 0);
1914- options.back ().set (v);
1915-
1916- /* Notify other plugins that it is unsafe to change geometry or serverGeometry
1917- * FIXME: That API should not be accessible to plugins, this is a hack to avoid
1918- * breaking ABI */
1919-
1920- screen->handleCompizEvent ("core", "lock_position", options);
1921- }
1922 }
1923
1924 void
1925@@ -2183,23 +1901,34 @@
1926 {
1927 if (dx || dy)
1928 {
1929- gettimeofday (&priv->lastGeometryUpdate, NULL);
1930-
1931- /* Don't allow window movement to overwrite working geometries
1932- * last received from the server if we know there are pending
1933- * ConfigureNotify events on this window. That's a clunky workaround
1934- * and a FIXME in any case, however, until we can break the API
1935- * and remove CompWindow::move, this will need to be the case */
1936-
1937- if (!priv->pendingConfigures.pending ())
1938+ XWindowChanges xwc = XWINDOWCHANGES_INIT;
1939+ unsigned int valueMask = CWX | CWY;
1940+
1941+ xwc.x = priv->serverGeometry.x () + dx;
1942+ xwc.y = priv->serverGeometry.y () + dy;
1943+
1944+ priv->nextMoveImmediate = immediate;
1945+
1946+ configureXWindow (valueMask, &xwc);
1947+ }
1948+}
1949+
1950+void
1951+PrivateWindow::move (int dx,
1952+ int dy,
1953+ bool immediate)
1954+{
1955+ if (dx || dy)
1956+ {
1957+ priv->geometry.setX (priv->geometry.x () + dx);
1958+ priv->geometry.setY (priv->geometry.y () + dy);
1959+ priv->frameGeometry.setX (priv->frameGeometry.x () + dx);
1960+ priv->frameGeometry.setY (priv->frameGeometry.y () + dy);
1961+
1962+ if (priv->attrib.override_redirect)
1963 {
1964- priv->geometry.setX (priv->geometry.x () + dx);
1965- priv->geometry.setY (priv->geometry.y () + dy);
1966- priv->frameGeometry.setX (priv->frameGeometry.x () + dx);
1967- priv->frameGeometry.setY (priv->frameGeometry.y () + dy);
1968-
1969- priv->pendingPositionUpdates = true;
1970-
1971+ priv->serverGeometry = priv->geometry;
1972+ priv->serverFrameGeometry = priv->frameGeometry;
1973 priv->region.translate (dx, dy);
1974 priv->inputRegion.translate (dx, dy);
1975 if (!priv->frameRegion.isEmpty ())
1976@@ -2207,19 +1936,7 @@
1977
1978 priv->invisible = priv->isInvisible ();
1979
1980- moveNotify (dx, dy, immediate);
1981- }
1982- else
1983- {
1984- XWindowChanges xwc = XWINDOWCHANGES_INIT;
1985- unsigned int valueMask = CWX | CWY;
1986- compLogMessage ("core", CompLogLevelDebug, "pending configure notifies on 0x%x, "\
1987- "moving window asyncrhonously!", (unsigned int) priv->serverId);
1988-
1989- xwc.x = priv->serverGeometry.x () + dx;
1990- xwc.y = priv->serverGeometry.y () + dy;
1991-
1992- configureXWindow (valueMask, &xwc);
1993+ window->moveNotify (dx, dy, true);
1994 }
1995 }
1996 }
1997@@ -2230,22 +1947,6 @@
1998 return !mEvents.empty ();
1999 }
2000
2001-bool
2002-PrivateWindow::checkClear ()
2003-{
2004- if (pendingConfigures.pending ())
2005- {
2006- /* FIXME: This is a hack to avoid performance regressions
2007- * and must be removed in 0.9.6 */
2008- compLogMessage ("core", CompLogLevelWarn, "failed to receive ConfigureNotify event on 0x%x\n",
2009- id);
2010- pendingConfigures.dump ();
2011- pendingConfigures.clear ();
2012- }
2013-
2014- return false;
2015-}
2016-
2017 void
2018 compiz::X11::PendingEventQueue::add (PendingEvent::Ptr p)
2019 {
2020@@ -2280,9 +1981,9 @@
2021 {
2022 compiz::X11::PendingEvent::dump ();
2023
2024- compLogMessage ("core", CompLogLevelDebug, "- x: %i y: %i width: %i height: %i "\
2025+ compLogMessage ("core", CompLogLevelDebug, "- x: %i y: %i width: %i height: %i x2: %i y2 %i"\
2026 "border: %i, sibling: 0x%x",
2027- mXwc.x, mXwc.y, mXwc.width, mXwc.height, mXwc.border_width, mXwc.sibling);
2028+ mXwc.x, mXwc.y, mXwc.width, mXwc.height, mXwc.x + mXwc.width, mXwc.y + mXwc.height, mXwc.border_width, mXwc.sibling);
2029 }
2030
2031 bool
2032@@ -2467,21 +2168,6 @@
2033 mValueMask (valueMask),
2034 mXwc (*xwc)
2035 {
2036- CompOption::Vector options;
2037- CompOption::Value v;
2038-
2039- options.push_back (CompOption ("window", CompOption::TypeInt));
2040- v.set ((int) w);
2041- options.back ().set (v);
2042- options.push_back (CompOption ("active", CompOption::TypeInt));
2043- v.set ((int) 1);
2044- options.back ().set (v);
2045-
2046- /* Notify other plugins that it is unsafe to change geometry or serverGeometry
2047- * FIXME: That API should not be accessible to plugins, this is a hack to avoid
2048- * breaking ABI */
2049-
2050- screen->handleCompizEvent ("core", "lock_position", options);
2051 }
2052
2053 compiz::X11::PendingConfigureEvent::~PendingConfigureEvent ()
2054@@ -2491,57 +2177,6 @@
2055 void
2056 CompWindow::syncPosition ()
2057 {
2058- gettimeofday (&priv->lastConfigureRequest, NULL);
2059-
2060- unsigned int valueMask = CWX | CWY;
2061- XWindowChanges xwc = XWINDOWCHANGES_INIT;
2062-
2063- if (priv->pendingPositionUpdates && !priv->pendingConfigures.pending ())
2064- {
2065- if (priv->serverFrameGeometry.x () == priv->frameGeometry.x ())
2066- valueMask &= ~(CWX);
2067- if (priv->serverFrameGeometry.y () == priv->frameGeometry.y ())
2068- valueMask &= ~(CWY);
2069-
2070- /* Because CompWindow::move can update the geometry last
2071- * received from the server, we must indicate that no values
2072- * changed, because when the ConfigureNotify comes around
2073- * the values are going to be the same. That's obviously
2074- * broken behaviour and worthy of a FIXME, but requires
2075- * larger changes to the window movement system. */
2076- if (valueMask)
2077- {
2078- priv->serverGeometry.setX (priv->geometry.x ());
2079- priv->serverGeometry.setY (priv->geometry.y ());
2080- priv->serverFrameGeometry.setX (priv->frameGeometry.x ());
2081- priv->serverFrameGeometry.setY (priv->frameGeometry.y ());
2082-
2083- xwc.x = priv->serverFrameGeometry.x ();
2084- xwc.y = priv->serverFrameGeometry.y ();
2085-
2086- compiz::X11::PendingEvent::Ptr pc =
2087- boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
2088- new compiz::X11::PendingConfigureEvent (
2089- screen->dpy (), priv->serverFrame, 0, &xwc)));
2090-
2091- priv->pendingConfigures.add (pc);
2092-
2093- /* Got 3 seconds to get its stuff together */
2094- if (priv->mClearCheckTimeout.active ())
2095- priv->mClearCheckTimeout.stop ();
2096- priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
2097- 2000, 2500);
2098- XConfigureWindow (screen->dpy (), ROOTPARENT (this), valueMask, &xwc);
2099-
2100- if (priv->serverFrame)
2101- {
2102- XMoveWindow (screen->dpy (), priv->wrapper,
2103- priv->serverInput.left, priv->serverInput.top);
2104- sendConfigureNotify ();
2105- }
2106- }
2107- priv->pendingPositionUpdates = false;
2108- }
2109 }
2110
2111 bool
2112@@ -3342,14 +2977,41 @@
2113 {
2114 unsigned int frameValueMask = 0;
2115
2116- /* Immediately sync window position
2117- * if plugins were updating w->geometry () directly
2118- * in order to avoid a race condition */
2119-
2120- window->syncPosition ();
2121+ if (id == screen->root ())
2122+ {
2123+ compLogMessage ("core", CompLogLevelWarn, "attempted to reconfigure root window");
2124+ return;
2125+ }
2126
2127 /* Remove redundant bits */
2128
2129+ xwc->x = valueMask & CWX ? xwc->x : serverGeometry.x ();
2130+ xwc->y = valueMask & CWY ? xwc->y : serverGeometry.y ();
2131+ xwc->width = valueMask & CWWidth ? xwc->width : serverGeometry.width ();
2132+ xwc->height = valueMask & CWHeight ? xwc->height : serverGeometry.height ();
2133+ xwc->border_width = valueMask & CWBorderWidth ? xwc->border_width : serverGeometry.border ();
2134+
2135+ /* Don't allow anything that might generate a BadValue */
2136+ if (valueMask & CWWidth && !xwc->width)
2137+ {
2138+ compLogMessage ("core", CompLogLevelWarn, "Attempted to set < 1 width on a window");
2139+ xwc->width = 1;
2140+ }
2141+
2142+ if (valueMask & CWHeight && !xwc->height)
2143+ {
2144+ compLogMessage ("core", CompLogLevelWarn, "Attempted to set < 1 height on a window");
2145+ xwc->height = 1;
2146+ }
2147+
2148+ int dx = valueMask & CWX ? xwc->x - serverGeometry.x () : 0;
2149+ int dy = valueMask & CWY ? xwc->y - serverGeometry.y () : 0;
2150+ int dwidth = valueMask & CWWidth ? xwc->width - serverGeometry.width () : 0;
2151+ int dheight = valueMask & CWHeight ? xwc->height - serverGeometry.height () : 0;
2152+
2153+ /* FIXME: This is a total fallacy for the reparenting case
2154+ * at least since the client doesn't actually move here, it only
2155+ * moves within the frame */
2156 if (valueMask & CWX && serverGeometry.x () == xwc->x)
2157 valueMask &= ~(CWX);
2158
2159@@ -3416,18 +3078,15 @@
2160 compLogMessage ("core", CompLogLevelWarn, "restack_mode not Above");
2161 }
2162
2163- frameValueMask = valueMask;
2164+ frameValueMask = CWX | CWY | CWWidth | CWHeight | (valueMask & (CWStackMode | CWSibling));
2165
2166- if (frameValueMask & CWX &&
2167- serverFrameGeometry.x () == xwc->x - serverGeometry.border () - serverInput.left)
2168+ if (serverFrameGeometry.x () == xwc->x - serverGeometry.border () - serverInput.left)
2169 frameValueMask &= ~(CWX);
2170
2171- if (frameValueMask & CWY &&
2172- serverFrameGeometry.y () == xwc->y - serverGeometry.border () - serverInput.top)
2173+ if (serverFrameGeometry.y () == xwc->y - serverGeometry.border () - serverInput.top)
2174 frameValueMask &= ~(CWY);
2175
2176- if (frameValueMask & CWWidth &&
2177- serverFrameGeometry.width () == xwc->width + serverGeometry.border () * 2
2178+ if (serverFrameGeometry.width () == xwc->width + serverGeometry.border () * 2
2179 + serverInput.left + serverInput.right)
2180 frameValueMask &= ~(CWWidth);
2181
2182@@ -3437,19 +3096,64 @@
2183
2184 if (shaded)
2185 {
2186- if (frameValueMask & CWHeight &&
2187- serverFrameGeometry.height () == serverGeometry.border () * 2
2188+ if (serverFrameGeometry.height () == serverGeometry.border () * 2
2189 + serverInput.top + serverInput.bottom)
2190 frameValueMask &= ~(CWHeight);
2191 }
2192 else
2193 {
2194- if (frameValueMask & CWHeight &&
2195- serverFrameGeometry.height () == xwc->height + serverGeometry.border () * 2
2196+ if (serverFrameGeometry.height () == xwc->height + serverGeometry.border () * 2
2197 + serverInput.top + serverInput.bottom)
2198 frameValueMask &= ~(CWHeight);
2199 }
2200
2201+
2202+ if (valueMask & CWStackMode &&
2203+ ((xwc->stack_mode != TopIf) && (xwc->stack_mode != BottomIf) && (xwc->stack_mode != Opposite) &&
2204+ (xwc->stack_mode != Above) && (xwc->stack_mode != Below)))
2205+ {
2206+ compLogMessage ("core", CompLogLevelWarn, "Invalid stack mode %i", xwc->stack_mode);
2207+ valueMask &= ~(CWStackMode | CWSibling);
2208+ }
2209+
2210+ /* Don't allow anything that might cause a BadMatch error */
2211+
2212+ if (valueMask & CWSibling && !(valueMask & CWStackMode))
2213+ {
2214+ compLogMessage ("core", CompLogLevelWarn, "Didn't specify a CWStackMode for CWSibling");
2215+ valueMask &= ~CWSibling;
2216+ }
2217+
2218+ if (valueMask & CWSibling && xwc->sibling == (serverFrame ? serverFrame : id))
2219+ {
2220+ compLogMessage ("core", CompLogLevelWarn, "Can't restack a window relative to itself");
2221+ valueMask &= ~CWSibling;
2222+ }
2223+
2224+ if (valueMask & CWBorderWidth && attrib.c_class == InputOnly)
2225+ {
2226+ compLogMessage ("core", CompLogLevelWarn, "Cannot set border_width of an input_only window");
2227+ valueMask &= ~CWBorderWidth;
2228+ }
2229+
2230+ if (valueMask & CWSibling)
2231+ {
2232+ CompWindow *sibling = screen->findTopLevelWindow (xwc->sibling);
2233+
2234+ if (!sibling)
2235+ {
2236+ compLogMessage ("core", CompLogLevelWarn, "Attempted to restack relative to 0x%x which is "\
2237+ "not a child of the root window or a window compiz owns", static_cast <unsigned int> (xwc->sibling));
2238+ valueMask &= ~(CWSibling | CWStackMode);
2239+ }
2240+ else if (sibling->frame () && xwc->sibling != sibling->frame ())
2241+ {
2242+ compLogMessage ("core", CompLogLevelWarn, "Attempted to restack relative to 0x%x which is "\
2243+ "not a child of the root window", static_cast <unsigned int> (xwc->sibling));
2244+ valueMask &= ~(CWSibling | CWStackMode);
2245+ }
2246+ }
2247+
2248 /* Can't set the border width of frame windows */
2249 frameValueMask &= ~(CWBorderWidth);
2250
2251@@ -3476,11 +3180,8 @@
2252 + serverInput.top + serverInput.bottom);
2253 }
2254
2255-
2256 if (serverFrame)
2257 {
2258- gettimeofday (&lastConfigureRequest, NULL);
2259-
2260 if (frameValueMask)
2261 {
2262 XWindowChanges wc = *xwc;
2263@@ -3496,13 +3197,10 @@
2264 screen->dpy (), priv->serverFrame, frameValueMask, &wc)));
2265
2266 pendingConfigures.add (pc);
2267- if (priv->mClearCheckTimeout.active ())
2268- priv->mClearCheckTimeout.stop ();
2269- priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
2270- 2000, 2500);
2271
2272 XConfigureWindow (screen->dpy (), serverFrame, frameValueMask, &wc);
2273 }
2274+
2275 valueMask &= ~(CWSibling | CWStackMode);
2276
2277 /* If the frame has changed position (eg, serverInput.top
2278@@ -3528,6 +3226,39 @@
2279
2280 if (valueMask)
2281 XConfigureWindow (screen->dpy (), id, valueMask, xwc);
2282+
2283+ /* When updating plugins we care about
2284+ * the absolute position */
2285+ if (abs (dx))
2286+ valueMask |= CWX;
2287+ if (abs (dy))
2288+ valueMask |= CWY;
2289+ if (abs (dwidth))
2290+ valueMask |= CWWidth;
2291+ if (abs (dheight))
2292+ valueMask |= CWHeight;
2293+
2294+ if (!attrib.override_redirect)
2295+ {
2296+ if (valueMask & (CWWidth | CWHeight))
2297+ {
2298+ updateRegion ();
2299+ window->resizeNotify (dx, dy, dwidth, dheight);
2300+ }
2301+ else if (valueMask & (CWX | CWY))
2302+ {
2303+ region.translate (dx, dy);
2304+ inputRegion.translate (dx, dy);
2305+ if (!frameRegion.isEmpty ())
2306+ frameRegion.translate (dx, dy);
2307+
2308+ if (abs (dx) || abs (dy))
2309+ {
2310+ window->moveNotify (dx, dy, priv->nextMoveImmediate);
2311+ priv->nextMoveImmediate = true;
2312+ }
2313+ }
2314+ }
2315 }
2316
2317 bool
2318@@ -4305,10 +4036,6 @@
2319 screen->dpy (), serverFrame, valueMask, &lxwc)));
2320
2321 pendingConfigures.add (pc);
2322- if (priv->mClearCheckTimeout.active ())
2323- priv->mClearCheckTimeout.stop ();
2324- priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
2325- 2000, 2500);
2326 }
2327
2328 /* Below with no sibling puts the window at the bottom
2329@@ -4612,8 +4339,8 @@
2330 PrivateWindow::ensureWindowVisibility ()
2331 {
2332 int x1, y1, x2, y2;
2333- int width = serverGeometry.width () + serverGeometry.border () * 2;
2334- int height = serverGeometry.height () + serverGeometry.border () * 2;
2335+ int width = serverGeometry.widthIncBorders ();
2336+ int height = serverGeometry.heightIncBorders ();
2337 int dx = 0;
2338 int dy = 0;
2339
2340@@ -5473,10 +5200,10 @@
2341 }
2342 else
2343 {
2344- m = priv->geometry.x () + offX;
2345- if (m - priv->input.left < (int) s->width () - vWidth)
2346+ m = priv->serverGeometry.x () + offX;
2347+ if (m - priv->serverInput.left < (int) s->width () - vWidth)
2348 rv.setX (offX + vWidth);
2349- else if (m + priv->width + priv->input.right > vWidth)
2350+ else if (m + priv->serverGeometry.width () + priv->serverInput.right > vWidth)
2351 rv.setX (offX - vWidth);
2352 else
2353 rv.setX (offX);
2354@@ -5488,10 +5215,10 @@
2355 }
2356 else
2357 {
2358- m = priv->geometry.y () + offY;
2359- if (m - priv->input.top < (int) s->height () - vHeight)
2360+ m = priv->serverGeometry.y () + offY;
2361+ if (m - priv->serverInput.top < (int) s->height () - vHeight)
2362 rv.setY (offY + vHeight);
2363- else if (m + priv->height + priv->input.bottom > vHeight)
2364+ else if (m + priv->serverGeometry.height () + priv->serverInput.bottom > vHeight)
2365 rv.setY (offY - vHeight);
2366 else
2367 rv.setY (offY);
2368@@ -6014,8 +5741,8 @@
2369 y -= screen->vp ().y () * screen->height ();
2370 }
2371
2372- tx = x - priv->geometry.x ();
2373- ty = y - priv->geometry.y ();
2374+ tx = x - priv->serverGeometry.x ();
2375+ ty = y - priv->serverGeometry.y ();
2376
2377 if (tx || ty)
2378 {
2379@@ -6037,21 +5764,21 @@
2380
2381 if (screen->vpSize ().width ()!= 1)
2382 {
2383- m = priv->geometry.x () + tx;
2384+ m = priv->serverGeometry.x () + tx;
2385
2386 if (m - priv->output.left < (int) screen->width () - vWidth)
2387 wx = tx + vWidth;
2388- else if (m + priv->width + priv->output.right > vWidth)
2389+ else if (m + priv->serverGeometry.width () + priv->output.right > vWidth)
2390 wx = tx - vWidth;
2391 }
2392
2393 if (screen->vpSize ().height () != 1)
2394 {
2395- m = priv->geometry.y () + ty;
2396+ m = priv->serverGeometry.y () + ty;
2397
2398 if (m - priv->output.top < (int) screen->height () - vHeight)
2399 wy = ty + vHeight;
2400- else if (m + priv->height + priv->output.bottom > vHeight)
2401+ else if (m + priv->serverGeometry.height () + priv->output.bottom > vHeight)
2402 wy = ty - vHeight;
2403 }
2404
2405@@ -6206,8 +5933,8 @@
2406 svp = screen->vp ();
2407 size = *screen;
2408
2409- x = window->geometry ().x () + (svp.x () - vp.x ()) * size.width ();
2410- y = window->geometry ().y () + (svp.y () - vp.y ()) * size.height ();
2411+ x = window->serverGeometry ().x () + (svp.x () - vp.x ()) * size.width ();
2412+ y = window->serverGeometry ().y () + (svp.y () - vp.y ()) * size.height ();
2413 window->moveToViewportPosition (x, y, true);
2414
2415 if (allowWindowFocus (0, timestamp))
2416@@ -6276,9 +6003,6 @@
2417 priv->serverFrameGeometry = priv->frameGeometry = priv->syncGeometry
2418 = priv->geometry = priv->serverGeometry;
2419
2420- priv->width = priv->attrib.width + priv->attrib.border_width * 2;
2421- priv->height = priv->attrib.height + priv->attrib.border_width * 2;
2422-
2423 priv->sizeHints.flags = 0;
2424
2425 priv->recalcNormalHints ();
2426@@ -6300,8 +6024,7 @@
2427
2428 if (priv->attrib.c_class != InputOnly)
2429 {
2430- priv->region = CompRegion (priv->attrib.x, priv->attrib.y,
2431- priv->width, priv->height);
2432+ priv->region = CompRegion (priv->serverGeometry);
2433 priv->inputRegion = priv->region;
2434
2435 /* need to check for DisplayModal state on all windows */
2436@@ -6531,8 +6254,6 @@
2437 hints (NULL),
2438 inputHint (true),
2439 alpha (false),
2440- width (0),
2441- height (0),
2442 region (),
2443 wmType (0),
2444 type (CompWindowTypeUnknownMask),
2445@@ -6567,7 +6288,6 @@
2446 pendingUnmaps (0),
2447 pendingMaps (0),
2448 pendingConfigures (screen->dpy ()),
2449- pendingPositionUpdates (false),
2450
2451 startupId (0),
2452 resName (0),
2453@@ -6745,14 +6465,12 @@
2454 void
2455 CompWindow::updateFrameRegion ()
2456 {
2457- if (priv->serverFrame &&
2458- priv->serverGeometry.width () == priv->geometry.width () &&
2459- priv->serverGeometry.height () == priv->geometry.height ())
2460+ if (priv->serverFrame)
2461 {
2462 CompRect r;
2463 int x, y;
2464
2465- priv->frameRegion = CompRegion ();
2466+ priv->frameRegion = emptyRegion;
2467
2468 updateFrameRegion (priv->frameRegion);
2469
2470@@ -6761,16 +6479,16 @@
2471 r = priv->region.boundingRect ();
2472 priv->frameRegion -= r;
2473
2474- r.setGeometry (r.x1 () - priv->input.left,
2475- r.y1 () - priv->input.top,
2476- r.width () + priv->input.right + priv->input.left,
2477- r.height () + priv->input.bottom + priv->input.top);
2478+ r.setGeometry (r.x1 () - priv->serverInput.left,
2479+ r.y1 () - priv->serverInput.top,
2480+ r.width () + priv->serverInput.right + priv->serverInput.left,
2481+ r.height () + priv->serverInput.bottom + priv->serverInput.top);
2482
2483 priv->frameRegion &= CompRegion (r);
2484 }
2485
2486- x = priv->geometry.x () - priv->input.left;
2487- y = priv->geometry.y () - priv->input.top;
2488+ x = priv->serverGeometry.x () - priv->serverInput.left;
2489+ y = priv->serverGeometry.y () - priv->serverInput.top;
2490
2491 XShapeCombineRegion (screen->dpy (), priv->serverFrame,
2492 ShapeBounding, -x, -y,
2493@@ -6788,6 +6506,10 @@
2494 CompWindow::setWindowFrameExtents (CompWindowExtents *b,
2495 CompWindowExtents *i)
2496 {
2497+ /* override redirect windows can't have frame extents */
2498+ if (priv->attrib.override_redirect)
2499+ return;
2500+
2501 /* Input extents are used for frame size,
2502 * Border extents used for placement.
2503 */
2504@@ -6811,6 +6533,11 @@
2505
2506 priv->updateSize ();
2507 priv->updateFrameWindow ();
2508+
2509+ /* Always send a moveNotify
2510+ * whenever the frame extents update
2511+ * so that plugins can re-position appropriately */
2512+ moveNotify (0, 0, true);
2513 }
2514
2515 /* Use b for _NET_WM_FRAME_EXTENTS here because
2516@@ -7094,10 +6821,10 @@
2517 /* Wait for the reparent to finish */
2518 XSync (dpy, false);
2519
2520- xwc.x = serverGeometry.x () - serverGeometry.border ();
2521- xwc.y = serverGeometry.y () - serverGeometry.border ();
2522- xwc.width = serverGeometry.width () + serverGeometry.border () * 2;
2523- xwc.height = serverGeometry.height () + serverGeometry.border () * 2;
2524+ xwc.x = serverGeometry.xMinusBorder ();
2525+ xwc.y = serverGeometry.yMinusBorder ();
2526+ xwc.width = serverGeometry.widthIncBorders ();
2527+ xwc.height = serverGeometry.heightIncBorders ();
2528
2529 XConfigureWindow (dpy, serverFrame, CWX | CWY | CWWidth | CWHeight, &xwc);
2530
2531@@ -7171,7 +6898,9 @@
2532 XDestroyWindow (screen->dpy (), serverFrame);
2533 XDestroyWindow (screen->dpy (), wrapper);
2534
2535+ // Finally, (i.e. after updating state) notify the change
2536 window->windowNotify (CompWindowNotifyUnreparent);
2537+
2538 /* This window is no longer "managed" in the
2539 * reparenting sense so clear its pending event
2540 * queue ... though maybe in future it would
2541
2542=== modified file 'src/window/geometry/include/core/windowgeometry.h'
2543--- src/window/geometry/include/core/windowgeometry.h 2012-01-19 20:08:32 +0000
2544+++ src/window/geometry/include/core/windowgeometry.h 2012-04-18 12:32:31 +0000
2545@@ -64,6 +64,12 @@
2546 compiz::window::Geometry change (const compiz::window::Geometry &g, unsigned int mask) const;
2547 void applyChange (const compiz::window::Geometry &g, unsigned int mask);
2548
2549+ int xMinusBorder () const { return x () - mBorder; }
2550+ int yMinusBorder () const { return y () - mBorder; }
2551+
2552+ unsigned int widthIncBorders () const { return width () + mBorder * 2; }
2553+ unsigned int heightIncBorders () const { return height () + mBorder * 2; }
2554+
2555 private:
2556 int mBorder;
2557 };
2558
2559=== modified file 'src/window/geometry/tests/window-geometry/src/test-window-geometry.cpp'
2560--- src/window/geometry/tests/window-geometry/src/test-window-geometry.cpp 2012-03-30 16:30:13 +0000
2561+++ src/window/geometry/tests/window-geometry/src/test-window-geometry.cpp 2012-04-18 12:32:31 +0000
2562@@ -87,3 +87,13 @@
2563 EXPECT_EQ (rg, compiz::window::Geometry (49, 99, 199, 299, 5));
2564 EXPECT_EQ (mask, CHANGE_X | CHANGE_Y | CHANGE_WIDTH | CHANGE_HEIGHT);
2565 }
2566+
2567+TEST_F(CompWindowGeometryTestGeometry, TestBorders)
2568+{
2569+ compiz::window::Geometry g (1, 1, 1, 1, 1);
2570+
2571+ EXPECT_EQ (g.xMinusBorder (), 0);
2572+ EXPECT_EQ (g.yMinusBorder (), 0);
2573+ EXPECT_EQ (g.widthIncBorders (), 3);
2574+ EXPECT_EQ (g.heightIncBorders (), 3);
2575+}
2576
2577=== modified file 'src/windowgeometry.cpp'
2578--- src/windowgeometry.cpp 2012-01-23 05:44:19 +0000
2579+++ src/windowgeometry.cpp 2012-04-18 12:32:31 +0000
2580@@ -30,160 +30,153 @@
2581 CompWindow::Geometry &
2582 CompWindow::serverGeometry () const
2583 {
2584- return priv->serverGeometry;
2585+ return priv->attrib.override_redirect ? priv->geometry : priv->serverGeometry;
2586 }
2587
2588 CompWindow::Geometry &
2589 CompWindow::geometry () const
2590 {
2591- return priv->geometry;
2592+ return priv->attrib.override_redirect ? priv->geometry : priv->serverGeometry;
2593 }
2594
2595 int
2596 CompWindow::x () const
2597 {
2598- return priv->geometry.x ();
2599+ return geometry ().x ();
2600 }
2601
2602 int
2603 CompWindow::y () const
2604 {
2605- return priv->geometry.y ();
2606+ return geometry ().y ();
2607 }
2608
2609 CompPoint
2610 CompWindow::pos () const
2611 {
2612- return CompPoint (priv->geometry.x (), priv->geometry.y ());
2613+ return CompPoint (geometry ().x (), geometry ().y ());
2614 }
2615
2616 /* With border */
2617 int
2618 CompWindow::width () const
2619 {
2620- return priv->width +
2621- priv->geometry.border () * 2;
2622+ return geometry ().widthIncBorders ();
2623 }
2624
2625 int
2626 CompWindow::height () const
2627 {
2628- return priv->height +
2629- priv->geometry.border () * 2;;
2630+ return geometry ().heightIncBorders ();
2631 }
2632
2633 CompSize
2634 CompWindow::size () const
2635 {
2636- return CompSize (priv->width + priv->geometry.border () * 2,
2637- priv->height + priv->geometry.border () * 2);
2638+ return CompSize (width (), height ());
2639 }
2640
2641 int
2642 CompWindow::serverX () const
2643 {
2644- return priv->serverGeometry.x ();
2645+ return serverGeometry ().x ();
2646 }
2647
2648 int
2649 CompWindow::serverY () const
2650 {
2651- return priv->serverGeometry.y ();
2652+ return serverGeometry ().y ();
2653 }
2654
2655 CompPoint
2656 CompWindow::serverPos () const
2657 {
2658- return CompPoint (priv->serverGeometry.x (),
2659- priv->serverGeometry.y ());
2660+ return CompPoint (serverGeometry ().x (),
2661+ serverGeometry ().y ());
2662 }
2663
2664 /* With border */
2665 int
2666 CompWindow::serverWidth () const
2667 {
2668- return priv->serverGeometry.width () +
2669- 2 * priv->serverGeometry.border ();
2670+ return serverGeometry ().widthIncBorders ();
2671 }
2672
2673 int
2674 CompWindow::serverHeight () const
2675 {
2676- return priv->serverGeometry.height () +
2677- 2 * priv->serverGeometry.border ();
2678+ return serverGeometry ().heightIncBorders ();
2679 }
2680
2681 const CompSize
2682 CompWindow::serverSize () const
2683 {
2684- return CompSize (priv->serverGeometry.width () +
2685- 2 * priv->serverGeometry.border (),
2686- priv->serverGeometry.height () +
2687- 2 * priv->serverGeometry.border ());
2688+ return CompSize (serverGeometry ().widthIncBorders (),
2689+ serverGeometry ().heightIncBorders ());
2690 }
2691
2692 CompRect
2693 CompWindow::borderRect () const
2694 {
2695- return CompRect (priv->geometry.x () - priv->geometry.border () - priv->border.left,
2696- priv->geometry.y () - priv->geometry.border () - priv->border.top,
2697- priv->geometry.width () + priv->geometry.border () * 2 +
2698+ return CompRect (geometry ().xMinusBorder () - priv->border.left,
2699+ geometry ().yMinusBorder () - priv->border.top,
2700+ geometry ().widthIncBorders () +
2701 priv->border.left + priv->border.right,
2702- priv->geometry.height () + priv->geometry.border () * 2 +
2703+ geometry ().heightIncBorders () +
2704 priv->border.top + priv->border.bottom);
2705 }
2706
2707 CompRect
2708 CompWindow::serverBorderRect () const
2709 {
2710- return CompRect (priv->serverGeometry.x () - priv->geometry.border () - priv->border.left,
2711- priv->serverGeometry.y () - priv->geometry.border () - priv->border.top,
2712- priv->serverGeometry.width () + priv->geometry.border () * 2 +
2713+ return CompRect (serverGeometry ().xMinusBorder () - priv->border.left,
2714+ serverGeometry ().yMinusBorder () - priv->border.top,
2715+ serverGeometry ().widthIncBorders () +
2716 priv->border.left + priv->border.right,
2717- priv->serverGeometry.height () + priv->geometry.border () * 2 +
2718+ serverGeometry ().heightIncBorders() +
2719 priv->border.top + priv->border.bottom);
2720 }
2721
2722 CompRect
2723 CompWindow::inputRect () const
2724 {
2725- return CompRect (priv->geometry.x () - priv->geometry.border () - priv->serverInput.left,
2726- priv->geometry.y () - priv->geometry.border () - priv->serverInput.top,
2727- priv->geometry.width () + priv->geometry.border () * 2 +
2728+ return CompRect (geometry ().xMinusBorder () - priv->serverInput.left,
2729+ geometry ().yMinusBorder () - priv->serverInput.top,
2730+ geometry ().widthIncBorders () +
2731 priv->serverInput.left + priv->serverInput.right,
2732- priv->geometry.height () +priv->geometry.border () * 2 +
2733+ geometry ().heightIncBorders () +
2734 priv->serverInput.top + priv->serverInput.bottom);
2735 }
2736
2737 CompRect
2738 CompWindow::serverInputRect () const
2739 {
2740- return CompRect (priv->serverGeometry.x () - priv->serverGeometry.border () - priv->serverInput.left,
2741- priv->serverGeometry.y () - priv->serverGeometry.border () - priv->serverInput.top,
2742- priv->serverGeometry.width () + priv->serverGeometry.border () * 2 +
2743+ return CompRect (serverGeometry ().xMinusBorder () - priv->serverInput.left,
2744+ serverGeometry ().yMinusBorder () - priv->serverInput.top,
2745+ serverGeometry ().widthIncBorders () +
2746 priv->serverInput.left + priv->serverInput.right,
2747- priv->serverGeometry.height () + priv->serverGeometry.border () * 2 +
2748+ serverGeometry ().heightIncBorders () +
2749 priv->serverInput.top + priv->serverInput.bottom);
2750 }
2751
2752 CompRect
2753 CompWindow::outputRect () const
2754 {
2755- return CompRect (priv->geometry.x () - priv->serverGeometry.border ()- priv->output.left,
2756- priv->geometry.y () - priv->serverGeometry.border () - priv->output.top,
2757- priv->geometry.width () + priv->serverGeometry.border () * 2 +
2758+ return CompRect (geometry ().xMinusBorder ()- priv->output.left,
2759+ geometry ().yMinusBorder () - priv->output.top,
2760+ geometry ().widthIncBorders () +
2761 priv->output.left + priv->output.right,
2762- priv->geometry.height () + priv->serverGeometry.border () * 2 +
2763+ geometry ().heightIncBorders () +
2764 priv->output.top + priv->output.bottom);
2765 }
2766
2767 CompRect
2768 CompWindow::serverOutputRect () const
2769 {
2770- return CompRect (priv->serverGeometry.x () - priv->serverGeometry.border () - priv->output.left,
2771- priv->serverGeometry.y () - priv->serverGeometry.border () - priv->output.top,
2772- priv->serverGeometry.width () + priv->serverGeometry.border () * 2 +
2773+ return CompRect (serverGeometry ().xMinusBorder () - priv->output.left,
2774+ serverGeometry ().yMinusBorder () - priv->output.top,
2775+ serverGeometry ().widthIncBorders () +
2776 priv->output.left + priv->output.right,
2777- priv->serverGeometry.height () + priv->serverGeometry.border () * 2 +
2778+ serverGeometry ().heightIncBorders () +
2779 priv->output.top + priv->output.bottom);
2780 }

Subscribers

People subscribed via source and target branches