Merge lp:~smspillaz/unity/unity.maybe_fix_861143 into lp:unity

Proposed by Sam Spilsbury
Status: Merged
Approved by: Gord Allott
Approved revision: no longer in the source branch.
Merged at revision: 1686
Proposed branch: lp:~smspillaz/unity/unity.maybe_fix_861143
Merge into: lp:unity
Diff against target: 282 lines (+95/-34)
6 files modified
plugins/unityshell/src/PanelMenuView.cpp (+36/-3)
plugins/unityshell/src/PanelMenuView.h (+3/-0)
plugins/unityshell/src/PluginAdapter.cpp (+43/-31)
plugins/unityshell/src/PluginAdapter.h (+3/-0)
plugins/unityshell/src/WindowManager.h (+2/-0)
plugins/unityshell/src/unityshell.cpp (+8/-0)
To merge this branch: bzr merge lp:~smspillaz/unity/unity.maybe_fix_861143
Reviewer Review Type Date Requested Status
Unity Team Pending
Review via email: mp+77786@code.launchpad.net

Description of the change

Maybe fix LP#861143 (I can't reproduce it, but some debugging with Cimi showed what may have been going on)

Instead of explicitly undecorating windows when they are maximized, listen
for changes in decoration state on PropertyNotify events on the windows
themselves and respond to them, because we might get the maximization
event when the window is mapped before compiz has had a chance to decorate
the window.

Also cover the case where a window is withdrawn and then mapped maximized
again, where we wouldn't redecorate those windows.

In order to avoid cycling on our own undecoration requests, we set the
high bit on _MOTIF_WM_HINTS decoration field, if that high bit is
present and the window is otherwise undecorated, we should treat it
like it is still a decorated window and redecorate it when
it is restored. (Applications that explicitly undecorate the window
while this high bit is set are likely to clear the high bit and overwrite the
whole property, so we will be notified when this happens and can respond accordingly)

To post a comment you must log in.
Revision history for this message
Andrea Cimitan (cimi) wrote :

Here fixes the bug

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

Awesome

On Sat, Oct 1, 2011 at 10:43 PM, Andrea Cimitan
<email address hidden> wrote:
> Here fixes the bug
> --
> https://code.launchpad.net/~smspillaz/unity/unity.maybe_fix_861143/+merge/77786
> You are the owner of lp:~smspillaz/unity/unity.maybe_fix_861143.
>

--
Sam Spilsbury

Revision history for this message
Andrea Cimitan (cimi) wrote :

I can test the branch on another PC affected by the bug... Not now though
:-)

Revision history for this message
Andrea Cimitan (cimi) wrote :

