Merge lp:~compiz-team/compiz/compiz.fix_1188900 into lp:compiz/0.9.10

Proposed by Sam Spilsbury
Status: Merged
Approved by: Andrea Azzarone
Approved revision: 3742
Merged at revision: 3742
Proposed branch: lp:~compiz-team/compiz/compiz.fix_1188900
Merge into: lp:compiz/0.9.10
Prerequisite: lp:~compiz-team/compiz/compiz.fix_1189369
Diff against target: 2107 lines (+2046/-2)
7 files modified
plugins/decor/CMakeLists.txt (+2/-0)
plugins/decor/tests/CMakeLists.txt (+1/-0)
plugins/decor/tests/acceptance/CMakeLists.txt (+1/-0)
plugins/decor/tests/acceptance/xorg-gtest/CMakeLists.txt (+36/-0)
plugins/decor/tests/acceptance/xorg-gtest/compiz_decor_acceptance_tests.cpp (+2003/-0)
tests/xorg-gtest/CMakeLists.txt (+1/-0)
tests/xorg-gtest/include/compiz-xorg-gtest.h (+2/-2)
To merge this branch: bzr merge lp:~compiz-team/compiz/compiz.fix_1188900
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Andrea Azzarone Approve
MC Return Approve
Review via email: mp+168386@code.launchpad.net

Commit message

Provide a basic decor plugin acceptance test suite.

This change provides a simple acceptance test suite for the decor plugin. It
creates a fake window decorator (cdt::FakeDecorator) and allows users to
create fake decorations (eg cdt::FakePixmapDecoration) which can be serialized
as decoration properties and set on windows under xorg-gtest. It also launches
compiz with the opengl, composite and decor plugins loaded and runs some
basic tests. Among them:

BaseDecorAcceptance.
  Startup:

    Basic canary "can we start compiz with these plugins" test

  FakeDecoratorSessionOwnerNameSetOnSelectionOwner:

    Create a fake decorator, ensure that libdecoration sets our
    session name "fake" on the selection owner

  FakeDecoratorReceiveClientMessage:

    Create fake decorator, ensure that libdecoration posts a client
    message to the root window announcing that the new decorator exists.

  DecorationSupportsWindowType:

    Create a fake decorator, announce support for the WINDOW type decorations
    and ensure that the correct atom is set on the session owner window.

  DecorationSupportsPixmapType:

    Create a fake decorator, announce support for the PIXMAP type decorations
    and ensure that the correct atom is set on the session owner window.

DecorFakeDecoratorAcceptance.
  WindowDefaultFallbackNoExtents:

    By default, newly created windows should recieve a fallback decoration
    but they should not have any frame extents.

DecorWithPixmapDefaultsAcceptance.

  These tests create a default pixmap decoration to use in the hypothetical
  situation that the window decorator hasn't yet generated a decoration
  for this window.

  FallbackRecieveInputFrameNotify:

    Verify that we get a _COMPIZ_WINDOW_DECOR_INPUT_FRAME property set on
    the client when it is created and mapped (eg, an input frame window
    was annonuced to be created)

  FallbackHasInputFrameInParent:

    Verify that a second window exists in the frame window after this
    message was recieved.

  FallbackNormalWindowExtentOnDecoration:

    Verify that _NET_FRAME_EXTENTS is set to the default window extents
    for the default decoration when the window was mapped.

  FallbackNormalWindowInputOnFrame:

    Verify that the input window matches the extents set.

PixmapDecoratedWindowAcceptance.

  These tests create a new window and an associated unique decoration for
  that window.

  MaximizeBorderExtentsOnMaximize:

    Maximize the window and ensure that the correct border extents are used.

  MaximizeBorderExtentsOnVertMaximize:

    Vertically maximize the window and ensure that the correct border extents
    are used.

  MaximizeBorderExtentsOnHorzMaximize:

    Horizontally maximize the window and ensure that the correct border
    extents are used.

  MaximizeFrameWindowSizeEqOutputSize:

    Maximie the window and ensure that the frame window exactly equals
    the output size.

  VertMaximizeFrameWindowSizeEqOutputYHeight:

    Maximize the window and ensure that the frame window's Y and Height
    values are consistent with the output size.

  HorzMaximizeFrameWindowSizeEqOutputXWidth:

    Ditto horizontal maximization.

  DISABLED_VertMaximizeFrameWindowSizeSameXWidth:

    Maximize the window vertically and ensure that the frame window's
    border-relative X position and width does not change.

    This test is disabled, as the behavior in compiz is currently broken,
    (but it means that we can fix it later and enable the test).

  DISABLED_HorzMaximizeFrameWindowSizeSameYHeight

    Maximize the window horizontally and ensure that the frame window's
    border-relative Y position and height does not change.

    This test is disabled, as the behavior in compiz is currently broken,
    (but it means that we can fix it later and enable the test).

(LP: #1188900)

Description of the change

Provide a basic decor plugin acceptance test suite.

This change provides a simple acceptance test suite for the decor plugin. It
creates a fake window decorator (cdt::FakeDecorator) and allows users to
create fake decorations (eg cdt::FakePixmapDecoration) which can be serialized
as decoration properties and set on windows under xorg-gtest. It also launches
compiz with the opengl, composite and decor plugins loaded and runs some
basic tests. Among them:

BaseDecorAcceptance.
  Startup:

    Basic canary "can we start compiz with these plugins" test

  FakeDecoratorSessionOwnerNameSetOnSelectionOwner:

    Create a fake decorator, ensure that libdecoration sets our
    session name "fake" on the selection owner

  FakeDecoratorReceiveClientMessage:

    Create fake decorator, ensure that libdecoration posts a client
    message to the root window announcing that the new decorator exists.

  DecorationSupportsWindowType:

    Create a fake decorator, announce support for the WINDOW type decorations
    and ensure that the correct atom is set on the session owner window.

  DecorationSupportsPixmapType:

    Create a fake decorator, announce support for the PIXMAP type decorations
    and ensure that the correct atom is set on the session owner window.

DecorFakeDecoratorAcceptance.
  WindowDefaultFallbackNoExtents:

    By default, newly created windows should recieve a fallback decoration
    but they should not have any frame extents.

DecorWithPixmapDefaultsAcceptance.

  These tests create a default pixmap decoration to use in the hypothetical
  situation that the window decorator hasn't yet generated a decoration
  for this window.

  FallbackRecieveInputFrameNotify:

    Verify that we get a _COMPIZ_WINDOW_DECOR_INPUT_FRAME property set on
    the client when it is created and mapped (eg, an input frame window
    was annonuced to be created)

  FallbackHasInputFrameInParent:

    Verify that a second window exists in the frame window after this
    message was recieved.

  FallbackNormalWindowExtentOnDecoration:

    Verify that _NET_FRAME_EXTENTS is set to the default window extents
    for the default decoration when the window was mapped.

  FallbackNormalWindowInputOnFrame:

    Verify that the input window matches the extents set.

PixmapDecoratedWindowAcceptance.

  These tests create a new window and an associated unique decoration for
  that window.

  MaximizeBorderExtentsOnMaximize:

    Maximize the window and ensure that the correct border extents are used.

  MaximizeBorderExtentsOnVertMaximize:

    Vertically maximize the window and ensure that the correct border extents
    are used.

  MaximizeBorderExtentsOnHorzMaximize:

    Horizontally maximize the window and ensure that the correct border
    extents are used.

  MaximizeFrameWindowSizeEqOutputSize:

    Maximie the window and ensure that the frame window exactly equals
    the output size.

  VertMaximizeFrameWindowSizeEqOutputYHeight:

    Maximize the window and ensure that the frame window's Y and Height
    values are consistent with the output size.

  HorzMaximizeFrameWindowSizeEqOutputXWidth:

    Ditto horizontal maximization.

  DISABLED_VertMaximizeFrameWindowSizeSameXWidth:

    Maximize the window vertically and ensure that the frame window's
    border-relative X position and width does not change.

    This test is disabled, as the behavior in compiz is currently broken,
    (but it means that we can fix it later and enable the test).

  DISABLED_HorzMaximizeFrameWindowSizeSameYHeight

    Maximize the window horizontally and ensure that the frame window's
    border-relative Y position and height does not change.

    This test is disabled, as the behavior in compiz is currently broken,
    (but it means that we can fix it later and enable the test).

Notes and Discussion:

 1. This does not cover all of the decor plugin's functionality. I just wanted to get at least these tests in-trunk and reviewed now that the diff is approaching 2000~ lines.

 2. compiz_decor_acceptance_tests.cpp should probably be split up into multiple files for each of the components (matchers, helper functions etc). At the moment its just all in one file until the majority of tests are implemented and we can figure out the best way to split the file up.

 3. As there isn't any way to specify multiple plugin load directories yet, these tests are not yet run by default. I'll implement that functionality later as it will take some time to do and is largely unrelated to this branch.

At the moment this means that you need to make install before running the test binary. Its found in build/plugins/decor/tests/acceptance/xorg-gtest

 4. Some tests are marked as DISABLED. That's because they test for behavior that doesn't quite work yet. Ideally, we'd fix the broken behavior and get to a point where all the tests can be re-enabled.,

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
MC Return (mc-return) wrote :

A minor typo in the commit message:

Maximie the window and ensure that the frame window exactly equals
    the output size.

Redundant brackets here:

230 + for (ct::CompizProcess::PluginList::iterator it = baseList.begin ();
231 + it != baseList.end ();
232 + ++it)
233 + {
234 + list.push_back (*it);
235 + }

You could align those Atoms also with Window:

142 + Atom mUtf8StringAtom;
143 + Atom mDecorationManagerNameAtom;
144 +
145 + Window mRootWindow;

All just minor issues, so no real need to fix anything here -> so take it, or leave it ;)

+1 from me.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
MC Return (mc-return) wrote :

So I guess this is ready to go ?

review: Approve
Revision history for this message
MC Return (mc-return) wrote :

