Add Qt/QML desktop shell and Nebula.UI
Introduce a new production desktop shell at `shells/desktop/shell` built with C++20, Qt Quick/QML, and LayerShellQt, including top bar, launcher, desktop surfaces, shell state, and mock app data. Add the shared `packages/nebula-ui` QML module (theme, controls, focus, icons) and wire it into the shell build. Retire the old GTK/WebKit native host by removing `shells/desktop/native`, move the React shell UI to `shells/desktop/prototype-react` as an archived design reference, and update root/compositor/session documentation to reflect the new Linux-only production architecture and temporary Sway role.
This commit is contained in:
@@ -0,0 +1,369 @@
|
||||
import QtQuick
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property string name: "nebula"
|
||||
property color color: Theme.textPrimary
|
||||
property int size: 16
|
||||
property real value: 1
|
||||
|
||||
implicitWidth: size
|
||||
implicitHeight: size
|
||||
Accessible.ignored: true
|
||||
|
||||
Canvas {
|
||||
id: canvas
|
||||
anchors.fill: parent
|
||||
antialiasing: true
|
||||
onPaint: root.paint(getContext("2d"))
|
||||
}
|
||||
|
||||
onNameChanged: canvas.requestPaint()
|
||||
onColorChanged: canvas.requestPaint()
|
||||
onValueChanged: canvas.requestPaint()
|
||||
onWidthChanged: canvas.requestPaint()
|
||||
onHeightChanged: canvas.requestPaint()
|
||||
|
||||
function paint(ctx) {
|
||||
ctx.reset()
|
||||
ctx.strokeStyle = root.color
|
||||
ctx.fillStyle = root.color
|
||||
ctx.lineCap = "round"
|
||||
ctx.lineJoin = "round"
|
||||
ctx.scale(width / 24, height / 24)
|
||||
|
||||
switch (root.name) {
|
||||
case "nebula":
|
||||
paintNebula(ctx)
|
||||
break
|
||||
case "search":
|
||||
paintSearch(ctx)
|
||||
break
|
||||
case "wifi":
|
||||
paintWifi(ctx)
|
||||
break
|
||||
case "speaker":
|
||||
paintSpeaker(ctx)
|
||||
break
|
||||
case "battery":
|
||||
paintBattery(ctx)
|
||||
break
|
||||
case "power":
|
||||
paintPower(ctx)
|
||||
break
|
||||
case "restart":
|
||||
paintRestart(ctx)
|
||||
break
|
||||
case "folder":
|
||||
paintFolder(ctx)
|
||||
break
|
||||
case "globe":
|
||||
paintGlobe(ctx)
|
||||
break
|
||||
case "terminal":
|
||||
paintTerminal(ctx)
|
||||
break
|
||||
case "settings":
|
||||
paintSettings(ctx)
|
||||
break
|
||||
case "game":
|
||||
paintGame(ctx)
|
||||
break
|
||||
case "photo":
|
||||
paintPhoto(ctx)
|
||||
break
|
||||
case "music":
|
||||
paintMusic(ctx)
|
||||
break
|
||||
case "document":
|
||||
paintDocument(ctx)
|
||||
break
|
||||
default:
|
||||
paintFolder(ctx)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
function paintNebula(ctx) {
|
||||
ctx.beginPath()
|
||||
ctx.arc(12, 12, 4.2, 0, Math.PI * 2)
|
||||
ctx.fill()
|
||||
|
||||
ctx.save()
|
||||
ctx.translate(12, 12)
|
||||
ctx.rotate(-26 * Math.PI / 180)
|
||||
ctx.scale(10 / 4.15, 1)
|
||||
ctx.lineWidth = 1.35 * (4.15 / 10)
|
||||
ctx.beginPath()
|
||||
ctx.arc(0, 0, 4.15, 0, Math.PI * 2)
|
||||
ctx.stroke()
|
||||
ctx.restore()
|
||||
}
|
||||
|
||||
function paintSearch(ctx) {
|
||||
ctx.lineWidth = 1.6
|
||||
ctx.beginPath()
|
||||
ctx.arc(11, 11, 6.25, 0, Math.PI * 2)
|
||||
ctx.stroke()
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(15.8, 15.8)
|
||||
ctx.lineTo(20, 20)
|
||||
ctx.stroke()
|
||||
}
|
||||
|
||||
function paintWifi(ctx) {
|
||||
const strength = root.value
|
||||
ctx.lineWidth = 1.6
|
||||
ctx.globalAlpha = strength > 0 ? 1 : 0.28
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(4.8, 15.2)
|
||||
ctx.bezierCurveTo(8.8, 11.2, 15.2, 11.2, 19.2, 15.2)
|
||||
ctx.stroke()
|
||||
ctx.globalAlpha = strength > 1 ? 1 : 0.28
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(7.4, 17.4)
|
||||
ctx.bezierCurveTo(10, 14.9, 14, 14.9, 16.6, 17.4)
|
||||
ctx.stroke()
|
||||
ctx.globalAlpha = 1
|
||||
ctx.beginPath()
|
||||
ctx.arc(12, 20, 1.15, 0, Math.PI * 2)
|
||||
ctx.fill()
|
||||
}
|
||||
|
||||
function paintSpeaker(ctx) {
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(4.5, 9.4)
|
||||
ctx.lineTo(7.6, 9.4)
|
||||
ctx.lineTo(12, 6.2)
|
||||
ctx.lineTo(12, 17.8)
|
||||
ctx.lineTo(7.6, 14.6)
|
||||
ctx.lineTo(4.5, 14.6)
|
||||
ctx.closePath()
|
||||
ctx.fill()
|
||||
ctx.lineWidth = 1.5
|
||||
ctx.beginPath()
|
||||
ctx.arc(12.5, 12, 4.2, -0.7, 0.7)
|
||||
ctx.stroke()
|
||||
ctx.globalAlpha = 0.7
|
||||
ctx.beginPath()
|
||||
ctx.arc(12.5, 12, 7.2, -0.85, 0.85)
|
||||
ctx.stroke()
|
||||
ctx.globalAlpha = 1
|
||||
}
|
||||
|
||||
function paintBattery(ctx) {
|
||||
ctx.lineWidth = 1.5
|
||||
ctx.beginPath()
|
||||
roundedRect(ctx, 2.5, 7.25, 16.5, 9.5, 2)
|
||||
ctx.stroke()
|
||||
ctx.beginPath()
|
||||
roundedRect(ctx, 19.5, 10, 2, 4, 0.6)
|
||||
ctx.fill()
|
||||
const fillWidth = Math.max(1.5, (14 * Math.min(100, Math.max(0, root.value))) / 100)
|
||||
ctx.beginPath()
|
||||
roundedRect(ctx, 4.2, 9, fillWidth, 6, 1)
|
||||
ctx.fill()
|
||||
}
|
||||
|
||||
function paintPower(ctx) {
|
||||
ctx.lineWidth = 1.7
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(12, 4.5)
|
||||
ctx.lineTo(12, 11.7)
|
||||
ctx.stroke()
|
||||
ctx.beginPath()
|
||||
ctx.arc(12, 13, 6.2, Math.PI * 1.15, Math.PI * -0.15, false)
|
||||
ctx.stroke()
|
||||
}
|
||||
|
||||
function paintRestart(ctx) {
|
||||
ctx.lineWidth = 1.7
|
||||
ctx.beginPath()
|
||||
ctx.arc(12, 12, 7, -0.2, Math.PI * 1.55, true)
|
||||
ctx.stroke()
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(19, 5.2)
|
||||
ctx.lineTo(19, 9.6)
|
||||
ctx.lineTo(14.6, 9.6)
|
||||
ctx.stroke()
|
||||
}
|
||||
|
||||
function paintFolder(ctx) {
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(3.5, 8.2)
|
||||
ctx.quadraticCurveTo(3.5, 6.4, 5.3, 6.4)
|
||||
ctx.lineTo(9.4, 6.4)
|
||||
ctx.lineTo(11, 8.2)
|
||||
ctx.lineTo(18.7, 8.2)
|
||||
ctx.quadraticCurveTo(20.5, 8.2, 20.5, 10)
|
||||
ctx.lineTo(20.5, 16.8)
|
||||
ctx.quadraticCurveTo(20.5, 18.6, 18.7, 18.6)
|
||||
ctx.lineTo(5.3, 18.6)
|
||||
ctx.quadraticCurveTo(3.5, 18.6, 3.5, 16.8)
|
||||
ctx.closePath()
|
||||
ctx.fill()
|
||||
}
|
||||
|
||||
function paintGlobe(ctx) {
|
||||
ctx.lineWidth = 1.6
|
||||
ctx.beginPath()
|
||||
ctx.arc(12, 12, 7.25, 0, Math.PI * 2)
|
||||
ctx.stroke()
|
||||
ctx.lineWidth = 1.4
|
||||
ctx.save()
|
||||
ctx.translate(12, 12)
|
||||
ctx.scale(3.1 / 7.25, 1)
|
||||
ctx.beginPath()
|
||||
ctx.arc(0, 0, 7.25, 0, Math.PI * 2)
|
||||
ctx.stroke()
|
||||
ctx.restore()
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(5.2, 12)
|
||||
ctx.lineTo(18.8, 12)
|
||||
ctx.stroke()
|
||||
}
|
||||
|
||||
function paintTerminal(ctx) {
|
||||
ctx.lineWidth = 1.7
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(7, 9.2)
|
||||
ctx.lineTo(10.4, 12)
|
||||
ctx.lineTo(7, 14.8)
|
||||
ctx.stroke()
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(12.2, 15.2)
|
||||
ctx.lineTo(17, 15.2)
|
||||
ctx.stroke()
|
||||
}
|
||||
|
||||
function paintSettings(ctx) {
|
||||
ctx.beginPath()
|
||||
ctx.arc(12, 12, 2.4, 0, Math.PI * 2)
|
||||
ctx.fill()
|
||||
ctx.lineWidth = 1.6
|
||||
const ticks = [
|
||||
[12, 5.2, 12, 6.8],
|
||||
[12, 17.2, 12, 18.8],
|
||||
[5.2, 12, 6.8, 12],
|
||||
[17.2, 12, 18.8, 12],
|
||||
[7.2, 7.2, 8.3, 8.3],
|
||||
[15.7, 15.7, 16.8, 16.8],
|
||||
[16.8, 7.2, 15.7, 8.3],
|
||||
[8.3, 15.7, 7.2, 16.8]
|
||||
]
|
||||
for (let i = 0; i < ticks.length; i++) {
|
||||
const t = ticks[i]
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(t[0], t[1])
|
||||
ctx.lineTo(t[2], t[3])
|
||||
ctx.stroke()
|
||||
}
|
||||
}
|
||||
|
||||
function paintGame(ctx) {
|
||||
ctx.lineWidth = 1.5
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(5.2, 10.4)
|
||||
ctx.lineTo(18.8, 10.4)
|
||||
ctx.quadraticCurveTo(20.4, 10.4, 20.3, 12.1)
|
||||
ctx.lineTo(19.8, 15.3)
|
||||
ctx.quadraticCurveTo(19.6, 16.9, 18.5, 16.9)
|
||||
ctx.lineTo(16.3, 16.9)
|
||||
ctx.lineTo(15, 15.1)
|
||||
ctx.lineTo(10, 15.1)
|
||||
ctx.lineTo(8.7, 16.9)
|
||||
ctx.lineTo(6.5, 16.9)
|
||||
ctx.quadraticCurveTo(5.4, 16.9, 5.2, 15.3)
|
||||
ctx.lineTo(4.7, 12.1)
|
||||
ctx.quadraticCurveTo(4.6, 10.4, 5.2, 10.4)
|
||||
ctx.closePath()
|
||||
ctx.stroke()
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(8, 12.4)
|
||||
ctx.lineTo(8, 15.6)
|
||||
ctx.moveTo(6.4, 14)
|
||||
ctx.lineTo(9.6, 14)
|
||||
ctx.stroke()
|
||||
ctx.beginPath()
|
||||
ctx.arc(15.4, 13.2, 0.9, 0, Math.PI * 2)
|
||||
ctx.fill()
|
||||
ctx.beginPath()
|
||||
ctx.arc(17.2, 15, 0.9, 0, Math.PI * 2)
|
||||
ctx.fill()
|
||||
}
|
||||
|
||||
function paintPhoto(ctx) {
|
||||
ctx.lineWidth = 1.5
|
||||
ctx.beginPath()
|
||||
roundedRect(ctx, 4, 6.2, 16, 11.6, 2)
|
||||
ctx.stroke()
|
||||
ctx.beginPath()
|
||||
ctx.arc(9, 10.2, 1.3, 0, Math.PI * 2)
|
||||
ctx.fill()
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(7.2, 15.8)
|
||||
ctx.lineTo(10.6, 12.4)
|
||||
ctx.lineTo(13.2, 15)
|
||||
ctx.lineTo(15.4, 12.9)
|
||||
ctx.lineTo(18.8, 15.8)
|
||||
ctx.stroke()
|
||||
}
|
||||
|
||||
function paintMusic(ctx) {
|
||||
ctx.lineWidth = 1.6
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(10, 16.6)
|
||||
ctx.lineTo(10, 7.4)
|
||||
ctx.lineTo(18, 5.8)
|
||||
ctx.lineTo(18, 15.2)
|
||||
ctx.stroke()
|
||||
ctx.beginPath()
|
||||
ctx.arc(8.2, 16.6, 2.2, 0, Math.PI * 2)
|
||||
ctx.fill()
|
||||
ctx.beginPath()
|
||||
ctx.arc(16.2, 15.2, 2.2, 0, Math.PI * 2)
|
||||
ctx.fill()
|
||||
}
|
||||
|
||||
function paintDocument(ctx) {
|
||||
ctx.lineWidth = 1.5
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(7, 5.5)
|
||||
ctx.lineTo(13.2, 5.5)
|
||||
ctx.lineTo(17.5, 10)
|
||||
ctx.lineTo(17.5, 18.5)
|
||||
ctx.quadraticCurveTo(17.5, 20, 16, 20)
|
||||
ctx.lineTo(7, 20)
|
||||
ctx.quadraticCurveTo(5.5, 20, 5.5, 18.5)
|
||||
ctx.lineTo(5.5, 7)
|
||||
ctx.quadraticCurveTo(5.5, 5.5, 7, 5.5)
|
||||
ctx.closePath()
|
||||
ctx.stroke()
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(13.2, 5.5)
|
||||
ctx.lineTo(13.2, 10)
|
||||
ctx.lineTo(17.5, 10)
|
||||
ctx.stroke()
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(8.8, 13.4)
|
||||
ctx.lineTo(15.2, 13.4)
|
||||
ctx.moveTo(8.8, 16.2)
|
||||
ctx.lineTo(13.2, 16.2)
|
||||
ctx.stroke()
|
||||
}
|
||||
|
||||
function roundedRect(ctx, x, y, w, h, r) {
|
||||
const radius = Math.min(r, w / 2, h / 2)
|
||||
ctx.moveTo(x + radius, y)
|
||||
ctx.lineTo(x + w - radius, y)
|
||||
ctx.quadraticCurveTo(x + w, y, x + w, y + radius)
|
||||
ctx.lineTo(x + w, y + h - radius)
|
||||
ctx.quadraticCurveTo(x + w, y + h, x + w - radius, y + h)
|
||||
ctx.lineTo(x + radius, y + h)
|
||||
ctx.quadraticCurveTo(x, y + h, x, y + h - radius)
|
||||
ctx.lineTo(x, y + radius)
|
||||
ctx.quadraticCurveTo(x, y, x + radius, y)
|
||||
ctx.closePath()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user