on xenial help sign in
displace application windows when the OSK would cover them
commit4dd864f68eea262d14c3e7ef7f9425fa1e8ae99a authorMichael Zanetti <michael.zanetti@canonical.com> dateMon 27 Jun 2016, 18:44 (10 years ago) parent40aec9c17ffa97
7 files changed+96−52
qml/Stages/DesktopStage.qml+17−2 qml/Stages/WindowControlsOverlay.qml+2−2 qml/Stages/WindowDecoration.qml+2−2 qml/Stages/WindowResizeArea.qml+11−11 tests/mocks/Unity/Application/UbuntuKeyboardInfo.cpp+1−1 tests/qmltests/Stages/tst_DesktopStage.qml+27 tests/qmltests/Stages/tst_WindowResizeArea.qml+36−34
qml/Stages/DesktopStage.qml+17−2
@@ -263,8 +263,23 @@ AbstractStage {
263263 }
264264 }
265265 z: normalZ
266− x: priv.focusedAppDelegate ? priv.focusedAppDelegate.x + units.gu(3) : (normalZ - 1) * units.gu(3)
267− y: priv.focusedAppDelegate ? priv.focusedAppDelegate.y + units.gu(3) : normalZ * units.gu(3)
266+ x: requestedX // may be overridden in some states. Do not directly write to this.
267+ y: requestedY // may be overridden in some states. Do not directly write to this.
268+ property real requestedX: priv.focusedAppDelegate ? priv.focusedAppDelegate.x + units.gu(3) : (normalZ - 1) * units.gu(3)
269+ property real requestedY: priv.focusedAppDelegate ? priv.focusedAppDelegate.y + units.gu(3) : normalZ * units.gu(3)
270+
271+ Binding {
272+ target: appDelegate
273+ property: "y"
274+ value: appDelegate.requestedY -
275+ Math.min(appDelegate.requestedY - PanelState.panelHeight,
276+ Math.max(0, UbuntuKeyboardInfo.height - (appContainer.height - (appDelegate.requestedY + appDelegate.height))))
277+ when: appDelegate.focus && appDelegate.state == "normal"
278+ && SurfaceManager.inputMethodSurface
279+ && SurfaceManager.inputMethodSurface.state != Mir.HiddenState
280+ && SurfaceManager.inputMethodSurface.state != Mir.MinimizedState
281+
282+ }
268283
269284 width: decoratedWindow.width
270285 height: decoratedWindow.height
qml/Stages/WindowControlsOverlay.qml+2−2
@@ -94,8 +94,8 @@ Item {
9494 function handlePositionChanged(mouseX, mouseY) {
9595 if (priv.dragging) {
9696 var pos = mapToItem(root.target.parent, mouseX, mouseY);
97− root.target.x = Math.round(pos.x - priv.distanceX);
98− root.target.y = Math.round(Math.max(pos.y - priv.distanceY, PanelState.panelHeight));
97+ root.target.requestedX = Math.round(pos.x - priv.distanceX);
98+ root.target.requestedY = Math.round(Math.max(pos.y - priv.distanceY, PanelState.panelHeight));
9999 }
100100 }
101101 }
qml/Stages/WindowDecoration.qml+2−2
@@ -69,8 +69,8 @@ MouseArea {
6969 // Use integer coordinate values to ensure that target is left in a pixel-aligned
7070 // position. Mouse movement could have subpixel precision, yielding a fractional
7171 // mouse position.
72− root.target.x = Math.round(pos.x - priv.distanceX);
73− root.target.y = Math.round(Math.max(pos.y - priv.distanceY, PanelState.panelHeight));
72+ root.target.requestedX = Math.round(pos.x - priv.distanceX);
73+ root.target.requestedY = Math.round(Math.max(pos.y - priv.distanceY, PanelState.panelHeight));
7474 }
7575 }
7676
qml/Stages/WindowResizeArea.qml+11−11
@@ -55,8 +55,8 @@ MouseArea {
5555
5656 function updateNormalGeometry() {
5757 if (root.target.state == "normal") {
58− normalX = root.target.x
59− normalY = root.target.y
58+ normalX = root.target.requestedX
59+ normalY = root.target.requestedY
6060 normalWidth = root.target.width
6161 normalHeight = root.target.height
6262 }
@@ -73,14 +73,14 @@ MouseArea {
7373
7474 function loadWindowState() {
7575 var windowGeometry = windowStateStorage.getGeometry(root.windowId,
76− Qt.rect(target.x, target.y, defaultWidth, defaultHeight));
76+ Qt.rect(target.requestedX, target.requestedY, defaultWidth, defaultHeight));
7777
7878 target.requestedWidth = Qt.binding(function() { return Math.min(Math.max(windowGeometry.width, d.minimumWidth), screenWidth - root.leftMargin); });
7979 target.requestedHeight = Qt.binding(function() { return Math.min(Math.max(windowGeometry.height, d.minimumHeight),
8080 root.screenHeight - (target.fullscreen ? 0 : PanelState.panelHeight)); });
81− target.x = Qt.binding(function() { return Math.max(Math.min(windowGeometry.x, root.screenWidth - root.leftMargin - target.requestedWidth),
81+ target.requestedX = Qt.binding(function() { return Math.max(Math.min(windowGeometry.x, root.screenWidth - root.leftMargin - target.requestedWidth),
8282 (target.fullscreen ? 0 : root.leftMargin)); });
83− target.y = Qt.binding(function() { return Math.max(Math.min(windowGeometry.y, root.screenHeight - target.requestedHeight), PanelState.panelHeight); });
83+ target.requestedY = Qt.binding(function() { return Math.max(Math.min(windowGeometry.y, root.screenHeight - target.requestedHeight), PanelState.panelHeight); });
8484
8585 var windowState = windowStateStorage.getState(root.windowId, WindowStateStorage.WindowStateNormal)
8686 switch (windowState) {
@@ -258,8 +258,8 @@ MouseArea {
258258 var pos = mapToItem(root.target.parent, mouseX, mouseY);
259259 d.startMousePosX = pos.x;
260260 d.startMousePosY = pos.y;
261− d.startX = target.x;
262− d.startY = target.y;
261+ d.startX = target.requestedX;
262+ d.startY = target.requestedY;
263263 d.startWidth = target.width;
264264 d.startHeight = target.height;
265265 d.currentWidth = target.width;
@@ -296,7 +296,7 @@ MouseArea {
296296
297297 if (d.leftBorder) {
298298 var newTargetX = d.startX + deltaX;
299− var rightBorderX = target.x + target.width;
299+ var rightBorderX = target.requestedX + target.width;
300300 if (rightBorderX > newTargetX + d.minimumWidth) {
301301 if (rightBorderX < newTargetX + d.maximumWidth) {
302302 target.requestedWidth = rightBorderX - newTargetX;
@@ -322,7 +322,7 @@ MouseArea {
322322
323323 if (d.topBorder) {
324324 var newTargetY = Math.max(d.startY + deltaY, PanelState.panelHeight); // disallow resizing up past Panel
325− var bottomBorderY = target.y + target.height;
325+ var bottomBorderY = target.requestedY + target.height;
326326 if (bottomBorderY > newTargetY + d.minimumHeight) {
327327 if (bottomBorderY < newTargetY + d.maximumHeight) {
328328 target.requestedHeight = bottomBorderY - newTargetY;
@@ -351,13 +351,13 @@ MouseArea {
351351 target: root.target
352352 onWidthChanged: {
353353 if (d.moveLeftBorder) {
354− target.x += d.currentWidth - target.width;
354+ target.requestedX += d.currentWidth - target.width;
355355 }
356356 d.currentWidth = target.width;
357357 }
358358 onHeightChanged: {
359359 if (d.moveTopBorder) {
360− target.y += d.currentHeight - target.height;
360+ target.requestedY += d.currentHeight - target.height;
361361 }
362362 d.currentHeight = target.height;
363363 }
tests/mocks/Unity/Application/UbuntuKeyboardInfo.cpp+1−1
@@ -21,7 +21,7 @@ UbuntuKeyboardInfo::UbuntuKeyboardInfo(QObject *parent)
2121 m_x(0),
2222 m_y(0),
2323 m_width(200),
24− m_height(200)
24+ m_height(0)
2525{
2626}
2727
tests/qmltests/Stages/tst_DesktopStage.qml+27
@@ -517,6 +517,33 @@ Item {
517517 tryCompare(MirFocusController, "focusedSurface", null); // verify still no surface is focused
518518 }
519519
520+ function test_oskDisplacesWindow_data() {
521+ return [
522+ {tag: "no need to displace", windowHeight: units.gu(10), windowY: units.gu(5), targetDisplacement: units.gu(5)},
523+ {tag: "displace to top", windowHeight: units.gu(50), windowY: units.gu(10), targetDisplacement: PanelState.panelHeight},
524+ {tag: "displace a bit", windowHeight: units.gu(40), windowY: units.gu(10), targetDisplacement: (root.height / 2) - units.gu(40)},
525+ ]
526+ }
527+
528+ function test_oskDisplacesWindow(data) {
529+ var dashAppDelegate = startApplication("unity8-dash");
530+ var oldOSKState = SurfaceManager.inputMethodSurface.state;
531+ SurfaceManager.inputMethodSurface.state = Mir.RestoredState;
532+ verify(dashAppDelegate);
533+ dashAppDelegate.requestedHeight = data.windowHeight;
534+ dashAppDelegate.requestedY = data.windowY;
535+ UbuntuKeyboardInfo.height = 0;
536+ var initialY = dashAppDelegate.y;
537+ verify(initialY > PanelState.panelHeight);
538+
539+ UbuntuKeyboardInfo.height = root.height / 2;
540+ tryCompare(dashAppDelegate, "y", data.targetDisplacement);
541+
542+ UbuntuKeyboardInfo.height = 0;
543+ tryCompare(dashAppDelegate, "y", initialY);
544+ SurfaceManager.inputMethodSurface.state = oldOSKState;
545+ }
546+
520547 function test_minimizeApplicationHidesSurface() {
521548 compare(topSurfaceList.applicationAt(0).appId, "unity8-dash");
522549 var dashSurface = topSurfaceList.surfaceAt(0);
tests/qmltests/Stages/tst_WindowResizeArea.qml+36−34
@@ -44,8 +44,10 @@ Item {
4444 id: fakeWindow
4545 property alias resizeAreaMinWidth: windowResizeArea.minWidth
4646 property alias resizeAreaMinHeight: windowResizeArea.minHeight
47− x: units.gu(20)
48− y: units.gu(20)
47+ x: requestedX
48+ y: requestedY
49+ property real requestedX: units.gu(20)
50+ property real requestedY: units.gu(20)
4951 width: requestedWidth
5052 height: requestedHeight
5153 property real requestedWidth
@@ -226,8 +228,8 @@ Item {
226228 property var fakeWindow: windowLoader.item
227229
228230 function init() {
229− fakeWindow.x = units.gu(20)
230− fakeWindow.y = units.gu(20)
231+ fakeWindow.requestedX = units.gu(20)
232+ fakeWindow.requestedY = units.gu(20)
231233 fakeWindow.requestedWidth = units.gu(20)
232234 fakeWindow.requestedHeight = units.gu(20)
233235 fakeWindow.resizeAreaMinWidth = units.gu(15);
@@ -254,8 +256,8 @@ Item {
254256 }
255257
256258 function test_resizeWindowRightBottom(data) {
257− var initialWindowX = fakeWindow.x;
258− var initialWindowY = fakeWindow.y;
259+ var initialWindowX = fakeWindow.requestedX;
260+ var initialWindowY = fakeWindow.requestedY;
259261 var initialWindowWidth = fakeWindow.width
260262 var initialWindowHeight = fakeWindow.height
261263
@@ -266,8 +268,8 @@ Item {
266268 tryCompare(fakeWindow, "width", Math.max(initialWindowWidth + data.dx, fakeWindow.resizeAreaMinWidth));
267269 tryCompare(fakeWindow, "height", Math.max(initialWindowHeight + data.dy, fakeWindow.resizeAreaMinHeight));
268270
269− compare(fakeWindow.x, initialWindowX);
270− compare(fakeWindow.y, initialWindowY);
271+ compare(fakeWindow.requestedX, initialWindowX);
272+ compare(fakeWindow.requestedY, initialWindowY);
271273 }
272274
273275 function test_resizeWindowLeftTop_data() {
@@ -280,8 +282,8 @@ Item {
280282 }
281283
282284 function test_resizeWindowLeftTop(data) {
283− var initialWindowX = fakeWindow.x;
284− var initialWindowY = fakeWindow.y;
285+ var initialWindowX = fakeWindow.requestedX;
286+ var initialWindowY = fakeWindow.requestedY;
285287 var initialWindowWidth = fakeWindow.width
286288 var initialWindowHeight = fakeWindow.height
287289
@@ -294,13 +296,13 @@ Item {
294296
295297 var maxMoveX = initialWindowWidth - fakeWindow.resizeAreaMinWidth;
296298 var maxMoveY = initialWindowHeight - fakeWindow.resizeAreaMinHeight;
297− compare(fakeWindow.x, Math.min(initialWindowX + data.dx, initialWindowX + maxMoveX));
298− compare(fakeWindow.y, Math.min(initialWindowY + data.dy, initialWindowY + maxMoveY));
299+ compare(fakeWindow.requestedX, Math.min(initialWindowX + data.dx, initialWindowX + maxMoveX));
300+ compare(fakeWindow.requestedY, Math.min(initialWindowY + data.dy, initialWindowY + maxMoveY));
299301 }
300302
301303 function test_saveRestoreSize() {
302− var initialWindowX = fakeWindow.x;
303− var initialWindowY = fakeWindow.y;
304+ var initialWindowX = fakeWindow.requestedX;
305+ var initialWindowY = fakeWindow.requestedY;
304306 var initialWindowWidth = fakeWindow.width
305307 var initialWindowHeight = fakeWindow.height
306308
@@ -332,8 +334,8 @@ Item {
332334 }
333335
334336 function test_resizeSmallerAndLarger(data) {
335− var initialWindowX = fakeWindow.x;
336− var initialWindowY = fakeWindow.y;
337+ var initialWindowX = fakeWindow.requestedX;
338+ var initialWindowY = fakeWindow.requestedY;
337339 var initialWindowWidth = fakeWindow.width
338340 var initialWindowHeight = fakeWindow.height
339341
@@ -348,18 +350,18 @@ Item {
348350 }
349351
350352 function test_saveRestoreMaximized() {
351− var initialWindowX = fakeWindow.x;
352− var initialWindowY = fakeWindow.y;
353+ var initialWindowX = fakeWindow.requestedX;
354+ var initialWindowY = fakeWindow.requestedY;
353355
354356 var moveDelta = units.gu(5);
355357
356− fakeWindow.x = initialWindowX + moveDelta
357− fakeWindow.y = initialWindowY + moveDelta
358+ fakeWindow.requestedX = initialWindowX + moveDelta
359+ fakeWindow.requestedY = initialWindowY + moveDelta
358360
359361 // Now change the state to maximized. The window should not keep updating the stored values
360362 fakeWindow.maximize()
361− fakeWindow.x = 31415 // 0 is too risky to pass the test even when broken
362− fakeWindow.y = 31415
363+ fakeWindow.requestedX = 31415 // 0 is too risky to pass the test even when broken
364+ fakeWindow.requestedY = 31415
363365
364366 // This will destroy the window and recreate it
365367 windowLoader.active = false;
@@ -389,8 +391,8 @@ Item {
389391 }
390392
391393 function test_restoreMovesIntoBounds(data) {
392− fakeWindow.x = data.x;
393− fakeWindow.y = data.y;
394+ fakeWindow.requestedX = data.x;
395+ fakeWindow.requestedY = data.y;
394396 fakeWindow.width = data.w;
395397 fakeWindow.height = data.h;
396398 waitForRendering(root);
@@ -402,10 +404,10 @@ Item {
402404 waitForRendering(root)
403405
404406 // Make sure it's again where we left it in normal state before destroying
405− compare(fakeWindow.x >= 0, true)
406− compare(fakeWindow.y >= PanelState.panelHeight, true)
407− compare(fakeWindow.x + fakeWindow.width <= root.width, true)
408− compare(fakeWindow.y + fakeWindow.height <= root.height, true)
407+ compare(fakeWindow.requestedX >= 0, true)
408+ compare(fakeWindow.requestedY >= PanelState.panelHeight, true)
409+ compare(fakeWindow.requestedX + fakeWindow.width <= root.width, true)
410+ compare(fakeWindow.requestedY + fakeWindow.height <= root.height, true)
409411
410412 waitForRendering(root)
411413 }
@@ -417,8 +419,8 @@ Item {
417419 and height) increment value.
418420 */
419421 function test_sizeIncrement() {
420− var initialWindowX = fakeWindow.x;
421− var initialWindowY = fakeWindow.y;
422+ var initialWindowX = fakeWindow.requestedX;
423+ var initialWindowY = fakeWindow.requestedY;
422424 var initialWindowWidth = fakeWindow.width
423425 var initialWindowHeight = fakeWindow.height
424426
@@ -448,8 +450,8 @@ Item {
448450 Tests that when dragging a window border you cannot make it bigger than its maximum size
449451 */
450452 function test_maximumSize() {
451− fakeWindow.x = units.gu(1);
452− fakeWindow.y = units.gu(1);
453+ fakeWindow.requestedX = units.gu(1);
454+ fakeWindow.requestedY = units.gu(1);
453455 fakeWindow.resizeAreaMinWidth = 1; // so it does not interfere with anything
454456 fakeWindow.resizeAreaMinHeight = 1; // so it does not interfere with anything
455457 fakeWindow.requestedWidth = units.gu(10);
@@ -478,8 +480,8 @@ Item {
478480 Tests that when dragging a window border you cannot make it smaller than its minimum size
479481 */
480482 function test_minimumSize() {
481− fakeWindow.x = units.gu(1);
482− fakeWindow.y = units.gu(1);
483+ fakeWindow.requestedX = units.gu(1);
484+ fakeWindow.requestedY = units.gu(1);
483485 fakeWindow.resizeAreaMinWidth = 1; // so it does not interfere with anything
484486 fakeWindow.resizeAreaMinHeight = 1; // so it does not interfere with anything
485487 fakeWindow.requestedWidth = units.gu(20);