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

Proposed by Sam Spilsbury
Status: Superseded
Proposed branch: lp:~smspillaz/compiz-core/compiz-core.work_923683
Merge into: lp:compiz-core/0.9.5
Diff against target: 1316 lines (+247/-559)
9 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 (+1/-11)
plugins/opengl/src/window.cpp (+2/-2)
src/event.cpp (+2/-2)
src/privatewindow.h (+10/-12)
src/window.cpp (+195/-495)
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 Resubmitting
Alan Griffiths Needs Fixing
Review via email: mp+90906@code.launchpad.net

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

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.

We'll need to get CompRegion into a testable state though, which is probably easily done.

To post a comment you must log in.
2977. By Sam Spilsbury

Dump a bunch of debugging code

2978. By Sam Spilsbury

Dump more code nobody cares about

2979. By Sam Spilsbury

Dump more hacks

Revision history for this message
Sam Spilsbury (smspillaz) wrote :
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 :

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 :

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

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 :

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 :

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 :

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

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

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

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 :

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

review: Needs Resubmitting
2980. By Sam Spilsbury

Use serverGeometry for rectsToRegion so that there isn't a race condition
when we fetch the shape rectangles from the server and remove a mostly useless
section of configureXWindow

2981. By Sam Spilsbury

Remove commented code, use serverGeometry where appropriate

2982. By Sam Spilsbury

Remove XSynchronize

2983. By Sam Spilsbury

Merged from lp:compiz-core

2984. By Sam Spilsbury

Fix a memory leak in the decor plugin ... use shared_ptr etc

2985. By Sam Spilsbury

Don't spuriously re-create decorations when we don't need to. Also handle the
race between the decorator and the decor plugin when attempting to bind a pixmap
that hasn't been fully formed yet. (Should really use XSync barriers in future)

2986. By Sam Spilsbury

Merged from lp:compiz-core

2987. By Sam Spilsbury

Update PrivateWindow::isInvisible

2988. By Sam Spilsbury

Also adjust the client position inside the frame whenever the frame value mask
indicates that it might have moved.

2989. By Sam Spilsbury

Added a note for a fixme

2990. By Sam Spilsbury