Seems not :)

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Autolanding.
Approved revid is not set in launchpad. This is most likely a launchpad issue and re-approve should fix it. There is also a chance (although a very small one) this is a permission problem of the ps-jenkins bot.
http://jenkins.qa.ubuntu.com/job/compiz-autolanding/98/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/compiz-saucy-amd64-autolanding/10
    SUCCESS: http://jenkins.qa.ubuntu.com/job/compiz-saucy-armhf-autolanding/10
    SUCCESS: http://jenkins.qa.ubuntu.com/job/compiz-saucy-i386-autolanding/10

review: Needs Fixing (continuous-integration)
Revision history for this message
Andrea Azzarone (azzar1) wrote :

Ok this just adds tests. Code looks good overall. All tests pass.

[----------] Global test environment tear-down
Server terminated successfully (0). Closing log file.
[==========] 16 tests from 4 test cases ran. (5229 ms total)
[ PASSED ] 16 tests.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'plugins/decor/CMakeLists.txt'
--- plugins/decor/CMakeLists.txt 2012-09-25 01:15:36 +0000
+++ plugins/decor/CMakeLists.txt 2013-06-15 03:55:29 +0000
@@ -20,3 +20,5 @@
20endif (COMPIZ_BUILD_WITH_RPATH AND NOT COMPIZ_DISABLE_PLUGIN_DECOR)20endif (COMPIZ_BUILD_WITH_RPATH AND NOT COMPIZ_DISABLE_PLUGIN_DECOR)
2121
22install (PROGRAMS "src/compiz-decorator" DESTINATION ${exec_prefix})22install (PROGRAMS "src/compiz-decorator" DESTINATION ${exec_prefix})
23
24add_subdirectory (tests)
2325
=== added directory 'plugins/decor/tests'
=== added file 'plugins/decor/tests/CMakeLists.txt'
--- plugins/decor/tests/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ plugins/decor/tests/CMakeLists.txt 2013-06-15 03:55:29 +0000
@@ -0,0 +1,1 @@
1add_subdirectory (acceptance)
02
=== added directory 'plugins/decor/tests/acceptance'
=== added file 'plugins/decor/tests/acceptance/CMakeLists.txt'
--- plugins/decor/tests/acceptance/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ plugins/decor/tests/acceptance/CMakeLists.txt 2013-06-15 03:55:29 +0000
@@ -0,0 +1,1 @@
1add_subdirectory (xorg-gtest)
02
=== added directory 'plugins/decor/tests/acceptance/xorg-gtest'
=== added file 'plugins/decor/tests/acceptance/xorg-gtest/CMakeLists.txt'
--- plugins/decor/tests/acceptance/xorg-gtest/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ plugins/decor/tests/acceptance/xorg-gtest/CMakeLists.txt 2013-06-15 03:55:29 +0000
@@ -0,0 +1,36 @@
1include (FindPkgConfig)
2
3if (BUILD_XORG_GTEST)
4
5 include_directories (${compiz_SOURCE_DIR}/tests/shared
6 ${COMPIZ_XORG_SYSTEM_TEST_INCLUDE_DIR}
7 ${X11_INCLUDE_DIRS}
8 ${XORG_SERVER_INCLUDE_XORG_GTEST}
9 ${XORG_SERVER_GTEST_SRC}
10 ${GTEST_INCLUDE_DIRS})
11
12 link_directories (${X11_XI_LIBRARY_DIRS}
13 ${COMPIZ_COMPOSITE_DAMAGETRACKING_INTEGRATION_LIBRARY_DIRS})
14
15 add_executable (compiz_test_decor_acceptance
16 ${CMAKE_CURRENT_SOURCE_DIR}/compiz_decor_acceptance_tests.cpp)
17
18 set (COMPIZ_DECOR_ACCEPTANCE_TEST_LIBRARIES
19 xorg_gtest_all
20 compiz_xorg_gtest_main
21 compiz_xorg_gtest_system_test
22 decoration
23 ${GMOCK_LIBRARY}
24 ${GMOCK_MAIN_LIBRARY}
25 ${GTEST_BOTH_LIBRARIES}
26 ${XORG_SERVER_LIBRARIES}
27 ${X11_XI_LIBRARIES})
28
29 target_link_libraries (compiz_test_decor_acceptance
30 ${COMPIZ_DECOR_ACCEPTANCE_TEST_LIBRARIES})
31
32 # Not run by default yet until we're able to load plugins locally
33 #compiz_discover_tests (compiz_test_decor_acceptance WITH_XORG_GTEST)
34
35endif (BUILD_XORG_GTEST)
36
037
=== added file 'plugins/decor/tests/acceptance/xorg-gtest/compiz_decor_acceptance_tests.cpp'
--- plugins/decor/tests/acceptance/xorg-gtest/compiz_decor_acceptance_tests.cpp 1970-01-01 00:00:00 +0000
+++ plugins/decor/tests/acceptance/xorg-gtest/compiz_decor_acceptance_tests.cpp 2013-06-15 03:55:29 +0000
@@ -0,0 +1,2003 @@
1/*
2 * Compiz XOrg GTest Decoration Acceptance Tests
3 *
4 * Copyright (C) 2013 Sam Spilsbury.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 * Authored By:
21 * Sam Spilsbury <smspillaz@gmail.com>
22 */
23#include <gtest/gtest.h>
24#include <gmock/gmock.h>
25
26#include <sstream>
27#include <vector>
28
29#include <boost/shared_array.hpp>
30#include <boost/shared_ptr.hpp>
31
32#include <boost/bind.hpp>
33
34#include <X11/Xlib.h>
35#include <X11/Xatom.h>
36
37#include "decoration.h"
38
39#include <xorg/gtest/xorg-gtest.h>
40#include <compiz-xorg-gtest.h>
41
42namespace xt = xorg::testing;
43namespace ct = compiz::testing;
44
45using ::testing::AtLeast;
46using ::testing::ReturnNull;
47using ::testing::Return;
48using ::testing::MatcherInterface;
49using ::testing::MatchResultListener;
50using ::testing::Matcher;
51using ::testing::MakeMatcher;
52using ::testing::StrEq;
53using ::testing::_;
54
55class BaseDecorAcceptance :
56 public ct::AutostartCompizXorgSystemTestWithTestHelper
57{
58 public:
59
60 BaseDecorAcceptance ();
61
62 virtual void SetUp ();
63 virtual ct::CompizProcess::PluginList GetPluginList ();
64
65 protected:
66
67 Window mRootWindow;
68
69 Atom mUtf8StringAtom;
70 Atom mDecorationManagerNameAtom;
71 Atom mDecorationTypeAtom;
72 Atom mDecorationTypePixmap;
73 Atom mDecorationTypeWindow;
74 Atom mDecorationInputFrameAtom;
75 Atom mDecorationOutputFrameAtom;
76};
77
78BaseDecorAcceptance::BaseDecorAcceptance () :
79 mRootWindow (0),
80 mUtf8StringAtom (0),
81 mDecorationManagerNameAtom (0),
82 mDecorationTypeAtom (0),
83 mDecorationTypePixmap (0),
84 mDecorationTypeWindow (0),
85 mDecorationInputFrameAtom (0),
86 mDecorationOutputFrameAtom (0)
87{
88}
89
90void
91BaseDecorAcceptance::SetUp ()
92{
93 ct::AutostartCompizXorgSystemTestWithTestHelper::SetUp ();
94
95 mUtf8StringAtom = XInternAtom (Display (),
96 "UTF8_STRING",
97 1);
98
99 ASSERT_NE (0, mUtf8StringAtom);
100
101 mDecorationManagerNameAtom = XInternAtom (Display (),
102 "_COMPIZ_DM_NAME",
103 0);
104
105 ASSERT_NE (0, mDecorationManagerNameAtom);
106
107 mDecorationTypePixmap = XInternAtom (Display (),
108 DECOR_TYPE_PIXMAP_ATOM_NAME,
109 0);
110
111 ASSERT_NE (0, mDecorationTypePixmap);
112
113 mDecorationTypeWindow = XInternAtom (Display (),
114 DECOR_TYPE_WINDOW_ATOM_NAME,
115 0);
116
117 ASSERT_NE (0, mDecorationTypeWindow);
118
119 mDecorationTypeAtom = XInternAtom (Display (),
120 DECOR_TYPE_ATOM_NAME,
121 0);
122
123 ASSERT_NE (0, mDecorationTypeAtom);
124
125 mDecorationInputFrameAtom = XInternAtom (Display (),
126 DECOR_INPUT_FRAME_ATOM_NAME,
127 0);
128
129 ASSERT_NE (0, mDecorationInputFrameAtom);
130
131 mDecorationOutputFrameAtom = XInternAtom (Display (),
132 DECOR_OUTPUT_FRAME_ATOM_NAME,
133 0);
134
135 ASSERT_NE (0, mDecorationOutputFrameAtom);
136
137 mRootWindow = DefaultRootWindow (Display ());
138
139 ASSERT_NE (0, mRootWindow);
140}
141
142ct::CompizProcess::PluginList
143BaseDecorAcceptance::GetPluginList ()
144{
145 typedef ct::AutostartCompizXorgSystemTestWithTestHelper Base;
146 ct::CompizProcess::PluginList baseList (Base::GetPluginList ());
147 ct::CompizProcess::PluginList list;
148
149 list.push_back ("composite");
150 list.push_back ("opengl");
151 list.push_back ("decor");
152
153 for (ct::CompizProcess::PluginList::iterator it = baseList.begin ();
154 it != baseList.end ();
155 ++it)
156 list.push_back (*it);
157
158 return list;
159}
160
161namespace compiz
162{
163namespace decor
164{
165namespace testing
166{
167
168const char *DecorationClientName = "fake";
169
170const char *FailedToAcquireMessage =
171 "Could not acquire selection for an unknown reason";
172const char *OtherDecorationManagerRunningMessage =
173 "Another decoration manager is already running";
174
175class FakeDecorator
176{
177 public:
178
179 FakeDecorator (Display *d,
180 int supporting = WINDOW_DECORATION_TYPE_WINDOW);
181 ~FakeDecorator ();
182
183 Window currentSelectionOwner ();
184 Atom sessionOwnerAtom ();
185
186 Window supportingCheckWindow ();
187
188 private:
189
190 Display *mDpy;
191 int mScreenNumber;
192 Window mRootWindow;
193 int mSessionStatus;
194 Time mDecorationManagerTimestamp;
195
196 Atom mSessionOwnerAtom;
197 Window mSessionOwner;
198
199 Atom mSupportingHintAtom;
200 Atom mSupportingHintWindowAtom;
201 Window mSupportingHintWindow;
202
203};
204
205class FakeDecoration
206{
207 public:
208
209 typedef boost::shared_ptr <FakeDecoration> Ptr;
210
211 FakeDecoration (unsigned int type,
212 unsigned int state,
213 unsigned int actions,
214 unsigned int minWidth,
215 unsigned int minHeight);
216
217 virtual ~FakeDecoration ();
218
219 virtual size_t propertyDataSize () const = 0;
220 virtual void addPropertyData (std::vector <long> &) const = 0;
221
222 bool match (unsigned int type,
223 unsigned int state,
224 unsigned int actions) const;
225
226 protected:
227
228 void insertBaseData (std::vector <long> &) const;
229
230 static const size_t BaseDataSize = 5;
231
232 unsigned int mType;
233 unsigned int mState;
234 unsigned int mActions;
235
236 unsigned int mMinWidth;
237 unsigned int mMinHeight;
238};
239
240class FakeWindowTypeDecoration :
241 public FakeDecoration
242{
243 public:
244
245 FakeWindowTypeDecoration (unsigned int type,
246 unsigned int state,
247 unsigned int actions,
248 unsigned int minWidth,
249 unsigned int minHeight,
250 const decor_extents_t &restored,
251 const decor_extents_t &maximized);
252
253 protected:
254
255 size_t propertyDataSize () const;
256 void addPropertyData (std::vector<long> &) const;
257
258 static const unsigned int WindowDecorationSize = 8;
259
260 private:
261
262 decor_extents_t mRestored;
263 decor_extents_t mMaximized;
264};
265
266class FakePixmapTypeDecoration :
267 public FakeDecoration
268{
269 public:
270
271 FakePixmapTypeDecoration (unsigned int type,
272 unsigned int state,
273 unsigned int actions,
274 unsigned int minWidth,
275 unsigned int minHeight,
276 const decor_extents_t &restoredBorder,
277 const decor_extents_t &restoredInput,
278 const decor_extents_t &maximizedBorder,
279 const decor_extents_t &maximizedInput,
280 Display *dpy);
281 ~FakePixmapTypeDecoration ();
282
283 protected:
284
285 size_t propertyDataSize () const;
286 void addPropertyData (std::vector<long> &) const;
287
288 private:
289
290 decor_extents_t mRestoredBorder;
291 decor_extents_t mRestoredInput;
292 decor_extents_t mMaximizedBorder;
293 decor_extents_t mMaximizedInput;
294
295 decor_context_t mContext;
296 decor_quad_t mQuads[N_QUADS_MAX];
297 decor_layout_t mLayout;
298 unsigned int mNQuads;
299
300 Display *mDpy;
301 Pixmap mPixmap;
302};
303
304class FakeDecorationList
305{
306 public:
307
308 FakeDecorationList (unsigned int type) :
309 mDecorationType (type)
310 {
311 }
312
313 void AddDecoration (const FakeDecoration::Ptr &);
314 void RemoveDecoration (unsigned int type,
315 unsigned int state,
316 unsigned int actions);
317
318 void SetPropertyOnWindow (Display *dpy,
319 Window w,
320 Atom property);
321
322 private:
323
324 unsigned int mDecorationType;
325 std::vector <FakeDecoration::Ptr> decorations;
326};
327
328class AcquisitionFailed :
329 public std::exception
330{
331 public:
332
333 AcquisitionFailed (int status);
334
335 const char * what () const throw ();
336
337 private:
338
339 int mStatus;
340};
341
342}
343}
344}
345
346namespace
347{
348bool Advance (Display *d, bool result)
349{
350 return ct::AdvanceToNextEventOnSuccess (d, result);
351}
352
353class ManagerMessageMatcher :
354 public ct::ClientMessageXEventMatcher
355{
356 public:
357
358 ManagerMessageMatcher (Display *dpy,
359 Atom managed);
360
361 virtual bool MatchAndExplain (const XEvent &event,
362 MatchResultListener *listener) const;
363
364 virtual void DescribeTo (std::ostream *os) const;
365
366 private:
367
368 Display *mDpy;
369 Atom mManager;
370 Atom mManaged;
371};
372
373void FreePropertyData (unsigned char *array)
374{
375 if (array)
376 XFree (array);
377}
378
379int SafeFetchProperty (Display *dpy,
380 Window w,
381 Atom property,
382 long offset,
383 long length,
384 Atom requestedType,
385 Atom &returnType,
386 int &returnFormat,
387 unsigned long &returnNItems,
388 unsigned long &returnBytesRemaining,
389 boost::shared_ptr <unsigned char> &data)
390{
391 unsigned char *dataLocation;
392
393 int status = XGetWindowProperty (dpy, w, property, offset, length, 0,
394 requestedType, &returnType,
395 &returnFormat, &returnNItems,
396 &returnBytesRemaining,
397 &dataLocation);
398
399 data.reset (dataLocation,
400 boost::bind (FreePropertyData, _1));
401
402 return status;
403}
404
405void FetchAndVerifyProperty (Display *dpy,
406 Window w,
407 Atom property,
408 Atom expectedType,
409 int expectedFormat,
410 unsigned long expectedItems,
411 unsigned long expectedBytesAfter,
412 boost::shared_ptr <unsigned char> &data)
413{
414 Atom returnedType = 0;
415 int returnedFormat = 0;
416 unsigned long returnedNItems = 0;
417 unsigned long returnedBytesRemaining = 0;
418
419 std::stringstream ss;
420
421 int status = SafeFetchProperty (dpy,
422 w,
423 property,
424 0L,
425 1024L,
426 expectedType,
427 returnedType,
428 returnedFormat,
429 returnedNItems,
430 returnedBytesRemaining,
431 data);
432
433 if (status != Success)
434 ss << "XGetWindowProperty failed:" << std::endl;
435
436 if (returnedType != expectedType)
437 ss << "Expected type of " << XGetAtomName (dpy, expectedType)
438 << std::endl;
439
440 if (returnedFormat != expectedFormat)
441 ss << "Expected format of " << expectedFormat
442 << " but got " << returnedFormat << std::endl;
443
444 if (returnedNItems != expectedItems)
445 ss << "Expected " << expectedItems << " items"
446 << " but got " << returnedNItems << " items" << std::endl;
447
448 if (returnedBytesRemaining != expectedBytesAfter)
449 ss << "Expected " << expectedBytesAfter << " bytes remaining"
450 << " but got " << returnedBytesRemaining << " bytes remaining"
451 << std::endl;
452
453 if (!ss.str ().empty ())
454 throw std::logic_error (ss.str ());
455}
456}
457
458ManagerMessageMatcher::ManagerMessageMatcher (Display *dpy,
459 Atom managed) :
460 ct::ClientMessageXEventMatcher (dpy,
461 XInternAtom (dpy,
462 "MANAGER",
463 1),
464 DefaultRootWindow (dpy)),
465 mDpy (dpy),
466 mManaged (managed)
467{
468}
469
470bool
471ManagerMessageMatcher::MatchAndExplain (const XEvent &event,
472 MatchResultListener *listener) const
473{
474 if (ct::ClientMessageXEventMatcher::MatchAndExplain (event, listener))
475 {
476 /* Evaluate the second field for the atom */
477 return event.xclient.data.l[1] ==
478 static_cast <long> (mManaged);
479 }
480
481 return false;
482}
483
484void
485ManagerMessageMatcher::DescribeTo (std::ostream *os) const
486{
487 *os << "manager of selection atom " << XGetAtomName (mDpy, mManaged);
488}
489
490
491
492namespace cdt = compiz::decor::testing;
493
494cdt::FakeDecoration::FakeDecoration (unsigned int type,
495 unsigned int state,
496 unsigned int actions,
497 unsigned int minWidth,
498 unsigned int minHeight) :
499 mType (type),
500 mState (state),
501 mActions (actions),
502 mMinWidth (minWidth),
503 mMinHeight (minHeight)
504{
505}
506
507cdt::FakeDecoration::~FakeDecoration ()
508{
509}
510
511bool
512cdt::FakeDecoration::match (unsigned int type,
513 unsigned int state,
514 unsigned int actions) const
515{
516 return type == mType &&
517 state == mState &&
518 actions == mActions;
519}
520
521cdt::FakeWindowTypeDecoration::FakeWindowTypeDecoration (unsigned int type,
522 unsigned int state,
523 unsigned int actions,
524 unsigned int minWidth,
525 unsigned int minHeight,
526 const decor_extents_t &restored,
527 const decor_extents_t &maximized) :
528 FakeDecoration (type, state, actions, minWidth, minHeight),
529 mRestored (restored),
530 mMaximized (maximized)
531{
532}
533
534void
535cdt::FakeWindowTypeDecoration::addPropertyData (std::vector<long> &vec) const
536{
537 long propData[PROP_HEADER_SIZE + propertyDataSize ()];
538
539 decor_gen_window_property (propData,
540 0,
541 const_cast <decor_extents_t *> (&mRestored),
542 const_cast <decor_extents_t *> (&mMaximized),
543 mMinWidth,
544 mMinHeight,
545 mState,
546 mType,
547 mActions);
548
549 for (size_t i = PROP_HEADER_SIZE;
550 i < (PROP_HEADER_SIZE + propertyDataSize ());
551 ++i)
552 vec.push_back (propData[i]);
553}
554
555size_t
556cdt::FakeWindowTypeDecoration::propertyDataSize () const
557{
558 return WINDOW_PROP_SIZE;
559}
560
561cdt::FakePixmapTypeDecoration::FakePixmapTypeDecoration (unsigned int type,
562 unsigned int state,
563 unsigned int actions,
564 unsigned int minWidth,
565 unsigned int minHeight,
566 const decor_extents_t &restoredBorder,
567 const decor_extents_t &restoredInput,
568 const decor_extents_t &maximizedBorder,
569 const decor_extents_t &maximizedInput,
570 Display *dpy) :
571 FakeDecoration (type, state, actions, minWidth, minHeight),
572 mRestoredBorder (restoredBorder),
573 mRestoredInput (restoredInput),
574 mMaximizedBorder (maximizedBorder),
575 mMaximizedInput (maximizedInput),
576 mDpy (dpy),
577 mPixmap (XCreatePixmap (mDpy,
578 DefaultRootWindow (mDpy),
579 10,
580 10,
581 DefaultDepth (mDpy, (DefaultScreen (mDpy)))))
582{
583 /* 10x10 decoration, 0 corner space, 0 spacing, 2px each side */
584 mContext.extents.left = 2;
585 mContext.extents.right = 2;
586 mContext.extents.top = 2;
587 mContext.extents.bottom = 2;
588
589 mContext.left_space = 0;
590 mContext.right_space = 0;
591 mContext.top_space = 0;
592 mContext.bottom_space = 0;
593 mContext.left_corner_space = 0;
594 mContext.right_corner_space = 0;
595 mContext.top_corner_space = 0;
596 mContext.bottom_corner_space = 0;
597
598 decor_get_default_layout (&mContext, minWidth, minHeight, &mLayout);
599 mNQuads = decor_set_lSrStSbS_window_quads (mQuads, &mContext, &mLayout);
600}
601
602cdt::FakePixmapTypeDecoration::~FakePixmapTypeDecoration ()
603{
604 XFreePixmap (mDpy, mPixmap);
605}
606
607size_t
608cdt::FakePixmapTypeDecoration::propertyDataSize () const
609{
610 return BASE_PROP_SIZE + (QUAD_PROP_SIZE * mNQuads);
611}
612
613void
614cdt::FakePixmapTypeDecoration::addPropertyData (std::vector<long> &vec) const
615{
616 long propData[PROP_HEADER_SIZE + propertyDataSize ()];
617
618 decor_quads_to_property (propData,
619 0,
620 mPixmap,
621 const_cast <decor_extents_t *> (&mRestoredInput),
622 const_cast <decor_extents_t *> (&mRestoredBorder),
623 const_cast <decor_extents_t *> (&mMaximizedInput),
624 const_cast <decor_extents_t *> (&mMaximizedBorder),
625 mMinWidth,
626 mMinHeight,
627 const_cast <decor_quad_t *> (mQuads),
628 mNQuads,
629 mType,
630 mState,
631 mActions);
632
633 for (size_t i = PROP_HEADER_SIZE;
634 i < (PROP_HEADER_SIZE + propertyDataSize ());
635 ++i)
636 vec.push_back (propData[i]);
637}
638
639void
640cdt::FakeDecorationList::AddDecoration (const cdt::FakeDecoration::Ptr &decoration)
641{
642 decorations.push_back (decoration);
643}
644
645namespace
646{
647bool MatchesTypeStateAndActions (const cdt::FakeDecoration::Ptr &decoration,
648 unsigned int type,
649 unsigned int state,
650 unsigned int actions)
651{
652 return decoration->match (type, state, actions);
653}
654}
655
656void cdt::FakeDecorationList::RemoveDecoration (unsigned int type,
657 unsigned int state,
658 unsigned int actions)
659{
660 decorations.erase (
661 std::remove_if (decorations.begin (),
662 decorations.end (),
663 boost::bind (MatchesTypeStateAndActions,
664 _1,
665 type,
666 state,
667 actions)),
668 decorations.end ());
669}
670
671void
672cdt::FakeDecorationList::SetPropertyOnWindow (Display *dpy,
673 Window w,
674 Atom property)
675{
676 size_t size = PROP_HEADER_SIZE;
677 for (std::vector <FakeDecoration::Ptr>::iterator it = decorations.begin ();
678 it != decorations.end ();
679 ++it)
680 size += (*it)->propertyDataSize ();
681
682 std::vector <long> data;
683
684 data.reserve (size);
685
686 data.push_back (decor_version ());
687 data.push_back (mDecorationType);
688 data.push_back (decorations.size ());
689
690 for (std::vector <FakeDecoration::Ptr>::iterator it = decorations.begin ();
691 it != decorations.end ();
692 ++it)
693 (*it)->addPropertyData (data);
694
695 XChangeProperty (dpy,
696 w,
697 property,
698 XA_INTEGER,
699 32,
700 PropModeReplace,
701 reinterpret_cast <unsigned char *> (&data[0]),
702 size);
703}
704
705cdt::AcquisitionFailed::AcquisitionFailed (int status) :
706 mStatus (status)
707{
708}
709
710const char *
711cdt::AcquisitionFailed::what () const throw ()
712{
713 switch (mStatus)
714 {
715 case DECOR_ACQUIRE_STATUS_FAILED:
716 return FailedToAcquireMessage;
717 case DECOR_ACQUIRE_STATUS_OTHER_DM_RUNNING:
718 return OtherDecorationManagerRunningMessage;
719 default:
720 return "Unknown status";
721 }
722
723 return "Unknown status";
724}
725
726cdt::FakeDecorator::FakeDecorator (Display *d,
727 int supports) :
728 mDpy (d),
729 mScreenNumber (DefaultScreen (d)),
730 mRootWindow (DefaultRootWindow (d)),
731 mSessionStatus (decor_acquire_dm_session (d,
732 mScreenNumber,
733 "fake",
734 1,
735 &mDecorationManagerTimestamp)),
736 mSessionOwnerAtom (0),
737 mSessionOwner (0),
738 mSupportingHintAtom (XInternAtom (d, DECOR_TYPE_ATOM_NAME, 0)),
739 mSupportingHintWindowAtom (XInternAtom (d,
740 DECOR_SUPPORTING_DM_CHECK_ATOM_NAME,
741 0))
742{
743 if (mSessionStatus != DECOR_ACQUIRE_STATUS_SUCCESS)
744 throw AcquisitionFailed (mSessionStatus);
745
746 std::stringstream sessionOwnerStream;
747
748 sessionOwnerStream << "_COMPIZ_DM_S" << mScreenNumber;
749 mSessionOwnerAtom = XInternAtom (d,
750 sessionOwnerStream.str ().c_str (),
751 1);
752
753 mSessionOwner = XGetSelectionOwner (d, mSessionOwnerAtom);
754
755 if (!mSessionOwner)
756 throw std::runtime_error ("Expected a selection owner");
757
758 decor_set_dm_check_hint (d, mScreenNumber, supports);
759
760 boost::shared_ptr <unsigned char> data;
761
762 FetchAndVerifyProperty (mDpy,
763 mRootWindow,
764 mSupportingHintWindowAtom,
765 XA_WINDOW,
766 32,
767 1,
768 0,
769 data);
770
771 mSupportingHintWindow = *(reinterpret_cast <Window *> (data.get ()));
772
773 if (!mSupportingHintWindow)
774 throw std::runtime_error ("Failed to find supporting hint window");
775
776
777}
778
779cdt::FakeDecorator::~FakeDecorator ()
780{
781 /* Destroy the session owner, taking the selection with it */
782 XDestroyWindow (mDpy, mSessionOwner);
783 XDestroyWindow (mDpy, mSupportingHintWindow);
784}
785
786Window
787cdt::FakeDecorator::currentSelectionOwner ()
788{
789 return mSessionOwner;
790}
791
792Atom
793cdt::FakeDecorator::sessionOwnerAtom ()
794{
795 return mSessionOwnerAtom;
796}
797
798Atom
799cdt::FakeDecorator::supportingCheckWindow ()
800{
801 return mSupportingHintWindow;
802}
803
804TEST_F (BaseDecorAcceptance, Startup)
805{
806}
807
808TEST_F (BaseDecorAcceptance, FakeDecoratorSessionOwnerNameSetOnSelectionOwner)
809{
810 cdt::FakeDecorator decorator (Display ());
811 boost::shared_ptr <unsigned char> data;
812
813 FetchAndVerifyProperty (Display (),
814 decorator.currentSelectionOwner (),
815 mDecorationManagerNameAtom,
816 mUtf8StringAtom,
817 8,
818 4,
819 0,
820 data);
821
822 std::string name (reinterpret_cast <char *> (data.get ()));
823
824 EXPECT_THAT (name, StrEq (cdt::DecorationClientName));
825
826}
827
828TEST_F (BaseDecorAcceptance, FakeDecoratorReceiveClientMessage)
829{
830 cdt::FakeDecorator decorator (Display ());
831
832 ManagerMessageMatcher matcher (Display (),
833 decorator.sessionOwnerAtom ());
834
835 EXPECT_TRUE (Advance (Display (),
836 ct::WaitForEventOfTypeOnWindowMatching (Display (),
837 mRootWindow,
838 ClientMessage,
839 -1,
840 -1,
841 matcher)));
842}
843
844TEST_F (BaseDecorAcceptance, DecorationSupportsWindowType)
845{
846 cdt::FakeDecorator decorator (Display (),
847 WINDOW_DECORATION_TYPE_WINDOW);
848
849 boost::shared_ptr <unsigned char> data;
850
851 FetchAndVerifyProperty (Display (),
852 decorator.supportingCheckWindow (),
853 mDecorationTypeAtom,
854 XA_ATOM,
855 32,
856 1,
857 0,
858 data);
859
860 Atom *atoms = reinterpret_cast <Atom *> (data.get ());
861 EXPECT_EQ (atoms[0], mDecorationTypeWindow);
862}
863
864TEST_F (BaseDecorAcceptance, DecorationSupportsPixmapType)
865{
866 cdt::FakeDecorator decorator (Display (),
867 WINDOW_DECORATION_TYPE_PIXMAP);
868
869 boost::shared_ptr <unsigned char> data;
870
871 FetchAndVerifyProperty (Display (),
872 decorator.supportingCheckWindow (),
873 mDecorationTypeAtom,
874 XA_ATOM,
875 32,
876 1,
877 0,
878 data);
879
880 Atom *atoms = reinterpret_cast <Atom *> (data.get ());
881 EXPECT_EQ (atoms[0], mDecorationTypePixmap);
882}
883
884class DecorFakeDecoratorAcceptance :
885 public BaseDecorAcceptance
886{
887 protected:
888
889 virtual void SetUp ();
890 virtual void TearDown ();
891
892 virtual unsigned int SupportedDecorations () const;
893 virtual bool StartDecoratorOnSetUp () const;
894
895 void SetUpDecorator ();
896
897 std::auto_ptr <cdt::FakeDecorator> decorator;
898
899 Atom NETWMFrameExtentsAtom;
900 Atom WindowDecorationAtom;
901 Atom DefaultActiveDecorationAtom;
902 Atom DefaultBareDecorationAtom;
903};
904
905void
906DecorFakeDecoratorAcceptance::SetUp ()
907{
908 BaseDecorAcceptance::SetUp ();
909
910 NETWMFrameExtentsAtom = XInternAtom (Display (),
911 "_NET_FRAME_EXTENTS",
912 0);
913
914 WindowDecorationAtom = XInternAtom (Display (),
915 DECOR_WINDOW_ATOM_NAME,
916 0);
917
918 DefaultActiveDecorationAtom = XInternAtom (Display (),
919 DECOR_ACTIVE_ATOM_NAME,
920 0);
921
922 DefaultBareDecorationAtom = XInternAtom (Display (),
923 DECOR_BARE_ATOM_NAME,
924 0);
925
926 if (StartDecoratorOnSetUp ())
927 SetUpDecorator ();
928}
929
930void
931DecorFakeDecoratorAcceptance::SetUpDecorator ()
932{
933 decorator.reset (new cdt::FakeDecorator (Display (),
934 SupportedDecorations ()));
935}
936
937void
938DecorFakeDecoratorAcceptance::TearDown ()
939{
940 decorator.reset ();
941
942 BaseDecorAcceptance::TearDown ();
943}
944
945unsigned int
946DecorFakeDecoratorAcceptance::SupportedDecorations () const
947{
948 return WINDOW_DECORATION_TYPE_WINDOW;
949}
950
951bool
952DecorFakeDecoratorAcceptance::StartDecoratorOnSetUp () const
953{
954 return true;
955}
956
957namespace
958{
959void RecievePropertyNotifyEvents (Display *dpy,
960 Window w)
961{
962 XWindowAttributes attrib;
963
964 XGetWindowAttributes (dpy, w, &attrib);
965 XSelectInput (dpy, w, attrib.your_event_mask | PropertyChangeMask);
966}
967
968void WaitForPropertyNotify (Display *dpy,
969 Window w,
970 std::string const &prop)
971{
972 RecievePropertyNotifyEvents (dpy, w);
973
974 ct::PropertyNotifyXEventMatcher matcher (dpy,
975 prop);
976
977 ASSERT_TRUE (Advance (dpy,
978 ct::WaitForEventOfTypeOnWindowMatching (dpy,
979 w,
980 PropertyNotify,
981 -1,
982 -1,
983 matcher)));
984}
985
986void WaitForFrameExtents (Display *dpy,
987 Window w)
988{
989 RecievePropertyNotifyEvents (dpy, w);
990
991 XMapRaised (dpy, w);
992
993 WaitForPropertyNotify (dpy, w, "_NET_FRAME_EXTENTS");
994}
995
996Window FindParent (Display *dpy,
997 Window w)
998{
999 Window parent = 0;
1000 Window next = w;
1001 Window root = DefaultRootWindow (dpy);
1002
1003 while (next != root)
1004 {
1005 parent = next;
1006
1007 Window dummy;
1008 Window *children;
1009 unsigned int nchildren;
1010
1011 int status = XQueryTree (dpy, parent, &dummy, &next, &children, &nchildren);
1012 XFree (children);
1013
1014 if (!status)
1015 throw std::logic_error ("XQueryTree failed");
1016 }
1017
1018 return parent;
1019}
1020
1021void FreeWindowArray (Window *array)
1022{
1023 if (array)
1024 XFree (array);
1025}
1026
1027boost::shared_array <Window> FetchChildren (Display *dpy,
1028 Window w,
1029 unsigned int &n)
1030{
1031 Window *children;
1032 Window dummy;
1033
1034 int status = XQueryTree (dpy,
1035 w,
1036 &dummy,
1037 &dummy,
1038 &children,
1039 &n);
1040
1041 if (!status)
1042 throw std::logic_error ("XQueryTree failed");
1043
1044 return boost::shared_array <Window> (children,
1045 boost::bind (FreeWindowArray, _1));
1046}
1047
1048class FrameExtentsMatcher :
1049 public MatcherInterface <unsigned long *>
1050{
1051 public:
1052
1053 FrameExtentsMatcher (unsigned int left,
1054 unsigned int right,
1055 unsigned int top,
1056 unsigned int bottom);
1057
1058 bool MatchAndExplain (unsigned long *extents,
1059 MatchResultListener *listener) const;
1060
1061 void DescribeTo (std::ostream *os) const;
1062
1063 private:
1064
1065 unsigned int mLeft;
1066 unsigned int mRight;
1067 unsigned int mTop;
1068 unsigned int mBottom;
1069};
1070
1071Matcher <unsigned long *>
1072IsExtents (unsigned int left,
1073 unsigned int right,
1074 unsigned int top,
1075 unsigned int bottom)
1076{
1077 return MakeMatcher (new FrameExtentsMatcher (left, right, top, bottom));
1078}
1079}
1080
1081FrameExtentsMatcher::FrameExtentsMatcher (unsigned int left,
1082 unsigned int right,
1083 unsigned int top,
1084 unsigned int bottom) :
1085 mLeft (left),
1086 mRight (right),
1087 mTop (top),
1088 mBottom (bottom)
1089{
1090}
1091
1092bool
1093FrameExtentsMatcher::MatchAndExplain (unsigned long *extents,
1094 MatchResultListener *listener) const
1095{
1096 return mLeft == extents[0] &&
1097 mRight == extents[1] &&
1098 mTop == extents[2] &&
1099 mBottom == extents[3];
1100}
1101
1102void
1103FrameExtentsMatcher::DescribeTo (std::ostream *os) const
1104{
1105 *os << "Expected frame extents of :" << std::endl
1106 << " left: " << mLeft << std::endl
1107 << " right: " << mRight << std::endl
1108 << " top: " << mTop << std::endl
1109 << " bottom: " << mBottom << std::endl;
1110}
1111
1112TEST_F (DecorFakeDecoratorAcceptance, WindowDefaultFallbackNoExtents)
1113{
1114 Window w = ct::CreateNormalWindow (Display ());
1115 WaitForFrameExtents (Display (), w);
1116
1117 boost::shared_ptr <unsigned char> data;
1118
1119 FetchAndVerifyProperty (Display (),
1120 w,
1121 NETWMFrameExtentsAtom,
1122 XA_CARDINAL,
1123 32,
1124 4,
1125 0,
1126 data);
1127
1128 unsigned long *frameExtents =
1129 reinterpret_cast <unsigned long *> (data.get ());
1130
1131 EXPECT_THAT (frameExtents, IsExtents (0, 0, 0, 0));
1132}
1133
1134class DecorWithPixmapDefaultsAcceptance :
1135 public DecorFakeDecoratorAcceptance
1136{
1137 protected:
1138
1139 DecorWithPixmapDefaultsAcceptance ();
1140
1141 virtual void SetUp ();
1142 virtual void TearDown ();
1143 virtual unsigned int SupportedDecorations () const;
1144
1145 private:
1146
1147 Window mRoot;
1148
1149 protected:
1150
1151 cdt::FakeDecorationList rootActiveDecorationList;
1152 cdt::FakeDecorationList rootBareDecorationList;
1153
1154 static const unsigned int MaximizedBorderExtent = 1;
1155 static const unsigned int ActiveBorderExtent = 2;
1156 static const unsigned int ActiveInputExtent = 4;
1157};
1158
1159namespace
1160{
1161cdt::FakeDecoration::Ptr
1162MakeFakePixmapTypeDecoration (unsigned int type,
1163 unsigned int state,
1164 unsigned int actions,
1165 unsigned int minWidth,
1166 unsigned int minHeight,
1167 const decor_extents_t &restoredBorder,
1168 const decor_extents_t &restoredInput,
1169 const decor_extents_t &maximizedBorder,
1170 const decor_extents_t &maximizedInput,
1171 Display *dpy)
1172{
1173 cdt::FakeDecoration *decoration =
1174 new cdt::FakePixmapTypeDecoration (type,
1175 state,
1176 actions,
1177 minWidth,
1178 minHeight,
1179 restoredBorder,
1180 restoredInput,
1181 maximizedBorder,
1182 maximizedInput,
1183 dpy);
1184
1185 return boost::shared_ptr <cdt::FakeDecoration> (decoration);
1186}
1187
1188decor_extents_t
1189DecorationExtents (unsigned int left,
1190 unsigned int right,
1191 unsigned int top,
1192 unsigned int bottom)
1193{
1194 decor_extents_t extents;
1195
1196 extents.left = left;
1197 extents.right = right;
1198 extents.top = top;
1199 extents.bottom = bottom;
1200
1201 return extents;
1202}
1203
1204class ExtentsFromMatcher :
1205 public MatcherInterface <Window>
1206{
1207 public:
1208
1209 ExtentsFromMatcher (Display *dpy,
1210 Window w,
1211 const decor_extents_t &extents);
1212
1213 bool MatchAndExplain (Window window,
1214 MatchResultListener *listener) const;
1215
1216 void DescribeTo (std::ostream *os) const;
1217
1218 private:
1219
1220 Display *mDpy;
1221 Window mWindow;
1222 decor_extents_t mExpectedExtents;
1223};
1224
1225Matcher <Window>
1226ExtendsFromWindowBy (Display *dpy,
1227 Window w,
1228 const decor_extents_t &extents)
1229{
1230 return MakeMatcher (new ExtentsFromMatcher (dpy, w, extents));
1231}
1232}
1233
1234std::ostream &
1235operator<< (std::ostream &lhs, const decor_extents_t &extents)
1236{
1237 return lhs << "Extents: " << std::endl
1238 << " left: " << extents.left << std::endl
1239 << " right: " << extents.right << std::endl
1240 << " top: " << extents.top << std::endl
1241 << " bottom: " << extents.bottom << std::endl;
1242}
1243
1244ExtentsFromMatcher::ExtentsFromMatcher (Display *dpy,
1245 Window w,
1246 const decor_extents_t &extents) :
1247 mDpy (dpy),
1248 mWindow (w),
1249 mExpectedExtents (extents)
1250{
1251}
1252
1253bool
1254ExtentsFromMatcher::MatchAndExplain (Window window,
1255 MatchResultListener *listener) const
1256{
1257 unsigned int border, depth;
1258 Window root;
1259
1260 int compareX, compareY, matchX, matchY;
1261 unsigned int compareWidth, compareHeight, matchWidth, matchHeight;
1262
1263 if (!XGetGeometry (mDpy, window, &root,
1264 &matchX, &matchY, &matchWidth, &matchHeight,
1265 &border, &depth))
1266 throw std::logic_error ("XGetGeometry failed");
1267
1268 if (!XGetGeometry (mDpy, mWindow, &root,
1269 &compareX, &compareY, &compareWidth, &compareHeight,
1270 &border, &depth))
1271 throw std::logic_error ("XGetGeometry failed");
1272
1273 unsigned int left = matchX - compareX;
1274 unsigned int top = matchY - compareY;
1275 unsigned int right = (matchX + matchWidth) - (compareX + compareWidth);
1276 unsigned int bottom = (matchY + matchHeight) - (compareY + compareHeight);
1277
1278 decor_extents_t determinedExtents = DecorationExtents (left, right, top, bottom);
1279
1280 return decor_extents_cmp (&determinedExtents, &mExpectedExtents);
1281}
1282
1283void
1284ExtentsFromMatcher::DescribeTo (std::ostream *os) const
1285{
1286 *os << "Extends outwards from " << std::hex << mWindow << std::dec
1287 << " by: " << mExpectedExtents;
1288}
1289
1290DecorWithPixmapDefaultsAcceptance::DecorWithPixmapDefaultsAcceptance () :
1291 mRoot (0),
1292 rootActiveDecorationList (WINDOW_DECORATION_TYPE_PIXMAP),
1293 rootBareDecorationList (WINDOW_DECORATION_TYPE_PIXMAP)
1294{
1295}
1296
1297unsigned int
1298DecorWithPixmapDefaultsAcceptance::SupportedDecorations () const
1299{
1300 return WINDOW_DECORATION_TYPE_PIXMAP;
1301}
1302
1303void
1304DecorWithPixmapDefaultsAcceptance::SetUp ()
1305{
1306 DecorFakeDecoratorAcceptance::SetUp ();
1307
1308 mRoot = DefaultRootWindow (Display ());
1309
1310 unsigned int ResBo = ActiveBorderExtent;
1311 unsigned int ResIn = ActiveInputExtent;
1312 unsigned int MaxEx = MaximizedBorderExtent;
1313
1314 decor_extents_t activeBorderRestored (DecorationExtents (ResBo, ResBo, ResBo, ResBo));
1315 decor_extents_t activeBorderMaximized (DecorationExtents (MaxEx, MaxEx, MaxEx, MaxEx));
1316 decor_extents_t activeInputRestored (DecorationExtents (ResIn, ResIn, ResIn, ResIn));
1317 decor_extents_t activeInputMaximized (DecorationExtents (MaxEx, MaxEx, MaxEx, MaxEx));
1318
1319 decor_extents_t emptyExtents (DecorationExtents (0, 0, 0, 0));
1320
1321 cdt::FakeDecoration::Ptr rootActiveDecoration =
1322 MakeFakePixmapTypeDecoration (DECOR_WINDOW_TYPE_NORMAL,
1323 0,
1324 0,
1325 10, 10,
1326 activeBorderRestored,
1327 activeInputRestored,
1328 activeBorderMaximized,
1329 activeInputMaximized,
1330 Display ());
1331
1332 cdt::FakeDecoration::Ptr rootBareDecoration =
1333 MakeFakePixmapTypeDecoration (0, 0, 0,
1334 1, 1,
1335 emptyExtents,
1336 emptyExtents,
1337 emptyExtents,
1338 emptyExtents,
1339 Display ());
1340
1341 rootActiveDecorationList.AddDecoration (rootActiveDecoration);
1342 rootBareDecorationList.AddDecoration (rootBareDecoration);
1343
1344 rootActiveDecorationList.SetPropertyOnWindow (Display (),
1345 mRoot,
1346 DefaultActiveDecorationAtom);
1347 rootBareDecorationList.SetPropertyOnWindow (Display (),
1348 mRoot,
1349 DefaultBareDecorationAtom);
1350}
1351
1352void
1353DecorWithPixmapDefaultsAcceptance::TearDown ()
1354{
1355 /* Remove inserted decorations */
1356 rootActiveDecorationList.RemoveDecoration (DECOR_WINDOW_TYPE_NORMAL,
1357 0,
1358 0);
1359 rootBareDecorationList.RemoveDecoration (0, 0, 0);
1360
1361 DecorFakeDecoratorAcceptance::TearDown ();
1362}
1363
1364TEST_F (DecorWithPixmapDefaultsAcceptance, FallbackRecieveInputFrameNotify)
1365{
1366 Window w = ct::CreateNormalWindow (Display ());
1367 RecievePropertyNotifyEvents (Display (), w);
1368 XMapRaised (Display (), w);
1369
1370 ct::PropertyNotifyXEventMatcher matcher (Display (),
1371 DECOR_INPUT_FRAME_ATOM_NAME);
1372
1373 EXPECT_TRUE (Advance (Display (),
1374 ct::WaitForEventOfTypeOnWindowMatching (Display (),
1375 w,
1376 PropertyNotify,
1377 -1,
1378 -1,
1379 matcher)));
1380}
1381
1382TEST_F (DecorWithPixmapDefaultsAcceptance, FallbackHasInputFrameInParent)
1383{
1384 Window w = ct::CreateNormalWindow (Display ());
1385
1386 XMapRaised (Display (), w);
1387 WaitForPropertyNotify (Display (), w, DECOR_INPUT_FRAME_ATOM_NAME);
1388
1389 Window parent = FindParent (Display (), w);
1390
1391 unsigned int nChildren;
1392 boost::shared_array <Window> children (FetchChildren (Display (),
1393 parent,
1394 nChildren));
1395
1396 EXPECT_EQ (2, nChildren);
1397}
1398
1399namespace
1400{
1401Window FindDecorationWindowFromChildren (Display *dpy,
1402 const boost::shared_array <Window> &c,
1403 unsigned int nChildren)
1404{
1405 for (unsigned int i = 0; i < nChildren; ++i)
1406 {
1407 /* The decoration window will have no children, but
1408 * the wrapper window will have one child */
1409 unsigned int n;
1410 boost::shared_array <Window> childChildren (FetchChildren (dpy,
1411 c[i],
1412 n));
1413 if (n == 0)
1414 return c[i];
1415 }
1416
1417 return None;
1418}
1419}
1420
1421TEST_F (DecorWithPixmapDefaultsAcceptance, FallbackNormalWindowExtentOnDecoration)
1422{
1423 Window w = ct::CreateNormalWindow (Display ());
1424
1425 XMapRaised (Display (), w);
1426 WaitForPropertyNotify (Display (), w, DECOR_INPUT_FRAME_ATOM_NAME);
1427
1428 Window parent = FindParent (Display (), w);
1429
1430 unsigned int nChildren;
1431 boost::shared_array <Window> children (FetchChildren (Display (),
1432 parent,
1433 nChildren));
1434
1435 ASSERT_EQ (2, nChildren);
1436
1437 Window decorationWindow = FindDecorationWindowFromChildren (Display (),
1438 children,
1439 nChildren);
1440
1441 ASSERT_NE (None, decorationWindow);
1442
1443 decor_extents_t borderExtents (DecorationExtents (ActiveBorderExtent,
1444 ActiveBorderExtent,
1445 ActiveBorderExtent,
1446 ActiveBorderExtent));
1447 EXPECT_THAT (decorationWindow, ExtendsFromWindowBy (Display (),
1448 w,
1449 borderExtents));
1450}
1451
1452TEST_F (DecorWithPixmapDefaultsAcceptance, FallbackNormalWindowInputOnFrame)
1453{
1454 Window w = ct::CreateNormalWindow (Display ());
1455
1456 XMapRaised (Display (), w);
1457 WaitForPropertyNotify (Display (), w, DECOR_INPUT_FRAME_ATOM_NAME);
1458
1459 Window parent = FindParent (Display (), w);
1460
1461 decor_extents_t inputExtents (DecorationExtents (ActiveInputExtent,
1462 ActiveInputExtent,
1463 ActiveInputExtent,
1464 ActiveInputExtent));
1465 EXPECT_THAT (parent, ExtendsFromWindowBy (Display (),
1466 w,
1467 inputExtents));
1468}
1469
1470/* TODO: Get bare decorations tests */
1471
1472class PixmapDecoratedWindowAcceptance :
1473 public DecorWithPixmapDefaultsAcceptance
1474{
1475 public:
1476
1477 PixmapDecoratedWindowAcceptance ();
1478
1479 virtual void SetUp ();
1480 virtual void TearDown ();
1481
1482 virtual bool StartDecoratorOnSetUp () const;
1483
1484 protected:
1485
1486 Window mWindow;
1487 Window mParent;
1488 cdt::FakeDecorationList mDecorations;
1489};
1490
1491PixmapDecoratedWindowAcceptance::PixmapDecoratedWindowAcceptance () :
1492 mDecorations (WINDOW_DECORATION_TYPE_PIXMAP)
1493{
1494}
1495
1496void
1497PixmapDecoratedWindowAcceptance::SetUp ()
1498{
1499 DecorWithPixmapDefaultsAcceptance::SetUp ();
1500
1501 mWindow = ct::CreateNormalWindow (Display ());
1502 XSelectInput (Display (), mWindow,
1503 StructureNotifyMask |
1504 PropertyChangeMask);
1505 XMapRaised (Display (), mWindow);
1506
1507 /* Wait for the window to be reparented */
1508 Advance (Display (),
1509 ct::WaitForEventOfTypeOnWindow (Display (),
1510 mWindow,
1511 ReparentNotify,
1512 -1,
1513 -1));
1514
1515 /* Select for StructureNotify events on the parent window */
1516 mParent = FindParent (Display (), mWindow);
1517 XSelectInput (Display (), mParent, StructureNotifyMask);
1518
1519 /* Start the decorator */
1520 SetUpDecorator ();
1521
1522 unsigned int ResBo = ActiveBorderExtent;
1523 unsigned int ResIn = ActiveInputExtent;
1524 unsigned int MaxEx = MaximizedBorderExtent;
1525
1526 cdt::FakeDecoration::Ptr decoration =
1527 MakeFakePixmapTypeDecoration (DECOR_WINDOW_TYPE_NORMAL,
1528 0,
1529 0,
1530 10,
1531 10,
1532 DecorationExtents (ResBo, ResBo, ResBo, ResBo),
1533 DecorationExtents (ResIn, ResIn, ResIn, ResIn),
1534 DecorationExtents (MaxEx, MaxEx, MaxEx, MaxEx),
1535 DecorationExtents (MaxEx, MaxEx, MaxEx, MaxEx),
1536 Display ());
1537
1538 mDecorations.AddDecoration (decoration);
1539 mDecorations.SetPropertyOnWindow (Display (),
1540 mWindow,
1541 WindowDecorationAtom);
1542
1543 WaitForPropertyNotify (Display (), mWindow, DECOR_INPUT_FRAME_ATOM_NAME);
1544 WaitForPropertyNotify (Display (), mWindow, "_NET_FRAME_EXTENTS");
1545
1546 /* Wait for the parent window to be moved to -2, -2 */
1547 ct::ConfigureNotifyXEventMatcher matcher (None,
1548 0,
1549 ResBo - ResIn,
1550 ResBo - ResIn,
1551 0,
1552 0,
1553 CWX | CWY);
1554
1555 Advance (Display (),
1556 ct::WaitForEventOfTypeOnWindowMatching (Display (),
1557 mParent,
1558 ConfigureNotify,
1559 -1,
1560 -1,
1561 matcher));
1562}
1563
1564void
1565PixmapDecoratedWindowAcceptance::TearDown ()
1566{
1567 mDecorations.RemoveDecoration (DECOR_WINDOW_TYPE_NORMAL, 0, 0);
1568
1569 XDestroyWindow (Display (), mWindow);
1570
1571 DecorWithPixmapDefaultsAcceptance::TearDown ();
1572}
1573
1574bool
1575PixmapDecoratedWindowAcceptance::StartDecoratorOnSetUp () const
1576{
1577 return false;
1578}
1579
1580namespace
1581{
1582static const unsigned int RemoveState = 0;
1583static const unsigned int AddState = 1;
1584static const unsigned int ToggleState = 2;
1585
1586void ChangeStateOfWindow (Display *dpy,
1587 unsigned int mode,
1588 const std::string &state,
1589 Window w)
1590{
1591 XEvent event;
1592
1593 const long ClientTypePager = 2;
1594
1595 event.type = ClientMessage;
1596 event.xany.window = w;
1597
1598 event.xclient.format = 32;
1599 event.xclient.message_type = XInternAtom (dpy, "_NET_WM_STATE", 0);
1600
1601 event.xclient.data.l[0] = mode;
1602 event.xclient.data.l[1] = XInternAtom (dpy, state.c_str (), 0);
1603 event.xclient.data.l[2] = 0;
1604 event.xclient.data.l[3] = ClientTypePager;
1605
1606 XSendEvent (dpy,
1607 DefaultRootWindow (dpy),
1608 1,
1609 SubstructureRedirectMask,
1610 &event);
1611 XSync (dpy, 0);
1612}
1613
1614boost::shared_ptr <unsigned char>
1615FetchCardinalProperty (Display *dpy,
1616 Window w,
1617 Atom NETWMFrameExtentsAtom)
1618{
1619 boost::shared_ptr <unsigned char> data;
1620
1621 FetchAndVerifyProperty (dpy,
1622 w,
1623 NETWMFrameExtentsAtom,
1624 XA_CARDINAL,
1625 32,
1626 4,
1627 0,
1628 data);
1629
1630 return data;
1631}
1632}
1633
1634TEST_F (PixmapDecoratedWindowAcceptance, MaximizeBorderExtentsOnMaximize)
1635{
1636 ChangeStateOfWindow (Display (),
1637 AddState,
1638 "_NET_WM_STATE_MAXIMIZED_VERT",
1639 mWindow);
1640
1641 ChangeStateOfWindow (Display (),
1642 AddState,
1643 "_NET_WM_STATE_MAXIMIZED_HORZ",
1644 mWindow);
1645
1646 WaitForPropertyNotify (Display (), mWindow, "_NET_FRAME_EXTENTS");
1647
1648 boost::shared_ptr <unsigned char> data =
1649 FetchCardinalProperty (Display (),
1650 mWindow,
1651 NETWMFrameExtentsAtom);
1652
1653 unsigned long *frameExtents =
1654 reinterpret_cast <unsigned long *> (data.get ());
1655
1656 unsigned int MaxEx = MaximizedBorderExtent;
1657
1658 EXPECT_THAT (frameExtents, IsExtents (MaxEx, MaxEx, MaxEx, MaxEx));
1659}
1660
1661TEST_F (PixmapDecoratedWindowAcceptance, MaximizeBorderExtentsOnVertMaximize)
1662{
1663 ChangeStateOfWindow (Display (),
1664 AddState,
1665 "_NET_WM_STATE_MAXIMIZED_VERT",
1666 mWindow);
1667
1668 WaitForPropertyNotify (Display (), mWindow, "_NET_FRAME_EXTENTS");
1669
1670 boost::shared_ptr <unsigned char> data =
1671 FetchCardinalProperty (Display (),
1672 mWindow,
1673 NETWMFrameExtentsAtom);
1674
1675 unsigned long *frameExtents =
1676 reinterpret_cast <unsigned long *> (data.get ());
1677
1678 unsigned int MaxEx = MaximizedBorderExtent;
1679
1680 EXPECT_THAT (frameExtents, IsExtents (MaxEx, MaxEx, MaxEx, MaxEx));
1681}
1682
1683TEST_F (PixmapDecoratedWindowAcceptance, MaximizeBorderExtentsOnHorzMaximize)
1684{
1685 ChangeStateOfWindow (Display (),
1686 AddState,
1687 "_NET_WM_STATE_MAXIMIZED_HORZ",
1688 mWindow);
1689
1690 WaitForPropertyNotify (Display (), mWindow, "_NET_FRAME_EXTENTS");
1691
1692 boost::shared_ptr <unsigned char> data =
1693 FetchCardinalProperty (Display (),
1694 mWindow,
1695 NETWMFrameExtentsAtom);
1696
1697 unsigned long *frameExtents =
1698 reinterpret_cast <unsigned long *> (data.get ());
1699
1700 unsigned int MaxEx = MaximizedBorderExtent;
1701
1702 EXPECT_THAT (frameExtents, IsExtents (MaxEx, MaxEx, MaxEx, MaxEx));
1703}
1704
1705TEST_F (PixmapDecoratedWindowAcceptance, MaximizeFrameWindowSizeEqOutputSize)
1706{
1707 XWindowAttributes attrib;
1708 XGetWindowAttributes (Display (), DefaultRootWindow (Display ()), &attrib);
1709
1710 /* The assumption here is that there is only one output */
1711
1712 ChangeStateOfWindow (Display (),
1713 AddState,
1714 "_NET_WM_STATE_MAXIMIZED_VERT",
1715 mWindow);
1716
1717 ChangeStateOfWindow (Display (),
1718 AddState,
1719 "_NET_WM_STATE_MAXIMIZED_HORZ",
1720 mWindow);
1721
1722 ct::ConfigureNotifyXEventMatcher matcher (None,
1723 0,
1724 0,
1725 0,
1726 attrib.width,
1727 attrib.height,
1728 CWX | CWY | CWWidth | CWHeight);
1729
1730 EXPECT_TRUE (Advance (Display (),
1731 ct::WaitForEventOfTypeOnWindowMatching (Display (),
1732 mParent,
1733 ConfigureNotify,
1734 -1,
1735 -1,
1736 matcher)));
1737}
1738
1739TEST_F (PixmapDecoratedWindowAcceptance, VertMaximizeFrameWindowSizeEqOutputYHeight)
1740{
1741 XWindowAttributes attrib;
1742 XGetWindowAttributes (Display (), DefaultRootWindow (Display ()), &attrib);
1743
1744 ChangeStateOfWindow (Display (),
1745 AddState,
1746 "_NET_WM_STATE_MAXIMIZED_VERT",
1747 mWindow);
1748
1749 ct::ConfigureNotifyXEventMatcher matcher (None,
1750 0,
1751 0,
1752 0,
1753 0,
1754 attrib.height,
1755 CWY | CWHeight);
1756
1757 EXPECT_TRUE (Advance (Display (),
1758 ct::WaitForEventOfTypeOnWindowMatching (Display (),
1759 mParent,
1760 ConfigureNotify,
1761 -1,
1762 -1,
1763 matcher)));
1764}
1765
1766TEST_F (PixmapDecoratedWindowAcceptance, HorzMaximizeFrameWindowSizeEqOutputXWidth)
1767{
1768 XWindowAttributes attrib;
1769 XGetWindowAttributes (Display (), DefaultRootWindow (Display ()), &attrib);
1770
1771 ChangeStateOfWindow (Display (),
1772 AddState,
1773 "_NET_WM_STATE_MAXIMIZED_HORZ",
1774 mWindow);
1775
1776 ct::ConfigureNotifyXEventMatcher matcher (None,
1777 0,
1778 0,
1779 0,
1780 attrib.width,
1781 0,
1782 CWX | CWWidth);
1783
1784 EXPECT_TRUE (Advance (Display (),
1785 ct::WaitForEventOfTypeOnWindowMatching (Display (),
1786 mParent,
1787 ConfigureNotify,
1788 -1,
1789 -1,
1790 matcher)));
1791}
1792
1793namespace
1794{
1795class WindowGeometryMatcher :
1796 public MatcherInterface <Window>
1797{
1798 public:
1799
1800 WindowGeometryMatcher (Display *dpy,
1801 const Matcher <int> &x,
1802 const Matcher <int> &y,
1803 const Matcher <unsigned int> &width,
1804 const Matcher <unsigned int> &height,
1805 const Matcher <unsigned int> &border);
1806
1807 bool MatchAndExplain (Window x, MatchResultListener *listener) const;
1808 void DescribeTo (std::ostream *os) const;
1809
1810 private:
1811
1812 Display *mDpy;
1813
1814 Matcher <int> mX;
1815 Matcher <int> mY;
1816 Matcher <unsigned int> mWidth;
1817 Matcher <unsigned int> mHeight;
1818 Matcher <unsigned int> mBorder;
1819};
1820
1821Matcher <Window>
1822WindowGeometry (Display *dpy,
1823 const Matcher <int> &x,
1824 const Matcher <int> &y,
1825 const Matcher <unsigned int> &width,
1826 const Matcher <unsigned int> &height,
1827 const Matcher <unsigned int> &border)
1828{
1829 return MakeMatcher (new WindowGeometryMatcher (dpy,
1830 x,
1831 y,
1832 width,
1833 height,
1834 border));
1835}
1836}
1837
1838WindowGeometryMatcher::WindowGeometryMatcher (Display *dpy,
1839 const Matcher <int> &x,
1840 const Matcher <int> &y,
1841 const Matcher <unsigned int> &width,
1842 const Matcher <unsigned int> &height,
1843 const Matcher <unsigned int> &border) :
1844 mDpy (dpy),
1845 mX (x),
1846 mY (y),
1847 mWidth (width),
1848 mHeight (height),
1849 mBorder (border)
1850{
1851}
1852
1853bool
1854WindowGeometryMatcher::MatchAndExplain (Window w,
1855 MatchResultListener *listener) const
1856{
1857 Window root;
1858 int x, y;
1859 unsigned int width, height, border, depth;
1860
1861 if (!XGetGeometry (mDpy, w, &root, &x, &y, &width, &height, &border, &depth))
1862 throw std::logic_error ("XGetGeometry failed");
1863
1864 bool match = mX.MatchAndExplain (x, listener) &&
1865 mY.MatchAndExplain (y, listener) &&
1866 mWidth.MatchAndExplain (width, listener) &&
1867 mHeight.MatchAndExplain (height, listener) &&
1868 mBorder.MatchAndExplain (border, listener);
1869
1870 if (!match)
1871 {
1872 *listener << "Geometry:"
1873 << " x: " << x
1874 << " y: " << y
1875 << " width: " << width
1876 << " height: " << height
1877 << " border: " << border;
1878 }
1879
1880 return match;
1881}
1882
1883void
1884WindowGeometryMatcher::DescribeTo (std::ostream *os) const
1885{
1886 *os << "Window geometry matching :";
1887
1888 *os << std::endl << " - ";
1889 mX.DescribeTo (os);
1890
1891 *os << std::endl << " - ";
1892 mY.DescribeTo (os);
1893
1894 *os << std::endl << " - ";
1895 mWidth.DescribeTo (os);
1896
1897 *os << std::endl << " - ";
1898 mHeight.DescribeTo (os);
1899
1900 *os << std::endl << " - ";
1901 mBorder.DescribeTo (os);
1902}
1903
1904namespace
1905{
1906void WindowBorderPositionAttributes (Display *dpy,
1907 Window w,
1908 XWindowAttributes &attrib,
1909 unsigned int ActiveBorderExtent,
1910 unsigned int ActiveInputExtent)
1911{
1912 XGetWindowAttributes (dpy, w, &attrib);
1913
1914 /* Remove border - input offset */
1915 attrib.x -= (ActiveBorderExtent - ActiveInputExtent);
1916 attrib.y -= (ActiveBorderExtent - ActiveInputExtent);
1917 attrib.width -= (ActiveBorderExtent - ActiveInputExtent) * 2;
1918 attrib.height -= (ActiveBorderExtent - ActiveInputExtent) * 2;
1919}
1920}
1921
1922/* DISABLED - Upon maximization, x offset is 1, width offset is 10 */
1923TEST_F (PixmapDecoratedWindowAcceptance, DISABLED_VertMaximizeFrameWindowSizeSameXWidth)
1924{
1925 XWindowAttributes rootAttrib, attrib;
1926 XGetWindowAttributes (Display (), DefaultRootWindow (Display ()), &rootAttrib);
1927
1928 WindowBorderPositionAttributes (Display (), mParent, attrib, ActiveBorderExtent, ActiveInputExtent);
1929
1930 ChangeStateOfWindow (Display (),
1931 AddState,
1932 "_NET_WM_STATE_MAXIMIZED_VERT",
1933 mWindow);
1934
1935 /* Wait for the window to be maximized first */
1936 ct::ConfigureNotifyXEventMatcher matcher (None,
1937 0,
1938 0,
1939 0,
1940 0,
1941 rootAttrib.height,
1942 CWY | CWHeight);
1943
1944 Advance (Display (),
1945 ct::WaitForEventOfTypeOnWindowMatching (Display (),
1946 mParent,
1947 ConfigureNotify,
1948 -1,
1949 -1,
1950 matcher));
1951
1952 /* Query the window geometry and ensure that the width and
1953 * height have remained the same (adding on any extended borders,
1954 * in this case 0) */
1955 EXPECT_THAT (mParent, WindowGeometry (Display (),
1956 attrib.x,
1957 _,
1958 attrib.width,
1959 _,
1960 _));
1961}
1962
1963/* DISABLED - Upon maximization, y offset is 1, height offset is 10 */
1964TEST_F (PixmapDecoratedWindowAcceptance, DISABLED_HorzMaximizeFrameWindowSizeSameYHeight)
1965{
1966 XWindowAttributes rootAttrib, attrib;
1967 XGetWindowAttributes (Display (), DefaultRootWindow (Display ()), &rootAttrib);
1968
1969 WindowBorderPositionAttributes (Display (), mParent, attrib, ActiveBorderExtent, ActiveInputExtent);
1970
1971 ChangeStateOfWindow (Display (),
1972 AddState,
1973 "_NET_WM_STATE_MAXIMIZED_HORZ",
1974 mWindow);
1975
1976 /* Wait for the window to be maximized first */
1977 ct::ConfigureNotifyXEventMatcher matcher (None,
1978 0,
1979 0,
1980 0,
1981 rootAttrib.width,
1982 0,
1983 CWX | CWWidth);
1984
1985 Advance (Display (),
1986 ct::WaitForEventOfTypeOnWindowMatching (Display (),
1987 mParent,
1988 ConfigureNotify,
1989 -1,
1990 -1,
1991 matcher));
1992
1993 /* Query the window geometry and ensure that the width and
1994 * height have remained the same (adding on any extended borders,
1995 * in this case 0) */
1996 EXPECT_THAT (mParent, WindowGeometry (Display (),
1997 _,
1998 attrib.y,
1999 _,
2000 attrib.height,
2001 _));
2002}
2003
02004
=== modified file 'tests/xorg-gtest/CMakeLists.txt'
--- tests/xorg-gtest/CMakeLists.txt 2013-05-10 04:16:30 +0000
+++ tests/xorg-gtest/CMakeLists.txt 2013-06-15 03:55:29 +0000
@@ -37,6 +37,7 @@
37 ${CMAKE_CURRENT_SOURCE_DIR}/src/xorg_gtest_wrapper.cpp)37 ${CMAKE_CURRENT_SOURCE_DIR}/src/xorg_gtest_wrapper.cpp)
3838
39target_link_libraries (xorg_gtest_all39target_link_libraries (xorg_gtest_all
40 ${X11_XI_LIBRARIES}
40 ${GTEST_BOTH_LIBRARIES}41 ${GTEST_BOTH_LIBRARIES}
41 ${XORG_SERVER_GTEST_LIBRARIES})42 ${XORG_SERVER_GTEST_LIBRARIES})
4243
4344
=== modified file 'tests/xorg-gtest/include/compiz-xorg-gtest.h'
--- tests/xorg-gtest/include/compiz-xorg-gtest.h 2013-03-21 18:19:04 +0000
+++ tests/xorg-gtest/include/compiz-xorg-gtest.h 2013-06-15 03:55:29 +0000
@@ -213,6 +213,8 @@
213213
214 protected:214 protected:
215215
216 virtual void SetUp ();
217
216 Atom FetchAtom (const char *);218 Atom FetchAtom (const char *);
217 std::vector <long> WaitForWindowCreation (Window w);219 std::vector <long> WaitForWindowCreation (Window w);
218 bool IsOverrideRedirect (std::vector <long> &data);220 bool IsOverrideRedirect (std::vector <long> &data);
@@ -221,8 +223,6 @@
221223
222 private:224 private:
223225
224 virtual void SetUp ();
225
226 std::auto_ptr <PrivateAutostartCompizXorgSystemTestWithTestHelper> priv;226 std::auto_ptr <PrivateAutostartCompizXorgSystemTestWithTestHelper> priv;
227 };227 };
228 }228 }

Subscribers

People subscribed via source and target branches

to all changes: