├── Nord ├── DropdownMenuStyle.qml ├── KeyboardButton.qml ├── Login.qml ├── Main.qml ├── SessionButton.qml ├── assets │ ├── bg.jpg │ └── change_user.svg ├── components │ ├── ActionButton.qml │ ├── Battery.qml │ ├── Clock.qml │ ├── Input.qml │ ├── SessionManagementScreen.qml │ ├── UserDelegate.qml │ ├── UserList.qml │ ├── VirtualKeyboard.qml │ └── artwork │ │ ├── logout_primary.svgz │ │ ├── restart_primary.svgz │ │ └── shutdown_primary.svgz ├── faces │ └── .face.icon ├── metadata.desktop ├── preview.png └── theme.conf ├── README.md └── wallpaper └── wallpaper.jpg /Nord/DropdownMenuStyle.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | 3 | import org.kde.plasma.core 2.0 as PlasmaCore 4 | 5 | import QtQuick.Controls.Styles 1.4 as QQCS 6 | import QtQuick.Controls 1.3 as QQC 7 | 8 | QQCS.MenuStyle { 9 | frame: Rectangle { 10 | color: "#2e3440" 11 | border.color: "#232831" 12 | border.width: 1 13 | } 14 | itemDelegate.label: QQC.Label { 15 | height: contentHeight * 2 16 | verticalAlignment: Text.AlignVCenter 17 | color: config.highlight_color 18 | font.pointSize: config.fontSize 19 | font.family: config.font 20 | text: styleData.text 21 | } 22 | itemDelegate.background: Rectangle { 23 | visible: styleData.selected 24 | color: config.selected_color 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Nord/KeyboardButton.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | 3 | import org.kde.plasma.core 2.0 as PlasmaCore 4 | import org.kde.plasma.components 2.0 as PlasmaComponents 5 | 6 | import QtQuick.Controls 1.3 as QQC 7 | 8 | PlasmaComponents.ToolButton { 9 | id: keyboardButton 10 | 11 | property int currentIndex: -1 12 | 13 | text: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Keyboard Layout: %1", instantiator.objectAt(currentIndex).shortName) 14 | implicitWidth: minimumWidth 15 | font.pointSize: config.fontSize 16 | 17 | visible: menu.items.length > 1 18 | 19 | Component.onCompleted: currentIndex = Qt.binding(function() {return keyboard.currentLayout}); 20 | 21 | menu: QQC.Menu { 22 | id: keyboardMenu 23 | style: DropdownMenuStyle {} 24 | Instantiator { 25 | id: instantiator 26 | model: keyboard.layouts 27 | onObjectAdded: keyboardMenu.insertItem(index, object) 28 | onObjectRemoved: keyboardMenu.removeItem( object ) 29 | delegate: QQC.MenuItem { 30 | text: modelData.longName 31 | property string shortName: modelData.shortName 32 | onTriggered: { 33 | keyboard.currentLayout = model.index 34 | } 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Nord/Login.qml: -------------------------------------------------------------------------------- 1 | import "components" 2 | 3 | import QtQuick 2.2 4 | import QtQuick.Layouts 1.2 5 | import QtQuick.Controls 2.4 6 | import QtQuick.Controls.Styles 1.4 7 | 8 | import org.kde.plasma.core 2.0 as PlasmaCore 9 | import org.kde.plasma.components 2.0 as PlasmaComponents 10 | 11 | SessionManagementScreen { 12 | id: root 13 | property Item mainPasswordBox: passwordBox 14 | 15 | property bool showUsernamePrompt: !showUserList 16 | 17 | property string lastUserName 18 | property bool loginScreenUiVisible: false 19 | 20 | //the y position that should be ensured visible when the on screen keyboard is visible 21 | property int visibleBoundary: mapFromItem(loginButton, 0, 0).y 22 | onHeightChanged: visibleBoundary = mapFromItem(loginButton, 0, 0).y + loginButton.height + units.smallSpacing 23 | 24 | signal loginRequest(string username, string password) 25 | 26 | onShowUsernamePromptChanged: { 27 | if (!showUsernamePrompt) { 28 | lastUserName = "" 29 | } 30 | } 31 | 32 | /* 33 | * Login has been requested with the following username and password 34 | * If username field is visible, it will be taken from that, otherwise from the "name" property of the currentIndex 35 | */ 36 | function startLogin() { 37 | var username = showUsernamePrompt ? userNameInput.text : userList.selectedUser 38 | var password = passwordBox.text 39 | 40 | //this is partly because it looks nicer 41 | //but more importantly it works round a Qt bug that can trigger if the app is closed with a TextField focused 42 | //DAVE REPORT THE FRICKING THING AND PUT A LINK 43 | loginButton.forceActiveFocus(); 44 | loginRequest(username, password); 45 | } 46 | 47 | Input { 48 | id: userNameInput 49 | Layout.fillWidth: true 50 | text: lastUserName 51 | visible: showUsernamePrompt 52 | focus: showUsernamePrompt && !lastUserName //if there's a username prompt it gets focus first, otherwise password does 53 | placeholderText: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Username") 54 | 55 | onAccepted: 56 | if (root.loginScreenUiVisible) { 57 | passwordBox.forceActiveFocus() 58 | } 59 | } 60 | 61 | Input { 62 | id: passwordBox 63 | placeholderText: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Password") 64 | focus: !showUsernamePrompt || lastUserName 65 | echoMode: TextInput.Password 66 | color: "#4C566A" 67 | 68 | Layout.fillWidth: true 69 | 70 | onAccepted: { 71 | if (root.loginScreenUiVisible) { 72 | startLogin(); 73 | } 74 | } 75 | 76 | Keys.onEscapePressed: { 77 | mainStack.currentItem.forceActiveFocus(); 78 | } 79 | 80 | //if empty and left or right is pressed change selection in user switch 81 | //this cannot be in keys.onLeftPressed as then it doesn't reach the password box 82 | Keys.onPressed: { 83 | if (event.key == Qt.Key_Left && !text) { 84 | userList.decrementCurrentIndex(); 85 | event.accepted = true 86 | } 87 | if (event.key == Qt.Key_Right && !text) { 88 | userList.incrementCurrentIndex(); 89 | event.accepted = true 90 | } 91 | } 92 | 93 | Connections { 94 | target: sddm 95 | onLoginFailed: { 96 | passwordBox.selectAll() 97 | passwordBox.forceActiveFocus() 98 | } 99 | } 100 | } 101 | Button { 102 | id: loginButton 103 | text: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Log In") 104 | enabled: passwordBox.text != "" 105 | 106 | Layout.topMargin: 10 107 | Layout.bottomMargin: 10 108 | Layout.fillWidth: true 109 | 110 | font.pointSize: config.fontSize 111 | font.family: config.font 112 | 113 | contentItem: Text { 114 | text: loginButton.text 115 | font: loginButton.font 116 | opacity: enabled ? 1.0 : 1.0 117 | color: config.highlight_color 118 | horizontalAlignment: Text.AlignHCenter 119 | verticalAlignment: Text.AlignVCenter 120 | elide: Text.ElideRight 121 | } 122 | 123 | background: Rectangle { 124 | id: buttonBackground 125 | width: parent.width 126 | height: 30 127 | radius: width / 2 128 | color: "#82ABAA" 129 | opacity: enabled ? 1.0 : 1.0 130 | } 131 | 132 | onClicked: startLogin(); 133 | } 134 | 135 | } 136 | -------------------------------------------------------------------------------- /Nord/Main.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 David Edmundson 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU Library General Public License as 6 | * published by the Free Software Foundation; either version 2 or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details 13 | * 14 | * You should have received a copy of the GNU Library General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | import QtQuick 2.8 21 | 22 | import QtQuick.Layouts 1.1 23 | import QtQuick.Controls 1.1 24 | import QtGraphicalEffects 1.0 25 | 26 | import org.kde.plasma.core 2.0 as PlasmaCore 27 | import org.kde.plasma.components 2.0 as PlasmaComponents 28 | import org.kde.plasma.extras 2.0 as PlasmaExtras 29 | 30 | import "components" 31 | 32 | PlasmaCore.ColorScope { 33 | id: root 34 | 35 | readonly property bool softwareRendering: GraphicsInfo.api === GraphicsInfo.Software 36 | 37 | colorGroup: PlasmaCore.Theme.ComplementaryColorGroup 38 | 39 | width: 1600 40 | height: 900 41 | 42 | property string notificationMessage 43 | 44 | LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft 45 | LayoutMirroring.childrenInherit: true 46 | 47 | PlasmaCore.DataSource { 48 | id: keystateSource 49 | engine: "keystate" 50 | connectedSources: "Caps Lock" 51 | } 52 | 53 | Image { 54 | id: wallpaper 55 | height: parent.height 56 | width: parent.width 57 | source: config.background || config.Background 58 | asynchronous: true 59 | cache: true 60 | clip: true 61 | } 62 | 63 | MouseArea { 64 | id: loginScreenRoot 65 | anchors.fill: parent 66 | 67 | property bool uiVisible: true 68 | property bool blockUI: mainStack.depth > 1 || userListComponent.mainPasswordBox.text.length > 0 || inputPanel.keyboardActive || config.type != "image" 69 | 70 | hoverEnabled: true 71 | drag.filterChildren: true 72 | onPressed: uiVisible = true; 73 | onPositionChanged: uiVisible = true; 74 | onUiVisibleChanged: { 75 | if (blockUI) { 76 | fadeoutTimer.running = false; 77 | } else if (uiVisible) { 78 | fadeoutTimer.restart(); 79 | } 80 | } 81 | onBlockUIChanged: { 82 | if (blockUI) { 83 | fadeoutTimer.running = false; 84 | uiVisible = true; 85 | } else { 86 | fadeoutTimer.restart(); 87 | } 88 | } 89 | 90 | Keys.onPressed: { 91 | uiVisible = true; 92 | event.accepted = false; 93 | } 94 | 95 | //takes one full minute for the ui to disappear 96 | Timer { 97 | id: fadeoutTimer 98 | running: true 99 | interval: 60000 100 | onTriggered: { 101 | if (!loginScreenRoot.blockUI) { 102 | loginScreenRoot.uiVisible = false; 103 | } 104 | } 105 | } 106 | 107 | StackView { 108 | id: mainStack 109 | anchors.centerIn: parent 110 | height: root.height / 2 111 | width: parent.width / 3 112 | 113 | focus: true //StackView is an implicit focus scope, so we need to give this focus so the item inside will have it 114 | 115 | Timer { 116 | //SDDM has a bug in 0.13 where even though we set the focus on the right item within the window, the window doesn't have focus 117 | //it is fixed in 6d5b36b28907b16280ff78995fef764bb0c573db which will be 0.14 118 | //we need to call "window->activate()" *After* it's been shown. We can't control that in QML so we use a shoddy timer 119 | //it's been this way for all Plasma 5.x without a huge problem 120 | running: true 121 | repeat: false 122 | interval: 200 123 | onTriggered: mainStack.forceActiveFocus() 124 | } 125 | 126 | initialItem: Login { 127 | id: userListComponent 128 | userListModel: userModel 129 | loginScreenUiVisible: loginScreenRoot.uiVisible 130 | userListCurrentIndex: userModel.lastIndex >= 0 ? userModel.lastIndex : 0 131 | lastUserName: userModel.lastUser 132 | 133 | showUserList: { 134 | if ( !userListModel.hasOwnProperty("count") 135 | || !userListModel.hasOwnProperty("disableAvatarsThreshold")) 136 | return (userList.y + mainStack.y) > 0 137 | 138 | if ( userListModel.count == 0 ) return false 139 | 140 | return userListModel.count <= userListModel.disableAvatarsThreshold && (userList.y + mainStack.y) > 0 141 | } 142 | 143 | notificationMessage: { 144 | var text = "" 145 | if (keystateSource.data["Caps Lock"]["Locked"]) { 146 | text += i18nd("plasma_lookandfeel_org.kde.lookandfeel","Caps Lock is on") 147 | if (root.notificationMessage) { 148 | text += " • " 149 | } 150 | } 151 | text += root.notificationMessage 152 | return text 153 | } 154 | 155 | actionItems: [ 156 | ActionButton { 157 | iconSource: "system-suspend" 158 | text: i18ndc("plasma_lookandfeel_org.kde.lookandfeel","Suspend to RAM","Sleep") 159 | onClicked: sddm.suspend() 160 | enabled: sddm.canSuspend 161 | visible: !inputPanel.keyboardActive 162 | }, 163 | ActionButton { 164 | iconSource: "system-reboot" 165 | text: i18nd("plasma_lookandfeel_org.kde.lookandfeel","Restart") 166 | onClicked: sddm.reboot() 167 | enabled: sddm.canReboot 168 | visible: !inputPanel.keyboardActive 169 | }, 170 | ActionButton { 171 | iconSource: "system-shutdown" 172 | text: i18nd("plasma_lookandfeel_org.kde.lookandfeel","Shut Down") 173 | onClicked: sddm.powerOff() 174 | enabled: sddm.canPowerOff 175 | visible: !inputPanel.keyboardActive 176 | }] 177 | 178 | onLoginRequest: { 179 | root.notificationMessage = "" 180 | sddm.login(username, password, sessionButton.currentIndex) 181 | } 182 | } 183 | 184 | Behavior on opacity { 185 | OpacityAnimator { 186 | duration: units.longDuration 187 | } 188 | } 189 | } 190 | 191 | Loader { 192 | id: inputPanel 193 | state: "hidden" 194 | property bool keyboardActive: item ? item.active : false 195 | onKeyboardActiveChanged: { 196 | if (keyboardActive) { 197 | state = "visible" 198 | } else { 199 | state = "hidden"; 200 | } 201 | } 202 | source: "components/VirtualKeyboard.qml" 203 | anchors { 204 | left: parent.left 205 | right: parent.right 206 | } 207 | 208 | function showHide() { 209 | state = state == "hidden" ? "visible" : "hidden"; 210 | } 211 | 212 | states: [ 213 | State { 214 | name: "visible" 215 | PropertyChanges { 216 | target: mainStack 217 | y: Math.min(0, root.height - inputPanel.height - userListComponent.visibleBoundary) 218 | } 219 | PropertyChanges { 220 | target: inputPanel 221 | y: root.height - inputPanel.height 222 | opacity: 1 223 | } 224 | }, 225 | State { 226 | name: "hidden" 227 | PropertyChanges { 228 | target: mainStack 229 | y: 0 230 | } 231 | PropertyChanges { 232 | target: inputPanel 233 | y: root.height - root.height/4 234 | opacity: 0 235 | } 236 | } 237 | ] 238 | transitions: [ 239 | Transition { 240 | from: "hidden" 241 | to: "visible" 242 | SequentialAnimation { 243 | ScriptAction { 244 | script: { 245 | inputPanel.item.activated = true; 246 | Qt.inputMethod.show(); 247 | } 248 | } 249 | ParallelAnimation { 250 | NumberAnimation { 251 | target: mainStack 252 | property: "y" 253 | duration: units.longDuration 254 | easing.type: Easing.InOutQuad 255 | } 256 | NumberAnimation { 257 | target: inputPanel 258 | property: "y" 259 | duration: units.longDuration 260 | easing.type: Easing.OutQuad 261 | } 262 | OpacityAnimator { 263 | target: inputPanel 264 | duration: units.longDuration 265 | easing.type: Easing.OutQuad 266 | } 267 | } 268 | } 269 | }, 270 | Transition { 271 | from: "visible" 272 | to: "hidden" 273 | SequentialAnimation { 274 | ParallelAnimation { 275 | NumberAnimation { 276 | target: mainStack 277 | property: "y" 278 | duration: units.longDuration 279 | easing.type: Easing.InOutQuad 280 | } 281 | NumberAnimation { 282 | target: inputPanel 283 | property: "y" 284 | duration: units.longDuration 285 | easing.type: Easing.InQuad 286 | } 287 | OpacityAnimator { 288 | target: inputPanel 289 | duration: units.longDuration 290 | easing.type: Easing.InQuad 291 | } 292 | } 293 | ScriptAction { 294 | script: { 295 | Qt.inputMethod.hide(); 296 | } 297 | } 298 | } 299 | } 300 | ] 301 | } 302 | 303 | 304 | Component { 305 | id: userPromptComponent 306 | Login { 307 | showUsernamePrompt: true 308 | notificationMessage: root.notificationMessage 309 | loginScreenUiVisible: loginScreenRoot.uiVisible 310 | 311 | // using a model rather than a QObject list to avoid QTBUG-75900 312 | userListModel: ListModel { 313 | ListElement { 314 | name: "" 315 | iconSource: "" 316 | } 317 | Component.onCompleted: { 318 | // as we can't bind inside ListElement 319 | setProperty(0, "name", i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Type in Username and Password")); 320 | } 321 | } 322 | 323 | onLoginRequest: { 324 | root.notificationMessage = "" 325 | sddm.login(username, password, sessionButton.currentIndex) 326 | } 327 | 328 | actionItems: [ 329 | ActionButton { 330 | iconSource: "system-suspend" 331 | text: i18ndc("plasma_lookandfeel_org.kde.lookandfeel","Suspend to RAM","Sleep") 332 | onClicked: sddm.suspend() 333 | enabled: sddm.canSuspend 334 | visible: !inputPanel.keyboardActive 335 | }, 336 | ActionButton { 337 | iconSource: "system-reboot" 338 | text: i18nd("plasma_lookandfeel_org.kde.lookandfeel","Restart") 339 | onClicked: sddm.reboot() 340 | enabled: sddm.canReboot 341 | visible: !inputPanel.keyboardActive 342 | }, 343 | ActionButton { 344 | iconSource: "system-shutdown" 345 | text: i18nd("plasma_lookandfeel_org.kde.lookandfeel","Shut Down") 346 | onClicked: sddm.powerOff() 347 | enabled: sddm.canPowerOff 348 | visible: !inputPanel.keyboardActive 349 | }, 350 | ActionButton { 351 | iconSource: "go-previous" 352 | text: i18nd("plasma_lookandfeel_org.kde.lookandfeel","List Users") 353 | onClicked: mainStack.pop() 354 | visible: !inputPanel.keyboardActive 355 | } 356 | ] 357 | } 358 | } 359 | 360 | Rectangle { 361 | id: blurBg 362 | anchors.fill: parent 363 | anchors.centerIn: parent 364 | color: "#4C566A" 365 | opacity: 0 366 | z:-1 367 | } 368 | 369 | Rectangle { 370 | id: formBg 371 | width: mainStack.width 372 | height: mainStack.height 373 | x: root.width / 2 - width / 2 374 | y: root.height / 2 - height / 3 375 | radius: 10 376 | color: "#2e3440" 377 | opacity: 1.0 378 | z:-1 379 | DropShadow { 380 | anchors.fill: formBg 381 | cached: true 382 | horizontalOffset: 3 383 | verticalOffset: 3 384 | radius: 10 385 | samples: 50 386 | color: "#aa000000" 387 | source: formBg 388 | } 389 | } 390 | 391 | ShaderEffectSource { 392 | id: blurArea 393 | sourceItem: wallpaper 394 | width: blurBg.width 395 | height: blurBg.height 396 | anchors.centerIn: blurBg 397 | sourceRect: Qt.rect(x,y,width,height) 398 | visible: true 399 | z:-2 400 | } 401 | 402 | GaussianBlur { 403 | id: blur 404 | height: blurBg.height 405 | width: blurBg.width 406 | source: blurArea 407 | radius: 0 408 | samples: 0 409 | cached: true 410 | anchors.centerIn: blurBg 411 | visible: true 412 | z:-2 413 | } 414 | 415 | RowLayout { 416 | id: footer 417 | anchors { 418 | bottom: parent.bottom 419 | left: parent.left 420 | margins: units.smallSpacing 421 | } 422 | 423 | Behavior on opacity { 424 | OpacityAnimator { 425 | duration: units.longDuration 426 | } 427 | } 428 | 429 | PlasmaComponents.ToolButton { 430 | text: i18ndc("plasma_lookandfeel_org.kde.lookandfeel", "Button to show/hide virtual keyboard", "Virtual Keyboard") 431 | iconName: inputPanel.keyboardActive ? "input-keyboard-virtual-on" : "input-keyboard-virtual-off" 432 | onClicked: inputPanel.showHide() 433 | visible: inputPanel.status == Loader.Ready 434 | } 435 | 436 | KeyboardButton { 437 | } 438 | 439 | SessionButton { 440 | id: sessionButton 441 | } 442 | 443 | } 444 | 445 | RowLayout { 446 | id: footerRight 447 | spacing: 10 448 | 449 | anchors { 450 | bottom: parent.bottom 451 | right: parent.right 452 | margins: 10 453 | } 454 | 455 | Behavior on opacity { 456 | OpacityAnimator { 457 | duration: units.longDuration 458 | } 459 | } 460 | 461 | Clock { 462 | id: clock 463 | visible: true 464 | } 465 | } 466 | } 467 | 468 | Connections { 469 | target: sddm 470 | onLoginFailed: { 471 | notificationMessage = i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Login Failed") 472 | } 473 | onLoginSucceeded: { 474 | //note SDDM will kill the greeter at some random point after this 475 | //there is no certainty any transition will finish, it depends on the time it 476 | //takes to complete the init 477 | mainStack.opacity = 0 478 | footer.opacity = 0 479 | footerRight.opacity = 0 480 | } 481 | } 482 | 483 | onNotificationMessageChanged: { 484 | if (notificationMessage) { 485 | notificationResetTimer.start(); 486 | } 487 | } 488 | 489 | Timer { 490 | id: notificationResetTimer 491 | interval: 3000 492 | onTriggered: notificationMessage = "" 493 | } 494 | } 495 | -------------------------------------------------------------------------------- /Nord/SessionButton.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 David Edmundson 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU Library General Public License as 6 | * published by the Free Software Foundation; either version 2 or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details 13 | * 14 | * You should have received a copy of the GNU Library General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | import QtQuick 2.2 21 | 22 | import org.kde.plasma.core 2.0 as PlasmaCore 23 | import org.kde.plasma.components 2.0 as PlasmaComponents 24 | 25 | import QtQuick.Controls 1.3 as QQC 26 | 27 | PlasmaComponents.ToolButton { 28 | id: root 29 | property int currentIndex: -1 30 | 31 | implicitWidth: minimumWidth 32 | 33 | visible: menu.items.length > 1 34 | 35 | text: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Desktop Session: %1", instantiator.objectAt(currentIndex).text || "") 36 | 37 | font.pointSize: config.fontSize 38 | 39 | Component.onCompleted: { 40 | currentIndex = sessionModel.lastIndex 41 | } 42 | 43 | menu: QQC.Menu { 44 | id: menu 45 | style: DropdownMenuStyle {} 46 | Instantiator { 47 | id: instantiator 48 | model: sessionModel 49 | onObjectAdded: menu.insertItem(index, object) 50 | onObjectRemoved: menu.removeItem( object ) 51 | delegate: QQC.MenuItem { 52 | text: model.name 53 | onTriggered: { 54 | root.currentIndex = model.index 55 | } 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Nord/assets/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nautilor/nord-sddm/ad72c3c7048c8aabe85bab41cbeab5f3c4502250/Nord/assets/bg.jpg -------------------------------------------------------------------------------- /Nord/assets/change_user.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Nord/components/ActionButton.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 David Edmundson 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU Library General Public License as 6 | * published by the Free Software Foundation; either version 2 or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details 13 | * 14 | * You should have received a copy of the GNU Library General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | import QtQuick 2.2 21 | import org.kde.plasma.core 2.0 as PlasmaCore 22 | import org.kde.plasma.components 2.0 as PlasmaComponents 23 | 24 | Item { 25 | id: root 26 | property alias text: label.text 27 | property alias iconSource: icon.source 28 | property alias containsMouse: mouseArea.containsMouse 29 | property alias font: label.font 30 | signal clicked 31 | 32 | activeFocusOnTab: true 33 | 34 | property int iconSize: units.gridUnit * 2.5 35 | 36 | implicitWidth: Math.max(iconSize + units.largeSpacing * 2, label.contentWidth) 37 | implicitHeight: iconSize + units.smallSpacing + label.implicitHeight 38 | 39 | opacity: activeFocus || containsMouse ? 1.5 : 0.97 40 | Behavior on opacity { 41 | PropertyAnimation { // OpacityAnimator makes it turn black at random intervals 42 | duration: units.longDuration * 2 43 | easing.type: Easing.InOutQuad 44 | } 45 | } 46 | 47 | 48 | PlasmaCore.IconItem { 49 | id: icon 50 | anchors { 51 | top: parent.top 52 | horizontalCenter: parent.horizontalCenter 53 | } 54 | width: iconSize 55 | height: iconSize 56 | 57 | colorGroup: PlasmaCore.ColorScope.colorGroup 58 | active: mouseArea.containsMouse || root.activeFocus 59 | } 60 | PlasmaComponents.Label { 61 | id: label 62 | anchors { 63 | top: icon.bottom 64 | topMargin: units.smallSpacing 65 | left: parent.left 66 | right: parent.right 67 | } 68 | horizontalAlignment: Text.AlignHCenter 69 | verticalAlignment: Text.AlignTop 70 | wrapMode: Text.WordWrap 71 | font.underline: root.activeFocus 72 | font.pointSize: config.fontSize 73 | font.family: config.font 74 | color:activeFocus || containsMouse ? config.highlight_color : config.color 75 | } 76 | 77 | MouseArea { 78 | id: mouseArea 79 | hoverEnabled: true 80 | onClicked: root.clicked() 81 | anchors.fill: parent 82 | } 83 | 84 | Keys.onEnterPressed: clicked() 85 | Keys.onReturnPressed: clicked() 86 | Keys.onSpacePressed: clicked() 87 | 88 | Accessible.onPressAction: clicked() 89 | Accessible.role: Accessible.Button 90 | Accessible.name: label.text 91 | } 92 | -------------------------------------------------------------------------------- /Nord/components/Battery.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Kai Uwe Broulik 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU Library General Public License as 6 | * published by the Free Software Foundation; either version 2 or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details 13 | * 14 | * You should have received a copy of the GNU Library General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | import QtQuick 2.2 21 | 22 | import org.kde.plasma.core 2.0 as PlasmaCore 23 | import org.kde.plasma.components 2.0 as PlasmaComponents 24 | import org.kde.plasma.workspace.components 2.0 as PW 25 | 26 | Row { 27 | spacing: units.smallSpacing 28 | visible: pmSource.data["Battery"]["Has Cumulative"] 29 | 30 | PlasmaCore.DataSource { 31 | id: pmSource 32 | engine: "powermanagement" 33 | connectedSources: ["Battery", "AC Adapter"] 34 | } 35 | 36 | PW.BatteryIcon { 37 | id: battery 38 | hasBattery: pmSource.data["Battery"]["Has Battery"] || false 39 | percent: pmSource.data["Battery"]["Percent"] || 0 40 | pluggedIn: pmSource.data["AC Adapter"] ? pmSource.data["AC Adapter"]["Plugged in"] : false 41 | 42 | height: batteryLabel.height 43 | width: height 44 | } 45 | 46 | PlasmaComponents.Label { 47 | id: batteryLabel 48 | height: undefined 49 | text: i18nd("plasma_lookandfeel_org.kde.lookandfeel","%1%", battery.percent) 50 | Accessible.name: i18nd("plasma_lookandfeel_org.kde.lookandfeel","Battery at %1%", battery.percent) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Nord/components/Clock.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 David Edmundson 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU Library General Public License as 6 | * published by the Free Software Foundation; either version 2 or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details 13 | * 14 | * You should have received a copy of the GNU Library General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | import QtQuick 2.8 21 | import QtQuick.Layouts 1.1 22 | import QtQuick.Controls 2.5 23 | import org.kde.plasma.core 2.0 24 | 25 | RowLayout { 26 | readonly property bool softwareRendering: GraphicsInfo.api === GraphicsInfo.Software 27 | 28 | 29 | Label { 30 | text: Qt.formatDate(timeSource.data["Local"]["DateTime"], Qt.DefaultLocaleLongDate) 31 | color: config.color 32 | style: softwareRendering ? Text.Outline : Text.Normal 33 | styleColor: softwareRendering ? ColorScope.backgroundColor : "transparent" //no outline, doesn't matter 34 | font.pointSize: 11 35 | Layout.alignment: Qt.AlignHCenter 36 | font.family: config.font 37 | 38 | } 39 | Label { 40 | text: Qt.formatTime(timeSource.data["Local"]["DateTime"]) 41 | color: config.color 42 | style: softwareRendering ? Text.Outline : Text.Normal 43 | styleColor: softwareRendering ? ColorScope.backgroundColor : "transparent" //no outline, doesn't matter 44 | font.pointSize: 11 45 | Layout.alignment: Qt.AlignHCenter 46 | font.family: config.font 47 | 48 | } 49 | DataSource { 50 | id: timeSource 51 | engine: "time" 52 | connectedSources: ["Local"] 53 | interval: 1000 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Nord/components/Input.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | import QtQuick.Layouts 1.2 3 | import QtQuick.Controls 2.4 4 | import QtQuick.Controls.Styles 1.4 5 | 6 | TextField { 7 | placeholderTextColor: config.color 8 | palette.text: config.color 9 | font.pointSize: config.fontSize 10 | font.family: config.font 11 | background: Rectangle { 12 | color: "#2e3440" 13 | radius: parent.width / 2 14 | height: 30 15 | width: parent.width 16 | opacity: 0.7 17 | anchors.centerIn: parent 18 | } 19 | } -------------------------------------------------------------------------------- /Nord/components/SessionManagementScreen.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 David Edmundson 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU Library General Public License as 6 | * published by the Free Software Foundation; either version 2 or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details 13 | * 14 | * You should have received a copy of the GNU Library General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | 21 | import QtQuick 2.2 22 | 23 | import QtQuick.Layouts 1.1 24 | import QtQuick.Controls 1.1 25 | 26 | import org.kde.plasma.core 2.0 as PlasmaCore 27 | import org.kde.plasma.components 2.0 as PlasmaComponents 28 | 29 | Item { 30 | id: root 31 | 32 | /* 33 | * Any message to be displayed to the user, visible above the text fields 34 | */ 35 | property alias notificationMessage: notificationsLabel.text 36 | 37 | /* 38 | * A list of Items (typically ActionButtons) to be shown in a Row beneath the prompts 39 | */ 40 | property alias actionItems: actionItemsLayout.children 41 | 42 | /* 43 | * A model with a list of users to show in the view 44 | * The following roles should exist: 45 | * - name 46 | * - iconSource 47 | * 48 | * The following are also handled: 49 | * - vtNumber 50 | * - displayNumber 51 | * - session 52 | * - isTty 53 | */ 54 | property alias userListModel: userListView.model 55 | 56 | /* 57 | * Self explanatory 58 | */ 59 | property alias userListCurrentIndex: userListView.currentIndex 60 | property var userListCurrentModelData: userListView.currentItem === null ? [] : userListView.currentItem.m 61 | property bool showUserList: true 62 | 63 | property alias userList: userListView 64 | 65 | default property alias _children: innerLayout.children 66 | 67 | UserList { 68 | id: userListView 69 | visible: showUserList && y > 0 70 | anchors { 71 | bottom: parent.verticalCenter 72 | left: parent.left 73 | right: parent.right 74 | } 75 | } 76 | 77 | //goal is to show the prompts, in ~16 grid units high, then the action buttons 78 | //but collapse the space between the prompts and actions if there's no room 79 | //ui is constrained to 16 grid units wide, or the screen 80 | ColumnLayout { 81 | id: prompts 82 | anchors.top: parent.verticalCenter 83 | anchors.topMargin: units.gridUnit * 0.5 84 | anchors.left: parent.left 85 | anchors.right: parent.right 86 | anchors.bottom: parent.bottom 87 | PlasmaComponents.Label { 88 | id: notificationsLabel 89 | Layout.maximumWidth: units.gridUnit * 16 90 | Layout.alignment: Qt.AlignHCenter 91 | Layout.fillWidth: true 92 | horizontalAlignment: Text.AlignHCenter 93 | wrapMode: Text.WordWrap 94 | font.italic: true 95 | } 96 | ColumnLayout { 97 | Layout.minimumHeight: implicitHeight 98 | Layout.maximumHeight: units.gridUnit * 10 99 | Layout.maximumWidth: units.gridUnit * 16 100 | Layout.alignment: Qt.AlignHCenter 101 | ColumnLayout { 102 | id: innerLayout 103 | Layout.alignment: Qt.AlignHCenter 104 | Layout.fillWidth: true 105 | } 106 | Item { 107 | Layout.fillHeight: true 108 | } 109 | } 110 | Row { //deliberately not rowlayout as I'm not trying to resize child items 111 | id: actionItemsLayout 112 | spacing: units.smallSpacing 113 | Layout.alignment: Qt.AlignHCenter 114 | } 115 | Item { 116 | Layout.fillHeight: true 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /Nord/components/UserDelegate.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 David Edmundson 3 | * Copyright 2014 Aleix Pol Gonzalez 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU Library General Public License as 7 | * published by the Free Software Foundation; either version 2 or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details 14 | * 15 | * You should have received a copy of the GNU Library General Public 16 | * License along with this program; if not, write to the 17 | * Free Software Foundation, Inc., 18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | import QtQuick 2.8 22 | import org.kde.plasma.core 2.0 as PlasmaCore 23 | import org.kde.plasma.components 2.0 as PlasmaComponents 24 | 25 | Item { 26 | id: wrapper 27 | 28 | // If we're using software rendering, draw outlines instead of shadows 29 | // See https://bugs.kde.org/show_bug.cgi?id=398317 30 | readonly property bool softwareRendering: GraphicsInfo.api === GraphicsInfo.Software 31 | 32 | property bool isCurrent: true 33 | 34 | readonly property var m: model 35 | property string name 36 | property string userName 37 | property string avatarPath 38 | property string iconSource 39 | property bool constrainText: true 40 | property alias nameFontSize: usernameDelegate.font.pointSize 41 | property int fontSize: config.fontSize - 1 42 | signal clicked() 43 | 44 | property real faceSize: Math.min(width, height - usernameDelegate.height - units.smallSpacing) 45 | 46 | opacity: isCurrent ? 1.0 : 0.5 47 | 48 | Behavior on opacity { 49 | OpacityAnimator { 50 | duration: units.longDuration 51 | } 52 | } 53 | 54 | // Draw a translucent background circle under the user picture 55 | Rectangle { 56 | anchors.centerIn: imageSource 57 | width: imageSource.width + 2 // Subtract to prevent fringing 58 | height: width 59 | radius: width / 2 60 | color: "#232831" 61 | } 62 | 63 | Item { 64 | id: imageSource 65 | anchors { 66 | bottom: usernameDelegate.top 67 | bottomMargin: units.largeSpacing 68 | horizontalCenter: parent.horizontalCenter 69 | } 70 | Behavior on width { 71 | PropertyAnimation { 72 | from: faceSize 73 | duration: units.longDuration * 2; 74 | } 75 | } 76 | width: isCurrent ? faceSize : faceSize - units.largeSpacing 77 | height: width 78 | 79 | //Image takes priority, taking a full path to a file, if that doesn't exist we show an icon 80 | Image { 81 | id: face 82 | source: wrapper.avatarPath 83 | sourceSize: Qt.size(faceSize, faceSize) 84 | fillMode: Image.PreserveAspectCrop 85 | anchors.fill: parent 86 | } 87 | 88 | PlasmaCore.IconItem { 89 | id: faceIcon 90 | source: iconSource 91 | visible: (face.status == Image.Error || face.status == Image.Null) 92 | anchors.fill: parent 93 | anchors.margins: units.gridUnit * 0.5 // because mockup says so... 94 | colorGroup: PlasmaCore.ColorScope.colorGroup 95 | } 96 | } 97 | 98 | ShaderEffect { 99 | anchors { 100 | bottom: usernameDelegate.top 101 | bottomMargin: units.largeSpacing 102 | horizontalCenter: parent.horizontalCenter 103 | } 104 | 105 | width: imageSource.width 106 | height: imageSource.height 107 | 108 | supportsAtlasTextures: true 109 | 110 | property var source: ShaderEffectSource { 111 | sourceItem: imageSource 112 | // software rendering is just a fallback so we can accept not having a rounded avatar here 113 | hideSource: wrapper.GraphicsInfo.api !== GraphicsInfo.Software 114 | live: true // otherwise the user in focus will show a blurred avatar 115 | } 116 | 117 | property var colorBorder: "#00000000" 118 | 119 | //draw a circle with an antialised border 120 | //innerRadius = size of the inner circle with contents 121 | //outerRadius = size of the border 122 | //blend = area to blend between two colours 123 | //all sizes are normalised so 0.5 == half the width of the texture 124 | 125 | //if copying into another project don't forget to connect themeChanged to update() 126 | //but in SDDM that's a bit pointless 127 | fragmentShader: " 128 | varying highp vec2 qt_TexCoord0; 129 | uniform highp float qt_Opacity; 130 | uniform lowp sampler2D source; 131 | 132 | uniform lowp vec4 colorBorder; 133 | highp float blend = 0.01; 134 | highp float innerRadius = 0.47; 135 | highp float outerRadius = 0.49; 136 | lowp vec4 colorEmpty = vec4(0.0, 0.0, 0.0, 0.0); 137 | 138 | void main() { 139 | lowp vec4 colorSource = texture2D(source, qt_TexCoord0.st); 140 | 141 | highp vec2 m = qt_TexCoord0 - vec2(0.5, 0.5); 142 | highp float dist = sqrt(m.x * m.x + m.y * m.y); 143 | 144 | if (dist < innerRadius) 145 | gl_FragColor = colorSource; 146 | else if (dist < innerRadius + blend) 147 | gl_FragColor = mix(colorSource, colorBorder, ((dist - innerRadius) / blend)); 148 | else if (dist < outerRadius) 149 | gl_FragColor = colorBorder; 150 | else if (dist < outerRadius + blend) 151 | gl_FragColor = mix(colorBorder, colorEmpty, ((dist - outerRadius) / blend)); 152 | else 153 | gl_FragColor = colorEmpty ; 154 | 155 | gl_FragColor = gl_FragColor * qt_Opacity; 156 | } 157 | " 158 | } 159 | 160 | PlasmaComponents.Label { 161 | id: usernameDelegate 162 | font.pointSize: Math.max(fontSize + 2,theme.defaultFont.pointSize + 2) 163 | anchors { 164 | bottom: parent.bottom 165 | horizontalCenter: parent.horizontalCenter 166 | } 167 | height: implicitHeight // work around stupid bug in Plasma Components that sets the height 168 | width: constrainText ? parent.width : implicitWidth 169 | text: wrapper.name 170 | style: softwareRendering ? Text.Outline : Text.Normal 171 | styleColor: softwareRendering ? PlasmaCore.ColorScope.backgroundColor : "transparent" //no outline, doesn't matter 172 | elide: Text.ElideRight 173 | horizontalAlignment: Text.AlignHCenter 174 | color: config.color 175 | //make an indication that this has active focus, this only happens when reached with keyboard navigation 176 | font.underline: wrapper.activeFocus 177 | font.family: config.font 178 | } 179 | 180 | MouseArea { 181 | anchors.fill: parent 182 | hoverEnabled: true 183 | 184 | onClicked: wrapper.clicked(); 185 | } 186 | 187 | Accessible.name: name 188 | Accessible.role: Accessible.Button 189 | function accessiblePressAction() { wrapper.clicked() } 190 | } 191 | -------------------------------------------------------------------------------- /Nord/components/UserList.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 David Edmundson 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU Library General Public License as 6 | * published by the Free Software Foundation; either version 2 or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details 13 | * 14 | * You should have received a copy of the GNU Library General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | import QtQuick 2.2 21 | 22 | ListView { 23 | id: view 24 | readonly property string selectedUser: currentItem ? currentItem.userName : "" 25 | readonly property int userItemWidth: units.gridUnit * 8 26 | readonly property int userItemHeight: units.gridUnit * 8 27 | 28 | implicitHeight: userItemHeight 29 | 30 | activeFocusOnTab : true 31 | 32 | /* 33 | * Signals that a user was explicitly selected 34 | */ 35 | signal userSelected; 36 | 37 | orientation: ListView.Horizontal 38 | highlightRangeMode: ListView.StrictlyEnforceRange 39 | 40 | //centre align selected item (which implicitly centre aligns the rest 41 | preferredHighlightBegin: width/2 - userItemWidth/2 42 | preferredHighlightEnd: preferredHighlightBegin 43 | 44 | delegate: UserDelegate { 45 | avatarPath: model.icon || "" 46 | iconSource: model.iconName || "user-identity" 47 | 48 | name: { 49 | var displayName = model.realName || model.name 50 | 51 | if (model.vtNumber === undefined || model.vtNumber < 0) { 52 | return displayName 53 | } 54 | 55 | if (!model.session) { 56 | return i18ndc("plasma_lookandfeel_org.kde.lookandfeel", "Nobody logged in on that session", "Unused") 57 | } 58 | 59 | 60 | var location = "" 61 | if (model.isTty) { 62 | location = i18ndc("plasma_lookandfeel_org.kde.lookandfeel", "User logged in on console number", "TTY %1", model.vtNumber) 63 | } else if (model.displayNumber) { 64 | location = i18ndc("plasma_lookandfeel_org.kde.lookandfeel", "User logged in on console (X display number)", "on TTY %1 (Display %2)", model.vtNumber, model.displayNumber) 65 | } 66 | 67 | if (location) { 68 | return i18ndc("plasma_lookandfeel_org.kde.lookandfeel", "Username (location)", "%1 (%2)", displayName, location) 69 | } 70 | 71 | return displayName 72 | } 73 | 74 | userName: model.name 75 | 76 | width: userItemWidth 77 | height: userItemHeight 78 | 79 | //if we only have one delegate, we don't need to clip the text as it won't be overlapping with anything 80 | constrainText: ListView.view.count > 1 81 | 82 | isCurrent: ListView.isCurrentItem 83 | 84 | onClicked: { 85 | ListView.view.currentIndex = index; 86 | ListView.view.userSelected(); 87 | } 88 | } 89 | 90 | Keys.onEscapePressed: view.userSelected() 91 | Keys.onEnterPressed: view.userSelected() 92 | Keys.onReturnPressed: view.userSelected() 93 | } 94 | -------------------------------------------------------------------------------- /Nord/components/VirtualKeyboard.qml: -------------------------------------------------------------------------------- 1 | /******************************************************************** 2 | This file is part of the KDE project. 3 | 4 | Copyright (C) 2017 Martin Gräßlin 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | *********************************************************************/ 19 | 20 | import QtQuick 2.5 21 | import QtQuick.VirtualKeyboard 2.1 22 | 23 | InputPanel { 24 | id: inputPanel 25 | property bool activated: false 26 | active: activated && Qt.inputMethod.visible 27 | visible: active 28 | width: parent.width 29 | } 30 | -------------------------------------------------------------------------------- /Nord/components/artwork/logout_primary.svgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nautilor/nord-sddm/ad72c3c7048c8aabe85bab41cbeab5f3c4502250/Nord/components/artwork/logout_primary.svgz -------------------------------------------------------------------------------- /Nord/components/artwork/restart_primary.svgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nautilor/nord-sddm/ad72c3c7048c8aabe85bab41cbeab5f3c4502250/Nord/components/artwork/restart_primary.svgz -------------------------------------------------------------------------------- /Nord/components/artwork/shutdown_primary.svgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nautilor/nord-sddm/ad72c3c7048c8aabe85bab41cbeab5f3c4502250/Nord/components/artwork/shutdown_primary.svgz -------------------------------------------------------------------------------- /Nord/faces/.face.icon: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 14 | 15 | -------------------------------------------------------------------------------- /Nord/metadata.desktop: -------------------------------------------------------------------------------- 1 | [SddmGreeterTheme] 2 | Name=Nord 3 | Description=Nord sddm theme 4 | Author=nautilor 5 | Copyright=(c) 2021, nautilor 6 | License=GPL 3+ 7 | Type=sddm-theme 8 | Version=0.1 9 | Website=https://github.com/nautilor/nord-sddm/ 10 | Screenshot=preview.png 11 | MainScript=Main.qml 12 | ConfigFile=theme.conf 13 | TranslationsDirectory=translations 14 | Email=edoardo.zerbo@gmail.com 15 | Theme-Id=Nord 16 | Theme-API=2.0 17 | -------------------------------------------------------------------------------- /Nord/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nautilor/nord-sddm/ad72c3c7048c8aabe85bab41cbeab5f3c4502250/Nord/preview.png -------------------------------------------------------------------------------- /Nord/theme.conf: -------------------------------------------------------------------------------- 1 | [General] 2 | type=image 3 | color=#C3C7D1 4 | highlight_color=#ffffff 5 | selected_color=#698989 6 | selected_fg_color=#2e3440 7 | fontSize=10 8 | Background="assets/bg.jpg" 9 | font="JetBrainsMono Nerd Font Mono" 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Nord SDDM Login Screen 2 | 3 | This is my custom login screen based on the Nord colorscheme 4 | 5 | # Installation 6 | - Move the folder `Nord` in the sddm themes folder 7 | 8 | ```bash 9 | sudo cp -R Nord /usr/share/sddm/themes/ 10 | ``` 11 | 12 | - Edit sddm config to use the new theme 13 | 14 | ```bash 15 | /usr/lib/sddm/sddm.conf.d/default.conf 16 | ``` 17 | 18 | and in the section `[Theme]` change the value `Current=...` to be `Current=Nord` 19 | 20 | # Test Theme 21 | To test the theme without having to logout everytime just use 22 | 23 | ```bash 24 | sddm-greeter --test-mode --theme Nord 25 | ``` 26 | 27 | 28 | # User Icon outside of KDE 29 | 30 | If you are using a window manager like bspwm and want to show a user icon at login just take a picture and move it to `/usr/share/sddm/faces/username.face.icon` 31 | 32 | > replace username with your own one 33 | 34 | # Screenshots 35 | ![preview](Nord/preview.png) 36 | 37 | # Wallpaper 38 | ![wall](wallpaper/wallpaper.jpg) -------------------------------------------------------------------------------- /wallpaper/wallpaper.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nautilor/nord-sddm/ad72c3c7048c8aabe85bab41cbeab5f3c4502250/wallpaper/wallpaper.jpg --------------------------------------------------------------------------------