Merge lp:~unity-team/qtmir/dpr into lp:qtmir

Proposed by Gerry Boland
Status: Work in progress
Proposed branch: lp:~unity-team/qtmir/dpr
Merge into: lp:qtmir
Diff against target: 722 lines (+187/-116) (has conflicts)
14 files modified
debian/changelog (+9/-0)
src/modules/Unity/Application/mirsurface.cpp (+63/-61)
src/modules/Unity/Application/mirsurface.h (+8/-8)
src/modules/Unity/Application/mirsurfaceinterface.h (+8/-8)
src/modules/Unity/Application/mirsurfaceitem.cpp (+36/-16)
src/modules/Unity/Application/mirsurfaceitem.h (+1/-0)
src/platforms/mirserver/qteventfeeder.cpp (+13/-6)
src/platforms/mirserver/qteventfeeder.h (+1/-0)
src/platforms/mirserver/screen.cpp (+26/-5)
src/platforms/mirserver/screen.h (+5/-2)
src/platforms/mirserver/screencontroller.cpp (+2/-2)
src/platforms/mirserver/screenwindow.cpp (+5/-0)
src/platforms/mirserver/screenwindow.h (+2/-0)
tests/modules/common/fake_mirsurface.h (+8/-8)
Text conflict in debian/changelog
To merge this branch: bzr merge lp:~unity-team/qtmir/dpr
Reviewer Review Type Date Requested Status
Unity8 CI Bot (community) continuous-integration Needs Fixing
Daniel d'Andrada (community) Approve
PS Jenkins bot (community) continuous-integration Needs Fixing
Review via email: mp+257514@code.launchpad.net

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/qtubuntu/DPR2/+merge/281664

* 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.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Gerry Boland (gerboland) wrote :

 * 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/qtubuntu/DPR/+merge/257515
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

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Daniel d'Andrada (dandrader) wrote :

In src/modules/Unity/Application/mirsurfaceitem.cpp:

"""
- int qmlWidth = (int)width();
- int qmlHeight = (int)height();
+ const qreal dpr = devicePixelRatio();
+ int qmlWidth = (int)width() * dpr;
+ int qmlHeight = (int)height() * dpr;
"""

Now they're no longer representing the qml width and height, thus the naming is misleading.
Better calling them something like newMirWidth and newMirHeight.

Also it would be more correct to cast to int *after* the dpr multiplication: (int)(width() * dpr)

review: Needs Fixing
Revision history for this message
Daniel d'Andrada (dandrader) wrote :

In src/modules/Unity/Application/mirsurfaceitem.cpp:

"""
         qCDebug(QTMIR_SURFACES) << "MirSurfaceItem::syncSurfaceSizeWithItemSize()";
- mir::geometry::Size newMirSize((int)width(), (int)height());
+ mir::geometry::Size newMirSize(scaledWidth, scaledHeight);
         m_surface->resize(newMirSize);
- setImplicitSize(width(), height());
+ setImplicitSize(scaledWidth, scaledHeight);
     }
 }
"""

The implicit size should not be scaled.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel d'Andrada (dandrader) wrote :

The debian/changelog entry is misplaced. Likely the result of a bad merge with trunk.

Revision history for this message
Daniel d'Andrada (dandrader) wrote :

The only way I see of saving MirSurface from knowing about DPR is passing it the event data directly as parameters instead of giving it the whole QEvent.

Eg:

MirSurface::mouseMoveEvent(QMouseEvent *event, qreal dpr)

Would be:

MirSurface::mouseMoveEvent(Qt::MouseButtons buttons, ulong timestamp, Qt::KeyboardModifiers modifiers, int x, int y)

Which is actually not a bad thing.

Revision history for this message
Gerry Boland (gerboland) wrote :

> The only way I see of saving MirSurface from knowing about DPR is passing it
> the event data directly as parameters instead of giving it the whole QEvent.
>
> Eg:
>
> MirSurface::mouseMoveEvent(QMouseEvent *event, qreal dpr)
>
> Would be:
>
> MirSurface::mouseMoveEvent(Qt::MouseButtons buttons, ulong timestamp,
> Qt::KeyboardModifiers modifiers, int x, int y)
>
> Which is actually not a bad thing.

For touch events too?

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Daniel d'Andrada (dandrader) wrote :

On 18/09/15 08:44, Gerry Boland wrote:
>> The only way I see of saving MirSurface from knowing about DPR is passing it
>> the event data directly as parameters instead of giving it the whole QEvent.
>>
>> Eg:
>>
>> MirSurface::mouseMoveEvent(QMouseEvent *event, qreal dpr)
>>
>> Would be:
>>
>> MirSurface::mouseMoveEvent(Qt::MouseButtons buttons, ulong timestamp,
>> Qt::KeyboardModifiers modifiers, int x, int y)
>>
>> Which is actually not a bad thing.
> For touch events too?

You'll have to to copy the QList<QTouchEvent::TouchPoint> parameter so
you can transform the points. Is that what you're afraid of (performance
hit)?

Revision history for this message
Gerry Boland (gerboland) wrote :

> On 18/09/15 08:44, Gerry Boland wrote:
> >> The only way I see of saving MirSurface from knowing about DPR is passing
> it
> >> the event data directly as parameters instead of giving it the whole
> QEvent.
> >>
> >> Eg:
> >>
> >> MirSurface::mouseMoveEvent(QMouseEvent *event, qreal dpr)
> >>
> >> Would be:
> >>
> >> MirSurface::mouseMoveEvent(Qt::MouseButtons buttons, ulong timestamp,
> >> Qt::KeyboardModifiers modifiers, int x, int y)
> >>
> >> Which is actually not a bad thing.
> > For touch events too?
>
> You'll have to to copy the QList<QTouchEvent::TouchPoint> parameter so
> you can transform the points. Is that what you're afraid of (performance
> hit)?

