mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-10-22 03:04:01 -04:00
* mux: add herdr backend
* mux: remove herdr service tests
* mux: include herdr in settings subtitle
* mux: add translator context to the multiplexers subtitle
* mux: drive the service from a backend table
Each backend (tmux, zellij, herdr) is one entry in MuxBackends.js with
its commands and parser, so the service no longer branches on muxType
in eight places and the settings dropdown lists the table keys. One
availability check runs for the selected backend and re-runs when the
backend changes. The herdr parser reads the real {sessions:[...]}
shape only.
150 lines
4.1 KiB
QML
150 lines
4.1 KiB
QML
pragma Singleton
|
|
pragma ComponentBehavior: Bound
|
|
|
|
import QtQuick
|
|
import Quickshell
|
|
import Quickshell.Io
|
|
import qs.Common
|
|
import qs.Services
|
|
import "../Common/MuxBackends.js" as MuxBackends
|
|
|
|
Singleton {
|
|
id: root
|
|
readonly property var log: Log.scoped("MuxService")
|
|
|
|
property var sessions: []
|
|
property bool loading: false
|
|
property bool currentMuxAvailable: false
|
|
|
|
readonly property string muxType: SettingsData.muxType
|
|
readonly property var backend: MuxBackends.BACKENDS[muxType] ?? MuxBackends.BACKENDS.tmux
|
|
readonly property string displayName: backend.displayName
|
|
readonly property bool supportsRename: !!backend.rename
|
|
|
|
readonly property var terminalFlags: ({
|
|
"ghostty": ["-e"],
|
|
"kitty": ["-e"],
|
|
"alacritty": ["-e"],
|
|
"foot": [],
|
|
"wezterm": ["start", "--"],
|
|
"gnome-terminal": ["--"],
|
|
"xterm": ["-e"],
|
|
"konsole": ["-e"],
|
|
"st": ["-e"],
|
|
"terminator": ["-e"],
|
|
"xfce4-terminal": ["-e"]
|
|
})
|
|
|
|
function getTerminalFlag(terminal) {
|
|
return terminalFlags[terminal] ?? ["-e"];
|
|
}
|
|
|
|
readonly property string terminal: SessionData.resolveTerminal() || "ghostty"
|
|
|
|
function _terminalPrefix() {
|
|
return [terminal].concat(getTerminalFlag(terminal));
|
|
}
|
|
|
|
Process {
|
|
id: availabilityCheck
|
|
command: ["sh", "-c", "command -v " + root.backend.list[0]]
|
|
running: false
|
|
onExited: code => {
|
|
root.currentMuxAvailable = (code === 0);
|
|
}
|
|
}
|
|
|
|
// Restart so a backend switch mid-check never inherits the old binary's result
|
|
function checkAvailability() {
|
|
if (availabilityCheck.running)
|
|
availabilityCheck.running = false;
|
|
Qt.callLater(function () {
|
|
availabilityCheck.running = true;
|
|
});
|
|
}
|
|
|
|
onBackendChanged: checkAvailability()
|
|
Component.onCompleted: checkAvailability()
|
|
|
|
Process {
|
|
id: listProcess
|
|
running: false
|
|
|
|
stdout: StdioCollector {
|
|
onStreamFinished: {
|
|
try {
|
|
root.sessions = root.backend.parse(text).filter(session => !root._isSessionExcluded(session.name));
|
|
} catch (e) {
|
|
log.error("Error parsing sessions:", e);
|
|
root.sessions = [];
|
|
}
|
|
root.loading = false;
|
|
}
|
|
}
|
|
|
|
stderr: SplitParser {
|
|
onRead: line => {
|
|
if (line.trim())
|
|
log.error("stderr:", line);
|
|
}
|
|
}
|
|
|
|
onExited: code => {
|
|
if (code !== 0 && code !== 1) {
|
|
log.warn("Process exited with code:", code);
|
|
root.sessions = [];
|
|
}
|
|
root.loading = false;
|
|
}
|
|
}
|
|
|
|
function refreshSessions() {
|
|
if (!root.currentMuxAvailable) {
|
|
root.sessions = [];
|
|
return;
|
|
}
|
|
|
|
root.loading = true;
|
|
|
|
if (listProcess.running)
|
|
listProcess.running = false;
|
|
|
|
listProcess.command = root.backend.list;
|
|
Qt.callLater(function () {
|
|
listProcess.running = true;
|
|
});
|
|
}
|
|
|
|
function _isSessionExcluded(name) {
|
|
return MuxBackends.isSessionExcluded(name, SettingsData.muxSessionFilter);
|
|
}
|
|
|
|
function _runInTerminal(name, argv) {
|
|
if (SettingsData.muxUseCustomCommand && SettingsData.muxCustomCommand) {
|
|
Quickshell.execDetached([Paths.expandTilde(SettingsData.muxCustomCommand), name]);
|
|
return;
|
|
}
|
|
Quickshell.execDetached(_terminalPrefix().concat(argv));
|
|
}
|
|
|
|
function attachToSession(name) {
|
|
_runInTerminal(name, root.backend.attach(name));
|
|
}
|
|
|
|
function createSession(name) {
|
|
_runInTerminal(name, root.backend.create(name));
|
|
}
|
|
|
|
function renameSession(oldName, newName) {
|
|
if (!root.supportsRename)
|
|
return;
|
|
Quickshell.execDetached(root.backend.rename(oldName, newName));
|
|
Qt.callLater(refreshSessions);
|
|
}
|
|
|
|
function killSession(name) {
|
|
Quickshell.execDetached(root.backend.kill(name));
|
|
Qt.callLater(refreshSessions);
|
|
}
|
|
}
|