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

Proposed by Sam Spilsbury
Status: Merged
Merged at revision: 3110
Proposed branch: lp:~smspillaz/compiz-core/compiz-core.work_923683
Merge into: lp:compiz-core/0.9.8
Prerequisite: lp:~smspillaz/compiz-core/compiz-core.fix_969101
Diff against target: 2394 lines (+509/-779)
19 files modified
plugins/composite/src/window.cpp (+15/-35)
plugins/decor/src/decor.cpp (+66/-53)
plugins/decor/src/decor.h (+2/-3)
plugins/move/src/move.cpp (+2/-4)
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 (+1/-11)
plugins/resize/src/resize.h (+0/-2)
plugins/wobbly/src/wobbly.cpp (+5/-4)
src/event.cpp (+1/-1)
src/privatewindow.h (+7/-8)
src/screen.cpp (+4/-2)
src/window.cpp (+270/-543)
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 Approve
Alan Griffiths Approve
Sam Spilsbury Pending
Review via email: mp+102687@code.launchpad.net

This proposal supersedes 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

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 and resizeNotify are only ever called pre-request 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
 * various const correctness where it made sense
 * cleaned up the whole geometry.width () + geometry.border () * 2 nonsense
 * 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 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.

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 : Posted in a previous version of this proposal

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 : Posted in a previous version of this proposal

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 : Posted in a previous version of this proposal

> 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 : Posted in a previous version of this proposal

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 : Posted in a previous version of this proposal

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

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

I'm resubmitting this into the development branch now.

Please Please Please.

We will not be supporting plugins like wobbly and friends in later versions of ubuntu. As such, minor regressions in those plugins are not a good reason to reject this branch.

Normal resize mode is another can of worms. Please don't talk about it either.

The only valid reasons to block this branch are
1) Bad code
2) A regression in the actual supported ubuntu usecases

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

I can imagine regressions #1, #2 and #4 being accepted and ignored indefinitely. But #3 is something I would not want to see in 0.9.8.0. It's a commonly used feature (albeit unofficial) that has worked perfectly until now. If you don't want to fix it then either myself or Alan will be motivated to, because it's annoying us personally.

Please try to fix regression #3 before we merge this branch.

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

Regressions 1, 3 and 4 fixed (even if they were tiny)

If you want to fix regression 2 (even though its not really a regression, just a race condition that has always existed), then please check out lp:~smspillaz/compiz-core/compiz-core.decor_synchronization . That adds some synchronization primitives to the decoration protocol which fixes races where pixmaps were being bound after destruction.

I've also cleaned up the code a bit now that we don't need to use server* in client code, so the diff size should be smaller.

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

Can we rename this merge "Groundhog Day"?

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

Not seen any problems over the last few of hours of use (but not been running wobbly). 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 :

Pointless use of abs(): All uses of the abs() function in the diff appear to be numerically pointless;
    if (abs (foo))
is the same as:
    if (foo)

Pointless temporary creation/destruction:
1345 + priv->region = priv->inputRegion = CompRegion ();
Should just assign emptyRegion I think.

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

But the good news is that it's running nicely so far.

3032. By Sam Spilsbury

Fix logic errors

Revision history for this message
Daniel van Vugt (vanvugt) :
review: Approve
3033. By Sam Spilsbury

!= 0 not necessary

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

Since grabbing latest revision and switching to wobbly I'm seeing misplacement of half-maximized windows.

3034. By Sam Spilsbury

Merge lp:compiz-core

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

Alan, can you elaborate?

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

> Alan, can you elaborate?

E.g. drag a window to RHS and get half max highlight. Release and the window goes to a position that is not at the side of the screen.

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

Hmm, I can't reproduce any such regressions with wobbly+grid plugins and this branch.

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

> Hmm, I can't reproduce any such regressions with wobbly+grid plugins and this
> branch.

Odd. Am testing something else just now, but will retest shortly.

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

Looks good now. (Can't reproduce friday's problems.)

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