Well more generally, it seems to be so much work just for a multiplication. Is why I'm hesitating.

Revision history for this message
Daniel d'Andrada (dandrader) wrote :

In mirsurfaceitem.cpp:

"""
m_lastTouchEvent->touchPoints = touchPoints; ////????
"""

????

Revision history for this message
Daniel d'Andrada (dandrader) wrote :

In mirsurfceitem.cpp:

"""
Note: all geometry is in device-pixels, except that contained in variables with the
"""

s/device-pixels/device-independent pixels

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Daniel d'Andrada (dandrader) wrote :

"""
const float kP = mir_touch_event_axis_value(tev, i, mir_touch_axis_pressure) / dpr;
"""

Not sure if the pressure axis has any relationship with x & y dimensions to deserve the dpr conversion.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Daniel d'Andrada (dandrader) wrote :
review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel d'Andrada (dandrader) wrote :

In MirSurfaceItem::updatePaintNode, I would move the "const qreal dpr" declaration next to the single place where it's used.

Revision history for this message
Daniel d'Andrada (dandrader) wrote :

Still in MirSurfaceItem::updatePaintNode:

"""
qreal u = targetRect.width() / textureSize.width() * dpr;
"""

Would be better expressed as:

"""
qreal u = (targetRect.width() * dpr) / textureSize.width();
"""

To make it obvious that your're converting targetRect.width() from DIP (or layout pixels) to actual/physical pixels, which is the unit of textureSize.width().

Likewise for the v coordinate.

Revision history for this message
Daniel d'Andrada (dandrader) wrote :

In src/platforms/mirserver/qteventfeeder.cpp:

"""
    qreal getDevicePixelRatio() override
    {
        return qGuiApp->devicePixelRatio(); // FIXME: make per-screen.
    }
"""

Qt coding style doesn't use the "get" prefix for getters. I think we should stick to it unless there's a good reason to deviate.

Revision history for this message
Daniel d'Andrada (dandrader) wrote :

In QtEventFeeder::dispatchPointer:

"""
    auto movement = QPointF(mir_pointer_event_axis_value(pev, mir_pointer_axis_relative_x) / dpr,
                            mir_pointer_event_axis_value(pev, mir_pointer_axis_relative_y)) / dpr;
"""

I think you meant:

"""
    auto movement = QPointF(mir_pointer_event_axis_value(pev, mir_pointer_axis_relative_x) / dpr,
                            mir_pointer_event_axis_value(pev, mir_pointer_axis_relative_y) / dpr);
"""

review: Needs Fixing
Revision history for this message
Daniel d'Andrada (dandrader) wrote :

Nitpick in Screen::Screen

"""
    bool ok;
    const int dpr = qGetEnvIntValue("QT_DEVICE_PIXEL_RATIO", &ok);
    m_devicePixelRatio = (ok && dpr > 0) ? dpr : 1.0;
"""

