ScreenRecorder Service + Reconnected the utility button
This commit is contained in:
parent
c1f22d5e87
commit
e7588b29d9
10 changed files with 142 additions and 51 deletions
|
|
@ -49,7 +49,6 @@ Singleton {
|
|||
vol = 0
|
||||
}
|
||||
root._volume = vol
|
||||
|
||||
}
|
||||
|
||||
function onMutedChanged() {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
64
Services/ScreenRecorder.qml
Normal file
64
Services/ScreenRecorder.qml
Normal 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"])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue