Merge lp:~unity-team/qtubuntu/DPR into lp:qtubuntu

Proposed by Gerry Boland on 2015-04-27
Status: Superseded
Proposed branch: lp:~unity-team/qtubuntu/DPR
Merge into: lp:qtubuntu
Diff against target: 1541 lines (+394/-344)
17 files modified
README (+19/-6)
debian/changelog (+6/-0)
src/ubuntumirclient/backingstore.cpp (+11/-5)
src/ubuntumirclient/clipboard.cpp (+6/-5)
src/ubuntumirclient/cursor.cpp (+1/-3)
src/ubuntumirclient/glcontext.cpp (+11/-30)
src/ubuntumirclient/input.cpp (+27/-36)
src/ubuntumirclient/input.h (+1/-0)
src/ubuntumirclient/integration.cpp (+4/-4)
src/ubuntumirclient/logging.h (+6/-17)
src/ubuntumirclient/plugin.cpp (+3/-0)
src/ubuntumirclient/screen.cpp (+80/-73)
src/ubuntumirclient/screen.h (+2/-0)
src/ubuntumirclient/ubuntumirclient.pro (+2/-1)
src/ubuntumirclient/utils.h (+29/-0)
src/ubuntumirclient/window.cpp (+181/-162)
src/ubuntumirclient/window.h (+5/-2)
To merge this branch: bzr merge lp:~unity-team/qtubuntu/DPR
Reviewer Review Type Date Requested Status
Daniel d'Andrada (community) 2015-04-27 Approve on 2015-10-13
PS Jenkins bot continuous-integration Approve on 2015-10-13
Review via email: mp+257515@code.launchpad.net

This proposal has been superseded by a proposal from 2015-12-17.

Commit Message

Add device pixel ratio support

Description of the Change

 * Are there any related MPs required for this MP to build/function as expected? Please list.
Nothing depends on this directly, but to do a full test, you'll need:
https://code.launchpad.net/~unity-team/qtmir/dpr/+merge/257514
https://code.launchpad.net/~ubuntu-sdk-team/ubuntu-ui-toolkit/dpr/+merge/256470
https://code.launchpad.net/~mzanetti/ubuntu-settings-components/dpr/+merge/253944

 * Did you perform an exploratory manual test run of your code change and any related functionality?
Y
 * If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
N/A

To post a comment you must log in.
lp:~unity-team/qtubuntu/DPR updated on 2015-04-27
261. By Gerry Boland on 2015-04-27

Restore two logging outputs as being debug-build only

PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
lp:~unity-team/qtubuntu/DPR updated on 2015-04-28
262. By Daniel d'Andrada on 2015-04-28

Update copyright years

PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Daniel d'Andrada (dandrader) wrote :

In src/ubuntumirclient/window.cpp

"""
    // Window manager can give us a final size different from what we asked for
    // so let's check what we ended up getting
    {
        MirSurfaceParameters parameters;
        mir_surface_get_parameters(d->surface, &parameters);

        geometry.setWidth(divideAndRoundUp(parameters.width, devicePixelRatio()));
        geometry.setHeight(divideAndRoundUp(parameters.height, devicePixelRatio()));

        DLOG("[ubuntumirclient QPA] created surface has pixel size (%d, %d) and device-pixel size (%d, %d)",
                parameters.width, parameters.height, geometry.width(), geometry.height());
    }

    // Assume that the buffer size matches the surface size at creation time
    d->bufferSize = geometry.size();
"""

Here bufferSize will be initialized with a scaled size, but it should have the real size.
So bufferSize initialization should probably moved above the line "// Window manager can give us a final size different[...]".

review: Needs Fixing
lp:~unity-team/qtubuntu/DPR updated on 2015-04-30
263. By Gerry Boland on 2015-04-30

Error in mixing pixels & devicepixels for initial surface size, rectified

264. By Gerry Boland on 2015-04-30

Use suffix "Px" to help distinguish pixel from device pixel

PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Gerry Boland (gerboland) wrote :

@Daniel, you were correct, I had mixed up a case where pixel != devicePixel. Since this is far too easy to screw up, I thought it a good idea to append "Px" to any variable that is in pixels, and so any other geometry is in device pixels. I think it helps distinguish them.

Daniel d'Andrada (dandrader) wrote :

In src/ubuntumirclient/window.cpp:

"""
    DLOG("[ubuntumirclient QPA] creating surface at (%d, %d) with pixel size (%d, %d) with title '%s'\n",
            d->bufferSizePx.x(), d->bufferSizePx.y(), d->bufferSizePx.width(), d->bufferSizePx.height(), title.data());
"""

