Merge lp:~3v1n0/unity/fix-688117 into lp:unity

Proposed by Marco Trevisan (Treviño)
Status: Rejected
Rejected by: Jason Smith
Proposed branch: lp:~3v1n0/unity/fix-688117
Merge into: lp:unity
Prerequisite: lp:~3v1n0/unity/fix-690143
Diff against target: 247 lines (+119/-44)
2 files modified
plugins/unityshell/src/BamfLauncherIcon.cpp (+116/-44)
plugins/unityshell/src/BamfLauncherIcon.h (+3/-0)
To merge this branch: bzr merge lp:~3v1n0/unity/fix-688117
Reviewer Review Type Date Requested Status
Jason Smith (community) Needs Resubmitting
Review via email: mp+70084@code.launchpad.net

Description of the change

Fixing bug #688117

To get this, when all the application windows are in the selected workspace, we had to revert the order we activate the windows, and finally to move the focus to the top one.
Otherwise in the case that all the windows are in a different workspace we need a workaround, and basically before we have to activate the background windows, then wait for the workspace switch to be completed and finally to activate the top window.

/* OLD:
Unfortunately when we do a workspace switch there's no way to do this, and neither re-stacking the top window seems to help. */

Branch updated to give better support to the urgent windows.

To post a comment you must log in.
Revision history for this message
Jason Smith (jassmith) wrote :

Thank you for this branch. It was amazingly helpful in finally fixing the raise bug (though I did not use your code, you made me realize how to fix it). If there is anything I missed please let me know, and if not, please know your code was not a waste but a huge inspiration for the fix (which works cross workspace too).

review: Needs Resubmitting
Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

I've made a test with your code, it seems to work in some cases but it's buggy in some others.

