Merge lp:~smspillaz/compiz-core/fix-893467 into lp:compiz-core/0.9.5
- fix-893467
- Merge into 0.9.5
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 |
Related bugs: |
|
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 |
Commit message
Description of the change
Rework window positioning API somewhat.
CompWindow:
CompositeWindow
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:
CompWindow:
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:
* compiz:
* compiz:
-> This replaces lines of code like, eg:
XWindowChanges xwc;
unsigned int mask = CWX | CWY;
xwc.x = foo;
xwc.y = bar;
w-
With:
compiz:
compiz:
ng.setX (foo);
ng.setY (bar);
send.
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:
CompWindow:
CompWindow:
CompWindow:
CompWindow:
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:
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.
-> CompositedPosit
-> 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
Sam Spilsbury (smspillaz) wrote : | # |
- 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.
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!
- 2902. By Sam Spilsbury
-
Cleanup
- 2903. By Sam Spilsbury
-
Fix merge error
- 2904. By Sam Spilsbury
-
Merged fix-POTfile-893995 into fix-893467.
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.
- 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.
Alan Griffiths (alan-griffiths) wrote : | # |
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.
2635 + if (!(changeMask & CHANGE_WIDTH) && (int) old.width () > sizeHints.
2645 + if (!(changeMask & CHANGE_HEIGHT) && (int) old.height () < sizeHints.
2655 + if (!(changeMask & CHANGE_HEIGHT) && (int) old.height () > sizeHints.
(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.
3018 + if (!(changeMask & CWHeight))
3019 + xwc->height = serverGeometry.
3020 +*/
...
3068 +/* XXX: Is there a reason why this needs to be here ?
3069 + xwcm |= addWindowSizeCh
3070 xwc->width, xwc->height,
3071 xwc->border_
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,
};
(Although stylistically UPPERCASE is usually reserved for preprocessor macros.)
This would allow
- unsigned int changeMask (const compiz:
+ ChangeMask changeMask (const Geometry &g) const;
namespaces
o namespaces are used intermittently and inconsistently - they should be consistent.
$ grep namespace `find ../include/ -name \*.h`
..
..
..
..
(The change introduces ::compiz::window.)
o it isn't necessary to explicitly specify namespaces when in the namespace:
unsigned int changeMask (const compiz:
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:
~~~~~~~
STUFF NOT IN CHANGE
class PrivateWindow
o is a struct with lots of member functions - bad existing design
o Ought to be n...
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:
CompositeWindow
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.
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.
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.
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:/
But if your approach is just as fast, then that's good too.
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.
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)
- 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
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.
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://
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:/
> You are the owner of lp:~smspillaz/compiz-core/fix-893467.
>
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/
460 if (op->flags & MATCH_OP_AND_MASK)
(gdb) bt
#0 matchEvalOps (list=..., w=0xa048b0) at /home/dan/
#1 0x00007ffff216c280 in DecorWindow::update (this=0xa11d90, allowDecoration
#2 0x00007ffff216b1a6 in DecorWindow:
#3 0x00007ffff2172ae4 in getInstance (base=0xa048b0) at /home/dan/
#4 PluginClassHand
#5 0x00007ffff2172bfc in CompPlugin:
#6 0x0000000000458ab1 in CompScreen:
#7 0x0000000000458910 in CompManager:
#8 0x000000000045a40e in CompPlugin::push (p=0x68d380) at /home/dan/
#9 0x000000000042f6d8 in PrivateScreen:
#10 0x0000000000433f61 in CompScreen::init (this=0x67dbb0, name=<optimised out>) at /home/dan/
#11 0x000000000042476d in CompManager::init (this=0x7ffffff
#12 0x000000000042215d in main (argc=<optimised out>, argv=0x7fffffff
(gdb) quit
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.
Daniel van Vugt (vanvugt) wrote : | # |
If this branch can't be stabilized soon, please consider merging my new one instead/first:
https:/
- 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
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 ®ion); |
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; |
Rework window positioning API somewhat.
CompWindow: :position () makes a request to change the server side position of the window ::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).
CompositeWindow
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.