Merge lp:~gerboland/qtubuntu/add--more-surface-type-support into lp:qtubuntu
- add--more-surface-type-support
- Merge into trunk
Proposed by
Gerry Boland
Status: | Superseded |
---|---|
Proposed branch: | lp:~gerboland/qtubuntu/add--more-surface-type-support |
Merge into: | lp:qtubuntu |
Diff against target: |
1063 lines (+480/-188) 17 files modified
debian/control (+1/-0) src/ubuntumirclient/backingstore.cpp (+7/-3) src/ubuntumirclient/backingstore.h (+1/-0) src/ubuntumirclient/debugextension.cpp (+55/-0) src/ubuntumirclient/debugextension.h (+39/-0) src/ubuntumirclient/desktopwindow.cpp (+26/-0) src/ubuntumirclient/desktopwindow.h (+29/-0) src/ubuntumirclient/glcontext.cpp (+0/-2) src/ubuntumirclient/input.cpp (+2/-0) src/ubuntumirclient/integration.cpp (+30/-11) src/ubuntumirclient/integration.h (+4/-1) src/ubuntumirclient/logging.h (+1/-0) src/ubuntumirclient/plugin.cpp (+5/-11) src/ubuntumirclient/plugin.h (+2/-3) src/ubuntumirclient/ubuntumirclient.pro (+4/-0) src/ubuntumirclient/window.cpp (+270/-156) src/ubuntumirclient/window.h (+4/-1) |
To merge this branch: | bzr merge lp:~gerboland/qtubuntu/add--more-surface-type-support |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Unity8 CI Bot | continuous-integration | Needs Fixing | |
Ubuntu Phablet Team | Pending | ||
Review via email:
|
This proposal has been superseded by a proposal from 2016-10-13.
Commit message
Add support for more surface types and surface repositioning.
Helps Menus, Dropdowns and Tooltips to work with Mir
Description of the change
To post a comment you must log in.
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
review:
Needs Fixing
(continuous-integration)
- 298. By Gerry Boland
-
Fix input method bug, missing break in switch
- 299. By Gerry Boland
-
Using mirclient version better for gating on mirclient api
- 300. By Gerry Boland
-
Fix for dialogs crash
- 301. By Gerry Boland
-
This is not python, fix comment
- 302. By Gerry Boland
-
Only set internal position in setGeometry, not size
- 303. By Gerry Boland
-
Merge trunk & resolve conflict
Unmerged revisions
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'debian/control' |
2 | --- debian/control 2016-08-24 12:40:30 +0000 |
3 | +++ debian/control 2016-10-13 10:20:24 +0000 |
4 | @@ -11,6 +11,7 @@ |
5 | libglib2.0-dev, |
6 | libinput-dev, |
7 | libmirclient-dev (>= 0.13.0), |
8 | + libmirclient-debug-extension-dev, |
9 | libmtdev-dev, |
10 | libubuntu-application-api-dev (>= 2.9.0), |
11 | libudev-dev, |
12 | |
13 | === modified file 'src/ubuntumirclient/backingstore.cpp' |
14 | --- src/ubuntumirclient/backingstore.cpp 2016-04-20 16:10:06 +0000 |
15 | +++ src/ubuntumirclient/backingstore.cpp 2016-10-13 10:20:24 +0000 |
16 | @@ -35,9 +35,7 @@ |
17 | window->setSurfaceType(QSurface::OpenGLSurface); |
18 | } |
19 | |
20 | -UbuntuBackingStore::~UbuntuBackingStore() |
21 | -{ |
22 | -} |
23 | +UbuntuBackingStore::~UbuntuBackingStore() = default; |
24 | |
25 | void UbuntuBackingStore::flush(QWindow* window, const QRegion& region, const QPoint& offset) |
26 | { |
27 | @@ -125,3 +123,9 @@ |
28 | { |
29 | return &mImage; |
30 | } |
31 | + |
32 | +QImage UbuntuBackingStore::toImage() const |
33 | +{ |
34 | + // used by QPlatformBackingStore::composeAndFlush |
35 | + return mImage; |
36 | +} |
37 | |
38 | === modified file 'src/ubuntumirclient/backingstore.h' |
39 | --- src/ubuntumirclient/backingstore.h 2014-11-11 14:34:12 +0000 |
40 | +++ src/ubuntumirclient/backingstore.h 2016-10-13 10:20:24 +0000 |
41 | @@ -34,6 +34,7 @@ |
42 | void flush(QWindow* window, const QRegion& region, const QPoint& offset) override; |
43 | void resize(const QSize& size, const QRegion& staticContents) override; |
44 | QPaintDevice* paintDevice() override; |
45 | + QImage toImage() const override; |
46 | |
47 | protected: |
48 | void updateTexture(); |
49 | |
50 | === added file 'src/ubuntumirclient/debugextension.cpp' |
51 | --- src/ubuntumirclient/debugextension.cpp 1970-01-01 00:00:00 +0000 |
52 | +++ src/ubuntumirclient/debugextension.cpp 2016-10-13 10:20:24 +0000 |
53 | @@ -0,0 +1,55 @@ |
54 | +/* |
55 | + * Copyright (C) 2016 Canonical, Ltd. |
56 | + * |
57 | + * This program is free software: you can redistribute it and/or modify it under |
58 | + * the terms of the GNU Lesser General Public License version 3, as published by |
59 | + * the Free Software Foundation. |
60 | + * |
61 | + * This program is distributed in the hope that it will be useful, but WITHOUT |
62 | + * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, |
63 | + * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
64 | + * Lesser General Public License for more details. |
65 | + * |
66 | + * You should have received a copy of the GNU Lesser General Public License |
67 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
68 | + */ |
69 | + |
70 | +#include "debugextension.h" |
71 | + |
72 | +#include "logging.h" |
73 | + |
74 | +// mir client debug |
75 | +#include <mir_toolkit/debug/surface.h> |
76 | + |
77 | +Q_LOGGING_CATEGORY(ubuntumirclientDebug, "ubuntumirclient.debug") |
78 | + |
79 | +UbuntuDebugExtension::UbuntuDebugExtension() |
80 | + : m_mirclientDebug(QStringLiteral("mirclient-debug-extension"), 1) |
81 | + , m_mapper(nullptr) |
82 | +{ |
83 | + qCDebug(ubuntumirclientDebug) << "NOTICE: Loading mirclient-debug-extension"; |
84 | + m_mapper = (MapperPrototype) m_mirclientDebug.resolve("mir_debug_surface_coords_to_screen"); |
85 | + |
86 | + if (!m_mirclientDebug.isLoaded()) { |
87 | + qCWarning(ubuntumirclientDebug) << "ERROR: mirclient-debug-extension failed to load:" |
88 | + << m_mirclientDebug.errorString(); |
89 | + } else if (!m_mapper) { |
90 | + qCWarning(ubuntumirclientDebug) << "ERROR: unable to find required symbols in mirclient-debug-extension:" |
91 | + << m_mirclientDebug.errorString(); |
92 | + } |
93 | +} |
94 | + |
95 | +QPoint UbuntuDebugExtension::mapSurfacePointToScreen(MirSurface *surface, const QPoint &point) |
96 | +{ |
97 | + if (!m_mapper) { |
98 | + return point; |
99 | + } |
100 | + |
101 | + QPoint mappedPoint; |
102 | + bool status = m_mapper(surface, point.x(), point.y(), &mappedPoint.rx(), &mappedPoint.ry()); |
103 | + if (status) { |
104 | + return mappedPoint; |
105 | + } else { |
106 | + return point; |
107 | + } |
108 | +} |
109 | |
110 | === added file 'src/ubuntumirclient/debugextension.h' |
111 | --- src/ubuntumirclient/debugextension.h 1970-01-01 00:00:00 +0000 |
112 | +++ src/ubuntumirclient/debugextension.h 2016-10-13 10:20:24 +0000 |
113 | @@ -0,0 +1,39 @@ |
114 | +/* |
115 | + * Copyright (C) 2016 Canonical, Ltd. |
116 | + * |
117 | + * This program is free software: you can redistribute it and/or modify it under |
118 | + * the terms of the GNU Lesser General Public License version 3, as published by |
119 | + * the Free Software Foundation. |
120 | + * |
121 | + * This program is distributed in the hope that it will be useful, but WITHOUT |
122 | + * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, |
123 | + * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
124 | + * Lesser General Public License for more details. |
125 | + * |
126 | + * You should have received a copy of the GNU Lesser General Public License |
127 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
128 | + */ |
129 | + |
130 | +#ifndef UBUNTU_DEBUG_EXTENSION_H |
131 | +#define UBUNTU_DEBUG_EXTENSION_H |
132 | + |
133 | +#include <QPoint> |
134 | +#include <QLibrary> |
135 | +struct MirSurface; |
136 | + |
137 | +typedef bool (*MapperPrototype)(MirSurface* surface, int x, int y, int* screenX, int* screenY); |
138 | + |
139 | + |
140 | +class UbuntuDebugExtension |
141 | +{ |
142 | +public: |
143 | + UbuntuDebugExtension(); |
144 | + |
145 | + QPoint mapSurfacePointToScreen(MirSurface *, const QPoint &point); |
146 | + |
147 | +private: |
148 | + QLibrary m_mirclientDebug; |
149 | + MapperPrototype m_mapper; |
150 | +}; |
151 | + |
152 | +#endif // UBUNTU_DEBUG_EXTENSION_H |
153 | |
154 | === added file 'src/ubuntumirclient/desktopwindow.cpp' |
155 | --- src/ubuntumirclient/desktopwindow.cpp 1970-01-01 00:00:00 +0000 |
156 | +++ src/ubuntumirclient/desktopwindow.cpp 2016-10-13 10:20:24 +0000 |
157 | @@ -0,0 +1,26 @@ |
158 | +/* |
159 | + * Copyright (C) 2016 Canonical, Ltd. |
160 | + * |
161 | + * This program is free software: you can redistribute it and/or modify it under |
162 | + * the terms of the GNU Lesser General Public License version 3, as published by |
163 | + * the Free Software Foundation. |
164 | + * |
165 | + * This program is distributed in the hope that it will be useful, but WITHOUT |
166 | + * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, |
167 | + * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
168 | + * Lesser General Public License for more details. |
169 | + * |
170 | + * You should have received a copy of the GNU Lesser General Public License |
171 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
172 | + */ |
173 | + |
174 | +#include "desktopwindow.h" |
175 | + |
176 | +// local |
177 | +#include "logging.h" |
178 | + |
179 | +UbuntuDesktopWindow::UbuntuDesktopWindow(QWindow *window) |
180 | + : QPlatformWindow(window) |
181 | +{ |
182 | + qCDebug(ubuntumirclient, "UbuntuDesktopWindow(window=%p)", window); |
183 | +} |
184 | |
185 | === added file 'src/ubuntumirclient/desktopwindow.h' |
186 | --- src/ubuntumirclient/desktopwindow.h 1970-01-01 00:00:00 +0000 |
187 | +++ src/ubuntumirclient/desktopwindow.h 2016-10-13 10:20:24 +0000 |
188 | @@ -0,0 +1,29 @@ |
189 | +/* |
190 | + * Copyright (C) 2016 Canonical, Ltd. |
191 | + * |
192 | + * This program is free software: you can redistribute it and/or modify it under |
193 | + * the terms of the GNU Lesser General Public License version 3, as published by |
194 | + * the Free Software Foundation. |
195 | + * |
196 | + * This program is distributed in the hope that it will be useful, but WITHOUT |
197 | + * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, |
198 | + * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
199 | + * Lesser General Public License for more details. |
200 | + * |
201 | + * You should have received a copy of the GNU Lesser General Public License |
202 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
203 | + */ |
204 | + |
205 | +#ifndef UBUNTU_DESKTOP_WINDOW_H |
206 | +#define UBUNTU_DESKTOP_WINDOW_H |
207 | + |
208 | +#include <qpa/qplatformwindow.h> |
209 | + |
210 | +// TODO Implement it. For now it's just an empty, dummy class. |
211 | +class UbuntuDesktopWindow : public QPlatformWindow |
212 | +{ |
213 | +public: |
214 | + UbuntuDesktopWindow(QWindow*); |
215 | +}; |
216 | + |
217 | +#endif // UBUNTU_DESKTOP_WINDOW_H |
218 | |
219 | === modified file 'src/ubuntumirclient/glcontext.cpp' |
220 | --- src/ubuntumirclient/glcontext.cpp 2016-08-17 15:32:38 +0000 |
221 | +++ src/ubuntumirclient/glcontext.cpp 2016-10-13 10:20:24 +0000 |
222 | @@ -74,8 +74,6 @@ |
223 | |
224 | bool UbuntuOpenGLContext::makeCurrent(QPlatformSurface* surface) |
225 | { |
226 | - Q_ASSERT(surface->surface()->surfaceType() == QSurface::OpenGLSurface); |
227 | - |
228 | const bool ret = QEGLPlatformContext::makeCurrent(surface); |
229 | |
230 | if (Q_LIKELY(ret)) { |
231 | |
232 | === modified file 'src/ubuntumirclient/input.cpp' |
233 | --- src/ubuntumirclient/input.cpp 2016-09-21 10:25:33 +0000 |
234 | +++ src/ubuntumirclient/input.cpp 2016-10-13 10:20:24 +0000 |
235 | @@ -501,6 +501,8 @@ |
236 | const auto localPoint = QPointF(mir_pointer_event_axis_value(pev, mir_pointer_axis_x), |
237 | mir_pointer_event_axis_value(pev, mir_pointer_axis_y)); |
238 | |
239 | + mLastInputWindow = platformWindow; |
240 | + |
241 | switch (action) { |
242 | case mir_pointer_action_button_up: |
243 | case mir_pointer_action_button_down: |
244 | |
245 | === modified file 'src/ubuntumirclient/integration.cpp' |
246 | --- src/ubuntumirclient/integration.cpp 2016-09-28 10:51:25 +0000 |
247 | +++ src/ubuntumirclient/integration.cpp 2016-10-13 10:20:24 +0000 |
248 | @@ -18,6 +18,8 @@ |
249 | #include "integration.h" |
250 | #include "backingstore.h" |
251 | #include "clipboard.h" |
252 | +#include "desktopwindow.h" |
253 | +#include "debugextension.h" |
254 | #include "glcontext.h" |
255 | #include "input.h" |
256 | #include "logging.h" |
257 | @@ -29,6 +31,7 @@ |
258 | // Qt |
259 | #include <QFileInfo> |
260 | #include <QGuiApplication> |
261 | +#include <private/qeglpbuffer_p.h> |
262 | #include <qpa/qplatformnativeinterface.h> |
263 | #include <qpa/qplatforminputcontextfactory_p.h> |
264 | #include <qpa/qplatforminputcontext.h> |
265 | @@ -70,7 +73,8 @@ |
266 | QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationSuspended); |
267 | } |
268 | |
269 | -UbuntuClientIntegration::UbuntuClientIntegration() |
270 | + |
271 | +UbuntuClientIntegration::UbuntuClientIntegration(int argc, char **argv) |
272 | : QPlatformIntegration() |
273 | , mNativeInterface(new UbuntuNativeInterface(this)) |
274 | , mFontDb(new QGenericUnixFontDatabase) |
275 | @@ -105,6 +109,17 @@ |
276 | mEglNativeDisplay = mir_connection_get_egl_native_display(mMirConnection); |
277 | ASSERT((mEglDisplay = eglGetDisplay(mEglNativeDisplay)) != EGL_NO_DISPLAY); |
278 | ASSERT(eglInitialize(mEglDisplay, nullptr, nullptr) == EGL_TRUE); |
279 | + |
280 | + // Has debug mode been requsted, either with "-testability" switch or QT_LOAD_TESTABILITY env var |
281 | + bool testability = qEnvironmentVariableIsSet("QT_LOAD_TESTABILITY"); |
282 | + for (int i=1; !testability && i<argc; i++) { |
283 | + if (strcmp(argv[i], "-testability") == 0) { |
284 | + testability = true; |
285 | + } |
286 | + } |
287 | + if (testability) { |
288 | + mDebugExtension.reset(new UbuntuDebugExtension); |
289 | + } |
290 | } |
291 | |
292 | void UbuntuClientIntegration::initialize() |
293 | @@ -211,21 +226,17 @@ |
294 | |
295 | QPlatformWindow* UbuntuClientIntegration::createPlatformWindow(QWindow* window) const |
296 | { |
297 | - return new UbuntuWindow(window, mInput, mNativeInterface, mEglDisplay, mMirConnection); |
298 | + if (window->type() == Qt::Desktop) { |
299 | + // Desktop windows should not be backed up by a mir surface as they don't draw anything (nor should). |
300 | + return new UbuntuDesktopWindow(window); |
301 | + } else { |
302 | + return new UbuntuWindow(window, mInput, mNativeInterface, mEglDisplay, mMirConnection, mDebugExtension.data()); |
303 | + } |
304 | } |
305 | |
306 | bool UbuntuClientIntegration::hasCapability(QPlatformIntegration::Capability cap) const |
307 | { |
308 | switch (cap) { |
309 | - case ThreadedPixmaps: |
310 | - return true; |
311 | - |
312 | - case OpenGL: |
313 | - return true; |
314 | - |
315 | - case ApplicationState: |
316 | - return true; |
317 | - |
318 | case ThreadedOpenGL: |
319 | if (qEnvironmentVariableIsEmpty("QTUBUNTU_NO_THREADED_OPENGL")) { |
320 | return true; |
321 | @@ -233,8 +244,16 @@ |
322 | qCDebug(ubuntumirclient, "disabled threaded OpenGL"); |
323 | return false; |
324 | } |
325 | + |
326 | + case ThreadedPixmaps: |
327 | + case OpenGL: |
328 | + case ApplicationState: |
329 | case MultipleWindows: |
330 | case NonFullScreenWindows: |
331 | +#if QT_VERSION > QT_VERSION_CHECK(5, 5, 0) |
332 | + case SwitchableWidgetComposition: |
333 | +#endif |
334 | + case RasterGLSurface: // needed for QQuickWidget |
335 | return true; |
336 | default: |
337 | return QPlatformIntegration::hasCapability(cap); |
338 | |
339 | === modified file 'src/ubuntumirclient/integration.h' |
340 | --- src/ubuntumirclient/integration.h 2016-08-24 12:40:30 +0000 |
341 | +++ src/ubuntumirclient/integration.h 2016-10-13 10:20:24 +0000 |
342 | @@ -29,6 +29,7 @@ |
343 | |
344 | #include <EGL/egl.h> |
345 | |
346 | +class UbuntuDebugExtension; |
347 | class UbuntuInput; |
348 | class UbuntuNativeInterface; |
349 | class UbuntuScreen; |
350 | @@ -39,7 +40,7 @@ |
351 | Q_OBJECT |
352 | |
353 | public: |
354 | - UbuntuClientIntegration(); |
355 | + UbuntuClientIntegration(int argc, char **argv); |
356 | virtual ~UbuntuClientIntegration(); |
357 | |
358 | // QPlatformIntegration methods. |
359 | @@ -64,6 +65,7 @@ |
360 | EGLDisplay eglDisplay() const { return mEglDisplay; } |
361 | EGLNativeDisplayType eglNativeDisplay() const { return mEglNativeDisplay; } |
362 | UbuntuScreenObserver *screenObserver() const { return mScreenObserver.data(); } |
363 | + UbuntuDebugExtension *debugExtension() const { return mDebugExtension.data(); } |
364 | |
365 | private Q_SLOTS: |
366 | void destroyScreen(UbuntuScreen *screen); |
367 | @@ -81,6 +83,7 @@ |
368 | |
369 | UbuntuInput* mInput; |
370 | QPlatformInputContext* mInputContext; |
371 | + QScopedPointer<UbuntuDebugExtension> mDebugExtension; |
372 | QScopedPointer<UbuntuScreenObserver> mScreenObserver; |
373 | qreal mScaleFactor; |
374 | |
375 | |
376 | === modified file 'src/ubuntumirclient/logging.h' |
377 | --- src/ubuntumirclient/logging.h 2016-06-22 17:16:33 +0000 |
378 | +++ src/ubuntumirclient/logging.h 2016-10-13 10:20:24 +0000 |
379 | @@ -26,5 +26,6 @@ |
380 | Q_DECLARE_LOGGING_CATEGORY(ubuntumirclientInput) |
381 | Q_DECLARE_LOGGING_CATEGORY(ubuntumirclientGraphics) |
382 | Q_DECLARE_LOGGING_CATEGORY(ubuntumirclientCursor) |
383 | +Q_DECLARE_LOGGING_CATEGORY(ubuntumirclientDebug) |
384 | |
385 | #endif // QUBUNTULOGGING_H |
386 | |
387 | === modified file 'src/ubuntumirclient/plugin.cpp' |
388 | --- src/ubuntumirclient/plugin.cpp 2015-12-04 16:19:33 +0000 |
389 | +++ src/ubuntumirclient/plugin.cpp 2016-10-13 10:20:24 +0000 |
390 | @@ -1,5 +1,5 @@ |
391 | /* |
392 | - * Copyright (C) 2014 Canonical, Ltd. |
393 | + * Copyright (C) 2014-2016 Canonical, Ltd. |
394 | * |
395 | * This program is free software: you can redistribute it and/or modify it under |
396 | * the terms of the GNU Lesser General Public License version 3, as published by |
397 | @@ -20,15 +20,9 @@ |
398 | |
399 | Q_LOGGING_CATEGORY(ubuntumirclient, "ubuntumirclient", QtWarningMsg) |
400 | |
401 | -QStringList UbuntuMirClientIntegrationPlugin::keys() const |
402 | -{ |
403 | - QStringList list; |
404 | - list << QStringLiteral("ubuntumirclient"); |
405 | - return list; |
406 | -} |
407 | - |
408 | -QPlatformIntegration* UbuntuMirClientIntegrationPlugin::create(const QString &system, |
409 | - const QStringList &) |
410 | +QPlatformIntegration *UbuntuMirClientIntegrationPlugin::create(const QString &system, |
411 | + const QStringList &/*paramList*/, |
412 | + int &argc, char **argv) |
413 | { |
414 | if (system.toLower() == QLatin1String("ubuntumirclient")) { |
415 | #ifdef PLATFORM_API_TOUCH |
416 | @@ -36,7 +30,7 @@ |
417 | #else |
418 | setenv("UBUNTU_PLATFORM_API_BACKEND", "desktop_mirclient", 1); |
419 | #endif |
420 | - return new UbuntuClientIntegration; |
421 | + return new UbuntuClientIntegration(argc, argv); |
422 | } else { |
423 | return 0; |
424 | } |
425 | |
426 | === modified file 'src/ubuntumirclient/plugin.h' |
427 | --- src/ubuntumirclient/plugin.h 2014-06-18 23:10:00 +0000 |
428 | +++ src/ubuntumirclient/plugin.h 2016-10-13 10:20:24 +0000 |
429 | @@ -1,5 +1,5 @@ |
430 | /* |
431 | - * Copyright (C) 2014 Canonical, Ltd. |
432 | + * Copyright (C) 2014-2016 Canonical, Ltd. |
433 | * |
434 | * This program is free software: you can redistribute it and/or modify it under |
435 | * the terms of the GNU Lesser General Public License version 3, as published by |
436 | @@ -25,8 +25,7 @@ |
437 | Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "ubuntumirclient.json") |
438 | |
439 | public: |
440 | - QStringList keys() const; |
441 | - QPlatformIntegration* create(const QString&, const QStringList&); |
442 | + QPlatformIntegration *create(const QString &system, const QStringList ¶mList, int &argc, char **argv) override; |
443 | }; |
444 | |
445 | #endif // UBUNTU_CLIENT_PLUGIN_H |
446 | |
447 | === modified file 'src/ubuntumirclient/ubuntumirclient.pro' |
448 | --- src/ubuntumirclient/ubuntumirclient.pro 2016-09-28 10:51:25 +0000 |
449 | +++ src/ubuntumirclient/ubuntumirclient.pro 2016-10-13 10:20:24 +0000 |
450 | @@ -18,6 +18,8 @@ |
451 | backingstore.cpp \ |
452 | clipboard.cpp \ |
453 | cursor.cpp \ |
454 | + debugextension.cpp \ |
455 | + desktopwindow.cpp \ |
456 | glcontext.cpp \ |
457 | input.cpp \ |
458 | integration.cpp \ |
459 | @@ -33,6 +35,8 @@ |
460 | backingstore.h \ |
461 | clipboard.h \ |
462 | cursor.h \ |
463 | + debugextension.h \ |
464 | + desktopwindow.h \ |
465 | glcontext.h \ |
466 | input.h \ |
467 | integration.h \ |
468 | |
469 | === modified file 'src/ubuntumirclient/window.cpp' |
470 | --- src/ubuntumirclient/window.cpp 2016-09-28 10:33:40 +0000 |
471 | +++ src/ubuntumirclient/window.cpp 2016-10-13 10:20:24 +0000 |
472 | @@ -16,12 +16,15 @@ |
473 | |
474 | // Local |
475 | #include "window.h" |
476 | +#include "debugextension.h" |
477 | #include "nativeinterface.h" |
478 | #include "input.h" |
479 | +#include "integration.h" |
480 | #include "screen.h" |
481 | #include "logging.h" |
482 | |
483 | #include <mir_toolkit/mir_client_library.h> |
484 | +#include <mir_toolkit/version.h> |
485 | |
486 | // Qt |
487 | #include <qpa/qwindowsysteminterface.h> |
488 | @@ -121,6 +124,23 @@ |
489 | } |
490 | } |
491 | |
492 | +const char *mirSurfaceTypeToStr(MirSurfaceType type) |
493 | +{ |
494 | + switch (type) { |
495 | + case mir_surface_type_normal: return "Normal"; /**< AKA "regular" */ |
496 | + case mir_surface_type_utility: return "Utility"; /**< AKA "floating regular" */ |
497 | + case mir_surface_type_dialog: return "Dialog"; |
498 | + case mir_surface_type_gloss: return "Gloss"; |
499 | + case mir_surface_type_freestyle: return "Freestyle"; |
500 | + case mir_surface_type_menu: return "Menu"; |
501 | + case mir_surface_type_inputmethod: return "Input Method"; /**< AKA "OSK" or handwriting etc. */ |
502 | + case mir_surface_type_satellite: return "Satellite"; /**< AKA "toolbox"/"toolbar" */ |
503 | + case mir_surface_type_tip: return "Tip"; /**< AKA "tooltip" */ |
504 | + case mir_surface_types: Q_UNREACHABLE(); |
505 | + } |
506 | + return ""; |
507 | +} |
508 | + |
509 | MirSurfaceState qtWindowStateToMirSurfaceState(Qt::WindowState state) |
510 | { |
511 | switch (state) { |
512 | @@ -138,6 +158,27 @@ |
513 | } |
514 | } |
515 | |
516 | +MirSurfaceType qtWindowTypeToMirSurfaceType(Qt::WindowType type) |
517 | +{ |
518 | + switch (type & Qt::WindowType_Mask) { |
519 | + case Qt::Dialog: |
520 | + return mir_surface_type_dialog; |
521 | + case Qt::Sheet: |
522 | + case Qt::Drawer: |
523 | + return mir_surface_type_utility; |
524 | + case Qt::Popup: |
525 | + case Qt::Tool: |
526 | + return mir_surface_type_menu; |
527 | + case Qt::ToolTip: |
528 | + return mir_surface_type_tip; |
529 | + case Qt::SplashScreen: |
530 | + return mir_surface_type_freestyle; |
531 | + case Qt::Window: |
532 | + default: |
533 | + return mir_surface_type_normal; |
534 | + } |
535 | +} |
536 | + |
537 | WId makeId() |
538 | { |
539 | static int id = 1; |
540 | @@ -163,51 +204,91 @@ |
541 | return parent ? static_cast<UbuntuWindow *>(parent->handle()) : nullptr; |
542 | } |
543 | |
544 | -Spec makeSurfaceSpec(QWindow *window, UbuntuInput *input, MirPixelFormat pixelFormat, MirConnection *connection) |
545 | -{ |
546 | - const auto geom = window->geometry(); |
547 | - const int width = geom.width() > 0 ? geom.width() : 1; |
548 | - const int height = geom.height() > 0 ? geom.height() : 1; |
549 | +bool requiresParent(const MirSurfaceType type) |
550 | +{ |
551 | + switch (type) { |
552 | + case mir_surface_type_utility: |
553 | + case mir_surface_type_gloss: |
554 | + case mir_surface_type_menu: |
555 | + case mir_surface_type_satellite: |
556 | + case mir_surface_type_tip: |
557 | + return true; |
558 | + default: |
559 | + return false; |
560 | + } |
561 | +} |
562 | + |
563 | +bool requiresParent(const Qt::WindowType type) |
564 | +{ |
565 | + return requiresParent(qtWindowTypeToMirSurfaceType(type)); |
566 | +} |
567 | + |
568 | +bool isMovable(const Qt::WindowType type) |
569 | +{ |
570 | + auto mirType = qtWindowTypeToMirSurfaceType(type); |
571 | + switch (mirType) { |
572 | + case mir_surface_type_menu: |
573 | + case mir_surface_type_tip: |
574 | + return true; |
575 | + default: |
576 | + return false; |
577 | + } |
578 | +} |
579 | + |
580 | +Spec makeSurfaceSpec(QWindow *window, MirPixelFormat pixelFormat, UbuntuWindow *parentWindowHandle, |
581 | + MirConnection *connection) |
582 | +{ |
583 | + const auto geometry = window->geometry(); |
584 | + const int width = geometry.width() > 0 ? geometry.width() : 1; |
585 | + const int height = geometry.height() > 0 ? geometry.height() : 1; |
586 | + auto type = qtWindowTypeToMirSurfaceType(window->type()); |
587 | |
588 | if (U_ON_SCREEN_KEYBOARD_ROLE == roleFor(window)) { |
589 | - qCDebug(ubuntumirclient, "makeSurfaceSpec(window=%p) - creating input method surface (width=%d, height=%d", window, width, height); |
590 | - return Spec{mir_connection_create_spec_for_input_method(connection, width, height, pixelFormat)}; |
591 | - } |
592 | - |
593 | - const Qt::WindowType type = window->type(); |
594 | - if (type == Qt::Popup) { |
595 | - auto parent = transientParentFor(window); |
596 | - if (parent == nullptr) { |
597 | - //NOTE: We cannot have a parentless popup - |
598 | - //try using the last surface to receive input as that will most likely be |
599 | - //the one that caused this popup to be created |
600 | - parent = input->lastInputWindow(); |
601 | - } |
602 | - if (parent) { |
603 | - auto pos = geom.topLeft(); |
604 | - pos -= parent->geometry().topLeft(); |
605 | - MirRectangle location{pos.x(), pos.y(), 0, 0}; |
606 | - qCDebug(ubuntumirclient, "makeSurfaceSpec(window=%p) - creating menu surface(width:%d, height:%d)", window, width, height); |
607 | - return Spec{mir_connection_create_spec_for_menu( |
608 | - connection, width, height, pixelFormat, parent->mirSurface(), |
609 | - &location, mir_edge_attachment_any)}; |
610 | - } else { |
611 | - qCDebug(ubuntumirclient, "makeSurfaceSpec(window=%p) - cannot create a menu without a parent!", window); |
612 | - } |
613 | - } else if (type == Qt::Dialog) { |
614 | - auto parent = transientParentFor(window); |
615 | - if (parent) { |
616 | - // Modal dialog |
617 | - qCDebug(ubuntumirclient, "makeSurfaceSpec(window=%p) - creating modal dialog (width=%d, height=%d", window, width, height); |
618 | - return Spec{mir_connection_create_spec_for_modal_dialog(connection, width, height, pixelFormat, parent->mirSurface())}; |
619 | - } else { |
620 | - // TODO: do Qt parentless dialogs have the same semantics as mir? |
621 | - qCDebug(ubuntumirclient, "makeSurfaceSpec(window=%p) - creating parentless dialog (width=%d, height=%d)", window, width, height); |
622 | - return Spec{mir_connection_create_spec_for_dialog(connection, width, height, pixelFormat)}; |
623 | - } |
624 | - } |
625 | - qCDebug(ubuntumirclient, "makeSurfaceSpec(window=%p) - creating normal surface(type=0x%x, width=%d, height=%d)", window, type, width, height); |
626 | - return Spec{mir_connection_create_spec_for_normal_surface(connection, width, height, pixelFormat)}; |
627 | + type = mir_surface_type_inputmethod; |
628 | + } |
629 | + |
630 | + MirRectangle location{geometry.x(), geometry.y(), 0, 0}; |
631 | + MirSurface *parent = nullptr; |
632 | + if (parentWindowHandle) { |
633 | + parent = parentWindowHandle->mirSurface(); |
634 | + // Qt uses absolute positioning, but Mir positions surfaces relative to parent. |
635 | + location.top -= parentWindowHandle->geometry().top(); |
636 | + location.left -= parentWindowHandle->geometry().left(); |
637 | + } |
638 | + |
639 | + Spec spec; |
640 | + |
641 | + switch (type) { |
642 | + case mir_surface_type_menu: |
643 | + spec = Spec{mir_connection_create_spec_for_menu(connection, width, height, pixelFormat, parent, |
644 | + &location, mir_edge_attachment_any)}; |
645 | + break; |
646 | + case mir_surface_type_dialog: |
647 | + spec = Spec{mir_connection_create_spec_for_modal_dialog(connection, width, height, pixelFormat, parent)}; |
648 | + break; |
649 | + case mir_surface_type_utility: |
650 | + spec = Spec{mir_connection_create_spec_for_dialog(connection, width, height, pixelFormat)}; |
651 | + break; |
652 | + case mir_surface_type_tip: |
653 | +#if MIR_SERVER_VERSION < MIR_VERSION_NUMBER(0, 25, 0) |
654 | + spec = Spec{mir_connection_create_spec_for_tooltip(connection, width, height, pixelFormat, parent, |
655 | + &location)}; |
656 | +#else |
657 | + spec = Spec{mir_connection_create_spec_for_tip(connection, width, height, pixelFormat, parent, |
658 | + &location, mir_edge_attachment_any)}; |
659 | +#endif |
660 | + break; |
661 | + case mir_surface_type_inputmethod: |
662 | + spec = Spec{mir_connection_create_spec_for_input_method(connection, width, height, pixelFormat)}; |
663 | + default: |
664 | + spec = Spec{mir_connection_create_spec_for_normal_surface(connection, width, height, pixelFormat)}; |
665 | + break; |
666 | + } |
667 | + |
668 | + qCDebug(ubuntumirclient, "makeSurfaceSpec(window=%p): %s spec (type=0x%x, position=(%d, %d)px, size=(%dx%d)px)", |
669 | + window, mirSurfaceTypeToStr(type), window->type(), location.left, location.top, width, height); |
670 | + |
671 | + return std::move(spec); |
672 | } |
673 | |
674 | void setSizingConstraints(MirSurfaceSpec *spec, const QSize& minSize, const QSize& maxSize, const QSize& increment) |
675 | @@ -228,11 +309,11 @@ |
676 | } |
677 | } |
678 | |
679 | -MirSurface *createMirSurface(QWindow *window, int mirOutputId, UbuntuInput *input, MirPixelFormat pixelFormat, |
680 | - MirConnection *connection, mir_surface_event_callback inputCallback, |
681 | - void* inputContext) |
682 | +MirSurface *createMirSurface(QWindow *window, int mirOutputId, UbuntuWindow *parentWindowHandle, |
683 | + MirPixelFormat pixelFormat, MirConnection *connection, |
684 | + mir_surface_event_callback inputCallback, void *inputContext) |
685 | { |
686 | - auto spec = makeSurfaceSpec(window, input, pixelFormat, connection); |
687 | + auto spec = makeSurfaceSpec(window, pixelFormat, parentWindowHandle, connection); |
688 | |
689 | // Install event handler as early as possible |
690 | mir_surface_spec_set_event_handler(spec.get(), inputCallback, inputContext); |
691 | @@ -255,6 +336,20 @@ |
692 | return surface; |
693 | } |
694 | |
695 | +UbuntuWindow *getParentIfNecessary(QWindow *window, UbuntuInput *input) |
696 | +{ |
697 | + UbuntuWindow *parentWindowHandle = nullptr; |
698 | + if (requiresParent(window->type())) { |
699 | + parentWindowHandle = transientParentFor(window); |
700 | + if (parentWindowHandle == nullptr) { |
701 | + // NOTE: Mir requires this surface have a parent. Try using the last surface to receive input as that will |
702 | + // most likely be the one that caused this surface to be created |
703 | + parentWindowHandle = input->lastInputWindow(); |
704 | + } |
705 | + } |
706 | + return parentWindowHandle; |
707 | +} |
708 | + |
709 | MirPixelFormat disableAlphaBufferIfPossible(MirPixelFormat pixelFormat) |
710 | { |
711 | switch(pixelFormat) { |
712 | @@ -286,98 +381,18 @@ |
713 | |
714 | } //namespace |
715 | |
716 | + |
717 | + |
718 | class UbuntuSurface |
719 | { |
720 | public: |
721 | - UbuntuSurface(UbuntuWindow *platformWindow, EGLDisplay display, UbuntuInput *input, MirConnection *connection) |
722 | - : mWindow(platformWindow->window()) |
723 | - , mPlatformWindow(platformWindow) |
724 | - , mInput(input) |
725 | - , mConnection(connection) |
726 | - , mEglDisplay(display) |
727 | - , mNeedsRepaint(false) |
728 | - , mParented(mWindow->transientParent() || mWindow->parent()) |
729 | - , mFormat(mWindow->requestedFormat()) |
730 | - , mShellChrome(mWindow->flags() & LowChromeWindowHint ? mir_shell_chrome_low : mir_shell_chrome_normal) |
731 | - { |
732 | - // Have Qt choose most suitable EGLConfig for the requested surface format, and update format to reflect it |
733 | - EGLConfig config = q_configFromGLFormat(display, mFormat, true); |
734 | - if (config == 0) { |
735 | - // Older Intel Atom-based devices only support OpenGL 1.4 compatibility profile but by default |
736 | - // QML asks for at least OpenGL 2.0. The XCB GLX backend ignores this request and returns a |
737 | - // 1.4 context, but the XCB EGL backend tries to honour it, and fails. The 1.4 context appears to |
738 | - // have sufficient capabilities on MESA (i915) to render correctly however. So reduce the default |
739 | - // requested OpenGL version to 1.0 to ensure EGL will give us a working context (lp:1549455). |
740 | - static const bool isMesa = QString(eglQueryString(display, EGL_VENDOR)).contains(QStringLiteral("Mesa")); |
741 | - if (isMesa) { |
742 | - qCDebug(ubuntumirclientGraphics, "Attempting to choose OpenGL 1.4 context which may suit Mesa"); |
743 | - mFormat.setMajorVersion(1); |
744 | - mFormat.setMinorVersion(4); |
745 | - config = q_configFromGLFormat(display, mFormat, true); |
746 | - } |
747 | - } |
748 | - if (config == 0) { |
749 | - qCritical() << "Qt failed to choose a suitable EGLConfig to suit the surface format" << mFormat; |
750 | - } |
751 | - |
752 | - mFormat = q_glFormatFromConfig(display, config, mFormat); |
753 | - |
754 | - // Have Mir decide the pixel format most suited to the chosen EGLConfig. This is the only way |
755 | - // Mir will know what EGLConfig has been chosen - it cannot deduce it from the buffers. |
756 | - auto pixelFormat = mir_connection_get_egl_pixel_format(connection, display, config); |
757 | - // But the chosen EGLConfig might have an alpha buffer enabled, even if not requested by the client. |
758 | - // If that's the case, try to edit the chosen pixel format in order to disable the alpha buffer. |
759 | - // This is an optimisation for the compositor, as it can avoid blending this surface. |
760 | - if (mWindow->requestedFormat().alphaBufferSize() < 0) { |
761 | - pixelFormat = disableAlphaBufferIfPossible(pixelFormat); |
762 | - } |
763 | - |
764 | - const auto outputId = static_cast<UbuntuScreen *>(mWindow->screen()->handle())->mirOutputId(); |
765 | - |
766 | - mMirSurface = createMirSurface(mWindow, outputId, input, pixelFormat, connection, surfaceEventCallback, this); |
767 | - mEglSurface = eglCreateWindowSurface(mEglDisplay, config, nativeWindowFor(mMirSurface), nullptr); |
768 | - |
769 | - mNeedsExposeCatchup = mir_surface_get_visibility(mMirSurface) == mir_surface_visibility_occluded; |
770 | - |
771 | - // Window manager can give us a final size different from what we asked for |
772 | - // so let's check what we ended up getting |
773 | - MirSurfaceParameters parameters; |
774 | - mir_surface_get_parameters(mMirSurface, ¶meters); |
775 | - |
776 | - auto geom = mWindow->geometry(); |
777 | - geom.setWidth(parameters.width); |
778 | - geom.setHeight(parameters.height); |
779 | - if (mWindow->windowState() == Qt::WindowFullScreen) { |
780 | - geom.moveTop(0); |
781 | - } else { |
782 | - geom.moveTop(panelHeight()); |
783 | - } |
784 | - |
785 | - // Assume that the buffer size matches the surface size at creation time |
786 | - mBufferSize = geom.size(); |
787 | - platformWindow->QPlatformWindow::setGeometry(geom); |
788 | - QWindowSystemInterface::handleGeometryChange(mWindow, geom); |
789 | - |
790 | - qCDebug(ubuntumirclient) << "Created surface with geometry:" << geom << "title:" << mWindow->title() |
791 | - << "role:" << roleFor(mWindow); |
792 | - qCDebug(ubuntumirclientGraphics) |
793 | - << "Requested format:" << mWindow->requestedFormat() |
794 | - << "\nActual format:" << mFormat |
795 | - << "with associated Mir pixel format:" << mirPixelFormatToStr(pixelFormat); |
796 | - } |
797 | - |
798 | - ~UbuntuSurface() |
799 | - { |
800 | - if (mEglSurface != EGL_NO_SURFACE) |
801 | - eglDestroySurface(mEglDisplay, mEglSurface); |
802 | - if (mMirSurface) |
803 | - mir_surface_release_sync(mMirSurface); |
804 | - } |
805 | + UbuntuSurface(UbuntuWindow *platformWindow, EGLDisplay display, UbuntuInput *input, MirConnection *connection); |
806 | + ~UbuntuSurface(); |
807 | |
808 | UbuntuSurface(const UbuntuSurface &) = delete; |
809 | UbuntuSurface& operator=(const UbuntuSurface &) = delete; |
810 | |
811 | - void resize(const QSize& newSize); |
812 | + void updateGeometry(const QRect &newGeometry); |
813 | void updateTitle(const QString& title); |
814 | void setSizingConstraints(const QSize& minSize, const QSize& maxSize, const QSize& increment); |
815 | |
816 | @@ -413,6 +428,7 @@ |
817 | UbuntuWindow * const mPlatformWindow; |
818 | UbuntuInput * const mInput; |
819 | MirConnection * const mConnection; |
820 | + UbuntuWindow * mParentWindowHandle{nullptr}; |
821 | |
822 | MirSurface* mMirSurface; |
823 | const EGLDisplay mEglDisplay; |
824 | @@ -422,6 +438,7 @@ |
825 | bool mParented; |
826 | QSize mBufferSize; |
827 | QSurfaceFormat mFormat; |
828 | + MirPixelFormat mPixelFormat; |
829 | |
830 | QMutex mTargetSizeMutex; |
831 | QSize mTargetSize; |
832 | @@ -429,23 +446,102 @@ |
833 | QString mPersistentIdStr; |
834 | }; |
835 | |
836 | -void UbuntuSurface::resize(const QSize& size) |
837 | -{ |
838 | - qCDebug(ubuntumirclient,"resize(window=%p, width=%d, height=%d)", mWindow, size.width(), size.height()); |
839 | - |
840 | - if (mWindow->windowState() == Qt::WindowFullScreen || mWindow->windowState() == Qt::WindowMaximized) { |
841 | - qCDebug(ubuntumirclient, "resize(window=%p) - not resizing, window is maximized or fullscreen", mWindow); |
842 | - return; |
843 | - } |
844 | - |
845 | - if (size.isEmpty()) { |
846 | - qCDebug(ubuntumirclient, "resize(window=%p) - not resizing, size is empty", mWindow); |
847 | - return; |
848 | - } |
849 | - |
850 | - Spec spec{mir_connection_create_spec_for_changes(mConnection)}; |
851 | - mir_surface_spec_set_width(spec.get(), size.width()); |
852 | - mir_surface_spec_set_height(spec.get(), size.height()); |
853 | +UbuntuSurface::UbuntuSurface(UbuntuWindow *platformWindow, EGLDisplay display, UbuntuInput *input, MirConnection *connection) |
854 | + : mWindow(platformWindow->window()) |
855 | + , mPlatformWindow(platformWindow) |
856 | + , mInput(input) |
857 | + , mConnection(connection) |
858 | + , mEglDisplay(display) |
859 | + , mNeedsRepaint(false) |
860 | + , mParented(mWindow->transientParent() || mWindow->parent()) |
861 | + , mFormat(mWindow->requestedFormat()) |
862 | + , mShellChrome(mWindow->flags() & LowChromeWindowHint ? mir_shell_chrome_low : mir_shell_chrome_normal) |
863 | +{ |
864 | + // Have Qt choose most suitable EGLConfig for the requested surface format, and update format to reflect it |
865 | + EGLConfig config = q_configFromGLFormat(display, mFormat, true); |
866 | + if (config == 0) { |
867 | + // Older Intel Atom-based devices only support OpenGL 1.4 compatibility profile but by default |
868 | + // QML asks for at least OpenGL 2.0. The XCB GLX backend ignores this request and returns a |
869 | + // 1.4 context, but the XCB EGL backend tries to honour it, and fails. The 1.4 context appears to |
870 | + // have sufficient capabilities on MESA (i915) to render correctly however. So reduce the default |
871 | + // requested OpenGL version to 1.0 to ensure EGL will give us a working context (lp:1549455). |
872 | + static const bool isMesa = QString(eglQueryString(display, EGL_VENDOR)).contains(QStringLiteral("Mesa")); |
873 | + if (isMesa) { |
874 | + qCDebug(ubuntumirclientGraphics, "Attempting to choose OpenGL 1.4 context which may suit Mesa"); |
875 | + mFormat.setMajorVersion(1); |
876 | + mFormat.setMinorVersion(4); |
877 | + config = q_configFromGLFormat(display, mFormat, true); |
878 | + } |
879 | + } |
880 | + if (config == 0) { |
881 | + qCritical() << "Qt failed to choose a suitable EGLConfig to suit the surface format" << mFormat; |
882 | + } |
883 | + |
884 | + mFormat = q_glFormatFromConfig(display, config, mFormat); |
885 | + |
886 | + // Have Mir decide the pixel format most suited to the chosen EGLConfig. This is the only way |
887 | + // Mir will know what EGLConfig has been chosen - it cannot deduce it from the buffers. |
888 | + mPixelFormat = mir_connection_get_egl_pixel_format(connection, display, config); |
889 | + // But the chosen EGLConfig might have an alpha buffer enabled, even if not requested by the client. |
890 | + // If that's the case, try to edit the chosen pixel format in order to disable the alpha buffer. |
891 | + // This is an optimisation for the compositor, as it can avoid blending this surface. |
892 | + if (mWindow->requestedFormat().alphaBufferSize() < 0) { |
893 | + mPixelFormat = disableAlphaBufferIfPossible(mPixelFormat); |
894 | + } |
895 | + |
896 | + const auto outputId = static_cast<UbuntuScreen *>(mWindow->screen()->handle())->mirOutputId(); |
897 | + |
898 | + mParentWindowHandle = getParentIfNecessary(mWindow, input); |
899 | + |
900 | + mMirSurface = createMirSurface(mWindow, outputId, mParentWindowHandle, mPixelFormat, connection, surfaceEventCallback, this); |
901 | + mEglSurface = eglCreateWindowSurface(mEglDisplay, config, nativeWindowFor(mMirSurface), nullptr); |
902 | + |
903 | + mNeedsExposeCatchup = mir_surface_get_visibility(mMirSurface) == mir_surface_visibility_occluded; |
904 | + |
905 | + // Window manager can give us a final size different from what we asked for |
906 | + // so let's check what we ended up getting |
907 | + MirSurfaceParameters parameters; |
908 | + mir_surface_get_parameters(mMirSurface, ¶meters); |
909 | + |
910 | + auto geom = mWindow->geometry(); |
911 | + geom.setWidth(parameters.width); |
912 | + geom.setHeight(parameters.height); |
913 | + |
914 | + // Assume that the buffer size matches the surface size at creation time |
915 | + mBufferSize = geom.size(); |
916 | + platformWindow->QPlatformWindow::setGeometry(geom); |
917 | + QWindowSystemInterface::handleGeometryChange(mWindow, geom); |
918 | + |
919 | + qCDebug(ubuntumirclient) << "Created surface with geometry:" << geom << "title:" << mWindow->title() |
920 | + << "role:" << roleFor(mWindow); |
921 | + qCDebug(ubuntumirclientGraphics) |
922 | + << "Requested format:" << mWindow->requestedFormat() |
923 | + << "\nActual format:" << mFormat |
924 | + << "with associated Mir pixel format:" << mirPixelFormatToStr(mPixelFormat); |
925 | +} |
926 | + |
927 | +UbuntuSurface::~UbuntuSurface() |
928 | +{ |
929 | + if (mEglSurface != EGL_NO_SURFACE) |
930 | + eglDestroySurface(mEglDisplay, mEglSurface); |
931 | + if (mMirSurface) { |
932 | + mir_surface_release_sync(mMirSurface); |
933 | + } |
934 | +} |
935 | + |
936 | +void UbuntuSurface::updateGeometry(const QRect &newGeometry) |
937 | +{ |
938 | + qCDebug(ubuntumirclient,"updateGeometry(window=%p, width=%d, height=%d)", mWindow, |
939 | + newGeometry.width(), newGeometry.height()); |
940 | + |
941 | + Spec spec; |
942 | + if (isMovable(mWindow->type())) { |
943 | + spec = Spec{makeSurfaceSpec(mWindow, mPixelFormat, mParentWindowHandle, mConnection)}; |
944 | + } else { |
945 | + spec = Spec{mir_connection_create_spec_for_changes(mConnection)}; |
946 | + mir_surface_spec_set_width(spec.get(), newGeometry.width()); |
947 | + mir_surface_spec_set_height(spec.get(), newGeometry.height()); |
948 | + } |
949 | mir_surface_apply_spec(mMirSurface, spec.get()); |
950 | } |
951 | |
952 | @@ -600,13 +696,14 @@ |
953 | } |
954 | |
955 | UbuntuWindow::UbuntuWindow(QWindow *w, UbuntuInput *input, UbuntuNativeInterface *native, |
956 | - EGLDisplay eglDisplay, MirConnection *mirConnection) |
957 | + EGLDisplay eglDisplay, MirConnection *mirConnection, UbuntuDebugExtension *debugExt) |
958 | : QObject(nullptr) |
959 | , QPlatformWindow(w) |
960 | , mId(makeId()) |
961 | , mWindowState(w->windowState()) |
962 | , mWindowFlags(w->flags()) |
963 | , mWindowVisible(false) |
964 | + , mDebugExtention(debugExt) |
965 | , mNativeInterface(native) |
966 | , mSurface(new UbuntuSurface{this, eglDisplay, input, mirConnection}) |
967 | , mScale(1.0) |
968 | @@ -688,7 +785,7 @@ |
969 | |
970 | void UbuntuWindow::handleSurfaceVisibilityChanged(bool visible) |
971 | { |
972 | - qCDebug(ubuntumirclient, "handleSurfaceFocused(window=%p)", window()); |
973 | + qCDebug(ubuntumirclient, "handleSurfaceVisibilityChanged(window=%p, visible=%d)", window(), visible); |
974 | |
975 | if (mWindowVisible == visible) return; |
976 | mWindowVisible = visible; |
977 | @@ -737,6 +834,10 @@ |
978 | */ |
979 | void UbuntuWindow::updatePanelHeightHack(bool enable) |
980 | { |
981 | + if ((window()->type() & Qt::WindowType_Mask) != Qt::Window) { // only plain windows get the hack |
982 | + return; |
983 | + } |
984 | + |
985 | QMutexLocker lock(&mMutex); |
986 | |
987 | QRect newGeometry = geometry(); |
988 | @@ -756,13 +857,17 @@ |
989 | void UbuntuWindow::setGeometry(const QRect &rect) |
990 | { |
991 | QMutexLocker lock(&mMutex); |
992 | + |
993 | + if (window()->windowState() == Qt::WindowFullScreen || window()->windowState() == Qt::WindowMaximized) { |
994 | + qCDebug(ubuntumirclient, "setGeometry(window=%p) - not resizing, window is maximized or fullscreen", window()); |
995 | + return; |
996 | + } |
997 | + |
998 | qCDebug(ubuntumirclient, "setGeometry (window=%p, position=(%d, %d)dp, size=(%dx%d)dp)", |
999 | window(), rect.x(), rect.y(), rect.width(), rect.height()); |
1000 | - |
1001 | - //NOTE: mir surfaces cannot be moved by the client so ignore the topLeft coordinates |
1002 | - const auto newSize = rect.size(); |
1003 | - |
1004 | - mSurface->resize(newSize); |
1005 | + QPlatformWindow::setGeometry(rect); // Immediately update internal geometry so Qt believes position updated |
1006 | + |
1007 | + mSurface->updateGeometry(rect); |
1008 | // Note: don't call handleGeometryChange here, wait to see what Mir replies with. |
1009 | } |
1010 | |
1011 | @@ -819,6 +924,15 @@ |
1012 | return mSurface->format(); |
1013 | } |
1014 | |
1015 | +QPoint UbuntuWindow::mapToGlobal(const QPoint &pos) const |
1016 | +{ |
1017 | + if (mDebugExtention) { |
1018 | + return mDebugExtention->mapSurfacePointToScreen(mSurface->mirSurface(), pos); |
1019 | + } else { |
1020 | + return pos; |
1021 | + } |
1022 | +} |
1023 | + |
1024 | void* UbuntuWindow::eglSurface() const |
1025 | { |
1026 | return mSurface->eglSurface(); |
1027 | |
1028 | === modified file 'src/ubuntumirclient/window.h' |
1029 | --- src/ubuntumirclient/window.h 2016-09-21 10:25:33 +0000 |
1030 | +++ src/ubuntumirclient/window.h 2016-10-13 10:20:24 +0000 |
1031 | @@ -27,6 +27,7 @@ |
1032 | |
1033 | #include <EGL/egl.h> |
1034 | |
1035 | +class UbuntuDebugExtension; |
1036 | class UbuntuNativeInterface; |
1037 | class UbuntuInput; |
1038 | class UbuntuScreen; |
1039 | @@ -39,7 +40,7 @@ |
1040 | Q_OBJECT |
1041 | public: |
1042 | UbuntuWindow(QWindow *w, UbuntuInput *input, UbuntuNativeInterface* native, EGLDisplay eglDisplay, |
1043 | - MirConnection *mirConnection); |
1044 | + MirConnection *mirConnection, UbuntuDebugExtension *debugExt); |
1045 | virtual ~UbuntuWindow(); |
1046 | |
1047 | // QPlatformWindow methods. |
1048 | @@ -52,6 +53,7 @@ |
1049 | void propagateSizeHints() override; |
1050 | bool isExposed() const override; |
1051 | |
1052 | + QPoint mapToGlobal(const QPoint &pos) const override; |
1053 | QSurfaceFormat format() const override; |
1054 | |
1055 | // Additional Window properties exposed by NativeInterface |
1056 | @@ -79,6 +81,7 @@ |
1057 | Qt::WindowFlags mWindowFlags; |
1058 | bool mWindowVisible; |
1059 | bool mWindowExposed; |
1060 | + UbuntuDebugExtension *mDebugExtention; |
1061 | UbuntuNativeInterface *mNativeInterface; |
1062 | std::unique_ptr<UbuntuSurface> mSurface; |
1063 | float mScale; |
FAILED: Continuous integration, rev:297 /unity8- jenkins. ubuntu. com/job/ lp-qtubuntu- ci/145/
https:/
Executed test runs:
Click here to trigger a rebuild: /unity8- jenkins. ubuntu. com/job/ lp-qtubuntu- ci/145/ rebuild
https:/