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

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

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

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

Description of the change

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

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

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

Caveats:

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

Testing plan?

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

To post a comment you must log in.
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 :

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 :

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

#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 :

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 :

> > #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 :

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

2991. By Sam Spilsbury

Cleanup, fix removal of XSynchronize and detect error conditions

2992. By Sam Spilsbury

Fix silly typo

2993. By Sam Spilsbury

Merge lp:compiz-core

2994. By Sam Spilsbury

Use reference

2995. By Sam Spilsbury

Merge trunk

2996. By Sam Spilsbury

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

2997. By Sam Spilsbury

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

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

2998. By Sam Spilsbury

Replace instances of geometry with serverGeoemtry where appropriate

2999. By Sam Spilsbury

Merge lp:compiz-core

3000. By Sam Spilsbury

Fix typoo

3001. By Sam Spilsbury

Merge trunk

3002. By Sam Spilsbury

Remove abi breaks

3003. By Sam Spilsbury

Don't break abi

3004. By Sam Spilsbury

Use geometry last sent to server to calculate damage rects

3005. By Sam Spilsbury

Use server side rects for calculating clip regions

3006. By Sam Spilsbury

Use serverGeometry

3007. By Sam Spilsbury

Damage the screen when windows are resized

3008. By Sam Spilsbury

Style issue

3009. By Sam Spilsbury

Merged trunk and fixed a number of problems with resize synchronization

3010. By Sam Spilsbury

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

3011. By Sam Spilsbury

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

Only rebind on paints.

3012. By Sam Spilsbury

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

3013. By Sam Spilsbury

Null check

3014. By Sam Spilsbury

resize: unconditionally finish the resize operation when releasing the button

3015. By Sam Spilsbury

Merge trunk

3016. By Sam Spilsbury

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

3017. By Sam Spilsbury

Cleanup wobbly model update code

3018. By Sam Spilsbury

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

3019. By Sam Spilsbury

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

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

3020. By Sam Spilsbury

Clean some cruft

3021. By Sam Spilsbury

Update decoration matrix of shaded windows

3022. By Sam Spilsbury

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

3023. By Sam Spilsbury

Merge lp:compiz-core

3024. By Sam Spilsbury

Don't notify plugins of unreparent in the right place

3025. By Sam Spilsbury

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

3026. By Sam Spilsbury

updateState is bitwise, so never clobber it

3027. By Sam Spilsbury

Base decision to send notifications to plugins on absolute position
changes

3028. By Sam Spilsbury

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

3029. By Sam Spilsbury

Remove some unnecessary cahgnes in the wobbly plugin

3030. By Sam Spilsbury

Merge lp:compiz-core

3031. By Sam Spilsbury

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

3032. By Sam Spilsbury

Fix logic errors

3033. By Sam Spilsbury

!= 0 not necessary

3034. By Sam Spilsbury

Merge lp:compiz-core

Unmerged revisions

3034. By Sam Spilsbury

Merge lp:compiz-core

3033. By Sam Spilsbury

!= 0 not necessary

3032. By Sam Spilsbury

Fix logic errors

3031. By Sam Spilsbury

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

3030. By Sam Spilsbury

Merge lp:compiz-core

3029. By Sam Spilsbury

Remove some unnecessary cahgnes in the wobbly plugin

3028. By Sam Spilsbury

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

3027. By Sam Spilsbury

Base decision to send notifications to plugins on absolute position
changes

3026. By Sam Spilsbury

updateState is bitwise, so never clobber it

