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

Proposed by Sam Spilsbury
Status: Superseded
Proposed branch: lp:~smspillaz/compiz-core/compiz-core.work_923683
Merge into: lp:compiz-core
Prerequisite: lp:~smspillaz/compiz-core/compiz-core.fix_969101
Diff against target: 2730 lines (+586/-827) (has conflicts)
21 files modified
plugins/composite/src/window.cpp (+19/-39)
plugins/decor/src/decor.cpp (+102/-49)
plugins/decor/src/decor.h (+4/-3)
plugins/move/src/move.cpp (+10/-12)
plugins/opengl/src/paint.cpp (+11/-18)
plugins/opengl/src/privates.h (+7/-1)
plugins/opengl/src/window.cpp (+40/-18)
plugins/place/src/constrain-to-workarea/src/constrain-to-workarea.cpp (+4/-6)
plugins/place/src/place.cpp (+19/-24)
plugins/resize/src/resize.cpp (+8/-18)
plugins/resize/src/resize.h (+0/-2)
plugins/wobbly/src/wobbly.cpp (+37/-40)
plugins/wobbly/src/wobbly.h (+2/-0)
src/actions.cpp (+2/-2)
src/event.cpp (+1/-1)
src/privatewindow.h (+7/-8)
src/screen.cpp (+4/-2)
src/window.cpp (+262/-546)
src/window/geometry/include/core/windowgeometry.h (+6/-0)
src/window/geometry/tests/window-geometry/src/test-window-geometry.cpp (+10/-0)
src/windowgeometry.cpp (+31/-38)
Text conflict in plugins/decor/src/decor.cpp
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
Alan Griffiths Approve
Sam Spilsbury Pending
Review via email: mp+102098@code.launchpad.net

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

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

Description of the change

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

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

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

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

Caveats:

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

Testing plan?

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

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

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

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

const correctness

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

more const correctness

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

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

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

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

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

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

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

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

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

DIE

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

DIE

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

GOOD IN THEORY:

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

* Simplified: Replacing 559 lines of code with 247.

UNSURE ABOUT THE THEORY:

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

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

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

BAD IN THEORY:

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

GOOD IN PRACTICE:

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

BAD IN PRACTICE:

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

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

CONCLUSION:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Read more...

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

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

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

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

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

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

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

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

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

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

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

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

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

I'm tempted by

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

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

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

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

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

+1 for all three

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

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

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

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

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

I'm not really sure ?

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

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

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

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

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

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

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

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

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

I still think that needs fixing.

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

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

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

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

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

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

Notes for the future:

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

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

Unfortunately still fails basic testing. The same bug remains;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

The practical problem:

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

The theoretical problem:

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

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

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

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

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

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

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

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

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

    //XSynchronize (dpy, TRUE);

:) Haven't merged your other branch

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

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

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

Perhaps remember to pull from trunk more often.

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

where trunk == lp:compiz-core

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Alright.

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

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

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

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

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

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

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

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

Steps to reproduce the issue:

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

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

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

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

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

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

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

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

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

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

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

Attachments sent via email. This is interesting though;

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

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

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

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

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

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

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

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

> I swear occasionally I see them on screen too.

Under what circumstances?

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Yes, fixable

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

Please elaborate further on why this is a regression.

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

Most likely copy-and-paste errors

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

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

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

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

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

Thank you. Fixing.

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

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

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

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

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

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

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

Looks like a mistake:

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

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

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

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

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

The main paths causing this massive performance regression are:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Also some thoughts on those optimizations would be nice :)

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

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

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

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

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

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

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

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

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

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

(Daniel logs off)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Unfortunately performance is getting worse, not better.

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

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

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

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

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

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

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

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

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

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

This branch does appear to fix bug 862430.

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

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

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

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

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

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

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

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

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

Resubmitted again.

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

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

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

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

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

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

Typo : bug 932520

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Both issues fixed, please re-review.

Will look into the 1px shift later.

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

Confirm wobbly windows fixed. They are rather cute!

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

As above.

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

LGTM

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

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

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

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

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

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

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

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

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

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

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

Okay.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Maybe we're both right?

;)

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

Issues with the wobbly plugin fixed.

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

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

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

[Still using wobbly of course] largely fixed.

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

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

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

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

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

Also contains conflicts.

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

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

