Merge lp:~unity-team/unity/more-multi-monitor into lp:unity

Proposed by Neil J. Patel
Status: Merged
Approved by: Rodrigo Moya
Approved revision: no longer in the source branch.
Merged at revision: 1005
Proposed branch: lp:~unity-team/unity/more-multi-monitor
Merge into: lp:unity
Diff against target: 1163 lines (+617/-108)
18 files modified
src/PanelController.cpp (+212/-0)
src/PanelController.h (+58/-0)
src/PanelIndicatorObjectEntryView.cpp (+2/-2)
src/PanelMenuView.cpp (+69/-7)
src/PanelMenuView.h (+9/-0)
src/PanelView.cpp (+33/-3)
src/PanelView.h (+7/-1)
src/PlacesController.h (+1/-0)
src/PluginAdapter.cpp (+18/-0)
src/PluginAdapter.h (+2/-0)
src/UScreen.cpp (+121/-0)
src/UScreen.h (+53/-0)
src/WindowManager.cpp (+7/-2)
src/WindowManager.h (+2/-0)
src/unity-panel-view-accessible.cpp (+2/-2)
src/unityshell.cpp (+16/-81)
src/unityshell.h (+3/-10)
tests/CMakeLists.txt (+2/-0)
To merge this branch: bzr merge lp:~unity-team/unity/more-multi-monitor
Reviewer Review Type Date Requested Status
Rodrigo Moya (community) Approve
Alejandro Piñeiro (community) Approve
Gord Allott (community) Approve
Review via email: mp+54389@code.launchpad.net

Description of the change

Okay, this is a biggy in the can-break-the-world sense of things :)

It adds a panel per monitor, which exhibits the follow behaviour:

- Home button is only on primary monitor (this is because I don't have the time to make laucnehr and dash work correctly with >1 home button

- Menubar/title/window buttons only draw on the monitor where the active window is.

- If you move a window to another monitor, the menubar/title/window-buttons will follow

- F10, Alt+$foo therefore effect the monitor where the active window is

- All monitors get the app/system indicators

- Tray is a bit weird (can be on any monitor), will fix that separately.

Please make sure:

1. Normal case of one monitor still works
2. Two monitors work as described
3. Monitors of different size etc work

I'll ask apinheiro to make sure I didn't break a11y.

To post a comment you must log in.
Revision history for this message
Gord Allott (gordallott) wrote :

Works well on my un-even monitors (1920x1600 - 1440x900) with two comments

Fullscreen doesn't work if you don't have the fullscreen application focused anymore, i loaded up a video to test on my second monitor, set it in to fullscreen mode and clicked on a window on my first monitor, panel is now drawn over the video on the second monitor. tested with VLC

Windows should only be considered on a monitor if the window has a significant portion on that monitor (> 50%? probably needs some testing to find the "right" amount - especially for applications that you might actually want spanning > 1 monitor

review: Approve
Revision history for this message
Alejandro Piñeiro (apinheiro) wrote :

I have tested it and the launcher part and other things (like the key event reemission) are working.

Anyway, it also modifies a lot the panel, so I added rodrigo to the review list, in order to check it.

As I said, it is ok for me.

review: Approve
Revision history for this message
Rodrigo Moya (rodrigo-moya) wrote :

Seems the panel service keeps working as expected, approving

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'src/PanelController.cpp'
2--- src/PanelController.cpp 1970-01-01 00:00:00 +0000
3+++ src/PanelController.cpp 2011-03-23 17:01:13 +0000
4@@ -0,0 +1,212 @@
5+/*
6+ * Copyright (C) 2011 Canonical Ltd
7+ *
8+ * This program is free software: you can redistribute it and/or modify
9+ * it under the terms of the GNU General Public License version 3 as
10+ * published by the Free Software Foundation.
11+ *
12+ * This program is distributed in the hope that it will be useful,
13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+ * GNU General Public License for more details.
16+ *
17+ * You should have received a copy of the GNU General Public License
18+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
19+ *
20+ * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
21+ */
22+
23+#include "PanelController.h"
24+
25+#include "UScreen.h"
26+
27+#include "unitya11y.h"
28+#include "unity-util-accessible.h"
29+
30+PanelController::PanelController ()
31+: _bfb_size (66),
32+ _opacity (1.0f)
33+{
34+ UScreen *screen = UScreen::GetDefault ();
35+
36+ screen->changed.connect (sigc::mem_fun (this, &PanelController::OnScreenChanged));
37+
38+ OnScreenChanged (screen->GetPrimaryMonitor (), screen->GetMonitors ());
39+}
40+
41+PanelController::~PanelController ()
42+{
43+
44+}
45+
46+void
47+PanelController::SetBFBSize (int size)
48+{
49+ std::vector<nux::BaseWindow *>::iterator it, eit = _windows.end ();
50+
51+ _bfb_size = size;
52+
53+ for (it = _windows.begin (); it != eit; ++it)
54+ {
55+ ViewForWindow (*it)->GetHomeButton ()->SetButtonWidth (_bfb_size);
56+ }
57+}
58+
59+void
60+PanelController::StartFirstMenuShow ()
61+{
62+ std::vector<nux::BaseWindow *>::iterator it, eit = _windows.end ();
63+
64+ for (it = _windows.begin (); it != eit; ++it)
65+ {
66+ PanelView *view = ViewForWindow (*it);
67+
68+ view->StartFirstMenuShow ();
69+ }
70+}
71+
72+void
73+PanelController::EndFirstMenuShow ()
74+{
75+ std::vector<nux::BaseWindow *>::iterator it, eit = _windows.end ();
76+
77+ for (it = _windows.begin (); it != eit; ++it)
78+ {
79+ PanelView *view = ViewForWindow (*it);
80+ view->EndFirstMenuShow ();
81+ }
82+}
83+
84+void
85+PanelController::SetOpacity (float opacity)
86+{
87+ std::vector<nux::BaseWindow *>::iterator it, eit = _windows.end ();
88+
89+ _opacity = opacity;
90+
91+ for (it = _windows.begin (); it != eit; ++it)
92+ {
93+ ViewForWindow (*it)->SetOpacity (_opacity);
94+ }
95+}
96+
97+PanelView *
98+PanelController::ViewForWindow (nux::BaseWindow *window)
99+{
100+ nux::Layout *layout = window->GetLayout ();
101+ std::list<nux::Area *>::iterator it = layout->GetChildren ().begin ();
102+
103+ return static_cast<PanelView *> (*it);
104+}
105+
106+// We need to put a panel on every monitor, and try and re-use the panels we already have
107+void
108+PanelController::OnScreenChanged (int primary_monitor, std::vector<nux::Geometry>& monitors)
109+{
110+ std::vector<nux::BaseWindow *>::iterator it, eit = _windows.end ();
111+ int n_monitors = monitors.size ();
112+ int i = 0;
113+
114+ for (it = _windows.begin (); it != eit; ++it)
115+ {
116+ if (i < n_monitors)
117+ {
118+ PanelView *view;
119+
120+ (*it)->EnableInputWindow (false);
121+ (*it)->InputWindowEnableStruts (false);
122+
123+ nux::Geometry geo = monitors[i];
124+ geo.height = 24;
125+ (*it)->SetGeometry (geo);
126+
127+ view = ViewForWindow (*it);
128+ view->SetPrimary (i == primary_monitor);
129+ view->SetMonitor (i);
130+
131+ (*it)->EnableInputWindow (true);
132+ (*it)->InputWindowEnableStruts (true);
133+
134+ i++;
135+ }
136+ }
137+
138+ // Add new ones if needed
139+ if (i < n_monitors)
140+ {
141+ for (i = i; i < n_monitors; i++)
142+ {
143+ nux::BaseWindow *window;
144+ PanelView *view;
145+ nux::HLayout *layout;
146+
147+ layout = new nux::HLayout();
148+
149+ view = new PanelView ();
150+ view->SetMaximumHeight (24);
151+ view->GetHomeButton ()->SetButtonWidth (_bfb_size);
152+ view->SetOpacity (_opacity);
153+ view->SetPrimary (i == primary_monitor);
154+ view->SetMonitor (i);
155+ AddChild (view);
156+
157+ layout->AddView (view, 1);
158+ layout->SetContentDistribution (nux::eStackLeft);
159+ layout->SetVerticalExternalMargin (0);
160+ layout->SetHorizontalExternalMargin (0);
161+
162+ window = new nux::BaseWindow("");
163+ window->SinkReference ();
164+ window->SetConfigureNotifyCallback(&PanelController::WindowConfigureCallback, window);
165+ window->SetLayout(layout);
166+ window->SetBackgroundColor(nux::Color(0x00000000));
167+ window->ShowWindow(true);
168+ window->EnableInputWindow(true, "panel", false, false);
169+ window->InputWindowEnableStruts(true);
170+
171+ nux::Geometry geo = monitors[i];
172+ geo.height = 24;
173+ window->SetGeometry (geo);
174+
175+ /* FIXME: this should not be manual, should be managed with a
176+ show/hide callback like in GAIL*/
177+ if (unity_a11y_initialized () == TRUE)
178+ unity_util_accessible_add_window (window);
179+
180+ _windows.push_back (window);
181+ }
182+ }
183+
184+ if ((int)_windows.size () > n_monitors)
185+ {
186+ std::vector<nux::BaseWindow*>::iterator sit;
187+ for (sit = it; sit != eit; ++sit)
188+ {
189+ (*sit)->UnReference ();
190+ }
191+
192+ _windows.erase (it, _windows.end ());
193+ }
194+}
195+
196+void
197+PanelController::WindowConfigureCallback (int window_width,
198+ int window_height,
199+ nux::Geometry& geo,
200+ void *user_data)
201+{
202+ nux::BaseWindow *window = static_cast<nux::BaseWindow *> (user_data);
203+ geo = window->GetGeometry ();
204+}
205+
206+const gchar *
207+PanelController::GetName ()
208+{
209+ return "PanelController";
210+}
211+
212+void
213+PanelController::AddProperties (GVariantBuilder *builder)
214+{
215+
216+}
217
218=== added file 'src/PanelController.h'
219--- src/PanelController.h 1970-01-01 00:00:00 +0000
220+++ src/PanelController.h 2011-03-23 17:01:13 +0000
221@@ -0,0 +1,58 @@
222+/*
223+ * Copyright (C) 2011 Canonical Ltd
224+ *
225+ * This program is free software: you can redistribute it and/or modify
226+ * it under the terms of the GNU General Public License version 3 as
227+ * published by the Free Software Foundation.
228+ *
229+ * This program is distributed in the hope that it will be useful,
230+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
231+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
232+ * GNU General Public License for more details.
233+ *
234+ * You should have received a copy of the GNU General Public License
235+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
236+ *
237+ * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
238+ */
239+
240+#ifndef _PANEL_CONTROLLER_H_
241+#define _PANEL_CONTROLLER_H_
242+
243+#include <Nux/Nux.h>
244+#include <Nux/BaseWindow.h>
245+#include <vector>
246+
247+#include "Introspectable.h"
248+#include "PanelView.h"
249+
250+class PanelController : public nux::Object, public Introspectable
251+{
252+public:
253+ PanelController ();
254+ ~PanelController ();
255+
256+ void SetBFBSize (int size);
257+ void StartFirstMenuShow ();
258+ void EndFirstMenuShow ();
259+ void SetOpacity (float opacity);
260+
261+protected:
262+ const gchar * GetName ();
263+ void AddProperties (GVariantBuilder *builder);
264+
265+private:
266+ PanelView * ViewForWindow (nux::BaseWindow *window);
267+ void OnScreenChanged (int primary_monitor, std::vector<nux::Geometry>& monitors);
268+
269+ static void WindowConfigureCallback (int window_width,
270+ int window_height,
271+ nux::Geometry& geo,
272+ void *user_data);
273+private:
274+ std::vector<nux::BaseWindow *> _windows;
275+ int _bfb_size;
276+ float _opacity;
277+};
278+
279+#endif // _PANEL_CONTROLLER_H_
280
281=== modified file 'src/PanelIndicatorObjectEntryView.cpp'
282--- src/PanelIndicatorObjectEntryView.cpp 2011-03-17 09:41:28 +0000
283+++ src/PanelIndicatorObjectEntryView.cpp 2011-03-23 17:01:13 +0000
284@@ -73,7 +73,7 @@
285 || (_proxy->icon_visible && _proxy->icon_sensitive))
286 {
287 _proxy->ShowMenu (GetAbsoluteGeometry ().x + 1, //cairo translation
288- PANEL_HEIGHT,
289+ GetAbsoluteGeometry ().y + PANEL_HEIGHT,
290 time (NULL),
291 nux::GetEventButton (button_flags));
292 }
293@@ -89,7 +89,7 @@
294 PanelIndicatorObjectEntryView::Activate ()
295 {
296 _proxy->ShowMenu (GetAbsoluteGeometry().x + 1, //cairo translation FIXME: Make this into one function
297- PANEL_HEIGHT,
298+ GetAbsoluteGeometry ().y + PANEL_HEIGHT,
299 time (NULL),
300 1);
301 }
302
303=== modified file 'src/PanelMenuView.cpp'
304--- src/PanelMenuView.cpp 2011-03-22 13:32:19 +0000
305+++ src/PanelMenuView.cpp 2011-03-23 17:01:13 +0000
306@@ -41,6 +41,8 @@
307 #include "ubus-server.h"
308 #include "UBusMessages.h"
309
310+#include "UScreen.h"
311+
312 #define BUTTONS_WIDTH 72
313
314 static void on_active_window_changed (BamfMatcher *matcher,
315@@ -66,7 +68,11 @@
316 _last_width (0),
317 _last_height (0),
318 _places_showing (false),
319- _show_now_activated (false)
320+ _show_now_activated (false),
321+ _we_control_active (false),
322+ _monitor (0),
323+ _active_xid (0),
324+ _active_moved_id (0)
325 {
326 WindowManager *win_manager;
327
328@@ -108,6 +114,7 @@
329 win_manager->window_maximized.connect (sigc::mem_fun (this, &PanelMenuView::OnWindowMaximized));
330 win_manager->window_restored.connect (sigc::mem_fun (this, &PanelMenuView::OnWindowRestored));
331 win_manager->window_unmapped.connect (sigc::mem_fun (this, &PanelMenuView::OnWindowUnmapped));
332+ win_manager->window_moved.connect (sigc::mem_fun (this, &PanelMenuView::OnWindowMoved));
333
334 PanelStyle::GetDefault ()->changed.connect (sigc::mem_fun (this, &PanelMenuView::Refresh));
335
336@@ -133,6 +140,9 @@
337 _menu_layout->UnReference ();
338 _window_buttons->UnReference ();
339 _panel_titlebar_grab_area->UnReference ();
340+
341+ if (_active_moved_id)
342+ g_source_remove (_active_moved_id);
343 }
344
345 void
346@@ -159,6 +169,9 @@
347 long ret = TraverseInfo;
348 nux::Geometry geo = GetAbsoluteGeometry ();
349
350+ if (!_we_control_active)
351+ return _panel_titlebar_grab_area->OnEvent (ievent, ret, ProcessEventInfo);
352+
353 if (geo.IsPointInside (ievent.e_x, ievent.e_y))
354 {
355 if (_is_inside != true)
356@@ -253,7 +266,7 @@
357 nux::ColorLayer layer (nux::Color (0x00000000), true, rop);
358 gPainter.PushDrawLayer (GfxContext, GetGeometry (), &layer);
359
360- if (_is_own_window || _places_showing)
361+ if (_is_own_window || _places_showing || !_we_control_active)
362 {
363
364 }
365@@ -351,7 +364,7 @@
366
367 GfxContext.PushClippingRectangle (geo);
368
369- if (!_is_own_window && !_places_showing)
370+ if (!_is_own_window && !_places_showing && _we_control_active)
371 {
372 if (_is_inside || _last_active_view || _show_now_activated)
373 {
374@@ -668,13 +681,19 @@
375 BamfView *new_view)
376 {
377 _is_maximized = false;
378-
379+ _active_xid = 0;
380+ if (_active_moved_id)
381+ g_source_remove (_active_moved_id);
382+ _active_moved_id = 0;
383
384 if (BAMF_IS_WINDOW (new_view))
385 {
386 BamfWindow *window = BAMF_WINDOW (new_view);
387- guint32 xid = bamf_window_get_xid (window);
388+ guint32 xid = _active_xid = bamf_window_get_xid (window);
389 _is_maximized = WindowManager::Default ()->IsWindowMaximized (xid);
390+ nux::Geometry geo = WindowManager::Default ()->GetWindowGeometry (xid);
391+
392+ _we_control_active = UScreen::GetDefault ()->GetMonitorGeometry (_monitor).IsPointInside (geo.x + (geo.width/2), geo.y);
393
394 if (_decor_map.find (xid) == _decor_map.end ())
395 {
396@@ -803,6 +822,32 @@
397 FullRedraw ();
398 }
399
400+gboolean
401+PanelMenuView::UpdateActiveWindowPosition (PanelMenuView *self)
402+{
403+ nux::Geometry geo = WindowManager::Default ()->GetWindowGeometry (self->_active_xid);
404+
405+ self->_we_control_active = UScreen::GetDefault ()->GetMonitorGeometry (self->_monitor).IsPointInside (geo.x + (geo.width/2), geo.y);
406+
407+ self->_active_moved_id = 0;
408+
409+ self->QueueDraw ();
410+
411+ return FALSE;
412+}
413+
414+void
415+PanelMenuView::OnWindowMoved (guint xid)
416+{
417+ if (_active_xid == xid)
418+ {
419+ if (_active_moved_id)
420+ g_source_remove (_active_moved_id);
421+
422+ _active_moved_id = g_timeout_add (250, (GSourceFunc)PanelMenuView::UpdateActiveWindowPosition, this);
423+ }
424+}
425+
426 void
427 PanelMenuView::OnCloseClicked ()
428 {
429@@ -843,6 +888,8 @@
430 PanelMenuView::GetMaximizedWindow ()
431 {
432 guint32 window_xid = 0;
433+ nux::Geometry monitor = UScreen::GetDefault ()->GetMonitorGeometry (_monitor);
434+
435 // Find the front-most of the maximized windows we are controlling
436 foreach (guint32 xid, _maximized_set)
437 {
438@@ -850,8 +897,12 @@
439 if (WindowManager::Default ()->IsWindowOnCurrentDesktop (xid)
440 && !WindowManager::Default ()->IsWindowObscured (xid))
441 {
442- window_xid = xid;
443- break;
444+ nux::Geometry geo = WindowManager::Default ()->GetWindowGeometry (xid);
445+ if (monitor.IsPointInside (geo.x + (geo.width/2), geo.y))
446+ {
447+ window_xid = xid;
448+ break;
449+ }
450 }
451 }
452 return window_xid;
453@@ -971,3 +1022,14 @@
454 QueueDraw ();
455 }
456
457+void
458+PanelMenuView::SetMonitor (int monitor)
459+{
460+ _monitor = monitor;
461+}
462+
463+bool
464+PanelMenuView::GetControlsActive ()
465+{
466+ return _we_control_active;
467+}
468
469=== modified file 'src/PanelMenuView.h'
470--- src/PanelMenuView.h 2011-03-22 13:32:19 +0000
471+++ src/PanelMenuView.h 2011-03-23 17:01:13 +0000
472@@ -75,6 +75,7 @@
473 void OnWindowUnmapped (guint32 xid);
474 void OnWindowMaximized (guint32 xid);
475 void OnWindowRestored (guint32 xid);
476+ void OnWindowMoved (guint32 xid);
477
478 guint32 GetMaximizedWindow ();
479
480@@ -89,6 +90,8 @@
481 void OnMinimizeClicked ();
482 void OnRestoreClicked ();
483 void OnWindowButtonsRedraw ();
484+ void SetMonitor (int monitor);
485+ bool GetControlsActive ();
486
487 protected:
488 const gchar * GetName ();
489@@ -100,6 +103,7 @@
490 static void OnPlaceViewShown (GVariant *data, PanelMenuView *self);
491 static void OnPlaceViewHidden (GVariant *data, PanelMenuView *self);
492 void UpdateShowNow (bool ignore);
493+ static gboolean UpdateActiveWindowPosition (PanelMenuView *self);
494
495 private:
496 BamfMatcher* _matcher;
497@@ -130,5 +134,10 @@
498
499 bool _places_showing;
500 bool _show_now_activated;
501+
502+ bool _we_control_active;
503+ int _monitor;
504+ guint32 _active_xid;
505+ guint32 _active_moved_id;
506 };
507 #endif
508
509=== modified file 'src/PanelView.cpp'
510--- src/PanelView.cpp 2011-03-17 09:30:07 +0000
511+++ src/PanelView.cpp 2011-03-23 17:01:13 +0000
512@@ -46,7 +46,9 @@
513 PanelView::PanelView (NUX_FILE_LINE_DECL)
514 : View (NUX_FILE_LINE_PARAM),
515 _is_dirty (true),
516- _opacity (1.0f)
517+ _opacity (1.0f),
518+ _is_primary (false),
519+ _monitor (0)
520 {
521 _needs_geo_sync = false;
522 _style = new PanelStyle ();
523@@ -129,7 +131,7 @@
524
525 GfxContext.PopClippingRectangle ();
526
527- if (_needs_geo_sync)
528+ if (_needs_geo_sync && _menu_view->GetControlsActive ())
529 {
530 SyncGeometries ();
531 _needs_geo_sync = false;
532@@ -313,6 +315,9 @@
533 {
534 std::list<Area *>::iterator it;
535
536+ if (!_menu_view->GetControlsActive ())
537+ return;
538+
539 std::list<Area *> my_children = _layout->GetChildren ();
540 for (it = my_children.begin(); it != my_children.end(); it++)
541 {
542@@ -355,7 +360,7 @@
543 // Useful Public Methods
544 //
545 PanelHomeButton *
546-PanelView::HomeButton ()
547+PanelView::GetHomeButton ()
548 {
549 return _home_button;
550 }
551@@ -371,6 +376,9 @@
552 {
553 std::list<Area *>::iterator it;
554
555+ if (!_menu_view->GetControlsActive ())
556+ return;
557+
558 std::list<Area *> my_children = _layout->GetChildren ();
559 for (it = my_children.begin(); it != my_children.end(); it++)
560 {
561@@ -409,6 +417,12 @@
562 ForceUpdateBackground ();
563 }
564
565+bool
566+PanelView::GetPrimary ()
567+{
568+ return _is_primary;
569+}
570+
571 static void
572 on_sync_geometries_done_cb (GObject *source,
573 GAsyncResult *res,
574@@ -426,6 +440,14 @@
575 }
576
577 void
578+PanelView::SetPrimary (bool primary)
579+{
580+ _is_primary = primary;
581+
582+ _home_button->SetVisible (primary);
583+}
584+
585+void
586 PanelView::SyncGeometries ()
587 {
588 GVariantBuilder b;
589@@ -491,3 +513,11 @@
590
591 g_variant_unref (method_args);
592 }
593+
594+void
595+PanelView::SetMonitor (int monitor)
596+{
597+ _monitor = monitor;
598+ _menu_view->SetMonitor (monitor);
599+}
600+
601
602=== modified file 'src/PanelView.h'
603--- src/PanelView.h 2011-03-17 09:30:07 +0000
604+++ src/PanelView.h 2011-03-23 17:01:13 +0000
605@@ -52,8 +52,12 @@
606 void OnEntryActivateRequest (const char *entry_id);
607 void OnEntryActivated (const char *entry_id);
608 void OnSynced ();
609+
610+ void SetPrimary (bool primary);
611+ bool GetPrimary ();
612+ void SetMonitor (int monitor);
613
614- PanelHomeButton * HomeButton ();
615+ PanelHomeButton * GetHomeButton ();
616
617 void StartFirstMenuShow ();
618 void EndFirstMenuShow ();
619@@ -89,6 +93,8 @@
620 bool _is_dirty;
621 float _opacity;
622 bool _needs_geo_sync;
623+ bool _is_primary;
624+ int _monitor;
625 };
626
627 #endif // PANEL_VIEW_H
628
629=== modified file 'src/PlacesController.h'
630--- src/PlacesController.h 2011-03-10 13:15:55 +0000
631+++ src/PlacesController.h 2011-03-23 17:01:13 +0000
632@@ -14,6 +14,7 @@
633 * along with this program. If not, see <http://www.gnu.org/licenses/>.
634 *
635 * Authored by: Gordon Allott <gord.allott@canonical.com>
636+ * Neil Jagdish Patel <neil.patel@canonical.com>
637 */
638
639 #ifndef PLACES_CONTROLLER_H
640
641=== modified file 'src/PluginAdapter.cpp'
642--- src/PluginAdapter.cpp 2011-03-22 13:32:19 +0000
643+++ src/PluginAdapter.cpp 2011-03-23 17:01:13 +0000
644@@ -448,6 +448,24 @@
645 window->lower ();
646 }
647
648+nux::Geometry
649+PluginAdapter::GetWindowGeometry (guint32 xid)
650+{
651+ Window win = (Window)xid;
652+ CompWindow *window;
653+ nux::Geometry geo (0, 0, 1, 1);
654+
655+ window = m_Screen->findWindow (win);
656+ if (window)
657+ {
658+ geo.x = window->x ();
659+ geo.y = window->y ();
660+ geo.width = window->width ();
661+ geo.height = window->height ();
662+ }
663+ return geo;
664+}
665+
666 void PluginAdapter::MaximizeIfBigEnough (CompWindow *window)
667 {
668 XClassHint classHint;
669
670=== modified file 'src/PluginAdapter.h'
671--- src/PluginAdapter.h 2011-03-22 13:32:19 +0000
672+++ src/PluginAdapter.h 2011-03-23 17:01:13 +0000
673@@ -89,6 +89,8 @@
674 void Lower (guint32 xid);
675
676 void MaximizeIfBigEnough (CompWindow *window);
677+
678+ nux::Geometry GetWindowGeometry (guint32 xid);
679
680 protected:
681 PluginAdapter(CompScreen *screen);
682
683=== added file 'src/UScreen.cpp'
684--- src/UScreen.cpp 1970-01-01 00:00:00 +0000
685+++ src/UScreen.cpp 2011-03-23 17:01:13 +0000
686@@ -0,0 +1,121 @@
687+/*
688+ * Copyright (C) 2011 Canonical Ltd
689+ *
690+ * This program is free software: you can redistribute it and/or modify
691+ * it under the terms of the GNU General Public License version 3 as
692+ * published by the Free Software Foundation.
693+ *
694+ * This program is distributed in the hope that it will be useful,
695+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
696+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
697+ * GNU General Public License for more details.
698+ *
699+ * You should have received a copy of the GNU General Public License
700+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
701+ *
702+ * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
703+ */
704+
705+#include "UScreen.h"
706+
707+static UScreen *_default_screen = NULL;
708+
709+UScreen::UScreen ()
710+: _refresh_id (0)
711+{
712+ GdkScreen *screen;
713+
714+ screen = gdk_screen_get_default ();
715+ g_signal_connect (screen, "size-changed",
716+ (GCallback)UScreen::Changed, this);
717+ g_signal_connect (screen, "monitors-changed",
718+ (GCallback)UScreen::Changed, this);
719+
720+ Refresh ();
721+}
722+
723+UScreen::~UScreen ()
724+{
725+ if (_default_screen == this)
726+ _default_screen = NULL;
727+
728+ g_signal_handlers_disconnect_by_func ((gpointer)gdk_screen_get_default (),
729+ (gpointer)UScreen::Changed,
730+ (gpointer)this);
731+}
732+
733+UScreen *
734+UScreen::GetDefault ()
735+{
736+ if (G_UNLIKELY (!_default_screen))
737+ _default_screen = new UScreen ();
738+
739+ return _default_screen;
740+}
741+
742+int
743+UScreen::GetPrimaryMonitor ()
744+{
745+ return gdk_screen_get_primary_monitor (gdk_screen_get_default ());
746+}
747+
748+nux::Geometry&
749+UScreen::GetMonitorGeometry (int monitor)
750+{
751+ return _monitors[monitor];
752+}
753+
754+std::vector<nux::Geometry>&
755+UScreen::GetMonitors ()
756+{
757+ return _monitors;
758+}
759+
760+void
761+UScreen::Changed (GdkScreen *screen, UScreen *self)
762+{
763+ if (self->_refresh_id)
764+ return;
765+
766+ self->_refresh_id = g_idle_add ((GSourceFunc)UScreen::OnIdleChanged, self);
767+}
768+
769+gboolean
770+UScreen::OnIdleChanged (UScreen *self)
771+{
772+ self->_refresh_id = 0;
773+ self->Refresh ();
774+
775+ return FALSE;
776+}
777+
778+void
779+UScreen::Refresh ()
780+{
781+ GdkScreen *screen;
782+ int primary;
783+
784+ screen = gdk_screen_get_default ();
785+ primary = GetPrimaryMonitor ();
786+
787+ _monitors.erase (_monitors.begin (), _monitors.end ());
788+
789+ g_print ("\nScreen geometry changed:\n");
790+
791+ for (int i = 0; i < gdk_screen_get_n_monitors (screen); i++)
792+ {
793+ GdkRectangle rect = { 0 };
794+
795+ gdk_screen_get_monitor_geometry (screen, i, &rect);
796+
797+ nux::Geometry geo (rect.x, rect.y, rect.width, rect.height);
798+ _monitors.push_back (geo);
799+
800+ g_print (" Monitor %d%s\n", i, i == primary ? "(primary)" : "");
801+ g_print (" %dx%dx%dx%d\n", geo.x, geo.y, geo.width, geo.height);
802+ }
803+
804+ g_print ("\n");
805+
806+ changed.emit (primary, _monitors);
807+}
808
809=== added file 'src/UScreen.h'
810--- src/UScreen.h 1970-01-01 00:00:00 +0000
811+++ src/UScreen.h 2011-03-23 17:01:13 +0000
812@@ -0,0 +1,53 @@
813+/*
814+ * Copyright (C) 2011 Canonical Ltd
815+ *
816+ * This program is free software: you can redistribute it and/or modify
817+ * it under the terms of the GNU General Public License version 3 as
818+ * published by the Free Software Foundation.
819+ *
820+ * This program is distributed in the hope that it will be useful,
821+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
822+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
823+ * GNU General Public License for more details.
824+ *
825+ * You should have received a copy of the GNU General Public License
826+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
827+ *
828+ * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
829+ */
830+
831+#ifndef _UNITY_SCREEN_H_
832+#define _UNITY_SCREEN_H_
833+
834+#include <gdk/gdk.h>
835+#include <Nux/Nux.h>
836+#include <sigc++/sigc++.h>
837+#include <vector>
838+
839+class UScreen : public sigc::trackable
840+{
841+public:
842+ UScreen ();
843+ ~UScreen ();
844+
845+ static UScreen * GetDefault ();
846+
847+ int GetPrimaryMonitor ();
848+ nux::Geometry& GetMonitorGeometry (int monitor);
849+
850+ std::vector<nux::Geometry>& GetMonitors ();
851+
852+ // <void, primary_monitor, monitors>
853+ sigc::signal<void, int, std::vector<nux::Geometry>&> changed;
854+
855+private:
856+ static void Changed (GdkScreen *screen, UScreen *self);
857+ static gboolean OnIdleChanged (UScreen *self);
858+ void Refresh ();
859+
860+private:
861+ std::vector<nux::Geometry> _monitors;
862+ guint32 _refresh_id;
863+};
864+
865+#endif // _UNITY_SCREEN_H_
866
867=== modified file 'src/WindowManager.cpp'
868--- src/WindowManager.cpp 2011-03-15 23:36:05 +0000
869+++ src/WindowManager.cpp 2011-03-23 17:01:13 +0000
870@@ -68,11 +68,11 @@
871 g_debug ("%s", G_STRFUNC);
872 }
873
874- void Close (guint32 xid)
875+ void Close (guint32 xid)
876 {
877 g_debug ("%s", G_STRFUNC);
878 }
879-
880+
881 void Activate (guint32 xid)
882 {
883 g_debug ("%s", G_STRFUNC);
884@@ -87,6 +87,11 @@
885 {
886 g_debug ("%s", G_STRFUNC);
887 }
888+
889+ nux::Geometry GetWindowGeometry (guint xid)
890+ {
891+ return nux::Geometry (0, 0, 1, 1);
892+ }
893 };
894
895 WindowManager *
896
897=== modified file 'src/WindowManager.h'
898--- src/WindowManager.h 2011-03-22 13:32:19 +0000
899+++ src/WindowManager.h 2011-03-23 17:01:13 +0000
900@@ -65,6 +65,8 @@
901
902 void StartMove (guint32 id, int, int);
903
904+ virtual nux::Geometry GetWindowGeometry (guint32 xid) = 0;
905+
906 // Signals
907 sigc::signal<void, guint32> window_mapped;
908 sigc::signal<void, guint32> window_unmapped;
909
910=== modified file 'src/unity-panel-view-accessible.cpp'
911--- src/unity-panel-view-accessible.cpp 2011-02-17 12:57:17 +0000
912+++ src/unity-panel-view-accessible.cpp 2011-03-23 17:01:13 +0000
913@@ -99,7 +99,7 @@
914 return 0;
915
916 panel = dynamic_cast<PanelView *>(nux_object);
917- if ((home_button = panel->HomeButton ()) != NULL)
918+ if ((home_button = panel->GetHomeButton ()) != NULL)
919 rc = 1;
920
921 return rc;
922@@ -120,7 +120,7 @@
923 return NULL;
924
925 panel = dynamic_cast<PanelView *>(nux_object);
926- if ((home_button = panel->HomeButton ()) != NULL)
927+ if ((home_button = panel->GetHomeButton ()) != NULL)
928 {
929 nux::Object *child = NULL;
930
931
932=== modified file 'src/unityshell.cpp'
933--- src/unityshell.cpp 2011-03-23 10:59:57 +0000
934+++ src/unityshell.cpp 2011-03-23 17:01:13 +0000
935@@ -277,7 +277,7 @@
936 if (state & CompAction::StateInitKey)
937 action->setState (action->state () | CompAction::StateTermKey);
938
939- panelView->StartFirstMenuShow ();
940+ panelController->StartFirstMenuShow ();
941 return false;
942 }
943
944@@ -286,7 +286,7 @@
945 CompAction::State state,
946 CompOption::Vector &options)
947 {
948- panelView->EndFirstMenuShow ();
949+ panelController->EndFirstMenuShow ();
950 return false;
951 }
952
953@@ -568,15 +568,6 @@
954 geo.width, self->_primary_monitor.height - 24);
955 }
956
957-/* Configure callback for the panel window */
958-void
959-UnityScreen::panelWindowConfigureCallback(int WindowWidth, int WindowHeight, nux::Geometry& geo, void *user_data)
960-{
961- UnityScreen *self = static_cast<UnityScreen *> (user_data);
962- geo = nux::Geometry(self->_primary_monitor.x, self->_primary_monitor.y,
963- self->_primary_monitor.width, 24);
964-}
965-
966 /* Start up nux after OpenGL is initialized */
967 void
968 UnityScreen::initUnity(nux::NThread* thread, void* InitData)
969@@ -615,10 +606,10 @@
970 launcher->SetUrgentAnimation ((Launcher::UrgentAnimation) optionGetUrgentAnimation ());
971 break;
972 case UnityshellOptions::PanelOpacity:
973- panelView->SetOpacity (optionGetPanelOpacity ());
974+ panelController->SetOpacity (optionGetPanelOpacity ());
975 break;
976 case UnityshellOptions::IconSize:
977- panelHomeButton->SetButtonWidth (optionGetIconSize()+18);
978+ panelController->SetBFBSize (optionGetIconSize()+18);
979 launcher->SetIconSize (optionGetIconSize()+6, optionGetIconSize());
980 PlacesController::SetLauncherSize (optionGetIconSize()+18);
981
982@@ -652,8 +643,9 @@
983 {
984 GdkScreen *scr;
985 GdkRectangle rect;
986- nux::Geometry lCurGeom, pCurGeom;
987+ nux::Geometry lCurGeom;
988 gint primary_monitor;
989+ int panel_height = 24;
990
991 if (!needsRelayout)
992 return;
993@@ -665,42 +657,23 @@
994
995 wt->SetWindowSize (rect.width, rect.height);
996
997- pCurGeom = panelWindow->GetGeometry();
998 lCurGeom = launcherWindow->GetGeometry();
999-
1000- panelWindow->EnableInputWindow(false);
1001- panelWindow->InputWindowEnableStruts(false);
1002-
1003- panelView->SetMaximumWidth(rect.width);
1004- launcher->SetMaximumHeight(rect.height - pCurGeom.height);
1005-
1006- g_debug ("setting to primary screen rect: x=%d y=%d w=%d h=%d",
1007+ launcher->SetMaximumHeight(rect.height - panel_height);
1008+
1009+ g_debug ("Setting to primary screen rect: x=%d y=%d w=%d h=%d",
1010 rect.x,
1011 rect.y,
1012 rect.width,
1013 rect.height);
1014
1015- panelWindow->SetGeometry(nux::Geometry(rect.x,
1016- rect.y,
1017- rect.width,
1018- pCurGeom.height));
1019- panelView->SetGeometry(nux::Geometry(rect.x,
1020- rect.y,
1021- rect.width,
1022- pCurGeom.height));
1023-
1024 launcherWindow->SetGeometry(nux::Geometry(rect.x,
1025- rect.y + pCurGeom.height,
1026+ rect.y + panel_height,
1027 lCurGeom.width,
1028- rect.height - pCurGeom.height));
1029+ rect.height - panel_height));
1030 launcher->SetGeometry(nux::Geometry(rect.x,
1031- rect.y + pCurGeom.height,
1032+ rect.y + panel_height,
1033 lCurGeom.width,
1034- rect.height - pCurGeom.height));
1035-
1036- panelWindow->EnableInputWindow(true);
1037- panelWindow->InputWindowEnableStruts(true);
1038-
1039+ rect.height - panel_height));
1040 needsRelayout = false;
1041 }
1042
1043@@ -863,21 +836,10 @@
1044 UnityScreen::~UnityScreen ()
1045 {
1046 launcherWindow->UnReference ();
1047- panelWindow->UnReference ();
1048+ panelController->UnReference ();
1049 unity_a11y_finalize ();
1050 }
1051
1052-/* Can't create windows until after we have initialized everything */
1053-gboolean UnityScreen::strutHackTimeout (gpointer data)
1054-{
1055- UnityScreen *self = (UnityScreen*) data;
1056-
1057- self->panelWindow->InputWindowEnableStruts(false);
1058- self->panelWindow->InputWindowEnableStruts(true);
1059-
1060- return FALSE;
1061-}
1062-
1063 /* Start up the launcher */
1064 void UnityScreen::initLauncher (nux::NThread* thread, void* InitData)
1065 {
1066@@ -919,34 +881,8 @@
1067
1068 /* Setup panel */
1069 LOGGER_START_PROCESS ("initLauncher-Panel");
1070- self->panelView = new PanelView ();
1071- self->AddChild (self->panelView);
1072-
1073- self->panelHomeButton = self->panelView->HomeButton ();
1074-
1075- layout = new nux::HLayout();
1076-
1077- self->panelView->SetMaximumHeight(24);
1078- layout->AddView(self->panelView, 1);
1079- layout->SetContentDistribution(nux::eStackLeft);
1080- layout->SetVerticalExternalMargin(0);
1081- layout->SetHorizontalExternalMargin(0);
1082-
1083- self->panelWindow = new nux::BaseWindow("");
1084- self->panelWindow->SinkReference ();
1085-
1086- self->panelWindow->SetConfigureNotifyCallback(&UnityScreen::panelWindowConfigureCallback, self);
1087- self->panelWindow->SetLayout(layout);
1088- self->panelWindow->SetBackgroundColor(nux::Color(0x00000000));
1089- self->panelWindow->ShowWindow(true);
1090- self->panelWindow->EnableInputWindow(true, "panel", false, false);
1091- self->panelWindow->InputWindowEnableStruts(true);
1092-
1093- /* FIXME: this should not be manual, should be managed with a
1094- show/hide callback like in GAIL*/
1095- if (unity_a11y_initialized () == TRUE)
1096- unity_util_accessible_add_window (self->panelWindow);
1097-
1098+ self->panelController = new PanelController ();
1099+ self->AddChild (self->panelController);
1100 LOGGER_END_PROCESS ("initLauncher-Panel");
1101
1102 /* Setup Places */
1103@@ -961,7 +897,6 @@
1104 self->launcher->SetLaunchAnimation (Launcher::LAUNCH_ANIMATION_PULSE);
1105 self->launcher->SetUrgentAnimation (Launcher::URGENT_ANIMATION_WIGGLE);
1106 self->ScheduleRelayout (2000);
1107- g_timeout_add (2000, &UnityScreen::strutHackTimeout, self);
1108
1109 END_FUNCTION ();
1110 }
1111
1112=== modified file 'src/unityshell.h'
1113--- src/unityshell.h 2011-03-21 08:57:21 +0000
1114+++ src/unityshell.h 2011-03-23 17:01:13 +0000
1115@@ -33,8 +33,8 @@
1116 #include "Introspectable.h"
1117 #include "Launcher.h"
1118 #include "LauncherController.h"
1119-#include "PanelView.h"
1120-#include "PanelHomeButton.h"
1121+#include "PanelController.h"
1122+#include "UScreen.h"
1123 #include "PlacesController.h"
1124 #include "GestureEngine.h"
1125 #include "DebugDBusInterface.h"
1126@@ -173,14 +173,8 @@
1127 launcherWindowConfigureCallback(int WindowWidth, int WindowHeight, nux::Geometry& geo, void* user_data);
1128
1129 static void
1130- panelWindowConfigureCallback(int WindowWidth, int WindowHeight, nux::Geometry& geo, void* user_data);
1131-
1132- static void
1133 initUnity(nux::NThread* thread, void* InitData);
1134
1135- static gboolean
1136- strutHackTimeout (gpointer data);
1137-
1138 static void
1139 OnStartKeyNav (GVariant* data, void* value);
1140
1141@@ -204,8 +198,7 @@
1142
1143 Launcher *launcher;
1144 LauncherController *controller;
1145- PanelView *panelView;
1146- PanelHomeButton *panelHomeButton;
1147+ PanelController *panelController;
1148 PlacesController *placesController;
1149 GestureEngine *gestureEngine;
1150 nux::WindowThread *wt;
1151
1152=== modified file 'tests/CMakeLists.txt'
1153--- tests/CMakeLists.txt 2011-03-22 16:04:22 +0000
1154+++ tests/CMakeLists.txt 2011-03-23 17:01:13 +0000
1155@@ -120,6 +120,8 @@
1156 ../src/WindowButtons.h
1157 ../src/WindowManager.cpp
1158 ../src/WindowManager.h
1159+ ../src/UScreen.cpp
1160+ ../src/UScreen.h
1161 ../src/ubus-server.cpp
1162 ../src/ubus-server.h
1163 )