Double-checked all the header (ABI) changes against plugins-main, plugins-extra and unity. Confirmed the affected classes are not used in any of the major plugin packages.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'plugins/composite/src/window.cpp'
--- plugins/composite/src/window.cpp 2012-03-22 17:00:51 +0000
+++ plugins/composite/src/window.cpp 2012-04-23 05:39:20 +0000
@@ -128,6 +128,9 @@
128 /* We have to grab the server here to make sure that window128 /* We have to grab the server here to make sure that window
129 is mapped when getting the window pixmap */129 is mapped when getting the window pixmap */
130 XGrabServer (screen->dpy ());130 XGrabServer (screen->dpy ());
131
132 /* Flush changes to the server and wait for it to process them */
133 XSync (screen->dpy (), false);
131 XGetWindowAttributes (screen->dpy (),134 XGetWindowAttributes (screen->dpy (),
132 ROOTPARENT (priv->window), &attr);135 ROOTPARENT (priv->window), &attr);
133 if (attr.map_state != IsViewable)136 if (attr.map_state != IsViewable)
@@ -250,7 +253,7 @@
250253
251 if (x2 > x1 && y2 > y1)254 if (x2 > x1 && y2 > y1)
252 {255 {
253 CompWindow::Geometry geom = priv->window->geometry ();256 const CompWindow::Geometry &geom = priv->window->serverGeometry ();
254257
255 x1 += geom.x () + geom.border ();258 x1 += geom.x () + geom.border ();
256 y1 += geom.y () + geom.border ();259 y1 += geom.y () + geom.border ();
@@ -272,20 +275,20 @@
272 {275 {
273 int x1, x2, y1, y2;276 int x1, x2, y1, y2;
274277
275 CompWindow::Geometry geom = priv->window->geometry ();278 const CompWindow::Geometry &geom = priv->window->geometry ();
276 CompWindowExtents output = priv->window->output ();279 const CompWindowExtents &output = priv->window->output ();
277280
278 /* top */281 /* top */
279 x1 = -output.left - geom.border ();282 x1 = -output.left - geom.border ();
280 y1 = -output.top - geom.border ();283 y1 = -output.top - geom.border ();
281 x2 = priv->window->size ().width () + output.right - geom.border ();284 x2 = priv->window->size ().width () + output.right;
282 y2 = -geom.border ();285 y2 = -geom.border ();
283286
284 if (x1 < x2 && y1 < y2)287 if (x1 < x2 && y1 < y2)
285 addDamageRect (CompRect (x1, y1, x2 - x1, y2 - y1));288 addDamageRect (CompRect (x1, y1, x2 - x1, y2 - y1));
286289
287 /* bottom */290 /* bottom */
288 y1 = priv->window->size ().height () - geom.border ();291 y1 = priv->window->size ().height ();
289 y2 = y1 + output.bottom - geom.border ();292 y2 = y1 + output.bottom - geom.border ();
290293
291 if (x1 < x2 && y1 < y2)294 if (x1 < x2 && y1 < y2)
@@ -295,13 +298,13 @@
295 x1 = -output.left - geom.border ();298 x1 = -output.left - geom.border ();
296 y1 = -geom.border ();299 y1 = -geom.border ();
297 x2 = -geom.border ();300 x2 = -geom.border ();
298 y2 = priv->window->size ().height () - geom.border ();301 y2 = priv->window->size ().height ();
299302
300 if (x1 < x2 && y1 < y2)303 if (x1 < x2 && y1 < y2)
301 addDamageRect (CompRect (x1, y1, x2 - x1, y2 - y1));304 addDamageRect (CompRect (x1, y1, x2 - x1, y2 - y1));
302305
303 /* right */306 /* right */
304 x1 = priv->window->size ().width () - geom.border ();307 x1 = priv->window->size ().width ();
305 x2 = x1 + output.right - geom.border ();308 x2 = x1 + output.right - geom.border ();
306309
307 if (x1 < x2 && y1 < y2)310 if (x1 < x2 && y1 < y2)
@@ -322,7 +325,7 @@
322 x = rect.x ();325 x = rect.x ();
323 y = rect.y ();326 y = rect.y ();
324327
325 CompWindow::Geometry geom = priv->window->geometry ();328 const CompWindow::Geometry &geom = priv->window->geometry ();
326 x += geom.x () + geom.border ();329 x += geom.x () + geom.border ();
327 y += geom.y () + geom.border ();330 y += geom.y () + geom.border ();
328331
@@ -341,7 +344,7 @@
341 if (priv->window->shaded () || force ||344 if (priv->window->shaded () || force ||
342 (priv->window->isViewable ()))345 (priv->window->isViewable ()))
343 {346 {
344 int border = priv->window->geometry ().border ();347 int border = priv->window->serverGeometry ().border ();
345348
346 int x1 = -MAX (priv->window->output ().left,349 int x1 = -MAX (priv->window->output ().left,
347 priv->window->input ().left) - border;350 priv->window->input ().left) - border;
@@ -410,7 +413,7 @@
410413
411 if (!w->damageRect (initial, CompRect (x, y, width, height)))414 if (!w->damageRect (initial, CompRect (x, y, width, height)))
412 {415 {
413 CompWindow::Geometry geom = w->priv->window->geometry ();416 const CompWindow::Geometry &geom = w->priv->window->geometry ();
414417
415 x += geom.x () + geom.border ();418 x += geom.x () + geom.border ();
416 y += geom.y () + geom.border ();419 y += geom.y () + geom.border ();
@@ -557,10 +560,6 @@
557{560{
558 window->resizeNotify (dx, dy, dwidth, dheight);561 window->resizeNotify (dx, dy, dwidth, dheight);
559562
560 Pixmap pixmap = None;
561 CompSize size = CompSize ();
562
563
564 if (window->shaded () || (window->isViewable ()))563 if (window->shaded () || (window->isViewable ()))
565 {564 {
566 int x, y, x1, x2, y1, y2;565 int x, y, x1, x2, y1, y2;
@@ -578,25 +577,6 @@
578 cScreen->damageRegion (CompRegion (CompRect (x1, y1, x2 - x1, y2 - y1)));577 cScreen->damageRegion (CompRegion (CompRect (x1, y1, x2 - x1, y2 - y1)));
579 }578 }
580579
581 if (window->mapNum () && redirected)
582 {
583 unsigned int actualWidth, actualHeight, ui;
584 Window root;
585 Status result;
586 int i;
587
588 pixmap = XCompositeNameWindowPixmap (screen->dpy (), ROOTPARENT (window));
589 result = XGetGeometry (screen->dpy (), pixmap, &root, &i, &i,
590 &actualWidth, &actualHeight, &ui, &ui);
591 size = CompSize (actualWidth, actualHeight);
592 if (!result || actualWidth != (unsigned int) window->size ().width () ||
593 actualHeight != (unsigned int) window->size ().height ())
594 {
595 XFreePixmap (screen->dpy (), pixmap);
596 return;
597 }
598 }
599
600 if (((!window->mapNum () && window->isViewable ()) ||580 if (((!window->mapNum () && window->isViewable ()) ||
601 window->state () & CompWindowStateHiddenMask) && window->hasUnmapReference ())581 window->state () & CompWindowStateHiddenMask) && window->hasUnmapReference ())
602 {582 {
@@ -627,9 +607,9 @@
627607
628 x1 = x - window->output ().left - dx;608 x1 = x - window->output ().left - dx;
629 y1 = y - window->output ().top - dy;609 y1 = y - window->output ().top - dy;
630 x2 = x + window->size ().width () +610 x2 = x + window->geometry ().width () +
631 window->output ().right - dx;611 window->output ().right - dx;
632 y2 = y + window->size ().height () +612 y2 = y + window->geometry ().height () +
633 window->output ().bottom - dy;613 window->output ().bottom - dy;
634614
635 cScreen->damageRegion (CompRegion (CompRect (x1, y1, x2 - x1, y2 - y1)));615 cScreen->damageRegion (CompRegion (CompRect (x1, y1, x2 - x1, y2 - y1)));
636616
=== modified file 'plugins/decor/src/decor.cpp'
--- plugins/decor/src/decor.cpp 2012-04-20 10:40:23 +0000
+++ plugins/decor/src/decor.cpp 2012-04-23 05:39:20 +0000
@@ -223,30 +223,38 @@
223223
224 const CompRegion *preg = NULL;224 const CompRegion *preg = NULL;
225225
226 if ((mask & (PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK |226 if (mClipGroup)
227 PAINT_WINDOW_WITH_OFFSET_MASK)))
228 preg = &region;
229 else if (mask & PAINT_WINDOW_TRANSFORMED_MASK)
230 preg = &infiniteRegion;
231 else
232 {227 {
233 tmpRegion = mOutputRegion;228 if ((mask & (PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK |
234 tmpRegion &= region;229 PAINT_WINDOW_WITH_OFFSET_MASK)))
235
236 if (tmpRegion.isEmpty ())
237 preg = &region;230 preg = &region;
231 else if (mask & PAINT_WINDOW_TRANSFORMED_MASK)
232 preg = &infiniteRegion;
238 else233 else
239 preg = &shadowRegion;234 {
235 tmpRegion = mOutputRegion;
236 tmpRegion &= region;
237
238 if (tmpRegion.isEmpty ())
239 preg = &region;
240 else
241 preg = &shadowRegion;
242 }
243
244 /* In case some plugin needs to paint us with an offset region */
245 if (preg->isEmpty ())
246 preg = &region;
240 }247 }
241248 else
242 /* In case some plugin needs to paint us with an offset region */
243 if (preg->isEmpty ())
244 preg = &region;249 preg = &region;
245250
246 const CompRegion &reg (*preg);251 const CompRegion &reg (*preg);
247252
248 gWindow->geometry ().reset ();253 gWindow->geometry ().reset ();
249254
255 if (updateMatrix)
256 updateDecorationScale ();
257
250 for (int i = 0; i < wd->nQuad; i++)258 for (int i = 0; i < wd->nQuad; i++)
251 {259 {
252 box.setGeometry (wd->quad[i].box.x1,260 box.setGeometry (wd->quad[i].box.x1,
@@ -275,6 +283,9 @@
275 if (gWindow->textures ().empty ())283 if (gWindow->textures ().empty ())
276 return;284 return;
277285
286 if (updateMatrix)
287 updateDecorationScale ();
288
278 if (gWindow->textures ().size () == 1)289 if (gWindow->textures ().size () == 1)
279 {290 {
280 ml[0] = gWindow->matrices ()[0];291 ml[0] = gWindow->matrices ()[0];
@@ -1017,6 +1028,8 @@
1017 wd->quad[i].box.y1 * wd->quad[i].matrix.yy +1028 wd->quad[i].box.y1 * wd->quad[i].matrix.yy +
1018 wd->quad[i].box.x1 * wd->quad[i].matrix.yx;1029 wd->quad[i].box.x1 * wd->quad[i].matrix.yx;
1019 }1030 }
1031
1032 updateMatrix = false;
1020}1033}
10211034
1022/*1035/*
@@ -1047,7 +1060,16 @@
1047 unsigned int height = window->size ().height ();1060 unsigned int height = window->size ().height ();
10481061
1049 if (window->shaded ())1062 if (window->shaded ())
1050 height = 0;1063 {
1064 if (dScreen->cScreen &&
1065 dScreen->cScreen->compositingActive ())
1066 {
1067 if (!cWindow->pixmap ())
1068 height = 0;
1069 }
1070 else
1071 height = 0;
1072 }
10511073
1052 computeQuadBox (&wd->decor->quad[i], width, height,1074 computeQuadBox (&wd->decor->quad[i], width, height,
1053 &x1, &y1, &x2, &y2, &sx, &sy);1075 &x1, &y1, &x2, &y2, &sx, &sy);
@@ -1060,6 +1082,7 @@
1060 wd->quad[i].box.y1 = y1 + y;1082 wd->quad[i].box.y1 = y1 + y;
1061 wd->quad[i].box.x2 = x2 + x;1083 wd->quad[i].box.x2 = x2 + x;
1062 wd->quad[i].box.y2 = y2 + y;1084 wd->quad[i].box.y2 = y2 + y;
1085
1063 wd->quad[i].sx = sx;1086 wd->quad[i].sx = sx;
1064 wd->quad[i].sy = sy;1087 wd->quad[i].sy = sy;
1065 }1088 }
@@ -1083,7 +1106,7 @@
1083DecorWindow::checkSize (const Decoration::Ptr &decoration)1106DecorWindow::checkSize (const Decoration::Ptr &decoration)
1084{1107{
1085 return (decoration->minWidth <= (int) window->size ().width () &&1108 return (decoration->minWidth <= (int) window->size ().width () &&
1086 decoration->minHeight <= (int) window->size ().height ());1109 decoration->minHeight <= (int) window->size ().height ());
1087}1110}
10881111
1089/*1112/*
@@ -1523,6 +1546,9 @@
1523 if (decorate)1546 if (decorate)
1524 updateFrame ();1547 updateFrame ();
1525 window->updateWindowOutputExtents ();1548 window->updateWindowOutputExtents ();
1549
1550 updateReg = true;
1551 updateMatrix = true;
1526 mOutputRegion = CompRegion (window->outputRect ());1552 mOutputRegion = CompRegion (window->outputRect ());
1527 updateGroupShadows ();1553 updateGroupShadows ();
1528 if (dScreen->cmActive)1554 if (dScreen->cmActive)
@@ -1686,7 +1712,6 @@
1686 XRectangle rects[4];1712 XRectangle rects[4];
1687 int x, y, width, height;1713 int x, y, width, height;
1688 CompWindow::Geometry server = window->serverGeometry ();1714 CompWindow::Geometry server = window->serverGeometry ();
1689 int bw = server.border () * 2;
1690 CompWindowExtents input;1715 CompWindowExtents input;
1691 CompWindowExtents border;1716 CompWindowExtents border;
1692 Window parent;1717 Window parent;
@@ -1713,8 +1738,8 @@
17131738
1714 x = window->border ().left - border.left;1739 x = window->border ().left - border.left;
1715 y = window->border ().top - border.top;1740 y = window->border ().top - border.top;
1716 width = server.width () + input.left + input.right + bw;1741 width = server.widthIncBorders () + input.left + input.right;
1717 height = server.height ()+ input.top + input.bottom + bw;1742 height = server.heightIncBorders ()+ input.top + input.bottom ;
17181743
1719 /* Non switcher windows are rooted relative to the frame window of the client1744 /* Non switcher windows are rooted relative to the frame window of the client
1720 * and switchers need to be offset by the window geometry of the client */1745 * and switchers need to be offset by the window geometry of the client */
@@ -1853,7 +1878,6 @@
1853 XRectangle rects[4];1878 XRectangle rects[4];
1854 int x, y, width, height;1879 int x, y, width, height;
1855 CompWindow::Geometry server = window->serverGeometry ();1880 CompWindow::Geometry server = window->serverGeometry ();
1856 int bw = server.border () * 2;
1857 CompWindowExtents input;1881 CompWindowExtents input;
18581882
1859 /* Determine frame extents */1883 /* Determine frame extents */
@@ -1864,8 +1888,8 @@
18641888
1865 x = window->input ().left - input.left;1889 x = window->input ().left - input.left;
1866 y = window->input ().top - input.top;1890 y = window->input ().top - input.top;
1867 width = server.width () + input.left + input.right + bw;1891 width = server.widthIncBorders () + input.left + input.right;
1868 height = server.height ()+ input.top + input.bottom + bw;1892 height = server.heightIncBorders ()+ input.top + input.bottom;
18691893
1870 if (window->shaded ())1894 if (window->shaded ())
1871 height = input.top + input.bottom;1895 height = input.top + input.bottom;
@@ -2107,7 +2131,9 @@
2107 region += infiniteRegion;2131 region += infiniteRegion;
2108 }2132 }
2109 }2133 }
2134
2110 updateReg = true;2135 updateReg = true;
2136 updateMatrix = true;
2111}2137}
21122138
2113/*2139/*
@@ -2129,6 +2155,7 @@
2129 regions[i].translate (input.x (), input.y ());2155 regions[i].translate (input.x (), input.y ());
2130 regions[i] &= window->frameRegion ();2156 regions[i] &= window->frameRegion ();
2131 }2157 }
2158
2132 updateReg = false;2159 updateReg = false;
2133}2160}
21342161
@@ -2159,6 +2186,7 @@
2159 * anyways, since the window is unmapped. Also need to2186 * anyways, since the window is unmapped. Also need to
2160 * update the shadow clip regions for panels and other windows */2187 * update the shadow clip regions for panels and other windows */
2161 update (true);2188 update (true);
2189 updateDecorationScale ();
2162 if (dScreen->mMenusClipGroup.pushClippable (this))2190 if (dScreen->mMenusClipGroup.pushClippable (this))
2163 updateGroupShadows ();2191 updateGroupShadows ();
21642192
@@ -2180,7 +2208,7 @@
2180 * anyways, since the window is unmapped. Also need to2208 * anyways, since the window is unmapped. Also need to
2181 * update the shadow clip regions for panels and other windows */2209 * update the shadow clip regions for panels and other windows */
2182 update (true);2210 update (true);
21832211 updateDecorationScale ();
2184 /* Preserve the group shadow update ptr */2212 /* Preserve the group shadow update ptr */
2185 DecorClipGroupInterface *clipGroup = mClipGroup;2213 DecorClipGroupInterface *clipGroup = mClipGroup;
21862214
@@ -2367,6 +2395,7 @@
2367 if (w)2395 if (w)
2368 {2396 {
2369 DECOR_WINDOW (w);2397 DECOR_WINDOW (w);
2398
2370 dw->updateDecoration ();2399 dw->updateDecoration ();
23712400
2372 dw->update (true);2401 dw->update (true);
@@ -2702,10 +2731,10 @@
2702 wd->quad[i].box.x2 += dx;2731 wd->quad[i].box.x2 += dx;
2703 wd->quad[i].box.y2 += dy;2732 wd->quad[i].box.y2 += dy;
2704 }2733 }
2705
2706 setDecorationMatrices ();
2707 }2734 }
2735
2708 updateReg = true;2736 updateReg = true;
2737 updateMatrix = true;
27092738
2710 mInputRegion.translate (dx, dy);2739 mInputRegion.translate (dx, dy);
2711 mOutputRegion.translate (dx, dy);2740 mOutputRegion.translate (dx, dy);
@@ -2717,32 +2746,6 @@
2717}2746}
27182747
2719/*2748/*
2720 * DecorWindow::resizeTimeout
2721 *
2722 * Called from the timeout on ::resizeNotify,
2723 * set the shading and unshading bits and also
2724 * updates the decoration. See the comment
2725 * in ::resizeNotify as to why the timeout
2726 * is necessary here
2727 *
2728 */
2729bool
2730DecorWindow::resizeTimeout ()
2731{
2732 if (shading || unshading)
2733 {
2734 shading = false;
2735 unshading = false;
2736
2737 updateDecoration ();
2738 }
2739
2740 if (!window->hasUnmapReference ())
2741 update (true);
2742 return false;
2743}
2744
2745/*
2746 * DecorWindow::resizeNotify2749 * DecorWindow::resizeNotify
2747 *2750 *
2748 * Called whenever a window is resized. Update scaled quads and 2751 * Called whenever a window is resized. Update scaled quads and
@@ -2753,6 +2756,11 @@
2753void2756void
2754DecorWindow::resizeNotify (int dx, int dy, int dwidth, int dheight)2757DecorWindow::resizeNotify (int dx, int dy, int dwidth, int dheight)
2755{2758{
2759 if (shading || unshading)
2760 {
2761 shading = false;
2762 unshading = false;
2763 }
2756 /* FIXME: we should not need a timer for calling decorWindowUpdate,2764 /* FIXME: we should not need a timer for calling decorWindowUpdate,
2757 and only call updateWindowDecorationScale if decorWindowUpdate2765 and only call updateWindowDecorationScale if decorWindowUpdate
2758 returns false. Unfortunately, decorWindowUpdate may call2766 returns false. Unfortunately, decorWindowUpdate may call
@@ -2760,8 +2768,7 @@
2760 we never should call a wrapped function that's currently2768 we never should call a wrapped function that's currently
2761 processed, we need the timer for the moment. updateWindowOutputExtents2769 processed, we need the timer for the moment. updateWindowOutputExtents
2762 should be fixed so that it does not emit a resize notification. */2770 should be fixed so that it does not emit a resize notification. */
2763 resizeUpdate.start (boost::bind (&DecorWindow::resizeTimeout, this), 0);2771 updateMatrix = true;
2764 updateDecorationScale ();
2765 updateReg = true;2772 updateReg = true;
27662773
2767 mInputRegion = CompRegion (window->inputRect ());2774 mInputRegion = CompRegion (window->inputRect ());
@@ -2769,7 +2776,12 @@
2769 if (dScreen->cmActive && mClipGroup)2776 if (dScreen->cmActive && mClipGroup)
2770 updateGroupShadows ();2777 updateGroupShadows ();
27712778
2779 updateReg = true;
2780
2772 window->resizeNotify (dx, dy, dwidth, dheight);2781 window->resizeNotify (dx, dy, dwidth, dheight);
2782
2783 /* FIXME: remove */
2784 CompositeScreen::get (screen)->damageScreen ();
2773}2785}
27742786
27752787
@@ -3007,6 +3019,7 @@
3007 pixmapFailed (false),3019 pixmapFailed (false),
3008 regions (),3020 regions (),
3009 updateReg (true),3021 updateReg (true),
3022 updateMatrix (true),
3010 unshading (false),3023 unshading (false),
3011 shading (false),3024 shading (false),
3012 isSwitcher (false),3025 isSwitcher (false),
30133026
=== modified file 'plugins/decor/src/decor.h'
--- plugins/decor/src/decor.h 2012-04-20 10:09:00 +0000
+++ plugins/decor/src/decor.h 2012-04-23 05:39:20 +0000
@@ -159,7 +159,7 @@
159159
160class WindowDecoration {160class WindowDecoration {
161 public:161 public:
162 static WindowDecoration * create (const Decoration::Ptr &);162 static WindowDecoration * create (const Decoration::Ptr &d);
163 static void destroy (WindowDecoration *);163 static void destroy (WindowDecoration *);
164164
165 public:165 public:
@@ -250,8 +250,6 @@
250250
251 bool damageRect (bool, const CompRect &);251 bool damageRect (bool, const CompRect &);
252252
253 void computeShadowRegion ();
254
255 bool glDraw (const GLMatrix &, GLFragment::Attrib &,253 bool glDraw (const GLMatrix &, GLFragment::Attrib &,
256 const CompRegion &, unsigned int);254 const CompRegion &, unsigned int);
257 void glDecorate (const GLMatrix &, GLFragment::Attrib &,255 void glDecorate (const GLMatrix &, GLFragment::Attrib &,
@@ -322,6 +320,7 @@
322320
323 CompRegion::Vector regions;321 CompRegion::Vector regions;
324 bool updateReg;322 bool updateReg;
323 bool updateMatrix;
325324
326 CompTimer resizeUpdate;325 CompTimer resizeUpdate;
327 CompTimer moveUpdate;326 CompTimer moveUpdate;
328327
=== modified file 'plugins/move/src/move.cpp'
--- plugins/move/src/move.cpp 2012-02-16 05:31:28 +0000
+++ plugins/move/src/move.cpp 2012-04-23 05:39:20 +0000
@@ -316,10 +316,8 @@
316316
317 wX = w->geometry ().x ();317 wX = w->geometry ().x ();
318 wY = w->geometry ().y ();318 wY = w->geometry ().y ();
319 wWidth = w->geometry ().width () +319 wWidth = w->geometry ().widthIncBorders ();
320 w->geometry ().border () * 2;320 wHeight = w->geometry ().heightIncBorders ();
321 wHeight = w->geometry ().height () +
322 w->geometry ().border () * 2;
323321
324 ms->x += xRoot - lastPointerX;322 ms->x += xRoot - lastPointerX;
325 ms->y += yRoot - lastPointerY;323 ms->y += yRoot - lastPointerY;
326324
=== modified file 'plugins/opengl/src/paint.cpp'
--- plugins/opengl/src/paint.cpp 2012-03-19 09:19:04 +0000
+++ plugins/opengl/src/paint.cpp 2012-04-23 05:39:20 +0000
@@ -1194,7 +1194,7 @@
1194 !priv->cWindow->damaged ())1194 !priv->cWindow->damaged ())
1195 return true;1195 return true;
11961196
1197 if (priv->textures.empty () && !bind ())1197 if (textures ().empty () && !bind ())
1198 return false;1198 return false;
11991199
1200 if (mask & PAINT_WINDOW_TRANSLUCENT_MASK)1200 if (mask & PAINT_WINDOW_TRANSLUCENT_MASK)
@@ -1210,26 +1210,19 @@
1210 //1210 //
1211 priv->gScreen->setTexEnvMode (GL_REPLACE);1211 priv->gScreen->setTexEnvMode (GL_REPLACE);
12121212
1213 if (priv->textures.size () == 1)1213 if (priv->updateState & PrivateGLWindow::UpdateMatrix)
1214 priv->setWindowMatrix ();
1215
1216 if (priv->updateState & PrivateGLWindow::UpdateRegion)
1217 priv->updateWindowRegions ();
1218
1219 for (unsigned int i = 0; i < textures ().size (); i++)
1214 {1220 {
1215 ml[0] = priv->matrices[0];1221 ml[0] = priv->matrices[i];
1216 priv->geometry.reset ();1222 priv->geometry.reset ();
1217 glAddGeometry (ml, priv->window->region (), reg);1223 glAddGeometry (ml, priv->regions[i], reg);
1218 if (priv->geometry.vCount)1224 if (priv->geometry.vCount)
1219 glDrawTexture (priv->textures[0], fragment, mask);1225 glDrawTexture (textures ()[i], fragment, mask);
1220 }
1221 else
1222 {
1223 if (priv->updateReg)
1224 priv->updateWindowRegions ();
1225 for (unsigned int i = 0; i < priv->textures.size (); i++)
1226 {
1227 ml[0] = priv->matrices[i];
1228 priv->geometry.reset ();
1229 glAddGeometry (ml, priv->regions[i], reg);
1230 if (priv->geometry.vCount)
1231 glDrawTexture (priv->textures[i], fragment, mask);
1232 }
1233 }1226 }
12341227
1235 return true;1228 return true;
12361229
=== modified file 'plugins/opengl/src/privates.h'
--- plugins/opengl/src/privates.h 2012-04-20 07:35:20 +0000
+++ plugins/opengl/src/privates.h 2012-04-23 05:39:20 +0000
@@ -132,6 +132,11 @@
132 public CompositeWindowInterface132 public CompositeWindowInterface
133{133{
134 public:134 public:
135
136 static const unsigned int UpdateRegion = 1 << 0;
137 static const unsigned int UpdateMatrix = 1 << 1;
138
139 public:
135 PrivateGLWindow (CompWindow *w, GLWindow *gw);140 PrivateGLWindow (CompWindow *w, GLWindow *gw);
136 ~PrivateGLWindow ();141 ~PrivateGLWindow ();
137142
@@ -151,7 +156,8 @@
151 GLTexture::List textures;156 GLTexture::List textures;
152 GLTexture::MatrixList matrices;157 GLTexture::MatrixList matrices;
153 CompRegion::Vector regions;158 CompRegion::Vector regions;
154 bool updateReg;159 unsigned int updateState;
160 bool needsRebind;
155161
156 CompRegion clip;162 CompRegion clip;
157163
158164
=== modified file 'plugins/opengl/src/window.cpp'
--- plugins/opengl/src/window.cpp 2012-03-22 17:00:51 +0000
+++ plugins/opengl/src/window.cpp 2012-04-23 05:39:20 +0000
@@ -54,7 +54,8 @@
54 gScreen (GLScreen::get (screen)),54 gScreen (GLScreen::get (screen)),
55 textures (),55 textures (),
56 regions (),56 regions (),
57 updateReg (true),57 updateState (UpdateRegion | UpdateMatrix),
58 needsRebind (true),
58 clip (),59 clip (),
59 bindFailed (false),60 bindFailed (false),
60 geometry (),61 geometry (),
@@ -87,28 +88,41 @@
87 matrices[i].x0 -= (input.x () * matrices[i].xx);88 matrices[i].x0 -= (input.x () * matrices[i].xx);
88 matrices[i].y0 -= (input.y () * matrices[i].yy);89 matrices[i].y0 -= (input.y () * matrices[i].yy);
89 }90 }
91
92 updateState &= ~(UpdateMatrix);
90}93}
9194
92bool95bool
93GLWindow::bind ()96GLWindow::bind ()
94{97{
95 if ((!priv->cWindow->pixmap () && !priv->cWindow->bind ()))98 if ((!priv->cWindow->pixmap () && !priv->cWindow->bind ()))
96 return false;99 {
100 if (!priv->textures.empty ())
101 {
102 /* Getting a new pixmap failed, recycle the old texture */
103 priv->needsRebind = false;
104 return true;
105 }
106 }
97107
98 priv->textures =108 GLTexture::List textures =
99 GLTexture::bindPixmapToTexture (priv->cWindow->pixmap (),109 GLTexture::bindPixmapToTexture (priv->cWindow->pixmap (),
100 priv->cWindow->size ().width (),110 priv->cWindow->size ().width (),
101 priv->cWindow->size ().height (),111 priv->cWindow->size ().height (),
102 priv->window->depth ());112 priv->window->depth ());
103 if (priv->textures.empty ())113 if (textures.empty ())
104 {114 {
105 compLogMessage ("opengl", CompLogLevelInfo,115 compLogMessage ("opengl", CompLogLevelInfo,
106 "Couldn't bind redirected window 0x%x to "116 "Couldn't bind redirected window 0x%x to "
107 "texture\n", (int) priv->window->id ());117 "texture\n", (int) priv->window->id ());
108 }118 }
119 else
120 {
121 priv->textures = textures;
122 priv->needsRebind = false;
123 }
109124
110 priv->setWindowMatrix ();125 priv->updateState |= PrivateGLWindow::UpdateRegion | PrivateGLWindow::UpdateMatrix;
111 priv->updateReg = true;
112126
113 return true;127 return true;
114}128}
@@ -116,12 +130,12 @@
116void130void
117GLWindow::release ()131GLWindow::release ()
118{132{
119 priv->textures.clear ();133 /* Release the pixmap but don't release
120134 * the texture (yet) */
121 if (priv->cWindow->pixmap ())135 if (priv->cWindow->pixmap ())
122 {
123 priv->cWindow->release ();136 priv->cWindow->release ();
124 }137
138 priv->needsRebind = true;
125}139}
126140
127bool141bool
@@ -180,8 +194,7 @@
180PrivateGLWindow::resizeNotify (int dx, int dy, int dwidth, int dheight)194PrivateGLWindow::resizeNotify (int dx, int dy, int dwidth, int dheight)
181{195{
182 window->resizeNotify (dx, dy, dwidth, dheight);196 window->resizeNotify (dx, dy, dwidth, dheight);
183 setWindowMatrix ();197 updateState |= PrivateGLWindow::UpdateMatrix | PrivateGLWindow::UpdateRegion;
184 updateReg = true;
185 if (!window->hasUnmapReference ())198 if (!window->hasUnmapReference ())
186 gWindow->release ();199 gWindow->release ();
187}200}
@@ -190,8 +203,10 @@
190PrivateGLWindow::moveNotify (int dx, int dy, bool now)203PrivateGLWindow::moveNotify (int dx, int dy, bool now)
191{204{
192 window->moveNotify (dx, dy, now);205 window->moveNotify (dx, dy, now);
193 updateReg = true;206 updateState |= PrivateGLWindow::UpdateMatrix;
194 setWindowMatrix ();207
208 foreach (CompRegion &r, regions)
209 r.translate (dx, dy);
195}210}
196211
197void212void
@@ -298,6 +313,13 @@
298const GLTexture::List &313const GLTexture::List &
299GLWindow::textures () const314GLWindow::textures () const
300{315{
316 static const GLTexture::List emptyList;
317
318 /* No pixmap backs this window, let
319 * users know that the window needs rebinding */
320 if (priv->needsRebind)
321 return emptyList;
322
301 return priv->textures;323 return priv->textures;
302}324}
303325
@@ -338,13 +360,13 @@
338PrivateGLWindow::updateFrameRegion (CompRegion &region)360PrivateGLWindow::updateFrameRegion (CompRegion &region)
339{361{
340 window->updateFrameRegion (region);362 window->updateFrameRegion (region);
341 updateReg = true;363 updateState |= PrivateGLWindow::UpdateRegion;
342}364}
343365
344void366void
345PrivateGLWindow::updateWindowRegions ()367PrivateGLWindow::updateWindowRegions ()
346{368{
347 CompRect input (window->inputRect ());369 CompRect input (window->serverInputRect ());
348370
349 if (regions.size () != textures.size ())371 if (regions.size () != textures.size ())
350 regions.resize (textures.size ());372 regions.resize (textures.size ());
@@ -354,7 +376,7 @@
354 regions[i].translate (input.x (), input.y ());376 regions[i].translate (input.x (), input.y ());
355 regions[i] &= window->region ();377 regions[i] &= window->region ();
356 }378 }
357 updateReg = false;379 updateState &= ~(UpdateRegion);
358}380}
359381
360unsigned int382unsigned int
361383
=== modified file 'plugins/place/src/constrain-to-workarea/src/constrain-to-workarea.cpp'
--- plugins/place/src/constrain-to-workarea/src/constrain-to-workarea.cpp 2012-01-20 06:13:07 +0000
+++ plugins/place/src/constrain-to-workarea/src/constrain-to-workarea.cpp 2012-04-23 05:39:20 +0000
@@ -61,13 +61,11 @@
61 }61 }
6262
63 left = x - border.left;63 left = x - border.left;
64 right = left + g.width () + (border.left +64 right = left + g.widthIncBorders () + (border.left +
65 border.right +65 border.right);
66 2 * g.border ());
67 top = y - border.top;66 top = y - border.top;
68 bottom = top + g.height () + (border.top +67 bottom = top + g.heightIncBorders () + (border.top +
69 border.bottom +68 border.bottom);
70 2 * g.border ());
7169
72 if ((right - left) > workArea.width ())70 if ((right - left) > workArea.width ())
73 {71 {
7472
=== modified file 'plugins/place/src/place.cpp'
--- plugins/place/src/place.cpp 2012-02-02 17:01:15 +0000
+++ plugins/place/src/place.cpp 2012-04-23 05:39:20 +0000
@@ -343,37 +343,36 @@
343 CompWindow::Geometry geom;343 CompWindow::Geometry geom;
344 int output;344 int output;
345345
346 geom.set (xwc->x, xwc->y, xwc->width, xwc->height,
347 window->serverGeometry ().border ());
348
346 if (clampToViewport)349 if (clampToViewport)
347 {350 {
348 /* left, right, top, bottom target coordinates, clamed to viewport351 /* left, right, top, bottom target coordinates, clamed to viewport
349 * sizes as we don't need to validate movements to other viewports;352 * sizes as we don't need to validate movements to other viewports;
350 * we are only interested in inner-viewport movements */353 * we are only interested in inner-viewport movements */
351354
352 x = xwc->x % screen->width ();355 x = geom.x () % screen->width ();
353 if ((x + xwc->width) < 0)356 if ((geom.x2 ()) < 0)
354 x += screen->width ();357 x += screen->width ();
355358
356 y = xwc->y % screen->height ();359 y = geom.y () % screen->height ();
357 if ((y + xwc->height) < 0)360 if ((geom.y2 ()) < 0)
358 y += screen->height ();361 y += screen->height ();
359 }362 }
360 else363 else
361 {364 {
362 x = xwc->x;365 x = geom.x ();
363 y = xwc->y;366 y = geom.y ();
364 }367 }
365368
366 left = x - window->border ().left;369 left = x - window->border ().left;
367 right = left + xwc->width + (window->border ().left +370 right = left + geom.widthIncBorders () + (window->border ().left +
368 window->border ().right +371 window->border ().right);
369 2 * window->serverGeometry ().border ());
370 top = y - window->border ().top;372 top = y - window->border ().top;
371 bottom = top + xwc->height + (window->border ().top +373 bottom = top + geom.heightIncBorders () + (window->border ().top +
372 window->border ().bottom +374 window->border ().bottom);
373 2 * window->serverGeometry ().border ());
374375
375 geom.set (xwc->x, xwc->y, xwc->width, xwc->height,
376 window->serverGeometry ().border ());
377 output = screen->outputDeviceForGeometry (geom);376 output = screen->outputDeviceForGeometry (geom);
378 workArea = screen->getWorkareaForOutput (output);377 workArea = screen->getWorkareaForOutput (output);
379378
@@ -746,10 +745,8 @@
746{745{
747 if (PlaceScreen::get (screen)->getPointerPosition (pos))746 if (PlaceScreen::get (screen)->getPointerPosition (pos))
748 {747 {
749 unsigned int dx = (window->serverGeometry ().width () / 2) -748 unsigned int dx = (window->serverGeometry ().widthIncBorders () / 2);
750 window->serverGeometry ().border ();749 unsigned int dy = (window->serverGeometry ().heightIncBorders () / 2);
751 unsigned int dy = (window->serverGeometry ().height () / 2) -
752 window->serverGeometry ().border ();
753 pos -= CompPoint (dx, dy);750 pos -= CompPoint (dx, dy);
754 }751 }
755 else752 else
@@ -1200,14 +1197,12 @@
12001197
1201 extents.left = pos.x () - window->border ().left;1198 extents.left = pos.x () - window->border ().left;
1202 extents.top = pos.y () - window->border ().top;1199 extents.top = pos.y () - window->border ().top;
1203 extents.right = extents.left + window->serverWidth () +1200 extents.right = extents.left + window->serverGeometry ().heightIncBorders () +
1204 (window->border ().left +1201 (window->border ().left +
1205 window->border ().right +1202 window->border ().right);
1206 2 * window->serverGeometry ().border ());1203 extents.bottom = extents.top + window->serverGeometry ().widthIncBorders () +
1207 extents.bottom = extents.top + window->serverHeight () +
1208 (window->border ().top +1204 (window->border ().top +
1209 window->border ().bottom +1205 window->border ().bottom);
1210 2 * window->serverGeometry ().border ());
12111206
1212 delta = workArea.right () - extents.right;1207 delta = workArea.right () - extents.right;
1213 if (delta < 0)1208 if (delta < 0)
12141209
=== modified file 'plugins/resize/src/resize.cpp'
--- plugins/resize/src/resize.cpp 2012-02-16 05:31:28 +0000
+++ plugins/resize/src/resize.cpp 2012-04-23 05:39:20 +0000
@@ -642,8 +642,7 @@
642 w->configureXWindow (mask, &xwc);642 w->configureXWindow (mask, &xwc);
643 }643 }
644644
645 if (!(mask & (CWWidth | CWHeight)))645 rs->finishResizing ();
646 rs->finishResizing ();
647646
648 if (rs->grabIndex)647 if (rs->grabIndex)
649 {648 {
@@ -1510,15 +1509,6 @@
1510}1509}
15111510
1512void1511void
1513ResizeWindow::resizeNotify (int dx, int dy, int dwidth, int dheight)
1514{
1515 window->resizeNotify (dx, dy, dwidth, dheight);
1516
1517 if (rScreen->w == window && !rScreen->grabIndex)
1518 rScreen->finishResizing ();
1519}
1520
1521void
1522ResizeScreen::glPaintRectangle (const GLScreenPaintAttrib &sAttrib,1512ResizeScreen::glPaintRectangle (const GLScreenPaintAttrib &sAttrib,
1523 const GLMatrix &transform,1513 const GLMatrix &transform,
1524 CompOutput *output,1514 CompOutput *output,
15251515
=== modified file 'plugins/resize/src/resize.h'
--- plugins/resize/src/resize.h 2012-02-09 07:48:57 +0000
+++ plugins/resize/src/resize.h 2012-04-23 05:39:20 +0000
@@ -162,8 +162,6 @@
162 ResizeWindow (CompWindow *w);162 ResizeWindow (CompWindow *w);
163 ~ResizeWindow ();163 ~ResizeWindow ();
164164
165 void resizeNotify (int, int, int, int);
166
167 bool damageRect (bool, const CompRect &);165 bool damageRect (bool, const CompRect &);
168166
169 bool glPaint (const GLWindowPaintAttrib &, const GLMatrix &,167 bool glPaint (const GLWindowPaintAttrib &, const GLMatrix &,
170168
=== modified file 'plugins/wobbly/src/wobbly.cpp'
--- plugins/wobbly/src/wobbly.cpp 2011-03-14 16:12:45 +0000
+++ plugins/wobbly/src/wobbly.cpp 2012-04-23 05:39:20 +0000
@@ -1772,7 +1772,7 @@
17721772
1773 if (ww->isWobblyWin () && ww->ensureModel ())1773 if (ww->isWobblyWin () && ww->ensureModel ())
1774 {1774 {
1775 CompRect outRect (w->outputRect ());1775 CompRect outRect (w->serverOutputRect ());
17761776
1777 ww->model->setMiddleAnchor (outRect.x (), outRect.y (),1777 ww->model->setMiddleAnchor (outRect.x (), outRect.y (),
1778 outRect.width (), outRect.height ());1778 outRect.width (), outRect.height ());
@@ -1901,7 +1901,7 @@
1901 switch (focusEffect) {1901 switch (focusEffect) {
1902 case WobblyOptions::FocusEffectShiver:1902 case WobblyOptions::FocusEffectShiver:
1903 {1903 {
1904 CompRect outRect (w->outputRect ());1904 CompRect outRect (w->serverOutputRect ());
19051905
1906 ww->model->adjustObjectsForShiver (outRect.x (),1906 ww->model->adjustObjectsForShiver (outRect.x (),
1907 outRect.y (),1907 outRect.y (),
@@ -2131,7 +2131,8 @@
2131 }2131 }
2132 wScreen->moveWindow = false;2132 wScreen->moveWindow = false;
21332133
2134 if ((mask & CompWindowGrabButtonMask) &&2134 if (mask & (CompWindowGrabButtonMask) &&
2135 mask & (CompWindowGrabMoveMask) &&
2135 wScreen->optionGetMoveWindowMatch ().evaluate (window) &&2136 wScreen->optionGetMoveWindowMatch ().evaluate (window) &&
2136 isWobblyWin ())2137 isWobblyWin ())
2137 {2138 {
@@ -2192,7 +2193,7 @@
2192 if (wScreen->yConstrained)2193 if (wScreen->yConstrained)
2193 {2194 {
2194 int output =2195 int output =
2195 ::screen->outputDeviceForGeometry (window->geometry ());2196 ::screen->outputDeviceForGeometry (window->serverGeometry ());
2196 wScreen->constraintBox =2197 wScreen->constraintBox =
2197 &::screen->outputDevs ()[output].workArea ();2198 &::screen->outputDevs ()[output].workArea ();
2198 }2199 }
21992200
=== modified file 'src/event.cpp'
--- src/event.cpp 2012-04-05 16:25:37 +0000
+++ src/event.cpp 2012-04-23 05:39:20 +0000
@@ -1251,7 +1251,7 @@
1251 }1251 }
12521252
1253 /* been shaded */1253 /* been shaded */
1254 if (w->priv->height == 0)1254 if (w->shaded ())
1255 {1255 {
1256 if (w->id () == priv->activeWindow)1256 if (w->id () == priv->activeWindow)
1257 w->moveInputFocusTo ();1257 w->moveInputFocusTo ();
12581258
=== modified file 'src/privatewindow.h'
--- src/privatewindow.h 2012-03-02 18:02:07 +0000
+++ src/privatewindow.h 2012-04-23 05:39:20 +0000
@@ -34,7 +34,6 @@
34#include <core/timer.h>34#include <core/timer.h>
35#include "privatescreen.h"35#include "privatescreen.h"
3636
37
38typedef CompWindowExtents CompFullscreenMonitorSet;37typedef CompWindowExtents CompFullscreenMonitorSet;
3938
40class PrivateWindow {39class PrivateWindow {
@@ -167,6 +166,11 @@
167166
168 bool handleSyncAlarm ();167 bool handleSyncAlarm ();
169168
169 void move (int dx, int dy, bool sync);
170 bool resize (int dx, int dy, int dwidth, int dheight, int dborder);
171 bool resize (const CompWindow::Geometry &g);
172 bool resize (const XWindowAttributes &attrib);
173
170 void configure (XConfigureEvent *ce);174 void configure (XConfigureEvent *ce);
171175
172 void configureFrame (XConfigureEvent *ce);176 void configureFrame (XConfigureEvent *ce);
@@ -241,13 +245,8 @@
241 XSizeHints sizeHints;245 XSizeHints sizeHints;
242 XWMHints *hints;246 XWMHints *hints;
243247
244 struct timeval lastGeometryUpdate;
245 struct timeval lastConfigureRequest;
246
247 bool inputHint;248 bool inputHint;
248 bool alpha;249 bool alpha;
249 int width;
250 int height;
251 CompRegion region;250 CompRegion region;
252 CompRegion inputRegion;251 CompRegion inputRegion;
253 CompRegion frameRegion;252 CompRegion frameRegion;
@@ -290,8 +289,6 @@
290 typedef std::pair <XWindowChanges, unsigned int> XWCValueMask;289 typedef std::pair <XWindowChanges, unsigned int> XWCValueMask;
291290
292 compiz::X11::PendingEventQueue pendingConfigures;291 compiz::X11::PendingEventQueue pendingConfigures;
293 CompTimer mClearCheckTimeout;
294 bool pendingPositionUpdates;
295292
296 char *startupId;293 char *startupId;
297 char *resName;294 char *resName;
@@ -327,6 +324,8 @@
327324
328 bool closeRequests;325 bool closeRequests;
329 Time lastCloseRequestTime;326 Time lastCloseRequestTime;
327
328 bool nextMoveImmediate;
330};329};
331330
332#endif331#endif
333332
=== modified file 'src/screen.cpp'
--- src/screen.cpp 2012-04-20 09:58:29 +0000
+++ src/screen.cpp 2012-04-23 05:39:20 +0000
@@ -4071,8 +4071,8 @@
4071 CompRect rect (gm);4071 CompRect rect (gm);
4072 int offset;4072 int offset;
40734073
4074 rect.setWidth (rect.width () + (gm.border () * 2));4074 rect.setWidth (gm.widthIncBorders ());
4075 rect.setHeight (rect.height () + (gm.border () * 2));4075 rect.setHeight (gm.heightIncBorders ());
40764076
4077 offset = rect.centerX () < 0 ? -1 : 0;4077 offset = rect.centerX () < 0 ? -1 : 0;
4078 viewport.setX (priv->vp.x () + ((rect.centerX () / width ()) + offset) %4078 viewport.setX (priv->vp.x () + ((rect.centerX () / width ()) + offset) %
@@ -4681,6 +4681,8 @@
4681 return false;4681 return false;
4682 }4682 }
46834683
4684 /* Use synchronous behaviour when running with --sync, useful
4685 * for getting stacktraces when X Errors occurr */
4684 XSynchronize (dpy, synchronousX ? True : False);4686 XSynchronize (dpy, synchronousX ? True : False);
46854687
4686 snprintf (displayString_, 255, "DISPLAY=%s",4688 snprintf (displayString_, 255, "DISPLAY=%s",
46874689
=== modified file 'src/window.cpp'
--- src/window.cpp 2012-04-20 08:27:16 +0000
+++ src/window.cpp 2012-04-23 05:39:20 +0000
@@ -77,8 +77,8 @@
77PrivateWindow::isInvisible() const77PrivateWindow::isInvisible() const
78{78{
79 return attrib.map_state != IsViewable ||79 return attrib.map_state != IsViewable ||
80 attrib.x + width + output.right <= 0 ||80 attrib.x + geometry.width () + output.right <= 0 ||
81 attrib.y + height + output.bottom <= 0 ||81 attrib.y + geometry.height () + output.bottom <= 0 ||
82 attrib.x - output.left >= (int) screen->width () ||82 attrib.x - output.left >= (int) screen->width () ||
83 attrib.y - output.top >= (int) screen->height ();83 attrib.y - output.top >= (int) screen->height ();
84}84}
@@ -813,292 +813,14 @@
813 if (!serverFrame)813 if (!serverFrame)
814 return;814 return;
815815
816816 xwc.x = serverGeometry.x ();
817 gettimeofday (&lastConfigureRequest, NULL);817 xwc.y = serverGeometry.y ();
818 /* Flush any changes made to serverFrameGeometry or serverGeometry to the server818 xwc.width = serverGeometry.width ();
819 * since there is a race condition where geometries will go out-of-sync with819 xwc.height = serverGeometry.height ();
820 * window movement */820 xwc.border_width = serverGeometry.border ();
821821
822 window->syncPosition ();822 window->configureXWindow (valueMask, &xwc);
823823 window->windowNotify (CompWindowNotifyFrameUpdate);
824 if (serverInput.left || serverInput.right || serverInput.top || serverInput.bottom)
825 {
826 int bw = serverGeometry.border () * 2;
827
828 xwc.x = serverGeometry.x () - serverInput.left;
829 xwc.y = serverGeometry.y () - serverInput.top;
830 xwc.width = serverGeometry.width () + serverInput.left + serverInput.right + bw;
831 if (shaded)
832 xwc.height = serverInput.top + serverInput.bottom + bw;
833 else
834 xwc.height = serverGeometry.height () + serverInput.top + serverInput.bottom + bw;
835
836 if (shaded)
837 height = serverInput.top + serverInput.bottom;
838
839 if (serverFrameGeometry.x () == xwc.x)
840 valueMask &= ~(CWX);
841 else
842 serverFrameGeometry.setX (xwc.x);
843
844 if (serverFrameGeometry.y () == xwc.y)
845 valueMask &= ~(CWY);
846 else
847 serverFrameGeometry.setY (xwc.y);
848
849 if (serverFrameGeometry.width () == xwc.width)
850 valueMask &= ~(CWWidth);
851 else
852 serverFrameGeometry.setWidth (xwc.width);
853
854 if (serverFrameGeometry.height () == xwc.height)
855 valueMask &= ~(CWHeight);
856 else
857 serverFrameGeometry.setHeight (xwc.height);
858
859 /* Geometry is the same, so we're not going to get a ConfigureNotify
860 * event when the window is configured, which means that other plugins
861 * won't know that the client, frame and wrapper windows got shifted
862 * around (and might result in display corruption, eg in OpenGL */
863 if (valueMask == 0)
864 {
865 XConfigureEvent xev;
866 XWindowAttributes attrib;
867 unsigned int nchildren = 0;
868 Window rootRet = 0, parentRet = 0;
869 Window *children = NULL;
870
871 xev.type = ConfigureNotify;
872 xev.event = screen->root ();
873 xev.window = priv->serverFrame;
874
875 XGrabServer (screen->dpy ());
876
877 if (XGetWindowAttributes (screen->dpy (), priv->serverFrame, &attrib))
878 {
879 xev.x = attrib.x;
880 xev.y = attrib.y;
881 xev.width = attrib.width;
882 xev.height = attrib.height;
883 xev.border_width = attrib.border_width;
884 xev.above = None;
885
886 /* We need to ensure that the stacking order is
887 * based on the current server stacking order so
888 * find the sibling to this window's frame in the
889 * server side stack and stack above that */
890 XQueryTree (screen->dpy (), screen->root (), &rootRet, &parentRet, &children, &nchildren);
891
892 if (nchildren)
893 {
894 for (unsigned int i = 0; i < nchildren; i++)
895 {
896 if (i + 1 == nchildren ||
897 children[i + 1] == ROOTPARENT (window))
898 {
899 xev.above = children[i];
900 break;
901 }
902 }
903 }
904
905 if (children)
906 XFree (children);
907
908 if (!xev.above)
909 xev.above = (window->serverPrev) ? ROOTPARENT (window->serverPrev) : None;
910
911 xev.override_redirect = priv->attrib.override_redirect;
912
913 }
914
915 compiz::X11::PendingEvent::Ptr pc =
916 boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
917 new compiz::X11::PendingConfigureEvent (
918 screen->dpy (), serverFrame, valueMask, &xwc)));
919
920 pendingConfigures.add (pc);
921 if (priv->mClearCheckTimeout.active ())
922 priv->mClearCheckTimeout.stop ();
923 priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
924 2000, 2500);
925
926 XSendEvent (screen->dpy (), screen->root (), false,
927 SubstructureNotifyMask, (XEvent *) &xev);
928
929 XUngrabServer (screen->dpy ());
930 XSync (screen->dpy (), false);
931 }
932 else
933 {
934 compiz::X11::PendingEvent::Ptr pc =
935 boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
936 new compiz::X11::PendingConfigureEvent (
937 screen->dpy (), serverFrame, valueMask, &xwc)));
938
939 pendingConfigures.add (pc);
940 if (priv->mClearCheckTimeout.active ())
941 priv->mClearCheckTimeout.stop ();
942 priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
943 2000, 2500);
944 XConfigureWindow (screen->dpy (), serverFrame, valueMask, &xwc);
945 }
946
947 if (shaded)
948 {
949 XUnmapWindow (screen->dpy (), wrapper);
950 }
951 else
952 {
953 XMapWindow (screen->dpy (), wrapper);
954 XMoveResizeWindow (screen->dpy (), wrapper, serverInput.left, serverInput.top,
955 serverGeometry.width (), serverGeometry.height ());
956 }
957 XMoveResizeWindow (screen->dpy (), id, 0, 0,
958 serverGeometry.width (), serverGeometry.height ());
959 window->sendConfigureNotify ();
960 window->windowNotify (CompWindowNotifyFrameUpdate);
961 }
962 else
963 {
964 int bw = serverGeometry.border () * 2;
965
966 xwc.x = serverGeometry.x ();
967 xwc.y = serverGeometry.y ();
968 xwc.width = serverGeometry.width () + bw;
969
970 /* FIXME: It doesn't make much sense to allow undecorated windows to be
971 * shaded */
972 if (shaded)
973 xwc.height = bw;
974 else
975 xwc.height = serverGeometry.height () + bw;
976
977 if (serverFrameGeometry.x () == xwc.x)
978 valueMask &= ~(CWX);
979 else
980 serverFrameGeometry.setX (xwc.x);
981
982 if (serverFrameGeometry.y () == xwc.y)
983 valueMask &= ~(CWY);
984 else
985 serverFrameGeometry.setY (xwc.y);
986
987 if (serverFrameGeometry.width () == xwc.width)
988 valueMask &= ~(CWWidth);
989 else
990 serverFrameGeometry.setWidth (xwc.width);
991
992 if (serverFrameGeometry.height () == xwc.height)
993 valueMask &= ~(CWHeight);
994 else
995 serverFrameGeometry.setHeight (xwc.height);
996
997 /* Geometry is the same, so we're not going to get a ConfigureNotify
998 * event when the window is configured, which means that other plugins
999 * won't know that the client, frame and wrapper windows got shifted
1000 * around (and might result in display corruption, eg in OpenGL */
1001 if (valueMask == 0)
1002 {
1003 XConfigureEvent xev;
1004 XWindowAttributes attrib;
1005 unsigned int nchildren = 0;
1006 Window rootRet = 0, parentRet = 0;
1007 Window *children = NULL;
1008
1009 xev.type = ConfigureNotify;
1010 xev.event = screen->root ();
1011 xev.window = priv->serverFrame;
1012
1013 XGrabServer (screen->dpy ());
1014
1015 if (XGetWindowAttributes (screen->dpy (), priv->serverFrame, &attrib))
1016 {
1017 xev.x = attrib.x;
1018 xev.y = attrib.y;
1019 xev.width = attrib.width;
1020 xev.height = attrib.height;
1021 xev.border_width = attrib.border_width;
1022 xev.above = None;
1023
1024 /* We need to ensure that the stacking order is
1025 * based on the current server stacking order so
1026 * find the sibling to this window's frame in the
1027 * server side stack and stack above that */
1028 XQueryTree (screen->dpy (), screen->root (), &rootRet, &parentRet, &children, &nchildren);
1029
1030 if (nchildren)
1031 {
1032 for (unsigned int i = 0; i < nchildren; i++)
1033 {
1034 if (i + 1 == nchildren ||
1035 children[i + 1] == ROOTPARENT (window))
1036 {
1037 xev.above = children[i];
1038 break;
1039 }
1040 }
1041 }
1042
1043 if (children)
1044 XFree (children);
1045
1046 if (!xev.above)
1047 xev.above = (window->serverPrev) ? ROOTPARENT (window->serverPrev) : None;
1048
1049 xev.override_redirect = priv->attrib.override_redirect;
1050
1051 }
1052
1053 compiz::X11::PendingEvent::Ptr pc =
1054 boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
1055 new compiz::X11::PendingConfigureEvent (
1056 screen->dpy (), serverFrame, valueMask, &xwc)));
1057
1058 pendingConfigures.add (pc);
1059 if (priv->mClearCheckTimeout.active ())
1060 priv->mClearCheckTimeout.stop ();
1061 priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
1062 2000, 2500);
1063
1064 XSendEvent (screen->dpy (), screen->root (), false,
1065 SubstructureNotifyMask, (XEvent *) &xev);
1066
1067 XUngrabServer (screen->dpy ());
1068 XSync (screen->dpy (), false);
1069 }
1070 else
1071 {
1072 compiz::X11::PendingEvent::Ptr pc =
1073 boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
1074 new compiz::X11::PendingConfigureEvent (
1075 screen->dpy (), serverFrame, valueMask, &xwc)));
1076
1077 pendingConfigures.add (pc);
1078 if (priv->mClearCheckTimeout.active ())
1079 priv->mClearCheckTimeout.stop ();
1080 priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
1081 2000, 2500);
1082
1083 XConfigureWindow (screen->dpy (), serverFrame, valueMask, &xwc);
1084 }
1085
1086 if (shaded)
1087 {
1088 XUnmapWindow (screen->dpy (), wrapper);
1089 }
1090 else
1091 {
1092 XMapWindow (screen->dpy (), wrapper);
1093 XMoveResizeWindow (screen->dpy (), wrapper, 0, 0,
1094 serverGeometry.width (), serverGeometry.height ());
1095 }
1096
1097 XMoveResizeWindow (screen->dpy (), id, 0, 0,
1098 serverGeometry.width (), serverGeometry.height ());
1099 window->sendConfigureNotify ();
1100 window->windowNotify (CompWindowNotifyFrameUpdate);
1101 }
1102 window->recalcActions ();824 window->recalcActions ();
1103}825}
1104826
@@ -1138,11 +860,12 @@
1138{860{
1139 CompRegion ret;861 CompRegion ret;
1140 int x1, x2, y1, y2;862 int x1, x2, y1, y2;
863 const CompWindow::Geometry &geom = attrib.override_redirect ? priv->geometry : priv->serverGeometry;
1141864
1142 for (unsigned int i = 0; i < n; i++)865 for (unsigned int i = 0; i < n; i++)
1143 {866 {
1144 x1 = rects[i].x + priv->geometry.border ();867 x1 = rects[i].x + geom.border ();
1145 y1 = rects[i].y + priv->geometry.border ();868 y1 = rects[i].y + geom.border ();
1146 x2 = x1 + rects[i].width;869 x2 = x1 + rects[i].width;
1147 y2 = y1 + rects[i].height;870 y2 = y1 + rects[i].height;
1148871
@@ -1150,17 +873,17 @@
1150 x1 = 0;873 x1 = 0;
1151 if (y1 < 0)874 if (y1 < 0)
1152 y1 = 0;875 y1 = 0;
1153 if (x2 > priv->width)876 if (x2 > geom.width ())
1154 x2 = priv->width;877 x2 = geom.width ();
1155 if (y2 > priv->height)878 if (y2 > geom.height ())
1156 y2 = priv->height;879 y2 = geom.height ();
1157880
1158 if (y1 < y2 && x1 < x2)881 if (y1 < y2 && x1 < x2)
1159 {882 {
1160 x1 += priv->geometry.x ();883 x1 += geom.x ();
1161 y1 += priv->geometry.y ();884 y1 += geom.y ();
1162 x2 += priv->geometry.x ();885 x2 += geom.x ();
1163 y2 += priv->geometry.y ();886 y2 += geom.y ();
1164887
1165 ret += CompRect (x1, y1, x2 - x1, y2 - y1);888 ret += CompRect (x1, y1, x2 - x1, y2 - y1);
1166 }889 }
@@ -1180,25 +903,27 @@
1180 XRectangle r, *boundingShapeRects = NULL;903 XRectangle r, *boundingShapeRects = NULL;
1181 XRectangle *inputShapeRects = NULL;904 XRectangle *inputShapeRects = NULL;
1182 int nBounding = 0, nInput = 0;905 int nBounding = 0, nInput = 0;
906 const CompWindow::Geometry &geom = attrib.override_redirect ? priv->geometry : priv->serverGeometry;
1183907
1184 priv->region = CompRegion ();908 priv->region = priv->inputRegion = emptyRegion;
1185 priv->inputRegion = CompRegion ();
1186909
1187 if (screen->XShape ())910 if (screen->XShape ())
1188 {911 {
1189 int order;912 int order;
1190913
914 /* We should update the server here */
915 XSync (screen->dpy (), false);
916
1191 boundingShapeRects = XShapeGetRectangles (screen->dpy (), priv->id,917 boundingShapeRects = XShapeGetRectangles (screen->dpy (), priv->id,
1192 ShapeBounding, &nBounding, &order);918 ShapeBounding, &nBounding, &order);
1193 inputShapeRects = XShapeGetRectangles (screen->dpy (), priv->id,919 inputShapeRects = XShapeGetRectangles (screen->dpy (), priv->id,
1194 ShapeInput, &nInput, &order);920 ShapeInput, &nInput, &order);
1195
1196 }921 }
1197922
1198 r.x = -priv->geometry.border ();923 r.x = -geom.border ();
1199 r.y = -priv->geometry.border ();924 r.y = -geom.border ();
1200 r.width = priv->width + priv->geometry.border ();925 r.width = geom.widthIncBorders ();
1201 r.height = priv->height + priv->geometry.border ();926 r.height = geom.heightIncBorders ();
1202927
1203 if (nBounding < 1)928 if (nBounding < 1)
1204 {929 {
@@ -1664,6 +1389,9 @@
1664 }1389 }
16651390
1666 windowNotify (CompWindowNotifyMap);1391 windowNotify (CompWindowNotifyMap);
1392 /* Send a resizeNotify to plugins to indicate
1393 * that the map is complete */
1394 resizeNotify (0, 0, 0, 0);
1667}1395}
16681396
1669void1397void
@@ -1732,7 +1460,7 @@
1732 priv->attrib.map_state = IsUnmapped;1460 priv->attrib.map_state = IsUnmapped;
1733 priv->invisible = true;1461 priv->invisible = true;
17341462
1735 if (priv->shaded && priv->height)1463 if (priv->shaded)
1736 {1464 {
1737 priv->updateFrameWindow ();1465 priv->updateFrameWindow ();
1738 }1466 }
@@ -1817,7 +1545,7 @@
1817}1545}
18181546
1819bool1547bool
1820CompWindow::resize (CompWindow::Geometry gm)1548PrivateWindow::resize (const CompWindow::Geometry &gm)
1821{1549{
1822 /* Input extents are now the last thing sent1550 /* Input extents are now the last thing sent
1823 * from the server. This might not work in some1551 * from the server. This might not work in some
@@ -1834,12 +1562,8 @@
1834 priv->geometry.height () != gm.height () ||1562 priv->geometry.height () != gm.height () ||
1835 priv->geometry.border () != gm.border ())1563 priv->geometry.border () != gm.border ())
1836 {1564 {
1837 int pw, ph;
1838 int dx, dy, dwidth, dheight;1565 int dx, dy, dwidth, dheight;
18391566
1840 pw = gm.width () + gm.border () * 2;
1841 ph = gm.height () + gm.border () * 2;
1842
1843 dx = gm.x () - priv->geometry.x ();1567 dx = gm.x () - priv->geometry.x ();
1844 dy = gm.y () - priv->geometry.y ();1568 dy = gm.y () - priv->geometry.y ();
1845 dwidth = gm.width () - priv->geometry.width ();1569 dwidth = gm.width () - priv->geometry.width ();
@@ -1849,37 +1573,58 @@
1849 gm.width (), gm.height (),1573 gm.width (), gm.height (),
1850 gm.border ());1574 gm.border ());
18511575
1852 priv->width = pw;
1853 priv->height = ph;
1854
1855 if (priv->mapNum)
1856 priv->updateRegion ();
1857
1858 resizeNotify (dx, dy, dwidth, dheight);
1859
1860 priv->invisible = priv->isInvisible ();1576 priv->invisible = priv->isInvisible ();
1577
1578 if (priv->attrib.override_redirect)
1579 {
1580 priv->serverGeometry = priv->geometry;
1581 priv->serverFrameGeometry = priv->frameGeometry;
1582
1583 if (priv->mapNum)
1584 priv->updateRegion ();
1585
1586 window->resizeNotify (dx, dy, dwidth, dheight);
1587 }
1861 }1588 }
1862 else if (priv->geometry.x () != gm.x () || priv->geometry.y () != gm.y ())1589 else if (priv->geometry.x () != gm.x () || priv->geometry.y () != gm.y ())
1863 {1590 {
1864 int dx, dy;1591 move (gm.x () - priv->geometry.x (),
18651592 gm.y () - priv->geometry.y (), true);
1866 dx = gm.x () - priv->geometry.x ();
1867 dy = gm.y () - priv->geometry.y ();
1868
1869 priv->geometry.setX (gm.x ());
1870 priv->geometry.setY (gm.y ());
1871
1872 priv->region.translate (dx, dy);
1873 priv->inputRegion.translate (dx, dy);
1874 if (!priv->frameRegion.isEmpty ())
1875 priv->frameRegion.translate (dx, dy);
1876
1877 priv->invisible = priv->isInvisible ();
1878
1879 moveNotify (dx, dy, true);
1880 }1593 }
18811594
1882 updateFrameRegion ();1595 return true;
1596}
1597
1598bool
1599PrivateWindow::resize (const XWindowAttributes &attr)
1600{
1601 return resize (CompWindow::Geometry (attr.x, attr.y, attr.width, attr.height,
1602 attr.border_width));
1603}
1604
1605bool
1606PrivateWindow::resize (int x,
1607 int y,
1608 int width,
1609 int height,
1610 int border)
1611{
1612 return resize (CompWindow::Geometry (x, y, width, height, border));
1613}
1614
1615bool
1616CompWindow::resize (CompWindow::Geometry gm)
1617{
1618 XWindowChanges xwc = XWINDOWCHANGES_INIT;
1619 unsigned int valueMask = CWX | CWY | CWWidth | CWHeight | CWBorderWidth;
1620
1621 xwc.x = gm.x ();
1622 xwc.y = gm.y ();
1623 xwc.width = gm.width ();
1624 xwc.height = gm.height ();
1625 xwc.border_width = gm.border ();
1626
1627 configureXWindow (valueMask, &xwc);
18831628
1884 return true;1629 return true;
1885}1630}
@@ -2047,13 +1792,7 @@
2047 ce->border_width);1792 ce->border_width);
2048 else1793 else
2049 {1794 {
2050 if (ce->override_redirect)1795 resize (ce->x, ce->y, ce->width, ce->height, ce->border_width);
2051 {
2052 priv->serverGeometry.set (ce->x, ce->y, ce->width, ce->height,
2053 ce->border_width);
2054 }
2055
2056 window->resize (ce->x, ce->y, ce->width, ce->height, ce->border_width);
2057 }1796 }
20581797
2059 if (ce->event == screen->root ())1798 if (ce->event == screen->root ())
@@ -2123,9 +1862,9 @@
2123 * windows since we didn't resize them1862 * windows since we didn't resize them
2124 * on configureXWindow */1863 * on configureXWindow */
2125 if (priv->shaded)1864 if (priv->shaded)
2126 height = priv->serverGeometry.height () - priv->serverGeometry.border () * 2 - priv->serverInput.top - priv->serverInput.bottom;1865 height = priv->serverGeometry.heightIncBorders () - priv->serverInput.top - priv->serverInput.bottom;
2127 else1866 else
2128 height = ce->height - priv->serverGeometry.border () * 2 - priv->serverInput.top - priv->serverInput.bottom;1867 height = ce->height + priv->serverGeometry.border () * 2 - priv->serverInput.top - priv->serverInput.bottom;
21291868
2130 /* set the frame geometry */1869 /* set the frame geometry */
2131 priv->frameGeometry.set (ce->x, ce->y, ce->width, ce->height, ce->border_width);1870 priv->frameGeometry.set (ce->x, ce->y, ce->width, ce->height, ce->border_width);
@@ -2134,7 +1873,7 @@
2134 if (priv->syncWait)1873 if (priv->syncWait)
2135 priv->syncGeometry.set (x, y, width, height, ce->border_width);1874 priv->syncGeometry.set (x, y, width, height, ce->border_width);
2136 else1875 else
2137 window->resize (x, y, width, height, ce->border_width);1876 resize (x, y, width, height, ce->border_width);
21381877
2139 if (priv->restack (ce->above))1878 if (priv->restack (ce->above))
2140 priv->updatePassiveButtonGrabs ();1879 priv->updatePassiveButtonGrabs ();
@@ -2143,27 +1882,6 @@
21431882
2144 if (above)1883 if (above)
2145 above->priv->updatePassiveButtonGrabs ();1884 above->priv->updatePassiveButtonGrabs ();
2146
2147 if (!pendingConfigures.pending ())
2148 {
2149 /* Tell plugins its ok to start doing stupid things again but
2150 * obviously FIXME */
2151 CompOption::Vector options;
2152 CompOption::Value v;
2153
2154 options.push_back (CompOption ("window", CompOption::TypeInt));
2155 v.set ((int) id);
2156 options.back ().set (v);
2157 options.push_back (CompOption ("active", CompOption::TypeInt));
2158 v.set ((int) 0);
2159 options.back ().set (v);
2160
2161 /* Notify other plugins that it is unsafe to change geometry or serverGeometry
2162 * FIXME: That API should not be accessible to plugins, this is a hack to avoid
2163 * breaking ABI */
2164
2165 screen->handleCompizEvent ("core", "lock_position", options);
2166 }
2167}1885}
21681886
2169void1887void
@@ -2186,23 +1904,34 @@
2186{1904{
2187 if (dx || dy)1905 if (dx || dy)
2188 {1906 {
2189 gettimeofday (&priv->lastGeometryUpdate, NULL);1907 XWindowChanges xwc = XWINDOWCHANGES_INIT;
21901908 unsigned int valueMask = CWX | CWY;
2191 /* Don't allow window movement to overwrite working geometries1909
2192 * last received from the server if we know there are pending1910 xwc.x = priv->serverGeometry.x () + dx;
2193 * ConfigureNotify events on this window. That's a clunky workaround1911 xwc.y = priv->serverGeometry.y () + dy;
2194 * and a FIXME in any case, however, until we can break the API1912
2195 * and remove CompWindow::move, this will need to be the case */1913 priv->nextMoveImmediate = immediate;
21961914
2197 if (!priv->pendingConfigures.pending ())1915 configureXWindow (valueMask, &xwc);
1916 }
1917}
1918
1919void
1920PrivateWindow::move (int dx,
1921 int dy,
1922 bool immediate)
1923{
1924 if (dx || dy)
1925 {
1926 priv->geometry.setX (priv->geometry.x () + dx);
1927 priv->geometry.setY (priv->geometry.y () + dy);
1928 priv->frameGeometry.setX (priv->frameGeometry.x () + dx);
1929 priv->frameGeometry.setY (priv->frameGeometry.y () + dy);
1930
1931 if (priv->attrib.override_redirect)
2198 {1932 {
2199 priv->geometry.setX (priv->geometry.x () + dx);1933 priv->serverGeometry = priv->geometry;
2200 priv->geometry.setY (priv->geometry.y () + dy);1934 priv->serverFrameGeometry = priv->frameGeometry;
2201 priv->frameGeometry.setX (priv->frameGeometry.x () + dx);
2202 priv->frameGeometry.setY (priv->frameGeometry.y () + dy);
2203
2204 priv->pendingPositionUpdates = true;
2205
2206 priv->region.translate (dx, dy);1935 priv->region.translate (dx, dy);
2207 priv->inputRegion.translate (dx, dy);1936 priv->inputRegion.translate (dx, dy);
2208 if (!priv->frameRegion.isEmpty ())1937 if (!priv->frameRegion.isEmpty ())
@@ -2210,19 +1939,7 @@
22101939
2211 priv->invisible = priv->isInvisible ();1940 priv->invisible = priv->isInvisible ();
22121941
2213 moveNotify (dx, dy, immediate);1942 window->moveNotify (dx, dy, true);
2214 }
2215 else
2216 {
2217 XWindowChanges xwc = XWINDOWCHANGES_INIT;
2218 unsigned int valueMask = CWX | CWY;
2219 compLogMessage ("core", CompLogLevelDebug, "pending configure notifies on 0x%x, "\
2220 "moving window asyncrhonously!", (unsigned int) priv->serverId);
2221
2222 xwc.x = priv->serverGeometry.x () + dx;
2223 xwc.y = priv->serverGeometry.y () + dy;
2224
2225 configureXWindow (valueMask, &xwc);
2226 }1943 }
2227 }1944 }
2228}1945}
@@ -2233,22 +1950,6 @@
2233 return !mEvents.empty ();1950 return !mEvents.empty ();
2234}1951}
22351952
2236bool
2237PrivateWindow::checkClear ()
2238{
2239 if (pendingConfigures.pending ())
2240 {
2241 /* FIXME: This is a hack to avoid performance regressions
2242 * and must be removed in 0.9.6 */
2243 compLogMessage ("core", CompLogLevelWarn, "failed to receive ConfigureNotify event on 0x%x\n",
2244 id);
2245 pendingConfigures.dump ();
2246 pendingConfigures.clear ();
2247 }
2248
2249 return false;
2250}
2251
2252void1953void
2253compiz::X11::PendingEventQueue::add (PendingEvent::Ptr p)1954compiz::X11::PendingEventQueue::add (PendingEvent::Ptr p)
2254{1955{
@@ -2470,21 +2171,6 @@
2470 mValueMask (valueMask),2171 mValueMask (valueMask),
2471 mXwc (*xwc)2172 mXwc (*xwc)
2472{2173{
2473 CompOption::Vector options;
2474 CompOption::Value v;
2475
2476 options.push_back (CompOption ("window", CompOption::TypeInt));
2477 v.set ((int) w);
2478 options.back ().set (v);
2479 options.push_back (CompOption ("active", CompOption::TypeInt));
2480 v.set ((int) 1);
2481 options.back ().set (v);
2482
2483 /* Notify other plugins that it is unsafe to change geometry or serverGeometry
2484 * FIXME: That API should not be accessible to plugins, this is a hack to avoid
2485 * breaking ABI */
2486
2487 screen->handleCompizEvent ("core", "lock_position", options);
2488}2174}
24892175
2490compiz::X11::PendingConfigureEvent::~PendingConfigureEvent ()2176compiz::X11::PendingConfigureEvent::~PendingConfigureEvent ()
@@ -2494,57 +2180,6 @@
2494void2180void
2495CompWindow::syncPosition ()2181CompWindow::syncPosition ()
2496{2182{
2497 gettimeofday (&priv->lastConfigureRequest, NULL);
2498
2499 unsigned int valueMask = CWX | CWY;
2500 XWindowChanges xwc = XWINDOWCHANGES_INIT;
2501
2502 if (priv->pendingPositionUpdates && !priv->pendingConfigures.pending ())
2503 {
2504 if (priv->serverFrameGeometry.x () == priv->frameGeometry.x ())
2505 valueMask &= ~(CWX);
2506 if (priv->serverFrameGeometry.y () == priv->frameGeometry.y ())
2507 valueMask &= ~(CWY);
2508
2509 /* Because CompWindow::move can update the geometry last
2510 * received from the server, we must indicate that no values
2511 * changed, because when the ConfigureNotify comes around
2512 * the values are going to be the same. That's obviously
2513 * broken behaviour and worthy of a FIXME, but requires
2514 * larger changes to the window movement system. */
2515 if (valueMask)
2516 {
2517 priv->serverGeometry.setX (priv->geometry.x ());
2518 priv->serverGeometry.setY (priv->geometry.y ());
2519 priv->serverFrameGeometry.setX (priv->frameGeometry.x ());
2520 priv->serverFrameGeometry.setY (priv->frameGeometry.y ());
2521
2522 xwc.x = priv->serverFrameGeometry.x ();
2523 xwc.y = priv->serverFrameGeometry.y ();
2524
2525 compiz::X11::PendingEvent::Ptr pc =
2526 boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
2527 new compiz::X11::PendingConfigureEvent (
2528 screen->dpy (), priv->serverFrame, 0, &xwc)));
2529
2530 priv->pendingConfigures.add (pc);
2531
2532 /* Got 3 seconds to get its stuff together */
2533 if (priv->mClearCheckTimeout.active ())
2534 priv->mClearCheckTimeout.stop ();
2535 priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
2536 2000, 2500);
2537 XConfigureWindow (screen->dpy (), ROOTPARENT (this), valueMask, &xwc);
2538
2539 if (priv->serverFrame)
2540 {
2541 XMoveWindow (screen->dpy (), priv->wrapper,
2542 priv->serverInput.left, priv->serverInput.top);
2543 sendConfigureNotify ();
2544 }
2545 }
2546 priv->pendingPositionUpdates = false;
2547 }
2548}2183}
25492184
2550bool2185bool
@@ -3345,14 +2980,41 @@
3345{2980{
3346 unsigned int frameValueMask = 0;2981 unsigned int frameValueMask = 0;
33472982
3348 /* Immediately sync window position2983 if (id == screen->root ())
3349 * if plugins were updating w->geometry () directly2984 {
3350 * in order to avoid a race condition */2985 compLogMessage ("core", CompLogLevelWarn, "attempted to reconfigure root window");
33512986 return;
3352 window->syncPosition ();2987 }
33532988
3354 /* Remove redundant bits */2989 /* Remove redundant bits */
33552990
2991 xwc->x = valueMask & CWX ? xwc->x : serverGeometry.x ();
2992 xwc->y = valueMask & CWY ? xwc->y : serverGeometry.y ();
2993 xwc->width = valueMask & CWWidth ? xwc->width : serverGeometry.width ();
2994 xwc->height = valueMask & CWHeight ? xwc->height : serverGeometry.height ();
2995 xwc->border_width = valueMask & CWBorderWidth ? xwc->border_width : serverGeometry.border ();
2996
2997 /* Don't allow anything that might generate a BadValue */
2998 if (valueMask & CWWidth && !xwc->width)
2999 {
3000 compLogMessage ("core", CompLogLevelWarn, "Attempted to set < 1 width on a window");
3001 xwc->width = 1;
3002 }
3003
3004 if (valueMask & CWHeight && !xwc->height)
3005 {
3006 compLogMessage ("core", CompLogLevelWarn, "Attempted to set < 1 height on a window");
3007 xwc->height = 1;
3008 }
3009
3010 int dx = valueMask & CWX ? xwc->x - serverGeometry.x () : 0;
3011 int dy = valueMask & CWY ? xwc->y - serverGeometry.y () : 0;
3012 int dwidth = valueMask & CWWidth ? xwc->width - serverGeometry.width () : 0;
3013 int dheight = valueMask & CWHeight ? xwc->height - serverGeometry.height () : 0;
3014
3015 /* FIXME: This is a total fallacy for the reparenting case
3016 * at least since the client doesn't actually move here, it only
3017 * moves within the frame */
3356 if (valueMask & CWX && serverGeometry.x () == xwc->x)3018 if (valueMask & CWX && serverGeometry.x () == xwc->x)
3357 valueMask &= ~(CWX);3019 valueMask &= ~(CWX);
33583020
@@ -3419,18 +3081,15 @@
3419 compLogMessage ("core", CompLogLevelWarn, "restack_mode not Above");3081 compLogMessage ("core", CompLogLevelWarn, "restack_mode not Above");
3420 }3082 }
34213083
3422 frameValueMask = valueMask;3084 frameValueMask = CWX | CWY | CWWidth | CWHeight | (valueMask & (CWStackMode | CWSibling));
34233085
3424 if (frameValueMask & CWX &&3086 if (serverFrameGeometry.x () == xwc->x - serverGeometry.border () - serverInput.left)
3425 serverFrameGeometry.x () == xwc->x - serverGeometry.border () - serverInput.left)
3426 frameValueMask &= ~(CWX);3087 frameValueMask &= ~(CWX);
34273088
3428 if (frameValueMask & CWY &&3089 if (serverFrameGeometry.y () == xwc->y - serverGeometry.border () - serverInput.top)
3429 serverFrameGeometry.y () == xwc->y - serverGeometry.border () - serverInput.top)
3430 frameValueMask &= ~(CWY);3090 frameValueMask &= ~(CWY);
34313091
3432 if (frameValueMask & CWWidth &&3092 if (serverFrameGeometry.width () == xwc->width + serverGeometry.border () * 2
3433 serverFrameGeometry.width () == xwc->width + serverGeometry.border () * 2
3434 + serverInput.left + serverInput.right)3093 + serverInput.left + serverInput.right)
3435 frameValueMask &= ~(CWWidth);3094 frameValueMask &= ~(CWWidth);
34363095
@@ -3440,19 +3099,64 @@
34403099
3441 if (shaded)3100 if (shaded)
3442 {3101 {
3443 if (frameValueMask & CWHeight &&3102 if (serverFrameGeometry.height () == serverGeometry.border () * 2
3444 serverFrameGeometry.height () == serverGeometry.border () * 2
3445 + serverInput.top + serverInput.bottom)3103 + serverInput.top + serverInput.bottom)
3446 frameValueMask &= ~(CWHeight);3104 frameValueMask &= ~(CWHeight);
3447 }3105 }
3448 else3106 else
3449 {3107 {
3450 if (frameValueMask & CWHeight &&3108 if (serverFrameGeometry.height () == xwc->height + serverGeometry.border () * 2
3451 serverFrameGeometry.height () == xwc->height + serverGeometry.border () * 2
3452 + serverInput.top + serverInput.bottom)3109 + serverInput.top + serverInput.bottom)
3453 frameValueMask &= ~(CWHeight);3110 frameValueMask &= ~(CWHeight);
3454 }3111 }
34553112
3113
3114 if (valueMask & CWStackMode &&
3115 ((xwc->stack_mode != TopIf) && (xwc->stack_mode != BottomIf) && (xwc->stack_mode != Opposite) &&
3116 (xwc->stack_mode != Above) && (xwc->stack_mode != Below)))
3117 {
3118 compLogMessage ("core", CompLogLevelWarn, "Invalid stack mode %i", xwc->stack_mode);
3119 valueMask &= ~(CWStackMode | CWSibling);
3120 }
3121
3122 /* Don't allow anything that might cause a BadMatch error */
3123
3124 if (valueMask & CWSibling && !(valueMask & CWStackMode))
3125 {
3126 compLogMessage ("core", CompLogLevelWarn, "Didn't specify a CWStackMode for CWSibling");
3127 valueMask &= ~CWSibling;
3128 }
3129
3130 if (valueMask & CWSibling && xwc->sibling == (serverFrame ? serverFrame : id))
3131 {
3132 compLogMessage ("core", CompLogLevelWarn, "Can't restack a window relative to itself");
3133 valueMask &= ~CWSibling;
3134 }
3135
3136 if (valueMask & CWBorderWidth && attrib.c_class == InputOnly)
3137 {
3138 compLogMessage ("core", CompLogLevelWarn, "Cannot set border_width of an input_only window");
3139 valueMask &= ~CWBorderWidth;
3140 }
3141
3142 if (valueMask & CWSibling)
3143 {
3144 CompWindow *sibling = screen->findTopLevelWindow (xwc->sibling);
3145
3146 if (!sibling)
3147 {
3148 compLogMessage ("core", CompLogLevelWarn, "Attempted to restack relative to 0x%x which is "\
3149 "not a child of the root window or a window compiz owns", static_cast <unsigned int> (xwc->sibling));
3150 valueMask &= ~(CWSibling | CWStackMode);
3151 }
3152 else if (sibling->frame () && xwc->sibling != sibling->frame ())
3153 {
3154 compLogMessage ("core", CompLogLevelWarn, "Attempted to restack relative to 0x%x which is "\
3155 "not a child of the root window", static_cast <unsigned int> (xwc->sibling));
3156 valueMask &= ~(CWSibling | CWStackMode);
3157 }
3158 }
3159
3456 /* Can't set the border width of frame windows */3160 /* Can't set the border width of frame windows */
3457 frameValueMask &= ~(CWBorderWidth);3161 frameValueMask &= ~(CWBorderWidth);
34583162
@@ -3479,11 +3183,8 @@
3479 + serverInput.top + serverInput.bottom);3183 + serverInput.top + serverInput.bottom);
3480 }3184 }
34813185
3482
3483 if (serverFrame)3186 if (serverFrame)
3484 {3187 {
3485 gettimeofday (&lastConfigureRequest, NULL);
3486
3487 if (frameValueMask)3188 if (frameValueMask)
3488 {3189 {
3489 XWindowChanges wc = *xwc;3190 XWindowChanges wc = *xwc;
@@ -3499,13 +3200,10 @@
3499 screen->dpy (), priv->serverFrame, frameValueMask, &wc)));3200 screen->dpy (), priv->serverFrame, frameValueMask, &wc)));
35003201
3501 pendingConfigures.add (pc);3202 pendingConfigures.add (pc);
3502 if (priv->mClearCheckTimeout.active ())
3503 priv->mClearCheckTimeout.stop ();
3504 priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
3505 2000, 2500);
35063203
3507 XConfigureWindow (screen->dpy (), serverFrame, frameValueMask, &wc);3204 XConfigureWindow (screen->dpy (), serverFrame, frameValueMask, &wc);
3508 }3205 }
3206
3509 valueMask &= ~(CWSibling | CWStackMode);3207 valueMask &= ~(CWSibling | CWStackMode);
35103208
3511 /* If the frame has changed position (eg, serverInput.top3209 /* If the frame has changed position (eg, serverInput.top
@@ -3531,6 +3229,39 @@
35313229
3532 if (valueMask)3230 if (valueMask)
3533 XConfigureWindow (screen->dpy (), id, valueMask, xwc);3231 XConfigureWindow (screen->dpy (), id, valueMask, xwc);
3232
3233 /* When updating plugins we care about
3234 * the absolute position */
3235 if (dx)
3236 valueMask |= CWX;
3237 if (dy)
3238 valueMask |= CWY;
3239 if (dwidth)
3240 valueMask |= CWWidth;
3241 if (dheight)
3242 valueMask |= CWHeight;
3243
3244 if (!attrib.override_redirect)
3245 {
3246 if (valueMask & (CWWidth | CWHeight))
3247 {
3248 updateRegion ();
3249 window->resizeNotify (dx, dy, dwidth, dheight);
3250 }
3251 else if (valueMask & (CWX | CWY))
3252 {
3253 region.translate (dx, dy);
3254 inputRegion.translate (dx, dy);
3255 if (!frameRegion.isEmpty ())
3256 frameRegion.translate (dx, dy);
3257
3258 if (dx || dy)
3259 {
3260 window->moveNotify (dx, dy, priv->nextMoveImmediate);
3261 priv->nextMoveImmediate = true;
3262 }
3263 }
3264 }
3534}3265}
35353266
3536bool3267bool
@@ -4308,10 +4039,6 @@
4308 screen->dpy (), serverFrame, valueMask, &lxwc)));4039 screen->dpy (), serverFrame, valueMask, &lxwc)));
43094040
4310 pendingConfigures.add (pc);4041 pendingConfigures.add (pc);
4311 if (priv->mClearCheckTimeout.active ())
4312 priv->mClearCheckTimeout.stop ();
4313 priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
4314 2000, 2500);
4315 }4042 }
43164043
4317 /* Below with no sibling puts the window at the bottom4044 /* Below with no sibling puts the window at the bottom
@@ -4615,8 +4342,8 @@
4615PrivateWindow::ensureWindowVisibility ()4342PrivateWindow::ensureWindowVisibility ()
4616{4343{
4617 int x1, y1, x2, y2;4344 int x1, y1, x2, y2;
4618 int width = serverGeometry.width () + serverGeometry.border () * 2;4345 int width = serverGeometry.widthIncBorders ();
4619 int height = serverGeometry.height () + serverGeometry.border () * 2;4346 int height = serverGeometry.heightIncBorders ();
4620 int dx = 0;4347 int dx = 0;
4621 int dy = 0;4348 int dy = 0;
46224349
@@ -5476,10 +5203,10 @@
5476 }5203 }
5477 else5204 else
5478 {5205 {
5479 m = priv->geometry.x () + offX;5206 m = priv->serverGeometry.x () + offX;
5480 if (m - priv->input.left < (int) s->width () - vWidth)5207 if (m - priv->serverInput.left < (int) s->width () - vWidth)
5481 rv.setX (offX + vWidth);5208 rv.setX (offX + vWidth);
5482 else if (m + priv->width + priv->input.right > vWidth)5209 else if (m + priv->serverGeometry.width () + priv->serverInput.right > vWidth)
5483 rv.setX (offX - vWidth);5210 rv.setX (offX - vWidth);
5484 else5211 else
5485 rv.setX (offX);5212 rv.setX (offX);
@@ -5491,10 +5218,10 @@
5491 }5218 }
5492 else5219 else
5493 {5220 {
5494 m = priv->geometry.y () + offY;5221 m = priv->serverGeometry.y () + offY;
5495 if (m - priv->input.top < (int) s->height () - vHeight)5222 if (m - priv->serverInput.top < (int) s->height () - vHeight)
5496 rv.setY (offY + vHeight);5223 rv.setY (offY + vHeight);
5497 else if (m + priv->height + priv->input.bottom > vHeight)5224 else if (m + priv->serverGeometry.height () + priv->serverInput.bottom > vHeight)
5498 rv.setY (offY - vHeight);5225 rv.setY (offY - vHeight);
5499 else5226 else
5500 rv.setY (offY);5227 rv.setY (offY);
@@ -6017,8 +5744,8 @@
6017 y -= screen->vp ().y () * screen->height ();5744 y -= screen->vp ().y () * screen->height ();
6018 }5745 }
60195746
6020 tx = x - priv->geometry.x ();5747 tx = x - priv->serverGeometry.x ();
6021 ty = y - priv->geometry.y ();5748 ty = y - priv->serverGeometry.y ();
60225749
6023 if (tx || ty)5750 if (tx || ty)
6024 {5751 {
@@ -6040,21 +5767,21 @@
60405767
6041 if (screen->vpSize ().width ()!= 1)5768 if (screen->vpSize ().width ()!= 1)
6042 {5769 {
6043 m = priv->geometry.x () + tx;5770 m = priv->serverGeometry.x () + tx;
60445771
6045 if (m - priv->output.left < (int) screen->width () - vWidth)5772 if (m - priv->output.left < (int) screen->width () - vWidth)
6046 wx = tx + vWidth;5773 wx = tx + vWidth;
6047 else if (m + priv->width + priv->output.right > vWidth)5774 else if (m + priv->serverGeometry.width () + priv->output.right > vWidth)
6048 wx = tx - vWidth;5775 wx = tx - vWidth;
6049 }5776 }
60505777
6051 if (screen->vpSize ().height () != 1)5778 if (screen->vpSize ().height () != 1)
6052 {5779 {
6053 m = priv->geometry.y () + ty;5780 m = priv->serverGeometry.y () + ty;
60545781
6055 if (m - priv->output.top < (int) screen->height () - vHeight)5782 if (m - priv->output.top < (int) screen->height () - vHeight)
6056 wy = ty + vHeight;5783 wy = ty + vHeight;
6057 else if (m + priv->height + priv->output.bottom > vHeight)5784 else if (m + priv->serverGeometry.height () + priv->output.bottom > vHeight)
6058 wy = ty - vHeight;5785 wy = ty - vHeight;
6059 }5786 }
60605787
@@ -6209,8 +5936,8 @@
6209 svp = screen->vp ();5936 svp = screen->vp ();
6210 size = *screen;5937 size = *screen;
62115938
6212 x = window->geometry ().x () + (svp.x () - vp.x ()) * size.width ();5939 x = window->serverGeometry ().x () + (svp.x () - vp.x ()) * size.width ();
6213 y = window->geometry ().y () + (svp.y () - vp.y ()) * size.height ();5940 y = window->serverGeometry ().y () + (svp.y () - vp.y ()) * size.height ();
6214 window->moveToViewportPosition (x, y, true);5941 window->moveToViewportPosition (x, y, true);
62155942
6216 if (allowWindowFocus (0, timestamp))5943 if (allowWindowFocus (0, timestamp))
@@ -6279,9 +6006,6 @@
6279 priv->serverFrameGeometry = priv->frameGeometry = priv->syncGeometry6006 priv->serverFrameGeometry = priv->frameGeometry = priv->syncGeometry
6280 = priv->geometry = priv->serverGeometry;6007 = priv->geometry = priv->serverGeometry;
62816008
6282 priv->width = priv->attrib.width + priv->attrib.border_width * 2;
6283 priv->height = priv->attrib.height + priv->attrib.border_width * 2;
6284
6285 priv->sizeHints.flags = 0;6009 priv->sizeHints.flags = 0;
62866010
6287 priv->recalcNormalHints ();6011 priv->recalcNormalHints ();
@@ -6303,8 +6027,7 @@
63036027
6304 if (priv->attrib.c_class != InputOnly)6028 if (priv->attrib.c_class != InputOnly)
6305 {6029 {
6306 priv->region = CompRegion (priv->attrib.x, priv->attrib.y,6030 priv->region = CompRegion (priv->serverGeometry);
6307 priv->width, priv->height);
6308 priv->inputRegion = priv->region;6031 priv->inputRegion = priv->region;
63096032
6310 /* need to check for DisplayModal state on all windows */6033 /* need to check for DisplayModal state on all windows */
@@ -6534,8 +6257,6 @@
6534 hints (NULL),6257 hints (NULL),
6535 inputHint (true),6258 inputHint (true),
6536 alpha (false),6259 alpha (false),
6537 width (0),
6538 height (0),
6539 region (),6260 region (),
6540 wmType (0),6261 wmType (0),
6541 type (CompWindowTypeUnknownMask),6262 type (CompWindowTypeUnknownMask),
@@ -6570,7 +6291,6 @@
6570 pendingUnmaps (0),6291 pendingUnmaps (0),
6571 pendingMaps (0),6292 pendingMaps (0),
6572 pendingConfigures (screen->dpy ()),6293 pendingConfigures (screen->dpy ()),
6573 pendingPositionUpdates (false),
65746294
6575 startupId (0),6295 startupId (0),
6576 resName (0),6296 resName (0),
@@ -6748,14 +6468,12 @@
6748void6468void
6749CompWindow::updateFrameRegion ()6469CompWindow::updateFrameRegion ()
6750{6470{
6751 if (priv->serverFrame &&6471 if (priv->serverFrame)
6752 priv->serverGeometry.width () == priv->geometry.width () &&
6753 priv->serverGeometry.height () == priv->geometry.height ())
6754 {6472 {
6755 CompRect r;6473 CompRect r;
6756 int x, y;6474 int x, y;
67576475
6758 priv->frameRegion = CompRegion ();6476 priv->frameRegion = emptyRegion;
67596477
6760 updateFrameRegion (priv->frameRegion);6478 updateFrameRegion (priv->frameRegion);
67616479
@@ -6764,16 +6482,16 @@
6764 r = priv->region.boundingRect ();6482 r = priv->region.boundingRect ();
6765 priv->frameRegion -= r;6483 priv->frameRegion -= r;
67666484
6767 r.setGeometry (r.x1 () - priv->input.left,6485 r.setGeometry (r.x1 () - priv->serverInput.left,
6768 r.y1 () - priv->input.top,6486 r.y1 () - priv->serverInput.top,
6769 r.width () + priv->input.right + priv->input.left,6487 r.width () + priv->serverInput.right + priv->serverInput.left,
6770 r.height () + priv->input.bottom + priv->input.top);6488 r.height () + priv->serverInput.bottom + priv->serverInput.top);
67716489
6772 priv->frameRegion &= CompRegion (r);6490 priv->frameRegion &= CompRegion (r);
6773 }6491 }
67746492
6775 x = priv->geometry.x () - priv->input.left;6493 x = priv->serverGeometry.x () - priv->serverInput.left;
6776 y = priv->geometry.y () - priv->input.top;6494 y = priv->serverGeometry.y () - priv->serverInput.top;
67776495
6778 XShapeCombineRegion (screen->dpy (), priv->serverFrame,6496 XShapeCombineRegion (screen->dpy (), priv->serverFrame,
6779 ShapeBounding, -x, -y,6497 ShapeBounding, -x, -y,
@@ -6791,6 +6509,10 @@
6791CompWindow::setWindowFrameExtents (CompWindowExtents *b,6509CompWindow::setWindowFrameExtents (CompWindowExtents *b,
6792 CompWindowExtents *i)6510 CompWindowExtents *i)
6793{6511{
6512 /* override redirect windows can't have frame extents */
6513 if (priv->attrib.override_redirect)
6514 return;
6515
6794 /* Input extents are used for frame size,6516 /* Input extents are used for frame size,
6795 * Border extents used for placement.6517 * Border extents used for placement.
6796 */6518 */
@@ -6814,6 +6536,11 @@
68146536
6815 priv->updateSize ();6537 priv->updateSize ();
6816 priv->updateFrameWindow ();6538 priv->updateFrameWindow ();
6539
6540 /* Always send a moveNotify
6541 * whenever the frame extents update
6542 * so that plugins can re-position appropriately */
6543 moveNotify (0, 0, true);
6817 }6544 }
68186545
6819 /* Use b for _NET_WM_FRAME_EXTENTS here because6546 /* Use b for _NET_WM_FRAME_EXTENTS here because
@@ -7097,10 +6824,10 @@
7097 /* Wait for the reparent to finish */6824 /* Wait for the reparent to finish */
7098 XSync (dpy, false);6825 XSync (dpy, false);
70996826
7100 xwc.x = serverGeometry.x () - serverGeometry.border ();6827 xwc.x = serverGeometry.xMinusBorder ();
7101 xwc.y = serverGeometry.y () - serverGeometry.border ();6828 xwc.y = serverGeometry.yMinusBorder ();
7102 xwc.width = serverGeometry.width () + serverGeometry.border () * 2;6829 xwc.width = serverGeometry.widthIncBorders ();
7103 xwc.height = serverGeometry.height () + serverGeometry.border () * 2;6830 xwc.height = serverGeometry.heightIncBorders ();
71046831
7105 XConfigureWindow (dpy, serverFrame, CWX | CWY | CWWidth | CWHeight, &xwc);6832 XConfigureWindow (dpy, serverFrame, CWX | CWY | CWWidth | CWHeight, &xwc);
71066833
71076834
=== modified file 'src/window/geometry/include/core/windowgeometry.h'
--- src/window/geometry/include/core/windowgeometry.h 2012-01-19 20:08:32 +0000
+++ src/window/geometry/include/core/windowgeometry.h 2012-04-23 05:39:20 +0000
@@ -64,6 +64,12 @@
64 compiz::window::Geometry change (const compiz::window::Geometry &g, unsigned int mask) const;64 compiz::window::Geometry change (const compiz::window::Geometry &g, unsigned int mask) const;
65 void applyChange (const compiz::window::Geometry &g, unsigned int mask);65 void applyChange (const compiz::window::Geometry &g, unsigned int mask);
6666
67 int xMinusBorder () const { return x () - mBorder; }
68 int yMinusBorder () const { return y () - mBorder; }
69
70 unsigned int widthIncBorders () const { return width () + mBorder * 2; }
71 unsigned int heightIncBorders () const { return height () + mBorder * 2; }
72
67private:73private:
68 int mBorder;74 int mBorder;
69};75};
7076
=== modified file 'src/window/geometry/tests/window-geometry/src/test-window-geometry.cpp'
--- src/window/geometry/tests/window-geometry/src/test-window-geometry.cpp 2012-03-30 16:30:13 +0000
+++ src/window/geometry/tests/window-geometry/src/test-window-geometry.cpp 2012-04-23 05:39:20 +0000
@@ -87,3 +87,13 @@
87 EXPECT_EQ (rg, compiz::window::Geometry (49, 99, 199, 299, 5));87 EXPECT_EQ (rg, compiz::window::Geometry (49, 99, 199, 299, 5));
88 EXPECT_EQ (mask, CHANGE_X | CHANGE_Y | CHANGE_WIDTH | CHANGE_HEIGHT);88 EXPECT_EQ (mask, CHANGE_X | CHANGE_Y | CHANGE_WIDTH | CHANGE_HEIGHT);
89}89}
90
91TEST_F(CompWindowGeometryTestGeometry, TestBorders)
92{
93 compiz::window::Geometry g (1, 1, 1, 1, 1);
94
95 EXPECT_EQ (g.xMinusBorder (), 0);
96 EXPECT_EQ (g.yMinusBorder (), 0);
97 EXPECT_EQ (g.widthIncBorders (), 3);
98 EXPECT_EQ (g.heightIncBorders (), 3);
99}
90100
=== modified file 'src/windowgeometry.cpp'
--- src/windowgeometry.cpp 2012-01-23 05:44:19 +0000
+++ src/windowgeometry.cpp 2012-04-23 05:39:20 +0000
@@ -30,160 +30,153 @@
30CompWindow::Geometry &30CompWindow::Geometry &
31CompWindow::serverGeometry () const31CompWindow::serverGeometry () const
32{32{
33 return priv->serverGeometry;33 return priv->attrib.override_redirect ? priv->geometry : priv->serverGeometry;
34}34}
3535
36CompWindow::Geometry &36CompWindow::Geometry &
37CompWindow::geometry () const37CompWindow::geometry () const
38{38{
39 return priv->geometry;39 return priv->attrib.override_redirect ? priv->geometry : priv->serverGeometry;
40}40}
4141
42int42int
43CompWindow::x () const43CompWindow::x () const
44{44{
45 return priv->geometry.x ();45 return geometry ().x ();
46}46}
4747
48int48int
49CompWindow::y () const49CompWindow::y () const
50{50{
51 return priv->geometry.y ();51 return geometry ().y ();
52}52}
5353
54CompPoint54CompPoint
55CompWindow::pos () const55CompWindow::pos () const
56{56{
57 return CompPoint (priv->geometry.x (), priv->geometry.y ());57 return CompPoint (geometry ().x (), geometry ().y ());
58}58}
5959
60/* With border */60/* With border */
61int61int
62CompWindow::width () const62CompWindow::width () const
63{63{
64 return priv->width +64 return geometry ().widthIncBorders ();
65 priv->geometry.border () * 2;
66}65}
6766
68int67int
69CompWindow::height () const68CompWindow::height () const
70{69{
71 return priv->height +70 return geometry ().heightIncBorders ();
72 priv->geometry.border () * 2;;
73}71}
7472
75CompSize73CompSize
76CompWindow::size () const74CompWindow::size () const
77{75{
78 return CompSize (priv->width + priv->geometry.border () * 2,76 return CompSize (width (), height ());
79 priv->height + priv->geometry.border () * 2);
80}77}
8178
82int79int
83CompWindow::serverX () const80CompWindow::serverX () const
84{81{
85 return priv->serverGeometry.x ();82 return serverGeometry ().x ();
86}83}
8784
88int85int
89CompWindow::serverY () const86CompWindow::serverY () const
90{87{
91 return priv->serverGeometry.y ();88 return serverGeometry ().y ();
92}89}
9390
94CompPoint91CompPoint
95CompWindow::serverPos () const92CompWindow::serverPos () const
96{93{
97 return CompPoint (priv->serverGeometry.x (),94 return CompPoint (serverGeometry ().x (),
98 priv->serverGeometry.y ());95 serverGeometry ().y ());
99}96}
10097
101/* With border */98/* With border */
102int99int
103CompWindow::serverWidth () const100CompWindow::serverWidth () const
104{101{
105 return priv->serverGeometry.width () +102 return serverGeometry ().widthIncBorders ();
106 2 * priv->serverGeometry.border ();
107}103}
108104
109int105int
110CompWindow::serverHeight () const106CompWindow::serverHeight () const
111{107{
112 return priv->serverGeometry.height () +108 return serverGeometry ().heightIncBorders ();
113 2 * priv->serverGeometry.border ();
114}109}
115110
116const CompSize111const CompSize
117CompWindow::serverSize () const112CompWindow::serverSize () const
118{113{
119 return CompSize (priv->serverGeometry.width () +114 return CompSize (serverGeometry ().widthIncBorders (),
120 2 * priv->serverGeometry.border (),115 serverGeometry ().heightIncBorders ());
121 priv->serverGeometry.height () +
122 2 * priv->serverGeometry.border ());
123}116}
124117
125CompRect118CompRect
126CompWindow::borderRect () const119CompWindow::borderRect () const
127{120{
128 return CompRect (priv->geometry.x () - priv->geometry.border () - priv->border.left,121 return CompRect (geometry ().xMinusBorder () - priv->border.left,
129 priv->geometry.y () - priv->geometry.border () - priv->border.top,122 geometry ().yMinusBorder () - priv->border.top,
130 priv->geometry.width () + priv->geometry.border () * 2 +123 geometry ().widthIncBorders () +
131 priv->border.left + priv->border.right,124 priv->border.left + priv->border.right,
132 priv->geometry.height () + priv->geometry.border () * 2 +125 geometry ().heightIncBorders () +
133 priv->border.top + priv->border.bottom);126 priv->border.top + priv->border.bottom);
134}127}
135128
136CompRect129CompRect
137CompWindow::serverBorderRect () const130CompWindow::serverBorderRect () const
138{131{
139 return CompRect (priv->serverGeometry.x () - priv->geometry.border () - priv->border.left,132 return CompRect (serverGeometry ().xMinusBorder () - priv->border.left,
140 priv->serverGeometry.y () - priv->geometry.border () - priv->border.top,133 serverGeometry ().yMinusBorder () - priv->border.top,
141 priv->serverGeometry.width () + priv->geometry.border () * 2 +134 serverGeometry ().widthIncBorders () +
142 priv->border.left + priv->border.right,135 priv->border.left + priv->border.right,
143 priv->serverGeometry.height () + priv->geometry.border () * 2 +136 serverGeometry ().heightIncBorders() +
144 priv->border.top + priv->border.bottom);137 priv->border.top + priv->border.bottom);
145}138}
146139
147CompRect140CompRect
148CompWindow::inputRect () const141CompWindow::inputRect () const
149{142{
150 return CompRect (priv->geometry.x () - priv->geometry.border () - priv->serverInput.left,143 return CompRect (geometry ().xMinusBorder () - priv->serverInput.left,
151 priv->geometry.y () - priv->geometry.border () - priv->serverInput.top,144 geometry ().yMinusBorder () - priv->serverInput.top,
152 priv->geometry.width () + priv->geometry.border () * 2 +145 geometry ().widthIncBorders () +
153 priv->serverInput.left + priv->serverInput.right,146 priv->serverInput.left + priv->serverInput.right,
154 priv->geometry.height () +priv->geometry.border () * 2 +147 geometry ().heightIncBorders () +
155 priv->serverInput.top + priv->serverInput.bottom);148 priv->serverInput.top + priv->serverInput.bottom);
156}149}
157150
158CompRect151CompRect
159CompWindow::serverInputRect () const152CompWindow::serverInputRect () const
160{153{
161 return CompRect (priv->serverGeometry.x () - priv->serverGeometry.border () - priv->serverInput.left,154 return CompRect (serverGeometry ().xMinusBorder () - priv->serverInput.left,
162 priv->serverGeometry.y () - priv->serverGeometry.border () - priv->serverInput.top,155 serverGeometry ().yMinusBorder () - priv->serverInput.top,
163 priv->serverGeometry.width () + priv->serverGeometry.border () * 2 +156 serverGeometry ().widthIncBorders () +
164 priv->serverInput.left + priv->serverInput.right,157 priv->serverInput.left + priv->serverInput.right,
165 priv->serverGeometry.height () + priv->serverGeometry.border () * 2 +158 serverGeometry ().heightIncBorders () +
166 priv->serverInput.top + priv->serverInput.bottom);159 priv->serverInput.top + priv->serverInput.bottom);
167}160}
168161
169CompRect162CompRect
170CompWindow::outputRect () const163CompWindow::outputRect () const
171{164{
172 return CompRect (priv->geometry.x () - priv->serverGeometry.border ()- priv->output.left,165 return CompRect (geometry ().xMinusBorder ()- priv->output.left,
173 priv->geometry.y () - priv->serverGeometry.border () - priv->output.top,166 geometry ().yMinusBorder () - priv->output.top,
174 priv->geometry.width () + priv->serverGeometry.border () * 2 +167 geometry ().widthIncBorders () +
175 priv->output.left + priv->output.right,168 priv->output.left + priv->output.right,
176 priv->geometry.height () + priv->serverGeometry.border () * 2 +169 geometry ().heightIncBorders () +
177 priv->output.top + priv->output.bottom);170 priv->output.top + priv->output.bottom);
178}171}
179172
180CompRect173CompRect
181CompWindow::serverOutputRect () const174CompWindow::serverOutputRect () const
182{175{
183 return CompRect (priv->serverGeometry.x () - priv->serverGeometry.border () - priv->output.left,176 return CompRect (serverGeometry ().xMinusBorder () - priv->output.left,
184 priv->serverGeometry.y () - priv->serverGeometry.border () - priv->output.top,177 serverGeometry ().yMinusBorder () - priv->output.top,
185 priv->serverGeometry.width () + priv->serverGeometry.border () * 2 +178 serverGeometry ().widthIncBorders () +
186 priv->output.left + priv->output.right,179 priv->output.left + priv->output.right,
187 priv->serverGeometry.height () + priv->serverGeometry.border () * 2 +180 serverGeometry ().heightIncBorders () +
188 priv->output.top + priv->output.bottom);181 priv->output.top + priv->output.bottom);
189}182}

Subscribers

People subscribed via source and target branches