From 6e76c1196ce46ef4e1fba7dfecc7e9731adfb376 Mon Sep 17 00:00:00 2001 From: Valentine Omonya Date: Sun, 14 Dec 2025 03:00:43 +0300 Subject: [PATCH 1/3] Added my screen recorder config --- modules/utilities/cards/Record.qml | 228 ++++++++++++++++++++++---- services/Recorder.qml | 253 +++++++++++++++++++++++++---- 2 files changed, 417 insertions(+), 64 deletions(-) diff --git a/modules/utilities/cards/Record.qml b/modules/utilities/cards/Record.qml index 273c64002..c4de7f1b7 100644 --- a/modules/utilities/cards/Record.qml +++ b/modules/utilities/cards/Record.qml @@ -19,6 +19,11 @@ StyledRect { radius: Appearance.rounding.normal color: Colours.tPalette.m3surfaceContainer + property bool actuallyRecording: Recorder.running + property string lastError: "" + property string currentVideoMode: "fullscreen" + property string currentAudioMode: "none" + ColumnLayout { id: layout @@ -38,7 +43,7 @@ StyledRect { } radius: Appearance.rounding.full - color: Recorder.running ? Colours.palette.m3secondary : Colours.palette.m3secondaryContainer + color: root.actuallyRecording ? Colours.palette.m3secondary : Colours.palette.m3secondaryContainer MaterialIcon { id: icon @@ -47,7 +52,7 @@ StyledRect { anchors.horizontalCenterOffset: -0.5 anchors.verticalCenterOffset: 1.5 text: "screen_record" - color: Recorder.running ? Colours.palette.m3onSecondary : Colours.palette.m3onSecondaryContainer + color: root.actuallyRecording ? Colours.palette.m3onSecondary : Colours.palette.m3onSecondaryContainer font.pointSize: Appearance.font.size.large } } @@ -65,51 +70,117 @@ StyledRect { StyledText { Layout.fillWidth: true - text: Recorder.paused ? qsTr("Recording paused") : Recorder.running ? qsTr("Recording running") : qsTr("Recording off") - color: Colours.palette.m3onSurfaceVariant + text: { + if (root.lastError !== "") return qsTr("Error: %1").arg(root.lastError); + if (Recorder.paused) return qsTr("Recording paused"); + if (root.actuallyRecording) { + const videoText = root.currentVideoMode; + const audioText = root.currentAudioMode === "none" ? "no audio" : root.currentAudioMode; + return qsTr("Recording %1 - %2").arg(videoText).arg(audioText); + } + return qsTr("Recording off"); + } + color: root.lastError !== "" ? Colours.palette.m3error : Colours.palette.m3onSurfaceVariant font.pointSize: Appearance.font.size.small elide: Text.ElideRight } } SplitButton { - disabled: Recorder.running - active: menuItems.find(m => root.props.recordingMode === m.icon + m.text) ?? menuItems[0] - menu.onItemSelected: item => root.props.recordingMode = item.icon + item.text + disabled: root.actuallyRecording + active: menuItems.find(m => root.props.recordingMode === m.mode) ?? menuItems[0] + menu.onItemSelected: item => { + root.props.recordingMode = item.mode; + root.currentVideoMode = item.videoMode; + root.currentAudioMode = item.audioMode; + } menuItems: [ MenuItem { + property string mode: "fullscreen" + property string videoMode: "fullscreen" + property string audioMode: "none" icon: "fullscreen" text: qsTr("Record fullscreen") activeText: qsTr("Fullscreen") - onClicked: Recorder.start() + onClicked: startRecording() }, MenuItem { + property string mode: "region" + property string videoMode: "region" + property string audioMode: "none" icon: "screenshot_region" text: qsTr("Record region") activeText: qsTr("Region") - onClicked: Recorder.start(["-r"]) + onClicked: startRecording() }, MenuItem { - icon: "select_to_speak" - text: qsTr("Record fullscreen with sound") - activeText: qsTr("Fullscreen") - onClicked: Recorder.start(["-s"]) + property string mode: "window" + property string videoMode: "window" + property string audioMode: "none" + icon: "web_asset" + text: qsTr("Record window") + activeText: qsTr("Window") + onClicked: startRecording() + }, + MenuItem { + property string mode: "mic" + property string videoMode: "fullscreen" + property string audioMode: "mic" + icon: "mic" + text: qsTr("Record fullscreen with mic") + activeText: qsTr("Mic") + onClicked: startRecording() }, MenuItem { + property string mode: "system" + property string videoMode: "fullscreen" + property string audioMode: "system" icon: "volume_up" - text: qsTr("Record region with sound") - activeText: qsTr("Region") - onClicked: Recorder.start(["-sr"]) + text: qsTr("Record fullscreen with system audio") + activeText: qsTr("System") + onClicked: startRecording() + }, + MenuItem { + property string mode: "combined" + property string videoMode: "fullscreen" + property string audioMode: "combined" + icon: "settings_voice" + text: qsTr("Record fullscreen with mic + system") + activeText: qsTr("Combined") + onClicked: startRecording() } ] } } + StyledRect { + id: errorBanner + Layout.fillWidth: true + visible: root.lastError !== "" + implicitHeight: visible ? errorText.implicitHeight + Appearance.padding.normal * 2 : 0 + radius: Appearance.rounding.small + color: Colours.palette.m3errorContainer + + StyledText { + id: errorText + anchors.fill: parent + anchors.margins: Appearance.padding.normal + text: root.lastError + color: Colours.palette.m3onErrorContainer + wrapMode: Text.Wrap + font.pointSize: Appearance.font.size.small + } + + Behavior on implicitHeight { + Anim { duration: Appearance.anim.durations.small } + } + } + Loader { id: listOrControls - property bool running: Recorder.running + property bool running: root.actuallyRecording Layout.fillWidth: true Layout.preferredHeight: implicitHeight @@ -117,9 +188,7 @@ StyledRect { Behavior on Layout.preferredHeight { id: locHeightAnim - enabled: false - Anim {} } @@ -175,7 +244,6 @@ StyledRect { Component { id: recordingList - RecordingList { props: root.props visibilities: root.visibilities @@ -184,7 +252,6 @@ StyledRect { Component { id: recordingControls - RowLayout { spacing: Appearance.spacing.normal @@ -197,7 +264,6 @@ StyledRect { StyledText { id: recText - anchors.centerIn: parent animate: true text: Recorder.paused ? "PAUSED" : "REC" @@ -210,10 +276,9 @@ StyledRect { } SequentialAnimation on opacity { - running: !Recorder.paused + running: !Recorder.paused && root.actuallyRecording alwaysRunToEnd: true loops: Animation.Infinite - Anim { from: 1 to: 0 @@ -232,17 +297,14 @@ StyledRect { StyledText { text: { const elapsed = Recorder.elapsed; - const hours = Math.floor(elapsed / 3600); const mins = Math.floor((elapsed % 3600) / 60); const secs = Math.floor(elapsed % 60).toString().padStart(2, "0"); - let time; if (hours > 0) time = `${hours}:${mins.toString().padStart(2, "0")}:${secs}`; else time = `${mins}:${secs}`; - return qsTr("Recording for %1").arg(time); } font.pointSize: Appearance.font.size.normal @@ -261,7 +323,6 @@ StyledRect { font.pointSize: Appearance.font.size.large onClicked: { Recorder.togglePause(); - internalChecked = Recorder.paused; } } @@ -270,7 +331,116 @@ StyledRect { inactiveColour: Colours.palette.m3error inactiveOnColour: Colours.palette.m3onError font.pointSize: Appearance.font.size.large - onClicked: Recorder.stop() + onClicked: stopRecording() + } + } + } + + function startRecording() { + // Clear any previous errors + root.lastError = ""; + + const mode = root.props.recordingMode || "fullscreen"; + + // Map the combined mode to separate video and audio modes + let videoMode = "fullscreen"; + let audioMode = "none"; + + switch(mode) { + case "fullscreen": + videoMode = "fullscreen"; + audioMode = "none"; + break; + case "region": + videoMode = "region"; + audioMode = "none"; + break; + case "window": + videoMode = "window"; + audioMode = "none"; + break; + case "mic": + videoMode = "fullscreen"; + audioMode = "mic"; + break; + case "system": + videoMode = "fullscreen"; + audioMode = "system"; + break; + case "combined": + videoMode = "fullscreen"; + audioMode = "combined"; + break; + } + + root.currentVideoMode = videoMode; + root.currentAudioMode = audioMode; + + console.log("Starting recording - Video:", videoMode, "Audio:", audioMode); + + // Call Recorder service + const success = Recorder.start(videoMode, audioMode); + + if (!success) { + root.lastError = "Failed to start recording"; + } + } + + function stopRecording() { + root.lastError = ""; + Recorder.stop(); + } + + // Clear error after timeout + Timer { + id: errorTimeout + interval: 10000 + repeat: false + running: root.lastError !== "" + onTriggered: { + root.lastError = ""; + } + } + + Connections { + target: Recorder + + function onRunningChanged() { + // Sync actuallyRecording with Recorder.running + root.actuallyRecording = Recorder.running; + + if (!Recorder.running) { + console.log("Recording stopped"); + } + } + + function onErrorOccurred(errorMsg) { + console.error("Recorder error:", errorMsg); + root.lastError = errorMsg; + errorTimeout.restart(); + } + + function onRecordingStarted() { + console.log("Recording started successfully"); + root.lastError = ""; + } + + function onRecordingStopped() { + console.log("Recording stopped successfully"); + } + } + + Component.onCompleted: { + // Sync initial state + root.actuallyRecording = Recorder.running; + + // Set initial mode if saved + if (root.props.recordingMode) { + const mode = root.props.recordingMode; + const item = menuItems.find(m => m.mode === mode); + if (item) { + root.currentVideoMode = item.videoMode; + root.currentAudioMode = item.audioMode; } } } diff --git a/services/Recorder.qml b/services/Recorder.qml index e4ce6a8bd..7abbbc8ae 100644 --- a/services/Recorder.qml +++ b/services/Recorder.qml @@ -10,25 +10,86 @@ Singleton { readonly property alias running: props.running readonly property alias paused: props.paused readonly property alias elapsed: props.elapsed - property bool needsStart - property list startArgs - property bool needsStop - property bool needsPause - - function start(extraArgs: list): void { - needsStart = true; - startArgs = extraArgs; - checkProc.running = true; + + signal errorOccurred(string errorMsg) + signal recordingStarted() + signal recordingStopped() + + function start(videoMode: string, audioMode: string): bool { + if (props.running) { + console.warn("Recording already running"); + errorOccurred("Recording already in progress"); + return false; + } + + // Build command array + const args = ["caelestia", "record", "--mode", videoMode]; + + if (audioMode && audioMode !== "none") { + args.push("--audio", audioMode); + } + + console.log("Executing:", args.join(" ")); + + try { + Quickshell.execDetached(args); + props.running = true; + props.paused = false; + props.elapsed = 0; + verifyTimer.restart(); + recordingStarted(); + return true; + } catch (error) { + console.error("Failed to start recording:", error); + errorOccurred("Failed to execute recording command: " + error); + props.running = false; + return false; + } } function stop(): void { - needsStop = true; - checkProc.running = true; + if (!props.running) { + console.warn("No recording to stop"); + return; + } + + console.log("Stopping recording"); + + try { + Quickshell.execDetached(["caelestia", "record", "--stop"]); + // Don't immediately set running to false - wait for process to confirm + stopVerifyTimer.restart(); + } catch (error) { + console.error("Failed to stop recording:", error); + errorOccurred("Failed to stop recording: " + error); + // Force state reset on error + props.running = false; + props.paused = false; + props.elapsed = 0; + recordingStopped(); + } } function togglePause(): void { - needsPause = true; - checkProc.running = true; + if (!props.running) { + console.warn("No recording to pause"); + return; + } + + console.log("Toggling pause"); + + try { + Quickshell.execDetached(["caelestia", "record", "--pause"]); + props.paused = !props.paused; + } catch (error) { + console.error("Failed to toggle pause:", error); + errorOccurred("Failed to pause/resume recording: " + error); + } + } + + function verifyRunning(): bool { + statusProc.running = true; + return props.running; } PersistentProperties { @@ -36,47 +97,169 @@ Singleton { property bool running: false property bool paused: false - property real elapsed: 0 // Might get too large for int + property real elapsed: 0 reloadableId: "recorder" } + // Main process checker - runs periodically when recording Process { id: checkProc - running: true + running: false command: ["pidof", "gpu-screen-recorder"] + onExited: code => { - props.running = code === 0; + const wasRunning = props.running; + const isRunning = code === 0; - if (code === 0) { - if (root.needsStop) { - Quickshell.execDetached(["caelestia", "record"]); - props.running = false; - props.paused = false; - } else if (root.needsPause) { - Quickshell.execDetached(["caelestia", "record", "-p"]); - props.paused = !props.paused; - } - } else if (root.needsStart) { - Quickshell.execDetached(["caelestia", "record", ...root.startArgs]); - props.running = true; + // Detect unexpected stop + if (wasRunning && !isRunning) { + console.warn("Recording process stopped unexpectedly"); + props.running = false; props.paused = false; props.elapsed = 0; + recordingStopped(); } - root.needsStart = false; - root.needsStop = false; - root.needsPause = false; + // Schedule next check if still recording + if (props.running) { + statusCheckTimer.restart(); + } + } + } + + // Verification timer after start + Timer { + id: verifyTimer + interval: 1500 + repeat: false + onTriggered: { + console.log("Verifying recording started"); + statusProc.running = true; } } - Connections { - target: Time - // enabled: props.running && !props.paused + // Verification timer after stop + Timer { + id: stopVerifyTimer + interval: 500 + repeat: false + onTriggered: { + console.log("Verifying recording stopped"); + stopStatusProc.running = true; + } + } + + // Status check process for start verification + Process { + id: statusProc - function onSecondsChanged(): void { + running: false + command: ["pidof", "gpu-screen-recorder"] + + onExited: code => { + const isRunning = code === 0; + + if (!isRunning && props.running) { + console.error("Recording process failed to start"); + errorOccurred("Recording process failed to start"); + props.running = false; + props.paused = false; + props.elapsed = 0; + } else if (isRunning && props.running) { + console.log("Recording verified running"); + statusCheckTimer.restart(); + } + } + } + + // Status check process for stop verification + Process { + id: stopStatusProc + + running: false + command: ["pidof", "gpu-screen-recorder"] + + onExited: code => { + const isRunning = code === 0; + + if (!isRunning) { + console.log("Recording stopped successfully"); + props.running = false; + props.paused = false; + props.elapsed = 0; + recordingStopped(); + } else { + // Process still running, try again + console.warn("Process still running, checking again"); + stopVerifyTimer.restart(); + } + } + } + + // Elapsed time tracker + Timer { + id: elapsedTimer + interval: 1000 + repeat: true + running: props.running && !props.paused + + onTriggered: { props.elapsed++; } } + + // Periodic status check while recording + Timer { + id: statusCheckTimer + interval: 3000 + repeat: false + + onTriggered: { + if (props.running) { + checkProc.running = true; + } + } + } + + // Initialize on component completion + Component.onCompleted: { + console.log("Recorder service initialized"); + // Check initial state + initialStatusProc.running = true; + } + + // Initial status check + Process { + id: initialStatusProc + + running: false + command: ["pidof", "gpu-screen-recorder"] + + onExited: code => { + if (code === 0) { + console.log("Found existing recording process"); + props.running = true; + statusCheckTimer.restart(); + } else { + console.log("No existing recording process"); + props.running = false; + props.paused = false; + props.elapsed = 0; + } + } + } + + // Cleanup on destruction + Component.onDestruction: { + if (props.running) { + console.log("Service destroyed while recording - stopping recording"); + try { + Quickshell.execDetached(["caelestia", "record", "--stop"]); + } catch (error) { + console.error("Failed to stop recording on cleanup:", error); + } + } + } } From c289eed8ac8ba23f860d9eba6a4ba8e9b118eade Mon Sep 17 00:00:00 2001 From: Valentine Omonya Date: Sun, 14 Dec 2025 03:21:38 +0300 Subject: [PATCH 2/3] Updated audio options --- services/Recorder.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/Recorder.qml b/services/Recorder.qml index 7abbbc8ae..be83629ca 100644 --- a/services/Recorder.qml +++ b/services/Recorder.qml @@ -25,7 +25,7 @@ Singleton { // Build command array const args = ["caelestia", "record", "--mode", videoMode]; - if (audioMode && audioMode !== "none") { + if (audioMode) { args.push("--audio", audioMode); } From 99713ff1cd9fa17a64807ca2bc8d370113329cc4 Mon Sep 17 00:00:00 2001 From: MateusAquino Date: Tue, 6 Jan 2026 15:17:37 -0300 Subject: [PATCH 3/3] feat: add persisted audio sources dropdown --- config/Config.qml | 5 + config/UtilitiesConfig.qml | 7 + modules/utilities/Wrapper.qml | 1 + modules/utilities/cards/Record.qml | 238 +++++++++++++++++++---------- 4 files changed, 169 insertions(+), 82 deletions(-) diff --git a/config/Config.qml b/config/Config.qml index b875eef69..484748a39 100644 --- a/config/Config.qml +++ b/config/Config.qml @@ -379,6 +379,11 @@ Singleton { vpn: { enabled: utilities.vpn.enabled, provider: utilities.vpn.provider + }, + recording: { + videoMode: utilities.recording.videoMode, + recordSystem: utilities.recording.recordSystem, + recordMicrophone: utilities.recording.recordMicrophone } }; } diff --git a/config/UtilitiesConfig.qml b/config/UtilitiesConfig.qml index 5779d8826..a0f287086 100644 --- a/config/UtilitiesConfig.qml +++ b/config/UtilitiesConfig.qml @@ -7,6 +7,13 @@ JsonObject { property Sizes sizes: Sizes {} property Toasts toasts: Toasts {} property Vpn vpn: Vpn {} + property Recording recording: Recording {} + + component Recording: JsonObject { + property string videoMode: "fullscreen" + property bool recordSystem: false + property bool recordMicrophone: false + } component Sizes: JsonObject { property int width: 430 diff --git a/modules/utilities/Wrapper.qml b/modules/utilities/Wrapper.qml index 77178e36e..842a550f9 100644 --- a/modules/utilities/Wrapper.qml +++ b/modules/utilities/Wrapper.qml @@ -14,6 +14,7 @@ Item { readonly property PersistentProperties props: PersistentProperties { property bool recordingListExpanded: false + property bool recordingAudioExpanded: false property string recordingConfirmDelete property string recordingMode diff --git a/modules/utilities/cards/Record.qml b/modules/utilities/cards/Record.qml index c4de7f1b7..7caccc83f 100644 --- a/modules/utilities/cards/Record.qml +++ b/modules/utilities/cards/Record.qml @@ -21,8 +21,17 @@ StyledRect { property bool actuallyRecording: Recorder.running property string lastError: "" - property string currentVideoMode: "fullscreen" - property string currentAudioMode: "none" + property string currentVideoMode: Config.utilities.recording.videoMode + + // Computed audio mode based on settings + readonly property string currentAudioMode: { + const recordSystem = Config.utilities.recording.recordSystem; + const recordMic = Config.utilities.recording.recordMicrophone; + if (recordSystem && recordMic) return "combined"; + if (recordSystem) return "system"; + if (recordMic) return "mic"; + return "none"; + } ColumnLayout { id: layout @@ -88,18 +97,16 @@ StyledRect { SplitButton { disabled: root.actuallyRecording - active: menuItems.find(m => root.props.recordingMode === m.mode) ?? menuItems[0] + active: menuItems.find(m => m.mode === Config.utilities.recording.videoMode) ?? menuItems[0] menu.onItemSelected: item => { - root.props.recordingMode = item.mode; - root.currentVideoMode = item.videoMode; - root.currentAudioMode = item.audioMode; + Config.utilities.recording.videoMode = item.mode; + root.currentVideoMode = item.mode; + Config.save(); } menuItems: [ MenuItem { property string mode: "fullscreen" - property string videoMode: "fullscreen" - property string audioMode: "none" icon: "fullscreen" text: qsTr("Record fullscreen") activeText: qsTr("Fullscreen") @@ -107,8 +114,6 @@ StyledRect { }, MenuItem { property string mode: "region" - property string videoMode: "region" - property string audioMode: "none" icon: "screenshot_region" text: qsTr("Record region") activeText: qsTr("Region") @@ -116,39 +121,10 @@ StyledRect { }, MenuItem { property string mode: "window" - property string videoMode: "window" - property string audioMode: "none" icon: "web_asset" text: qsTr("Record window") activeText: qsTr("Window") onClicked: startRecording() - }, - MenuItem { - property string mode: "mic" - property string videoMode: "fullscreen" - property string audioMode: "mic" - icon: "mic" - text: qsTr("Record fullscreen with mic") - activeText: qsTr("Mic") - onClicked: startRecording() - }, - MenuItem { - property string mode: "system" - property string videoMode: "fullscreen" - property string audioMode: "system" - icon: "volume_up" - text: qsTr("Record fullscreen with system audio") - activeText: qsTr("System") - onClicked: startRecording() - }, - MenuItem { - property string mode: "combined" - property string videoMode: "fullscreen" - property string audioMode: "combined" - icon: "settings_voice" - text: qsTr("Record fullscreen with mic + system") - activeText: qsTr("Combined") - onClicked: startRecording() } ] } @@ -177,6 +153,144 @@ StyledRect { } } + // Audio Sources Section + ColumnLayout { + Layout.fillWidth: true + visible: !root.actuallyRecording + spacing: Appearance.spacing.small + + RowLayout { + spacing: Appearance.spacing.small + + StyledText { + text: qsTr("Audio Sources") + font.pointSize: Appearance.font.size.small + color: Colours.palette.m3onSurfaceVariant + } + + Item { Layout.fillWidth: true } + + IconButton { + icon: root.props.recordingAudioExpanded ? "expand_less" : "expand_more" + type: IconButton.Tonal + font.pointSize: Appearance.font.size.small + onClicked: { + root.props.recordingAudioExpanded = !root.props.recordingAudioExpanded; + } + } + } + + ColumnLayout { + Layout.fillWidth: true + visible: root.props.recordingAudioExpanded + spacing: Appearance.spacing.smaller + + // System Audio (Default Sink) + RowLayout { + Layout.fillWidth: true + spacing: Appearance.spacing.normal + + StyledSwitch { + checked: Config.utilities.recording.recordSystem + onToggled: { + Config.utilities.recording.recordSystem = checked; + Config.save(); + } + } + + StyledText { + Layout.preferredWidth: 85 + text: qsTr("System") + font.pointSize: Appearance.font.size.small + elide: Text.ElideRight + } + + StyledSlider { + id: systemVolumeSlider + Layout.fillWidth: true + implicitHeight: 24 + opacity: Config.utilities.recording.recordSystem ? 1.0 : 0.5 + from: 0 + to: 1 + value: Audio.volume + onMoved: { + Audio.setVolume(value); + } + } + + StyledText { + text: Math.round(Audio.volume * 100) + "%" + font.pointSize: Appearance.font.size.small + color: Colours.palette.m3onSurfaceVariant + Layout.preferredWidth: 40 + } + + IconButton { + icon: Audio.muted ? "volume_off" : "volume_up" + type: Audio.muted ? IconButton.Filled : IconButton.Tonal + font.pointSize: Appearance.font.size.small + onClicked: { + if (Audio.sink?.audio) { + Audio.sink.audio.muted = !Audio.sink.audio.muted; + } + } + } + } + + // Microphone (Default Source) + RowLayout { + Layout.fillWidth: true + spacing: Appearance.spacing.normal + + StyledSwitch { + checked: Config.utilities.recording.recordMicrophone + onToggled: { + Config.utilities.recording.recordMicrophone = checked; + Config.save(); + } + } + + StyledText { + Layout.preferredWidth: 85 + text: qsTr("Microphone") + font.pointSize: Appearance.font.size.small + elide: Text.ElideRight + } + + StyledSlider { + id: micVolumeSlider + Layout.fillWidth: true + implicitHeight: 24 + opacity: Config.utilities.recording.recordMicrophone ? 1.0 : 0.5 + from: 0 + to: 1 + value: Audio.sourceVolume + onMoved: { + Audio.setSourceVolume(value); + } + } + + StyledText { + text: Math.round(Audio.sourceVolume * 100) + "%" + font.pointSize: Appearance.font.size.small + color: Colours.palette.m3onSurfaceVariant + Layout.preferredWidth: 40 + } + + IconButton { + icon: Audio.sourceMuted ? "mic_off" : "mic" + type: Audio.sourceMuted ? IconButton.Filled : IconButton.Tonal + font.pointSize: Appearance.font.size.small + onClicked: { + if (Audio.source?.audio) { + Audio.source.audio.muted = !Audio.source.audio.muted; + } + } + } + } + } + } + Loader { id: listOrControls @@ -340,41 +454,10 @@ StyledRect { // Clear any previous errors root.lastError = ""; - const mode = root.props.recordingMode || "fullscreen"; - - // Map the combined mode to separate video and audio modes - let videoMode = "fullscreen"; - let audioMode = "none"; - - switch(mode) { - case "fullscreen": - videoMode = "fullscreen"; - audioMode = "none"; - break; - case "region": - videoMode = "region"; - audioMode = "none"; - break; - case "window": - videoMode = "window"; - audioMode = "none"; - break; - case "mic": - videoMode = "fullscreen"; - audioMode = "mic"; - break; - case "system": - videoMode = "fullscreen"; - audioMode = "system"; - break; - case "combined": - videoMode = "fullscreen"; - audioMode = "combined"; - break; - } + const videoMode = Config.utilities.recording.videoMode || "fullscreen"; + const audioMode = root.currentAudioMode; root.currentVideoMode = videoMode; - root.currentAudioMode = audioMode; console.log("Starting recording - Video:", videoMode, "Audio:", audioMode); @@ -433,15 +516,6 @@ StyledRect { Component.onCompleted: { // Sync initial state root.actuallyRecording = Recorder.running; - - // Set initial mode if saved - if (root.props.recordingMode) { - const mode = root.props.recordingMode; - const item = menuItems.find(m => m.mode === mode); - if (item) { - root.currentVideoMode = item.videoMode; - root.currentAudioMode = item.audioMode; - } - } + root.currentVideoMode = Config.utilities.recording.videoMode || "fullscreen"; } }