114 lines
3.1 KiB
QML
114 lines
3.1 KiB
QML
// The overview — a replacement for GNOME's Activities. Opened with Super+grave
|
|
// (the lead wires the IPC; this file only reacts to ShellState.overviewOpen).
|
|
//
|
|
// The compositor blurs and dims what is behind this surface via the
|
|
// `qs-overlay` layer rule; the scrim below adds the tint on top of that.
|
|
|
|
import Quickshell
|
|
import Quickshell.Wayland
|
|
import Quickshell.Hyprland
|
|
import QtQuick
|
|
import qs.config
|
|
import qs.services
|
|
|
|
PanelWindow {
|
|
id: root
|
|
|
|
anchors {
|
|
top: true
|
|
bottom: true
|
|
left: true
|
|
right: true
|
|
}
|
|
|
|
color: "transparent"
|
|
exclusiveZone: 0
|
|
exclusionMode: ExclusionMode.Ignore
|
|
|
|
// Matched by the `qs-overlay` layer rule in hypr/rules.lua — do not rename.
|
|
WlrLayershell.namespace: "qs-overview"
|
|
WlrLayershell.layer: WlrLayer.Overlay
|
|
WlrLayershell.keyboardFocus: root.open ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None
|
|
|
|
readonly property bool open: ShellState.overviewOpen
|
|
|
|
// The window has to stay mapped for the length of the close animation,
|
|
// otherwise it vanishes instantly and only the open transition is ever
|
|
// seen. `mapped` tracks overviewOpen, delayed on the way down.
|
|
property bool mapped: false
|
|
visible: mapped
|
|
|
|
// Each open bumps the token, which makes every thumbnail re-capture once.
|
|
// Nothing captures while the overview is closed or idle.
|
|
property int refreshToken: 0
|
|
|
|
onOpenChanged: {
|
|
if (open) {
|
|
unmapTimer.stop();
|
|
// The IPC/toplevel caches can lag a fast workspace switch.
|
|
Hyprland.refreshWorkspaces();
|
|
Hyprland.refreshToplevels();
|
|
mapped = true;
|
|
refreshToken++;
|
|
Qt.callLater(() => body.prepare());
|
|
} else {
|
|
unmapTimer.restart();
|
|
}
|
|
}
|
|
|
|
Timer {
|
|
id: unmapTimer
|
|
interval: Theme.durNormal
|
|
onTriggered: root.mapped = false
|
|
}
|
|
|
|
Item {
|
|
id: surface
|
|
anchors.fill: parent
|
|
focus: true
|
|
|
|
Keys.onEscapePressed: ShellState.close()
|
|
|
|
opacity: root.open ? 1 : 0
|
|
|
|
Behavior on opacity {
|
|
NumberAnimation {
|
|
duration: Theme.durNormal
|
|
easing.type: Easing.OutCubic
|
|
}
|
|
}
|
|
|
|
transform: Scale {
|
|
origin.x: surface.width / 2
|
|
origin.y: surface.height / 2
|
|
xScale: root.open ? 1 : 0.96
|
|
yScale: xScale
|
|
|
|
Behavior on xScale {
|
|
NumberAnimation {
|
|
duration: Theme.durNormal
|
|
easing.type: Easing.OutCubic
|
|
}
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
anchors.fill: parent
|
|
color: Theme.alpha(Theme.bgDark, Theme.overlayAlpha)
|
|
|
|
// Clicking anywhere that is not a card dismisses, as in GNOME.
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
onClicked: ShellState.close()
|
|
}
|
|
}
|
|
|
|
OverviewBody {
|
|
id: body
|
|
anchors.fill: parent
|
|
refreshToken: root.refreshToken
|
|
open: root.open
|
|
}
|
|
}
|
|
}
|