No forgetting, deleting or clearing on a single press, anywhere
Claude-Session: https://claude.ai/code/session_01Ms2FbjQy31TVf3CEvQhGM8
This commit is contained in:
@@ -41,11 +41,36 @@ Item {
|
||||
return list;
|
||||
}
|
||||
|
||||
// Forgetting is armed in place rather than through ConfirmAction: a 44px
|
||||
// row inside a 300px popup has no width for a Keep/Forget it pair beside
|
||||
// the device name, so the trash glyph arms itself and the row's own
|
||||
// sublabel becomes the question. The token is ShellState's, the same one
|
||||
// ConfirmAction uses, so arming here disarms whatever was armed elsewhere
|
||||
// and only one confirm is ever live app-wide.
|
||||
//
|
||||
// The token is keyed by device address rather than held on the delegate,
|
||||
// because discovery rebuilds this list -- and every delegate in it -- every
|
||||
// time BlueZ reports something new. An arm parked on the row object would
|
||||
// be dropped by the next scan result; keyed by address it survives the
|
||||
// rebuild and is only ever cleared by a press or by the section closing.
|
||||
readonly property string forgetPrefix: "bluetooth-forget-quick:"
|
||||
|
||||
function forgetId(device): string {
|
||||
return root.forgetPrefix + (device.address || device.name || "");
|
||||
}
|
||||
|
||||
function disarmForget(): void {
|
||||
if (ShellState.armedConfirm.indexOf(root.forgetPrefix) === 0)
|
||||
ShellState.armedConfirm = "";
|
||||
}
|
||||
|
||||
onActiveChanged: {
|
||||
if (root.active)
|
||||
if (root.active) {
|
||||
Connectivity.acquireDiscovery(root.scanHold);
|
||||
else
|
||||
} else {
|
||||
Connectivity.releaseDiscovery(root.scanHold);
|
||||
root.disarmForget();
|
||||
}
|
||||
}
|
||||
|
||||
Component.onDestruction: Connectivity.releaseDiscovery(root.scanHold)
|
||||
@@ -106,18 +131,36 @@ Item {
|
||||
|
||||
required property var modelData
|
||||
|
||||
readonly property bool forgetArmed:
|
||||
ShellState.armedConfirm === root.forgetId(deviceRow.modelData)
|
||||
|
||||
width: parent.width
|
||||
// BlueZ reports a plain freedesktop name ("audio-headphones");
|
||||
// the symbolic variant is the one that can be recolored.
|
||||
icon: deviceRow.modelData.icon !== "" ? deviceRow.modelData.icon + "-symbolic" : "bluetooth-symbolic"
|
||||
iconFallback: "bluetooth-symbolic"
|
||||
label: deviceRow.modelData.name || deviceRow.modelData.address
|
||||
sublabel: root.stateText(deviceRow.modelData)
|
||||
// Armed, the row states the question and what it costs, since
|
||||
// the glyph alone is too small to carry either.
|
||||
sublabel: deviceRow.forgetArmed
|
||||
? "Press again to drop the pairing"
|
||||
: root.stateText(deviceRow.modelData)
|
||||
selected: deviceRow.modelData.connected
|
||||
onClicked: root.activate(deviceRow.modelData)
|
||||
// While armed the row body is the way out: a press anywhere
|
||||
// else on it takes the arming back instead of connecting, so
|
||||
// the escape is the largest target on screen.
|
||||
onClicked: {
|
||||
if (deviceRow.forgetArmed) {
|
||||
root.disarmForget();
|
||||
return;
|
||||
}
|
||||
root.activate(deviceRow.modelData);
|
||||
}
|
||||
|
||||
// Forgetting is destructive enough that it gets its own
|
||||
// control rather than sharing the row click.
|
||||
// control rather than sharing the row click -- and its own
|
||||
// two presses. See root.forgetPrefix for why the arming
|
||||
// happens in place here rather than through ConfirmAction.
|
||||
IconButton {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
visible: deviceRow.modelData.paired
|
||||
@@ -125,7 +168,28 @@ Item {
|
||||
iconSize: 13
|
||||
icon: "user-trash-symbolic"
|
||||
iconFallback: "window-close-symbolic"
|
||||
onClicked: deviceRow.modelData.forget()
|
||||
tint: deviceRow.forgetArmed ? Theme.danger : Theme.fg
|
||||
onClicked: {
|
||||
if (!deviceRow.forgetArmed) {
|
||||
ShellState.armedConfirm = root.forgetId(deviceRow.modelData);
|
||||
return;
|
||||
}
|
||||
root.disarmForget();
|
||||
deviceRow.modelData.forget();
|
||||
}
|
||||
|
||||
// Behind the parent's own fill, so the hover tint still
|
||||
// reads on top of it. Danger appears only once armed --
|
||||
// the first press must not look like the last one.
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
z: -1
|
||||
radius: parent.radius
|
||||
visible: deviceRow.forgetArmed
|
||||
color: Theme.alpha(Theme.danger, 0.3)
|
||||
border.width: 1
|
||||
border.color: Theme.alpha(Theme.danger, 0.6)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user