3025. By Sam Spilsbury

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'include/core/window.h'
--- include/core/window.h 2012-02-16 09:55:06 +0000
+++ include/core/window.h 2012-02-28 07:29:19 +0000
@@ -406,9 +406,9 @@
406406
407 bool hasUnmapReference ();407 bool hasUnmapReference ();
408408
409 bool resize (XWindowAttributes);409 bool resize (const XWindowAttributes &);
410410
411 bool resize (Geometry);411 bool resize (const Geometry &);
412412
413 bool resize (int x, int y, int width, int height,413 bool resize (int x, int y, int width, int height,
414 int border = 0);414 int border = 0);
415415
=== modified file 'plugins/composite/src/window.cpp'
--- plugins/composite/src/window.cpp 2012-02-01 17:49:07 +0000
+++ plugins/composite/src/window.cpp 2012-02-28 07:29:19 +0000
@@ -250,7 +250,7 @@
250250
251 if (x2 > x1 && y2 > y1)251 if (x2 > x1 && y2 > y1)
252 {252 {
253 CompWindow::Geometry geom = priv->window->geometry ();253 CompWindow::Geometry geom = priv->window->serverGeometry ();
254254
255 x1 += geom.x () + geom.border ();255 x1 += geom.x () + geom.border ();
256 y1 += geom.y () + geom.border ();256 y1 += geom.y () + geom.border ();
@@ -272,20 +272,20 @@
272 {272 {
273 int x1, x2, y1, y2;273 int x1, x2, y1, y2;
274274
275 CompWindow::Geometry geom = priv->window->geometry ();275 const CompWindow::Geometry &geom = priv->window->serverGeometry ();
276 CompWindowExtents output = priv->window->output ();276 const CompWindowExtents &output = priv->window->output ();
277277
278 /* top */278 /* top */
279 x1 = -output.left - geom.border ();279 x1 = -output.left - geom.border ();
280 y1 = -output.top - geom.border ();280 y1 = -output.top - geom.border ();
281 x2 = priv->window->size ().width () + output.right - geom.border ();281 x2 = priv->window->serverGeometry ().width () + geom.border () + output.right;
282 y2 = -geom.border ();282 y2 = -geom.border ();
283283
284 if (x1 < x2 && y1 < y2)284 if (x1 < x2 && y1 < y2)
285 addDamageRect (CompRect (x1, y1, x2 - x1, y2 - y1));285 addDamageRect (CompRect (x1, y1, x2 - x1, y2 - y1));
286286
287 /* bottom */287 /* bottom */
288 y1 = priv->window->size ().height () - geom.border ();288 y1 = priv->window->serverGeometry ().height () + geom.border ();
289 y2 = y1 + output.bottom - geom.border ();289 y2 = y1 + output.bottom - geom.border ();
290290
291 if (x1 < x2 && y1 < y2)291 if (x1 < x2 && y1 < y2)
@@ -295,13 +295,13 @@
295 x1 = -output.left - geom.border ();295 x1 = -output.left - geom.border ();
296 y1 = -geom.border ();296 y1 = -geom.border ();
297 x2 = -geom.border ();297 x2 = -geom.border ();
298 y2 = priv->window->size ().height () - geom.border ();298 y2 = priv->window->serverGeometry ().height () - geom.border ();
299299
300 if (x1 < x2 && y1 < y2)300 if (x1 < x2 && y1 < y2)
301 addDamageRect (CompRect (x1, y1, x2 - x1, y2 - y1));301 addDamageRect (CompRect (x1, y1, x2 - x1, y2 - y1));
302302
303 /* right */303 /* right */
304 x1 = priv->window->size ().width () - geom.border ();304 x1 = priv->window->serverGeometry ().width () - geom.border ();
305 x2 = x1 + output.right - geom.border ();305 x2 = x1 + output.right - geom.border ();
306306
307 if (x1 < x2 && y1 < y2)307 if (x1 < x2 && y1 < y2)
@@ -322,7 +322,7 @@
322 x = rect.x ();322 x = rect.x ();
323 y = rect.y ();323 y = rect.y ();
324324
325 CompWindow::Geometry geom = priv->window->geometry ();325 const CompWindow::Geometry &geom = priv->window->serverGeometry ();
326 x += geom.x () + geom.border ();326 x += geom.x () + geom.border ();
327 y += geom.y () + geom.border ();327 y += geom.y () + geom.border ();
328328
@@ -341,16 +341,16 @@
341 if (priv->window->shaded () || force ||341 if (priv->window->shaded () || force ||
342 (priv->window->isViewable ()))342 (priv->window->isViewable ()))
343 {343 {
344 int border = priv->window->geometry ().border ();344 int border = priv->window->serverGeometry ().border ();
345345
346 int x1 = -MAX (priv->window->output ().left,346 int x1 = -MAX (priv->window->output ().left,
347 priv->window->input ().left) - border;347 priv->window->input ().left) - border;
348 int y1 = -MAX (priv->window->output ().top,348 int y1 = -MAX (priv->window->output ().top,
349 priv->window->input ().top) - border;349 priv->window->input ().top) - border;
350 int x2 = priv->window->size ().width () +350 int x2 = priv->window->serverGeometry ().width () +
351 MAX (priv->window->output ().right,351 MAX (priv->window->output ().right,
352 priv->window->input ().right) ;352 priv->window->input ().right) ;
353 int y2 = priv->window->size ().height () +353 int y2 = priv->window->serverGeometry ().height () +
354 MAX (priv->window->output ().bottom,354 MAX (priv->window->output ().bottom,
355 priv->window->input ().bottom) ;355 priv->window->input ().bottom) ;
356 CompRect r (x1, y1, x2 - x1, y2 - y1);356 CompRect r (x1, y1, x2 - x1, y2 - y1);
@@ -410,7 +410,7 @@
410410
411 if (!w->damageRect (initial, CompRect (x, y, width, height)))411 if (!w->damageRect (initial, CompRect (x, y, width, height)))
412 {412 {
413 CompWindow::Geometry geom = w->priv->window->geometry ();413 CompWindow::Geometry geom = w->priv->window->serverGeometry ();
414414
415 x += geom.x () + geom.border ();415 x += geom.x () + geom.border ();
416 y += geom.y () + geom.border ();416 y += geom.y () + geom.border ();
@@ -622,14 +622,14 @@
622 {622 {
623 int x, y, x1, x2, y1, y2;623 int x, y, x1, x2, y1, y2;
624624
625 x = window->geometry ().x ();625 x = window->serverGeometry ().x ();
626 y = window->geometry ().y ();626 y = window->serverGeometry ().y ();
627627
628 x1 = x - window->output ().left - dx;628 x1 = x - window->output ().left - dx;
629 y1 = y - window->output ().top - dy;629 y1 = y - window->output ().top - dy;
630 x2 = x + window->size ().width () +630 x2 = x + window->serverGeometry ().width () +
631 window->output ().right - dx;631 window->output ().right - dx;
632 y2 = y + window->size ().height () +632 y2 = y + window->serverGeometry ().height () +
633 window->output ().bottom - dy;633 window->output ().bottom - dy;
634634
635 cScreen->damageRegion (CompRegion (CompRect (x1, y1, x2 - x1, y2 - y1)));635 cScreen->damageRegion (CompRegion (CompRect (x1, y1, x2 - x1, y2 - y1)));
636636
=== modified file 'plugins/decor/src/decor.cpp'
--- plugins/decor/src/decor.cpp 2012-02-27 09:58:19 +0000
+++ plugins/decor/src/decor.cpp 2012-02-28 07:29:19 +0000
@@ -91,7 +91,7 @@
91void91void
92DecorWindow::computeShadowRegion ()92DecorWindow::computeShadowRegion ()
93{93{
94 shadowRegion = CompRegion (window->outputRect ());94 shadowRegion = CompRegion (window->serverOutputRect ());
9595
96 if (window->type () == CompWindowTypeDropdownMenuMask ||96 if (window->type () == CompWindowTypeDropdownMenuMask ||
97 window->type () == CompWindowTypePopupMenuMask)97 window->type () == CompWindowTypePopupMenuMask)
@@ -141,11 +141,11 @@
141 if (window->type () == CompWindowTypeDropdownMenuMask &&141 if (window->type () == CompWindowTypeDropdownMenuMask &&
142 shadowRegion == CompRegionRef (window->outputRect ().region ()))142 shadowRegion == CompRegionRef (window->outputRect ().region ()))
143 {143 {
144 CompRect area (window->outputRect ().x1 (),144 CompRect area (window->serverOutputRect ().x1 (),
145 window->outputRect ().y1 (),145 window->serverOutputRect ().y1 (),
146 window->outputRect ().width (),146 window->serverOutputRect ().width (),
147 window->inputRect ().y1 () -147 window->serverInputRect ().y1 () -
148 window->outputRect ().y1 ());148 window->serverOutputRect ().y1 ());
149149
150 shadowRegion -= area;150 shadowRegion -= area;
151 }151 }
@@ -1072,8 +1072,8 @@
1072 for (i = 0; i < wd->nQuad; i++)1072 for (i = 0; i < wd->nQuad; i++)
1073 {1073 {
1074 int x, y;1074 int x, y;
1075 unsigned int width = window->size ().width ();1075 unsigned int width = window->geometry ().width ();
1076 unsigned int height = window->size ().height ();1076 unsigned int height = window->geometry ().height ();
10771077
1078 if (window->shaded ())1078 if (window->shaded ())
1079 height = 0;1079 height = 0;
@@ -1082,8 +1082,8 @@
1082 &x1, &y1, &x2, &y2, &sx, &sy);1082 &x1, &y1, &x2, &y2, &sx, &sy);
10831083
1084 /* Translate by x and y points of this window */1084 /* Translate by x and y points of this window */
1085 x = window->geometry ().x ();1085 x = window->serverGeometry ().x ();
1086 y = window->geometry ().y ();1086 y = window->serverGeometry ().y ();
10871087
1088 wd->quad[i].box.x1 = x1 + x;1088 wd->quad[i].box.x1 = x1 + x;
1089 wd->quad[i].box.y1 = y1 + y;1089 wd->quad[i].box.y1 = y1 + y;
@@ -1111,8 +1111,8 @@
1111bool1111bool
1112DecorWindow::checkSize (const Decoration::Ptr &decoration)1112DecorWindow::checkSize (const Decoration::Ptr &decoration)
1113{1113{
1114 return (decoration->minWidth <= (int) window->size ().width () &&1114 return (decoration->minWidth <= (int) window->geometry ().width () &&
1115 decoration->minHeight <= (int) window->size ().height ());1115 decoration->minHeight <= (int) window->geometry ().height ());
1116}1116}
11171117
1118/*1118/*
@@ -2124,8 +2124,8 @@
2124 {2124 {
2125 int x, y;2125 int x, y;
21262126
2127 x = window->geometry (). x ();2127 x = window->serverGeometry (). x ();
2128 y = window->geometry (). y ();2128 y = window->serverGeometry (). y ();
21292129
2130 region += frameRegion.translated (x - wd->decor->input.left,2130 region += frameRegion.translated (x - wd->decor->input.left,
2131 y - wd->decor->input.top);2131 y - wd->decor->input.top);
@@ -2146,7 +2146,7 @@
2146void2146void
2147DecorWindow::updateWindowRegions ()2147DecorWindow::updateWindowRegions ()
2148{2148{
2149 const CompRect &input (window->inputRect ());2149 const CompRect &input (window->serverInputRect ());
21502150
2151 if (regions.size () != gWindow->textures ().size ())2151 if (regions.size () != gWindow->textures ().size ())
2152 regions.resize (gWindow->textures ().size ());2152 regions.resize (gWindow->textures ().size ());
21532153
=== 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-02-28 07:29:19 +0000
@@ -138,8 +138,8 @@
138 {138 {
139 int xRoot, yRoot;139 int xRoot, yRoot;
140140
141 xRoot = w->geometry ().x () + (w->size ().width () / 2);141 xRoot = w->serverGeometry ().x () + (w->size ().width () / 2);
142 yRoot = w->geometry ().y () + (w->size ().height () / 2);142 yRoot = w->serverGeometry ().y () + (w->size ().height () / 2);
143143
144 s->warpPointer (xRoot - pointerX, yRoot - pointerY);144 s->warpPointer (xRoot - pointerX, yRoot - pointerY);
145 }145 }
@@ -169,8 +169,8 @@
169 if (ms->w)169 if (ms->w)
170 {170 {
171 if (state & CompAction::StateCancel)171 if (state & CompAction::StateCancel)
172 ms->w->move (ms->savedX - ms->w->geometry ().x (),172 ms->w->move (ms->savedX - ms->w->serverGeometry ().x (),
173 ms->savedY - ms->w->geometry ().y (), false);173 ms->savedY - ms->w->serverGeometry ().y (), false);
174174
175 ms->w->syncPosition ();175 ms->w->syncPosition ();
176176
@@ -314,12 +314,12 @@
314314
315 w = ms->w;315 w = ms->w;
316316
317 wX = w->geometry ().x ();317 wX = w->serverGeometry ().x ();
318 wY = w->geometry ().y ();318 wY = w->serverGeometry ().y ();
319 wWidth = w->geometry ().width () +319 wWidth = w->serverGeometry ().width () +
320 w->geometry ().border () * 2;320 w->serverGeometry ().border () * 2;
321 wHeight = w->geometry ().height () +321 wHeight = w->serverGeometry ().height () +
322 w->geometry ().border () * 2;322 w->serverGeometry ().border () * 2;
323323
324 ms->x += xRoot - lastPointerX;324 ms->x += xRoot - lastPointerX;
325 ms->y += yRoot - lastPointerY;325 ms->y += yRoot - lastPointerY;
@@ -484,8 +484,8 @@
484484
485 if (dx || dy)485 if (dx || dy)
486 {486 {
487 w->move (wX + dx - w->geometry ().x (),487 w->move (wX + dx - w->serverGeometry ().x (),
488 wY + dy - w->geometry ().y (), false);488 wY + dy - w->serverGeometry ().y (), false);
489489
490 if (!ms->optionGetLazyPositioning ())490 if (!ms->optionGetLazyPositioning ())
491 w->syncPosition ();491 w->syncPosition ();
492492
=== modified file 'plugins/opengl/src/window.cpp'
--- plugins/opengl/src/window.cpp 2011-03-11 12:15:30 +0000
+++ plugins/opengl/src/window.cpp 2012-02-28 07:29:19 +0000
@@ -76,7 +76,7 @@
76void76void
77PrivateGLWindow::setWindowMatrix ()77PrivateGLWindow::setWindowMatrix ()
78{78{
79 CompRect input (window->inputRect ());79 CompRect input (window->serverInputRect ());
8080
81 if (textures.size () != matrices.size ())81 if (textures.size () != matrices.size ())
82 matrices.resize (textures.size ());82 matrices.resize (textures.size ());
@@ -344,7 +344,7 @@
344void344void
345PrivateGLWindow::updateWindowRegions ()345PrivateGLWindow::updateWindowRegions ()
346{346{
347 CompRect input (window->inputRect ());347 CompRect input (window->serverInputRect ());
348348
349 if (regions.size () != textures.size ())349 if (regions.size () != textures.size ())
350 regions.resize (textures.size ());350 regions.resize (textures.size ());
351351
=== modified file 'src/event.cpp'
--- src/event.cpp 2012-02-22 05:13:00 +0000
+++ src/event.cpp 2012-02-28 07:29:19 +0000
@@ -1249,7 +1249,7 @@
1249 }1249 }
12501250
1251 /* been shaded */1251 /* been shaded */
1252 if (w->priv->height == 0)1252 if (w->shaded ())
1253 {1253 {
1254 if (w->id () == priv->activeWindow)1254 if (w->id () == priv->activeWindow)
1255 w->moveInputFocusTo ();1255 w->moveInputFocusTo ();
12561256
=== modified file 'src/privatewindow.h'
--- src/privatewindow.h 2012-02-14 14:37:04 +0000
+++ src/privatewindow.h 2012-02-28 07:29:19 +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);
@@ -207,8 +211,6 @@
207211
208 void readIconHint ();212 void readIconHint ();
209213
210 bool checkClear ();
211
212 public:214 public:
213215
214 PrivateWindow *priv;216 PrivateWindow *priv;
@@ -240,13 +242,8 @@
240 XSizeHints sizeHints;242 XSizeHints sizeHints;
241 XWMHints *hints;243 XWMHints *hints;
242244
243 struct timeval lastGeometryUpdate;
244 struct timeval lastConfigureRequest;
245
246 bool inputHint;245 bool inputHint;
247 bool alpha;246 bool alpha;
248 int width;
249 int height;
250 CompRegion region;247 CompRegion region;
251 CompRegion inputRegion;248 CompRegion inputRegion;
252 CompRegion frameRegion;249 CompRegion frameRegion;
@@ -289,8 +286,6 @@
289 typedef std::pair <XWindowChanges, unsigned int> XWCValueMask;286 typedef std::pair <XWindowChanges, unsigned int> XWCValueMask;
290287
291 compiz::X11::PendingEventQueue pendingConfigures;288 compiz::X11::PendingEventQueue pendingConfigures;
292 CompTimer mClearCheckTimeout;
293 bool pendingPositionUpdates;
294289
295 char *startupId;290 char *startupId;
296 char *resName;291 char *resName;
@@ -326,6 +321,8 @@
326321
327 bool closeRequests;322 bool closeRequests;
328 Time lastCloseRequestTime;323 Time lastCloseRequestTime;
324
325 bool nextMoveImmediate;
329};326};
330327
331class CoreWindow328class CoreWindow
332329
=== modified file 'src/screen.cpp'
--- src/screen.cpp 2012-02-24 12:18:12 +0000
+++ src/screen.cpp 2012-02-28 07:29:19 +0000
@@ -4536,6 +4536,8 @@
4536 return false;4536 return false;
4537 }4537 }
45384538
4539 /* Use synchronous behaviour when running with --sync, useful
4540 * for getting stacktraces when X Errors occurr */
4539 XSynchronize (dpy, synchronousX ? True : False);4541 XSynchronize (dpy, synchronousX ? True : False);
45404542
4541 snprintf (displayString, 255, "DISPLAY=%s",4543 snprintf (displayString, 255, "DISPLAY=%s",
45424544
=== modified file 'src/window.cpp'
--- src/window.cpp 2012-02-20 02:30:34 +0000
+++ src/window.cpp 2012-02-28 07:29:19 +0000
@@ -75,8 +75,8 @@
75PrivateWindow::isInvisible() const75PrivateWindow::isInvisible() const
76{76{
77 return attrib.map_state != IsViewable ||77 return attrib.map_state != IsViewable ||
78 attrib.x + width + output.right <= 0 ||78 attrib.x + geometry.width () + output.right <= 0 ||
79 attrib.y + height + output.bottom <= 0 ||79 attrib.y + geometry.height () + output.bottom <= 0 ||
80 attrib.x - output.left >= (int) screen->width () ||80 attrib.x - output.left >= (int) screen->width () ||
81 attrib.y - output.top >= (int) screen->height ();81 attrib.y - output.top >= (int) screen->height ();
82}82}
@@ -808,292 +808,14 @@
808 if (!serverFrame)808 if (!serverFrame)
809 return;809 return;
810810
811811 xwc.x = serverGeometry.x ();
812 gettimeofday (&lastConfigureRequest, NULL);812 xwc.y = serverGeometry.y ();
813 /* Flush any changes made to serverFrameGeometry or serverGeometry to the server813 xwc.width = serverGeometry.width ();
814 * since there is a race condition where geometries will go out-of-sync with814 xwc.height = serverGeometry.height ();
815 * window movement */815 xwc.border_width = serverGeometry.border ();
816816
817 window->syncPosition ();817 window->configureXWindow (valueMask, &xwc);
818818 window->windowNotify (CompWindowNotifyFrameUpdate);
819 if (serverInput.left || serverInput.right || serverInput.top || serverInput.bottom)
820 {
821 int bw = serverGeometry.border () * 2;
822
823 xwc.x = serverGeometry.x () - serverInput.left;
824 xwc.y = serverGeometry.y () - serverInput.top;
825 xwc.width = serverGeometry.width () + serverInput.left + serverInput.right + bw;
826 if (shaded)
827 xwc.height = serverInput.top + serverInput.bottom + bw;
828 else
829 xwc.height = serverGeometry.height () + serverInput.top + serverInput.bottom + bw;
830
831 if (shaded)
832 height = serverInput.top + serverInput.bottom;
833
834 if (serverFrameGeometry.x () == xwc.x)
835 valueMask &= ~(CWX);
836 else
837 serverFrameGeometry.setX (xwc.x);
838
839 if (serverFrameGeometry.y () == xwc.y)
840 valueMask &= ~(CWY);
841 else
842 serverFrameGeometry.setY (xwc.y);
843
844 if (serverFrameGeometry.width () == xwc.width)
845 valueMask &= ~(CWWidth);
846 else
847 serverFrameGeometry.setWidth (xwc.width);
848
849 if (serverFrameGeometry.height () == xwc.height)
850 valueMask &= ~(CWHeight);
851 else
852 serverFrameGeometry.setHeight (xwc.height);
853
854 /* Geometry is the same, so we're not going to get a ConfigureNotify
855 * event when the window is configured, which means that other plugins
856 * won't know that the client, frame and wrapper windows got shifted
857 * around (and might result in display corruption, eg in OpenGL */
858 if (valueMask == 0)
859 {
860 XConfigureEvent xev;
861 XWindowAttributes attrib;
862 unsigned int nchildren = 0;
863 Window rootRet = 0, parentRet = 0;
864 Window *children = NULL;
865
866 xev.type = ConfigureNotify;
867 xev.event = screen->root ();
868 xev.window = priv->serverFrame;
869
870 XGrabServer (screen->dpy ());
871
872 if (XGetWindowAttributes (screen->dpy (), priv->serverFrame, &attrib))
873 {
874 xev.x = attrib.x;
875 xev.y = attrib.y;
876 xev.width = attrib.width;
877 xev.height = attrib.height;
878 xev.border_width = attrib.border_width;
879 xev.above = None;
880
881 /* We need to ensure that the stacking order is
882 * based on the current server stacking order so
883 * find the sibling to this window's frame in the
884 * server side stack and stack above that */
885 XQueryTree (screen->dpy (), screen->root (), &rootRet, &parentRet, &children, &nchildren);
886
887 if (nchildren)
888 {
889 for (unsigned int i = 0; i < nchildren; i++)
890 {
891 if (i + 1 == nchildren ||
892 children[i + 1] == ROOTPARENT (window))
893 {
894 xev.above = children[i];
895 break;
896 }
897 }
898 }
899
900 if (children)
901 XFree (children);
902
903 if (!xev.above)
904 xev.above = (window->serverPrev) ? ROOTPARENT (window->serverPrev) : None;
905
906 xev.override_redirect = priv->attrib.override_redirect;
907
908 }
909
910 compiz::X11::PendingEvent::Ptr pc =
911 boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
912 new compiz::X11::PendingConfigureEvent (
913 screen->dpy (), serverFrame, valueMask, &xwc)));
914
915 pendingConfigures.add (pc);
916 if (priv->mClearCheckTimeout.active ())
917 priv->mClearCheckTimeout.stop ();
918 priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
919 2000, 2500);
920
921 XSendEvent (screen->dpy (), screen->root (), false,
922 SubstructureNotifyMask, (XEvent *) &xev);
923
924 XUngrabServer (screen->dpy ());
925 XSync (screen->dpy (), false);
926 }
927 else
928 {
929 compiz::X11::PendingEvent::Ptr pc =
930 boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
931 new compiz::X11::PendingConfigureEvent (
932 screen->dpy (), serverFrame, valueMask, &xwc)));
933
934 pendingConfigures.add (pc);
935 if (priv->mClearCheckTimeout.active ())
936 priv->mClearCheckTimeout.stop ();
937 priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
938 2000, 2500);
939 XConfigureWindow (screen->dpy (), serverFrame, valueMask, &xwc);
940 }
941
942 if (shaded)
943 {
944 XUnmapWindow (screen->dpy (), wrapper);
945 }
946 else
947 {
948 XMapWindow (screen->dpy (), wrapper);
949 XMoveResizeWindow (screen->dpy (), wrapper, serverInput.left, serverInput.top,
950 serverGeometry.width (), serverGeometry.height ());
951 }
952 XMoveResizeWindow (screen->dpy (), id, 0, 0,
953 serverGeometry.width (), serverGeometry.height ());
954 window->sendConfigureNotify ();
955 window->windowNotify (CompWindowNotifyFrameUpdate);
956 }
957 else
958 {
959 int bw = serverGeometry.border () * 2;
960
961 xwc.x = serverGeometry.x ();
962 xwc.y = serverGeometry.y ();
963 xwc.width = serverGeometry.width () + bw;
964
965 /* FIXME: It doesn't make much sense to allow undecorated windows to be
966 * shaded */
967 if (shaded)
968 xwc.height = bw;
969 else
970 xwc.height = serverGeometry.height () + bw;
971
972 if (serverFrameGeometry.x () == xwc.x)
973 valueMask &= ~(CWX);
974 else
975 serverFrameGeometry.setX (xwc.x);
976
977 if (serverFrameGeometry.y () == xwc.y)
978 valueMask &= ~(CWY);
979 else
980 serverFrameGeometry.setY (xwc.y);
981
982 if (serverFrameGeometry.width () == xwc.width)
983 valueMask &= ~(CWWidth);
984 else
985 serverFrameGeometry.setWidth (xwc.width);
986
987 if (serverFrameGeometry.height () == xwc.height)
988 valueMask &= ~(CWHeight);
989 else
990 serverFrameGeometry.setHeight (xwc.height);
991
992 /* Geometry is the same, so we're not going to get a ConfigureNotify
993 * event when the window is configured, which means that other plugins
994 * won't know that the client, frame and wrapper windows got shifted
995 * around (and might result in display corruption, eg in OpenGL */
996 if (valueMask == 0)
997 {
998 XConfigureEvent xev;
999 XWindowAttributes attrib;
1000 unsigned int nchildren = 0;
1001 Window rootRet = 0, parentRet = 0;
1002 Window *children = NULL;
1003
1004 xev.type = ConfigureNotify;
1005 xev.event = screen->root ();
1006 xev.window = priv->serverFrame;
1007
1008 XGrabServer (screen->dpy ());
1009
1010 if (XGetWindowAttributes (screen->dpy (), priv->serverFrame, &attrib))
1011 {
1012 xev.x = attrib.x;
1013 xev.y = attrib.y;
1014 xev.width = attrib.width;
1015 xev.height = attrib.height;
1016 xev.border_width = attrib.border_width;
1017 xev.above = None;
1018
1019 /* We need to ensure that the stacking order is
1020 * based on the current server stacking order so
1021 * find the sibling to this window's frame in the
1022 * server side stack and stack above that */
1023 XQueryTree (screen->dpy (), screen->root (), &rootRet, &parentRet, &children, &nchildren);
1024
1025 if (nchildren)
1026 {
1027 for (unsigned int i = 0; i < nchildren; i++)
1028 {
1029 if (i + 1 == nchildren ||
1030 children[i + 1] == ROOTPARENT (window))
1031 {
1032 xev.above = children[i];
1033 break;
1034 }
1035 }
1036 }
1037
1038 if (children)
1039 XFree (children);
1040
1041 if (!xev.above)
1042 xev.above = (window->serverPrev) ? ROOTPARENT (window->serverPrev) : None;
1043
1044 xev.override_redirect = priv->attrib.override_redirect;
1045
1046 }
1047
1048 compiz::X11::PendingEvent::Ptr pc =
1049 boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
1050 new compiz::X11::PendingConfigureEvent (
1051 screen->dpy (), serverFrame, valueMask, &xwc)));
1052
1053 pendingConfigures.add (pc);
1054 if (priv->mClearCheckTimeout.active ())
1055 priv->mClearCheckTimeout.stop ();
1056 priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
1057 2000, 2500);
1058
1059 XSendEvent (screen->dpy (), screen->root (), false,
1060 SubstructureNotifyMask, (XEvent *) &xev);
1061
1062 XUngrabServer (screen->dpy ());
1063 XSync (screen->dpy (), false);
1064 }
1065 else
1066 {
1067 compiz::X11::PendingEvent::Ptr pc =
1068 boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
1069 new compiz::X11::PendingConfigureEvent (
1070 screen->dpy (), serverFrame, valueMask, &xwc)));
1071
1072 pendingConfigures.add (pc);
1073 if (priv->mClearCheckTimeout.active ())
1074 priv->mClearCheckTimeout.stop ();
1075 priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
1076 2000, 2500);
1077
1078 XConfigureWindow (screen->dpy (), serverFrame, valueMask, &xwc);
1079 }
1080
1081 if (shaded)
1082 {
1083 XUnmapWindow (screen->dpy (), wrapper);
1084 }
1085 else
1086 {
1087 XMapWindow (screen->dpy (), wrapper);
1088 XMoveResizeWindow (screen->dpy (), wrapper, 0, 0,
1089 serverGeometry.width (), serverGeometry.height ());
1090 }
1091
1092 XMoveResizeWindow (screen->dpy (), id, 0, 0,
1093 serverGeometry.width (), serverGeometry.height ());
1094 window->sendConfigureNotify ();
1095 window->windowNotify (CompWindowNotifyFrameUpdate);
1096 }
1097 window->recalcActions ();819 window->recalcActions ();
1098}820}
1099821
@@ -1136,8 +858,8 @@
1136858
1137 for (unsigned int i = 0; i < n; i++)859 for (unsigned int i = 0; i < n; i++)
1138 {860 {
1139 x1 = rects[i].x + priv->geometry.border ();861 x1 = rects[i].x + priv->serverGeometry.border ();
1140 y1 = rects[i].y + priv->geometry.border ();862 y1 = rects[i].y + priv->serverGeometry.border ();
1141 x2 = x1 + rects[i].width;863 x2 = x1 + rects[i].width;
1142 y2 = y1 + rects[i].height;864 y2 = y1 + rects[i].height;
1143865
@@ -1145,17 +867,17 @@
1145 x1 = 0;867 x1 = 0;
1146 if (y1 < 0)868 if (y1 < 0)
1147 y1 = 0;869 y1 = 0;
1148 if (x2 > priv->width)870 if (x2 > priv->serverGeometry.width ())
1149 x2 = priv->width;871 x2 = priv->serverGeometry.height ();
1150 if (y2 > priv->height)872 if (y2 > priv->serverGeometry.width ())
1151 y2 = priv->height;873 y2 = priv->serverGeometry.height ();
1152874
1153 if (y1 < y2 && x1 < x2)875 if (y1 < y2 && x1 < x2)
1154 {876 {
1155 x1 += priv->geometry.x ();877 x1 += priv->serverGeometry.x ();
1156 y1 += priv->geometry.y ();878 y1 += priv->serverGeometry.y ();
1157 x2 += priv->geometry.x ();879 x2 += priv->serverGeometry.x ();
1158 y2 += priv->geometry.y ();880 y2 += priv->serverGeometry.y ();
1159881
1160 ret += CompRect (x1, y1, x2 - x1, y2 - y1);882 ret += CompRect (x1, y1, x2 - x1, y2 - y1);
1161 }883 }
@@ -1183,17 +905,19 @@
1183 {905 {
1184 int order;906 int order;
1185907
908 /* We should update the server here */
909 XSync (screen->dpy (), false);
910
1186 boundingShapeRects = XShapeGetRectangles (screen->dpy (), priv->id,911 boundingShapeRects = XShapeGetRectangles (screen->dpy (), priv->id,
1187 ShapeBounding, &nBounding, &order);912 ShapeBounding, &nBounding, &order);
1188 inputShapeRects = XShapeGetRectangles (screen->dpy (), priv->id,913 inputShapeRects = XShapeGetRectangles (screen->dpy (), priv->id,
1189 ShapeInput, &nInput, &order);914 ShapeInput, &nInput, &order);
1190
1191 }915 }
1192916
1193 r.x = -priv->geometry.border ();917 r.x = -priv->serverGeometry.border ();
1194 r.y = -priv->geometry.border ();918 r.y = -priv->serverGeometry.border ();
1195 r.width = priv->width + priv->geometry.border ();919 r.width = priv->serverGeometry.width () + priv->serverGeometry.border ();
1196 r.height = priv->height + priv->geometry.border ();920 r.height = priv->serverGeometry.height () + priv->serverGeometry.border ();
1197921
1198 if (nBounding < 1)922 if (nBounding < 1)
1199 {923 {
@@ -1726,7 +1450,7 @@
1726 priv->attrib.map_state = IsUnmapped;1450 priv->attrib.map_state = IsUnmapped;
1727 priv->invisible = true;1451 priv->invisible = true;
17281452
1729 if (priv->shaded && priv->height)1453 if (priv->shaded)
1730 {1454 {
1731 priv->updateFrameWindow ();1455 priv->updateFrameWindow ();
1732 }1456 }
@@ -1794,7 +1518,7 @@
1794}1518}
17951519
1796bool1520bool
1797CompWindow::resize (XWindowAttributes attr)1521CompWindow::resize (const XWindowAttributes &attr)
1798{1522{
1799 return resize (Geometry (attr.x, attr.y, attr.width, attr.height,1523 return resize (Geometry (attr.x, attr.y, attr.width, attr.height,
1800 attr.border_width));1524 attr.border_width));
@@ -1811,7 +1535,7 @@
1811}1535}
18121536
1813bool1537bool
1814CompWindow::resize (CompWindow::Geometry gm)1538PrivateWindow::resize (const CompWindow::Geometry &gm)
1815{1539{
1816 /* Input extents are now the last thing sent1540 /* Input extents are now the last thing sent
1817 * from the server. This might not work in some1541 * from the server. This might not work in some
@@ -1828,12 +1552,8 @@
1828 priv->geometry.height () != gm.height () ||1552 priv->geometry.height () != gm.height () ||
1829 priv->geometry.border () != gm.border ())1553 priv->geometry.border () != gm.border ())
1830 {1554 {
1831 int pw, ph;
1832 int dx, dy, dwidth, dheight;1555 int dx, dy, dwidth, dheight;
18331556
1834 pw = gm.width () + gm.border () * 2;
1835 ph = gm.height () + gm.border () * 2;
1836
1837 dx = gm.x () - priv->geometry.x ();1557 dx = gm.x () - priv->geometry.x ();
1838 dy = gm.y () - priv->geometry.y ();1558 dy = gm.y () - priv->geometry.y ();
1839 dwidth = gm.width () - priv->geometry.width ();1559 dwidth = gm.width () - priv->geometry.width ();
@@ -1843,37 +1563,60 @@
1843 gm.width (), gm.height (),1563 gm.width (), gm.height (),
1844 gm.border ());1564 gm.border ());
18451565
1846 priv->width = pw;1566 if (priv->attrib.override_redirect)
1847 priv->height = ph;1567 {
1568 priv->serverGeometry = priv->geometry;
1569 priv->serverFrameGeometry = priv->frameGeometry;
1570 }
18481571
1849 if (priv->mapNum)1572 if (priv->mapNum)
1850 priv->updateRegion ();1573 priv->updateRegion ();
18511574
1852 resizeNotify (dx, dy, dwidth, dheight);1575 window->resizeNotify (dx, dy, dwidth, dheight);
18531576
1854 priv->invisible = priv->isInvisible ();1577 priv->invisible = priv->isInvisible ();
1855 }1578 }
1856 else if (priv->geometry.x () != gm.x () || priv->geometry.y () != gm.y ())1579 else if (priv->geometry.x () != gm.x () || priv->geometry.y () != gm.y ())
1857 {1580 {
1858 int dx, dy;1581 move (gm.x () - priv->geometry.x (),
18591582 gm.y () - priv->geometry.y (), true);
1860 dx = gm.x () - priv->geometry.x ();
1861 dy = gm.y () - priv->geometry.y ();
1862
1863 priv->geometry.setX (gm.x ());
1864 priv->geometry.setY (gm.y ());
1865
1866 priv->region.translate (dx, dy);
1867 priv->inputRegion.translate (dx, dy);
1868 if (!priv->frameRegion.isEmpty ())
1869 priv->frameRegion.translate (dx, dy);
1870
1871 priv->invisible = priv->isInvisible ();
1872
1873 moveNotify (dx, dy, true);
1874 }1583 }
18751584
1876 updateFrameRegion ();1585 window->updateFrameRegion ();
1586
1587 return true;
1588}
1589
1590bool
1591PrivateWindow::resize (const XWindowAttributes &attr)
1592{
1593 return resize (CompWindow::Geometry (attr.x, attr.y, attr.width, attr.height,
1594 attr.border_width));
1595}
1596
1597bool
1598PrivateWindow::resize (int x,
1599 int y,
1600 int width,
1601 int height,
1602 int border)
1603{
1604 return resize (CompWindow::Geometry (x, y, width, height, border));
1605}
1606
1607bool
1608CompWindow::resize (const CompWindow::Geometry &gm)
1609{
1610 XWindowChanges xwc = XWINDOWCHANGES_INIT;
1611 unsigned int valueMask = CWX | CWY | CWWidth | CWHeight | CWBorderWidth;
1612
1613 xwc.x = gm.x ();
1614 xwc.y = gm.y ();
1615 xwc.width = gm.width ();
1616 xwc.height = gm.height ();
1617 xwc.border_width = gm.border ();
1618
1619 configureXWindow (valueMask, &xwc);
18771620
1878 return true;1621 return true;
1879}1622}
@@ -2041,13 +1784,7 @@
2041 ce->border_width);1784 ce->border_width);
2042 else1785 else
2043 {1786 {
2044 if (ce->override_redirect)1787 resize (ce->x, ce->y, ce->width, ce->height, ce->border_width);
2045 {
2046 priv->serverGeometry.set (ce->x, ce->y, ce->width, ce->height,
2047 ce->border_width);
2048 }
2049
2050 window->resize (ce->x, ce->y, ce->width, ce->height, ce->border_width);
2051 }1788 }
20521789
2053 if (ce->event == screen->root ())1790 if (ce->event == screen->root ())
@@ -2128,7 +1865,7 @@
2128 if (priv->syncWait)1865 if (priv->syncWait)
2129 priv->syncGeometry.set (x, y, width, height, ce->border_width);1866 priv->syncGeometry.set (x, y, width, height, ce->border_width);
2130 else1867 else
2131 window->resize (x, y, width, height, ce->border_width);1868 resize (x, y, width, height, ce->border_width);
21321869
2133 if (priv->restack (ce->above))1870 if (priv->restack (ce->above))
2134 priv->updatePassiveButtonGrabs ();1871 priv->updatePassiveButtonGrabs ();
@@ -2137,27 +1874,6 @@
21371874
2138 if (above)1875 if (above)
2139 above->priv->updatePassiveButtonGrabs ();1876 above->priv->updatePassiveButtonGrabs ();
2140
2141 if (!pendingConfigures.pending ())
2142 {
2143 /* Tell plugins its ok to start doing stupid things again but
2144 * obviously FIXME */
2145 CompOption::Vector options;
2146 CompOption::Value v;
2147
2148 options.push_back (CompOption ("window", CompOption::TypeInt));
2149 v.set ((int) id);
2150 options.back ().set (v);
2151 options.push_back (CompOption ("active", CompOption::TypeInt));
2152 v.set ((int) 0);
2153 options.back ().set (v);
2154
2155 /* Notify other plugins that it is unsafe to change geometry or serverGeometry
2156 * FIXME: That API should not be accessible to plugins, this is a hack to avoid
2157 * breaking ABI */
2158
2159 screen->handleCompizEvent ("core", "lock_position", options);
2160 }
2161}1877}
21621878
2163void1879void
@@ -2180,23 +1896,34 @@
2180{1896{
2181 if (dx || dy)1897 if (dx || dy)
2182 {1898 {
2183 gettimeofday (&priv->lastGeometryUpdate, NULL);1899 XWindowChanges xwc = XWINDOWCHANGES_INIT;
21841900 unsigned int valueMask = CWX | CWY;
2185 /* Don't allow window movement to overwrite working geometries1901
2186 * last received from the server if we know there are pending1902 xwc.x = priv->serverGeometry.x () + dx;
2187 * ConfigureNotify events on this window. That's a clunky workaround1903 xwc.y = priv->serverGeometry.y () + dy;
2188 * and a FIXME in any case, however, until we can break the API1904
2189 * and remove CompWindow::move, this will need to be the case */1905 priv->nextMoveImmediate = immediate;
21901906
2191 if (!priv->pendingConfigures.pending ())1907 configureXWindow (valueMask, &xwc);
1908 }
1909}
1910
1911void
1912PrivateWindow::move (int dx,
1913 int dy,
1914 bool immediate)
1915{
1916 if (dx || dy)
1917 {
1918 priv->geometry.setX (priv->geometry.x () + dx);
1919 priv->geometry.setY (priv->geometry.y () + dy);
1920 priv->frameGeometry.setX (priv->frameGeometry.x () + dx);
1921 priv->frameGeometry.setY (priv->frameGeometry.y () + dy);
1922
1923 if (priv->attrib.override_redirect)
2192 {1924 {
2193 priv->geometry.setX (priv->geometry.x () + dx);1925 priv->serverGeometry = priv->geometry;
2194 priv->geometry.setY (priv->geometry.y () + dy);1926 priv->serverFrameGeometry = priv->frameGeometry;
2195 priv->frameGeometry.setX (priv->frameGeometry.x () + dx);
2196 priv->frameGeometry.setY (priv->frameGeometry.y () + dy);
2197
2198 priv->pendingPositionUpdates = true;
2199
2200 priv->region.translate (dx, dy);1927 priv->region.translate (dx, dy);
2201 priv->inputRegion.translate (dx, dy);1928 priv->inputRegion.translate (dx, dy);
2202 if (!priv->frameRegion.isEmpty ())1929 if (!priv->frameRegion.isEmpty ())
@@ -2204,19 +1931,7 @@
22041931
2205 priv->invisible = priv->isInvisible ();1932 priv->invisible = priv->isInvisible ();
22061933
2207 moveNotify (dx, dy, immediate);1934 window->moveNotify (dx, dy, true);
2208 }
2209 else
2210 {
2211 XWindowChanges xwc = XWINDOWCHANGES_INIT;
2212 unsigned int valueMask = CWX | CWY;
2213 compLogMessage ("core", CompLogLevelDebug, "pending configure notifies on 0x%x, "\
2214 "moving window asyncrhonously!", (unsigned int) priv->serverId);
2215
2216 xwc.x = priv->serverGeometry.x () + dx;
2217 xwc.y = priv->serverGeometry.y () + dy;
2218
2219 configureXWindow (valueMask, &xwc);
2220 }1935 }
2221 }1936 }
2222}1937}
@@ -2227,22 +1942,6 @@
2227 return !mEvents.empty ();1942 return !mEvents.empty ();
2228}1943}
22291944
2230bool
2231PrivateWindow::checkClear ()
2232{
2233 if (pendingConfigures.pending ())
2234 {
2235 /* FIXME: This is a hack to avoid performance regressions
2236 * and must be removed in 0.9.6 */
2237 compLogMessage ("core", CompLogLevelWarn, "failed to receive ConfigureNotify event on 0x%x\n",
2238 id);
2239 pendingConfigures.dump ();
2240 pendingConfigures.clear ();
2241 }
2242
2243 return false;
2244}
2245
2246void1945void
2247compiz::X11::PendingEventQueue::add (PendingEvent::Ptr p)1946compiz::X11::PendingEventQueue::add (PendingEvent::Ptr p)
2248{1947{
@@ -2464,21 +2163,6 @@
2464 mValueMask (valueMask),2163 mValueMask (valueMask),
2465 mXwc (*xwc)2164 mXwc (*xwc)
2466{2165{
2467 CompOption::Vector options;
2468 CompOption::Value v;
2469
2470 options.push_back (CompOption ("window", CompOption::TypeInt));
2471 v.set ((int) w);
2472 options.back ().set (v);
2473 options.push_back (CompOption ("active", CompOption::TypeInt));
2474 v.set ((int) 1);
2475 options.back ().set (v);
2476
2477 /* Notify other plugins that it is unsafe to change geometry or serverGeometry
2478 * FIXME: That API should not be accessible to plugins, this is a hack to avoid
2479 * breaking ABI */
2480
2481 screen->handleCompizEvent ("core", "lock_position", options);
2482}2166}
24832167
2484compiz::X11::PendingConfigureEvent::~PendingConfigureEvent ()2168compiz::X11::PendingConfigureEvent::~PendingConfigureEvent ()
@@ -2488,57 +2172,6 @@
2488void2172void
2489CompWindow::syncPosition ()2173CompWindow::syncPosition ()
2490{2174{
2491 gettimeofday (&priv->lastConfigureRequest, NULL);
2492
2493 unsigned int valueMask = CWX | CWY;
2494 XWindowChanges xwc = XWINDOWCHANGES_INIT;
2495
2496 if (priv->pendingPositionUpdates && !priv->pendingConfigures.pending ())
2497 {
2498 if (priv->serverFrameGeometry.x () == priv->frameGeometry.x ())
2499 valueMask &= ~(CWX);
2500 if (priv->serverFrameGeometry.y () == priv->frameGeometry.y ())
2501 valueMask &= ~(CWY);
2502
2503 /* Because CompWindow::move can update the geometry last
2504 * received from the server, we must indicate that no values
2505 * changed, because when the ConfigureNotify comes around
2506 * the values are going to be the same. That's obviously
2507 * broken behaviour and worthy of a FIXME, but requires
2508 * larger changes to the window movement system. */
2509 if (valueMask)
2510 {
2511 priv->serverGeometry.setX (priv->geometry.x ());
2512 priv->serverGeometry.setY (priv->geometry.y ());
2513 priv->serverFrameGeometry.setX (priv->frameGeometry.x ());
2514 priv->serverFrameGeometry.setY (priv->frameGeometry.y ());
2515
2516 xwc.x = priv->serverFrameGeometry.x ();
2517 xwc.y = priv->serverFrameGeometry.y ();
2518
2519 compiz::X11::PendingEvent::Ptr pc =
2520 boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
2521 new compiz::X11::PendingConfigureEvent (
2522 screen->dpy (), priv->serverFrame, 0, &xwc)));
2523
2524 priv->pendingConfigures.add (pc);
2525
2526 /* Got 3 seconds to get its stuff together */
2527 if (priv->mClearCheckTimeout.active ())
2528 priv->mClearCheckTimeout.stop ();
2529 priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
2530 2000, 2500);
2531 XConfigureWindow (screen->dpy (), ROOTPARENT (this), valueMask, &xwc);
2532
2533 if (priv->serverFrame)
2534 {
2535 XMoveWindow (screen->dpy (), priv->wrapper,
2536 priv->serverInput.left, priv->serverInput.top);
2537 sendConfigureNotify ();
2538 }
2539 }
2540 priv->pendingPositionUpdates = false;
2541 }
2542}2175}
25432176
2544bool2177bool
@@ -3360,14 +2993,23 @@
3360{2993{
3361 unsigned int frameValueMask = 0;2994 unsigned int frameValueMask = 0;
33622995
3363 /* Immediately sync window position2996 if (id == screen->root ())
3364 * if plugins were updating w->geometry () directly2997 {
3365 * in order to avoid a race condition */2998 compLogMessage ("core", CompLogLevelWarn, "attempted to reconfigure root window");
33662999 return;
3367 window->syncPosition ();3000 }
33683001
3369 /* Remove redundant bits */3002 /* Remove redundant bits */
33703003
3004 xwc->x = valueMask & CWX ? xwc->x : serverGeometry.x ();
3005 xwc->y = valueMask & CWY ? xwc->y : serverGeometry.y ();
3006 xwc->width = valueMask & CWWidth ? xwc->width : serverGeometry.width ();
3007 xwc->height = valueMask & CWHeight ? xwc->height : serverGeometry.height ();
3008 xwc->border_width = valueMask & CWBorderWidth ? xwc->border_width : serverGeometry.border ();
3009
3010 /* FIXME: This is a total fallacy for the reparenting case
3011 * at least since the client doesn't actually move here, it only
3012 * moves within the frame */
3371 if (valueMask & CWX && serverGeometry.x () == xwc->x)3013 if (valueMask & CWX && serverGeometry.x () == xwc->x)
3372 valueMask &= ~(CWX);3014 valueMask &= ~(CWX);
33733015
@@ -3434,18 +3076,15 @@
3434 compLogMessage ("core", CompLogLevelWarn, "restack_mode not Above");3076 compLogMessage ("core", CompLogLevelWarn, "restack_mode not Above");
3435 }3077 }
34363078
3437 frameValueMask = valueMask;3079 frameValueMask = CWX | CWY | CWWidth | CWHeight | (valueMask & (CWStackMode | CWSibling));
34383080
3439 if (frameValueMask & CWX &&3081 if (serverFrameGeometry.x () == xwc->x - serverGeometry.border () - serverInput.left)
3440 serverFrameGeometry.x () == xwc->x - serverGeometry.border () - serverInput.left)
3441 frameValueMask &= ~(CWX);3082 frameValueMask &= ~(CWX);
34423083
3443 if (frameValueMask & CWY &&3084 if (serverFrameGeometry.y () == xwc->y - serverGeometry.border () - serverInput.top)
3444 serverFrameGeometry.y () == xwc->y - serverGeometry.border () - serverInput.top)
3445 frameValueMask &= ~(CWY);3085 frameValueMask &= ~(CWY);
34463086
3447 if (frameValueMask & CWWidth &&3087 if (serverFrameGeometry.width () == xwc->width + serverGeometry.border () * 2
3448 serverFrameGeometry.width () == xwc->width + serverGeometry.border () * 2
3449 + serverInput.left + serverInput.right)3088 + serverInput.left + serverInput.right)
3450 frameValueMask &= ~(CWWidth);3089 frameValueMask &= ~(CWWidth);
34513090
@@ -3455,19 +3094,76 @@
34553094
3456 if (shaded)3095 if (shaded)
3457 {3096 {
3458 if (frameValueMask & CWHeight &&3097 if (serverFrameGeometry.height () == serverGeometry.border () * 2
3459 serverFrameGeometry.height () == serverGeometry.border () * 2
3460 + serverInput.top + serverInput.bottom)3098 + serverInput.top + serverInput.bottom)
3461 frameValueMask &= ~(CWHeight);3099 frameValueMask &= ~(CWHeight);
3462 }3100 }
3463 else3101 else
3464 {3102 {
3465 if (frameValueMask & CWHeight &&3103 if (serverFrameGeometry.height () == xwc->height + serverGeometry.border () * 2
3466 serverFrameGeometry.height () == xwc->height + serverGeometry.border () * 2
3467 + serverInput.top + serverInput.bottom)3104 + serverInput.top + serverInput.bottom)
3468 frameValueMask &= ~(CWHeight);3105 frameValueMask &= ~(CWHeight);
3469 }3106 }
34703107
3108 /* Don't allow anything that might generate a BadValue */
3109 if (valueMask & CWWidth && !xwc->width)
3110 {
3111 compLogMessage ("core", CompLogLevelWarn, "Attempted to set < 1 width on a window");
3112 xwc->width = 1;
3113 }
3114
3115 if (valueMask & CWHeight && !xwc->height)
3116 {
3117 compLogMessage ("core", CompLogLevelWarn, "Attempted to set < 1 height on a window");
3118 xwc->height = 1;
3119 }
3120
3121 if (valueMask & CWStackMode &&
3122 ((xwc->stack_mode != TopIf) && (xwc->stack_mode != BottomIf) && (xwc->stack_mode != Opposite) &&
3123 (xwc->stack_mode != Above) && (xwc->stack_mode != Below)))
3124 {
3125 compLogMessage ("core", CompLogLevelWarn, "Invalid stack mode %i", xwc->stack_mode);
3126 valueMask &= ~(CWStackMode | CWSibling);
3127 }
3128
3129 /* Don't allow anything that might cause a BadMatch error */
3130
3131 if (valueMask & CWSibling && !(valueMask & CWStackMode))
3132 {
3133 compLogMessage ("core", CompLogLevelWarn, "Didn't specify a CWStackMode for CWSibling");
3134 valueMask &= ~CWSibling;
3135 }
3136
3137 if (valueMask & CWSibling && xwc->sibling == (serverFrame ? serverFrame : id))
3138 {
3139 compLogMessage ("core", CompLogLevelWarn, "Can't restack a window relative to itself");
3140 valueMask &= ~CWSibling;
3141 }
3142
3143 if (valueMask & CWBorderWidth && attrib.c_class == InputOnly)
3144 {
3145 compLogMessage ("core", CompLogLevelWarn, "Cannot set border_width of an input_only window");
3146 valueMask &= ~CWBorderWidth;
3147 }
3148
3149 if (valueMask & CWSibling)
3150 {
3151 CompWindow *sibling = screen->findTopLevelWindow (xwc->sibling);
3152
3153 if (!sibling)
3154 {
3155 compLogMessage ("core", CompLogLevelWarn, "Attempted to restack relative to 0x%x which is "\
3156 "not a child of the root window or a window compiz owns", static_cast <unsigned int> (xwc->sibling));
3157 valueMask &= ~(CWSibling | CWStackMode);
3158 }
3159 else if (sibling->frame () && xwc->sibling != sibling->frame ())
3160 {
3161 compLogMessage ("core", CompLogLevelWarn, "Attempted to restack relative to 0x%x which is "\
3162 "not a child of the root window", static_cast <unsigned int> (xwc->sibling));
3163 valueMask &= ~(CWSibling | CWStackMode);
3164 }
3165 }
3166
3471 /* Can't set the border width of frame windows */3167 /* Can't set the border width of frame windows */
3472 frameValueMask &= ~(CWBorderWidth);3168 frameValueMask &= ~(CWBorderWidth);
34733169
@@ -3494,11 +3190,8 @@
3494 + serverInput.top + serverInput.bottom);3190 + serverInput.top + serverInput.bottom);
3495 }3191 }
34963192
3497
3498 if (serverFrame)3193 if (serverFrame)
3499 {3194 {
3500 gettimeofday (&lastConfigureRequest, NULL);
3501
3502 if (frameValueMask)3195 if (frameValueMask)
3503 {3196 {
3504 XWindowChanges wc = *xwc;3197 XWindowChanges wc = *xwc;
@@ -3514,15 +3207,20 @@
3514 screen->dpy (), priv->serverFrame, frameValueMask, &wc)));3207 screen->dpy (), priv->serverFrame, frameValueMask, &wc)));
35153208
3516 pendingConfigures.add (pc);3209 pendingConfigures.add (pc);
3517 if (priv->mClearCheckTimeout.active ())
3518 priv->mClearCheckTimeout.stop ();
3519 priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
3520 2000, 2500);
35213210
3522 XConfigureWindow (screen->dpy (), serverFrame, frameValueMask, &wc);3211 XConfigureWindow (screen->dpy (), serverFrame, frameValueMask, &wc);
3523 }3212 }
3213
3524 valueMask &= ~(CWSibling | CWStackMode);3214 valueMask &= ~(CWSibling | CWStackMode);
35253215
3216 /* If the frame has changed position (eg, serverInput.top
3217 * or serverInput.left have changed) then we also need to
3218 * update the client and wrapper position */
3219 if (!(valueMask & CWX))
3220 valueMask |= frameValueMask & CWX;
3221 if (!(valueMask & CWY))
3222 valueMask |= frameValueMask & CWY;
3223
3526 if (valueMask)3224 if (valueMask)
3527 {3225 {
3528 xwc->x = serverInput.left;3226 xwc->x = serverInput.left;
@@ -3710,6 +3408,9 @@
3710CompWindow::configureXWindow (unsigned int valueMask,3408CompWindow::configureXWindow (unsigned int valueMask,
3711 XWindowChanges *xwc)3409 XWindowChanges *xwc)
3712{3410{
3411 int dx = valueMask & CWX ? xwc->x - priv->serverGeometry.x () : 0;
3412 int dy = valueMask & CWY ? xwc->y - priv->serverGeometry.y () : 0;
3413
3713 if (priv->managed && (valueMask & (CWSibling | CWStackMode)))3414 if (priv->managed && (valueMask & (CWSibling | CWStackMode)))
3714 {3415 {
3715 CompWindowList transients;3416 CompWindowList transients;
@@ -3764,6 +3465,16 @@
3764 {3465 {
3765 priv->reconfigureXWindow (valueMask, xwc);3466 priv->reconfigureXWindow (valueMask, xwc);
3766 }3467 }
3468
3469 if (!overrideRedirect () && (dx || dy))
3470 {
3471 priv->region.translate (dx, dy);
3472 priv->inputRegion.translate (dx, dy);
3473 if (!priv->frameRegion.isEmpty ())
3474 priv->frameRegion.translate (dx, dy);
3475 moveNotify (dx, dy, priv->nextMoveImmediate);
3476 priv->nextMoveImmediate = true;
3477 }
3767}3478}
37683479
3769int3480int
@@ -4315,10 +4026,6 @@
4315 screen->dpy (), serverFrame, valueMask, &lxwc)));4026 screen->dpy (), serverFrame, valueMask, &lxwc)));
43164027
4317 pendingConfigures.add (pc);4028 pendingConfigures.add (pc);
4318 if (priv->mClearCheckTimeout.active ())
4319 priv->mClearCheckTimeout.stop ();
4320 priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
4321 2000, 2500);
4322 }4029 }
43234030
4324 /* Below with no sibling puts the window at the bottom4031 /* Below with no sibling puts the window at the bottom
@@ -5489,7 +5196,7 @@
5489 m = priv->geometry.x () + offX;5196 m = priv->geometry.x () + offX;
5490 if (m - priv->input.left < (int) s->width () - vWidth)5197 if (m - priv->input.left < (int) s->width () - vWidth)
5491 rv.setX (offX + vWidth);5198 rv.setX (offX + vWidth);
5492 else if (m + priv->width + priv->input.right > vWidth)5199 else if (m + priv->geometry.width () + priv->input.right > vWidth)
5493 rv.setX (offX - vWidth);5200 rv.setX (offX - vWidth);
5494 else5201 else
5495 rv.setX (offX);5202 rv.setX (offX);
@@ -5504,7 +5211,7 @@
5504 m = priv->geometry.y () + offY;5211 m = priv->geometry.y () + offY;
5505 if (m - priv->input.top < (int) s->height () - vHeight)5212 if (m - priv->input.top < (int) s->height () - vHeight)
5506 rv.setY (offY + vHeight);5213 rv.setY (offY + vHeight);
5507 else if (m + priv->height + priv->input.bottom > vHeight)5214 else if (m + priv->geometry.height () + priv->input.bottom > vHeight)
5508 rv.setY (offY - vHeight);5215 rv.setY (offY - vHeight);
5509 else5216 else
5510 rv.setY (offY);5217 rv.setY (offY);
@@ -6080,7 +5787,7 @@
60805787
6081 if (m - priv->output.left < (int) screen->width () - vWidth)5788 if (m - priv->output.left < (int) screen->width () - vWidth)
6082 wx = tx + vWidth;5789 wx = tx + vWidth;
6083 else if (m + priv->width + priv->output.right > vWidth)5790 else if (m + priv->geometry.width () + priv->output.right > vWidth)
6084 wx = tx - vWidth;5791 wx = tx - vWidth;
6085 }5792 }
60865793
@@ -6090,7 +5797,7 @@
60905797
6091 if (m - priv->output.top < (int) screen->height () - vHeight)5798 if (m - priv->output.top < (int) screen->height () - vHeight)
6092 wy = ty + vHeight;5799 wy = ty + vHeight;
6093 else if (m + priv->height + priv->output.bottom > vHeight)5800 else if (m + priv->geometry.height () + priv->output.bottom > vHeight)
6094 wy = ty - vHeight;5801 wy = ty - vHeight;
6095 }5802 }
60965803
@@ -6316,9 +6023,6 @@
6316 priv->serverFrameGeometry = priv->frameGeometry = priv->syncGeometry6023 priv->serverFrameGeometry = priv->frameGeometry = priv->syncGeometry
6317 = priv->geometry = priv->serverGeometry;6024 = priv->geometry = priv->serverGeometry;
63186025
6319 priv->width = priv->attrib.width + priv->attrib.border_width * 2;
6320 priv->height = priv->attrib.height + priv->attrib.border_width * 2;
6321
6322 priv->sizeHints.flags = 0;6026 priv->sizeHints.flags = 0;
63236027
6324 priv->recalcNormalHints ();6028 priv->recalcNormalHints ();
@@ -6340,8 +6044,7 @@
63406044
6341 if (priv->attrib.c_class != InputOnly)6045 if (priv->attrib.c_class != InputOnly)
6342 {6046 {
6343 priv->region = CompRegion (priv->attrib.x, priv->attrib.y,6047 priv->region = CompRegion (priv->serverGeometry);
6344 priv->width, priv->height);
6345 priv->inputRegion = priv->region;6048 priv->inputRegion = priv->region;
63466049
6347 /* need to check for DisplayModal state on all windows */6050 /* need to check for DisplayModal state on all windows */
@@ -6586,8 +6289,6 @@
6586 hints (NULL),6289 hints (NULL),
6587 inputHint (true),6290 inputHint (true),
6588 alpha (false),6291 alpha (false),
6589 width (0),
6590 height (0),
6591 region (),6292 region (),
6592 wmType (0),6293 wmType (0),
6593 type (CompWindowTypeUnknownMask),6294 type (CompWindowTypeUnknownMask),
@@ -6622,7 +6323,6 @@
6622 pendingUnmaps (0),6323 pendingUnmaps (0),
6623 pendingMaps (0),6324 pendingMaps (0),
6624 pendingConfigures (screen->dpy ()),6325 pendingConfigures (screen->dpy ()),
6625 pendingPositionUpdates (false),
66266326
6627 startupId (0),6327 startupId (0),
6628 resName (0),6328 resName (0),
@@ -6824,8 +6524,8 @@
6824 priv->frameRegion &= CompRegion (r);6524 priv->frameRegion &= CompRegion (r);
6825 }6525 }
68266526
6827 x = priv->geometry.x () - priv->input.left;6527 x = priv->serverGeometry.x () - priv->input.left;
6828 y = priv->geometry.y () - priv->input.top;6528 y = priv->serverGeometry.y () - priv->input.top;
68296529
6830 XShapeCombineRegion (screen->dpy (), priv->serverFrame,6530 XShapeCombineRegion (screen->dpy (), priv->serverFrame,
6831 ShapeBounding, -x, -y,6531 ShapeBounding, -x, -y,
@@ -6866,6 +6566,11 @@
68666566
6867 priv->updateSize ();6567 priv->updateSize ();
6868 priv->updateFrameWindow ();6568 priv->updateFrameWindow ();
6569
6570 /* Always send a moveNotify
6571 * whenever the frame extents update
6572 * so that plugins can re-position appropriately */
6573 moveNotify (0, 0, true);
6869 }6574 }
68706575
6871 /* Use b for _NET_WM_FRAME_EXTENTS here because6576 /* Use b for _NET_WM_FRAME_EXTENTS here because
68726577
=== modified file 'src/windowgeometry.cpp'
--- src/windowgeometry.cpp 2012-01-23 05:44:19 +0000
+++ src/windowgeometry.cpp 2012-02-28 07:29:19 +0000
@@ -61,22 +61,22 @@
61int61int
62CompWindow::width () const62CompWindow::width () const
63{63{
64 return priv->width +64 return priv->geometry.width () +
65 priv->geometry.border () * 2;65 priv->geometry.border () * 2;
66}66}
6767
68int68int
69CompWindow::height () const69CompWindow::height () const
70{70{
71 return priv->height +71 return priv->geometry.height () +
72 priv->geometry.border () * 2;;72 priv->geometry.border () * 2;;
73}73}
7474
75CompSize75CompSize
76CompWindow::size () const76CompWindow::size () const
77{77{
78 return CompSize (priv->width + priv->geometry.border () * 2,78 return CompSize (priv->geometry.width () + priv->geometry.border () * 2,
79 priv->height + priv->geometry.border () * 2);79 priv->geometry.height () + priv->geometry.border () * 2);
80}80}
8181
82int82int

Subscribers

People subscribed via source and target branches