NTextInput: simplified code in an attempt to fix text selection issues with mouse.

Not fixed yet, but I know where the conflict is!
This commit is contained in:
LemmyCook 2025-09-05 15:08:45 -04:00
parent 56fedcf495
commit 3140039ccb
5 changed files with 81 additions and 92 deletions

View file

@ -243,52 +243,45 @@ NPanel {
anchors.margins: Style.marginL * scaling anchors.margins: Style.marginL * scaling
spacing: Style.marginM * scaling spacing: Style.marginM * scaling
Item { NTextInput {
id: searchInputWrap id: searchInput
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: Math.round(Style.barHeight * scaling)
NTextInput { fontSize: Style.fontSizeL * scaling
id: searchInput fontWeight: Style.fontWeightSemiBold
anchors.fill: parent
inputMaxWidth: Number.MAX_SAFE_INTEGER
fontSize: Style.fontSizeL * scaling text: searchText
fontWeight: Style.fontWeightSemiBold placeholderText: "Search entries... or use > for commands"
text: searchText onTextChanged: searchText = text
placeholderText: "Search entries... or use > for commands"
onTextChanged: searchText = text Component.onCompleted: {
if (searchInput.inputItem && searchInput.inputItem.visible) {
searchInput.inputItem.forceActiveFocus()
Component.onCompleted: { // Override the TextField's default Home/End behavior
if (searchInput.inputItem && searchInput.inputItem.visible) { searchInput.inputItem.Keys.priority = Keys.BeforeItem
searchInput.inputItem.forceActiveFocus() searchInput.inputItem.Keys.onPressed.connect(function (event) {
// Intercept Home and End BEFORE the TextField handles them
// Override the TextField's default Home/End behavior if (event.key === Qt.Key_Home) {
searchInput.inputItem.Keys.priority = Keys.BeforeItem ui.selectFirst()
searchInput.inputItem.Keys.onPressed.connect(function (event) { event.accepted = true
// Intercept Home and End BEFORE the TextField handles them return
if (event.key === Qt.Key_Home) { } else if (event.key === Qt.Key_End) {
ui.selectFirst() ui.selectLast()
event.accepted = true event.accepted = true
return return
} else if (event.key === Qt.Key_End) { }
ui.selectLast() })
event.accepted = true searchInput.inputItem.Keys.onDownPressed.connect(function (event) {
return ui.selectNext()
} })
}) searchInput.inputItem.Keys.onUpPressed.connect(function (event) {
searchInput.inputItem.Keys.onDownPressed.connect(function (event) { ui.selectPrevious()
ui.selectNext() })
}) searchInput.inputItem.Keys.onReturnPressed.connect(function (event) {
searchInput.inputItem.Keys.onUpPressed.connect(function (event) { ui.activate()
ui.selectPrevious() })
})
searchInput.inputItem.Keys.onReturnPressed.connect(function (event) {
ui.activate()
})
}
} }
} }
} }

View file

@ -477,25 +477,23 @@ NPanel {
} }
} }
sourceComponent: ColumnLayout { sourceComponent: ScrollView {
ScrollView { id: scrollView
id: scrollView Layout.fillWidth: true
Layout.fillWidth: true Layout.fillHeight: true
Layout.fillHeight: true ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff ScrollBar.vertical.policy: ScrollBar.AsNeeded
ScrollBar.vertical.policy: ScrollBar.AsNeeded padding: Style.marginL * scaling
padding: Style.marginL * scaling clip: true
clip: true
Component.onCompleted: { Component.onCompleted: {
root.activeScrollView = scrollView root.activeScrollView = scrollView
} }
Loader { Loader {
active: true active: true
sourceComponent: root.tabsModel[index].source sourceComponent: root.tabsModel[index].source
width: scrollView.availableWidth width: scrollView.availableWidth
}
} }
} }
} }

View file

