diff --git a/reload-popup/README.md b/reload-popup/README.md new file mode 100644 index 0000000..2f29168 --- /dev/null +++ b/reload-popup/README.md @@ -0,0 +1,14 @@ +# Reload Popup + +A popup in the corner of the screen that appears when hot reloading the configuration, +which you can easily add to an existing shell. + +You can try it out by running `quickshell -p shell.qml` which will put a simple bar +on the screen. The popup will appear if the file is edited, and display the error +if the configuration is invalid. + +After making a good edit: +![](./reload-good.png) + +After making a bad edit: +![](./reload-bad.png) diff --git a/reload-popup/ReloadPopup.qml b/reload-popup/ReloadPopup.qml new file mode 100644 index 0000000..36b4a54 --- /dev/null +++ b/reload-popup/ReloadPopup.qml @@ -0,0 +1,126 @@ +import QtQuick +import QtQuick.Layouts +import Quickshell + +Scope { + id: root + property bool failed; + property string errorString; + + // Connect to the Quickshell global to listen for the reload signals. + Connections { + target: Quickshell + + function onReloadCompleted() { + root.failed = false; + popupLoader.loading = true; + } + + function onReloadFailed(error: string) { + // Close any existing popup before making a new one. + popupLoader.active = false; + + root.failed = true; + root.errorString = error; + popupLoader.loading = true; + } + } + + // Keep the popup in a loader because it isn't needed most of the timeand will take up + // memory that could be used for something else. + LazyLoader { + id: popupLoader + + PanelWindow { + id: popup + + anchors { + top: true + left: true + } + + margins { + top: 25 + left: 25 + } + + width: rect.width + height: rect.height + + // color blending is a bit odd as detailed in the type reference. + color: "transparent" + + Rectangle { + id: rect + color: failed ? "#40802020" : "#40009020" + + implicitHeight: layout.implicitHeight + 50 + implicitWidth: layout.implicitWidth + 30 + + // Fills the whole area of the rectangle, making any clicks go to it, + // which dismiss the popup. + MouseArea { + id: mouseArea + anchors.fill: parent + onClicked: popupLoader.active = false + + // makes the mouse area track mouse hovering, so the hide animation + // can be paused when hovering. + hoverEnabled: true + } + + ColumnLayout { + id: layout + anchors { + top: parent.top + topMargin: 20 + horizontalCenter: parent.horizontalCenter + } + + Text { + text: root.failed ? "Reload failed." : "Reloaded completed!" + color: "white" + } + + Text { + text: root.errorString + color: "white" + // When visible is false, it also takes up no space. + visible: root.errorString != "" + } + } + + // A progress bar on the bottom of the screen, showing how long until the + // popup is removed. + Rectangle { + id: bar + color: "#20ffffff" + anchors.bottom: parent.bottom + anchors.left: parent.left + height: 20 + + PropertyAnimation { + id: anim + target: bar + property: "width" + from: rect.width + to: 0 + duration: failed ? 10000 : 800 + onFinished: popupLoader.active = false + + // Pause the animation when the mouse is hovering over the popup, + // so it stays onscreen while reading. This updates reactively + // when the mouse moves on and off the popup. + paused: mouseArea.containsMouse + } + } + + // We could set `running: true` inside the animation, but the width of the + // rectangle might not be calculated yet, due to the layout. + // In the `Component.onCompleted` event handler, all of the component's + // properties and children have been initialized. + Component.onCompleted: anim.start() + } + } + } +} diff --git a/reload-popup/reload-bad.png b/reload-popup/reload-bad.png new file mode 100644 index 0000000..1ab3f9e Binary files /dev/null and b/reload-popup/reload-bad.png differ diff --git a/reload-popup/reload-good.png b/reload-popup/reload-good.png new file mode 100644 index 0000000..8e2745e Binary files /dev/null and b/reload-popup/reload-good.png differ diff --git a/reload-popup/shell.qml b/reload-popup/shell.qml new file mode 100644 index 0000000..04f9001 --- /dev/null +++ b/reload-popup/shell.qml @@ -0,0 +1,25 @@ +import QtQuick +import Quickshell + +ShellRoot { + // Add the popup to the shell. + ReloadPopup {} + + // The rest of your shell, in this case a very simple bar. + // Try editing this. + PanelWindow { + anchors { + left: true + top: true + right: true + } + + height: 30 + + Text { + anchors.centerIn: parent + text: "I'm a bar!" + an error + } + } +}