Changeset View
Changeset View
Standalone View
Standalone View
lookandfeel/contents/lockscreen/LockScreenUi.qml
Show All 22 Lines | |||||
23 | 23 | | |||
24 | import org.kde.plasma.core 2.0 as PlasmaCore | 24 | import org.kde.plasma.core 2.0 as PlasmaCore | ||
25 | import org.kde.plasma.components 2.0 as PlasmaComponents | 25 | import org.kde.plasma.components 2.0 as PlasmaComponents | ||
26 | 26 | | |||
27 | import org.kde.plasma.private.sessions 2.0 | 27 | import org.kde.plasma.private.sessions 2.0 | ||
28 | import "../components" | 28 | import "../components" | ||
29 | 29 | | |||
30 | PlasmaCore.ColorScope { | 30 | PlasmaCore.ColorScope { | ||
31 | id: lockScreenRoot | | |||
32 | 31 | | |||
33 | colorGroup: PlasmaCore.Theme.ComplementaryColorGroup | 32 | colorGroup: PlasmaCore.Theme.ComplementaryColorGroup | ||
34 | 33 | | |||
35 | Connections { | 34 | Connections { | ||
36 | target: authenticator | 35 | target: authenticator | ||
37 | onFailed: { | 36 | onFailed: { | ||
38 | root.notification = i18nd("plasma_lookandfeel_org.kde.lookandfeel","Unlocking failed"); | 37 | root.notification = i18nd("plasma_lookandfeel_org.kde.lookandfeel","Unlocking failed"); | ||
39 | } | 38 | } | ||
Show All 24 Lines | |||||
64 | 63 | | |||
65 | Loader { | 64 | Loader { | ||
66 | id: changeSessionComponent | 65 | id: changeSessionComponent | ||
67 | active: false | 66 | active: false | ||
68 | source: "ChangeSession.qml" | 67 | source: "ChangeSession.qml" | ||
69 | visible: false | 68 | visible: false | ||
70 | } | 69 | } | ||
71 | 70 | | |||
71 | Item { | ||||
72 | id: lockScreenRoot | ||||
73 | | ||||
74 | x: parent.x | ||||
75 | y: parent.y | ||||
76 | width: parent.width | ||||
77 | height: parent.height | ||||
78 | | ||||
79 | Component.onCompleted: PropertyAnimation { id: launchAnimation; target: lockScreenRoot; property: "opacity"; from: 0; to: 1; duration: 1000 } | ||||
80 | | ||||
81 | states: [ | ||||
82 | State { | ||||
83 | name: "onOtherSession" | ||||
84 | // for slide out animation | ||||
85 | PropertyChanges { target: lockScreenRoot; y: lockScreenRoot.height } | ||||
86 | // we also change the opacity just to be sure it's not visible even on unexpected screen dimension changes with possible race conditions | ||||
87 | PropertyChanges { target: lockScreenRoot; opacity: 0 } | ||||
88 | } | ||||
89 | ] | ||||
90 | | ||||
91 | transitions: | ||||
92 | Transition { | ||||
93 | // we only animate switchting to another session, because kscreenlocker doesn't get notified when | ||||
94 | // coming from another session back and so we wouldn't know when to trigger the animation exactly | ||||
95 | from: "" | ||||
96 | to: "onOtherSession" | ||||
97 | | ||||
98 | PropertyAnimation { id: stateChangeAnimation; properties: "y"; duration: 300; easing: Easing.InQuad} | ||||
99 | PropertyAnimation { properties: "opacity"; duration: 300} | ||||
100 | | ||||
101 | onRunningChanged: { | ||||
102 | // after the animation has finished switch session: since we only animate the transition TO state "onOtherSession" | ||||
103 | // and not the other way around, we don't have to check the state we transitioned into | ||||
104 | if (/* lockScreenRoot.state == "onOtherSession" && */ !running) { | ||||
105 | mainStack.currentItem.switchSession() | ||||
106 | } | ||||
107 | } | ||||
108 | } | ||||
109 | | ||||
72 | Clock { | 110 | Clock { | ||
73 | anchors.bottom: parent.verticalCenter | 111 | anchors.bottom: parent.verticalCenter | ||
74 | anchors.bottomMargin: units.gridUnit * 13 | 112 | anchors.bottomMargin: units.gridUnit * 13 | ||
75 | anchors.horizontalCenter: parent.horizontalCenter | 113 | anchors.horizontalCenter: parent.horizontalCenter | ||
76 | } | 114 | } | ||
77 | 115 | | |||
78 | ListModel { | 116 | ListModel { | ||
79 | id: users | 117 | id: users | ||
80 | 118 | | |||
81 | Component.onCompleted: { | 119 | Component.onCompleted: { | ||
82 | users.append({name: kscreenlocker_userName, | 120 | users.append({name: kscreenlocker_userName, | ||
83 | realName: kscreenlocker_userName, | 121 | realName: kscreenlocker_userName, | ||
84 | icon: kscreenlocker_userImage, | 122 | icon: kscreenlocker_userImage, | ||
85 | 123 | | |||
86 | }) | 124 | }) | ||
87 | } | 125 | } | ||
88 | } | 126 | } | ||
89 | 127 | | |||
90 | StackView { | 128 | StackView { | ||
91 | id: mainStack | 129 | id: mainStack | ||
92 | anchors.fill: parent | 130 | anchors.fill: parent | ||
93 | focus: true //StackView is an implicit focus scope, so we need to give this focus so the item inside will have it | 131 | focus: true //StackView is an implicit focus scope, so we need to give this focus so the item inside will have it | ||
132 | | ||||
94 | initialItem: MainBlock { | 133 | initialItem: MainBlock { | ||
134 | id: mainBlock | ||||
davidedmundson: you don't need to do this. (and if you do need to do this, something else is wrong)
They're… | |||||
I think you need at least to switch the focus actively when the current item is changed. The best way is maybe to declare FocusScopes on the items, but I couldn't get the layout to work with this strategy. On the other hand I've simplified my solution by now setting the focus directly in the onStatusChanged handlers. Take a look at the second revision. romangg: I think you need at least to switch the focus actively when the current item is changed. The… | |||||
135 | | ||||
136 | Stack.onStatusChanged: { | ||||
137 | // prepare for presenting again to the user | ||||
138 | if (Stack.status == Stack.Activating) { | ||||
139 | mainPasswordBox.remove(0, mainPasswordBox.length) | ||||
140 | mainPasswordBox.focus = true | ||||
141 | } | ||||
142 | } | ||||
95 | userListModel: users | 143 | userListModel: users | ||
96 | notificationMessage: { | 144 | notificationMessage: { | ||
97 | var text = "" | 145 | var text = "" | ||
98 | if (keystateSource.data["Caps Lock"]["Locked"]) { | 146 | if (keystateSource.data["Caps Lock"]["Locked"]) { | ||
99 | text += i18nd("plasma_lookandfeel_org.kde.lookandfeel","Caps Lock is on") | 147 | text += i18nd("plasma_lookandfeel_org.kde.lookandfeel","Caps Lock is on") | ||
100 | if (root.notification) { | 148 | if (root.notification) { | ||
101 | text += " • " | 149 | text += " • " | ||
102 | } | 150 | } | ||
Show All 16 Lines | 161 | actionItems: [ | |||
119 | } | 167 | } | ||
120 | ] | 168 | ] | ||
121 | } | 169 | } | ||
122 | } | 170 | } | ||
123 | 171 | | |||
124 | Component { | 172 | Component { | ||
125 | id: switchSessionPage | 173 | id: switchSessionPage | ||
126 | SessionManagementScreen { | 174 | SessionManagementScreen { | ||
175 | property var switchSession: finalSwitchSession | ||||
176 | | ||||
177 | Stack.onStatusChanged: { | ||||
178 | if (Stack.status == Stack.Activating) { | ||||
179 | focus = true | ||||
180 | } | ||||
181 | } | ||||
182 | | ||||
127 | userListModel: sessionsModel | 183 | userListModel: sessionsModel | ||
128 | 184 | | |||
185 | // initiating animation of lockscreen for session switch | ||||
a.b.c.d is a sign of a bad layering it will break when someone else refactors. get MainBlock to clear itself when it gets focus davidedmundson: a.b.c.d is a sign of a bad layering it will break when someone else refactors.
get MainBlock… | |||||
186 | function initSwitchSession() { | ||||
187 | lockScreenRoot.state = 'onOtherSession' | ||||
188 | } | ||||
189 | | ||||
190 | // initiating session switch and preparing lockscreen for possible return of user | ||||
191 | function finalSwitchSession() { | ||||
192 | mainStack.pop({immediate:true}) | ||||
193 | sessionsModel.switchUser(userListCurrentModelData.vtNumber) | ||||
194 | lockScreenRoot.state = '' | ||||
195 | } | ||||
196 | | ||||
197 | Keys.onLeftPressed: userList.decrementCurrentIndex() | ||||
198 | Keys.onRightPressed: userList.incrementCurrentIndex() | ||||
199 | Keys.onEnterPressed: initSwitchSession() | ||||
200 | Keys.onReturnPressed: initSwitchSession() | ||||
201 | Keys.onEscapePressed: mainStack.pop() | ||||
202 | | ||||
129 | PlasmaComponents.Button { | 203 | PlasmaComponents.Button { | ||
130 | Layout.fillWidth: true | 204 | Layout.fillWidth: true | ||
131 | text: userListCurrentIndex == sessionsModel.count - 1 ? i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Start New Session") : i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Switch Session") | 205 | text: userListCurrentIndex == sessionsModel.count - 1 ? i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Start New Session") : i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Switch Session") | ||
132 | onClicked: { | 206 | onClicked: initSwitchSession() | ||
133 | sessionsModel.switchUser(userListCurrentModelData.vtNumber) | | |||
134 | mainStack.pop() | | |||
135 | } | | |||
136 | } | 207 | } | ||
137 | 208 | | |||
138 | actionItems: [ | 209 | actionItems: [ | ||
139 | ActionButton { | 210 | ActionButton { | ||
140 | iconSource: "go-previous" | 211 | iconSource: "go-previous" | ||
141 | text: i18nd("plasma_lookandfeel_org.kde.lookandfeel","Back") | 212 | text: i18nd("plasma_lookandfeel_org.kde.lookandfeel","Back") | ||
142 | onClicked: mainStack.pop() | 213 | onClicked: mainStack.pop() | ||
143 | } | 214 | } | ||
Show All 23 Lines | 228 | RowLayout { | |||
167 | } | 238 | } | ||
168 | 239 | | |||
169 | Item { | 240 | Item { | ||
170 | Layout.fillWidth: true | 241 | Layout.fillWidth: true | ||
171 | } | 242 | } | ||
172 | 243 | | |||
173 | Battery {} | 244 | Battery {} | ||
174 | } | 245 | } | ||
175 | 246 | } | |||
176 | 247 | | |||
177 | Component.onCompleted: { | 248 | Component.onCompleted: { | ||
178 | // version support checks | 249 | // version support checks | ||
179 | if (root.interfaceVersion < 1) { | 250 | if (root.interfaceVersion < 1) { | ||
180 | // ksmserver of 5.4, with greeter of 5.5 | 251 | // ksmserver of 5.4, with greeter of 5.5 | ||
181 | root.viewVisible = true; | 252 | root.viewVisible = true; | ||
182 | } | 253 | } | ||
183 | } | 254 | } | ||
184 | } | 255 | } |
you don't need to do this. (and if you do need to do this, something else is wrong)
They're within separate focus scopes, both "focusitems" should always have focus, then you switch currentItem we change which focusscope is active.