Search code examples
qtqmlkde-plasma

userModel.lastUser contains empty string


I'm creating my own SDDM theme. During development, I noticed that userModel.lastUser contains an empty string in test mode. I checked on other SDDM themes - the same thing. In normal mode everything is ok. How can I fix this?

Did everything in accordance with the official documentation: https://github.com/sddm/sddm/wiki/Theming

Fragment of my code:

Item {
    id: root

    signal selected(var userName)

    property string userName: userModel.lastUser
    property string currentIconPath: usersList.currentItem.iconPath
    property string currentUserName: usersList.currentItem.userName

    ListView {
        id: usersList

        model: userModel
        delegate: Text {
            id: userItem
            visible: false
            text: model.name

            function select() {
                selected(name)
                usersList.currentIndex = index
                currentIconPath = icon
                currentUserName = name
            }

            Component.onCompleted: {
                if (name === userModel.lastUser) {
                    userItem.select()
                }
                console.log(userModel.lastUser)
                //userItem.select()
            }
        }
    }
    ...

Solution

  • I did the following small tweaks to your application:

    • I eliminated lastUser - I couldn't find meaning in this property
    • I update currentUserName and currentIconPath when it is selected, this part I kept
    • I rewrote the selection to be based on reading and writing currentIndex. The advantage of using currentIndex, is the ListView control has built-in support for Key_Up and Key_Down key presses as long as the ListView control is the current focused control
    • I introduced an onClicked handler so that the currentIndex gets updated and that the keyboard focus is reasserted
    • It wasn't clear why your delegate was an invisible Text, I replaced it with Frame with an ItemDelegate because I can (1) supply an icon, (2) change the color
    • I rewrote Component.onCompleted to initialize currentIndex to the last item in the list model because it appears that there appears to be a need to initialize focus on the last item. The Component.onCompleted was moved from the delegate to the ListView. This is because when it was on the delegate it would have fired EVERY time the delegate got rendered. Imagine the impact of this when you were to scroll through long list. The last visible item isn't necessarily the last item on the list
    import QtQuick
    import QtQuick.Controls
    Page {
        signal selected()
        property alias currentIndex: usersList.currentIndex
        property var currentUser: currentIndex >= 0 && currentIndex < userModel.count ? userModel.get(currentIndex) : null
        property string currentIconPath: currentUser ? currentUser.iconPath : ""
        property string currentUserName: currentUser ? currentUser.userName : ""
        ListView {
            id: usersList
            anchors.fill: parent
            model: userModel
            delegate: Frame {
                width: ListView.view.width
                property bool isCurrentItem: ListView.isCurrentItem
                background: Rectangle {
                    color: isCurrentItem ? "steelblue" : "#eee"
                    border.color: "grey"
                }
                ItemDelegate {
                    id: userItem
                    width: parent.width
                    icon.source: model.iconPath
                    icon.color: isCurrentItem ? "white" : "grey"
                    palette.text: isCurrentItem ? "white" : "black"
                    text: model.userName
                    onClicked: {
                        usersList.currentIndex = index;
                        usersList.forceActiveFocus();
                        selected();
                    }
                }
            }
            Component.onCompleted: currentIndex = model.count - 1
        }
    
        ListModel {
            id: userModel
            ListElement { userName: "Bill Gates"; iconPath: "smile-32.svg" }
            ListElement { userName: "Steve Jobs"; iconPath: "user-32.svg" }
            ListElement { userName: "Jeff Bezos"; iconPath: "smile-32.svg" }
        }
    
        footer: Frame {
            Text {
                text: "currentIndex: " + currentIndex + " currentUserName: " + JSON.stringify(currentUserName) + " currentIconPath: " + JSON.stringify(currentIconPath) + " "
            }
        }
    }
    
    //smile-32.svg
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M16 29.8A13.8 13.8 0 1 1 29.8 16 13.815 13.815 0 0 1 16 29.8zm0-26.6A12.8 12.8 0 1 0 28.8 16 12.815 12.815 0 0 0 16 3.2zm-4.5 10.6a1.2 1.2 0 0 0 .608-.168 1.52 1.52 0 0 0 .464-.43 1.927 1.927 0 0 0 .278-.572 2.234 2.234 0 0 0 0-1.26 1.927 1.927 0 0 0-.278-.571 1.52 1.52 0 0 0-.464-.431 1.185 1.185 0 0 0-1.216 0 1.52 1.52 0 0 0-.464.43 1.927 1.927 0 0 0-.277.572 2.234 2.234 0 0 0 0 1.26 1.927 1.927 0 0 0 .277.571 1.52 1.52 0 0 0 .464.431 1.2 1.2 0 0 0 .608.168zm9.608-.168a1.52 1.52 0 0 0 .464-.43 1.927 1.927 0 0 0 .278-.572 2.234 2.234 0 0 0 0-1.26 1.927 1.927 0 0 0-.278-.571 1.52 1.52 0 0 0-.464-.431 1.185 1.185 0 0 0-1.216 0 1.52 1.52 0 0 0-.464.43 1.927 1.927 0 0 0-.277.572 2.234 2.234 0 0 0 0 1.26 1.927 1.927 0 0 0 .277.571 1.52 1.52 0 0 0 .464.431 1.185 1.185 0 0 0 1.216 0zm3.223 5.743l-.926-.379a7.863 7.863 0 0 1-7.39 4.976.166.166 0 0 0-.032 0 7.863 7.863 0 0 1-7.388-4.976l-.926.379a8.846 8.846 0 0 0 8.313 5.597.21.21 0 0 0 .035 0 8.848 8.848 0 0 0 8.314-5.597z"/><path fill="none" d="M0 0h32v32H0z"/></svg>
    
    //user-32.svg
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M19.5 15h-7A6.508 6.508 0 0 0 6 21.5V29h20v-7.5a6.508 6.508 0 0 0-6.5-6.5zM25 28H7v-6.5a5.506 5.506 0 0 1 5.5-5.5h7a5.506 5.506 0 0 1 5.5 5.5zm-9-14.2A5.8 5.8 0 1 0 10.2 8a5.806 5.806 0 0 0 5.8 5.8zm0-10.633A4.833 4.833 0 1 1 11.167 8 4.839 4.839 0 0 1 16 3.167z"/><path fill="none" d="M0 0h32v32H0z"/></svg>
    

    You can Try it Online!