summaryrefslogtreecommitdiff
path: root/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Services/MuxService.qml
diff options
context:
space:
mode:
Diffstat (limited to 'raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Services/MuxService.qml')
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Services/MuxService.qml230
1 files changed, 230 insertions, 0 deletions
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Services/MuxService.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Services/MuxService.qml
new file mode 100644
index 0000000..c2f941c
--- /dev/null
+++ b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Services/MuxService.qml
@@ -0,0 +1,230 @@
+pragma Singleton
+pragma ComponentBehavior: Bound
+
+import QtQuick
+import Quickshell
+import Quickshell.Io
+import qs.Common
+
+Singleton {
+ id: root
+
+ property var sessions: []
+ property bool loading: false
+
+ property bool tmuxAvailable: false
+ property bool zellijAvailable: false
+ readonly property bool currentMuxAvailable: muxType === "zellij" ? zellijAvailable : tmuxAvailable
+
+ readonly property string muxType: SettingsData.muxType
+ readonly property string displayName: muxType === "zellij" ? "Zellij" : "Tmux"
+
+ 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: Quickshell.env("TERMINAL") || "ghostty"
+
+ function _terminalPrefix() {
+ return [terminal].concat(getTerminalFlag(terminal))
+ }
+
+ Process {
+ id: tmuxCheckProcess
+ command: ["which", "tmux"]
+ running: false
+ onExited: (code) => { root.tmuxAvailable = (code === 0) }
+ }
+
+ Process {
+ id: zellijCheckProcess
+ command: ["which", "zellij"]
+ running: false
+ onExited: (code) => { root.zellijAvailable = (code === 0) }
+ }
+
+ function checkAvailability() {
+ tmuxCheckProcess.running = true
+ zellijCheckProcess.running = true
+ }
+
+ Component.onCompleted: checkAvailability()
+
+ Process {
+ id: listProcess
+ running: false
+
+ stdout: StdioCollector {
+ onStreamFinished: {
+ try {
+ if (root.muxType === "zellij")
+ root._parseZellijSessions(text)
+ else
+ root._parseTmuxSessions(text)
+ } catch (e) {
+ console.error("[MuxService] Error parsing sessions:", e)
+ root.sessions = []
+ }
+ root.loading = false
+ }
+ }
+
+ stderr: SplitParser {
+ onRead: (line) => {
+ if (line.trim())
+ console.error("[MuxService] stderr:", line)
+ }
+ }
+
+ onExited: (code) => {
+ if (code !== 0 && code !== 1) {
+ console.warn("[MuxService] 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
+
+ if (root.muxType === "zellij")
+ listProcess.command = ["zellij", "list-sessions", "--no-formatting"]
+ else
+ listProcess.command = ["tmux", "list-sessions", "-F", "#{session_name}|#{session_windows}|#{session_attached}"]
+
+ Qt.callLater(function () {
+ listProcess.running = true
+ })
+ }
+
+ function _isSessionExcluded(name) {
+ var filter = SettingsData.muxSessionFilter.trim()
+ if (filter.length === 0)
+ return false
+ var parts = filter.split(",")
+ for (var i = 0; i < parts.length; i++) {
+ var pattern = parts[i].trim()
+ if (pattern.length === 0)
+ continue
+ if (pattern.startsWith("/") && pattern.endsWith("/") && pattern.length > 2) {
+ try {
+ var re = new RegExp(pattern.slice(1, -1))
+ if (re.test(name))
+ return true
+ } catch (e) {}
+ } else {
+ if (name.toLowerCase() === pattern.toLowerCase())
+ return true
+ }
+ }
+ return false
+ }
+
+ function _parseTmuxSessions(output) {
+ var sessionList = []
+ var lines = output.trim().split('\n')
+
+ for (var i = 0; i < lines.length; i++) {
+ var line = lines[i].trim()
+ if (line.length === 0)
+ continue
+
+ var parts = line.split('|')
+ if (parts.length >= 3 && !_isSessionExcluded(parts[0])) {
+ sessionList.push({
+ name: parts[0],
+ windows: parts[1],
+ attached: parts[2] === "1"
+ })
+ }
+ }
+
+ root.sessions = sessionList
+ }
+
+ function _parseZellijSessions(output) {
+ var sessionList = []
+ var lines = output.trim().split('\n')
+
+ for (var i = 0; i < lines.length; i++) {
+ var line = lines[i].trim()
+ if (line.length === 0)
+ continue
+
+ var exited = line.includes("(EXITED")
+ var bracketIdx = line.indexOf(" [")
+ var name = (bracketIdx > 0 ? line.substring(0, bracketIdx) : line).trim()
+
+ if (!_isSessionExcluded(name)) {
+ sessionList.push({
+ name: name,
+ windows: "N/A",
+ attached: !exited
+ })
+ }
+ }
+
+ root.sessions = sessionList
+ }
+
+ function attachToSession(name) {
+ if (SettingsData.muxUseCustomCommand && SettingsData.muxCustomCommand) {
+ Quickshell.execDetached([SettingsData.muxCustomCommand, name])
+ } else if (root.muxType === "zellij") {
+ Quickshell.execDetached(_terminalPrefix().concat(["zellij", "attach", name]))
+ } else {
+ Quickshell.execDetached(_terminalPrefix().concat(["tmux", "attach", "-t", name]))
+ }
+ }
+
+ function createSession(name) {
+ if (SettingsData.muxUseCustomCommand && SettingsData.muxCustomCommand) {
+ Quickshell.execDetached([SettingsData.muxCustomCommand, name])
+ } else if (root.muxType === "zellij") {
+ Quickshell.execDetached(_terminalPrefix().concat(["zellij", "-s", name]))
+ } else {
+ Quickshell.execDetached(_terminalPrefix().concat(["tmux", "new-session", "-s", name]))
+ }
+ }
+
+ readonly property bool supportsRename: muxType !== "zellij"
+
+ function renameSession(oldName, newName) {
+ if (root.muxType === "zellij")
+ return
+ Quickshell.execDetached(["tmux", "rename-session", "-t", oldName, newName])
+ Qt.callLater(refreshSessions)
+ }
+
+ function killSession(name) {
+ if (root.muxType === "zellij") {
+ Quickshell.execDetached(["zellij", "kill-session", name])
+ } else {
+ Quickshell.execDetached(["tmux", "kill-session", "-t", name])
+ }
+ Qt.callLater(refreshSessions)
+ }
+}