Merge lp:~vanvugt/compiz/fix-980663-1041066 into lp:compiz/0.9.8
- fix-980663-1041066
- Merge into 0.9.8
Status: | Merged |
---|---|
Approved by: | Daniel van Vugt |
Approved revision: | 3346 |
Merged at revision: | 3338 |
Proposed branch: | lp:~vanvugt/compiz/fix-980663-1041066 |
Merge into: | lp:compiz/0.9.8 |
Diff against target: |
371 lines (+266/-18) 7 files modified
plugins/opengl/CMakeLists.txt (+4/-1) plugins/opengl/src/fsregion/CMakeLists.txt (+7/-0) plugins/opengl/src/fsregion/fsregion.cpp (+54/-0) plugins/opengl/src/fsregion/fsregion.h (+55/-0) plugins/opengl/src/fsregion/tests/CMakeLists.txt (+10/-0) plugins/opengl/src/fsregion/tests/test-fsregion.cpp (+121/-0) plugins/opengl/src/paint.cpp (+15/-17) |
To merge this branch: | bzr merge lp:~vanvugt/compiz/fix-980663-1041066 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Sam Spilsbury | Approve | ||
Compiz Maintainers | Pending | ||
Review via email: mp+122650@code.launchpad.net |
This proposal supersedes a proposal from 2012-09-04.
Commit message
Make "Unredirect Fullscreen Windows" more reliable. This fixes the problem
with unredirection failing to engage at all (LP: #1041066) when
gtk-window-
This also fixes the problem with unredirect hiding all windows,
because it thinks the desktop window should be stacked on top (LP: #980663).
Unfortunately, both issues are so tightly coupled that they can only really
be fixed and tested together.
Description of the change
Make "Unredirect Fullscreen Windows" more reliable. This fixes the problem
with unredirection failing to engage at all (LP: #1041066) when
gtk-window-
This also fixes the problem with unredirect hiding all windows,
because it thinks the desktop window should be stacked on top (LP: #980663).
Unfortunately, both issues are so tightly coupled that they can only really
be fixed and tested together.
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal | # |
115 +/*
116 + * Why mock locally? Because...
117 + * 1. Code is cleaner without typecasts, so we need to ensure that
118 + * Output::Window is-a CompWindow when not mocking.
119 + * 2. No polymorphism is required = fewer classes, less code, easier to follow.
120 + */
121 +#ifdef OUTPUTWINDOW
122 +class MockCompWindow
123 +{
124 +public:
125 + MockCompWindow (unsigned int type, int x, int y, int width, int height) :
126 + flags (type), reg (x, y, width, height) {}
127 + unsigned int type () const { return flags; }
128 + const CompRegion ®ion () const { return reg; }
129 +
130 +private:
131 + unsigned int flags;
132 + CompRegion reg;
133 +};
134 +#else
135 +#define OUTPUTWINDOW CompWindow
136 +#endif
Yeah, I disagree with this :)
1. It relies on a define for the code to compile the right way
a. (Unity has code that does this and its not nice to work with)
2. Ifdefs make the code harder to follow in general. The code is doing two different things depending on how it was compiled. This could introduce subtle gotchas.
3. This code is relying on an implicit interface (eg, what the caller is doing with CompWindow). This means that
when it breaks, it will be non-obvious as to why (eg, instead of being told that MockCompWindow does not
implement the interface, you get a normal compile error saying that certain functions don't exist on this object
that #defines itself into existence at compile time).
4. The Window definition conflicts with the Xlib one.
If you don't want to use an interface class (this is a point I agree on), here are some alternatives:
a. Output::occlude is only really interested in three things from CompWindow, firstly whether or not it can take focus (I will deal with this later), and secondly a means to get a CompositeWindow and thirdly its covering region. You can do something like this:
typedef enum _FocusableState
{
CanTakeFocus = 0,
NoFocusAllowed = 1
} FocusableState;
//
Output::occlude (FocusableState focusState,
{
57 +
58 + if (!fullscreen &&
60 + reg == untouched)
61 + {
62 + fullscreen = win;
63 + }
64 + untouched -= reg;
}
Window
Output:
{
return Window;
}
// not under test
FocusableState
compiz:
{
if (window->type () & NO_FOCUS_MASK)
return NoFocusAllowed;
return CanTakeFocus;
}
Use the code like this:
FocusableState focusState = WindowTypeToFoc
output.occlude (focusState, window->id (), window->region ());
Window fullscreenWindow = output.
CompWindow *fullscreenComp
CompositeWindow *compositeFulls
compositeFullsc
I personally don't like using the Xlib Window handle as a means to identify windows within compiz, and would personally prefer that compiz:
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
Actually, I thought of all of that already and disagree with almost all of it :)
I'll try to find a nicer way to hide and clean up the mocking. However changing a class' public interface is usually a mistake. Test cases can change how you do your implementation, but should never change the interfaces.
I'm not using compiz_
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
Also, test-output is in a namespace already by virtue of its directory:
build/plugins/
However I will rename it internally at least so you can tell what and where it is just from the CTest output.
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
Clean-ups all round.
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal | # |
"Actually, I thought of all of that already and disagree with almost all of it :)"
Could you elaborate? I didn't say that you needed to change any public interfaces.
This is still very confusing:
380 +#ifdef MOCK_COMPWINDOW
381 + typedef Stackable Window;
382 +#else
383 + typedef CompWindow Window;
384 +#endif
The code is compiled twice, and you have an abstract base class in one version and a concrete class in another. What this essentially is, is a template implemented in terms of #define.
If you're going to create an abstract base class, why not just go all the way and make PrivateGLWindow inherit Stackable, put a redirect method in Stackable and make it call through to PrivateGLWindow? That way you don't need to rely on a define, and you only need to compile this code once.
96 +include_
97 +add_definition
98 +set(exe "compiz_
99 +add_executable
100 +target_
101 +add_test(
"I'm not using compiz_
It doesn't necessitate that at all. The tests are only organized that way because this is the way I happened to organize them. (Also, when in doubt, its a good idea to be consistent rather than go against the grain - I'm happy to change the organization if we can agree on a better way).
Here's the syntax for compiz_
compiz_
The coverage argument is optional, but does require that the tested code goes into a separate library (which you should do anyways because currently the code is compiled twice, which is the exact problem that unity has which I am trying to avoid).
I strongly recommend using this function. It has the following purposes:
1. It adds every individual test to the CTest manifest, meaning that you always have a perfectly clean environment on setup and teardown (defend against subtle bugs where tests are stateful and rely on each other when they shouldn't).
2. You have per-test resolution when something fails from "make test"
3. Its the best way to get your code added to the coverage report, so that you can see if your tests are actually excersizing the code all round. (You can add to the coverage report yourself, however that's several hundred lines of CMake code).
Another good reason:
4. If someone else adds a test using compiz_
"WindowStack" also feels weird. Its not a window stack - its a class that accumulates uncovered screen regions to determine which windows are not occluded. Also "stackable" in the namespace compiz::opengl feels weird too. Its not a "stackable", in compiz terms "stackable" means something more like a window that sits in a stack and can be re-arranged. I...
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal | # |
I apologize if I seem ... opinionated, I'm just trying to distill what the intention is and the best way of effecting that intention
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal | # |
Looking much better without the #define.
I think that Output can take the X11 definition of a "Window" (eg, typedef unsigned int Window) rather than using void *, it means the same thing in both instances and makes the code slightly more clear as to what is being used to identify the window. There's no need to link to xlib for this, all there is a header dependency on <X11/Xlib.h>
Now that Output is taking references to the data that it needs to use to identify which window is on top, there's not much need for MockCompWindow anymore. The boolean parameter in Output can be changed to an enum, eg
typedef enum _FocusAllowedState
{
NoFocusAllowed,
FocusAllowed
}
Output::occlude (FocusAllowed, region, window) is more expressive than Output::occlude (true, region, window).
Finally, it would be good if output.cpp was a static library that was linked into opengl. I've tried to avoid setting the trend of compiling any source file more than once in the tree (like Unity does), and would like to keep the source tree this way.
compiz_
If you are using another static library, you can create coverage targets as so
compiz_
That will ensure that you can get coverage reports from "make coverage"
The preferred method of addressing source files in a cmake tree is this:
${CMAKE_
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal | # |
If possible by the way, see if you can find a better name for "Output". I still think there's some confusion between "Output" and "CompOutput" - the responsibility of this class seems to be finding a fullscreen window to unredirect based on which windows are not occluded.
I did mention it before, but I find that difficulty in finding a name for a class might indicate that its doing too many unrelated things. In this case, the class is checking for a window to unredirect and then offering a way to get the result. Perhaps it would be better if it stored an interface by which the window could be unredirected and then provided a method to call into the class to unredirect the saved fullscreen window. That way the class could be called "UnoccludedWind
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
Lots of clean-ups and renaming.
I disagree with the bi-state enumeration and think a boolean is clearer in cases like this where you can use it.
I disagree with the suggested approach to coverage where you have to put code in a static library to get coverage data. Getting coverage information should be transparently possible for all test cases. I'm surprised it's not done that way already, but we can improve that later. See also bug 1045665.
And I disagree with putting a single, single-use class in a separate library just to avoid recompiling it in the test cases. Clarity and a simpler source tree is more important.
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal | # |
> Lots of clean-ups and renaming.
>
> I disagree with the bi-state enumeration and think a boolean is clearer in
> cases like this where you can use it.
How is:
isCoveredBy (region, true);
Any more clear than
isCoveredBy (region, FullscreenWindow); or isCoveredBy (region, NormalWindow);
Read it aloud.
"is covered by region true" vs "is covered by region, a FullscreenWindow" "is covered by region, a NormalWindow".
Not blocking on this, but please consider it.
>
> I disagree with the suggested approach to coverage where you have to put code
> in a static library to get coverage data. Getting coverage information should
> be transparently possible for all test cases. I'm surprised it's not done that
> way already, but we can improve that later. See also bug 1045665.
Right, the /current/ coverage system doesn't support this case. In fact, if you pass it the testcase as the coverage target, you should be able to get a coverage report on that file though:
>
> And I disagree with putting a single, single-use class in a separate library
> just to avoid recompiling it in the test cases. Clarity and a simpler source
> tree is more important.
add_library (compiz_
target_
...
compiz_plugin (opengl ... LIBRARIES compiz_
The source tree doesn't exactly have to be reorganized to make it work.
We aren't using autotools - any buildsystem that requires you to compile a file twice is a travesty and I won't allow this trend to be set in compiz. Unity does exactly this and it annoys me greatly - it takes at least fifteen minutes longer than it should to compile because nobody took the time to ensure that files were only compiled once.
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
I don't care any more. I'm willing to compromise any which way to get this merged. A week on a fix that took me 10 minutes is crazy...
WIP again.
Sam Spilsbury (smspillaz) wrote : | # |
All looking good now.
Unity Merger (unity-merger) wrote : | # |
The Jenkins job https:/
Not merging it.
Sam Spilsbury (smspillaz) wrote : | # |
So I can't believe this, but the automerge still has -DCOMPIZ_
if (COMPIZ_
add_subdirectory (tests)
endif (COMPIZ_
I note that we should probably develop a cmake file with macros for this stuff.
Sam Spilsbury (smspillaz) wrote : | # |
Once that's fixed, just approve the branch again (though the chances are it won't merge anyways as jenkins is out of space)
- 3346. By Daniel van Vugt
-
Building of tests is conditional, apparently. This fixes a Jenkins failure.
Preview Diff
1 | === modified file 'plugins/opengl/CMakeLists.txt' |
2 | --- plugins/opengl/CMakeLists.txt 2012-08-29 08:41:58 +0000 |
3 | +++ plugins/opengl/CMakeLists.txt 2012-09-05 03:21:22 +0000 |
4 | @@ -3,9 +3,12 @@ |
5 | include (CompizPlugin) |
6 | |
7 | set (INTERNAL_LIBRARIES |
8 | - compiz_opengl_double_buffer) |
9 | + compiz_opengl_double_buffer |
10 | + compiz_opengl_fsregion |
11 | +) |
12 | |
13 | add_subdirectory (src/doublebuffer) |
14 | +add_subdirectory (src/fsregion) |
15 | |
16 | if (USE_GLES) |
17 | compiz_plugin(opengl PLUGINDEPS composite CFLAGSADD "-DUSE_GLES -std=c++0x" LIBRARIES ${OPENGLES2_LIBRARIES} ${INTERNAL_LIBRARIES} dl INCDIRS ${OPENGLES2_INCLUDE_DIR}) |
18 | |
19 | === added directory 'plugins/opengl/src/fsregion' |
20 | === added file 'plugins/opengl/src/fsregion/CMakeLists.txt' |
21 | --- plugins/opengl/src/fsregion/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
22 | +++ plugins/opengl/src/fsregion/CMakeLists.txt 2012-09-05 03:21:22 +0000 |
23 | @@ -0,0 +1,7 @@ |
24 | +if (COMPIZ_BUILD_TESTING) |
25 | +add_subdirectory (tests) |
26 | +endif () |
27 | + |
28 | +add_library (compiz_opengl_fsregion STATIC fsregion.cpp) |
29 | +target_link_libraries (compiz_opengl_fsregion compiz_core) |
30 | + |
31 | |
32 | === added file 'plugins/opengl/src/fsregion/fsregion.cpp' |
33 | --- plugins/opengl/src/fsregion/fsregion.cpp 1970-01-01 00:00:00 +0000 |
34 | +++ plugins/opengl/src/fsregion/fsregion.cpp 2012-09-05 03:21:22 +0000 |
35 | @@ -0,0 +1,54 @@ |
36 | +/* |
37 | + * Compiz opengl plugin, FullscreenRegion class |
38 | + * |
39 | + * Copyright (c) 2012 Canonical Ltd. |
40 | + * Author: Daniel van Vugt <daniel.van.vugt@canonical.com> |
41 | + * |
42 | + * Permission is hereby granted, free of charge, to any person obtaining a |
43 | + * copy of this software and associated documentation files (the "Software"), |
44 | + * to deal in the Software without restriction, including without limitation |
45 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
46 | + * and/or sell copies of the Software, and to permit persons to whom the |
47 | + * Software is furnished to do so, subject to the following conditions: |
48 | + * |
49 | + * The above copyright notice and this permission notice shall be included in |
50 | + * all copies or substantial portions of the Software. |
51 | + * |
52 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
53 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
54 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
55 | + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
56 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
57 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
58 | + * DEALINGS IN THE SOFTWARE. |
59 | + */ |
60 | + |
61 | +#include "fsregion.h" |
62 | + |
63 | +namespace compiz { |
64 | +namespace opengl { |
65 | + |
66 | +FullscreenRegion::FullscreenRegion (const CompRect &rect) : |
67 | + covered (false), |
68 | + untouched (rect) |
69 | +{ |
70 | +} |
71 | + |
72 | +bool |
73 | +FullscreenRegion::isCoveredBy (const CompRegion ®ion, WinType type) |
74 | +{ |
75 | + bool fullscreen = false; |
76 | + |
77 | + if (!covered && type == Normal && region == untouched) |
78 | + { |
79 | + covered = true; |
80 | + fullscreen = true; |
81 | + } |
82 | + |
83 | + untouched -= region; |
84 | + |
85 | + return fullscreen; |
86 | +} |
87 | + |
88 | +} // namespace opengl |
89 | +} // namespace compiz |
90 | |
91 | === added file 'plugins/opengl/src/fsregion/fsregion.h' |
92 | --- plugins/opengl/src/fsregion/fsregion.h 1970-01-01 00:00:00 +0000 |
93 | +++ plugins/opengl/src/fsregion/fsregion.h 2012-09-05 03:21:22 +0000 |
94 | @@ -0,0 +1,55 @@ |
95 | +/* |
96 | + * Compiz opengl plugin, FullscreenRegion class |
97 | + * |
98 | + * Copyright (c) 2012 Canonical Ltd. |
99 | + * Author: Daniel van Vugt <daniel.van.vugt@canonical.com> |
100 | + * |
101 | + * Permission is hereby granted, free of charge, to any person obtaining a |
102 | + * copy of this software and associated documentation files (the "Software"), |
103 | + * to deal in the Software without restriction, including without limitation |
104 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
105 | + * and/or sell copies of the Software, and to permit persons to whom the |
106 | + * Software is furnished to do so, subject to the following conditions: |
107 | + * |
108 | + * The above copyright notice and this permission notice shall be included in |
109 | + * all copies or substantial portions of the Software. |
110 | + * |
111 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
112 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
113 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
114 | + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
115 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
116 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
117 | + * DEALINGS IN THE SOFTWARE. |
118 | + */ |
119 | + |
120 | +#ifndef __COMPIZ_OPENGL_FSREGION_H |
121 | +#define __COMPIZ_OPENGL_FSREGION_H |
122 | +#include "core/rect.h" |
123 | +#include "core/region.h" |
124 | + |
125 | +namespace compiz { |
126 | +namespace opengl { |
127 | + |
128 | +class FullscreenRegion |
129 | +{ |
130 | +public: |
131 | + typedef enum |
132 | + { |
133 | + Normal, |
134 | + Desktop |
135 | + } WinType; |
136 | + |
137 | + FullscreenRegion (const CompRect &rect); |
138 | + |
139 | + // isCoveredBy is called for windows from TOP to BOTTOM |
140 | + bool isCoveredBy (const CompRegion ®ion, WinType type = Normal); |
141 | + |
142 | +private: |
143 | + bool covered; |
144 | + CompRegion untouched; |
145 | +}; |
146 | + |
147 | +} // namespace opengl |
148 | +} // namespace compiz |
149 | +#endif |
150 | |
151 | === added directory 'plugins/opengl/src/fsregion/tests' |
152 | === added file 'plugins/opengl/src/fsregion/tests/CMakeLists.txt' |
153 | --- plugins/opengl/src/fsregion/tests/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
154 | +++ plugins/opengl/src/fsregion/tests/CMakeLists.txt 2012-09-05 03:21:22 +0000 |
155 | @@ -0,0 +1,10 @@ |
156 | +include_directories (${GTEST_INCLUDE_DIRS} ..) |
157 | +set (exe "compiz_opengl_test_fsregion") |
158 | +add_executable (${exe} test-fsregion.cpp) |
159 | +target_link_libraries (${exe} |
160 | + compiz_opengl_fsregion |
161 | + compiz_core |
162 | + ${GTEST_BOTH_LIBRARIES} |
163 | +) |
164 | +compiz_discover_tests(${exe} COVERAGE compiz_opengl_fsregion) |
165 | + |
166 | |
167 | === added file 'plugins/opengl/src/fsregion/tests/test-fsregion.cpp' |
168 | --- plugins/opengl/src/fsregion/tests/test-fsregion.cpp 1970-01-01 00:00:00 +0000 |
169 | +++ plugins/opengl/src/fsregion/tests/test-fsregion.cpp 2012-09-05 03:21:22 +0000 |
170 | @@ -0,0 +1,121 @@ |
171 | +/* |
172 | + * Compiz opengl plugin, FullscreenRegion class |
173 | + * |
174 | + * Copyright (c) 2012 Canonical Ltd. |
175 | + * Author: Daniel van Vugt <daniel.van.vugt@canonical.com> |
176 | + * |
177 | + * Permission is hereby granted, free of charge, to any person obtaining a |
178 | + * copy of this software and associated documentation files (the "Software"), |
179 | + * to deal in the Software without restriction, including without limitation |
180 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
181 | + * and/or sell copies of the Software, and to permit persons to whom the |
182 | + * Software is furnished to do so, subject to the following conditions: |
183 | + * |
184 | + * The above copyright notice and this permission notice shall be included in |
185 | + * all copies or substantial portions of the Software. |
186 | + * |
187 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
188 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
189 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
190 | + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
191 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
192 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
193 | + * DEALINGS IN THE SOFTWARE. |
194 | + */ |
195 | + |
196 | +#include "gtest/gtest.h" |
197 | +#include "fsregion.h" |
198 | + |
199 | +using namespace compiz::opengl; |
200 | + |
201 | +TEST (OpenGLFullscreenRegion, NoWindows) |
202 | +{ |
203 | + FullscreenRegion monitor (CompRect (0, 0, 1024, 768)); |
204 | + EXPECT_FALSE (monitor.isCoveredBy (CompRegion (0, 0, 1024, 768), |
205 | + FullscreenRegion::Desktop)); |
206 | +} |
207 | + |
208 | +TEST (OpenGLFullscreenRegion, OneFullscreen) |
209 | +{ |
210 | + FullscreenRegion monitor (CompRect (0, 0, 1024, 768)); |
211 | + EXPECT_TRUE (monitor.isCoveredBy (CompRegion (0, 0, 1024, 768))); |
212 | + EXPECT_FALSE (monitor.isCoveredBy (CompRegion (0, 0, 1024, 768), |
213 | + FullscreenRegion::Desktop)); |
214 | +} |
215 | + |
216 | +TEST (OpenGLFullscreenRegion, FullscreenNoDesktop) |
217 | +{ |
218 | + FullscreenRegion monitor (CompRect (0, 0, 1024, 768)); |
219 | + EXPECT_TRUE (monitor.isCoveredBy (CompRegion (0, 0, 1024, 768))); |
220 | +} |
221 | + |
222 | +TEST (OpenGLFullscreenRegion, NormalWindows) |
223 | +{ |
224 | + FullscreenRegion monitor (CompRect (0, 0, 1024, 768)); |
225 | + EXPECT_FALSE (monitor.isCoveredBy (CompRegion (10, 10, 40, 30))); |
226 | + EXPECT_FALSE (monitor.isCoveredBy (CompRegion (20, 20, 50, 20))); |
227 | + EXPECT_FALSE (monitor.isCoveredBy (CompRegion (0, 0, 1024, 768), |
228 | + FullscreenRegion::Desktop)); |
229 | +} |
230 | + |
231 | +TEST (OpenGLFullscreenRegion, TwoFullscreen) |
232 | +{ |
233 | + FullscreenRegion monitor (CompRect (0, 0, 1024, 768)); |
234 | + EXPECT_TRUE (monitor.isCoveredBy (CompRegion (0, 0, 1024, 768))); |
235 | + EXPECT_FALSE (monitor.isCoveredBy (CompRegion (10, 10, 40, 30))); |
236 | + EXPECT_FALSE (monitor.isCoveredBy (CompRegion (20, 20, 50, 20))); |
237 | + EXPECT_FALSE (monitor.isCoveredBy (CompRegion (0, 0, 1024, 768))); |
238 | + EXPECT_FALSE (monitor.isCoveredBy (CompRegion (0, 0, 1024, 768), |
239 | + FullscreenRegion::Desktop)); |
240 | +} |
241 | + |
242 | +TEST (OpenGLFullscreenRegion, Offscreen) |
243 | +{ |
244 | + FullscreenRegion monitor (CompRect (0, 0, 1024, 768)); |
245 | + EXPECT_FALSE (monitor.isCoveredBy (CompRegion (-100, -100, 1, 1))); |
246 | + EXPECT_FALSE (monitor.isCoveredBy (CompRegion (2000, 2000, 123, 456))); |
247 | + EXPECT_TRUE (monitor.isCoveredBy (CompRegion (0, 0, 1024, 768))); |
248 | + EXPECT_FALSE (monitor.isCoveredBy (CompRegion (10, 10, 40, 30))); |
249 | + EXPECT_FALSE (monitor.isCoveredBy (CompRegion (20, 20, 50, 20))); |
250 | + EXPECT_FALSE (monitor.isCoveredBy (CompRegion (0, 0, 1024, 768))); |
251 | + EXPECT_FALSE (monitor.isCoveredBy (CompRegion (0, 0, 1024, 768), |
252 | + FullscreenRegion::Desktop)); |
253 | +} |
254 | + |
255 | +TEST (OpenGLFullscreenRegion, CancelFullscreen1) |
256 | +{ |
257 | + FullscreenRegion monitor (CompRect (0, 0, 1024, 768)); |
258 | + EXPECT_FALSE (monitor.isCoveredBy (CompRegion (500, 500, 345, 234))); |
259 | + EXPECT_FALSE (monitor.isCoveredBy (CompRegion (0, 0, 1024, 768))); |
260 | + EXPECT_FALSE (monitor.isCoveredBy (CompRegion (10, 10, 40, 30))); |
261 | + EXPECT_FALSE (monitor.isCoveredBy (CompRegion (20, 20, 50, 20))); |
262 | + EXPECT_FALSE (monitor.isCoveredBy (CompRegion (0, 0, 1024, 768))); |
263 | + EXPECT_FALSE (monitor.isCoveredBy (CompRegion (0, 0, 1024, 768), |
264 | + FullscreenRegion::Desktop)); |
265 | +} |
266 | + |
267 | +TEST (OpenGLFullscreenRegion, CancelFullscreen2) |
268 | +{ |
269 | + FullscreenRegion monitor (CompRect (0, 0, 1024, 768)); |
270 | + EXPECT_FALSE (monitor.isCoveredBy (CompRegion (-100, -100, 1, 1))); |
271 | + EXPECT_FALSE (monitor.isCoveredBy (CompRegion (2000, 2000, 123, 456))); |
272 | + EXPECT_FALSE (monitor.isCoveredBy (CompRegion (500, 500, 345, 234))); |
273 | + EXPECT_FALSE (monitor.isCoveredBy (CompRegion (0, 0, 1024, 768))); |
274 | + EXPECT_FALSE (monitor.isCoveredBy (CompRegion (10, 10, 40, 30))); |
275 | + EXPECT_FALSE (monitor.isCoveredBy (CompRegion (20, 20, 50, 20))); |
276 | + EXPECT_FALSE (monitor.isCoveredBy (CompRegion (0, 0, 1024, 768))); |
277 | + EXPECT_FALSE (monitor.isCoveredBy (CompRegion (0, 0, 1024, 768), |
278 | + FullscreenRegion::Desktop)); |
279 | +} |
280 | + |
281 | +TEST (OpenGLFullscreenRegion, Overflow) |
282 | +{ |
283 | + FullscreenRegion monitor (CompRect (0, 0, 1024, 768)); |
284 | + EXPECT_FALSE (monitor.isCoveredBy (CompRegion (10, 10, 40, 30))); |
285 | + EXPECT_FALSE (monitor.isCoveredBy (CompRegion (-10, -10, 1044, 788))); |
286 | + EXPECT_FALSE (monitor.isCoveredBy (CompRegion (0, 0, 1024, 768))); |
287 | + EXPECT_FALSE (monitor.isCoveredBy (CompRegion (0, 0, 1024, 768), |
288 | + FullscreenRegion::Desktop)); |
289 | +} |
290 | + |
291 | + |
292 | |
293 | === modified file 'plugins/opengl/src/paint.cpp' |
294 | --- plugins/opengl/src/paint.cpp 2012-08-30 09:05:04 +0000 |
295 | +++ plugins/opengl/src/paint.cpp 2012-09-05 03:21:22 +0000 |
296 | @@ -38,9 +38,12 @@ |
297 | #include <opengl/opengl.h> |
298 | |
299 | #include "privates.h" |
300 | +#include "fsregion/fsregion.h" |
301 | |
302 | #define DEG2RAD (M_PI / 180.0f) |
303 | |
304 | +using namespace compiz::opengl; |
305 | + |
306 | GLScreenPaintAttrib defaultScreenPaintAttrib = { |
307 | 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -DEFAULT_Z_CAMERA |
308 | }; |
309 | @@ -241,7 +244,7 @@ |
310 | CompRegion tmpRegion (region); |
311 | CompWindow *w; |
312 | GLWindow *gw; |
313 | - int count, windowMask, odMask; |
314 | + int windowMask, odMask; |
315 | CompWindow *fullscreenWindow = NULL; |
316 | bool status, unredirectFS; |
317 | bool withOffset = false; |
318 | @@ -257,12 +260,10 @@ |
319 | if (mask & PAINT_SCREEN_TRANSFORMED_MASK) |
320 | { |
321 | windowMask = PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK; |
322 | - count = 1; |
323 | } |
324 | else |
325 | { |
326 | windowMask = 0; |
327 | - count = 0; |
328 | } |
329 | |
330 | /* |
331 | @@ -274,6 +275,8 @@ |
332 | |
333 | if (!(mask & PAINT_SCREEN_NO_OCCLUSION_DETECTION_MASK)) |
334 | { |
335 | + FullscreenRegion fs (*output); |
336 | + |
337 | /* detect occlusions */ |
338 | for (rit = pl.rbegin (); rit != pl.rend (); ++rit) |
339 | { |
340 | @@ -336,23 +339,18 @@ |
341 | tmpRegion -= w->region (); |
342 | |
343 | /* unredirect top most fullscreen windows. */ |
344 | - if (count == 0 && unredirectFS) |
345 | + FullscreenRegion::WinType type = |
346 | + w->type () & CompWindowTypeDesktopMask ? |
347 | + FullscreenRegion::Desktop : |
348 | + FullscreenRegion::Normal; |
349 | + |
350 | + if (unredirectFS && |
351 | + !(mask & PAINT_SCREEN_TRANSFORMED_MASK) && |
352 | + fs.isCoveredBy (w->region (), type)) |
353 | { |
354 | - if (w->region () == screen->region () && |
355 | - tmpRegion.isEmpty ()) |
356 | - { |
357 | - fullscreenWindow = w; |
358 | - } |
359 | - else |
360 | - { |
361 | - foreach (CompOutput &o, screen->outputDevs ()) |
362 | - if (w->region () == CompRegion (o)) |
363 | - fullscreenWindow = w; |
364 | - } |
365 | + fullscreenWindow = w; |
366 | } |
367 | } |
368 | - |
369 | - count++; |
370 | } |
371 | } |
372 |
Seems to work perfectly. But on hold until I figure out if automated testing is possible for this right now, without making the code totally unmaintainable...