@ -22,9 +22,11 @@ ColumnLayout {
fallbackIcon: "person" fallbackIcon: "person"
borderColor: Color.mPrimary borderColor: Color.mPrimary
borderWidth: Math.max(1, Style.borderM * scaling) borderWidth: Math.max(1, Style.borderM * scaling)
Layout.alignment: Qt.AlignTop
} }
NTextInput { NTextInput {
Layout.fillWidth: true
label: `${Quickshell.env("USER") || "user"}'s profile picture` label: `${Quickshell.env("USER") || "user"}'s profile picture`
description: "Your profile picture that appears throughout the interface." description: "Your profile picture that appears throughout the interface."
text: Settings.data.general.avatarImage text: Settings.data.general.avatarImage

View file

@ -278,7 +278,6 @@ ColumnLayout {
NTextInput { NTextInput {
label: "Custom Interval" label: "Custom Interval"
description: "Enter time as HH:MM (e.g., 01:30)." description: "Enter time as HH:MM (e.g., 01:30)."
inputMaxWidth: 100 * scaling
text: { text: {
const s = Settings.data.wallpaper.randomIntervalSec const s = Settings.data.wallpaper.randomIntervalSec
const h = Math.floor(s / 3600) const h = Math.floor(s / 3600)

View file

@ -11,7 +11,6 @@ ColumnLayout {
property string description: "" property string description: ""
property bool readOnly: false property bool readOnly: false
property bool enabled: true property bool enabled: true
property int inputMaxWidth: Math.round(420 * scaling)
property color labelColor: Color.mOnSurface property color labelColor: Color.mOnSurface
property color descriptionColor: Color.mOnSurfaceVariant property color descriptionColor: Color.mOnSurfaceVariant
property string fontFamily: Settings.data.ui.fontDefault property string fontFamily: Settings.data.ui.fontDefault
@ -26,7 +25,6 @@ ColumnLayout {
signal editingFinished signal editingFinished
spacing: Style.marginS * scaling spacing: Style.marginS * scaling
implicitHeight: frame.height
NLabel { NLabel {
label: root.label label: root.label
@ -34,6 +32,7 @@ ColumnLayout {
labelColor: root.labelColor labelColor: root.labelColor
descriptionColor: root.descriptionColor descriptionColor: root.descriptionColor
visible: root.label !== "" || root.description !== "" visible: root.label !== "" || root.description !== ""
Layout.fillWidth: true
} }
// Container // Container
@ -42,50 +41,48 @@ ColumnLayout {
Layout.fillWidth: true Layout.fillWidth: true
Layout.minimumWidth: 80 * scaling Layout.minimumWidth: 80 * scaling
Layout.maximumWidth: root.inputMaxWidth
implicitWidth: parent.width
implicitHeight: Style.baseWidgetSize * 1.1 * scaling implicitHeight: Style.baseWidgetSize * 1.1 * scaling
radius: Style.radiusM * scaling radius: Style.radiusM * scaling
color: Color.mSurface color: Color.mSurface
border.color: Color.mOutline border.color: input.activeFocus ? Color.mSecondary : Color.mOutline
border.width: Math.max(1, Style.borderS * scaling) border.width: Math.max(1, Style.borderS * scaling)
// Focus ring Behavior on border.color {
Rectangle { ColorAnimation {
anchors.fill: parent duration: Style.animationFast
radius: frame.radius
color: Color.transparent
border.color: input.activeFocus ? Color.mSecondary : Color.transparent
border.width: input.activeFocus ? Math.max(1, Style.borderS * scaling) : 0
Behavior on border.color {
ColorAnimation {
duration: Style.animationFast
}
} }
} }
RowLayout { TextField {
id: input
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: Style.marginM * scaling anchors.leftMargin: Style.marginM * scaling
anchors.rightMargin: Style.marginM * scaling anchors.rightMargin: Style.marginM * scaling
spacing: Style.marginS * scaling
TextField { verticalAlignment: TextInput.AlignVCenter
id: input
Layout.fillWidth: true echoMode: TextInput.Normal
echoMode: TextInput.Normal readOnly: root.readOnly
readOnly: root.readOnly enabled: root.enabled
enabled: root.enabled color: Color.mOnSurface
color: Color.mOnSurface placeholderTextColor: Qt.alpha(Color.mOnSurfaceVariant, 0.6)
placeholderTextColor: Qt.alpha(Color.mOnSurfaceVariant, 0.6)
background: null selectByMouse: true
font.family: fontFamily
font.pointSize: fontSize topPadding: 0
font.weight: fontWeight bottomPadding: 0
onEditingFinished: root.editingFinished() leftPadding: 0
} rightPadding: 0
background: null
font.family: root.fontFamily
font.pointSize: root.fontSize
font.weight: root.fontWeight
onEditingFinished: root.editingFinished()
} }
} }
} }