Merge lp:~sjakthol/compiz/fix-986051 into lp:compiz/0.9.10

Proposed by Sami Jaktholm
Status: Merged
Approved by: Sam Spilsbury
Approved revision: 3768
Merged at revision: 3775
Proposed branch: lp:~sjakthol/compiz/fix-986051
Merge into: lp:compiz/0.9.10
Diff against target: 214 lines (+32/-54)
2 files modified
plugins/decor/src/decor.cpp (+3/-3)
plugins/decor/tests/acceptance/xorg-gtest/compiz_decor_acceptance_tests.cpp (+29/-51)
To merge this branch: bzr merge lp:~sjakthol/compiz/fix-986051
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Sam Spilsbury Approve
MC Return Needs Information
Review via email: mp+175740@code.launchpad.net

Commit message

Decor: Use maximized border extents only if window is fully maximized.

The decorator draws a normal border around semi-maximized windows. When
maximized border extents were used for semi-maximized windows, compiz didn't
reserve any space for the border in its geometry calculations.

At least following problems are a result of this behavior:
- Semi-maximized windows have 1px borders drawn on adjacent workspaces
  (LP: #986051).
- Grid placed window overlaps the adjacent viewport (LP: #898870).

Description of the change

Some observations
- this seems fix the issues with gtk-window-decorator (both metacity and cairo mode)
- haven't been able to test kde-window-decorator
- Emerald seems to still be broken with this but that's because Emerald gives compiz invalid frame extents for restored windows.

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

Hmm, I though the convention was to use the maximized border extents whenever a window was semi-maximized. I can't remember now what the design was supposed to be though. I think it might have been to use the normal borders.

If that's the case, then you'll need to update the acceptance tests for this. They're found in decor/tests/acceptance/xorg-gtest/compiz_decor_acceptance_tests. There should be a few tests in there that vertically maximize and horizontally maximize windows and expect the window to be placed with respect to its maximized extents. Those expectations need to be replaced with ones that use the normal extents instead.

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

All that being said, "not reserving any space for the border in geometry calculations" very much sounds like an issue that could be resolved without changing the extents used for maximized windows. Since quite recently the X and Width co-ordinates for the window border should be preserved through a maximize, so:

restored.x - restoredBorder.left == maximized.x - maximizedBorder.left.

There are even tests to verify that behaviour: PixmapDecoratedWindowAcceptance.HorzMaximizeFrameWindowSameYHeight
PixmapDecoratedWindowAcceptance.VertMaximizeFrameWindowSameXWidth

All in all, if this were still a problem, I would think it would be that the window was already one-pixel offscreen by its border before being maximized. The grid plugin moves the window before maximizing it, so that could be a cause.

Revision history for this message
Sami Jaktholm (sjakthol) wrote :

> Hmm, I though the convention was to use the maximized border extents whenever
> a window was semi-maximized. I can't remember now what the design was supposed
> to be though. I think it might have been to use the normal borders.

I don't know about the design but currently with gtk-window-decorator I can see that:
- normal windows have normal border
- semi-maximized windows have normal border
- maximized windows have the maximized border (which is no border).

> All that being said, "not reserving any space for the border in geometry
> calculations" very much sounds like an issue that could be resolved without
> changing the extents used for maximized windows.

With that I meant that decor plugin sets border extents to (0, 0, 28, 0) while the window really had a border with extents of (1, 1, 28, 1). Geometry calculations would have reserved space for the border had they known there was one.

> Since quite recently the X and Width co-ordinates for the window border
> should be preserved through a maximize, so:
>
> restored.x - restoredBorder.left == maximized.x - maximizedBorder.left.
>
> There are even tests to verify that behaviour:
> PixmapDecoratedWindowAcceptance.HorzMaximizeFrameWindowSameYHeight
> PixmapDecoratedWindowAcceptance.VertMaximizeFrameWindowSameXWidth

I don't think that applies to this case. In case of horizontally maximized windows, those tests ensure that Y and height don't change. However, the problem here is that when a window is horizontally maximized X and Width are wrong. The X for window content is 0 and Width is screen->width (). Now if there's a border around the contents, the border doesn't fit to the screen.

> All in all, if this were still a problem, I would think it would be that the
> window was already one-pixel offscreen by its border before being maximized.
> The grid plugin moves the window before maximizing it, so that could be a
> cause.

Grid might very be buggy. But this also happens with core semi-maximized windows. If you horizontally semi-maximize a window by right clicking the maximize button, the left border is shown in the viewport on the left and right border in the one on the right. There's no moving involved there. Just a change to the window state and a call to addWindowSizeChanges which takes care of the maximization.

But I'll fix those tests...

Revision history for this message
Sami Jaktholm (sjakthol) wrote :

I've investigated the tests and been able to fix the following cases:
- PixmapDecoratedWindowAcceptance.MaximizeBorderExtentsOnMaximize
- PixmapDecoratedWindowAcceptance.MaximizedBorderExtentsOnVertMaximize (renamed to RestoredBorderExtents...)
- PixmapDecoratedWindowAcceptance.MaximizedBorderExtentsOnHorzMaximize (renamed to RestoredBorderExtents...)

I'll push a fix for those in a moment.

However, there's still few tests broken:

- PixmapDecoratedWindowAcceptance.VertMaximizeFrameWindowSizeEqOutputYHeight
- PixmapDecoratedWindowAcceptance.HorzMaximizeFrameWindowSizeEqOutputXWidth

I'm not sure whether these above are relevant anymore. As semi-maximized windows have a restored border they will also have a restored frame. So these would basically become tests for the correct frame window size of restored windows.

- PixmapDecoratedWindowAcceptance.VertMaximizeFrameWindowSizeSameXWidth
- PixmapDecoratedWindowAcceptance.HorzMaximizeFrameWindowSizeSameYHeight

For these two, I'm not really sure what's actually going on. It seems that currently in trunk the frame window size stays constant altough the frame extents change on semi-maximize. But when the extents stay constant, the frame window size changes. As I'm not very familiar with decor, window frames or extents I need to take a closer look at the code to put some sense into this.

lp:~sjakthol/compiz/fix-986051 updated
3766. By Sami Jaktholm

Merge trunk

3767. By Sami Jaktholm

Test fixes

Revision history for this message
Sam Spilsbury (smspillaz) wrote :
Download full text (3.3 KiB)

>
> With that I meant that decor plugin sets border extents to (0, 0, 28, 0) while
> the window really had a border with extents of (1, 1, 28, 1). Geometry
> calculations would have reserved space for the border had they known there was
> one.

Ah okay that makes sense. I think that would have been gtk-window-decorator using the actual restored decoration while sending the maximized extents, so we needed to fix this in decor too. Thanks.

>
> > Since quite recently the X and Width co-ordinates for the window border
> > should be preserved through a maximize, so:
> >
> > restored.x - restoredBorder.left == maximized.x - maximizedBorder.left.
> >
> > There are even tests to verify that behaviour:
> > PixmapDecoratedWindowAcceptance.HorzMaximizeFrameWindowSameYHeight
> > PixmapDecoratedWindowAcceptance.VertMaximizeFrameWindowSameXWidth
>
> I don't think that applies to this case. In case of horizontally maximized
> windows, those tests ensure that Y and height don't change. However, the
> problem here is that when a window is horizontally maximized X and Width are
> wrong. The X for window content is 0 and Width is screen->width (). Now if
> there's a border around the contents, the border doesn't fit to the screen.
...
> - PixmapDecoratedWindowAcceptance.VertMaximizeFrameWindowSizeEqOutputYHeight
> - PixmapDecoratedWindowAcceptance.HorzMaximizeFrameWindowSizeEqOutputXWidth
>
> I'm not sure whether these above are relevant anymore. As semi-maximized
> windows have a restored border they will also have a restored frame. So these
> would basically become tests for the correct frame window size of restored
> windows.

The border geometry should exactly fit within the maximize area (eg, x == 0, w == screen->width ()) and the window content should fit exactly within the border (eg, x = border.left, w = screen->width () - (border.left + border.right)).

I think the tests check for the frame window geometry, but perhaps they don't check the border geometry?

>
> - PixmapDecoratedWindowAcceptance.VertMaximizeFrameWindowSizeSameXWidth
> - PixmapDecoratedWindowAcceptance.HorzMaximizeFrameWindowSizeSameYHeight
>
> For these two, I'm not really sure what's actually going on. It seems that
> currently in trunk the frame window size stays constant altough the frame
> extents change on semi-maximize. But when the extents stay constant, the frame
> window size changes. As I'm not very familiar with decor, window frames or
> extents I need to take a closer look at the code to put some sense into this.

I should probably clarify:

Frame Geometry == Geometry of the topmost parent window (which includes the invisible resize area, AKA "input area", the border, and the window). It might often be the case that this window would be larger than the output size when maximized.
Border Geometry == Geometry of the client including any decorations. It is never the case that this geometry would be larger than the output size when maximized.
Client Geometry == Geometry of the client. It might often be the case that this window would be smaller than the output size when maximized, but it will never be larger.

The decor plugin is somewhat complicated due to the large numb...

Read more...

lp:~sjakthol/compiz/fix-986051 updated
3768. By Sami Jaktholm

More text fixes.

Revision history for this message
Sami Jaktholm (sjakthol) wrote :

The rest of the tests are now fixed and passing. I just hope they are testing what they are supposed to test.

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

Yep, that looks fine to me. For semi-maximized windows with restored decorations, they might still have an extended input area, so that needs to be reflected in the width and height.

I'll approve this for now, but it might make the release after 0.9.10.

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

Wow, Sami -> you are on fire ! +1
Will test ASAP.

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

Sami, did you test Emerald with disabled Emerald setting "Use Decoration Cropping" ?

review: Needs Information
Revision history for this message
Sami Jaktholm (sjakthol) wrote :

I only tested emerald with default settings, and it didn't work with or without this branch.

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

Emerald is not supported we should not block branches if it is giving incorrect extents information in its protocol usage.

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

> Emerald is not supported we should not block branches if it is giving
> incorrect extents information in its protocol usage.

I did not want to block anything. It was just a question.
I really do not understand the hate regarding Emerald and I do not understand why the most advanced of the decorators is the only one we choose to not support...
It was always working perfectly until the global menu came along...

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
1=== modified file 'plugins/decor/src/decor.cpp'
2--- plugins/decor/src/decor.cpp 2013-07-15 04:21:45 +0000
3+++ plugins/decor/src/decor.cpp 2013-07-19 19:21:27 +0000
4@@ -1608,7 +1608,7 @@
5 /* Set extents based on maximize/unmaximize state
6 * FIXME: With the new type system, this should be
7 * removed */
8- if (decorMaximizeState)
9+ if (decorMaximizeState == MAXIMIZE_STATE)
10 window->setWindowFrameExtents (&decoration->maxBorder,
11 &decoration->maxInput);
12 else if (!window->hasUnmapReference ())
13@@ -1779,7 +1779,7 @@
14 parent = window->frame ();
15
16 /* Determine frame extents */
17- if ((window->state () & MAXIMIZE_STATE))
18+ if ((window->state () & MAXIMIZE_STATE) == MAXIMIZE_STATE)
19 {
20 border = wd->decor->maxBorder;
21 input = wd->decor->maxInput;
22@@ -1935,7 +1935,7 @@
23 CompWindowExtents input;
24
25 /* Determine frame extents */
26- if ((window->state () & MAXIMIZE_STATE))
27+ if ((window->state () & MAXIMIZE_STATE) == MAXIMIZE_STATE)
28 input = wd->decor->maxInput;
29 else
30 input = wd->decor->input;
31
32=== modified file 'plugins/decor/tests/acceptance/xorg-gtest/compiz_decor_acceptance_tests.cpp'
33--- plugins/decor/tests/acceptance/xorg-gtest/compiz_decor_acceptance_tests.cpp 2013-07-15 04:21:45 +0000
34+++ plugins/decor/tests/acceptance/xorg-gtest/compiz_decor_acceptance_tests.cpp 2013-07-19 19:21:27 +0000
35@@ -2159,6 +2159,8 @@
36 AddState,
37 "_NET_WM_STATE_MAXIMIZED_VERT",
38 mTestWindow);
39+
40+ WaitForPropertyNotify (Display (), mTestWindow, "_NET_FRAME_EXTENTS");
41
42 ChangeStateOfWindow (Display (),
43 AddState,
44@@ -2180,7 +2182,7 @@
45 EXPECT_THAT (frameExtents, IsExtents (MaxEx, MaxEx, MaxEx, MaxEx));
46 }
47
48-TEST_F (PixmapDecoratedWindowAcceptance, MaximizeBorderExtentsOnVertMaximize)
49+TEST_F (PixmapDecoratedWindowAcceptance, RestoredBorderExtentsOnVertMaximize)
50 {
51 ChangeStateOfWindow (Display (),
52 AddState,
53@@ -2197,12 +2199,12 @@
54 unsigned long *frameExtents =
55 reinterpret_cast <unsigned long *> (data.get ());
56
57- unsigned int MaxEx = MaximizedBorderExtent;
58+ unsigned int ActEx = RealDecorationActiveBorderExtent;
59
60- EXPECT_THAT (frameExtents, IsExtents (MaxEx, MaxEx, MaxEx, MaxEx));
61+ EXPECT_THAT (frameExtents, IsExtents (ActEx, ActEx, ActEx, ActEx));
62 }
63
64-TEST_F (PixmapDecoratedWindowAcceptance, MaximizeBorderExtentsOnHorzMaximize)
65+TEST_F (PixmapDecoratedWindowAcceptance, RestoredBorderExtentsOnHorzMaximize)
66 {
67 ChangeStateOfWindow (Display (),
68 AddState,
69@@ -2219,9 +2221,9 @@
70 unsigned long *frameExtents =
71 reinterpret_cast <unsigned long *> (data.get ());
72
73- unsigned int MaxEx = MaximizedBorderExtent;
74-
75- EXPECT_THAT (frameExtents, IsExtents (MaxEx, MaxEx, MaxEx, MaxEx));
76+ unsigned int ActEx = RealDecorationActiveBorderExtent;
77+
78+ EXPECT_THAT (frameExtents, IsExtents (ActEx, ActEx, ActEx, ActEx));
79 }
80
81 TEST_F (PixmapDecoratedWindowAcceptance, MaximizeFrameWindowSizeEqOutputSize)
82@@ -2258,7 +2260,7 @@
83 matcher)));
84 }
85
86-TEST_F (PixmapDecoratedWindowAcceptance, VertMaximizeFrameWindowSizeEqOutputYHeight)
87+TEST_F (PixmapDecoratedWindowAcceptance, VertMaximizeFrameWindowYHeight)
88 {
89 XWindowAttributes attrib;
90 XGetWindowAttributes (Display (), DefaultRootWindow (Display ()), &attrib);
91@@ -2268,12 +2270,13 @@
92 "_NET_WM_STATE_MAXIMIZED_VERT",
93 mTestWindow);
94
95+ int offset = RealDecorationActiveBorderExtent - ActiveInputExtent;
96 ct::ConfigureNotifyXEventMatcher matcher (None,
97 0,
98 0,
99- 0,
100- 0,
101- attrib.height,
102+ offset,
103+ 0,
104+ attrib.height - 2 * offset,
105 CWY | CWHeight);
106
107 EXPECT_TRUE (Advance (Display (),
108@@ -2285,7 +2288,7 @@
109 matcher)));
110 }
111
112-TEST_F (PixmapDecoratedWindowAcceptance, HorzMaximizeFrameWindowSizeEqOutputXWidth)
113+TEST_F (PixmapDecoratedWindowAcceptance, HorzMaximizeFrameWindowXWidth)
114 {
115 XWindowAttributes attrib;
116 XGetWindowAttributes (Display (), DefaultRootWindow (Display ()), &attrib);
117@@ -2295,11 +2298,12 @@
118 "_NET_WM_STATE_MAXIMIZED_HORZ",
119 mTestWindow);
120
121+ int offset = RealDecorationActiveBorderExtent - ActiveInputExtent;
122 ct::ConfigureNotifyXEventMatcher matcher (None,
123 0,
124- 0,
125- 0,
126- attrib.width,
127+ offset,
128+ 0,
129+ attrib.width - 2 * offset,
130 0,
131 CWX | CWWidth);
132
133@@ -2312,34 +2316,11 @@
134 matcher)));
135 }
136
137-namespace
138-{
139-void WindowBorderPositionAttributes (Display *dpy,
140- Window w,
141- XWindowAttributes &attrib,
142- unsigned int ActiveBorderExtent,
143- unsigned int ActiveInputExtent)
144-{
145- XGetWindowAttributes (dpy, w, &attrib);
146-
147- /* Remove input - border offset */
148- attrib.x += (ActiveInputExtent - ActiveBorderExtent);
149- attrib.y += (ActiveInputExtent - ActiveBorderExtent);
150- attrib.width -= (ActiveInputExtent - ActiveBorderExtent) * 2;
151- attrib.height -= (ActiveInputExtent - ActiveBorderExtent) * 2;
152-}
153-}
154-
155 TEST_F (PixmapDecoratedWindowAcceptance, VertMaximizeFrameWindowSizeSameXWidth)
156 {
157 XWindowAttributes rootAttrib, attrib;
158 XGetWindowAttributes (Display (), DefaultRootWindow (Display ()), &rootAttrib);
159-
160- WindowBorderPositionAttributes (Display (),
161- mTestWindowParent,
162- attrib,
163- RealDecorationActiveBorderExtent,
164- ActiveInputExtent);
165+ XGetWindowAttributes (Display (), mTestWindowParent, &attrib);
166
167 ChangeStateOfWindow (Display (),
168 AddState,
169@@ -2347,12 +2328,13 @@
170 mTestWindow);
171
172 /* Wait for the window to be maximized first */
173+ int offset = RealDecorationActiveBorderExtent - ActiveInputExtent;
174 WaitForConfigureOn (Display (),
175 mTestWindowParent,
176 0,
177- 0,
178- 0,
179- rootAttrib.height,
180+ offset,
181+ 0,
182+ rootAttrib.height - 2 * offset,
183 CWY | CWHeight);
184
185 /* Query the window geometry and ensure that the width and
186@@ -2372,12 +2354,7 @@
187 {
188 XWindowAttributes rootAttrib, attrib;
189 XGetWindowAttributes (Display (), DefaultRootWindow (Display ()), &rootAttrib);
190-
191- WindowBorderPositionAttributes (Display (),
192- mTestWindowParent,
193- attrib,
194- RealDecorationActiveBorderExtent,
195- ActiveInputExtent);
196+ XGetWindowAttributes (Display (), mTestWindowParent, &attrib);
197
198 ChangeStateOfWindow (Display (),
199 AddState,
200@@ -2385,11 +2362,12 @@
201 mTestWindow);
202
203 /* Wait for the window to be maximized first */
204+ int offset = RealDecorationActiveBorderExtent - ActiveInputExtent;
205 WaitForConfigureOn (Display (),
206 mTestWindowParent,
207- 0,
208- 0,
209- rootAttrib.width,
210+ offset,
211+ 0,
212+ rootAttrib.width - 2 * offset,
213 0,
214 CWX | CWWidth);
215

Subscribers

People subscribed via source and target branches