aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--desktop/island/ClockPill.qml38
-rw-r--r--desktop/island/Island.qml10
-rw-r--r--desktop/island/calendar/CalendarPanel.qml4
3 files changed, 45 insertions, 7 deletions
diff --git a/desktop/island/ClockPill.qml b/desktop/island/ClockPill.qml
index 93e840f..4ed8e38 100644
--- a/desktop/island/ClockPill.qml
+++ b/desktop/island/ClockPill.qml
@@ -14,16 +14,31 @@ import Quickshell.Widgets
import QtQuick
import ".."
import "../modules/vm"
+import "calendar"
import "Logic.js" as Logic
// Date and time at rest, with one dot per VM that is not plainly shut off.
// During a flick: the workspace's desktop icon, the app's icon and its name.
+// A click opens the calendar panel in this capsule.
Capsule {
id: pill
property bool flicking: false
property string flickWs: ""
property string flickApp: ""
+ property string panel: ""
+
+ signal openCalendar()
+ signal closeCalendar()
+
+ expanded: panel === "calendar"
+ panelWidth: 620
+ panelHeight: calendarPanel.implicitHeight + 28
+
+ // The island calls these: focus moves into the panel when it opens, and
+ // Escape asks the panel before closing it.
+ function focusPanel() { calendarPanel.reset(); calendarPanel.forceActiveFocus(); }
+ function back() { return calendarPanel.back(); }
readonly property var entry: flickApp ? DesktopEntries.heuristicLookup(flickApp) : null
readonly property string wsIcon: Workspaces.icon(flickWs)
@@ -42,7 +57,7 @@ Capsule {
id: restRow
anchors.centerIn: parent
spacing: 10
- opacity: pill.flicking ? 0 : 1
+ opacity: pill.flicking || pill.expanded ? 0 : 1
Behavior on opacity { NumberAnimation { duration: 150 } }
Text {
@@ -74,7 +89,7 @@ Capsule {
id: flickRow
anchors.centerIn: parent
spacing: 8
- opacity: pill.flicking ? 1 : 0
+ opacity: pill.flicking && !pill.expanded ? 1 : 0
Behavior on opacity { NumberAnimation { duration: 150 } }
// The desktop sits in a badge so it does not read as a second app
@@ -126,4 +141,23 @@ Capsule {
color: Theme.text
}
}
+
+ // At rest the whole pill is the button; open, the panel takes the clicks.
+ MouseArea {
+ anchors.fill: parent
+ enabled: !pill.expanded
+ cursorShape: Qt.PointingHandCursor
+ onClicked: pill.openCalendar()
+ }
+
+ CalendarPanel {
+ id: calendarPanel
+ x: 14
+ y: 14
+ width: pill.panelWidth - 28
+ opacity: pill.expanded ? 1 : 0
+ visible: opacity > 0
+ Behavior on opacity { NumberAnimation { duration: 160 } }
+ onCloseRequested: pill.closeCalendar()
+ }
}
diff --git a/desktop/island/Island.qml b/desktop/island/Island.qml
index 43422dc..61701d8 100644
--- a/desktop/island/Island.qml
+++ b/desktop/island/Island.qml
@@ -36,7 +36,7 @@ PanelWindow {
WlrLayershell.namespace: "quickshell-island"
WlrLayershell.keyboardFocus: panel !== "" ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
- // "", "sound" or "controls".
+ // "", "sound", "controls" or "calendar".
property string panel: ""
// --- reveal and hide -------------------------------------------------
@@ -57,7 +57,8 @@ PanelWindow {
else if (panel === "" && !menuHeld) hideTimer.restart();
}
onPanelChanged: {
- if (panel !== "") keys.forceActiveFocus();
+ if (panel === "calendar") clock.focusPanel();
+ else if (panel !== "") keys.forceActiveFocus();
else if (!hovered) hideTimer.restart();
}
@@ -140,7 +141,7 @@ PanelWindow {
// Key events reach a focused item, not the window (AGENTS.md).
Item {
id: keys
- Keys.onEscapePressed: win.panel = ""
+ Keys.onEscapePressed: if (!(win.panel === "calendar" && clock.back())) win.panel = ""
}
// --- geometry --------------------------------------------------------
@@ -202,6 +203,9 @@ PanelWindow {
flicking: win.flicking
flickWs: win.flickWs
flickApp: win.flickApp
+ panel: win.panel
+ onOpenCalendar: win.panel = win.panel === "calendar" ? "" : "calendar"
+ onCloseCalendar: win.panel = ""
}
StatusPill {
diff --git a/desktop/island/calendar/CalendarPanel.qml b/desktop/island/calendar/CalendarPanel.qml
index 9515a9a..5d193eb 100644
--- a/desktop/island/calendar/CalendarPanel.qml
+++ b/desktop/island/calendar/CalendarPanel.qml
@@ -90,12 +90,12 @@ Item {
}
// Escape: the editor first, then the panel.
- function escape() {
+ function back() {
if (panel.editing) { panel.closeEditor(); return true; }
return false;
}
- Keys.onEscapePressed: if (!panel.escape()) panel.closeRequested()
+ Keys.onEscapePressed: if (!panel.back()) panel.closeRequested()
Component.onCompleted: panel.reset()