repositories / dotfiles
dotfiles
bugabingas dorkfiles
owned by admin
quickshell/nuguland/SurfaceManager.qml
Rawimport QtQuick
import "popoutCatalog.js" as PopoutCatalog
import "diagnostics.js" as DiagnosticData
Item {
id: root
property int operationId: 0
property bool popoutOpen: false
property bool popoutClosing: false
property string popoutPhase: "closed"
property string popoutName: ""
property string popoutOutput: ""
property string activeLoaderName: ""
property string pendingLoaderName: ""
property string removingLoaderName: ""
property var previousContent: ({})
property string lastInteraction: ""
property string lastCloseReason: ""
property rect popoutAnchor: Qt.rect(0, 0, 0, 0)
property real popoutProgress: 0
property int screenWidth: 0
property int screenHeight: 0
property int barHeight: 34
property string orientation: "horizontal"
property var powerService
property var mediaService
property var trayService
property Niri niriService
property var returnWindowId: null
readonly property bool vertical: orientation === "vertical"
property var anchorRegistry: ({})
// Ordinary view state lives for the shell session, never on disk.
property var panelStates: ({
"clock": {
"scrollY": 0
},
"system": {
"scrollY": 0
},
"notifications": {
"scrollY": 0
},
"noko": {
"scrollY": 0
},
"connectivity": {
"scrollY": 0,
"expandedSsid": ""
},
"launcher": {
"query": "",
"selectedId": "",
"scrollY": 0
},
"clipboard": {
"query": "",
"selectedId": "",
"scrollY": 0
},
"audio": {
"scrollY": 0,
"expandedSink": "",
"expandedSource": ""
},
"brightness": {
"scrollY": 0
},
"media": {
"scrollY": 0
},
"tray": {
"scrollY": 0
},
"power": {
"scrollY": 0
}
})
signal dismissing(string name)
readonly property int closeRetentionMs: 0
function parseRect(text) {
const parts = String(text).split(/[, x]+/).filter(p => {
return p.length > 0;
}).map(Number);
if (parts.length !== 4 || parts.some(n => {
return !Number.isFinite(n);
}))
return Qt.rect(0, 0, 0, 0);
return Qt.rect(parts[0], parts[1], parts[2], parts[3]);
}
function dismissTask() {
dismissing(popoutName);
if (popoutName === "power" && powerService)
powerService.cancelAction();
}
function rectObject(rect) {
return {
"x": Math.round(rect.x),
"y": Math.round(rect.y),
"width": Math.round(rect.width),
"height": Math.round(rect.height)
};
}
function emptyPanel(name) {
const service = name === "media" ? root.mediaService : (name === "tray" ? root.trayService : null);
if (!service)
return false;
const state = JSON.parse(service.stateJson());
return (name === "media" ? (state.players || []) : (state.items || [])).length === 0;
}
function popoutWidth(name) {
const entry = Object.prototype.hasOwnProperty.call(PopoutCatalog.entries, String(name)) ? PopoutCatalog.entries[String(name)] : null;
const wanted = emptyPanel(name) ? 368 : (entry ? entry.width : 520);
const along = vertical ? screenWidth - barHeight : screenWidth;
return along > 0 ? Math.min(wanted, Math.max(1, along - 16)) : wanted;
}
function heightBudget(wanted, minimum = 220) {
const reserve = vertical ? 48 : barHeight + 48;
const maxHeight = screenHeight > 0 ? Math.max(260, screenHeight - reserve) : 680;
return Math.min(maxHeight, Math.max(minimum, Number(wanted)));
}
function powerContentSize() {
const width = popoutWidth("power");
const state = powerService ? JSON.parse(powerService.stateJson()) : ({
"battery": {},
"externalDevices": []
});
const hasBattery = !!(state.battery && state.battery.present);
const deviceCount = (state.externalDevices || []).length;
const entry = PopoutCatalog.entries.power;
const deviceHeight = deviceCount > 0 ? Math.ceil(deviceCount / 2) * 40 + 4 : 0;
const confirmationHeight = state.pendingConfirmation ? 116 : 0;
return {
"width": width,
"height": heightBudget((hasBattery ? entry.batteryHeight : entry.height) + deviceHeight + confirmationHeight, entry.height)
};
}
function popoutContentSize(name) {
const key = String(name);
if (key === "power")
return powerContentSize();
const entry = Object.prototype.hasOwnProperty.call(PopoutCatalog.entries, key) ? PopoutCatalog.entries[key] : null;
return {
"width": popoutWidth(key),
"height": emptyPanel(key) ? heightBudget(104, 104) : heightBudget(entry ? entry.height : PopoutCatalog.fallbackHeight)
};
}
function popupWindowAnchorRect() {
if (vertical)
return {
"x": Math.max(1, Math.round(barHeight)),
"y": 0,
"width": 1,
"height": screenHeight > 0 ? screenHeight : popoutContentSize(popoutName).height
};
return {
"x": 0,
"y": Math.max(1, Math.round(barHeight)),
"width": screenWidth > 0 ? screenWidth : popoutContentSize(popoutName).width,
"height": 1
};
}
function popupCardFrame(progress) {
const t = Math.max(0, Math.min(1, Number(progress)));
const contentSize = popoutContentSize(popoutName);
if (vertical) {
const surfaceHeight = screenHeight > 0 ? screenHeight : contentSize.height;
return {
"source": "left-bar-slide-fade",
"progress": t,
"currentRect": {
"x": Math.round(barHeight - 18 + 26 * t),
"y": Math.max(8, Math.round((surfaceHeight - contentSize.height) / 2) + 8),
"width": Math.max(1, Math.round(contentSize.width - 16)),
"height": Math.max(1, Math.round(contentSize.height - 16))
},
"opacity": t
};
}
const surfaceWidth = screenWidth > 0 ? screenWidth : contentSize.width;
return {
"source": "simple-center-slide-fade",
"progress": t,
"currentRect": {
"x": Math.max(8, Math.round((surfaceWidth - contentSize.width) / 2) + 8),
"y": Math.round(barHeight - 18 + 26 * t),
"width": Math.max(1, Math.round(contentSize.width - 16)),
"height": Math.max(1, Math.round(contentSize.height - 16))
},
"opacity": t
};
}
function popoutContentCatalog() {
return PopoutCatalog.catalogJson();
}
function registerAnchor(name, anchorText) {
const next = Object.assign({}, anchorRegistry);
next[String(name)] = rectObject(parseRect(anchorText));
anchorRegistry = next;
return registeredAnchors();
}
function registeredAnchors() {
return JSON.stringify(anchorRegistry);
}
function setPopoutScreen(width, height, topBarThickness, orient) {
screenWidth = Math.max(0, Number(width));
screenHeight = Math.max(0, Number(height));
barHeight = Math.max(1, Number(topBarThickness || barHeight));
if (orient === "horizontal" || orient === "vertical")
orientation = orient;
return popoutState();
}
function clampedTarget(origin, contentSize) {
const edges = [];
if (vertical) {
let y = Math.round(origin.y - contentSize.height / 2);
if (y < 0) {
y = 0;
edges.push("top");
}
if (screenHeight > 0 && y + contentSize.height > screenHeight) {
y = Math.max(0, screenHeight - contentSize.height);
edges.length = 0;
edges.push("bottom");
}
return {
"rect": {
"x": Math.max(0, Math.round(barHeight)),
"y": y,
"width": contentSize.width,
"height": contentSize.height
},
"edges": edges
};
}
let x = Math.round(origin.x - contentSize.width / 2);
if (x < 0) {
x = 0;
edges.push("left");
}
if (screenWidth > 0 && x + contentSize.width > screenWidth) {
x = Math.max(0, screenWidth - contentSize.width);
edges.length = 0;
edges.push("right");
}
return {
"rect": {
"x": x,
"y": origin.y,
"width": contentSize.width,
"height": contentSize.height
},
"edges": edges
};
}
function openPopout(name, anchorText, outputName) {
const nextName = String(name);
const wasOpen = popoutOpen && !popoutClosing;
if (wasOpen && popoutName !== nextName)
dismissTask();
if (!wasOpen)
returnWindowId = niriService ? niriService.focusedWindow : null;
operationId = DiagnosticData.nextOperationId(operationId);
unloadTimer.stop();
openTimer.stop();
popoutClosing = false;
lastInteraction = "";
lastCloseReason = "";
popoutName = nextName;
popoutOutput = String(outputName || "");
activeLoaderName = nextName;
pendingLoaderName = "";
removingLoaderName = "";
previousContent = ({});
popoutAnchor = parseRect(anchorText);
popoutOpen = true;
if (wasOpen) {
popoutProgress = 1;
popoutPhase = "open";
} else {
popoutPhase = "opening";
popoutProgress = 0;
openTimer.restart();
}
console.info(JSON.stringify(DiagnosticData.transition(wasOpen ? "switched" : "opening", root)));
return popoutState();
}
function openRegisteredPopout(name, outputName) {
const anchor = anchorRegistry[String(name)] || {
"x": 0,
"y": 0,
"width": 0,
"height": 0
};
return openPopout(name, `${anchor.x},${anchor.y},${anchor.width},${anchor.height}`, outputName);
}
function hoverRegisteredPopout(name) {
// Hover is discovery, never navigation away from an active task.
return popoutState();
}
function closePopout(reason) {
if (!popoutOpen && !popoutClosing)
return popoutState();
dismissTask();
operationId = DiagnosticData.nextOperationId(operationId);
openTimer.stop();
if (reason && String(reason).length > 0)
lastCloseReason = String(reason);
popoutOpen = false;
popoutClosing = false;
popoutProgress = 0;
popoutPhase = "closed";
popoutName = "";
popoutOutput = "";
activeLoaderName = "";
pendingLoaderName = "";
removingLoaderName = "";
previousContent = ({});
console.info(JSON.stringify(DiagnosticData.transition("closed", root)));
return popoutState();
}
function popoutInteraction(kind) {
lastInteraction = String(kind);
if (lastInteraction === "inside")
return popoutState();
if (lastInteraction === "outside" || lastInteraction === "escape" || lastInteraction === "focus-grab-outside" || lastInteraction === "escape-key")
return closePopout(lastInteraction);
return popoutState();
}
function popoutState() {
const contentSize = popoutContentSize(popoutName);
const origin = vertical ? {
"x": Math.round(popoutAnchor.x + popoutAnchor.width),
"y": Math.round(popoutAnchor.y + popoutAnchor.height / 2)
} : {
"x": Math.round(popoutAnchor.x + popoutAnchor.width / 2),
"y": Math.round(popoutAnchor.y + popoutAnchor.height)
};
const target = clampedTarget(origin, contentSize);
return JSON.stringify({
"open": popoutOpen,
"closing": popoutClosing,
"phase": popoutPhase,
"name": popoutName,
"output": popoutOutput,
"lastInteraction": lastInteraction,
"lastCloseReason": lastCloseReason,
"anchor": rectObject(popoutAnchor),
"origin": origin,
"contentSize": contentSize,
"popupAnchorRect": popupWindowAnchorRect(),
"popupCardFrame": popupCardFrame(popoutProgress),
"activeLoaderName": activeLoaderName,
"pendingLoaderName": pendingLoaderName,
"removingLoaderName": removingLoaderName,
"previousContent": previousContent,
"screen": {
"width": screenWidth,
"height": screenHeight,
"barHeight": barHeight
},
"progress": popoutProgress,
"transition": {
"host": "bar",
"animation": vertical ? "left-bar-slide-fade" : "simple-center-slide-fade",
"direction": vertical ? (popoutClosing ? "left-out" : "right-in") : (popoutClosing ? "up-out" : "down-in"),
"loaderActive": popoutOpen,
"targetRect": popupWindowAnchorRect()
}
});
}
function completeOpen() {
if (!popoutOpen || popoutClosing || popoutPhase !== "opening")
return;
popoutProgress = 1;
popoutPhase = "open";
console.info(JSON.stringify(DiagnosticData.transition("opened", root)));
}
Timer {
id: openTimer
interval: root.closeRetentionMs
repeat: false
onTriggered: root.completeOpen()
}
Timer {
id: unloadTimer
interval: root.closeRetentionMs
repeat: false
onTriggered: {
root.popoutClosing = false;
root.popoutPhase = "closed";
root.popoutName = "";
root.popoutOutput = "";
root.activeLoaderName = "";
root.pendingLoaderName = "";
root.removingLoaderName = "";
root.previousContent = ({});
}
}
}