Merge lp:~smspillaz/compiz-core/fix-893467 into lp:compiz-core/0.9.5

Proposed by Sam Spilsbury
Status: Rejected
Rejected by: Sam Spilsbury
Proposed branch: lp:~smspillaz/compiz-core/fix-893467
Merge into: lp:compiz-core/0.9.5
Prerequisite: lp:~smspillaz/compiz-core/fix-POTfile-893995
Diff against target: 3374 lines (+1052/-787)
26 files modified
include/core/core.h (+0/-1)
include/core/screen.h (+2/-2)
include/core/window.h (+72/-45)
plugins/compiztoolbox/src/compiztoolbox.cpp (+7/-7)
plugins/composite/include/composite/composite.h (+22/-7)
plugins/composite/src/privates.h (+5/-0)
plugins/composite/src/screen.cpp (+2/-2)
plugins/composite/src/window.cpp (+51/-12)
plugins/decor/src/decor.cpp (+19/-22)
plugins/move/src/move.cpp (+33/-25)
plugins/move/src/move.h (+4/-0)
plugins/opengl/src/paint.cpp (+20/-9)
plugins/opengl/src/privates.h (+2/-1)
plugins/opengl/src/window.cpp (+35/-12)
plugins/place/src/place.cpp (+8/-46)
plugins/resize/src/resize.cpp (+27/-36)
plugins/rotate/src/rotate.cpp (+5/-6)
plugins/switcher/src/switcher.cpp (+22/-12)
plugins/water/src/water.cpp (+1/-1)
plugins/wobbly/src/wobbly.cpp (+125/-29)
plugins/wobbly/src/wobbly.h (+45/-5)
src/event.cpp (+30/-47)
src/privatewindow.h (+33/-11)
src/screen.cpp (+5/-5)
src/window.cpp (+428/-437)
src/windowgeometry.cpp (+49/-7)
To merge this branch: bzr merge lp:~smspillaz/compiz-core/fix-893467
Reviewer Review Type Date Requested Status
Daniel van Vugt Needs Fixing
Alan Griffiths Needs Fixing
Thomi Richards (community) Needs Fixing
Review via email: mp+84054@code.launchpad.net

Description of the change

Rework window positioning API somewhat.

CompWindow::position () makes a request to change the server side position of the window
CompositeWindow::applyOffset () applies a real-time paint-offset to that window, so that plugins can "immediately" update the window position without the server round-trip, but this offset will be reset to 0,0 as soon as there is a successful request to the server to change the position of the window (and the last-sent-to-server position will be used in that case).

This branch updates window display matrices immediately. It works for the time-being, but this solution probably won't work out in the long-term so maybe it would be better to use a proper transformation matrix like global paint offsets in the cube, expo and wall plugins do it. Eg, in the cube and wall plugins, wrapping around the last viewport to the first will result in the window going off-screen.

Moved CompWindow::Geometry into its own namesapce (compiz::window::Geometry)

CompWindow::geometry () and CompWindow::serverGeometry () are no longer directly mutable by plugins, these MUST be updated through CompWindow::position.

In the plugins, the dependency on X in order to change a window position at least is now removed - all change requests are done through compiz::window::Geometry - in order to do relative changes, we have:

 * compiz::window::Geometry::changeMask (const compiz::window::Geometry &old) which returns a bitmask of which values have changed from the current and the old geometry.

 * compiz::window::Geometry::applyChange (const compiz::window::Geometry &new, unsigned int mask) which copies only the marked bits from the new geometry to the current geometry object.

  -> This replaces lines of code like, eg:

     XWindowChanges xwc;
     unsigned int mask = CWX | CWY;

     xwc.x = foo;
     xwc.y = bar;

     w->configureXWindow (mask, &xwc);

  With:

     compiz::window::Geometry ng;
     compiz::window::Geometry send = w->serverGeometry ();
     ng.setX (foo);
     ng.setY (bar);

     send.applyChange (ng, CHANGE_X | CHANGE_Y);

     w->position (ng);

CompWindow::resize, CompWindow::move immediately update the local position of the window, bypassing the position sent by the server. Exposing this API in the base has historically caused problems because of race conditions with the server. They are now moved to PrivateWindow and plugins should use CompWindow::position in order to update the *real* position of the window by making a request to the server, or CompositeWindow::applyOffset in order to apply an offset from the real position without the overhead of making the server request.

CompWindow::configureXWindow bypassed constrainment and other rules that could be enforced by plugins and encoraged a system where plugins were fighting each other over window positions. That has now been removed - constrainment is enforced by specifying which constrainment flags are relevant in CompWidnow::position.

CompWindow::moveResize was only really relevant to resize requests by application so it was moved to PrivateWindow.

CompWindow::validateResizeRequest duplicates the existing functionality provided by CompWindow::position in terms of allowing other plugins to modify what the sent position will be before it actually gets sent. As such, it was also removed.

CompWindow::syncPosition was a hack to switch between synchronous and asynchronous operation and was removed. Related hacks to make this work were removed.

In the OpenGL plugin, we are now using the position last sent to the server in order to update display matrices and paint regions. The visible update should always be immediate whenever a new request is sent to the server - slow server implementations or slow servers could cause visible glitches as the server is "catching up". Similarly in core, the exact nonrectangular region of the window is translated immediately on calls to ::position (), but the actual shape of the region (apart from its translation) is updated when the server-side geometry comes back to us since that requires a server round-trip to fetch, and if you did it on send and receive, that would be two round-trips.

In the move plugin we're no longer writing directly to the geometry of the window in order to get "immediate" movement, instead using the composite plugin's paint offsets and CompWindow::position to send the position of the window to the server as soon as the user ungrabs the window.

As a proof of concept for this system to work across all other plugins, the wobbly plugin was ported to use this new system, as it is arguably the most complex plugin which depends on position updates.

 -> CompositedPositionTracker is class to track the visible position of the window on screen, as it takes any new applied offsets and position updates and then updates the models after events are handled as to the new position of the window.

 -> Damage regions were updated to make use of the paint offsets.

Stuff that doesn't work with this branch:

 -> The cube and rotate plugins

Next in pipeline: lp:~smspillaz/compiz-core/fix-timer-warnings-893998
 -> The decor plugin

To post a comment you must log in.
Revision history for this message
Sam Spilsbury (smspillaz) wrote :

Rework window positioning API somewhat.

CompWindow::position () makes a request to change the server side position of the window
CompositeWindow::applyOffset () applies a real-time paint-offset to that window, so that plugins can "immediately" update the window position without the server round-trip, but this offset will be reset to 0,0 as soon as there is a successful request to the server to change the position of the window (and the last-sent-to-server position will be used in that case).

This branch updates window display matrices immediately. It works for the time-being, but this solution probably won't work out in the long-term so maybe it would be better to use a proper transformation matrix like global paint offsets in the cube, expo and wall plugins do it.

lp:~smspillaz/compiz-core/fix-893467 updated
2898. By Sam Spilsbury

Fix typo

2899. By Sam Spilsbury

Specify parameter names in the public API

2900. By Sam Spilsbury

Cleanup - don't prematurely pessimize, const correctness etc.

2901. By Sam Spilsbury

Merged fix-POTfile-893995 into fix-893467.

Revision history for this message
Thomi Richards (thomir-deactivatedaccount) wrote :

Hi,

A few notes:

First, I'm not qualified to ensure that your changes actually do what they're supposed to - I know next to nothing about Compiz, and, to be honest, the sight of the compiz code fills me with trepidation. What I *can* do is check for stylistic consistency, and point out any places in the public API where I feel a comment or two would help. My point is that we really need to get someone else who understands compiz to look at these branches.

window.h:
 * ln 219 - comments above preprocessor macros need to be Doxygen-style comments, like the others on the lines above.

 * In your Geometry class, the border() and setBorder() methods should be declared next to each other.

 * The unit tests for this class need to be landed as part of this merge, not later in the pipeline.

As a general rule, #defining things makes me nervous, but it's obviously the "compiz way", so you'd better stick with the established coding standards. I'm nervous because #define ignores all scoping rules.

composite.h:
 * ln 318 - need comment.
 * is it called positionOffset or paintOffset? The comment and the method name should be the same, whichever you pick.

privates.h:
 * ln 125 - need comment.

move.cpp:
 * ln 451 - don't comment out code - delete it. This looks especially odd when compared to the previous revision.

privatewindow.h:
 * ln 82 - it's not obvious to me what the difference is between configureXWindow and reconfigureXWindow - perhaps a comment explaining what the difference is?

That's it!

review: Needs Fixing
lp:~smspillaz/compiz-core/fix-893467 updated
2902. By Sam Spilsbury

Cleanup

2903. By Sam Spilsbury

Fix merge error

2904. By Sam Spilsbury

Merged fix-POTfile-893995 into fix-893467.

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

Sam - It looks like this might indeed fix bug 764330. Can you reproduce bug 764330 to verify?

Also, please try to spend more time searching existing bugs to identify the bugs you are fixing. It creates a bit of a mess when you regularly fix bugs but don't know which existing bugs you're fixing, so the bug records never get updated, and users are not aware their bugs are getting fixed.

lp:~smspillaz/compiz-core/fix-893467 updated
2905. By Sam Spilsbury

Merged fix-POTfile-893995 into fix-893467.

2906. By Sam Spilsbury

Merged fix-POTfile-893995 into fix-893467.

2907. By Sam Spilsbury

Merged fix-POTfile-893995 into fix-893467.

2908. By Sam Spilsbury

Merged fix-POTfile-893995 into fix-893467.

2909. By Sam Spilsbury

Merged fix-POTfile-893995 into fix-893467.

2910. By Sam Spilsbury

Merged fix-POTfile-893995 into fix-893467.

2911. By Sam Spilsbury

Merge

2912. By Sam Spilsbury

Merged fix-POTfile-893995 into fix-893467.

2913. By Sam Spilsbury

Merged fix-POTfile-893995 into fix-893467.

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :
Download full text (3.5 KiB)

tests
  o are there no unit, integration or systems tests for any of this?

window.cpp
  o there are unnecessary c-style casts in expressions like:
     2625 + if (!(changeMask & CHANGE_WIDTH) && (int) old.width () < sizeHints.min_width)
     2635 + if (!(changeMask & CHANGE_WIDTH) && (int) old.width () > sizeHints.max_width)
     2645 + if (!(changeMask & CHANGE_HEIGHT) && (int) old.height () < sizeHints.min_height)
     2655 + if (!(changeMask & CHANGE_HEIGHT) && (int) old.height () > sizeHints.max_height)

    (width() & height() return an int - and static_cast would be the way)

  o Comments are a poor substitute for version control. Vis:

     3011 +/*
     3012 + if (!(changeMask & CWX))
     3013 + xwc->x = serverGeometry.x ();
     3014 + if (!(changeMask & CWY))
     3015 + xwc->y = serverGeometry.y ();
     3016 + if (!(changeMask & CWWidth))
     3017 + xwc->width = serverGeometry.width ();
     3018 + if (!(changeMask & CWHeight))
     3019 + xwc->height = serverGeometry.height ();
     3020 +*/
     ...
     3068 +/* XXX: Is there a reason why this needs to be here ?
     3069 + xwcm |= addWindowSizeChanges (xwc, Geometry (xwc->x, xwc->y,
     3070 xwc->width, xwc->height,
     3071 xwc->border_width));
     3072 +*/

  o Is there a significance to the "/* XXX ..." comments in the code?

window.h

  o defining constants like this...

     110 +#define CHANGE_X 1 << 0
     111 +#define CHANGE_Y 1 << 1
     112 +#define CHANGE_WIDTH 1 << 2
     113 +#define CHANGE_HEIGHT 1 << 3
     114 +#define CHANGE_BORDER 1 << 4

    ...is dangerous - there are operators (e.g. +) that bind tighter that <<.

    That's why macros like this should be in parentheses. Anyway, enums are better. Vis:

    enum ChangeMask {
        CHANGE_X = 1 << 0,
        CHANGE_Y = 1 << 1,
        CHANGE_WIDTH = 1 << 2,
        CHANGE_HEIGHT = 1 << 3,
        CHANGE_BORDER = 1 << 4
    };

    (Although stylistically UPPERCASE is usually reserved for preprocessor macros.)

    This would allow

      - unsigned int changeMask (const compiz::window::Geometry &g) const;
      + ChangeMask changeMask (const Geometry &g) const;

