Merge lp:~unity-2d-team/unity-2d/Shell-MultiMonitor into lp:unity-2d

Proposed by Albert Astals Cid
Status: Superseded
Proposed branch: lp:~unity-2d-team/unity-2d/Shell-MultiMonitor
Merge into: lp:unity-2d
Diff against target: 5104 lines (+2027/-885)
74 files modified
libunity-2d-private/src/CMakeLists.txt (+1/-0)
libunity-2d-private/src/application.cpp (+68/-36)
libunity-2d-private/src/application.h (+5/-3)
libunity-2d-private/src/applicationslist.cpp (+23/-50)
libunity-2d-private/src/applicationslist.h (+8/-3)
libunity-2d-private/src/applicationslistdbus.cpp (+9/-6)
libunity-2d-private/src/applicationslistmanager.cpp (+98/-0)
libunity-2d-private/src/applicationslistmanager.h (+49/-0)
libunity-2d-private/src/bfb.cpp (+39/-16)
libunity-2d-private/src/bfb.h (+9/-6)
libunity-2d-private/src/dashclient.cpp (+27/-0)
libunity-2d-private/src/dashclient.h (+8/-0)
libunity-2d-private/src/hudclient.cpp (+28/-0)
libunity-2d-private/src/hudclient.h (+8/-0)
libunity-2d-private/src/indicatorentrywidget.cpp (+13/-3)
libunity-2d-private/src/indicatorentrywidget.h (+2/-0)
libunity-2d-private/src/launcherdevice.cpp (+6/-0)
libunity-2d-private/src/launcherdevice.h (+1/-0)
libunity-2d-private/src/launcheritem.cpp (+4/-10)
libunity-2d-private/src/launcheritem.h (+4/-2)
libunity-2d-private/src/listaggregatormodel.cpp (+21/-0)
libunity-2d-private/src/listaggregatormodel.h (+2/-0)
libunity-2d-private/src/panelpalettemanager.cpp (+4/-2)
libunity-2d-private/src/screeninfo.cpp (+11/-0)
libunity-2d-private/src/screeninfo.h (+1/-0)
libunity-2d-private/src/strutmanager.cpp (+8/-3)
libunity-2d-private/src/trash.cpp (+6/-0)
libunity-2d-private/src/trash.h (+1/-0)
libunity-2d-private/src/unity2ddeclarativeview.cpp (+95/-114)
libunity-2d-private/src/unity2ddeclarativeview.h (+29/-15)
libunity-2d-private/src/unity2dpanel.cpp (+0/-35)
libunity-2d-private/src/unity2dpanel.h (+0/-18)
libunity-2d-private/src/workspaces.cpp (+6/-0)
libunity-2d-private/src/workspaces.h (+1/-0)
panel/applets/appname/appnameapplet.cpp (+4/-4)
panel/applets/appname/windowhelper.cpp (+12/-9)
panel/applets/appname/windowhelper.h (+1/-1)
shell/DashLoader.qml (+36/-0)
shell/HudLoader.qml (+35/-0)
shell/Shell.qml (+110/-78)
shell/app/CMakeLists.txt (+6/-0)
shell/app/dash.xml (+9/-0)
shell/app/dashdbus.cpp (+21/-13)
shell/app/dashdbus.h (+6/-3)
shell/app/hud.xml (+9/-0)
shell/app/huddbus.cpp (+13/-7)
shell/app/huddbus.h (+6/-3)
shell/app/shell.cpp (+4/-30)
shell/app/shelldbus.cpp (+4/-4)
shell/app/shelldbus.h (+3/-3)
shell/app/shelldeclarativeview.cpp (+27/-232)
shell/app/shelldeclarativeview.h (+12/-55)
shell/app/shellmanager.cpp (+683/-0)
shell/app/shellmanager.h (+128/-0)
shell/common/Background.qml (+12/-2)
shell/common/VisibilityController.qml (+4/-4)
shell/common/visibilityBehaviors/IntelliHideBehavior.qml (+2/-2)
shell/dash/Dash.qml (+49/-38)
shell/dash/Home.qml (+3/-3)
shell/dash/LensBar.qml (+1/-1)
shell/hud/Hud.qml (+11/-5)
shell/launcher/Launcher.qml (+5/-27)
shell/launcher/LauncherItem.qml (+2/-1)
shell/launcher/LauncherList.qml (+19/-10)
shell/launcher/LauncherLoader.qml (+22/-7)
shell/launcher/ListViewDragAndDrop.qml (+6/-0)
spread/Workspaces.qml (+2/-0)
spread/app/spreadmanager.cpp (+6/-3)
spread/app/spreadview.cpp (+7/-3)
spread/app/spreadview.h (+2/-0)
tests/dash/fullscreen.rb (+17/-14)
tests/multimonitor/dash-moving.rb (+129/-0)
tests/run-tests.rb (+2/-0)
tests/shell/input_shaping_common.rb (+2/-1)
To merge this branch: bzr merge lp:~unity-2d-team/unity-2d/Shell-MultiMonitor
Reviewer Review Type Date Requested Status
MichaƂ Sawicz Pending
Review via email: mp+97208@code.launchpad.net

This proposal supersedes a proposal from 2012-02-23.

This proposal has been superseded by a proposal from 2012-03-15.

Description of the change

Multimonitor support for the shell

To post a comment you must log in.
1013. By Albert Astals Cid

Bad merge

1014. By Albert Astals Cid

declarativeView is not a root context property but a per view one

1015. By Albert Astals Cid

Kill manualSliding

1016. By Albert Astals Cid

Merge Spread-Multimonitor2

1017. By Albert Astals Cid

Merge bzr+ssh://bazaar.launchpad.net/~aacid/unity-2d/Spread-Multimonitor2/

1018. By Albert Astals Cid

onlyOneLauncherChanged changing means panelsFreeGeomtryChanged

1019. By Albert Astals Cid

Merge

1020. By Albert Astals Cid

Merge

1021. By Albert Astals Cid

Remove one space

1022. By Albert Astals Cid

Add braces

1023. By Albert Astals Cid

Use smarter way of reading the arg suggested by Gerry

1024. By Albert Astals Cid

toggleDash -> toggleDashRequested

1025. By Albert Astals Cid

Protect against a shell without hudloader

1026. By Albert Astals Cid

Workaround dbus problems

1027. By Albert Astals Cid

Pass a parent to the PanelPaletteManager QObject so it is properly deleted when the Unity2dPanel goes away

1028. By Albert Astals Cid

Removing means removing, you know?

1029. By Albert Astals Cid

Connect to monitors-changed of gdk screen to see if that help us detecting primary display change

1030. By Albert Astals Cid

Query the geometry when really needed, fixes moving the dash around screens of different sizes

1031. By Albert Astals Cid

Retrigger a capture of the background when moving the hud/dash around

1032. By Albert Astals Cid

Revert r1029, doesn't help with nvidia and is not needed with intel

1033. By Albert Astals Cid

Get the screenshot from the correct position

1034. By Albert Astals Cid

Propagate launcher application moves to other launchers once the drop is finished

1035. By Albert Astals Cid