Also send moveNotify for override redirect windows

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-01-20 15:20:44 +0000
+++ include/core/window.h 2012-01-31 17:22:24 +0000
@@ -398,9 +398,9 @@
398398
399 bool hasUnmapReference ();399 bool hasUnmapReference ();
400400
401 bool resize (XWindowAttributes);401 bool resize (const XWindowAttributes &);
402402
403 bool resize (Geometry);403 bool resize (const Geometry &);
404404
405 bool resize (int x, int y, int width, int height,405 bool resize (int x, int y, int width, int height,
406 int border = 0);406 int border = 0);
407407
=== modified file 'plugins/composite/src/window.cpp'
--- plugins/composite/src/window.cpp 2012-01-16 09:50:28 +0000
+++ plugins/composite/src/window.cpp 2012-01-31 17:22:24 +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-01-21 19:05:23 +0000
+++ plugins/decor/src/decor.cpp 2012-01-31 17:22:24 +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)
@@ -142,11 +142,11 @@
142 if (window->type () == CompWindowTypeDropdownMenuMask &&142 if (window->type () == CompWindowTypeDropdownMenuMask &&
143 shadowRegion == CompRegion (window->outputRect ()))143 shadowRegion == CompRegion (window->outputRect ()))
144 {144 {
145 CompRect area (window->outputRect ().x1 (),145 CompRect area (window->serverOutputRect ().x1 (),
146 window->outputRect ().y1 (),146 window->serverOutputRect ().y1 (),
147 window->outputRect ().width (),147 window->serverOutputRect ().width (),
148 window->inputRect ().y1 () -148 window->serverInputRect ().y1 () -
149 window->outputRect ().y1 ());149 window->serverOutputRect ().y1 ());
150150
151 shadowRegion = shadowRegion.subtracted (area);151 shadowRegion = shadowRegion.subtracted (area);
152 }152 }
@@ -1020,8 +1020,8 @@
1020 for (i = 0; i < wd->nQuad; i++)1020 for (i = 0; i < wd->nQuad; i++)
1021 {1021 {
1022 int x, y;1022 int x, y;
1023 unsigned int width = window->size ().width ();1023 unsigned int width = window->geometry ().width ();
1024 unsigned int height = window->size ().height ();1024 unsigned int height = window->geometry ().height ();
10251025
1026 if (window->shaded ())1026 if (window->shaded ())
1027 height = 0;1027 height = 0;
@@ -1030,8 +1030,8 @@
1030 &x1, &y1, &x2, &y2, &sx, &sy);1030 &x1, &y1, &x2, &y2, &sx, &sy);
10311031
1032 /* Translate by x and y points of this window */1032 /* Translate by x and y points of this window */
1033 x = window->geometry ().x ();1033 x = window->serverGeometry ().x ();
1034 y = window->geometry ().y ();1034 y = window->serverGeometry ().y ();
10351035
1036 wd->quad[i].box.x1 = x1 + x;1036 wd->quad[i].box.x1 = x1 + x;
1037 wd->quad[i].box.y1 = y1 + y;1037 wd->quad[i].box.y1 = y1 + y;
@@ -1059,8 +1059,8 @@
1059bool1059bool
1060DecorWindow::checkSize (Decoration *decoration)1060DecorWindow::checkSize (Decoration *decoration)
1061{1061{
1062 return (decoration->minWidth <= (int) window->size ().width () &&1062 return (decoration->minWidth <= (int) window->geometry ().width () &&
1063 decoration->minHeight <= (int) window->size ().height ());1063 decoration->minHeight <= (int) window->geometry ().height ());
1064}1064}
10651065
1066/*1066/*
@@ -2054,8 +2054,8 @@
2054 {2054 {
2055 int x, y;2055 int x, y;
20562056
2057 x = window->geometry (). x ();2057 x = window->serverGeometry (). x ();
2058 y = window->geometry (). y ();2058 y = window->serverGeometry (). y ();
20592059
2060 region += frameRegion.translated (x - wd->decor->input.left,2060 region += frameRegion.translated (x - wd->decor->input.left,
2061 y - wd->decor->input.top);2061 y - wd->decor->input.top);
@@ -2076,7 +2076,7 @@
2076void2076void
2077DecorWindow::updateWindowRegions ()2077DecorWindow::updateWindowRegions ()
2078{2078{
2079 const CompRect &input (window->inputRect ());2079 const CompRect &input (window->serverInputRect ());
20802080
2081 if (regions.size () != gWindow->textures ().size ())2081 if (regions.size () != gWindow->textures ().size ())
2082 regions.resize (gWindow->textures ().size ());2082 regions.resize (gWindow->textures ().size ());
20832083
=== modified file 'plugins/move/src/move.cpp'
--- plugins/move/src/move.cpp 2012-01-20 14:42:53 +0000
+++ plugins/move/src/move.cpp 2012-01-31 17:22:24 +0000
@@ -487,18 +487,8 @@
487 w->move (wX + dx - w->geometry ().x (),487 w->move (wX + dx - w->geometry ().x (),
488 wY + dy - w->geometry ().y (), false);488 wY + dy - w->geometry ().y (), false);
489489
490 if (ms->optionGetLazyPositioning () && ms->hasCompositing)490 if (!ms->optionGetLazyPositioning ())
491 {
492 /* FIXME: This form of lazy positioning is broken and should
493 be replaced asap. Current code exists just to avoid a
494 major performance regression in the 0.5.2 release. */
495 w->serverGeometry ().setX (w->geometry ().x ());
496 w->serverGeometry ().setY (w->geometry ().y ());
497 }
498 else
499 {
500 w->syncPosition ();491 w->syncPosition ();
501 }
502492
503 ms->x -= dx;493 ms->x -= dx;
504 ms->y -= dy;494 ms->y -= dy;
505495
=== 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-01-31 17:22:24 +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-01-19 18:12:31 +0000
+++ src/event.cpp 2012-01-31 17:22:24 +0000
@@ -1179,12 +1179,12 @@
1179 w->priv->managed = true;1179 w->priv->managed = true;
1180 }1180 }
11811181
1182 /* been shaded */1182 /* been shaded
1183 if (w->priv->height == 0)1183 if (w->priv->height == 0)
1184 {1184 {
1185 if (w->id () == priv->activeWindow)1185 if (w->id () == priv->activeWindow)
1186 w->moveInputFocusTo ();1186 w->moveInputFocusTo ();
1187 }1187 }*/
11881188
1189 w->map ();1189 w->map ();
1190 }1190 }
11911191
=== modified file 'src/privatewindow.h'
--- src/privatewindow.h 2011-10-10 14:56:06 +0000
+++ src/privatewindow.h 2012-01-31 17:22:24 +0000
@@ -36,8 +36,8 @@
3636
37#define WINDOW_INVISIBLE(w) \37#define WINDOW_INVISIBLE(w) \
38 ((w)->attrib.map_state != IsViewable || \38 ((w)->attrib.map_state != IsViewable || \
39 (w)->attrib.x + (w)->width + (w)->output.right <= 0 || \39 (w)->attrib.x + (w)->geometry.width () + (w)->output.right <= 0 || \
40 (w)->attrib.y + (w)->height + (w)->output.bottom <= 0 || \40 (w)->attrib.y + (w)->geometry.height () + (w)->output.bottom <= 0 || \
41 (w)->attrib.x - (w)->output.left >= (int) screen->width () || \41 (w)->attrib.x - (w)->output.left >= (int) screen->width () || \
42 (w)->attrib.y - (w)->output.top >= (int) screen->height () )42 (w)->attrib.y - (w)->output.top >= (int) screen->height () )
4343
@@ -171,6 +171,11 @@
171171
172 bool handleSyncAlarm ();172 bool handleSyncAlarm ();
173173
174 void move (int dx, int dy, bool sync);
175 bool resize (int dx, int dy, int dwidth, int dheight, int dborder);
176 bool resize (const CompWindow::Geometry &g);
177 bool resize (const XWindowAttributes &attrib);
178
174 void configure (XConfigureEvent *ce);179 void configure (XConfigureEvent *ce);
175180
176 void configureFrame (XConfigureEvent *ce);181 void configureFrame (XConfigureEvent *ce);
@@ -211,8 +216,6 @@
211216
212 void readIconHint ();217 void readIconHint ();
213218
214 bool checkClear ();
215
216 public:219 public:
217220
218 PrivateWindow *priv;221 PrivateWindow *priv;
@@ -244,13 +247,8 @@
244 XSizeHints sizeHints;247 XSizeHints sizeHints;
245 XWMHints *hints;248 XWMHints *hints;
246249
247 struct timeval lastGeometryUpdate;
248 struct timeval lastConfigureRequest;
249
250 bool inputHint;250 bool inputHint;
251 bool alpha;251 bool alpha;;
252 int width;
253 int height;
254 CompRegion region;252 CompRegion region;
255 CompRegion inputRegion;253 CompRegion inputRegion;
256 CompRegion frameRegion;254 CompRegion frameRegion;
@@ -293,8 +291,6 @@
293 typedef std::pair <XWindowChanges, unsigned int> XWCValueMask;291 typedef std::pair <XWindowChanges, unsigned int> XWCValueMask;
294292
295 compiz::X11::PendingEventQueue pendingConfigures;293 compiz::X11::PendingEventQueue pendingConfigures;
296 CompTimer mClearCheckTimeout;
297 bool pendingPositionUpdates;
298294
299 char *startupId;295 char *startupId;
300 char *resName;296 char *resName;
@@ -330,6 +326,8 @@
330326
331 bool closeRequests;327 bool closeRequests;
332 Time lastCloseRequestTime;328 Time lastCloseRequestTime;
329
330 bool nextMoveImmediate;
333};331};
334332
335class CoreWindow333class CoreWindow
336334
=== modified file 'src/window.cpp'
--- src/window.cpp 2012-01-25 09:20:47 +0000
+++ src/window.cpp 2012-01-31 17:22:24 +0000
@@ -798,292 +798,14 @@
798 if (!serverFrame)798 if (!serverFrame)
799 return;799 return;
800800
801801 xwc.x = serverGeometry.x ();
802 gettimeofday (&lastConfigureRequest, NULL);802 xwc.y = serverGeometry.y ();
803 /* Flush any changes made to serverFrameGeometry or serverGeometry to the server803 xwc.width = serverGeometry.width ();
804 * since there is a race condition where geometries will go out-of-sync with804 xwc.height = serverGeometry.height ();
805 * window movement */805 xwc.border_width = serverGeometry.border ();
806806
807 window->syncPosition ();807 window->configureXWindow (valueMask, &xwc);
808808 window->windowNotify (CompWindowNotifyFrameUpdate);
809 if (serverInput.left || serverInput.right || serverInput.top || serverInput.bottom)
810 {
811 int bw = serverGeometry.border () * 2;
812
813 xwc.x = serverGeometry.x () - serverInput.left;
814 xwc.y = serverGeometry.y () - serverInput.top;
815 xwc.width = serverGeometry.width () + serverInput.left + serverInput.right + bw;
816 if (shaded)
817 xwc.height = serverInput.top + serverInput.bottom + bw;
818 else
819 xwc.height = serverGeometry.height () + serverInput.top + serverInput.bottom + bw;
820
821 if (shaded)
822 height = serverInput.top + serverInput.bottom;
823
824 if (serverFrameGeometry.x () == xwc.x)
825 valueMask &= ~(CWX);
826 else
827 serverFrameGeometry.setX (xwc.x);
828
829 if (serverFrameGeometry.y () == xwc.y)
830 valueMask &= ~(CWY);
831 else
832 serverFrameGeometry.setY (xwc.y);
833
834 if (serverFrameGeometry.width () == xwc.width)
835 valueMask &= ~(CWWidth);
836 else
837 serverFrameGeometry.setWidth (xwc.width);
838
839 if (serverFrameGeometry.height () == xwc.height)
840 valueMask &= ~(CWHeight);
841 else
842 serverFrameGeometry.setHeight (xwc.height);
843
844 /* Geometry is the same, so we're not going to get a ConfigureNotify
845 * event when the window is configured, which means that other plugins
846 * won't know that the client, frame and wrapper windows got shifted
847 * around (and might result in display corruption, eg in OpenGL */
848 if (valueMask == 0)
849 {
850 XConfigureEvent xev;
851 XWindowAttributes attrib;
852 unsigned int nchildren = 0;
853 Window rootRet = 0, parentRet = 0;
854 Window *children = NULL;
855
856 xev.type = ConfigureNotify;
857 xev.event = screen->root ();
858 xev.window = priv->serverFrame;
859
860 XGrabServer (screen->dpy ());
861
862 if (XGetWindowAttributes (screen->dpy (), priv->serverFrame, &attrib))
863 {
864 xev.x = attrib.x;
865 xev.y = attrib.y;
866 xev.width = attrib.width;
867 xev.height = attrib.height;
868 xev.border_width = attrib.border_width;
869 xev.above = None;
870
871 /* We need to ensure that the stacking order is
872 * based on the current server stacking order so
873 * find the sibling to this window's frame in the
874 * server side stack and stack above that */
875 XQueryTree (screen->dpy (), screen->root (), &rootRet, &parentRet, &children, &nchildren);
876
877 if (nchildren)
878 {
879 for (unsigned int i = 0; i < nchildren; i++)
880 {
881 if (i + 1 == nchildren ||
882 children[i + 1] == ROOTPARENT (window))
883 {
884 xev.above = children[i];
885 break;
886 }
887 }
888 }
889
890 if (children)
891 XFree (children);
892
893 if (!xev.above)
894 xev.above = (window->serverPrev) ? ROOTPARENT (window->serverPrev) : None;
895
896 xev.override_redirect = priv->attrib.override_redirect;
897
898 }
899
900 compiz::X11::PendingEvent::Ptr pc =
901 boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
902 new compiz::X11::PendingConfigureEvent (
903 screen->dpy (), serverFrame, valueMask, &xwc)));
904
905 pendingConfigures.add (pc);
906 if (priv->mClearCheckTimeout.active ())
907 priv->mClearCheckTimeout.stop ();
908 priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
909 2000, 2500);
910
911 XSendEvent (screen->dpy (), screen->root (), false,
912 SubstructureNotifyMask, (XEvent *) &xev);
913
914 XUngrabServer (screen->dpy ());
915 XSync (screen->dpy (), false);
916 }
917 else
918 {
919 compiz::X11::PendingEvent::Ptr pc =
920 boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
921 new compiz::X11::PendingConfigureEvent (
922 screen->dpy (), serverFrame, valueMask, &xwc)));
923
924 pendingConfigures.add (pc);
925 if (priv->mClearCheckTimeout.active ())
926 priv->mClearCheckTimeout.stop ();
927 priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
928 2000, 2500);
929 XConfigureWindow (screen->dpy (), serverFrame, valueMask, &xwc);
930 }
931
932 if (shaded)
933 {
934 XUnmapWindow (screen->dpy (), wrapper);
935 }
936 else
937 {
938 XMapWindow (screen->dpy (), wrapper);
939 XMoveResizeWindow (screen->dpy (), wrapper, serverInput.left, serverInput.top,
940 serverGeometry.width (), serverGeometry.height ());
941 }
942 XMoveResizeWindow (screen->dpy (), id, 0, 0,
943 serverGeometry.width (), serverGeometry.height ());
944 window->sendConfigureNotify ();
945 window->windowNotify (CompWindowNotifyFrameUpdate);
946 }
947 else
948 {
949 int bw = serverGeometry.border () * 2;
950
951 xwc.x = serverGeometry.x ();
952 xwc.y = serverGeometry.y ();
953 xwc.width = serverGeometry.width () + bw;
954
955 /* FIXME: It doesn't make much sense to allow undecorated windows to be
956 * shaded */
957 if (shaded)
958 xwc.height = bw;
959 else
960 xwc.height = serverGeometry.height () + bw;
961
962 if (serverFrameGeometry.x () == xwc.x)
963 valueMask &= ~(CWX);
964 else
965 serverFrameGeometry.setX (xwc.x);
966
967 if (serverFrameGeometry.y () == xwc.y)
968 valueMask &= ~(CWY);
969 else
970 serverFrameGeometry.setY (xwc.y);
971
972 if (serverFrameGeometry.width () == xwc.width)
973 valueMask &= ~(CWWidth);
974 else
975 serverFrameGeometry.setWidth (xwc.width);
976
977 if (serverFrameGeometry.height () == xwc.height)
978 valueMask &= ~(CWHeight);
979 else
980 serverFrameGeometry.setHeight (xwc.height);
981
982 /* Geometry is the same, so we're not going to get a ConfigureNotify
983 * event when the window is configured, which means that other plugins
984 * won't know that the client, frame and wrapper windows got shifted
985 * around (and might result in display corruption, eg in OpenGL */
986 if (valueMask == 0)
987 {
988 XConfigureEvent xev;
989 XWindowAttributes attrib;
990 unsigned int nchildren = 0;
991 Window rootRet = 0, parentRet = 0;
992 Window *children = NULL;
993
994 xev.type = ConfigureNotify;
995 xev.event = screen->root ();
996 xev.window = priv->serverFrame;
997
998 XGrabServer (screen->dpy ());
999
1000 if (XGetWindowAttributes (screen->dpy (), priv->serverFrame, &attrib))
1001 {
1002 xev.x = attrib.x;
1003 xev.y = attrib.y;
1004 xev.width = attrib.width;
1005 xev.height = attrib.height;
1006 xev.border_width = attrib.border_width;
1007 xev.above = None;
1008
1009 /* We need to ensure that the stacking order is
1010 * based on the current server stacking order so
1011 * find the sibling to this window's frame in the
1012 * server side stack and stack above that */
1013 XQueryTree (screen->dpy (), screen->root (), &rootRet, &parentRet, &children, &nchildren);
1014
1015 if (nchildren)
1016 {
1017 for (unsigned int i = 0; i < nchildren; i++)
1018 {
1019 if (i + 1 == nchildren ||
1020 children[i + 1] == ROOTPARENT (window))
1021 {
1022 xev.above = children[i];
1023 break;
1024 }
1025 }
1026 }
1027
1028 if (children)
1029 XFree (children);
1030
1031 if (!xev.above)
1032 xev.above = (window->serverPrev) ? ROOTPARENT (window->serverPrev) : None;
1033
1034 xev.override_redirect = priv->attrib.override_redirect;
1035
1036 }
1037
1038 compiz::X11::PendingEvent::Ptr pc =
1039 boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
1040 new compiz::X11::PendingConfigureEvent (
1041 screen->dpy (), serverFrame, valueMask, &xwc)));
1042
1043 pendingConfigures.add (pc);
1044 if (priv->mClearCheckTimeout.active ())
1045 priv->mClearCheckTimeout.stop ();
1046 priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
1047 2000, 2500);
1048
1049 XSendEvent (screen->dpy (), screen->root (), false,
1050 SubstructureNotifyMask, (XEvent *) &xev);
1051
1052 XUngrabServer (screen->dpy ());
1053 XSync (screen->dpy (), false);
1054 }
1055 else
1056 {
1057 compiz::X11::PendingEvent::Ptr pc =
1058 boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
1059 new compiz::X11::PendingConfigureEvent (
1060 screen->dpy (), serverFrame, valueMask, &xwc)));
1061
1062 pendingConfigures.add (pc);
1063 if (priv->mClearCheckTimeout.active ())
1064 priv->mClearCheckTimeout.stop ();
1065 priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
1066 2000, 2500);
1067
1068 XConfigureWindow (screen->dpy (), serverFrame, valueMask, &xwc);
1069 }
1070
1071 if (shaded)
1072 {
1073 XUnmapWindow (screen->dpy (), wrapper);
1074 }
1075 else
1076 {
1077 XMapWindow (screen->dpy (), wrapper);
1078 XMoveResizeWindow (screen->dpy (), wrapper, 0, 0,
1079 serverGeometry.width (), serverGeometry.height ());
1080 }
1081
1082 XMoveResizeWindow (screen->dpy (), id, 0, 0,
1083 serverGeometry.width (), serverGeometry.height ());
1084 window->sendConfigureNotify ();
1085 window->windowNotify (CompWindowNotifyFrameUpdate);
1086 }
1087 window->recalcActions ();809 window->recalcActions ();
1088}810}
1089811
@@ -1135,10 +857,10 @@
1135 x1 = 0;857 x1 = 0;
1136 if (y1 < 0)858 if (y1 < 0)
1137 y1 = 0;859 y1 = 0;
1138 if (x2 > priv->width)860 if (x2 > priv->geometry.width ())
1139 x2 = priv->width;861 x2 = priv->geometry.height ();
1140 if (y2 > priv->height)862 if (y2 > priv->geometry.width ())
1141 y2 = priv->height;863 y2 = priv->geometry.height ();
1142864
1143 if (y1 < y2 && x1 < x2)865 if (y1 < y2 && x1 < x2)
1144 {866 {
@@ -1182,8 +904,8 @@
1182904
1183 r.x = -priv->geometry.border ();905 r.x = -priv->geometry.border ();
1184 r.y = -priv->geometry.border ();906 r.y = -priv->geometry.border ();
1185 r.width = priv->width + priv->geometry.border ();907 r.width = priv->geometry.width () + priv->geometry.border ();
1186 r.height = priv->height + priv->geometry.border ();908 r.height = priv->geometry.height () + priv->geometry.border ();
1187909
1188 if (nBounding < 1)910 if (nBounding < 1)
1189 {911 {
@@ -1716,7 +1438,7 @@
1716 priv->attrib.map_state = IsUnmapped;1438 priv->attrib.map_state = IsUnmapped;
1717 priv->invisible = true;1439 priv->invisible = true;
17181440
1719 if (priv->shaded && priv->height)1441 if (priv->shaded && priv->geometry.height ())
1720 {1442 {
1721 priv->updateFrameWindow ();1443 priv->updateFrameWindow ();
1722 }1444 }
@@ -1784,7 +1506,7 @@
1784}1506}
17851507
1786bool1508bool
1787CompWindow::resize (XWindowAttributes attr)1509CompWindow::resize (const XWindowAttributes &attr)
1788{1510{
1789 return resize (Geometry (attr.x, attr.y, attr.width, attr.height,1511 return resize (Geometry (attr.x, attr.y, attr.width, attr.height,
1790 attr.border_width));1512 attr.border_width));
@@ -1801,7 +1523,7 @@
1801}1523}
18021524
1803bool1525bool
1804CompWindow::resize (CompWindow::Geometry gm)1526PrivateWindow::resize (const CompWindow::Geometry &gm)
1805{1527{
1806 /* Input extents are now the last thing sent1528 /* Input extents are now the last thing sent
1807 * from the server. This might not work in some1529 * from the server. This might not work in some
@@ -1818,12 +1540,8 @@
1818 priv->geometry.height () != gm.height () ||1540 priv->geometry.height () != gm.height () ||
1819 priv->geometry.border () != gm.border ())1541 priv->geometry.border () != gm.border ())
1820 {1542 {
1821 int pw, ph;
1822 int dx, dy, dwidth, dheight;1543 int dx, dy, dwidth, dheight;
18231544
1824 pw = gm.width () + gm.border () * 2;
1825 ph = gm.height () + gm.border () * 2;
1826
1827 dx = gm.x () - priv->geometry.x ();1545 dx = gm.x () - priv->geometry.x ();
1828 dy = gm.y () - priv->geometry.y ();1546 dy = gm.y () - priv->geometry.y ();
1829 dwidth = gm.width () - priv->geometry.width ();1547 dwidth = gm.width () - priv->geometry.width ();
@@ -1833,37 +1551,60 @@
1833 gm.width (), gm.height (),1551 gm.width (), gm.height (),
1834 gm.border ());1552 gm.border ());
18351553
1836 priv->width = pw;1554 if (priv->attrib.override_redirect)
1837 priv->height = ph;1555 {
1556 priv->serverGeometry = priv->geometry;
1557 priv->serverFrameGeometry = priv->frameGeometry;
1558 }
18381559
1839 if (priv->mapNum)1560 if (priv->mapNum)
1840 priv->updateRegion ();1561 priv->updateRegion ();
18411562
1842 resizeNotify (dx, dy, dwidth, dheight);1563 window->resizeNotify (dx, dy, dwidth, dheight);
18431564
1844 priv->invisible = WINDOW_INVISIBLE (priv);1565 priv->invisible = WINDOW_INVISIBLE (priv);
1845 }1566 }
1846 else if (priv->geometry.x () != gm.x () || priv->geometry.y () != gm.y ())1567 else if (priv->geometry.x () != gm.x () || priv->geometry.y () != gm.y ())
1847 {1568 {
1848 int dx, dy;1569 move (gm.x () - priv->geometry.x (),
18491570 gm.y () - priv->geometry.y (), true);
1850 dx = gm.x () - priv->geometry.x ();
1851 dy = gm.y () - priv->geometry.y ();
1852
1853 priv->geometry.setX (gm.x ());
1854 priv->geometry.setY (gm.y ());
1855
1856 priv->region.translate (dx, dy);
1857 priv->inputRegion.translate (dx, dy);
1858 if (!priv->frameRegion.isEmpty ())
1859 priv->frameRegion.translate (dx, dy);
1860
1861 priv->invisible = WINDOW_INVISIBLE (priv);
1862
1863 moveNotify (dx, dy, true);
1864 }1571 }
18651572
1866 updateFrameRegion ();1573 window->updateFrameRegion ();
1574
1575 return true;
1576}
1577
1578bool
1579PrivateWindow::resize (const XWindowAttributes &attr)
1580{
1581 return resize (CompWindow::Geometry (attr.x, attr.y, attr.width, attr.height,
1582 attr.border_width));
1583}
1584
1585bool
1586PrivateWindow::resize (int x,
1587 int y,
1588 int width,
1589 int height,
1590 int border)
1591{
1592 return resize (CompWindow::Geometry (x, y, width, height, border));
1593}
1594
1595bool
1596CompWindow::resize (const CompWindow::Geometry &gm)
1597{
1598 XWindowChanges xwc = XWINDOWCHANGES_INIT;
1599 unsigned int valueMask = CWX | CWY | CWWidth | CWHeight | CWBorderWidth;
1600
1601 xwc.x = gm.x ();
1602 xwc.y = gm.y ();
1603 xwc.width = gm.width ();
1604 xwc.height = gm.height ();
1605 xwc.border_width = gm.border ();
1606
1607 configureXWindow (valueMask, &xwc);
18671608
1868 return true;1609 return true;
1869}1610}
@@ -2031,13 +1772,7 @@
2031 ce->border_width);1772 ce->border_width);
2032 else1773 else
2033 {1774 {
2034 if (ce->override_redirect)1775 resize (ce->x, ce->y, ce->width, ce->height, ce->border_width);
2035 {
2036 priv->serverGeometry.set (ce->x, ce->y, ce->width, ce->height,
2037 ce->border_width);
2038 }
2039
2040 window->resize (ce->x, ce->y, ce->width, ce->height, ce->border_width);
2041 }1776 }
20421777
2043 if (ce->event == screen->root ())1778 if (ce->event == screen->root ())
@@ -2118,7 +1853,7 @@
2118 if (priv->syncWait)1853 if (priv->syncWait)
2119 priv->syncGeometry.set (x, y, width, height, ce->border_width);1854 priv->syncGeometry.set (x, y, width, height, ce->border_width);
2120 else1855 else
2121 window->resize (x, y, width, height, ce->border_width);1856 resize (x, y, width, height, ce->border_width);
21221857
2123 if (priv->restack (ce->above))1858 if (priv->restack (ce->above))
2124 priv->updatePassiveButtonGrabs ();1859 priv->updatePassiveButtonGrabs ();
@@ -2127,27 +1862,6 @@
21271862
2128 if (above)1863 if (above)
2129 above->priv->updatePassiveButtonGrabs ();1864 above->priv->updatePassiveButtonGrabs ();
2130
2131 if (!pendingConfigures.pending ())
2132 {
2133 /* Tell plugins its ok to start doing stupid things again but
2134 * obviously FIXME */
2135 CompOption::Vector options;
2136 CompOption::Value v;
2137
2138 options.push_back (CompOption ("window", CompOption::TypeInt));
2139 v.set ((int) id);
2140 options.back ().set (v);
2141 options.push_back (CompOption ("active", CompOption::TypeInt));
2142 v.set ((int) 0);
2143 options.back ().set (v);
2144
2145 /* Notify other plugins that it is unsafe to change geometry or serverGeometry
2146 * FIXME: That API should not be accessible to plugins, this is a hack to avoid
2147 * breaking ABI */
2148
2149 screen->handleCompizEvent ("core", "lock_position", options);
2150 }
2151}1865}
21521866
2153void1867void
@@ -2170,43 +1884,39 @@
2170{1884{
2171 if (dx || dy)1885 if (dx || dy)
2172 {1886 {
2173 gettimeofday (&priv->lastGeometryUpdate, NULL);1887 XWindowChanges xwc = XWINDOWCHANGES_INIT;
21741888 unsigned int valueMask = CWX | CWY;
2175 /* Don't allow window movement to overwrite working geometries1889
2176 * last received from the server if we know there are pending1890 xwc.x = priv->serverGeometry.x () + dx;
2177 * ConfigureNotify events on this window. That's a clunky workaround1891 xwc.y = priv->serverGeometry.y () + dy;
2178 * and a FIXME in any case, however, until we can break the API1892
2179 * and remove CompWindow::move, this will need to be the case */1893 priv->nextMoveImmediate = immediate;
21801894
2181 if (!priv->pendingConfigures.pending ())1895 configureXWindow (valueMask, &xwc);
1896 }
1897}
1898
1899void
1900PrivateWindow::move (int dx,
1901 int dy,
1902 bool immediate)
1903{
1904 if (dx || dy)
1905 {
1906 priv->geometry.setX (priv->geometry.x () + dx);
1907 priv->geometry.setY (priv->geometry.y () + dy);
1908 priv->frameGeometry.setX (priv->frameGeometry.x () + dx);
1909 priv->frameGeometry.setY (priv->frameGeometry.y () + dy);
1910
1911 if (priv->attrib.override_redirect)
2182 {1912 {
2183 priv->geometry.setX (priv->geometry.x () + dx);1913 priv->serverGeometry = priv->geometry;
2184 priv->geometry.setY (priv->geometry.y () + dy);1914 priv->serverFrameGeometry = priv->frameGeometry;
2185 priv->frameGeometry.setX (priv->frameGeometry.x () + dx);
2186 priv->frameGeometry.setY (priv->frameGeometry.y () + dy);
2187
2188 priv->pendingPositionUpdates = true;
2189
2190 priv->region.translate (dx, dy);1915 priv->region.translate (dx, dy);
2191 priv->inputRegion.translate (dx, dy);1916 priv->inputRegion.translate (dx, dy);
2192 if (!priv->frameRegion.isEmpty ())1917 if (!priv->frameRegion.isEmpty ())
2193 priv->frameRegion.translate (dx, dy);1918 priv->frameRegion.translate (dx, dy);
21941919 priv->window->moveNotify (dx, dy, immediate);
2195 priv->invisible = WINDOW_INVISIBLE (priv);
2196
2197 moveNotify (dx, dy, immediate);
2198 }
2199 else
2200 {
2201 XWindowChanges xwc = XWINDOWCHANGES_INIT;
2202 unsigned int valueMask = CWX | CWY;
2203 compLogMessage ("core", CompLogLevelDebug, "pending configure notifies on 0x%x, "\
2204 "moving window asyncrhonously!", (unsigned int) priv->serverId);
2205
2206 xwc.x = priv->serverGeometry.x () + dx;
2207 xwc.y = priv->serverGeometry.y () + dy;
2208
2209 configureXWindow (valueMask, &xwc);
2210 }1920 }
2211 }1921 }
2212}1922}
@@ -2217,22 +1927,6 @@
2217 return !mEvents.empty ();1927 return !mEvents.empty ();
2218}1928}
22191929
2220bool
2221PrivateWindow::checkClear ()
2222{
2223 if (pendingConfigures.pending ())
2224 {
2225 /* FIXME: This is a hack to avoid performance regressions
2226 * and must be removed in 0.9.6 */
2227 compLogMessage ("core", CompLogLevelWarn, "failed to receive ConfigureNotify event on 0x%x\n",
2228 id);
2229 pendingConfigures.dump ();
2230 pendingConfigures.clear ();
2231 }
2232
2233 return false;
2234}
2235
2236void1930void
2237compiz::X11::PendingEventQueue::add (PendingEvent::Ptr p)1931compiz::X11::PendingEventQueue::add (PendingEvent::Ptr p)
2238{1932{
@@ -2454,21 +2148,6 @@
2454 mValueMask (valueMask),2148 mValueMask (valueMask),
2455 mXwc (*xwc)2149 mXwc (*xwc)
2456{2150{
2457 CompOption::Vector options;
2458 CompOption::Value v;
2459
2460 options.push_back (CompOption ("window", CompOption::TypeInt));
2461 v.set ((int) w);
2462 options.back ().set (v);
2463 options.push_back (CompOption ("active", CompOption::TypeInt));
2464 v.set ((int) 1);
2465 options.back ().set (v);
2466
2467 /* Notify other plugins that it is unsafe to change geometry or serverGeometry
2468 * FIXME: That API should not be accessible to plugins, this is a hack to avoid
2469 * breaking ABI */
2470
2471 screen->handleCompizEvent ("core", "lock_position", options);
2472}2151}
24732152
2474compiz::X11::PendingConfigureEvent::~PendingConfigureEvent ()2153compiz::X11::PendingConfigureEvent::~PendingConfigureEvent ()
@@ -2478,57 +2157,6 @@
2478void2157void
2479CompWindow::syncPosition ()2158CompWindow::syncPosition ()
2480{2159{
2481 gettimeofday (&priv->lastConfigureRequest, NULL);
2482
2483 unsigned int valueMask = CWX | CWY;
2484 XWindowChanges xwc = XWINDOWCHANGES_INIT;
2485
2486 if (priv->pendingPositionUpdates && !priv->pendingConfigures.pending ())
2487 {
2488 if (priv->serverFrameGeometry.x () == priv->frameGeometry.x ())
2489 valueMask &= ~(CWX);
2490 if (priv->serverFrameGeometry.y () == priv->frameGeometry.y ())
2491 valueMask &= ~(CWY);
2492
2493 /* Because CompWindow::move can update the geometry last
2494 * received from the server, we must indicate that no values
2495 * changed, because when the ConfigureNotify comes around
2496 * the values are going to be the same. That's obviously
2497 * broken behaviour and worthy of a FIXME, but requires
2498 * larger changes to the window movement system. */
2499 if (valueMask)
2500 {
2501 priv->serverGeometry.setX (priv->geometry.x ());
2502 priv->serverGeometry.setY (priv->geometry.y ());
2503 priv->serverFrameGeometry.setX (priv->frameGeometry.x ());
2504 priv->serverFrameGeometry.setY (priv->frameGeometry.y ());
2505
2506 xwc.x = priv->serverFrameGeometry.x ();
2507 xwc.y = priv->serverFrameGeometry.y ();
2508
2509 compiz::X11::PendingEvent::Ptr pc =
2510 boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
2511 new compiz::X11::PendingConfigureEvent (
2512 screen->dpy (), priv->serverFrame, 0, &xwc)));
2513
2514 priv->pendingConfigures.add (pc);
2515
2516 /* Got 3 seconds to get its stuff together */
2517 if (priv->mClearCheckTimeout.active ())
2518 priv->mClearCheckTimeout.stop ();
2519 priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
2520 2000, 2500);
2521 XConfigureWindow (screen->dpy (), ROOTPARENT (this), valueMask, &xwc);
2522
2523 if (priv->serverFrame)
2524 {
2525 XMoveWindow (screen->dpy (), priv->wrapper,
2526 priv->serverInput.left, priv->serverInput.top);
2527 sendConfigureNotify ();
2528 }
2529 }
2530 priv->pendingPositionUpdates = false;
2531 }
2532}2160}
25332161
2534bool2162bool
@@ -3350,6 +2978,12 @@
33502978
3351 /* Remove redundant bits */2979 /* Remove redundant bits */
33522980
2981 xwc->x = valueMask & CWX ? xwc->x : serverGeometry.x ();
2982 xwc->y = valueMask & CWY ? xwc->y : serverGeometry.y ();
2983 xwc->width = valueMask & CWWidth ? xwc->width : serverGeometry.width ();
2984 xwc->height = valueMask & CWHeight ? xwc->height : serverGeometry.height ();
2985 xwc->border_width = valueMask & CWBorderWidth ? xwc->border_width : serverGeometry.border ();
2986
3353 if (valueMask & CWX && serverGeometry.x () == xwc->x)2987 if (valueMask & CWX && serverGeometry.x () == xwc->x)
3354 valueMask &= ~(CWX);2988 valueMask &= ~(CWX);
33552989
@@ -3416,18 +3050,15 @@
3416 compLogMessage ("core", CompLogLevelWarn, "restack_mode not Above");3050 compLogMessage ("core", CompLogLevelWarn, "restack_mode not Above");
3417 }3051 }
34183052
3419 frameValueMask = valueMask;3053 frameValueMask = CWX | CWY | CWWidth | CWHeight | (valueMask & (CWStackMode | CWSibling));
34203054
3421 if (frameValueMask & CWX &&3055 if (serverFrameGeometry.x () == xwc->x - serverGeometry.border () - serverInput.left)
3422 serverFrameGeometry.x () == xwc->x - serverGeometry.border () - serverInput.left)
3423 frameValueMask &= ~(CWX);3056 frameValueMask &= ~(CWX);
34243057
3425 if (frameValueMask & CWY &&3058 if (serverFrameGeometry.y () == xwc->y - serverGeometry.border () - serverInput.top)
3426 serverFrameGeometry.y () == xwc->y - serverGeometry.border () - serverInput.top)
3427 frameValueMask &= ~(CWY);3059 frameValueMask &= ~(CWY);
34283060
3429 if (frameValueMask & CWWidth &&3061 if (serverFrameGeometry.width () == xwc->width + serverGeometry.border () * 2
3430 serverFrameGeometry.width () == xwc->width + serverGeometry.border () * 2
3431 + serverInput.left + serverInput.right)3062 + serverInput.left + serverInput.right)
3432 frameValueMask &= ~(CWWidth);3063 frameValueMask &= ~(CWWidth);
34333064
@@ -3437,15 +3068,13 @@
34373068
3438 if (shaded)3069 if (shaded)
3439 {3070 {
3440 if (frameValueMask & CWHeight &&3071 if (serverFrameGeometry.height () == serverGeometry.border () * 2
3441 serverFrameGeometry.height () == serverGeometry.border () * 2
3442 + serverInput.top + serverInput.bottom)3072 + serverInput.top + serverInput.bottom)
3443 frameValueMask &= ~(CWHeight);3073 frameValueMask &= ~(CWHeight);
3444 }3074 }
3445 else3075 else
3446 {3076 {
3447 if (frameValueMask & CWHeight &&3077 if (serverFrameGeometry.height () == xwc->height + serverGeometry.border () * 2
3448 serverFrameGeometry.height () == xwc->height + serverGeometry.border () * 2
3449 + serverInput.top + serverInput.bottom)3078 + serverInput.top + serverInput.bottom)
3450 frameValueMask &= ~(CWHeight);3079 frameValueMask &= ~(CWHeight);
3451 }3080 }
@@ -3479,8 +3108,6 @@
34793108
3480 if (serverFrame)3109 if (serverFrame)
3481 {3110 {
3482 gettimeofday (&lastConfigureRequest, NULL);
3483
3484 if (frameValueMask)3111 if (frameValueMask)
3485 {3112 {
3486 XWindowChanges wc = *xwc;3113 XWindowChanges wc = *xwc;
@@ -3496,13 +3123,83 @@
3496 screen->dpy (), priv->serverFrame, frameValueMask, &wc)));3123 screen->dpy (), priv->serverFrame, frameValueMask, &wc)));
34973124
3498 pendingConfigures.add (pc);3125 pendingConfigures.add (pc);
3499 if (priv->mClearCheckTimeout.active ())
3500 priv->mClearCheckTimeout.stop ();
3501 priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
3502 2000, 2500);
35033126
3504 XConfigureWindow (screen->dpy (), serverFrame, frameValueMask, &wc);3127 XConfigureWindow (screen->dpy (), serverFrame, frameValueMask, &wc);
3505 }3128 }
3129 else
3130 {
3131 /* Craft an XConfigureWindow event to send to the frame window */
3132 XConfigureEvent xev;
3133 XWindowAttributes attrib;
3134 unsigned int nchildren = 0;
3135 Window rootRet = 0, parentRet = 0;
3136 Window *children = NULL;
3137
3138 XWindowChanges wc = *xwc;
3139
3140 wc.x = serverFrameGeometry.x ();
3141 wc.y = serverFrameGeometry.y ();
3142 wc.width = serverFrameGeometry.width ();
3143 wc.height = serverFrameGeometry.height ();
3144
3145 xev.type = ConfigureNotify;
3146 xev.event = screen->root ();
3147 xev.window = priv->serverFrame;
3148
3149 XGrabServer (screen->dpy ());
3150
3151 if (XGetWindowAttributes (screen->dpy (), priv->serverFrame, &attrib))
3152 {
3153 xev.x = attrib.x;
3154 xev.y = attrib.y;
3155 xev.width = attrib.width;
3156 xev.height = attrib.height;
3157 xev.border_width = attrib.border_width;
3158 xev.above = None;
3159
3160 /* We need to ensure that the stacking order is
3161 * based on the current server stacking order so
3162 * find the sibling to this window's frame in the
3163 * server side stack and stack above that */
3164 XQueryTree (screen->dpy (), screen->root (), &rootRet, &parentRet, &children, &nchildren);
3165
3166 if (nchildren)
3167 {
3168 for (unsigned int i = 0; i < nchildren; i++)
3169 {
3170 if (i + 1 == nchildren ||
3171 children[i + 1] == ROOTPARENT (window))
3172 {
3173 xev.above = children[i];
3174 break;
3175 }
3176 }
3177 }
3178
3179 if (children)
3180 XFree (children);
3181
3182 if (!xev.above)
3183 xev.above = (window->serverPrev) ? ROOTPARENT (window->serverPrev) : None;
3184
3185 xev.override_redirect = priv->attrib.override_redirect;
3186
3187 }
3188
3189 compiz::X11::PendingEvent::Ptr pc =
3190 boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
3191 new compiz::X11::PendingConfigureEvent (
3192 screen->dpy (), serverFrame, valueMask, &wc)));
3193
3194 pendingConfigures.add (pc);
3195
3196 XSendEvent (screen->dpy (), screen->root (), false,
3197 SubstructureNotifyMask, (XEvent *) &xev);
3198
3199 XUngrabServer (screen->dpy ());
3200 XSync (screen->dpy (), false);
3201 }
3202
3506 valueMask &= ~(CWSibling | CWStackMode);3203 valueMask &= ~(CWSibling | CWStackMode);
35073204
3508 if (valueMask)3205 if (valueMask)
@@ -3692,6 +3389,9 @@
3692CompWindow::configureXWindow (unsigned int valueMask,3389CompWindow::configureXWindow (unsigned int valueMask,
3693 XWindowChanges *xwc)3390 XWindowChanges *xwc)
3694{3391{
3392 int dx = valueMask & CWX ? xwc->x - priv->serverGeometry.x () : 0;
3393 int dy = valueMask & CWY ? xwc->y - priv->serverGeometry.y () : 0;
3394
3695 if (priv->managed && (valueMask & (CWSibling | CWStackMode)))3395 if (priv->managed && (valueMask & (CWSibling | CWStackMode)))
3696 {3396 {
3697 CompWindowList transients;3397 CompWindowList transients;
@@ -3746,6 +3446,17 @@
3746 {3446 {
3747 priv->reconfigureXWindow (valueMask, xwc);3447 priv->reconfigureXWindow (valueMask, xwc);
3748 }3448 }
3449
3450 if (!overrideRedirect () && (dx || dy))
3451 {
3452 priv->region.translate (dx, dy);
3453 priv->inputRegion.translate (dx, dy);
3454 if (!priv->frameRegion.isEmpty ())
3455 priv->frameRegion.translate (dx, dy);
3456 moveNotify (dx, dy, priv->nextMoveImmediate);
3457
3458 priv->nextMoveImmediate = true;
3459 }
3749}3460}
37503461
3751int3462int
@@ -4297,10 +4008,6 @@
4297 screen->dpy (), serverFrame, valueMask, &lxwc)));4008 screen->dpy (), serverFrame, valueMask, &lxwc)));
42984009
4299 pendingConfigures.add (pc);4010 pendingConfigures.add (pc);
4300 if (priv->mClearCheckTimeout.active ())
4301 priv->mClearCheckTimeout.stop ();
4302 priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
4303 2000, 2500);
4304 }4011 }
43054012
4306 /* Below with no sibling puts the window at the bottom4013 /* Below with no sibling puts the window at the bottom
@@ -5472,7 +5179,7 @@
5472 m = priv->geometry.x () + offX;5179 m = priv->geometry.x () + offX;
5473 if (m - priv->input.left < (int) s->width () - vWidth)5180 if (m - priv->input.left < (int) s->width () - vWidth)
5474 rv.setX (offX + vWidth);5181 rv.setX (offX + vWidth);
5475 else if (m + priv->width + priv->input.right > vWidth)5182 else if (m + priv->geometry.width () + priv->input.right > vWidth)
5476 rv.setX (offX - vWidth);5183 rv.setX (offX - vWidth);
5477 else5184 else
5478 rv.setX (offX);5185 rv.setX (offX);
@@ -5487,7 +5194,7 @@
5487 m = priv->geometry.y () + offY;5194 m = priv->geometry.y () + offY;
5488 if (m - priv->input.top < (int) s->height () - vHeight)5195 if (m - priv->input.top < (int) s->height () - vHeight)
5489 rv.setY (offY + vHeight);5196 rv.setY (offY + vHeight);
5490 else if (m + priv->height + priv->input.bottom > vHeight)5197 else if (m + priv->geometry.height () + priv->input.bottom > vHeight)
5491 rv.setY (offY - vHeight);5198 rv.setY (offY - vHeight);
5492 else5199 else
5493 rv.setY (offY);5200 rv.setY (offY);
@@ -6063,7 +5770,7 @@
60635770
6064 if (m - priv->output.left < (int) screen->width () - vWidth)5771 if (m - priv->output.left < (int) screen->width () - vWidth)
6065 wx = tx + vWidth;5772 wx = tx + vWidth;
6066 else if (m + priv->width + priv->output.right > vWidth)5773 else if (m + priv->geometry.width () + priv->output.right > vWidth)
6067 wx = tx - vWidth;5774 wx = tx - vWidth;
6068 }5775 }
60695776
@@ -6073,7 +5780,7 @@
60735780
6074 if (m - priv->output.top < (int) screen->height () - vHeight)5781 if (m - priv->output.top < (int) screen->height () - vHeight)
6075 wy = ty + vHeight;5782 wy = ty + vHeight;
6076 else if (m + priv->height + priv->output.bottom > vHeight)5783 else if (m + priv->geometry.height () + priv->output.bottom > vHeight)
6077 wy = ty - vHeight;5784 wy = ty - vHeight;
6078 }5785 }
60795786
@@ -6299,9 +6006,6 @@
6299 priv->serverFrameGeometry = priv->frameGeometry = priv->syncGeometry6006 priv->serverFrameGeometry = priv->frameGeometry = priv->syncGeometry
6300 = priv->geometry = priv->serverGeometry;6007 = priv->geometry = priv->serverGeometry;
63016008
6302 priv->width = priv->attrib.width + priv->attrib.border_width * 2;
6303 priv->height = priv->attrib.height + priv->attrib.border_width * 2;
6304
6305 priv->sizeHints.flags = 0;6009 priv->sizeHints.flags = 0;
63066010
6307 priv->recalcNormalHints ();6011 priv->recalcNormalHints ();
@@ -6323,8 +6027,7 @@
63236027
6324 if (priv->attrib.c_class != InputOnly)6028 if (priv->attrib.c_class != InputOnly)
6325 {6029 {
6326 priv->region = CompRegion (priv->attrib.x, priv->attrib.y,6030 priv->region = CompRegion (static_cast <CompRect> (priv->serverGeometry));
6327 priv->width, priv->height);
6328 priv->inputRegion = priv->region;6031 priv->inputRegion = priv->region;
63296032
6330 /* need to check for DisplayModal state on all windows */6033 /* need to check for DisplayModal state on all windows */
@@ -6569,8 +6272,6 @@
6569 hints (NULL),6272 hints (NULL),
6570 inputHint (true),6273 inputHint (true),
6571 alpha (false),6274 alpha (false),
6572 width (0),
6573 height (0),
6574 region (),6275 region (),
6575 wmType (0),6276 wmType (0),
6576 type (CompWindowTypeUnknownMask),6277 type (CompWindowTypeUnknownMask),
@@ -6605,7 +6306,6 @@
6605 pendingUnmaps (0),6306 pendingUnmaps (0),
6606 pendingMaps (0),6307 pendingMaps (0),
6607 pendingConfigures (screen->dpy ()),6308 pendingConfigures (screen->dpy ()),
6608 pendingPositionUpdates (false),
66096309
6610 startupId (0),6310 startupId (0),
6611 resName (0),6311 resName (0),
66126312
=== modified file 'src/windowgeometry.cpp'
--- src/windowgeometry.cpp 2012-01-23 05:44:19 +0000
+++ src/windowgeometry.cpp 2012-01-31 17:22:24 +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