namespaces

  o namespaces are used intermittently and inconsistently - they should be consistent.

     $ grep namespace `find ../include/ -name \*.h`
     ../include/core/window.h:namespace compiz
     ../include/core/window.h:namespace window
     ../include/core/atoms.h:namespace Atoms {
     ../include/core/session.h:namespace CompSession {

    (The change introduces ::compiz::window.)

  o it isn't necessary to explicitly specify namespaces when in the namespace:

      unsigned int changeMask (const compiz::window::Geometry &g) const;
                                     ----------------

  o when accessing a load of stuff from the same namespace a namespace alias is convenient. Vis:

      namespace cw = compiz::window;

  o when using few things from a namespace a using directive may help. Vis:

      using compiz::window::Geometry;

~~~~~~~
STUFF NOT IN CHANGE

class PrivateWindow

  o is a struct with lots of member functions - bad existing design
  o Ought to be n...

Read more...

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

It sounds to me like the design is fundamentally wrong. It's fixing a race condition by intentionally introducing a (controlled) race condition:

"CompWindow::position () makes a request to change the server side position of the window
CompositeWindow::applyOffset () applies a real-time paint-offset to that window, so that plugins can "immediately" update the window position without the server round-trip,"

One thing a window decorator/manager should never do is to make any assumption about window position or size before it comes from the server. You must wait for the round trip before updating your local copy of the position/size info. This also has the potential to make other similar bugs like but 803296 worse, and introduce yet more position/resize regressions.

On a different note about the macros;
  #define CHANGE_X 1 << 0
should at the very least be protected from operator precedence rules with parentheses:
  #define CHANGE_X (1 << 0)
but an enum is even better, because the symbol then becomes a debug symbol too.

Alan... please try to discuss the style problems elsewhere. Because they are not specific to just this proposal and apply to all the compiz code in general.

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

That all said, I am willing to accept these changes even if just the macros get fixed. Because Sam's code is now so different with so many changes, that I feel the only way forward is to accept all his changes. Then we may resync our branches and can more easily test what is actually broken.

However it all comes back to a fundamental problem, which I complain to Sam about regularly. That is his changes are too large for people to be able to review and test them easily. Which of course slows everyone down. Proposals either don't get reviewed or they get inadequately reviewed for their complexity, leading to compiz regressions.

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

>
> One thing a window decorator/manager should never do is to make any assumption
> about window position or size before it comes from the server. You must wait
> for the round trip before updating your local copy of the position/size info.
> This also has the potential to make other similar bugs like but 803296 worse,
> and introduce yet more position/resize regressions.

Indeed, however waiting for the server is actually really slow. I've tried forcing a situation where the paint position is only updated on server position changes and window movement is really "jerky". Using the paint offsets is not much better either, but its a lot better than what we had previously, where plugins would implicitly clobber the last received server position in order to immediately update the position of the window. At least with this design, the plugins explicitly know that there is an "offset" from the real server position, rather than playing guesswork around the other plugins. In addition, CompWindow::move would be called both when the plugins want to update the drawn position of the window and when the server side position is changed, which means that the move handlers for the plugins were getting called twice.

>
> On a different note about the macros;
> #define CHANGE_X 1 << 0
> should at the very least be protected from operator precedence rules with
> parentheses:
> #define CHANGE_X (1 << 0)
> but an enum is even better, because the symbol then becomes a debug symbol
> too.
>
> Alan... please try to discuss the style problems elsewhere. Because they are
> not specific to just this proposal and apply to all the compiz code in
> general.

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

According to my own testing and the testing of everyone who has commented in bug 764330, it's not slow at all. In fact, it's really fast which is the point. FYI, "waiting for the server" does not mean to block. It simply means tell the server where to move the window and then forget about it till you get the events telling you the move is finished.

See lines 47-64 of:
https://code.launchpad.net/~vanvugt/compiz-core/fix-764330-trunk/+merge/86497

But if your approach is just as fast, then that's good too.

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

As far as I can tell from that code, the painted position isn't going to be changed until the configure event comes back from the server. In the case where the sever is operating slowly, that means that movement is going to happen a few frames behind everything else. Its also very slow for plugins like, eg, wobbly, which is dependent on the same immediate updates.

This approach is slightly more complex, but also, IMO, more comprehensive. It removes entirely the hack that allows windows to immediately update the position of the window and also removes similar hacks like syncPosition, which means that we can now match every update that comes from the server with what we are sending to it.

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

> As far as I can tell from that code, the painted position isn't going to be
> changed until the configure event comes back from the server. In the case
> where the sever is operating slowly, that means that movement is going to
> happen a few frames behind everything else. Its also very slow for plugins
> like, eg, wobbly, which is dependent on the same immediate updates.
>
> This approach is slightly more complex, but also, IMO, more comprehensive. It
> removes entirely the hack that allows windows to immediately update the
> position of the window and also removes similar hacks like syncPosition, which
> means that we can now match every update that comes from the server with what
> we are sending to it.

(Although, I think I'm being unfair here by just looking at the code, so I'll run it too and see how it goes)

lp:~smspillaz/compiz-core/fix-893467 updated
2914. By Sam Spilsbury

Merged fix-POTfile-893995 into fix-893467.

2915. By Sam Spilsbury

Merge

2916. By Sam Spilsbury

Track changes in core

2917. By Sam Spilsbury

Cleanup

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

OK, I have no more argument here. Clearly you've considered the situation carefully enough.

I now (partially) like the idea of the paint offsets for performance. It does sound like the best way right now to minimize visible lag. But I can't help but think there is a more elegant fix that none of us have thought of yet. Gnome Shell doesn't suffer from any kind of lag problem like this. I haven't looked at the relevant gnome source code... Does it use paint offsets? Or something else that we're missing?

Up to now, I've just assumed there must be some unseen bottleneck in compiz making the whole move/sync problem slower than it should be. But that's just a hunch. Maybe offsets are the only way to achieve "perfect" visual sync... ?

Sorry I don't have time to re-review and finally approve this today.

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

On Sat, 14 Jan 2012, Daniel van Vugt wrote:

> OK, I have no more argument here. Clearly you've considered the situation carefully enough.
>
> I now (partially) like the idea of the paint offsets for performance. It does sound like the best way right now to minimize visible lag. But I can't help but think there is a more elegant fix that none of us have thought of yet. Gnome Shell doesn't suffer from any kind of lag problem like this. I haven't looked at the relevant gnome source code... Does it use paint offsets? Or something else that we're missing?
>

Paint offsets are a kind of weird solution - I agree. I'd like to look
into what mutter does to acheive the same thing. (It uses the same kind of
do-effect / sync position code
http://git.gnome.org/browse/mutter/tree/src/compositor/meta-window-actor.c#n1329).
I think for reasons I've explained before, I think such an approach is
problematic, especially when throwing plugins into the mix.

> Up to now, I've just assumed there must be some unseen bottleneck in compiz making the whole move/sync problem slower than it should be. But that's just a hunch. Maybe offsets are the only way to achieve "perfect" visual sync... ?
>

I think that the decor plugin is also another place where optimization can
occur. My stupid shadow clipping algorithm is really slow, and to be
honest, I'm leaning towards dropping it entirely, or introducing a concept
of "layered" shadows if I can't optimize it any more.

> Sorry I don't have time to re-review and finally approve this today.

I have to get on a flight back home anyways, so its all good

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

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

I've now actually built a tested the code in a clean compiz environment. Lots of problems to report:

1. Some minor conflicts with lp:compiz-core. Easy to fix.
2. First run: Xorg using all my CPU and RAM.
3. Second run: compiz crashed (see below for the stack)
4. Third run: Major desktop corruption. move plugin broken - window contents would move while decorations stayed in place.

Program received signal SIGSEGV, Segmentation fault.
matchEvalOps (list=..., w=0xa048b0) at /home/dan/bzr/compiz-core/offsets/src/match.cpp:460
460 if (op->flags & MATCH_OP_AND_MASK)
(gdb) bt
#0 matchEvalOps (list=..., w=0xa048b0) at /home/dan/bzr/compiz-core/offsets/src/match.cpp:460
#1 0x00007ffff216c280 in DecorWindow::update (this=0xa11d90, allowDecoration=true) at /home/dan/bzr/compiz-core/offsets/plugins/decor/src/decor.cpp:1469
#2 0x00007ffff216b1a6 in DecorWindow::DecorWindow (this=0xa11d90, w=0xa048b0) at /home/dan/bzr/compiz-core/offsets/plugins/decor/src/decor.cpp:3066
#3 0x00007ffff2172ae4 in getInstance (base=0xa048b0) at /home/dan/bzr/compiz-core/offsets/plugins/../src/pluginclasshandler/include/core/pluginclasshandler.h:225
#4 PluginClassHandler<DecorWindow, CompWindow, 0>::get (base=0xa048b0) at /home/dan/bzr/compiz-core/offsets/plugins/../src/pluginclasshandler/include/core/pluginclasshandler.h:256
#5 0x00007ffff2172bfc in CompPlugin::VTableForScreenAndWindow<DecorScreen, DecorWindow>::initWindow (this=<optimised out>, w=<optimised out>) at /home/dan/bzr/compiz-core/offsets/plugins/../include/core/plugin.h:249
#6 0x0000000000458ab1 in CompScreen::initPluginForScreen (this=0x67dbb0, p=0x68d380) at /home/dan/bzr/compiz-core/offsets/src/plugin.cpp:330
#7 0x0000000000458910 in CompManager::initPlugin (p=0x68d380) at /home/dan/bzr/compiz-core/offsets/src/plugin.cpp:294
#8 0x000000000045a40e in CompPlugin::push (p=0x68d380) at /home/dan/bzr/compiz-core/offsets/src/plugin.cpp:502
#9 0x000000000042f6d8 in PrivateScreen::updatePlugins (this=0x67dc60) at /home/dan/bzr/compiz-core/offsets/src/screen.cpp:888
#10 0x0000000000433f61 in CompScreen::init (this=0x67dbb0, name=<optimised out>) at /home/dan/bzr/compiz-core/offsets/src/screen.cpp:4749
#11 0x000000000042476d in CompManager::init (this=0x7fffffffe4f0) at /home/dan/bzr/compiz-core/offsets/src/main.cpp:224
#12 0x000000000042215d in main (argc=<optimised out>, argv=0x7fffffffe618) at /home/dan/bzr/compiz-core/offsets/src/main.cpp:287
(gdb) quit

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

In case I made a mistake I've now triple-checked the results. This branch continues to be highly unstable/unusable while using the same testing on lp:compiz-core is problem-free.

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

If this branch can't be stabilized soon, please consider merging my new one instead/first:
https://code.launchpad.net/~vanvugt/compiz-core/fix-764330-simplified-trunk/+merge/88834

lp:~smspillaz/compiz-core/fix-893467 updated
2918. By Sam Spilsbury

Merged fix-POTfile-893995 into fix-893467.

2919. By Sam Spilsbury

Merged fix-POTfile-893995 into fix-893467.

2920. By Sam Spilsbury

Merged fix-POTfile-893995 into fix-893467.

2921. By Sam Spilsbury

Merged fix-POTfile-893995 into fix-893467.

2922. By Sam Spilsbury

Merged fix-POTfile-893995 into fix-893467.

2923. By Sam Spilsbury

Merge

2924. By Sam Spilsbury

Merge

2925. By Sam Spilsbury

Merged fix-POTfile-893995 into fix-893467.

Unmerged revisions

2925. By Sam Spilsbury

Merged fix-POTfile-893995 into fix-893467.

2924. By Sam Spilsbury

Merge

2923. By Sam Spilsbury

Merge

2922. By Sam Spilsbury

Merged fix-POTfile-893995 into fix-893467.

2921. By Sam Spilsbury

Merged fix-POTfile-893995 into fix-893467.

2920. By Sam Spilsbury

Merged fix-POTfile-893995 into fix-893467.

2919. By Sam Spilsbury

Merged fix-POTfile-893995 into fix-893467.

2918. By Sam Spilsbury

Merged fix-POTfile-893995 into fix-893467.

2917. By Sam Spilsbury

Cleanup

2916. By Sam Spilsbury

Track changes in core

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'include/core/core.h'
2--- include/core/core.h 2012-01-19 06:08:11 +0000
3+++ include/core/core.h 2012-01-19 18:20:31 +0000
4@@ -26,7 +26,6 @@
5 #ifndef _COMPIZ_CORE_H
6 #define _COMPIZ_CORE_H
7
8-
9 #include "abiversion.h"
10
11 #include <stdio.h>
12
13=== modified file 'include/core/screen.h'
14--- include/core/screen.h 2011-09-19 12:54:22 +0000
15+++ include/core/screen.h 2012-01-19 18:20:31 +0000
16@@ -325,10 +325,10 @@
17
18 const CompRect & getWorkareaForOutput (unsigned int outputNum) const;
19
20- void viewportForGeometry (const CompWindow::Geometry &gm,
21+ void viewportForGeometry (const compiz::window::Geometry &gm,
22 CompPoint &viewport);
23
24- int outputDeviceForGeometry (const CompWindow::Geometry& gm);
25+ int outputDeviceForGeometry (const compiz::window::Geometry& gm);
26
27 CompPoint vp ();
28
29
30=== modified file 'include/core/window.h'
31--- include/core/window.h 2012-01-19 18:20:30 +0000
32+++ include/core/window.h 2012-01-19 18:20:31 +0000
33@@ -156,6 +156,15 @@
34 #define CompWindowGrabResizeMask (1 << 3)
35 #define CompWindowGrabExternalAppMask (1 << 4)
36
37+enum ChangeMask
38+{
39+ CHANGE_X = 1 << 0,
40+ CHANGE_Y = 1 << 1,
41+ CHANGE_WIDTH = 1 << 2,
42+ CHANGE_HEIGHT = 1 << 3,
43+ CHANGE_BORDER = 1 << 4
44+};
45+
46 /**
47 * Enumeration value which represents
48 * how a window will be stacked by compiz
49@@ -217,6 +226,56 @@
50 XRectangle bottom;
51 };
52
53+namespace compiz
54+{
55+namespace window
56+{
57+/**
58+ * Constrain the window size according to the
59+ * XSizeHints constraints and other relevant
60+ * constraints
61+ */
62+static const unsigned int ConstrainSize = (1 << 0);
63+
64+/**
65+ * Constrain the position to the workarea, such
66+ * that the window cannot go offscreen or
67+ * underneath panels
68+ */
69+static const unsigned int ConstrainPositionWorkarea (1 << 1);
70+
71+/**
72+ * Constrain the position to the virtual screen,
73+ * such that the window cannot go outside of
74+ * the viewport limits (eg vpSize * screen size)
75+ */
76+static const unsigned int ConstrainPositionVirtualScreen (1 << 2);
77+
78+/**
79+ * A mutable object about the dimensions and location of a CompWindow.
80+ */
81+class Geometry :
82+ public CompRect
83+{
84+public:
85+ Geometry ();
86+ Geometry (int x, int y, int width, int height, int border);
87+
88+ int border () const;
89+ void setBorder (int border);
90+
91+ void set (int x, int y, int width, int height, int border);
92+
93+ unsigned int changeMask (const Geometry &g) const;
94+ void applyChange (const Geometry &g, unsigned int mask);
95+
96+private:
97+ int mBorder;
98+};
99+
100+}
101+}
102+
103 /**
104 * Wrappable core window functions. Derive from this class
105 * and overload these functions in order to have your function called
106@@ -234,9 +293,11 @@
107 virtual void activate ();
108 virtual bool place (CompPoint &pos);
109
110- virtual void validateResizeRequest (unsigned int &mask,
111- XWindowChanges *xwc,
112- unsigned int source);
113+ virtual bool position (compiz::window::Geometry &g,
114+ unsigned int source = 0,
115+ unsigned int constrainment = compiz::window::ConstrainSize |
116+ compiz::window::ConstrainPositionWorkarea |
117+ compiz::window::ConstrainPositionVirtualScreen);
118
119 virtual void resizeNotify (int dx, int dy, int dwidth, int dheight);
120 virtual void moveNotify (int dx, int dy, bool immediate);
121@@ -271,24 +332,6 @@
122 {
123 public:
124
125- /**
126- * A mutable object about the dimensions and location of a CompWindow.
127- */
128- class Geometry : public CompRect
129- {
130- public:
131- Geometry ();
132- Geometry (int, int, int, int, int);
133-
134- int border () const;
135-
136- void set (int, int, int, int, int);
137- void setBorder (int);
138-
139- private:
140- int mBorder;
141- };
142-
143 typedef boost::function<void (CompWindow *)> ForEach;
144 typedef std::map<Window, CompWindow *> Map;
145
146@@ -306,7 +349,7 @@
147 * Geometry retrieved from the
148 * last ConfigureNotify event received
149 */
150- Geometry & geometry () const;
151+ const compiz::window::Geometry & geometry () const;
152
153 int x () const;
154 int y () const;
155@@ -320,7 +363,7 @@
156 /**
157 * Geometry last sent to the server
158 */
159- Geometry & serverGeometry () const;
160+ const compiz::window::Geometry & serverGeometry () const;
161
162 int serverX () const;
163 int serverY () const;
164@@ -418,30 +461,10 @@
165
166 bool hasUnmapReference ();
167
168- bool resize (XWindowAttributes);
169-
170- bool resize (Geometry);
171-
172- bool resize (int x, int y, int width, int height,
173- int border = 0);
174-
175- void move (int dx, int dy, bool immediate = true);
176-
177- void syncPosition ();
178-
179 void moveInputFocusTo ();
180
181 void moveInputFocusToOtherWindow ();
182
183- /* wraps XConfigureWindow and updates serverGeometry */
184- void configureXWindow (unsigned int valueMask,
185- XWindowChanges *xwc);
186-
187- void moveResize (XWindowChanges *xwc,
188- unsigned int xwcm,
189- int gravity,
190- unsigned int source);
191-
192 void raise ();
193
194 void lower ();
195@@ -532,8 +555,12 @@
196 WRAPABLE_HND (2, WindowInterface, bool, focus);
197 WRAPABLE_HND (3, WindowInterface, void, activate);
198 WRAPABLE_HND (4, WindowInterface, bool, place, CompPoint &);
199- WRAPABLE_HND (5, WindowInterface, void, validateResizeRequest,
200- unsigned int &, XWindowChanges *, unsigned int);
201+ WRAPABLE_HND (5, WindowInterface, bool, position,
202+ compiz::window::Geometry &,
203+ unsigned int = 0,
204+ unsigned int = compiz::window::ConstrainSize |
205+ compiz::window::ConstrainPositionWorkarea |
206+ compiz::window::ConstrainPositionVirtualScreen);
207
208 WRAPABLE_HND (6, WindowInterface, void, resizeNotify,
209 int, int, int, int);
210
211=== modified file 'plugins/compiztoolbox/src/compiztoolbox.cpp'
212--- plugins/compiztoolbox/src/compiztoolbox.cpp 2012-01-18 16:26:45 +0000
213+++ plugins/compiztoolbox/src/compiztoolbox.cpp 2012-01-19 18:20:31 +0000
214@@ -209,7 +209,7 @@
215 {
216 if (!window->mapNum () || !window->isViewable ())
217 {
218- CompWindow::Geometry &sg = window->serverGeometry ();
219+ const compiz::window::Geometry &sg = window->serverGeometry ();
220 if (sg.x () + sg.width () <= 0 ||
221 sg.y () + sg.height () <= 0 ||
222 sg.x () >= (int) ::screen->width () ||
223@@ -406,12 +406,12 @@
224 if (!openGLAvailable)
225 return;
226
227- GLWindowPaintAttrib sAttrib (attrib);
228- IconMode iconMode;
229- int wx, wy;
230- float width, height;
231- GLTexture *icon = NULL;
232- CompWindow::Geometry &g = window->geometry ();
233+ GLWindowPaintAttrib sAttrib (attrib);
234+ IconMode iconMode;
235+ int wx, wy;
236+ float width, height;
237+ GLTexture *icon = NULL;
238+ const compiz::window::Geometry &g = window->geometry ();
239
240 mask |= PAINT_WINDOW_TRANSFORMED_MASK;
241
242
243=== modified file 'plugins/composite/include/composite/composite.h'
244--- plugins/composite/include/composite/composite.h 2012-01-18 16:26:45 +0000
245+++ plugins/composite/include/composite/composite.h 2012-01-19 18:20:31 +0000
246@@ -30,7 +30,7 @@
247
248 #include <X11/extensions/Xcomposite.h>
249
250-#define COMPIZ_COMPOSITE_ABI 3
251+#define COMPIZ_COMPOSITE_ABI 4
252
253 #include "core/pluginclasshandler.h"
254 #include "core/timer.h"
255@@ -173,10 +173,6 @@
256 public CompOption::Class
257 {
258 public:
259-
260-
261-
262- public:
263 CompositeScreen (CompScreen *s);
264 ~CompositeScreen ();
265
266@@ -217,7 +213,7 @@
267 int & overlayWindowCount ();
268
269 void setWindowPaintOffset (int x, int y);
270- CompPoint windowPaintOffset ();
271+ const CompPoint & windowPaintOffset () const;
272
273 /**
274 * Limits the number of redraws per second
275@@ -317,10 +313,23 @@
276 * parts of the screen need to be redrawn on next pass
277 */
278 virtual bool damageRect (bool initial, const CompRect &rect);
279+
280+ /**
281+ * Hookable function to apply a paint offset to this window only
282+ *
283+ * Plugins which are interested in the difference applied by other
284+ * plugins, eg, they need to update state immediately on a composited
285+ * offset application, like when a window is moving, should hook this function
286+ *
287+ * This function applies a difference in offset to the existing offset,
288+ * eg, it functions relatively to CompositeWindow::paintOffset
289+ *
290+ * @param d Difference in offset being applied */
291+ virtual void applyOffset (const CompPoint &d);
292 };
293
294 class CompositeWindow :
295- public WrapableHandler<CompositeWindowInterface, 1>,
296+ public WrapableHandler<CompositeWindowInterface, 2>,
297 public PluginClassHandler<CompositeWindow, CompWindow, COMPIZ_COMPOSITE_ABI>
298 {
299 public:
300@@ -422,9 +431,15 @@
301 */
302 unsigned short saturation ();
303
304+ /**
305+ * Returns current paint offset for this window */
306+ const CompPoint & paintOffset () const;
307+
308 WRAPABLE_HND (0, CompositeWindowInterface, bool, damageRect,
309 bool, const CompRect &);
310
311+ WRAPABLE_HND (1, CompositeWindowInterface, void, applyOffset, const CompPoint &);
312+
313 friend class PrivateCompositeWindow;
314 friend class CompositeScreen;
315
316
317=== modified file 'plugins/composite/src/privates.h'
318--- plugins/composite/src/privates.h 2011-11-14 07:41:22 +0000
319+++ plugins/composite/src/privates.h 2012-01-19 18:20:31 +0000
320@@ -117,6 +117,9 @@
321 ~PrivateCompositeWindow ();
322
323 void windowNotify (CompWindowNotify n);
324+ bool position (compiz::window::Geometry &g,
325+ unsigned int source,
326+ unsigned int constrainment);
327 void resizeNotify (int dx, int dy, int dwidth, int dheight);
328 void moveNotify (int dx, int dy, bool now);
329
330@@ -148,6 +151,8 @@
331 XRectangle *damageRects;
332 int sizeDamage;
333 int nDamage;
334+
335+ CompPoint offset;
336 };
337
338 #endif
339
340=== modified file 'plugins/composite/src/screen.cpp'
341--- plugins/composite/src/screen.cpp 2012-01-19 04:07:41 +0000
342+++ plugins/composite/src/screen.cpp 2012-01-19 18:20:31 +0000
343@@ -626,8 +626,8 @@
344 priv->windowPaintOffset = CompPoint (x, y);
345 }
346
347-CompPoint
348-CompositeScreen::windowPaintOffset ()
349+const CompPoint &
350+CompositeScreen::windowPaintOffset () const
351 {
352 return priv->windowPaintOffset;
353 }
354
355=== modified file 'plugins/composite/src/window.cpp'
356--- plugins/composite/src/window.cpp 2012-01-16 09:50:28 +0000
357+++ plugins/composite/src/window.cpp 2012-01-19 18:20:31 +0000
358@@ -98,7 +98,8 @@
359 saturation (COLOR),
360 damageRects (0),
361 sizeDamage (0),
362- nDamage (0)
363+ nDamage (0),
364+ offset (0, 0)
365 {
366 WindowInterface::setHandler (w);
367 }
368@@ -250,7 +251,7 @@
369
370 if (x2 > x1 && y2 > y1)
371 {
372- CompWindow::Geometry geom = priv->window->geometry ();
373+ compiz::window::Geometry geom = priv->window->geometry ();
374
375 x1 += geom.x () + geom.border ();
376 y1 += geom.y () + geom.border ();
377@@ -272,7 +273,7 @@
378 {
379 int x1, x2, y1, y2;
380
381- CompWindow::Geometry geom = priv->window->geometry ();
382+ compiz::window::Geometry geom = priv->window->geometry ();
383 CompWindowExtents output = priv->window->output ();
384
385 /* top */
386@@ -318,17 +319,24 @@
387 if (!damageRect (false, rect))
388 {
389 int x, y;
390+ CompRegion damage = CompRegion ();
391
392 x = rect.x ();
393 y = rect.y ();
394
395- CompWindow::Geometry geom = priv->window->geometry ();
396+ const compiz::window::Geometry &geom = priv->window->geometry ();
397+
398 x += geom.x () + geom.border ();
399 y += geom.y () + geom.border ();
400
401- priv->cScreen->damageRegion (CompRegion (CompRect (x, y,
402- rect.width (),
403- rect.height ())));
404+ /* Damage this region */
405+
406+ x += priv->offset.x ();
407+ y += priv->offset.y ();
408+
409+ damage += CompRect (x, y, rect.width (), rect.height ());
410+
411+ priv->cScreen->damageRegion (damage);
412 }
413 }
414
415@@ -410,7 +418,7 @@
416
417 if (!w->damageRect (initial, CompRect (x, y, width, height)))
418 {
419- CompWindow::Geometry geom = w->priv->window->geometry ();
420+ compiz::window::Geometry geom = w->priv->window->geometry ();
421
422 x += geom.x () + geom.border ();
423 y += geom.y () + geom.border ();
424@@ -488,6 +496,12 @@
425 return priv->saturation;
426 }
427
428+const CompPoint &
429+CompositeWindow::paintOffset () const
430+{
431+ return priv->offset;
432+}
433+
434 bool
435 CompositeWindow::damageRect (bool initial,
436 const CompRect &rect)
437@@ -497,6 +511,19 @@
438 }
439
440 void
441+CompositeWindow::applyOffset (const CompPoint &d)
442+{
443+ WRAPABLE_HND_FUNCTN (applyOffset, d);
444+
445+ if (d != CompPoint ())
446+ {
447+ addDamage (true);
448+ priv->offset += d;
449+ addDamage (true);
450+ }
451+}
452+
453+void
454 PrivateCompositeWindow::windowNotify (CompWindowNotify n)
455 {
456 switch (n)
457@@ -552,6 +579,18 @@
458 window->windowNotify (n);
459 }
460
461+bool
462+PrivateCompositeWindow::position (compiz::window::Geometry &g,
463+ unsigned int source,
464+ unsigned int constrainment)
465+{
466+ cWindow->addDamage ();
467+ cWindow->applyOffset (CompPoint (-offset.x (), -offset.y ()));
468+ cWindow->addDamage ();
469+
470+ return window->position (g, source, constrainment);
471+}
472+
473 void
474 PrivateCompositeWindow::resizeNotify (int dx, int dy, int dwidth, int dheight)
475 {
476@@ -560,7 +599,6 @@
477 Pixmap pixmap = None;
478 CompSize size = CompSize ();
479
480-
481 if (window->shaded () || (window->isViewable ()))
482 {
483 int x, y, x1, x2, y1, y2;
484@@ -611,8 +649,6 @@
485 this->pixmap = pixmap;
486 this->size = size;
487 }
488-
489- cWindow->addDamage ();
490 }
491
492 void
493@@ -634,7 +670,6 @@
494
495 cScreen->damageRegion (CompRegion (CompRect (x1, y1, x2 - x1, y2 - y1)));
496 }
497- cWindow->addDamage ();
498
499 window->moveNotify (dx, dy, now);
500 }
501@@ -642,3 +677,7 @@
502 bool
503 CompositeWindowInterface::damageRect (bool initial, const CompRect &rect)
504 WRAPABLE_DEF (damageRect, initial, rect)
505+
506+void
507+CompositeWindowInterface::applyOffset (const CompPoint &p)
508+ WRAPABLE_DEF (applyOffset, p)
509
510=== modified file 'plugins/decor/src/decor.cpp'
511--- plugins/decor/src/decor.cpp 2012-01-19 06:08:11 +0000
512+++ plugins/decor/src/decor.cpp 2012-01-19 18:20:31 +0000
513@@ -1124,24 +1124,25 @@
514 /*
515 * decorOffsetMove
516 *
517- * Function called on a timer (to avoid calling configureXWindow from
518+ * Function called on a timer (to avoid calling position from
519 * within a ::moveNotify) which actually moves the window by the offset
520 * specified in the xwc. Also sends a notification that the window
521 * was decorated
522 *
523 */
524 static bool
525-decorOffsetMove (CompWindow *w, XWindowChanges xwc, unsigned int mask)
526+decorOffsetMove (CompWindow *w, CompPoint d, unsigned int mask)
527 {
528 CompOption::Vector o (1);
529+ compiz::window::Geometry ng = w->serverGeometry ();
530
531 o.at (0).setName ("window", CompOption::TypeInt);
532 o.at (0).value ().set ((int) w->id ());
533
534- xwc.x += w->serverGeometry ().x ();
535- xwc.y += w->serverGeometry ().y ();
536-
537- w->configureXWindow (mask, &xwc);
538+ ng.setPos (w->serverGeometry ().pos () + d);
539+
540+ w->position (ng);
541+
542 screen->handleCompizEvent ("decor", "window_decorated", o);
543 return false;
544 }
545@@ -1570,26 +1571,22 @@
546 if (window->placed () && !window->overrideRedirect () &&
547 (moveDx || moveDy))
548 {
549- XWindowChanges xwc;
550- unsigned int mask = CWX | CWY;
551-
552- memset (&xwc, 0, sizeof (XWindowChanges));
553-
554- /* Grab the geometry last sent to server at configureXWindow
555+ /* Grab the geometry last sent to server at position ()
556 * time and not here since serverGeometry may be updated by
557- * the time that we do call configureXWindow */
558- xwc.x = moveDx;
559- xwc.y = moveDy;
560+ * the time that we do call position () */
561+
562+ CompPoint d (moveDx, moveDy);
563+ unsigned int mask = CHANGE_X | CHANGE_Y;
564
565 /* Except if it's fullscreen, maximized or such */
566 if (window->state () & CompWindowStateFullscreenMask)
567- mask &= ~(CWX | CWY);
568+ mask &= ~(CHANGE_X | CHANGE_Y);
569
570 if (window->state () & CompWindowStateMaximizedHorzMask)
571- mask &= ~CWX;
572+ mask &= ~CHANGE_X;
573
574 if (window->state () & CompWindowStateMaximizedVertMask)
575- mask &= ~CWY;
576+ mask &= ~CHANGE_Y;
577
578 if (window->saveMask () & CWX)
579 window->saveWc ().x += moveDx;
580@@ -1609,9 +1606,9 @@
581 * refcounting in case we need to keep it alive
582 */
583 if (!allowDecoration)
584- decorOffsetMove (window, xwc, mask);
585+ decorOffsetMove (window, d, mask);
586 else
587- moveUpdate.start (boost::bind (decorOffsetMove, window, xwc, mask), 0);
588+ moveUpdate.start (boost::bind (decorOffsetMove, window, d, mask), 0);
589 }
590 }
591
592@@ -1705,7 +1702,7 @@
593 {
594 XRectangle rects[4];
595 int x, y, width, height;
596- CompWindow::Geometry server = window->serverGeometry ();
597+ compiz::window::Geometry server = window->serverGeometry ();
598 int bw = server.border () * 2;
599 CompWindowExtents input;
600 CompWindowExtents border;
601@@ -1872,7 +1869,7 @@
602 {
603 XRectangle rects[4];
604 int x, y, width, height;
605- CompWindow::Geometry server = window->serverGeometry ();
606+ compiz::window::Geometry server = window->serverGeometry ();
607 int bw = server.border () * 2;
608 CompWindowExtents input;
609
610
611=== modified file 'plugins/move/src/move.cpp'
612--- plugins/move/src/move.cpp 2012-01-19 18:20:30 +0000
613+++ plugins/move/src/move.cpp 2012-01-19 18:20:31 +0000
614@@ -115,6 +115,8 @@
615
616 if (ms->grab)
617 {
618+ MOVE_WINDOW (w);
619+
620 unsigned int grabMask = CompWindowGrabMoveMask |
621 CompWindowGrabButtonMask;
622
623@@ -146,12 +148,15 @@
624
625 if (ms->moveOpacity != OPAQUE)
626 {
627- MOVE_WINDOW (w);
628-
629 if (mw->cWindow)
630 mw->cWindow->addDamage ();
631 if (mw->gWindow)
632- mw->gWindow->glPaintSetEnabled (mw, true);
633+ mw->gWindow->glPaintSetEnabled (mw, true);
634+ }
635+
636+ if (ms->hasCompositing && mw->cWindow)
637+ {
638+ mw->cWindow->addDamage ();
639 }
640 }
641 }
642@@ -168,19 +173,27 @@
643
644 if (ms->w)
645 {
646+ /* Other plugins may have updated serverGeometry based
647+ * on the position offset, use w->geometry here */
648+ compiz::window::Geometry ng = ms->w->geometry ();
649+
650+ MOVE_WINDOW (ms->w);
651+
652+ ms->w->ungrabNotify ();
653+
654 if (state & CompAction::StateCancel)
655- ms->w->move (ms->savedX - ms->w->geometry ().x (),
656- ms->savedY - ms->w->geometry ().y (), false);
657+ ng.setPos (CompPoint (ms->savedX, ms->savedY));
658+ else
659+ ng.setPos (ng.pos () + mw->cWindow->paintOffset ());
660
661- ms->w->syncPosition ();
662+ ms->w->position (ng);
663+ mw->cWindow->addDamage ();
664
665 /* update window attributes as window constraints may have
666 changed - needed e.g. if a maximized window was moved
667 to another output device */
668 ms->w->updateAttributes (CompStackingUpdateModeNone);
669
670- ms->w->ungrabNotify ();
671-
672 if (ms->grab)
673 {
674 screen->removeGrab (ms->grab, NULL);
675@@ -189,8 +202,6 @@
676
677 if (ms->moveOpacity != OPAQUE)
678 {
679- MOVE_WINDOW (ms->w);
680-
681 if (mw->cWindow)
682 mw->cWindow->addDamage ();
683 if (mw->gWindow)
684@@ -434,11 +445,6 @@
685 {
686 int wy;
687
688- /* update server position before maximizing
689- window again so that it is maximized on
690- correct output */
691- w->syncPosition ();
692-
693 w->maximize (ms->origState);
694
695 wy = workArea.y () + (w->border ().top >> 1);
696@@ -484,20 +490,23 @@
697
698 if (dx || dy)
699 {
700- w->move (wX + dx - w->geometry ().x (),
701- wY + dy - w->geometry ().y (), false);
702+ compiz::window::Geometry og = w->geometry ();
703+ CompPoint d = CompPoint (wX + dx - og.x (),
704+ wY + dy - og.y ());
705+
706+ MOVE_WINDOW (ms->w);
707
708 if (ms->optionGetLazyPositioning () && ms->hasCompositing)
709 {
710- /* FIXME: This form of lazy positioning is broken and should
711- be replaced asap. Current code exists just to avoid a
712- major performance regression in the 0.5.2 release. */
713- w->serverGeometry ().setX (w->geometry ().x ());
714- w->serverGeometry ().setY (w->geometry ().y ());
715+ mw->cWindow->applyOffset (d);
716 }
717 else
718 {
719- w->syncPosition ();
720+ compiz::window::Geometry ng = ms->w->serverGeometry ();
721+
722+ ng.setPos (ng.pos () + d);
723+
724+ ms->w->position (ng);
725 }
726
727 ms->x -= dx;
728@@ -679,8 +688,7 @@
729 MoveScreen::registerPaintHandler(compiz::composite::PaintHandler *pHnd)
730 {
731 hasCompositing = true;
732- cScreen->registerPaintHandler (pHnd);
733- return true;
734+ return cScreen->registerPaintHandler (pHnd);
735 }
736
737 void
738
739=== modified file 'plugins/move/src/move.h'
740--- plugins/move/src/move.h 2012-01-19 18:20:30 +0000
741+++ plugins/move/src/move.h 2012-01-19 18:20:31 +0000
742@@ -98,6 +98,7 @@
743
744 class MoveWindow :
745 public GLWindowInterface,
746+ public CompositeWindowInterface,
747 public PluginClassHandler<MoveWindow,CompWindow>
748 {
749 public:
750@@ -109,6 +110,9 @@
751 {
752 if (gWindow)
753 GLWindowInterface::setHandler (gWindow, false);
754+
755+ if (cWindow)
756+ CompositeWindowInterface::setHandler (cWindow);
757 };
758
759 bool glPaint (const GLWindowPaintAttrib &, const GLMatrix &,
760
761=== modified file 'plugins/opengl/src/paint.cpp'
762--- plugins/opengl/src/paint.cpp 2012-01-19 06:08:11 +0000
763+++ plugins/opengl/src/paint.cpp 2012-01-19 18:20:31 +0000
764@@ -260,13 +260,16 @@
765
766 odMask = PAINT_WINDOW_OCCLUSION_DETECTION_MASK;
767
768- if ((cScreen->windowPaintOffset ().x () != 0 ||
769- cScreen->windowPaintOffset ().y () != 0) &&
770+ const CompPoint &offset =
771+ cScreen->windowPaintOffset ();
772+
773+ if ((offset.x () != 0 ||
774+ offset.y () != 0) &&
775 !w->onAllViewports ())
776 {
777 withOffset = true;
778
779- offXY = w->getMovementForOffset (cScreen->windowPaintOffset ());
780+ offXY = w->getMovementForOffset (offset);
781
782 vTransform = transform;
783 vTransform.translate (offXY.x (), offXY.y (), 0);
784@@ -341,11 +344,14 @@
785 (!(mask & PAINT_SCREEN_NO_OCCLUSION_DETECTION_MASK)) ?
786 gw->clip () : region;
787
788- if ((cScreen->windowPaintOffset ().x () != 0 ||
789- cScreen->windowPaintOffset ().y () != 0) &&
790+ CompPoint offset =
791+ cScreen->windowPaintOffset ();
792+
793+ if ((offset.x () != 0 ||
794+ offset.y () != 0) &&
795 !w->onAllViewports ())
796 {
797- offXY = w->getMovementForOffset (cScreen->windowPaintOffset ());
798+ offXY = w->getMovementForOffset (offset);
799
800 vTransform = transform;
801 vTransform.translate (offXY.x (), offXY.y (), 0);
802@@ -1201,9 +1207,15 @@
803
804 if (priv->textures.size () == 1)
805 {
806+ /* Need to use the paint offset region
807+ * too */
808+
809+ CompRegion pr = priv->window->region ();
810+ pr.translate (priv->cWindow->paintOffset ());
811+
812 ml[0] = priv->matrices[0];
813 priv->geometry.reset ();
814- glAddGeometry (ml, priv->window->region (), reg);
815+ glAddGeometry (ml, pr, reg);
816 if (priv->geometry.vCount)
817 glDrawTexture (priv->textures[0], fragment, mask);
818 }
819@@ -1234,7 +1246,6 @@
820
821 GLFragment::Attrib fragment (attrib);
822 bool status;
823-
824 priv->lastPaint = attrib;
825
826 if (priv->window->alpha () || attrib.opacity != OPAQUE)
827@@ -1263,7 +1274,7 @@
828 return true;
829
830 if (mask & PAINT_WINDOW_TRANSFORMED_MASK ||
831- mask & PAINT_WINDOW_WITH_OFFSET_MASK)
832+ mask & PAINT_WINDOW_WITH_OFFSET_MASK)
833 {
834 glPushMatrix ();
835 glLoadMatrixf (transform.getMatrix ());
836
837=== modified file 'plugins/opengl/src/privates.h'
838--- plugins/opengl/src/privates.h 2012-01-19 06:08:11 +0000
839+++ plugins/opengl/src/privates.h 2012-01-19 18:20:31 +0000
840@@ -137,9 +137,10 @@
841 PrivateGLWindow (CompWindow *w, GLWindow *gw);
842 ~PrivateGLWindow ();
843
844+ void applyOffset (const CompPoint &);
845+ bool position (compiz::window::Geometry &g, unsigned int source, unsigned int constrainment);
846 void windowNotify (CompWindowNotify n);
847 void resizeNotify (int dx, int dy, int dwidth, int dheight);
848- void moveNotify (int dx, int dy, bool now);
849 void updateFrameRegion (CompRegion &region);
850
851 void setWindowMatrix ();
852
853=== modified file 'plugins/opengl/src/window.cpp'
854--- plugins/opengl/src/window.cpp 2011-03-11 12:15:30 +0000
855+++ plugins/opengl/src/window.cpp 2012-01-19 18:20:31 +0000
856@@ -76,7 +76,9 @@
857 void
858 PrivateGLWindow::setWindowMatrix ()
859 {
860- CompRect input (window->inputRect ());
861+ CompRect input (window->serverInputRect ());
862+
863+ input.setPos (input.pos () + cWindow->paintOffset ());
864
865 if (textures.size () != matrices.size ())
866 matrices.resize (textures.size ());
867@@ -175,26 +177,45 @@
868 return priv->lastPaint;
869 }
870
871+void
872+PrivateGLWindow::applyOffset(const CompPoint &d)
873+{
874+ cWindow->applyOffset (d);
875+
876+ setWindowMatrix ();
877+}
878+
879+bool
880+PrivateGLWindow::position (compiz::window::Geometry &g,
881+ unsigned int source,
882+ unsigned int constrainment)
883+{
884+ /* Don't update window matrix twice */
885+
886+ cWindow->applyOffsetSetEnabled (this, false);
887+
888+ bool ret = window->position (g, source, constrainment);
889+
890+ cWindow->applyOffsetSetEnabled (this, true);
891+
892+ if (ret)
893+ {
894+ setWindowMatrix ();
895+ updateReg = true;
896+ }
897+
898+ return ret;
899+}
900
901 void
902 PrivateGLWindow::resizeNotify (int dx, int dy, int dwidth, int dheight)
903 {
904 window->resizeNotify (dx, dy, dwidth, dheight);
905- setWindowMatrix ();
906- updateReg = true;
907 if (!window->hasUnmapReference ())
908 gWindow->release ();
909 }
910
911 void
912-PrivateGLWindow::moveNotify (int dx, int dy, bool now)
913-{
914- window->moveNotify (dx, dy, now);
915- updateReg = true;
916- setWindowMatrix ();
917-}
918-
919-void
920 PrivateGLWindow::windowNotify (CompWindowNotify n)
921 {
922 switch (n)
923@@ -344,7 +365,9 @@
924 void
925 PrivateGLWindow::updateWindowRegions ()
926 {
927- CompRect input (window->inputRect ());
928+ CompRect input (window->serverInputRect ());
929+
930+ input.setPos (input.pos () + cWindow->paintOffset ());
931
932 if (regions.size () != textures.size ())
933 regions.resize (textures.size ());
934
935=== modified file 'plugins/place/src/place.cpp'
936--- plugins/place/src/place.cpp 2011-05-07 17:31:52 +0000
937+++ plugins/place/src/place.cpp 2012-01-19 18:20:31 +0000
938@@ -293,8 +293,12 @@
939 }
940 if (mask)
941 {
942+ compiz::window::Geometry ng (xwc.x, xwc.y, xwc.width, xwc.height, xwc.border_width);
943+
944+ ng.applyChange (w->geometry (), mask);
945+
946 /* actually move/resize window in directions given by mask */
947- w->configureXWindow (mask, &xwc);
948+ w->position (ng, 0);
949 }
950 }
951 }
952@@ -493,7 +497,7 @@
953 {
954 CompRect workArea;
955 int x, y, left, right, bottom, top;
956- CompWindow::Geometry geom;
957+ compiz::window::Geometry geom;
958 int output;
959
960 if (clampToViewport)
961@@ -626,48 +630,6 @@
962 }
963
964 void
965-PlaceWindow::validateResizeRequest (unsigned int &mask,
966- XWindowChanges *xwc,
967- unsigned int source)
968-{
969- CompRect workArea;
970- CompWindow::Geometry geom;
971- bool sizeOnly = false;
972-
973- window->validateResizeRequest (mask, xwc, source);
974-
975- if (!mask)
976- return;
977-
978- if (source == ClientTypePager)
979- return;
980-
981- if (window->state () & CompWindowStateFullscreenMask)
982- return;
983-
984- if (window->wmType () & (CompWindowTypeDockMask |
985- CompWindowTypeDesktopMask))
986- return;
987-
988- /* do nothing if the window was already (at least partially) offscreen */
989- if (window->serverX () < 0 ||
990- window->serverX () + window->serverWidth () > screen->width () ||
991- window->serverY () < 0 ||
992- window->serverY () + window->serverHeight () > screen->height ())
993- {
994- return;
995- }
996-
997- if (hasUserDefinedPosition (false))
998- /* try to keep the window position intact for USPosition -
999- obviously we can't do that if we need to change the size */
1000- sizeOnly = true;
1001-
1002- doValidateResizeRequest (mask, xwc, sizeOnly, true);
1003-
1004-}
1005-
1006-void
1007 PlaceScreen::addSupportedAtoms (std::vector<Atom> &atoms)
1008 {
1009
1010@@ -782,7 +744,7 @@
1011 if ((unsigned int) output.id () == (unsigned int) ~0)
1012 {
1013 int id;
1014- CompWindow::Geometry geom (window->serverGeometry ());
1015+ compiz::window::Geometry geom (window->serverGeometry ());
1016
1017 geom.setPos (pos);
1018
1019@@ -1446,7 +1408,7 @@
1020 break;
1021 case ConstrainOnly:
1022 {
1023- CompWindow::Geometry geom = window->serverGeometry ();
1024+ compiz::window::Geometry geom = window->serverGeometry ();
1025
1026 geom.setPos (pos);
1027 output = screen->outputDeviceForGeometry (geom);
1028
1029=== modified file 'plugins/resize/src/resize.cpp'
1030--- plugins/resize/src/resize.cpp 2012-01-18 16:26:45 +0000
1031+++ plugins/resize/src/resize.cpp 2012-01-19 18:20:31 +0000
1032@@ -318,7 +318,7 @@
1033
1034 RESIZE_SCREEN (screen);
1035
1036- CompWindow::Geometry server = w->serverGeometry ();
1037+ const compiz::window::Geometry &server = w->serverGeometry ();
1038
1039 x = CompOption::getIntOptionNamed (options, "x", pointerX);
1040 y = CompOption::getIntOptionNamed (options, "y", pointerY);
1041@@ -570,20 +570,19 @@
1042
1043 if (rs->w)
1044 {
1045- CompWindow *w = rs->w;
1046- XWindowChanges xwc;
1047+ CompWindow *w = rs->w;
1048+ compiz::window::Geometry ng = w->serverGeometry ();
1049 unsigned int mask = 0;
1050
1051 if (rs->mode == ResizeOptions::ModeNormal)
1052 {
1053 if (state & CompAction::StateCancel)
1054 {
1055- xwc.x = rs->savedGeometry.x;
1056- xwc.y = rs->savedGeometry.y;
1057- xwc.width = rs->savedGeometry.width;
1058- xwc.height = rs->savedGeometry.height;
1059-
1060- mask = CWX | CWY | CWWidth | CWHeight;
1061+ ng.applyChange (compiz::window::Geometry (rs->savedGeometry.x,
1062+ rs->savedGeometry.y,
1063+ rs->savedGeometry.width,
1064+ rs->savedGeometry.height, 0),
1065+ CHANGE_X | CHANGE_Y | CHANGE_WIDTH | CHANGE_HEIGHT);
1066 }
1067 }
1068 else
1069@@ -608,12 +607,11 @@
1070 }
1071 else
1072 {
1073- xwc.x = geometry.x;
1074- xwc.y = geometry.y;
1075- xwc.width = geometry.width;
1076- xwc.height = geometry.height;
1077-
1078- mask = CWX | CWY | CWWidth | CWHeight;
1079+ ng.applyChange (compiz::window::Geometry (geometry.x,
1080+ geometry.y,
1081+ geometry.width,
1082+ geometry.height, 0),
1083+ CHANGE_X | CHANGE_Y | CHANGE_WIDTH | CHANGE_HEIGHT);
1084 }
1085
1086 if (rs->mode != ResizeOptions::ModeNormal)
1087@@ -627,20 +625,12 @@
1088 }
1089 }
1090
1091- if ((mask & CWWidth) &&
1092- xwc.width == (int) w->serverGeometry ().width ())
1093- mask &= ~CWWidth;
1094-
1095- if ((mask & CWHeight) &&
1096- xwc.height == (int) w->serverGeometry ().height ())
1097- mask &= ~CWHeight;
1098-
1099 if (mask)
1100 {
1101- if (mask & (CWWidth | CWHeight))
1102+ if (mask & (CHANGE_WIDTH | CHANGE_HEIGHT))
1103 w->sendSyncRequest ();
1104
1105- w->configureXWindow (mask, &xwc);
1106+ w->position (ng);
1107 }
1108
1109 if (!(mask & (CWWidth | CWHeight)))
1110@@ -668,19 +658,20 @@
1111 if (w->syncWait ())
1112 return;
1113
1114- if (w->serverGeometry ().width () != geometry.width ||
1115- w->serverGeometry ().height () != geometry.height)
1116+ compiz::window::Geometry rg = compiz::window::Geometry (geometry.x,
1117+ geometry.y,
1118+ geometry.width,
1119+ geometry.height, 0);
1120+ unsigned int changeMask = w->serverGeometry ().changeMask (rg);
1121+
1122+ if (changeMask & (CHANGE_WIDTH | CHANGE_HEIGHT))
1123 {
1124- XWindowChanges xwc;
1125+ compiz::window::Geometry ng = w->serverGeometry ();
1126
1127- xwc.x = geometry.x;
1128- xwc.y = geometry.y;
1129- xwc.width = geometry.width;
1130- xwc.height = geometry.height;
1131+ ng.applyChange (rg, changeMask);
1132
1133 w->sendSyncRequest ();
1134-
1135- w->configureXWindow (CWX | CWY | CWWidth | CWHeight, &xwc);
1136+ w->position (ng);
1137 }
1138 }
1139
1140@@ -714,7 +705,7 @@
1141 {
1142 int x, y, left, top, width, height;
1143
1144- CompWindow::Geometry server = w->serverGeometry ();
1145+ const compiz::window::Geometry &server = w->serverGeometry ();
1146 const CompWindowExtents &border = w->border ();
1147
1148 left = server.x () - border.left;
1149@@ -754,7 +745,7 @@
1150 int xDist, yDist;
1151 int minPointerOffsetX, minPointerOffsetY;
1152
1153- CompWindow::Geometry server = w->serverGeometry ();
1154+ const compiz::window::Geometry &server = w->serverGeometry ();
1155
1156 xDist = xRoot - (server.x () + (server.width () / 2));
1157 yDist = yRoot - (server.y () + (server.height () / 2));
1158
1159=== modified file 'plugins/rotate/src/rotate.cpp'
1160--- plugins/rotate/src/rotate.cpp 2012-01-18 16:26:45 +0000
1161+++ plugins/rotate/src/rotate.cpp 2012-01-19 18:20:31 +0000
1162@@ -112,10 +112,6 @@
1163 void
1164 RotateScreen::releaseMoveWindow ()
1165 {
1166- CompWindow *w = screen->findWindow (mMoveWindow);
1167- if (w)
1168- w->syncPosition ();
1169-
1170 mMoveWindow = None;
1171 }
1172
1173@@ -227,8 +223,11 @@
1174 w = screen->findWindow (mMoveWindow);
1175 if (w)
1176 {
1177- w->move (mMoveWindowX - w->x (), 0);
1178- w->syncPosition ();
1179+ compiz::window::Geometry ng = w->serverGeometry ();
1180+
1181+ ng.setX (mMoveWindowX);
1182+
1183+ w->position (ng);
1184 }
1185 }
1186 /* only focus default window if switcher isn't active */
1187
1188=== modified file 'plugins/switcher/src/switcher.cpp'
1189--- plugins/switcher/src/switcher.cpp 2011-03-11 18:13:44 +0000
1190+++ plugins/switcher/src/switcher.cpp 2012-01-19 18:20:31 +0000
1191@@ -77,20 +77,30 @@
1192 {
1193 CompWindow *w = screen->findWindow (popupWindow);
1194
1195- XWindowChanges xwc;
1196- unsigned int valueMask = 0;
1197-
1198- valueMask |= (CWX | CWY | CWWidth | CWHeight);
1199-
1200- xwc.x = x - WINDOW_WIDTH (count) / 2;
1201- xwc.y = y - WINDOW_HEIGHT / 2;
1202- xwc.width = WINDOW_WIDTH (count);
1203- xwc.height = WINDOW_HEIGHT;
1204-
1205 if (w)
1206- w->configureXWindow (valueMask, &xwc);
1207+ {
1208+ compiz::window::Geometry g (x - WINDOW_WIDTH (count) / 2,
1209+ y - WINDOW_HEIGHT / 2,
1210+ WINDOW_WIDTH (count),
1211+ WINDOW_HEIGHT,
1212+ 0);
1213+
1214+ w->position (g);
1215+ }
1216 else
1217+ {
1218+ XWindowChanges xwc;
1219+ unsigned int valueMask = 0;
1220+
1221+ valueMask |= (CWX | CWY | CWWidth | CWHeight);
1222+
1223+ xwc.x = x - WINDOW_WIDTH (count) / 2;
1224+ xwc.y = y - WINDOW_HEIGHT / 2;
1225+ xwc.width = WINDOW_WIDTH (count);
1226+ xwc.height = WINDOW_HEIGHT;
1227+
1228 XConfigureWindow (screen->dpy (), popupWindow, valueMask, &xwc);
1229+ }
1230 }
1231 }
1232
1233@@ -956,7 +966,7 @@
1234 int x, y, x1, x2, cx, i;
1235 unsigned short color[4];
1236
1237- CompWindow::Geometry &g = window->geometry ();
1238+ const compiz::window::Geometry &g = window->geometry ();
1239
1240 if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK ||
1241 sScreen->ignoreSwitcher)
1242
1243=== modified file 'plugins/water/src/water.cpp'
1244--- plugins/water/src/water.cpp 2012-01-18 16:26:45 +0000
1245+++ plugins/water/src/water.cpp 2012-01-19 18:20:31 +0000
1246@@ -1148,7 +1148,7 @@
1247 w = screen->findWindow (xid);
1248 if (w)
1249 {
1250- CompWindow::Geometry &g = w->geometry ();
1251+ const compiz::window::Geometry &g = w->geometry ();
1252 XPoint p[2];
1253
1254 p[0].x = g.x () - w->border ().left;
1255
1256=== modified file 'plugins/wobbly/src/wobbly.cpp'
1257--- plugins/wobbly/src/wobbly.cpp 2011-03-14 16:12:45 +0000
1258+++ plugins/wobbly/src/wobbly.cpp 2012-01-19 18:20:31 +0000
1259@@ -693,6 +693,61 @@
1260 setMiddleAnchor (x, y, width, height);
1261 }
1262
1263+CompositedPositionTracker::CompositedPositionTracker (const compiz::window::Geometry &geom,
1264+ CompPoint diff,
1265+ UpdateProc f) :
1266+ lastPosition (geom.pos ()),
1267+ currentPosition (geom.pos ()),
1268+ lastOffset (diff),
1269+ currentOffset (diff),
1270+ updateFunc (f)
1271+{
1272+ updateHandle.setTimes (0, 0);
1273+ updateHandle.setCallback (boost::bind (&CompositedPositionTracker::dispatchUpdate, this));
1274+}
1275+
1276+CompositedPositionTracker::~CompositedPositionTracker ()
1277+{
1278+ updateHandle.stop ();
1279+}
1280+
1281+CompPoint
1282+CompositedPositionTracker::absolute ()
1283+{
1284+ return currentPosition + currentOffset;
1285+}
1286+
1287+CompPoint
1288+CompositedPositionTracker::diff ()
1289+{
1290+ return (currentPosition - lastPosition) + (currentOffset - lastOffset);
1291+}
1292+
1293+void
1294+CompositedPositionTracker::updatePosition (const CompPoint &dPosition)
1295+{
1296+ currentPosition += dPosition;
1297+ updateHandle.start ();
1298+}
1299+
1300+void
1301+CompositedPositionTracker::updateOffset (const CompPoint &dOffset)
1302+{
1303+ currentOffset += dOffset;
1304+ updateHandle.start ();
1305+}
1306+
1307+bool
1308+CompositedPositionTracker::dispatchUpdate ()
1309+{
1310+ updateFunc (diff ());
1311+
1312+ lastOffset = currentOffset;
1313+ lastPosition = currentPosition;
1314+
1315+ return false;
1316+}
1317+
1318 void
1319 WobblyWindow::updateModelSnapping ()
1320 {
1321@@ -1251,7 +1306,7 @@
1322 if (!model)
1323 {
1324 unsigned int edgeMask = 0;
1325- CompRect outRect (window->outputRect ());
1326+ const CompRect &outRect (window->outputRect ());
1327
1328 if (window->type () & CompWindowTypeNormalMask)
1329 edgeMask = WestEdgeMask | EastEdgeMask | NorthEdgeMask |
1330@@ -1311,7 +1366,7 @@
1331 if (window->width () == 1 && window->height () == 1)
1332 return false;
1333
1334- CompWindow::Geometry &geom = window->geometry ();
1335+ const compiz::window::Geometry &geom = window->geometry ();
1336
1337 /* avoid fullscreen windows */
1338 if (geom.x () <= 0 &&
1339@@ -1359,6 +1414,7 @@
1340 if ((ww->state & MAXIMIZE_STATE) && ww->grabbed)
1341 ww->wobblingMask |= WobblyForceMask;
1342
1343+
1344 if (ww->wobblingMask)
1345 {
1346 /* snapped to more than one edge, we have to reduce
1347@@ -1411,16 +1467,17 @@
1348 ww->model = 0;
1349
1350 if (w->geometry ().x () == w->serverX () &&
1351- w->geometry ().y () == w->serverY ())
1352+ w->geometry ().y () == w->serverY () &&
1353+ !ww->grabbed)
1354 {
1355- w->move (model->topLeft.x +
1356- w->output ().left -
1357- w->geometry ().x (),
1358- model->topLeft.y +
1359- w->output ().top -
1360- w->geometry ().y (),
1361- true);
1362- w->syncPosition ();
1363+ compiz::window::Geometry ng = w->geometry ();
1364+
1365+ ng.setPos (CompPoint (model->topLeft.x,
1366+ model->topLeft.y));
1367+
1368+ w->positionSetEnabled (ww, false);
1369+ w->position (ng);
1370+ w->positionSetEnabled (ww, true);
1371 }
1372
1373 ww->model = model;
1374@@ -1448,8 +1505,10 @@
1375 else
1376 cw->addDamage ();
1377
1378- int wx = w->geometry ().x ();
1379- int wy = w->geometry ().y ();
1380+ const CompPoint &offset = ww->cWindow->paintOffset ();
1381+
1382+ int wx = w->geometry ().x () + offset.x ();
1383+ int wy = w->geometry ().y () + offset.y ();
1384 int borderWidth = w->geometry ().border ();
1385
1386 // Damage a box that's 1-pixel larger on each side
1387@@ -1579,6 +1638,9 @@
1388 }
1389
1390 CompRect outRect (window->outputRect ());
1391+
1392+ outRect.setPos (outRect.pos () + cWindow->paintOffset ());
1393+
1394 wx = outRect.x ();
1395 wy = outRect.y ();
1396 width = outRect.width ();
1397@@ -1772,7 +1834,7 @@
1398
1399 if (ww->isWobblyWin () && ww->ensureModel ())
1400 {
1401- CompRect outRect (w->outputRect ());
1402+ const CompRect &outRect (w->outputRect ());
1403
1404 ww->model->setMiddleAnchor (outRect.x (), outRect.y (),
1405 outRect.width (), outRect.height ());
1406@@ -1901,7 +1963,7 @@
1407 switch (focusEffect) {
1408 case WobblyOptions::FocusEffectShiver:
1409 {
1410- CompRect outRect (w->outputRect ());
1411+ const CompRect &outRect (w->outputRect ());
1412
1413 ww->model->adjustObjectsForShiver (outRect.x (),
1414 outRect.y (),
1415@@ -1977,7 +2039,7 @@
1416 wScreen->optionGetMapWindowMatch ().evaluate (window) &&
1417 ensureModel ())
1418 {
1419- CompRect outRect (window->outputRect ());
1420+ const CompRect &outRect (window->outputRect ());
1421
1422 model->initObjects (outRect.x (), outRect.y (),
1423 outRect.width (), outRect.height ());
1424@@ -2083,13 +2145,11 @@
1425 }
1426
1427 void
1428-WobblyWindow::moveNotify (int dx,
1429- int dy,
1430- bool immediate)
1431+WobblyWindow::onMovement (CompPoint diff)
1432 {
1433 if (model)
1434 {
1435- if (grabbed && !immediate)
1436+ if (grabbed)
1437 {
1438 if (state & MAXIMIZE_STATE)
1439 {
1440@@ -2098,23 +2158,48 @@
1441 {
1442 if (object->immobile)
1443 {
1444- object->position.x += dx;
1445- object->position.y += dy;
1446+ object->position.x += diff.x ();
1447+ object->position.y += diff.y ();
1448 }
1449 }
1450 }
1451 else
1452 {
1453- model->anchorObject->position.x += dx;
1454- model->anchorObject->position.y += dy;
1455+ model->anchorObject->position.x += diff.x ();
1456+ model->anchorObject->position.y += diff.y ();
1457 }
1458
1459 wScreen->startWobbling (this);
1460 }
1461 else
1462- model->move (dx, dy);
1463+ model->move (diff.x (), diff.y ());
1464 }
1465-
1466+}
1467+
1468+bool
1469+WobblyWindow::position (compiz::window::Geometry &g,
1470+ unsigned int source,
1471+ unsigned int constrainment)
1472+{
1473+ CompPoint d = g.pos () - window->serverGeometry ().pos ();
1474+ bool ret = window->position (g, source, constrainment);
1475+
1476+ tracker.updatePosition (d);
1477+
1478+ return ret;
1479+}
1480+
1481+void
1482+WobblyWindow::applyOffset (const CompPoint &dOffset)
1483+{
1484+ cWindow->applyOffset (dOffset);
1485+
1486+ tracker.updateOffset (dOffset);
1487+}
1488+
1489+void
1490+WobblyWindow::moveNotify (int dx, int dy, bool immediate)
1491+{
1492 window->moveNotify (dx, dy, immediate);
1493 }
1494
1495@@ -2144,7 +2229,7 @@
1496
1497 if (wScreen->optionGetMaximizeEffect ())
1498 {
1499- CompRect outRect (window->outputRect ());
1500+ const CompRect &outRect (window->outputRect ());
1501
1502 if (window->state () & MAXIMIZE_STATE)
1503 {
1504@@ -2224,6 +2309,8 @@
1505
1506 wScreen->startWobbling (this);
1507 }
1508+
1509+
1510 }
1511 }
1512
1513@@ -2252,7 +2339,7 @@
1514 if (wScreen->optionGetMaximizeEffect () &&
1515 (state & MAXIMIZE_STATE))
1516 {
1517- CompRect outRect (window->outputRect ());
1518+ const CompRect &outRect (window->outputRect ());
1519
1520 model->addEdgeAnchors (outRect.x (), outRect.y (),
1521 outRect.width (), outRect.height ());
1522@@ -2336,7 +2423,10 @@
1523 model (0),
1524 wobblingMask (0),
1525 grabbed (false),
1526- state (w->state ())
1527+ state (w->state ()),
1528+ tracker (w->geometry (),
1529+ cWindow->paintOffset (),
1530+ boost::bind (&WobblyWindow::onMovement, this, _1))
1531 {
1532 if ((w->mapNum () && wScreen->optionGetMaximizeEffect ()) ||
1533 wScreen->optionGetMapEffect () != WobblyOptions::MapEffectNone)
1534@@ -2348,6 +2438,12 @@
1535 WindowInterface::setHandler (window);
1536 CompositeWindowInterface::setHandler (cWindow, false);
1537 GLWindowInterface::setHandler (gWindow, false);
1538+
1539+ /* Always enable the applyOffset function
1540+ * as we need that to get synchronous position
1541+ * updates from the compositor */
1542+
1543+ cWindow->applyOffsetSetEnabled (this, true);
1544 }
1545
1546 WobblyWindow::~WobblyWindow ()
1547
1548=== modified file 'plugins/wobbly/src/wobbly.h'
1549--- plugins/wobbly/src/wobbly.h 2009-12-25 19:50:25 +0000
1550+++ plugins/wobbly/src/wobbly.h 2012-01-19 18:20:31 +0000
1551@@ -193,6 +193,41 @@
1552 unsigned int snapCnt[4];
1553 };
1554
1555+/* Prevents double updates on the model
1556+ * when due to changes in offset and position */
1557+class CompositedPositionTracker
1558+{
1559+public:
1560+
1561+ typedef boost::function <void (CompPoint)> UpdateProc;
1562+
1563+ CompositedPositionTracker (const compiz::window::Geometry &geom,
1564+ CompPoint diff,
1565+ UpdateProc f);
1566+ ~CompositedPositionTracker ();
1567+
1568+ void updatePosition (const CompPoint &dPosition);
1569+ void updateOffset (const CompPoint &dOffset);
1570+
1571+ CompPoint absolute ();
1572+ CompPoint diff ();
1573+
1574+protected:
1575+
1576+ bool dispatchUpdate ();
1577+
1578+private:
1579+
1580+ CompPoint lastPosition;
1581+ CompPoint currentPosition;
1582+
1583+ CompPoint lastOffset;
1584+ CompPoint currentOffset;
1585+
1586+ CompTimer updateHandle;
1587+ UpdateProc updateFunc;
1588+};
1589+
1590 class WobblyScreen :
1591 public PluginClassHandler<WobblyScreen, CompScreen>,
1592 public ScreenInterface,
1593@@ -272,8 +307,11 @@
1594 void enableWobbling (bool enabling);
1595 void initiateMapEffect ();
1596
1597+ void onMovement (CompPoint d);
1598+
1599 // WindowInterface methods
1600 void resizeNotify (int dx, int dy, int dwidth, int dheight);
1601+ bool position (compiz::window::Geometry &g, unsigned int source, unsigned int constrainment);
1602 void moveNotify (int dx, int dy, bool immediate);
1603 void grabNotify (int x, int y, unsigned int state, unsigned int mask);
1604 void ungrabNotify ();
1605@@ -281,6 +319,7 @@
1606
1607 // CompositeWindowInterface methods
1608 bool damageRect (bool, const CompRect &);
1609+ void applyOffset (const CompPoint &);
1610
1611 // GLWindowInterface methods
1612 bool glPaint (const GLWindowPaintAttrib &, const GLMatrix &,
1613@@ -295,11 +334,12 @@
1614 CompositeWindow *cWindow;
1615 GLWindow *gWindow;
1616
1617- Model *model;
1618- unsigned int wobblingMask;
1619- bool grabbed;
1620- bool velocity;
1621- unsigned int state;
1622+ Model *model;
1623+ unsigned int wobblingMask;
1624+ bool grabbed;
1625+ bool velocity;
1626+ unsigned int state;
1627+ CompositedPositionTracker tracker;
1628 };
1629
1630 class WobblyPluginVTable :
1631
1632=== modified file 'src/event.cpp'
1633--- src/event.cpp 2012-01-19 18:20:30 +0000
1634+++ src/event.cpp 2012-01-19 18:20:31 +0000
1635@@ -48,7 +48,7 @@
1636 {
1637 priv->syncWait = false;
1638
1639- if (window->resize (priv->syncGeometry))
1640+ if (resize (priv->syncGeometry))
1641 {
1642 window->windowNotify (CompWindowNotifySyncAlarm);
1643 }
1644@@ -1576,43 +1576,23 @@
1645 w = findWindow (event->xclient.window);
1646 if (w)
1647 {
1648- unsigned int xwcm = 0;
1649- XWindowChanges xwc;
1650- int gravity;
1651- int value_mask;
1652- unsigned int source;
1653+ compiz::window::Geometry g = w->serverGeometry ();
1654+ compiz::window::Geometry ng = compiz::window::Geometry (event->xclient.data.l[1],
1655+ event->xclient.data.l[2],
1656+ event->xclient.data.l[3],
1657+ event->xclient.data.l[4], 0);
1658+ int gravity;
1659+ int value_mask;
1660+ unsigned int source;
1661
1662 gravity = (event->xclient.data.l[0] & 0xFF);
1663 value_mask = (event->xclient.data.l[0] & 0xF00) >> 8;
1664 source = (event->xclient.data.l[0] & 0xF000) >> 12;
1665
1666- memset (&xwc, 0, sizeof (xwc));
1667-
1668- if (value_mask & CWX)
1669- {
1670- xwcm |= CWX;
1671- xwc.x = event->xclient.data.l[1];
1672- }
1673-
1674- if (value_mask & CWY)
1675- {
1676- xwcm |= CWY;
1677- xwc.y = event->xclient.data.l[2];
1678- }
1679-
1680- if (value_mask & CWWidth)
1681- {
1682- xwcm |= CWWidth;
1683- xwc.width = event->xclient.data.l[3];
1684- }
1685-
1686- if (value_mask & CWHeight)
1687- {
1688- xwcm |= CWHeight;
1689- xwc.height = event->xclient.data.l[4];
1690- }
1691-
1692- w->moveResize (&xwc, xwcm, gravity, source);
1693+ g.applyChange (ng, value_mask);
1694+
1695+ /* XXX: Gravity */
1696+ w->priv->moveResize (ng, value_mask, gravity, source);
1697 }
1698 }
1699 else if (event->xclient.message_type == Atoms::restackWindow)
1700@@ -1744,18 +1724,13 @@
1701 w = findWindow (event->xconfigurerequest.window);
1702 if (w && w->managed ())
1703 {
1704- XWindowChanges xwc;
1705-
1706- memset (&xwc, 0, sizeof (xwc));
1707-
1708- xwc.x = event->xconfigurerequest.x;
1709- xwc.y = event->xconfigurerequest.y;
1710- xwc.width = event->xconfigurerequest.width;
1711- xwc.height = event->xconfigurerequest.height;
1712- xwc.border_width = event->xconfigurerequest.border_width;
1713-
1714- w->moveResize (&xwc, event->xconfigurerequest.value_mask,
1715- 0, ClientTypeUnknown);
1716+ compiz::window::Geometry g (event->xconfigurerequest.x,
1717+ event->xconfigurerequest.y,
1718+ event->xconfigurerequest.width,
1719+ event->xconfigurerequest.height,
1720+ event->xconfigurerequest.border_width);
1721+
1722+ w->position (g, event->xconfigurerequest.value_mask, ClientTypeUnknown);
1723
1724 if (event->xconfigurerequest.value_mask & CWStackMode)
1725 {
1726@@ -1817,7 +1792,15 @@
1727 * is not override redirect, and may have changed
1728 * to being not override redirect */
1729 w->priv->setOverrideRedirect (false);
1730- w->configureXWindow (xwcm, &xwc);
1731+
1732+ compiz::window::Geometry g = w->geometry ();
1733+
1734+ g.applyChange (compiz::window::Geometry (xwc.x,
1735+ xwc.y,
1736+ xwc.width,
1737+ xwc.height,
1738+ xwc.border_width), xwcm);
1739+ w->position (g);
1740 }
1741 else
1742 XConfigureWindow (priv->dpy, event->xconfigurerequest.window,
1743@@ -1976,7 +1959,7 @@
1744 foreach (CompWindow *dw, dockWindows)
1745 {
1746 xwc.sibling = sibling;
1747- dw->configureXWindow (mask, &xwc);
1748+ dw->priv->configureXWindow (mask, &xwc);
1749 }
1750 }
1751 }
1752
1753=== modified file 'src/privatewindow.h'
1754--- src/privatewindow.h 2011-10-10 14:56:06 +0000
1755+++ src/privatewindow.h 2012-01-19 18:20:31 +0000
1756@@ -79,7 +79,10 @@
1757
1758 int restoreGeometry (XWindowChanges *xwc, int mask);
1759
1760- void reconfigureXWindow (unsigned int valueMask,
1761+ void configureXWindow (unsigned int valueMask,
1762+ XWindowChanges *xwc);
1763+
1764+ void applyConfigureXWindow (unsigned int valueMask,
1765 XWindowChanges *xwc);
1766
1767 static bool stackDocks (CompWindow *w,
1768@@ -103,11 +106,11 @@
1769
1770 CompWindow * getModalTransient ();
1771
1772- int addWindowSizeChanges (XWindowChanges *xwc,
1773- CompWindow::Geometry old);
1774+ unsigned int addWindowSizeChanges (compiz::window::Geometry &ng,
1775+ const compiz::window::Geometry &old);
1776
1777- int addWindowStackChanges (XWindowChanges *xwc,
1778- CompWindow *sibling);
1779+ unsigned int addWindowStackChanges (XWindowChanges *xwc,
1780+ CompWindow *sibling);
1781
1782 static CompWindow * findValidStackSiblingBelow (CompWindow *w,
1783 CompWindow *sibling);
1784@@ -135,6 +138,23 @@
1785 int width,
1786 int height);
1787
1788+ bool resize (XWindowAttributes);
1789+
1790+ bool resize (compiz::window::Geometry);
1791+
1792+ bool resize (int x, int y, int width, int height,
1793+ int border = 0);
1794+
1795+ void move (int dx, int dy, bool immediate = true);
1796+
1797+ void
1798+ moveResize (compiz::window::Geometry &ng,
1799+ unsigned int changeMask,
1800+ int gravity,
1801+ unsigned int source);
1802+
1803+ void syncPosition ();
1804+
1805 bool reparent ();
1806 void unreparent ();
1807
1808@@ -177,7 +197,9 @@
1809
1810 void circulate (XCirculateEvent *ce);
1811
1812- unsigned int adjustConfigureRequestForGravity (XWindowChanges *xwc,
1813+ CompOutput * selectOutputForGeometry (const compiz::window::Geometry &);
1814+
1815+ unsigned int adjustConfigureRequestForGravity (compiz::window::Geometry &,
1816 unsigned int xwcm,
1817 int gravity,
1818 int direction);
1819@@ -235,10 +257,10 @@
1820 * the class and override redirect state
1821 */
1822 XWindowAttributes attrib;
1823- CompWindow::Geometry geometry;
1824- CompWindow::Geometry serverGeometry;
1825- CompWindow::Geometry frameGeometry;
1826- CompWindow::Geometry serverFrameGeometry;
1827+ compiz::window::Geometry geometry;
1828+ compiz::window::Geometry serverGeometry;
1829+ compiz::window::Geometry frameGeometry;
1830+ compiz::window::Geometry serverFrameGeometry;
1831 Window transientFor;
1832 Window clientLeader;
1833 XSizeHints sizeHints;
1834@@ -326,7 +348,7 @@
1835 CompTimer syncWaitTimer;
1836
1837 bool syncWait;
1838- CompWindow::Geometry syncGeometry;
1839+ compiz::window::Geometry syncGeometry;
1840
1841 bool closeRequests;
1842 Time lastCloseRequestTime;
1843
1844=== modified file 'src/screen.cpp'
1845--- src/screen.cpp 2012-01-19 18:20:30 +0000
1846+++ src/screen.cpp 2012-01-19 18:20:31 +0000
1847@@ -1762,7 +1762,7 @@
1848 xwc.x = w->serverGeometry ().x () + moveX;
1849 xwc.y = w->serverGeometry ().y () + moveY;
1850
1851- w->configureXWindow (valueMask, &xwc);
1852+ w->priv->configureXWindow (valueMask, &xwc);
1853 }
1854 }
1855 }
1856@@ -3538,7 +3538,7 @@
1857 xwc.x = w->serverGeometry ().x () + pnt.x ();
1858 xwc.y = w->serverGeometry ().y () + pnt.y ();
1859
1860- w->configureXWindow (valueMask, &xwc);
1861+ w->priv->configureXWindow (valueMask, &xwc);
1862 }
1863
1864 if (sync)
1865@@ -3696,7 +3696,7 @@
1866 int
1867 CompScreen::outputDeviceForPoint (int x, int y)
1868 {
1869- CompWindow::Geometry geom (x, y, 1, 1, 0);
1870+ compiz::window::Geometry geom (x, y, 1, 1, 0);
1871
1872 return outputDeviceForGeometry (geom);
1873 }
1874@@ -3782,7 +3782,7 @@
1875 is currently computed as the viewport where the center of the window is
1876 located. */
1877 void
1878-CompScreen::viewportForGeometry (const CompWindow::Geometry& gm,
1879+CompScreen::viewportForGeometry (const compiz::window::Geometry& gm,
1880 CompPoint& viewport)
1881 {
1882 CompRect rect (gm);
1883@@ -3801,7 +3801,7 @@
1884 }
1885
1886 int
1887-CompScreen::outputDeviceForGeometry (const CompWindow::Geometry& gm)
1888+CompScreen::outputDeviceForGeometry (const compiz::window::Geometry& gm)
1889 {
1890 int overlapAreas[priv->outputDevs.size ()];
1891 int highest, seen, highestScore;
1892
1893=== modified file 'src/window.cpp'
1894--- src/window.cpp 2012-01-19 18:20:30 +0000
1895+++ src/window.cpp 2012-01-19 18:20:31 +0000
1896@@ -795,14 +795,6 @@
1897 if (!serverFrame)
1898 return;
1899
1900-
1901- gettimeofday (&lastConfigureRequest, NULL);
1902- /* Flush any changes made to serverFrameGeometry or serverGeometry to the server
1903- * since there is a race condition where geometries will go out-of-sync with
1904- * window movement */
1905-
1906- window->syncPosition ();
1907-
1908 if (serverInput.left || serverInput.right || serverInput.top || serverInput.bottom)
1909 {
1910 int bw = serverGeometry.border () * 2;
1911@@ -1123,8 +1115,8 @@
1912
1913 for (unsigned int i = 0; i < n; i++)
1914 {
1915- x1 = rects[i].x + priv->geometry.border ();
1916- y1 = rects[i].y + priv->geometry.border ();
1917+ x1 = rects[i].x + priv->serverGeometry.border ();
1918+ y1 = rects[i].y + priv->serverGeometry.border ();
1919 x2 = x1 + rects[i].width;
1920 y2 = y1 + rects[i].height;
1921
1922@@ -1139,10 +1131,10 @@
1923
1924 if (y1 < y2 && x1 < x2)
1925 {
1926- x1 += priv->geometry.x ();
1927- y1 += priv->geometry.y ();
1928- x2 += priv->geometry.x ();
1929- y2 += priv->geometry.y ();
1930+ x1 += priv->serverGeometry.x ();
1931+ y1 += priv->serverGeometry.y ();
1932+ x2 += priv->serverGeometry.x ();
1933+ y2 += priv->serverGeometry.y ();
1934
1935 ret += CompRect (x1, y1, x2 - x1, y2 - y1);
1936 }
1937@@ -1177,10 +1169,13 @@
1938
1939 }
1940
1941- r.x = -priv->geometry.border ();
1942- r.y = -priv->geometry.border ();
1943- r.width = priv->width + priv->geometry.border ();
1944- r.height = priv->height + priv->geometry.border ();
1945+ /* XShapeGetRectangles is a synchronous request
1946+ * so use the geometry last sent to the server */
1947+
1948+ r.x = -priv->serverGeometry.border ();
1949+ r.y = -priv->serverGeometry.border ();
1950+ r.width = priv->serverGeometry.width () + priv->serverGeometry.border ();
1951+ r.height = priv->serverGeometry.height () + priv->serverGeometry.border ();
1952
1953 if (nBounding < 1)
1954 {
1955@@ -1678,22 +1673,26 @@
1956
1957 if (priv->unmanaging)
1958 {
1959- XWindowChanges xwc;
1960+ compiz::window::Geometry ng = priv->serverGeometry;
1961 unsigned int xwcm;
1962 int gravity = priv->sizeHints.win_gravity;
1963
1964 /* revert gravity adjustment made at MapNotify time */
1965- xwc.x = priv->serverGeometry.x ();
1966- xwc.y = priv->serverGeometry.y ();
1967- xwc.width = 0;
1968- xwc.height = 0;
1969-
1970- xwcm = priv->adjustConfigureRequestForGravity (&xwc,
1971- CWX | CWY,
1972+ xwcm = priv->adjustConfigureRequestForGravity (ng,
1973+ CHANGE_X | CHANGE_Y,
1974 gravity,
1975 -1);
1976+
1977+ XWindowChanges xwc;
1978+
1979+ xwc.x = ng.x ();
1980+ xwc.y = ng.y ();
1981+ xwc.width = ng.width ();
1982+ xwc.height = ng.height ();
1983+ xwc.border_width = ng.border ();
1984+
1985 if (xwcm)
1986- configureXWindow (xwcm, &xwc);
1987+ priv->configureXWindow (xwcm, &xwc);
1988
1989 priv->unmanaging = false;
1990 }
1991@@ -1781,24 +1780,24 @@
1992 }
1993
1994 bool
1995-CompWindow::resize (XWindowAttributes attr)
1996-{
1997- return resize (Geometry (attr.x, attr.y, attr.width, attr.height,
1998- attr.border_width));
1999-}
2000-
2001-bool
2002-CompWindow::resize (int x,
2003- int y,
2004- int width,
2005- int height,
2006- int border)
2007-{
2008- return resize (Geometry (x, y, width, height, border));
2009-}
2010-
2011-bool
2012-CompWindow::resize (CompWindow::Geometry gm)
2013+PrivateWindow::resize (XWindowAttributes attr)
2014+{
2015+ return resize (compiz::window::Geometry (attr.x, attr.y, attr.width, attr.height,
2016+ attr.border_width));
2017+}
2018+
2019+bool
2020+PrivateWindow::resize (int x,
2021+ int y,
2022+ int width,
2023+ int height,
2024+ int border)
2025+{
2026+ return resize (compiz::window::Geometry (x, y, width, height, border));
2027+}
2028+
2029+bool
2030+PrivateWindow::resize (compiz::window::Geometry gm)
2031 {
2032 /* Input extents are now the last thing sent
2033 * from the server. This might not work in some
2034@@ -1833,10 +1832,12 @@
2035 priv->width = pw;
2036 priv->height = ph;
2037
2038+ /* Update the entire region again here */
2039+
2040 if (priv->mapNum)
2041 priv->updateRegion ();
2042
2043- resizeNotify (dx, dy, dwidth, dheight);
2044+ window->resizeNotify (dx, dy, dwidth, dheight);
2045
2046 priv->invisible = WINDOW_INVISIBLE (priv);
2047 }
2048@@ -1850,17 +1851,12 @@
2049 priv->geometry.setX (gm.x ());
2050 priv->geometry.setY (gm.y ());
2051
2052- priv->region.translate (dx, dy);
2053- priv->inputRegion.translate (dx, dy);
2054- if (!priv->frameRegion.isEmpty ())
2055- priv->frameRegion.translate (dx, dy);
2056-
2057 priv->invisible = WINDOW_INVISIBLE (priv);
2058
2059- moveNotify (dx, dy, true);
2060+ window->moveNotify (dx, dy, true);
2061 }
2062
2063- updateFrameRegion ();
2064+ window->updateFrameRegion ();
2065
2066 return true;
2067 }
2068@@ -2034,7 +2030,7 @@
2069 ce->border_width);
2070 }
2071
2072- window->resize (ce->x, ce->y, ce->width, ce->height, ce->border_width);
2073+ resize (ce->x, ce->y, ce->width, ce->height, ce->border_width);
2074 }
2075
2076 if (ce->event == screen->root ())
2077@@ -2111,11 +2107,10 @@
2078 /* set the frame geometry */
2079 priv->frameGeometry.set (ce->x, ce->y, ce->width, ce->height, ce->border_width);
2080
2081-
2082 if (priv->syncWait)
2083 priv->syncGeometry.set (x, y, width, height, ce->border_width);
2084 else
2085- window->resize (x, y, width, height, ce->border_width);
2086+ resize (x, y, width, height, ce->border_width);
2087
2088 if (priv->restack (ce->above))
2089 priv->updatePassiveButtonGrabs ();
2090@@ -2161,50 +2156,27 @@
2091 }
2092
2093 void
2094-CompWindow::move (int dx,
2095- int dy,
2096- bool immediate)
2097+PrivateWindow::move (int dx,
2098+ int dy,
2099+ bool immediate)
2100 {
2101 if (dx || dy)
2102 {
2103 gettimeofday (&priv->lastGeometryUpdate, NULL);
2104
2105- /* Don't allow window movement to overwrite working geometries
2106- * last received from the server if we know there are pending
2107- * ConfigureNotify events on this window. That's a clunky workaround
2108- * and a FIXME in any case, however, until we can break the API
2109- * and remove CompWindow::move, this will need to be the case */
2110-
2111- if (!priv->pendingConfigures.pending ())
2112- {
2113- priv->geometry.setX (priv->geometry.x () + dx);
2114- priv->geometry.setY (priv->geometry.y () + dy);
2115- priv->frameGeometry.setX (priv->frameGeometry.x () + dx);
2116- priv->frameGeometry.setY (priv->frameGeometry.y () + dy);
2117-
2118- priv->pendingPositionUpdates = true;
2119-
2120- priv->region.translate (dx, dy);
2121- priv->inputRegion.translate (dx, dy);
2122- if (!priv->frameRegion.isEmpty ())
2123- priv->frameRegion.translate (dx, dy);
2124-
2125- priv->invisible = WINDOW_INVISIBLE (priv);
2126-
2127- moveNotify (dx, dy, immediate);
2128- }
2129- else
2130- {
2131- XWindowChanges xwc;
2132- unsigned int valueMask = CWX | CWY;
2133- compLogMessage ("core", CompLogLevelDebug, "pending configure notifies on 0x%x, "\
2134- "moving window asyncrhonously!", (unsigned int) priv->serverId);
2135-
2136- xwc.x = priv->serverGeometry.x () + dx;
2137- xwc.y = priv->serverGeometry.y () + dy;
2138-
2139- configureXWindow (valueMask, &xwc);
2140- }
2141+ priv->geometry.setX (priv->geometry.x () + dx);
2142+ priv->geometry.setY (priv->geometry.y () + dy);
2143+ priv->frameGeometry.setX (priv->frameGeometry.x () + dx);
2144+ priv->frameGeometry.setY (priv->frameGeometry.y () + dy);
2145+
2146+ priv->region.translate (dx, dy);
2147+ priv->inputRegion.translate (dx, dy);
2148+ if (!priv->frameRegion.isEmpty ())
2149+ priv->frameRegion.translate (dx, dy);
2150+
2151+ priv->invisible = WINDOW_INVISIBLE (priv);
2152+
2153+ window->moveNotify (dx, dy, immediate);
2154 }
2155 }
2156
2157@@ -2473,7 +2445,7 @@
2158 }
2159
2160 void
2161-CompWindow::syncPosition ()
2162+PrivateWindow::syncPosition ()
2163 {
2164 gettimeofday (&priv->lastConfigureRequest, NULL);
2165
2166@@ -2515,13 +2487,13 @@
2167 priv->mClearCheckTimeout.stop ();
2168 priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
2169 2000, 2500);
2170- XConfigureWindow (screen->dpy (), ROOTPARENT (this), valueMask, &xwc);
2171+ XConfigureWindow (screen->dpy (), ROOTPARENT (window), valueMask, &xwc);
2172
2173 if (priv->serverFrame)
2174 {
2175 XMoveWindow (screen->dpy (), priv->wrapper,
2176 priv->serverInput.left, priv->serverInput.top);
2177- sendConfigureNotify ();
2178+ window->sendConfigureNotify ();
2179 }
2180 }
2181 priv->pendingPositionUpdates = false;
2182@@ -2564,67 +2536,102 @@
2183 return false;
2184 }
2185
2186-void
2187-CompWindow::validateResizeRequest (unsigned int &mask,
2188- XWindowChanges *xwc,
2189- unsigned int source)
2190+bool
2191+CompWindow::position (compiz::window::Geometry &g,
2192+ unsigned int source,
2193+ unsigned int constrainment)
2194 {
2195- WRAPABLE_HND_FUNCTN (validateResizeRequest, mask, xwc, source)
2196+ WRAPABLE_HND_FUNCTN_RETURN (bool, position, g, source, constrainment)
2197+
2198+ unsigned int changeMask = priv->serverGeometry.changeMask (g);
2199
2200 if (!(priv->type & (CompWindowTypeDockMask |
2201 CompWindowTypeFullscreenMask |
2202 CompWindowTypeUnknownMask)))
2203 {
2204- if (mask & CWY)
2205+ if (changeMask & CHANGE_Y)
2206 {
2207 int min, max;
2208
2209 min = screen->workArea ().y () + priv->input.top;
2210 max = screen->workArea ().bottom ();
2211
2212+ /* Sticky windows can't go offscreen */
2213 if (priv->state & CompWindowStateStickyMask &&
2214- (xwc->y < min || xwc->y > max))
2215+ (g.y () < min || g.y () > max) &&
2216+ constrainment & compiz::window::ConstrainPositionWorkarea)
2217 {
2218- xwc->y = priv->serverGeometry.y ();
2219+ g.setY (priv->serverGeometry.y ());
2220 }
2221- else
2222+ else if (constrainment & compiz::window::ConstrainPositionVirtualScreen)
2223 {
2224+ /* Otherwise, don't wrap around workspaces */
2225 min -= screen->vp ().y () * screen->height ();
2226 max += (screen->vpSize ().height () - screen->vp ().y () - 1) *
2227 screen->height ();
2228
2229- if (xwc->y < min)
2230- xwc->y = min;
2231- else if (xwc->y > max)
2232- xwc->y = max;
2233+ if (g.y () < min)
2234+ g.setY (min);
2235+ else if (g.y () > max)
2236+ g.setY (max);
2237 }
2238 }
2239
2240- if (mask & CWX)
2241+ if (changeMask & CHANGE_X)
2242 {
2243 int min, max;
2244
2245 min = screen->workArea ().x () + priv->input.left;
2246 max = screen->workArea ().right ();
2247
2248+ /* Sticky windows can't go offscreen */
2249 if (priv->state & CompWindowStateStickyMask &&
2250- (xwc->x < min || xwc->x > max))
2251+ (g.x () < min || g.x () > max) &&
2252+ constrainment & compiz::window::ConstrainPositionWorkarea)
2253 {
2254- xwc->x = priv->serverGeometry.x ();
2255+ g.setX (priv->serverGeometry.x ());
2256 }
2257- else
2258+ else if (constrainment & compiz::window::ConstrainPositionVirtualScreen)
2259 {
2260+ /* Otherwise, don't wrap around workspaces */
2261 min -= screen->vp ().x () * screen->width ();
2262 max += (screen->vpSize ().width () - screen->vp ().x () - 1) *
2263 screen->width ();
2264
2265- if (xwc->x < min)
2266- xwc->x = min;
2267- else if (xwc->x > max)
2268- xwc->x = max;
2269+ if (g.x () < min)
2270+ g.setX (min);
2271+ else if (g.x () > max)
2272+ g.setX (max);
2273 }
2274 }
2275 }
2276+
2277+ if (changeMask)
2278+ {
2279+ XWindowChanges xwc;
2280+ CompPoint dp = g.pos () - priv->serverGeometry.pos ();
2281+
2282+ xwc.x = g.x ();
2283+ xwc.y = g.y ();
2284+ xwc.width = g.width ();
2285+ xwc.height = g.height ();
2286+ xwc.border_width = g.border ();
2287+
2288+ priv->configureXWindow (changeMask, &xwc);
2289+
2290+ /* Also translate regions but don't do a full update
2291+ * since that involves round trips to get the shape
2292+ * rectangles and is slow. */
2293+
2294+ priv->region.translate (dp);
2295+ priv->inputRegion.translate (dp);
2296+ if (!priv->frameRegion.isEmpty ())
2297+ priv->frameRegion.translate (dp);
2298+
2299+ return true;
2300+ }
2301+
2302+ return false;
2303 }
2304
2305 void
2306@@ -2640,8 +2647,7 @@
2307 bool immediate)
2308 WRAPABLE_HND_FUNCTN (moveNotify, dx, dy, immediate)
2309
2310-void
2311-CompWindow::windowNotify (CompWindowNotify n)
2312+void CompWindow::windowNotify (CompWindowNotify n)
2313 WRAPABLE_HND_FUNCTN (windowNotify, n)
2314
2315 void
2316@@ -2654,6 +2660,7 @@
2317 priv->grabbed = true;
2318 }
2319
2320+
2321 void
2322 CompWindow::ungrabNotify ()
2323 {
2324@@ -2683,7 +2690,7 @@
2325 xwc.x = serverGeometry ().x () + (screen->vp ().x () - vp.x ()) * screen->width ();
2326 xwc.y = serverGeometry ().y () + (screen->vp ().y () - vp.y ()) * screen->height ();
2327
2328- configureXWindow (valueMask, &xwc);
2329+ priv->configureXWindow (valueMask, &xwc);
2330 }
2331 }
2332 }
2333@@ -3334,17 +3341,11 @@
2334 }
2335
2336 void
2337-PrivateWindow::reconfigureXWindow (unsigned int valueMask,
2338+PrivateWindow::applyConfigureXWindow (unsigned int valueMask,
2339 XWindowChanges *xwc)
2340 {
2341 unsigned int frameValueMask = 0;
2342
2343- /* Immediately sync window position
2344- * if plugins were updating w->geometry () directly
2345- * in order to avoid a race condition */
2346-
2347- window->syncPosition ();
2348-
2349 /* Remove redundant bits */
2350
2351 if (valueMask & CWX && serverGeometry.x () == xwc->x)
2352@@ -3686,8 +3687,8 @@
2353 }
2354
2355 void
2356-CompWindow::configureXWindow (unsigned int valueMask,
2357- XWindowChanges *xwc)
2358+PrivateWindow::configureXWindow (unsigned int valueMask,
2359+ XWindowChanges *xwc)
2360 {
2361 if (priv->managed && (valueMask & (CWSibling | CWStackMode)))
2362 {
2363@@ -3695,7 +3696,7 @@
2364 CompWindowList ancestors;
2365 CompWindowList docks;
2366
2367- /* Since the window list is being reordered in reconfigureXWindow
2368+ /* Since the window list is being reordered in applyConfigureXWindow
2369 the list of windows which need to be restacked must be stored
2370 first. The windows are stacked in the opposite order than they
2371 were previously stacked, in order that they are above xwc->sibling
2372@@ -3703,29 +3704,29 @@
2373 have to restack all the windows again. */
2374
2375 /* transient children above */
2376- if (PrivateWindow::stackTransients (this, NULL, xwc, transients))
2377+ if (PrivateWindow::stackTransients (window, NULL, xwc, transients))
2378 {
2379 /* ancestors, siblings and sibling transients below */
2380- PrivateWindow::stackAncestors (this, xwc, ancestors);
2381+ PrivateWindow::stackAncestors (window, xwc, ancestors);
2382
2383 for (CompWindowList::reverse_iterator w = ancestors.rbegin ();
2384 w != ancestors.rend (); w++)
2385 {
2386- (*w)->priv->reconfigureXWindow (CWSibling | CWStackMode, xwc);
2387+ (*w)->priv->applyConfigureXWindow (CWSibling | CWStackMode, xwc);
2388 xwc->sibling = ROOTPARENT (*w);
2389 }
2390
2391- this->priv->reconfigureXWindow (valueMask, xwc);
2392- xwc->sibling = ROOTPARENT (this);
2393+ this->priv->applyConfigureXWindow (valueMask, xwc);
2394+ xwc->sibling = ROOTPARENT (window);
2395
2396 for (CompWindowList::reverse_iterator w = transients.rbegin ();
2397 w != transients.rend (); w++)
2398 {
2399- (*w)->priv->reconfigureXWindow (CWSibling | CWStackMode, xwc);
2400+ (*w)->priv->applyConfigureXWindow (CWSibling | CWStackMode, xwc);
2401 xwc->sibling = ROOTPARENT (*w);
2402 }
2403
2404- if (PrivateWindow::stackDocks (this, docks, xwc, &valueMask))
2405+ if (PrivateWindow::stackDocks (window, docks, xwc, &valueMask))
2406 {
2407 Window sibling = xwc->sibling;
2408 xwc->stack_mode = Above;
2409@@ -3734,31 +3735,21 @@
2410 foreach (CompWindow *dw, docks)
2411 {
2412 xwc->sibling = sibling;
2413- dw->priv->reconfigureXWindow (valueMask, xwc);
2414+ dw->priv->applyConfigureXWindow (valueMask, xwc);
2415 }
2416 }
2417 }
2418 }
2419 else if (priv->id)
2420 {
2421- priv->reconfigureXWindow (valueMask, xwc);
2422+ priv->applyConfigureXWindow (valueMask, xwc);
2423 }
2424 }
2425
2426-int
2427-PrivateWindow::addWindowSizeChanges (XWindowChanges *xwc,
2428- CompWindow::Geometry old)
2429+CompOutput *
2430+PrivateWindow::selectOutputForGeometry (const compiz::window::Geometry &old)
2431 {
2432- CompRect workArea;
2433- int mask = 0;
2434- int x, y;
2435 CompOutput *output;
2436- CompPoint viewport;
2437-
2438- screen->viewportForGeometry (old, viewport);
2439-
2440- x = (viewport.x () - screen->vp ().x ()) * screen->width ();
2441- y = (viewport.y () - screen->vp ().y ()) * screen->height ();
2442
2443 /* Try to select and output device that the window is on first
2444 * and make sure if we are fullscreening or maximizing that the
2445@@ -3770,8 +3761,8 @@
2446 if (state & CompWindowStateFullscreenMask ||
2447 state & CompWindowStateMaximizedHorzMask)
2448 {
2449- int width = (mask & CWWidth) ? xwc->width : old.width ();
2450- int height = (mask & CWHeight) ? xwc->height : old.height ();
2451+ int width = old.width ();
2452+ int height = old.height ();
2453
2454 window->constrainNewWindowSize (width, height, &width, &height);
2455
2456@@ -3803,8 +3794,8 @@
2457 if (state & CompWindowStateFullscreenMask ||
2458 state & CompWindowStateMaximizedVertMask)
2459 {
2460- int width = (mask & CWWidth) ? xwc->width : old.width ();
2461- int height = (mask & CWHeight) ? xwc->height : old.height ();
2462+ int width = old.width ();
2463+ int height = old.height ();
2464
2465 window->constrainNewWindowSize (width, height, &width, &height);
2466
2467@@ -3833,117 +3824,146 @@
2468 }
2469 }
2470
2471+ return output;
2472+}
2473+
2474+unsigned int
2475+PrivateWindow::addWindowSizeChanges (compiz::window::Geometry &ng,
2476+ const compiz::window::Geometry &old)
2477+{
2478+ CompRect workArea;
2479+ unsigned int changeMask = 0;
2480+ int x, y;
2481+ CompOutput *output;
2482+ CompPoint viewport;
2483+
2484+ screen->viewportForGeometry (old, viewport);
2485+
2486+ x = (viewport.x () - screen->vp ().x ()) * screen->width ();
2487+ y = (viewport.y () - screen->vp ().y ()) * screen->height ();
2488+
2489+ /* XXX: This was old.applyChange (n, mask), but mask
2490+ * is always zero at this point */
2491+ output = selectOutputForGeometry (old);
2492 workArea = output->workArea ();
2493
2494 if (type & CompWindowTypeFullscreenMask)
2495 {
2496- saveGeometry (CWX | CWY | CWWidth | CWHeight | CWBorderWidth);
2497+ saveGeometry (CHANGE_X | CHANGE_Y | CHANGE_WIDTH | CHANGE_HEIGHT | CHANGE_BORDER);
2498
2499 if (fullscreenMonitorsSet)
2500 {
2501- xwc->x = x + fullscreenMonitorRect.x ();
2502- xwc->y = y + fullscreenMonitorRect.y ();
2503- xwc->width = fullscreenMonitorRect.width ();
2504- xwc->height = fullscreenMonitorRect.height ();
2505+ ng = compiz::window::Geometry (x + fullscreenMonitorRect.x (),
2506+ y + fullscreenMonitorRect.y (),
2507+ fullscreenMonitorRect.width (),
2508+ fullscreenMonitorRect.height (), 0);
2509 }
2510 else
2511 {
2512- xwc->x = x + output->x ();
2513- xwc->y = y + output->y ();
2514- xwc->width = output->width ();
2515- xwc->height = output->height ();
2516+ ng = compiz::window::Geometry (x + output->x (),
2517+ y + output->y (),
2518+ width + output->width (),
2519+ height + output->height (), 0);
2520 }
2521
2522- xwc->border_width = 0;
2523-
2524- mask |= CWX | CWY | CWWidth | CWHeight | CWBorderWidth;
2525+ changeMask |= CHANGE_X | CHANGE_Y | CHANGE_WIDTH | CHANGE_HEIGHT | CHANGE_BORDER;
2526 }
2527 else
2528 {
2529- mask |= restoreGeometry (xwc, CWBorderWidth);
2530+ XWindowChanges xwc;
2531+
2532+ changeMask |= restoreGeometry (&xwc, CHANGE_BORDER);
2533+
2534 if (state & CompWindowStateMaximizedVertMask)
2535 {
2536- saveGeometry (CWY | CWHeight);
2537-
2538- xwc->height = workArea.height () - border.top -
2539- border.bottom - old.border () * 2;
2540-
2541- mask |= CWHeight;
2542+ saveGeometry (CHANGE_Y | CHANGE_HEIGHT);
2543+
2544+ ng.setHeight (workArea.height () - border.top - border.bottom - old.border () * 2);
2545+
2546+ changeMask |= CHANGE_HEIGHT;
2547 }
2548 else
2549 {
2550- mask |= restoreGeometry (xwc, CWY | CWHeight);
2551+ changeMask |= restoreGeometry (&xwc, CHANGE_Y | CHANGE_HEIGHT);
2552 }
2553
2554 if (state & CompWindowStateMaximizedHorzMask)
2555 {
2556- saveGeometry (CWX | CWWidth);
2557-
2558- xwc->width = workArea.width () - border.left -
2559- border.right - old.border () * 2;
2560-
2561- mask |= CWWidth;
2562+ saveGeometry (CHANGE_X | CHANGE_WIDTH);
2563+
2564+ ng.setWidth (workArea.width () - border.left - border.right - old.border () * 2);
2565+
2566+ changeMask |= CHANGE_WIDTH;
2567 }
2568 else
2569 {
2570- mask |= restoreGeometry (xwc, CWX | CWWidth);
2571+ changeMask |= restoreGeometry (&xwc, CHANGE_X | CHANGE_WIDTH);
2572 }
2573
2574+ compiz::window::Geometry xg = compiz::window::Geometry (xwc.x,
2575+ xwc.y,
2576+ xwc.width,
2577+ xwc.height,
2578+ xwc.border_width);
2579+
2580+ ng.applyChange (xg, changeMask);
2581+
2582 /* constrain window width if smaller than minimum width */
2583- if (!(mask & CWWidth) && (int) old.width () < sizeHints.min_width)
2584+ if (!(changeMask & CHANGE_WIDTH) && old.width () < sizeHints.min_width)
2585 {
2586- xwc->width = sizeHints.min_width;
2587- mask |= CWWidth;
2588+ ng.setWidth (sizeHints.min_width);
2589+ changeMask |= CHANGE_WIDTH;
2590 }
2591
2592 /* constrain window width if greater than maximum width */
2593- if (!(mask & CWWidth) && (int) old.width () > sizeHints.max_width)
2594+ if (!(changeMask & CHANGE_WIDTH) && old.width () > sizeHints.max_width)
2595 {
2596- xwc->width = sizeHints.max_width;
2597- mask |= CWWidth;
2598+ ng.setWidth (sizeHints.max_width);
2599+ changeMask |= CHANGE_WIDTH;
2600 }
2601
2602 /* constrain window height if smaller than minimum height */
2603- if (!(mask & CWHeight) && (int) old.height () < sizeHints.min_height)
2604+ if (!(changeMask & CHANGE_HEIGHT) && old.height () < sizeHints.min_height)
2605 {
2606- xwc->height = sizeHints.min_height;
2607- mask |= CWHeight;
2608+ ng.setHeight (sizeHints.min_height);
2609+ changeMask |= CHANGE_HEIGHT;
2610 }
2611
2612 /* constrain window height if greater than maximum height */
2613- if (!(mask & CWHeight) && (int) old.height () > sizeHints.max_height)
2614+ if (!(changeMask & CHANGE_HEIGHT) && old.height () > sizeHints.max_height)
2615 {
2616- xwc->height = sizeHints.max_height;
2617- mask |= CWHeight;
2618+ ng.setHeight (sizeHints.max_height);
2619+ changeMask |= CHANGE_HEIGHT;
2620 }
2621
2622- if (mask & (CWWidth | CWHeight))
2623+ if (changeMask & (CHANGE_WIDTH | CHANGE_HEIGHT))
2624 {
2625+ compiz::window::Geometry constrained = old;
2626 int width, height, max;
2627
2628- width = (mask & CWWidth) ? xwc->width : old.width ();
2629- height = (mask & CWHeight) ? xwc->height : old.height ();
2630+ constrained.applyChange (ng, changeMask);
2631+ ng.setSize (CompSize (old.width (), old.height ()));
2632
2633- xwc->width = old.width ();
2634- xwc->height = old.height ();
2635+ width = constrained.width ();
2636+ height = constrained.height ();
2637
2638 window->constrainNewWindowSize (width, height, &width, &height);
2639
2640 if (width != (int) old.width ())
2641 {
2642- mask |= CWWidth;
2643- xwc->width = width;
2644+ changeMask |= CHANGE_WIDTH;
2645+ ng.setWidth (width);
2646 }
2647 else
2648- mask &= ~CWWidth;
2649+ changeMask &= ~CHANGE_WIDTH;
2650
2651 if (height != (int) old.height ())
2652 {
2653- mask |= CWHeight;
2654- xwc->height = height;
2655+ changeMask |= CHANGE_HEIGHT;
2656+ ng.setHeight (height);
2657 }
2658 else
2659- mask &= ~CWHeight;
2660+ changeMask &= ~CHANGE_HEIGHT;
2661
2662 if (state & CompWindowStateMaximizedVertMask)
2663 {
2664@@ -3951,8 +3971,8 @@
2665 * by the gravity value (so that the corner that the gravity specifies
2666 * is 'anchored' to that edge of the workarea) */
2667
2668- xwc->y = y + workArea.y () + border.top;
2669- mask |= CWY;
2670+ ng.setY (y + workArea.y () + border.top);
2671+ changeMask |= CHANGE_Y;
2672
2673 switch (priv->sizeHints.win_gravity)
2674 {
2675@@ -3960,13 +3980,13 @@
2676 case SouthEastGravity:
2677 case SouthGravity:
2678 /* Shift the window so that the bottom meets the top of the bottom */
2679- height = xwc->height + old.border () * 2;
2680+ height = ng.height () + old.border () * 2;
2681
2682 max = y + workArea.bottom ();
2683- if (xwc->y + xwc->height + border.bottom > max)
2684+ if (ng.y () + ng.height () + border.bottom > max)
2685 {
2686- xwc->y = max - height - border.bottom;
2687- mask |= CWY;
2688+ ng.setY (max - height - border.bottom);
2689+ changeMask |= CHANGE_Y;
2690 }
2691 break;
2692 /* For EastGravity, WestGravity and CenterGravity we default to the top
2693@@ -3988,29 +4008,29 @@
2694
2695 if (state & CompWindowStateMaximizedHorzMask)
2696 {
2697- xwc->x = x + workArea.x () + border.left;
2698- mask |= CWX;
2699+ ng.setX (x + workArea.x () + border.left);
2700+ changeMask |= CHANGE_X;
2701
2702 switch (priv->sizeHints.win_gravity)
2703 {
2704 case NorthEastGravity:
2705 case SouthEastGravity:
2706 case EastGravity:
2707- width = xwc->width + old.border () * 2;
2708+ width = ng.width () + old.border () * 2;
2709
2710 max = x + workArea.right ();
2711
2712 if (old.x () + (int) old.width () + border.right > max)
2713 {
2714- xwc->x = max - width - border.right;
2715- mask |= CWX;
2716+ ng.setX (max - width - border.right);
2717+ changeMask |= CHANGE_X;
2718 }
2719 else if (old.x () + width + border.right > max)
2720 {
2721- xwc->x = x + workArea.x () +
2722+ ng.setX (x + workArea.x () +
2723 (workArea.width () - border.left - width -
2724- border.right) / 2 + border.left;
2725- mask |= CWX;
2726+ border.right) / 2 + border.left);
2727+ changeMask |= CHANGE_X;
2728 }
2729 /* For NorthGravity, SouthGravity and CenterGravity we default to the top
2730 * of the window since the user should at least be able to close it
2731@@ -4030,244 +4050,209 @@
2732 }
2733 }
2734
2735- if ((mask & CWX) && (xwc->x == old.x ()))
2736- mask &= ~CWX;
2737-
2738- if ((mask & CWY) && (xwc->y == old.y ()))
2739- mask &= ~CWY;
2740-
2741- if ((mask & CWWidth) && (xwc->width == (int) old.width ()))
2742- mask &= ~CWWidth;
2743-
2744- if ((mask & CWHeight) && (xwc->height == (int) old.height ()))
2745- mask &= ~CWHeight;
2746-
2747- return mask;
2748+ /* Only keep bits that have changed */
2749+ changeMask &= ng.changeMask (old);
2750+
2751+ return changeMask;
2752 }
2753
2754 unsigned int
2755-PrivateWindow::adjustConfigureRequestForGravity (XWindowChanges *xwc,
2756- unsigned int xwcm,
2757- int gravity,
2758- int direction)
2759+PrivateWindow::adjustConfigureRequestForGravity (compiz::window::Geometry &ng,
2760+ unsigned int changeMask,
2761+ int gravity,
2762+ int direction)
2763 {
2764- int newX, newY;
2765+ compiz::window::Geometry og (ng);
2766 unsigned int mask = 0;
2767
2768- newX = xwc->x;
2769- newY = xwc->y;
2770-
2771- if (xwcm & (CWX | CWWidth))
2772- {
2773- switch (gravity) {
2774- case NorthWestGravity:
2775- case WestGravity:
2776- case SouthWestGravity:
2777- if (xwcm & CWX)
2778- newX += priv->border.left * direction;
2779- break;
2780-
2781- case NorthGravity:
2782- case CenterGravity:
2783- case SouthGravity:
2784- if (xwcm & CWX)
2785- newX -= (xwc->width / 2 - priv->border.left +
2786- (priv->border.left + priv->border.right) / 2) * direction;
2787- else
2788- newX -= (xwc->width - priv->serverGeometry.width ()) * direction;
2789- break;
2790-
2791- case NorthEastGravity:
2792- case EastGravity:
2793- case SouthEastGravity:
2794- if (xwcm & CWX)
2795- newX -= xwc->width + priv->border.right * direction;
2796- else
2797- newX -= (xwc->width - priv->serverGeometry.width ()) * direction;
2798- break;
2799-
2800- case StaticGravity:
2801- default:
2802- break;
2803- }
2804- }
2805-
2806- if (xwcm & (CWY | CWHeight))
2807- {
2808- switch (gravity) {
2809- case NorthWestGravity:
2810- case NorthGravity:
2811- case NorthEastGravity:
2812- if (xwcm & CWY)
2813- newY = xwc->y + priv->border.top * direction;
2814- break;
2815-
2816- case WestGravity:
2817- case CenterGravity:
2818- case EastGravity:
2819- if (xwcm & CWY)
2820- newY -= (xwc->height / 2 - priv->border.top +
2821- (priv->border.top + priv->border.bottom) / 2) * direction;
2822- else
2823- newY -= ((xwc->height - priv->serverGeometry.height ()) / 2) * direction;
2824- break;
2825-
2826- case SouthWestGravity:
2827- case SouthGravity:
2828- case SouthEastGravity:
2829- if (xwcm & CWY)
2830- newY -= xwc->height + priv->border.bottom * direction;
2831- else
2832- newY -= (xwc->height - priv->serverGeometry.height ()) * direction;
2833- break;
2834-
2835- case StaticGravity:
2836- default:
2837- break;
2838- }
2839- }
2840-
2841- if (newX != xwc->x)
2842- {
2843- xwc->x += (newX - xwc->x);
2844- mask |= CWX;
2845- }
2846-
2847- if (newY != xwc->y)
2848- {
2849- xwc->y += (newY - xwc->y);
2850- mask |= CWY;
2851- }
2852+ if (changeMask & (CHANGE_X | CHANGE_WIDTH))
2853+ {
2854+ switch (gravity) {
2855+ case NorthWestGravity:
2856+ case WestGravity:
2857+ case SouthWestGravity:
2858+ if (changeMask & CWX)
2859+ ng.setX (ng.x () + priv->border.left * direction);
2860+ break;
2861+
2862+ case NorthGravity:
2863+ case CenterGravity:
2864+ case SouthGravity:
2865+ if (changeMask & CWX)
2866+ ng.setX (ng.x () - (ng.width () / 2 - priv->border.left +
2867+ (priv->border.left + priv->border.right) / 2) * direction);
2868+ else
2869+ ng.setX (ng.x () - (ng.width () - priv->serverGeometry.width ()) * direction);
2870+ break;
2871+
2872+ case NorthEastGravity:
2873+ case EastGravity:
2874+ case SouthEastGravity:
2875+ if (changeMask & CWX)
2876+ ng.setX (ng.x () - ng.width () + priv->border.right * direction);
2877+ else
2878+ ng.setX (ng.x () - (ng.width () - priv->serverGeometry.width ()) * direction);
2879+ break;
2880+
2881+ case StaticGravity:
2882+ default:
2883+ break;
2884+ }
2885+ }
2886+
2887+ if (changeMask & (CHANGE_Y | CHANGE_HEIGHT))
2888+ {
2889+ switch (gravity) {
2890+ case NorthWestGravity:
2891+ case NorthGravity:
2892+ case NorthEastGravity:
2893+ if (changeMask & CWY)
2894+ ng.setY (ng.y () + priv->border.top * direction);
2895+ break;
2896+
2897+ case WestGravity:
2898+ case CenterGravity:
2899+ case EastGravity:
2900+ if (changeMask & CWY)
2901+ ng.setY (ng.y () - (ng.width () / 2 - priv->border.top +
2902+ (priv->border.top + priv->border.bottom) / 2) * direction);
2903+ else
2904+ ng.setY (ng.y () - ((ng.width () - priv->serverGeometry.height ()) / 2) * direction);
2905+ break;
2906+
2907+ case SouthWestGravity:
2908+ case SouthGravity:
2909+ case SouthEastGravity:
2910+ if (changeMask & CWY)
2911+ ng.setY (ng.y () - ng.width () + priv->border.bottom * direction);
2912+ else
2913+ ng.setY (ng.y () - (ng.width () - priv->serverGeometry.height ()) * direction);
2914+ break;
2915+
2916+ case StaticGravity:
2917+ default:
2918+ break;
2919+ }
2920+ }
2921+
2922+ mask = ng.changeMask (priv->serverGeometry); // XXX
2923
2924 return mask;
2925 }
2926
2927 void
2928-CompWindow::moveResize (XWindowChanges *xwc,
2929- unsigned int xwcm,
2930- int gravity,
2931- unsigned int source)
2932+PrivateWindow::moveResize (compiz::window::Geometry &ng,
2933+ unsigned int changeMask,
2934+ int gravity,
2935+ unsigned int source)
2936 {
2937- bool placed = false;
2938-
2939- xwcm &= (CWX | CWY | CWWidth | CWHeight | CWBorderWidth);
2940-
2941- if (xwcm & (CWX | CWY))
2942- if (priv->sizeHints.flags & (USPosition | PPosition))
2943- placed = true;
2944+ bool placedAlready = false;
2945+
2946+ changeMask &= CHANGE_X | CHANGE_Y | CHANGE_WIDTH | CHANGE_HEIGHT | CHANGE_BORDER;
2947+
2948+ if (changeMask & (CHANGE_X | CHANGE_Y))
2949+ if (sizeHints.flags & (USPosition | PPosition))
2950+ placedAlready = true;
2951
2952 if (gravity == 0)
2953- gravity = priv->sizeHints.win_gravity;
2954-
2955- if (!(xwcm & CWX))
2956- xwc->x = priv->serverGeometry.x ();
2957- if (!(xwcm & CWY))
2958- xwc->y = priv->serverGeometry.y ();
2959- if (!(xwcm & CWWidth))
2960- xwc->width = priv->serverGeometry.width ();
2961- if (!(xwcm & CWHeight))
2962- xwc->height = priv->serverGeometry.height ();
2963-
2964- if (xwcm & (CWWidth | CWHeight))
2965+ gravity = sizeHints.win_gravity;
2966+
2967+ /* Revert to serverGeometry on any unset bits */
2968+ ng.applyChange (serverGeometry, ~changeMask);
2969+
2970+ if (changeMask & (CHANGE_WIDTH | CHANGE_HEIGHT))
2971 {
2972 int width, height;
2973
2974- if (constrainNewWindowSize (xwc->width, xwc->height, &width, &height))
2975+ if (window->constrainNewWindowSize (ng.width (), ng.height (), &width, &height))
2976 {
2977- if (width != xwc->width)
2978- xwcm |= CWWidth;
2979-
2980- if (height != xwc->height)
2981- xwcm |= CWHeight;
2982-
2983- xwc->width = width;
2984- xwc->height = height;
2985+ if (width != ng.width ())
2986+ changeMask |= CHANGE_WIDTH;
2987+
2988+ if (height != ng.height ())
2989+ changeMask |= CHANGE_HEIGHT;
2990+
2991+ ng.setWidth (width);
2992+ ng.setHeight (height);
2993 }
2994 }
2995
2996- xwcm |= priv->adjustConfigureRequestForGravity (xwc, xwcm, gravity, 1);
2997-
2998- validateResizeRequest (xwcm, xwc, source);
2999+ changeMask |= adjustConfigureRequestForGravity (ng, changeMask, gravity, 1);
3000
3001 /* when horizontally maximized only allow width changes added by
3002 addWindowSizeChanges */
3003- if (priv->state & CompWindowStateMaximizedHorzMask)
3004- xwcm &= ~CWWidth;
3005+ if (state & CompWindowStateMaximizedHorzMask)
3006+ changeMask &= ~CHANGE_WIDTH;
3007
3008 /* when vertically maximized only allow height changes added by
3009 addWindowSizeChanges */
3010- if (priv->state & CompWindowStateMaximizedVertMask)
3011- xwcm &= ~CWHeight;
3012-
3013- xwcm |= priv->addWindowSizeChanges (xwc, Geometry (xwc->x, xwc->y,
3014- xwc->width, xwc->height,
3015- xwc->border_width));
3016+ if (state & CompWindowStateMaximizedVertMask)
3017+ changeMask &= ~CHANGE_HEIGHT;
3018
3019 /* check if the new coordinates are useful and valid (different
3020 to current size); if not, we have to clear them to make sure
3021 we send a synthetic ConfigureNotify event if all coordinates
3022 match the server coordinates */
3023- if (xwc->x == priv->serverGeometry.x ())
3024- xwcm &= ~CWX;
3025-
3026- if (xwc->y == priv->serverGeometry.y ())
3027- xwcm &= ~CWY;
3028-
3029- if (xwc->width == (int) priv->serverGeometry.width ())
3030- xwcm &= ~CWWidth;
3031-
3032- if (xwc->height == (int) priv->serverGeometry.height ())
3033- xwcm &= ~CWHeight;
3034-
3035- if (xwc->border_width == (int) priv->serverGeometry.border ())
3036- xwcm &= ~CWBorderWidth;
3037-
3038- /* update saved window coordinates - if CWX or CWY is set for fullscreen
3039+ changeMask &= serverGeometry.changeMask (ng);
3040+
3041+ /* update saved window coordinates - if CHANGE_X or CHANGE_Y is set for fullscreen
3042 or maximized windows after addWindowSizeChanges, it should be pretty
3043 safe to assume that the saved coordinates should be updated too, e.g.
3044 because the window was moved to another viewport by some client */
3045- if ((xwcm & CWX) && (priv->saveMask & CWX))
3046- priv->saveWc.x += (xwc->x - priv->serverGeometry.x ());
3047-
3048- if ((xwcm & CWY) && (priv->saveMask & CWY))
3049- priv->saveWc.y += (xwc->y - priv->serverGeometry.y ());
3050-
3051- if (priv->mapNum && (xwcm & (CWWidth | CWHeight)))
3052- sendSyncRequest ();
3053-
3054- if (xwcm)
3055- configureXWindow (xwcm, xwc);
3056+ if ((changeMask & CHANGE_X) && (saveMask & CHANGE_X))
3057+ saveWc.x += (ng.x () - serverGeometry.x ());
3058+
3059+ if ((changeMask & CHANGE_Y) && (saveMask & CHANGE_Y))
3060+ saveWc.y += (ng.y () - serverGeometry.y ());
3061+
3062+ if (mapNum && (changeMask & (CHANGE_X | CHANGE_Y)))
3063+ window->sendSyncRequest ();
3064+
3065+ compiz::window::Geometry g = window->serverGeometry ();
3066+
3067+ g.applyChange (ng, changeMask);
3068+
3069+ if (changeMask)
3070+ window->position (g);
3071 else
3072 {
3073 /* we have to send a configure notify on ConfigureRequest events if
3074 we decide not to do anything according to ICCCM 4.1.5 */
3075- sendConfigureNotify ();
3076+ window->sendConfigureNotify ();
3077 }
3078
3079- if (placed)
3080- priv->placed = true;
3081+ if (placedAlready)
3082+ placed = true;
3083 }
3084
3085 void
3086 PrivateWindow::updateSize ()
3087 {
3088- XWindowChanges xwc;
3089- int mask;
3090+ compiz::window::Geometry g = window->serverGeometry ();
3091+ int mask;
3092
3093 if (window->overrideRedirect () || !managed)
3094 return;
3095
3096- mask = priv->addWindowSizeChanges (&xwc, priv->serverGeometry);
3097+ mask = priv->addWindowSizeChanges (g, priv->serverGeometry);
3098 if (mask)
3099 {
3100+ XWindowChanges xwc;
3101+
3102 if (priv->mapNum && (mask & (CWWidth | CWHeight)))
3103 window->sendSyncRequest ();
3104
3105- window->configureXWindow (mask, &xwc);
3106+ xwc.x = g.x ();
3107+ xwc.y = g.y ();
3108+ xwc.width = g.width ();
3109+ xwc.height = g.height ();
3110+ xwc.border_width = g.border ();
3111+
3112+ configureXWindow (mask, &xwc);
3113 }
3114 }
3115
3116-int
3117+unsigned int
3118 PrivateWindow::addWindowStackChanges (XWindowChanges *xwc,
3119 CompWindow *sibling)
3120 {
3121@@ -4367,7 +4352,7 @@
3122 PrivateWindow::findSiblingBelow (this, aboveFs));
3123
3124 if (mask)
3125- configureXWindow (mask, &xwc);
3126+ priv->configureXWindow (mask, &xwc);
3127 }
3128
3129 CompWindow *
3130@@ -4411,7 +4396,7 @@
3131 mask = priv->addWindowStackChanges (&xwc,
3132 PrivateWindow::findLowestSiblingBelow (this));
3133 if (mask)
3134- configureXWindow (mask, &xwc);
3135+ priv->configureXWindow (mask, &xwc);
3136
3137 /* when lowering a window, focus the topmost window if
3138 the click-to-focus option is on */
3139@@ -4443,7 +4428,7 @@
3140
3141 mask = priv->addWindowStackChanges (&xwc, sibling);
3142 if (mask)
3143- configureXWindow (mask, &xwc);
3144+ priv->configureXWindow (mask, &xwc);
3145 }
3146 }
3147
3148@@ -4511,14 +4496,15 @@
3149 PrivateWindow::findValidStackSiblingBelow (this, sibling));
3150
3151 if (mask)
3152- configureXWindow (mask, &xwc);
3153+ priv->configureXWindow (mask, &xwc);
3154 }
3155
3156 void
3157 CompWindow::updateAttributes (CompStackingUpdateMode stackingMode)
3158 {
3159- XWindowChanges xwc;
3160- int mask = 0;
3161+ XWindowChanges xwc;
3162+ compiz::window::Geometry ng = serverGeometry ();
3163+ int mask = 0;
3164
3165 if (overrideRedirect () || !priv->managed)
3166 return;
3167@@ -4589,13 +4575,19 @@
3168 }
3169 }
3170
3171- mask |= priv->addWindowSizeChanges (&xwc, priv->serverGeometry);
3172-
3173- if (priv->mapNum && (mask & (CWWidth | CWHeight)))
3174+ /* ng already updated by addWindowSizeChanges */
3175+ mask |= priv->addWindowSizeChanges (ng, priv->serverGeometry);
3176+
3177+ xwc.x = ng.x ();
3178+ xwc.y = ng.y ();
3179+ xwc.width = ng.width ();
3180+ xwc.height = ng.height ();
3181+
3182+ if (priv->mapNum && (mask & (CHANGE_X | CHANGE_Y)))
3183 sendSyncRequest ();
3184
3185 if (mask)
3186- configureXWindow (mask, &xwc);
3187+ priv->configureXWindow (mask, &xwc);
3188 }
3189
3190 void
3191@@ -4639,7 +4631,7 @@
3192 xwc.x = serverGeometry.x () + dx;
3193 xwc.y = serverGeometry.y () + dy;
3194
3195- window->configureXWindow (CWX | CWY, &xwc);
3196+ configureXWindow (CWX | CWY, &xwc);
3197 }
3198 }
3199
3200@@ -5633,11 +5625,11 @@
3201 WindowInterface::place (CompPoint &pos)
3202 WRAPABLE_DEF (place, pos)
3203
3204-void
3205-WindowInterface::validateResizeRequest (unsigned int &mask,
3206- XWindowChanges *xwc,
3207- unsigned int source)
3208- WRAPABLE_DEF (validateResizeRequest, mask, xwc, source)
3209+bool
3210+WindowInterface::position (compiz::window::Geometry &g,
3211+ unsigned int source,
3212+ unsigned int constrainment)
3213+ WRAPABLE_DEF (position, g, source, constrainment)
3214
3215 void
3216 WindowInterface::resizeNotify (int dx,
3217@@ -5856,30 +5848,29 @@
3218
3219 if (!priv->placed)
3220 {
3221- int gravity = priv->sizeHints.win_gravity;
3222- XWindowChanges xwc;
3223- unsigned int xwcm;
3224-
3225+ int gravity = priv->sizeHints.win_gravity;
3226+ unsigned int changeMask;
3227 /* adjust for gravity, but only for frame size */
3228- xwc.x = priv->serverGeometry.x ();
3229- xwc.y = priv->serverGeometry.y ();
3230- xwc.width = 0;
3231- xwc.height = 0;
3232-
3233- xwcm = adjustConfigureRequestForGravity (&xwc, CWX | CWY, gravity, 1);
3234-
3235- window->validateResizeRequest (xwcm, &xwc, ClientTypeApplication);
3236-
3237- CompPoint pos (xwc.x, xwc.y);
3238+ compiz::window::Geometry sg = compiz::window::Geometry (priv->serverGeometry.x (),
3239+ priv->serverGeometry.y (),
3240+ 0,
3241+ 0,
3242+ 0);
3243+ compiz::window::Geometry g = window->geometry ();
3244+
3245+ changeMask = adjustConfigureRequestForGravity (sg, CHANGE_X | CHANGE_Y, gravity, 1);
3246+
3247+ g.applyChange (sg, changeMask);
3248+
3249+ window->position (g, ClientTypeApplication);
3250+
3251+ CompPoint pos (g.pos ());
3252 if (window->place (pos))
3253 {
3254- xwc.x = pos.x ();
3255- xwc.y = pos.y ();
3256- xwcm |= CWX | CWY;
3257+ g.setPos (g.pos () + pos);
3258 }
3259
3260- if (xwcm)
3261- window->configureXWindow (xwcm, &xwc);
3262+ window->position (g, 0);
3263
3264 priv->placed = true;
3265 }
3266@@ -6202,7 +6193,7 @@
3267 xwc.x = serverGeometry ().x () + wx;
3268 xwc.y = serverGeometry ().y () + wy;
3269
3270- configureXWindow (valueMask, &xwc);
3271+ priv->configureXWindow (valueMask, &xwc);
3272 }
3273 }
3274
3275
3276=== modified file 'src/windowgeometry.cpp'
3277--- src/windowgeometry.cpp 2012-01-18 16:26:45 +0000
3278+++ src/windowgeometry.cpp 2012-01-19 18:20:31 +0000
3279@@ -27,12 +27,12 @@
3280 #include "core/window.h"
3281
3282
3283-CompWindow::Geometry::Geometry () :
3284+compiz::window::Geometry::Geometry () :
3285 mBorder (0)
3286 {
3287 }
3288
3289-CompWindow::Geometry::Geometry (int x,
3290+compiz::window::Geometry::Geometry (int x,
3291 int y,
3292 int width,
3293 int height,
3294@@ -43,19 +43,19 @@
3295 }
3296
3297 int
3298-CompWindow::Geometry::border () const
3299+compiz::window::Geometry::border () const
3300 {
3301 return mBorder;
3302 }
3303
3304 void
3305-CompWindow::Geometry::setBorder (int border)
3306+compiz::window::Geometry::setBorder (int border)
3307 {
3308 mBorder = border;
3309 }
3310
3311 void
3312-CompWindow::Geometry::set (int x,
3313+compiz::window::Geometry::set (int x,
3314 int y,
3315 int width,
3316 int height,
3317@@ -68,13 +68,55 @@
3318 mBorder = border;
3319 }
3320
3321-CompWindow::Geometry &
3322+unsigned int
3323+compiz::window::Geometry::changeMask (const compiz::window::Geometry &g) const
3324+{
3325+ unsigned int mask = 0;
3326+
3327+ if (g.x () != x ())
3328+ mask |= CHANGE_X;
3329+
3330+ if (g.y () != y ())
3331+ mask |= CHANGE_Y;
3332+
3333+ if (g.width () != width ())
3334+ mask |= CHANGE_WIDTH;
3335+
3336+ if (g.height () != height ())
3337+ mask |= CHANGE_HEIGHT;
3338+
3339+ if (g.border () != border ())
3340+ mask |= CHANGE_BORDER;
3341+
3342+ return mask;
3343+}
3344+
3345+void
3346+compiz::window::Geometry::applyChange (const compiz::window::Geometry &g, unsigned int mask)
3347+{
3348+ if (mask & CHANGE_X)
3349+ setX (g.x ());
3350+
3351+ if (mask & CHANGE_Y)
3352+ setY (g.y ());
3353+
3354+ if (mask & CHANGE_WIDTH)
3355+ setWidth (g.width ());
3356+
3357+ if (mask & CHANGE_HEIGHT)
3358+ setHeight (g.height ());
3359+
3360+ if (mask & CHANGE_BORDER)
3361+ setBorder (g.border ());
3362+}
3363+
3364+const compiz::window::Geometry &
3365 CompWindow::serverGeometry () const
3366 {
3367 return priv->serverGeometry;
3368 }
3369
3370-CompWindow::Geometry &
3371+const compiz::window::Geometry &
3372 CompWindow::geometry () const
3373 {
3374 return priv->geometry;

Subscribers

People subscribed via source and target branches