Merge lp:~unity-team/qtubuntu/screen-info into lp:qtubuntu
- screen-info
- Merge into trunk
Proposed by
Michał Sawicz
Status: | Work in progress |
---|---|
Proposed branch: | lp:~unity-team/qtubuntu/screen-info |
Merge into: | lp:qtubuntu |
Prerequisite: | lp:~nick-dedekind/qtubuntu/shell_chrome |
Diff against target: |
1696 lines (+777/-270) 15 files modified
src/ubuntumirclient/backingstore.cpp (+11/-5) src/ubuntumirclient/input.cpp (+101/-53) src/ubuntumirclient/input.h (+2/-0) src/ubuntumirclient/integration.cpp (+51/-14) src/ubuntumirclient/integration.h (+12/-3) src/ubuntumirclient/nativeinterface.cpp (+55/-3) src/ubuntumirclient/nativeinterface.h (+11/-1) src/ubuntumirclient/screen.cpp (+100/-62) src/ubuntumirclient/screen.h (+26/-4) src/ubuntumirclient/screenobserver.cpp (+131/-0) src/ubuntumirclient/screenobserver.h (+54/-0) src/ubuntumirclient/ubuntumirclient.pro (+4/-1) src/ubuntumirclient/utils.h (+29/-0) src/ubuntumirclient/window.cpp (+172/-118) src/ubuntumirclient/window.h (+18/-6) |
To merge this branch: | bzr merge lp:~unity-team/qtubuntu/screen-info |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Unity8 CI Bot | continuous-integration | Approve | |
Ubuntu Phablet Team | Pending | ||
Review via email: mp+286329@code.launchpad.net |
This proposal supersedes a proposal from 2016-02-03.
Commit message
Dynamic scaling support
Description of the change
To post a comment you must log in.
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
review:
Approve
(continuous-integration)
Unmerged revisions
- 329. By Michał Sawicz
-
Merge trunk
- 328. By Nick Dedekind
-
remerge
- 327. By Nick Dedekind
-
merged with parent
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'src/ubuntumirclient/backingstore.cpp' | |||
2 | --- src/ubuntumirclient/backingstore.cpp 2014-12-04 12:29:39 +0000 | |||
3 | +++ src/ubuntumirclient/backingstore.cpp 2016-04-20 15:51:01 +0000 | |||
4 | @@ -1,5 +1,5 @@ | |||
5 | 1 | /* | 1 | /* |
7 | 2 | * Copyright (C) 2014 Canonical, Ltd. | 2 | * Copyright (C) 2014-2015 Canonical, Ltd. |
8 | 3 | * | 3 | * |
9 | 4 | * This program is free software: you can redistribute it and/or modify it under | 4 | * This program is free software: you can redistribute it and/or modify it under |
10 | 5 | * the terms of the GNU Lesser General Public License version 3, as published by | 5 | * the terms of the GNU Lesser General Public License version 3, as published by |
11 | @@ -43,8 +43,10 @@ | |||
12 | 43 | { | 43 | { |
13 | 44 | Q_UNUSED(region); | 44 | Q_UNUSED(region); |
14 | 45 | Q_UNUSED(offset); | 45 | Q_UNUSED(offset); |
15 | 46 | const int dpr = int(window->devicePixelRatio()); | ||
16 | 47 | |||
17 | 46 | mContext->makeCurrent(window); | 48 | mContext->makeCurrent(window); |
19 | 47 | glViewport(0, 0, window->width(), window->height()); | 49 | glViewport(0, 0, window->width() * dpr, window->height() * dpr); |
20 | 48 | 50 | ||
21 | 49 | updateTexture(); | 51 | updateTexture(); |
22 | 50 | 52 | ||
23 | @@ -75,12 +77,14 @@ | |||
24 | 75 | 77 | ||
25 | 76 | QRegion fixed; | 78 | QRegion fixed; |
26 | 77 | QRect imageRect = mImage.rect(); | 79 | QRect imageRect = mImage.rect(); |
27 | 80 | const int dpr = int(window()->devicePixelRatio()); | ||
28 | 78 | 81 | ||
30 | 79 | /* Following code taken from QEGLPlatformBackingStore under the terms of the Lesser GPL v2.1 licence | 82 | /* Following code a modified form of that in QEGLPlatformBackingStore, used under the terms of the Lesser GPL v2.1 licence |
31 | 80 | * Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). */ | 83 | * Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). */ |
32 | 81 | Q_FOREACH (const QRect &rect, mDirty.rects()) { | 84 | Q_FOREACH (const QRect &rect, mDirty.rects()) { |
33 | 85 | QRect scaledRect(rect.topLeft() * dpr, rect.size() * dpr); | ||
34 | 82 | // intersect with image rect to be sure | 86 | // intersect with image rect to be sure |
36 | 83 | QRect r = imageRect & rect; | 87 | QRect r = imageRect & scaledRect; |
37 | 84 | 88 | ||
38 | 85 | // if the rect is wide enough it is cheaper to just extend it instead of doing an image copy | 89 | // if the rect is wide enough it is cheaper to just extend it instead of doing an image copy |
39 | 86 | if (r.width() >= imageRect.width() / 2) { | 90 | if (r.width() >= imageRect.width() / 2) { |
40 | @@ -115,7 +119,9 @@ | |||
41 | 115 | 119 | ||
42 | 116 | void UbuntuBackingStore::resize(const QSize& size, const QRegion& /*staticContents*/) | 120 | void UbuntuBackingStore::resize(const QSize& size, const QRegion& /*staticContents*/) |
43 | 117 | { | 121 | { |
45 | 118 | mImage = QImage(size, QImage::Format_RGB32); | 122 | const int dpr = int(window()->devicePixelRatio()); |
46 | 123 | mImage = QImage(size * dpr, QImage::Format_RGB32); | ||
47 | 124 | mImage.setDevicePixelRatio(dpr); | ||
48 | 119 | 125 | ||
49 | 120 | if (mTexture->isCreated()) | 126 | if (mTexture->isCreated()) |
50 | 121 | mTexture->destroy(); | 127 | mTexture->destroy(); |
51 | 122 | 128 | ||
52 | === modified file 'src/ubuntumirclient/input.cpp' | |||
53 | --- src/ubuntumirclient/input.cpp 2016-03-22 08:49:43 +0000 | |||
54 | +++ src/ubuntumirclient/input.cpp 2016-04-20 15:51:01 +0000 | |||
55 | @@ -224,6 +224,8 @@ | |||
56 | 224 | return "mir_event_type_close_surface"; | 224 | return "mir_event_type_close_surface"; |
57 | 225 | case mir_event_type_input: | 225 | case mir_event_type_input: |
58 | 226 | return "mir_event_type_input"; | 226 | return "mir_event_type_input"; |
59 | 227 | case mir_event_type_surface_output: | ||
60 | 228 | return "mir_event_type_surface_output"; | ||
61 | 227 | default: | 229 | default: |
62 | 228 | return "invalid"; | 230 | return "invalid"; |
63 | 229 | } | 231 | } |
64 | @@ -259,55 +261,26 @@ | |||
65 | 259 | break; | 261 | break; |
66 | 260 | case mir_event_type_resize: | 262 | case mir_event_type_resize: |
67 | 261 | { | 263 | { |
68 | 262 | Q_ASSERT(ubuntuEvent->window->screen() == mIntegration->screen()); | ||
69 | 263 | |||
70 | 264 | auto resizeEvent = mir_event_get_resize_event(nativeEvent); | 264 | auto resizeEvent = mir_event_get_resize_event(nativeEvent); |
71 | 265 | 265 | ||
75 | 266 | mIntegration->screen()->handleWindowSurfaceResize( | 266 | // Enable workaround for Screen rotation |
76 | 267 | mir_resize_event_get_width(resizeEvent), | 267 | auto screen = static_cast<UbuntuScreen*>(ubuntuEvent->window->screen()); |
77 | 268 | mir_resize_event_get_height(resizeEvent)); | 268 | if (screen) { |
78 | 269 | screen->handleWindowSurfaceResize( | ||
79 | 270 | mir_resize_event_get_width(resizeEvent), | ||
80 | 271 | mir_resize_event_get_height(resizeEvent)); | ||
81 | 272 | } | ||
82 | 269 | 273 | ||
83 | 270 | ubuntuEvent->window->handleSurfaceResized(mir_resize_event_get_width(resizeEvent), | 274 | ubuntuEvent->window->handleSurfaceResized(mir_resize_event_get_width(resizeEvent), |
84 | 271 | mir_resize_event_get_height(resizeEvent)); | 275 | mir_resize_event_get_height(resizeEvent)); |
85 | 272 | break; | 276 | break; |
86 | 273 | } | 277 | } |
87 | 274 | case mir_event_type_surface: | 278 | case mir_event_type_surface: |
124 | 275 | { | 279 | handleSurfaceEvent(ubuntuEvent->window, mir_event_get_surface_event(nativeEvent)); |
125 | 276 | auto surfaceEvent = mir_event_get_surface_event(nativeEvent); | 280 | break; |
126 | 277 | auto surfaceEventAttribute = mir_surface_event_get_attribute(surfaceEvent); | 281 | case mir_event_type_surface_output: |
127 | 278 | 282 | handleSurfaceOutputEvent(ubuntuEvent->window, mir_event_get_surface_output_event(nativeEvent)); | |
128 | 279 | if (surfaceEventAttribute == mir_surface_attrib_focus) { | 283 | break; |
93 | 280 | const bool focused = mir_surface_event_get_attribute_value(surfaceEvent) == mir_surface_focused; | ||
94 | 281 | // Mir may have sent a pair of focus lost/gained events, so we need to "peek" into the queue | ||
95 | 282 | // so that we don't deactivate windows prematurely. | ||
96 | 283 | if (focused) { | ||
97 | 284 | mPendingFocusGainedEvents--; | ||
98 | 285 | ubuntuEvent->window->handleSurfaceFocused(); | ||
99 | 286 | QWindowSystemInterface::handleWindowActivated(ubuntuEvent->window->window(), Qt::ActiveWindowFocusReason); | ||
100 | 287 | |||
101 | 288 | // NB: Since processing of system events is queued, never check qGuiApp->applicationState() | ||
102 | 289 | // as it might be outdated. Always call handleApplicationStateChanged() with the latest | ||
103 | 290 | // state regardless. | ||
104 | 291 | QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationActive); | ||
105 | 292 | |||
106 | 293 | } else if(!mPendingFocusGainedEvents) { | ||
107 | 294 | qCDebug(ubuntumirclient, "No windows have focus"); | ||
108 | 295 | QWindowSystemInterface::handleWindowActivated(nullptr, Qt::ActiveWindowFocusReason); | ||
109 | 296 | QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationInactive); | ||
110 | 297 | } | ||
111 | 298 | } else if (surfaceEventAttribute == mir_surface_attrib_state) { | ||
112 | 299 | MirSurfaceState state = static_cast<MirSurfaceState>(mir_surface_event_get_attribute_value(surfaceEvent)); | ||
113 | 300 | |||
114 | 301 | if (state == mir_surface_state_hidden) { | ||
115 | 302 | ubuntuEvent->window->handleSurfaceVisibilityChanged(false); | ||
116 | 303 | } else { | ||
117 | 304 | // it's visible! | ||
118 | 305 | ubuntuEvent->window->handleSurfaceVisibilityChanged(true); | ||
119 | 306 | ubuntuEvent->window->handleSurfaceStateChanged(mirSurfaceStateToWindowState(state)); | ||
120 | 307 | } | ||
121 | 308 | } | ||
122 | 309 | break; | ||
123 | 310 | } | ||
129 | 311 | case mir_event_type_orientation: | 284 | case mir_event_type_orientation: |
130 | 312 | dispatchOrientationEvent(ubuntuEvent->window->window(), mir_event_get_orientation_event(nativeEvent)); | 285 | dispatchOrientationEvent(ubuntuEvent->window->window(), mir_event_get_orientation_event(nativeEvent)); |
131 | 313 | break; | 286 | break; |
132 | @@ -372,6 +345,7 @@ | |||
133 | 372 | const QRect kWindowGeometry = window->geometry(); | 345 | const QRect kWindowGeometry = window->geometry(); |
134 | 373 | QList<QWindowSystemInterface::TouchPoint> touchPoints; | 346 | QList<QWindowSystemInterface::TouchPoint> touchPoints; |
135 | 374 | 347 | ||
136 | 348 | const int dpr = int(window->devicePixelRatio()); | ||
137 | 375 | 349 | ||
138 | 376 | // TODO: Is it worth setting the Qt::TouchPointStationary ones? Currently they are left | 350 | // TODO: Is it worth setting the Qt::TouchPointStationary ones? Currently they are left |
139 | 377 | // as Qt::TouchPointMoved | 351 | // as Qt::TouchPointMoved |
140 | @@ -379,10 +353,10 @@ | |||
141 | 379 | for (unsigned int i = 0; i < kPointerCount; ++i) { | 353 | for (unsigned int i = 0; i < kPointerCount; ++i) { |
142 | 380 | QWindowSystemInterface::TouchPoint touchPoint; | 354 | QWindowSystemInterface::TouchPoint touchPoint; |
143 | 381 | 355 | ||
148 | 382 | const float kX = mir_touch_event_axis_value(tev, i, mir_touch_axis_x) + kWindowGeometry.x(); | 356 | const float kX = mir_touch_event_axis_value(tev, i, mir_touch_axis_x) / dpr + kWindowGeometry.x(); |
149 | 383 | const float kY = mir_touch_event_axis_value(tev, i, mir_touch_axis_y) + kWindowGeometry.y(); // see bug lp:1346633 workaround comments elsewhere | 357 | const float kY = mir_touch_event_axis_value(tev, i, mir_touch_axis_y) / dpr + kWindowGeometry.y(); // see bug lp:1346633 workaround comments elsewhere |
150 | 384 | const float kW = mir_touch_event_axis_value(tev, i, mir_touch_axis_touch_major); | 358 | const float kW = mir_touch_event_axis_value(tev, i, mir_touch_axis_touch_major) / dpr; |
151 | 385 | const float kH = mir_touch_event_axis_value(tev, i, mir_touch_axis_touch_minor); | 359 | const float kH = mir_touch_event_axis_value(tev, i, mir_touch_axis_touch_minor) / dpr; |
152 | 386 | const float kP = mir_touch_event_axis_value(tev, i, mir_touch_axis_pressure); | 360 | const float kP = mir_touch_event_axis_value(tev, i, mir_touch_axis_pressure); |
153 | 387 | touchPoint.id = mir_touch_event_id(tev, i); | 361 | touchPoint.id = mir_touch_event_id(tev, i); |
154 | 388 | touchPoint.normalPosition = QPointF(kX / kWindowGeometry.width(), kY / kWindowGeometry.height()); | 362 | touchPoint.normalPosition = QPointF(kX / kWindowGeometry.width(), kY / kWindowGeometry.height()); |
155 | @@ -525,14 +499,16 @@ | |||
156 | 525 | 499 | ||
157 | 526 | void UbuntuInput::dispatchPointerEvent(UbuntuWindow *platformWindow, const MirInputEvent *ev) | 500 | void UbuntuInput::dispatchPointerEvent(UbuntuWindow *platformWindow, const MirInputEvent *ev) |
158 | 527 | { | 501 | { |
167 | 528 | auto window = platformWindow->window(); | 502 | const int dpr = int(platformWindow->devicePixelRatio()); |
168 | 529 | auto timestamp = mir_input_event_get_event_time(ev) / 1000000; | 503 | const auto window = platformWindow->window(); |
169 | 530 | 504 | const auto timestamp = mir_input_event_get_event_time(ev) / 1000000; | |
170 | 531 | auto pev = mir_input_event_get_pointer_event(ev); | 505 | |
171 | 532 | auto action = mir_pointer_event_action(pev); | 506 | const auto pev = mir_input_event_get_pointer_event(ev); |
172 | 533 | auto localPoint = QPointF(mir_pointer_event_axis_value(pev, mir_pointer_axis_x), | 507 | const auto action = mir_pointer_event_action(pev); |
173 | 534 | mir_pointer_event_axis_value(pev, mir_pointer_axis_y)); | 508 | |
174 | 535 | auto modifiers = qt_modifiers_from_mir(mir_pointer_event_modifiers(pev)); | 509 | const auto modifiers = qt_modifiers_from_mir(mir_pointer_event_modifiers(pev)); |
175 | 510 | const auto localPoint = QPointF(mir_pointer_event_axis_value(pev, mir_pointer_axis_x) / dpr, | ||
176 | 511 | mir_pointer_event_axis_value(pev, mir_pointer_axis_y) / dpr); | ||
177 | 536 | 512 | ||
178 | 537 | switch (action) { | 513 | switch (action) { |
179 | 538 | case mir_pointer_action_button_up: | 514 | case mir_pointer_action_button_up: |
180 | @@ -620,3 +596,75 @@ | |||
181 | 620 | new OrientationChangeEvent(OrientationChangeEvent::mType, orientation)); | 596 | new OrientationChangeEvent(OrientationChangeEvent::mType, orientation)); |
182 | 621 | } | 597 | } |
183 | 622 | 598 | ||
184 | 599 | void UbuntuInput::handleSurfaceEvent(const QPointer<UbuntuWindow> &window, const MirSurfaceEvent *event) | ||
185 | 600 | { | ||
186 | 601 | auto surfaceEventAttribute = mir_surface_event_get_attribute(event); | ||
187 | 602 | |||
188 | 603 | switch (surfaceEventAttribute) { | ||
189 | 604 | case mir_surface_attrib_focus: { | ||
190 | 605 | const bool focused = mir_surface_event_get_attribute_value(event) == mir_surface_focused; | ||
191 | 606 | // Mir may have sent a pair of focus lost/gained events, so we need to "peek" into the queue | ||
192 | 607 | // so that we don't deactivate windows prematurely. | ||
193 | 608 | if (focused) { | ||
194 | 609 | mPendingFocusGainedEvents--; | ||
195 | 610 | window->handleSurfaceFocused(); | ||
196 | 611 | QWindowSystemInterface::handleWindowActivated(window->window(), Qt::ActiveWindowFocusReason); | ||
197 | 612 | |||
198 | 613 | // NB: Since processing of system events is queued, never check qGuiApp->applicationState() | ||
199 | 614 | // as it might be outdated. Always call handleApplicationStateChanged() with the latest | ||
200 | 615 | // state regardless. | ||
201 | 616 | QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationActive); | ||
202 | 617 | |||
203 | 618 | } else if(!mPendingFocusGainedEvents) { | ||
204 | 619 | qCDebug(ubuntumirclient, "No windows have focus"); | ||
205 | 620 | QWindowSystemInterface::handleWindowActivated(nullptr, Qt::ActiveWindowFocusReason); | ||
206 | 621 | QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationInactive); | ||
207 | 622 | } | ||
208 | 623 | break; | ||
209 | 624 | } | ||
210 | 625 | case mir_surface_attrib_visibility: | ||
211 | 626 | window->handleSurfaceExposeChange( | ||
212 | 627 | mir_surface_event_get_attribute_value(event) == mir_surface_visibility_exposed); | ||
213 | 628 | break; | ||
214 | 629 | // Remaining attributes are ones client sets for server, and server should not override them | ||
215 | 630 | case mir_surface_attrib_state: { | ||
216 | 631 | MirSurfaceState state = static_cast<MirSurfaceState>(mir_surface_event_get_attribute_value(event)); | ||
217 | 632 | if (state == mir_surface_state_hidden) { | ||
218 | 633 | window->handleSurfaceVisibilityChanged(false); | ||
219 | 634 | } else { | ||
220 | 635 | // it's visible! | ||
221 | 636 | window->handleSurfaceVisibilityChanged(true); | ||
222 | 637 | window->handleSurfaceStateChanged(mirSurfaceStateToWindowState(state)); | ||
223 | 638 | } | ||
224 | 639 | break; | ||
225 | 640 | } | ||
226 | 641 | case mir_surface_attrib_type: | ||
227 | 642 | case mir_surface_attrib_swapinterval: | ||
228 | 643 | case mir_surface_attrib_dpi: | ||
229 | 644 | case mir_surface_attrib_preferred_orientation: | ||
230 | 645 | case mir_surface_attribs: | ||
231 | 646 | break; | ||
232 | 647 | } | ||
233 | 648 | } | ||
234 | 649 | |||
235 | 650 | void UbuntuInput::handleSurfaceOutputEvent(const QPointer<UbuntuWindow> &window, const MirSurfaceOutputEvent *event) | ||
236 | 651 | { | ||
237 | 652 | const uint32_t outputId = mir_surface_output_event_get_output_id(event); | ||
238 | 653 | const int dpi = mir_surface_output_event_get_dpi(event); | ||
239 | 654 | const MirFormFactor formFactor = mir_surface_output_event_get_form_factor(event); | ||
240 | 655 | const float scale = mir_surface_output_event_get_scale(event); | ||
241 | 656 | |||
242 | 657 | const auto screenObserver = mIntegration->screenObserver(); | ||
243 | 658 | UbuntuScreen *screen = screenObserver->findScreenWithId(outputId); | ||
244 | 659 | if (!screen) { | ||
245 | 660 | qWarning() << "Mir notified window" << window->window() << "on an unknown screen with id" << outputId; | ||
246 | 661 | return; | ||
247 | 662 | } | ||
248 | 663 | |||
249 | 664 | screenObserver->handleScreenPropertiesChange(screen, dpi, formFactor, scale); | ||
250 | 665 | window->handleScreenPropertiesChange(formFactor, scale); | ||
251 | 666 | |||
252 | 667 | if (window->screen() != screen) { | ||
253 | 668 | QWindowSystemInterface::handleWindowScreenChanged(window->window(), screen->screen()); | ||
254 | 669 | } | ||
255 | 670 | } | ||
256 | 623 | 671 | ||
257 | === modified file 'src/ubuntumirclient/input.h' | |||
258 | --- src/ubuntumirclient/input.h 2015-12-09 13:02:07 +0000 | |||
259 | +++ src/ubuntumirclient/input.h 2016-04-20 15:51:01 +0000 | |||
260 | @@ -49,6 +49,8 @@ | |||
261 | 49 | void dispatchInputEvent(UbuntuWindow *window, const MirInputEvent *event); | 49 | void dispatchInputEvent(UbuntuWindow *window, const MirInputEvent *event); |
262 | 50 | 50 | ||
263 | 51 | void dispatchOrientationEvent(QWindow* window, const MirOrientationEvent *event); | 51 | void dispatchOrientationEvent(QWindow* window, const MirOrientationEvent *event); |
264 | 52 | void handleSurfaceEvent(const QPointer<UbuntuWindow> &window, const MirSurfaceEvent *event); | ||
265 | 53 | void handleSurfaceOutputEvent(const QPointer<UbuntuWindow> &window, const MirSurfaceOutputEvent *event); | ||
266 | 52 | 54 | ||
267 | 53 | private: | 55 | private: |
268 | 54 | UbuntuClientIntegration* mIntegration; | 56 | UbuntuClientIntegration* mIntegration; |
269 | 55 | 57 | ||
270 | === modified file 'src/ubuntumirclient/integration.cpp' | |||
271 | --- src/ubuntumirclient/integration.cpp 2016-01-04 17:18:51 +0000 | |||
272 | +++ src/ubuntumirclient/integration.cpp 2016-04-20 15:51:01 +0000 | |||
273 | @@ -88,19 +88,26 @@ | |||
274 | 88 | "rejected the incoming connection, so check its log file"); | 88 | "rejected the incoming connection, so check its log file"); |
275 | 89 | 89 | ||
276 | 90 | mNativeInterface->setMirConnection(u_application_instance_get_mir_connection(mInstance)); | 90 | mNativeInterface->setMirConnection(u_application_instance_get_mir_connection(mInstance)); |
281 | 91 | 91 | } | |
282 | 92 | // Create default screen. | 92 | |
283 | 93 | mScreen = new UbuntuScreen(u_application_instance_get_mir_connection(mInstance)); | 93 | void UbuntuClientIntegration::initialize() |
284 | 94 | screenAdded(mScreen); | 94 | { |
285 | 95 | MirConnection *mirConnection = u_application_instance_get_mir_connection(mInstance); | ||
286 | 96 | |||
287 | 97 | // Init the ScreenObserver | ||
288 | 98 | mScreenObserver.reset(new UbuntuScreenObserver(mirConnection)); | ||
289 | 99 | connect(mScreenObserver.data(), &UbuntuScreenObserver::screenAdded, | ||
290 | 100 | [this](UbuntuScreen *screen) { this->screenAdded(screen); }); | ||
291 | 101 | connect(mScreenObserver.data(), &UbuntuScreenObserver::screenRemoved, | ||
292 | 102 | this, &UbuntuClientIntegration::destroyScreen); | ||
293 | 103 | |||
294 | 104 | Q_FOREACH(auto screen, mScreenObserver->screens()) { | ||
295 | 105 | screenAdded(screen); | ||
296 | 106 | } | ||
297 | 95 | 107 | ||
298 | 96 | // Initialize input. | 108 | // Initialize input. |
306 | 97 | if (qEnvironmentVariableIsEmpty("QTUBUNTU_NO_INPUT")) { | 109 | mInput = new UbuntuInput(this); |
307 | 98 | mInput = new UbuntuInput(this); | 110 | mInputContext = QPlatformInputContextFactory::create(); |
301 | 99 | mInputContext = QPlatformInputContextFactory::create(); | ||
302 | 100 | } else { | ||
303 | 101 | mInput = nullptr; | ||
304 | 102 | mInputContext = nullptr; | ||
305 | 103 | } | ||
308 | 104 | 111 | ||
309 | 105 | // compute the scale factor | 112 | // compute the scale factor |
310 | 106 | const int defaultGridUnit = 8; | 113 | const int defaultGridUnit = 8; |
311 | @@ -120,7 +127,6 @@ | |||
312 | 120 | { | 127 | { |
313 | 121 | delete mInput; | 128 | delete mInput; |
314 | 122 | delete mInputContext; | 129 | delete mInputContext; |
315 | 123 | delete mScreen; | ||
316 | 124 | delete mServices; | 130 | delete mServices; |
317 | 125 | } | 131 | } |
318 | 126 | 132 | ||
319 | @@ -165,8 +171,8 @@ | |||
320 | 165 | 171 | ||
321 | 166 | QPlatformWindow* UbuntuClientIntegration::createPlatformWindow(QWindow* window) | 172 | QPlatformWindow* UbuntuClientIntegration::createPlatformWindow(QWindow* window) |
322 | 167 | { | 173 | { |
325 | 168 | return new UbuntuWindow(window, mClipboard, static_cast<UbuntuScreen*>(mScreen), | 174 | return new UbuntuWindow(window, mClipboard, mInput, mNativeInterface, |
326 | 169 | mInput, u_application_instance_get_mir_connection(mInstance)); | 175 | u_application_instance_get_mir_connection(mInstance)); |
327 | 170 | } | 176 | } |
328 | 171 | 177 | ||
329 | 172 | bool UbuntuClientIntegration::hasCapability(QPlatformIntegration::Capability cap) const | 178 | bool UbuntuClientIntegration::hasCapability(QPlatformIntegration::Capability cap) const |
330 | @@ -262,3 +268,34 @@ | |||
331 | 262 | { | 268 | { |
332 | 263 | return new UbuntuOffscreenSurface(surface); | 269 | return new UbuntuOffscreenSurface(surface); |
333 | 264 | } | 270 | } |
334 | 271 | |||
335 | 272 | void UbuntuClientIntegration::destroyScreen(UbuntuScreen *screen) | ||
336 | 273 | { | ||
337 | 274 | // FIXME: on deleting a screen while a Window is on it, Qt will automatically | ||
338 | 275 | // move the window to the primaryScreen(). This will trigger a screenChanged | ||
339 | 276 | // signal, causing things like QQuickScreenAttached to re-fetch screen properties | ||
340 | 277 | // like DPI and physical size. However this is crashing, as Qt is calling virtual | ||
341 | 278 | // functions on QPlatformScreen, for reasons unclear. As workaround, move window | ||
342 | 279 | // to primaryScreen() before deleting the screen. Might be QTBUG-38650 | ||
343 | 280 | |||
344 | 281 | QScreen *primaryScreen = QGuiApplication::primaryScreen(); | ||
345 | 282 | if (screen != primaryScreen->handle()) { | ||
346 | 283 | uint32_t movedWindowCount = 0; | ||
347 | 284 | Q_FOREACH (QWindow *w, QGuiApplication::topLevelWindows()) { | ||
348 | 285 | if (w->screen()->handle() == screen) { | ||
349 | 286 | QWindowSystemInterface::handleWindowScreenChanged(w, primaryScreen); | ||
350 | 287 | ++movedWindowCount; | ||
351 | 288 | } | ||
352 | 289 | } | ||
353 | 290 | if (movedWindowCount > 0) { | ||
354 | 291 | QWindowSystemInterface::flushWindowSystemEvents(); | ||
355 | 292 | } | ||
356 | 293 | } | ||
357 | 294 | |||
358 | 295 | qDebug() << "Removing Screen with id" << screen->outputId() << "and geometry" << screen->geometry(); | ||
359 | 296 | #if QT_VERSION < QT_VERSION_CHECK(5, 5, 0) | ||
360 | 297 | delete screen; | ||
361 | 298 | #else | ||
362 | 299 | this->destroyScreen(screen); | ||
363 | 300 | #endif | ||
364 | 301 | } | ||
365 | 265 | 302 | ||
366 | === modified file 'src/ubuntumirclient/integration.h' | |||
367 | --- src/ubuntumirclient/integration.h 2016-01-04 17:18:51 +0000 | |||
368 | +++ src/ubuntumirclient/integration.h 2016-04-20 15:51:01 +0000 | |||
369 | @@ -21,6 +21,7 @@ | |||
370 | 21 | #include <QSharedPointer> | 21 | #include <QSharedPointer> |
371 | 22 | 22 | ||
372 | 23 | #include "platformservices.h" | 23 | #include "platformservices.h" |
373 | 24 | #include "screenobserver.h" | ||
374 | 24 | 25 | ||
375 | 25 | // platform-api | 26 | // platform-api |
376 | 26 | #include <ubuntu/application/description.h> | 27 | #include <ubuntu/application/description.h> |
377 | @@ -31,7 +32,10 @@ | |||
378 | 31 | class UbuntuNativeInterface; | 32 | class UbuntuNativeInterface; |
379 | 32 | class UbuntuScreen; | 33 | class UbuntuScreen; |
380 | 33 | 34 | ||
382 | 34 | class UbuntuClientIntegration : public QPlatformIntegration { | 35 | class UbuntuClientIntegration : public QObject, public QPlatformIntegration |
383 | 36 | { | ||
384 | 37 | Q_OBJECT | ||
385 | 38 | |||
386 | 35 | public: | 39 | public: |
387 | 36 | UbuntuClientIntegration(); | 40 | UbuntuClientIntegration(); |
388 | 37 | virtual ~UbuntuClientIntegration(); | 41 | virtual ~UbuntuClientIntegration(); |
389 | @@ -53,10 +57,15 @@ | |||
390 | 53 | 57 | ||
391 | 54 | QPlatformOpenGLContext* createPlatformOpenGLContext(QOpenGLContext* context); | 58 | QPlatformOpenGLContext* createPlatformOpenGLContext(QOpenGLContext* context); |
392 | 55 | QPlatformWindow* createPlatformWindow(QWindow* window); | 59 | QPlatformWindow* createPlatformWindow(QWindow* window); |
394 | 56 | UbuntuScreen* screen() const { return mScreen; } | 60 | UbuntuScreenObserver *screenObserver() const { return mScreenObserver.data(); } |
395 | 61 | |||
396 | 62 | void initialize() override; | ||
397 | 57 | 63 | ||
398 | 58 | QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const override; | 64 | QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const override; |
399 | 59 | 65 | ||
400 | 66 | private Q_SLOTS: | ||
401 | 67 | void destroyScreen(UbuntuScreen *screen); | ||
402 | 68 | |||
403 | 60 | private: | 69 | private: |
404 | 61 | void setupOptions(); | 70 | void setupOptions(); |
405 | 62 | void setupDescription(); | 71 | void setupDescription(); |
406 | @@ -66,10 +75,10 @@ | |||
407 | 66 | 75 | ||
408 | 67 | UbuntuPlatformServices* mServices; | 76 | UbuntuPlatformServices* mServices; |
409 | 68 | 77 | ||
410 | 69 | UbuntuScreen* mScreen; | ||
411 | 70 | UbuntuInput* mInput; | 78 | UbuntuInput* mInput; |
412 | 71 | QPlatformInputContext* mInputContext; | 79 | QPlatformInputContext* mInputContext; |
413 | 72 | QSharedPointer<UbuntuClipboard> mClipboard; | 80 | QSharedPointer<UbuntuClipboard> mClipboard; |
414 | 81 | QScopedPointer<UbuntuScreenObserver> mScreenObserver; | ||
415 | 73 | qreal mScaleFactor; | 82 | qreal mScaleFactor; |
416 | 74 | 83 | ||
417 | 75 | // Platform API stuff | 84 | // Platform API stuff |
418 | 76 | 85 | ||
419 | === modified file 'src/ubuntumirclient/nativeinterface.cpp' | |||
420 | --- src/ubuntumirclient/nativeinterface.cpp 2015-12-15 16:16:06 +0000 | |||
421 | +++ src/ubuntumirclient/nativeinterface.cpp 2016-04-20 15:51:01 +0000 | |||
422 | @@ -18,6 +18,7 @@ | |||
423 | 18 | #include "nativeinterface.h" | 18 | #include "nativeinterface.h" |
424 | 19 | #include "screen.h" | 19 | #include "screen.h" |
425 | 20 | #include "glcontext.h" | 20 | #include "glcontext.h" |
426 | 21 | #include "window.h" | ||
427 | 21 | 22 | ||
428 | 22 | // Qt | 23 | // Qt |
429 | 23 | #include <private/qguiapplication_p.h> | 24 | #include <private/qguiapplication_p.h> |
430 | @@ -35,6 +36,8 @@ | |||
431 | 35 | insert("nativeorientation", UbuntuNativeInterface::NativeOrientation); | 36 | insert("nativeorientation", UbuntuNativeInterface::NativeOrientation); |
432 | 36 | insert("display", UbuntuNativeInterface::Display); | 37 | insert("display", UbuntuNativeInterface::Display); |
433 | 37 | insert("mirconnection", UbuntuNativeInterface::MirConnection); | 38 | insert("mirconnection", UbuntuNativeInterface::MirConnection); |
434 | 39 | insert("scale", UbuntuNativeInterface::Scale); | ||
435 | 40 | insert("formfactor", UbuntuNativeInterface::FormFactor); | ||
436 | 38 | } | 41 | } |
437 | 39 | }; | 42 | }; |
438 | 40 | 43 | ||
439 | @@ -123,10 +126,59 @@ | |||
440 | 123 | if (!ubuntuResourceMap()->contains(kLowerCaseResource)) | 126 | if (!ubuntuResourceMap()->contains(kLowerCaseResource)) |
441 | 124 | return NULL; | 127 | return NULL; |
442 | 125 | const ResourceType kResourceType = ubuntuResourceMap()->value(kLowerCaseResource); | 128 | const ResourceType kResourceType = ubuntuResourceMap()->value(kLowerCaseResource); |
443 | 129 | if (!screen) | ||
444 | 130 | screen = QGuiApplication::primaryScreen(); | ||
445 | 131 | auto ubuntuScreen = static_cast<UbuntuScreen*>(screen->handle()); | ||
446 | 126 | if (kResourceType == UbuntuNativeInterface::Display) { | 132 | if (kResourceType == UbuntuNativeInterface::Display) { |
450 | 127 | if (!screen) | 133 | return ubuntuScreen->eglNativeDisplay(); |
451 | 128 | screen = QGuiApplication::primaryScreen(); | 134 | // Changes to the following properties are emitted via the UbuntuNativeInterface::screenPropertyChanged |
452 | 129 | return static_cast<UbuntuScreen*>(screen->handle())->eglNativeDisplay(); | 135 | // signal fired by UbuntuScreen. Connect to this signal for these properties updates. |
453 | 136 | // WARNING: code highly thread unsafe! | ||
454 | 137 | } else if (kResourceType == UbuntuNativeInterface::Scale) { | ||
455 | 138 | // In application code, read with: | ||
456 | 139 | // float scale = *reinterpret_cast<float*>(nativeResourceForScreen("scale", screen())); | ||
457 | 140 | return &ubuntuScreen->mScale; | ||
458 | 141 | } else if (kResourceType == UbuntuNativeInterface::FormFactor) { | ||
459 | 142 | return &ubuntuScreen->mFormFactor; | ||
460 | 130 | } else | 143 | } else |
461 | 131 | return NULL; | 144 | return NULL; |
462 | 132 | } | 145 | } |
463 | 146 | |||
464 | 147 | // Changes to these properties are emitted via the UbuntuNativeInterface::windowPropertyChanged | ||
465 | 148 | // signal fired by UbuntuWindow. Connect to this signal for these properties updates. | ||
466 | 149 | QVariantMap UbuntuNativeInterface::windowProperties(QPlatformWindow *window) const | ||
467 | 150 | { | ||
468 | 151 | QVariantMap propertyMap; | ||
469 | 152 | auto w = static_cast<UbuntuWindow*>(window); | ||
470 | 153 | if (w) { | ||
471 | 154 | propertyMap.insert("scale", w->scale()); | ||
472 | 155 | propertyMap.insert("formFactor", w->formFactor()); | ||
473 | 156 | } | ||
474 | 157 | return propertyMap; | ||
475 | 158 | } | ||
476 | 159 | |||
477 | 160 | QVariant UbuntuNativeInterface::windowProperty(QPlatformWindow *window, const QString &name) const | ||
478 | 161 | { | ||
479 | 162 | auto w = static_cast<UbuntuWindow*>(window); | ||
480 | 163 | if (!w) { | ||
481 | 164 | return QVariant(); | ||
482 | 165 | } | ||
483 | 166 | |||
484 | 167 | if (name == QStringLiteral("scale")) { | ||
485 | 168 | return w->scale(); | ||
486 | 169 | } else if (name == QStringLiteral("formFactor")) { | ||
487 | 170 | return w->formFactor(); | ||
488 | 171 | } else { | ||
489 | 172 | return QVariant(); | ||
490 | 173 | } | ||
491 | 174 | } | ||
492 | 175 | |||
493 | 176 | QVariant UbuntuNativeInterface::windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const | ||
494 | 177 | { | ||
495 | 178 | QVariant returnVal = windowProperty(window, name); | ||
496 | 179 | if (!returnVal.isValid()) { | ||
497 | 180 | return defaultValue; | ||
498 | 181 | } else { | ||
499 | 182 | return returnVal; | ||
500 | 183 | } | ||
501 | 184 | } | ||
502 | 133 | 185 | ||
503 | === modified file 'src/ubuntumirclient/nativeinterface.h' | |||
504 | --- src/ubuntumirclient/nativeinterface.h 2015-08-27 09:41:47 +0000 | |||
505 | +++ src/ubuntumirclient/nativeinterface.h 2016-04-20 15:51:01 +0000 | |||
506 | @@ -19,9 +19,12 @@ | |||
507 | 19 | 19 | ||
508 | 20 | #include <qpa/qplatformnativeinterface.h> | 20 | #include <qpa/qplatformnativeinterface.h> |
509 | 21 | 21 | ||
510 | 22 | class QPlatformScreen; | ||
511 | 23 | |||
512 | 22 | class UbuntuNativeInterface : public QPlatformNativeInterface { | 24 | class UbuntuNativeInterface : public QPlatformNativeInterface { |
513 | 25 | Q_OBJECT | ||
514 | 23 | public: | 26 | public: |
516 | 24 | enum ResourceType { EglDisplay, EglContext, NativeOrientation, Display, MirConnection }; | 27 | enum ResourceType { EglDisplay, EglContext, NativeOrientation, Display, MirConnection, Scale, FormFactor }; |
517 | 25 | 28 | ||
518 | 26 | UbuntuNativeInterface(); | 29 | UbuntuNativeInterface(); |
519 | 27 | ~UbuntuNativeInterface(); | 30 | ~UbuntuNativeInterface(); |
520 | @@ -35,10 +38,17 @@ | |||
521 | 35 | void* nativeResourceForScreen(const QByteArray& resourceString, | 38 | void* nativeResourceForScreen(const QByteArray& resourceString, |
522 | 36 | QScreen* screen) override; | 39 | QScreen* screen) override; |
523 | 37 | 40 | ||
524 | 41 | QVariantMap windowProperties(QPlatformWindow *window) const override; | ||
525 | 42 | QVariant windowProperty(QPlatformWindow *window, const QString &name) const override; | ||
526 | 43 | QVariant windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const override; | ||
527 | 44 | |||
528 | 38 | // New methods. | 45 | // New methods. |
529 | 39 | const QByteArray& genericEventFilterType() const { return mGenericEventFilterType; } | 46 | const QByteArray& genericEventFilterType() const { return mGenericEventFilterType; } |
530 | 40 | void setMirConnection(void *mirConnection) { mMirConnection = mirConnection; } | 47 | void setMirConnection(void *mirConnection) { mMirConnection = mirConnection; } |
531 | 41 | 48 | ||
532 | 49 | Q_SIGNALS: // New signals | ||
533 | 50 | void screenPropertyChanged(QPlatformScreen *screen, const QString &propertyName); | ||
534 | 51 | |||
535 | 42 | private: | 52 | private: |
536 | 43 | const QByteArray mGenericEventFilterType; | 53 | const QByteArray mGenericEventFilterType; |
537 | 44 | Qt::ScreenOrientation* mNativeOrientation; | 54 | Qt::ScreenOrientation* mNativeOrientation; |
538 | 45 | 55 | ||
539 | === modified file 'src/ubuntumirclient/screen.cpp' | |||
540 | --- src/ubuntumirclient/screen.cpp 2015-12-09 13:01:28 +0000 | |||
541 | +++ src/ubuntumirclient/screen.cpp 2016-04-20 15:51:01 +0000 | |||
542 | @@ -18,11 +18,13 @@ | |||
543 | 18 | #include "screen.h" | 18 | #include "screen.h" |
544 | 19 | #include "logging.h" | 19 | #include "logging.h" |
545 | 20 | #include "orientationchangeevent_p.h" | 20 | #include "orientationchangeevent_p.h" |
546 | 21 | #include "nativeinterface.h" | ||
547 | 22 | #include "utils.h" | ||
548 | 21 | 23 | ||
549 | 22 | #include <mir_toolkit/mir_client_library.h> | 24 | #include <mir_toolkit/mir_client_library.h> |
550 | 23 | 25 | ||
551 | 24 | // Qt | 26 | // Qt |
553 | 25 | #include <QCoreApplication> | 27 | #include <QGuiApplication> |
554 | 26 | #include <QtCore/qmath.h> | 28 | #include <QtCore/qmath.h> |
555 | 27 | #include <QScreen> | 29 | #include <QScreen> |
556 | 28 | #include <QThread> | 30 | #include <QThread> |
557 | @@ -101,37 +103,29 @@ | |||
558 | 101 | } | 103 | } |
559 | 102 | } | 104 | } |
560 | 103 | 105 | ||
561 | 106 | namespace { | ||
562 | 107 | int qGetEnvIntValue(const char *varName, bool *ok) | ||
563 | 108 | { | ||
564 | 109 | return qgetenv(varName).toInt(ok); | ||
565 | 110 | } | ||
566 | 111 | } // anonymous namespace | ||
567 | 112 | |||
568 | 113 | |||
569 | 104 | const QEvent::Type OrientationChangeEvent::mType = | 114 | const QEvent::Type OrientationChangeEvent::mType = |
570 | 105 | static_cast<QEvent::Type>(QEvent::registerEventType()); | 115 | static_cast<QEvent::Type>(QEvent::registerEventType()); |
571 | 106 | 116 | ||
595 | 107 | static const MirDisplayOutput *find_active_output( | 117 | |
596 | 108 | const MirDisplayConfiguration *conf) | 118 | UbuntuScreen::UbuntuScreen(const MirDisplayOutput &output, MirConnection *connection) |
597 | 109 | { | 119 | : mDevicePixelRatio(1.0) |
598 | 110 | const MirDisplayOutput *output = NULL; | 120 | , mFormat(QImage::Format_RGB32) |
576 | 111 | for (uint32_t d = 0; d < conf->num_outputs; d++) | ||
577 | 112 | { | ||
578 | 113 | const MirDisplayOutput *out = conf->outputs + d; | ||
579 | 114 | |||
580 | 115 | if (out->used && | ||
581 | 116 | out->connected && | ||
582 | 117 | out->num_modes && | ||
583 | 118 | out->current_mode < out->num_modes) | ||
584 | 119 | { | ||
585 | 120 | output = out; | ||
586 | 121 | break; | ||
587 | 122 | } | ||
588 | 123 | } | ||
589 | 124 | |||
590 | 125 | return output; | ||
591 | 126 | } | ||
592 | 127 | |||
593 | 128 | UbuntuScreen::UbuntuScreen(MirConnection *connection) | ||
594 | 129 | : mFormat(QImage::Format_RGB32) | ||
599 | 130 | , mDepth(32) | 121 | , mDepth(32) |
600 | 122 | , mDpi{0} | ||
601 | 123 | , mFormFactor{mir_form_factor_unknown} | ||
602 | 124 | , mScale{1.0} | ||
603 | 131 | , mOutputId(0) | 125 | , mOutputId(0) |
604 | 132 | , mSurfaceFormat() | ||
605 | 133 | , mEglDisplay(EGL_NO_DISPLAY) | 126 | , mEglDisplay(EGL_NO_DISPLAY) |
606 | 134 | , mEglConfig(nullptr) | 127 | , mEglConfig(nullptr) |
607 | 128 | , mSurfaceFormat() | ||
608 | 135 | , mCursor(connection) | 129 | , mCursor(connection) |
609 | 136 | { | 130 | { |
610 | 137 | // Initialize EGL. | 131 | // Initialize EGL. |
611 | @@ -164,45 +158,15 @@ | |||
612 | 164 | } | 158 | } |
613 | 165 | 159 | ||
614 | 166 | // Set vblank swap interval. | 160 | // Set vblank swap interval. |
624 | 167 | int swapInterval = kSwapInterval; | 161 | bool ok; |
625 | 168 | QByteArray swapIntervalString = qgetenv("QTUBUNTU_SWAPINTERVAL"); | 162 | int swapInterval = qGetEnvIntValue("QTUBUNTU_SWAPINTERVAL", &ok); |
626 | 169 | if (!swapIntervalString.isEmpty()) { | 163 | if (!ok) |
627 | 170 | bool ok; | 164 | swapInterval = kSwapInterval; |
628 | 171 | swapInterval = swapIntervalString.toInt(&ok); | 165 | |
629 | 172 | if (!ok) | 166 | qCDebug(ubuntumirclient, "Setting swap interval to %d", swapInterval); |
621 | 173 | swapInterval = kSwapInterval; | ||
622 | 174 | } | ||
623 | 175 | qCDebug(ubuntumirclient, "setting swap interval to %d", swapInterval); | ||
630 | 176 | eglSwapInterval(mEglDisplay, swapInterval); | 167 | eglSwapInterval(mEglDisplay, swapInterval); |
631 | 177 | 168 | ||
660 | 178 | // Get screen resolution. | 169 | setMirDisplayOutput(output); |
633 | 179 | auto configDeleter = [](MirDisplayConfiguration *config) { mir_display_config_destroy(config); }; | ||
634 | 180 | using configUp = std::unique_ptr<MirDisplayConfiguration, decltype(configDeleter)>; | ||
635 | 181 | configUp displayConfig(mir_connection_create_display_config(connection), configDeleter); | ||
636 | 182 | ASSERT(displayConfig != nullptr); | ||
637 | 183 | |||
638 | 184 | auto const displayOutput = find_active_output(displayConfig.get()); | ||
639 | 185 | ASSERT(displayOutput != nullptr); | ||
640 | 186 | |||
641 | 187 | mOutputId = displayOutput->output_id; | ||
642 | 188 | |||
643 | 189 | mPhysicalSize = QSizeF(displayOutput->physical_width_mm, displayOutput->physical_height_mm); | ||
644 | 190 | qCDebug(ubuntumirclient, "screen physical size: %.2fx%.2f", mPhysicalSize.width(), mPhysicalSize.height()); | ||
645 | 191 | |||
646 | 192 | const MirDisplayMode *mode = &displayOutput->modes[displayOutput->current_mode]; | ||
647 | 193 | const int kScreenWidth = mode->horizontal_resolution; | ||
648 | 194 | const int kScreenHeight = mode->vertical_resolution; | ||
649 | 195 | Q_ASSERT(kScreenWidth > 0 && kScreenHeight > 0); | ||
650 | 196 | |||
651 | 197 | qCDebug(ubuntumirclient, "screen resolution: %dx%d", kScreenWidth, kScreenHeight); | ||
652 | 198 | |||
653 | 199 | mGeometry = QRect(0, 0, kScreenWidth, kScreenHeight); | ||
654 | 200 | |||
655 | 201 | // Set the default orientation based on the initial screen dimmensions. | ||
656 | 202 | mNativeOrientation = (mGeometry.width() >= mGeometry.height()) ? Qt::LandscapeOrientation : Qt::PortraitOrientation; | ||
657 | 203 | |||
658 | 204 | // If it's a landscape device (i.e. some tablets), start in landscape, otherwise portrait | ||
659 | 205 | mCurrentOrientation = (mNativeOrientation == Qt::LandscapeOrientation) ? Qt::LandscapeOrientation : Qt::PortraitOrientation; | ||
661 | 206 | } | 170 | } |
662 | 207 | 171 | ||
663 | 208 | UbuntuScreen::~UbuntuScreen() | 172 | UbuntuScreen::~UbuntuScreen() |
664 | @@ -278,3 +242,77 @@ | |||
665 | 278 | QWindowSystemInterface::handleScreenOrientationChange(screen(), mCurrentOrientation); | 242 | QWindowSystemInterface::handleScreenOrientationChange(screen(), mCurrentOrientation); |
666 | 279 | } | 243 | } |
667 | 280 | } | 244 | } |
668 | 245 | |||
669 | 246 | void UbuntuScreen::setMirDisplayOutput(const MirDisplayOutput &output) | ||
670 | 247 | { | ||
671 | 248 | // Physical screen size | ||
672 | 249 | mPhysicalSize.setWidth(output.physical_width_mm); | ||
673 | 250 | mPhysicalSize.setHeight(output.physical_height_mm); | ||
674 | 251 | |||
675 | 252 | // Pixel Format | ||
676 | 253 | // mFormat = qImageFormatFromMirPixelFormat(output.current_format); // GERRY: TODO | ||
677 | 254 | |||
678 | 255 | // Pixel depth | ||
679 | 256 | mDepth = 8 * MIR_BYTES_PER_PIXEL(output.current_format); | ||
680 | 257 | |||
681 | 258 | // Mode = Resolution & refresh rate | ||
682 | 259 | MirDisplayMode mode = output.modes[output.current_mode]; | ||
683 | 260 | mNativeGeometry.setX(output.position_x); | ||
684 | 261 | mNativeGeometry.setY(output.position_y); | ||
685 | 262 | mNativeGeometry.setWidth(mode.horizontal_resolution); | ||
686 | 263 | mNativeGeometry.setHeight(mode.vertical_resolution); | ||
687 | 264 | mRefreshRate = mode.refresh_rate; | ||
688 | 265 | |||
689 | 266 | // geometry in device pixels | ||
690 | 267 | mGeometry.setX(mNativeGeometry.x() / mDevicePixelRatio); | ||
691 | 268 | mGeometry.setY(mNativeGeometry.y() / mDevicePixelRatio); | ||
692 | 269 | mGeometry.setWidth(mNativeGeometry.width() / mDevicePixelRatio); | ||
693 | 270 | mGeometry.setHeight(mNativeGeometry.height() / mDevicePixelRatio); | ||
694 | 271 | |||
695 | 272 | // Misc | ||
696 | 273 | // mScale = output.scale; // missing from MirDisplayOutput, wait for later setAdditionalMirDisplayProperties call | ||
697 | 274 | // mFormFactor = output.form_factor; // ditto | ||
698 | 275 | mOutputId = output.output_id; | ||
699 | 276 | |||
700 | 277 | // Set the default orientation based on the initial screen dimmensions. | ||
701 | 278 | mNativeOrientation = (mGeometry.width() >= mGeometry.height()) ? Qt::LandscapeOrientation : Qt::PortraitOrientation; | ||
702 | 279 | |||
703 | 280 | // If it's a landscape device (i.e. some tablets), start in landscape, otherwise portrait | ||
704 | 281 | mCurrentOrientation = (mNativeOrientation == Qt::LandscapeOrientation) ? Qt::LandscapeOrientation : Qt::PortraitOrientation; | ||
705 | 282 | } | ||
706 | 283 | |||
707 | 284 | void UbuntuScreen::setAdditionalMirDisplayProperties(float scale, MirFormFactor formFactor, float dpi) | ||
708 | 285 | { | ||
709 | 286 | auto nativeInterface = static_cast<UbuntuNativeInterface *>(qGuiApp->platformNativeInterface()); | ||
710 | 287 | if (!qFuzzyCompare(mScale, scale)) { | ||
711 | 288 | mScale = scale; | ||
712 | 289 | Q_EMIT nativeInterface->screenPropertyChanged(this, QStringLiteral("scale")); | ||
713 | 290 | } | ||
714 | 291 | if (mFormFactor != formFactor) { | ||
715 | 292 | mFormFactor = formFactor; | ||
716 | 293 | Q_EMIT nativeInterface->screenPropertyChanged(this, QStringLiteral("formFactor")); | ||
717 | 294 | } | ||
718 | 295 | |||
719 | 296 | bool ok; | ||
720 | 297 | int dpr = qGetEnvIntValue("QT_DEVICE_PIXEL_RATIO", &ok); | ||
721 | 298 | if (ok && dpr > 0) { | ||
722 | 299 | qCDebug(ubuntumirclient, "Fixing Device Pixel Ratio to %d", dpr); | ||
723 | 300 | mDevicePixelRatio = dpr; | ||
724 | 301 | } else { | ||
725 | 302 | mDevicePixelRatio = 1.0; //qCeil(scale); // FIXME - unable to announce change in this until can delete/recreate Screen. | ||
726 | 303 | } | ||
727 | 304 | |||
728 | 305 | if (mDpi != dpi) { | ||
729 | 306 | mDpi = dpi; | ||
730 | 307 | QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(screen(), dpi, dpi); | ||
731 | 308 | } | ||
732 | 309 | } | ||
733 | 310 | |||
734 | 311 | QDpi UbuntuScreen::logicalDpi() const | ||
735 | 312 | { | ||
736 | 313 | if (mDpi > 0) { | ||
737 | 314 | return QDpi(mDpi, mDpi); | ||
738 | 315 | } else { | ||
739 | 316 | return QPlatformScreen::logicalDpi(); | ||
740 | 317 | } | ||
741 | 318 | } | ||
742 | 281 | 319 | ||
743 | === modified file 'src/ubuntumirclient/screen.h' | |||
744 | --- src/ubuntumirclient/screen.h 2015-11-23 11:10:24 +0000 | |||
745 | +++ src/ubuntumirclient/screen.h 2016-04-20 15:51:01 +0000 | |||
746 | @@ -19,17 +19,21 @@ | |||
747 | 19 | 19 | ||
748 | 20 | #include <qpa/qplatformscreen.h> | 20 | #include <qpa/qplatformscreen.h> |
749 | 21 | #include <QSurfaceFormat> | 21 | #include <QSurfaceFormat> |
750 | 22 | |||
751 | 23 | #include <mircommon/mir_toolkit/common.h> // just for MirFormFactor enum | ||
752 | 24 | |||
753 | 22 | #include <EGL/egl.h> | 25 | #include <EGL/egl.h> |
754 | 23 | 26 | ||
755 | 24 | #include "cursor.h" | 27 | #include "cursor.h" |
756 | 25 | 28 | ||
757 | 26 | struct MirConnection; | 29 | struct MirConnection; |
758 | 30 | struct MirDisplayOutput; | ||
759 | 27 | 31 | ||
760 | 28 | class UbuntuScreen : public QObject, public QPlatformScreen | 32 | class UbuntuScreen : public QObject, public QPlatformScreen |
761 | 29 | { | 33 | { |
762 | 30 | Q_OBJECT | 34 | Q_OBJECT |
763 | 31 | public: | 35 | public: |
765 | 32 | UbuntuScreen(MirConnection *connection); | 36 | UbuntuScreen(const MirDisplayOutput &output, MirConnection *connection); |
766 | 33 | virtual ~UbuntuScreen(); | 37 | virtual ~UbuntuScreen(); |
767 | 34 | 38 | ||
768 | 35 | // QPlatformScreen methods. | 39 | // QPlatformScreen methods. |
769 | @@ -38,6 +42,8 @@ | |||
770 | 38 | QRect geometry() const override { return mGeometry; } | 42 | QRect geometry() const override { return mGeometry; } |
771 | 39 | QRect availableGeometry() const override { return mGeometry; } | 43 | QRect availableGeometry() const override { return mGeometry; } |
772 | 40 | QSizeF physicalSize() const override { return mPhysicalSize; } | 44 | QSizeF physicalSize() const override { return mPhysicalSize; } |
773 | 45 | qreal devicePixelRatio() const override { return mDevicePixelRatio; } | ||
774 | 46 | QDpi logicalDpi() const override; | ||
775 | 41 | Qt::ScreenOrientation nativeOrientation() const override { return mNativeOrientation; } | 47 | Qt::ScreenOrientation nativeOrientation() const override { return mNativeOrientation; } |
776 | 42 | Qt::ScreenOrientation orientation() const override { return mNativeOrientation; } | 48 | Qt::ScreenOrientation orientation() const override { return mNativeOrientation; } |
777 | 43 | QPlatformCursor *cursor() const override { return const_cast<UbuntuCursor*>(&mCursor); } | 49 | QPlatformCursor *cursor() const override { return const_cast<UbuntuCursor*>(&mCursor); } |
778 | @@ -47,6 +53,15 @@ | |||
779 | 47 | EGLDisplay eglDisplay() const { return mEglDisplay; } | 53 | EGLDisplay eglDisplay() const { return mEglDisplay; } |
780 | 48 | EGLConfig eglConfig() const { return mEglConfig; } | 54 | EGLConfig eglConfig() const { return mEglConfig; } |
781 | 49 | EGLNativeDisplayType eglNativeDisplay() const { return mEglNativeDisplay; } | 55 | EGLNativeDisplayType eglNativeDisplay() const { return mEglNativeDisplay; } |
782 | 56 | |||
783 | 57 | // Additional Screen properties from Mir | ||
784 | 58 | uint32_t outputId() const { return mOutputId; } | ||
785 | 59 | MirFormFactor formFactor() const { return mFormFactor; } | ||
786 | 60 | float scale() const { return mScale; } | ||
787 | 61 | |||
788 | 62 | // Internally used methods | ||
789 | 63 | void setMirDisplayOutput(const MirDisplayOutput &output); | ||
790 | 64 | void setAdditionalMirDisplayProperties(float scale, MirFormFactor formFactor, float dpi); | ||
791 | 50 | void handleWindowSurfaceResize(int width, int height); | 65 | void handleWindowSurfaceResize(int width, int height); |
792 | 51 | uint32_t mirOutputId() const { return mOutputId; } | 66 | uint32_t mirOutputId() const { return mOutputId; } |
793 | 52 | 67 | ||
794 | @@ -54,18 +69,25 @@ | |||
795 | 54 | void customEvent(QEvent* event) override; | 69 | void customEvent(QEvent* event) override; |
796 | 55 | 70 | ||
797 | 56 | private: | 71 | private: |
799 | 57 | QRect mGeometry; | 72 | QRect mGeometry, mNativeGeometry; |
800 | 58 | QSizeF mPhysicalSize; | 73 | QSizeF mPhysicalSize; |
801 | 74 | qreal mDevicePixelRatio; | ||
802 | 59 | Qt::ScreenOrientation mNativeOrientation; | 75 | Qt::ScreenOrientation mNativeOrientation; |
803 | 60 | Qt::ScreenOrientation mCurrentOrientation; | 76 | Qt::ScreenOrientation mCurrentOrientation; |
804 | 61 | QImage::Format mFormat; | 77 | QImage::Format mFormat; |
805 | 62 | int mDepth; | 78 | int mDepth; |
806 | 79 | int mDpi; | ||
807 | 80 | qreal mRefreshRate; | ||
808 | 81 | MirFormFactor mFormFactor; | ||
809 | 82 | float mScale; | ||
810 | 63 | uint32_t mOutputId; | 83 | uint32_t mOutputId; |
811 | 64 | QSurfaceFormat mSurfaceFormat; | ||
812 | 65 | EGLDisplay mEglDisplay; | 84 | EGLDisplay mEglDisplay; |
813 | 66 | EGLConfig mEglConfig; | 85 | EGLConfig mEglConfig; |
814 | 67 | EGLNativeDisplayType mEglNativeDisplay; | 86 | EGLNativeDisplayType mEglNativeDisplay; |
816 | 68 | UbuntuCursor mCursor; | 87 | QSurfaceFormat mSurfaceFormat; |
817 | 88 | UbuntuCursor mCursor; //GERRY try const | ||
818 | 89 | |||
819 | 90 | friend class UbuntuNativeInterface; | ||
820 | 69 | }; | 91 | }; |
821 | 70 | 92 | ||
822 | 71 | #endif // UBUNTU_SCREEN_H | 93 | #endif // UBUNTU_SCREEN_H |
823 | 72 | 94 | ||
824 | === added file 'src/ubuntumirclient/screenobserver.cpp' | |||
825 | --- src/ubuntumirclient/screenobserver.cpp 1970-01-01 00:00:00 +0000 | |||
826 | +++ src/ubuntumirclient/screenobserver.cpp 2016-04-20 15:51:01 +0000 | |||
827 | @@ -0,0 +1,131 @@ | |||
828 | 1 | /* | ||
829 | 2 | * Copyright (C) 2015 Canonical, Ltd. | ||
830 | 3 | * | ||
831 | 4 | * This program is free software: you can redistribute it and/or modify it under | ||
832 | 5 | * the terms of the GNU Lesser General Public License version 3, as published by | ||
833 | 6 | * the Free Software Foundation. | ||
834 | 7 | * | ||
835 | 8 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
836 | 9 | * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, | ||
837 | 10 | * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
838 | 11 | * Lesser General Public License for more details. | ||
839 | 12 | * | ||
840 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
841 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
842 | 15 | */ | ||
843 | 16 | |||
844 | 17 | #include "screenobserver.h" | ||
845 | 18 | #include "screen.h" | ||
846 | 19 | #include "window.h" | ||
847 | 20 | #include "logging.h" | ||
848 | 21 | |||
849 | 22 | // Qt | ||
850 | 23 | #include <QMetaObject> | ||
851 | 24 | #include <QPointer> | ||
852 | 25 | |||
853 | 26 | // Mir | ||
854 | 27 | #include <mirclient/mir_toolkit/mir_connection.h> | ||
855 | 28 | |||
856 | 29 | #include <memory> | ||
857 | 30 | |||
858 | 31 | namespace { | ||
859 | 32 | static void displayConfigurationChangedCallback(MirConnection */*connection*/, void* context) | ||
860 | 33 | { | ||
861 | 34 | ASSERT(context != NULL); | ||
862 | 35 | UbuntuScreenObserver *observer = static_cast<UbuntuScreenObserver *>(context); | ||
863 | 36 | QMetaObject::invokeMethod(observer, "update"); | ||
864 | 37 | } | ||
865 | 38 | } // anonymous namespace | ||
866 | 39 | |||
867 | 40 | UbuntuScreenObserver::UbuntuScreenObserver(MirConnection *mirConnection) | ||
868 | 41 | : mMirConnection(mirConnection) | ||
869 | 42 | { | ||
870 | 43 | mir_connection_set_display_config_change_callback(mirConnection, ::displayConfigurationChangedCallback, this); | ||
871 | 44 | update(); | ||
872 | 45 | } | ||
873 | 46 | |||
874 | 47 | void UbuntuScreenObserver::update() | ||
875 | 48 | { | ||
876 | 49 | // Wrap MirDisplayConfiguration to always delete when out of scope | ||
877 | 50 | auto configDeleter = [](MirDisplayConfiguration *config) { mir_display_config_destroy(config); }; | ||
878 | 51 | using configUp = std::unique_ptr<MirDisplayConfiguration, decltype(configDeleter)>; | ||
879 | 52 | configUp displayConfig(mir_connection_create_display_config(mMirConnection), configDeleter); | ||
880 | 53 | |||
881 | 54 | // Mir only tells us something changed, it is up to us to figure out what. | ||
882 | 55 | QList<UbuntuScreen*> newScreenList; | ||
883 | 56 | QList<UbuntuScreen*> oldScreenList = mScreenList; | ||
884 | 57 | mScreenList.clear(); | ||
885 | 58 | |||
886 | 59 | for (uint32_t i=0; i<displayConfig->num_outputs; i++) { | ||
887 | 60 | MirDisplayOutput output = displayConfig->outputs[i]; | ||
888 | 61 | if (output.used && output.connected) { | ||
889 | 62 | UbuntuScreen *screen = findScreenWithId(oldScreenList, output.output_id); | ||
890 | 63 | if (screen) { // we've already set up this display before, refresh its internals | ||
891 | 64 | screen->setMirDisplayOutput(output); | ||
892 | 65 | oldScreenList.removeAll(screen); | ||
893 | 66 | } else { | ||
894 | 67 | // new display, so create UbuntuScreen for it | ||
895 | 68 | screen = new UbuntuScreen(output, mMirConnection); | ||
896 | 69 | newScreenList.append(screen); | ||
897 | 70 | qDebug() << "Added Screen with id" << output.output_id << "and geometry" << screen->geometry(); | ||
898 | 71 | } | ||
899 | 72 | mScreenList.append(screen); | ||
900 | 73 | } | ||
901 | 74 | } | ||
902 | 75 | |||
903 | 76 | // Announce old & unused Screens, should be deleted by the slot | ||
904 | 77 | Q_FOREACH (const auto screen, oldScreenList) { | ||
905 | 78 | Q_EMIT screenRemoved(screen); | ||
906 | 79 | } | ||
907 | 80 | |||
908 | 81 | /* | ||
909 | 82 | * Mir's MirDisplayOutput does not include formFactor or scale for some reason, but Qt | ||
910 | 83 | * will want that information on creating the QScreen. Only way we get that info is when | ||
911 | 84 | * Mir positions a Window on that Screen. See "handleScreenPropertiesChange" method | ||
912 | 85 | */ | ||
913 | 86 | |||
914 | 87 | // Announce new Screens | ||
915 | 88 | Q_FOREACH (const auto screen, newScreenList) { | ||
916 | 89 | Q_EMIT screenAdded(screen); | ||
917 | 90 | } | ||
918 | 91 | |||
919 | 92 | qDebug() << "======================================="; | ||
920 | 93 | for (auto screen: mScreenList) { | ||
921 | 94 | qDebug() << screen << "- id:" << screen->outputId() | ||
922 | 95 | << "geometry:" << screen->geometry() | ||
923 | 96 | << "form factor:" << screen->formFactor() | ||
924 | 97 | << "scale:" << screen->scale(); | ||
925 | 98 | } | ||
926 | 99 | qDebug() << "======================================="; | ||
927 | 100 | } | ||
928 | 101 | |||
929 | 102 | UbuntuScreen *UbuntuScreenObserver::findScreenWithId(uint32_t id) | ||
930 | 103 | { | ||
931 | 104 | return findScreenWithId(mScreenList, id); | ||
932 | 105 | } | ||
933 | 106 | |||
934 | 107 | UbuntuScreen *UbuntuScreenObserver::findScreenWithId(const QList<UbuntuScreen *> &list, uint32_t id) | ||
935 | 108 | { | ||
936 | 109 | Q_FOREACH (const auto screen, list) { | ||
937 | 110 | if (screen->outputId() == id) { | ||
938 | 111 | return screen; | ||
939 | 112 | } | ||
940 | 113 | } | ||
941 | 114 | return nullptr; | ||
942 | 115 | } | ||
943 | 116 | |||
944 | 117 | void UbuntuScreenObserver::handleScreenPropertiesChange(UbuntuScreen *screen, int dpi, | ||
945 | 118 | MirFormFactor formFactor, float scale) | ||
946 | 119 | { | ||
947 | 120 | screen->setAdditionalMirDisplayProperties(scale, formFactor, dpi); | ||
948 | 121 | |||
949 | 122 | qDebug() << "======================================="; | ||
950 | 123 | for (auto screen: mScreenList) { | ||
951 | 124 | qDebug() << screen << "- id:" << screen->outputId() | ||
952 | 125 | << "geometry:" << screen->geometry() | ||
953 | 126 | << "form factor:" << screen->formFactor() | ||
954 | 127 | << "scale:" << screen->scale(); | ||
955 | 128 | } | ||
956 | 129 | qDebug() << "======================================="; | ||
957 | 130 | } | ||
958 | 131 | |||
959 | 0 | 132 | ||
960 | === added file 'src/ubuntumirclient/screenobserver.h' | |||
961 | --- src/ubuntumirclient/screenobserver.h 1970-01-01 00:00:00 +0000 | |||
962 | +++ src/ubuntumirclient/screenobserver.h 2016-04-20 15:51:01 +0000 | |||
963 | @@ -0,0 +1,54 @@ | |||
964 | 1 | /* | ||
965 | 2 | * Copyright (C) 2015 Canonical, Ltd. | ||
966 | 3 | * | ||
967 | 4 | * This program is free software: you can redistribute it and/or modify it under | ||
968 | 5 | * the terms of the GNU Lesser General Public License version 3, as published by | ||
969 | 6 | * the Free Software Foundation. | ||
970 | 7 | * | ||
971 | 8 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
972 | 9 | * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, | ||
973 | 10 | * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
974 | 11 | * Lesser General Public License for more details. | ||
975 | 12 | * | ||
976 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
977 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
978 | 15 | */ | ||
979 | 16 | |||
980 | 17 | #ifndef UBUNTU_SCREEN_OBSERVER_H | ||
981 | 18 | #define UBUNTU_SCREEN_OBSERVER_H | ||
982 | 19 | |||
983 | 20 | #include <QObject> | ||
984 | 21 | |||
985 | 22 | #include <mir_toolkit/mir_connection.h> | ||
986 | 23 | |||
987 | 24 | class UbuntuScreen; | ||
988 | 25 | |||
989 | 26 | class UbuntuScreenObserver : public QObject | ||
990 | 27 | { | ||
991 | 28 | Q_OBJECT | ||
992 | 29 | |||
993 | 30 | public: | ||
994 | 31 | UbuntuScreenObserver(MirConnection *connection); | ||
995 | 32 | |||
996 | 33 | QList<UbuntuScreen*> screens() const { return mScreenList; } | ||
997 | 34 | UbuntuScreen *findScreenWithId(uint32_t id); | ||
998 | 35 | |||
999 | 36 | void handleScreenPropertiesChange(UbuntuScreen *screen, int dpi, | ||
1000 | 37 | MirFormFactor formFactor, float scale); | ||
1001 | 38 | |||
1002 | 39 | Q_SIGNALS: | ||
1003 | 40 | void screenAdded(UbuntuScreen *screen); | ||
1004 | 41 | void screenRemoved(UbuntuScreen *screen); | ||
1005 | 42 | |||
1006 | 43 | private Q_SLOTS: | ||
1007 | 44 | void update(); | ||
1008 | 45 | |||
1009 | 46 | private: | ||
1010 | 47 | UbuntuScreen *findScreenWithId(const QList<UbuntuScreen *> &list, uint32_t id); | ||
1011 | 48 | void removeScreen(UbuntuScreen *screen); | ||
1012 | 49 | |||
1013 | 50 | MirConnection *mMirConnection; | ||
1014 | 51 | QList<UbuntuScreen*> mScreenList; | ||
1015 | 52 | }; | ||
1016 | 53 | |||
1017 | 54 | #endif // UBUNTU_SCREEN_OBSERVER_H | ||
1018 | 0 | 55 | ||
1019 | === modified file 'src/ubuntumirclient/ubuntumirclient.pro' | |||
1020 | --- src/ubuntumirclient/ubuntumirclient.pro 2016-02-25 21:02:19 +0000 | |||
1021 | +++ src/ubuntumirclient/ubuntumirclient.pro 2016-04-20 15:51:01 +0000 | |||
1022 | @@ -26,6 +26,7 @@ | |||
1023 | 26 | platformservices.cpp \ | 26 | platformservices.cpp \ |
1024 | 27 | plugin.cpp \ | 27 | plugin.cpp \ |
1025 | 28 | screen.cpp \ | 28 | screen.cpp \ |
1026 | 29 | screenobserver.cpp \ | ||
1027 | 29 | theme.cpp \ | 30 | theme.cpp \ |
1028 | 30 | window.cpp | 31 | window.cpp |
1029 | 31 | 32 | ||
1030 | @@ -42,9 +43,11 @@ | |||
1031 | 42 | orientationchangeevent_p.h \ | 43 | orientationchangeevent_p.h \ |
1032 | 43 | platformservices.h \ | 44 | platformservices.h \ |
1033 | 44 | plugin.h \ | 45 | plugin.h \ |
1034 | 46 | screenobserver.h \ | ||
1035 | 45 | screen.h \ | 47 | screen.h \ |
1036 | 46 | theme.h \ | 48 | theme.h \ |
1038 | 47 | window.h | 49 | window.h \ |
1039 | 50 | utils.h | ||
1040 | 48 | 51 | ||
1041 | 49 | # Installation path | 52 | # Installation path |
1042 | 50 | target.path += $$[QT_INSTALL_PLUGINS]/platforms | 53 | target.path += $$[QT_INSTALL_PLUGINS]/platforms |
1043 | 51 | 54 | ||
1044 | === added file 'src/ubuntumirclient/utils.h' | |||
1045 | --- src/ubuntumirclient/utils.h 1970-01-01 00:00:00 +0000 | |||
1046 | +++ src/ubuntumirclient/utils.h 2016-04-20 15:51:01 +0000 | |||
1047 | @@ -0,0 +1,29 @@ | |||
1048 | 1 | /* | ||
1049 | 2 | * Copyright (C) 2015 Canonical, Ltd. | ||
1050 | 3 | * | ||
1051 | 4 | * This program is free software: you can redistribute it and/or modify it under | ||
1052 | 5 | * the terms of the GNU Lesser General Public License version 3, as published by | ||
1053 | 6 | * the Free Software Foundation. | ||
1054 | 7 | * | ||
1055 | 8 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
1056 | 9 | * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, | ||
1057 | 10 | * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
1058 | 11 | * Lesser General Public License for more details. | ||
1059 | 12 | * | ||
1060 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
1061 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1062 | 15 | */ | ||
1063 | 16 | |||
1064 | 17 | #ifndef UTILS_H | ||
1065 | 18 | #define UTILS_H | ||
1066 | 19 | |||
1067 | 20 | #include <QtGlobal> | ||
1068 | 21 | |||
1069 | 22 | namespace { | ||
1070 | 23 | inline int divideAndRoundUp(int numerator, qreal denominator) | ||
1071 | 24 | { | ||
1072 | 25 | return ceil((qreal)numerator / denominator); | ||
1073 | 26 | } | ||
1074 | 27 | } // anonymous namespace | ||
1075 | 28 | |||
1076 | 29 | #endif // UTILS_H | ||
1077 | 0 | 30 | ||
1078 | === modified file 'src/ubuntumirclient/window.cpp' | |||
1079 | --- src/ubuntumirclient/window.cpp 2016-03-14 17:37:19 +0000 | |||
1080 | +++ src/ubuntumirclient/window.cpp 2016-04-20 15:51:01 +0000 | |||
1081 | @@ -17,8 +17,10 @@ | |||
1082 | 17 | // Local | 17 | // Local |
1083 | 18 | #include "window.h" | 18 | #include "window.h" |
1084 | 19 | #include "clipboard.h" | 19 | #include "clipboard.h" |
1085 | 20 | #include "nativeinterface.h" | ||
1086 | 20 | #include "input.h" | 21 | #include "input.h" |
1087 | 21 | #include "screen.h" | 22 | #include "screen.h" |
1088 | 23 | #include "utils.h" | ||
1089 | 22 | #include "logging.h" | 24 | #include "logging.h" |
1090 | 23 | 25 | ||
1091 | 24 | #include <mir_toolkit/mir_client_library.h> | 26 | #include <mir_toolkit/mir_client_library.h> |
1092 | @@ -34,6 +36,11 @@ | |||
1093 | 34 | 36 | ||
1094 | 35 | #include <EGL/egl.h> | 37 | #include <EGL/egl.h> |
1095 | 36 | 38 | ||
1096 | 39 | |||
1097 | 40 | /* | ||
1098 | 41 | * Note: all geometry is in device-independent pixels, except that contained in variables with the | ||
1099 | 42 | * suffix "Px" - whose units are (physical) pixels | ||
1100 | 43 | */ | ||
1101 | 37 | Q_LOGGING_CATEGORY(ubuntumirclientBufferSwap, "ubuntumirclient.bufferSwap", QtWarningMsg) | 44 | Q_LOGGING_CATEGORY(ubuntumirclientBufferSwap, "ubuntumirclient.bufferSwap", QtWarningMsg) |
1102 | 38 | 45 | ||
1103 | 39 | const Qt::WindowType LowChromeWindowHint = (Qt::WindowType)0x00800000; | 46 | const Qt::WindowType LowChromeWindowHint = (Qt::WindowType)0x00800000; |
1104 | @@ -153,13 +160,14 @@ | |||
1105 | 153 | Spec makeSurfaceSpec(QWindow *window, UbuntuInput *input, MirConnection *connection) | 160 | Spec makeSurfaceSpec(QWindow *window, UbuntuInput *input, MirConnection *connection) |
1106 | 154 | { | 161 | { |
1107 | 155 | const auto geom = window->geometry(); | 162 | const auto geom = window->geometry(); |
1110 | 156 | const int width = geom.width() > 0 ? geom.width() : 1; | 163 | const int dpr = int(window->devicePixelRatio()); |
1111 | 157 | const int height = geom.height() > 0 ? geom.height() : 1; | 164 | const int widthPx = geom.width() > 0 ? geom.width() * dpr : 1; |
1112 | 165 | const int heightPx = geom.height() > 0 ? geom.height() * dpr : 1; | ||
1113 | 158 | const auto pixelFormat = defaultPixelFormatFor(connection); | 166 | const auto pixelFormat = defaultPixelFormatFor(connection); |
1114 | 159 | 167 | ||
1115 | 160 | if (U_ON_SCREEN_KEYBOARD_ROLE == roleFor(window)) { | 168 | if (U_ON_SCREEN_KEYBOARD_ROLE == roleFor(window)) { |
1118 | 161 | qCDebug(ubuntumirclient, "makeSurfaceSpec(window=%p) - creating input method surface (width=%d, height=%d", window, width, height); | 169 | qCDebug(ubuntumirclient, "makeSurfaceSpec(window=%p) - creating input method surface with size=(%dx%d)px", window, widthPx, heightPx); |
1119 | 162 | return Spec{mir_connection_create_spec_for_input_method(connection, width, height, pixelFormat)}; | 170 | return Spec{mir_connection_create_spec_for_input_method(connection, widthPx, heightPx, pixelFormat)}; |
1120 | 163 | } | 171 | } |
1121 | 164 | 172 | ||
1122 | 165 | const Qt::WindowType type = window->type(); | 173 | const Qt::WindowType type = window->type(); |
1123 | @@ -172,13 +180,13 @@ | |||
1124 | 172 | parent = input->lastFocusedWindow(); | 180 | parent = input->lastFocusedWindow(); |
1125 | 173 | } | 181 | } |
1126 | 174 | if (parent) { | 182 | if (parent) { |
1131 | 175 | auto pos = geom.topLeft(); | 183 | auto posPx = geom.topLeft() * dpr; |
1132 | 176 | pos -= parent->geometry().topLeft(); | 184 | posPx -= parent->geometry().topLeft() * dpr; |
1133 | 177 | MirRectangle location{pos.x(), pos.y(), 0, 0}; | 185 | MirRectangle location{posPx.x(), posPx.y(), 0, 0}; |
1134 | 178 | qCDebug(ubuntumirclient, "makeSurfaceSpec(window=%p) - creating menu surface(width:%d, height:%d)", window, width, height); | 186 | qCDebug(ubuntumirclient, "makeSurfaceSpec(window=%p) - creating menu surface with size=(%dx%d)px", window, widthPx, heightPx); |
1135 | 179 | return Spec{mir_connection_create_spec_for_menu( | 187 | return Spec{mir_connection_create_spec_for_menu( |
1138 | 180 | connection, width, height, pixelFormat, parent->mirSurface(), | 188 | connection, widthPx, heightPx, pixelFormat, parent->mirSurface(), |
1139 | 181 | &location, mir_edge_attachment_any)}; | 189 | &location, mir_edge_attachment_any)}; |
1140 | 182 | } else { | 190 | } else { |
1141 | 183 | qCDebug(ubuntumirclient, "makeSurfaceSpec(window=%p) - cannot create a menu without a parent!", window); | 191 | qCDebug(ubuntumirclient, "makeSurfaceSpec(window=%p) - cannot create a menu without a parent!", window); |
1142 | 184 | } | 192 | } |
1143 | @@ -186,37 +194,39 @@ | |||
1144 | 186 | auto parent = transientParentFor(window); | 194 | auto parent = transientParentFor(window); |
1145 | 187 | if (parent) { | 195 | if (parent) { |
1146 | 188 | // Modal dialog | 196 | // Modal dialog |
1149 | 189 | qCDebug(ubuntumirclient, "makeSurfaceSpec(window=%p) - creating modal dialog (width=%d, height=%d", window, width, height); | 197 | qCDebug(ubuntumirclient, "makeSurfaceSpec(window=%p) - creating modal dialog with size=(%dx%d)px", window, widthPx, heightPx); |
1150 | 190 | return Spec{mir_connection_create_spec_for_modal_dialog(connection, width, height, pixelFormat, parent->mirSurface())}; | 198 | return Spec{mir_connection_create_spec_for_modal_dialog(connection, widthPx, heightPx, pixelFormat, parent->mirSurface())}; |
1151 | 191 | } else { | 199 | } else { |
1152 | 192 | // TODO: do Qt parentless dialogs have the same semantics as mir? | 200 | // TODO: do Qt parentless dialogs have the same semantics as mir? |
1155 | 193 | qCDebug(ubuntumirclient, "makeSurfaceSpec(window=%p) - creating parentless dialog (width=%d, height=%d)", window, width, height); | 201 | qCDebug(ubuntumirclient, "makeSurfaceSpec(window=%p) - creating parentless dialog with size=(%dx%d)px", window, widthPx, heightPx); |
1156 | 194 | return Spec{mir_connection_create_spec_for_dialog(connection, width, height, pixelFormat)}; | 202 | return Spec{mir_connection_create_spec_for_dialog(connection, widthPx, heightPx, pixelFormat)}; |
1157 | 195 | } | 203 | } |
1158 | 196 | } | 204 | } |
1161 | 197 | qCDebug(ubuntumirclient, "makeSurfaceSpec(window=%p) - creating normal surface(type=0x%x, width=%d, height=%d)", window, type, width, height); | 205 | qCDebug(ubuntumirclient, "makeSurfaceSpec(window=%p) - creating normal surface(type=0x%x, with size=(%dx%d)px", window, type, widthPx, heightPx); |
1162 | 198 | return Spec{mir_connection_create_spec_for_normal_surface(connection, width, height, pixelFormat)}; | 206 | return Spec{mir_connection_create_spec_for_normal_surface(connection, widthPx, heightPx, pixelFormat)}; |
1163 | 199 | } | 207 | } |
1164 | 200 | 208 | ||
1166 | 201 | void setSizingConstraints(MirSurfaceSpec *spec, const QSize& minSize, const QSize& maxSize, const QSize& increment) | 209 | void setSizingConstraints(MirSurfaceSpec *spec, const QSize &minSizePx, const QSize &maxSizePx, const QSize &incrementPx) |
1167 | 202 | { | 210 | { |
1181 | 203 | mir_surface_spec_set_min_width(spec, minSize.width()); | 211 | mir_surface_spec_set_min_width(spec, minSizePx.width()); |
1182 | 204 | mir_surface_spec_set_min_height(spec, minSize.height()); | 212 | mir_surface_spec_set_min_height(spec, minSizePx.height()); |
1183 | 205 | if (maxSize.width() >= minSize.width()) { | 213 | if (maxSizePx.width() >= minSizePx.width()) { |
1184 | 206 | mir_surface_spec_set_max_width(spec, maxSize.width()); | 214 | mir_surface_spec_set_max_width(spec, maxSizePx.width()); |
1185 | 207 | } | 215 | } |
1186 | 208 | if (maxSize.height() >= minSize.height()) { | 216 | if (maxSizePx.height() >= minSizePx.height()) { |
1187 | 209 | mir_surface_spec_set_max_height(spec, maxSize.height()); | 217 | mir_surface_spec_set_max_height(spec, maxSizePx.height()); |
1188 | 210 | } | 218 | } |
1189 | 211 | if (increment.width() > 0) { | 219 | if (incrementPx.width() > 0) { |
1190 | 212 | mir_surface_spec_set_width_increment(spec, increment.width()); | 220 | mir_surface_spec_set_width_increment(spec, incrementPx.width()); |
1191 | 213 | } | 221 | } |
1192 | 214 | if (increment.height() > 0) { | 222 | if (incrementPx.height() > 0) { |
1193 | 215 | mir_surface_spec_set_height_increment(spec, increment.height()); | 223 | mir_surface_spec_set_height_increment(spec, incrementPx.height()); |
1194 | 216 | } | 224 | } |
1195 | 217 | } | 225 | } |
1196 | 218 | 226 | ||
1198 | 219 | MirSurface *createMirSurface(QWindow *window, UbuntuScreen *screen, UbuntuInput *input, MirConnection *connection) | 227 | MirSurface *createMirSurface(QWindow *window, UbuntuScreen *screen, UbuntuInput *input, |
1199 | 228 | MirConnection *connection, mir_surface_event_callback inputCallback, | ||
1200 | 229 | void* inputContext) | ||
1201 | 220 | { | 230 | { |
1202 | 221 | auto spec = makeSurfaceSpec(window, input, connection); | 231 | auto spec = makeSurfaceSpec(window, input, connection); |
1203 | 222 | const auto title = window->title().toUtf8(); | 232 | const auto title = window->title().toUtf8(); |
1204 | @@ -228,6 +238,8 @@ | |||
1205 | 228 | mir_surface_spec_set_fullscreen_on_output(spec.get(), screen->mirOutputId()); | 238 | mir_surface_spec_set_fullscreen_on_output(spec.get(), screen->mirOutputId()); |
1206 | 229 | } | 239 | } |
1207 | 230 | 240 | ||
1208 | 241 | mir_surface_spec_set_event_handler(spec.get(), inputCallback, inputContext); | ||
1209 | 242 | |||
1210 | 231 | if (window->flags() & LowChromeWindowHint) { | 243 | if (window->flags() & LowChromeWindowHint) { |
1211 | 232 | mir_surface_spec_set_shell_chrome(spec.get(), mir_shell_chrome_low); | 244 | mir_surface_spec_set_shell_chrome(spec.get(), mir_shell_chrome_low); |
1212 | 233 | } | 245 | } |
1213 | @@ -256,6 +268,10 @@ | |||
1214 | 256 | 268 | ||
1215 | 257 | } //namespace | 269 | } //namespace |
1216 | 258 | 270 | ||
1217 | 271 | /* | ||
1218 | 272 | * UbuntuSurface - wraps a MirSurface | ||
1219 | 273 | * All units are in pixels only (no device pixels). | ||
1220 | 274 | */ | ||
1221 | 259 | class UbuntuSurface | 275 | class UbuntuSurface |
1222 | 260 | { | 276 | { |
1223 | 261 | public: | 277 | public: |
1224 | @@ -264,36 +280,26 @@ | |||
1225 | 264 | , mPlatformWindow(platformWindow) | 280 | , mPlatformWindow(platformWindow) |
1226 | 265 | , mInput(input) | 281 | , mInput(input) |
1227 | 266 | , mConnection(connection) | 282 | , mConnection(connection) |
1228 | 267 | , mMirSurface(createMirSurface(mWindow, screen, input, connection)) | ||
1229 | 268 | , mEglDisplay(screen->eglDisplay()) | 283 | , mEglDisplay(screen->eglDisplay()) |
1230 | 269 | , mEglSurface(eglCreateWindowSurface(mEglDisplay, screen->eglConfig(), nativeWindowFor(mMirSurface), nullptr)) | ||
1231 | 270 | , mNeedsRepaint(false) | 284 | , mNeedsRepaint(false) |
1232 | 271 | , mParented(mWindow->transientParent() || mWindow->parent()) | 285 | , mParented(mWindow->transientParent() || mWindow->parent()) |
1233 | 272 | , mShellChrome(mWindow->flags() & LowChromeWindowHint ? mir_shell_chrome_low : mir_shell_chrome_normal) | 286 | , mShellChrome(mWindow->flags() & LowChromeWindowHint ? mir_shell_chrome_low : mir_shell_chrome_normal) |
1234 | 273 | { | 287 | { |
1236 | 274 | mir_surface_set_event_handler(mMirSurface, surfaceEventCallback, this); | 288 | mMirSurface = createMirSurface(mWindow, screen, input, connection, surfaceEventCallback, this); |
1237 | 289 | mEglSurface = eglCreateWindowSurface(mEglDisplay, screen->eglConfig(), nativeWindowFor(mMirSurface), nullptr); | ||
1238 | 275 | 290 | ||
1239 | 276 | // Window manager can give us a final size different from what we asked for | 291 | // Window manager can give us a final size different from what we asked for |
1240 | 277 | // so let's check what we ended up getting | 292 | // so let's check what we ended up getting |
1241 | 278 | MirSurfaceParameters parameters; | 293 | MirSurfaceParameters parameters; |
1242 | 279 | mir_surface_get_parameters(mMirSurface, ¶meters); | 294 | mir_surface_get_parameters(mMirSurface, ¶meters); |
1243 | 280 | 295 | ||
1244 | 281 | auto geom = mWindow->geometry(); | ||
1245 | 282 | geom.setWidth(parameters.width); | ||
1246 | 283 | geom.setHeight(parameters.height); | ||
1247 | 284 | if (mWindow->windowState() == Qt::WindowFullScreen) { | ||
1248 | 285 | geom.setY(0); | ||
1249 | 286 | } else { | ||
1250 | 287 | geom.setY(panelHeight()); | ||
1251 | 288 | } | ||
1252 | 289 | |||
1253 | 290 | // Assume that the buffer size matches the surface size at creation time | 296 | // Assume that the buffer size matches the surface size at creation time |
1257 | 291 | mBufferSize = geom.size(); | 297 | mBufferSizePx.rwidth() = parameters.width; |
1258 | 292 | platformWindow->QPlatformWindow::setGeometry(geom); | 298 | mBufferSizePx.rheight() = parameters.height; |
1256 | 293 | QWindowSystemInterface::handleGeometryChange(mWindow, geom); | ||
1259 | 294 | 299 | ||
1262 | 295 | qCDebug(ubuntumirclient, "created surface at (%d, %d) with size (%d, %d), title '%s', role: '%d'\n", | 300 | qCDebug(ubuntumirclient, "created surface with size=(%dx%d)px, title='%s', role=%d", |
1263 | 296 | geom.x(), geom.y(), geom.width(), geom.height(), mWindow->title().toUtf8().constData(), roleFor(mWindow)); | 301 | parameters.width, parameters.height, qPrintable(mWindow->title()), roleFor(mWindow)); |
1264 | 302 | mPlatformWindow->updateWindowSize(parameters.width, parameters.height); | ||
1265 | 297 | } | 303 | } |
1266 | 298 | 304 | ||
1267 | 299 | ~UbuntuSurface() | 305 | ~UbuntuSurface() |
1268 | @@ -304,15 +310,15 @@ | |||
1269 | 304 | mir_surface_release_sync(mMirSurface); | 310 | mir_surface_release_sync(mMirSurface); |
1270 | 305 | } | 311 | } |
1271 | 306 | 312 | ||
1274 | 307 | UbuntuSurface(UbuntuSurface const&) = delete; | 313 | UbuntuSurface(const UbuntuSurface &) = delete; |
1275 | 308 | UbuntuSurface& operator=(UbuntuSurface const&) = delete; | 314 | UbuntuSurface& operator=(const UbuntuSurface &) = delete; |
1276 | 309 | 315 | ||
1280 | 310 | void resize(const QSize& newSize); | 316 | void resize(const QSize &newSizePx); |
1281 | 311 | void updateTitle(const QString& title); | 317 | void updateTitle(const QString &title); |
1282 | 312 | void setSizingConstraints(const QSize& minSize, const QSize& maxSize, const QSize& increment); | 318 | void setSizingConstraints(const QSize &minSizePx, const QSize &maxSizePx, const QSize &incrementPx); |
1283 | 313 | 319 | ||
1284 | 314 | void onSwapBuffersDone(); | 320 | void onSwapBuffersDone(); |
1286 | 315 | void handleSurfaceResized(int width, int height); | 321 | void handleSurfaceResized(int widthPx, int heightPx); |
1287 | 316 | int needsRepaint() const; | 322 | int needsRepaint() const; |
1288 | 317 | 323 | ||
1289 | 318 | MirSurfaceState state() const { return mir_surface_get_state(mMirSurface); } | 324 | MirSurfaceState state() const { return mir_surface_get_state(mMirSurface); } |
1290 | @@ -329,7 +335,7 @@ | |||
1291 | 329 | bool hasParent() const { return mParented; } | 335 | bool hasParent() const { return mParented; } |
1292 | 330 | 336 | ||
1293 | 331 | private: | 337 | private: |
1295 | 332 | static void surfaceEventCallback(MirSurface* surface, const MirEvent *event, void* context); | 338 | static void surfaceEventCallback(MirSurface *surface, const MirEvent *event, void *context); |
1296 | 333 | void postEvent(const MirEvent *event); | 339 | void postEvent(const MirEvent *event); |
1297 | 334 | 340 | ||
1298 | 335 | QWindow * const mWindow; | 341 | QWindow * const mWindow; |
1299 | @@ -337,40 +343,40 @@ | |||
1300 | 337 | UbuntuInput * const mInput; | 343 | UbuntuInput * const mInput; |
1301 | 338 | MirConnection * const mConnection; | 344 | MirConnection * const mConnection; |
1302 | 339 | 345 | ||
1304 | 340 | MirSurface * const mMirSurface; | 346 | MirSurface* mMirSurface; |
1305 | 341 | const EGLDisplay mEglDisplay; | 347 | const EGLDisplay mEglDisplay; |
1307 | 342 | const EGLSurface mEglSurface; | 348 | EGLSurface mEglSurface; |
1308 | 343 | 349 | ||
1309 | 344 | bool mNeedsRepaint; | 350 | bool mNeedsRepaint; |
1310 | 345 | bool mParented; | 351 | bool mParented; |
1312 | 346 | QSize mBufferSize; | 352 | QSize mBufferSizePx; |
1313 | 347 | 353 | ||
1314 | 348 | QMutex mTargetSizeMutex; | 354 | QMutex mTargetSizeMutex; |
1316 | 349 | QSize mTargetSize; | 355 | QSize mTargetSizePx; |
1317 | 350 | MirShellChrome mShellChrome; | 356 | MirShellChrome mShellChrome; |
1318 | 351 | }; | 357 | }; |
1319 | 352 | 358 | ||
1321 | 353 | void UbuntuSurface::resize(const QSize& size) | 359 | void UbuntuSurface::resize(const QSize &sizePx) |
1322 | 354 | { | 360 | { |
1324 | 355 | qCDebug(ubuntumirclient,"resize(window=%p, width=%d, height=%d)", mWindow, size.width(), size.height()); | 361 | qCDebug(ubuntumirclient,"resize(window=%p) to (%dx%d)px", mWindow, sizePx.width(), sizePx.height()); |
1325 | 356 | 362 | ||
1326 | 357 | if (mWindow->windowState() == Qt::WindowFullScreen || mWindow->windowState() == Qt::WindowMaximized) { | 363 | if (mWindow->windowState() == Qt::WindowFullScreen || mWindow->windowState() == Qt::WindowMaximized) { |
1327 | 358 | qCDebug(ubuntumirclient, "resize(window=%p) - not resizing, window is maximized or fullscreen", mWindow); | 364 | qCDebug(ubuntumirclient, "resize(window=%p) - not resizing, window is maximized or fullscreen", mWindow); |
1328 | 359 | return; | 365 | return; |
1329 | 360 | } | 366 | } |
1330 | 361 | 367 | ||
1332 | 362 | if (size.isEmpty()) { | 368 | if (sizePx.isEmpty()) { |
1333 | 363 | qCDebug(ubuntumirclient, "resize(window=%p) - not resizing, size is empty", mWindow); | 369 | qCDebug(ubuntumirclient, "resize(window=%p) - not resizing, size is empty", mWindow); |
1334 | 364 | return; | 370 | return; |
1335 | 365 | } | 371 | } |
1336 | 366 | 372 | ||
1337 | 367 | Spec spec{mir_connection_create_spec_for_changes(mConnection)}; | 373 | Spec spec{mir_connection_create_spec_for_changes(mConnection)}; |
1340 | 368 | mir_surface_spec_set_width(spec.get(), size.width()); | 374 | mir_surface_spec_set_width(spec.get(), sizePx.width()); |
1341 | 369 | mir_surface_spec_set_height(spec.get(), size.height()); | 375 | mir_surface_spec_set_height(spec.get(), sizePx.height()); |
1342 | 370 | mir_surface_apply_spec(mMirSurface, spec.get()); | 376 | mir_surface_apply_spec(mMirSurface, spec.get()); |
1343 | 371 | } | 377 | } |
1344 | 372 | 378 | ||
1346 | 373 | void UbuntuSurface::updateTitle(const QString& newTitle) | 379 | void UbuntuSurface::updateTitle(const QString &newTitle) |
1347 | 374 | { | 380 | { |
1348 | 375 | const auto title = newTitle.toUtf8(); | 381 | const auto title = newTitle.toUtf8(); |
1349 | 376 | Spec spec{mir_connection_create_spec_for_changes(mConnection)}; | 382 | Spec spec{mir_connection_create_spec_for_changes(mConnection)}; |
1350 | @@ -378,14 +384,14 @@ | |||
1351 | 378 | mir_surface_apply_spec(mMirSurface, spec.get()); | 384 | mir_surface_apply_spec(mMirSurface, spec.get()); |
1352 | 379 | } | 385 | } |
1353 | 380 | 386 | ||
1355 | 381 | void UbuntuSurface::setSizingConstraints(const QSize& minSize, const QSize& maxSize, const QSize& increment) | 387 | void UbuntuSurface::setSizingConstraints(const QSize &minSizePx, const QSize &maxSizePx, const QSize &incrementPx) |
1356 | 382 | { | 388 | { |
1357 | 383 | Spec spec{mir_connection_create_spec_for_changes(mConnection)}; | 389 | Spec spec{mir_connection_create_spec_for_changes(mConnection)}; |
1359 | 384 | ::setSizingConstraints(spec.get(), minSize, maxSize, increment); | 390 | ::setSizingConstraints(spec.get(), minSizePx, maxSizePx, incrementPx); |
1360 | 385 | mir_surface_apply_spec(mMirSurface, spec.get()); | 391 | mir_surface_apply_spec(mMirSurface, spec.get()); |
1361 | 386 | } | 392 | } |
1362 | 387 | 393 | ||
1364 | 388 | void UbuntuSurface::handleSurfaceResized(int width, int height) | 394 | void UbuntuSurface::handleSurfaceResized(int widthPx, int heightPx) |
1365 | 389 | { | 395 | { |
1366 | 390 | QMutexLocker lock(&mTargetSizeMutex); | 396 | QMutexLocker lock(&mTargetSizeMutex); |
1367 | 391 | 397 | ||
1368 | @@ -395,13 +401,13 @@ | |||
1369 | 395 | // see TODO in postEvent as the ideal way we should handle this. | 401 | // see TODO in postEvent as the ideal way we should handle this. |
1370 | 396 | // The actual buffer size may or may have not changed at this point, so let the rendering | 402 | // The actual buffer size may or may have not changed at this point, so let the rendering |
1371 | 397 | // thread drive the window geometry updates. | 403 | // thread drive the window geometry updates. |
1373 | 398 | mNeedsRepaint = mTargetSize.width() == width && mTargetSize.height() == height; | 404 | mNeedsRepaint = mTargetSizePx.width() == widthPx && mTargetSizePx.height() == heightPx; |
1374 | 399 | } | 405 | } |
1375 | 400 | 406 | ||
1376 | 401 | int UbuntuSurface::needsRepaint() const | 407 | int UbuntuSurface::needsRepaint() const |
1377 | 402 | { | 408 | { |
1378 | 403 | if (mNeedsRepaint) { | 409 | if (mNeedsRepaint) { |
1380 | 404 | if (mTargetSize != mBufferSize) { | 410 | if (mTargetSizePx != mBufferSizePx) { |
1381 | 405 | //If the buffer hasn't changed yet, we need at least two redraws, | 411 | //If the buffer hasn't changed yet, we need at least two redraws, |
1382 | 406 | //once to get the new buffer size and propagate the geometry changes | 412 | //once to get the new buffer size and propagate the geometry changes |
1383 | 407 | //and the second to redraw the content at the new size | 413 | //and the second to redraw the content at the new size |
1384 | @@ -436,29 +442,25 @@ | |||
1385 | 436 | static int sFrameNumber = 0; | 442 | static int sFrameNumber = 0; |
1386 | 437 | ++sFrameNumber; | 443 | ++sFrameNumber; |
1387 | 438 | 444 | ||
1408 | 439 | EGLint eglSurfaceWidth = -1; | 445 | EGLint eglSurfaceWidthPx = -1; |
1409 | 440 | EGLint eglSurfaceHeight = -1; | 446 | EGLint eglSurfaceHeightPx = -1; |
1410 | 441 | eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, &eglSurfaceWidth); | 447 | eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, &eglSurfaceWidthPx); |
1411 | 442 | eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, &eglSurfaceHeight); | 448 | eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, &eglSurfaceHeightPx); |
1412 | 443 | 449 | ||
1413 | 444 | const bool validSize = eglSurfaceWidth > 0 && eglSurfaceHeight > 0; | 450 | const bool validSize = eglSurfaceWidthPx > 0 && eglSurfaceHeightPx > 0; |
1414 | 445 | 451 | ||
1415 | 446 | if (validSize && (mBufferSize.width() != eglSurfaceWidth || mBufferSize.height() != eglSurfaceHeight)) { | 452 | if (validSize && (mBufferSizePx.width() != eglSurfaceWidthPx || mBufferSizePx.height() != eglSurfaceHeightPx)) { |
1416 | 447 | 453 | ||
1417 | 448 | qCDebug(ubuntumirclientBufferSwap, "onSwapBuffersDone(window=%p) [%d] - size changed (%d, %d) => (%d, %d)", | 454 | qCDebug(ubuntumirclientBufferSwap, "onSwapBuffersDone(window=%p) [%d] - buffer size changed (%dx%d)px => (%dx%d)px", |
1418 | 449 | mWindow, sFrameNumber, mBufferSize.width(), mBufferSize.height(), eglSurfaceWidth, eglSurfaceHeight); | 455 | mWindow, sFrameNumber, mBufferSizePx.width(), mBufferSizePx.height(), eglSurfaceWidthPx, eglSurfaceHeightPx); |
1419 | 450 | 456 | ||
1420 | 451 | mBufferSize.rwidth() = eglSurfaceWidth; | 457 | mBufferSizePx.rwidth() = eglSurfaceWidthPx; |
1421 | 452 | mBufferSize.rheight() = eglSurfaceHeight; | 458 | mBufferSizePx.rheight() = eglSurfaceHeightPx; |
1422 | 453 | 459 | ||
1423 | 454 | QRect newGeometry = mPlatformWindow->geometry(); | 460 | mPlatformWindow->updateWindowSize(eglSurfaceWidthPx, eglSurfaceHeightPx); |
1404 | 455 | newGeometry.setSize(mBufferSize); | ||
1405 | 456 | |||
1406 | 457 | mPlatformWindow->QPlatformWindow::setGeometry(newGeometry); | ||
1407 | 458 | QWindowSystemInterface::handleGeometryChange(mWindow, newGeometry); | ||
1424 | 459 | } else { | 461 | } else { |
1427 | 460 | qCDebug(ubuntumirclientBufferSwap, "onSwapBuffersDone(window=%p) [%d] - buffer size (%d,%d)", | 462 | qCDebug(ubuntumirclientBufferSwap, "onSwapBuffersDone(window=%p) [%d] - buffer size=(%dx%d)px", |
1428 | 461 | mWindow, sFrameNumber, mBufferSize.width(), mBufferSize.height()); | 463 | mWindow, sFrameNumber, mBufferSizePx.width(), mBufferSizePx.height()); |
1429 | 462 | } | 464 | } |
1430 | 463 | } | 465 | } |
1431 | 464 | 466 | ||
1432 | @@ -479,13 +481,13 @@ | |||
1433 | 479 | // As a workaround, we use the width/height as an identifier of this latest event | 481 | // As a workaround, we use the width/height as an identifier of this latest event |
1434 | 480 | // so the event handler (handleSurfaceResized) can discard/ignore old ones. | 482 | // so the event handler (handleSurfaceResized) can discard/ignore old ones. |
1435 | 481 | const auto resizeEvent = mir_event_get_resize_event(event); | 483 | const auto resizeEvent = mir_event_get_resize_event(event); |
1439 | 482 | const auto width = mir_resize_event_get_width(resizeEvent); | 484 | const auto widthPx = mir_resize_event_get_width(resizeEvent); |
1440 | 483 | const auto height = mir_resize_event_get_height(resizeEvent); | 485 | const auto heightPx = mir_resize_event_get_height(resizeEvent); |
1441 | 484 | qCDebug(ubuntumirclient, "resizeEvent(window=%p, width=%d, height=%d)", mWindow, width, height); | 486 | qCDebug(ubuntumirclient, "resizeEvent(window=%p, size=(%dx%d)px", mWindow, widthPx, heightPx); |
1442 | 485 | 487 | ||
1443 | 486 | QMutexLocker lock(&mTargetSizeMutex); | 488 | QMutexLocker lock(&mTargetSizeMutex); |
1446 | 487 | mTargetSize.rwidth() = width; | 489 | mTargetSizePx.rwidth() = widthPx; |
1447 | 488 | mTargetSize.rheight() = height; | 490 | mTargetSizePx.rheight() = heightPx; |
1448 | 489 | } | 491 | } |
1449 | 490 | 492 | ||
1450 | 491 | mInput->postEvent(mPlatformWindow, event); | 493 | mInput->postEvent(mPlatformWindow, event); |
1451 | @@ -501,8 +503,8 @@ | |||
1452 | 501 | mir_surface_apply_spec(mMirSurface, spec.get()); | 503 | mir_surface_apply_spec(mMirSurface, spec.get()); |
1453 | 502 | } | 504 | } |
1454 | 503 | 505 | ||
1457 | 504 | UbuntuWindow::UbuntuWindow(QWindow *w, const QSharedPointer<UbuntuClipboard> &clipboard, UbuntuScreen *screen, | 506 | UbuntuWindow::UbuntuWindow(QWindow *w, const QSharedPointer<UbuntuClipboard> &clipboard, |
1458 | 505 | UbuntuInput *input, MirConnection *connection) | 507 | UbuntuInput *input, UbuntuNativeInterface *native, MirConnection *connection) |
1459 | 506 | : QObject(nullptr) | 508 | : QObject(nullptr) |
1460 | 507 | , QPlatformWindow(w) | 509 | , QPlatformWindow(w) |
1461 | 508 | , mId(makeId()) | 510 | , mId(makeId()) |
1462 | @@ -510,9 +512,16 @@ | |||
1463 | 510 | , mWindowState(w->windowState()) | 512 | , mWindowState(w->windowState()) |
1464 | 511 | , mWindowFlags(w->flags()) | 513 | , mWindowFlags(w->flags()) |
1465 | 512 | , mWindowVisible(false) | 514 | , mWindowVisible(false) |
1467 | 513 | , mSurface(new UbuntuSurface{this, screen, input, connection}) | 515 | , mWindowExposed(true) |
1468 | 516 | , mNativeInterface(native) | ||
1469 | 517 | , mSurface(new UbuntuSurface{this, static_cast<UbuntuScreen*>(w->screen()->handle()), input, connection}) | ||
1470 | 518 | , mScale(1.0) | ||
1471 | 519 | , mFormFactor(mir_form_factor_unknown) | ||
1472 | 514 | { | 520 | { |
1474 | 515 | qCDebug(ubuntumirclient, "UbuntuWindow(window=%p, screen=%p, input=%p, surf=%p)", w, screen, input, mSurface.get()); | 521 | qCDebug(ubuntumirclient, "UbuntuWindow(window=%p, screen=%p, input=%p, surf=%p) with title '%s', role: '%d'", |
1475 | 522 | w, w->screen()->handle(), input, mSurface.get(), qPrintable(window()->title()), roleFor(window())); | ||
1476 | 523 | |||
1477 | 524 | enablePanelHeightHack(w->windowState() != Qt::WindowFullScreen); | ||
1478 | 516 | } | 525 | } |
1479 | 517 | 526 | ||
1480 | 518 | UbuntuWindow::~UbuntuWindow() | 527 | UbuntuWindow::~UbuntuWindow() |
1481 | @@ -520,12 +529,25 @@ | |||
1482 | 520 | qCDebug(ubuntumirclient, "~UbuntuWindow(window=%p)", this); | 529 | qCDebug(ubuntumirclient, "~UbuntuWindow(window=%p)", this); |
1483 | 521 | } | 530 | } |
1484 | 522 | 531 | ||
1486 | 523 | void UbuntuWindow::handleSurfaceResized(int width, int height) | 532 | void UbuntuWindow::updateWindowSize(int widthPx, int heightPx) // after when Mir has resized the surface |
1487 | 533 | { | ||
1488 | 534 | const float dpr = devicePixelRatio(); | ||
1489 | 535 | auto geom = geometry(); | ||
1490 | 536 | geom.setWidth(divideAndRoundUp(widthPx, dpr)); | ||
1491 | 537 | geom.setHeight(divideAndRoundUp(heightPx, dpr)); | ||
1492 | 538 | |||
1493 | 539 | QPlatformWindow::setGeometry(geom); | ||
1494 | 540 | QWindowSystemInterface::handleGeometryChange(window(), geom); | ||
1495 | 541 | |||
1496 | 542 | qCDebug(ubuntumirclient) << "Surface geometry updated:" << geom; | ||
1497 | 543 | } | ||
1498 | 544 | |||
1499 | 545 | void UbuntuWindow::handleSurfaceResized(int widthPx, int heightPx) | ||
1500 | 524 | { | 546 | { |
1501 | 525 | QMutexLocker lock(&mMutex); | 547 | QMutexLocker lock(&mMutex); |
1503 | 526 | qCDebug(ubuntumirclient, "handleSurfaceResize(window=%p, width=%d, height=%d)", window(), width, height); | 548 | qCDebug(ubuntumirclient, "handleSurfaceResize(window=%p, size=(%dx%d)px", window(), widthPx, heightPx); |
1504 | 527 | 549 | ||
1506 | 528 | mSurface->handleSurfaceResized(width, height); | 550 | mSurface->handleSurfaceResized(widthPx, heightPx); |
1507 | 529 | 551 | ||
1508 | 530 | // This resize event could have occurred just after the last buffer swap for this window. | 552 | // This resize event could have occurred just after the last buffer swap for this window. |
1509 | 531 | // This means the client may still be holding a buffer with the older size. The first redraw call | 553 | // This means the client may still be holding a buffer with the older size. The first redraw call |
1510 | @@ -536,11 +558,23 @@ | |||
1511 | 536 | lock.unlock(); | 558 | lock.unlock(); |
1512 | 537 | qCDebug(ubuntumirclient, "handleSurfaceResize(window=%p) redraw %d times", window(), numRepaints); | 559 | qCDebug(ubuntumirclient, "handleSurfaceResize(window=%p) redraw %d times", window(), numRepaints); |
1513 | 538 | for (int i = 0; i < numRepaints; i++) { | 560 | for (int i = 0; i < numRepaints; i++) { |
1515 | 539 | qCDebug(ubuntumirclient, "handleSurfaceResize(window=%p) repainting width=%d, height=%d", window(), geometry().size().width(), geometry().size().height()); | 561 | qCDebug(ubuntumirclient, "handleSurfaceResize(window=%p) repainting size=(%dx%d)dp", window(), geometry().size().width(), geometry().size().height()); |
1516 | 540 | QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size())); | 562 | QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size())); |
1517 | 541 | } | 563 | } |
1518 | 542 | } | 564 | } |
1519 | 543 | 565 | ||
1520 | 566 | void UbuntuWindow::handleSurfaceExposeChange(bool exposed) | ||
1521 | 567 | { | ||
1522 | 568 | QMutexLocker lock(&mMutex); | ||
1523 | 569 | qCDebug(ubuntumirclient, "handleSurfaceExposeChange(window=%p, exposed=%s)", window(), exposed ? "true" : "false"); | ||
1524 | 570 | |||
1525 | 571 | if (mWindowExposed == exposed) return; | ||
1526 | 572 | mWindowExposed = exposed; | ||
1527 | 573 | |||
1528 | 574 | lock.unlock(); | ||
1529 | 575 | QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size())); | ||
1530 | 576 | } | ||
1531 | 577 | |||
1532 | 544 | void UbuntuWindow::handleSurfaceFocused() | 578 | void UbuntuWindow::handleSurfaceFocused() |
1533 | 545 | { | 579 | { |
1534 | 546 | qCDebug(ubuntumirclient, "handleSurfaceFocused(window=%p)", window()); | 580 | qCDebug(ubuntumirclient, "handleSurfaceFocused(window=%p)", window()); |
1535 | @@ -621,19 +655,19 @@ | |||
1536 | 621 | } | 655 | } |
1537 | 622 | } | 656 | } |
1538 | 623 | 657 | ||
1540 | 624 | void UbuntuWindow::setGeometry(const QRect& rect) | 658 | void UbuntuWindow::setGeometry(const QRect &rect) |
1541 | 625 | { | 659 | { |
1542 | 626 | QMutexLocker lock(&mMutex); | 660 | QMutexLocker lock(&mMutex); |
1545 | 627 | qCDebug(ubuntumirclient, "setGeometry (window=%p, x=%d, y=%d, width=%d, height=%d)", | 661 | qCDebug(ubuntumirclient, "setGeometry (window=%p, position=(%d, %d)dp, size=(%dx%d)dp)", |
1546 | 628 | window(), rect.x(), rect.y(), rect.width(), rect.height()); | 662 | window(), rect.x(), rect.y(), rect.width(), rect.height()); |
1547 | 629 | 663 | ||
1548 | 630 | //NOTE: mir surfaces cannot be moved by the client so ignore the topLeft coordinates | 664 | //NOTE: mir surfaces cannot be moved by the client so ignore the topLeft coordinates |
1549 | 631 | const auto newSize = rect.size(); | 665 | const auto newSize = rect.size(); |
1550 | 632 | auto newGeometry = geometry(); | 666 | auto newGeometry = geometry(); |
1551 | 633 | newGeometry.setSize(newSize); | 667 | newGeometry.setSize(newSize); |
1552 | 634 | QPlatformWindow::setGeometry(newGeometry); | ||
1553 | 635 | 668 | ||
1555 | 636 | mSurface->resize(newSize); | 669 | mSurface->resize(newSize * devicePixelRatio()); |
1556 | 670 | // Note: don't call handleGeometryChange here, wait to see what Mir replies with. | ||
1557 | 637 | } | 671 | } |
1558 | 638 | 672 | ||
1559 | 639 | void UbuntuWindow::setVisible(bool visible) | 673 | void UbuntuWindow::setVisible(bool visible) |
1560 | @@ -658,10 +692,9 @@ | |||
1561 | 658 | lock.unlock(); | 692 | lock.unlock(); |
1562 | 659 | updateSurfaceState(); | 693 | updateSurfaceState(); |
1563 | 660 | QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size())); | 694 | QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size())); |
1564 | 661 | QWindowSystemInterface::flushWindowSystemEvents(); | ||
1565 | 662 | } | 695 | } |
1566 | 663 | 696 | ||
1568 | 664 | void UbuntuWindow::setWindowTitle(const QString& title) | 697 | void UbuntuWindow::setWindowTitle(const QString &title) |
1569 | 665 | { | 698 | { |
1570 | 666 | QMutexLocker lock(&mMutex); | 699 | QMutexLocker lock(&mMutex); |
1571 | 667 | qCDebug(ubuntumirclient, "setWindowTitle(window=%p) title=%s)", window(), title.toUtf8().constData()); | 700 | qCDebug(ubuntumirclient, "setWindowTitle(window=%p) title=%s)", window(), title.toUtf8().constData()); |
1572 | @@ -672,16 +705,22 @@ | |||
1573 | 672 | { | 705 | { |
1574 | 673 | QMutexLocker lock(&mMutex); | 706 | QMutexLocker lock(&mMutex); |
1575 | 674 | const auto win = window(); | 707 | const auto win = window(); |
1581 | 675 | qCDebug(ubuntumirclient, "propagateSizeHints(window=%p) min(%d,%d), max(%d,%d) increment(%d, %d)", | 708 | const float dpr = devicePixelRatio(); |
1582 | 676 | win, win->minimumSize().width(), win->minimumSize().height(), | 709 | qCDebug(ubuntumirclient, "propagateSizeHints(window=%p) min(%dx%d)dp; max(%dx%d)dp; increment(%dx%d)dp", |
1583 | 677 | win->maximumSize().width(), win->maximumSize().height(), | 710 | win, win->minimumSize().width(), win->minimumSize().height(), |
1584 | 678 | win->sizeIncrement().width(), win->sizeIncrement().height()); | 711 | win->maximumSize().width(), win->maximumSize().height(), |
1585 | 679 | mSurface->setSizingConstraints(win->minimumSize(), win->maximumSize(), win->sizeIncrement()); | 712 | win->sizeIncrement().width(), win->sizeIncrement().height()); |
1586 | 713 | mSurface->setSizingConstraints(win->minimumSize() * dpr, win->maximumSize() * dpr, win->sizeIncrement() * dpr); | ||
1587 | 714 | } | ||
1588 | 715 | |||
1589 | 716 | qreal UbuntuWindow::devicePixelRatio() const | ||
1590 | 717 | { | ||
1591 | 718 | return screen() ? screen()->devicePixelRatio() : 1.0; // not impossible a Window has no attached Screen | ||
1592 | 680 | } | 719 | } |
1593 | 681 | 720 | ||
1594 | 682 | bool UbuntuWindow::isExposed() const | 721 | bool UbuntuWindow::isExposed() const |
1595 | 683 | { | 722 | { |
1597 | 684 | return mWindowVisible; | 723 | return mWindowVisible && mWindowExposed; |
1598 | 685 | } | 724 | } |
1599 | 686 | 725 | ||
1600 | 687 | void* UbuntuWindow::eglSurface() const | 726 | void* UbuntuWindow::eglSurface() const |
1601 | @@ -705,6 +744,21 @@ | |||
1602 | 705 | mSurface->onSwapBuffersDone(); | 744 | mSurface->onSwapBuffersDone(); |
1603 | 706 | } | 745 | } |
1604 | 707 | 746 | ||
1605 | 747 | void UbuntuWindow::handleScreenPropertiesChange(MirFormFactor formFactor, float scale) | ||
1606 | 748 | { | ||
1607 | 749 | // Update the scale & form factor native-interface properties for the windows affected | ||
1608 | 750 | // as there is no convenient way to emit signals for those custom properties on a QScreen | ||
1609 | 751 | if (formFactor != mFormFactor) { | ||
1610 | 752 | mFormFactor = formFactor; | ||
1611 | 753 | Q_EMIT mNativeInterface->windowPropertyChanged(this, QStringLiteral("formFactor")); | ||
1612 | 754 | } | ||
1613 | 755 | |||
1614 | 756 | if (!qFuzzyCompare(scale, mScale)) { | ||
1615 | 757 | mScale = scale; | ||
1616 | 758 | Q_EMIT mNativeInterface->windowPropertyChanged(this, QStringLiteral("scale")); | ||
1617 | 759 | } | ||
1618 | 760 | } | ||
1619 | 761 | |||
1620 | 708 | void UbuntuWindow::updateSurfaceState() | 762 | void UbuntuWindow::updateSurfaceState() |
1621 | 709 | { | 763 | { |
1622 | 710 | QMutexLocker lock(&mMutex); | 764 | QMutexLocker lock(&mMutex); |
1623 | 711 | 765 | ||
1624 | === modified file 'src/ubuntumirclient/window.h' | |||
1625 | --- src/ubuntumirclient/window.h 2016-02-18 15:45:21 +0000 | |||
1626 | +++ src/ubuntumirclient/window.h 2016-04-20 15:51:01 +0000 | |||
1627 | @@ -18,13 +18,15 @@ | |||
1628 | 18 | #define UBUNTU_WINDOW_H | 18 | #define UBUNTU_WINDOW_H |
1629 | 19 | 19 | ||
1630 | 20 | #include <qpa/qplatformwindow.h> | 20 | #include <qpa/qplatformwindow.h> |
1631 | 21 | #include <QLoggingCategory> | ||
1632 | 22 | #include <QSharedPointer> | 21 | #include <QSharedPointer> |
1633 | 23 | #include <QMutex> | 22 | #include <QMutex> |
1634 | 24 | 23 | ||
1635 | 24 | #include <mir_toolkit/common.h> // needed only for MirFormFactor enum | ||
1636 | 25 | |||
1637 | 25 | #include <memory> | 26 | #include <memory> |
1638 | 26 | 27 | ||
1639 | 27 | class UbuntuClipboard; | 28 | class UbuntuClipboard; |
1640 | 29 | class UbuntuNativeInterface; | ||
1641 | 28 | class UbuntuInput; | 30 | class UbuntuInput; |
1642 | 29 | class UbuntuScreen; | 31 | class UbuntuScreen; |
1643 | 30 | class UbuntuSurface; | 32 | class UbuntuSurface; |
1644 | @@ -35,8 +37,8 @@ | |||
1645 | 35 | { | 37 | { |
1646 | 36 | Q_OBJECT | 38 | Q_OBJECT |
1647 | 37 | public: | 39 | public: |
1650 | 38 | UbuntuWindow(QWindow *w, const QSharedPointer<UbuntuClipboard> &clipboard, UbuntuScreen *screen, | 40 | UbuntuWindow(QWindow *w, const QSharedPointer<UbuntuClipboard> &clipboard, |
1651 | 39 | UbuntuInput *input, MirConnection *mirConnection); | 41 | UbuntuInput *input, UbuntuNativeInterface* native, MirConnection *mirConnection); |
1652 | 40 | virtual ~UbuntuWindow(); | 42 | virtual ~UbuntuWindow(); |
1653 | 41 | 43 | ||
1654 | 42 | // QPlatformWindow methods. | 44 | // QPlatformWindow methods. |
1655 | @@ -48,28 +50,38 @@ | |||
1656 | 48 | void setWindowTitle(const QString &title) override; | 50 | void setWindowTitle(const QString &title) override; |
1657 | 49 | void propagateSizeHints() override; | 51 | void propagateSizeHints() override; |
1658 | 50 | bool isExposed() const override; | 52 | bool isExposed() const override; |
1659 | 53 | qreal devicePixelRatio() const override; | ||
1660 | 54 | |||
1661 | 55 | // Additional Window properties exposed by NativeInterface | ||
1662 | 56 | MirFormFactor formFactor() const { return mFormFactor; } | ||
1663 | 57 | float scale() const { return mScale; } | ||
1664 | 51 | 58 | ||
1665 | 52 | // New methods. | 59 | // New methods. |
1666 | 53 | void *eglSurface() const; | 60 | void *eglSurface() const; |
1667 | 54 | MirSurface *mirSurface() const; | 61 | MirSurface *mirSurface() const; |
1669 | 55 | void handleSurfaceResized(int width, int height); | 62 | void updateWindowSize(int widthPx, int heightPx); |
1670 | 63 | void handleSurfaceResized(int widthPx, int heightPx); | ||
1671 | 64 | void handleSurfaceExposeChange(bool exposed); | ||
1672 | 56 | void handleSurfaceFocused(); | 65 | void handleSurfaceFocused(); |
1673 | 57 | void handleSurfaceVisibilityChanged(bool visible); | 66 | void handleSurfaceVisibilityChanged(bool visible); |
1674 | 58 | void handleSurfaceStateChanged(Qt::WindowState state); | 67 | void handleSurfaceStateChanged(Qt::WindowState state); |
1675 | 59 | void onSwapBuffersDone(); | 68 | void onSwapBuffersDone(); |
1676 | 69 | void handleScreenPropertiesChange(MirFormFactor formFactor, float scale); | ||
1677 | 60 | 70 | ||
1678 | 61 | private: | 71 | private: |
1679 | 62 | void enablePanelHeightHack(bool enable); | 72 | void enablePanelHeightHack(bool enable); |
1680 | 63 | void updateSurfaceState(); | 73 | void updateSurfaceState(); |
1681 | 64 | |||
1682 | 65 | mutable QMutex mMutex; | 74 | mutable QMutex mMutex; |
1683 | 66 | const WId mId; | 75 | const WId mId; |
1684 | 67 | const QSharedPointer<UbuntuClipboard> mClipboard; | 76 | const QSharedPointer<UbuntuClipboard> mClipboard; |
1685 | 68 | Qt::WindowState mWindowState; | 77 | Qt::WindowState mWindowState; |
1686 | 69 | Qt::WindowFlags mWindowFlags; | 78 | Qt::WindowFlags mWindowFlags; |
1687 | 70 | bool mWindowVisible; | 79 | bool mWindowVisible; |
1689 | 71 | 80 | bool mWindowExposed; | |
1690 | 81 | UbuntuNativeInterface *mNativeInterface; | ||
1691 | 72 | std::unique_ptr<UbuntuSurface> mSurface; | 82 | std::unique_ptr<UbuntuSurface> mSurface; |
1692 | 83 | float mScale; | ||
1693 | 84 | MirFormFactor mFormFactor; | ||
1694 | 73 | }; | 85 | }; |
1695 | 74 | 86 | ||
1696 | 75 | #endif // UBUNTU_WINDOW_H | 87 | #endif // UBUNTU_WINDOW_H |
PASSED: Continuous integration, rev:329 /unity8- jenkins. ubuntu. com/job/ lp-qtubuntu- ci/37/ /unity8- jenkins. ubuntu. com/job/ build-0- fetch/1381 /unity8- jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= vivid+overlay/ 1350 /unity8- jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= xenial/ 1350 /unity8- jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= xenial+ overlay/ 1350 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= vivid+overlay/ 1350 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= vivid+overlay/ 1350/artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= xenial/ 1350 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= xenial/ 1350/artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= xenial+ overlay/ 1350 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= xenial+ overlay/ 1350/artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= vivid+overlay/ 1350 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= vivid+overlay/ 1350/artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= xenial/ 1350 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= xenial/ 1350/artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= xenial+ overlay/ 1350 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= xenial+ overlay/ 1350/artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= vivid+overlay/ 1350 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= vivid+overlay/ 1350/artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= xenial/ 1350 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= xenial/ 1350/artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= xenial+ overlay/ 1350 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= xenial+ overlay/ 1350/artifact/ output/ *zip*/output. zip
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild: /unity8- jenkins. ubuntu. com/job/ lp-qtubuntu- ci/37/rebuild
https:/