Merge lp:~unity-2d-team/unity-2d/Shell-MultiMonitor into lp:unity-2d
- Shell-MultiMonitor
- Merge into trunk
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 | ||||
Related bugs: |
|
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.
Commit message
Description of the change
Multimonitor support for the shell
- 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
-
onlyOneLauncher
Changed changing means panelsFreeGeomt ryChanged - 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
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' |
4759 | Binary 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' |