review: Needs Fixing
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 'plugins/composite/src/window.cpp'
--- plugins/composite/src/window.cpp 2012-03-22 17:00:51 +0000
+++ plugins/composite/src/window.cpp 2012-04-17 08:08:21 +0000
@@ -128,6 +128,9 @@
128 /* We have to grab the server here to make sure that window128 /* We have to grab the server here to make sure that window
129 is mapped when getting the window pixmap */129 is mapped when getting the window pixmap */
130 XGrabServer (screen->dpy ());130 XGrabServer (screen->dpy ());
131
132 /* Flush changes to the server and wait for it to process them */
133 XSync (screen->dpy (), false);
131 XGetWindowAttributes (screen->dpy (),134 XGetWindowAttributes (screen->dpy (),
132 ROOTPARENT (priv->window), &attr);135 ROOTPARENT (priv->window), &attr);
133 if (attr.map_state != IsViewable)136 if (attr.map_state != IsViewable)
@@ -250,7 +253,7 @@
250253
251 if (x2 > x1 && y2 > y1)254 if (x2 > x1 && y2 > y1)
252 {255 {
253 CompWindow::Geometry geom = priv->window->geometry ();256 const CompWindow::Geometry &geom = priv->window->serverGeometry ();
254257
255 x1 += geom.x () + geom.border ();258 x1 += geom.x () + geom.border ();
256 y1 += geom.y () + geom.border ();259 y1 += geom.y () + geom.border ();
@@ -272,20 +275,20 @@
272 {275 {
273 int x1, x2, y1, y2;276 int x1, x2, y1, y2;
274277
275 CompWindow::Geometry geom = priv->window->geometry ();278 const CompWindow::Geometry &geom = priv->window->serverGeometry ();
276 CompWindowExtents output = priv->window->output ();279 const CompWindowExtents &output = priv->window->output ();
277280
278 /* top */281 /* top */
279 x1 = -output.left - geom.border ();282 x1 = -output.left - geom.border ();
280 y1 = -output.top - geom.border ();283 y1 = -output.top - geom.border ();
281 x2 = priv->window->size ().width () + output.right - geom.border ();284 x2 = geom.width () + geom.border () + output.right;
282 y2 = -geom.border ();285 y2 = -geom.border ();
283286
284 if (x1 < x2 && y1 < y2)287 if (x1 < x2 && y1 < y2)
285 addDamageRect (CompRect (x1, y1, x2 - x1, y2 - y1));288 addDamageRect (CompRect (x1, y1, x2 - x1, y2 - y1));
286289
287 /* bottom */290 /* bottom */
288 y1 = priv->window->size ().height () - geom.border ();291 y1 = geom.height () + geom.border ();
289 y2 = y1 + output.bottom - geom.border ();292 y2 = y1 + output.bottom - geom.border ();
290293
291 if (x1 < x2 && y1 < y2)294 if (x1 < x2 && y1 < y2)
@@ -295,13 +298,13 @@
295 x1 = -output.left - geom.border ();298 x1 = -output.left - geom.border ();
296 y1 = -geom.border ();299 y1 = -geom.border ();
297 x2 = -geom.border ();300 x2 = -geom.border ();
298 y2 = priv->window->size ().height () - geom.border ();301 y2 = geom.height () - geom.border ();
299302
300 if (x1 < x2 && y1 < y2)303 if (x1 < x2 && y1 < y2)
301 addDamageRect (CompRect (x1, y1, x2 - x1, y2 - y1));304 addDamageRect (CompRect (x1, y1, x2 - x1, y2 - y1));
302305
303 /* right */306 /* right */
304 x1 = priv->window->size ().width () - geom.border ();307 x1 = geom.width () - geom.border ();
305 x2 = x1 + output.right - geom.border ();308 x2 = x1 + output.right - geom.border ();
306309
307 if (x1 < x2 && y1 < y2)310 if (x1 < x2 && y1 < y2)
@@ -322,7 +325,7 @@
322 x = rect.x ();325 x = rect.x ();
323 y = rect.y ();326 y = rect.y ();
324327
325 CompWindow::Geometry geom = priv->window->geometry ();328 const CompWindow::Geometry &geom = priv->window->serverGeometry ();
326 x += geom.x () + geom.border ();329 x += geom.x () + geom.border ();
327 y += geom.y () + geom.border ();330 y += geom.y () + geom.border ();
328331
@@ -341,16 +344,16 @@
341 if (priv->window->shaded () || force ||344 if (priv->window->shaded () || force ||
342 (priv->window->isViewable ()))345 (priv->window->isViewable ()))
343 {346 {
344 int border = priv->window->geometry ().border ();347 int border = priv->window->serverGeometry ().border ();
345348
346 int x1 = -MAX (priv->window->output ().left,349 int x1 = -MAX (priv->window->output ().left,
347 priv->window->input ().left) - border;350 priv->window->input ().left) - border;
348 int y1 = -MAX (priv->window->output ().top,351 int y1 = -MAX (priv->window->output ().top,
349 priv->window->input ().top) - border;352 priv->window->input ().top) - border;
350 int x2 = priv->window->size ().width () +353 int x2 = priv->window->serverGeometry ().width () +
351 MAX (priv->window->output ().right,354 MAX (priv->window->output ().right,
352 priv->window->input ().right) ;355 priv->window->input ().right) ;
353 int y2 = priv->window->size ().height () +356 int y2 = priv->window->serverGeometry ().height () +
354 MAX (priv->window->output ().bottom,357 MAX (priv->window->output ().bottom,
355 priv->window->input ().bottom) ;358 priv->window->input ().bottom) ;
356 CompRect r (x1, y1, x2 - x1, y2 - y1);359 CompRect r (x1, y1, x2 - x1, y2 - y1);
@@ -410,7 +413,7 @@
410413
411 if (!w->damageRect (initial, CompRect (x, y, width, height)))414 if (!w->damageRect (initial, CompRect (x, y, width, height)))
412 {415 {
413 CompWindow::Geometry geom = w->priv->window->geometry ();416 CompWindow::Geometry geom = w->priv->window->serverGeometry ();
414417
415 x += geom.x () + geom.border ();418 x += geom.x () + geom.border ();
416 y += geom.y () + geom.border ();419 y += geom.y () + geom.border ();
@@ -557,10 +560,6 @@
557{560{
558 window->resizeNotify (dx, dy, dwidth, dheight);561 window->resizeNotify (dx, dy, dwidth, dheight);
559562
560 Pixmap pixmap = None;
561 CompSize size = CompSize ();
562
563
564 if (window->shaded () || (window->isViewable ()))563 if (window->shaded () || (window->isViewable ()))
565 {564 {
566 int x, y, x1, x2, y1, y2;565 int x, y, x1, x2, y1, y2;
@@ -578,25 +577,6 @@
578 cScreen->damageRegion (CompRegion (CompRect (x1, y1, x2 - x1, y2 - y1)));577 cScreen->damageRegion (CompRegion (CompRect (x1, y1, x2 - x1, y2 - y1)));
579 }578 }
580579
581 if (window->mapNum () && redirected)
582 {
583 unsigned int actualWidth, actualHeight, ui;
584 Window root;
585 Status result;
586 int i;
587
588 pixmap = XCompositeNameWindowPixmap (screen->dpy (), ROOTPARENT (window));
589 result = XGetGeometry (screen->dpy (), pixmap, &root, &i, &i,
590 &actualWidth, &actualHeight, &ui, &ui);
591 size = CompSize (actualWidth, actualHeight);
592 if (!result || actualWidth != (unsigned int) window->size ().width () ||
593 actualHeight != (unsigned int) window->size ().height ())
594 {
595 XFreePixmap (screen->dpy (), pixmap);
596 return;
597 }
598 }
599
600 if (((!window->mapNum () && window->isViewable ()) ||580 if (((!window->mapNum () && window->isViewable ()) ||
601 window->state () & CompWindowStateHiddenMask) && window->hasUnmapReference ())581 window->state () & CompWindowStateHiddenMask) && window->hasUnmapReference ())
602 {582 {
@@ -622,14 +602,14 @@
622 {602 {
623 int x, y, x1, x2, y1, y2;603 int x, y, x1, x2, y1, y2;
624604
625 x = window->geometry ().x ();605 x = window->serverGeometry ().x ();
626 y = window->geometry ().y ();606 y = window->serverGeometry ().y ();
627607
628 x1 = x - window->output ().left - dx;608 x1 = x - window->output ().left - dx;
629 y1 = y - window->output ().top - dy;609 y1 = y - window->output ().top - dy;
630 x2 = x + window->size ().width () +610 x2 = x + window->serverGeometry ().width () +
631 window->output ().right - dx;611 window->output ().right - dx;
632 y2 = y + window->size ().height () +612 y2 = y + window->serverGeometry ().height () +
633 window->output ().bottom - dy;613 window->output ().bottom - dy;
634614
635 cScreen->damageRegion (CompRegion (CompRect (x1, y1, x2 - x1, y2 - y1)));615 cScreen->damageRegion (CompRegion (CompRect (x1, y1, x2 - x1, y2 - y1)));
636616
=== modified file 'plugins/decor/src/decor.cpp'
--- plugins/decor/src/decor.cpp 2012-04-17 04:05:07 +0000
+++ plugins/decor/src/decor.cpp 2012-04-17 08:08:21 +0000
@@ -221,6 +221,7 @@
221 GLTexture::MatrixList ml (1);221 GLTexture::MatrixList ml (1);
222 mask |= PAINT_WINDOW_BLEND_MASK;222 mask |= PAINT_WINDOW_BLEND_MASK;
223223
224<<<<<<< TREE
224 const CompRegion *preg = NULL;225 const CompRegion *preg = NULL;
225226
226 if ((mask & (PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK |227 if ((mask & (PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK |
@@ -245,8 +246,42 @@
245246
246 const CompRegion &reg (*preg);247 const CompRegion &reg (*preg);
247248
249=======
250 const CompRegion *preg = NULL;
251
252 if (mClipGroup)
253 {
254 if ((mask & (PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK |
255 PAINT_WINDOW_WITH_OFFSET_MASK)))
256 preg = &region;
257 else if (mask & PAINT_WINDOW_TRANSFORMED_MASK)
258 preg = &infiniteRegion;
259 else
260 {
261 tmpRegion = mOutputRegion;
262 tmpRegion &= region;
263
264 if (tmpRegion.isEmpty ())
265 preg = &region;
266 else
267 preg = &shadowRegion;
268 }
269
270 /* In case some plugin needs to paint us with an offset region */
271 if (preg->isEmpty ())
272 preg = &region;
273 }
274 else
275 preg = &region;
276
277 const CompRegion &reg (*preg);
278
279>>>>>>> MERGE-SOURCE
248 gWindow->geometry ().reset ();280 gWindow->geometry ().reset ();
249281
282 if (updateMatrix)
283 updateDecorationScale ();
284
250 for (int i = 0; i < wd->nQuad; i++)285 for (int i = 0; i < wd->nQuad; i++)
251 {286 {
252 box.setGeometry (wd->quad[i].box.x1,287 box.setGeometry (wd->quad[i].box.x1,
@@ -275,6 +310,9 @@
275 if (gWindow->textures ().empty ())310 if (gWindow->textures ().empty ())
276 return;311 return;
277312
313 if (updateMatrix)
314 updateDecorationScale ();
315
278 if (gWindow->textures ().size () == 1)316 if (gWindow->textures ().size () == 1)
279 {317 {
280 ml[0] = gWindow->matrices ()[0];318 ml[0] = gWindow->matrices ()[0];
@@ -1017,6 +1055,8 @@
1017 wd->quad[i].box.y1 * wd->quad[i].matrix.yy +1055 wd->quad[i].box.y1 * wd->quad[i].matrix.yy +
1018 wd->quad[i].box.x1 * wd->quad[i].matrix.yx;1056 wd->quad[i].box.x1 * wd->quad[i].matrix.yx;
1019 }1057 }
1058
1059 updateMatrix = false;
1020}1060}
10211061
1022/*1062/*
@@ -1043,8 +1083,8 @@
1043 for (i = 0; i < wd->nQuad; i++)1083 for (i = 0; i < wd->nQuad; i++)
1044 {1084 {
1045 int x, y;1085 int x, y;
1046 unsigned int width = window->size ().width ();1086 unsigned int width = window->overrideRedirect () ? window->geometry ().width () : window->serverGeometry ().width ();
1047 unsigned int height = window->size ().height ();1087 unsigned int height = window->overrideRedirect () ? window->geometry ().height () : window->serverGeometry ().height ();
10481088
1049 if (window->shaded ())1089 if (window->shaded ())
1050 height = 0;1090 height = 0;
@@ -1053,13 +1093,14 @@
1053 &x1, &y1, &x2, &y2, &sx, &sy);1093 &x1, &y1, &x2, &y2, &sx, &sy);
10541094
1055 /* Translate by x and y points of this window */1095 /* Translate by x and y points of this window */
1056 x = window->geometry ().x ();1096 x = window->overrideRedirect () ? window->geometry ().x () : window->serverGeometry ().x ();
1057 y = window->geometry ().y ();1097 y = window->overrideRedirect () ? window->geometry ().y () : window->serverGeometry ().y ();
10581098
1059 wd->quad[i].box.x1 = x1 + x;1099 wd->quad[i].box.x1 = x1 + x;
1060 wd->quad[i].box.y1 = y1 + y;1100 wd->quad[i].box.y1 = y1 + y;
1061 wd->quad[i].box.x2 = x2 + x;1101 wd->quad[i].box.x2 = x2 + x;
1062 wd->quad[i].box.y2 = y2 + y;1102 wd->quad[i].box.y2 = y2 + y;
1103
1063 wd->quad[i].sx = sx;1104 wd->quad[i].sx = sx;
1064 wd->quad[i].sy = sy;1105 wd->quad[i].sy = sy;
1065 }1106 }
@@ -1082,8 +1123,8 @@
1082bool1123bool
1083DecorWindow::checkSize (const Decoration::Ptr &decoration)1124DecorWindow::checkSize (const Decoration::Ptr &decoration)
1084{1125{
1085 return (decoration->minWidth <= (int) window->size ().width () &&1126 return (decoration->minWidth <= (int) window->serverGeometry ().width () &&
1086 decoration->minHeight <= (int) window->size ().height ());1127 decoration->minHeight <= (int) window->serverGeometry ().height ());
1087}1128}
10881129
1089/*1130/*
@@ -1502,7 +1543,7 @@
1502 */1543 */
1503 if (decoration)1544 if (decoration)
1504 {1545 {
1505 wd = WindowDecoration::create (decoration);1546 wd = WindowDecoration::create ( decoration);
1506 if (!wd)1547 if (!wd)
1507 return false;1548 return false;
15081549
@@ -1523,8 +1564,16 @@
1523 if (decorate)1564 if (decorate)
1524 updateFrame ();1565 updateFrame ();
1525 window->updateWindowOutputExtents ();1566 window->updateWindowOutputExtents ();
1567<<<<<<< TREE
1526 mOutputRegion = CompRegion (window->outputRect ());1568 mOutputRegion = CompRegion (window->outputRect ());
1527 updateGroupShadows ();1569 updateGroupShadows ();
1570=======
1571
1572 updateReg = true;
1573 updateMatrix = true;
1574 mOutputRegion = CompRegion (window->serverOutputRect ());
1575 updateGroupShadows ();
1576>>>>>>> MERGE-SOURCE
1528 if (dScreen->cmActive)1577 if (dScreen->cmActive)
1529 cWindow->damageOutputExtents ();1578 cWindow->damageOutputExtents ();
1530 updateDecorationScale ();1579 updateDecorationScale ();
@@ -1687,7 +1736,6 @@
1687 XRectangle rects[4];1736 XRectangle rects[4];
1688 int x, y, width, height;1737 int x, y, width, height;
1689 CompWindow::Geometry server = window->serverGeometry ();1738 CompWindow::Geometry server = window->serverGeometry ();
1690 int bw = server.border () * 2;
1691 CompWindowExtents input;1739 CompWindowExtents input;
1692 CompWindowExtents border;1740 CompWindowExtents border;
1693 Window parent;1741 Window parent;
@@ -1714,8 +1762,8 @@
17141762
1715 x = window->border ().left - border.left;1763 x = window->border ().left - border.left;
1716 y = window->border ().top - border.top;1764 y = window->border ().top - border.top;
1717 width = server.width () + input.left + input.right + bw;1765 width = server.widthIncBorders () + input.left + input.right;
1718 height = server.height ()+ input.top + input.bottom + bw;1766 height = server.heightIncBorders ()+ input.top + input.bottom ;
17191767
1720 /* Non switcher windows are rooted relative to the frame window of the client1768 /* Non switcher windows are rooted relative to the frame window of the client
1721 * and switchers need to be offset by the window geometry of the client */1769 * and switchers need to be offset by the window geometry of the client */
@@ -1854,7 +1902,6 @@
1854 XRectangle rects[4];1902 XRectangle rects[4];
1855 int x, y, width, height;1903 int x, y, width, height;
1856 CompWindow::Geometry server = window->serverGeometry ();1904 CompWindow::Geometry server = window->serverGeometry ();
1857 int bw = server.border () * 2;
1858 CompWindowExtents input;1905 CompWindowExtents input;
18591906
1860 /* Determine frame extents */1907 /* Determine frame extents */
@@ -1865,8 +1912,8 @@
18651912
1866 x = window->input ().left - input.left;1913 x = window->input ().left - input.left;
1867 y = window->input ().top - input.top;1914 y = window->input ().top - input.top;
1868 width = server.width () + input.left + input.right + bw;1915 width = server.widthIncBorders () + input.left + input.right;
1869 height = server.height ()+ input.top + input.bottom + bw;1916 height = server.heightIncBorders ()+ input.top + input.bottom;
18701917
1871 if (window->shaded ())1918 if (window->shaded ())
1872 height = input.top + input.bottom;1919 height = input.top + input.bottom;
@@ -2097,8 +2144,8 @@
2097 {2144 {
2098 int x, y;2145 int x, y;
20992146
2100 x = window->geometry (). x ();2147 x = window->serverGeometry (). x ();
2101 y = window->geometry (). y ();2148 y = window->serverGeometry (). y ();
21022149
2103 region += frameRegion.translated (x - wd->decor->input.left,2150 region += frameRegion.translated (x - wd->decor->input.left,
2104 y - wd->decor->input.top);2151 y - wd->decor->input.top);
@@ -2108,6 +2155,7 @@
2108 region += infiniteRegion;2155 region += infiniteRegion;
2109 }2156 }
2110 }2157 }
2158
2111 updateReg = true;2159 updateReg = true;
2112}2160}
21132161
@@ -2119,7 +2167,7 @@
2119void2167void
2120DecorWindow::updateWindowRegions ()2168DecorWindow::updateWindowRegions ()
2121{2169{
2122 const CompRect &input (window->inputRect ());2170 const CompRect &input (window->serverInputRect ());
21232171
2124 if (regions.size () != gWindow->textures ().size ())2172 if (regions.size () != gWindow->textures ().size ())
2125 regions.resize (gWindow->textures ().size ());2173 regions.resize (gWindow->textures ().size ());
@@ -2130,6 +2178,7 @@
2130 regions[i].translate (input.x (), input.y ());2178 regions[i].translate (input.x (), input.y ());
2131 regions[i] &= window->frameRegion ();2179 regions[i] &= window->frameRegion ();
2132 }2180 }
2181
2133 updateReg = false;2182 updateReg = false;
2134}2183}
21352184
@@ -2368,7 +2417,13 @@
2368 if (w)2417 if (w)
2369 {2418 {
2370 DECOR_WINDOW (w);2419 DECOR_WINDOW (w);
2371 dw->updateDecoration ();2420
2421 if (dw->wd && dw->wd->decor)
2422 {
2423 if ((dw->wd->decor->minWidth < w->serverGeometry ().width () ||
2424 dw->wd->decor->minHeight < w->serverGeometry ().height ()))
2425 dw->updateDecoration ();
2426 }
23722427
2373 dw->update (true);2428 dw->update (true);
2374 }2429 }
@@ -2703,10 +2758,10 @@
2703 wd->quad[i].box.x2 += dx;2758 wd->quad[i].box.x2 += dx;
2704 wd->quad[i].box.y2 += dy;2759 wd->quad[i].box.y2 += dy;
2705 }2760 }
2706
2707 setDecorationMatrices ();
2708 }2761 }
2762
2709 updateReg = true;2763 updateReg = true;
2764 updateMatrix = true;
27102765
2711 mInputRegion.translate (dx, dy);2766 mInputRegion.translate (dx, dy);
2712 mOutputRegion.translate (dx, dy);2767 mOutputRegion.translate (dx, dy);
@@ -2717,30 +2772,18 @@
2717 window->moveNotify (dx, dy, immediate);2772 window->moveNotify (dx, dy, immediate);
2718}2773}
27192774
2720/*2775void
2721 * DecorWindow::resizeTimeout2776DecorWindow::grabNotify (int x, int y, unsigned int state, unsigned int mask)
2722 *2777{
2723 * Called from the timeout on ::resizeNotify,2778 window->grabNotify (x, y, state, mask);
2724 * set the shading and unshading bits and also2779}
2725 * updates the decoration. See the comment2780
2726 * in ::resizeNotify as to why the timeout2781void
2727 * is necessary here2782DecorWindow::ungrabNotify ()
2728 *2783{
2729 */2784 update (true);
2730bool2785
2731DecorWindow::resizeTimeout ()2786 window->ungrabNotify ();
2732{
2733 if (shading || unshading)
2734 {
2735 shading = false;
2736 unshading = false;
2737
2738 updateDecoration ();
2739 }
2740
2741 if (!window->hasUnmapReference ())
2742 update (true);
2743 return false;
2744}2787}
27452788
2746/*2789/*
@@ -2754,6 +2797,11 @@
2754void2797void
2755DecorWindow::resizeNotify (int dx, int dy, int dwidth, int dheight)2798DecorWindow::resizeNotify (int dx, int dy, int dwidth, int dheight)
2756{2799{
2800 if (shading || unshading)
2801 {
2802 shading = false;
2803 unshading = false;
2804 }
2757 /* FIXME: we should not need a timer for calling decorWindowUpdate,2805 /* FIXME: we should not need a timer for calling decorWindowUpdate,
2758 and only call updateWindowDecorationScale if decorWindowUpdate2806 and only call updateWindowDecorationScale if decorWindowUpdate
2759 returns false. Unfortunately, decorWindowUpdate may call2807 returns false. Unfortunately, decorWindowUpdate may call
@@ -2761,16 +2809,20 @@
2761 we never should call a wrapped function that's currently2809 we never should call a wrapped function that's currently
2762 processed, we need the timer for the moment. updateWindowOutputExtents2810 processed, we need the timer for the moment. updateWindowOutputExtents
2763 should be fixed so that it does not emit a resize notification. */2811 should be fixed so that it does not emit a resize notification. */
2764 resizeUpdate.start (boost::bind (&DecorWindow::resizeTimeout, this), 0);2812 updateMatrix = true;
2765 updateDecorationScale ();
2766 updateReg = true;2813 updateReg = true;
27672814
2768 mInputRegion = CompRegion (window->inputRect ());2815 mInputRegion = CompRegion (window->overrideRedirect () ? window->inputRect () : window->serverInputRect ());
2769 mOutputRegion = CompRegion (window->outputRect ());2816 mOutputRegion = CompRegion (window->overrideRedirect () ? window->outputRect () : window->serverOutputRect ());
2770 if (dScreen->cmActive && mClipGroup)2817 if (dScreen->cmActive && mClipGroup)
2771 updateGroupShadows ();2818 updateGroupShadows ();
27722819
2820 updateReg = true;
2821
2773 window->resizeNotify (dx, dy, dwidth, dheight);2822 window->resizeNotify (dx, dy, dwidth, dheight);
2823
2824 /* FIXME: remove */
2825 CompositeScreen::get (screen)->damageScreen ();
2774}2826}
27752827
27762828
@@ -3008,13 +3060,14 @@
3008 pixmapFailed (false),3060 pixmapFailed (false),
3009 regions (),3061 regions (),
3010 updateReg (true),3062 updateReg (true),
3063 updateMatrix (true),
3011 unshading (false),3064 unshading (false),
3012 shading (false),3065 shading (false),
3013 isSwitcher (false),3066 isSwitcher (false),
3014 frameExtentsRequested (false),3067 frameExtentsRequested (false),
3015 mClipGroup (NULL),3068 mClipGroup (NULL),
3016 mOutputRegion (window->outputRect ()),3069 mOutputRegion (window->overrideRedirect () ? window->outputRect () : window->serverOutputRect ()),
3017 mInputRegion (window->inputRect ())3070 mInputRegion (window->overrideRedirect () ? window->inputRect () : window->serverInputRect ())
3018{3071{
3019 WindowInterface::setHandler (window);3072 WindowInterface::setHandler (window);
30203073
30213074
=== modified file 'plugins/decor/src/decor.h'
--- plugins/decor/src/decor.h 2012-03-30 14:29:18 +0000
+++ plugins/decor/src/decor.h 2012-04-17 08:08:21 +0000
@@ -159,7 +159,7 @@
159159
160class WindowDecoration {160class WindowDecoration {
161 public:161 public:
162 static WindowDecoration * create (const Decoration::Ptr &);162 static WindowDecoration * create (const Decoration::Ptr &d);
163 static void destroy (WindowDecoration *);163 static void destroy (WindowDecoration *);
164164
165 public:165 public:
@@ -245,13 +245,13 @@
245 void getOutputExtents (CompWindowExtents&);245 void getOutputExtents (CompWindowExtents&);
246 void resizeNotify (int, int, int, int);246 void resizeNotify (int, int, int, int);
247 void moveNotify (int, int, bool);247 void moveNotify (int, int, bool);
248 void grabNotify (int x, int y, unsigned int state, unsigned int mask);
249 void ungrabNotify ();
248 void stateChangeNotify (unsigned int);250 void stateChangeNotify (unsigned int);
249 void updateFrameRegion (CompRegion &region);251 void updateFrameRegion (CompRegion &region);
250252
251 bool damageRect (bool, const CompRect &);253 bool damageRect (bool, const CompRect &);
252254
253 void computeShadowRegion ();
254
255 bool glDraw (const GLMatrix &, GLFragment::Attrib &,255 bool glDraw (const GLMatrix &, GLFragment::Attrib &,
256 const CompRegion &, unsigned int);256 const CompRegion &, unsigned int);
257 void glDecorate (const GLMatrix &, GLFragment::Attrib &,257 void glDecorate (const GLMatrix &, GLFragment::Attrib &,
@@ -322,6 +322,7 @@
322322
323 CompRegion::Vector regions;323 CompRegion::Vector regions;
324 bool updateReg;324 bool updateReg;
325 bool updateMatrix;
325326
326 CompTimer resizeUpdate;327 CompTimer resizeUpdate;
327 CompTimer moveUpdate;328 CompTimer moveUpdate;
328329
=== modified file 'plugins/move/src/move.cpp'
--- plugins/move/src/move.cpp 2012-02-16 05:31:28 +0000
+++ plugins/move/src/move.cpp 2012-04-17 08:08:21 +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,10 @@
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 ().widthIncBorders ();
320 w->geometry ().border () * 2;320 wHeight = w->serverGeometry ().heightIncBorders ();
321 wHeight = w->geometry ().height () +
322 w->geometry ().border () * 2;
323321
324 ms->x += xRoot - lastPointerX;322 ms->x += xRoot - lastPointerX;
325 ms->y += yRoot - lastPointerY;323 ms->y += yRoot - lastPointerY;
@@ -484,8 +482,8 @@
484482
485 if (dx || dy)483 if (dx || dy)
486 {484 {
487 w->move (wX + dx - w->geometry ().x (),485 w->move (wX + dx - w->serverGeometry ().x (),
488 wY + dy - w->geometry ().y (), false);486 wY + dy - w->serverGeometry ().y (), false);
489487
490 if (!ms->optionGetLazyPositioning ())488 if (!ms->optionGetLazyPositioning ())
491 w->syncPosition ();489 w->syncPosition ();
492490
=== modified file 'plugins/opengl/src/paint.cpp'
--- plugins/opengl/src/paint.cpp 2012-03-19 09:19:04 +0000
+++ plugins/opengl/src/paint.cpp 2012-04-17 08:08:21 +0000
@@ -1194,7 +1194,7 @@
1194 !priv->cWindow->damaged ())1194 !priv->cWindow->damaged ())
1195 return true;1195 return true;
11961196
1197 if (priv->textures.empty () && !bind ())1197 if (textures ().empty () && !bind ())
1198 return false;1198 return false;
11991199
1200 if (mask & PAINT_WINDOW_TRANSLUCENT_MASK)1200 if (mask & PAINT_WINDOW_TRANSLUCENT_MASK)
@@ -1210,26 +1210,19 @@
1210 //1210 //
1211 priv->gScreen->setTexEnvMode (GL_REPLACE);1211 priv->gScreen->setTexEnvMode (GL_REPLACE);
12121212
1213 if (priv->textures.size () == 1)1213 if (priv->updateState & PrivateGLWindow::UpdateMatrix)
1214 priv->setWindowMatrix ();
1215
1216 if (priv->updateState & PrivateGLWindow::UpdateRegion)
1217 priv->updateWindowRegions ();
1218
1219 for (unsigned int i = 0; i < textures ().size (); i++)
1214 {1220 {
1215 ml[0] = priv->matrices[0];1221 ml[0] = priv->matrices[i];
1216 priv->geometry.reset ();1222 priv->geometry.reset ();
1217 glAddGeometry (ml, priv->window->region (), reg);1223 glAddGeometry (ml, priv->regions[i], reg);
1218 if (priv->geometry.vCount)1224 if (priv->geometry.vCount)
1219 glDrawTexture (priv->textures[0], fragment, mask);1225 glDrawTexture (textures ()[i], fragment, mask);
1220 }
1221 else
1222 {
1223 if (priv->updateReg)
1224 priv->updateWindowRegions ();
1225 for (unsigned int i = 0; i < priv->textures.size (); i++)
1226 {
1227 ml[0] = priv->matrices[i];
1228 priv->geometry.reset ();
1229 glAddGeometry (ml, priv->regions[i], reg);
1230 if (priv->geometry.vCount)
1231 glDrawTexture (priv->textures[i], fragment, mask);
1232 }
1233 }1226 }
12341227
1235 return true;1228 return true;
12361229
=== modified file 'plugins/opengl/src/privates.h'
--- plugins/opengl/src/privates.h 2012-02-08 10:54:35 +0000
+++ plugins/opengl/src/privates.h 2012-04-17 08:08:21 +0000
@@ -134,6 +134,11 @@
134 public CompositeWindowInterface134 public CompositeWindowInterface
135{135{
136 public:136 public:
137
138 static const unsigned int UpdateRegion = 1 << 0;
139 static const unsigned int UpdateMatrix = 1 << 1;
140
141 public:
137 PrivateGLWindow (CompWindow *w, GLWindow *gw);142 PrivateGLWindow (CompWindow *w, GLWindow *gw);
138 ~PrivateGLWindow ();143 ~PrivateGLWindow ();
139144
@@ -153,7 +158,8 @@
153 GLTexture::List textures;158 GLTexture::List textures;
154 GLTexture::MatrixList matrices;159 GLTexture::MatrixList matrices;
155 CompRegion::Vector regions;160 CompRegion::Vector regions;
156 bool updateReg;161 unsigned int updateState;
162 bool needsRebind;
157163
158 CompRegion clip;164 CompRegion clip;
159165
160166
=== modified file 'plugins/opengl/src/window.cpp'
--- plugins/opengl/src/window.cpp 2012-03-22 17:00:51 +0000
+++ plugins/opengl/src/window.cpp 2012-04-17 08:08:21 +0000
@@ -54,7 +54,8 @@
54 gScreen (GLScreen::get (screen)),54 gScreen (GLScreen::get (screen)),
55 textures (),55 textures (),
56 regions (),56 regions (),
57 updateReg (true),57 updateState (UpdateRegion | UpdateMatrix),
58 needsRebind (true),
58 clip (),59 clip (),
59 bindFailed (false),60 bindFailed (false),
60 geometry (),61 geometry (),
@@ -76,7 +77,7 @@
76void77void
77PrivateGLWindow::setWindowMatrix ()78PrivateGLWindow::setWindowMatrix ()
78{79{
79 CompRect input (window->inputRect ());80 CompRect input (window->overrideRedirect () ? window->inputRect () : window->serverInputRect ());
8081
81 if (textures.size () != matrices.size ())82 if (textures.size () != matrices.size ())
82 matrices.resize (textures.size ());83 matrices.resize (textures.size ());
@@ -87,28 +88,41 @@
87 matrices[i].x0 -= (input.x () * matrices[i].xx);88 matrices[i].x0 -= (input.x () * matrices[i].xx);
88 matrices[i].y0 -= (input.y () * matrices[i].yy);89 matrices[i].y0 -= (input.y () * matrices[i].yy);
89 }90 }
91
92 updateState &= ~(UpdateMatrix);
90}93}
9194
92bool95bool
93GLWindow::bind ()96GLWindow::bind ()
94{97{
95 if ((!priv->cWindow->pixmap () && !priv->cWindow->bind ()))98 if ((!priv->cWindow->pixmap () && !priv->cWindow->bind ()))
96 return false;99 {
100 if (!priv->textures.empty ())
101 {
102 /* Getting a new pixmap failed, recycle the old texture */
103 priv->needsRebind = false;
104 return true;
105 }
106 }
97107
98 priv->textures =108 GLTexture::List textures =
99 GLTexture::bindPixmapToTexture (priv->cWindow->pixmap (),109 GLTexture::bindPixmapToTexture (priv->cWindow->pixmap (),
100 priv->cWindow->size ().width (),110 priv->cWindow->size ().width (),
101 priv->cWindow->size ().height (),111 priv->cWindow->size ().height (),
102 priv->window->depth ());112 priv->window->depth ());
103 if (priv->textures.empty ())113 if (textures.empty ())
104 {114 {
105 compLogMessage ("opengl", CompLogLevelInfo,115 compLogMessage ("opengl", CompLogLevelInfo,
106 "Couldn't bind redirected window 0x%x to "116 "Couldn't bind redirected window 0x%x to "
107 "texture\n", (int) priv->window->id ());117 "texture\n", (int) priv->window->id ());
108 }118 }
119 else
120 {
121 priv->textures = textures;
122 priv->needsRebind = false;
123 }
109124
110 priv->setWindowMatrix ();125 priv->updateState = PrivateGLWindow::UpdateRegion | PrivateGLWindow::UpdateMatrix;
111 priv->updateReg = true;
112126
113 return true;127 return true;
114}128}
@@ -116,12 +130,12 @@
116void130void
117GLWindow::release ()131GLWindow::release ()
118{132{
119 priv->textures.clear ();133 /* Release the pixmap but don't release
120134 * the texture (yet) */
121 if (priv->cWindow->pixmap ())135 if (priv->cWindow->pixmap ())
122 {
123 priv->cWindow->release ();136 priv->cWindow->release ();
124 }137
138 priv->needsRebind = true;
125}139}
126140
127bool141bool
@@ -180,8 +194,7 @@
180PrivateGLWindow::resizeNotify (int dx, int dy, int dwidth, int dheight)194PrivateGLWindow::resizeNotify (int dx, int dy, int dwidth, int dheight)
181{195{
182 window->resizeNotify (dx, dy, dwidth, dheight);196 window->resizeNotify (dx, dy, dwidth, dheight);
183 setWindowMatrix ();197 updateState = PrivateGLWindow::UpdateMatrix | PrivateGLWindow::UpdateRegion;
184 updateReg = true;
185 if (!window->hasUnmapReference ())198 if (!window->hasUnmapReference ())
186 gWindow->release ();199 gWindow->release ();
187}200}
@@ -190,8 +203,10 @@
190PrivateGLWindow::moveNotify (int dx, int dy, bool now)203PrivateGLWindow::moveNotify (int dx, int dy, bool now)
191{204{
192 window->moveNotify (dx, dy, now);205 window->moveNotify (dx, dy, now);
193 updateReg = true;206 updateState = PrivateGLWindow::UpdateMatrix;
194 setWindowMatrix ();207
208 foreach (CompRegion &r, regions)
209 r.translate (dx, dy);
195}210}
196211
197void212void
@@ -298,6 +313,13 @@
298const GLTexture::List &313const GLTexture::List &
299GLWindow::textures () const314GLWindow::textures () const
300{315{
316 static const GLTexture::List emptyList;
317
318 /* No pixmap backs this window, let
319 * users know that the window needs rebinding */
320 if (priv->needsRebind)
321 return emptyList;
322
301 return priv->textures;323 return priv->textures;
302}324}
303325
@@ -338,13 +360,13 @@
338PrivateGLWindow::updateFrameRegion (CompRegion &region)360PrivateGLWindow::updateFrameRegion (CompRegion &region)
339{361{
340 window->updateFrameRegion (region);362 window->updateFrameRegion (region);
341 updateReg = true;363 updateState = PrivateGLWindow::UpdateRegion;
342}364}
343365
344void366void
345PrivateGLWindow::updateWindowRegions ()367PrivateGLWindow::updateWindowRegions ()
346{368{
347 CompRect input (window->inputRect ());369 CompRect input (window->serverInputRect ());
348370
349 if (regions.size () != textures.size ())371 if (regions.size () != textures.size ())
350 regions.resize (textures.size ());372 regions.resize (textures.size ());
@@ -354,7 +376,7 @@
354 regions[i].translate (input.x (), input.y ());376 regions[i].translate (input.x (), input.y ());
355 regions[i] &= window->region ();377 regions[i] &= window->region ();
356 }378 }
357 updateReg = false;379 updateState &= ~(UpdateRegion);
358}380}
359381
360unsigned int382unsigned int
361383
=== modified file 'plugins/place/src/constrain-to-workarea/src/constrain-to-workarea.cpp'
--- plugins/place/src/constrain-to-workarea/src/constrain-to-workarea.cpp 2012-01-20 06:13:07 +0000
+++ plugins/place/src/constrain-to-workarea/src/constrain-to-workarea.cpp 2012-04-17 08:08:21 +0000
@@ -61,13 +61,11 @@
61 }61 }
6262
63 left = x - border.left;63 left = x - border.left;
64 right = left + g.width () + (border.left +64 right = left + g.widthIncBorders () + (border.left +
65 border.right +65 border.right);
66 2 * g.border ());
67 top = y - border.top;66 top = y - border.top;
68 bottom = top + g.height () + (border.top +67 bottom = top + g.heightIncBorders () + (border.top +
69 border.bottom +68 border.bottom);
70 2 * g.border ());
7169
72 if ((right - left) > workArea.width ())70 if ((right - left) > workArea.width ())
73 {71 {
7472
=== modified file 'plugins/place/src/place.cpp'
--- plugins/place/src/place.cpp 2012-02-02 17:01:15 +0000
+++ plugins/place/src/place.cpp 2012-04-17 08:08:21 +0000
@@ -343,37 +343,36 @@
343 CompWindow::Geometry geom;343 CompWindow::Geometry geom;
344 int output;344 int output;
345345
346 geom.set (xwc->x, xwc->y, xwc->width, xwc->height,
347 window->serverGeometry ().border ());
348
346 if (clampToViewport)349 if (clampToViewport)
347 {350 {
348 /* left, right, top, bottom target coordinates, clamed to viewport351 /* left, right, top, bottom target coordinates, clamed to viewport
349 * sizes as we don't need to validate movements to other viewports;352 * sizes as we don't need to validate movements to other viewports;
350 * we are only interested in inner-viewport movements */353 * we are only interested in inner-viewport movements */
351354
352 x = xwc->x % screen->width ();355 x = geom.x () % screen->width ();
353 if ((x + xwc->width) < 0)356 if ((geom.x2 ()) < 0)
354 x += screen->width ();357 x += screen->width ();
355358
356 y = xwc->y % screen->height ();359 y = geom.y () % screen->height ();
357 if ((y + xwc->height) < 0)360 if ((geom.y2 ()) < 0)
358 y += screen->height ();361 y += screen->height ();
359 }362 }
360 else363 else
361 {364 {
362 x = xwc->x;365 x = geom.x ();
363 y = xwc->y;366 y = geom.y ();
364 }367 }
365368
366 left = x - window->border ().left;369 left = x - window->border ().left;
367 right = left + xwc->width + (window->border ().left +370 right = left + geom.widthIncBorders () + (window->border ().left +
368 window->border ().right +371 window->border ().right);
369 2 * window->serverGeometry ().border ());
370 top = y - window->border ().top;372 top = y - window->border ().top;
371 bottom = top + xwc->height + (window->border ().top +373 bottom = top + geom.heightIncBorders () + (window->border ().top +
372 window->border ().bottom +374 window->border ().bottom);
373 2 * window->serverGeometry ().border ());
374375
375 geom.set (xwc->x, xwc->y, xwc->width, xwc->height,
376 window->serverGeometry ().border ());
377 output = screen->outputDeviceForGeometry (geom);376 output = screen->outputDeviceForGeometry (geom);
378 workArea = screen->getWorkareaForOutput (output);377 workArea = screen->getWorkareaForOutput (output);
379378
@@ -746,10 +745,8 @@
746{745{
747 if (PlaceScreen::get (screen)->getPointerPosition (pos))746 if (PlaceScreen::get (screen)->getPointerPosition (pos))
748 {747 {
749 unsigned int dx = (window->serverGeometry ().width () / 2) -748 unsigned int dx = (window->serverGeometry ().widthIncBorders () / 2);
750 window->serverGeometry ().border ();749 unsigned int dy = (window->serverGeometry ().heightIncBorders () / 2);
751 unsigned int dy = (window->serverGeometry ().height () / 2) -
752 window->serverGeometry ().border ();
753 pos -= CompPoint (dx, dy);750 pos -= CompPoint (dx, dy);
754 }751 }
755 else752 else
@@ -1200,14 +1197,12 @@
12001197
1201 extents.left = pos.x () - window->border ().left;1198 extents.left = pos.x () - window->border ().left;
1202 extents.top = pos.y () - window->border ().top;1199 extents.top = pos.y () - window->border ().top;
1203 extents.right = extents.left + window->serverWidth () +1200 extents.right = extents.left + window->serverGeometry ().heightIncBorders () +
1204 (window->border ().left +1201 (window->border ().left +
1205 window->border ().right +1202 window->border ().right);
1206 2 * window->serverGeometry ().border ());1203 extents.bottom = extents.top + window->serverGeometry ().widthIncBorders () +
1207 extents.bottom = extents.top + window->serverHeight () +
1208 (window->border ().top +1204 (window->border ().top +
1209 window->border ().bottom +1205 window->border ().bottom);
1210 2 * window->serverGeometry ().border ());
12111206
1212 delta = workArea.right () - extents.right;1207 delta = workArea.right () - extents.right;
1213 if (delta < 0)1208 if (delta < 0)
12141209
=== modified file 'plugins/resize/src/resize.cpp'
--- plugins/resize/src/resize.cpp 2012-02-16 05:31:28 +0000
+++ plugins/resize/src/resize.cpp 2012-04-17 08:08:21 +0000
@@ -56,7 +56,7 @@
56void56void
57ResizeWindow::getStretchScale (BoxPtr pBox, float *xScale, float *yScale)57ResizeWindow::getStretchScale (BoxPtr pBox, float *xScale, float *yScale)
58{58{
59 CompRect rect (window->borderRect ());59 CompRect rect (window->serverBorderRect ());
6060
61 *xScale = (rect.width ()) ? (pBox->x2 - pBox->x1) /61 *xScale = (rect.width ()) ? (pBox->x2 - pBox->x1) /
62 (float) rect.width () : 1.0f;62 (float) rect.width () : 1.0f;
@@ -642,8 +642,7 @@
642 w->configureXWindow (mask, &xwc);642 w->configureXWindow (mask, &xwc);
643 }643 }
644644
645 if (!(mask & (CWWidth | CWHeight)))645 rs->finishResizing ();
646 rs->finishResizing ();
647646
648 if (rs->grabIndex)647 if (rs->grabIndex)
649 {648 {
@@ -1467,10 +1466,10 @@
1467 getPaintRectangle (&box);1466 getPaintRectangle (&box);
1468 damageRectangle (&box);1467 damageRectangle (&box);
14691468
1470 box.x1 = w->outputRect ().x ();1469 box.x1 = w->serverOutputRect ().x ();
1471 box.y1 = w->outputRect ().y ();1470 box.y1 = w->serverOutputRect ().y ();
1472 box.x2 = box.x1 + w->outputRect ().width ();1471 box.x2 = box.x1 + w->serverOutputRect ().width ();
1473 box.y2 = box.y1 + w->outputRect ().height ();1472 box.y2 = box.y1 + w->serverOutputRect ().height ();
14741473
1475 damageRectangle (&box);1474 damageRectangle (&box);
1476 }1475 }
@@ -1510,15 +1509,6 @@
1510}1509}
15111510
1512void1511void
1513ResizeWindow::resizeNotify (int dx, int dy, int dwidth, int dheight)
1514{
1515 window->resizeNotify (dx, dy, dwidth, dheight);
1516
1517 if (rScreen->w == window && !rScreen->grabIndex)
1518 rScreen->finishResizing ();
1519}
1520
1521void
1522ResizeScreen::glPaintRectangle (const GLScreenPaintAttrib &sAttrib,1512ResizeScreen::glPaintRectangle (const GLScreenPaintAttrib &sAttrib,
1523 const GLMatrix &transform,1513 const GLMatrix &transform,
1524 CompOutput *output,1514 CompOutput *output,
@@ -1649,8 +1639,8 @@
1649 rScreen->getPaintRectangle (&box);1639 rScreen->getPaintRectangle (&box);
1650 getStretchScale (&box, &xScale, &yScale);1640 getStretchScale (&box, &xScale, &yScale);
16511641
1652 x = window->geometry (). x ();1642 x = window->serverGeometry (). x ();
1653 y = window->geometry (). y ();1643 y = window->serverGeometry (). y ();
16541644
1655 xOrigin = x - window->border ().left;1645 xOrigin = x - window->border ().left;
1656 yOrigin = y - window->border ().top;1646 yOrigin = y - window->border ().top;
16571647
=== modified file 'plugins/resize/src/resize.h'
--- plugins/resize/src/resize.h 2012-02-09 07:48:57 +0000
+++ plugins/resize/src/resize.h 2012-04-17 08:08:21 +0000
@@ -162,8 +162,6 @@
162 ResizeWindow (CompWindow *w);162 ResizeWindow (CompWindow *w);
163 ~ResizeWindow ();163 ~ResizeWindow ();
164164
165 void resizeNotify (int, int, int, int);
166
167 bool damageRect (bool, const CompRect &);165 bool damageRect (bool, const CompRect &);
168166
169 bool glPaint (const GLWindowPaintAttrib &, const GLMatrix &,167 bool glPaint (const GLWindowPaintAttrib &, const GLMatrix &,
170168
=== modified file 'plugins/wobbly/src/wobbly.cpp'
--- plugins/wobbly/src/wobbly.cpp 2011-03-14 16:12:45 +0000
+++ plugins/wobbly/src/wobbly.cpp 2012-04-17 08:08:21 +0000
@@ -71,9 +71,9 @@
71 }71 }
72 else if (!p->invisible () && (p->type () & SNAP_WINDOW_TYPE))72 else if (!p->invisible () && (p->type () & SNAP_WINDOW_TYPE))
73 {73 {
74 s = p->geometry ().y () - p->border ().top -74 s = p->serverGeometry ().y () - p->border ().top -
75 window->output ().top;75 window->output ().top;
76 e = p->geometry ().y () + p->height () + p->border ().bottom +76 e = p->serverGeometry ().y () + p->height () + p->border ().bottom +
77 window->output ().bottom;77 window->output ().bottom;
78 }78 }
79 else79 else
@@ -102,7 +102,7 @@
102 if (p->mapNum () && p->struts ())102 if (p->mapNum () && p->struts ())
103 v = p->struts ()->left.x + p->struts ()->left.width;103 v = p->struts ()->left.x + p->struts ()->left.width;
104 else104 else
105 v = p->geometry ().x () + p->width () +105 v = p->serverGeometry ().x () + p->width () +
106 p->border ().right;106 p->border ().right;
107107
108 if (v <= x)108 if (v <= x)
@@ -179,9 +179,9 @@
179 }179 }
180 else if (!p->invisible () && (p->type () & SNAP_WINDOW_TYPE))180 else if (!p->invisible () && (p->type () & SNAP_WINDOW_TYPE))
181 {181 {
182 s = p->geometry ().y () - p->border ().top -182 s = p->serverGeometry ().y () - p->border ().top -
183 window->output ().top;183 window->output ().top;
184 e = p->geometry ().y () + p->height () + p->border ().bottom +184 e = p->serverGeometry ().y () + p->height () + p->border ().bottom +
185 window->output ().bottom;185 window->output ().bottom;
186 }186 }
187 else187 else
@@ -210,7 +210,7 @@
210 if (p->mapNum () && p->struts ())210 if (p->mapNum () && p->struts ())
211 v = p->struts ()->right.x;211 v = p->struts ()->right.x;
212 else212 else
213 v = p->geometry ().x () - p->border ().left;213 v = p->serverGeometry ().x () - p->border ().left;
214214
215 if (v >= x)215 if (v >= x)
216 {216 {
@@ -286,9 +286,9 @@
286 }286 }
287 else if (!p->invisible () && (p->type () & SNAP_WINDOW_TYPE))287 else if (!p->invisible () && (p->type () & SNAP_WINDOW_TYPE))
288 {288 {
289 s = p->geometry ().x () - p->border ().left -289 s = p->serverGeometry ().x () - p->border ().left -
290 window->output ().left;290 window->output ().left;
291 e = p->geometry ().x () + p->width () + p->border ().right +291 e = p->serverGeometry ().x () + p->width () + p->border ().right +
292 window->output ().right;292 window->output ().right;
293 }293 }
294 else294 else
@@ -317,7 +317,7 @@
317 if (p->mapNum () && p->struts ())317 if (p->mapNum () && p->struts ())
318 v = p->struts ()->top.y + p->struts ()->top.height;318 v = p->struts ()->top.y + p->struts ()->top.height;
319 else319 else
320 v = p->geometry ().y () + p->height () + p->border ().bottom;320 v = p->serverGeometry ().y () + p->height () + p->border ().bottom;
321321
322 if (v <= y)322 if (v <= y)
323 {323 {
@@ -393,9 +393,9 @@
393 }393 }
394 else if (!p->invisible () && (p->type () & SNAP_WINDOW_TYPE))394 else if (!p->invisible () && (p->type () & SNAP_WINDOW_TYPE))
395 {395 {
396 s = p->geometry ().x () - p->border ().left -396 s = p->serverGeometry ().x () - p->border ().left -
397 window->output ().left;397 window->output ().left;
398 e = p->geometry ().x () + p->width () + p->border ().right +398 e = p->serverGeometry ().x () + p->width () + p->border ().right +
399 window->output ().right;399 window->output ().right;
400 }400 }
401 else401 else
@@ -424,7 +424,7 @@
424 if (p->mapNum () && p->struts ())424 if (p->mapNum () && p->struts ())
425 v = p->struts ()->bottom.y;425 v = p->struts ()->bottom.y;
426 else426 else
427 v = p->geometry ().y () - p->border ().top;427 v = p->serverGeometry ().y () - p->border ().top;
428428
429 if (v >= y)429 if (v >= y)
430 {430 {
@@ -1251,7 +1251,7 @@
1251 if (!model)1251 if (!model)
1252 {1252 {
1253 unsigned int edgeMask = 0;1253 unsigned int edgeMask = 0;
1254 CompRect outRect (window->outputRect ());1254 CompRect outRect (window->serverOutputRect ());
12551255
1256 if (window->type () & CompWindowTypeNormalMask)1256 if (window->type () & CompWindowTypeNormalMask)
1257 edgeMask = WestEdgeMask | EastEdgeMask | NorthEdgeMask |1257 edgeMask = WestEdgeMask | EastEdgeMask | NorthEdgeMask |
@@ -1311,7 +1311,7 @@
1311 if (window->width () == 1 && window->height () == 1)1311 if (window->width () == 1 && window->height () == 1)
1312 return false;1312 return false;
13131313
1314 CompWindow::Geometry &geom = window->geometry ();1314 CompWindow::Geometry &geom = window->serverGeometry ();
13151315
1316 /* avoid fullscreen windows */1316 /* avoid fullscreen windows */
1317 if (geom.x () <= 0 &&1317 if (geom.x () <= 0 &&
@@ -1406,23 +1406,16 @@
1406 }1406 }
1407 }1407 }
1408 }1408 }
1409 else1409 else if (ww->dropGeometry == w->serverGeometry ())
1410 {1410 {
1411 ww->model = 0;1411 ww->model = 0;
14121412
1413 if (w->geometry ().x () == w->serverX () &&1413 XWindowChanges xwc;
1414 w->geometry ().y () == w->serverY ())1414
1415 {1415 xwc.x = model->topLeft.x + w->output ().left;
1416 w->move (model->topLeft.x +1416 xwc.y = model->topLeft.y + w->output ().top;
1417 w->output ().left -1417
1418 w->geometry ().x (),1418 w->configureXWindow (CWX | CWY, &xwc);
1419 model->topLeft.y +
1420 w->output ().top -
1421 w->geometry ().y (),
1422 true);
1423 w->syncPosition ();
1424 }
1425
1426 ww->model = model;1419 ww->model = model;
1427 }1420 }
14281421
@@ -1448,9 +1441,9 @@
1448 else1441 else
1449 cw->addDamage ();1442 cw->addDamage ();
14501443
1451 int wx = w->geometry ().x ();1444 int wx = w->serverGeometry ().x ();
1452 int wy = w->geometry ().y ();1445 int wy = w->serverGeometry ().y ();
1453 int borderWidth = w->geometry ().border ();1446 int borderWidth = w->serverGeometry ().border ();
14541447
1455 // Damage a box that's 1-pixel larger on each side1448 // Damage a box that's 1-pixel larger on each side
1456 // to prevent artifacts1449 // to prevent artifacts
@@ -1578,7 +1571,7 @@
1578 }1571 }
1579 }1572 }
15801573
1581 CompRect outRect (window->outputRect ());1574 CompRect outRect (window->serverOutputRect ());
1582 wx = outRect.x ();1575 wx = outRect.x ();
1583 wy = outRect.y ();1576 wy = outRect.y ();
1584 width = outRect.width ();1577 width = outRect.width ();
@@ -1772,7 +1765,7 @@
17721765
1773 if (ww->isWobblyWin () && ww->ensureModel ())1766 if (ww->isWobblyWin () && ww->ensureModel ())
1774 {1767 {
1775 CompRect outRect (w->outputRect ());1768 CompRect outRect (w->serverOutputRect ());
17761769
1777 ww->model->setMiddleAnchor (outRect.x (), outRect.y (),1770 ww->model->setMiddleAnchor (outRect.x (), outRect.y (),
1778 outRect.width (), outRect.height ());1771 outRect.width (), outRect.height ());
@@ -1901,7 +1894,7 @@
1901 switch (focusEffect) {1894 switch (focusEffect) {
1902 case WobblyOptions::FocusEffectShiver:1895 case WobblyOptions::FocusEffectShiver:
1903 {1896 {
1904 CompRect outRect (w->outputRect ());1897 CompRect outRect (w->serverOutputRect ());
19051898
1906 ww->model->adjustObjectsForShiver (outRect.x (),1899 ww->model->adjustObjectsForShiver (outRect.x (),
1907 outRect.y (),1900 outRect.y (),
@@ -1977,7 +1970,7 @@
1977 wScreen->optionGetMapWindowMatch ().evaluate (window) &&1970 wScreen->optionGetMapWindowMatch ().evaluate (window) &&
1978 ensureModel ())1971 ensureModel ())
1979 {1972 {
1980 CompRect outRect (window->outputRect ());1973 CompRect outRect (window->serverOutputRect ());
19811974
1982 model->initObjects (outRect.x (), outRect.y (),1975 model->initObjects (outRect.x (), outRect.y (),
1983 outRect.width (), outRect.height ());1976 outRect.width (), outRect.height ());
@@ -2006,7 +1999,7 @@
2006 int dwidth,1999 int dwidth,
2007 int dheight)2000 int dheight)
2008{2001{
2009 CompRect outRect (window->outputRect ());2002 CompRect outRect (window->serverOutputRect ());
20102003
2011 if (wScreen->optionGetMaximizeEffect () &&2004 if (wScreen->optionGetMaximizeEffect () &&
2012 isWobblyWin () &&2005 isWobblyWin () &&
@@ -2128,10 +2121,12 @@
2128 {2121 {
2129 wScreen->grabMask = mask;2122 wScreen->grabMask = mask;
2130 wScreen->grabWindow = window;2123 wScreen->grabWindow = window;
2124 dropGeometry = CompWindow::Geometry (0, 0, 0, 0, 0);
2131 }2125 }
2132 wScreen->moveWindow = false;2126 wScreen->moveWindow = false;
21332127
2134 if ((mask & CompWindowGrabButtonMask) &&2128 if (mask & (CompWindowGrabButtonMask) &&
2129 mask & (CompWindowGrabMoveMask) &&
2135 wScreen->optionGetMoveWindowMatch ().evaluate (window) &&2130 wScreen->optionGetMoveWindowMatch ().evaluate (window) &&
2136 isWobblyWin ())2131 isWobblyWin ())
2137 {2132 {
@@ -2144,7 +2139,7 @@
21442139
2145 if (wScreen->optionGetMaximizeEffect ())2140 if (wScreen->optionGetMaximizeEffect ())
2146 {2141 {
2147 CompRect outRect (window->outputRect ());2142 CompRect outRect (window->serverOutputRect ());
21482143
2149 if (window->state () & MAXIMIZE_STATE)2144 if (window->state () & MAXIMIZE_STATE)
2150 {2145 {
@@ -2192,7 +2187,7 @@
2192 if (wScreen->yConstrained)2187 if (wScreen->yConstrained)
2193 {2188 {
2194 int output =2189 int output =
2195 ::screen->outputDeviceForGeometry (window->geometry ());2190 ::screen->outputDeviceForGeometry (window->serverGeometry ());
2196 wScreen->constraintBox =2191 wScreen->constraintBox =
2197 &::screen->outputDevs ()[output].workArea ();2192 &::screen->outputDevs ()[output].workArea ();
2198 }2193 }
@@ -2252,7 +2247,7 @@
2252 if (wScreen->optionGetMaximizeEffect () &&2247 if (wScreen->optionGetMaximizeEffect () &&
2253 (state & MAXIMIZE_STATE))2248 (state & MAXIMIZE_STATE))
2254 {2249 {
2255 CompRect outRect (window->outputRect ());2250 CompRect outRect (window->serverOutputRect ());
22562251
2257 model->addEdgeAnchors (outRect.x (), outRect.y (),2252 model->addEdgeAnchors (outRect.x (), outRect.y (),
2258 outRect.width (), outRect.height ());2253 outRect.width (), outRect.height ());
@@ -2262,6 +2257,8 @@
2262 }2257 }
22632258
2264 grabbed = false;2259 grabbed = false;
2260
2261 dropGeometry = window->serverGeometry ();
2265 }2262 }
22662263
2267 window->ungrabNotify ();2264 window->ungrabNotify ();
22682265
=== modified file 'plugins/wobbly/src/wobbly.h'
--- plugins/wobbly/src/wobbly.h 2009-12-25 19:50:25 +0000
+++ plugins/wobbly/src/wobbly.h 2012-04-17 08:08:21 +0000
@@ -300,6 +300,8 @@
300 bool grabbed;300 bool grabbed;
301 bool velocity;301 bool velocity;
302 unsigned int state;302 unsigned int state;
303
304 CompWindow::Geometry dropGeometry;
303};305};
304306
305class WobblyPluginVTable :307class WobblyPluginVTable :
306308
=== modified file 'src/actions.cpp'
--- src/actions.cpp 2012-01-31 14:52:20 +0000
+++ src/actions.cpp 2012-04-17 08:08:21 +0000
@@ -201,9 +201,9 @@
201 time = CompOption::getIntOptionNamed (options, "time", CurrentTime);201 time = CompOption::getIntOptionNamed (options, "time", CurrentTime);
202 button = CompOption::getIntOptionNamed (options, "button", 0);202 button = CompOption::getIntOptionNamed (options, "button", 0);
203 x = CompOption::getIntOptionNamed (options, "x",203 x = CompOption::getIntOptionNamed (options, "x",
204 w->geometry ().x ());204 w->serverGeometry ().x ());
205 y = CompOption::getIntOptionNamed (options, "y",205 y = CompOption::getIntOptionNamed (options, "y",
206 w->geometry ().y ());206 w->serverGeometry ().y ());
207207
208 screen->toolkitAction (Atoms::toolkitActionWindowMenu,208 screen->toolkitAction (Atoms::toolkitActionWindowMenu,
209 time, w->id (), button, x, y);209 time, w->id (), button, x, y);
210210
=== modified file 'src/event.cpp'
--- src/event.cpp 2012-04-04 03:11:55 +0000
+++ src/event.cpp 2012-04-17 08:08:21 +0000
@@ -1251,7 +1251,7 @@
1251 }1251 }
12521252
1253 /* been shaded */1253 /* been shaded */
1254 if (w->priv->height == 0)1254 if (w->shaded ())
1255 {1255 {
1256 if (w->id () == priv->activeWindow)1256 if (w->id () == priv->activeWindow)
1257 w->moveInputFocusTo ();1257 w->moveInputFocusTo ();
12581258
=== modified file 'src/privatewindow.h'
--- src/privatewindow.h 2012-03-02 18:02:07 +0000
+++ src/privatewindow.h 2012-04-17 08:08:21 +0000
@@ -34,7 +34,6 @@
34#include <core/timer.h>34#include <core/timer.h>
35#include "privatescreen.h"35#include "privatescreen.h"
3636
37
38typedef CompWindowExtents CompFullscreenMonitorSet;37typedef CompWindowExtents CompFullscreenMonitorSet;
3938
40class PrivateWindow {39class PrivateWindow {
@@ -167,6 +166,11 @@
167166
168 bool handleSyncAlarm ();167 bool handleSyncAlarm ();
169168
169 void move (int dx, int dy, bool sync);
170 bool resize (int dx, int dy, int dwidth, int dheight, int dborder);
171 bool resize (const CompWindow::Geometry &g);
172 bool resize (const XWindowAttributes &attrib);
173
170 void configure (XConfigureEvent *ce);174 void configure (XConfigureEvent *ce);
171175
172 void configureFrame (XConfigureEvent *ce);176 void configureFrame (XConfigureEvent *ce);
@@ -241,13 +245,8 @@
241 XSizeHints sizeHints;245 XSizeHints sizeHints;
242 XWMHints *hints;246 XWMHints *hints;
243247
244 struct timeval lastGeometryUpdate;
245 struct timeval lastConfigureRequest;
246
247 bool inputHint;248 bool inputHint;
248 bool alpha;249 bool alpha;
249 int width;
250 int height;
251 CompRegion region;250 CompRegion region;
252 CompRegion inputRegion;251 CompRegion inputRegion;
253 CompRegion frameRegion;252 CompRegion frameRegion;
@@ -290,8 +289,6 @@
290 typedef std::pair <XWindowChanges, unsigned int> XWCValueMask;289 typedef std::pair <XWindowChanges, unsigned int> XWCValueMask;
291290
292 compiz::X11::PendingEventQueue pendingConfigures;291 compiz::X11::PendingEventQueue pendingConfigures;
293 CompTimer mClearCheckTimeout;
294 bool pendingPositionUpdates;
295292
296 char *startupId;293 char *startupId;
297 char *resName;294 char *resName;
@@ -327,6 +324,8 @@
327324
328 bool closeRequests;325 bool closeRequests;
329 Time lastCloseRequestTime;326 Time lastCloseRequestTime;
327
328 bool nextMoveImmediate;
330};329};
331330
332#endif331#endif
333332
=== modified file 'src/screen.cpp'
--- src/screen.cpp 2012-03-30 06:26:33 +0000
+++ src/screen.cpp 2012-04-17 08:08:21 +0000
@@ -4060,8 +4060,8 @@
4060 CompRect rect (gm);4060 CompRect rect (gm);
4061 int offset;4061 int offset;
40624062
4063 rect.setWidth (rect.width () + (gm.border () * 2));4063 rect.setWidth (gm.widthIncBorders ());
4064 rect.setHeight (rect.height () + (gm.border () * 2));4064 rect.setHeight (gm.heightIncBorders ());
40654065
4066 offset = rect.centerX () < 0 ? -1 : 0;4066 offset = rect.centerX () < 0 ? -1 : 0;
4067 viewport.setX (priv->vp.x () + ((rect.centerX () / width ()) + offset) %4067 viewport.setX (priv->vp.x () + ((rect.centerX () / width ()) + offset) %
@@ -4657,6 +4657,8 @@
4657 return false;4657 return false;
4658 }4658 }
46594659
4660 /* Use synchronous behaviour when running with --sync, useful
4661 * for getting stacktraces when X Errors occurr */
4660 XSynchronize (dpy, synchronousX ? True : False);4662 XSynchronize (dpy, synchronousX ? True : False);
46614663
4662 snprintf (displayString, 255, "DISPLAY=%s",4664 snprintf (displayString, 255, "DISPLAY=%s",
46634665
=== modified file 'src/window.cpp'
--- src/window.cpp 2012-04-16 09:44:13 +0000
+++ src/window.cpp 2012-04-17 08:08:21 +0000
@@ -77,8 +77,8 @@
77PrivateWindow::isInvisible() const77PrivateWindow::isInvisible() const
78{78{
79 return attrib.map_state != IsViewable ||79 return attrib.map_state != IsViewable ||
80 attrib.x + width + output.right <= 0 ||80 attrib.x + geometry.width () + output.right <= 0 ||
81 attrib.y + height + output.bottom <= 0 ||81 attrib.y + geometry.height () + output.bottom <= 0 ||
82 attrib.x - output.left >= (int) screen->width () ||82 attrib.x - output.left >= (int) screen->width () ||
83 attrib.y - output.top >= (int) screen->height ();83 attrib.y - output.top >= (int) screen->height ();
84}84}
@@ -810,292 +810,14 @@
810 if (!serverFrame)810 if (!serverFrame)
811 return;811 return;
812812
813813 xwc.x = serverGeometry.x ();
814 gettimeofday (&lastConfigureRequest, NULL);814 xwc.y = serverGeometry.y ();
815 /* Flush any changes made to serverFrameGeometry or serverGeometry to the server815 xwc.width = serverGeometry.width ();
816 * since there is a race condition where geometries will go out-of-sync with816 xwc.height = serverGeometry.height ();
817 * window movement */817 xwc.border_width = serverGeometry.border ();
818818
819 window->syncPosition ();819 window->configureXWindow (valueMask, &xwc);
820820 window->windowNotify (CompWindowNotifyFrameUpdate);
821 if (serverInput.left || serverInput.right || serverInput.top || serverInput.bottom)
822 {
823 int bw = serverGeometry.border () * 2;
824
825 xwc.x = serverGeometry.x () - serverInput.left;
826 xwc.y = serverGeometry.y () - serverInput.top;
827 xwc.width = serverGeometry.width () + serverInput.left + serverInput.right + bw;
828 if (shaded)
829 xwc.height = serverInput.top + serverInput.bottom + bw;
830 else
831 xwc.height = serverGeometry.height () + serverInput.top + serverInput.bottom + bw;
832
833 if (shaded)
834 height = serverInput.top + serverInput.bottom;
835
836 if (serverFrameGeometry.x () == xwc.x)
837 valueMask &= ~(CWX);
838 else
839 serverFrameGeometry.setX (xwc.x);
840
841 if (serverFrameGeometry.y () == xwc.y)
842 valueMask &= ~(CWY);
843 else
844 serverFrameGeometry.setY (xwc.y);
845
846 if (serverFrameGeometry.width () == xwc.width)
847 valueMask &= ~(CWWidth);
848 else
849 serverFrameGeometry.setWidth (xwc.width);
850
851 if (serverFrameGeometry.height () == xwc.height)
852 valueMask &= ~(CWHeight);
853 else
854 serverFrameGeometry.setHeight (xwc.height);
855
856 /* Geometry is the same, so we're not going to get a ConfigureNotify
857 * event when the window is configured, which means that other plugins
858 * won't know that the client, frame and wrapper windows got shifted
859 * around (and might result in display corruption, eg in OpenGL */
860 if (valueMask == 0)
861 {
862 XConfigureEvent xev;
863 XWindowAttributes attrib;
864 unsigned int nchildren = 0;
865 Window rootRet = 0, parentRet = 0;
866 Window *children = NULL;
867
868 xev.type = ConfigureNotify;
869 xev.event = screen->root ();
870 xev.window = priv->serverFrame;
871
872 XGrabServer (screen->dpy ());
873
874 if (XGetWindowAttributes (screen->dpy (), priv->serverFrame, &attrib))
875 {
876 xev.x = attrib.x;
877 xev.y = attrib.y;
878 xev.width = attrib.width;
879 xev.height = attrib.height;
880 xev.border_width = attrib.border_width;
881 xev.above = None;
882
883 /* We need to ensure that the stacking order is
884 * based on the current server stacking order so
885 * find the sibling to this window's frame in the
886 * server side stack and stack above that */
887 XQueryTree (screen->dpy (), screen->root (), &rootRet, &parentRet, &children, &nchildren);
888
889 if (nchildren)
890 {
891 for (unsigned int i = 0; i < nchildren; i++)
892 {
893 if (i + 1 == nchildren ||
894 children[i + 1] == ROOTPARENT (window))
895 {
896 xev.above = children[i];
897 break;
898 }
899 }
900 }
901
902 if (children)
903 XFree (children);
904
905 if (!xev.above)
906 xev.above = (window->serverPrev) ? ROOTPARENT (window->serverPrev) : None;
907
908 xev.override_redirect = priv->attrib.override_redirect;
909
910 }
911
912 compiz::X11::PendingEvent::Ptr pc =
913 boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
914 new compiz::X11::PendingConfigureEvent (
915 screen->dpy (), serverFrame, valueMask, &xwc)));
916
917 pendingConfigures.add (pc);
918 if (priv->mClearCheckTimeout.active ())
919 priv->mClearCheckTimeout.stop ();
920 priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
921 2000, 2500);
922
923 XSendEvent (screen->dpy (), screen->root (), false,
924 SubstructureNotifyMask, (XEvent *) &xev);
925
926 XUngrabServer (screen->dpy ());
927 XSync (screen->dpy (), false);
928 }
929 else
930 {
931 compiz::X11::PendingEvent::Ptr pc =
932 boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
933 new compiz::X11::PendingConfigureEvent (
934 screen->dpy (), serverFrame, valueMask, &xwc)));
935
936 pendingConfigures.add (pc);
937 if (priv->mClearCheckTimeout.active ())
938 priv->mClearCheckTimeout.stop ();
939 priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
940 2000, 2500);
941 XConfigureWindow (screen->dpy (), serverFrame, valueMask, &xwc);
942 }
943
944 if (shaded)
945 {
946 XUnmapWindow (screen->dpy (), wrapper);
947 }
948 else
949 {
950 XMapWindow (screen->dpy (), wrapper);
951 XMoveResizeWindow (screen->dpy (), wrapper, serverInput.left, serverInput.top,
952 serverGeometry.width (), serverGeometry.height ());
953 }
954 XMoveResizeWindow (screen->dpy (), id, 0, 0,
955 serverGeometry.width (), serverGeometry.height ());
956 window->sendConfigureNotify ();
957 window->windowNotify (CompWindowNotifyFrameUpdate);
958 }
959 else
960 {
961 int bw = serverGeometry.border () * 2;
962
963 xwc.x = serverGeometry.x ();
964 xwc.y = serverGeometry.y ();
965 xwc.width = serverGeometry.width () + bw;
966
967 /* FIXME: It doesn't make much sense to allow undecorated windows to be
968 * shaded */
969 if (shaded)
970 xwc.height = bw;
971 else
972 xwc.height = serverGeometry.height () + bw;
973
974 if (serverFrameGeometry.x () == xwc.x)
975 valueMask &= ~(CWX);
976 else
977 serverFrameGeometry.setX (xwc.x);
978
979 if (serverFrameGeometry.y () == xwc.y)
980 valueMask &= ~(CWY);
981 else
982 serverFrameGeometry.setY (xwc.y);
983
984 if (serverFrameGeometry.width () == xwc.width)
985 valueMask &= ~(CWWidth);
986 else
987 serverFrameGeometry.setWidth (xwc.width);
988
989 if (serverFrameGeometry.height () == xwc.height)
990 valueMask &= ~(CWHeight);
991 else
992 serverFrameGeometry.setHeight (xwc.height);
993
994 /* Geometry is the same, so we're not going to get a ConfigureNotify
995 * event when the window is configured, which means that other plugins
996 * won't know that the client, frame and wrapper windows got shifted
997 * around (and might result in display corruption, eg in OpenGL */
998 if (valueMask == 0)
999 {
1000 XConfigureEvent xev;
1001 XWindowAttributes attrib;
1002 unsigned int nchildren = 0;
1003 Window rootRet = 0, parentRet = 0;
1004 Window *children = NULL;
1005
1006 xev.type = ConfigureNotify;
1007 xev.event = screen->root ();
1008 xev.window = priv->serverFrame;
1009
1010 XGrabServer (screen->dpy ());
1011
1012 if (XGetWindowAttributes (screen->dpy (), priv->serverFrame, &attrib))
1013 {
1014 xev.x = attrib.x;
1015 xev.y = attrib.y;
1016 xev.width = attrib.width;
1017 xev.height = attrib.height;
1018 xev.border_width = attrib.border_width;
1019 xev.above = None;
1020
1021 /* We need to ensure that the stacking order is
1022 * based on the current server stacking order so
1023 * find the sibling to this window's frame in the
1024 * server side stack and stack above that */
1025 XQueryTree (screen->dpy (), screen->root (), &rootRet, &parentRet, &children, &nchildren);
1026
1027 if (nchildren)
1028 {
1029 for (unsigned int i = 0; i < nchildren; i++)
1030 {
1031 if (i + 1 == nchildren ||
1032 children[i + 1] == ROOTPARENT (window))
1033 {
1034 xev.above = children[i];
1035 break;
1036 }
1037 }
1038 }
1039
1040 if (children)
1041 XFree (children);
1042
1043 if (!xev.above)
1044 xev.above = (window->serverPrev) ? ROOTPARENT (window->serverPrev) : None;
1045
1046 xev.override_redirect = priv->attrib.override_redirect;
1047
1048 }
1049
1050 compiz::X11::PendingEvent::Ptr pc =
1051 boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
1052 new compiz::X11::PendingConfigureEvent (
1053 screen->dpy (), serverFrame, valueMask, &xwc)));
1054
1055 pendingConfigures.add (pc);
1056 if (priv->mClearCheckTimeout.active ())
1057 priv->mClearCheckTimeout.stop ();
1058 priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
1059 2000, 2500);
1060
1061 XSendEvent (screen->dpy (), screen->root (), false,
1062 SubstructureNotifyMask, (XEvent *) &xev);
1063
1064 XUngrabServer (screen->dpy ());
1065 XSync (screen->dpy (), false);
1066 }
1067 else
1068 {
1069 compiz::X11::PendingEvent::Ptr pc =
1070 boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
1071 new compiz::X11::PendingConfigureEvent (
1072 screen->dpy (), serverFrame, valueMask, &xwc)));
1073
1074 pendingConfigures.add (pc);
1075 if (priv->mClearCheckTimeout.active ())
1076 priv->mClearCheckTimeout.stop ();
1077 priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
1078 2000, 2500);
1079
1080 XConfigureWindow (screen->dpy (), serverFrame, valueMask, &xwc);
1081 }
1082
1083 if (shaded)
1084 {
1085 XUnmapWindow (screen->dpy (), wrapper);
1086 }
1087 else
1088 {
1089 XMapWindow (screen->dpy (), wrapper);
1090 XMoveResizeWindow (screen->dpy (), wrapper, 0, 0,
1091 serverGeometry.width (), serverGeometry.height ());
1092 }
1093
1094 XMoveResizeWindow (screen->dpy (), id, 0, 0,
1095 serverGeometry.width (), serverGeometry.height ());
1096 window->sendConfigureNotify ();
1097 window->windowNotify (CompWindowNotifyFrameUpdate);
1098 }
1099 window->recalcActions ();821 window->recalcActions ();
1100}822}
1101823
@@ -1135,11 +857,12 @@
1135{857{
1136 CompRegion ret;858 CompRegion ret;
1137 int x1, x2, y1, y2;859 int x1, x2, y1, y2;
860 const CompWindow::Geometry &geom = attrib.override_redirect ? priv->geometry : priv->serverGeometry;
1138861
1139 for (unsigned int i = 0; i < n; i++)862 for (unsigned int i = 0; i < n; i++)
1140 {863 {
1141 x1 = rects[i].x + priv->geometry.border ();864 x1 = rects[i].x + geom.border ();
1142 y1 = rects[i].y + priv->geometry.border ();865 y1 = rects[i].y + geom.border ();
1143 x2 = x1 + rects[i].width;866 x2 = x1 + rects[i].width;
1144 y2 = y1 + rects[i].height;867 y2 = y1 + rects[i].height;
1145868
@@ -1147,17 +870,17 @@
1147 x1 = 0;870 x1 = 0;
1148 if (y1 < 0)871 if (y1 < 0)
1149 y1 = 0;872 y1 = 0;
1150 if (x2 > priv->width)873 if (x2 > geom.width ())
1151 x2 = priv->width;874 x2 = geom.width ();
1152 if (y2 > priv->height)875 if (y2 > geom.height ())
1153 y2 = priv->height;876 y2 = geom.height ();
1154877
1155 if (y1 < y2 && x1 < x2)878 if (y1 < y2 && x1 < x2)
1156 {879 {
1157 x1 += priv->geometry.x ();880 x1 += geom.x ();
1158 y1 += priv->geometry.y ();881 y1 += geom.y ();
1159 x2 += priv->geometry.x ();882 x2 += geom.x ();
1160 y2 += priv->geometry.y ();883 y2 += geom.y ();
1161884
1162 ret += CompRect (x1, y1, x2 - x1, y2 - y1);885 ret += CompRect (x1, y1, x2 - x1, y2 - y1);
1163 }886 }
@@ -1177,25 +900,28 @@
1177 XRectangle r, *boundingShapeRects = NULL;900 XRectangle r, *boundingShapeRects = NULL;
1178 XRectangle *inputShapeRects = NULL;901 XRectangle *inputShapeRects = NULL;
1179 int nBounding = 0, nInput = 0;902 int nBounding = 0, nInput = 0;
903 const CompWindow::Geometry &geom = attrib.override_redirect ? priv->geometry : priv->serverGeometry;
1180904
1181 priv->region = CompRegion ();905 priv->region -= infiniteRegion;
1182 priv->inputRegion = CompRegion ();906 priv->inputRegion -= infiniteRegion;
1183907
1184 if (screen->XShape ())908 if (screen->XShape ())
1185 {909 {
1186 int order;910 int order;
1187911
912 /* We should update the server here */
913 XSync (screen->dpy (), false);
914
1188 boundingShapeRects = XShapeGetRectangles (screen->dpy (), priv->id,915 boundingShapeRects = XShapeGetRectangles (screen->dpy (), priv->id,
1189 ShapeBounding, &nBounding, &order);916 ShapeBounding, &nBounding, &order);
1190 inputShapeRects = XShapeGetRectangles (screen->dpy (), priv->id,917 inputShapeRects = XShapeGetRectangles (screen->dpy (), priv->id,
1191 ShapeInput, &nInput, &order);918 ShapeInput, &nInput, &order);
1192
1193 }919 }
1194920
1195 r.x = -priv->geometry.border ();921 r.x = -geom.border ();
1196 r.y = -priv->geometry.border ();922 r.y = -geom.border ();
1197 r.width = priv->width + priv->geometry.border ();923 r.width = geom.widthIncBorders ();
1198 r.height = priv->height + priv->geometry.border ();924 r.height = geom.heightIncBorders ();
1199925
1200 if (nBounding < 1)926 if (nBounding < 1)
1201 {927 {
@@ -1729,7 +1455,7 @@
1729 priv->attrib.map_state = IsUnmapped;1455 priv->attrib.map_state = IsUnmapped;
1730 priv->invisible = true;1456 priv->invisible = true;
17311457
1732 if (priv->shaded && priv->height)1458 if (priv->shaded)
1733 {1459 {
1734 priv->updateFrameWindow ();1460 priv->updateFrameWindow ();
1735 }1461 }
@@ -1814,7 +1540,7 @@
1814}1540}
18151541
1816bool1542bool
1817CompWindow::resize (CompWindow::Geometry gm)1543PrivateWindow::resize (const CompWindow::Geometry &gm)
1818{1544{
1819 /* Input extents are now the last thing sent1545 /* Input extents are now the last thing sent
1820 * from the server. This might not work in some1546 * from the server. This might not work in some
@@ -1831,12 +1557,8 @@
1831 priv->geometry.height () != gm.height () ||1557 priv->geometry.height () != gm.height () ||
1832 priv->geometry.border () != gm.border ())1558 priv->geometry.border () != gm.border ())
1833 {1559 {
1834 int pw, ph;
1835 int dx, dy, dwidth, dheight;1560 int dx, dy, dwidth, dheight;
18361561
1837 pw = gm.width () + gm.border () * 2;
1838 ph = gm.height () + gm.border () * 2;
1839
1840 dx = gm.x () - priv->geometry.x ();1562 dx = gm.x () - priv->geometry.x ();
1841 dy = gm.y () - priv->geometry.y ();1563 dy = gm.y () - priv->geometry.y ();
1842 dwidth = gm.width () - priv->geometry.width ();1564 dwidth = gm.width () - priv->geometry.width ();
@@ -1846,37 +1568,58 @@
1846 gm.width (), gm.height (),1568 gm.width (), gm.height (),
1847 gm.border ());1569 gm.border ());
18481570
1849 priv->width = pw;
1850 priv->height = ph;
1851
1852 if (priv->mapNum)
1853 priv->updateRegion ();
1854
1855 resizeNotify (dx, dy, dwidth, dheight);
1856
1857 priv->invisible = priv->isInvisible ();1571 priv->invisible = priv->isInvisible ();
1572
1573 if (priv->attrib.override_redirect)
1574 {
1575 priv->serverGeometry = priv->geometry;
1576 priv->serverFrameGeometry = priv->frameGeometry;
1577
1578 if (priv->mapNum)
1579 priv->updateRegion ();
1580
1581 window->resizeNotify (dx, dy, dwidth, dheight);
1582 }
1858 }1583 }
1859 else if (priv->geometry.x () != gm.x () || priv->geometry.y () != gm.y ())1584 else if (priv->geometry.x () != gm.x () || priv->geometry.y () != gm.y ())
1860 {1585 {
1861 int dx, dy;1586 move (gm.x () - priv->geometry.x (),
18621587 gm.y () - priv->geometry.y (), true);
1863 dx = gm.x () - priv->geometry.x ();
1864 dy = gm.y () - priv->geometry.y ();
1865
1866 priv->geometry.setX (gm.x ());
1867 priv->geometry.setY (gm.y ());
1868
1869 priv->region.translate (dx, dy);
1870 priv->inputRegion.translate (dx, dy);
1871 if (!priv->frameRegion.isEmpty ())
1872 priv->frameRegion.translate (dx, dy);
1873
1874 priv->invisible = priv->isInvisible ();
1875
1876 moveNotify (dx, dy, true);
1877 }1588 }
18781589
1879 updateFrameRegion ();1590 return true;
1591}
1592
1593bool
1594PrivateWindow::resize (const XWindowAttributes &attr)
1595{
1596 return resize (CompWindow::Geometry (attr.x, attr.y, attr.width, attr.height,
1597 attr.border_width));
1598}
1599
1600bool
1601PrivateWindow::resize (int x,
1602 int y,
1603 int width,
1604 int height,
1605 int border)
1606{
1607 return resize (CompWindow::Geometry (x, y, width, height, border));
1608}
1609
1610bool
1611CompWindow::resize (CompWindow::Geometry gm)
1612{
1613 XWindowChanges xwc = XWINDOWCHANGES_INIT;
1614 unsigned int valueMask = CWX | CWY | CWWidth | CWHeight | CWBorderWidth;
1615
1616 xwc.x = gm.x ();
1617 xwc.y = gm.y ();
1618 xwc.width = gm.width ();
1619 xwc.height = gm.height ();
1620 xwc.border_width = gm.border ();
1621
1622 configureXWindow (valueMask, &xwc);
18801623
1881 return true;1624 return true;
1882}1625}
@@ -2044,13 +1787,7 @@
2044 ce->border_width);1787 ce->border_width);
2045 else1788 else
2046 {1789 {
2047 if (ce->override_redirect)1790 resize (ce->x, ce->y, ce->width, ce->height, ce->border_width);
2048 {
2049 priv->serverGeometry.set (ce->x, ce->y, ce->width, ce->height,
2050 ce->border_width);
2051 }
2052
2053 window->resize (ce->x, ce->y, ce->width, ce->height, ce->border_width);
2054 }1791 }
20551792
2056 if (ce->event == screen->root ())1793 if (ce->event == screen->root ())
@@ -2120,9 +1857,9 @@
2120 * windows since we didn't resize them1857 * windows since we didn't resize them
2121 * on configureXWindow */1858 * on configureXWindow */
2122 if (priv->shaded)1859 if (priv->shaded)
2123 height = priv->serverGeometry.height () - priv->serverGeometry.border () * 2 - priv->serverInput.top - priv->serverInput.bottom;1860 height = priv->serverGeometry.heightIncBorders () - priv->serverInput.top - priv->serverInput.bottom;
2124 else1861 else
2125 height = ce->height - priv->serverGeometry.border () * 2 - priv->serverInput.top - priv->serverInput.bottom;1862 height = ce->height + priv->serverGeometry.border () * 2 - priv->serverInput.top - priv->serverInput.bottom;
21261863
2127 /* set the frame geometry */1864 /* set the frame geometry */
2128 priv->frameGeometry.set (ce->x, ce->y, ce->width, ce->height, ce->border_width);1865 priv->frameGeometry.set (ce->x, ce->y, ce->width, ce->height, ce->border_width);
@@ -2131,7 +1868,7 @@
2131 if (priv->syncWait)1868 if (priv->syncWait)
2132 priv->syncGeometry.set (x, y, width, height, ce->border_width);1869 priv->syncGeometry.set (x, y, width, height, ce->border_width);
2133 else1870 else
2134 window->resize (x, y, width, height, ce->border_width);1871 resize (x, y, width, height, ce->border_width);
21351872
2136 if (priv->restack (ce->above))1873 if (priv->restack (ce->above))
2137 priv->updatePassiveButtonGrabs ();1874 priv->updatePassiveButtonGrabs ();
@@ -2140,27 +1877,6 @@
21401877
2141 if (above)1878 if (above)
2142 above->priv->updatePassiveButtonGrabs ();1879 above->priv->updatePassiveButtonGrabs ();
2143
2144 if (!pendingConfigures.pending ())
2145 {
2146 /* Tell plugins its ok to start doing stupid things again but
2147 * obviously FIXME */
2148 CompOption::Vector options;
2149 CompOption::Value v;
2150
2151 options.push_back (CompOption ("window", CompOption::TypeInt));
2152 v.set ((int) id);
2153 options.back ().set (v);
2154 options.push_back (CompOption ("active", CompOption::TypeInt));
2155 v.set ((int) 0);
2156 options.back ().set (v);
2157
2158 /* Notify other plugins that it is unsafe to change geometry or serverGeometry
2159 * FIXME: That API should not be accessible to plugins, this is a hack to avoid
2160 * breaking ABI */
2161
2162 screen->handleCompizEvent ("core", "lock_position", options);
2163 }
2164}1880}
21651881
2166void1882void
@@ -2183,23 +1899,34 @@
2183{1899{
2184 if (dx || dy)1900 if (dx || dy)
2185 {1901 {
2186 gettimeofday (&priv->lastGeometryUpdate, NULL);1902 XWindowChanges xwc = XWINDOWCHANGES_INIT;
21871903 unsigned int valueMask = CWX | CWY;
2188 /* Don't allow window movement to overwrite working geometries1904
2189 * last received from the server if we know there are pending1905 xwc.x = priv->serverGeometry.x () + dx;
2190 * ConfigureNotify events on this window. That's a clunky workaround1906 xwc.y = priv->serverGeometry.y () + dy;
2191 * and a FIXME in any case, however, until we can break the API1907
2192 * and remove CompWindow::move, this will need to be the case */1908 priv->nextMoveImmediate = immediate;
21931909
2194 if (!priv->pendingConfigures.pending ())1910 configureXWindow (valueMask, &xwc);
1911 }
1912}
1913
1914void
1915PrivateWindow::move (int dx,
1916 int dy,
1917 bool immediate)
1918{
1919 if (dx || dy)
1920 {
1921 priv->geometry.setX (priv->geometry.x () + dx);
1922 priv->geometry.setY (priv->geometry.y () + dy);
1923 priv->frameGeometry.setX (priv->frameGeometry.x () + dx);
1924 priv->frameGeometry.setY (priv->frameGeometry.y () + dy);
1925
1926 if (priv->attrib.override_redirect)
2195 {1927 {
2196 priv->geometry.setX (priv->geometry.x () + dx);1928 priv->serverGeometry = priv->geometry;
2197 priv->geometry.setY (priv->geometry.y () + dy);1929 priv->serverFrameGeometry = priv->frameGeometry;
2198 priv->frameGeometry.setX (priv->frameGeometry.x () + dx);
2199 priv->frameGeometry.setY (priv->frameGeometry.y () + dy);
2200
2201 priv->pendingPositionUpdates = true;
2202
2203 priv->region.translate (dx, dy);1930 priv->region.translate (dx, dy);
2204 priv->inputRegion.translate (dx, dy);1931 priv->inputRegion.translate (dx, dy);
2205 if (!priv->frameRegion.isEmpty ())1932 if (!priv->frameRegion.isEmpty ())
@@ -2207,19 +1934,7 @@
22071934
2208 priv->invisible = priv->isInvisible ();1935 priv->invisible = priv->isInvisible ();
22091936
2210 moveNotify (dx, dy, immediate);1937 window->moveNotify (dx, dy, true);
2211 }
2212 else
2213 {
2214 XWindowChanges xwc = XWINDOWCHANGES_INIT;
2215 unsigned int valueMask = CWX | CWY;
2216 compLogMessage ("core", CompLogLevelDebug, "pending configure notifies on 0x%x, "\
2217 "moving window asyncrhonously!", (unsigned int) priv->serverId);
2218
2219 xwc.x = priv->serverGeometry.x () + dx;
2220 xwc.y = priv->serverGeometry.y () + dy;
2221
2222 configureXWindow (valueMask, &xwc);
2223 }1938 }
2224 }1939 }
2225}1940}
@@ -2230,22 +1945,6 @@
2230 return !mEvents.empty ();1945 return !mEvents.empty ();
2231}1946}
22321947
2233bool
2234PrivateWindow::checkClear ()
2235{
2236 if (pendingConfigures.pending ())
2237 {
2238 /* FIXME: This is a hack to avoid performance regressions
2239 * and must be removed in 0.9.6 */
2240 compLogMessage ("core", CompLogLevelWarn, "failed to receive ConfigureNotify event on 0x%x\n",
2241 id);
2242 pendingConfigures.dump ();
2243 pendingConfigures.clear ();
2244 }
2245
2246 return false;
2247}
2248
2249void1948void
2250compiz::X11::PendingEventQueue::add (PendingEvent::Ptr p)1949compiz::X11::PendingEventQueue::add (PendingEvent::Ptr p)
2251{1950{
@@ -2280,9 +1979,9 @@
2280{1979{
2281 compiz::X11::PendingEvent::dump ();1980 compiz::X11::PendingEvent::dump ();
22821981
2283 compLogMessage ("core", CompLogLevelDebug, "- x: %i y: %i width: %i height: %i "\1982 compLogMessage ("core", CompLogLevelDebug, "- x: %i y: %i width: %i height: %i x2: %i y2 %i"\
2284 "border: %i, sibling: 0x%x",1983 "border: %i, sibling: 0x%x",
2285 mXwc.x, mXwc.y, mXwc.width, mXwc.height, mXwc.border_width, mXwc.sibling);1984 mXwc.x, mXwc.y, mXwc.width, mXwc.height, mXwc.x + mXwc.width, mXwc.y + mXwc.height, mXwc.border_width, mXwc.sibling);
2286}1985}
22871986
2288bool1987bool
@@ -2467,21 +2166,6 @@
2467 mValueMask (valueMask),2166 mValueMask (valueMask),
2468 mXwc (*xwc)2167 mXwc (*xwc)
2469{2168{
2470 CompOption::Vector options;
2471 CompOption::Value v;
2472
2473 options.push_back (CompOption ("window", CompOption::TypeInt));
2474 v.set ((int) w);
2475 options.back ().set (v);
2476 options.push_back (CompOption ("active", CompOption::TypeInt));
2477 v.set ((int) 1);
2478 options.back ().set (v);
2479
2480 /* Notify other plugins that it is unsafe to change geometry or serverGeometry
2481 * FIXME: That API should not be accessible to plugins, this is a hack to avoid
2482 * breaking ABI */
2483
2484 screen->handleCompizEvent ("core", "lock_position", options);
2485}2169}
24862170
2487compiz::X11::PendingConfigureEvent::~PendingConfigureEvent ()2171compiz::X11::PendingConfigureEvent::~PendingConfigureEvent ()
@@ -2491,57 +2175,6 @@
2491void2175void
2492CompWindow::syncPosition ()2176CompWindow::syncPosition ()
2493{2177{
2494 gettimeofday (&priv->lastConfigureRequest, NULL);
2495
2496 unsigned int valueMask = CWX | CWY;
2497 XWindowChanges xwc = XWINDOWCHANGES_INIT;
2498
2499 if (priv->pendingPositionUpdates && !priv->pendingConfigures.pending ())
2500 {
2501 if (priv->serverFrameGeometry.x () == priv->frameGeometry.x ())
2502 valueMask &= ~(CWX);
2503 if (priv->serverFrameGeometry.y () == priv->frameGeometry.y ())
2504 valueMask &= ~(CWY);
2505
2506 /* Because CompWindow::move can update the geometry last
2507 * received from the server, we must indicate that no values
2508 * changed, because when the ConfigureNotify comes around
2509 * the values are going to be the same. That's obviously
2510 * broken behaviour and worthy of a FIXME, but requires
2511 * larger changes to the window movement system. */
2512 if (valueMask)
2513 {
2514 priv->serverGeometry.setX (priv->geometry.x ());
2515 priv->serverGeometry.setY (priv->geometry.y ());
2516 priv->serverFrameGeometry.setX (priv->frameGeometry.x ());
2517 priv->serverFrameGeometry.setY (priv->frameGeometry.y ());
2518
2519 xwc.x = priv->serverFrameGeometry.x ();
2520 xwc.y = priv->serverFrameGeometry.y ();
2521
2522 compiz::X11::PendingEvent::Ptr pc =
2523 boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
2524 new compiz::X11::PendingConfigureEvent (
2525 screen->dpy (), priv->serverFrame, 0, &xwc)));
2526
2527 priv->pendingConfigures.add (pc);
2528
2529 /* Got 3 seconds to get its stuff together */
2530 if (priv->mClearCheckTimeout.active ())
2531 priv->mClearCheckTimeout.stop ();
2532 priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
2533 2000, 2500);
2534 XConfigureWindow (screen->dpy (), ROOTPARENT (this), valueMask, &xwc);
2535
2536 if (priv->serverFrame)
2537 {
2538 XMoveWindow (screen->dpy (), priv->wrapper,
2539 priv->serverInput.left, priv->serverInput.top);
2540 sendConfigureNotify ();
2541 }
2542 }
2543 priv->pendingPositionUpdates = false;
2544 }
2545}2178}
25462179
2547bool2180bool
@@ -3342,14 +2975,41 @@
3342{2975{
3343 unsigned int frameValueMask = 0;2976 unsigned int frameValueMask = 0;
33442977
3345 /* Immediately sync window position2978 if (id == screen->root ())
3346 * if plugins were updating w->geometry () directly2979 {
3347 * in order to avoid a race condition */2980 compLogMessage ("core", CompLogLevelWarn, "attempted to reconfigure root window");
33482981 return;
3349 window->syncPosition ();2982 }
33502983
3351 /* Remove redundant bits */2984 /* Remove redundant bits */
33522985
2986 xwc->x = valueMask & CWX ? xwc->x : serverGeometry.x ();
2987 xwc->y = valueMask & CWY ? xwc->y : serverGeometry.y ();
2988 xwc->width = valueMask & CWWidth ? xwc->width : serverGeometry.width ();
2989 xwc->height = valueMask & CWHeight ? xwc->height : serverGeometry.height ();
2990 xwc->border_width = valueMask & CWBorderWidth ? xwc->border_width : serverGeometry.border ();
2991
2992 /* Don't allow anything that might generate a BadValue */
2993 if (valueMask & CWWidth && !xwc->width)
2994 {
2995 compLogMessage ("core", CompLogLevelWarn, "Attempted to set < 1 width on a window");
2996 xwc->width = 1;
2997 }
2998
2999 if (valueMask & CWHeight && !xwc->height)
3000 {
3001 compLogMessage ("core", CompLogLevelWarn, "Attempted to set < 1 height on a window");
3002 xwc->height = 1;
3003 }
3004
3005 int dx = valueMask & CWX ? xwc->x - serverGeometry.x () : 0;
3006 int dy = valueMask & CWY ? xwc->y - serverGeometry.y () : 0;
3007 int dwidth = valueMask & CWWidth ? xwc->width - serverGeometry.width () : 0;
3008 int dheight = valueMask & CWHeight ? xwc->height - serverGeometry.height () : 0;
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 */
3353 if (valueMask & CWX && serverGeometry.x () == xwc->x)3013 if (valueMask & CWX && serverGeometry.x () == xwc->x)
3354 valueMask &= ~(CWX);3014 valueMask &= ~(CWX);
33553015
@@ -3416,18 +3076,15 @@
3416 compLogMessage ("core", CompLogLevelWarn, "restack_mode not Above");3076 compLogMessage ("core", CompLogLevelWarn, "restack_mode not Above");
3417 }3077 }
34183078
3419 frameValueMask = valueMask;3079 frameValueMask = CWX | CWY | CWWidth | CWHeight | (valueMask & (CWStackMode | CWSibling));
34203080
3421 if (frameValueMask & CWX &&3081 if (serverFrameGeometry.x () == xwc->x - serverGeometry.border () - serverInput.left)
3422 serverFrameGeometry.x () == xwc->x - serverGeometry.border () - serverInput.left)
3423 frameValueMask &= ~(CWX);3082 frameValueMask &= ~(CWX);
34243083
3425 if (frameValueMask & CWY &&3084 if (serverFrameGeometry.y () == xwc->y - serverGeometry.border () - serverInput.top)
3426 serverFrameGeometry.y () == xwc->y - serverGeometry.border () - serverInput.top)
3427 frameValueMask &= ~(CWY);3085 frameValueMask &= ~(CWY);
34283086
3429 if (frameValueMask & CWWidth &&3087 if (serverFrameGeometry.width () == xwc->width + serverGeometry.border () * 2
3430 serverFrameGeometry.width () == xwc->width + serverGeometry.border () * 2
3431 + serverInput.left + serverInput.right)3088 + serverInput.left + serverInput.right)
3432 frameValueMask &= ~(CWWidth);3089 frameValueMask &= ~(CWWidth);
34333090
@@ -3437,19 +3094,64 @@
34373094
3438 if (shaded)3095 if (shaded)
3439 {3096 {
3440 if (frameValueMask & CWHeight &&3097 if (serverFrameGeometry.height () == serverGeometry.border () * 2
3441 serverFrameGeometry.height () == serverGeometry.border () * 2
3442 + serverInput.top + serverInput.bottom)3098 + serverInput.top + serverInput.bottom)
3443 frameValueMask &= ~(CWHeight);3099 frameValueMask &= ~(CWHeight);
3444 }3100 }
3445 else3101 else
3446 {3102 {
3447 if (frameValueMask & CWHeight &&3103 if (serverFrameGeometry.height () == xwc->height + serverGeometry.border () * 2
3448 serverFrameGeometry.height () == xwc->height + serverGeometry.border () * 2
3449 + serverInput.top + serverInput.bottom)3104 + serverInput.top + serverInput.bottom)
3450 frameValueMask &= ~(CWHeight);3105 frameValueMask &= ~(CWHeight);
3451 }3106 }
34523107
3108
3109 if (valueMask & CWStackMode &&
3110 ((xwc->stack_mode != TopIf) && (xwc->stack_mode != BottomIf) && (xwc->stack_mode != Opposite) &&
3111 (xwc->stack_mode != Above) && (xwc->stack_mode != Below)))
3112 {
3113 compLogMessage ("core", CompLogLevelWarn, "Invalid stack mode %i", xwc->stack_mode);
3114 valueMask &= ~(CWStackMode | CWSibling);
3115 }
3116
3117 /* Don't allow anything that might cause a BadMatch error */
3118
3119 if (valueMask & CWSibling && !(valueMask & CWStackMode))
3120 {
3121 compLogMessage ("core", CompLogLevelWarn, "Didn't specify a CWStackMode for CWSibling");
3122 valueMask &= ~CWSibling;
3123 }
3124
3125 if (valueMask & CWSibling && xwc->sibling == (serverFrame ? serverFrame : id))
3126 {
3127 compLogMessage ("core", CompLogLevelWarn, "Can't restack a window relative to itself");
3128 valueMask &= ~CWSibling;
3129 }
3130
3131 if (valueMask & CWBorderWidth && attrib.c_class == InputOnly)
3132 {
3133 compLogMessage ("core", CompLogLevelWarn, "Cannot set border_width of an input_only window");
3134 valueMask &= ~CWBorderWidth;
3135 }
3136
3137 if (valueMask & CWSibling)
3138 {
3139 CompWindow *sibling = screen->findTopLevelWindow (xwc->sibling);
3140
3141 if (!sibling)
3142 {
3143 compLogMessage ("core", CompLogLevelWarn, "Attempted to restack relative to 0x%x which is "\
3144 "not a child of the root window or a window compiz owns", static_cast <unsigned int> (xwc->sibling));
3145 valueMask &= ~(CWSibling | CWStackMode);
3146 }
3147 else if (sibling->frame () && xwc->sibling != sibling->frame ())
3148 {
3149 compLogMessage ("core", CompLogLevelWarn, "Attempted to restack relative to 0x%x which is "\
3150 "not a child of the root window", static_cast <unsigned int> (xwc->sibling));
3151 valueMask &= ~(CWSibling | CWStackMode);
3152 }
3153 }
3154
3453 /* Can't set the border width of frame windows */3155 /* Can't set the border width of frame windows */
3454 frameValueMask &= ~(CWBorderWidth);3156 frameValueMask &= ~(CWBorderWidth);
34553157
@@ -3476,11 +3178,8 @@
3476 + serverInput.top + serverInput.bottom);3178 + serverInput.top + serverInput.bottom);
3477 }3179 }
34783180
3479
3480 if (serverFrame)3181 if (serverFrame)
3481 {3182 {
3482 gettimeofday (&lastConfigureRequest, NULL);
3483
3484 if (frameValueMask)3183 if (frameValueMask)
3485 {3184 {
3486 XWindowChanges wc = *xwc;3185 XWindowChanges wc = *xwc;
@@ -3496,13 +3195,10 @@
3496 screen->dpy (), priv->serverFrame, frameValueMask, &wc)));3195 screen->dpy (), priv->serverFrame, frameValueMask, &wc)));
34973196
3498 pendingConfigures.add (pc);3197 pendingConfigures.add (pc);
3499 if (priv->mClearCheckTimeout.active ())
3500 priv->mClearCheckTimeout.stop ();
3501 priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
3502 2000, 2500);
35033198
3504 XConfigureWindow (screen->dpy (), serverFrame, frameValueMask, &wc);3199 XConfigureWindow (screen->dpy (), serverFrame, frameValueMask, &wc);
3505 }3200 }
3201
3506 valueMask &= ~(CWSibling | CWStackMode);3202 valueMask &= ~(CWSibling | CWStackMode);
35073203
3508 /* If the frame has changed position (eg, serverInput.top3204 /* If the frame has changed position (eg, serverInput.top
@@ -3528,6 +3224,28 @@
35283224
3529 if (valueMask)3225 if (valueMask)
3530 XConfigureWindow (screen->dpy (), id, valueMask, xwc);3226 XConfigureWindow (screen->dpy (), id, valueMask, xwc);
3227
3228 if (!attrib.override_redirect)
3229 {
3230 if (valueMask & (CWWidth | CWHeight))
3231 {
3232 updateRegion ();
3233 window->resizeNotify (dx, dy, dwidth, dheight);
3234 }
3235 else if (valueMask & (CWX | CWY))
3236 {
3237 region.translate (dx, dy);
3238 inputRegion.translate (dx, dy);
3239 if (!frameRegion.isEmpty ())
3240 frameRegion.translate (dx, dy);
3241
3242 if (dx || dy)
3243 {
3244 window->moveNotify (dx, dy, priv->nextMoveImmediate);
3245 priv->nextMoveImmediate = true;
3246 }
3247 }
3248 }
3531}3249}
35323250
3533bool3251bool
@@ -4305,10 +4023,6 @@
4305 screen->dpy (), serverFrame, valueMask, &lxwc)));4023 screen->dpy (), serverFrame, valueMask, &lxwc)));
43064024
4307 pendingConfigures.add (pc);4025 pendingConfigures.add (pc);
4308 if (priv->mClearCheckTimeout.active ())
4309 priv->mClearCheckTimeout.stop ();
4310 priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
4311 2000, 2500);
4312 }4026 }
43134027
4314 /* Below with no sibling puts the window at the bottom4028 /* Below with no sibling puts the window at the bottom
@@ -4612,8 +4326,8 @@
4612PrivateWindow::ensureWindowVisibility ()4326PrivateWindow::ensureWindowVisibility ()
4613{4327{
4614 int x1, y1, x2, y2;4328 int x1, y1, x2, y2;
4615 int width = serverGeometry.width () + serverGeometry.border () * 2;4329 int width = serverGeometry.widthIncBorders ();
4616 int height = serverGeometry.height () + serverGeometry.border () * 2;4330 int height = serverGeometry.heightIncBorders ();
4617 int dx = 0;4331 int dx = 0;
4618 int dy = 0;4332 int dy = 0;
46194333
@@ -5473,10 +5187,10 @@
5473 }5187 }
5474 else5188 else
5475 {5189 {
5476 m = priv->geometry.x () + offX;5190 m = priv->serverGeometry.x () + offX;
5477 if (m - priv->input.left < (int) s->width () - vWidth)5191 if (m - priv->serverInput.left < (int) s->width () - vWidth)
5478 rv.setX (offX + vWidth);5192 rv.setX (offX + vWidth);
5479 else if (m + priv->width + priv->input.right > vWidth)5193 else if (m + priv->serverGeometry.width () + priv->serverInput.right > vWidth)
5480 rv.setX (offX - vWidth);5194 rv.setX (offX - vWidth);
5481 else5195 else
5482 rv.setX (offX);5196 rv.setX (offX);
@@ -5488,10 +5202,10 @@
5488 }5202 }
5489 else5203 else
5490 {5204 {
5491 m = priv->geometry.y () + offY;5205 m = priv->serverGeometry.y () + offY;
5492 if (m - priv->input.top < (int) s->height () - vHeight)5206 if (m - priv->serverInput.top < (int) s->height () - vHeight)
5493 rv.setY (offY + vHeight);5207 rv.setY (offY + vHeight);
5494 else if (m + priv->height + priv->input.bottom > vHeight)5208 else if (m + priv->serverGeometry.height () + priv->serverInput.bottom > vHeight)
5495 rv.setY (offY - vHeight);5209 rv.setY (offY - vHeight);
5496 else5210 else
5497 rv.setY (offY);5211 rv.setY (offY);
@@ -6014,8 +5728,8 @@
6014 y -= screen->vp ().y () * screen->height ();5728 y -= screen->vp ().y () * screen->height ();
6015 }5729 }
60165730
6017 tx = x - priv->geometry.x ();5731 tx = x - priv->serverGeometry.x ();
6018 ty = y - priv->geometry.y ();5732 ty = y - priv->serverGeometry.y ();
60195733
6020 if (tx || ty)5734 if (tx || ty)
6021 {5735 {
@@ -6037,21 +5751,21 @@
60375751
6038 if (screen->vpSize ().width ()!= 1)5752 if (screen->vpSize ().width ()!= 1)
6039 {5753 {
6040 m = priv->geometry.x () + tx;5754 m = priv->serverGeometry.x () + tx;
60415755
6042 if (m - priv->output.left < (int) screen->width () - vWidth)5756 if (m - priv->output.left < (int) screen->width () - vWidth)
6043 wx = tx + vWidth;5757 wx = tx + vWidth;
6044 else if (m + priv->width + priv->output.right > vWidth)5758 else if (m + priv->serverGeometry.width () + priv->output.right > vWidth)
6045 wx = tx - vWidth;5759 wx = tx - vWidth;
6046 }5760 }
60475761
6048 if (screen->vpSize ().height () != 1)5762 if (screen->vpSize ().height () != 1)
6049 {5763 {
6050 m = priv->geometry.y () + ty;5764 m = priv->serverGeometry.y () + ty;
60515765
6052 if (m - priv->output.top < (int) screen->height () - vHeight)5766 if (m - priv->output.top < (int) screen->height () - vHeight)
6053 wy = ty + vHeight;5767 wy = ty + vHeight;
6054 else if (m + priv->height + priv->output.bottom > vHeight)5768 else if (m + priv->serverGeometry.height () + priv->output.bottom > vHeight)
6055 wy = ty - vHeight;5769 wy = ty - vHeight;
6056 }5770 }
60575771
@@ -6206,8 +5920,8 @@
6206 svp = screen->vp ();5920 svp = screen->vp ();
6207 size = *screen;5921 size = *screen;
62085922
6209 x = window->geometry ().x () + (svp.x () - vp.x ()) * size.width ();5923 x = window->serverGeometry ().x () + (svp.x () - vp.x ()) * size.width ();
6210 y = window->geometry ().y () + (svp.y () - vp.y ()) * size.height ();5924 y = window->serverGeometry ().y () + (svp.y () - vp.y ()) * size.height ();
6211 window->moveToViewportPosition (x, y, true);5925 window->moveToViewportPosition (x, y, true);
62125926
6213 if (allowWindowFocus (0, timestamp))5927 if (allowWindowFocus (0, timestamp))
@@ -6276,9 +5990,6 @@
6276 priv->serverFrameGeometry = priv->frameGeometry = priv->syncGeometry5990 priv->serverFrameGeometry = priv->frameGeometry = priv->syncGeometry
6277 = priv->geometry = priv->serverGeometry;5991 = priv->geometry = priv->serverGeometry;
62785992
6279 priv->width = priv->attrib.width + priv->attrib.border_width * 2;
6280 priv->height = priv->attrib.height + priv->attrib.border_width * 2;
6281
6282 priv->sizeHints.flags = 0;5993 priv->sizeHints.flags = 0;
62835994
6284 priv->recalcNormalHints ();5995 priv->recalcNormalHints ();
@@ -6300,8 +6011,7 @@
63006011
6301 if (priv->attrib.c_class != InputOnly)6012 if (priv->attrib.c_class != InputOnly)
6302 {6013 {
6303 priv->region = CompRegion (priv->attrib.x, priv->attrib.y,6014 priv->region = CompRegion (priv->serverGeometry);
6304 priv->width, priv->height);
6305 priv->inputRegion = priv->region;6015 priv->inputRegion = priv->region;
63066016
6307 /* need to check for DisplayModal state on all windows */6017 /* need to check for DisplayModal state on all windows */
@@ -6531,8 +6241,6 @@
6531 hints (NULL),6241 hints (NULL),
6532 inputHint (true),6242 inputHint (true),
6533 alpha (false),6243 alpha (false),
6534 width (0),
6535 height (0),
6536 region (),6244 region (),
6537 wmType (0),6245 wmType (0),
6538 type (CompWindowTypeUnknownMask),6246 type (CompWindowTypeUnknownMask),
@@ -6567,7 +6275,6 @@
6567 pendingUnmaps (0),6275 pendingUnmaps (0),
6568 pendingMaps (0),6276 pendingMaps (0),
6569 pendingConfigures (screen->dpy ()),6277 pendingConfigures (screen->dpy ()),
6570 pendingPositionUpdates (false),
65716278
6572 startupId (0),6279 startupId (0),
6573 resName (0),6280 resName (0),
@@ -6745,14 +6452,12 @@
6745void6452void
6746CompWindow::updateFrameRegion ()6453CompWindow::updateFrameRegion ()
6747{6454{
6748 if (priv->serverFrame &&6455 if (priv->serverFrame)
6749 priv->serverGeometry.width () == priv->geometry.width () &&
6750 priv->serverGeometry.height () == priv->geometry.height ())
6751 {6456 {
6752 CompRect r;6457 CompRect r;
6753 int x, y;6458 int x, y;
67546459
6755 priv->frameRegion = CompRegion ();6460 priv->frameRegion = emptyRegion;
67566461
6757 updateFrameRegion (priv->frameRegion);6462 updateFrameRegion (priv->frameRegion);
67586463
@@ -6761,16 +6466,16 @@
6761 r = priv->region.boundingRect ();6466 r = priv->region.boundingRect ();
6762 priv->frameRegion -= r;6467 priv->frameRegion -= r;
67636468
6764 r.setGeometry (r.x1 () - priv->input.left,6469 r.setGeometry (r.x1 () - priv->serverInput.left,
6765 r.y1 () - priv->input.top,6470 r.y1 () - priv->serverInput.top,
6766 r.width () + priv->input.right + priv->input.left,6471 r.width () + priv->serverInput.right + priv->serverInput.left,
6767 r.height () + priv->input.bottom + priv->input.top);6472 r.height () + priv->serverInput.bottom + priv->serverInput.top);
67686473
6769 priv->frameRegion &= CompRegion (r);6474 priv->frameRegion &= CompRegion (r);
6770 }6475 }
67716476
6772 x = priv->geometry.x () - priv->input.left;6477 x = priv->serverGeometry.x () - priv->serverInput.left;
6773 y = priv->geometry.y () - priv->input.top;6478 y = priv->serverGeometry.y () - priv->serverInput.top;
67746479
6775 XShapeCombineRegion (screen->dpy (), priv->serverFrame,6480 XShapeCombineRegion (screen->dpy (), priv->serverFrame,
6776 ShapeBounding, -x, -y,6481 ShapeBounding, -x, -y,
@@ -6788,6 +6493,10 @@
6788CompWindow::setWindowFrameExtents (CompWindowExtents *b,6493CompWindow::setWindowFrameExtents (CompWindowExtents *b,
6789 CompWindowExtents *i)6494 CompWindowExtents *i)
6790{6495{
6496 /* override redirect windows can't have frame extents */
6497 if (priv->attrib.override_redirect)
6498 return;
6499
6791 /* Input extents are used for frame size,6500 /* Input extents are used for frame size,
6792 * Border extents used for placement.6501 * Border extents used for placement.
6793 */6502 */
@@ -6811,6 +6520,11 @@
68116520
6812 priv->updateSize ();6521 priv->updateSize ();
6813 priv->updateFrameWindow ();6522 priv->updateFrameWindow ();
6523
6524 /* Always send a moveNotify
6525 * whenever the frame extents update
6526 * so that plugins can re-position appropriately */
6527 moveNotify (0, 0, true);
6814 }6528 }
68156529
6816 /* Use b for _NET_WM_FRAME_EXTENTS here because6530 /* Use b for _NET_WM_FRAME_EXTENTS here because
@@ -7094,10 +6808,10 @@
7094 /* Wait for the reparent to finish */6808 /* Wait for the reparent to finish */
7095 XSync (dpy, false);6809 XSync (dpy, false);
70966810
7097 xwc.x = serverGeometry.x () - serverGeometry.border ();6811 xwc.x = serverGeometry.xMinusBorder ();
7098 xwc.y = serverGeometry.y () - serverGeometry.border ();6812 xwc.y = serverGeometry.yMinusBorder ();
7099 xwc.width = serverGeometry.width () + serverGeometry.border () * 2;6813 xwc.width = serverGeometry.widthIncBorders ();
7100 xwc.height = serverGeometry.height () + serverGeometry.border () * 2;6814 xwc.height = serverGeometry.heightIncBorders ();
71016815
7102 XConfigureWindow (dpy, serverFrame, CWX | CWY | CWWidth | CWHeight, &xwc);6816 XConfigureWindow (dpy, serverFrame, CWX | CWY | CWWidth | CWHeight, &xwc);
71036817
@@ -7171,7 +6885,6 @@
7171 XDestroyWindow (screen->dpy (), serverFrame);6885 XDestroyWindow (screen->dpy (), serverFrame);
7172 XDestroyWindow (screen->dpy (), wrapper);6886 XDestroyWindow (screen->dpy (), wrapper);
71736887
7174 window->windowNotify (CompWindowNotifyUnreparent);
7175 /* This window is no longer "managed" in the6888 /* This window is no longer "managed" in the
7176 * reparenting sense so clear its pending event6889 * reparenting sense so clear its pending event
7177 * queue ... though maybe in future it would6890 * queue ... though maybe in future it would
@@ -7182,4 +6895,7 @@
7182 frame = None;6895 frame = None;
7183 wrapper = None;6896 wrapper = None;
7184 serverFrame = None;6897 serverFrame = None;
6898
6899 // Finally, (i.e. after updating state) notify the change
6900 window->windowNotify (CompWindowNotifyUnreparent);
7185}6901}
71866902
=== modified file 'src/window/geometry/include/core/windowgeometry.h'
--- src/window/geometry/include/core/windowgeometry.h 2012-01-19 20:08:32 +0000
+++ src/window/geometry/include/core/windowgeometry.h 2012-04-17 08:08:21 +0000
@@ -64,6 +64,12 @@
64 compiz::window::Geometry change (const compiz::window::Geometry &g, unsigned int mask) const;64 compiz::window::Geometry change (const compiz::window::Geometry &g, unsigned int mask) const;
65 void applyChange (const compiz::window::Geometry &g, unsigned int mask);65 void applyChange (const compiz::window::Geometry &g, unsigned int mask);
6666
67 int xMinusBorder () const { return x () - mBorder; }
68 int yMinusBorder () const { return y () - mBorder; }
69
70 unsigned int widthIncBorders () const { return width () + mBorder * 2; }
71 unsigned int heightIncBorders () const { return height () + mBorder * 2; }
72
67private:73private:
68 int mBorder;74 int mBorder;
69};75};
7076
=== modified file 'src/window/geometry/tests/window-geometry/src/test-window-geometry.cpp'
--- src/window/geometry/tests/window-geometry/src/test-window-geometry.cpp 2012-03-30 16:30:13 +0000
+++ src/window/geometry/tests/window-geometry/src/test-window-geometry.cpp 2012-04-17 08:08:21 +0000
@@ -87,3 +87,13 @@
87 EXPECT_EQ (rg, compiz::window::Geometry (49, 99, 199, 299, 5));87 EXPECT_EQ (rg, compiz::window::Geometry (49, 99, 199, 299, 5));
88 EXPECT_EQ (mask, CHANGE_X | CHANGE_Y | CHANGE_WIDTH | CHANGE_HEIGHT);88 EXPECT_EQ (mask, CHANGE_X | CHANGE_Y | CHANGE_WIDTH | CHANGE_HEIGHT);
89}89}
90
91TEST_F(CompWindowGeometryTestGeometry, TestBorders)
92{
93 compiz::window::Geometry g (1, 1, 1, 1, 1);
94
95 EXPECT_EQ (g.xMinusBorder (), 0);
96 EXPECT_EQ (g.yMinusBorder (), 0);
97 EXPECT_EQ (g.widthIncBorders (), 3);
98 EXPECT_EQ (g.heightIncBorders (), 3);
99}
90100
=== modified file 'src/windowgeometry.cpp'
--- src/windowgeometry.cpp 2012-01-23 05:44:19 +0000
+++ src/windowgeometry.cpp 2012-04-17 08:08:21 +0000
@@ -61,22 +61,19 @@
61int61int
62CompWindow::width () const62CompWindow::width () const
63{63{
64 return priv->width +64 return priv->geometry.widthIncBorders ();
65 priv->geometry.border () * 2;
66}65}
6766
68int67int
69CompWindow::height () const68CompWindow::height () const
70{69{
71 return priv->height +70 return priv->geometry.heightIncBorders ();
72 priv->geometry.border () * 2;;
73}71}
7472
75CompSize73CompSize
76CompWindow::size () const74CompWindow::size () const
77{75{
78 return CompSize (priv->width + priv->geometry.border () * 2,76 return CompSize (width (), height ());
79 priv->height + priv->geometry.border () * 2);
80}77}
8178
82int79int
@@ -102,88 +99,84 @@
102int99int
103CompWindow::serverWidth () const100CompWindow::serverWidth () const
104{101{
105 return priv->serverGeometry.width () +102 return priv->serverGeometry.widthIncBorders ();
106 2 * priv->serverGeometry.border ();
107}103}
108104
109int105int
110CompWindow::serverHeight () const106CompWindow::serverHeight () const
111{107{
112 return priv->serverGeometry.height () +108 return priv->serverGeometry.heightIncBorders ();
113 2 * priv->serverGeometry.border ();
114}109}
115110
116const CompSize111const CompSize
117CompWindow::serverSize () const112CompWindow::serverSize () const
118{113{
119 return CompSize (priv->serverGeometry.width () +114 return CompSize (priv->serverGeometry.widthIncBorders (),
120 2 * priv->serverGeometry.border (),115 priv->serverGeometry.heightIncBorders ());
121 priv->serverGeometry.height () +
122 2 * priv->serverGeometry.border ());
123}116}
124117
125CompRect118CompRect
126CompWindow::borderRect () const119CompWindow::borderRect () const
127{120{
128 return CompRect (priv->geometry.x () - priv->geometry.border () - priv->border.left,121 return CompRect (priv->geometry.xMinusBorder () - priv->border.left,
129 priv->geometry.y () - priv->geometry.border () - priv->border.top,122 priv->geometry.yMinusBorder () - priv->border.top,
130 priv->geometry.width () + priv->geometry.border () * 2 +123 priv->geometry.widthIncBorders () +
131 priv->border.left + priv->border.right,124 priv->border.left + priv->border.right,
132 priv->geometry.height () + priv->geometry.border () * 2 +125 priv->geometry.heightIncBorders () +
133 priv->border.top + priv->border.bottom);126 priv->border.top + priv->border.bottom);
134}127}
135128
136CompRect129CompRect
137CompWindow::serverBorderRect () const130CompWindow::serverBorderRect () const
138{131{
139 return CompRect (priv->serverGeometry.x () - priv->geometry.border () - priv->border.left,132 return CompRect (priv->serverGeometry.xMinusBorder () - priv->border.left,
140 priv->serverGeometry.y () - priv->geometry.border () - priv->border.top,133 priv->serverGeometry.yMinusBorder () - priv->border.top,
141 priv->serverGeometry.width () + priv->geometry.border () * 2 +134 priv->serverGeometry.widthIncBorders () +
142 priv->border.left + priv->border.right,135 priv->border.left + priv->border.right,
143 priv->serverGeometry.height () + priv->geometry.border () * 2 +136 priv->serverGeometry.heightIncBorders() +
144 priv->border.top + priv->border.bottom);137 priv->border.top + priv->border.bottom);
145}138}
146139
147CompRect140CompRect
148CompWindow::inputRect () const141CompWindow::inputRect () const
149{142{
150 return CompRect (priv->geometry.x () - priv->geometry.border () - priv->serverInput.left,143 return CompRect (priv->geometry.xMinusBorder () - priv->serverInput.left,
151 priv->geometry.y () - priv->geometry.border () - priv->serverInput.top,144 priv->geometry.yMinusBorder () - priv->serverInput.top,
152 priv->geometry.width () + priv->geometry.border () * 2 +145 priv->geometry.widthIncBorders () +
153 priv->serverInput.left + priv->serverInput.right,146 priv->serverInput.left + priv->serverInput.right,
154 priv->geometry.height () +priv->geometry.border () * 2 +147 priv->geometry.heightIncBorders () +
155 priv->serverInput.top + priv->serverInput.bottom);148 priv->serverInput.top + priv->serverInput.bottom);
156}149}
157150
158CompRect151CompRect
159CompWindow::serverInputRect () const152CompWindow::serverInputRect () const
160{153{
161 return CompRect (priv->serverGeometry.x () - priv->serverGeometry.border () - priv->serverInput.left,154 return CompRect (priv->serverGeometry.xMinusBorder () - priv->serverInput.left,
162 priv->serverGeometry.y () - priv->serverGeometry.border () - priv->serverInput.top,155 priv->serverGeometry.yMinusBorder () - priv->serverInput.top,
163 priv->serverGeometry.width () + priv->serverGeometry.border () * 2 +156 priv->serverGeometry.widthIncBorders () +
164 priv->serverInput.left + priv->serverInput.right,157 priv->serverInput.left + priv->serverInput.right,
165 priv->serverGeometry.height () + priv->serverGeometry.border () * 2 +158 priv->serverGeometry.heightIncBorders () +
166 priv->serverInput.top + priv->serverInput.bottom);159 priv->serverInput.top + priv->serverInput.bottom);
167}160}
168161
169CompRect162CompRect
170CompWindow::outputRect () const163CompWindow::outputRect () const
171{164{
172 return CompRect (priv->geometry.x () - priv->serverGeometry.border ()- priv->output.left,165 return CompRect (priv->geometry.xMinusBorder ()- priv->output.left,
173 priv->geometry.y () - priv->serverGeometry.border () - priv->output.top,166 priv->geometry.yMinusBorder () - priv->output.top,
174 priv->geometry.width () + priv->serverGeometry.border () * 2 +167 priv->geometry.widthIncBorders () +
175 priv->output.left + priv->output.right,168 priv->output.left + priv->output.right,
176 priv->geometry.height () + priv->serverGeometry.border () * 2 +169 priv->geometry.heightIncBorders () +
177 priv->output.top + priv->output.bottom);170 priv->output.top + priv->output.bottom);
178}171}
179172
180CompRect173CompRect
181CompWindow::serverOutputRect () const174CompWindow::serverOutputRect () const
182{175{
183 return CompRect (priv->serverGeometry.x () - priv->serverGeometry.border () - priv->output.left,176 return CompRect (priv->serverGeometry.xMinusBorder () - priv->output.left,
184 priv->serverGeometry.y () - priv->serverGeometry.border () - priv->output.top,177 priv->serverGeometry.yMinusBorder () - priv->output.top,
185 priv->serverGeometry.width () + priv->serverGeometry.border () * 2 +178 priv->serverGeometry.widthIncBorders () +
186 priv->output.left + priv->output.right,179 priv->output.left + priv->output.right,
187 priv->serverGeometry.height () + priv->serverGeometry.border () * 2 +180 priv->serverGeometry.heightIncBorders () +
188 priv->output.top + priv->output.bottom);181 priv->output.top + priv->output.bottom);
189}182}

Subscribers

People subscribed via source and target branches