bufferSizePx has no x() and y() (as it's a QSize, not a QRect). I think code won't build if you enable debug logging?

review: Needs Fixing
lp:~unity-team/qtubuntu/DPR updated on 2015-05-05
265. By Gerry Boland on 2015-05-05

Fix debug build fails

PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
lp:~unity-team/qtubuntu/DPR updated on 2015-06-17
266. By Gerry Boland on 2015-06-17

Merge trunk

PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
lp:~unity-team/qtubuntu/DPR updated on 2015-07-10
267. By Gerry Boland on 2015-07-10

Merge trunk

268. By Gerry Boland on 2015-07-10

Minor terminology clarification

PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~unity-team/qtubuntu/DPR updated on 2015-07-10
269. By Gerry Boland on 2015-07-10

Merge trunk again

PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~unity-team/qtubuntu/DPR updated on 2015-07-10
270. By Gerry Boland on 2015-07-10

Fix ftbfs

PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~unity-team/qtubuntu/DPR updated on 2015-07-14
271. By Gerry Boland on 2015-07-14

Consolidate variable names, fix build

PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
lp:~unity-team/qtubuntu/DPR updated on 2015-07-14
272. By Gerry Boland on 2015-07-14

Bump version

PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
lp:~unity-team/qtubuntu/DPR updated on 2015-08-12
273. By Gerry Boland on 2015-08-12

Merge trunk

PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
lp:~unity-team/qtubuntu/DPR updated on 2015-08-24
274. By Gerry Boland on 2015-08-24

Merge trunk

PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
lp:~unity-team/qtubuntu/DPR updated on 2015-09-01
275. By Gerry Boland on 2015-09-01

Merge trunk & fix conflicts

PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
lp:~unity-team/qtubuntu/DPR updated on 2015-09-08
276. By Gerry Boland on 2015-09-08

Resized surface should consider dpr when notifying qt of final size

PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
lp:~unity-team/qtubuntu/DPR updated on 2015-10-12
277. By Gerry Boland on 2015-10-12

Merge trunk

278. By Gerry Boland on 2015-10-12

Bump changelog entry

PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Gerry Boland (gerboland) wrote :

Ok, should be good to go

lp:~unity-team/qtubuntu/DPR updated on 2015-10-13
279. By Gerry Boland on 2015-10-13

Clarify terminology

280. By Gerry Boland on 2015-10-13

Another

Daniel d'Andrada (dandrader) wrote :

Looks good to me (didn't test yet).

review: Approve (code)
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Daniel d'Andrada (dandrader) wrote :

And it works fine as well.

review: Approve
lp:~unity-team/qtubuntu/DPR updated on 2016-01-05
281. By Gerry Boland on 2015-12-11

Updated against latest qtmir trunk

282. By Gerry Boland on 2015-12-11

Minor cleanups

283. By Gerry Boland on 2015-12-12

Merge trunk

284. By Gerry Boland on 2015-12-15

Typo making initial surface geometry incorrect

285. By Gerry Boland on 2015-12-15

Fix camera app sizing - only tell qt about geometry change after mir replies, do not assume it will occur

286. By Gerry Boland on 2015-12-15

Fix surfaces positioning when going to & from fullscreen

287. By Gerry Boland on 2015-12-16

Fix bug in panel-height hack where fullscreen surface could actually have the hack enabled. Also do little renaming & typo fix

288. By Gerry Boland on 2015-12-16

Merge Daniel's categroy logging branch

289. By Gerry Boland on 2015-12-17

Merge updated loggingCategory

290. By Gerry Boland on 2015-12-17

Bad merge, fixing

291. By Gerry Boland on 2016-01-05

Merge loggingCategory with merged trunk

292. By Gerry Boland on 2016-01-05

Bump changelog date to suit

Unmerged revisions

292. By Gerry Boland on 2016-01-05

Bump changelog date to suit

291. By Gerry Boland on 2016-01-05

Merge loggingCategory with merged trunk

290. By Gerry Boland on 2015-12-17

Bad merge, fixing

289. By Gerry Boland on 2015-12-17

Merge updated loggingCategory

288. By Gerry Boland on 2015-12-16

Merge Daniel's categroy logging branch

287. By Gerry Boland on 2015-12-16

Fix bug in panel-height hack where fullscreen surface could actually have the hack enabled. Also do little renaming & typo fix

286. By Gerry Boland on 2015-12-15

Fix surfaces positioning when going to & from fullscreen

285. By Gerry Boland on 2015-12-15

Fix camera app sizing - only tell qt about geometry change after mir replies, do not assume it will occur

284. By Gerry Boland on 2015-12-15

Typo making initial surface geometry incorrect

283. By Gerry Boland on 2015-12-12

Merge trunk

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'README'
2--- README 2014-06-18 23:10:00 +0000
3+++ README 2015-12-17 10:58:59 +0000
4@@ -1,15 +1,15 @@
5 1. Description
6 2. Running
7- 3. Building
8- 4. QPA native interface
9- 5. QPA properties
10+ 3. Debug messages and logging
11+ 4. Building
12+ 5. QPA native interface
13
14
15 1. Description
16 --------------
17
18 QtUbuntu contains a QPA (Qt Platform Abstraction) plugin based on the Ubuntu
19- Platform API
20+ Platform API and Mir client API
21
22
23 2 Running
24@@ -39,7 +39,20 @@
25 QTUBUNTU_ICON_THEME: Specifies the default icon theme name.
26
27
28-3. Building
29+3 Debug messages and logging
30+----------------------------
31+
32+ QtUbuntu uses Qt logging categories (see QLoggingCategory class documentation
33+ for more information). By default warnings and critical messages are
34+ logged and debug messages are disabled. QtUbuntu provides the following
35+ logging categories:
36+
37+ * ubuntumirclient.input - Messages related to input and other Mir events.
38+ * ubuntumirclient.swapBuffers - Messages related to surface buffer swapping.
39+ * ubuntumirclient - For all other messages.
40+
41+
42+4. Building
43 -----------
44
45 To compile QtUbuntu, create the makefiles with qmake and build with
46@@ -54,7 +67,7 @@
47 $ qmake CONFIG+=debug
48
49
50-4. QPA native interface
51+5. QPA native interface
52 -----------------------
53
54 The QPA plugin exposes a native interface allowing to retrieve
55
56=== modified file 'debian/changelog'
57--- debian/changelog 2015-12-07 16:21:01 +0000
58+++ debian/changelog 2015-12-17 10:58:59 +0000
59@@ -1,3 +1,9 @@
60+qtubuntu (0.63) UNRELEASED; urgency=medium
61+
62+ * Add support for Qt5.4's devicePixelRatio UI scaling mechanism
63+
64+ -- Gerry Boland <gerry.boland@canonical.com> Mon, 12 Oct 2015 12:44:27 +0100
65+
66 qtubuntu (0.62+16.04.20151207-0ubuntu1) xenial; urgency=medium
67
68 [ Daniel d'Andrada ]
69
70=== modified file 'src/ubuntumirclient/backingstore.cpp'
71--- src/ubuntumirclient/backingstore.cpp 2014-12-04 12:29:39 +0000
72+++ src/ubuntumirclient/backingstore.cpp 2015-12-17 10:58:59 +0000
73@@ -1,5 +1,5 @@
74 /*
75- * Copyright (C) 2014 Canonical, Ltd.
76+ * Copyright (C) 2014-2015 Canonical, Ltd.
77 *
78 * This program is free software: you can redistribute it and/or modify it under
79 * the terms of the GNU Lesser General Public License version 3, as published by
80@@ -43,8 +43,10 @@
81 {
82 Q_UNUSED(region);
83 Q_UNUSED(offset);
84+ const int dpr = int(window->devicePixelRatio());
85+
86 mContext->makeCurrent(window);
87- glViewport(0, 0, window->width(), window->height());
88+ glViewport(0, 0, window->width() * dpr, window->height() * dpr);
89
90 updateTexture();
91
92@@ -75,12 +77,14 @@
93
94 QRegion fixed;
95 QRect imageRect = mImage.rect();
96+ const int dpr = int(window()->devicePixelRatio());
97
98- /* Following code taken from QEGLPlatformBackingStore under the terms of the Lesser GPL v2.1 licence
99+ /* Following code a modified form of that in QEGLPlatformBackingStore, used under the terms of the Lesser GPL v2.1 licence
100 * Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). */
101 Q_FOREACH (const QRect &rect, mDirty.rects()) {
102+ QRect scaledRect(rect.topLeft() * dpr, rect.size() * dpr);
103 // intersect with image rect to be sure
104- QRect r = imageRect & rect;
105+ QRect r = imageRect & scaledRect;
106
107 // if the rect is wide enough it is cheaper to just extend it instead of doing an image copy
108 if (r.width() >= imageRect.width() / 2) {
109@@ -115,7 +119,9 @@
110
111 void UbuntuBackingStore::resize(const QSize& size, const QRegion& /*staticContents*/)
112 {
113- mImage = QImage(size, QImage::Format_RGB32);
114+ const int dpr = int(window()->devicePixelRatio());
115+ mImage = QImage(size * dpr, QImage::Format_RGB32);
116+ mImage.setDevicePixelRatio(dpr);
117
118 if (mTexture->isCreated())
119 mTexture->destroy();
120
121=== modified file 'src/ubuntumirclient/clipboard.cpp'
122--- src/ubuntumirclient/clipboard.cpp 2015-11-17 14:49:30 +0000
123+++ src/ubuntumirclient/clipboard.cpp 2015-12-17 10:58:59 +0000
124@@ -15,6 +15,7 @@
125 */
126
127 #include "clipboard.h"
128+#include "logging.h"
129
130 #include <QtCore/QMimeData>
131 #include <QtCore/QStringList>
132@@ -80,7 +81,7 @@
133
134 QDBusPendingReply<QByteArray> reply = *call;
135 if (reply.isError()) {
136- qCritical("UbuntuClipboard - Failed to get system clipboard contents via D-Bus. %s, %s",
137+ qCCritical(ubuntumirclient, "Failed to get system clipboard contents via D-Bus. %s, %s",
138 qPrintable(reply.error().name()), qPrintable(reply.error().message()));
139 // TODO: Might try again later a number of times...
140 } else {
141@@ -94,7 +95,7 @@
142 {
143 QDBusPendingReply<void> reply = *call;
144 if (reply.isError()) {
145- qCritical("UbuntuClipboard - Failed to set the system clipboard contents via D-Bus. %s, %s",
146+ qCCritical(ubuntumirclient, "Failed to set the system clipboard contents via D-Bus. %s, %s",
147 qPrintable(reply.error().name()), qPrintable(reply.error().message()));
148 // TODO: Might try again later a number of times...
149 }
150@@ -113,7 +114,7 @@
151 mIsOutdated = false;
152 emitChanged(QClipboard::Clipboard);
153 } else {
154- qWarning("UbuntuClipboard - Got invalid serialized mime data. Ignoring it.");
155+ qCWarning(ubuntumirclient) << "Got invalid serialized mime data. Ignoring it.";
156 }
157 }
158
159@@ -128,7 +129,7 @@
160 QStringLiteral("ContentsChanged"),
161 this, SLOT(updateMimeData(QByteArray)));
162 if (!ok) {
163- qCritical("UbuntuClipboard - Failed to connect to ContentsChanged signal form the D-Bus system clipboard.");
164+ qCCritical(ubuntumirclient) << "Failed to connect to ContentsChanged signal form the D-Bus system clipboard.";
165 }
166
167 mDBusClipboard = new QDBusInterface(QStringLiteral("com.canonical.QtMir"),
168@@ -176,7 +177,7 @@
169 }
170 }
171 } else {
172- qWarning("UbuntuClipboard: Not sending contents (%d bytes) to the global clipboard as it's"
173+ qCWarning(ubuntumirclient, "Not sending contents (%d bytes) to the global clipboard as it's"
174 " bigger than the maximum allowed size of %d bytes", bufferSize, maxBufferSize);
175 }
176
177
178=== modified file 'src/ubuntumirclient/cursor.cpp'
179--- src/ubuntumirclient/cursor.cpp 2015-11-24 13:12:48 +0000
180+++ src/ubuntumirclient/cursor.cpp 2015-12-17 10:58:59 +0000
181@@ -49,7 +49,6 @@
182 }
183
184 namespace {
185-#if !defined(QT_NO_DEBUG)
186 const char *qtCursorShapeToStr(Qt::CursorShape shape)
187 {
188 switch(shape) {
189@@ -103,7 +102,6 @@
190 return "???";
191 }
192 }
193-#endif // !defined(QT_NO_DEBUG)
194 } // anonymous namespace
195
196 void UbuntuCursor::changeCursor(QCursor *windowCursor, QWindow *window)
197@@ -120,7 +118,7 @@
198
199
200 if (windowCursor) {
201- DLOG("[ubuntumirclient QPA] changeCursor shape=%s, window=%p\n", qtCursorShapeToStr(windowCursor->shape()), window);
202+ qCDebug(ubuntumirclient, "changeCursor shape=%s, window=%p", qtCursorShapeToStr(windowCursor->shape()), window);
203 if (!windowCursor->pixmap().isNull()) {
204 configureMirCursorWithPixmapQCursor(surface, *windowCursor);
205 } else if (windowCursor->shape() == Qt::BitmapCursor) {
206
207=== modified file 'src/ubuntumirclient/glcontext.cpp'
208--- src/ubuntumirclient/glcontext.cpp 2015-10-23 19:29:38 +0000
209+++ src/ubuntumirclient/glcontext.cpp 2015-12-17 10:58:59 +0000
210@@ -1,5 +1,5 @@
211 /*
212- * Copyright (C) 2014 Canonical, Ltd.
213+ * Copyright (C) 2014-2015 Canonical, Ltd.
214 *
215 * This program is free software: you can redistribute it and/or modify it under
216 * the terms of the GNU Lesser General Public License version 3, as published by
217@@ -19,24 +19,22 @@
218 #include "logging.h"
219 #include <QtPlatformSupport/private/qeglconvenience_p.h>
220
221-#if !defined(QT_NO_DEBUG)
222 static void printOpenGLESConfig() {
223 static bool once = true;
224 if (once) {
225 const char* string = (const char*) glGetString(GL_VENDOR);
226- LOG("OpenGL ES vendor: %s", string);
227+ qCDebug(ubuntumirclient, "OpenGL ES vendor: %s", string);
228 string = (const char*) glGetString(GL_RENDERER);
229- LOG("OpenGL ES renderer: %s", string);
230+ qCDebug(ubuntumirclient, "OpenGL ES renderer: %s", string);
231 string = (const char*) glGetString(GL_VERSION);
232- LOG("OpenGL ES version: %s", string);
233+ qCDebug(ubuntumirclient, "OpenGL ES version: %s", string);
234 string = (const char*) glGetString(GL_SHADING_LANGUAGE_VERSION);
235- LOG("OpenGL ES Shading Language version: %s", string);
236+ qCDebug(ubuntumirclient, "OpenGL ES Shading Language version: %s", string);
237 string = (const char*) glGetString(GL_EXTENSIONS);
238- LOG("OpenGL ES extensions: %s", string);
239+ qCDebug(ubuntumirclient, "OpenGL ES extensions: %s", string);
240 once = false;
241 }
242 }
243-#endif
244
245 static EGLenum api_in_use()
246 {
247@@ -62,7 +60,7 @@
248
249 mEglContext = eglCreateContext(mEglDisplay, screen->eglConfig(), share ? share->eglContext() : EGL_NO_CONTEXT,
250 attribs.constData());
251- DASSERT(mEglContext != EGL_NO_CONTEXT);
252+ Q_ASSERT(mEglContext != EGL_NO_CONTEXT);
253 }
254
255 UbuntuOpenGLContext::~UbuntuOpenGLContext()
256@@ -72,28 +70,20 @@
257
258 bool UbuntuOpenGLContext::makeCurrent(QPlatformSurface* surface)
259 {
260- DASSERT(surface->surface()->surfaceType() == QSurface::OpenGLSurface);
261+ Q_ASSERT(surface->surface()->surfaceType() == QSurface::OpenGLSurface);
262 EGLSurface eglSurface = static_cast<UbuntuWindow*>(surface)->eglSurface();
263-#if defined(QT_NO_DEBUG)
264- eglBindAPI(api_in_use());
265- eglMakeCurrent(mEglDisplay, eglSurface, eglSurface, mEglContext);
266-#else
267 ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE);
268 ASSERT(eglMakeCurrent(mEglDisplay, eglSurface, eglSurface, mEglContext) == EGL_TRUE);
269- printOpenGLESConfig();
270-#endif
271+ if (ubuntumirclient().isDebugEnabled()) {
272+ printOpenGLESConfig();
273+ }
274 return true;
275 }
276
277 void UbuntuOpenGLContext::doneCurrent()
278 {
279-#if defined(QT_NO_DEBUG)
280- eglBindAPI(api_in_use());
281- eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
282-#else
283 ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE);
284 ASSERT(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) == EGL_TRUE);
285-#endif
286 }
287
288 void UbuntuOpenGLContext::swapBuffers(QPlatformSurface* surface)
289@@ -101,23 +91,14 @@
290 UbuntuWindow *ubuntuWindow = static_cast<UbuntuWindow*>(surface);
291
292 EGLSurface eglSurface = ubuntuWindow->eglSurface();
293-#if defined(QT_NO_DEBUG)
294- eglBindAPI(api_in_use());
295- eglSwapBuffers(mEglDisplay, eglSurface);
296-#else
297 ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE);
298 ASSERT(eglSwapBuffers(mEglDisplay, eglSurface) == EGL_TRUE);
299-#endif
300
301 ubuntuWindow->onSwapBuffersDone();
302 }
303
304 void (*UbuntuOpenGLContext::getProcAddress(const QByteArray& procName)) ()
305 {
306-#if defined(QT_NO_DEBUG)
307- eglBindAPI(api_in_use());
308-#else
309 ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE);
310-#endif
311 return eglGetProcAddress(procName.constData());
312 }
313
314=== modified file 'src/ubuntumirclient/input.cpp'
315--- src/ubuntumirclient/input.cpp 2015-12-07 16:20:47 +0000
316+++ src/ubuntumirclient/input.cpp 2015-12-17 10:58:59 +0000
317@@ -24,9 +24,7 @@
318 #include "orientationchangeevent_p.h"
319
320 // Qt
321-#if !defined(QT_NO_DEBUG)
322 #include <QtCore/QThread>
323-#endif
324 #include <QtCore/qglobal.h>
325 #include <QtCore/QCoreApplication>
326 #include <private/qguiapplication_p.h>
327@@ -38,7 +36,7 @@
328
329 #include <mir_toolkit/mir_client_library.h>
330
331-#define LOG_EVENTS 0
332+Q_LOGGING_CATEGORY(ubuntumirclientInput, "ubuntumirclient.input", QtWarningMsg)
333
334 // XKB Keysyms which do not map directly to Qt types (i.e. Unicode points)
335 static const uint32_t KeyTable[] = {
336@@ -158,7 +156,6 @@
337 // Qt will take care of deleting mTouchDevice.
338 }
339
340-#if (LOG_EVENTS != 0)
341 static const char* nativeEventTypeToStr(MirEventType t)
342 {
343 switch (t)
344@@ -180,20 +177,18 @@
345 case mir_event_type_input:
346 return "mir_event_type_input";
347 default:
348- DLOG("Invalid event type %d", t);
349 return "invalid";
350 }
351 }
352-#endif // LOG_EVENTS != 0
353
354 void UbuntuInput::customEvent(QEvent* event)
355 {
356- DASSERT(QThread::currentThread() == thread());
357+ Q_ASSERT(QThread::currentThread() == thread());
358 UbuntuEvent* ubuntuEvent = static_cast<UbuntuEvent*>(event);
359 const MirEvent *nativeEvent = ubuntuEvent->nativeEvent;
360
361 if ((ubuntuEvent->window == nullptr) || (ubuntuEvent->window->window() == nullptr)) {
362- qWarning() << "Attempted to deliver an event to a non-existent window, ignoring.";
363+ qCWarning(ubuntumirclient) << "Attempted to deliver an event to a non-existent window, ignoring.";
364 return;
365 }
366
367@@ -202,13 +197,11 @@
368 if (QWindowSystemInterface::handleNativeEvent(
369 ubuntuEvent->window->window(), mEventFilterType,
370 const_cast<void *>(static_cast<const void *>(nativeEvent)), &result) == true) {
371- DLOG("event filtered out by native interface");
372+ qCDebug(ubuntumirclient, "event filtered out by native interface");
373 return;
374 }
375
376- #if (LOG_EVENTS != 0)
377- LOG("UbuntuInput::customEvent(type=%s)", nativeEventTypeToStr(mir_event_get_type(nativeEvent)));
378- #endif
379+ qCDebug(ubuntumirclientInput, "customEvent(type=%s)", nativeEventTypeToStr(mir_event_get_type(nativeEvent)));
380
381 // Event dispatching.
382 switch (mir_event_get_type(nativeEvent))
383@@ -245,7 +238,7 @@
384 QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationActive);
385 }
386 } else if(!mPendingFocusGainedEvents) {
387- DLOG("[ubuntumirclient QPA] No windows have focus");
388+ qCDebug(ubuntumirclient, "No windows have focus");
389 QWindowSystemInterface::handleWindowActivated(nullptr, Qt::ActiveWindowFocusReason);
390 if (qGuiApp->applicationState() == Qt::ApplicationActive) {
391 QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationInactive);
392@@ -261,7 +254,7 @@
393 QWindowSystemInterface::handleCloseEvent(ubuntuEvent->window->window());
394 break;
395 default:
396- DLOG("unhandled event type: %d", static_cast<int>(mir_event_get_type(nativeEvent)));
397+ qCDebug(ubuntumirclient, "unhandled event type: %d", static_cast<int>(mir_event_get_type(nativeEvent)));
398 }
399 }
400
401@@ -318,6 +311,7 @@
402 const QRect kWindowGeometry = window->geometry();
403 QList<QWindowSystemInterface::TouchPoint> touchPoints;
404
405+ const int dpr = int(window->devicePixelRatio());
406
407 // TODO: Is it worth setting the Qt::TouchPointStationary ones? Currently they are left
408 // as Qt::TouchPointMoved
409@@ -325,10 +319,10 @@
410 for (unsigned int i = 0; i < kPointerCount; ++i) {
411 QWindowSystemInterface::TouchPoint touchPoint;
412
413- const float kX = mir_touch_event_axis_value(tev, i, mir_touch_axis_x) + kWindowGeometry.x();
414- const float kY = mir_touch_event_axis_value(tev, i, mir_touch_axis_y) + kWindowGeometry.y(); // see bug lp:1346633 workaround comments elsewhere
415- const float kW = mir_touch_event_axis_value(tev, i, mir_touch_axis_touch_major);
416- const float kH = mir_touch_event_axis_value(tev, i, mir_touch_axis_touch_minor);
417+ const float kX = mir_touch_event_axis_value(tev, i, mir_touch_axis_x) / dpr + kWindowGeometry.x();
418+ const float kY = mir_touch_event_axis_value(tev, i, mir_touch_axis_y) / dpr + kWindowGeometry.y(); // see bug lp:1346633 workaround comments elsewhere
419+ const float kW = mir_touch_event_axis_value(tev, i, mir_touch_axis_touch_major) / dpr;
420+ const float kH = mir_touch_event_axis_value(tev, i, mir_touch_axis_touch_minor) / dpr;
421 const float kP = mir_touch_event_axis_value(tev, i, mir_touch_axis_pressure);
422 touchPoint.id = mir_touch_event_id(tev, i);
423 touchPoint.normalPosition = QPointF(kX / kWindowGeometry.width(), kY / kWindowGeometry.height());
424@@ -425,7 +419,7 @@
425 QKeyEvent qKeyEvent(keyType, sym, modifiers, text, is_auto_rep);
426 qKeyEvent.setTimestamp(timestamp);
427 if (context->filterEvent(&qKeyEvent)) {
428- DLOG("key event filtered out by input context");
429+ qCDebug(ubuntumirclient, "key event filtered out by input context");
430 return;
431 }
432 }
433@@ -455,14 +449,16 @@
434
435 void UbuntuInput::dispatchPointerEvent(UbuntuWindow *platformWindow, const MirInputEvent *ev)
436 {
437- auto window = platformWindow->window();
438- auto timestamp = mir_input_event_get_event_time(ev) / 1000000;
439-
440- auto pev = mir_input_event_get_pointer_event(ev);
441- auto action = mir_pointer_event_action(pev);
442- auto localPoint = QPointF(mir_pointer_event_axis_value(pev, mir_pointer_axis_x),
443- mir_pointer_event_axis_value(pev, mir_pointer_axis_y));
444- auto modifiers = qt_modifiers_from_mir(mir_pointer_event_modifiers(pev));
445+ const int dpr = int(platformWindow->devicePixelRatio());
446+ const auto window = platformWindow->window();
447+ const auto timestamp = mir_input_event_get_event_time(ev) / 1000000;
448+
449+ const auto pev = mir_input_event_get_pointer_event(ev);
450+ const auto action = mir_pointer_event_action(pev);
451+
452+ const auto modifiers = qt_modifiers_from_mir(mir_pointer_event_modifiers(pev));
453+ const auto localPoint = QPointF(mir_pointer_event_axis_value(pev, mir_pointer_axis_x) / dpr,
454+ mir_pointer_event_axis_value(pev, mir_pointer_axis_y) / dpr);
455
456 switch (action) {
457 case mir_pointer_action_button_up:
458@@ -489,11 +485,10 @@
459 QWindowSystemInterface::handleLeaveEvent(window);
460 break;
461 default:
462- DLOG("Unrecognized pointer event");
463+ qCDebug(ubuntumirclient, "Unrecognized pointer event");
464 }
465 }
466
467-#if (LOG_EVENTS != 0)
468 static const char* nativeOrientationDirectionToStr(MirOrientation orientation)
469 {
470 switch (orientation) {
471@@ -513,18 +508,14 @@
472 return "INVALID!";
473 }
474 }
475-#endif
476
477 void UbuntuInput::dispatchOrientationEvent(QWindow *window, const MirOrientationEvent *event)
478 {
479 MirOrientation mir_orientation = mir_orientation_event_get_direction(event);
480- #if (LOG_EVENTS != 0)
481- // Orientation event logging.
482- LOG("ORIENTATION direction: %s", nativeOrientationDirectionToStr(mir_orientation));
483- #endif
484+ qCDebug(ubuntumirclientInput, "orientation direction: %s", nativeOrientationDirectionToStr(mir_orientation));
485
486 if (!window->screen()) {
487- DLOG("Window has no associated screen, dropping orientation event");
488+ qCDebug(ubuntumirclient, "Window has no associated screen, dropping orientation event");
489 return;
490 }
491
492@@ -543,7 +534,7 @@
493 orientation = OrientationChangeEvent::RightUp;
494 break;
495 default:
496- DLOG("No such orientation %d", mir_orientation);
497+ qCDebug(ubuntumirclient, "No such orientation %d", mir_orientation);
498 return;
499 }
500
501
502=== modified file 'src/ubuntumirclient/input.h'
503--- src/ubuntumirclient/input.h 2015-10-24 04:56:44 +0000
504+++ src/ubuntumirclient/input.h 2015-12-17 10:58:59 +0000
505@@ -20,6 +20,7 @@
506 // Qt
507 #include <qpa/qwindowsysteminterface.h>
508 #include <QAtomicInt>
509+#include <QLoggingCategory>
510
511 #include <mir_toolkit/mir_client_library.h>
512
513
514=== modified file 'src/ubuntumirclient/integration.cpp'
515--- src/ubuntumirclient/integration.cpp 2015-11-20 15:43:25 +0000
516+++ src/ubuntumirclient/integration.cpp 2015-12-17 10:58:59 +0000
517@@ -45,7 +45,7 @@
518 {
519 Q_UNUSED(options)
520 Q_UNUSED(context)
521- DASSERT(context != NULL);
522+ Q_ASSERT(context != NULL);
523 if (qGuiApp->focusWindow()) {
524 QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationActive);
525 } else {
526@@ -56,13 +56,13 @@
527 static void aboutToStopCallback(UApplicationArchive *archive, void* context)
528 {
529 Q_UNUSED(archive)
530- DASSERT(context != NULL);
531+ Q_ASSERT(context != NULL);
532 UbuntuClientIntegration* integration = static_cast<UbuntuClientIntegration*>(context);
533 QPlatformInputContext *inputContext = integration->inputContext();
534 if (inputContext) {
535 inputContext->hideInputPanel();
536 } else {
537- qWarning("UbuntuClientIntegration aboutToStopCallback(): no input context");
538+ qCWarning(ubuntumirclient) << "aboutToStopCallback(): no input context";
539 }
540 QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationSuspended);
541 }
542@@ -184,7 +184,7 @@
543 if (qEnvironmentVariableIsEmpty("QTUBUNTU_NO_THREADED_OPENGL")) {
544 return true;
545 } else {
546- DLOG("ubuntumirclient: disabled threaded OpenGL");
547+ qCDebug(ubuntumirclient, "disabled threaded OpenGL");
548 return false;
549 }
550 case MultipleWindows:
551
552=== modified file 'src/ubuntumirclient/logging.h'
553--- src/ubuntumirclient/logging.h 2014-06-18 23:10:00 +0000
554+++ src/ubuntumirclient/logging.h 2015-12-17 10:58:59 +0000
555@@ -1,5 +1,5 @@
556 /*
557- * Copyright (C) 2014 Canonical, Ltd.
558+ * Copyright (C) 2014-2015 Canonical, Ltd.
559 *
560 * This program is free software: you can redistribute it and/or modify it under
561 * the terms of the GNU Lesser General Public License version 3, as published by
562@@ -17,23 +17,12 @@
563 #ifndef QUBUNTULOGGING_H
564 #define QUBUNTULOGGING_H
565
566-// Logging and assertion macros.
567-#define LOG(...) qDebug(__VA_ARGS__)
568-#define LOG_IF(cond,...) do { if (cond) qDebug(__VA_ARGS__); } while(0)
569+#include <QLoggingCategory>
570+
571 #define ASSERT(cond) ((!(cond)) ? qt_assert(#cond,__FILE__,__LINE__) : qt_noop())
572-#define NOT_REACHED() qt_assert("Not reached!",__FILE__,__LINE__)
573
574-// Logging and assertion macros are compiled out for release builds.
575-#if !defined(QT_NO_DEBUG)
576-#define DLOG(...) LOG(__VA_ARGS__)
577-#define DLOG_IF(cond,...) LOG_IF((cond), __VA_ARGS__)
578-#define DASSERT(cond) ASSERT((cond))
579-#define DNOT_REACHED() NOT_REACHED()
580-#else
581-#define DLOG(...) qt_noop()
582-#define DLOG_IF(cond,...) qt_noop()
583-#define DASSERT(cond) qt_noop()
584-#define DNOT_REACHED() qt_noop()
585-#endif
586+Q_DECLARE_LOGGING_CATEGORY(ubuntumirclient)
587+Q_DECLARE_LOGGING_CATEGORY(ubuntumirclientBufferSwap)
588+Q_DECLARE_LOGGING_CATEGORY(ubuntumirclientInput)
589
590 #endif // QUBUNTULOGGING_H
591
592=== modified file 'src/ubuntumirclient/plugin.cpp'
593--- src/ubuntumirclient/plugin.cpp 2015-09-29 13:09:01 +0000
594+++ src/ubuntumirclient/plugin.cpp 2015-12-17 10:58:59 +0000
595@@ -16,6 +16,9 @@
596
597 #include "plugin.h"
598 #include "integration.h"
599+#include "logging.h"
600+
601+Q_LOGGING_CATEGORY(ubuntumirclient, "ubuntumirclient", QtWarningMsg)
602
603 QStringList UbuntuMirClientIntegrationPlugin::keys() const
604 {
605
606=== modified file 'src/ubuntumirclient/screen.cpp'
607--- src/ubuntumirclient/screen.cpp 2015-11-23 11:10:24 +0000
608+++ src/ubuntumirclient/screen.cpp 2015-12-17 10:58:59 +0000
609@@ -18,6 +18,7 @@
610 #include "screen.h"
611 #include "logging.h"
612 #include "orientationchangeevent_p.h"
613+#include "utils.h"
614
615 #include <mir_toolkit/mir_client_library.h>
616
617@@ -33,8 +34,6 @@
618
619 static const int kSwapInterval = 1;
620
621-#if !defined(QT_NO_DEBUG)
622-
623 static const char *orientationToStr(Qt::ScreenOrientation orientation) {
624 switch (orientation) {
625 case Qt::PrimaryOrientation:
626@@ -53,52 +52,62 @@
627 }
628
629 static void printEglConfig(EGLDisplay display, EGLConfig config) {
630- DASSERT(display != EGL_NO_DISPLAY);
631- DASSERT(config != nullptr);
632- static const struct { const EGLint attrib; const char* name; } kAttribs[] = {
633- { EGL_BUFFER_SIZE, "EGL_BUFFER_SIZE" },
634- { EGL_ALPHA_SIZE, "EGL_ALPHA_SIZE" },
635- { EGL_BLUE_SIZE, "EGL_BLUE_SIZE" },
636- { EGL_GREEN_SIZE, "EGL_GREEN_SIZE" },
637- { EGL_RED_SIZE, "EGL_RED_SIZE" },
638- { EGL_DEPTH_SIZE, "EGL_DEPTH_SIZE" },
639- { EGL_STENCIL_SIZE, "EGL_STENCIL_SIZE" },
640- { EGL_CONFIG_CAVEAT, "EGL_CONFIG_CAVEAT" },
641- { EGL_CONFIG_ID, "EGL_CONFIG_ID" },
642- { EGL_LEVEL, "EGL_LEVEL" },
643- { EGL_MAX_PBUFFER_HEIGHT, "EGL_MAX_PBUFFER_HEIGHT" },
644- { EGL_MAX_PBUFFER_PIXELS, "EGL_MAX_PBUFFER_PIXELS" },
645- { EGL_MAX_PBUFFER_WIDTH, "EGL_MAX_PBUFFER_WIDTH" },
646- { EGL_NATIVE_RENDERABLE, "EGL_NATIVE_RENDERABLE" },
647- { EGL_NATIVE_VISUAL_ID, "EGL_NATIVE_VISUAL_ID" },
648- { EGL_NATIVE_VISUAL_TYPE, "EGL_NATIVE_VISUAL_TYPE" },
649- { EGL_SAMPLES, "EGL_SAMPLES" },
650- { EGL_SAMPLE_BUFFERS, "EGL_SAMPLE_BUFFERS" },
651- { EGL_SURFACE_TYPE, "EGL_SURFACE_TYPE" },
652- { EGL_TRANSPARENT_TYPE, "EGL_TRANSPARENT_TYPE" },
653- { EGL_TRANSPARENT_BLUE_VALUE, "EGL_TRANSPARENT_BLUE_VALUE" },
654- { EGL_TRANSPARENT_GREEN_VALUE, "EGL_TRANSPARENT_GREEN_VALUE" },
655- { EGL_TRANSPARENT_RED_VALUE, "EGL_TRANSPARENT_RED_VALUE" },
656- { EGL_BIND_TO_TEXTURE_RGB, "EGL_BIND_TO_TEXTURE_RGB" },
657- { EGL_BIND_TO_TEXTURE_RGBA, "EGL_BIND_TO_TEXTURE_RGBA" },
658- { EGL_MIN_SWAP_INTERVAL, "EGL_MIN_SWAP_INTERVAL" },
659- { EGL_MAX_SWAP_INTERVAL, "EGL_MAX_SWAP_INTERVAL" },
660- { -1, NULL }
661- };
662- const char* string = eglQueryString(display, EGL_VENDOR);
663- LOG("EGL vendor: %s", string);
664- string = eglQueryString(display, EGL_VERSION);
665- LOG("EGL version: %s", string);
666- string = eglQueryString(display, EGL_EXTENSIONS);
667- LOG("EGL extensions: %s", string);
668- LOG("EGL configuration attibutes:");
669- for (int index = 0; kAttribs[index].attrib != -1; index++) {
670- EGLint value;
671- if (eglGetConfigAttrib(display, config, kAttribs[index].attrib, &value))
672- LOG(" %s: %d", kAttribs[index].name, static_cast<int>(value));
673- }
674+ Q_ASSERT(display != EGL_NO_DISPLAY);
675+ Q_ASSERT(config != nullptr);
676+
677+ static const struct { const EGLint attrib; const char* name; } kAttribs[] = {
678+ { EGL_BUFFER_SIZE, "EGL_BUFFER_SIZE" },
679+ { EGL_ALPHA_SIZE, "EGL_ALPHA_SIZE" },
680+ { EGL_BLUE_SIZE, "EGL_BLUE_SIZE" },
681+ { EGL_GREEN_SIZE, "EGL_GREEN_SIZE" },
682+ { EGL_RED_SIZE, "EGL_RED_SIZE" },
683+ { EGL_DEPTH_SIZE, "EGL_DEPTH_SIZE" },
684+ { EGL_STENCIL_SIZE, "EGL_STENCIL_SIZE" },
685+ { EGL_CONFIG_CAVEAT, "EGL_CONFIG_CAVEAT" },
686+ { EGL_CONFIG_ID, "EGL_CONFIG_ID" },
687+ { EGL_LEVEL, "EGL_LEVEL" },
688+ { EGL_MAX_PBUFFER_HEIGHT, "EGL_MAX_PBUFFER_HEIGHT" },
689+ { EGL_MAX_PBUFFER_PIXELS, "EGL_MAX_PBUFFER_PIXELS" },
690+ { EGL_MAX_PBUFFER_WIDTH, "EGL_MAX_PBUFFER_WIDTH" },
691+ { EGL_NATIVE_RENDERABLE, "EGL_NATIVE_RENDERABLE" },
692+ { EGL_NATIVE_VISUAL_ID, "EGL_NATIVE_VISUAL_ID" },
693+ { EGL_NATIVE_VISUAL_TYPE, "EGL_NATIVE_VISUAL_TYPE" },
694+ { EGL_SAMPLES, "EGL_SAMPLES" },
695+ { EGL_SAMPLE_BUFFERS, "EGL_SAMPLE_BUFFERS" },
696+ { EGL_SURFACE_TYPE, "EGL_SURFACE_TYPE" },
697+ { EGL_TRANSPARENT_TYPE, "EGL_TRANSPARENT_TYPE" },
698+ { EGL_TRANSPARENT_BLUE_VALUE, "EGL_TRANSPARENT_BLUE_VALUE" },
699+ { EGL_TRANSPARENT_GREEN_VALUE, "EGL_TRANSPARENT_GREEN_VALUE" },
700+ { EGL_TRANSPARENT_RED_VALUE, "EGL_TRANSPARENT_RED_VALUE" },
701+ { EGL_BIND_TO_TEXTURE_RGB, "EGL_BIND_TO_TEXTURE_RGB" },
702+ { EGL_BIND_TO_TEXTURE_RGBA, "EGL_BIND_TO_TEXTURE_RGBA" },
703+ { EGL_MIN_SWAP_INTERVAL, "EGL_MIN_SWAP_INTERVAL" },
704+ { EGL_MAX_SWAP_INTERVAL, "EGL_MAX_SWAP_INTERVAL" },
705+ { -1, NULL }
706+ };
707+ const char* string = eglQueryString(display, EGL_VENDOR);
708+ qCDebug(ubuntumirclient, "EGL vendor: %s", string);
709+
710+ string = eglQueryString(display, EGL_VERSION);
711+ qCDebug(ubuntumirclient, "EGL version: %s", string);
712+
713+ string = eglQueryString(display, EGL_EXTENSIONS);
714+ qCDebug(ubuntumirclient, "EGL extensions: %s", string);
715+
716+ qCDebug(ubuntumirclient, "EGL configuration attibutes:");
717+ for (int index = 0; kAttribs[index].attrib != -1; index++) {
718+ EGLint value;
719+ if (eglGetConfigAttrib(display, config, kAttribs[index].attrib, &value))
720+ qCDebug(ubuntumirclient, " %s: %d", kAttribs[index].name, static_cast<int>(value));
721+ }
722 }
723-#endif
724+
725+namespace {
726+ int qGetEnvIntValue(const char *varName, bool *ok)
727+ {
728+ return qgetenv(varName).toInt(ok);
729+ }
730+} // anonymous namespace
731
732
733 const QEvent::Type OrientationChangeEvent::mType =
734@@ -150,7 +159,7 @@
735 mSurfaceFormat.setStencilBufferSize(8);
736 if (!qEnvironmentVariableIsEmpty("QTUBUNTU_MULTISAMPLE")) {
737 mSurfaceFormat.setSamples(4);
738- DLOG("ubuntumirclient: setting MSAA to 4 samples");
739+ qCDebug(ubuntumirclient, "setting MSAA to 4 samples");
740 }
741 #ifdef QTUBUNTU_USE_OPENGL
742 mSurfaceFormat.setRenderableType(QSurfaceFormat::OpenGL);
743@@ -159,23 +168,23 @@
744 #endif
745 mEglConfig = q_configFromGLFormat(mEglDisplay, mSurfaceFormat, true);
746
747- #if !defined(QT_NO_DEBUG)
748- printEglConfig(mEglDisplay, mEglConfig);
749- #endif
750+ if (ubuntumirclient().isDebugEnabled()) {
751+ printEglConfig(mEglDisplay, mEglConfig);
752+ }
753
754 // Set vblank swap interval.
755- int swapInterval = kSwapInterval;
756- QByteArray swapIntervalString = qgetenv("QTUBUNTU_SWAPINTERVAL");
757- if (!swapIntervalString.isEmpty()) {
758- bool ok;
759- swapInterval = swapIntervalString.toInt(&ok);
760- if (!ok)
761- swapInterval = kSwapInterval;
762- }
763- DLOG("ubuntumirclient: setting swap interval to %d", swapInterval);
764+ bool ok;
765+ int swapInterval = qGetEnvIntValue("QTUBUNTU_SWAPINTERVAL", &ok);
766+ if (!ok)
767+ swapInterval = kSwapInterval;
768+
769+ qCDebug(ubuntumirclient, "Setting swap interval to %d", swapInterval);
770 eglSwapInterval(mEglDisplay, swapInterval);
771
772- // Get screen resolution.
773+ // Get screen resolution and properties.
774+ int dpr = qGetEnvIntValue("QT_DEVICE_PIXEL_RATIO", &ok);
775+ mDevicePixelRatio = (ok && dpr > 0) ? dpr : 1.0;
776+
777 auto configDeleter = [](MirDisplayConfiguration *config) { mir_display_config_destroy(config); };
778 using configUp = std::unique_ptr<MirDisplayConfiguration, decltype(configDeleter)>;
779 configUp displayConfig(mir_connection_create_display_config(connection), configDeleter);
780@@ -187,19 +196,17 @@
781 mOutputId = displayOutput->output_id;
782
783 mPhysicalSize = QSizeF(displayOutput->physical_width_mm, displayOutput->physical_height_mm);
784- DLOG("ubuntumirclient: screen physical size: %.2fx%.2f", mPhysicalSize.width(), mPhysicalSize.height());
785+ qCDebug(ubuntumirclient, "Screen physical size: %.2fx%.2f mm", mPhysicalSize.width(), mPhysicalSize.height());
786
787 const MirDisplayMode *mode = &displayOutput->modes[displayOutput->current_mode];
788- const int kScreenWidth = mode->horizontal_resolution;
789- const int kScreenHeight = mode->vertical_resolution;
790- DASSERT(kScreenWidth > 0 && kScreenHeight > 0);
791+ const int kScreenWidth = divideAndRoundUp(mode->horizontal_resolution, mDevicePixelRatio);
792+ const int kScreenHeight = divideAndRoundUp(mode->vertical_resolution, mDevicePixelRatio);
793+ ASSERT(kScreenWidth > 0 && kScreenHeight > 0);
794
795- DLOG("ubuntumirclient: screen resolution: %dx%d", kScreenWidth, kScreenHeight);
796+ qCDebug(ubuntumirclient, "Screen resolution: %dx%ddp", kScreenWidth, kScreenHeight);
797
798 mGeometry = QRect(0, 0, kScreenWidth, kScreenHeight);
799
800- DLOG("QUbuntuScreen::QUbuntuScreen (this=%p)", this);
801-
802 // Set the default orientation based on the initial screen dimmensions.
803 mNativeOrientation = (mGeometry.width() >= mGeometry.height()) ? Qt::LandscapeOrientation : Qt::PortraitOrientation;
804
805@@ -213,7 +220,7 @@
806 }
807
808 void UbuntuScreen::customEvent(QEvent* event) {
809- DASSERT(QThread::currentThread() == thread());
810+ Q_ASSERT(QThread::currentThread() == thread());
811
812 OrientationChangeEvent* oReadingEvent = static_cast<OrientationChangeEvent*>(event);
813 switch (oReadingEvent->mOrientation) {
814@@ -238,13 +245,13 @@
815 break;
816 }
817 default: {
818- DLOG("UbuntuScreen::customEvent - Unknown orientation.");
819+ qCDebug(ubuntumirclient, "UbuntuScreen::customEvent - Unknown orientation.");
820 return;
821 }
822 }
823
824 // Raise the event signal so that client apps know the orientation changed
825- DLOG("UbuntuScreen::customEvent - handling orientation change to %s", orientationToStr(mCurrentOrientation));
826+ qCDebug(ubuntumirclient, "UbuntuScreen::customEvent - handling orientation change to %s", orientationToStr(mCurrentOrientation));
827 QWindowSystemInterface::handleScreenOrientationChange(screen(), mCurrentOrientation);
828 }
829
830@@ -265,7 +272,7 @@
831 mGeometry.setWidth(currGeometry.height());
832 mGeometry.setHeight(currGeometry.width());
833
834- DLOG("UbuntuScreen::handleWindowSurfaceResize - new screen geometry (w=%d, h=%d)",
835+ qCDebug(ubuntumirclient, "UbuntuScreen::handleWindowSurfaceResize - new screen geometry (w=%d, h=%d)",
836 mGeometry.width(), mGeometry.height());
837 QWindowSystemInterface::handleScreenGeometryChange(screen(),
838 mGeometry /* newGeometry */,
839@@ -276,7 +283,7 @@
840 } else {
841 mCurrentOrientation = Qt::LandscapeOrientation;
842 }
843- DLOG("UbuntuScreen::handleWindowSurfaceResize - new orientation %s",orientationToStr(mCurrentOrientation));
844+ qCDebug(ubuntumirclient, "UbuntuScreen::handleWindowSurfaceResize - new orientation %s",orientationToStr(mCurrentOrientation));
845 QWindowSystemInterface::handleScreenOrientationChange(screen(), mCurrentOrientation);
846 }
847 }
848
849=== modified file 'src/ubuntumirclient/screen.h'
850--- src/ubuntumirclient/screen.h 2015-11-23 11:10:24 +0000
851+++ src/ubuntumirclient/screen.h 2015-12-17 10:58:59 +0000
852@@ -38,6 +38,7 @@
853 QRect geometry() const override { return mGeometry; }
854 QRect availableGeometry() const override { return mGeometry; }
855 QSizeF physicalSize() const override { return mPhysicalSize; }
856+ qreal devicePixelRatio() const override { return mDevicePixelRatio; }
857 Qt::ScreenOrientation nativeOrientation() const override { return mNativeOrientation; }
858 Qt::ScreenOrientation orientation() const override { return mNativeOrientation; }
859 QPlatformCursor *cursor() const override { return const_cast<UbuntuCursor*>(&mCursor); }
860@@ -56,6 +57,7 @@
861 private:
862 QRect mGeometry;
863 QSizeF mPhysicalSize;
864+ qreal mDevicePixelRatio;
865 Qt::ScreenOrientation mNativeOrientation;
866 Qt::ScreenOrientation mCurrentOrientation;
867 QImage::Format mFormat;
868
869=== modified file 'src/ubuntumirclient/ubuntumirclient.pro'
870--- src/ubuntumirclient/ubuntumirclient.pro 2015-11-10 11:16:14 +0000
871+++ src/ubuntumirclient/ubuntumirclient.pro 2015-12-17 10:58:59 +0000
872@@ -42,7 +42,8 @@
873 plugin.h \
874 screen.h \
875 theme.h \
876- window.h
877+ window.h \
878+ utils.h
879
880 # Installation path
881 target.path += $$[QT_INSTALL_PLUGINS]/platforms
882
883=== added file 'src/ubuntumirclient/utils.h'
884--- src/ubuntumirclient/utils.h 1970-01-01 00:00:00 +0000
885+++ src/ubuntumirclient/utils.h 2015-12-17 10:58:59 +0000
886@@ -0,0 +1,29 @@
887+/*
888+ * Copyright (C) 2015 Canonical, Ltd.
889+ *
890+ * This program is free software: you can redistribute it and/or modify it under
891+ * the terms of the GNU Lesser General Public License version 3, as published by
892+ * the Free Software Foundation.
893+ *
894+ * This program is distributed in the hope that it will be useful, but WITHOUT
895+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
896+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
897+ * Lesser General Public License for more details.
898+ *
899+ * You should have received a copy of the GNU Lesser General Public License
900+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
901+ */
902+
903+#ifndef UTILS_H
904+#define UTILS_H
905+
906+#include <QtGlobal>
907+
908+namespace {
909+ inline int divideAndRoundUp(int numerator, qreal denominator)
910+ {
911+ return ceil((qreal)numerator / denominator);
912+ }
913+} // anonymous namespace
914+
915+#endif // UTILS_H
916
917=== modified file 'src/ubuntumirclient/window.cpp'
918--- src/ubuntumirclient/window.cpp 2015-12-07 16:20:58 +0000
919+++ src/ubuntumirclient/window.cpp 2015-12-17 10:58:59 +0000
920@@ -19,6 +19,7 @@
921 #include "clipboard.h"
922 #include "input.h"
923 #include "screen.h"
924+#include "utils.h"
925 #include "logging.h"
926
927 #include <mir_toolkit/mir_client_library.h>
928@@ -34,6 +35,13 @@
929
930 #include <EGL/egl.h>
931
932+
933+/*
934+ * Note: all geometry is in device-independent pixels, except that contained in variables with the
935+ * suffix "Px" - whose units are (physical) pixels
936+ */
937+Q_LOGGING_CATEGORY(ubuntumirclientBufferSwap, "ubuntumirclient.bufferSwap", QtWarningMsg)
938+
939 namespace
940 {
941
942@@ -75,12 +83,11 @@
943 case Qt::WindowMinimized:
944 return mir_surface_state_minimized;
945 default:
946- LOG("Unexpected Qt::WindowState: %d", state);
947+ qCWarning(ubuntumirclient, "Unexpected Qt::WindowState: %d", state);
948 return mir_surface_state_restored;
949 }
950 }
951
952-#if !defined(QT_NO_DEBUG)
953 const char *qtWindowStateToStr(Qt::WindowState state)
954 {
955 switch (state) {
956@@ -96,7 +103,6 @@
957 return "!?";
958 }
959 }
960-#endif
961
962 WId makeId()
963 {
964@@ -133,67 +139,68 @@
965
966 Spec makeSurfaceSpec(QWindow *window, UbuntuInput *input, MirConnection *connection)
967 {
968- const auto geom = window->geometry();
969- const int width = geom.width() > 0 ? geom.width() : 1;
970- const int height = geom.height() > 0 ? geom.height() : 1;
971- const auto pixelFormat = defaultPixelFormatFor(connection);
972-
973- if (U_ON_SCREEN_KEYBOARD_ROLE == roleFor(window)) {
974- DLOG("[ubuntumirclient QPA] makeSurfaceSpec(window=%p) - creating input method surface (width=%d, height=%d", window, width, height);
975- return Spec{mir_connection_create_spec_for_input_method(connection, width, height, pixelFormat)};
976- }
977-
978- const Qt::WindowType type = window->type();
979- if (type == Qt::Popup) {
980- auto parent = transientParentFor(window);
981- if (parent == nullptr) {
982- //NOTE: We cannot have a parentless popup -
983- //try using the last surface to receive input as that will most likely be
984- //the one that caused this popup to be created
985- parent = input->lastFocusedWindow();
986- }
987- if (parent) {
988- auto pos = geom.topLeft();
989- pos -= parent->geometry().topLeft();
990- MirRectangle location{pos.x(), pos.y(), 0, 0};
991- DLOG("[ubuntumirclient QPA] makeSurfaceSpec(window=%p) - creating menu surface(width:%d, height:%d)", window, width, height);
992- return Spec{mir_connection_create_spec_for_menu(
993- connection, width, height, pixelFormat, parent->mirSurface(),
994- &location, mir_edge_attachment_any)};
995- } else {
996- DLOG("[ubuntumirclient QPA] makeSurfaceSpec(window=%p) - cannot create a menu without a parent!", window);
997- }
998- } else if (type == Qt::Dialog) {
999- auto parent = transientParentFor(window);
1000- if (parent) {
1001- // Modal dialog
1002- DLOG("[ubuntumirclient QPA] makeSurfaceSpec(window=%p) - creating modal dialog (width=%d, height=%d", window, width, height);
1003- return Spec{mir_connection_create_spec_for_modal_dialog(connection, width, height, pixelFormat, parent->mirSurface())};
1004- } else {
1005- // TODO: do Qt parentless dialogs have the same semantics as mir?
1006- DLOG("[ubuntumirclient QPA] makeSurfaceSpec(window=%p) - creating parentless dialog (width=%d, height=%d)", window, width, height);
1007- return Spec{mir_connection_create_spec_for_dialog(connection, width, height, pixelFormat)};
1008- }
1009- }
1010- DLOG("[ubuntumirclient QPA] makeSurfaceSpec(window=%p) - creating normal surface(type=0x%x, width=%d, height=%d)", window, type, width, height);
1011- return Spec{mir_connection_create_spec_for_normal_surface(connection, width, height, pixelFormat)};
1012+ const auto geom = window->geometry();
1013+ const int dpr = int(window->devicePixelRatio());
1014+ const int widthPx = geom.width() > 0 ? geom.width() * dpr : 1;
1015+ const int heightPx = geom.height() > 0 ? geom.height() * dpr : 1;
1016+ const auto pixelFormat = defaultPixelFormatFor(connection);
1017+
1018+ if (U_ON_SCREEN_KEYBOARD_ROLE == roleFor(window)) {
1019+ qCDebug(ubuntumirclient, "makeSurfaceSpec(window=%p) - creating input method surface with size=(%dx%d)px", window, widthPx, heightPx);
1020+ return Spec{mir_connection_create_spec_for_input_method(connection, widthPx, heightPx, pixelFormat)};
1021+ }
1022+
1023+ const Qt::WindowType type = window->type();
1024+ if (type == Qt::Popup) {
1025+ auto parent = transientParentFor(window);
1026+ if (parent == nullptr) {
1027+ //NOTE: We cannot have a parentless popup -
1028+ //try using the last surface to receive input as that will most likely be
1029+ //the one that caused this popup to be created
1030+ parent = input->lastFocusedWindow();
1031+ }
1032+ if (parent) {
1033+ auto posPx = geom.topLeft() * dpr;
1034+ posPx -= parent->geometry().topLeft() * dpr;
1035+ MirRectangle location{posPx.x(), posPx.y(), 0, 0};
1036+ qCDebug(ubuntumirclient, "makeSurfaceSpec(window=%p) - creating menu surface with size=(%dx%d)px", window, widthPx, heightPx);
1037+ return Spec{mir_connection_create_spec_for_menu(
1038+ connection, widthPx, heightPx, pixelFormat, parent->mirSurface(),
1039+ &location, mir_edge_attachment_any)};
1040+ } else {
1041+ qCDebug(ubuntumirclient, "makeSurfaceSpec(window=%p) - cannot create a menu without a parent!", window);
1042+ }
1043+ } else if (type == Qt::Dialog) {
1044+ auto parent = transientParentFor(window);
1045+ if (parent) {
1046+ // Modal dialog
1047+ qCDebug(ubuntumirclient, "makeSurfaceSpec(window=%p) - creating modal dialog with size=(%dx%d)px", window, widthPx, heightPx);
1048+ return Spec{mir_connection_create_spec_for_modal_dialog(connection, widthPx, heightPx, pixelFormat, parent->mirSurface())};
1049+ } else {
1050+ // TODO: do Qt parentless dialogs have the same semantics as mir?
1051+ qCDebug(ubuntumirclient, "makeSurfaceSpec(window=%p) - creating parentless dialog with size=(%dx%d)px", window, widthPx, heightPx);
1052+ return Spec{mir_connection_create_spec_for_dialog(connection, widthPx, heightPx, pixelFormat)};
1053+ }
1054+ }
1055+ qCDebug(ubuntumirclient, "makeSurfaceSpec(window=%p) - creating normal surface(type=0x%x, with size=(%dx%d)px", window, type, widthPx, heightPx);
1056+ return Spec{mir_connection_create_spec_for_normal_surface(connection, widthPx, heightPx, pixelFormat)};
1057 }
1058
1059-void setSizingConstraints(MirSurfaceSpec *spec, const QSize& minSize, const QSize& maxSize, const QSize& increment)
1060+void setSizingConstraints(MirSurfaceSpec *spec, const QSize &minSizePx, const QSize &maxSizePx, const QSize &incrementPx)
1061 {
1062- mir_surface_spec_set_min_width(spec, minSize.width());
1063- mir_surface_spec_set_min_height(spec, minSize.height());
1064- if (maxSize.width() >= minSize.width()) {
1065- mir_surface_spec_set_max_width(spec, maxSize.width());
1066- }
1067- if (maxSize.height() >= minSize.height()) {
1068- mir_surface_spec_set_max_height(spec, maxSize.height());
1069- }
1070- if (increment.width() > 0) {
1071- mir_surface_spec_set_width_increment(spec, increment.width());
1072- }
1073- if (increment.height() > 0) {
1074- mir_surface_spec_set_height_increment(spec, increment.height());
1075+ mir_surface_spec_set_min_width(spec, minSizePx.width());
1076+ mir_surface_spec_set_min_height(spec, minSizePx.height());
1077+ if (maxSizePx.width() >= minSizePx.width()) {
1078+ mir_surface_spec_set_max_width(spec, maxSizePx.width());
1079+ }
1080+ if (maxSizePx.height() >= minSizePx.height()) {
1081+ mir_surface_spec_set_max_height(spec, maxSizePx.height());
1082+ }
1083+ if (incrementPx.width() > 0) {
1084+ mir_surface_spec_set_width_increment(spec, incrementPx.width());
1085+ }
1086+ if (incrementPx.height() > 0) {
1087+ mir_surface_spec_set_height_increment(spec, incrementPx.height());
1088 }
1089 }
1090
1091@@ -233,6 +240,10 @@
1092
1093 } //namespace
1094
1095+/*
1096+ * UbuntuSurface - wraps a MirSurface
1097+ * All units are in pixels only (no device pixels).
1098+ */
1099 class UbuntuSurface
1100 {
1101 public:
1102@@ -248,7 +259,6 @@
1103 , mNeedsRepaint(false)
1104 , mParented(mWindow->transientParent() || mWindow->parent())
1105 , mWindowState(mWindow->windowState())
1106-
1107 {
1108 mir_surface_set_event_handler(mMirSurface, surfaceEventCallback, this);
1109
1110@@ -257,22 +267,13 @@
1111 MirSurfaceParameters parameters;
1112 mir_surface_get_parameters(mMirSurface, &parameters);
1113
1114- auto geom = mWindow->geometry();
1115- geom.setWidth(parameters.width);
1116- geom.setHeight(parameters.height);
1117- if (mWindowState == Qt::WindowFullScreen) {
1118- geom.setY(0);
1119- } else {
1120- geom.setY(panelHeight());
1121- }
1122-
1123 // Assume that the buffer size matches the surface size at creation time
1124- mBufferSize = geom.size();
1125- platformWindow->QPlatformWindow::setGeometry(geom);
1126- QWindowSystemInterface::handleGeometryChange(mWindow, geom);
1127+ mBufferSizePx.rwidth() = parameters.width;
1128+ mBufferSizePx.rheight() = parameters.height;
1129
1130- DLOG("[ubuntumirclient QPA] created surface at (%d, %d) with size (%d, %d), title '%s', role: '%d'\n",
1131- geom.x(), geom.y(), geom.width(), geom.height(), mWindow->title().toUtf8().constData(), roleFor(mWindow));
1132+ qCDebug(ubuntumirclient, "created surface with size=(%dx%d)px, title='%s', role=%d",
1133+ parameters.width, parameters.height, qPrintable(mWindow->title()), roleFor(mWindow));
1134+ mPlatformWindow->updateWindowSize(parameters.width, parameters.height);
1135 }
1136
1137 ~UbuntuSurface()
1138@@ -283,24 +284,24 @@
1139 mir_surface_release_sync(mMirSurface);
1140 }
1141
1142- UbuntuSurface(UbuntuSurface const&) = delete;
1143- UbuntuSurface& operator=(UbuntuSurface const&) = delete;
1144+ UbuntuSurface(const UbuntuSurface &) = delete;
1145+ UbuntuSurface& operator=(const UbuntuSurface &) = delete;
1146
1147- void resize(const QSize& newSize);
1148+ void resize(const QSize &newSizePx);
1149 void setState(Qt::WindowState newState);
1150 void setVisible(bool state);
1151- void updateTitle(const QString& title);
1152- void setSizingConstraints(const QSize& minSize, const QSize& maxSize, const QSize& increment);
1153+ void updateTitle(const QString &title);
1154+ void setSizingConstraints(const QSize &minSizePx, const QSize &maxSizePx, const QSize &incrementPx);
1155
1156 void onSwapBuffersDone();
1157- void handleSurfaceResized(int width, int height);
1158+ void handleSurfaceResized(int widthPx, int heightPx);
1159 int needsRepaint() const;
1160
1161 EGLSurface eglSurface() const { return mEglSurface; }
1162 MirSurface *mirSurface() const { return mMirSurface; }
1163
1164 private:
1165- static void surfaceEventCallback(MirSurface* surface, const MirEvent *event, void* context);
1166+ static void surfaceEventCallback(MirSurface *surface, const MirEvent *event, void *context);
1167 void postEvent(const MirEvent *event);
1168 void updateSurface();
1169
1170@@ -317,29 +318,29 @@
1171 bool mNeedsRepaint;
1172 bool mParented;
1173 Qt::WindowState mWindowState;
1174- QSize mBufferSize;
1175+ QSize mBufferSizePx;
1176
1177 QMutex mTargetSizeMutex;
1178- QSize mTargetSize;
1179+ QSize mTargetSizePx;
1180 };
1181
1182-void UbuntuSurface::resize(const QSize& size)
1183+void UbuntuSurface::resize(const QSize &sizePx)
1184 {
1185- DLOG("[ubuntumirclient QPA] resize(window=%p, width=%d, height=%d)", mWindow, size.width(), size.height());
1186+ qCDebug(ubuntumirclient,"resize(window=%p) to (%dx%d)px", mWindow, sizePx.width(), sizePx.height());
1187
1188 if (mWindowState == Qt::WindowFullScreen || mWindowState == Qt::WindowMaximized) {
1189- DLOG("[ubuntumirclient QPA] resize(window=%p) - not resizing, window is maximized or fullscreen", mWindow);
1190+ qCDebug(ubuntumirclient, "resize(window=%p) - not resizing, window is maximized or fullscreen", mWindow);
1191 return;
1192 }
1193
1194- if (size.isEmpty()) {
1195- DLOG("[ubuntumirclient QPA] resize(window=%p) - not resizing, size is empty", mWindow);
1196+ if (sizePx.isEmpty()) {
1197+ qCDebug(ubuntumirclient, "resize(window=%p) - not resizing, size is empty", mWindow);
1198 return;
1199 }
1200
1201 Spec spec{mir_connection_create_spec_for_changes(mConnection)};
1202- mir_surface_spec_set_width(spec.get(), size.width());
1203- mir_surface_spec_set_height(spec.get(), size.height());
1204+ mir_surface_spec_set_width(spec.get(), sizePx.width());
1205+ mir_surface_spec_set_height(spec.get(), sizePx.height());
1206 mir_surface_apply_spec(mMirSurface, spec.get());
1207 }
1208
1209@@ -365,7 +366,7 @@
1210 mir_wait_for(mir_surface_set_state(mMirSurface, newState));
1211 }
1212
1213-void UbuntuSurface::updateTitle(const QString& newTitle)
1214+void UbuntuSurface::updateTitle(const QString &newTitle)
1215 {
1216 const auto title = newTitle.toUtf8();
1217 Spec spec{mir_connection_create_spec_for_changes(mConnection)};
1218@@ -373,14 +374,14 @@
1219 mir_surface_apply_spec(mMirSurface, spec.get());
1220 }
1221
1222-void UbuntuSurface::setSizingConstraints(const QSize& minSize, const QSize& maxSize, const QSize& increment)
1223+void UbuntuSurface::setSizingConstraints(const QSize &minSizePx, const QSize &maxSizePx, const QSize &incrementPx)
1224 {
1225 Spec spec{mir_connection_create_spec_for_changes(mConnection)};
1226- ::setSizingConstraints(spec.get(), minSize, maxSize, increment);
1227+ ::setSizingConstraints(spec.get(), minSizePx, maxSizePx, incrementPx);
1228 mir_surface_apply_spec(mMirSurface, spec.get());
1229 }
1230
1231-void UbuntuSurface::handleSurfaceResized(int width, int height)
1232+void UbuntuSurface::handleSurfaceResized(int widthPx, int heightPx)
1233 {
1234 QMutexLocker lock(&mTargetSizeMutex);
1235
1236@@ -390,13 +391,13 @@
1237 // see TODO in postEvent as the ideal way we should handle this.
1238 // The actual buffer size may or may have not changed at this point, so let the rendering
1239 // thread drive the window geometry updates.
1240- mNeedsRepaint = mTargetSize.width() == width && mTargetSize.height() == height;
1241+ mNeedsRepaint = mTargetSizePx.width() == widthPx && mTargetSizePx.height() == heightPx;
1242 }
1243
1244 int UbuntuSurface::needsRepaint() const
1245 {
1246 if (mNeedsRepaint) {
1247- if (mTargetSize != mBufferSize) {
1248+ if (mTargetSizePx != mBufferSizePx) {
1249 //If the buffer hasn't changed yet, we need at least two redraws,
1250 //once to get the new buffer size and propagate the geometry changes
1251 //and the second to redraw the content at the new size
1252@@ -412,34 +413,28 @@
1253
1254 void UbuntuSurface::onSwapBuffersDone()
1255 {
1256-#if !defined(QT_NO_DEBUG)
1257 static int sFrameNumber = 0;
1258 ++sFrameNumber;
1259-#endif
1260-
1261- EGLint eglSurfaceWidth = -1;
1262- EGLint eglSurfaceHeight = -1;
1263- eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, &eglSurfaceWidth);
1264- eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, &eglSurfaceHeight);
1265-
1266- const bool validSize = eglSurfaceWidth > 0 && eglSurfaceHeight > 0;
1267-
1268- if (validSize && (mBufferSize.width() != eglSurfaceWidth || mBufferSize.height() != eglSurfaceHeight)) {
1269-
1270- DLOG("[ubuntumirclient QPA] onSwapBuffersDone(window=%p) [%d] - size changed (%d, %d) => (%d, %d)",
1271- mWindow, sFrameNumber, mBufferSize.width(), mBufferSize.height(), eglSurfaceWidth, eglSurfaceHeight);
1272-
1273- mBufferSize.rwidth() = eglSurfaceWidth;
1274- mBufferSize.rheight() = eglSurfaceHeight;
1275-
1276- QRect newGeometry = mPlatformWindow->geometry();
1277- newGeometry.setSize(mBufferSize);
1278-
1279- mPlatformWindow->QPlatformWindow::setGeometry(newGeometry);
1280- QWindowSystemInterface::handleGeometryChange(mWindow, newGeometry);
1281+
1282+ EGLint eglSurfaceWidthPx = -1;
1283+ EGLint eglSurfaceHeightPx = -1;
1284+ eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, &eglSurfaceWidthPx);
1285+ eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, &eglSurfaceHeightPx);
1286+
1287+ const bool validSize = eglSurfaceWidthPx > 0 && eglSurfaceHeightPx > 0;
1288+
1289+ if (validSize && (mBufferSizePx.width() != eglSurfaceWidthPx || mBufferSizePx.height() != eglSurfaceHeightPx)) {
1290+
1291+ qCDebug(ubuntumirclientBufferSwap, "onSwapBuffersDone(window=%p) [%d] - buffer size changed (%dx%d)px => (%dx%d)px",
1292+ mWindow, sFrameNumber, mBufferSizePx.width(), mBufferSizePx.height(), eglSurfaceWidthPx, eglSurfaceHeightPx);
1293+
1294+ mBufferSizePx.rwidth() = eglSurfaceWidthPx;
1295+ mBufferSizePx.rheight() = eglSurfaceHeightPx;
1296+
1297+ mPlatformWindow->updateWindowSize(eglSurfaceWidthPx, eglSurfaceHeightPx);
1298 } else {
1299- DLOG("[ubuntumirclient QPA] onSwapBuffersDone(window=%p) [%d] - buffer size (%d,%d)",
1300- mWindow, sFrameNumber, mBufferSize.width(), mBufferSize.height());
1301+ qCDebug(ubuntumirclientBufferSwap, "onSwapBuffersDone(window=%p) [%d] - buffer size=(%dx%d)px",
1302+ mWindow, sFrameNumber, mBufferSizePx.width(), mBufferSizePx.height());
1303 }
1304 }
1305
1306@@ -460,13 +455,13 @@
1307 // As a workaround, we use the width/height as an identifier of this latest event
1308 // so the event handler (handleSurfaceResized) can discard/ignore old ones.
1309 const auto resizeEvent = mir_event_get_resize_event(event);
1310- const auto width = mir_resize_event_get_width(resizeEvent);
1311- const auto height = mir_resize_event_get_height(resizeEvent);
1312- DLOG("[ubuntumirclient QPA] resizeEvent(window=%p, width=%d, height=%d)", mWindow, width, height);
1313+ const auto widthPx = mir_resize_event_get_width(resizeEvent);
1314+ const auto heightPx = mir_resize_event_get_height(resizeEvent);
1315+ qCDebug(ubuntumirclient, "resizeEvent(window=%p, size=(%dx%d)px", mWindow, widthPx, heightPx);
1316
1317 QMutexLocker lock(&mTargetSizeMutex);
1318- mTargetSize.rwidth() = width;
1319- mTargetSize.rheight() = height;
1320+ mTargetSizePx.rwidth() = widthPx;
1321+ mTargetSizePx.rheight() = heightPx;
1322 }
1323
1324 mInput->postEvent(mPlatformWindow, event);
1325@@ -474,14 +469,14 @@
1326
1327 void UbuntuSurface::updateSurface()
1328 {
1329- DLOG("[ubuntumirclient QPA] updateSurface(window=%p)", mWindow);
1330+ qCDebug(ubuntumirclient, "updateSurface(window=%p)", mWindow);
1331
1332 if (!mParented && mWindow->type() == Qt::Dialog) {
1333 // The dialog may have been parented after creation time
1334 // so morph it into a modal dialog
1335 auto parent = transientParentFor(mWindow);
1336 if (parent) {
1337- DLOG("[ubuntumirclient QPA] updateSurface(window=%p) dialog now parented", mWindow);
1338+ qCDebug(ubuntumirclient, "updateSurface(window=%p) dialog now parented", mWindow);
1339 mParented = true;
1340 Spec spec{mir_connection_create_spec_for_changes(mConnection)};
1341 mir_surface_spec_set_parent(spec.get(), parent->mirSurface());
1342@@ -498,20 +493,36 @@
1343 , mClipboard(clipboard)
1344 , mSurface(new UbuntuSurface{this, screen, input, connection})
1345 {
1346- DLOG("[ubuntumirclient QPA] UbuntuWindow(window=%p, screen=%p, input=%p, surf=%p)", w, screen, input, mSurface.get());
1347+ qCDebug(ubuntumirclient, "UbuntuWindow(window=%p, screen=%p, input=%p, surf=%p) with title '%s', role: '%d'",
1348+ w, screen, input, mSurface.get(), qPrintable(window()->title()), roleFor(window()));
1349+
1350+ enablePanelHeightHack(w->windowState() != Qt::WindowFullScreen);
1351 }
1352
1353 UbuntuWindow::~UbuntuWindow()
1354 {
1355- DLOG("[ubuntumirclient QPA] ~UbuntuWindow(window=%p)", this);
1356-}
1357-
1358-void UbuntuWindow::handleSurfaceResized(int width, int height)
1359+ qCDebug(ubuntumirclient, "~UbuntuWindow(window=%p)", this);
1360+}
1361+
1362+void UbuntuWindow::updateWindowSize(int widthPx, int heightPx) // after when Mir has resized the surface
1363+{
1364+ const float dpr = devicePixelRatio();
1365+ auto geom = geometry();
1366+ geom.setWidth(divideAndRoundUp(widthPx, dpr));
1367+ geom.setHeight(divideAndRoundUp(heightPx, dpr));
1368+
1369+ QPlatformWindow::setGeometry(geom);
1370+ QWindowSystemInterface::handleGeometryChange(window(), geom);
1371+
1372+ qCDebug(ubuntumirclient) << "Surface geometry updated:" << geom;
1373+}
1374+
1375+void UbuntuWindow::handleSurfaceResized(int widthPx, int heightPx)
1376 {
1377 QMutexLocker lock(&mMutex);
1378- DLOG("[ubuntumirclient QPA] handleSurfaceResize(window=%p, width=%d, height=%d)", window(), width, height);
1379+ qCDebug(ubuntumirclient, "handleSurfaceResize(window=%p, size=(%dx%d)px", window(), widthPx, heightPx);
1380
1381- mSurface->handleSurfaceResized(width, height);
1382+ mSurface->handleSurfaceResized(widthPx, heightPx);
1383
1384 // This resize event could have occurred just after the last buffer swap for this window.
1385 // This means the client may still be holding a buffer with the older size. The first redraw call
1386@@ -519,16 +530,16 @@
1387 // updated size but it still needs re-rendering so another redraw may be needed.
1388 // A mir API to drop the currently held buffer would help here, so that we wouldn't have to redraw twice
1389 auto const numRepaints = mSurface->needsRepaint();
1390- DLOG("[ubuntumirclient QPA] handleSurfaceResize(window=%p) redraw %d times", window(), numRepaints);
1391+ qCDebug(ubuntumirclient, "handleSurfaceResize(window=%p) redraw %d times", window(), numRepaints);
1392 for (int i = 0; i < numRepaints; i++) {
1393- DLOG("[ubuntumirclient QPA] handleSurfaceResize(window=%p) repainting width=%d, height=%d", window(), geometry().size().width(), geometry().size().height());
1394+ qCDebug(ubuntumirclient, "handleSurfaceResize(window=%p) repainting size=(%dx%d)dp", window(), geometry().size().width(), geometry().size().height());
1395 QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
1396 }
1397 }
1398
1399 void UbuntuWindow::handleSurfaceFocused()
1400 {
1401- DLOG("[ubuntumirclient QPA] handleSurfaceFocused(window=%p)", window());
1402+ qCDebug(ubuntumirclient, "handleSurfaceFocused(window=%p)", window());
1403
1404 // System clipboard contents might have changed while this window was unfocused and without
1405 // this process getting notified about it because it might have been suspended (due to
1406@@ -542,10 +553,10 @@
1407 void UbuntuWindow::setWindowState(Qt::WindowState state)
1408 {
1409 QMutexLocker lock(&mMutex);
1410- DLOG("[ubuntumirclient QPA] setWindowState(window=%p, %s)", this, qtWindowStateToStr(state));
1411+ qCDebug(ubuntumirclient, "setWindowState(window=%p, %s)", this, qtWindowStateToStr(state));
1412 mSurface->setState(state);
1413
1414- updatePanelHeightHack(state);
1415+ enablePanelHeightHack(state != Qt::WindowFullScreen);
1416 }
1417
1418 /*
1419@@ -554,38 +565,40 @@
1420 window is always on the top-left corner, right below the indicators panel if not
1421 in fullscreen.
1422 */
1423-void UbuntuWindow::updatePanelHeightHack(Qt::WindowState state)
1424+void UbuntuWindow::enablePanelHeightHack(bool enable)
1425 {
1426- if (state == Qt::WindowFullScreen && geometry().y() != 0) {
1427- QRect newGeometry = geometry();
1428+ QRect newGeometry = geometry();
1429+ if (enable) {
1430+ newGeometry.setY(panelHeight());
1431+ } else {
1432 newGeometry.setY(0);
1433- QWindowSystemInterface::handleGeometryChange(window(), newGeometry);
1434- } else if (geometry().y() == 0) {
1435- QRect newGeometry = geometry();
1436- newGeometry.setY(panelHeight());
1437+ }
1438+
1439+ if (newGeometry != geometry()) {
1440+ QPlatformWindow::setGeometry(newGeometry);
1441 QWindowSystemInterface::handleGeometryChange(window(), newGeometry);
1442 }
1443 }
1444
1445-void UbuntuWindow::setGeometry(const QRect& rect)
1446+void UbuntuWindow::setGeometry(const QRect &rect)
1447 {
1448 QMutexLocker lock(&mMutex);
1449- DLOG("[ubuntumirclient QPA] setGeometry (window=%p, x=%d, y=%d, width=%d, height=%d)",
1450- window(), rect.x(), rect.y(), rect.width(), rect.height());
1451+ qCDebug(ubuntumirclient, "setGeometry (window=%p, position=(%d, %d)dp, size=(%dx%d)dp)",
1452+ window(), rect.x(), rect.y(), rect.width(), rect.height());
1453
1454 //NOTE: mir surfaces cannot be moved by the client so ignore the topLeft coordinates
1455 const auto newSize = rect.size();
1456 auto newGeometry = geometry();
1457 newGeometry.setSize(newSize);
1458- QPlatformWindow::setGeometry(newGeometry);
1459
1460- mSurface->resize(newSize);
1461+ mSurface->resize(newSize * devicePixelRatio());
1462+ // Note: don't call handleGeometryChange here, wait to see what Mir replies with.
1463 }
1464
1465 void UbuntuWindow::setVisible(bool visible)
1466 {
1467 QMutexLocker lock(&mMutex);
1468- DLOG("[ubuntumirclient QPA] setVisible (window=%p, visible=%s)", window(), visible ? "true" : "false");
1469+ qCDebug(ubuntumirclient, "setVisible (window=%p, visible=%s)", window(), visible ? "true" : "false");
1470
1471 mSurface->setVisible(visible);
1472 const QRect& exposeRect = visible ? QRect(QPoint(), geometry().size()) : QRect();
1473@@ -595,10 +608,10 @@
1474 QWindowSystemInterface::flushWindowSystemEvents();
1475 }
1476
1477-void UbuntuWindow::setWindowTitle(const QString& title)
1478+void UbuntuWindow::setWindowTitle(const QString &title)
1479 {
1480 QMutexLocker lock(&mMutex);
1481- DLOG("[ubuntumirclient QPA] setWindowTitle(window=%p) title=%s)", window(), title.toUtf8().constData());
1482+ qCDebug(ubuntumirclient, "setWindowTitle(window=%p) title=%s)", window(), title.toUtf8().constData());
1483 mSurface->updateTitle(title);
1484 }
1485
1486@@ -606,11 +619,17 @@
1487 {
1488 QMutexLocker lock(&mMutex);
1489 const auto win = window();
1490- DLOG("[ubuntumirclient QPA] propagateSizeHints(window=%p) min(%d,%d), max(%d,%d) increment(%d, %d)",
1491- win, win->minimumSize().width(), win->minimumSize().height(),
1492- win->maximumSize().width(), win->maximumSize().height(),
1493- win->sizeIncrement().width(), win->sizeIncrement().height());
1494- mSurface->setSizingConstraints(win->minimumSize(), win->maximumSize(), win->sizeIncrement());
1495+ const float dpr = devicePixelRatio();
1496+ qCDebug(ubuntumirclient, "propagateSizeHints(window=%p) min(%dx%d)dp; max(%dx%d)dp; increment(%dx%d)dp",
1497+ win, win->minimumSize().width(), win->minimumSize().height(),
1498+ win->maximumSize().width(), win->maximumSize().height(),
1499+ win->sizeIncrement().width(), win->sizeIncrement().height());
1500+ mSurface->setSizingConstraints(win->minimumSize() * dpr, win->maximumSize() * dpr, win->sizeIncrement() * dpr);
1501+}
1502+
1503+qreal UbuntuWindow::devicePixelRatio() const
1504+{
1505+ return screen() ? screen()->devicePixelRatio() : 1.0; // not impossible a Window has no attached Screen
1506 }
1507
1508 void* UbuntuWindow::eglSurface() const
1509
1510=== modified file 'src/ubuntumirclient/window.h'
1511--- src/ubuntumirclient/window.h 2015-12-07 16:20:58 +0000
1512+++ src/ubuntumirclient/window.h 2015-12-17 10:58:59 +0000
1513@@ -18,6 +18,7 @@
1514 #define UBUNTU_WINDOW_H
1515
1516 #include <qpa/qplatformwindow.h>
1517+#include <QLoggingCategory>
1518 #include <QSharedPointer>
1519 #include <QMutex>
1520
1521@@ -45,16 +46,18 @@
1522 void setVisible(bool visible) override;
1523 void setWindowTitle(const QString &title) override;
1524 void propagateSizeHints() override;
1525+ qreal devicePixelRatio() const override;
1526
1527 // New methods.
1528 void *eglSurface() const;
1529 MirSurface *mirSurface() const;
1530- void handleSurfaceResized(int width, int height);
1531+ void updateWindowSize(int widthPx, int heightPx);
1532+ void handleSurfaceResized(int widthPx, int heightPx);
1533 void handleSurfaceFocused();
1534 void onSwapBuffersDone();
1535
1536 private:
1537- void updatePanelHeightHack(Qt::WindowState);
1538+ void enablePanelHeightHack(bool enable);
1539 mutable QMutex mMutex;
1540 const WId mId;
1541 const QSharedPointer<UbuntuClipboard> mClipboard;

Subscribers

People subscribed via source and target branches