Add floating traffic-light window chrome

Introduces a dedicated layer-shell `WindowChromeSurface` that renders macOS-style traffic-light controls over the focused Sway window titlebar, replacing the old top-bar window controls. Adds theme tokens and a reusable `TrafficLightButton` component, updates shell QML/CMake wiring, and adjusts Sway titlebar padding/title format so window titles do not overlap the overlay. Window tracking was extended with focused-window geometry/deco/fullscreen properties plus backend refresh support so the chrome follows window movement and state changes in near real time.
This commit is contained in:
2026-08-26 22:38:33 +12:00
parent 08e67845a5
commit 4321209e92
14 changed files with 452 additions and 92 deletions
@@ -0,0 +1,43 @@
import QtQuick
import QtQuick.Window
import org.kde.layershell 1.0 as LayerShell
import Nebula.UI
import Nebula.Windows
Window {
id: root
readonly property bool active: WindowService.hasFocusedWindow
&& !WindowService.focusedWindowFullscreen
&& !ShellState.launcherOpen
readonly property int chromeX: WindowService.focusedWindowX
+ WindowService.focusedWindowDecoX
+ Theme.windowChromeInset
readonly property int chromeY: {
const top = WindowService.focusedWindowY + WindowService.focusedWindowDecoY
const decoHeight = WindowService.focusedWindowDecoHeight
if (decoHeight <= 0)
return top + 6
return top + Math.max(0, Math.round((decoHeight - height) / 2))
}
title: qsTr("Nebula Window Chrome")
color: "transparent"
flags: Qt.FramelessWindowHint | Qt.WindowDoesNotAcceptFocus
visible: root.active
width: Math.max(1, controls.implicitWidth)
height: Math.max(1, controls.implicitHeight)
LayerShell.Window.scope: "nebula-window-chrome"
LayerShell.Window.layer: LayerShell.Window.LayerTop
LayerShell.Window.anchors: LayerShell.Window.AnchorLeft | LayerShell.Window.AnchorTop
LayerShell.Window.margins.left: Math.max(0, chromeX)
LayerShell.Window.margins.top: Math.max(0, chromeY)
LayerShell.Window.exclusionZone: 0
LayerShell.Window.keyboardInteractivity: LayerShell.Window.KeyboardInteractivityNone
WindowControls {
id: controls
anchors.centerIn: parent
}
}