ScreenRecorder Service + Reconnected the utility button

This commit is contained in:
quadbyte 2025-08-12 16:18:49 -04:00
parent c1f22d5e87
commit e7588b29d9
10 changed files with 142 additions and 51 deletions

View file

@ -49,7 +49,6 @@ Singleton {
vol = 0
}
root._volume = vol
}
function onMutedChanged() {

View file

@ -53,30 +53,30 @@ Singleton {
// Default theme colors
QtObject {
id: defaultTheme
property color backgroundPrimary: "#191724"
property color backgroundSecondary: "#1f1d2e"
property color backgroundTertiary: "#26233a"
property color surface: "#1f1d2e"
property color surfaceVariant: "#37354c"
property color textPrimary: "#e0def4"
property color textSecondary: "#908caa"
property color textDisabled: "#6e6a86"
property color accentPrimary: "#ebbcba"
property color accentSecondary: "#31748f"
property color accentTertiary: "#9ccfd8"
property color error: "#eb6f92"
property color warning: "#f6c177"
property color hover: "#c4a7e7"
property color onAccent: "#191724"
property color outline: "#44415a"
property color shadow: "#191724"
property color overlay: "#191724"
}
@ -84,30 +84,30 @@ Singleton {
// Wallust theme colors (loaded from Theme.json)
QtObject {
id: wallustTheme
property color backgroundPrimary: wallustData.backgroundPrimary
property color backgroundSecondary: wallustData.backgroundSecondary
property color backgroundTertiary: wallustData.backgroundTertiary
property color surface: wallustData.surface
property color surfaceVariant: wallustData.surfaceVariant
property color textPrimary: wallustData.textPrimary
property color textSecondary: wallustData.textSecondary
property color textDisabled: wallustData.textDisabled
property color accentPrimary: wallustData.accentPrimary
property color accentSecondary: wallustData.accentSecondary
property color accentTertiary: wallustData.accentTertiary
property color error: wallustData.error
property color warning: wallustData.warning
property color hover: wallustData.hover
property color onAccent: wallustData.onAccent
property color outline: wallustData.outline
property color shadow: wallustData.shadow
property color overlay: wallustData.overlay
}

View file

@ -49,7 +49,7 @@ Singleton {
// --------------------------------
function loadFromCache() {
const now = Time.timestamp
const now = Time.timestamp
if (!data.timestamp || (now >= data.timestamp + githubUpdateFrequency)) {
console.log("[GitHub] Cache expired or missing, fetching new data from GitHub...")
fetchFromGitHub()
@ -79,7 +79,7 @@ Singleton {
// --------------------------------
function saveData() {
data.timestamp = Time.timestamp
data.timestamp = Time.timestamp
Qt.callLater(() => {
// Access the FileView's writeAdapter method
var fileView = root.children.find(child => child.objectName === "githubDataFileView")

View file

@ -0,0 +1,64 @@
pragma Singleton
import QtQuick
import Quickshell
import qs.Services
Singleton {
id: root
readonly property var settings: Settings.data.screenRecorder
property bool isRecording: false
property string outputPath: ""
// Start or Stop recording
function toggleRecording() {
isRecording ? stopRecording() : startRecording()
}
// Start screen recording using Quickshell.execDetached
function startRecording() {
if (isRecording) {
return
}
isRecording = true
var filename = Time.getFormattedTimestamp() + ".mp4"
var videoDir = settings.directory
if (videoDir && !videoDir.endsWith("/")) {
videoDir += "/"
}
outputPath = videoDir + filename
var command = "gpu-screen-recorder -w portal" + " -f " + settings.frameRate + " -ac " + settings.audioCodec
+ " -k " + settings.videoCodec + " -a " + settings.audioSource + " -q " + settings.quality
+ " -cursor " + (settings.showCursor ? "yes" : "no") + " -cr " + settings.colorRange + " -o " + outputPath
//console.log("[ScreenRecorder]", command)
Quickshell.execDetached(["sh", "-c", command])
console.log("[ScreenRecorder] Started recording")
}
// Stop recording using Quickshell.execDetached
function stopRecording() {
if (!isRecording) {
return
}
Quickshell.execDetached(["sh", "-c", "pkill -SIGINT -f 'gpu-screen-recorder.*portal'"])
console.log("[ScreenRecorder] Finished recording:", outputPath)
// Just in case, force kill after 3 seconds
killTimer.running = true
isRecording = false
}
Timer {
id: killTimer
interval: 3000
running: false
repeat: false
onTriggered: {
Quickshell.execDetached(["sh", "-c", "pkill -9 -f 'gpu-screen-recorder.*portal' 2>/dev/null || true"])
}
}
}

View file

@ -105,9 +105,8 @@ Singleton {
property string videoCodec: "h264"
property string quality: "very_high"
property string colorRange: "limited"
property bool showCursor: true
// New: optional audio source selection (default: system output)
property string audioSource: "default_output"
property bool showCursor: true
}
// wallpaper

View file

@ -43,31 +43,51 @@ Singleton {
return Math.floor(Date.now() / 1000)
}
// Format an easy to read approximate duration ex: 4h32m
// Used to display the time remaining on the Battery widget
function formatVagueHumanReadableDuration(totalSeconds) {
const hours = Math.floor(totalSeconds / 3600)
const minutes = Math.floor((totalSeconds - (hours * 3600)) / 60)
const seconds = totalSeconds - (hours * 3600) - (minutes * 60)
var str = ""
if (hours) {
str += hours.toString() + "h"
}
if (minutes) {
str += minutes.toString() + "m"
}
if (!hours && !minutes) {
str += seconds.toString() + "s"
}
return str
}
/**
* Formats a Date object into a YYYYMMDD-HHMMSS string.
* @param {Date} [date=new Date()] - The date to format. Defaults to the current date and time.
* @returns {string} The formatted date string.
*/
function getFormattedTimestamp(date = new Date()) {
const year = date.getFullYear()
Timer {
interval: 1000
repeat: true
running: true
// getMonth() is zero-based, so we add 1
const month = String(date.getMonth() + 1).padStart(2, '0')
const day = String(date.getDate()).padStart(2, '0')
onTriggered: root.date = new Date()
}
const hours = String(date.getHours()).padStart(2, '0')
const minutes = String(date.getMinutes()).padStart(2, '0')
const seconds = String(date.getSeconds()).padStart(2, '0')
return `${year}${month}${day}-${hours}${minutes}${seconds}`
}
// Format an easy to read approximate duration ex: 4h32m
// Used to display the time remaining on the Battery widget
function formatVagueHumanReadableDuration(totalSeconds) {
const hours = Math.floor(totalSeconds / 3600)
const minutes = Math.floor((totalSeconds - (hours * 3600)) / 60)
const seconds = totalSeconds - (hours * 3600) - (minutes * 60)
var str = ""
if (hours) {
str += hours.toString() + "h"
}
if (minutes) {
str += minutes.toString() + "m"
}
if (!hours && !minutes) {
str += seconds.toString() + "s"
}
return str
}
Timer {
interval: 1000
repeat: true
running: true
onTriggered: root.date = new Date()
}
}

View file

@ -50,9 +50,10 @@ Singleton {
} else {
transitionType = Settings.data.wallpaper.swww.transitionType
}
changeWallpaperProcess.running = true
} else {
// Fallback: update the settings directly for non-SWWW mode
//console.log("[WP] Not using Swww, setting wallpaper directly")
}
@ -140,7 +141,7 @@ Singleton {
running: false
onStarted: {
}
onExited: function (exitCode, exitStatus) {
@ -159,6 +160,7 @@ Singleton {
running: false
stdout: StdioCollector {
onStreamFinished: {
// console.log(this.text)
}
}