Merge lp:~nick-dedekind/qtubuntu/shell_chrome into lp:qtubuntu
- shell_chrome
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Gerry Boland |
Approved revision: | 317 |
Merged at revision: | 311 |
Proposed branch: | lp:~nick-dedekind/qtubuntu/shell_chrome |
Merge into: | lp:qtubuntu |
Diff against target: |
516 lines (+212/-79) 3 files modified
src/ubuntumirclient/input.cpp (+39/-1) src/ubuntumirclient/window.cpp (+162/-77) src/ubuntumirclient/window.h (+11/-1) |
To merge this branch: | bzr merge lp:~nick-dedekind/qtubuntu/shell_chrome |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Gerry Boland (community) | Approve | ||
Unity8 CI Bot | continuous-integration | Approve | |
PS Jenkins bot | continuous-integration | Needs Fixing | |
Review via email: mp+286308@code.launchpad.net |
Commit message
Added support for low shell chrome
Description of the change
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:311
http://
Executed test runs:
FAILURE: http://
Click here to trigger a rebuild:
http://
- 312. By Nick Dedekind
-
use hidden state
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:312
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:312
http://
Executed test runs:
FAILURE: http://
Click here to trigger a rebuild:
http://
Gerry Boland (gerboland) wrote : | # |
+++ src/ubuntumircl
at the end of the anonymous namespace, could you please add "// namespace"
I always find
+}
+
+}
hard to parse because you're missing the hint the indent usually gives - since we don't indent namespace contents.
+++ src/ubuntumircl
+const Qt::WindowType WindowHidesShel
being a pedant, but if mir chose the name "shell chrome" I guess we should use its vocabulary too.
+ void updateSurface();
While it was private, I didn't mind, but now it is public, I do. Function name is terrible considering what it does. Please either rename, or refactor a little to avoid making it public member of UbuntuSurface.
There is a general problem in this file, it's unclear what UbuntuSurface is, and how it relates to UbuntuWindow, and what responsibilities it has. My understanding was that UbuntuSurface should wrap the mir surface api in a Qt way, but as you saw it also is saving state, and referring to state in UbuntuWindow/
So what you've done is natural, moving some states out of UbuntuSurface into UbuntuWindow. What is annoying is that UbuntuSurface imposes some sanity checks, referring to those states. I suspect we'll try to remove those, and trust that Mir will impose correct behaviour, instead of doing that here.
But
+ MirShellChrome mShellChrome;
does we need to save this state? Can we not just query the value from the mirclient api?
+ const QRect& exposeRect = mWindowVisible ? QRect(QPoint(), geometry().size()) : QRect();
& beside the variable name plz.
- 313. By Nick Dedekind
-
renamed flag
- 314. By Nick Dedekind
-
parent surface changes
- 315. By Nick Dedekind
-
removed unneeded code
Nick Dedekind (nick-dedekind) wrote : | # |
> +++ src/ubuntumircl
> at the end of the anonymous namespace, could you please add "// namespace"
> I always find
> +}
> +
> +}
> hard to parse because you're missing the hint the indent usually gives - since
> we don't indent namespace contents.
Done
>
>
> +++ src/ubuntumircl
> +const Qt::WindowType WindowHidesShel
> (Qt::WindowType
> being a pedant, but if mir chose the name "shell chrome" I guess we should use
> its vocabulary too.
Done
>
> + void updateSurface();
> While it was private, I didn't mind, but now it is public, I do. Function name
> is terrible considering what it does. Please either rename, or refactor a
> little to avoid making it public member of UbuntuSurface.
I've refactored, but not sure it's the best way. I'm wondering if we can mode the code to QPlatformWindow
We should probably be documenting everything we need to refactor!
>
> There is a general problem in this file, it's unclear what UbuntuSurface is,
> and how it relates to UbuntuWindow, and what responsibilities it has. My
> understanding was that UbuntuSurface should wrap the mir surface api in a Qt
> way, but as you saw it also is saving state, and referring to state in
> UbuntuWindow/
> is totally unclear.
>
> So what you've done is natural, moving some states out of UbuntuSurface into
> UbuntuWindow. What is annoying is that UbuntuSurface imposes some sanity
> checks, referring to those states. I suspect we'll try to remove those, and
> trust that Mir will impose correct behaviour, instead of doing that here.
>
> But
> + MirShellChrome mShellChrome;
> does we need to save this state? Can we not just query the value from the
> mirclient api?
There doesnt seem to be a client query api for this. It's pushed through the surface spec.
>
> + const QRect& exposeRect = mWindowVisible ? QRect(QPoint(),
> geometry().size()) : QRect();
> & beside the variable name plz.
Not needed. removed.
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:315
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
- 316. By Nick Dedekind
-
log
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:316
https:/
Executed test runs:
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:/
Click here to trigger a rebuild:
https:/
- 317. By Nick Dedekind
-
removed check for input method
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:317
https:/
Executed test runs:
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:/
Click here to trigger a rebuild:
https:/
Gerry Boland (gerboland) wrote : | # |
Ok, looks fine. Thanks!
Preview Diff
1 | === modified file 'src/ubuntumirclient/input.cpp' |
2 | --- src/ubuntumirclient/input.cpp 2016-02-02 11:07:38 +0000 |
3 | +++ src/ubuntumirclient/input.cpp 2016-03-14 17:37:49 +0000 |
4 | @@ -38,6 +38,9 @@ |
5 | |
6 | Q_LOGGING_CATEGORY(ubuntumirclientInput, "ubuntumirclient.input", QtWarningMsg) |
7 | |
8 | +namespace |
9 | +{ |
10 | + |
11 | // XKB Keysyms which do not map directly to Qt types (i.e. Unicode points) |
12 | static const uint32_t KeyTable[] = { |
13 | XKB_KEY_Escape, Qt::Key_Escape, |
14 | @@ -118,6 +121,29 @@ |
15 | 0, 0 |
16 | }; |
17 | |
18 | +Qt::WindowState mirSurfaceStateToWindowState(MirSurfaceState state) |
19 | +{ |
20 | + switch (state) { |
21 | + case mir_surface_state_fullscreen: |
22 | + return Qt::WindowFullScreen; |
23 | + case mir_surface_state_maximized: |
24 | + case mir_surface_state_vertmaximized: |
25 | + case mir_surface_state_horizmaximized: |
26 | + return Qt::WindowMaximized; |
27 | + case mir_surface_state_minimized: |
28 | + return Qt::WindowMinimized; |
29 | + case mir_surface_state_hidden: |
30 | + // We should be handling this state separately. |
31 | + Q_ASSERT(false); |
32 | + case mir_surface_state_restored: |
33 | + case mir_surface_state_unknown: |
34 | + default: |
35 | + return Qt::WindowNoState; |
36 | + } |
37 | +} |
38 | + |
39 | +} // namespace |
40 | + |
41 | class UbuntuEvent : public QEvent |
42 | { |
43 | public: |
44 | @@ -226,7 +252,9 @@ |
45 | case mir_event_type_surface: |
46 | { |
47 | auto surfaceEvent = mir_event_get_surface_event(nativeEvent); |
48 | - if (mir_surface_event_get_attribute(surfaceEvent) == mir_surface_attrib_focus) { |
49 | + auto surfaceEventAttribute = mir_surface_event_get_attribute(surfaceEvent); |
50 | + |
51 | + if (surfaceEventAttribute == mir_surface_attrib_focus) { |
52 | const bool focused = mir_surface_event_get_attribute_value(surfaceEvent) == mir_surface_focused; |
53 | // Mir may have sent a pair of focus lost/gained events, so we need to "peek" into the queue |
54 | // so that we don't deactivate windows prematurely. |
55 | @@ -245,6 +273,16 @@ |
56 | QWindowSystemInterface::handleWindowActivated(nullptr, Qt::ActiveWindowFocusReason); |
57 | QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationInactive); |
58 | } |
59 | + } else if (surfaceEventAttribute == mir_surface_attrib_state) { |
60 | + MirSurfaceState state = static_cast<MirSurfaceState>(mir_surface_event_get_attribute_value(surfaceEvent)); |
61 | + |
62 | + if (state == mir_surface_state_hidden) { |
63 | + ubuntuEvent->window->handleSurfaceVisibilityChanged(false); |
64 | + } else { |
65 | + // it's visible! |
66 | + ubuntuEvent->window->handleSurfaceVisibilityChanged(true); |
67 | + ubuntuEvent->window->handleSurfaceStateChanged(mirSurfaceStateToWindowState(state)); |
68 | + } |
69 | } |
70 | break; |
71 | } |
72 | |
73 | === modified file 'src/ubuntumirclient/window.cpp' |
74 | --- src/ubuntumirclient/window.cpp 2016-02-02 11:07:38 +0000 |
75 | +++ src/ubuntumirclient/window.cpp 2016-03-14 17:37:49 +0000 |
76 | @@ -36,6 +36,8 @@ |
77 | |
78 | Q_LOGGING_CATEGORY(ubuntumirclientBufferSwap, "ubuntumirclient.bufferSwap", QtWarningMsg) |
79 | |
80 | +const Qt::WindowType LowChromeWindowHint = (Qt::WindowType)0x00800000; |
81 | + |
82 | namespace |
83 | { |
84 | |
85 | @@ -65,23 +67,6 @@ |
86 | return reinterpret_cast<EGLNativeWindowType>(mir_buffer_stream_get_egl_native_window(stream)); |
87 | } |
88 | |
89 | -MirSurfaceState qtWindowStateToMirSurfaceState(Qt::WindowState state) |
90 | -{ |
91 | - switch (state) { |
92 | - case Qt::WindowNoState: |
93 | - return mir_surface_state_restored; |
94 | - case Qt::WindowFullScreen: |
95 | - return mir_surface_state_fullscreen; |
96 | - case Qt::WindowMaximized: |
97 | - return mir_surface_state_maximized; |
98 | - case Qt::WindowMinimized: |
99 | - return mir_surface_state_minimized; |
100 | - default: |
101 | - qCWarning(ubuntumirclient, "Unexpected Qt::WindowState: %d", state); |
102 | - return mir_surface_state_restored; |
103 | - } |
104 | -} |
105 | - |
106 | const char *qtWindowStateToStr(Qt::WindowState state) |
107 | { |
108 | switch (state) { |
109 | @@ -93,11 +78,45 @@ |
110 | return "Maximized"; |
111 | case Qt::WindowMinimized: |
112 | return "Minimized"; |
113 | + case Qt::WindowActive: |
114 | + return "Active"; |
115 | default: |
116 | return "!?"; |
117 | } |
118 | } |
119 | |
120 | +const char *mirSurfaceStateToStr(MirSurfaceState surfaceState) |
121 | +{ |
122 | + switch (surfaceState) { |
123 | + case mir_surface_state_unknown: return "unknown"; |
124 | + case mir_surface_state_restored: return "restored"; |
125 | + case mir_surface_state_minimized: return "minimized"; |
126 | + case mir_surface_state_maximized: return "vertmaximized"; |
127 | + case mir_surface_state_vertmaximized: return "vertmaximized"; |
128 | + case mir_surface_state_fullscreen: return "fullscreen"; |
129 | + case mir_surface_state_horizmaximized: return "horizmaximized"; |
130 | + case mir_surface_state_hidden: return "hidden"; |
131 | + default: return "!?"; |
132 | + } |
133 | +} |
134 | + |
135 | +MirSurfaceState qtWindowStateToMirSurfaceState(Qt::WindowState state) |
136 | +{ |
137 | + switch (state) { |
138 | + case Qt::WindowNoState: |
139 | + return mir_surface_state_restored; |
140 | + case Qt::WindowFullScreen: |
141 | + return mir_surface_state_fullscreen; |
142 | + case Qt::WindowMaximized: |
143 | + return mir_surface_state_maximized; |
144 | + case Qt::WindowMinimized: |
145 | + return mir_surface_state_minimized; |
146 | + default: |
147 | + qCWarning(ubuntumirclient, "Unexpected Qt::WindowState: %d", state); |
148 | + return mir_surface_state_restored; |
149 | + } |
150 | +} |
151 | + |
152 | WId makeId() |
153 | { |
154 | static int id = 1; |
155 | @@ -209,6 +228,10 @@ |
156 | mir_surface_spec_set_fullscreen_on_output(spec.get(), screen->mirOutputId()); |
157 | } |
158 | |
159 | + if (window->flags() & LowChromeWindowHint) { |
160 | + mir_surface_spec_set_shell_chrome(spec.get(), mir_shell_chrome_low); |
161 | + } |
162 | + |
163 | auto surface = mir_surface_create_sync(spec.get()); |
164 | Q_ASSERT(mir_surface_is_valid(surface)); |
165 | return surface; |
166 | @@ -244,11 +267,9 @@ |
167 | , mMirSurface(createMirSurface(mWindow, screen, input, connection)) |
168 | , mEglDisplay(screen->eglDisplay()) |
169 | , mEglSurface(eglCreateWindowSurface(mEglDisplay, screen->eglConfig(), nativeWindowFor(mMirSurface), nullptr)) |
170 | - , mVisible(false) |
171 | , mNeedsRepaint(false) |
172 | , mParented(mWindow->transientParent() || mWindow->parent()) |
173 | - , mWindowState(mWindow->windowState()) |
174 | - |
175 | + , mShellChrome(mWindow->flags() & LowChromeWindowHint ? mir_shell_chrome_low : mir_shell_chrome_normal) |
176 | { |
177 | mir_surface_set_event_handler(mMirSurface, surfaceEventCallback, this); |
178 | |
179 | @@ -260,7 +281,7 @@ |
180 | auto geom = mWindow->geometry(); |
181 | geom.setWidth(parameters.width); |
182 | geom.setHeight(parameters.height); |
183 | - if (mWindowState == Qt::WindowFullScreen) { |
184 | + if (mWindow->windowState() == Qt::WindowFullScreen) { |
185 | geom.setY(0); |
186 | } else { |
187 | geom.setY(panelHeight()); |
188 | @@ -287,8 +308,6 @@ |
189 | UbuntuSurface& operator=(UbuntuSurface const&) = delete; |
190 | |
191 | void resize(const QSize& newSize); |
192 | - void setState(Qt::WindowState newState); |
193 | - void setVisible(bool state); |
194 | void updateTitle(const QString& title); |
195 | void setSizingConstraints(const QSize& minSize, const QSize& maxSize, const QSize& increment); |
196 | |
197 | @@ -296,13 +315,22 @@ |
198 | void handleSurfaceResized(int width, int height); |
199 | int needsRepaint() const; |
200 | |
201 | + MirSurfaceState state() const { return mir_surface_get_state(mMirSurface); } |
202 | + void setState(MirSurfaceState state); |
203 | + |
204 | + MirSurfaceType type() const { return mir_surface_get_type(mMirSurface); } |
205 | + |
206 | + void setShellChrome(MirShellChrome shellChrome); |
207 | + |
208 | EGLSurface eglSurface() const { return mEglSurface; } |
209 | MirSurface *mirSurface() const { return mMirSurface; } |
210 | |
211 | + void setSurfaceParent(MirSurface*); |
212 | + bool hasParent() const { return mParented; } |
213 | + |
214 | private: |
215 | static void surfaceEventCallback(MirSurface* surface, const MirEvent *event, void* context); |
216 | void postEvent(const MirEvent *event); |
217 | - void updateSurface(); |
218 | |
219 | QWindow * const mWindow; |
220 | UbuntuWindow * const mPlatformWindow; |
221 | @@ -313,21 +341,20 @@ |
222 | const EGLDisplay mEglDisplay; |
223 | const EGLSurface mEglSurface; |
224 | |
225 | - bool mVisible; |
226 | bool mNeedsRepaint; |
227 | bool mParented; |
228 | - Qt::WindowState mWindowState; |
229 | QSize mBufferSize; |
230 | |
231 | QMutex mTargetSizeMutex; |
232 | QSize mTargetSize; |
233 | + MirShellChrome mShellChrome; |
234 | }; |
235 | |
236 | void UbuntuSurface::resize(const QSize& size) |
237 | { |
238 | qCDebug(ubuntumirclient,"resize(window=%p, width=%d, height=%d)", mWindow, size.width(), size.height()); |
239 | |
240 | - if (mWindowState == Qt::WindowFullScreen || mWindowState == Qt::WindowMaximized) { |
241 | + if (mWindow->windowState() == Qt::WindowFullScreen || mWindow->windowState() == Qt::WindowMaximized) { |
242 | qCDebug(ubuntumirclient, "resize(window=%p) - not resizing, window is maximized or fullscreen", mWindow); |
243 | return; |
244 | } |
245 | @@ -343,28 +370,6 @@ |
246 | mir_surface_apply_spec(mMirSurface, spec.get()); |
247 | } |
248 | |
249 | -void UbuntuSurface::setState(Qt::WindowState newState) |
250 | -{ |
251 | - mir_wait_for(mir_surface_set_state(mMirSurface, qtWindowStateToMirSurfaceState(newState))); |
252 | - mWindowState = newState; |
253 | -} |
254 | - |
255 | -void UbuntuSurface::setVisible(bool visible) |
256 | -{ |
257 | - if (mVisible == visible) |
258 | - return; |
259 | - |
260 | - mVisible = visible; |
261 | - |
262 | - if (mVisible) |
263 | - updateSurface(); |
264 | - |
265 | - // TODO: Use the new mir_surface_state_hidden state instead of mir_surface_state_minimized. |
266 | - // Will have to change qtmir and unity8 for that. |
267 | - const auto newState = visible ? qtWindowStateToMirSurfaceState(mWindowState) : mir_surface_state_minimized; |
268 | - mir_wait_for(mir_surface_set_state(mMirSurface, newState)); |
269 | -} |
270 | - |
271 | void UbuntuSurface::updateTitle(const QString& newTitle) |
272 | { |
273 | const auto title = newTitle.toUtf8(); |
274 | @@ -410,6 +415,22 @@ |
275 | return 0; |
276 | } |
277 | |
278 | +void UbuntuSurface::setState(MirSurfaceState state) |
279 | +{ |
280 | + mir_wait_for(mir_surface_set_state(mMirSurface, state)); |
281 | +} |
282 | + |
283 | +void UbuntuSurface::setShellChrome(MirShellChrome chrome) |
284 | +{ |
285 | + if (chrome != mShellChrome) { |
286 | + auto spec = Spec{mir_connection_create_spec_for_changes(mConnection)}; |
287 | + mir_surface_spec_set_shell_chrome(spec.get(), chrome); |
288 | + mir_surface_apply_spec(mMirSurface, spec.get()); |
289 | + |
290 | + mShellChrome = chrome; |
291 | + } |
292 | +} |
293 | + |
294 | void UbuntuSurface::onSwapBuffersDone() |
295 | { |
296 | static int sFrameNumber = 0; |
297 | @@ -470,22 +491,14 @@ |
298 | mInput->postEvent(mPlatformWindow, event); |
299 | } |
300 | |
301 | -void UbuntuSurface::updateSurface() |
302 | +void UbuntuSurface::setSurfaceParent(MirSurface* parent) |
303 | { |
304 | - qCDebug(ubuntumirclient, "updateSurface(window=%p)", mWindow); |
305 | + qCDebug(ubuntumirclient, "setSurfaceParent(window=%p)", mWindow); |
306 | |
307 | - if (!mParented && mWindow->type() == Qt::Dialog) { |
308 | - // The dialog may have been parented after creation time |
309 | - // so morph it into a modal dialog |
310 | - auto parent = transientParentFor(mWindow); |
311 | - if (parent) { |
312 | - qCDebug(ubuntumirclient, "updateSurface(window=%p) dialog now parented", mWindow); |
313 | - mParented = true; |
314 | - Spec spec{mir_connection_create_spec_for_changes(mConnection)}; |
315 | - mir_surface_spec_set_parent(spec.get(), parent->mirSurface()); |
316 | - mir_surface_apply_spec(mMirSurface, spec.get()); |
317 | - } |
318 | - } |
319 | + mParented = true; |
320 | + Spec spec{mir_connection_create_spec_for_changes(mConnection)}; |
321 | + mir_surface_spec_set_parent(spec.get(), parent); |
322 | + mir_surface_apply_spec(mMirSurface, spec.get()); |
323 | } |
324 | |
325 | UbuntuWindow::UbuntuWindow(QWindow *w, const QSharedPointer<UbuntuClipboard> &clipboard, UbuntuScreen *screen, |
326 | @@ -494,6 +507,9 @@ |
327 | , QPlatformWindow(w) |
328 | , mId(makeId()) |
329 | , mClipboard(clipboard) |
330 | + , mWindowState(w->windowState()) |
331 | + , mWindowFlags(w->flags()) |
332 | + , mWindowVisible(false) |
333 | , mSurface(new UbuntuSurface{this, screen, input, connection}) |
334 | { |
335 | qCDebug(ubuntumirclient, "UbuntuWindow(window=%p, screen=%p, input=%p, surf=%p)", w, screen, input, mSurface.get()); |
336 | @@ -517,6 +533,7 @@ |
337 | // updated size but it still needs re-rendering so another redraw may be needed. |
338 | // A mir API to drop the currently held buffer would help here, so that we wouldn't have to redraw twice |
339 | auto const numRepaints = mSurface->needsRepaint(); |
340 | + lock.unlock(); |
341 | qCDebug(ubuntumirclient, "handleSurfaceResize(window=%p) redraw %d times", window(), numRepaints); |
342 | for (int i = 0; i < numRepaints; i++) { |
343 | qCDebug(ubuntumirclient, "handleSurfaceResize(window=%p) repainting width=%d, height=%d", window(), geometry().size().width(), geometry().size().height()); |
344 | @@ -537,13 +554,47 @@ |
345 | mClipboard->requestDBusClipboardContents(); |
346 | } |
347 | |
348 | +void UbuntuWindow::handleSurfaceVisibilityChanged(bool visible) |
349 | +{ |
350 | + qCDebug(ubuntumirclient, "handleSurfaceFocused(window=%p)", window()); |
351 | + |
352 | + if (mWindowVisible == visible) return; |
353 | + mWindowVisible = visible; |
354 | + |
355 | + QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size())); |
356 | +} |
357 | + |
358 | +void UbuntuWindow::handleSurfaceStateChanged(Qt::WindowState state) |
359 | +{ |
360 | + qCDebug(ubuntumirclient, "handleSurfaceStateChanged(window=%p, %s)", window(), qtWindowStateToStr(state)); |
361 | + |
362 | + if (mWindowState == state) return; |
363 | + mWindowState = state; |
364 | + |
365 | + QWindowSystemInterface::handleWindowStateChanged(window(), state); |
366 | +} |
367 | + |
368 | void UbuntuWindow::setWindowState(Qt::WindowState state) |
369 | { |
370 | QMutexLocker lock(&mMutex); |
371 | qCDebug(ubuntumirclient, "setWindowState(window=%p, %s)", this, qtWindowStateToStr(state)); |
372 | - mSurface->setState(state); |
373 | - |
374 | - updatePanelHeightHack(state); |
375 | + |
376 | + if (mWindowState == state) return; |
377 | + mWindowState = state; |
378 | + |
379 | + lock.unlock(); |
380 | + updateSurfaceState(); |
381 | +} |
382 | + |
383 | +void UbuntuWindow::setWindowFlags(Qt::WindowFlags flags) |
384 | +{ |
385 | + QMutexLocker lock(&mMutex); |
386 | + qCDebug(ubuntumirclient, "setWindowFlags(window=%p, 0x%x)", this, (int)flags); |
387 | + |
388 | + if (mWindowFlags == flags) return; |
389 | + mWindowFlags = flags; |
390 | + |
391 | + mSurface->setShellChrome(mWindowFlags & LowChromeWindowHint ? mir_shell_chrome_low : mir_shell_chrome_normal); |
392 | } |
393 | |
394 | /* |
395 | @@ -552,16 +603,19 @@ |
396 | window is always on the top-left corner, right below the indicators panel if not |
397 | in fullscreen. |
398 | */ |
399 | -void UbuntuWindow::updatePanelHeightHack(Qt::WindowState state) |
400 | +void UbuntuWindow::enablePanelHeightHack(bool enable) |
401 | { |
402 | - if (state == Qt::WindowFullScreen && geometry().y() != 0) { |
403 | - QRect newGeometry = geometry(); |
404 | + QMutexLocker lock(&mMutex); |
405 | + |
406 | + QRect newGeometry = geometry(); |
407 | + if (enable) { |
408 | + newGeometry.setY(panelHeight()); |
409 | + } else { |
410 | newGeometry.setY(0); |
411 | - QPlatformWindow::setGeometry(newGeometry); |
412 | - QWindowSystemInterface::handleGeometryChange(window(), newGeometry); |
413 | - } else if (geometry().y() == 0) { |
414 | - QRect newGeometry = geometry(); |
415 | - newGeometry.setY(panelHeight()); |
416 | + } |
417 | + |
418 | + if (newGeometry != geometry()) { |
419 | + lock.unlock(); |
420 | QPlatformWindow::setGeometry(newGeometry); |
421 | QWindowSystemInterface::handleGeometryChange(window(), newGeometry); |
422 | } |
423 | @@ -587,11 +641,23 @@ |
424 | QMutexLocker lock(&mMutex); |
425 | qCDebug(ubuntumirclient, "setVisible (window=%p, visible=%s)", window(), visible ? "true" : "false"); |
426 | |
427 | - mSurface->setVisible(visible); |
428 | - const QRect& exposeRect = visible ? QRect(QPoint(), geometry().size()) : QRect(); |
429 | + if (mWindowVisible == visible) return; |
430 | + mWindowVisible = visible; |
431 | + |
432 | + if (visible) { |
433 | + if (!mSurface->hasParent() && window()->type() == Qt::Dialog) { |
434 | + // The dialog may have been parented after creation time |
435 | + // so morph it into a modal dialog |
436 | + auto parent = transientParentFor(window()); |
437 | + if (parent) { |
438 | + mSurface->setSurfaceParent(parent->mirSurface()); |
439 | + } |
440 | + } |
441 | + } |
442 | |
443 | lock.unlock(); |
444 | - QWindowSystemInterface::handleExposeEvent(window(), exposeRect); |
445 | + updateSurfaceState(); |
446 | + QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size())); |
447 | QWindowSystemInterface::flushWindowSystemEvents(); |
448 | } |
449 | |
450 | @@ -613,6 +679,11 @@ |
451 | mSurface->setSizingConstraints(win->minimumSize(), win->maximumSize(), win->sizeIncrement()); |
452 | } |
453 | |
454 | +bool UbuntuWindow::isExposed() const |
455 | +{ |
456 | + return mWindowVisible; |
457 | +} |
458 | + |
459 | void* UbuntuWindow::eglSurface() const |
460 | { |
461 | return mSurface->eglSurface(); |
462 | @@ -633,3 +704,17 @@ |
463 | QMutexLocker lock(&mMutex); |
464 | mSurface->onSwapBuffersDone(); |
465 | } |
466 | + |
467 | +void UbuntuWindow::updateSurfaceState() |
468 | +{ |
469 | + QMutexLocker lock(&mMutex); |
470 | + MirSurfaceState newState = mWindowVisible ? qtWindowStateToMirSurfaceState(mWindowState) : |
471 | + mir_surface_state_hidden; |
472 | + qCDebug(ubuntumirclient, "updateSurfaceState (window=%p, surfaceState=%s)", window(), mirSurfaceStateToStr(newState)); |
473 | + if (newState != mSurface->state()) { |
474 | + mSurface->setState(newState); |
475 | + |
476 | + lock.unlock(); |
477 | + enablePanelHeightHack(newState != mir_surface_state_fullscreen); |
478 | + } |
479 | +} |
480 | |
481 | === modified file 'src/ubuntumirclient/window.h' |
482 | --- src/ubuntumirclient/window.h 2015-12-16 17:55:47 +0000 |
483 | +++ src/ubuntumirclient/window.h 2016-03-14 17:37:49 +0000 |
484 | @@ -43,22 +43,32 @@ |
485 | WId winId() const override; |
486 | void setGeometry(const QRect&) override; |
487 | void setWindowState(Qt::WindowState state) override; |
488 | + void setWindowFlags(Qt::WindowFlags flags) override; |
489 | void setVisible(bool visible) override; |
490 | void setWindowTitle(const QString &title) override; |
491 | void propagateSizeHints() override; |
492 | + bool isExposed() const override; |
493 | |
494 | // New methods. |
495 | void *eglSurface() const; |
496 | MirSurface *mirSurface() const; |
497 | void handleSurfaceResized(int width, int height); |
498 | void handleSurfaceFocused(); |
499 | + void handleSurfaceVisibilityChanged(bool visible); |
500 | + void handleSurfaceStateChanged(Qt::WindowState state); |
501 | void onSwapBuffersDone(); |
502 | |
503 | private: |
504 | - void updatePanelHeightHack(Qt::WindowState); |
505 | + void enablePanelHeightHack(bool enable); |
506 | + void updateSurfaceState(); |
507 | + |
508 | mutable QMutex mMutex; |
509 | const WId mId; |
510 | const QSharedPointer<UbuntuClipboard> mClipboard; |
511 | + Qt::WindowState mWindowState; |
512 | + Qt::WindowFlags mWindowFlags; |
513 | + bool mWindowVisible; |
514 | + |
515 | std::unique_ptr<UbuntuSurface> mSurface; |
516 | }; |
517 |
FAILED: Continuous integration, rev:311 /unity8- jenkins. ubuntu. com/job/ lp-qtubuntu- 1-ci/14/ /unity8- jenkins. ubuntu. com/job/ build/542/ console /unity8- jenkins. ubuntu. com/job/ build-0- fetch/565 /unity8- jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= vivid+overlay/ 583 /unity8- jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= xenial/ 583 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= vivid+overlay/ 579/console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= xenial/ 579 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= xenial/ 579/artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= vivid+overlay/ 579/console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= xenial/ 579 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= xenial/ 579/artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= vivid+overlay/ 579/console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= xenial/ 579 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= xenial/ 579/artifact/ output/ *zip*/output. zip
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild: /unity8- jenkins. ubuntu. com/job/ lp-qtubuntu- 1-ci/14/ rebuild
https:/