Tested on a different pc that was exposing the bug... fixes the issue

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/unityshell/src/PanelMenuView.cpp'
2--- plugins/unityshell/src/PanelMenuView.cpp 2011-10-01 05:28:01 +0000
3+++ plugins/unityshell/src/PanelMenuView.cpp 2011-10-01 06:24:23 +0000
4@@ -135,8 +135,11 @@
5 win_manager->window_maximized.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowMaximized));
6 win_manager->window_restored.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowRestored));
7 win_manager->window_unmapped.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowUnmapped));
8+ win_manager->window_mapped.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowMapped));
9 win_manager->window_moved.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowMoved));
10 win_manager->window_resized.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowMoved));
11+ win_manager->window_decorated.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowDecorated));
12+ win_manager->window_undecorated.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowUndecorated));
13
14 PanelStyle::GetDefault()->changed.connect(sigc::mem_fun(this, &PanelMenuView::Refresh));
15
16@@ -984,7 +987,7 @@
17 // if we've just started tracking this window and it is maximized, let's
18 // make sure it's undecorated just in case it slipped by us earlier
19 // (I'm looking at you, Chromium!)
20- if (_is_maximized)
21+ if (_is_maximized && WindowManager::Default ()->IsWindowDecorated(xid))
22 {
23 WindowManager::Default()->Undecorate(xid);
24 _maximized_set.insert(xid);
25@@ -1051,8 +1054,38 @@
26 void
27 PanelMenuView::OnWindowUnmapped(guint32 xid)
28 {
29- _decor_map.erase(xid);
30- _maximized_set.erase(xid);
31+ if (WindowManager::Default()->IsWindowMaximized(xid))
32+ {
33+ WindowManager::Default()->Decorate(xid);
34+ _maximized_set.erase(xid);
35+ }
36+}
37+
38+void
39+PanelMenuView::OnWindowMapped(guint32 xid)
40+{
41+ if (WindowManager::Default()->IsWindowMaximized(xid))
42+ {
43+ WindowManager::Default()->Undecorate(xid);
44+ _maximized_set.insert(xid);
45+ }
46+}
47+
48+void
49+PanelMenuView::OnWindowDecorated(guint32 xid)
50+{
51+ _decor_map[xid] = true;
52+
53+ if (_maximized_set.find(xid) != _maximized_set.end ())
54+ {
55+ WindowManager::Default ()->Undecorate(xid);
56+ }
57+}
58+
59+void
60+PanelMenuView::OnWindowUndecorated(guint32 xid)
61+{
62+ _decor_map[xid] = false;
63 }
64
65 void
66
67=== modified file 'plugins/unityshell/src/PanelMenuView.h'
68--- plugins/unityshell/src/PanelMenuView.h 2011-09-28 16:24:09 +0000
69+++ plugins/unityshell/src/PanelMenuView.h 2011-10-01 06:24:23 +0000
70@@ -71,9 +71,12 @@
71 void OnWindowMinimized(guint32 xid);
72 void OnWindowUnminimized(guint32 xid);
73 void OnWindowUnmapped(guint32 xid);
74+ void OnWindowMapped(guint32 xid);
75 void OnWindowMaximized(guint32 xid);
76 void OnWindowRestored(guint32 xid);
77 void OnWindowMoved(guint32 xid);
78+ void OnWindowDecorated(guint32 xid);
79+ void OnWindowUndecorated(guint32 xid);
80
81 guint32 GetMaximizedWindow();
82
83
84=== modified file 'plugins/unityshell/src/PluginAdapter.cpp'
85--- plugins/unityshell/src/PluginAdapter.cpp 2011-09-29 07:49:23 +0000
86+++ plugins/unityshell/src/PluginAdapter.cpp 2011-10-01 06:24:23 +0000
87@@ -36,6 +36,7 @@
88
89 #define MWM_HINTS_FUNCTIONS (1L << 0)
90 #define MWM_HINTS_DECORATIONS (1L << 1)
91+#define MWM_HINTS_UNDECORATED_UNITY 0x80
92 #define _XA_MOTIF_WM_HINTS "_MOTIF_WM_HINTS"
93
94 /* static */
95@@ -141,6 +142,26 @@
96 }
97
98 void
99+PluginAdapter::NotifyNewDecorationState(guint32 xid)
100+{
101+ bool wasTracked = (_window_decoration_state.find (xid) != _window_decoration_state.end ());
102+ bool wasDecorated = false;
103+
104+ if (wasTracked)
105+ wasDecorated = _window_decoration_state[xid];
106+
107+ bool decorated = IsWindowDecorated (xid);
108+
109+ if (decorated == wasDecorated)
110+ return;
111+
112+ if (decorated && (!wasDecorated || !wasTracked))
113+ WindowManager::window_decorated.emit(xid);
114+ else if (wasDecorated || !wasTracked)
115+ WindowManager::window_undecorated.emit(xid);
116+}
117+
118+void
119 PluginAdapter::Notify(CompWindow* window, CompWindowNotify notify)
120 {
121 switch (notify)
122@@ -402,27 +423,20 @@
123 if (!hints)
124 return ret;
125
126- if (type == hints_atom && format != 0 && hints->flags & MWM_HINTS_DECORATIONS)
127+ /* Check for the presence of the high bit
128+ * if present, it means that we undecorated
129+ * this window, so don't mark it as undecorated */
130+ if (type == hints_atom && format != 0 &&
131+ hints->flags & MWM_HINTS_DECORATIONS)
132 {
133- ret = hints->decorations & (MwmDecorAll | MwmDecorTitle);
134+ /* Must have both bits set */
135+ _window_decoration_state[xid] = ret =
136+ (hints->decorations & (MwmDecorAll | MwmDecorTitle)) ||
137+ (hints->decorations & MWM_HINTS_UNDECORATED_UNITY);
138 }
139
140 XFree(hints);
141 return ret;
142-
143-/* FIXME compiz is too slow to update this value, and this could lead to
144- * issues like the bug #838923, since the read value isn't valid anymore
145- CompWindow* window;
146-
147- window = m_Screen->findWindow(win);
148- if (window)
149- {
150- unsigned int decor = window->mwmDecor();
151-
152- return decor & (MwmDecorAll | MwmDecorTitle);
153- }
154- return true;
155-*/
156 }
157
158 bool
159@@ -797,7 +811,7 @@
160 MotifWmHints hints = { 0 };
161
162 hints.flags = MWM_HINTS_DECORATIONS;
163- hints.decorations = GDK_DECOR_ALL;
164+ hints.decorations = GDK_DECOR_ALL & ~(MWM_HINTS_UNDECORATED_UNITY);
165
166 SetMwmWindowHints(xid, &hints);
167 }
168@@ -807,8 +821,11 @@
169 {
170 MotifWmHints hints = { 0 };
171
172+ /* Set the high bit to indicate that we undecorated this
173+ * window, when an application attempts to "undecorate"
174+ * the window again, this bit will be cleared */
175 hints.flags = MWM_HINTS_DECORATIONS;
176- hints.decorations = 0;
177+ hints.decorations = MWM_HINTS_UNDECORATED_UNITY;
178
179 SetMwmWindowHints(xid, &hints);
180 }
181@@ -831,7 +848,7 @@
182 Status status;
183 std::string win_wmclass;
184 int num_monitor;
185- CompOutput screen;
186+
187 int screen_width;
188 int screen_height;
189 float covering_part;
190@@ -839,6 +856,9 @@
191 if (!window)
192 return;
193
194+ if ((window->state() & MAXIMIZE_STATE) == MAXIMIZE_STATE)
195+ return;
196+
197 if (window->type() != CompWindowTypeNormalMask
198 || (window->actions() & MAXIMIZABLE) != MAXIMIZABLE)
199 return;
200@@ -856,17 +876,10 @@
201 return;
202
203 num_monitor = window->outputDevice();
204- screen = m_Screen->outputDevs().at(num_monitor);
205-
206- screen_height = screen.workArea().height();
207- screen_width = screen.workArea().width();
208-
209- if ((window->state() & MAXIMIZE_STATE) == MAXIMIZE_STATE)
210- {
211- LOG_DEBUG(logger) << "window mapped and already maximized, just undecorate";
212- Undecorate(window->id());
213- return;
214- }
215+ CompOutput &o = m_Screen->outputDevs().at(num_monitor);
216+
217+ screen_height = o.workArea().height();
218+ screen_width = o.workArea().width();
219
220 // use server<parameter> because the window won't show the real parameter as
221 // not mapped yet
222@@ -879,7 +892,6 @@
223 return;
224 }
225
226- Undecorate(window->id());
227 window->maximize(MAXIMIZE_STATE);
228 }
229
230
231=== modified file 'plugins/unityshell/src/PluginAdapter.h'
232--- plugins/unityshell/src/PluginAdapter.h 2011-09-27 03:41:15 +0000
233+++ plugins/unityshell/src/PluginAdapter.h 2011-10-01 06:24:23 +0000
234@@ -106,6 +106,7 @@
235 void NotifyResized(CompWindow* window, int x, int y, int w, int h);
236 void NotifyStateChange(CompWindow* window, unsigned int state, unsigned int last_state);
237 void NotifyCompizEvent(const char* plugin, const char* event, CompOption::Vector& option);
238+ void NotifyNewDecorationState(guint32 xid);
239
240 void Decorate(guint32 xid);
241 void Undecorate(guint32 xid);
242@@ -175,6 +176,8 @@
243 bool _in_show_desktop;
244 CompWindow* _last_focused_window;
245
246+ std::map<guint32, unsigned int> _window_decoration_state;
247+
248 static PluginAdapter* _default;
249 };
250
251
252=== modified file 'plugins/unityshell/src/WindowManager.h'
253--- plugins/unityshell/src/WindowManager.h 2011-09-27 03:41:15 +0000
254+++ plugins/unityshell/src/WindowManager.h 2011-10-01 06:24:23 +0000
255@@ -107,6 +107,8 @@
256 sigc::signal<void, guint32> window_resized;
257 sigc::signal<void, guint32> window_moved;
258 sigc::signal<void, guint32> window_focus_changed;
259+ sigc::signal<void, guint32> window_decorated;
260+ sigc::signal<void, guint32> window_undecorated;
261
262 sigc::signal<void> initiate_spread;
263 sigc::signal<void> terminate_spread;
264
265=== modified file 'plugins/unityshell/src/unityshell.cpp'
266--- plugins/unityshell/src/unityshell.cpp 2011-09-30 15:55:29 +0000
267+++ plugins/unityshell/src/unityshell.cpp 2011-10-01 06:24:23 +0000
268@@ -1021,6 +1021,14 @@
269 if (!skip_other_plugins)
270 screen->handleEvent(event);
271
272+ if (event->type == PropertyNotify)
273+ {
274+ if (event->xproperty.atom == Atoms::mwmHints)
275+ {
276+ PluginAdapter::Default ()->NotifyNewDecorationState(event->xproperty.window);
277+ }
278+ }
279+
280 if (!skip_other_plugins &&
281 screen->otherGrabExist("deco", "move", "switcher", "resize", NULL) &&
282 !switcherController->Visible())