For example: focus a window on a viewport, move to another viewport then click over its launcher icon: no viewport switch happens...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/unityshell/src/BamfLauncherIcon.cpp'
2--- plugins/unityshell/src/BamfLauncherIcon.cpp 2011-08-02 19:50:45 +0000
3+++ plugins/unityshell/src/BamfLauncherIcon.cpp 2011-08-02 19:50:46 +0000
4@@ -137,6 +137,7 @@
5 _dnd_hovered = false;
6 _launcher = IconManager;
7 _menu_desktop_shortcuts = NULL;
8+ _delayed_window = NULL;
9 char* icon_name = bamf_view_get_icon(BAMF_VIEW(m_App));
10
11 tooltip_text = BamfName();
12@@ -418,9 +419,11 @@
13 {
14 GList* children, *l;
15 BamfView* view;
16+ CompWindow* top_win = NULL;
17 bool any_urgent = false;
18 bool any_on_current = false;
19 bool any_mapped = false;
20+ bool any_focused = false;
21
22 children = bamf_view_get_children(BAMF_VIEW(m_App));
23
24@@ -434,13 +437,22 @@
25 if (BAMF_IS_WINDOW(view))
26 {
27 guint32 xid = bamf_window_get_xid(BAMF_WINDOW(view));
28-
29 CompWindow* window = m_Screen->findWindow((Window) xid);
30
31 if (window)
32 {
33 if (bamf_view_is_urgent(view))
34 any_urgent = true;
35+
36+ if (m_Screen->activeWindow() == xid)
37+ any_focused = true;
38+
39+ if (window->defaultViewport() == m_Screen->vp())
40+ any_on_current = true;
41+
42+ if (!window->minimized())
43+ any_mapped = true;
44+
45 windows.push_back(window);
46 }
47 }
48@@ -458,75 +470,135 @@
49 for (CompWindow* &win : m_Screen->windows())
50 {
51 if (std::find(windows.begin(), windows.end(), win) != windows.end())
52- tmp.push_back(win);
53+ tmp.insert(tmp.begin(), win);
54 }
55 windows = tmp;
56
57- /* filter based on workspace */
58- for (CompWindow* &win : windows)
59- {
60- if (win->defaultViewport() == m_Screen->vp())
61- {
62- any_on_current = true;
63- }
64-
65- if (!win->minimized())
66- {
67- any_mapped = true;
68- }
69-
70- if (any_on_current && any_mapped)
71- break;
72- }
73+ /*
74+ If no window is available in the current viewport we need to activate the
75+ other windows placed in the viewport which contains top window.
76+ However with the current compiz implementation if there are more of one
77+ window in the same viewport we have to activate the background windows
78+ before to switch viewport, and finally the top window.
79+ This is done using the event that compiz emits on viewport switch.
80+ */
81+ CompWindowList top_vp_windows;
82+ bool use_delayed_activate = false;
83
84 if (any_urgent)
85 {
86 // FIXME we cant use the compiz tracking since it is currently broken
87- /*for (it = windows.begin (); it != windows.end (); it++)
88- {
89- if ((*it)->state () & CompWindowStateDemandsAttentionMask)
90- {
91- (*it)->activate ();
92- break;
93- }
94- }*/
95- for (l = children; l; l = l->next)
96- {
97- view = (BamfView*) l->data;
98-
99- if (BAMF_IS_WINDOW(view))
100- {
101- guint32 xid = bamf_window_get_xid(BAMF_WINDOW(view));
102-
103- CompWindow* window = m_Screen->findWindow((Window) xid);
104-
105- if (window && bamf_view_is_urgent(view))
106+ // i.e. checking (win->state () & CompWindowStateDemandsAttentionMask)
107+
108+ for (CompWindow* &win : windows)
109+ {
110+ bool is_urgent = false;
111+
112+ for (l = children; l; l = l->next)
113+ {
114+ view = (BamfView*) l->data;
115+
116+ if (BAMF_IS_WINDOW(view) && bamf_view_is_urgent(view) &&
117+ win->id() == bamf_window_get_xid(BAMF_WINDOW(view)))
118 {
119- window->activate();
120+ is_urgent = true;
121 break;
122 }
123 }
124+
125+ if (is_urgent)
126+ {
127+ if (!top_win)
128+ {
129+ top_win = win;
130+ }
131+ else if (win->defaultViewport() == top_win->defaultViewport())
132+ {
133+ top_vp_windows.push_back(win);
134+ }
135+ }
136+ }
137+
138+ if (top_win)
139+ {
140+ if (top_vp_windows.size() > 0 && top_win->defaultViewport() != m_Screen->vp())
141+ {
142+ use_delayed_activate = true;
143+ }
144+ else
145+ {
146+ top_win->activate();
147+ }
148 }
149 }
150- else if (any_on_current)
151+ else if (!any_focused && any_on_current)
152 {
153 for (CompWindow* &win : windows)
154 {
155 if (win->defaultViewport() == m_Screen->vp() &&
156- ((any_mapped && !win->minimized()) || !any_mapped))
157+ (!any_mapped || (any_mapped && !win->minimized())))
158 {
159+ if (!top_win)
160+ top_win = win;
161+
162 win->activate();
163 }
164 }
165- }
166- else
167- {
168- (*(windows.rbegin()))->activate();
169+
170+ if (top_win)
171+ top_win->moveInputFocusTo();
172+ }
173+ else if (!any_focused)
174+ {
175+ for (CompWindow* &win : windows)
176+ {
177+ if (!any_mapped || (any_mapped && !win->minimized()))
178+ {
179+ if (!top_win)
180+ {
181+ top_win = win;
182+ }
183+ else if (win->defaultViewport() == top_win->defaultViewport())
184+ {
185+ top_vp_windows.push_back(win);
186+ }
187+ }
188+ }
189+
190+ if (top_vp_windows.size() > 0)
191+ {
192+ use_delayed_activate = true;
193+ }
194+ else if (top_win)
195+ {
196+ top_win->activate();
197+ }
198+ }
199+
200+ if (use_delayed_activate && top_vp_windows.size() > 0 && top_win)
201+ {
202+ _delayed_window = top_win;
203+ _delayed_connection = PluginAdapter::Default()->
204+ compiz_screen_viewport_switch_ended.connect(
205+ sigc::mem_fun(this,
206+ &BamfLauncherIcon::DelayedActivateWindow));
207+
208+ for (CompWindow* &win : top_vp_windows)
209+ win->activate();
210 }
211
212 g_list_free(children);
213 }
214
215+void BamfLauncherIcon::DelayedActivateWindow()
216+{
217+ if (_delayed_window)
218+ _delayed_window->activate();
219+
220+ _delayed_window = NULL;
221+ _delayed_connection.disconnect();
222+}
223+
224 bool BamfLauncherIcon::Spread(int state, bool force)
225 {
226 BamfView* view;
227
228=== modified file 'plugins/unityshell/src/BamfLauncherIcon.h'
229--- plugins/unityshell/src/BamfLauncherIcon.h 2011-08-02 19:50:45 +0000
230+++ plugins/unityshell/src/BamfLauncherIcon.h 2011-08-02 19:50:46 +0000
231@@ -80,6 +80,8 @@
232 std::map<std::string, DbusmenuMenuitem*> _menu_items;
233 std::map<std::string, gulong> _menu_callbacks;
234 DbusmenuMenuitem* _menu_desktop_shortcuts;
235+ sigc::connection _delayed_connection;
236+ CompWindow* _delayed_window;
237 gchar* _remote_uri;
238 bool _dnd_hovered;
239 guint _dnd_hover_timer;
240@@ -103,6 +105,7 @@
241
242 void OnWindowMinimized(guint32 xid);
243 void OnViewPortSwitchEnded();
244+ void DelayedActivateWindow();
245 bool OwnsWindow(Window w);
246
247 static void OnClosed(BamfView* view, gpointer data);