on xenial help sign in
Ensure the greeter password field is not covered by the keyboard
b162133Daniel d'Andrada
qml/Greeter/Greeter.qml+8
@@ -30,6 +30,9 @@ Showable {
30
30
31 property url background
31 property url background
32
32
33+ // so that it can be replaced in tests with a mock object
34+ property var inputMethod: Qt.inputMethod
35+
33 prepareToHide: function () {
36 prepareToHide: function () {
34 hideTranslation.to = greeter.x > 0 || d.forceRightOnNextHideAnimation ? greeter.width : -greeter.width;
37 hideTranslation.to = greeter.x > 0 || d.forceRightOnNextHideAnimation ? greeter.width : -greeter.width;
35 d.forceRightOnNextHideAnimation = false;
38 d.forceRightOnNextHideAnimation = false;
@@ -102,6 +105,11 @@ Showable {
102 }
105 }
103 onUnlocked: greeter.unlocked(uid);
106 onUnlocked: greeter.unlocked(uid);
104 }
107 }
108+ Binding {
109+ target: greeterContentLoader.item
110+ property: "inputMethod"
111+ value: greeter.inputMethod
112+ }
105 }
113 }
106
114
107 DragHandle {
115 DragHandle {
qml/Greeter/GreeterContent.qml+6−2
@@ -24,6 +24,8 @@ Item {
24 id: root
24 id: root
25 anchors.fill: parent
25 anchors.fill: parent
26
26
27+ property var inputMethod
28+
27 property bool ready: background.source == "" || background.status == Image.Ready || background.status == Image.Error
29 property bool ready: background.source == "" || background.status == Image.Ready || background.status == Image.Error
28
30
29 signal selected(int uid)
31 signal selected(int uid)
@@ -74,10 +76,12 @@ Item {
74 anchors {
76 anchors {
75 left: parent.left
77 left: parent.left
76 leftMargin: Math.min(parent.width * 0.16, units.gu(20))
78 leftMargin: Math.min(parent.width * 0.16, units.gu(20))
77− verticalCenter: parent.verticalCenter
79+ top: parent.top
78 }
80 }
79 width: units.gu(29)
81 width: units.gu(29)
80− height: parent.height
82+ height: inputMethod && inputMethod.visible ? parent.height - inputMethod.keyboardRectangle.height
83+ : parent.height
84+ Behavior on height { UbuntuNumberAnimation {} }
81
85
82 // TODO: Once we have a system API for determining which mode we are
86 // TODO: Once we have a system API for determining which mode we are
83 // in, tablet/phone/desktop, that should be used instead of narrowMode.
87 // in, tablet/phone/desktop, that should be used instead of narrowMode.
tests/qmltests/Greeter/tst_MultiGreeter.qml+80−2
@@ -15,6 +15,7 @@
15 */
15 */
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18+import QtQuick.Layouts 1.1
18import QtTest 1.0
19import QtTest 1.0
19import ".."
20import ".."
20import "../../../qml/Greeter"
21import "../../../qml/Greeter"
@@ -23,9 +24,21 @@ import LightDM 0.1 as LightDM
23import Unity.Test 0.1 as UT
24import Unity.Test 0.1 as UT
24
25
25Item {
26Item {
27+ id: root
26− width: units.gu(120)
28+ width: units.gu(140)
27 height: units.gu(80)
29 height: units.gu(80)
28
30
31+ QtObject {
32+ id: fakeInputMethod
33+ property bool visible: fakeKeyboard.visible
34+ property var keyboardRectangle: QtObject {
35+ property real x: fakeKeyboard.x
36+ property real y: fakeKeyboard.y
37+ property real width: fakeKeyboard.width
38+ property real height: fakeKeyboard.height
39+ }
40+ }
41+
29 Binding {
42 Binding {
30 target: LightDM.Greeter
43 target: LightDM.Greeter
31 property: "mockMode"
44 property: "mockMode"
@@ -39,7 +52,9 @@ Item {
39
52
40 Greeter {
53 Greeter {
41 id: greeter
54 id: greeter
42− anchors.fill: parent
55+ width: units.gu(120)
56+ height: root.height
57+ inputMethod: fakeInputMethod
43 locked: !LightDM.Greeter.authenticated
58 locked: !LightDM.Greeter.authenticated
44 }
59 }
45
60
@@ -54,6 +69,44 @@ Item {
54 }
69 }
55 }
70 }
56
71
72+ Rectangle {
73+ id: fakeKeyboard
74+ color: "green"
75+ opacity: 0.7
76+ anchors.bottom: root.bottom
77+ width: greeter.width
78+ height: greeter.height * 0.6
79+ visible: keyboardVisibleCheckbox.checked
80+ Text {
81+ text: "Keyboard Rectangle"
82+ color: "yellow"
83+ font.bold: true
84+ fontSizeMode: Text.Fit
85+ minimumPixelSize: 10; font.pixelSize: 200
86+ verticalAlignment: Text.AlignVCenter
87+ x: (parent.width - width) / 2
88+ y: (parent.height - height) / 2
89+ width: parent.width
90+ height: parent.height
91+ }
92+ }
93+
94+ Item {
95+ anchors {
96+ top: root.top
97+ bottom: root.bottom
98+ left: greeter.right
99+ right: root.right
100+ }
101+ RowLayout {
102+ Layout.fillWidth: true
103+ CheckBox {
104+ id: keyboardVisibleCheckbox
105+ }
106+ Label { text: "Keyboard Visible"; anchors.verticalCenter: parent.verticalCenter }
107+ }
108+ }
109+
57 SignalSpy {
110 SignalSpy {
58 id: unlockSpy
111 id: unlockSpy
59 target: greeter
112 target: greeter
@@ -76,6 +129,10 @@ Item {
76 name: "MultiGreeter"
129 name: "MultiGreeter"
77 when: windowShown
130 when: windowShown
78
131
132+ function cleanup() {
133+ keyboardVisibleCheckbox.checked = false;
134+ }
135+
79 function select_index(i) {
136 function select_index(i) {
80 // We could be anywhere in list; find target index to know which direction
137 // We could be anywhere in list; find target index to know which direction
81 var userlist = findChild(greeter, "userList")
138 var userlist = findChild(greeter, "userList")
@@ -393,5 +450,26 @@ Item {
393 tryCompare(spy, "count", 1)
450 tryCompare(spy, "count", 1)
394 greeterObj.destroy()
451 greeterObj.destroy()
395 }
452 }
453+
454+ function test_login_list_not_covered_by_keyboard() {
455+ var loginList = findChild(greeter, "loginLoader").item;
456+ compare(loginList.height, greeter.height);
457+
458+ // when the vkb shows up, loginList is moved up to remain fully uncovered
459+
460+ keyboardVisibleCheckbox.checked = true;
461+
462+ tryCompare(loginList, "height", greeter.height - fakeInputMethod.keyboardRectangle.height);
463+ tryCompareFunction( function() {
464+ var loginListRect = loginList.mapToItem(greeter, 0, 0, loginList.width, loginList.height);
465+ return loginListRect.y + loginListRect.height <= fakeInputMethod.keyboardRectangle.y;
466+ }, true);
467+
468+ // once the vkb goes away, loginList goes back to its full height
469+
470+ keyboardVisibleCheckbox.checked = false;
471+
472+ tryCompare(loginList, "height", greeter.height);
473+ }
396 }
474 }
397}
475}