mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-10-14 23:34:01 -04:00
Pressing Enter in the name field fires both the text field's accepted
signal and the dialog's own Return handler, so submitAndClose() runs
twice. The first call renames and hides the window, which clears the
field; the second call then renames to an empty string and unsets the
workspace name. The OK button only fires once, so it was unaffected.
Ignore submits once the window is hidden.
Signed-off-by: Thomas Kroll <[email protected]>
(cherry picked from commit eb0cb80884)
256 lines
8.5 KiB
QML
256 lines
8.5 KiB
QML
import QtQuick
|
|
import Quickshell
|
|
import qs.Common
|
|
import qs.Services
|
|
import qs.Widgets
|
|
|
|
DankFloatingWindow {
|
|
id: root
|
|
readonly property var log: Log.scoped("WorkspaceRenameModal")
|
|
|
|
readonly property int inputFieldHeight: Theme.fontSizeMedium + Theme.spacingL * 2
|
|
property var aqueousWorkspace: null
|
|
property bool renaming: false
|
|
|
|
objectName: "workspaceRenameModal"
|
|
title: I18n.tr("Rename Workspace")
|
|
minimumSize: Qt.size(400, 160)
|
|
maximumSize: Qt.size(400, 160)
|
|
visible: false
|
|
|
|
onClosed: hide()
|
|
|
|
function show(name) {
|
|
if (CompositorService.isAqueous) {
|
|
if (renaming)
|
|
return false;
|
|
const workspace = AqueousService.workspaces.find(ws => ws.output === AqueousService.seat?.output && ws.active);
|
|
if (!AqueousService.available || !AqueousService.seat || !workspace || !AqueousService.capabilities.commands || AqueousService.locked) {
|
|
ToastService.showError(I18n.tr("Error"), I18n.tr("Unavailable"));
|
|
return false;
|
|
}
|
|
aqueousWorkspace = {
|
|
id: workspace.id,
|
|
session: workspace.aqueousSession
|
|
};
|
|
name = workspace.name;
|
|
}
|
|
nameInput.text = name;
|
|
visible = true;
|
|
Qt.callLater(() => nameInput.forceActiveFocus());
|
|
return true;
|
|
}
|
|
|
|
function hide() {
|
|
visible = false;
|
|
}
|
|
|
|
function submitAndClose() {
|
|
if (!root.visible)
|
|
return;
|
|
if (aqueousWorkspace || CompositorService.isAqueous) {
|
|
if (!aqueousWorkspace || renaming)
|
|
return;
|
|
const target = aqueousWorkspace;
|
|
renaming = true;
|
|
AqueousService.command("workspace.rename", {
|
|
id: target.id,
|
|
session: target.session,
|
|
name: nameInput.text
|
|
}, success => {
|
|
if (root.aqueousWorkspace !== target)
|
|
return;
|
|
root.renaming = false;
|
|
if (success)
|
|
root.hide();
|
|
});
|
|
return;
|
|
}
|
|
renameWorkspace(nameInput.text);
|
|
hide();
|
|
}
|
|
|
|
function renameWorkspace(name) {
|
|
if (CompositorService.isNiri) {
|
|
NiriService.renameWorkspace(name);
|
|
} else if (CompositorService.isHyprland) {
|
|
HyprlandService.renameWorkspace(name);
|
|
} else {
|
|
log.warn("rename not supported for this compositor");
|
|
}
|
|
}
|
|
|
|
onVisibleChanged: {
|
|
if (visible) {
|
|
Qt.callLater(() => nameInput.forceActiveFocus());
|
|
return;
|
|
}
|
|
nameInput.text = "";
|
|
aqueousWorkspace = null;
|
|
renaming = false;
|
|
}
|
|
|
|
FocusScope {
|
|
id: contentFocusScope
|
|
|
|
anchors.fill: parent
|
|
focus: true
|
|
|
|
Keys.onEscapePressed: event => {
|
|
hide();
|
|
event.accepted = true;
|
|
}
|
|
|
|
Column {
|
|
id: contentCol
|
|
anchors.centerIn: parent
|
|
width: parent.width - Theme.spacingL * 2
|
|
spacing: Theme.spacingM
|
|
|
|
Item {
|
|
width: contentCol.width
|
|
height: Math.max(headerText.height, buttonRow.height)
|
|
|
|
MouseArea {
|
|
anchors.left: parent.left
|
|
anchors.right: buttonRow.left
|
|
anchors.rightMargin: Theme.spacingM
|
|
height: parent.height
|
|
onPressed: windowControls.tryStartMove()
|
|
onDoubleClicked: windowControls.tryToggleMaximize()
|
|
}
|
|
|
|
StyledText {
|
|
id: headerText
|
|
text: I18n.tr("Enter a new name for this workspace")
|
|
font.pixelSize: Theme.fontSizeMedium
|
|
color: Theme.surfaceTextMedium
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
width: parent.width - buttonRow.width - Theme.spacingM
|
|
}
|
|
|
|
Row {
|
|
id: buttonRow
|
|
anchors.right: parent.right
|
|
spacing: Theme.spacingXS
|
|
|
|
DankActionButton {
|
|
visible: windowControls.canMaximize
|
|
iconName: root.maximized ? "fullscreen_exit" : "fullscreen"
|
|
iconSize: Theme.iconSize - 4
|
|
iconColor: Theme.surfaceText
|
|
onClicked: windowControls.tryToggleMaximize()
|
|
}
|
|
|
|
DankActionButton {
|
|
iconName: "close"
|
|
iconSize: Theme.iconSize - 4
|
|
iconColor: Theme.surfaceText
|
|
onClicked: hide()
|
|
}
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
width: parent.width
|
|
height: inputFieldHeight
|
|
radius: Theme.cornerRadius
|
|
color: Theme.surfaceHover
|
|
border.color: nameInput.activeFocus ? Theme.primary : Theme.outlineStrong
|
|
border.width: nameInput.activeFocus ? 2 : 1
|
|
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
onClicked: nameInput.forceActiveFocus()
|
|
}
|
|
|
|
DankTextField {
|
|
id: nameInput
|
|
|
|
anchors.fill: parent
|
|
font.pixelSize: Theme.fontSizeMedium
|
|
textColor: Theme.surfaceText
|
|
placeholderText: I18n.tr("Workspace name")
|
|
backgroundColor: "transparent"
|
|
enabled: root.visible && !root.renaming
|
|
onAccepted: submitAndClose()
|
|
}
|
|
}
|
|
|
|
Item {
|
|
width: parent.width
|
|
height: 40
|
|
|
|
Row {
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
spacing: Theme.spacingM
|
|
|
|
Rectangle {
|
|
width: Math.max(70, cancelText.contentWidth + Theme.spacingM * 2)
|
|
height: 36
|
|
radius: Theme.cornerRadius
|
|
color: cancelArea.containsMouse ? Theme.surfaceTextHover : Theme.withAlpha(Theme.surfaceTextHover, 0)
|
|
border.color: Theme.surfaceVariantAlpha
|
|
border.width: 1
|
|
|
|
StyledText {
|
|
id: cancelText
|
|
anchors.centerIn: parent
|
|
text: I18n.tr("Cancel")
|
|
font.pixelSize: Theme.fontSizeMedium
|
|
color: Theme.surfaceText
|
|
font.weight: Font.Medium
|
|
}
|
|
|
|
MouseArea {
|
|
id: cancelArea
|
|
anchors.fill: parent
|
|
hoverEnabled: true
|
|
cursorShape: Qt.PointingHandCursor
|
|
onClicked: hide()
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
width: Math.max(80, renameText.contentWidth + Theme.spacingM * 2)
|
|
height: 36
|
|
radius: Theme.cornerRadius
|
|
color: renameArea.containsMouse ? Qt.darker(Theme.primary, 1.1) : Theme.primary
|
|
|
|
StyledText {
|
|
id: renameText
|
|
anchors.centerIn: parent
|
|
text: I18n.tr("Rename")
|
|
font.pixelSize: Theme.fontSizeMedium
|
|
color: Theme.background
|
|
font.weight: Font.Medium
|
|
}
|
|
|
|
MouseArea {
|
|
id: renameArea
|
|
enabled: !root.renaming
|
|
anchors.fill: parent
|
|
hoverEnabled: true
|
|
cursorShape: Qt.PointingHandCursor
|
|
onClicked: submitAndClose()
|
|
}
|
|
|
|
Behavior on color {
|
|
ColorAnimation {
|
|
duration: Theme.shortDuration
|
|
easing.type: Theme.standardEasing
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
FloatingWindowControls {
|
|
id: windowControls
|
|
targetWindow: root
|
|
}
|
|
}
|