You would be better off moving this whole snippet into a separate function instead of just the qGetEnvIntValue part (as it's used only once anyway). That would spare the constructor namespace from getting polluted with those helper variables ok and dpr.

PS: That's what happens when you re-review something. You start to nitpick :)

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Gerry Boland (gerboland) wrote :

I can merge this into trunk just fine. LP confused?

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel d'Andrada (dandrader) wrote :

Code looks fine. Didn't test yet.

review: Approve (code)
Revision history for this message
Daniel d'Andrada (dandrader) wrote :

And works fine as well.

review: Approve
Revision history for this message
Michał Sawicz (saviq) wrote :

Text conflict in debian/changelog

Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Michał Sawicz (saviq) wrote :

Text conflict in src/modules/Unity/Application/mirsurface.cpp
Text conflict in src/platforms/mirserver/screen.h
Text conflict in tests/framework/fake_mirsurface.h
3 conflicts encountered.

Revision history for this message
Gerry Boland (gerboland) wrote :

Marking WIP, needs rebasing on top of DGU work

Unmerged revisions

360. By Gerry Boland

Move DPR env var reading into dedicated function

359. By Gerry Boland

Typo in DPR calculation

358. By Gerry Boland

getDevicePixelRatio -> devicePixelRatio

357. By Gerry Boland

MirSurfaceItem::updatePaintNode - move calculation around to clarify intention

356. By Gerry Boland

MirSurfaceItem::updatePaintNode Move dpr inside block where it is used

355. By Gerry Boland

Merge trunk

354. By Gerry Boland

Fix scaling to render app surface correctly

353. By Gerry Boland

Add units to debug message

352. By Gerry Boland

Merge trunk

351. By Gerry Boland

Merge trunk

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2016-01-04 09:38:12 +0000
3+++ debian/changelog 2016-01-07 17:03:26 +0000
4@@ -1,3 +1,4 @@
5+<<<<<<< TREE
6 qtmir (0.4.7+16.04.20160104-0ubuntu1) xenial; urgency=medium
7
8 [ Daniel d'Andrada ]
9@@ -6,6 +7,14 @@
10
11 -- Michał Sawicz <michal.sawicz@canonical.com> Mon, 04 Jan 2016 09:38:12 +0000
12
13+=======
14+qtmir (0.4.8) UNRELEASED; urgency=medium
15+
16+ * Add support for devicePixelRatio, the Qt5.4 UI scaling system
17+
18+ -- Gerry Boland <gerry.boland@canonical.com> Mon, 04 Jan 2016 12:30:00 +0100
19+
20+>>>>>>> MERGE-SOURCE
21 qtmir (0.4.7+16.04.20151222-0ubuntu1) xenial; urgency=medium
22
23 * No-change rebuild to get -gles in sync
24
25=== modified file 'src/modules/Unity/Application/mirsurface.cpp'
26--- src/modules/Unity/Application/mirsurface.cpp 2015-12-10 13:08:43 +0000
27+++ src/modules/Unity/Application/mirsurface.cpp 2016-01-07 17:03:26 +0000
28@@ -73,34 +73,34 @@
29 return result;
30 }
31
32-mir::EventUPtr makeMirEvent(QMouseEvent *qtEvent, MirPointerAction action)
33+mir::EventUPtr makeMirEvent(QMouseEvent *qtEvent, MirPointerAction action, qreal dpr)
34 {
35 auto timestamp = uncompressTimestamp<qtmir::Timestamp>(qtmir::Timestamp(qtEvent->timestamp()));
36 auto modifiers = getMirModifiersFromQt(qtEvent->modifiers());
37 auto buttons = getMirButtonsFromQt(qtEvent->buttons());
38
39 return mir::events::make_event(0 /*DeviceID */, timestamp, 0 /* mac */, modifiers, action,
40- buttons, qtEvent->x(), qtEvent->y(), 0, 0, 0, 0);
41+ buttons, qtEvent->x() * dpr, qtEvent->y() * dpr, 0, 0, 0, 0);
42 }
43
44-mir::EventUPtr makeMirEvent(QHoverEvent *qtEvent, MirPointerAction action)
45+mir::EventUPtr makeMirEvent(QHoverEvent *qtEvent, MirPointerAction action, qreal dpr)
46 {
47 auto timestamp = uncompressTimestamp<qtmir::Timestamp>(qtmir::Timestamp(qtEvent->timestamp()));
48
49 MirPointerButtons buttons = 0;
50
51 return mir::events::make_event(0 /*DeviceID */, timestamp, 0 /* mac */, mir_input_event_modifier_none, action,
52- buttons, qtEvent->posF().x(), qtEvent->posF().y(), 0, 0, 0, 0);
53+ buttons, qtEvent->posF().x() * dpr, qtEvent->posF().y() * dpr, 0, 0, 0, 0);
54 }
55
56-mir::EventUPtr makeMirEvent(QWheelEvent *qtEvent)
57+mir::EventUPtr makeMirEvent(QWheelEvent *qtEvent, qreal dpr)
58 {
59 auto timestamp = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::milliseconds(qtEvent->timestamp()));
60 auto modifiers = getMirModifiersFromQt(qtEvent->modifiers());
61 auto buttons = getMirButtonsFromQt(qtEvent->buttons());
62
63 return mir::events::make_event(0 /*DeviceID */, timestamp, 0 /* mac */, modifiers, mir_pointer_action_motion,
64- buttons, qtEvent->x(), qtEvent->y(),
65+ buttons, qtEvent->x() * dpr, qtEvent->y() * dpr,
66 qtEvent->angleDelta().x(), qtEvent->angleDelta().y(),
67 0, 0);
68 }
69@@ -131,7 +131,8 @@
70 mir::EventUPtr makeMirEvent(Qt::KeyboardModifiers qmods,
71 const QList<QTouchEvent::TouchPoint> &qtTouchPoints,
72 Qt::TouchPointStates /* qtTouchPointStates */,
73- ulong qtTimestamp)
74+ ulong qtTimestamp,
75+ qreal dpr)
76 {
77 auto modifiers = getMirModifiersFromQt(qmods);
78 auto ev = mir::events::make_event(0, uncompressTimestamp<qtmir::Timestamp>(qtmir::Timestamp(qtTimestamp)),
79@@ -156,10 +157,10 @@
80 tooltype = mir_touch_tooltype_stylus;
81
82 mir::events::add_touch(*ev, id, action, tooltype,
83- touchPoint.pos().x(), touchPoint.pos().y(),
84+ touchPoint.pos().x() * dpr, touchPoint.pos().y() * dpr,
85 touchPoint.pressure(),
86- touchPoint.rect().width(),
87- touchPoint.rect().height(),
88+ touchPoint.rect().width() * dpr,
89+ touchPoint.rect().height() * dpr,
90 0 /* size */);
91 }
92
93@@ -429,16 +430,16 @@
94
95 void MirSurface::resize(int width, int height)
96 {
97- int mirWidth = m_surface->size().width.as_int();
98- int mirHeight = m_surface->size().height.as_int();
99+ const int mirWidth = m_surface->size().width.as_int();
100+ const int mirHeight = m_surface->size().height.as_int();
101
102 bool mirSizeIsDifferent = width != mirWidth || height != mirHeight;
103
104 if (clientIsRunning() && mirSizeIsDifferent) {
105 mir::geometry::Size newMirSize(width, height);
106 m_surface->resize(newMirSize);
107- DEBUG_MSG << " old (" << mirWidth << "," << mirHeight << ")"
108- << ", new (" << width << "," << height << ")";
109+ DEBUG_MSG << " old (" << mirWidth << "," << mirHeight << ")px"
110+ << ", new (" << width << "," << height << ")px";
111 }
112 }
113
114@@ -576,51 +577,51 @@
115 return m_surface->query(mir_surface_attrib_visibility) == mir_surface_visibility_exposed;
116 }
117
118-void MirSurface::mousePressEvent(QMouseEvent *event)
119-{
120- auto ev = makeMirEvent(event, mir_pointer_action_button_down);
121- m_surface->consume(*ev);
122- event->accept();
123-}
124-
125-void MirSurface::mouseMoveEvent(QMouseEvent *event)
126-{
127- auto ev = makeMirEvent(event, mir_pointer_action_motion);
128- m_surface->consume(*ev);
129- event->accept();
130-}
131-
132-void MirSurface::mouseReleaseEvent(QMouseEvent *event)
133-{
134- auto ev = makeMirEvent(event, mir_pointer_action_button_up);
135- m_surface->consume(*ev);
136- event->accept();
137-}
138-
139-void MirSurface::hoverEnterEvent(QHoverEvent *event)
140-{
141- auto ev = makeMirEvent(event, mir_pointer_action_enter);
142- m_surface->consume(*ev);
143- event->accept();
144-}
145-
146-void MirSurface::hoverLeaveEvent(QHoverEvent *event)
147-{
148- auto ev = makeMirEvent(event, mir_pointer_action_leave);
149- m_surface->consume(*ev);
150- event->accept();
151-}
152-
153-void MirSurface::hoverMoveEvent(QHoverEvent *event)
154-{
155- auto ev = makeMirEvent(event, mir_pointer_action_motion);
156- m_surface->consume(*ev);
157- event->accept();
158-}
159-
160-void MirSurface::wheelEvent(QWheelEvent *event)
161-{
162- auto ev = makeMirEvent(event);
163+void MirSurface::mousePressEvent(QMouseEvent *event, qreal dpr)
164+{
165+ auto ev = makeMirEvent(event, mir_pointer_action_button_down, dpr);
166+ m_surface->consume(*ev);
167+ event->accept();
168+}
169+
170+void MirSurface::mouseMoveEvent(QMouseEvent *event, qreal dpr)
171+{
172+ auto ev = makeMirEvent(event, mir_pointer_action_motion, dpr);
173+ m_surface->consume(*ev);
174+ event->accept();
175+}
176+
177+void MirSurface::mouseReleaseEvent(QMouseEvent *event, qreal dpr)
178+{
179+ auto ev = makeMirEvent(event, mir_pointer_action_button_up, dpr);
180+ m_surface->consume(*ev);
181+ event->accept();
182+}
183+
184+void MirSurface::hoverEnterEvent(QHoverEvent *event, qreal dpr)
185+{
186+ auto ev = makeMirEvent(event, mir_pointer_action_enter, dpr);
187+ m_surface->consume(*ev);
188+ event->accept();
189+}
190+
191+void MirSurface::hoverLeaveEvent(QHoverEvent *event, qreal dpr)
192+{
193+ auto ev = makeMirEvent(event, mir_pointer_action_leave, dpr);
194+ m_surface->consume(*ev);
195+ event->accept();
196+}
197+
198+void MirSurface::hoverMoveEvent(QHoverEvent *event, qreal dpr)
199+{
200+ auto ev = makeMirEvent(event, mir_pointer_action_motion, dpr);
201+ m_surface->consume(*ev);
202+ event->accept();
203+}
204+
205+void MirSurface::wheelEvent(QWheelEvent *event, qreal dpr)
206+{
207+ auto ev = makeMirEvent(event, dpr);
208 m_surface->consume(*ev);
209 event->accept();
210 }
211@@ -642,9 +643,10 @@
212 void MirSurface::touchEvent(Qt::KeyboardModifiers mods,
213 const QList<QTouchEvent::TouchPoint> &touchPoints,
214 Qt::TouchPointStates touchPointStates,
215- ulong timestamp)
216+ ulong timestamp,
217+ qreal dpr)
218 {
219- auto ev = makeMirEvent(mods, touchPoints, touchPointStates, timestamp);
220+ auto ev = makeMirEvent(mods, touchPoints, touchPointStates, timestamp, dpr);
221 m_surface->consume(*ev);
222 }
223
224
225=== modified file 'src/modules/Unity/Application/mirsurface.h'
226--- src/modules/Unity/Application/mirsurface.h 2015-12-10 13:08:43 +0000
227+++ src/modules/Unity/Application/mirsurface.h 2016-01-07 17:03:26 +0000
228@@ -101,13 +101,13 @@
229
230 void close() override;
231
232- void mousePressEvent(QMouseEvent *event) override;
233- void mouseMoveEvent(QMouseEvent *event) override;
234- void mouseReleaseEvent(QMouseEvent *event) override;
235- void hoverEnterEvent(QHoverEvent *event) override;
236- void hoverLeaveEvent(QHoverEvent *event) override;
237- void hoverMoveEvent(QHoverEvent *event) override;
238- void wheelEvent(QWheelEvent *event) override;
239+ void mousePressEvent(QMouseEvent *event, qreal dpr) override;
240+ void mouseMoveEvent(QMouseEvent *event, qreal dpr) override;
241+ void mouseReleaseEvent(QMouseEvent *event, qreal dpr) override;
242+ void hoverEnterEvent(QHoverEvent *event, qreal dpr) override;
243+ void hoverLeaveEvent(QHoverEvent *event, qreal dpr) override;
244+ void hoverMoveEvent(QHoverEvent *event, qreal dpr) override;
245+ void wheelEvent(QWheelEvent *event, qreal dpr) override;
246
247 void keyPressEvent(QKeyEvent *event) override;
248 void keyReleaseEvent(QKeyEvent *event) override;
249@@ -115,7 +115,7 @@
250 void touchEvent(Qt::KeyboardModifiers qmods,
251 const QList<QTouchEvent::TouchPoint> &qtTouchPoints,
252 Qt::TouchPointStates qtTouchPointStates,
253- ulong qtTimestamp) override;
254+ ulong qtTimestamp, qreal dpr) override;
255
256 QString appId() const override;
257
258
259=== modified file 'src/modules/Unity/Application/mirsurfaceinterface.h'
260--- src/modules/Unity/Application/mirsurfaceinterface.h 2015-12-10 13:08:43 +0000
261+++ src/modules/Unity/Application/mirsurfaceinterface.h 2016-01-07 17:03:26 +0000
262@@ -66,13 +66,13 @@
263
264 virtual void close() = 0;
265
266- virtual void mousePressEvent(QMouseEvent *event) = 0;
267- virtual void mouseMoveEvent(QMouseEvent *event) = 0;
268- virtual void mouseReleaseEvent(QMouseEvent *event) = 0;
269- virtual void hoverEnterEvent(QHoverEvent *event) = 0;
270- virtual void hoverLeaveEvent(QHoverEvent *event) = 0;
271- virtual void hoverMoveEvent(QHoverEvent *event) = 0;
272- virtual void wheelEvent(QWheelEvent *event) = 0;
273+ virtual void mousePressEvent(QMouseEvent *event, qreal dpr = 1.0) = 0;
274+ virtual void mouseMoveEvent(QMouseEvent *event, qreal dpr = 1.0) = 0;
275+ virtual void mouseReleaseEvent(QMouseEvent *event, qreal dpr = 1.0) = 0;
276+ virtual void hoverEnterEvent(QHoverEvent *event, qreal dpr = 1.0) = 0;
277+ virtual void hoverLeaveEvent(QHoverEvent *event, qreal dpr = 1.0) = 0;
278+ virtual void hoverMoveEvent(QHoverEvent *event, qreal dpr = 1.0) = 0;
279+ virtual void wheelEvent(QWheelEvent *event, qreal dpr = 1.0) = 0;
280
281 virtual void keyPressEvent(QKeyEvent *event) = 0;
282 virtual void keyReleaseEvent(QKeyEvent *event) = 0;
283@@ -80,7 +80,7 @@
284 virtual void touchEvent(Qt::KeyboardModifiers qmods,
285 const QList<QTouchEvent::TouchPoint> &qtTouchPoints,
286 Qt::TouchPointStates qtTouchPointStates,
287- ulong qtTimestamp) = 0;
288+ ulong qtTimestamp, qreal dpr = 1.0) = 0;
289
290 virtual QString appId() const = 0;
291
292
293=== modified file 'src/modules/Unity/Application/mirsurfaceitem.cpp'
294--- src/modules/Unity/Application/mirsurfaceitem.cpp 2015-12-10 13:08:43 +0000
295+++ src/modules/Unity/Application/mirsurfaceitem.cpp 2016-01-07 17:03:26 +0000
296@@ -54,6 +54,11 @@
297 QObject *textureProvider;
298 };
299
300+inline int divideAndRoundUp(int numerator, qreal denominator)
301+{
302+ return ceil((qreal)numerator / denominator);
303+}
304+
305 } // namespace {
306
307 class MirTextureProvider : public QSGTextureProvider
308@@ -81,6 +86,11 @@
309 QSharedPointer<QSGTexture> t;
310 };
311
312+/*
313+ * Note: all geometry is in device-independent pixels, except that contained in variables with the
314+ * suffix "Px" - whose units are physical pixels
315+ */
316+
317 MirSurfaceItem::MirSurfaceItem(QQuickItem *parent)
318 : MirSurfaceItemInterface(parent)
319 , m_surface(nullptr)
320@@ -248,13 +258,14 @@
321
322 if (m_fillMode == PadOrCrop) {
323 const QSize &textureSize = m_textureProvider->texture()->textureSize();
324+ const qreal dpr = devicePixelRatio();
325
326 QRectF targetRect;
327 targetRect.setWidth(qMin(width(), static_cast<qreal>(textureSize.width())));
328 targetRect.setHeight(qMin(height(), static_cast<qreal>(textureSize.height())));
329
330- qreal u = targetRect.width() / textureSize.width();
331- qreal v = targetRect.height() / textureSize.height();
332+ qreal u = (targetRect.width() * dpr) / textureSize.width();
333+ qreal v = (targetRect.height() * dpr) / textureSize.height();
334 node->setSubSourceRect(QRectF(0, 0, u, v));
335
336 node->setTargetRect(targetRect);
337@@ -285,12 +296,12 @@
338 if (type() == Mir::InputMethodType) {
339 // FIXME: Hack to get the VKB use case working while we don't have the proper solution in place.
340 if (isMouseInsideUbuntuKeyboard(event)) {
341- m_surface->mousePressEvent(event);
342+ m_surface->mousePressEvent(event, devicePixelRatio());
343 } else {
344 event->ignore();
345 }
346 } else {
347- m_surface->mousePressEvent(event);
348+ m_surface->mousePressEvent(event, devicePixelRatio());
349 }
350 } else {
351 event->ignore();
352@@ -300,7 +311,7 @@
353 void MirSurfaceItem::mouseMoveEvent(QMouseEvent *event)
354 {
355 if (m_consumesInput && m_surface && m_surface->live()) {
356- m_surface->mouseMoveEvent(event);
357+ m_surface->mouseMoveEvent(event, devicePixelRatio());
358 } else {
359 event->ignore();
360 }
361@@ -309,7 +320,7 @@
362 void MirSurfaceItem::mouseReleaseEvent(QMouseEvent *event)
363 {
364 if (m_consumesInput && m_surface && m_surface->live()) {
365- m_surface->mouseReleaseEvent(event);
366+ m_surface->mouseReleaseEvent(event, devicePixelRatio());
367 } else {
368 event->ignore();
369 }
370@@ -327,7 +338,7 @@
371 void MirSurfaceItem::hoverEnterEvent(QHoverEvent *event)
372 {
373 if (m_consumesInput && m_surface && m_surface->live()) {
374- m_surface->hoverEnterEvent(event);
375+ m_surface->hoverEnterEvent(event, devicePixelRatio());
376 } else {
377 event->ignore();
378 }
379@@ -336,7 +347,7 @@
380 void MirSurfaceItem::hoverLeaveEvent(QHoverEvent *event)
381 {
382 if (m_consumesInput && m_surface && m_surface->live()) {
383- m_surface->hoverLeaveEvent(event);
384+ m_surface->hoverLeaveEvent(event, devicePixelRatio());
385 } else {
386 event->ignore();
387 }
388@@ -345,7 +356,7 @@
389 void MirSurfaceItem::hoverMoveEvent(QHoverEvent *event)
390 {
391 if (m_consumesInput && m_surface && m_surface->live()) {
392- m_surface->hoverMoveEvent(event);
393+ m_surface->hoverMoveEvent(event, devicePixelRatio());
394 } else {
395 event->ignore();
396 }
397@@ -404,7 +415,7 @@
398 touchEvent.updateTouchPointStatesAndType();
399
400 m_surface->touchEvent(touchEvent.modifiers, touchEvent.touchPoints,
401- touchEvent.touchPointStates, touchEvent.timestamp);
402+ touchEvent.touchPointStates, touchEvent.timestamp, devicePixelRatio());
403
404 *m_lastTouchEvent = touchEvent;
405
406@@ -425,7 +436,7 @@
407 endCurrentTouchSequence(timestamp);
408 }
409
410- m_surface->touchEvent(mods, touchPoints, touchPointStates, timestamp);
411+ m_surface->touchEvent(mods, touchPoints, touchPointStates, timestamp, devicePixelRatio());
412
413 if (!m_lastTouchEvent) {
414 m_lastTouchEvent = new TouchEvent;
415@@ -537,10 +548,12 @@
416 }
417
418 // If one dimension is not set, fallback to the current value
419- int width = m_surfaceWidth > 0 ? m_surfaceWidth : m_surface->size().width();
420- int height = m_surfaceHeight > 0 ? m_surfaceHeight : m_surface->size().height();
421+ const int width = m_surfaceWidth > 0 ? m_surfaceWidth : m_surface->size().width();
422+ const int height = m_surfaceHeight > 0 ? m_surfaceHeight : m_surface->size().height();
423+ const int widthPx = width * devicePixelRatio();
424+ const int heightPx = height * devicePixelRatio();
425
426- m_surface->resize(width, height);
427+ m_surface->resize(widthPx, heightPx);
428 }
429
430 void MirSurfaceItem::updateMirSurfaceVisibility()
431@@ -565,6 +578,11 @@
432 m_textureProvider = nullptr;
433 }
434
435+qreal MirSurfaceItem::devicePixelRatio() const
436+{
437+ return window() ? window()->devicePixelRatio() : 1.0;
438+}
439+
440 void MirSurfaceItem::TouchEvent::updateTouchPointStatesAndType()
441 {
442 touchPointStates = 0;
443@@ -654,7 +672,8 @@
444 Q_EMIT surfaceStateChanged(m_surface->state());
445
446 updateMirSurfaceSize();
447- setImplicitSize(m_surface->size().width(), m_surface->size().height());
448+ setImplicitSize(divideAndRoundUp(m_surface->size().width(), devicePixelRatio()),
449+ divideAndRoundUp(m_surface->size().height(), devicePixelRatio()));
450 updateMirSurfaceVisibility();
451
452 // Qt::ArrowCursor is the default when no cursor has been explicitly set, so no point forwarding it.
453@@ -729,7 +748,8 @@
454
455 void MirSurfaceItem::onActualSurfaceSizeChanged(const QSize &size)
456 {
457- setImplicitSize(size.width(), size.height());
458+ setImplicitSize(divideAndRoundUp(size.width(), devicePixelRatio()),
459+ divideAndRoundUp(size.height(), devicePixelRatio()));
460 }
461
462 int MirSurfaceItem::surfaceHeight() const
463
464=== modified file 'src/modules/Unity/Application/mirsurfaceitem.h'
465--- src/modules/Unity/Application/mirsurfaceitem.h 2015-12-10 13:08:43 +0000
466+++ src/modules/Unity/Application/mirsurfaceitem.h 2016-01-07 17:03:26 +0000
467@@ -123,6 +123,7 @@
468 void onWindowChanged(QQuickWindow *window);
469
470 private:
471+ qreal devicePixelRatio() const;
472 void ensureTextureProvider();
473
474 bool hasTouchInsideUbuntuKeyboard(const QList<QTouchEvent::TouchPoint> &touchPoints);
475
476=== modified file 'src/platforms/mirserver/qteventfeeder.cpp'
477--- src/platforms/mirserver/qteventfeeder.cpp 2015-12-07 08:06:16 +0000
478+++ src/platforms/mirserver/qteventfeeder.cpp 2016-01-07 17:03:26 +0000
479@@ -395,6 +395,11 @@
480 return m_screenController->getWindowForPoint(point);
481 }
482
483+ qreal devicePixelRatio() override
484+ {
485+ return qGuiApp->devicePixelRatio(); // FIXME: make per-screen.
486+ }
487+
488 void registerTouchDevice(QTouchDevice *device) override
489 {
490 QWindowSystemInterface::registerTouchDevice(device);
491@@ -558,8 +563,9 @@
492
493 auto modifiers = getQtModifiersFromMir(mir_pointer_event_modifiers(pev));
494
495- auto movement = QPointF(mir_pointer_event_axis_value(pev, mir_pointer_axis_relative_x),
496- mir_pointer_event_axis_value(pev, mir_pointer_axis_relative_y));
497+ const qreal dpr = mQtWindowSystem->devicePixelRatio();
498+ auto movement = QPointF(mir_pointer_event_axis_value(pev, mir_pointer_axis_relative_x) / dpr,
499+ mir_pointer_event_axis_value(pev, mir_pointer_axis_relative_y) / dpr);
500
501 switch (action) {
502 case mir_pointer_action_button_up:
503@@ -653,6 +659,7 @@
504 // FIXME(loicm) Max pressure is device specific. That one is for the Samsung Galaxy Nexus. That
505 // needs to be fixed as soon as the compat input lib adds query support.
506 const float kMaxPressure = 1.28;
507+ const qreal dpr = mQtWindowSystem->devicePixelRatio();
508 const int kPointerCount = mir_touch_event_point_count(tev);
509 QList<QWindowSystemInterface::TouchPoint> touchPoints;
510 QWindow *window = nullptr;
511@@ -674,10 +681,10 @@
512 for (int i = 0; i < kPointerCount; ++i) {
513 QWindowSystemInterface::TouchPoint touchPoint;
514
515- const float kX = mir_touch_event_axis_value(tev, i, mir_touch_axis_x);
516- const float kY = mir_touch_event_axis_value(tev, i, mir_touch_axis_y);
517- const float kW = mir_touch_event_axis_value(tev, i, mir_touch_axis_touch_major);
518- const float kH = mir_touch_event_axis_value(tev, i, mir_touch_axis_touch_minor);
519+ const float kX = mir_touch_event_axis_value(tev, i, mir_touch_axis_x) / dpr;
520+ const float kY = mir_touch_event_axis_value(tev, i, mir_touch_axis_y) / dpr;
521+ const float kW = mir_touch_event_axis_value(tev, i, mir_touch_axis_touch_major) / dpr;
522+ const float kH = mir_touch_event_axis_value(tev, i, mir_touch_axis_touch_minor) / dpr;
523 const float kP = mir_touch_event_axis_value(tev, i, mir_touch_axis_pressure);
524 touchPoint.id = mir_touch_event_id(tev, i);
525
526
527=== modified file 'src/platforms/mirserver/qteventfeeder.h'
528--- src/platforms/mirserver/qteventfeeder.h 2015-11-19 14:17:54 +0000
529+++ src/platforms/mirserver/qteventfeeder.h 2016-01-07 17:03:26 +0000
530@@ -39,6 +39,7 @@
531 virtual ~QtWindowSystemInterface() {}
532 virtual void setScreenController(const QSharedPointer<ScreenController> &sc) = 0;
533 virtual QWindow* getWindowForTouchPoint(const QPoint &point) = 0;
534+ virtual qreal devicePixelRatio() { return 1.0; }
535 virtual QWindow* focusedWindow() = 0;
536 virtual void registerTouchDevice(QTouchDevice *device) = 0;
537 virtual void handleExtendedKeyEvent(QWindow *window, ulong timestamp, QEvent::Type type, int key,
538
539=== modified file 'src/platforms/mirserver/screen.cpp'
540--- src/platforms/mirserver/screen.cpp 2015-10-14 22:59:04 +0000
541+++ src/platforms/mirserver/screen.cpp 2016-01-07 17:03:26 +0000
542@@ -44,6 +44,7 @@
543 char *c = (char*)&i;
544 return *c == 1;
545 }
546+
547 static mir::renderer::gl::RenderTarget *as_render_target(
548 mir::graphics::DisplayBuffer *displayBuffer)
549 {
550@@ -56,6 +57,17 @@
551 return render_target;
552 }
553
554+qreal readDevicePixelRatioEnvVar()
555+{
556+ bool ok;
557+ const int dpr = qgetenv("QT_DEVICE_PIXEL_RATIO").toInt(&ok);
558+ if (ok && dpr > 0) {
559+ return (qreal) dpr;
560+ } else {
561+ return 1.0; // fallback value
562+ }
563+}
564+
565 enum QImage::Format qImageFormatFromMirPixelFormat(MirPixelFormat mirPixelFormat) {
566 switch (mirPixelFormat) {
567 case mir_pixel_format_abgr_8888:
568@@ -123,6 +135,9 @@
569 , m_screenWindow(nullptr)
570 , m_unityScreen(nullptr)
571 {
572+ // Get screen resolution and properties.
573+ m_devicePixelRatio = readDevicePixelRatioEnvVar();
574+
575 setMirDisplayConfiguration(screen);
576
577 // Set the default orientation based on the initial screen dimmensions.
578@@ -197,14 +212,20 @@
579 m_powerMode = screen.power_mode;
580
581 QRect oldGeometry = m_geometry;
582- // Position of screen in virtual desktop coordinate space
583- m_geometry.setTop(screen.top_left.y.as_int());
584- m_geometry.setLeft(screen.top_left.x.as_int());
585+ // Position of screen in virtual desktop coordinate space (physical pixels)
586+ m_nativeGeometry.setTop(screen.top_left.y.as_int());
587+ m_nativeGeometry.setLeft(screen.top_left.x.as_int());
588
589 // Mode = current resolution & refresh rate
590 mir::graphics::DisplayConfigurationMode mode = screen.modes.at(screen.current_mode_index);
591- m_geometry.setWidth(mode.size.width.as_int());
592- m_geometry.setHeight(mode.size.height.as_int());
593+ m_nativeGeometry.setWidth(mode.size.width.as_int());
594+ m_nativeGeometry.setHeight(mode.size.height.as_int());
595+
596+ // Geometry is in terms of device-independent pixels
597+ m_geometry.setTop(m_nativeGeometry.top() / m_devicePixelRatio);
598+ m_geometry.setLeft(m_nativeGeometry.left() / m_devicePixelRatio);
599+ m_geometry.setWidth(m_nativeGeometry.width() / m_devicePixelRatio);
600+ m_geometry.setHeight(m_nativeGeometry.height() / m_devicePixelRatio);
601
602 // DPI - unnecessary to calculate, default implementation in QPlatformScreen is sufficient
603
604
605=== modified file 'src/platforms/mirserver/screen.h'
606--- src/platforms/mirserver/screen.h 2015-10-14 22:59:04 +0000
607+++ src/platforms/mirserver/screen.h 2016-01-07 17:03:26 +0000
608@@ -44,13 +44,15 @@
609 ~Screen();
610
611 // QPlatformScreen methods.
612- QRect geometry() const override { return m_geometry; }
613+ QRect geometry() const override { return m_geometry; } // in device-independent pixels
614+ QRect nativeGeometry() const { return m_nativeGeometry; } // in physical pixels
615 int depth() const override { return m_depth; }
616 QImage::Format format() const override { return m_format; }
617 QSizeF physicalSize() const override { return m_physicalSize; }
618 qreal refreshRate() const override { return m_refreshRate; }
619 Qt::ScreenOrientation nativeOrientation() const override { return m_nativeOrientation; }
620 Qt::ScreenOrientation orientation() const override { return m_currentOrientation; }
621+ qreal devicePixelRatio() const override { return m_devicePixelRatio; }
622 QPlatformCursor *cursor() const override;
623
624 void toggleSensors(const bool enable) const;
625@@ -79,11 +81,12 @@
626 void doneCurrent();
627
628 private:
629- QRect m_geometry;
630+ QRect m_geometry, m_nativeGeometry;
631 int m_depth;
632 QImage::Format m_format;
633 QSizeF m_physicalSize;
634 qreal m_refreshRate;
635+ qreal m_devicePixelRatio;
636
637 mir::renderer::gl::RenderTarget *m_renderTarget;
638 mir::graphics::DisplaySyncGroup *m_displayGroup;
639
640=== modified file 'src/platforms/mirserver/screencontroller.cpp'
641--- src/platforms/mirserver/screencontroller.cpp 2015-10-21 11:34:56 +0000
642+++ src/platforms/mirserver/screencontroller.cpp 2016-01-07 17:03:26 +0000
643@@ -163,7 +163,7 @@
644 buffer.view_area().size.height.as_int());
645
646 for (auto screen : m_screenList) {
647- if (dbGeom == screen->geometry()) {
648+ if (dbGeom == screen->nativeGeometry()) {
649 screen->setMirDisplayBuffer(&buffer, &group);
650 break;
651 }
652@@ -174,7 +174,7 @@
653 qCDebug(QTMIR_SCREENS) << "=======================================";
654 for (auto screen: m_screenList) {
655 qCDebug(QTMIR_SCREENS) << screen << "- id:" << screen->m_outputId.as_value()
656- << "geometry:" << screen->geometry()
657+ << "geometry (px):" << screen->nativeGeometry()
658 << "window:" << screen->window()
659 << "type" << static_cast<int>(screen->outputType());
660 }
661
662=== modified file 'src/platforms/mirserver/screenwindow.cpp'
663--- src/platforms/mirserver/screenwindow.cpp 2015-10-15 07:05:16 +0000
664+++ src/platforms/mirserver/screenwindow.cpp 2016-01-07 17:03:26 +0000
665@@ -60,6 +60,11 @@
666 window->setSurfaceType(QSurface::OpenGLSurface);
667 }
668
669+qreal ScreenWindow::devicePixelRatio() const
670+{
671+ return screen()->devicePixelRatio();
672+}
673+
674 ScreenWindow::~ScreenWindow()
675 {
676 qCDebug(QTMIR_SCREENS) << "Destroying ScreenWindow" << this;
677
678=== modified file 'src/platforms/mirserver/screenwindow.h'
679--- src/platforms/mirserver/screenwindow.h 2015-10-14 22:59:04 +0000
680+++ src/platforms/mirserver/screenwindow.h 2016-01-07 17:03:26 +0000
681@@ -29,6 +29,8 @@
682 explicit ScreenWindow(QWindow *window);
683 virtual ~ScreenWindow();
684
685+ qreal devicePixelRatio() const override;
686+
687 bool isExposed() const override;
688 void setExposed(const bool exposed);
689
690
691=== modified file 'tests/modules/common/fake_mirsurface.h'
692--- tests/modules/common/fake_mirsurface.h 2015-12-10 13:08:43 +0000
693+++ tests/modules/common/fake_mirsurface.h 2016-01-07 17:03:26 +0000
694@@ -152,13 +152,13 @@
695
696 void setFocus(bool focus) override { m_focused = focus; }
697
698- void mousePressEvent(QMouseEvent *) override {}
699- void mouseMoveEvent(QMouseEvent *) override {}
700- void mouseReleaseEvent(QMouseEvent *) override {}
701- void hoverEnterEvent(QHoverEvent *) override {}
702- void hoverLeaveEvent(QHoverEvent *) override {}
703- void hoverMoveEvent(QHoverEvent *) override {}
704- void wheelEvent(QWheelEvent *) override {}
705+ void mousePressEvent(QMouseEvent *, qreal) override {}
706+ void mouseMoveEvent(QMouseEvent *, qreal) override {}
707+ void mouseReleaseEvent(QMouseEvent *, qreal) override {}
708+ void hoverEnterEvent(QHoverEvent *, qreal) override {}
709+ void hoverLeaveEvent(QHoverEvent *, qreal) override {}
710+ void hoverMoveEvent(QHoverEvent *, qreal) override {}
711+ void wheelEvent(QWheelEvent *, qreal) override {}
712
713 void keyPressEvent(QKeyEvent *) override {}
714 void keyReleaseEvent(QKeyEvent *) override {}
715@@ -166,7 +166,7 @@
716 void touchEvent(Qt::KeyboardModifiers mods,
717 const QList<QTouchEvent::TouchPoint> &points,
718 Qt::TouchPointStates states,
719- ulong timestamp) override {
720+ ulong timestamp, qreal) override {
721 m_touchesReceived.append(TouchEvent(mods, points, states, timestamp));
722 }
723

Subscribers

People subscribed via source and target branches