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