Minor fix for RTL dash placement in MM with screens of different size

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'libunity-2d-private/src/CMakeLists.txt'
2--- libunity-2d-private/src/CMakeLists.txt 2012-03-13 18:54:14 +0000
3+++ libunity-2d-private/src/CMakeLists.txt 2012-03-14 15:11:22 +0000
4@@ -45,6 +45,7 @@
5 application.cpp
6 applicationslist.cpp
7 applicationslistdbus.cpp
8+ applicationslistmanager.cpp
9 launcherdevice.cpp
10 launcherdeviceslist.cpp
11 launcherutility.cpp
12
13=== modified file 'libunity-2d-private/src/application.cpp'
14--- libunity-2d-private/src/application.cpp 2012-03-13 19:23:49 +0000
15+++ libunity-2d-private/src/application.cpp 2012-03-14 15:11:22 +0000
16@@ -69,6 +69,16 @@
17
18 const char* SHORTCUT_NICK_PROPERTY = "nick";
19
20+static int windowScreen(WnckWindow *window)
21+{
22+ // Check the window screen
23+ int x, y, width, height;
24+ wnck_window_get_geometry(window, &x, &y, &width, &height);
25+ const QRect windowRect(x, y, width, height);
26+ const QPoint pos = windowRect.center();
27+ return QApplication::desktop()->screenNumber(pos);
28+}
29+
30 Application::Application()
31 : m_application(NULL)
32 , m_desktopFileWatcher(NULL)
33@@ -78,6 +88,7 @@
34 , m_counter(0), m_counterVisible(false)
35 , m_emblem(QString()), m_emblemVisible(false)
36 , m_forceUrgent(false)
37+ , m_previousActiveScreen(-1)
38 , m_dynamicQuicklistServiceWatcher(NULL)
39 {
40 m_launching_timer.setSingleShot(true);
41@@ -93,6 +104,7 @@
42 m_geometryChangedTimer.setSingleShot(true);
43 m_geometryChangedTimer.setInterval(50);
44 connect(&m_geometryChangedTimer, SIGNAL(timeout()), this, SIGNAL(windowGeometryChanged()));
45+ connect(&m_geometryChangedTimer, SIGNAL(timeout()), this, SLOT(announceActiveScreenChangedIfNeeded()));
46 }
47
48 Application::Application(const Application& other)
49@@ -460,6 +472,15 @@
50 }
51
52 void
53+Application::announceActiveScreenChangedIfNeeded()
54+{
55+ if (m_previousActiveScreen != activeScreen()) {
56+ m_previousActiveScreen = activeScreen();
57+ Q_EMIT activeScreenChanged(m_previousActiveScreen);
58+ }
59+}
60+
61+void
62 Application::onBamfApplicationClosed(bool running)
63 {
64 if(running)
65@@ -493,7 +514,7 @@
66 }
67
68 void
69-Application::setIconGeometry(int x, int y, int width, int height, uint xid)
70+Application::setIconGeometry(int x, int y, int width, int height, int screen, uint xid)
71 {
72 if (m_application == NULL) {
73 return;
74@@ -512,12 +533,13 @@
75 return;
76 }
77
78- WnckScreen* screen = wnck_screen_get_default();
79- wnck_screen_force_update(screen);
80+ wnck_screen_force_update(wnck_screen_get_default());
81
82 for (int i = 0; i < size; ++i) {
83 WnckWindow* window = wnck_window_get(xids->at(i));
84- wnck_window_set_icon_geometry(window, x, y, width, height);
85+ if (screen == -1 || windowScreen(window) == screen) {
86+ wnck_window_set_icon_geometry(window, x, y, width, height);
87+ }
88 }
89 }
90
91@@ -528,8 +550,8 @@
92 return;
93 }
94
95- QScopedPointer<BamfUintList> xids(m_application->xids());
96- int size = xids->size();
97+ QScopedPointer<BamfWindowList> windows(m_application->windows());
98+ const int size = windows->size();
99 if (size < 1) {
100 return;
101 }
102@@ -538,10 +560,8 @@
103 wnck_screen_force_update(screen);
104
105 for (int i = 0; i < size; ++i) {
106- WnckWindow* window = wnck_window_get(xids->at(i));
107- m_gConnector.connect(G_OBJECT(window), "workspace-changed",
108- G_CALLBACK(Application::onWindowWorkspaceChanged), this);
109- m_gConnector.connect(G_OBJECT(window), "geometry-changed", G_CALLBACK(geometryChangedCB), this);
110+ BamfWindow *window = windows->at(i);
111+ onWindowAdded(window);
112 }
113 }
114
115@@ -554,6 +574,7 @@
116 m_gConnector.connect(G_OBJECT(wnck_window), "workspace-changed",
117 G_CALLBACK(Application::onWindowWorkspaceChanged), this);
118 m_gConnector.connect(G_OBJECT(wnck_window), "geometry-changed", G_CALLBACK(geometryChangedCB), this);
119+ connect(window, SIGNAL(ActiveChanged(bool)), this, SLOT(announceActiveScreenChangedIfNeeded()));
120 }
121 }
122
123@@ -682,6 +703,26 @@
124 return windowCount;
125 }
126
127+int
128+Application::activeScreen() const
129+{
130+ if (!active()) {
131+ return -1;
132+ }
133+
134+ BamfWindow *bamfWindow = BamfMatcher::get_default().active_window();
135+ if (bamfWindow == NULL) {
136+ return -1;
137+ }
138+
139+ WnckWindow *wnckWindow = wnck_window_get(bamfWindow->xid());
140+ if (wnckWindow == NULL) {
141+ return -1;
142+ }
143+
144+ return windowScreen(wnckWindow);
145+}
146+
147 void
148 Application::activate()
149 {
150@@ -991,28 +1032,15 @@
151 }
152 }
153
154-bool
155-Application::belongsToDifferentWorkspace()
156-{
157- int totalWindows = windowCount();
158- int windowsInCurrentWorkspace = windowCountOnCurrentWorkspace();
159- if (totalWindows > 0 && windowsInCurrentWorkspace == 0) {
160- return true;
161- }
162-
163- return false;
164-}
165-
166-bool
167-Application::belongsToDifferentScreen(int screen)
168+int
169+Application::windowsOnCurrentWorkspaceScreen(int screen)
170 {
171 if (!m_application) {
172- return false;
173+ return 0;
174 }
175
176- if (QApplication::desktop()->screenCount() == 1) {
177- return false;
178- }
179+ int windowCount = 0;
180+ WnckWorkspace *current = wnck_screen_get_active_workspace(wnck_screen_get_default());
181
182 QScopedPointer<BamfUintList> xids(m_application->xids());
183 for (int i = 0; i < xids->size(); i++) {
184@@ -1028,17 +1056,21 @@
185 }
186 }
187
188- // Check the window screen
189- int x, y, width, height;
190- wnck_window_get_geometry(window, &x, &y, &width, &height);
191- const QRect windowRect(x, y, width, height);
192- const QPoint pos = windowRect.center();
193- if (QApplication::desktop()->screenNumber(pos) == screen) {
194- return false;
195+ if (wnck_window_is_pinned(window)) {
196+ windowCount++;
197+ } else {
198+ WnckWorkspace *workspace = wnck_window_get_workspace(window);
199+ if (workspace == current) {
200+ if (screen == -1) {
201+ windowCount++;
202+ } else if (windowScreen(window) == screen) {
203+ windowCount++;
204+ }
205+ }
206 }
207 }
208
209- return true;
210+ return windowCount;
211 }
212
213 void
214
215=== modified file 'libunity-2d-private/src/application.h'
216--- libunity-2d-private/src/application.h 2012-03-12 12:46:39 +0000
217+++ libunity-2d-private/src/application.h 2012-03-14 15:11:22 +0000
218@@ -72,6 +72,7 @@
219
220 /* getters */
221 virtual bool active() const;
222+ virtual int activeScreen() const;
223 virtual bool running() const;
224 virtual int windowCount() const;
225 virtual bool urgent() const;
226@@ -101,12 +102,11 @@
227 Q_INVOKABLE virtual void activate();
228 Q_INVOKABLE void close();
229 Q_INVOKABLE void spread(bool showAllWorkspaces = false);
230- Q_INVOKABLE void setIconGeometry(int x, int y, int width, int height, uint xid=0);
231+ Q_INVOKABLE void setIconGeometry(int x, int y, int width, int height, int screen, uint xid=0);
232 Q_INVOKABLE virtual void launchNewInstance();
233
234 Q_INVOKABLE virtual void createMenuActions();
235- Q_INVOKABLE virtual bool belongsToDifferentWorkspace();
236- Q_INVOKABLE virtual bool belongsToDifferentScreen(int screen);
237+ Q_INVOKABLE virtual int windowsOnCurrentWorkspaceScreen(int screen);
238 Q_INVOKABLE void connectWindowSignals();
239
240 void updateOverlaysState(const QString& sender, const QMap<QString, QVariant>& properties);
241@@ -128,6 +128,7 @@
242 void updateHasVisibleWindow();
243 void updateWindowCount();
244 void updateCounterVisible();
245+ void announceActiveScreenChangedIfNeeded();
246
247 bool launch();
248 void show();
249@@ -172,6 +173,7 @@
250 QString m_emblem;
251 bool m_emblemVisible;
252 bool m_forceUrgent;
253+ int m_previousActiveScreen;
254
255 void updateBamfApplicationDependentProperties();
256 void monitorDesktopFile(const QString&);
257
258=== modified file 'libunity-2d-private/src/applicationslist.cpp'
259--- libunity-2d-private/src/applicationslist.cpp 2012-02-16 11:24:19 +0000
260+++ libunity-2d-private/src/applicationslist.cpp 2012-03-14 15:11:22 +0000
261@@ -16,8 +16,8 @@
262
263 #include "application.h"
264 #include "applicationslist.h"
265+#include "applicationslistmanager.h"
266 #include "webfavorite.h"
267-#include "applicationslistdbus.h"
268
269 #include "bamf-matcher.h"
270 #include "bamf-application.h"
271@@ -29,8 +29,6 @@
272
273 #include <QStringList>
274 #include <QDir>
275-#include <QDBusConnection>
276-#include <QDBusMessage>
277 #include <QFileInfo>
278 #include <QProcess>
279 #include <QX11Info>
280@@ -41,12 +39,6 @@
281 #include <libsn/sn.h>
282 }
283
284-
285-#define DBUS_SERVICE_UNITY "com.canonical.Unity"
286-#define DBUS_SERVICE_LAUNCHER_ENTRY "com.canonical.Unity.LauncherEntry"
287-#define DBUS_SERVICE_LAUNCHER "com.canonical.Unity.Launcher"
288-#define DBUS_OBJECT_LAUNCHER "/com/canonical/Unity/Launcher"
289-
290 /* List of executables that are too generic to be matched against a single application. */
291 static const QStringList EXECUTABLES_BLACKLIST = (QStringList() << "xdg-open");
292 static const QByteArray LATEST_SETTINGS_MIGRATION = "3.2.10";
293@@ -54,34 +46,6 @@
294 ApplicationsList::ApplicationsList(QObject *parent) :
295 QAbstractListModel(parent)
296 {
297- QDBusConnection session = QDBusConnection::sessionBus();
298- /* FIXME: libunity will send out the Update signal for LauncherEntries
299- only if it finds com.canonical.Unity on the bus, so let's just quickly
300- register ourselves as Unity here. Should be moved somewhere else more proper */
301- if (!session.registerService(DBUS_SERVICE_UNITY)) {
302- UQ_WARNING << "The name" << DBUS_SERVICE_UNITY << "is already taken on DBUS";
303- } else {
304- /* Set ourselves up to receive any Update signal coming from any
305- LauncherEntry */
306- session.connect(QString(), QString(),
307- DBUS_SERVICE_LAUNCHER_ENTRY, "Update",
308- this, SLOT(onRemoteEntryUpdated(QString,QMap<QString,QVariant>)));
309- }
310-
311- if (!session.registerService(DBUS_SERVICE_LAUNCHER)) {
312- UQ_WARNING << "The name" << DBUS_SERVICE_LAUNCHER << "is already taken on DBUS";
313- } else {
314- /* Set ourselves up to receive a method call from Software Center asking us to add
315- to favorites an application that is being installed and that the user requested
316- to be added. */
317- ApplicationsListDBUS *dbusAdapter = new ApplicationsListDBUS(this);
318- if (!session.registerObject(DBUS_OBJECT_LAUNCHER, dbusAdapter,
319- QDBusConnection::ExportAllSlots)) {
320- UQ_WARNING << "The object" << DBUS_OBJECT_LAUNCHER << "on" << DBUS_SERVICE_LAUNCHER
321- << "is already present on DBUS.";
322- }
323- }
324-
325 /* Register the display to receive startup notifications */
326 Display *xdisplay = QX11Info::display();
327 m_snDisplay = sn_display_new(xdisplay, NULL, NULL);
328@@ -108,6 +72,8 @@
329 }
330
331 load();
332+
333+ ApplicationsListManager::instance()->addList(this);
334 }
335
336 void
337@@ -151,19 +117,8 @@
338 return false;
339 }
340
341-void
342-ApplicationsList::onRemoteEntryUpdated(QString applicationURI, QMap<QString, QVariant> properties)
343+void ApplicationsList::remoteEntryUpdated(const QString& desktopFile, const QString& sender, const QString& applicationURI, const QMap<QString, QVariant>& properties)
344 {
345- UQ_RETURN_IF_FAIL(calledFromDBus());
346- QString sender = message().service();
347- QString desktopFile;
348- if (applicationURI.indexOf("application://") == 0) {
349- desktopFile = applicationURI.mid(14);
350- } else {
351- UQ_WARNING << "Ignoring update that didn't come from an application:// URI but from:" << applicationURI;
352- return;
353- }
354-
355 Q_FOREACH(Application *application, m_applications) {
356 if (QFileInfo(application->desktop_file()).fileName() == desktopFile) {
357 application->updateOverlaysState(sender, properties);
358@@ -176,6 +131,8 @@
359
360 ApplicationsList::~ApplicationsList()
361 {
362+ ApplicationsListManager::instance()->removeList(this);
363+
364 sn_monitor_context_unref(m_snContext);
365 sn_display_unref(m_snDisplay);
366
367@@ -502,7 +459,17 @@
368 }
369
370 void
371-ApplicationsList::move(int from, int to)
372+ApplicationsList::moveFinished(int from, int to)
373+{
374+ Q_FOREACH(ApplicationsList *other, ApplicationsListManager::instance()->m_lists) {
375+ if (other != this) {
376+ other->doMove(from, to);
377+ }
378+ }
379+}
380+
381+void
382+ApplicationsList::doMove(int from, int to)
383 {
384 QModelIndex parent;
385 /* When moving an item down, the destination index needs to be incremented
386@@ -511,6 +478,12 @@
387 beginMoveRows(parent, from, from, parent, to + (to > from ? 1 : 0));
388 m_applications.move(from, to);
389 endMoveRows();
390+}
391+
392+void
393+ApplicationsList::move(int from, int to)
394+{
395+ doMove(from, to);
396
397 if (m_applications[from]->sticky() || m_applications[to]->sticky()) {
398 /* Update favorites only if at least one of the applications is a favorite */
399
400=== modified file 'libunity-2d-private/src/applicationslist.h'
401--- libunity-2d-private/src/applicationslist.h 2012-02-16 11:24:19 +0000
402+++ libunity-2d-private/src/applicationslist.h 2012-03-14 15:11:22 +0000
403@@ -21,6 +21,7 @@
404 #include <QList>
405 #include <QVariant>
406 #include <QString>
407+#include <QStringList>
408 #include <QUrl>
409 #include <QObject>
410 #include <QtDeclarative/qdeclarative.h>
411@@ -37,10 +38,11 @@
412 class BamfApplication;
413 class BamfView;
414
415-class ApplicationsList : public QAbstractListModel, protected AbstractX11EventFilter, protected QDBusContext
416+class ApplicationsList : public QAbstractListModel, protected AbstractX11EventFilter
417 {
418 Q_OBJECT
419 friend class ApplicationsListDBUS;
420+ friend class ApplicationsListManager;
421
422 public:
423 ApplicationsList(QObject *parent = 0);
424@@ -54,6 +56,7 @@
425
426 public Q_SLOTS:
427 void move(int from, int to);
428+ void moveFinished(int from, int to);
429
430 Q_SIGNALS:
431 void applicationBecameUrgent(int index);
432@@ -73,6 +76,10 @@
433
434 void writeFavoritesToGConf();
435
436+ void remoteEntryUpdated(const QString& desktopFile, const QString& sender, const QString& applicationURI, const QMap<QString, QVariant>& properties);
437+
438+ void doMove(int from, int to);
439+
440 /* List of Application displayed in the launcher. */
441 QList<Application*> m_applications;
442 /* Hash of desktop file names to Application used to reduce
443@@ -102,8 +109,6 @@
444 void onApplicationLaunchingChanged(bool launching);
445 void onApplicationUrgentChanged(bool urgent);
446 void onApplicationUserVisibleChanged(bool user_visible);
447- void onRemoteEntryUpdated(QString applicationURI,
448- QMap<QString, QVariant> properties);
449 };
450
451 QML_DECLARE_TYPE(ApplicationsList)
452
453=== modified file 'libunity-2d-private/src/applicationslistdbus.cpp'
454--- libunity-2d-private/src/applicationslistdbus.cpp 2012-02-16 11:24:19 +0000
455+++ libunity-2d-private/src/applicationslistdbus.cpp 2012-03-14 15:11:22 +0000
456@@ -1,6 +1,7 @@
457 #include "application.h"
458 #include "applicationslistdbus.h"
459 #include "applicationslist.h"
460+#include "applicationslistmanager.h"
461
462 ApplicationsListDBUS::ApplicationsListDBUS(QObject *parent) :
463 QDBusAbstractAdaptor(parent)
464@@ -19,12 +20,14 @@
465 Q_UNUSED(icon_size)
466 Q_UNUSED(aptdaemon_task)
467
468- ApplicationsList* applicationsList = qobject_cast<ApplicationsList*>(parent());
469- if (applicationsList != NULL && !desktop_file.isEmpty()) {
470- applicationsList->insertFavoriteApplication(desktop_file);
471- Application *application = applicationsList->m_applicationForDesktopFile.value(desktop_file, NULL);
472- if (application != NULL) {
473- application->beginForceUrgent(1500);
474+ ApplicationsListManager* applicationsListManager = qobject_cast<ApplicationsListManager*>(parent());
475+ if (applicationsListManager != NULL && !desktop_file.isEmpty()) {
476+ Q_FOREACH(ApplicationsList *applicationsList, applicationsListManager->m_lists) {
477+ applicationsList->insertFavoriteApplication(desktop_file);
478+ Application *application = applicationsList->m_applicationForDesktopFile.value(desktop_file, NULL);
479+ if (application != NULL) {
480+ application->beginForceUrgent(1500);
481+ }
482 }
483 }
484 }
485
486=== added file 'libunity-2d-private/src/applicationslistmanager.cpp'
487--- libunity-2d-private/src/applicationslistmanager.cpp 1970-01-01 00:00:00 +0000
488+++ libunity-2d-private/src/applicationslistmanager.cpp 2012-03-14 15:11:22 +0000
489@@ -0,0 +1,98 @@
490+/*
491+ * Copyright (C) 2012 Canonical, Ltd.
492+ *
493+ * This program is free software; you can redistribute it and/or modify
494+ * it under the terms of the GNU General Public License as published by
495+ * the Free Software Foundation; version 3.
496+ *
497+ * This program is distributed in the hope that it will be useful,
498+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
499+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
500+ * GNU General Public License for more details.
501+ *
502+ * You should have received a copy of the GNU General Public License
503+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
504+ */
505+
506+#include "applicationslistmanager.h"
507+
508+// unity-2d
509+#include "applicationslist.h"
510+#include "applicationslistdbus.h"
511+#include "debug_p.h"
512+
513+// Qt
514+#include <QDBusConnection>
515+#include <QDBusMessage>
516+
517+#define DBUS_SERVICE_UNITY "com.canonical.Unity"
518+#define DBUS_SERVICE_LAUNCHER_ENTRY "com.canonical.Unity.LauncherEntry"
519+#define DBUS_SERVICE_LAUNCHER "com.canonical.Unity.Launcher"
520+#define DBUS_OBJECT_LAUNCHER "/com/canonical/Unity/Launcher"
521+
522+ApplicationsListManager::ApplicationsListManager()
523+{
524+ QDBusConnection session = QDBusConnection::sessionBus();
525+ /* FIXME: libunity will send out the Update signal for LauncherEntries
526+ only if it finds com.canonical.Unity on the bus, so let's just quickly
527+ register ourselves as Unity here. Should be moved somewhere else more proper */
528+ if (!session.registerService(DBUS_SERVICE_UNITY)) {
529+ UQ_WARNING << "The name" << DBUS_SERVICE_UNITY << "is already taken on DBUS";
530+ } else {
531+ /* Set ourselves up to receive any Update signal coming from any
532+ LauncherEntry */
533+ session.connect(QString(), QString(),
534+ DBUS_SERVICE_LAUNCHER_ENTRY, "Update",
535+ this, SLOT(onRemoteEntryUpdated(QString,QMap<QString,QVariant>)));
536+ }
537+
538+ if (!session.registerService(DBUS_SERVICE_LAUNCHER)) {
539+ UQ_WARNING << "The name" << DBUS_SERVICE_LAUNCHER << "is already taken on DBUS";
540+ } else {
541+ /* Set ourselves up to receive a method call from Software Center asking us to add
542+ to favorites an application that is being installed and that the user requested
543+ to be added. */
544+ ApplicationsListDBUS *dbusAdapter = new ApplicationsListDBUS(this);
545+ if (!session.registerObject(DBUS_OBJECT_LAUNCHER, dbusAdapter,
546+ QDBusConnection::ExportAllSlots)) {
547+ UQ_WARNING << "The object" << DBUS_OBJECT_LAUNCHER << "on" << DBUS_SERVICE_LAUNCHER
548+ << "is already present on DBUS.";
549+ }
550+ }
551+}
552+
553+ApplicationsListManager *ApplicationsListManager::instance()
554+{
555+ static ApplicationsListManager manager;
556+ return &manager;
557+}
558+
559+void ApplicationsListManager::addList(ApplicationsList *list)
560+{
561+ m_lists += list;
562+}
563+
564+void ApplicationsListManager::removeList(ApplicationsList *list)
565+{
566+ m_lists -= list;
567+}
568+
569+void
570+ApplicationsListManager::onRemoteEntryUpdated(QString applicationURI, QMap<QString, QVariant> properties)
571+{
572+ UQ_RETURN_IF_FAIL(calledFromDBus());
573+ QString sender = message().service();
574+ QString desktopFile;
575+ if (applicationURI.indexOf("application://") == 0) {
576+ desktopFile = applicationURI.mid(14);
577+ } else {
578+ UQ_WARNING << "Ignoring update that didn't come from an application:// URI but from:" << applicationURI;
579+ return;
580+ }
581+
582+ Q_FOREACH(ApplicationsList *list, m_lists) {
583+ list->remoteEntryUpdated(desktopFile, sender, applicationURI, properties);
584+ }
585+}
586+
587+#include "applicationslistmanager.moc"
588\ No newline at end of file
589
590=== added file 'libunity-2d-private/src/applicationslistmanager.h'
591--- libunity-2d-private/src/applicationslistmanager.h 1970-01-01 00:00:00 +0000
592+++ libunity-2d-private/src/applicationslistmanager.h 2012-03-14 15:11:22 +0000
593@@ -0,0 +1,49 @@
594+/*
595+ * Copyright (C) 2012 Canonical, Ltd.
596+ *
597+ * This program is free software; you can redistribute it and/or modify
598+ * it under the terms of the GNU General Public License as published by
599+ * the Free Software Foundation; version 3.
600+ *
601+ * This program is distributed in the hope that it will be useful,
602+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
603+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
604+ * GNU General Public License for more details.
605+ *
606+ * You should have received a copy of the GNU General Public License
607+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
608+ */
609+
610+#ifndef APPLICATIONSLISTMODEL_H
611+#define APPLICATIONSLISTMODEL_H
612+
613+#include <QObject>
614+#include <QDBusContext>
615+
616+#include <QSet>
617+
618+class ApplicationsList;
619+
620+class ApplicationsListManager : public QObject, protected QDBusContext
621+{
622+ Q_OBJECT
623+ friend class ApplicationsListDBUS;
624+ friend class ApplicationsList;
625+
626+public:
627+ static ApplicationsListManager *instance();
628+
629+ void addList(ApplicationsList *list);
630+ void removeList(ApplicationsList *list);
631+
632+private Q_SLOTS:
633+ void onRemoteEntryUpdated(QString applicationURI,
634+ QMap<QString, QVariant> properties);
635+
636+private:
637+ ApplicationsListManager();
638+
639+ QSet<ApplicationsList*> m_lists;
640+};
641+
642+#endif // APPLICATIONSLISTMODEL_H
643
644=== modified file 'libunity-2d-private/src/bfb.cpp'
645--- libunity-2d-private/src/bfb.cpp 2012-01-19 14:22:10 +0000
646+++ libunity-2d-private/src/bfb.cpp 2012-03-14 15:11:22 +0000
647@@ -27,7 +27,7 @@
648 // Qt
649
650 BfbItem::BfbItem()
651-: m_active(false), m_view(NULL)
652+: m_active(false), m_activeScreen(-1), m_manager(NULL)
653 {
654 }
655
656@@ -40,6 +40,15 @@
657 return m_active;
658 }
659
660+int BfbItem::activeScreen() const
661+{
662+ if (active()) {
663+ return m_activeScreen;
664+ } else {
665+ return -1;
666+ }
667+}
668+
669 bool BfbItem::running() const
670 {
671 return false;
672@@ -70,27 +79,28 @@
673 return false;
674 }
675
676-QObject* BfbItem::dashView() const
677+QObject* BfbItem::dashManager() const
678 {
679- return m_view;
680+ return m_manager;
681 }
682
683-void BfbItem::setDashView(QObject* view)
684+void BfbItem::setDashManager(QObject* manager)
685 {
686- if (m_view != NULL) {
687- disconnect(view);
688+ if (m_manager != NULL) {
689+ disconnect(m_manager);
690 }
691- m_view = view;
692- if (m_view != NULL) {
693- connect(view, SIGNAL(dashActiveChanged(bool)), this, SLOT(slotDashActiveChanged(bool)));
694+ m_manager = manager;
695+ if (m_manager != NULL) {
696+ connect(manager, SIGNAL(dashActiveChanged(bool)), this, SLOT(slotDashActiveChanged(bool)));
697+ connect(manager, SIGNAL(dashScreenChanged(int)), this, SLOT(slotDashScreenChanged(int)));
698 }
699 }
700
701 void BfbItem::activate()
702 {
703- Q_ASSERT(m_view != NULL);
704- if (m_view != NULL) {
705- QMetaObject::invokeMethod(m_view, "toggleDash");
706+ Q_ASSERT(m_manager != NULL);
707+ if (m_manager != NULL) {
708+ QMetaObject::invokeMethod(m_manager, "toggleDashRequested");
709 }
710 }
711
712@@ -103,6 +113,19 @@
713 if (m_active != active) {
714 m_active = active;
715 Q_EMIT activeChanged(m_active);
716+ if (m_active) {
717+ Q_EMIT activeScreenChanged(m_activeScreen);
718+ }
719+ }
720+}
721+
722+void BfbItem::slotDashScreenChanged(int activeScreen)
723+{
724+ if (m_activeScreen != activeScreen) {
725+ m_activeScreen = activeScreen;
726+ if (m_active) {
727+ Q_EMIT activeScreenChanged(m_activeScreen);
728+ }
729 }
730 }
731
732@@ -132,14 +155,14 @@
733 return QVariant::fromValue(m_bfbItem);
734 }
735
736-QObject* BfbModel::dashView() const
737+QObject* BfbModel::dashManager() const
738 {
739- return m_bfbItem->dashView();
740+ return m_bfbItem->dashManager();
741 }
742
743-void BfbModel::setDashView(QObject* view)
744+void BfbModel::setDashManager(QObject* manager)
745 {
746- m_bfbItem->setDashView(view);
747+ m_bfbItem->setDashManager(manager);
748 }
749
750 #include <bfb.moc>
751
752=== modified file 'libunity-2d-private/src/bfb.h'
753--- libunity-2d-private/src/bfb.h 2012-01-19 14:22:10 +0000
754+++ libunity-2d-private/src/bfb.h 2012-03-14 15:11:22 +0000
755@@ -35,6 +35,7 @@
756
757 /* getters */
758 virtual bool active() const;
759+ virtual int activeScreen() const;
760 virtual bool running() const;
761 virtual int windowCount() const;
762 virtual bool urgent() const;
763@@ -42,8 +43,8 @@
764 virtual QString icon() const;
765 virtual bool launching() const;
766
767- QObject* dashView() const;
768- void setDashView(QObject* view);
769+ QObject* dashManager() const;
770+ void setDashManager(QObject* manager);
771
772 /* methods */
773 Q_INVOKABLE virtual void activate();
774@@ -51,11 +52,13 @@
775
776 private Q_SLOTS:
777 void slotDashActiveChanged(bool active);
778+ void slotDashScreenChanged(int screen);
779
780 private:
781 Q_DISABLE_COPY(BfbItem)
782 bool m_active;
783- QObject* m_view;
784+ int m_activeScreen;
785+ QObject* m_manager;
786 };
787
788 Q_DECLARE_METATYPE(BfbItem*)
789@@ -64,7 +67,7 @@
790 class BfbModel : public QAbstractListModel
791 {
792 Q_OBJECT
793- Q_PROPERTY(QObject* dashView READ dashView WRITE setDashView)
794+ Q_PROPERTY(QObject* dashManager READ dashManager WRITE setDashManager)
795 public:
796 BfbModel(QObject* parent = 0);
797 ~BfbModel();
798@@ -72,8 +75,8 @@
799 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
800 int rowCount(const QModelIndex& parent = QModelIndex()) const;
801
802- QObject* dashView() const;
803- void setDashView(QObject* view);
804+ QObject* dashManager() const;
805+ void setDashManager(QObject* manager);
806
807 private:
808 Q_DISABLE_COPY(BfbModel)
809
810=== modified file 'libunity-2d-private/src/dashclient.cpp'
811--- libunity-2d-private/src/dashclient.cpp 2012-03-06 11:16:00 +0000
812+++ libunity-2d-private/src/dashclient.cpp 2012-03-14 15:11:22 +0000
813@@ -75,6 +75,8 @@
814 SLOT(slotActiveChanged(bool)));
815 connect(m_dashDbusIface, SIGNAL(alwaysFullScreenChanged(bool)),
816 SLOT(slotAlwaysFullScreenChanged(bool)));
817+ connect(m_dashDbusIface, SIGNAL(screenChanged(int)),
818+ SLOT(slotScreenChanged(int)));
819
820 QVariant value = m_dashDbusIface->property("active");
821 if (value.isValid()) {
822@@ -89,6 +91,13 @@
823 } else {
824 UQ_WARNING << "Fetching Dash.alwaysFullScreen property failed";
825 }
826+
827+ value = m_dashDbusIface->property("screen");
828+ if (value.isValid()) {
829+ m_screen = value.toInt();
830+ } else {
831+ UQ_WARNING << "Fetching Dash.screen property failed";
832+ }
833 }
834
835 DashClient* DashClient::instance()
836@@ -136,4 +145,22 @@
837 return m_alwaysFullScreen;
838 }
839
840+void DashClient::slotScreenChanged(int screen)
841+{
842+ if (screen != m_screen) {
843+ m_screen = screen;
844+ Q_EMIT screenChanged(screen);
845+ }
846+}
847+
848+int DashClient::screen() const
849+{
850+ return m_screen;
851+}
852+
853+bool DashClient::activeInScreen(int screen) const
854+{
855+ return active() && m_screen == screen;
856+}
857+
858 #include "dashclient.moc"
859
860=== modified file 'libunity-2d-private/src/dashclient.h'
861--- libunity-2d-private/src/dashclient.h 2012-03-06 10:06:05 +0000
862+++ libunity-2d-private/src/dashclient.h 2012-03-14 15:11:22 +0000
863@@ -37,6 +37,7 @@
864 Q_OBJECT
865 Q_PROPERTY(bool alwaysFullScreen READ alwaysFullScreen NOTIFY alwaysFullScreenChanged)
866 Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged)
867+ Q_PROPERTY(int screen READ screen NOTIFY screenChanged)
868
869 public:
870 static DashClient* instance();
871@@ -46,14 +47,20 @@
872
873 bool alwaysFullScreen() const;
874
875+ int screen() const;
876+
877+ bool activeInScreen(int screen) const;
878+
879 Q_SIGNALS:
880 void activeChanged(bool);
881 void alwaysFullScreenChanged();
882+ void screenChanged(int);
883
884 private Q_SLOTS:
885 void connectToDash();
886 void slotActiveChanged(bool);
887 void slotAlwaysFullScreenChanged(bool);
888+ void slotScreenChanged(int);
889
890 private:
891 DashClient(QObject* parent = 0);
892@@ -61,6 +68,7 @@
893 QDBusInterface* m_dashDbusIface;
894 bool m_active;
895 bool m_alwaysFullScreen;
896+ int m_screen;
897 };
898
899 #endif /* DASHCLIENT_H */
900
901=== modified file 'libunity-2d-private/src/hudclient.cpp'
902--- libunity-2d-private/src/hudclient.cpp 2012-03-06 11:16:00 +0000
903+++ libunity-2d-private/src/hudclient.cpp 2012-03-14 15:11:22 +0000
904@@ -72,6 +72,8 @@
905 QDBusConnection::sessionBus(), this);
906 connect(m_hudDbusIface, SIGNAL(activeChanged(bool)),
907 SLOT(slotActiveChanged(bool)));
908+ connect(m_hudDbusIface, SIGNAL(screenChanged(int)),
909+ SLOT(slotScreenChanged(int)));
910
911 QVariant value = m_hudDbusIface->property("active");
912 if (value.isValid()) {
913@@ -79,6 +81,14 @@
914 } else {
915 UQ_WARNING << "Fetching HUD.active property failed";
916 }
917+
918+ value = m_hudDbusIface->property("screen");
919+ if (value.isValid()) {
920+ m_screen = value.toInt();
921+ } else {
922+ UQ_WARNING << "Fetching Hud.screen property failed";
923+ }
924+
925 }
926
927 HUDClient* HUDClient::instance()
928@@ -113,4 +123,22 @@
929 }
930 }
931
932+void HUDClient::slotScreenChanged(int screen)
933+{
934+ if (screen != m_screen) {
935+ m_screen = screen;
936+ Q_EMIT screenChanged(screen);
937+ }
938+}
939+
940+int HUDClient::screen() const
941+{
942+ return m_screen;
943+}
944+
945+bool HUDClient::activeInScreen(int screen) const
946+{
947+ return active() && m_screen == screen;
948+}
949+
950 #include "hudclient.moc"
951
952=== modified file 'libunity-2d-private/src/hudclient.h'
953--- libunity-2d-private/src/hudclient.h 2012-03-06 10:06:05 +0000
954+++ libunity-2d-private/src/hudclient.h 2012-03-14 15:11:22 +0000
955@@ -36,6 +36,7 @@
956 {
957 Q_OBJECT
958 Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged)
959+ Q_PROPERTY(int screen READ screen NOTIFY screenChanged)
960
961 public:
962 static HUDClient* instance();
963@@ -43,18 +44,25 @@
964 bool active() const;
965 void setActive(bool active);
966
967+ int screen() const;
968+
969+ bool activeInScreen(int screen) const;
970+
971 Q_SIGNALS:
972 void activeChanged(bool);
973+ void screenChanged(int);
974
975 private Q_SLOTS:
976 void connectToHud();
977 void slotActiveChanged(bool);
978+ void slotScreenChanged(int);
979
980 private:
981 HUDClient(QObject* parent = 0);
982
983 QDBusInterface* m_hudDbusIface;
984 bool m_active;
985+ int m_screen;
986 };
987
988 #endif /* HUDCLIENT_H */
989
990=== modified file 'libunity-2d-private/src/indicatorentrywidget.cpp'
991--- libunity-2d-private/src/indicatorentrywidget.cpp 2012-02-12 15:10:03 +0000
992+++ libunity-2d-private/src/indicatorentrywidget.cpp 2012-03-14 15:11:22 +0000
993@@ -50,6 +50,7 @@
994 , m_padding(PADDING)
995 , m_hasIcon(false)
996 , m_hasLabel(false)
997+, m_activatedByThisEntry(false)
998 , m_gtkWidgetPath(gtk_widget_path_new())
999 {
1000 gtk_widget_path_append_type(m_gtkWidgetPath, GTK_TYPE_WINDOW);
1001@@ -59,6 +60,7 @@
1002
1003 setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
1004 m_entry->updated.connect(sigc::mem_fun(this, &IndicatorEntryWidget::updatePix));
1005+ m_entry->active_changed.connect(sigc::mem_fun(this, &IndicatorEntryWidget::onActiveChanged));
1006 }
1007
1008 IndicatorEntryWidget::~IndicatorEntryWidget()
1009@@ -166,7 +168,7 @@
1010 img.fill(Qt::transparent);
1011 QPainter painter(&img);
1012 painter.initFrom(this);
1013- if (m_entry->active()) {
1014+ if (m_activatedByThisEntry) {
1015 paintActiveBackground(&img);
1016 }
1017 if (m_hasIcon) {
1018@@ -200,6 +202,13 @@
1019 }
1020 }
1021
1022+void IndicatorEntryWidget::onActiveChanged(bool active)
1023+{
1024+ if (!active) {
1025+ m_activatedByThisEntry = false;
1026+ }
1027+}
1028+
1029 PangoLayout* IndicatorEntryWidget::createPangoLayout()
1030 {
1031 // Parse
1032@@ -266,7 +275,7 @@
1033 gtk_style_context_add_class(styleContext, GTK_STYLE_CLASS_MENUBAR);
1034 gtk_style_context_add_class(styleContext, GTK_STYLE_CLASS_MENUITEM);
1035
1036- if (m_entry->active()) {
1037+ if (m_activatedByThisEntry) {
1038 gtk_style_context_set_state(styleContext, GTK_STATE_FLAG_PRELIGHT);
1039 }
1040
1041@@ -332,7 +341,7 @@
1042
1043 void IndicatorEntryWidget::showMenu(Qt::MouseButton qtButton)
1044 {
1045- if (m_entry->active()) {
1046+ if (m_activatedByThisEntry) {
1047 return;
1048 }
1049 int nuxButton = qtButton == Qt::NoButton ? 0 : 1;
1050@@ -341,6 +350,7 @@
1051 time(NULL),
1052 nuxButton
1053 );
1054+ m_activatedByThisEntry = true;
1055 }
1056
1057 void IndicatorEntryWidget::setPadding(int padding)
1058
1059=== modified file 'libunity-2d-private/src/indicatorentrywidget.h'
1060--- libunity-2d-private/src/indicatorentrywidget.h 2011-08-22 09:17:03 +0000
1061+++ libunity-2d-private/src/indicatorentrywidget.h 2012-03-14 15:11:22 +0000
1062@@ -78,8 +78,10 @@
1063 int m_padding;
1064 bool m_hasIcon;
1065 bool m_hasLabel;
1066+ bool m_activatedByThisEntry;
1067 struct _GtkWidgetPath* m_gtkWidgetPath;
1068 void updatePix();
1069+ void onActiveChanged(bool active);
1070 QPixmap decodeIcon();
1071 void paintActiveBackground(QImage*);
1072
1073
1074=== modified file 'libunity-2d-private/src/launcherdevice.cpp'
1075--- libunity-2d-private/src/launcherdevice.cpp 2012-01-13 17:29:37 +0000
1076+++ libunity-2d-private/src/launcherdevice.cpp 2012-03-14 15:11:22 +0000
1077@@ -59,6 +59,12 @@
1078 return false;
1079 }
1080
1081+int
1082+LauncherDevice::activeScreen() const
1083+{
1084+ return -1;
1085+}
1086+
1087 bool
1088 LauncherDevice::running() const
1089 {
1090
1091=== modified file 'libunity-2d-private/src/launcherdevice.h'
1092--- libunity-2d-private/src/launcherdevice.h 2011-08-02 19:01:35 +0000
1093+++ libunity-2d-private/src/launcherdevice.h 2012-03-14 15:11:22 +0000
1094@@ -39,6 +39,7 @@
1095
1096 /* getters */
1097 virtual bool active() const;
1098+ virtual int activeScreen() const;
1099 virtual bool running() const;
1100 virtual int windowCount() const;
1101 virtual bool urgent() const;
1102
1103=== modified file 'libunity-2d-private/src/launcheritem.cpp'
1104--- libunity-2d-private/src/launcheritem.cpp 2012-03-01 14:26:38 +0000
1105+++ libunity-2d-private/src/launcheritem.cpp 2012-03-14 15:11:22 +0000
1106@@ -86,16 +86,10 @@
1107 /* Default to doing nothing. */
1108 }
1109
1110-bool
1111-LauncherItem::belongsToDifferentWorkspace()
1112-{
1113- return false;
1114-}
1115-
1116-bool
1117-LauncherItem::belongsToDifferentScreen(int)
1118-{
1119- return false;
1120+int
1121+LauncherItem::windowsOnCurrentWorkspaceScreen(int screen)
1122+{
1123+ return 0;
1124 }
1125
1126 bool
1127
1128=== modified file 'libunity-2d-private/src/launcheritem.h'
1129--- libunity-2d-private/src/launcheritem.h 2012-03-01 14:26:38 +0000
1130+++ libunity-2d-private/src/launcheritem.h 2012-03-14 15:11:22 +0000
1131@@ -33,6 +33,7 @@
1132 Q_OBJECT
1133
1134 Q_PROPERTY(bool active READ active NOTIFY activeChanged)
1135+ Q_PROPERTY(int activeScreen READ activeScreen NOTIFY activeScreenChanged)
1136 Q_PROPERTY(bool running READ running NOTIFY runningChanged)
1137 Q_PROPERTY(int windowCount READ windowCount NOTIFY windowCountChanged)
1138 Q_PROPERTY(bool urgent READ urgent NOTIFY urgentChanged)
1139@@ -56,6 +57,7 @@
1140
1141 /* getters */
1142 virtual bool active() const = 0;
1143+ virtual int activeScreen() const = 0;
1144 virtual bool running() const = 0;
1145 virtual int windowCount() const = 0;
1146 virtual bool urgent() const = 0;
1147@@ -79,14 +81,14 @@
1148 Q_INVOKABLE virtual void activate() = 0;
1149 Q_INVOKABLE virtual void createMenuActions() = 0;
1150 Q_INVOKABLE virtual void launchNewInstance();
1151- Q_INVOKABLE virtual bool belongsToDifferentWorkspace();
1152- Q_INVOKABLE virtual bool belongsToDifferentScreen(int screen);
1153+ Q_INVOKABLE virtual int windowsOnCurrentWorkspaceScreen(int screen);
1154
1155 protected:
1156 LauncherContextualMenu* m_menu;
1157
1158 Q_SIGNALS:
1159 void activeChanged(bool);
1160+ void activeScreenChanged(int);
1161 void runningChanged(bool);
1162 void windowCountChanged(int);
1163 void urgentChanged(bool);
1164
1165=== modified file 'libunity-2d-private/src/listaggregatormodel.cpp'
1166--- libunity-2d-private/src/listaggregatormodel.cpp 2011-07-29 13:49:34 +0000
1167+++ libunity-2d-private/src/listaggregatormodel.cpp 2012-03-14 15:11:22 +0000
1168@@ -130,6 +130,27 @@
1169 Q_ARG(int, to - offset));
1170 }
1171
1172+void
1173+ListAggregatorModel::moveFinished(int from, int to)
1174+{
1175+ QAbstractItemModel* model = modelAtIndex(from);
1176+ if (modelAtIndex(to) != model) {
1177+ UQ_WARNING << "cannot move an item from one model to another";
1178+ return;
1179+ }
1180+
1181+ if (qobject_cast<QSortFilterProxyModel*>(model) != NULL) {
1182+ UQ_WARNING << "cannot move the items of a QSortFilterProxyModel";
1183+ return;
1184+ }
1185+
1186+ int offset = computeOffset(model);
1187+ // "moveFinished" is not a member of QAbstractItemModel, cannot be invoked directly
1188+ QMetaObject::invokeMethod(model, "moveFinished",
1189+ Q_ARG(int, from - offset),
1190+ Q_ARG(int, to - offset));
1191+}
1192+
1193 int
1194 ListAggregatorModel::computeOffset(QAbstractItemModel* model) const
1195 {
1196
1197=== modified file 'libunity-2d-private/src/listaggregatormodel.h'
1198--- libunity-2d-private/src/listaggregatormodel.h 2011-07-29 13:49:34 +0000
1199+++ libunity-2d-private/src/listaggregatormodel.h 2012-03-14 15:11:22 +0000
1200@@ -62,6 +62,8 @@
1201 The item must remain in the same model. */
1202 void move(int from, int to);
1203
1204+ void moveFinished(int from, int to);
1205+
1206 protected:
1207 QList<QAbstractItemModel*> m_models;
1208
1209
1210=== modified file 'libunity-2d-private/src/panelpalettemanager.cpp'
1211--- libunity-2d-private/src/panelpalettemanager.cpp 2012-03-13 18:54:14 +0000
1212+++ libunity-2d-private/src/panelpalettemanager.cpp 2012-03-14 15:11:22 +0000
1213@@ -42,10 +42,12 @@
1214 }
1215
1216 PanelPaletteManager::PanelPaletteManager(Unity2dPanel* panel)
1217- : m_panel(panel)
1218+ : QObject(panel), m_panel(panel)
1219 {
1220 connect(DashClient::instance(), SIGNAL(activeChanged(bool)), this, SLOT(updatePalette()));
1221 connect(HUDClient::instance(), SIGNAL(activeChanged(bool)), this, SLOT(updatePalette()));
1222+ connect(DashClient::instance(), SIGNAL(screenChanged(int)), this, SLOT(updatePalette()));
1223+ connect(HUDClient::instance(), SIGNAL(screenChanged(int)), this, SLOT(updatePalette()));
1224
1225 m_gConnector.connect(gtk_settings_get_default(), "notify::gtk-theme-name", G_CALLBACK(onThemeChanged), this);
1226 updatePalette();
1227@@ -74,7 +76,7 @@
1228 gtk_style_context_get(context, GTK_STATE_FLAG_NORMAL, NULL);
1229
1230 QPalette pal;
1231- if (DashClient::instance()->active() || HUDClient::instance()->active()) {
1232+ if (DashClient::instance()->activeInScreen(m_panel->screen()) || HUDClient::instance()->activeInScreen(m_panel->screen())) {
1233 pal.setBrush(QPalette::Window, QColor(0, 0, 0, 168));
1234 } else {
1235 pal.setBrush(QPalette::Window, generateBackgroundBrush());
1236
1237=== modified file 'libunity-2d-private/src/screeninfo.cpp'
1238--- libunity-2d-private/src/screeninfo.cpp 2012-03-14 15:11:21 +0000
1239+++ libunity-2d-private/src/screeninfo.cpp 2012-03-14 15:11:22 +0000
1240@@ -17,6 +17,7 @@
1241 SLOT(updateGeometry(int)));
1242 connect(QApplication::desktop(), SIGNAL(workAreaResized(int)),
1243 SLOT(updateAvailableGeometry(int)));
1244+ connect(&launcher2dConfiguration(), SIGNAL(onlyOneLauncherChanged(bool)), SLOT(updatePanelsFreeGeometry()));
1245 }
1246
1247 ScreenInfo::ScreenInfo(int screen, QObject *parent) :
1248@@ -29,6 +30,7 @@
1249 SLOT(updateGeometry(int)));
1250 connect(QApplication::desktop(), SIGNAL(workAreaResized(int)),
1251 SLOT(updateAvailableGeometry(int)));
1252+ connect(&launcher2dConfiguration(), SIGNAL(onlyOneLauncherChanged(bool)), SLOT(updatePanelsFreeGeometry()));
1253 }
1254
1255 ScreenInfo::ScreenInfo(QWidget *widget, QObject *parent) :
1256@@ -42,6 +44,7 @@
1257 SLOT(updateGeometry(int)));
1258 connect(QApplication::desktop(), SIGNAL(workAreaResized(int)),
1259 SLOT(updateAvailableGeometry(int)));
1260+ connect(&launcher2dConfiguration(), SIGNAL(onlyOneLauncherChanged(bool)), SLOT(updatePanelsFreeGeometry()));
1261 }
1262
1263 ScreenInfo::ScreenInfo(Corner corner, QObject *parent) :
1264@@ -54,6 +57,7 @@
1265 SLOT(updateGeometry(int)));
1266 connect(QApplication::desktop(), SIGNAL(workAreaResized(int)),
1267 SLOT(updateAvailableGeometry(int)));
1268+ connect(&launcher2dConfiguration(), SIGNAL(onlyOneLauncherChanged(bool)), SLOT(updatePanelsFreeGeometry()));
1269 }
1270
1271 ScreenInfo::~ScreenInfo()
1272@@ -116,6 +120,13 @@
1273 }
1274 }
1275
1276+void ScreenInfo::updatePanelsFreeGeometry()
1277+{
1278+ if (m_screen != 0) {
1279+ Q_EMIT panelsFreeGeometryChanged(panelsFreeGeometry());
1280+ }
1281+}
1282+
1283 void ScreenInfo::updateScreen()
1284 {
1285 int screen;
1286
1287=== modified file 'libunity-2d-private/src/screeninfo.h'
1288--- libunity-2d-private/src/screeninfo.h 2012-03-14 15:11:21 +0000
1289+++ libunity-2d-private/src/screeninfo.h 2012-03-14 15:11:22 +0000
1290@@ -60,6 +60,7 @@
1291 private Q_SLOTS:
1292 void updateGeometry(int screen);
1293 void updateAvailableGeometry(int screen);
1294+ void updatePanelsFreeGeometry();
1295
1296 private:
1297 void updateScreen();
1298
1299=== modified file 'libunity-2d-private/src/strutmanager.cpp'
1300--- libunity-2d-private/src/strutmanager.cpp 2012-02-09 09:27:03 +0000
1301+++ libunity-2d-private/src/strutmanager.cpp 2012-03-14 15:11:22 +0000
1302@@ -181,17 +181,22 @@
1303 switch (m_edge) {
1304 case Unity2dPanel::LeftEdge:
1305 if (QApplication::isLeftToRight()) {
1306- struts[0] = realWidth();
1307+ struts[0] = screen.x() + realWidth();
1308 struts[4] = available.top();
1309 struts[5] = available.y() + available.height();
1310 } else {
1311- struts[1] = realWidth();
1312+ // Find the right-most X
1313+ int rightMostX = 0;
1314+ for (int i = 0; i < desktop->screenCount(); ++i) {
1315+ rightMostX = qMax(rightMostX, desktop->screenGeometry(i).right());
1316+ }
1317+ struts[1] = (rightMostX - screen.right()) + realWidth();
1318 struts[6] = available.top();
1319 struts[7] = available.y() + available.height();
1320 }
1321 break;
1322 case Unity2dPanel::TopEdge:
1323- struts[2] = realHeight();
1324+ struts[2] = screen.y() + realHeight();
1325 struts[8] = screen.left();
1326 struts[9] = screen.x() + screen.width();
1327 break;
1328
1329=== modified file 'libunity-2d-private/src/trash.cpp'
1330--- libunity-2d-private/src/trash.cpp 2011-11-24 08:45:18 +0000
1331+++ libunity-2d-private/src/trash.cpp 2012-03-14 15:11:22 +0000
1332@@ -62,6 +62,12 @@
1333 return false;
1334 }
1335
1336+int
1337+Trash::activeScreen() const
1338+{
1339+ return -1;
1340+}
1341+
1342 bool
1343 Trash::isTrashWindow(WnckWindow* window) const
1344 {
1345
1346=== modified file 'libunity-2d-private/src/trash.h'
1347--- libunity-2d-private/src/trash.h 2011-09-03 20:10:01 +0000
1348+++ libunity-2d-private/src/trash.h 2012-03-14 15:11:22 +0000
1349@@ -45,6 +45,7 @@
1350
1351 /* getters */
1352 virtual bool active() const;
1353+ virtual int activeScreen() const;
1354 virtual bool running() const;
1355 virtual int windowCount() const;
1356 virtual bool urgent() const;
1357
1358=== modified file 'libunity-2d-private/src/unity2ddeclarativeview.cpp'
1359--- libunity-2d-private/src/unity2ddeclarativeview.cpp 2012-03-12 11:56:39 +0000
1360+++ libunity-2d-private/src/unity2ddeclarativeview.cpp 2012-03-14 15:11:22 +0000
1361@@ -20,9 +20,11 @@
1362 #include <config.h>
1363
1364 #include "screeninfo.h"
1365-#include "gobjectcallback.h"
1366
1367+#include <QApplication>
1368 #include <QDebug>
1369+#include <QDeclarativeEngine>
1370+#include <QDeclarativeItem>
1371 #include <QGLWidget>
1372 #include <QVariant>
1373 #include <QX11Info>
1374@@ -32,39 +34,88 @@
1375 #include <X11/Xlib.h>
1376 #include <X11/Xatom.h>
1377
1378-#include "bamf-window.h"
1379-#include "bamf-matcher.h"
1380-
1381-// libwnck
1382-extern "C" {
1383-#include <libwnck/libwnck.h>
1384-}
1385-
1386-GOBJECT_CALLBACK1(activeWorkspaceChangedCB, "onActiveWorkspaceChanged");
1387-
1388 Unity2DDeclarativeView::Unity2DDeclarativeView(QWidget *parent) :
1389- QDeclarativeView(parent),
1390+ QGraphicsView(parent),
1391 m_screenInfo(NULL),
1392 m_useOpenGL(false),
1393 m_transparentBackground(false),
1394- m_last_focused_window(None)
1395+ m_rootItem(NULL)
1396 {
1397+ setScene(&m_scene);
1398+
1399+ setOptimizationFlags(QGraphicsView::DontSavePainterState);
1400+ setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1401+ setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1402+ setFrameStyle(NoFrame);
1403+
1404+ setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
1405+ scene()->setItemIndexMethod(QGraphicsScene::NoIndex);
1406+ viewport()->setFocusPolicy(Qt::NoFocus);
1407+ setFocusPolicy(Qt::StrongFocus);
1408+
1409+ scene()->setStickyFocus(true);
1410+
1411 if (!QFileInfo(UNITY_2D_SCHEMA_FILE).exists()) {
1412 m_useOpenGL = false;
1413 } else {
1414 m_useOpenGL = unity2dConfiguration().property("useOpengl").toBool();
1415 }
1416
1417- WnckScreen* screen = wnck_screen_get_default();
1418- g_signal_connect(G_OBJECT(screen), "active_workspace_changed", G_CALLBACK(activeWorkspaceChangedCB), this);
1419-
1420 setupViewport();
1421 }
1422
1423 Unity2DDeclarativeView::~Unity2DDeclarativeView()
1424 {
1425- WnckScreen* screen = wnck_screen_get_default();
1426- g_signal_handlers_disconnect_by_func(G_OBJECT(screen), gpointer(activeWorkspaceChangedCB), this);
1427+}
1428+
1429+QDeclarativeEngine* Unity2DDeclarativeView::engine()
1430+{
1431+ static QDeclarativeEngine* engine = new QDeclarativeEngine();
1432+ return engine;
1433+}
1434+
1435+QDeclarativeContext* Unity2DDeclarativeView::rootContext() const
1436+{
1437+ return engine()->rootContext();
1438+}
1439+
1440+QDeclarativeItem* Unity2DDeclarativeView::rootObject() const
1441+{
1442+ return m_rootItem;
1443+}
1444+
1445+void Unity2DDeclarativeView::forceActivateWindow()
1446+{
1447+ forceActivateWindow(effectiveWinId(), this);
1448+}
1449+
1450+void Unity2DDeclarativeView::setSource(const QUrl &source, const QMap<const char*, QVariant> &rootObjectProperties)
1451+{
1452+ QDeclarativeComponent* component = new QDeclarativeComponent(engine(), source, this);
1453+ QObject *instance = component->beginCreate(rootContext());
1454+ if (component->isError()) {
1455+ qDebug() << component->errors();
1456+ }
1457+ QMap<const char*, QVariant>::const_iterator it = rootObjectProperties.begin();
1458+ QMap<const char*, QVariant>::const_iterator itEnd = rootObjectProperties.end();
1459+ for ( ; it != itEnd; ++it) {
1460+ instance->setProperty(it.key(), it.value());
1461+ }
1462+ component->completeCreate();
1463+ m_rootItem = qobject_cast<QDeclarativeItem *>(instance);
1464+ connect(m_rootItem, SIGNAL(widthChanged()), SLOT(resizeToRootObject()));
1465+ connect(m_rootItem, SIGNAL(heightChanged()), SLOT(resizeToRootObject()));
1466+ resizeToRootObject();
1467+ m_scene.addItem(m_rootItem);
1468+ m_source = source;
1469+}
1470+
1471+void Unity2DDeclarativeView::resizeToRootObject()
1472+{
1473+ QSize size(m_rootItem->width(), m_rootItem->height());
1474+ resize(size);
1475+ setSceneRect(QRectF(0, 0, size.width(), size.height()));
1476+ Q_EMIT sceneResized(size);
1477 }
1478
1479 bool Unity2DDeclarativeView::useOpenGL() const
1480@@ -89,6 +140,11 @@
1481 return m_transparentBackground;
1482 }
1483
1484+QUrl Unity2DDeclarativeView::source() const
1485+{
1486+ return m_source;
1487+}
1488+
1489 void Unity2DDeclarativeView::setTransparentBackground(bool transparentBackground)
1490 {
1491 if (transparentBackground == m_transparentBackground) {
1492@@ -103,7 +159,12 @@
1493
1494 QPoint Unity2DDeclarativeView::globalPosition() const
1495 {
1496- return mapToGlobal(QPoint(0,0));
1497+ // FIXME This used to be mapToGlobal(QPoint(0,0)) that is the correct
1498+ // thing for all kind of widgets, but seems to fail sometimes if we
1499+ // call it just after a moveEvent, which is bad
1500+ // Since all our Unity2DDeclarativeView are toplevel windows we
1501+ // are workarounding it by just returning pos()
1502+ return pos();
1503 }
1504
1505 void Unity2DDeclarativeView::setupViewport()
1506@@ -163,74 +224,27 @@
1507
1508 void Unity2DDeclarativeView::showEvent(QShowEvent* event)
1509 {
1510- QDeclarativeView::showEvent(event);
1511+ QGraphicsView::showEvent(event);
1512 Q_EMIT visibleChanged(true);
1513 }
1514
1515 void Unity2DDeclarativeView::hideEvent(QHideEvent* event)
1516 {
1517- QDeclarativeView::hideEvent(event);
1518+ QGraphicsView::hideEvent(event);
1519 Q_EMIT visibleChanged(false);
1520 }
1521
1522-/* Obtaining & Discarding Keyboard Focus for Window on Demand
1523- *
1524- * In the X world, activating a window means to give it the input (keyboard)
1525- * focus. When a new window opens, X usually makes it active immediately.
1526- * Clicking on a window makes it active too.
1527- *
1528- * Qt does not have the capability to explicitly ask the window manager to
1529- * make an existing window active - setFocus() only forwards input focus to
1530- * whatever QWidget you specify.
1531- *
1532- * De-Activating a window is not possible with X (and hence with Qt). So
1533- * we work-around this by remembering which application is active prior to
1534- * stealing focus, and then Re-Activating it when we're finished. This is
1535- * not guaranteed to succeed, as previous window may have closed.
1536- *
1537- * The following methods deal with these tasks. Note that when the window
1538- * has been activated (deactivated), Qt will realise it has obtained (lost)
1539- * focus and act appropriately.
1540- */
1541-
1542-/* Ask Window Manager to activate this window and hence get keyboard focus */
1543-void Unity2DDeclarativeView::forceActivateWindow()
1544-{
1545- // Save reference to window with current keyboard focus
1546- if( m_last_focused_window == None ){
1547- saveActiveWindow();
1548- }
1549-
1550- // Show this window by giving it keyboard focus
1551- forceActivateThisWindow(this->effectiveWinId());
1552-}
1553-
1554-/* Ask Window Manager to deactivate this window - not guaranteed to succeed. */
1555-void Unity2DDeclarativeView::forceDeactivateWindow()
1556-{
1557- if( m_last_focused_window == None ){
1558- UQ_WARNING << "No previously focused window found, use mouse to select window.";
1559- return;
1560- }
1561-
1562- // What if previously focused window closed while we we had focus? Check if window
1563- // exists by seeing if it has attributes.
1564- int status;
1565- XWindowAttributes attributes;
1566- status = XGetWindowAttributes(QX11Info::display(), m_last_focused_window, &attributes);
1567- if ( status == BadWindow ){
1568- UQ_WARNING << "Previously focused window has gone, use mouse to select window.";
1569- return;
1570- }
1571-
1572- // Show this window by giving it keyboard focus
1573- forceActivateThisWindow(m_last_focused_window);
1574-
1575- m_last_focused_window = None;
1576- Q_EMIT lastFocusedWindowChanged(m_last_focused_window);
1577-}
1578-
1579-void Unity2DDeclarativeView::forceActivateThisWindow(WId window)
1580+void Unity2DDeclarativeView::keyPressEvent(QKeyEvent* event)
1581+{
1582+ QApplication::sendEvent(scene(), event);
1583+}
1584+
1585+void Unity2DDeclarativeView::keyReleaseEvent(QKeyEvent* event)
1586+{
1587+ QApplication::sendEvent(scene(), event);
1588+}
1589+
1590+void Unity2DDeclarativeView::forceActivateWindow(WId window, QWidget *w)
1591 {
1592 /* Workaround focus stealing prevention implemented by some window
1593 managers such as Compiz. This is the exact same code you will find in
1594@@ -262,35 +276,8 @@
1595 XFlush(display);
1596
1597 /* Use Qt's setFocus mechanism as a safety guard in case the above failed */
1598- setFocus();
1599-}
1600-
1601-/* Save WId of window with keyboard focus to m_last_focused_window */
1602-void Unity2DDeclarativeView::saveActiveWindow()
1603-{
1604- /* Using Bamf here, 'cause XGetFocusInputFocus returned a XId
1605- different by 1, which then could not be used with Bamf to
1606- get the application. The change does not result in any functional
1607- differences, though. */
1608- WId active_window = None;
1609- BamfWindow* bamf_active_window = BamfMatcher::get_default().active_window();
1610-
1611- /* Bamf can return a null active window - example case is just after
1612- login when no application has been yet been started. */
1613- if (bamf_active_window != NULL) {
1614- active_window = bamf_active_window->xid();
1615- }
1616-
1617- if (active_window != this->effectiveWinId() && active_window != m_last_focused_window) {
1618- m_last_focused_window = active_window;
1619- Q_EMIT lastFocusedWindowChanged(m_last_focused_window);
1620- }
1621-}
1622-
1623-void Unity2DDeclarativeView::onActiveWorkspaceChanged()
1624-{
1625- m_last_focused_window = None;
1626- Q_EMIT activeWorkspaceChanged();
1627+ if (w != NULL)
1628+ w->setFocus();
1629 }
1630
1631 ScreenInfo*
1632@@ -299,10 +286,4 @@
1633 return m_screenInfo;
1634 }
1635
1636-unsigned int
1637-Unity2DDeclarativeView::lastFocusedWindow() const
1638-{
1639- return m_last_focused_window;
1640-}
1641-
1642 #include <unity2ddeclarativeview.moc>
1643
1644=== modified file 'libunity-2d-private/src/unity2ddeclarativeview.h'
1645--- libunity-2d-private/src/unity2ddeclarativeview.h 2012-03-14 15:11:21 +0000
1646+++ libunity-2d-private/src/unity2ddeclarativeview.h 2012-03-14 15:11:22 +0000
1647@@ -17,11 +17,20 @@
1648 #ifndef UNITY2DDECLARATIVEVIEW_H
1649 #define UNITY2DDECLARATIVEVIEW_H
1650
1651-#include <QDeclarativeView>
1652+#include <QGraphicsView>
1653+
1654+#include <QMap>
1655+#include <QUrl>
1656+#include <QVariant>
1657
1658 class ScreenInfo;
1659
1660-class Unity2DDeclarativeView : public QDeclarativeView
1661+class QDeclarativeContext;
1662+class QDeclarativeEngine;
1663+class QDeclarativeItem;
1664+class QGraphicsObject;
1665+
1666+class Unity2DDeclarativeView : public QGraphicsView
1667 {
1668 Q_OBJECT
1669
1670@@ -30,7 +39,6 @@
1671 Q_PROPERTY(QPoint globalPosition READ globalPosition NOTIFY globalPositionChanged)
1672 Q_PROPERTY(ScreenInfo* screen READ screen NOTIFY screenChanged)
1673 Q_PROPERTY(bool visible READ isVisible NOTIFY visibleChanged)
1674- Q_PROPERTY(unsigned int lastFocusedWindow READ lastFocusedWindow NOTIFY lastFocusedWindowChanged)
1675
1676 public:
1677 Unity2DDeclarativeView(QWidget *parent = 0);
1678@@ -39,13 +47,20 @@
1679 // getters
1680 bool useOpenGL() const;
1681 bool transparentBackground() const;
1682+ QUrl source() const;
1683 QPoint globalPosition() const;
1684 ScreenInfo* screen() const;
1685- unsigned int lastFocusedWindow() const;
1686
1687 // setters
1688 void setUseOpenGL(bool);
1689 void setTransparentBackground(bool);
1690+ void setSource(const QUrl& source, const QMap<const char*, QVariant> &rootObjectProperties = QMap<const char*, QVariant>());
1691+
1692+ static QDeclarativeEngine *engine();
1693+ QDeclarativeContext* rootContext() const;
1694+ QDeclarativeItem* rootObject() const;
1695+
1696+ Q_INVOKABLE virtual void forceActivateWindow();
1697
1698 Q_SIGNALS:
1699 void useOpenGLChanged(bool);
1700@@ -53,31 +68,30 @@
1701 void globalPositionChanged(QPoint);
1702 void screenChanged(ScreenInfo*);
1703 void visibleChanged(bool);
1704- void activeWorkspaceChanged();
1705- void lastFocusedWindowChanged(unsigned int);
1706-
1707-public Q_SLOTS:
1708- void forceActivateWindow();
1709- void forceDeactivateWindow();
1710+ void sceneResized(QSize size);
1711
1712 protected:
1713 void setupViewport();
1714 virtual void moveEvent(QMoveEvent* event);
1715 virtual void showEvent(QShowEvent *event);
1716 virtual void hideEvent(QHideEvent* event);
1717+ virtual void keyPressEvent(QKeyEvent* event);
1718+ virtual void keyReleaseEvent(QKeyEvent* event);
1719+
1720+ static void forceActivateWindow(WId window, QWidget *w = NULL);
1721
1722 ScreenInfo* m_screenInfo;
1723
1724 private Q_SLOTS:
1725- void onActiveWorkspaceChanged();
1726+ void resizeToRootObject();
1727
1728 private:
1729- void saveActiveWindow();
1730- void forceActivateThisWindow(WId);
1731-
1732 bool m_useOpenGL;
1733 bool m_transparentBackground;
1734- WId m_last_focused_window;
1735+ QUrl m_source;
1736+
1737+ QGraphicsScene m_scene;
1738+ QDeclarativeItem* m_rootItem;
1739 };
1740
1741 Q_DECLARE_METATYPE(Unity2DDeclarativeView*)
1742
1743=== modified file 'libunity-2d-private/src/unity2dpanel.cpp'
1744--- libunity-2d-private/src/unity2dpanel.cpp 2012-03-12 11:21:15 +0000
1745+++ libunity-2d-private/src/unity2dpanel.cpp 2012-03-14 15:11:22 +0000
1746@@ -45,8 +45,6 @@
1747 Unity2dPanel::Edge m_edge;
1748 mutable IndicatorsManager* m_indicatorsManager;
1749 QHBoxLayout* m_layout;
1750- int m_delta;
1751- bool m_manualSliding;
1752 StrutManager m_strutManager;
1753 ScreenInfo* m_screenInfo;
1754
1755@@ -60,15 +58,12 @@
1756 case Unity2dPanel::LeftEdge:
1757 if (QApplication::isLeftToRight()) {
1758 rect = QRect(screen.left(), available.top(), q->width(), available.height());
1759- rect.moveLeft(m_delta);
1760 } else {
1761 rect = QRect(screen.right() - q->width(), available.top(), q->width(), available.height());
1762- rect.moveRight(screen.right() - m_delta);
1763 }
1764 break;
1765 case Unity2dPanel::TopEdge:
1766 rect = QRect(screen.left(), screen.top(), screen.width(), q->height());
1767- rect.moveTop(m_delta);
1768 break;
1769 }
1770
1771@@ -105,8 +100,6 @@
1772 d->q = this;
1773 d->m_edge = Unity2dPanel::TopEdge;
1774 d->m_indicatorsManager = 0;
1775- d->m_delta = 0;
1776- d->m_manualSliding = false;
1777 d->m_layout = new QHBoxLayout(this);
1778 d->m_layout->setMargin(0);
1779 d->m_layout->setSpacing(0);
1780@@ -214,39 +207,11 @@
1781 d->m_strutManager.setEnabled(value);
1782 }
1783
1784-int Unity2dPanel::delta() const
1785-{
1786- return d->m_delta;
1787-}
1788-
1789-void Unity2dPanel::setDelta(int delta)
1790-{
1791- /* Clamp delta to be between 0 and minus its size */
1792- int minDelta = -panelSize();
1793- int maxDelta = 0;
1794-
1795- d->m_delta = qMax(qMin(delta, maxDelta), minDelta);
1796- d->updateGeometry();
1797-}
1798-
1799 int Unity2dPanel::panelSize() const
1800 {
1801 return (d->m_edge == Unity2dPanel::TopEdge) ? height() : width();
1802 }
1803
1804-bool Unity2dPanel::manualSliding() const
1805-{
1806- return d->m_manualSliding;
1807-}
1808-
1809-void Unity2dPanel::setManualSliding(bool manualSliding)
1810-{
1811- if (d->m_manualSliding != manualSliding) {
1812- d->m_manualSliding = manualSliding;
1813- Q_EMIT manualSlidingChanged(d->m_manualSliding);
1814- }
1815-}
1816-
1817 QString Unity2dPanel::id() const
1818 {
1819 int screen = QApplication::desktop()->screenNumber(this);
1820
1821=== modified file 'libunity-2d-private/src/unity2dpanel.h'
1822--- libunity-2d-private/src/unity2dpanel.h 2012-03-07 14:34:03 +0000
1823+++ libunity-2d-private/src/unity2dpanel.h 2012-03-14 15:11:22 +0000
1824@@ -35,17 +35,6 @@
1825 class Unity2dPanel : public QWidget
1826 {
1827 Q_OBJECT
1828- /**
1829- * The amount of pixels the panel is moved from its edge. Useful for
1830- * animations.
1831- */
1832- Q_PROPERTY(int delta READ delta WRITE setDelta)
1833- /**
1834- * Whether the delta property is being set by an external client. Setting
1835- * this property to true stops any animation of the delta property triggered
1836- by slideIn() or slideOut().
1837- */
1838- Q_PROPERTY(int manualSliding READ manualSliding WRITE setManualSliding NOTIFY manualSlidingChanged)
1839 Q_PROPERTY(bool useStrut READ useStrut WRITE setUseStrut NOTIFY useStrutChanged)
1840 Q_ENUMS(Edge)
1841
1842@@ -80,18 +69,11 @@
1843 bool useStrut() const;
1844 void setUseStrut(bool);
1845
1846- int delta() const;
1847- void setDelta(int);
1848-
1849 int panelSize() const;
1850
1851- bool manualSliding() const;
1852- void setManualSliding(bool);
1853-
1854 QString id() const;
1855
1856 Q_SIGNALS:
1857- void manualSlidingChanged(bool);
1858 void useStrutChanged(bool);
1859
1860 protected:
1861
1862=== modified file 'libunity-2d-private/src/workspaces.cpp'
1863--- libunity-2d-private/src/workspaces.cpp 2011-07-29 13:49:34 +0000
1864+++ libunity-2d-private/src/workspaces.cpp 2012-03-14 15:11:22 +0000
1865@@ -49,6 +49,12 @@
1866 return false;
1867 }
1868
1869+int
1870+Workspaces::activeScreen() const
1871+{
1872+ return -1;
1873+}
1874+
1875 bool
1876 Workspaces::running() const
1877 {
1878
1879=== modified file 'libunity-2d-private/src/workspaces.h'
1880--- libunity-2d-private/src/workspaces.h 2011-07-29 13:49:34 +0000
1881+++ libunity-2d-private/src/workspaces.h 2012-03-14 15:11:22 +0000
1882@@ -38,6 +38,7 @@
1883
1884 /* getters */
1885 virtual bool active() const;
1886+ virtual int activeScreen() const;
1887 virtual bool running() const;
1888 virtual int windowCount() const;
1889 virtual bool urgent() const;
1890
1891=== modified file 'panel/applets/appname/appnameapplet.cpp'
1892--- panel/applets/appname/appnameapplet.cpp 2012-03-06 17:30:05 +0000
1893+++ panel/applets/appname/appnameapplet.cpp 2012-03-14 15:11:22 +0000
1894@@ -253,7 +253,7 @@
1895
1896 void setupWindowHelper()
1897 {
1898- m_windowHelper = new WindowHelper(q);
1899+ m_windowHelper = new WindowHelper(q->panel()->screen(), q);
1900 QObject::connect(m_windowHelper, SIGNAL(stateChanged()),
1901 q, SLOT(updateWidgets()));
1902 QObject::connect(m_windowHelper, SIGNAL(nameChanged()),
1903@@ -316,7 +316,7 @@
1904
1905 bool isMaximized = d->m_windowHelper->isMaximized();
1906 bool isUserVisibleApp = app ? app->user_visible() : false;
1907- bool isOnSameScreen = d->m_windowHelper->isMostlyOnScreen(QApplication::desktop()->screenNumber(this));
1908+ bool isOnSameScreen = d->m_windowHelper->isMostlyOnScreen(panel()->screen());
1909 bool isUnderMouse = rect().contains(mapFromGlobal(QCursor::pos()));
1910 bool isOpened = isOnSameScreen &&
1911 (isUnderMouse
1912@@ -325,8 +325,8 @@
1913 );
1914 bool showMenu = isOpened && !d->m_menuBarWidget->isEmpty() && isUserVisibleApp;
1915 bool dashCanResize = !DashClient::instance()->alwaysFullScreen();
1916- bool dashIsVisible = DashClient::instance()->active();
1917- bool hudIsVisible = HUDClient::instance()->active();
1918+ bool dashIsVisible = DashClient::instance()->activeInScreen(panel()->screen());
1919+ bool hudIsVisible = HUDClient::instance()->activeInScreen(panel()->screen());
1920 bool showWindowButtons = (isOpened && isMaximized) || dashIsVisible || hudIsVisible;
1921 bool showAppLabel = !(isMaximized && showMenu) && isUserVisibleApp && isOnSameScreen;
1922 bool showDesktopLabel = !app;
1923
1924=== modified file 'panel/applets/appname/windowhelper.cpp'
1925--- panel/applets/appname/windowhelper.cpp 2012-03-05 16:38:47 +0000
1926+++ panel/applets/appname/windowhelper.cpp 2012-03-14 15:11:22 +0000
1927@@ -57,16 +57,17 @@
1928 {
1929 WnckWindow* m_window;
1930 GConnector m_connector;
1931+ int m_screen;
1932 };
1933
1934-WindowHelper::WindowHelper(QObject* parent)
1935+WindowHelper::WindowHelper(int screen, QObject* parent)
1936 : QObject(parent)
1937 , d(new WindowHelperPrivate)
1938 {
1939 d->m_window = 0;
1940+ d->m_screen = screen;
1941
1942- WnckScreen* screen = wnck_screen_get_default();
1943- wnck_screen_force_update(screen);
1944+ wnck_screen_force_update(wnck_screen_get_default());
1945
1946 update();
1947
1948@@ -84,6 +85,8 @@
1949
1950 connect(DashClient::instance(), SIGNAL(activeChanged(bool)), SLOT(update()));
1951 connect(HUDClient::instance(), SIGNAL(activeChanged(bool)), SLOT(update()));
1952+ connect(DashClient::instance(), SIGNAL(screenChanged(int)), SLOT(update()));
1953+ connect(HUDClient::instance(), SIGNAL(screenChanged(int)), SLOT(update()));
1954 // FIXME: the queued connection should not be needed, however if it's not used when
1955 // (un)maximizing the dash, the panel will deadlock for some reason.
1956 connect(&dash2dConfiguration(), SIGNAL(fullScreenChanged(bool)), SLOT(update()),
1957@@ -130,7 +133,7 @@
1958
1959 bool WindowHelper::isMaximized() const
1960 {
1961- if (DashClient::instance()->active()) {
1962+ if (DashClient::instance()->activeInScreen(d->m_screen)) {
1963 return dash2dConfiguration().property("fullScreen").toBool();
1964 } else {
1965 if (d->m_window) {
1966@@ -166,9 +169,9 @@
1967
1968 void WindowHelper::close()
1969 {
1970- if (DashClient::instance()->active()) {
1971+ if (DashClient::instance()->activeInScreen(d->m_screen)) {
1972 DashClient::instance()->setActive(false);
1973- } else if (HUDClient::instance()->active()) {
1974+ } else if (HUDClient::instance()->activeInScreen(d->m_screen)) {
1975 HUDClient::instance()->setActive(false);
1976 } else {
1977 guint32 timestamp = QDateTime::currentDateTime().toTime_t();
1978@@ -178,14 +181,14 @@
1979
1980 void WindowHelper::minimize()
1981 {
1982- if (!DashClient::instance()->active()) {
1983+ if (!DashClient::instance()->activeInScreen(d->m_screen)) {
1984 wnck_window_minimize(d->m_window);
1985 }
1986 }
1987
1988 void WindowHelper::maximize()
1989 {
1990- if (DashClient::instance()->active()) {
1991+ if (DashClient::instance()->activeInScreen(d->m_screen)) {
1992 dash2dConfiguration().setProperty("fullScreen", QVariant(true));
1993 } else {
1994 /* This currently cannot happen, because the window buttons are not
1995@@ -197,7 +200,7 @@
1996
1997 void WindowHelper::unmaximize()
1998 {
1999- if (DashClient::instance()->active()) {
2000+ if (DashClient::instance()->activeInScreen(d->m_screen)) {
2001 dash2dConfiguration().setProperty("fullScreen", QVariant(false));
2002 } else {
2003 wnck_window_unmaximize(d->m_window);
2004
2005=== modified file 'panel/applets/appname/windowhelper.h'
2006--- panel/applets/appname/windowhelper.h 2012-02-07 16:48:45 +0000
2007+++ panel/applets/appname/windowhelper.h 2012-03-14 15:11:22 +0000
2008@@ -34,7 +34,7 @@
2009 {
2010 Q_OBJECT
2011 public:
2012- WindowHelper(QObject* parent);
2013+ WindowHelper(int screen, QObject* parent);
2014 ~WindowHelper();
2015
2016 void setXid(uint);
2017
2018=== added file 'shell/DashLoader.qml'
2019--- shell/DashLoader.qml 1970-01-01 00:00:00 +0000
2020+++ shell/DashLoader.qml 2012-03-14 15:11:22 +0000
2021@@ -0,0 +1,36 @@
2022+/*
2023+ * This file is part of unity-2d
2024+ *
2025+ * Copyright 2012 Canonical Ltd.
2026+ *
2027+ * This program is free software; you can redistribute it and/or modify
2028+ * it under the terms of the GNU General Public License as published by
2029+ * the Free Software Foundation; version 3.
2030+ *
2031+ * This program is distributed in the hope that it will be useful,
2032+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2033+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2034+ * GNU General Public License for more details.
2035+ *
2036+ * You should have received a copy of the GNU General Public License
2037+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2038+ */
2039+
2040+import QtQuick 1.1
2041+import "common/utils.js" as Utils
2042+
2043+Loader {
2044+ id: dashLoader
2045+ source: "dash/Dash.qml"
2046+ anchors.top: parent != undefined ? parent.top : undefined
2047+ x: Utils.isLeftToRight() ? launcherLoader.width : shell.width - width - launcherLoader.width
2048+ onLoaded: item.focus = true
2049+ opacity: item.active ? 1.0 : 0.0
2050+ focus: item.active
2051+
2052+ Binding {
2053+ target: dashLoader.item
2054+ property: "fullscreenWidth"
2055+ value: shell.width - launcherLoader.width
2056+ }
2057+}
2058
2059=== added file 'shell/HudLoader.qml'
2060--- shell/HudLoader.qml 1970-01-01 00:00:00 +0000
2061+++ shell/HudLoader.qml 2012-03-14 15:11:22 +0000
2062@@ -0,0 +1,35 @@
2063+/*
2064+ * This file is part of unity-2d
2065+ *
2066+ * Copyright 2012 Canonical Ltd.
2067+ *
2068+ * This program is free software; you can redistribute it and/or modify
2069+ * it under the terms of the GNU General Public License as published by
2070+ * the Free Software Foundation; version 3.
2071+ *
2072+ * This program is distributed in the hope that it will be useful,
2073+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2074+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2075+ * GNU General Public License for more details.
2076+ *
2077+ * You should have received a copy of the GNU General Public License
2078+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2079+ */
2080+
2081+import QtQuick 1.1
2082+import "common/utils.js" as Utils
2083+
2084+Loader {
2085+ id: hudLoader
2086+ property bool animating: item.animating
2087+ property bool active: item.active
2088+ onActiveChanged: item.active = active
2089+
2090+ source: "hud/Hud.qml"
2091+ anchors.top: parent != undefined ? parent.top : undefined
2092+ x: Utils.isLeftToRight() ? 0 : shell.width - width
2093+ onLoaded: item.focus = true
2094+ visible: item.active
2095+ focus: item.active
2096+ width: Math.min(shell.width, 1061)
2097+}
2098
2099=== modified file 'shell/Shell.qml'
2100--- shell/Shell.qml 2012-03-13 18:54:14 +0000
2101+++ shell/Shell.qml 2012-03-14 15:11:22 +0000
2102@@ -23,6 +23,11 @@
2103
2104 Item {
2105 id: shell
2106+
2107+ property variant declarativeView
2108+ property variant dashLoader
2109+ property variant hudLoader
2110+
2111 /* Space reserved by strutManager is taken off screen.availableGeometry but
2112 we want the shell to take all the available space, including the one we
2113 reserved ourselves via strutManager. */
2114@@ -34,12 +39,32 @@
2115
2116 Accessible.name: "shell"
2117
2118- property alias hudActive: hudLoader.active
2119-
2120 GestureHandler {
2121 id: gestureHandler
2122 }
2123
2124+ onDashLoaderChanged: {
2125+ if (shellManager.dashActive) {
2126+ if (dashLoader == undefined)
2127+ {
2128+ launcherLoader.visibilityController.endForceVisible("dash")
2129+ } else {
2130+ launcherLoader.visibilityController.beginForceVisible("dash")
2131+ }
2132+ }
2133+ }
2134+
2135+ onHudLoaderChanged: {
2136+ if (shellManager.hudActive) {
2137+ if (hudLoader == undefined)
2138+ {
2139+ launcherLoader.visibilityController.endForceHidden("hud")
2140+ } else {
2141+ launcherLoader.visibilityController.beginForceHidden("hud")
2142+ }
2143+ }
2144+ }
2145+
2146 LauncherLoader {
2147 id: launcherLoader
2148 anchors.top: parent.top
2149@@ -72,36 +97,14 @@
2150 }
2151 }
2152
2153- KeyNavigation.right: dashLoader
2154-
2155 Binding {
2156 target: launcherLoader.item
2157 property: "showMenus"
2158- value: !dashLoader.item.active && !hudLoader.item.active
2159+ value: (dashLoader == undefined || !dashLoader.item.active) && (hudLoader == undefined || !hudLoader.item.active)
2160 }
2161
2162 Behavior on x { NumberAnimation { id: launcherLoaderXAnimation; duration: 125 } }
2163
2164- Connections {
2165- target: declarativeView
2166- onDashActiveChanged: {
2167- if (declarativeView.dashActive) {
2168- if (hudLoader.item.active) hudLoader.item.active = false
2169- launcherLoader.visibilityController.beginForceVisible("dash")
2170- } else {
2171- launcherLoader.visibilityController.endForceVisible("dash")
2172- if (dashLoader.status == Loader.Ready) dashLoader.item.deactivateAllLenses()
2173- }
2174- }
2175- onGlobalPositionChanged: {
2176- var x = declarativeView.globalPosition.x + (Utils.isLeftToRight() ? 0 : shell.width)
2177- launcherLoader.item.barrierP1 = Qt.point(x, 0)
2178- launcherLoader.item.barrierP2 = Qt.point(x, declarativeView.screen.geometry.height)
2179- launcherLoader.item.barrierTriggerZoneP1 = Qt.point(x, declarativeView.globalPosition.y)
2180- launcherLoader.item.barrierTriggerZoneP2 = Qt.point(x, declarativeView.globalPosition.y + launcherLoader.height)
2181- }
2182- }
2183-
2184 SpreadMonitor {
2185 id: spread
2186 onShownChanged: if (shown) {
2187@@ -114,46 +117,37 @@
2188 }
2189 }
2190
2191-
2192- Loader {
2193- id: dashLoader
2194- source: "dash/Dash.qml"
2195- anchors.top: parent.top
2196- x: Utils.isLeftToRight() ? launcherLoader.width : shell.width - width - launcherLoader.width
2197- onLoaded: item.focus = true
2198- opacity: item.active ? 1.0 : 0.0
2199- focus: item.active
2200-
2201- Binding {
2202- target: dashLoader.item
2203- property: "fullscreenWidth"
2204- value: shell.width - launcherLoader.width
2205+ Connections {
2206+ target: shellManager
2207+
2208+ onDashActiveChanged: {
2209+ if (shellManager.dashActive) {
2210+ if (hudLoader != undefined && hudLoader.item.active) {
2211+ hudLoader.item.active = false
2212+ }
2213+ if (dashLoader != undefined) {
2214+ launcherLoader.visibilityController.beginForceVisible("dash")
2215+ }
2216+ } else {
2217+ if (dashLoader != undefined) {
2218+ launcherLoader.visibilityController.endForceVisible("dash")
2219+ if (dashLoader.status == Loader.Ready) dashLoader.item.deactivateAllLenses()
2220+ }
2221+ }
2222 }
2223- }
2224-
2225- Loader {
2226- id: hudLoader
2227- property bool animating: item.animating
2228- property bool active: item.active
2229- onActiveChanged: item.active = active
2230-
2231- source: "hud/Hud.qml"
2232- anchors.top: parent.top
2233- x: Utils.isLeftToRight() ? 0 : shell.width - width
2234- onLoaded: item.focus = true
2235- visible: item.active
2236- focus: item.active
2237- width: Math.min(shell.width, 1061)
2238- }
2239-
2240- Connections {
2241- target: hudLoader.item
2242- onActiveChanged: {
2243- if (hudLoader.item.active) {
2244- if (dashLoader.item.active) dashLoader.item.active = false
2245- launcherLoader.visibilityController.beginForceHidden("hud")
2246+
2247+ onHudActiveChanged: {
2248+ if (shellManager.hudActive) {
2249+ if (dashLoader != undefined && dashLoader.item.active) {
2250+ dashLoader.item.active = false
2251+ }
2252+ if (hudLoader != undefined) {
2253+ launcherLoader.visibilityController.beginForceHidden("hud")
2254+ }
2255 } else {
2256- launcherLoader.visibilityController.endForceHidden("hud")
2257+ if (hudLoader != undefined) {
2258+ launcherLoader.visibilityController.endForceHidden("hud")
2259+ }
2260 }
2261 }
2262 }
2263@@ -165,7 +159,7 @@
2264 launcherLoader.item.focusBFB()
2265 }
2266 onFocusChanged: {
2267- if (!declarativeView.focus && hudLoader.item.active) hudLoader.item.active = false
2268+ if (!declarativeView.focus && hudLoader!= undefined && hudLoader.item.active) hudLoader.item.active = false
2269
2270 /* FIXME: The launcher is forceVisible while it has activeFocus. However even though
2271 the documentation says that setting focus=false will make an item lose activeFocus
2272@@ -177,7 +171,16 @@
2273 }
2274 }
2275
2276- Component.onCompleted: declarativeView.show()
2277+ Component.onCompleted: {
2278+ if (declarativeView.screen.screen == 0) {
2279+ var loaderComponent = Qt.createComponent("DashLoader.qml");
2280+ dashLoader = loaderComponent.createObject(shell, {});
2281+
2282+ var loaderComponent = Qt.createComponent("HudLoader.qml");
2283+ hudLoader = loaderComponent.createObject(shell, {});
2284+ }
2285+ declarativeView.show()
2286+ }
2287
2288 Keys.onPressed: {
2289 if (event.key == Qt.Key_Escape || (event.key == Qt.Key_F4 && event.modifiers == Qt.AltModifier )) {
2290@@ -194,31 +197,37 @@
2291 }
2292
2293 InputShapeRectangle {
2294- rectangle: if (desktop.isCompositingManagerRunning) {
2295- Qt.rect(dashLoader.x, dashLoader.y, dashLoader.width, dashLoader.height)
2296- } else {
2297- Qt.rect(dashLoader.x, dashLoader.y, dashLoader.width - 7, dashLoader.height - 9)
2298+ rectangle: {
2299+ if (dashLoader != undefined) {
2300+ if (desktop.isCompositingManagerRunning) {
2301+ return Qt.rect(dashLoader.x, dashLoader.y, dashLoader.width, dashLoader.height)
2302+ } else {
2303+ return Qt.rect(dashLoader.x, dashLoader.y, dashLoader.width - 7, dashLoader.height - 9)
2304+ }
2305+ } else {
2306+ return Qt.rect(0, 0, 0, 0)
2307+ }
2308 }
2309- enabled: dashLoader.status == Loader.Ready && dashLoader.item.active
2310+ enabled: dashLoader != undefined && dashLoader.status == Loader.Ready && dashLoader.item.active
2311 mirrorHorizontally: Utils.isRightToLeft()
2312
2313 InputShapeMask {
2314 id: shape1
2315 source: "shell/common/artwork/desktop_dash_background_no_transparency.png"
2316 color: "red"
2317- position: Qt.point(dashLoader.width - 50, dashLoader.height - 49)
2318- enabled: declarativeView.dashMode == ShellDeclarativeView.DesktopMode
2319+ position: dashLoader != undefined ? Qt.point(dashLoader.width - 50, dashLoader.height - 49) : Qt.point(0, 0)
2320+ enabled: shellManager.dashMode == ShellManager.DesktopMode
2321 }
2322 }
2323
2324 InputShapeRectangle {
2325 id: hudInputShape
2326- enabled: hudLoader.status == Loader.Ready && hudLoader.item.active
2327+ enabled: hudLoader != undefined && hudLoader.status == Loader.Ready && hudLoader.item.active
2328
2329 InputShapeMask {
2330 source: "shell/common/artwork/desktop_dash_background_no_transparency.png"
2331 color: "red"
2332- position: Qt.point(hudLoader.width - 50, hudLoader.height - 49)
2333+ position: hudLoader != undefined ? Qt.point(hudLoader.width - 50, hudLoader.height - 49) : Qt.point(0, 0)
2334 }
2335 }
2336 }
2337@@ -237,13 +246,17 @@
2338 target: hudInputShape
2339 property: "rectangle"
2340 value: {
2341- if (desktop.isCompositingManagerRunning) {
2342- return Qt.rect(hudLoader.x, hudLoader.y, hudLoader.width, hudLoader.height)
2343+ if (hudLoader != undefined) {
2344+ if (desktop.isCompositingManagerRunning) {
2345+ return Qt.rect(hudLoader.x, hudLoader.y, hudLoader.width, hudLoader.height)
2346+ } else {
2347+ return Qt.rect(hudLoader.x, hudLoader.y, hudLoader.width - 7, hudLoader.height - 9)
2348+ }
2349 } else {
2350- return Qt.rect(hudLoader.x, hudLoader.y, hudLoader.width - 7, hudLoader.height - 9)
2351+ return Qt.rect(0, 0, 0, 0)
2352 }
2353 }
2354- when: !hudLoader.animating
2355+ when: hudLoader != undefined && !hudLoader.animating
2356 }
2357
2358 StrutManager {
2359@@ -254,4 +267,23 @@
2360 width: launcherLoader.width
2361 enabled: Utils.clamp(launcher2dConfiguration.hideMode, 0, 2) == 0
2362 }
2363+
2364+ PointerBarrier {
2365+ property int x: declarativeView.globalPosition.x + (Utils.isLeftToRight() ? 0 : shell.width)
2366+
2367+ id: leftBarrier
2368+ triggerDirection: Utils.isLeftToRight() ? PointerBarrier.TriggerFromRight : PointerBarrier.TriggerFromLeft
2369+ triggerZoneEnabled: !launcherLoader.visibilityController.shown
2370+ p1: Qt.point(x, declarativeView.screen.geometry.y)
2371+ p2: Qt.point(x, declarativeView.screen.geometry.y + declarativeView.screen.geometry.height)
2372+ triggerZoneP1: Qt.point(x, declarativeView.globalPosition.y)
2373+ triggerZoneP2: Qt.point(x, declarativeView.globalPosition.y + launcherLoader.height)
2374+ threshold: launcherLoader.launcherInHideMode && launcherLoader.loadLauncher ? launcher2dConfiguration.edgeStopVelocity : -1
2375+ maxVelocityMultiplier: launcher2dConfiguration.edgeResponsiveness
2376+ decayRate: launcher2dConfiguration.edgeDecayrate
2377+ triggerPressure: launcher2dConfiguration.edgeRevealPressure
2378+ breakPressure: launcher2dConfiguration.edgeOvercomePressure
2379+
2380+ onTriggered: launcherLoader.item.barrierTriggered()
2381+ }
2382 }
2383
2384=== modified file 'shell/app/CMakeLists.txt'
2385--- shell/app/CMakeLists.txt 2012-03-05 16:38:47 +0000
2386+++ shell/app/CMakeLists.txt 2012-03-14 15:11:22 +0000
2387@@ -9,6 +9,7 @@
2388 dashdbus.cpp
2389 huddbus.cpp
2390 shelldeclarativeview.cpp
2391+ shellmanager.cpp
2392 )
2393
2394 set(shell_MOC_HDRS
2395@@ -16,6 +17,7 @@
2396 dashdbus.h
2397 huddbus.h
2398 shelldeclarativeview.h
2399+ shellmanager.h
2400 )
2401
2402 qt4_wrap_cpp(shell_MOC_SRCS ${shell_MOC_HDRS})
2403@@ -33,6 +35,8 @@
2404 ${QTGCONF_INCLUDE_DIRS}
2405 ${DCONFQT_INCLUDE_DIRS}
2406 ${GTK_INCLUDE_DIRS}
2407+ ${QTBAMF_INCLUDE_DIRS}
2408+ ${WNCK_INCLUDE_DIRS}
2409 ${libunity-2d-private_SOURCE_DIR}/src
2410 )
2411
2412@@ -44,6 +48,8 @@
2413 ${QTGCONF_LDFLAGS}
2414 ${DCONFQT_LDFLAGS}
2415 ${GTK_LDFLAGS}
2416+ ${WNCK_LDFLAGS}
2417+ ${QTBAMF_LDFLAGS}
2418 ${X11_Xext_LIB}
2419 ${X11_X11_LIB}
2420 unity-2d-private
2421
2422=== modified file 'shell/app/dash.xml'
2423--- shell/app/dash.xml 2012-03-05 16:38:47 +0000
2424+++ shell/app/dash.xml 2012-03-14 15:11:22 +0000
2425@@ -27,6 +27,9 @@
2426 <property name="activeLens" type="s" access="readwrite">
2427 <dox:d>The currently active lens</dox:d>
2428 </property>
2429+ <property name="screen" type="i" access="read">
2430+ <dox:d>The screen with the dash</dox:d>
2431+ </property>
2432 <signal name="activeChanged">
2433 <dox:d>Signals when the active status of the Dash changes</dox:d>
2434 <arg name="active" type="b" direction="out">
2435@@ -45,6 +48,12 @@
2436 <dox:d>The currently active lens</dox:d>
2437 </arg>
2438 </signal>
2439+ <signal name="screenChanged">
2440+ <dox:d>Signals when the screen changes</dox:d>
2441+ <arg name="active" type="i" direction="out">
2442+ <dox:d>The screen with the dash</dox:d>
2443+ </arg>
2444+ </signal>
2445 </interface>
2446 </node>
2447
2448
2449=== modified file 'shell/app/dashdbus.cpp'
2450--- shell/app/dashdbus.cpp 2012-03-05 16:38:47 +0000
2451+++ shell/app/dashdbus.cpp 2012-03-14 15:11:22 +0000
2452@@ -21,19 +21,21 @@
2453 #include "dashadaptor.h"
2454
2455 // Local
2456-#include <shelldeclarativeview.h>
2457+#include <shellmanager.h>
2458
2459 // Qt
2460 #include <QtDBus/QDBusConnection>
2461 #include <QGraphicsObject>
2462
2463-DashDBus::DashDBus(ShellDeclarativeView* view, QObject* parent)
2464+DashDBus::DashDBus(ShellManager* manager, QObject* parent)
2465 : QObject(parent)
2466-, m_view(view)
2467+, m_manager(manager)
2468 {
2469- connect(m_view, SIGNAL(dashActiveChanged(bool)), SIGNAL(activeChanged(bool)));
2470- connect(m_view, SIGNAL(dashAlwaysFullScreenChanged(bool)), SIGNAL(alwaysFullScreenChanged(bool)));
2471- connect(m_view, SIGNAL(activeLensChanged(QString)), SIGNAL(activeLensChanged(QString)));
2472+ connect(m_manager, SIGNAL(dashActiveChanged(bool)), SIGNAL(activeChanged(bool)));
2473+ connect(m_manager, SIGNAL(dashAlwaysFullScreenChanged(bool)), SIGNAL(alwaysFullScreenChanged(bool)));
2474+ connect(m_manager, SIGNAL(dashActiveLensChanged(QString)), SIGNAL(activeLensChanged(QString)));
2475+
2476+ connect(m_manager, SIGNAL(dashScreenChanged(int)), SIGNAL(screenChanged(int)));
2477
2478 new DashAdaptor(this);
2479 }
2480@@ -41,41 +43,47 @@
2481 void
2482 DashDBus::activateHome()
2483 {
2484- Q_EMIT m_view->activateHome();
2485+ Q_EMIT m_manager->dashActivateHome();
2486 }
2487
2488 void
2489 DashDBus::activateLens(const QString& lensId)
2490 {
2491- Q_EMIT m_view->activateLens(lensId);
2492+ Q_EMIT m_manager->dashActivateLens(lensId);
2493 }
2494
2495 bool
2496 DashDBus::active() const
2497 {
2498- return m_view->dashActive();
2499+ return m_manager->dashActive();
2500 }
2501
2502 void
2503 DashDBus::setActive(bool active)
2504 {
2505- m_view->setDashActive(active);
2506+ m_manager->setDashActive(active);
2507 }
2508
2509 bool
2510 DashDBus::alwaysFullScreen() const
2511 {
2512- return m_view->dashAlwaysFullScreen();
2513+ return m_manager->dashAlwaysFullScreen();
2514 }
2515
2516 QString
2517 DashDBus::activeLens() const
2518 {
2519- return m_view->activeLens();
2520+ return m_manager->dashActiveLens();
2521 }
2522
2523 void
2524 DashDBus::setActiveLens(QString activeLens)
2525 {
2526- m_view->setActiveLens(activeLens);
2527+ m_manager->setDashActiveLens(activeLens);
2528+}
2529+
2530+int
2531+DashDBus::screen() const
2532+{
2533+ return m_manager->dashScreen();
2534 }
2535
2536=== modified file 'shell/app/dashdbus.h'
2537--- shell/app/dashdbus.h 2012-03-05 16:38:47 +0000
2538+++ shell/app/dashdbus.h 2012-03-14 15:11:22 +0000
2539@@ -23,7 +23,7 @@
2540 #include <QtCore/QObject>
2541 #include <QtDBus/QDBusContext>
2542
2543-class ShellDeclarativeView;
2544+class ShellManager;
2545
2546 /**
2547 * DBus interface for the dash.
2548@@ -37,15 +37,17 @@
2549 Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged)
2550 Q_PROPERTY(bool alwaysFullScreen READ alwaysFullScreen NOTIFY alwaysFullScreenChanged)
2551 Q_PROPERTY(QString activeLens READ activeLens WRITE setActiveLens NOTIFY activeLensChanged)
2552+ Q_PROPERTY(int screen READ screen NOTIFY screenChanged)
2553
2554 public:
2555- DashDBus(ShellDeclarativeView* view, QObject* parent=0);
2556+ DashDBus(ShellManager* manager, QObject* parent=0);
2557
2558 bool active() const;
2559 void setActive(bool active);
2560 bool alwaysFullScreen() const;
2561 QString activeLens() const;
2562 void setActiveLens(QString activeLens);
2563+ int screen() const;
2564
2565 public Q_SLOTS:
2566 Q_NOREPLY void activateHome();
2567@@ -55,9 +57,10 @@
2568 void activeChanged(bool);
2569 void alwaysFullScreenChanged(bool);
2570 void activeLensChanged(QString);
2571+ void screenChanged(int);
2572
2573 private:
2574- ShellDeclarativeView* m_view;
2575+ ShellManager* m_manager;
2576 };
2577
2578 #endif // DashDBus_H
2579
2580=== modified file 'shell/app/hud.xml'
2581--- shell/app/hud.xml 2012-03-05 16:38:47 +0000
2582+++ shell/app/hud.xml 2012-03-14 15:11:22 +0000
2583@@ -12,12 +12,21 @@
2584 <property name="active" type="b" access="readwrite">
2585 <dox:d>True if the HUD is active</dox:d>
2586 </property>
2587+ <property name="screen" type="i" access="read">
2588+ <dox:d>The screen with the HUD</dox:d>
2589+ </property>
2590 <signal name="activeChanged">
2591 <dox:d>Signals when the active status of the HUD changes</dox:d>
2592 <arg name="active" type="b" direction="out">
2593 <dox:d>True if the HUD is active</dox:d>
2594 </arg>
2595 </signal>
2596+ <signal name="screenChanged">
2597+ <dox:d>Signals when the screen changes</dox:d>
2598+ <arg name="active" type="i" direction="out">
2599+ <dox:d>The screen with the HUD</dox:d>
2600+ </arg>
2601+ </signal>
2602 </interface>
2603 </node>
2604
2605
2606=== modified file 'shell/app/huddbus.cpp'
2607--- shell/app/huddbus.cpp 2012-03-05 16:38:47 +0000
2608+++ shell/app/huddbus.cpp 2012-03-14 15:11:22 +0000
2609@@ -21,18 +21,18 @@
2610 #include "hudadaptor.h"
2611
2612 // Local
2613-#include <shelldeclarativeview.h>
2614+#include <shellmanager.h>
2615
2616 // Qt
2617 #include <QtDBus/QDBusConnection>
2618 #include <QGraphicsObject>
2619
2620-HUDDBus::HUDDBus(ShellDeclarativeView* view, QObject* parent)
2621+HUDDBus::HUDDBus(ShellManager* manager, QObject* parent)
2622 : QObject(parent)
2623-, m_view(view)
2624+, m_manager(manager)
2625 {
2626- /* QML's propertyChanged signals are simple, they don't pass the property value */
2627- connect(m_view->rootObject(), SIGNAL(hudActiveChanged()), SLOT(onHudActiveChanged()));
2628+ connect(m_manager, SIGNAL(hudActiveChanged()), SLOT(onHudActiveChanged()));
2629+ connect(m_manager, SIGNAL(hudScreenChanged(int)), SIGNAL(screenChanged(int)));
2630
2631 new HUDAdaptor(this);
2632 }
2633@@ -40,7 +40,7 @@
2634 bool
2635 HUDDBus::active() const
2636 {
2637- return m_view->rootObject()->property("hudActive").toBool();
2638+ return m_manager->hudActive();
2639 }
2640
2641 void
2642@@ -53,7 +53,13 @@
2643 HUDDBus::setActive(bool hudActive)
2644 {
2645 if (hudActive != active()) {
2646- m_view->rootObject()->setProperty("hudActive", hudActive);
2647+ m_manager->setHudActive(hudActive);
2648 Q_EMIT activeChanged(hudActive);
2649 }
2650 }
2651+
2652+int
2653+HUDDBus::screen() const
2654+{
2655+ return m_manager->hudScreen();
2656+}
2657
2658=== modified file 'shell/app/huddbus.h'
2659--- shell/app/huddbus.h 2012-03-05 16:38:47 +0000
2660+++ shell/app/huddbus.h 2012-03-14 15:11:22 +0000
2661@@ -23,7 +23,7 @@
2662 #include <QtCore/QObject>
2663 #include <QtDBus/QDBusContext>
2664
2665-class ShellDeclarativeView;
2666+class ShellManager;
2667
2668 /**
2669 * DBus interface for the HUD.
2670@@ -32,21 +32,24 @@
2671 {
2672 Q_OBJECT
2673 Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged)
2674+ Q_PROPERTY(int screen READ screen NOTIFY screenChanged)
2675
2676 public:
2677- HUDDBus(ShellDeclarativeView* view, QObject* parent=0);
2678+ HUDDBus(ShellManager* manager, QObject* parent=0);
2679
2680 bool active() const;
2681 void setActive(bool active);
2682+ int screen() const;
2683
2684 Q_SIGNALS:
2685 void activeChanged(bool);
2686+ void screenChanged(int);
2687
2688 private Q_SLOTS:
2689 void onHudActiveChanged();
2690
2691 private:
2692- ShellDeclarativeView* m_view;
2693+ ShellManager* m_manager;
2694 };
2695
2696 #endif // HudDBus_H
2697
2698=== modified file 'shell/app/shell.cpp'
2699--- shell/app/shell.cpp 2012-03-06 18:06:03 +0000
2700+++ shell/app/shell.cpp 2012-03-14 15:11:22 +0000
2701@@ -21,27 +21,16 @@
2702 // QT
2703 #include <QApplication>
2704 #include <QDebug>
2705-#include <QtDeclarative>
2706-#include <QDeclarativeEngine>
2707-#include <QDeclarativeView>
2708-#include <QDesktopWidget>
2709-#include <QDBusConnection>
2710-#include <QDBusConnectionInterface>
2711-#include <QDeclarativeContext>
2712-#include <QAbstractEventDispatcher>
2713 #include <QDir>
2714-
2715-// X11
2716-#include <X11/Xlib.h>
2717+#include <QUrl>
2718
2719 // unity-2d
2720 #include <gnomesessionclient.h>
2721 #include <unity2dapplication.h>
2722-#include <unity2ddebug.h>
2723
2724 // Local
2725 #include "config.h"
2726-#include "shelldeclarativeview.h"
2727+#include "shellmanager.h"
2728 #include "shelldbus.h"
2729
2730 int main(int argc, char *argv[])
2731@@ -69,22 +58,7 @@
2732 GnomeSessionClient client(INSTALL_PREFIX "/share/applications/unity-2d-shell.desktop");
2733 client.connectToSessionManager();
2734
2735- qmlRegisterType<ShellDeclarativeView>("Unity2d", 1, 0, "ShellDeclarativeView");
2736- ShellDeclarativeView view;
2737- view.setAccessibleName("Shell");
2738- if (arguments.contains("-opengl")) {
2739- view.setUseOpenGL(true);
2740- }
2741-
2742- application.installX11EventFilter(&view);
2743-
2744- view.engine()->addImportPath(unity2dImportPath());
2745- view.engine()->setBaseUrl(QUrl::fromLocalFile(unity2dDirectory() + "/shell/"));
2746-
2747- /* Load the QML UI, focus and show the window */
2748- view.setResizeMode(QDeclarativeView::SizeViewToRootObject);
2749- view.rootContext()->setContextProperty("declarativeView", &view);
2750- view.setSource(rootFileUrl);
2751+ ShellManager shells(rootFileUrl);
2752
2753 /* Unset DESKTOP_AUTOSTART_ID in order to avoid child processes (launched
2754 applications) to use the same client id.
2755@@ -101,7 +75,7 @@
2756 (see e.g. https://bugs.launchpad.net/bugs/684471). */
2757 QDir::setCurrent(QDir::homePath());
2758
2759- ShellDBus shellDBus(&view);
2760+ ShellDBus shellDBus(&shells);
2761 if (!shellDBus.connectToBus()) {
2762 qCritical() << "Another instance of the Shell already exists. Quitting.";
2763 return -1;
2764
2765=== modified file 'shell/app/shelldbus.cpp'
2766--- shell/app/shelldbus.cpp 2012-03-05 16:38:47 +0000
2767+++ shell/app/shelldbus.cpp 2012-03-14 15:11:22 +0000
2768@@ -32,9 +32,9 @@
2769 static const char* DASH_DBUS_OBJECT_PATH = "/Dash";
2770 static const char* HUD_DBUS_OBJECT_PATH = "/HUD";
2771
2772-ShellDBus::ShellDBus(ShellDeclarativeView* view, QObject* parent)
2773+ShellDBus::ShellDBus(ShellManager* manager, QObject* parent)
2774 : QObject(parent)
2775-, m_view(view)
2776+, m_manager(manager)
2777 {
2778 }
2779
2780@@ -51,10 +51,10 @@
2781 return false;
2782 }
2783
2784- DashDBus *dashDBus = new DashDBus(m_view, this);
2785+ DashDBus *dashDBus = new DashDBus(m_manager, this);
2786 QDBusConnection::sessionBus().registerObject(DASH_DBUS_OBJECT_PATH, dashDBus);
2787
2788- HUDDBus *hudDBus = new HUDDBus(m_view, this);
2789+ HUDDBus *hudDBus = new HUDDBus(m_manager, this);
2790 QDBusConnection::sessionBus().registerObject(HUD_DBUS_OBJECT_PATH, hudDBus);
2791
2792 return true;
2793
2794=== modified file 'shell/app/shelldbus.h'
2795--- shell/app/shelldbus.h 2012-03-06 11:09:04 +0000
2796+++ shell/app/shelldbus.h 2012-03-14 15:11:22 +0000
2797@@ -24,7 +24,7 @@
2798 #include <QtCore/QObject>
2799 #include <QtDBus/QDBusContext>
2800
2801-class ShellDeclarativeView;
2802+class ShellManager;
2803
2804 /**
2805 * DBus interface for the shell.
2806@@ -34,13 +34,13 @@
2807 Q_OBJECT
2808
2809 public:
2810- ShellDBus(ShellDeclarativeView* view, QObject* parent=0);
2811+ ShellDBus(ShellManager* manager, QObject* parent=0);
2812 ~ShellDBus();
2813
2814 bool connectToBus();
2815
2816 private:
2817- ShellDeclarativeView* m_view;
2818+ ShellManager* m_manager;
2819 };
2820
2821 #endif // ShellDBus_H
2822
2823=== modified file 'shell/app/shelldeclarativeview.cpp'
2824--- shell/app/shelldeclarativeview.cpp 2012-03-05 14:04:05 +0000
2825+++ shell/app/shelldeclarativeview.cpp 2012-03-14 15:11:22 +0000
2826@@ -17,17 +17,12 @@
2827 // Local
2828 #include <config.h>
2829 #include "shelldeclarativeview.h"
2830+#include "shellmanager.h"
2831 #include "dashdbus.h"
2832
2833 // libunity-2d-private
2834 #include <debug_p.h>
2835 #include <hotkey.h>
2836-#include <hotkeymonitor.h>
2837-#include <hotmodifier.h>
2838-#include <keyboardmodifiersmonitor.h>
2839-#include <keymonitor.h>
2840-#include <dashclient.h>
2841-#include <launcherclient.h>
2842 #include <screeninfo.h>
2843 #include <strutmanager.h>
2844
2845@@ -41,69 +36,25 @@
2846 #include <QtDBus/QDBusConnectionInterface>
2847 #include <QtDBus/QDBusInterface>
2848 #include <QX11Info>
2849-#include <QGraphicsObject>
2850+#include <QDeclarativeItem>
2851 #include <QFileInfo>
2852
2853 // X11
2854 #include <X11/Xlib.h>
2855 #include <X11/Xatom.h>
2856
2857-static const char* COMMANDS_LENS_ID = "commands.lens";
2858-
2859-static const int DASH_MIN_SCREEN_WIDTH = 1280;
2860-static const int DASH_MIN_SCREEN_HEIGHT = 1084;
2861-
2862-ShellDeclarativeView::ShellDeclarativeView()
2863+ShellDeclarativeView::ShellDeclarativeView(ShellManager *manager, const QUrl &sourceFileUrl, int screen)
2864 : Unity2DDeclarativeView()
2865- , m_mode(DesktopMode)
2866- , m_expanded(true)
2867- , m_active(false)
2868- , m_dashAlwaysFullScreen(false)
2869+ , m_sourceFileUrl(sourceFileUrl)
2870+ , m_manager(manager)
2871 {
2872 setAttribute(Qt::WA_X11NetWmWindowTypeDock, true);
2873 setTransparentBackground(QX11Info::isCompositingManagerRunning());
2874
2875- m_screenInfo = new ScreenInfo(ScreenInfo::TopLeft, this);
2876-
2877- connect(&launcher2dConfiguration(), SIGNAL(superKeyEnableChanged(bool)), SLOT(updateSuperKeyMonitoring()));
2878- updateSuperKeyMonitoring();
2879-
2880- /* Super tap shows the dash, super held shows the launcher hints */
2881- m_superHotModifier = KeyboardModifiersMonitor::instance()->getHotModifierFor(Qt::MetaModifier);
2882- connect(m_superHotModifier, SIGNAL(tapped()), SLOT(toggleDash()));
2883- connect(m_superHotModifier, SIGNAL(heldChanged(bool)), SIGNAL(superKeyHeldChanged(bool)));
2884-
2885- /* Alt tap shows the HUD */
2886- m_altHotModifier = KeyboardModifiersMonitor::instance()->getHotModifierFor(Qt::AltModifier);
2887- connect(m_altHotModifier, SIGNAL(tapped()), SIGNAL(toggleHud()));
2888-
2889- /* Alt+F1 reveal the launcher and gives the keyboard focus to the Dash Button. */
2890- Hotkey* altF1 = HotkeyMonitor::instance().getHotkeyFor(Qt::Key_F1, Qt::AltModifier);
2891- connect(altF1, SIGNAL(pressed()), SLOT(onAltF1Pressed()));
2892-
2893- /* Alt+F2 shows the dash with the commands lens activated. */
2894- Hotkey* altF2 = HotkeyMonitor::instance().getHotkeyFor(Qt::Key_F2, Qt::AltModifier);
2895- connect(altF2, SIGNAL(pressed()), SLOT(showCommandsLens()));
2896-
2897- /* Super+{n} for 0 ≀ n ≀ 9 activates the item with index (n + 9) % 10. */
2898- for (Qt::Key key = Qt::Key_0; key <= Qt::Key_9; key = (Qt::Key) (key + 1)) {
2899- Hotkey* hotkey = HotkeyMonitor::instance().getHotkeyFor(key, Qt::MetaModifier);
2900- connect(hotkey, SIGNAL(pressed()), SLOT(forwardNumericHotkey()));
2901- hotkey = HotkeyMonitor::instance().getHotkeyFor(key, Qt::MetaModifier | Qt::ShiftModifier);
2902- connect(hotkey, SIGNAL(pressed()), SLOT(forwardNumericHotkey()));
2903- }
2904+ m_screenInfo = new ScreenInfo(screen, this);
2905
2906 connect(m_screenInfo, SIGNAL(availableGeometryChanged(QRect)), SLOT(updateShellPosition()));
2907 updateShellPosition();
2908-
2909- // FIXME: we need to use a queued connection here otherwise QConf will deadlock for some reason
2910- // when we read any property from the slot (which we need to do). We need to check why this
2911- // happens and report a bug to dconf-qt to get it fixed.
2912- connect(&unity2dConfiguration(), SIGNAL(formFactorChanged(QString)),
2913- SLOT(updateDashAlwaysFullScreen()), Qt::QueuedConnection);
2914- connect(QApplication::desktop(), SIGNAL(resized(int)), SLOT(updateDashAlwaysFullScreen()));
2915-
2916- updateDashAlwaysFullScreen();
2917 }
2918
2919 void
2920@@ -147,7 +98,6 @@
2921 ShellDeclarativeView::focusOutEvent(QFocusEvent* event)
2922 {
2923 Unity2DDeclarativeView::focusOutEvent(event);
2924- setDashActive(false);
2925 Q_EMIT focusChanged();
2926 }
2927
2928@@ -177,6 +127,17 @@
2929 Unity2DDeclarativeView::resizeEvent(event);
2930 }
2931
2932+
2933+void ShellDeclarativeView::forceActivateWindow()
2934+{
2935+ m_manager->forceActivateShell(this);
2936+}
2937+
2938+void ShellDeclarativeView::forceDeactivateWindow()
2939+{
2940+ m_manager->forceDeactivateShell(this);
2941+}
2942+
2943 void
2944 ShellDeclarativeView::setWMFlags()
2945 {
2946@@ -200,181 +161,21 @@
2947 /* Note that this has to be called everytime the window is shown, as the WM
2948 will remove the flags when the window is hidden */
2949 setWMFlags();
2950-}
2951-
2952-void
2953-ShellDeclarativeView::setDashActive(bool value)
2954-{
2955- if (value != m_active) {
2956- m_active = value;
2957- Q_EMIT dashActiveChanged(m_active);
2958- }
2959-}
2960-
2961-bool
2962-ShellDeclarativeView::dashActive() const
2963-{
2964- return m_active;
2965-}
2966-
2967-bool
2968-ShellDeclarativeView::haveCustomHomeShortcuts() const
2969-{
2970- return QFileInfo(unity2dDirectory() + "/shell/dash/HomeShortcutsCustomized.qml").exists();
2971-}
2972-
2973-void
2974-ShellDeclarativeView::setDashMode(ShellDeclarativeView::DashMode mode)
2975-{
2976- if (m_mode == mode) {
2977- return;
2978- }
2979-
2980- m_mode = mode;
2981- dashModeChanged(m_mode);
2982-}
2983-
2984-ShellDeclarativeView::DashMode
2985-ShellDeclarativeView::dashMode() const
2986-{
2987- return m_mode;
2988-}
2989-
2990-void
2991-ShellDeclarativeView::setExpanded(bool value)
2992-{
2993- if (m_expanded == value) {
2994- return;
2995- }
2996-
2997- m_expanded = value;
2998- expandedChanged(m_expanded);
2999-}
3000-
3001-bool
3002-ShellDeclarativeView::expanded() const
3003-{
3004- return m_expanded;
3005-}
3006-
3007-bool ShellDeclarativeView::dashAlwaysFullScreen() const
3008-{
3009- return m_dashAlwaysFullScreen;
3010-}
3011-
3012-void
3013-ShellDeclarativeView::setActiveLens(const QString& activeLens)
3014-{
3015- if (activeLens != m_activeLens) {
3016- m_activeLens = activeLens;
3017- Q_EMIT activeLensChanged(activeLens);
3018- }
3019-}
3020-
3021-const QString&
3022-ShellDeclarativeView::activeLens() const
3023-{
3024- return m_activeLens;
3025-}
3026-
3027-void
3028-ShellDeclarativeView::toggleDash()
3029-{
3030- if (dashActive()) {
3031- setDashActive(false);
3032- forceDeactivateWindow();
3033- } else {
3034- Q_EMIT activateHome();
3035- }
3036-}
3037-
3038-void
3039-ShellDeclarativeView::showCommandsLens()
3040-{
3041- Q_EMIT activateLens(COMMANDS_LENS_ID);
3042-}
3043-
3044-void
3045-ShellDeclarativeView::onAltF1Pressed()
3046+ if (source().isEmpty()) {
3047+ QMap<const char*, QVariant> rootObjectProperties;
3048+ rootObjectProperties.insert("declarativeView", QVariant::fromValue(this));
3049+ setSource(m_sourceFileUrl, rootObjectProperties);
3050+ }
3051+}
3052+
3053+void
3054+ShellDeclarativeView::toggleLauncher()
3055 {
3056 if (!isActiveWindow()) {
3057 forceActivateWindow();
3058 Q_EMIT launcherFocusRequested();
3059 } else {
3060- if (dashActive()) {
3061- // focus the launcher instead of the dash
3062- setDashActive(false);
3063- Q_EMIT launcherFocusRequested();
3064- } else {
3065- // we assume that the launcher is focused; unfocus it by deactivating the shell window
3066- forceDeactivateWindow();
3067- }
3068- }
3069-}
3070-
3071-static QSize minimumSizeForDesktop()
3072-{
3073- return QSize(DASH_MIN_SCREEN_WIDTH, DASH_MIN_SCREEN_HEIGHT);
3074-}
3075-
3076-void ShellDeclarativeView::updateDashAlwaysFullScreen()
3077-{
3078- bool dashAlwaysFullScreen;
3079- if (unity2dConfiguration().property("formFactor").toString() != "desktop") {
3080- dashAlwaysFullScreen = true;
3081- } else {
3082- const QRect rect = m_screenInfo->geometry();
3083- const QSize minSize = minimumSizeForDesktop();
3084- dashAlwaysFullScreen = rect.width() < minSize.width() && rect.height() < minSize.height();
3085- }
3086-
3087- if (m_dashAlwaysFullScreen != dashAlwaysFullScreen) {
3088- m_dashAlwaysFullScreen = dashAlwaysFullScreen;
3089- Q_EMIT dashAlwaysFullScreenChanged(dashAlwaysFullScreen);
3090- }
3091-}
3092-
3093-void
3094-ShellDeclarativeView::updateSuperKeyMonitoring()
3095-{
3096- KeyboardModifiersMonitor *modifiersMonitor = KeyboardModifiersMonitor::instance();
3097- HotkeyMonitor& hotkeyMonitor = HotkeyMonitor::instance();
3098-
3099- QVariant value = launcher2dConfiguration().property("superKeyEnable");
3100- if (!value.isValid() || value.toBool() == true) {
3101- hotkeyMonitor.enableModifiers(Qt::MetaModifier);
3102- modifiersMonitor->enableModifiers(Qt::MetaModifier);
3103- } else {
3104- hotkeyMonitor.disableModifiers(Qt::MetaModifier);
3105- modifiersMonitor->disableModifiers(Qt::MetaModifier);
3106- }
3107-}
3108-
3109-void
3110-ShellDeclarativeView::forwardNumericHotkey()
3111-{
3112- Hotkey* hotkey = qobject_cast<Hotkey*>(sender());
3113- if (hotkey != NULL) {
3114- /* Shortcuts from 1 to 9 should activate the items with index
3115- from 1 to 9 (index 0 being the so-called "BFB" or Dash launcher).
3116- Shortcut for 0 should activate item with index 10.
3117- In other words, the indexes are activated in the same order as
3118- the keys appear on a standard keyboard. */
3119- Qt::Key key = hotkey->key();
3120- if (key >= Qt::Key_1 && key <= Qt::Key_9) {
3121- int index = key - Qt::Key_0;
3122- if (hotkey->modifiers() & Qt::ShiftModifier) {
3123- Q_EMIT newInstanceShortcutPressed(index);
3124- } else {
3125- Q_EMIT activateShortcutPressed(index);
3126- }
3127- } else if (key == Qt::Key_0) {
3128- if (hotkey->modifiers() & Qt::ShiftModifier) {
3129- Q_EMIT newInstanceShortcutPressed(10);
3130- } else {
3131- Q_EMIT activateShortcutPressed(10);
3132- }
3133- }
3134+ forceDeactivateWindow();
3135 }
3136 }
3137
3138@@ -450,9 +251,3 @@
3139 {
3140 return m_monitoredAreaContainsMouse;
3141 }
3142-
3143-bool
3144-ShellDeclarativeView::superKeyHeld() const
3145-{
3146- return m_superHotModifier->held();
3147-}
3148
3149=== modified file 'shell/app/shelldeclarativeview.h'
3150--- shell/app/shelldeclarativeview.h 2012-03-05 13:59:50 +0000
3151+++ shell/app/shelldeclarativeview.h 2012-03-14 15:11:22 +0000
3152@@ -27,21 +27,14 @@
3153 class LauncherClient;
3154 class ShellDBus;
3155 class ScreenInfo;
3156-class HotModifier;
3157+class Hotkey;
3158+class ShellManager;
3159
3160 class ShellDeclarativeView : public Unity2DDeclarativeView, public AbstractX11EventFilter
3161 {
3162 Q_OBJECT
3163- Q_ENUMS(DashMode)
3164
3165- Q_PROPERTY(bool dashActive READ dashActive WRITE setDashActive NOTIFY dashActiveChanged)
3166- Q_PROPERTY(bool expanded READ expanded WRITE setExpanded NOTIFY expandedChanged)
3167- Q_PROPERTY(DashMode dashMode READ dashMode WRITE setDashMode NOTIFY dashModeChanged)
3168- Q_PROPERTY(QString activeLens READ activeLens WRITE setActiveLens NOTIFY activeLensChanged)
3169 Q_PROPERTY(bool focus READ hasFocus NOTIFY focusChanged) // overridden to add notify
3170- Q_PROPERTY(bool dashAlwaysFullScreen READ dashAlwaysFullScreen NOTIFY dashAlwaysFullScreenChanged)
3171- Q_PROPERTY(bool superKeyHeld READ superKeyHeld NOTIFY superKeyHeldChanged)
3172- Q_PROPERTY(bool haveCustomHomeShortcuts READ haveCustomHomeShortcuts)
3173
3174 /* These two properties and mouse movement tracking on the widget are added here only because
3175 we need to detect when the mouse is inside the area occupied by the lancher. This should
3176@@ -54,60 +47,31 @@
3177 NOTIFY monitoredAreaContainsMouseChanged)
3178
3179 public:
3180- enum DashMode {
3181- DesktopMode,
3182- FullScreenMode
3183- };
3184- explicit ShellDeclarativeView();
3185+ ShellDeclarativeView(ShellManager *manager, const QUrl &sourceFileUrl, int screen);
3186
3187 /* getters */
3188- bool dashActive() const;
3189- bool haveCustomHomeShortcuts() const;
3190- DashMode dashMode() const;
3191- const QString& activeLens() const;
3192- bool expanded() const;
3193- bool superKeyHeld() const;
3194- bool dashAlwaysFullScreen() const;
3195 QRect monitoredArea() const;
3196 bool monitoredAreaContainsMouse() const;
3197
3198 /* setters */
3199- Q_SLOT void setDashActive(bool active);
3200- Q_INVOKABLE void setDashMode(DashMode);
3201- Q_INVOKABLE void setActiveLens(const QString& activeLens);
3202- Q_INVOKABLE void setExpanded(bool);
3203 void setMonitoredArea(QRect monitoredArea);
3204
3205 virtual bool x11EventFilter(XEvent* event);
3206
3207+ void toggleLauncher();
3208+
3209+ Q_INVOKABLE void forceActivateWindow();
3210+ Q_INVOKABLE void forceDeactivateWindow();
3211+
3212 Q_SIGNALS:
3213- void dashActiveChanged(bool);
3214- void dashModeChanged(DashMode);
3215- void expandedChanged(bool);
3216- void activeLensChanged(const QString&);
3217- void activateLens(const QString& lensId);
3218- void activateHome();
3219- void toggleHud();
3220 void focusChanged();
3221 void monitoredAreaChanged();
3222 void monitoredAreaContainsMouseChanged();
3223
3224- void dashAlwaysFullScreenChanged(bool dashAlwaysFullScreen);
3225- void superKeyHeldChanged(bool superKeyHeld);
3226 void activateShortcutPressed(int itemIndex);
3227 void newInstanceShortcutPressed(int itemIndex);
3228 void launcherFocusRequested();
3229
3230-private Q_SLOTS:
3231- void updateSuperKeyMonitoring();
3232- void forwardNumericHotkey();
3233-
3234- void toggleDash();
3235- void showCommandsLens();
3236- void onAltF1Pressed();
3237-
3238- void updateDashAlwaysFullScreen();
3239-
3240 protected:
3241 virtual void showEvent(QShowEvent *event);
3242 virtual void mouseMoveEvent(QMouseEvent *event);
3243@@ -123,19 +87,12 @@
3244 void setWMFlags();
3245 void updateInputShape();
3246
3247- DashMode m_mode;
3248- bool m_expanded;
3249- QString m_activeLens; /* Lens id of the active lens */
3250- bool m_active;
3251-
3252- bool m_dashAlwaysFullScreen;
3253 QRect m_monitoredArea;
3254 bool m_monitoredAreaContainsMouse;
3255-
3256- HotModifier* m_superHotModifier;
3257- HotModifier* m_altHotModifier;
3258-
3259- friend class DashDBus;
3260+ QUrl m_sourceFileUrl;
3261+ ShellManager *m_manager;
3262+
3263+ friend class ShellManager;
3264 };
3265
3266 Q_DECLARE_METATYPE(ShellDeclarativeView*)
3267
3268=== added file 'shell/app/shellmanager.cpp'
3269--- shell/app/shellmanager.cpp 1970-01-01 00:00:00 +0000
3270+++ shell/app/shellmanager.cpp 2012-03-14 15:11:22 +0000
3271@@ -0,0 +1,683 @@
3272+/*
3273+ * This file is part of unity-2d
3274+ *
3275+ * Copyright 2010 Canonical Ltd.
3276+ *
3277+ * This program is free software; you can redistribute it and/or modify
3278+ * it under the terms of the GNU General Public License as published by
3279+ * the Free Software Foundation; version 3.
3280+ *
3281+ * This program is distributed in the hope that it will be useful,
3282+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3283+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3284+ * GNU General Public License for more details.
3285+ *
3286+ * You should have received a copy of the GNU General Public License
3287+ * along with this program. If not, see <http://www.gnu.org/licenses/>
3288+ */
3289+
3290+#include "shellmanager.h"
3291+
3292+// Qt
3293+#include <QApplication>
3294+#include <QDebug>
3295+#include <QtDeclarative>
3296+#include <QDesktopWidget>
3297+#include <QX11Info>
3298+
3299+// libunity-2d-private
3300+#include <debug_p.h>
3301+#include <hotmodifier.h>
3302+#include <hotkeymonitor.h>
3303+#include <hotkey.h>
3304+#include <keyboardmodifiersmonitor.h>
3305+#include <keymonitor.h>
3306+#include <screeninfo.h>
3307+
3308+// Local
3309+#include "shelldeclarativeview.h"
3310+#include "config.h"
3311+
3312+// unity-2d
3313+#include <unity2ddebug.h>
3314+#include <gobjectcallback.h>
3315+
3316+// bamf
3317+#include "bamf-window.h"
3318+#include "bamf-matcher.h"
3319+
3320+// libwnck
3321+extern "C" {
3322+#define WNCK_I_KNOW_THIS_IS_UNSTABLE
3323+#include <libwnck/libwnck.h>
3324+}
3325+
3326+static const char* COMMANDS_LENS_ID = "commands.lens";
3327+static const int DASH_MIN_SCREEN_WIDTH = 1280;
3328+static const int DASH_MIN_SCREEN_HEIGHT = 1084;
3329+
3330+GOBJECT_CALLBACK1(activeWorkspaceChangedCB, "onActiveWorkspaceChanged");
3331+
3332+struct ShellManagerPrivate
3333+{
3334+ ShellManagerPrivate()
3335+ : q(NULL)
3336+ , m_shellWithDash(NULL)
3337+ , m_shellWithHud(NULL)
3338+ , m_hudLoader(NULL)
3339+ , m_dashAlwaysFullScreen(false)
3340+ , m_dashActive(false)
3341+ , m_dashMode(ShellManager::DesktopMode)
3342+ , m_superHotModifier(NULL)
3343+ , m_last_focused_window(None)
3344+ {}
3345+
3346+ enum ActiveShellUsage {
3347+ ActiveShellGeneralUse,
3348+ ActiveShellLauncherRelatedUse
3349+ };
3350+
3351+ ShellDeclarativeView* initShell(int screen);
3352+ void updateScreenCount(int newCount);
3353+ ShellDeclarativeView* activeShell(ActiveShellUsage usage) const;
3354+ void moveDashToShell(ShellDeclarativeView* newShell);
3355+ void moveHudToShell(ShellDeclarativeView* newShell);
3356+ void saveActiveWindow();
3357+
3358+ ShellManager *q;
3359+ QList<ShellDeclarativeView *> m_viewList;
3360+ ShellDeclarativeView * m_shellWithDash;
3361+ ShellDeclarativeView * m_shellWithHud;
3362+ QDeclarativeItem* m_hudLoader;
3363+ bool m_dashAlwaysFullScreen;
3364+ QUrl m_sourceFileUrl;
3365+ bool m_dashActive;
3366+ ShellManager::DashMode m_dashMode;
3367+ QString m_dashActiveLens; /* Lens id of the active lens */
3368+
3369+ HotModifier* m_superHotModifier;
3370+ HotModifier* m_altHotModifier;
3371+
3372+ WId m_last_focused_window;
3373+};
3374+
3375+
3376+ShellDeclarativeView *
3377+ShellManagerPrivate::initShell(int screen)
3378+{
3379+ const QStringList arguments = qApp->arguments();
3380+ ShellDeclarativeView * view = new ShellDeclarativeView(q, m_sourceFileUrl, screen);
3381+ view->setAccessibleName("Shell");
3382+ if (arguments.contains("-opengl")) {
3383+ view->setUseOpenGL(true);
3384+ }
3385+
3386+ Unity2dApplication::instance()->installX11EventFilter(view);
3387+
3388+ view->engine()->addImportPath(unity2dImportPath());
3389+ view->engine()->setBaseUrl(QUrl::fromLocalFile(unity2dDirectory() + "/shell/"));
3390+
3391+ view->rootContext()->setContextProperty("shellManager", q);
3392+
3393+ view->show();
3394+
3395+ return view;
3396+}
3397+
3398+ShellDeclarativeView *
3399+ShellManagerPrivate::activeShell(ActiveShellUsage usage) const
3400+{
3401+ bool launcherOnlyInOneScreen = launcher2dConfiguration().property("onlyOneLauncher").toBool();
3402+ if (usage == ActiveShellLauncherRelatedUse && launcherOnlyInOneScreen) {
3403+ return m_viewList.isEmpty() ? NULL : m_viewList[0];
3404+ }
3405+
3406+ int cursorScreen = QApplication::desktop()->screenNumber(QCursor::pos());
3407+ Q_FOREACH(ShellDeclarativeView * shell, m_viewList) {
3408+ if (shell->screen()->screen() == cursorScreen) {
3409+ return shell;
3410+ }
3411+ }
3412+ return 0;
3413+}
3414+
3415+void
3416+ShellManagerPrivate::updateScreenCount(int newCount)
3417+{
3418+ const int previousCount = m_viewList.size();
3419+
3420+ /* Instantiate new Shells as needed. */
3421+ for (int screen = previousCount; screen < newCount; ++screen) {
3422+ ShellDeclarativeView *shell = initShell(screen);
3423+ m_viewList.append(shell);
3424+
3425+ if (screen == 0) {
3426+ m_shellWithDash = m_viewList[0];
3427+ Q_EMIT q->dashShellChanged(m_shellWithDash);
3428+ Q_EMIT q->dashScreenChanged(q->dashScreen());
3429+
3430+ m_shellWithHud = m_viewList[0];
3431+ Q_EMIT q->hudShellChanged(m_shellWithHud);
3432+ Q_EMIT q->hudScreenChanged(q->hudScreen());
3433+
3434+ m_hudLoader = qobject_cast<QDeclarativeItem*>(m_shellWithHud->rootObject()->property("hudLoader").value<QObject *>());
3435+ if (m_hudLoader != NULL) {
3436+ QObject::connect(m_hudLoader, SIGNAL(activeChanged()), q, SIGNAL(hudActiveChanged()));
3437+ } else {
3438+ qWarning() << "Could not find the hudLoader";
3439+ }
3440+ }
3441+ }
3442+
3443+ /* Remove extra Shells if any. */
3444+ while (m_viewList.size() > newCount) {
3445+ ShellDeclarativeView *shell = m_viewList.takeLast();
3446+ if (shell == m_shellWithDash) {
3447+ if (newCount > 0) {
3448+ moveDashToShell(m_viewList[0]);
3449+ } else {
3450+ m_shellWithDash = NULL;
3451+ Q_EMIT q->dashShellChanged(NULL);
3452+ Q_EMIT q->dashScreenChanged(-1);
3453+ }
3454+ }
3455+ if (shell == m_shellWithHud) {
3456+ if (newCount > 0) {
3457+ moveHudToShell(m_viewList[0]);
3458+ } else {
3459+ m_shellWithHud = NULL;
3460+ Q_EMIT q->hudShellChanged(NULL);
3461+ Q_EMIT q->hudScreenChanged(-1);
3462+ }
3463+ }
3464+ shell->deleteLater();
3465+ }
3466+
3467+}
3468+
3469+static QList<QDeclarativeItem *> dumpFocusedItems(QObject *obj) {
3470+ QList<QDeclarativeItem *> res;
3471+ QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(obj);
3472+ if (item && item->hasFocus()) {
3473+ res << item;
3474+ }
3475+ Q_FOREACH (QObject *childObj, obj->children()) {
3476+ res += dumpFocusedItems(childObj);
3477+ }
3478+ return res;
3479+}
3480+
3481+static bool moveRootChildItemToShell(const char *itemName, ShellDeclarativeView* newShell, ShellDeclarativeView* oldShell)
3482+{
3483+ bool itemMoved = false;
3484+
3485+ if (newShell != oldShell) {
3486+ QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(oldShell->rootObject()->property(itemName).value<QObject *>());
3487+ if (item) {
3488+ const QGraphicsView::ViewportUpdateMode oldShellViewportUpdateMode = oldShell->viewportUpdateMode();
3489+ const QGraphicsView::ViewportUpdateMode newShellViewportUpdateMode = newShell->viewportUpdateMode();
3490+ oldShell->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
3491+ newShell->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
3492+
3493+ // Moving the item around makes it lose its focus values, remember them and set them later
3494+ const QList<QDeclarativeItem *> itemChildrenFocusedItems = dumpFocusedItems(item);
3495+
3496+ oldShell->rootObject()->setProperty(itemName, QVariant());
3497+ oldShell->scene()->removeItem(item);
3498+
3499+ item->setParentItem(qobject_cast<QDeclarativeItem*>(newShell->rootObject()));
3500+ newShell->rootObject()->setProperty(itemName, QVariant::fromValue<QObject*>(item));
3501+
3502+ Q_FOREACH(QDeclarativeItem *childrenItem, itemChildrenFocusedItems) {
3503+ childrenItem->setFocus(true);
3504+ }
3505+
3506+ oldShell->setViewportUpdateMode(oldShellViewportUpdateMode);
3507+ newShell->setViewportUpdateMode(newShellViewportUpdateMode);
3508+
3509+ itemMoved = true;
3510+ } else {
3511+ qWarning() << "moveRootChildItemToShell: Could not find the item" << itemName;
3512+ }
3513+ }
3514+
3515+ return itemMoved;
3516+}
3517+
3518+void ShellManagerPrivate::moveDashToShell(ShellDeclarativeView* newShell)
3519+{
3520+ if (moveRootChildItemToShell("dashLoader", newShell, m_shellWithDash)) {
3521+ m_shellWithDash = newShell;
3522+ Q_EMIT q->dashShellChanged(newShell);
3523+ Q_EMIT q->dashScreenChanged(q->dashScreen());
3524+ }
3525+}
3526+
3527+void ShellManagerPrivate::moveHudToShell(ShellDeclarativeView* newShell)
3528+{
3529+ if (moveRootChildItemToShell("hudLoader", newShell, m_shellWithHud)) {
3530+ m_shellWithHud = newShell;
3531+ Q_EMIT q->hudShellChanged(newShell);
3532+ Q_EMIT q->hudScreenChanged(q->hudScreen());
3533+ }
3534+}
3535+
3536+/* -------------------------- ShellManager -----------------------------*/
3537+
3538+ShellManager::ShellManager(const QUrl &sourceFileUrl, QObject* parent) :
3539+ QObject(parent)
3540+ ,d(new ShellManagerPrivate)
3541+{
3542+ d->q = this;
3543+ d->m_sourceFileUrl = sourceFileUrl;
3544+
3545+ qmlRegisterUncreatableType<ShellDeclarativeView>("Unity2d", 1, 0, "ShellDeclarativeView", "This can only be created from C++");
3546+ qmlRegisterUncreatableType<ShellManager>("Unity2d", 1, 0, "ShellManager", "This can only be created from C++");
3547+
3548+ QDesktopWidget* desktop = QApplication::desktop();
3549+
3550+ d->updateScreenCount(desktop->screenCount());
3551+
3552+ connect(desktop, SIGNAL(screenCountChanged(int)), SLOT(onScreenCountChanged(int)));
3553+
3554+ connect(&launcher2dConfiguration(), SIGNAL(superKeyEnableChanged(bool)), SLOT(updateSuperKeyMonitoring()));
3555+ updateSuperKeyMonitoring();
3556+
3557+ /* Super tap shows the dash, super held shows the launcher hints */
3558+ d->m_superHotModifier = KeyboardModifiersMonitor::instance()->getHotModifierFor(Qt::MetaModifier);
3559+ connect(d->m_superHotModifier, SIGNAL(tapped()), SLOT(toggleDashRequested()));
3560+ connect(d->m_superHotModifier, SIGNAL(heldChanged(bool)), SIGNAL(superKeyHeldChanged(bool)));
3561+
3562+ /* Alt tap shows the HUD */
3563+ d->m_altHotModifier = KeyboardModifiersMonitor::instance()->getHotModifierFor(Qt::AltModifier);
3564+ connect(d->m_altHotModifier, SIGNAL(tapped()), SLOT(toggleHudRequested()));
3565+
3566+ /* Alt+F1 reveals the launcher and gives the keyboard focus to the Dash Button. */
3567+ Hotkey* altF1 = HotkeyMonitor::instance().getHotkeyFor(Qt::Key_F1, Qt::AltModifier);
3568+ connect(altF1, SIGNAL(pressed()), SLOT(onAltF1Pressed()));
3569+
3570+ /* Alt+F2 shows the dash with the commands lens activated. */
3571+ Hotkey* altF2 = HotkeyMonitor::instance().getHotkeyFor(Qt::Key_F2, Qt::AltModifier);
3572+ connect(altF2, SIGNAL(pressed()), SLOT(onAltF2Pressed()));
3573+
3574+ /* Super+{n} for 0 ≀ n ≀ 9 activates the item with index (n + 9) % 10. */
3575+ for (Qt::Key key = Qt::Key_0; key <= Qt::Key_9; key = (Qt::Key) (key + 1)) {
3576+ Hotkey* hotkey = HotkeyMonitor::instance().getHotkeyFor(key, Qt::MetaModifier);
3577+ connect(hotkey, SIGNAL(pressed()), SLOT(onNumericHotkeyPressed()));
3578+ hotkey = HotkeyMonitor::instance().getHotkeyFor(key, Qt::MetaModifier | Qt::ShiftModifier);
3579+ connect(hotkey, SIGNAL(pressed()), SLOT(onNumericHotkeyPressed()));
3580+ }
3581+
3582+ // FIXME: we need to use a queued connection here otherwise QConf will deadlock for some reason
3583+ // when we read any property from the slot (which we need to do). We need to check why this
3584+ // happens and report a bug to dconf-qt to get it fixed.
3585+ connect(&unity2dConfiguration(), SIGNAL(formFactorChanged(QString)),
3586+ SLOT(updateDashAlwaysFullScreen()), Qt::QueuedConnection);
3587+ connect(this, SIGNAL(dashShellChanged(QObject *)), this, SLOT(updateDashAlwaysFullScreen()));
3588+ connect(QApplication::desktop(), SIGNAL(resized(int)), SLOT(updateDashAlwaysFullScreen()));
3589+
3590+ updateDashAlwaysFullScreen();
3591+
3592+ g_signal_connect(G_OBJECT(wnck_screen_get_default()), "active_workspace_changed", G_CALLBACK(activeWorkspaceChangedCB), this);
3593+}
3594+
3595+ShellManager::~ShellManager()
3596+{
3597+ g_signal_handlers_disconnect_by_func(G_OBJECT(wnck_screen_get_default()), gpointer(activeWorkspaceChangedCB), this);
3598+
3599+ qDeleteAll(d->m_viewList);
3600+ delete d;
3601+}
3602+
3603+void
3604+ShellManager::setDashActive(bool value)
3605+{
3606+ if (value != d->m_dashActive) {
3607+ d->m_dashActive = value;
3608+ Q_EMIT dashActiveChanged(d->m_dashActive);
3609+ }
3610+}
3611+
3612+bool
3613+ShellManager::dashActive() const
3614+{
3615+ return d->m_dashActive;
3616+}
3617+
3618+void
3619+ShellManager::setDashMode(DashMode mode)
3620+{
3621+ if (d->m_dashMode == mode) {
3622+ return;
3623+ }
3624+
3625+ d->m_dashMode = mode;
3626+ dashModeChanged(d->m_dashMode);
3627+}
3628+
3629+ShellManager::DashMode
3630+ShellManager::dashMode() const
3631+{
3632+ return d->m_dashMode;
3633+}
3634+
3635+void
3636+ShellManager::setDashActiveLens(const QString& activeLens)
3637+{
3638+ if (activeLens != d->m_dashActiveLens) {
3639+ d->m_dashActiveLens = activeLens;
3640+ Q_EMIT dashActiveLensChanged(activeLens);
3641+ }
3642+}
3643+
3644+const QString&
3645+ShellManager::dashActiveLens() const
3646+{
3647+ return d->m_dashActiveLens;
3648+}
3649+
3650+bool
3651+ShellManager::dashHaveCustomHomeShortcuts() const
3652+{
3653+ return QFileInfo(unity2dDirectory() + "/shell/dash/HomeShortcutsCustomized.qml").exists();
3654+}
3655+
3656+QObject *
3657+ShellManager::dashShell() const
3658+{
3659+ return d->m_shellWithDash;
3660+}
3661+
3662+int
3663+ShellManager::dashScreen() const
3664+{
3665+ if (d->m_shellWithDash != NULL) {
3666+ return d->m_shellWithDash->screen()->screen();
3667+ } else {
3668+ return -1;
3669+ }
3670+}
3671+
3672+bool
3673+ShellManager::dashAlwaysFullScreen() const
3674+{
3675+ return d->m_dashAlwaysFullScreen;
3676+}
3677+
3678+void
3679+ShellManager::onScreenCountChanged(int newCount)
3680+{
3681+ d->updateScreenCount(newCount);
3682+}
3683+
3684+void
3685+ShellManager::toggleDashRequested()
3686+{
3687+ ShellDeclarativeView * activeShell = d->activeShell(ShellManagerPrivate::ActiveShellLauncherRelatedUse);
3688+ if (activeShell) {
3689+ const bool differentShell = d->m_shellWithDash != activeShell;
3690+
3691+ if (dashActive() && !differentShell) {
3692+ setDashActive(false);
3693+ forceDeactivateShell(d->m_shellWithDash);
3694+ } else {
3695+ d->moveDashToShell(activeShell);
3696+ Q_EMIT dashActivateHome();
3697+ }
3698+ }
3699+}
3700+
3701+void
3702+ShellManager::toggleHudRequested()
3703+{
3704+ ShellDeclarativeView * activeShell = d->activeShell(ShellManagerPrivate::ActiveShellGeneralUse);
3705+ if (activeShell) {
3706+ const bool differentShell = d->m_shellWithHud != activeShell;
3707+
3708+ if (differentShell) {
3709+ d->moveHudToShell(activeShell);
3710+
3711+ if (!hudActive()) {
3712+ Q_EMIT toggleHud();
3713+ } else {
3714+ forceActivateShell(activeShell);
3715+ }
3716+ } else {
3717+ Q_EMIT toggleHud();
3718+ }
3719+ }
3720+}
3721+
3722+static QSize minimumSizeForDesktop()
3723+{
3724+ return QSize(DASH_MIN_SCREEN_WIDTH, DASH_MIN_SCREEN_HEIGHT);
3725+}
3726+
3727+void ShellManager::updateDashAlwaysFullScreen()
3728+{
3729+ bool dashAlwaysFullScreen;
3730+ if (unity2dConfiguration().property("formFactor").toString() != "desktop") {
3731+ dashAlwaysFullScreen = true;
3732+ } else {
3733+ const QRect rect = QApplication::desktop()->screenGeometry(d->m_shellWithDash);
3734+ const QSize minSize = minimumSizeForDesktop();
3735+ dashAlwaysFullScreen = rect.width() < minSize.width() && rect.height() < minSize.height();
3736+ }
3737+
3738+ if (d->m_dashAlwaysFullScreen != dashAlwaysFullScreen) {
3739+ d->m_dashAlwaysFullScreen = dashAlwaysFullScreen;
3740+ Q_EMIT dashAlwaysFullScreenChanged(dashAlwaysFullScreen);
3741+ }
3742+}
3743+
3744+void ShellManager::onActiveWorkspaceChanged()
3745+{
3746+ Q_EMIT activeWorkspaceChanged();
3747+ d->m_last_focused_window = None;
3748+ Q_EMIT lastFocusedWindowChanged(d->m_last_focused_window);
3749+}
3750+
3751+/* ----------------- super key handling ---------------- */
3752+
3753+void
3754+ShellManager::updateSuperKeyMonitoring()
3755+{
3756+ KeyboardModifiersMonitor *modifiersMonitor = KeyboardModifiersMonitor::instance();
3757+ HotkeyMonitor& hotkeyMonitor = HotkeyMonitor::instance();
3758+
3759+ QVariant value = launcher2dConfiguration().property("superKeyEnable");
3760+ if (!value.isValid() || value.toBool() == true) {
3761+ hotkeyMonitor.enableModifiers(Qt::MetaModifier);
3762+ modifiersMonitor->enableModifiers(Qt::MetaModifier);
3763+ } else {
3764+ hotkeyMonitor.disableModifiers(Qt::MetaModifier);
3765+ modifiersMonitor->disableModifiers(Qt::MetaModifier);
3766+ }
3767+}
3768+
3769+bool
3770+ShellManager::superKeyHeld() const
3771+{
3772+ if (d->m_superHotModifier == NULL) { // We are just initializing
3773+ return false;
3774+ }
3775+
3776+ return d->m_superHotModifier->held();
3777+}
3778+
3779+bool
3780+ShellManager::hudActive() const
3781+{
3782+ if (d->m_hudLoader == NULL) { // We are just initializing
3783+ return false;
3784+ }
3785+
3786+ return d->m_hudLoader->property("active").toBool();
3787+}
3788+
3789+void
3790+ShellManager::setHudActive(bool active)
3791+{
3792+ if (d->m_hudLoader != NULL) {
3793+ d->m_hudLoader->setProperty("active", active);
3794+ }
3795+}
3796+
3797+QObject *
3798+ShellManager::hudShell() const
3799+{
3800+ return d->m_shellWithHud;
3801+}
3802+
3803+int
3804+ShellManager::hudScreen() const
3805+{
3806+ if (d->m_shellWithHud != NULL) {
3807+ return d->m_shellWithHud->screen()->screen();
3808+ } else {
3809+ return -1;
3810+ }
3811+}
3812+
3813+/*------------------ Hotkeys Handling -----------------------*/
3814+
3815+void
3816+ShellManager::onAltF1Pressed()
3817+{
3818+ ShellDeclarativeView * activeShell = d->activeShell(ShellManagerPrivate::ActiveShellLauncherRelatedUse);
3819+ if (activeShell) {
3820+ if (dashActive()) {
3821+ // focus the launcher instead of the dash
3822+ setDashActive(false);
3823+ Q_EMIT activeShell->launcherFocusRequested();
3824+ } else {
3825+ activeShell->toggleLauncher();
3826+ }
3827+ }
3828+}
3829+
3830+void
3831+ShellManager::onAltF2Pressed()
3832+{
3833+ ShellDeclarativeView * activeShell = d->activeShell(ShellManagerPrivate::ActiveShellLauncherRelatedUse);
3834+ if (activeShell) {
3835+ d->moveDashToShell(activeShell);
3836+ Q_EMIT dashActivateLens(COMMANDS_LENS_ID);
3837+ }
3838+}
3839+
3840+void
3841+ShellManager::onNumericHotkeyPressed()
3842+{
3843+ Hotkey* hotkey = qobject_cast<Hotkey*>(sender());
3844+ if (hotkey) {
3845+ ShellDeclarativeView * activeShell = d->activeShell(ShellManagerPrivate::ActiveShellLauncherRelatedUse);
3846+ if (activeShell) {
3847+ /* Shortcuts from 1 to 9 should activate the items with index
3848+ from 1 to 9 (index 0 being the so-called "BFB" or Dash launcher).
3849+ Shortcut for 0 should activate item with index 10.
3850+ In other words, the indexes are activated in the same order as
3851+ the keys appear on a standard keyboard. */
3852+ Qt::Key key = hotkey->key();
3853+ if (key >= Qt::Key_1 && key <= Qt::Key_9) {
3854+ int index = key - Qt::Key_0;
3855+ if (hotkey->modifiers() & Qt::ShiftModifier) {
3856+ Q_EMIT activeShell->newInstanceShortcutPressed(index);
3857+ } else {
3858+ Q_EMIT activeShell->activateShortcutPressed(index);
3859+ }
3860+ } else if (key == Qt::Key_0) {
3861+ if (hotkey->modifiers() & Qt::ShiftModifier) {
3862+ Q_EMIT activeShell->newInstanceShortcutPressed(10);
3863+ } else {
3864+ Q_EMIT activeShell->activateShortcutPressed(10);
3865+ }
3866+ }
3867+ }
3868+ }
3869+}
3870+
3871+unsigned int ShellManager::lastFocusedWindow() const
3872+{
3873+ return d->m_last_focused_window;
3874+}
3875+
3876+/* Obtaining & Discarding Keyboard Focus for Window on Demand
3877+ *
3878+ * In the X world, activating a window means to give it the input (keyboard)
3879+ * focus. When a new window opens, X usually makes it active immediately.
3880+ * Clicking on a window makes it active too.
3881+ *
3882+ * Qt does not have the capability to explicitly ask the window manager to
3883+ * make an existing window active - setFocus() only forwards input focus to
3884+ * whatever QWidget you specify.
3885+ *
3886+ * De-Activating a window is not possible with X (and hence with Qt). So
3887+ * we work-around this by remembering which application is active prior to
3888+ * stealing focus, and then Re-Activating it when we're finished. This is
3889+ * not guaranteed to succeed, as previous window may have closed.
3890+ *
3891+ * The following methods deal with these tasks. Note that when the window
3892+ * has been activated (deactivated), Qt will realise it has obtained (lost)
3893+ * focus and act appropriately.
3894+ */
3895+
3896+/* Save WId of window with keyboard focus to m_last_focused_window */
3897+void ShellManagerPrivate::saveActiveWindow()
3898+{
3899+ /* Using Bamf here, 'cause XGetFocusInputFocus returned a XId
3900+ different by 1, which then could not be used with Bamf to
3901+ get the application. The change does not result in any functional
3902+ differences, though. */
3903+ const BamfWindow* bamf_active_window = BamfMatcher::get_default().active_window();
3904+
3905+ /* Bamf can return a null active window - example case is just after
3906+ login when no application has been yet been started. */
3907+ const WId active_window = bamf_active_window != NULL ? bamf_active_window->xid() : None;
3908+
3909+ bool notAShell = true;
3910+ Q_FOREACH(ShellDeclarativeView * shell, m_viewList) {
3911+ notAShell = notAShell && active_window != shell->effectiveWinId();
3912+ }
3913+
3914+ if (notAShell && active_window != m_last_focused_window) {
3915+ m_last_focused_window = active_window;
3916+ Q_EMIT q->lastFocusedWindowChanged(m_last_focused_window);
3917+ }
3918+}
3919+
3920+/* Ask Window Manager to activate this window and hence get keyboard focus */
3921+void ShellManager::forceActivateShell(ShellDeclarativeView *shell)
3922+{
3923+ // Save reference to window with current keyboard focus
3924+ if( d->m_last_focused_window == None ){
3925+ d->saveActiveWindow();
3926+ }
3927+
3928+ // Show this window by giving it keyboard focus
3929+ Unity2DDeclarativeView::forceActivateWindow(shell->effectiveWinId(), shell);
3930+}
3931+
3932+/* Ask Window Manager to deactivate this window - not guaranteed to succeed. */
3933+void ShellManager::forceDeactivateShell(ShellDeclarativeView *shell)
3934+{
3935+ if( d->m_last_focused_window == None ){
3936+ UQ_WARNING << "No previously focused window found, use mouse to select window.";
3937+ return;
3938+ }
3939+
3940+ // What if previously focused window closed while we we had focus? Check if window
3941+ // exists by seeing if it has attributes.
3942+ XWindowAttributes attributes;
3943+ const int status = XGetWindowAttributes(QX11Info::display(), d->m_last_focused_window, &attributes);
3944+ if ( status == BadWindow ){
3945+ UQ_WARNING << "Previously focused window has gone, use mouse to select window.";
3946+ return;
3947+ }
3948+
3949+ // Show this window by giving it keyboard focus
3950+ Unity2DDeclarativeView::forceActivateWindow(d->m_last_focused_window);
3951+
3952+ d->m_last_focused_window = None;
3953+ Q_EMIT lastFocusedWindowChanged(d->m_last_focused_window);
3954+}
3955
3956=== added file 'shell/app/shellmanager.h'
3957--- shell/app/shellmanager.h 1970-01-01 00:00:00 +0000
3958+++ shell/app/shellmanager.h 2012-03-14 15:11:22 +0000
3959@@ -0,0 +1,128 @@
3960+/*
3961+ * This file is part of unity-2d
3962+ *
3963+ * Copyright 2010 Canonical Ltd.
3964+ *
3965+ * This program is free software; you can redistribute it and/or modify
3966+ * it under the terms of the GNU General Public License as published by
3967+ * the Free Software Foundation; version 3.
3968+ *
3969+ * This program is distributed in the hope that it will be useful,
3970+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3971+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3972+ * GNU General Public License for more details.
3973+ *
3974+ * You should have received a copy of the GNU General Public License
3975+ * along with this program. If not, see <http://www.gnu.org/licenses/>
3976+ */
3977+#ifndef SHELLMANAGER_H
3978+#define SHELLMANAGER_H
3979+
3980+#include <QObject>
3981+struct ShellManagerPrivate;
3982+
3983+class ShellDeclarativeView;
3984+
3985+class QUrl;
3986+
3987+class ShellManager : public QObject
3988+{
3989+ Q_OBJECT
3990+
3991+ Q_ENUMS(DashMode)
3992+
3993+ Q_PROPERTY(bool dashActive READ dashActive WRITE setDashActive NOTIFY dashActiveChanged)
3994+ Q_PROPERTY(DashMode dashMode READ dashMode WRITE setDashMode NOTIFY dashModeChanged)
3995+ Q_PROPERTY(QString dashActiveLens READ dashActiveLens WRITE setDashActiveLens NOTIFY dashActiveLensChanged)
3996+ Q_PROPERTY(bool dashHaveCustomHomeShortcuts READ dashHaveCustomHomeShortcuts)
3997+ Q_PROPERTY(QObject *dashShell READ dashShell NOTIFY dashShellChanged)
3998+ Q_PROPERTY(int dashScreen READ dashScreen NOTIFY dashScreenChanged)
3999+ Q_PROPERTY(bool dashAlwaysFullScreen READ dashAlwaysFullScreen NOTIFY dashAlwaysFullScreenChanged)
4000+ Q_PROPERTY(bool superKeyHeld READ superKeyHeld NOTIFY superKeyHeldChanged)
4001+ Q_PROPERTY(bool hudActive READ hudActive WRITE setHudActive NOTIFY hudActiveChanged)
4002+ Q_PROPERTY(QObject *hudShell READ hudShell NOTIFY hudShellChanged)
4003+ Q_PROPERTY(int hudScreen READ hudScreen NOTIFY hudScreenChanged)
4004+ Q_PROPERTY(unsigned int lastFocusedWindow READ lastFocusedWindow NOTIFY lastFocusedWindowChanged)
4005+
4006+public:
4007+ enum DashMode {
4008+ DesktopMode,
4009+ FullScreenMode
4010+ };
4011+
4012+ ShellManager(const QUrl &sourceFileUrl, QObject* parent = 0);
4013+ ~ShellManager();
4014+
4015+ bool dashActive() const;
4016+ Q_SLOT void setDashActive(bool active);
4017+
4018+ DashMode dashMode() const;
4019+ Q_INVOKABLE void setDashMode(DashMode);
4020+
4021+ const QString& dashActiveLens() const;
4022+ Q_INVOKABLE void setDashActiveLens(const QString& activeLens);
4023+
4024+ bool dashHaveCustomHomeShortcuts() const;
4025+
4026+ QObject *dashShell() const;
4027+
4028+ int dashScreen() const;
4029+
4030+ bool dashAlwaysFullScreen() const;
4031+
4032+ bool superKeyHeld() const;
4033+
4034+ bool hudActive() const;
4035+ void setHudActive(bool active);
4036+
4037+ QObject *hudShell() const;
4038+
4039+ int hudScreen() const;
4040+
4041+ unsigned int lastFocusedWindow() const;
4042+
4043+ void forceActivateShell(ShellDeclarativeView *shell);
4044+ void forceDeactivateShell(ShellDeclarativeView *shell);
4045+
4046+Q_SIGNALS:
4047+ void dashActiveChanged(bool);
4048+ void dashModeChanged(DashMode);
4049+ void dashActiveLensChanged(const QString&);
4050+ void dashShellChanged(QObject *shell);
4051+ void dashScreenChanged(int screen);
4052+ void dashAlwaysFullScreenChanged(bool dashAlwaysFullScreen);
4053+ void superKeyHeldChanged(bool superKeyHeld);
4054+ void hudActiveChanged();
4055+ void hudShellChanged(QObject *shell);
4056+ void hudScreenChanged(int screen);
4057+ void lastFocusedWindowChanged(unsigned int wid);
4058+
4059+ void activeWorkspaceChanged();
4060+ void dashActivateHome();
4061+ void dashActivateLens(const QString& lensId);
4062+ void toggleHud();
4063+
4064+private Q_SLOTS:
4065+ void onScreenCountChanged(int);
4066+
4067+ void updateSuperKeyMonitoring();
4068+
4069+ void onAltF1Pressed();
4070+ void onAltF2Pressed();
4071+ void onNumericHotkeyPressed();
4072+ void toggleDashRequested();
4073+ void toggleHudRequested();
4074+
4075+ void updateDashAlwaysFullScreen();
4076+
4077+ void onActiveWorkspaceChanged();
4078+
4079+private:
4080+ Q_DISABLE_COPY(ShellManager)
4081+ ShellManagerPrivate * const d;
4082+
4083+friend class DashDBus;
4084+friend struct ShellManagerPrivate;
4085+};
4086+
4087+#endif // SHELLMANAGER_H
4088
4089=== modified file 'shell/common/Background.qml'
4090--- shell/common/Background.qml 2012-03-13 18:54:14 +0000
4091+++ shell/common/Background.qml 2012-03-14 15:11:22 +0000
4092@@ -27,6 +27,15 @@
4093 property bool fullscreen: false
4094 property int bottomBorderThickness
4095 property int rightBorderThickness
4096+ property bool activeTriggerHelper: true
4097+ property bool reallyActive: active && activeTriggerHelper
4098+ property variant view: undefined
4099+
4100+ function trigger()
4101+ {
4102+ activeTriggerHelper = false
4103+ activeTriggerHelper = true
4104+ }
4105
4106 /* Avoid redraw at rendering */
4107 effect: CacheEffect {}
4108@@ -49,7 +58,7 @@
4109
4110 /* Use an image of the root window which essentially is a
4111 capture of the entire screen */
4112- source: active ? "image://window/root" : ""
4113+ source: reallyActive ? "image://window/root" : ""
4114 cache: false
4115
4116 fillMode: Image.PreserveAspectCrop
4117@@ -57,7 +66,8 @@
4118 /* Place the screenshot of the desktop background on top of the desktop background,
4119 no matter where the DeclarativeView or the parent object are placed.
4120 */
4121- property variant origin: parent.mapFromItem(null, -declarativeView.globalPosition.x, -declarativeView.globalPosition.y)
4122+ property variant origin: parent.mapFromItem(null, background.view != undefined ? -background.view.globalPosition.x : -declarativeView.globalPosition.x,
4123+ background.view != undefined ? -background.view.globalPosition.y : -declarativeView.globalPosition.y)
4124 x: origin.x
4125 y: origin.y
4126 }
4127
4128=== modified file 'shell/common/VisibilityController.qml'
4129--- shell/common/VisibilityController.qml 2012-02-15 11:55:06 +0000
4130+++ shell/common/VisibilityController.qml 2012-03-14 15:11:22 +0000
4131@@ -45,7 +45,7 @@
4132 var stack = controller.forceVisibleStack
4133 var wasEmpty = Utils.hashEmpty(stack)
4134
4135- if (forceHidden) console.log("WARNING: beginForceVisible for id \"" + id +
4136+ if (forceHidden) console.log("DEBUG: beginForceVisible for id \"" + id +
4137 "\" called when forceHidden still true")
4138
4139 if (stack[id]) stack[id] += 1
4140@@ -64,7 +64,7 @@
4141 if (stack[id]) {
4142 stack[id] -= 1
4143 if (stack[id] === 0) delete stack[id]
4144- } else console.log("WARNING: endForceVisible for id \"" + id +
4145+ } else console.log("DEBUG: endForceVisible for id \"" + id +
4146 "\" called without matching startForceVisible")
4147
4148 controller.forceVisibleStack = stack
4149@@ -78,7 +78,7 @@
4150 var stack = controller.forceHiddenStack
4151 var wasEmpty = Utils.hashEmpty(stack)
4152
4153- if (forceVisible) console.log("WARNING: beginForceHidden for id \"" + id +
4154+ if (forceVisible) console.log("DEBUG: beginForceHidden for id \"" + id +
4155 "\" called when forceVisible still true")
4156
4157 if (stack[id]) stack[id] += 1
4158@@ -97,7 +97,7 @@
4159 if (stack[id]) {
4160 stack[id] -= 1
4161 if (stack[id] === 0) delete stack[id]
4162- } else console.log("WARNING: endForceHidden for id \"" + id +
4163+ } else console.log("DEBUG: endForceHidden for id \"" + id +
4164 "\" called without matching startForceHidden")
4165
4166 controller.forceHiddenStack = stack
4167
4168=== modified file 'shell/common/visibilityBehaviors/IntelliHideBehavior.qml'
4169--- shell/common/visibilityBehaviors/IntelliHideBehavior.qml 2012-03-05 14:06:58 +0000
4170+++ shell/common/visibilityBehaviors/IntelliHideBehavior.qml 2012-03-14 15:11:22 +0000
4171@@ -41,12 +41,12 @@
4172 monitoredArea: {
4173 if (intellihide.target) {
4174 if (Utils.isLeftToRight()) {
4175- return Qt.rect(0,
4176+ return Qt.rect(declarativeView.screen.geometry.x,
4177 intellihide.target.y,
4178 intellihide.target.width,
4179 intellihide.target.height)
4180 } else {
4181- return Qt.rect(declarativeView.screen.availableGeometry.width - intellihide.target.width,
4182+ return Qt.rect(declarativeView.screen.geometry.x + declarativeView.screen.availableGeometry.width - intellihide.target.width,
4183 intellihide.target.y,
4184 intellihide.target.width,
4185 intellihide.target.height)
4186
4187=== modified file 'shell/dash/Dash.qml'
4188--- shell/dash/Dash.qml 2012-03-13 18:54:14 +0000
4189+++ shell/dash/Dash.qml 2012-03-14 15:11:22 +0000
4190@@ -31,48 +31,60 @@
4191 LayoutMirroring.childrenInherit: true
4192
4193 property variant currentPage
4194- /* FIXME: 'active' property exactly mirrors 'declarativeView.dashActive'.
4195+ /* FIXME: 'active' property exactly mirrors 'shellManager.dashActive'.
4196 The final goal is to transition to using exclusively the QML 'active' property
4197- and drop the C++ 'declarativeView.dashActive'.
4198+ and drop the C++ 'shellManager.dashActive'.
4199 */
4200 property variant active
4201- /* The following way of mirroring the values of 'declarativeView.dashActive'
4202+ /* The following way of mirroring the values of 'shellManager.dashActive'
4203 and 'active' works now and QML does not see it as a binding loop but we
4204 cannot count on it long term.
4205 */
4206 Binding {
4207- target: declarativeView
4208+ target: shellManager
4209 property: "dashActive"
4210 value: dash.active
4211 }
4212 Binding {
4213 target: dash
4214 property: "active"
4215- value: declarativeView.dashActive
4216- }
4217-
4218- onActiveChanged: if (dash.active) declarativeView.forceActivateWindow()
4219+ value: shellManager.dashActive
4220+ }
4221+
4222+ onActiveChanged: if (dash.active) shellManager.dashShell.forceActivateWindow()
4223+
4224+ Connections {
4225+ target: shellManager
4226+ onDashShellChanged: {
4227+ if (dash.active) {
4228+ background.trigger()
4229+ shellManager.dashShell.forceActivateWindow()
4230+ }
4231+ }
4232+ }
4233
4234 property variant queuedLensId
4235
4236- Binding {
4237- target: declarativeView
4238- property: "expanded"
4239- value: (currentPage && currentPage.expanded != undefined) ? currentPage.expanded : true
4240- }
4241+ property bool expanded: (currentPage && currentPage.expanded != undefined) ? currentPage.expanded : true
4242
4243 Binding {
4244- target: declarativeView
4245+ target: shellManager
4246 property: "dashMode"
4247- value: declarativeView.dashAlwaysFullScreen || dash2dConfiguration.fullScreen ?
4248- ShellDeclarativeView.FullScreenMode : ShellDeclarativeView.DesktopMode
4249- }
4250-
4251- Connections {
4252- target: declarativeView
4253-
4254- onActivateHome: activateHome()
4255- onActivateLens: activateLens(lensId)
4256+ value: shellManager.alwaysFullScreen || dash2dConfiguration.fullScreen ?
4257+ ShellManager.FullScreenMode : ShellManager.DesktopMode
4258+ }
4259+
4260+ Connections {
4261+ target: shellManager
4262+
4263+ onDashActivateHome: activateHome()
4264+ onDashActivateLens: activateLens(lensId)
4265+ }
4266+
4267+ Connections {
4268+ target: shellManager.dashShell
4269+
4270+ onFocusChanged: if (!shellManager.dashShell.focus) active = false
4271 }
4272
4273 function activatePage(page) {
4274@@ -103,7 +115,7 @@
4275 for (var i=0; i<lenses.rowCount(); i++) {
4276 lenses.get(i).viewType = Lens.Hidden
4277 }
4278- declarativeView.activeLens = ""
4279+ shellManager.dashActiveLens = ""
4280 }
4281
4282 SpreadMonitor {
4283@@ -125,7 +137,7 @@
4284 return
4285 }
4286
4287- if (lensId == declarativeView.activeLens && dash.active) {
4288+ if (lensId == shellManager.dashActiveLens && dash.active) {
4289 /* we don't need to activate the lens, just show its UI */
4290 buildLensPage(lens)
4291 return
4292@@ -147,13 +159,13 @@
4293 }
4294
4295 buildLensPage(lens)
4296- declarativeView.activeLens = lens.id
4297+ shellManager.dashActiveLens = lens.id
4298 dash.active = true
4299 }
4300
4301 function activateHome() {
4302 if (spreadMonitor.shown) return
4303- if (declarativeView.haveCustomHomeShortcuts) {
4304+ if (shellManager.dashHaveCustomHomeShortcuts) {
4305 for (var i=0; i<lenses.rowCount(); i++) {
4306 lenses.get(i).viewType = Lens.Hidden
4307 }
4308@@ -161,7 +173,7 @@
4309 /* Take advantage of the fact that the loaded qml is local and setting
4310 the source loads it immediately making pageLoader.item valid */
4311 activatePage(pageLoader.item)
4312- declarativeView.activeLens = ""
4313+ shellManager.dashActiveLens = ""
4314 dash.active = true
4315 } else {
4316 activateLens("home.lens")
4317@@ -222,7 +234,8 @@
4318 anchors.fill: parent
4319
4320 active: dash.active
4321- fullscreen: declarativeView.dashMode != ShellDeclarativeView.DesktopMode
4322+ fullscreen: shellManager.dashMode != ShellManager.DesktopMode
4323+ view: shellManager.dashShell
4324 }
4325
4326 Item {
4327@@ -289,7 +302,7 @@
4328 KeyNavigation.left: search_entry
4329
4330 /* FilterPane is only to be displayed for lenses, not in the home page or Alt+F2 Run page */
4331- visible: declarativeView.activeLens != "home.lens" && declarativeView.activeLens != "" && declarativeView.activeLens != "commands.lens"
4332+ visible: shellManager.dashActiveLens != "home.lens" && shellManager.dashActiveLens != "" && shellManager.dashActiveLens != "commands.lens"
4333 lens: visible && currentPage != undefined ? currentPage.model : undefined
4334
4335 anchors.top: search_entry.anchors.top
4336@@ -342,33 +355,31 @@
4337 anchors.left: parent.left
4338 anchors.right: parent.right
4339 height: 44
4340- visible: declarativeView.expanded
4341+ visible: expanded
4342 }
4343 }
4344
4345 property int desktopCollapsedHeight: 115
4346 property int desktopExpandedHeight: 615
4347 property int desktopWidth: 996
4348- property int fullscreenWidth: declarativeView.screen.availableGeometry.width
4349- property int fullscreenHeight: declarativeView.screen.availableGeometry.height
4350
4351 states: [
4352 State {
4353 name: "desktop"
4354- when: declarativeView.dashMode == ShellDeclarativeView.DesktopMode
4355+ when: shellManager.dashMode == ShellManager.DesktopMode
4356 PropertyChanges {
4357 target: dash
4358 width: desktopWidth
4359- height: declarativeView.expanded ? desktopExpandedHeight : desktopCollapsedHeight
4360+ height: expanded ? desktopExpandedHeight : desktopCollapsedHeight
4361 }
4362 },
4363 State {
4364 name: "fullscreen"
4365- when: declarativeView.dashMode == ShellDeclarativeView.FullScreenMode
4366+ when: shellManager.dashMode == ShellManager.FullScreenMode
4367 PropertyChanges {
4368 target: dash
4369- width: fullscreenWidth
4370- height: fullscreenHeight
4371+ width: shellManager.dashShell != undefined ? shellManager.dashShell.screen.panelsFreeGeometry.width : 0
4372+ height: shellManager.dashShell != undefined ? shellManager.dashShell.screen.panelsFreeGeometry.height : 0
4373 }
4374 }
4375 ]
4376
4377=== modified file 'shell/dash/Home.qml'
4378--- shell/dash/Home.qml 2012-03-05 17:20:00 +0000
4379+++ shell/dash/Home.qml 2012-03-14 15:11:22 +0000
4380@@ -89,7 +89,7 @@
4381 verticalAlignment: Text.AlignVCenter
4382 }
4383
4384- opacity: (!expanded && declarativeView.dashMode == ShellDeclarativeView.DesktopMode) ? 1 : 0
4385+ opacity: (!expanded && shellManager.dashMode == ShellManager.DesktopMode) ? 1 : 0
4386 Behavior on opacity {NumberAnimation {duration: 100}}
4387
4388 onClicked: {
4389@@ -137,7 +137,7 @@
4390 id: shortcuts
4391
4392 focus: !globalSearchActive
4393- opacity: (!globalSearchActive && (shortcutsActive || declarativeView.dashMode == ShellDeclarativeView.FullScreenMode)) ? 1 : 0
4394+ opacity: (!globalSearchActive && (shortcutsActive || shellManager.dashMode == ShellManager.FullScreenMode)) ? 1 : 0
4395 anchors.horizontalCenter: parent.horizontalCenter
4396 anchors.verticalCenter: parent.verticalCenter
4397
4398@@ -173,7 +173,7 @@
4399 source: "../common/artwork/cross.png"
4400 }
4401
4402- opacity: (expanded && declarativeView.dashMode == ShellDeclarativeView.DesktopMode) ? 1 : 0
4403+ opacity: (expanded && shellManager.dashMode == ShellManager.DesktopMode) ? 1 : 0
4404 Behavior on opacity {NumberAnimation {duration: 100}}
4405
4406 onClicked: shortcutsActive = false
4407
4408=== modified file 'shell/dash/LensBar.qml'
4409--- shell/dash/LensBar.qml 2012-03-06 13:05:19 +0000
4410+++ shell/dash/LensBar.qml 2012-03-14 15:11:22 +0000
4411@@ -108,7 +108,7 @@
4412 }
4413 active: {
4414 /* we need this in order to activate the arrow when using a custom shortcuts file */
4415- if (item.id == "home.lens" && declarativeView.activeLens == "") {
4416+ if (item.id == "home.lens" && shellManager.dashActiveLens == "") {
4417 return true
4418 }
4419 return item.viewType == Lens.LensView
4420
4421=== modified file 'shell/hud/Hud.qml'
4422--- shell/hud/Hud.qml 2012-02-24 11:55:38 +0000
4423+++ shell/hud/Hud.qml 2012-03-14 15:11:22 +0000
4424@@ -45,7 +45,7 @@
4425
4426 WindowInfo {
4427 id: activeWindow
4428- contentXid: declarativeView.lastFocusedWindow
4429+ contentXid: shellManager.lastFocusedWindow
4430 }
4431
4432 SpreadMonitor {
4433@@ -55,7 +55,7 @@
4434
4435 onActiveChanged: {
4436 if (active) {
4437- declarativeView.forceActivateWindow()
4438+ shellManager.hudShell.forceActivateWindow()
4439 resultList.focus = true
4440 } else {
4441 hudModel.endSearch
4442@@ -64,9 +64,14 @@
4443 }
4444
4445 Connections {
4446- target: declarativeView
4447+ target: shellManager
4448
4449 onToggleHud: toggleHud()
4450+ onHudShellChanged: {
4451+ if (active) {
4452+ background.trigger()
4453+ }
4454+ }
4455 }
4456
4457 Keys.onPressed: {
4458@@ -75,12 +80,12 @@
4459
4460 function toggleHud() {
4461 if (spread.shown) return
4462- if (active) declarativeView.forceDeactivateWindow()
4463+ if (active) shellManager.hudShell.forceDeactivateWindow()
4464 active = !active
4465 }
4466
4467 function executeResult(resultId) {
4468- declarativeView.forceDeactivateWindow()
4469+ shellManager.hudShell.forceDeactivateWindow()
4470 hudModel.executeResult(resultId)
4471 active = false
4472 }
4473@@ -93,6 +98,7 @@
4474 anchors.fill: parent
4475
4476 active: hud.active
4477+ view: shellManager.hudShell
4478 }
4479
4480 Item {
4481
4482=== modified file 'shell/launcher/Launcher.qml'
4483--- shell/launcher/Launcher.qml 2012-03-13 18:54:14 +0000
4484+++ shell/launcher/Launcher.qml 2012-03-14 15:11:22 +0000
4485@@ -27,31 +27,9 @@
4486
4487 signal barrierTriggered
4488
4489- property bool shown
4490 property bool showMenus: true
4491
4492 property bool containsMouse: declarativeView.monitoredAreaContainsMouse
4493- property variant barrierP1
4494- property variant barrierP2
4495- property variant barrierTriggerZoneP1
4496- property variant barrierTriggerZoneP2
4497-
4498- PointerBarrier {
4499- id: barrier
4500- triggerDirection: Utils.isLeftToRight() ? PointerBarrier.TriggerFromRight : PointerBarrier.TriggerFromLeft
4501- triggerZoneEnabled: !shown
4502- p1: barrierP1
4503- p2: barrierP2
4504- triggerZoneP1: barrierTriggerZoneP1
4505- triggerZoneP2: barrierTriggerZoneP2
4506- threshold: launcher2dConfiguration.edgeStopVelocity
4507- maxVelocityMultiplier: launcher2dConfiguration.edgeResponsiveness
4508- decayRate: launcher2dConfiguration.edgeDecayrate
4509- triggerPressure: launcher2dConfiguration.edgeRevealPressure
4510- breakPressure: launcher2dConfiguration.edgeOvercomePressure
4511-
4512- onTriggered: launcher.barrierTriggered()
4513- }
4514
4515 function hideMenu() {
4516 if (main.visibleMenu !== undefined) {
4517@@ -87,8 +65,8 @@
4518 Rectangle {
4519 Accessible.name: "background"
4520 anchors.fill: parent
4521- anchors.rightMargin: Utils.isLeftToRight() && !declarativeView.dashActive ? border.width : 0
4522- anchors.leftMargin: Utils.isRightToLeft() && !declarativeView.dashActive ? border.width : 0
4523+ anchors.rightMargin: Utils.isLeftToRight() && !border.visible ? border.width : 0
4524+ anchors.leftMargin: Utils.isRightToLeft() && !border.visible ? border.width : 0
4525 color: "black"
4526 opacity: 0.66
4527 visible: desktop.isCompositingManagerRunning
4528@@ -102,7 +80,7 @@
4529 height: parent.height
4530 anchors.right: Utils.isLeftToRight() ? parent.right : undefined
4531 anchors.left: Utils.isLeftToRight() ? undefined : parent.left
4532- visible: declarativeView.dashActive
4533+ visible: shellManager.dashActive && shellManager.dashShell == declarativeView
4534 source: "artwork/border.png"
4535 fillMode: Image.Stretch
4536 }
4537@@ -114,7 +92,7 @@
4538 height: parent.height
4539 anchors.right: Utils.isLeftToRight() ? border.anchors.right : undefined
4540 anchors.left: Utils.isLeftToRight() ? undefined : border.anchors.left
4541- visible: !declarativeView.dashActive
4542+ visible: !border.visible
4543
4544 color: "white"
4545 opacity: 0.15
4546@@ -216,7 +194,7 @@
4547
4548 BfbModel {
4549 id: bfbModel
4550- dashView: declarativeView
4551+ dashManager: shellManager
4552 }
4553
4554 ApplicationsList {
4555
4556=== modified file 'shell/launcher/LauncherItem.qml'
4557--- shell/launcher/LauncherItem.qml 2012-02-15 13:26:26 +0000
4558+++ shell/launcher/LauncherItem.qml 2012-03-14 15:11:22 +0000
4559@@ -65,6 +65,7 @@
4560 property alias urgentAnimation: urgentAnimation
4561 property bool running: false
4562 property bool active: false
4563+ property bool activeOnThisScreen: false
4564 property bool urgent: false
4565 property bool launching: false
4566 property alias interactive: mouse.enabled
4567@@ -138,7 +139,7 @@
4568 mirror: Utils.isRightToLeft()
4569
4570 source: "image://blended/%1color=%2alpha=%3"
4571- .arg("launcher/artwork/launcher_arrow_rtl.png")
4572+ .arg("launcher/artwork/launcher_arrow_" + (activeOnThisScreen ? "" : "outline_" ) + "rtl.png")
4573 .arg("lightgrey")
4574 .arg(1.0)
4575
4576
4577=== modified file 'shell/launcher/LauncherList.qml'
4578--- shell/launcher/LauncherList.qml 2012-02-24 12:48:13 +0000
4579+++ shell/launcher/LauncherList.qml 2012-03-14 15:11:22 +0000
4580@@ -93,11 +93,12 @@
4581 }
4582
4583 function updatePips() {
4584- if (item.belongsToDifferentWorkspace()) {
4585+ var windowCount = item.windowsOnCurrentWorkspaceScreen(launcher2dConfiguration.onlyOneLauncher ? -1 : declarativeView.screen.screen);
4586+ if (windowCount == 0 && item.windowCount != 0) {
4587 launcherItem.pips = 1
4588 launcherItem.pipSource = "launcher/artwork/launcher_arrow_outline_ltr.png";
4589 } else {
4590- launcherItem.pips = Math.min(item.windowCount, 3)
4591+ launcherItem.pips = Math.min(windowCount, 3)
4592 launcherItem.pipSource = ("launcher/artwork/launcher_" + ((pips <= 1) ? "arrow" : "pip") + "_ltr.png")
4593 }
4594 }
4595@@ -113,9 +114,9 @@
4596 icon: item.icon != "" ? "image://icons/" + item.icon : "image://icons/unknown"
4597 running: item.running
4598 active: item.active
4599+ activeOnThisScreen: item.activeScreen == declarativeView.screen.screen
4600 urgent: item.urgent
4601 launching: item.launching
4602- pips: Math.min(item.windowCount, 3)
4603
4604 counter: item.counter
4605 counterVisible: item.counterVisible
4606@@ -125,7 +126,7 @@
4607 emblemVisible: item.emblemVisible
4608
4609 /* Launcher of index 0 is the so-called BFB or Dash launcher */
4610- shortcutVisible: declarativeView.superKeyHeld &&
4611+ shortcutVisible: shellManager.superKeyHeld &&
4612 ((item.toString().indexOf("Application") == 0 && index > 0 && index <= 10) ||
4613 item.shortcutKey != 0)
4614 shortcutText: {
4615@@ -157,7 +158,7 @@
4616 list.visibleMenu.hide()
4617 }
4618 list.visibleMenu = item.menu
4619- item.menu.show(width - 5, declarativeView.globalPosition.y + list.y - list.contentY +
4620+ item.menu.show(declarativeView.globalPosition.x + width - 5, declarativeView.globalPosition.y + list.y - list.contentY +
4621 y + height - selectionOutlineSize / 2)
4622 }
4623
4624@@ -262,9 +263,10 @@
4625
4626 function setIconGeometry() {
4627 if (running) {
4628+ var screen = launcher2dConfiguration.onlyOneLauncher ? -1 : declarativeView.screen.screen
4629 item.setIconGeometry(x + declarativeView.globalPosition.x,
4630 y + declarativeView.globalPosition.y,
4631- width, height)
4632+ width, height, screen)
4633 }
4634 }
4635
4636@@ -304,11 +306,18 @@
4637
4638 Connections {
4639 target: item
4640- onWindowAdded: item.setIconGeometry(x + declarativeView.globalPosition.x,
4641- y + declarativeView.globalPosition.y,
4642- width, height, xid)
4643+ onWindowAdded: {
4644+ var screen = launcher2dConfiguration.onlyOneLauncher ? -1 : declarativeView.screen.screen
4645+ item.setIconGeometry(x + declarativeView.globalPosition.x,
4646+ y + declarativeView.globalPosition.y,
4647+ width, height, screen, xid)
4648+ }
4649 onWindowCountChanged: updatePips()
4650 onWindowWorkspaceChanged: updatePips()
4651+ onWindowGeometryChanged: {
4652+ updatePips()
4653+ setIconGeometry()
4654+ }
4655 /* Not all items are applications. */
4656 ignoreUnknownSignals: true
4657 }
4658@@ -353,7 +362,7 @@
4659 }
4660
4661 Connections {
4662- target: declarativeView
4663+ target: shellManager
4664 onActiveWorkspaceChanged: updatePips()
4665 }
4666 Component.onCompleted: updatePips()
4667
4668=== modified file 'shell/launcher/LauncherLoader.qml'
4669--- shell/launcher/LauncherLoader.qml 2012-03-06 18:06:03 +0000
4670+++ shell/launcher/LauncherLoader.qml 2012-03-14 15:11:22 +0000
4671@@ -22,10 +22,22 @@
4672 import "../common/utils.js" as Utils
4673
4674 Loader {
4675+ property bool onlyOneLauncher: true
4676+ property bool loadLauncher: !onlyOneLauncher || declarativeView.screen.screen == 0
4677+
4678 id: launcherLoader
4679- source: "Launcher.qml"
4680+ source: loadLauncher ? "Launcher.qml" : ""
4681 property variant visibilityController: visibilityController
4682 onLoaded: item.focus = true
4683+ property bool launcherInHideMode: Utils.clamp(launcher2dConfiguration.hideMode, 0, 2) != 0
4684+
4685+ Timer {
4686+ // FIXME We need this timer because otherwise changing from
4687+ // onlyOneLauncher to !onlyOneLauncher gets us in what seems to be a dbus deadlock
4688+ id: launcher2dConfigurationWorkaround
4689+ interval: 1
4690+ onTriggered: launcherLoader.onlyOneLauncher = launcher2dConfiguration.onlyOneLauncher
4691+ }
4692
4693 VisibilityController {
4694 id: visibilityController
4695@@ -52,7 +64,7 @@
4696 Binding {
4697 target: declarativeView
4698 property: "monitoredArea"
4699- value: Qt.rect(launcherLoader.x, launcherLoader.item.y, launcherLoader.item.width, launcherLoader.item.height)
4700+ value: loadLauncher ? Qt.rect(launcherLoader.x, launcherLoader.item.y, launcherLoader.item.width, launcherLoader.item.height) : Qt.rect(0, 0, 0, 0)
4701 when: launcherBehavior.status == Loader.Ready && !launcherLoaderXAnimation.running
4702 }
4703
4704@@ -75,16 +87,19 @@
4705 }
4706
4707 Connections {
4708- target: declarativeView
4709+ target: shellManager
4710 onSuperKeyHeldChanged: {
4711 if (superKeyHeld) visibilityController.beginForceVisible()
4712 else visibilityController.endForceVisible()
4713 }
4714 }
4715
4716- Binding {
4717- target: launcherLoader.item
4718- property: "shown"
4719- value: visibilityController.shown
4720+ Connections {
4721+ target: launcher2dConfiguration
4722+ onOnlyOneLauncherChanged: {
4723+ launcher2dConfigurationWorkaround.start()
4724+ }
4725 }
4726+
4727+ Component.onCompleted: launcherLoader.onlyOneLauncher = launcher2dConfiguration.onlyOneLauncher
4728 }
4729
4730=== modified file 'shell/launcher/ListViewDragAndDrop.qml'
4731--- shell/launcher/ListViewDragAndDrop.qml 2011-11-11 10:19:14 +0000
4732+++ shell/launcher/ListViewDragAndDrop.qml 2012-03-14 15:11:22 +0000
4733@@ -35,6 +35,8 @@
4734
4735 /* list index of the tile being dragged */
4736 property int draggedTileIndex
4737+ /* first list index of the tile being dragged */
4738+ property int firstDraggedTileIndex
4739 /* id (desktop file path) of the tile being dragged */
4740 property string draggedTileId: ""
4741 /* absolute mouse coordinates in the list */
4742@@ -65,10 +67,14 @@
4743 events for other mouse areas below, which is not desired). */
4744 var coord = mapToItem(list.contentItem, mouse.x, mouse.y)
4745 draggedTileIndex = list.indexAt(coord.x, coord.y)
4746+ firstDraggedTileIndex = draggedTileIndex
4747 longPressDelay.start()
4748 }
4749 function drop() {
4750 longPressDelay.stop()
4751+ if (draggedTileId != "" && firstDraggedTileIndex != draggedTileIndex) {
4752+ items.moveFinished(firstDraggedTileIndex, draggedTileIndex)
4753+ }
4754 draggedTileId = ""
4755 parent.interactive = true
4756 }
4757
4758=== added file 'shell/launcher/artwork/launcher_arrow_outline_rtl.png'
4759Binary files shell/launcher/artwork/launcher_arrow_outline_rtl.png 1970-01-01 00:00:00 +0000 and shell/launcher/artwork/launcher_arrow_outline_rtl.png 2012-03-14 15:11:22 +0000 differ
4760=== modified file 'spread/Workspaces.qml'
4761--- spread/Workspaces.qml 2012-03-14 15:11:21 +0000
4762+++ spread/Workspaces.qml 2012-03-14 15:11:22 +0000
4763@@ -27,6 +27,8 @@
4764
4765 signal cancelAndExitStarted ()
4766
4767+ property variant declarativeView
4768+
4769 property int columns: desktop.workspaces.columns
4770 property int rows: desktop.workspaces.rows
4771
4772
4773=== modified file 'spread/app/spreadmanager.cpp'
4774--- spread/app/spreadmanager.cpp 2012-03-14 15:11:21 +0000
4775+++ spread/app/spreadmanager.cpp 2012-03-14 15:11:22 +0000
4776@@ -33,6 +33,8 @@
4777 , m_eventGrabbingView(NULL)
4778 , m_focusedView(NULL)
4779 {
4780+ qmlRegisterUncreatableType<SpreadView>("Unity2d", 1, 0, "SpreadView", "This can only be created from C++");
4781+
4782 QDesktopWidget* desktop = QApplication::desktop();
4783
4784 onScreenCountChanged(desktop->screenCount());
4785@@ -77,11 +79,12 @@
4786 connect(view, SIGNAL(visibleChanged(bool)), this, SLOT(onViewVisibleChanged(bool)));
4787 view->rootContext()->setContextProperty("control", &m_control);
4788 view->rootContext()->setContextProperty("spreadManager", this);
4789- view->rootContext()->setContextProperty("declarativeView", view);
4790
4791 /* Load the QML UI, focus and show the window */
4792- view->setResizeMode(QDeclarativeView::SizeRootObjectToView);
4793- view->setSource(QUrl("./Workspaces.qml"));
4794+ QMap<const char*, QVariant> rootObjectProperties;
4795+ rootObjectProperties.insert("declarativeView", QVariant::fromValue(view));
4796+ view->setSource(QUrl("./Workspaces.qml"), rootObjectProperties);
4797+ view->fitToAvailableSpace();
4798
4799 connect(view->rootObject(), SIGNAL(cancelAndExitStarted()), this, SIGNAL(startCancelAndExit()));
4800
4801
4802=== modified file 'spread/app/spreadview.cpp'
4803--- spread/app/spreadview.cpp 2012-03-14 15:11:21 +0000
4804+++ spread/app/spreadview.cpp 2012-03-14 15:11:22 +0000
4805@@ -22,6 +22,7 @@
4806 #include <QDesktopWidget>
4807 #include <QApplication>
4808 #include <QMouseEvent>
4809+#include <QDeclarativeItem>
4810
4811 #include "screeninfo.h"
4812
4813@@ -29,9 +30,7 @@
4814 : Unity2DDeclarativeView()
4815 {
4816 m_screenInfo = new ScreenInfo(screen, this);
4817- connect(m_screenInfo, SIGNAL(availableGeometryChanged(QRect)), SLOT(fitToAvailableSpace()));
4818-
4819- fitToAvailableSpace();
4820+ connect(m_screenInfo, SIGNAL(panelsFreeGeometryChanged(QRect)), SLOT(fitToAvailableSpace()));
4821 }
4822
4823 void SpreadView::fitToAvailableSpace()
4824@@ -39,4 +38,9 @@
4825 QRect geometry = m_screenInfo->panelsFreeGeometry();
4826 setGeometry(geometry);
4827 setFixedSize(geometry.size());
4828+ const int width = geometry.width();
4829+ const int height = geometry.height();
4830+ rootObject()->setWidth(width);
4831+ rootObject()->setHeight(height);
4832+ setSceneRect(QRectF(0, 0, width, height));
4833 }
4834
4835=== modified file 'spread/app/spreadview.h'
4836--- spread/app/spreadview.h 2012-03-14 15:11:21 +0000
4837+++ spread/app/spreadview.h 2012-03-14 15:11:22 +0000
4838@@ -36,5 +36,7 @@
4839 void fitToAvailableSpace();
4840 };
4841
4842+Q_DECLARE_METATYPE(SpreadView*)
4843+
4844 #endif // SPREADVIEW_H
4845
4846
4847=== modified file 'tests/dash/fullscreen.rb'
4848--- tests/dash/fullscreen.rb 2012-03-12 11:21:41 +0000
4849+++ tests/dash/fullscreen.rb 2012-03-14 15:11:22 +0000
4850@@ -39,6 +39,9 @@
4851 DASH_FULLSCREEN_KEY = '/com/canonical/unity-2d/dash/full-screen'
4852 DASH_FORMFACTOR_KEY = '/com/canonical/unity-2d/form-factor'
4853
4854+ dash_desktop_width = 996
4855+ dash_fullscreen_width = XDo::XWindow.display_geometry()[0] - LAUNCHER_WIDTH
4856+
4857 # Run once at the beginning of this test suite
4858 startup do
4859 $SUT.execute_shell_command 'killall unity-2d-shell'
4860@@ -98,19 +101,19 @@
4861 sleep 1
4862
4863 verify_equal('true', TIMEOUT, 'Dash did not appear') {
4864- @shell.ShellDeclarativeView()['dashActive']
4865+ @shell.Dash()['active']
4866 }
4867
4868- expected = dash_always_fullscreen ? 'FullScreenMode' : 'DesktopMode'
4869+ expected = dash_always_fullscreen ? dash_fullscreen_width : dash_desktop_width
4870 verify_equal(expected, TIMEOUT, 'Dash is in the wrong fullscreen state') {
4871- @shell.ShellDeclarativeView()['dashMode']
4872+ @shell.Dash()['width'].to_i()
4873 }
4874
4875 $SUT.execute_shell_command "dconf write #{DASH_FULLSCREEN_KEY} true"
4876 sleep 1
4877
4878- verify_equal('FullScreenMode', TIMEOUT, 'Dash is not fullscreen but should be') {
4879- @shell.ShellDeclarativeView()['dashMode']
4880+ verify_equal(dash_fullscreen_width, TIMEOUT, 'Dash is not fullscreen but should be') {
4881+ @shell.Dash()['width'].to_i()
4882 }
4883 end
4884
4885@@ -122,7 +125,7 @@
4886 XDo::Keyboard.super
4887 sleep 1
4888 verify_equal('true', TIMEOUT, 'Dash did not appear') {
4889- @shell.ShellDeclarativeView()['dashActive']
4890+ @shell.Dash()['active']
4891 }
4892
4893 maxbutton = nil
4894@@ -133,7 +136,7 @@
4895 maxbutton.tap if maxbutton
4896 sleep 1
4897 verify_equal('FullScreenMode', TIMEOUT, 'Dash should be fullsceen, but it is not' ) {
4898- @shell.ShellDeclarativeView()['dashMode']
4899+ @shell.ShellManager()['dashMode']
4900 }
4901
4902 # When always fullscreen tapping the max button does nothing, so the key should remain set to
4903@@ -147,7 +150,7 @@
4904 sleep 1
4905 expected = dash_always_fullscreen ? 'FullScreenMode' : 'DesktopMode'
4906 verify_equal(expected, TIMEOUT, 'Dash is in the wrong fullscreen state' ) {
4907- @shell.ShellDeclarativeView()['dashMode']
4908+ @shell.ShellManager()['dashMode']
4909 }
4910 verify_equal('false', TIMEOUT, 'Dash fullscreen key was not unset') {
4911 ($SUT.execute_shell_command "dconf read #{DASH_FULLSCREEN_KEY}").chop
4912@@ -161,10 +164,10 @@
4913 sleep 1
4914
4915 verify_equal('true', TIMEOUT, 'Dash did not appear') {
4916- @shell.ShellDeclarativeView()['dashActive']
4917+ @shell.Dash()['active']
4918 }
4919- verify_equal('FullScreenMode', TIMEOUT, 'Dash initial state is wrong') {
4920- @shell.ShellDeclarativeView()['dashMode']
4921+ verify_equal(dash_fullscreen_width, TIMEOUT, 'Dash initial state is wrong') {
4922+ @shell.Dash()['width'].to_i()
4923 }
4924 end
4925
4926@@ -175,10 +178,10 @@
4927 sleep 1
4928
4929 verify_equal('true', TIMEOUT, 'Dash did not appear') {
4930- @shell.ShellDeclarativeView()['dashActive']
4931+ @shell.Dash()['active']
4932 }
4933- verify_equal('FullScreenMode', TIMEOUT, 'Dash initial state is wrong') {
4934- @shell.ShellDeclarativeView()['dashMode']
4935+ verify_equal(dash_fullscreen_width, TIMEOUT, 'Dash initial state is wrong') {
4936+ @shell.Dash()['width'].to_i()
4937 }
4938 end
4939 end
4940
4941=== added directory 'tests/multimonitor'
4942=== added file 'tests/multimonitor/dash-moving.rb'
4943--- tests/multimonitor/dash-moving.rb 1970-01-01 00:00:00 +0000
4944+++ tests/multimonitor/dash-moving.rb 2012-03-14 15:11:22 +0000
4945@@ -0,0 +1,129 @@
4946+#!/usr/bin/env ruby1.8
4947+=begin
4948+/*
4949+ * This file is part of unity-2d
4950+ *
4951+ * Copyright 2012 Canonical Ltd.
4952+ *
4953+ * This program is free software; you can redistribute it and/or modify
4954+ * it under the terms of the GNU General Public License as published by
4955+ * the Free Software Foundation; version 3.
4956+ *
4957+ * This program is distributed in the hope that it will be useful,
4958+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4959+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4960+ * GNU General Public License for more details.
4961+ *
4962+ * You should have received a copy of the GNU General Public License
4963+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4964+ */
4965+=end
4966+
4967+require '../run-tests.rb' unless $INIT_COMPLETED
4968+require 'xdo/xwindow'
4969+require 'xdo/keyboard'
4970+require 'xdo/mouse'
4971+require 'tmpwindow'
4972+
4973+############################# Test Suite #############################
4974+context "Dash Tests" do
4975+ # Run once at the beginning of this test suite
4976+ startup do
4977+ $SUT.execute_shell_command 'killall unity-2d-shell'
4978+ $SUT.execute_shell_command 'killall unity-2d-shell'
4979+
4980+ # Minimize all windows
4981+ XDo::XWindow.toggle_minimize_all
4982+ end
4983+
4984+ # Run once at the end of this test suite
4985+ shutdown do
4986+ end
4987+
4988+ # Run before each test case begins
4989+ setup do
4990+ # Execute the application
4991+ @app = $SUT.run( :name => UNITY_2D_SHELL,
4992+ :arguments => "-testability",
4993+ :sleeptime => 2 )
4994+ end
4995+
4996+ # Run after each test case completes
4997+ teardown do
4998+ TmpWindow.close_all_windows
4999+ #Need to kill Launcher as it does not shutdown when politely asked
5000+ $SUT.execute_shell_command 'pkill -nf unity-2d-spread'
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches