refractor quick toggles data, add volume slider for waffles action center

This commit is contained in:
end-4
2025-11-17 23:43:25 +01:00
parent 9228165428
commit fcee7ce6f9
55 changed files with 939 additions and 470 deletions
@@ -572,7 +572,7 @@ Singleton {
}
property JsonObject waffles: JsonObject {
// Animations on Windoes are kinda janky. Set the following to
// Animations on Windoes are kinda janky. Setting the following to
// false will make (some) stuff also be like that for accuracy.
// Example: the right-click menu of the Start button
property bool smootherAnimations: true
@@ -580,6 +580,9 @@ Singleton {
property bool bottom: true
property bool leftAlignApps: false
}
property JsonObject actionCenter: JsonObject {
property list<string> toggles: []
}
}
}
}
@@ -0,0 +1,17 @@
import QtQuick
import qs.services
import qs.modules.common
import qs.modules.common.functions
import qs.modules.common.widgets
QuickToggleModel {
name: Translation.tr("Anti-flashbang")
tooltipText: Translation.tr("Anti-flashbang")
icon: "flash_off"
toggled: Config.options.light.antiFlashbang.enable
mainAction: () => {
Config.options.light.antiFlashbang.enable = !Config.options.light.antiFlashbang.enable;
}
hasMenu: true
}
@@ -0,0 +1,17 @@
import QtQuick
import qs.services
import qs.modules.common
import qs.modules.common.functions
import qs.modules.common.widgets
QuickToggleModel {
name: Translation.tr("Audio output")
statusText: toggled ? Translation.tr("Unmuted") : Translation.tr("Muted")
tooltipText: Translation.tr("Audio output | Right-click for volume mixer & device selector")
toggled: !Audio.sink?.audio?.muted
icon: Audio.sink?.audio?.muted ? "volume_off" : "volume_up"
mainAction: () => {
Audio.toggleMute()
}
hasMenu: true
}
@@ -0,0 +1,23 @@
import QtQuick
import Quickshell.Bluetooth
import qs.services
import qs.modules.common
import qs.modules.common.functions
import qs.modules.common.widgets
QuickToggleModel {
name: Translation.tr("Bluetooth")
statusText: BluetoothStatus.firstActiveDevice?.name ?? Translation.tr("No device")
tooltipText: Translation.tr("%1 | Right-click to configure").arg(
(BluetoothStatus.firstActiveDevice?.name ?? Translation.tr("Bluetooth"))
+ (BluetoothStatus.activeDeviceCount > 1 ? ` +${BluetoothStatus.activeDeviceCount - 1}` : "")
)
icon: BluetoothStatus.connected ? "bluetooth_connected" : BluetoothStatus.enabled ? "bluetooth" : "bluetooth_disabled"
available: BluetoothStatus.available
toggled: BluetoothStatus.enabled
mainAction: () => {
Bluetooth.defaultAdapter.enabled = !Bluetooth.defaultAdapter?.enabled
}
hasMenu: true
}
@@ -0,0 +1,78 @@
import QtQuick
import qs.services
import qs.modules.common
import qs.modules.common.functions
import qs.modules.common.widgets
import Quickshell
import Quickshell.Io
QuickToggleModel {
id: root
name: Translation.tr("Cloudflare WARP")
toggled: false
icon: "cloud_lock"
mainAction: () => {
if (toggled) {
root.toggled = false
Quickshell.execDetached(["warp-cli", "disconnect"])
} else {
root.toggled = true
Quickshell.execDetached(["warp-cli", "connect"])
}
}
Process {
id: connectProc
command: ["warp-cli", "connect"]
onExited: (exitCode, exitStatus) => {
if (exitCode !== 0) {
Quickshell.execDetached(["notify-send",
Translation.tr("Cloudflare WARP"),
Translation.tr("Connection failed. Please inspect manually with the <tt>warp-cli</tt> command")
, "-a", "Shell"
])
}
}
}
Process {
id: registrationProc
command: ["warp-cli", "registration", "new"]
onExited: (exitCode, exitStatus) => {
console.log("Warp registration exited with code and status:", exitCode, exitStatus)
if (exitCode === 0) {
connectProc.running = true
} else {
Quickshell.execDetached(["notify-send",
Translation.tr("Cloudflare WARP"),
Translation.tr("Registration failed. Please inspect manually with the <tt>warp-cli</tt> command"),
"-a", "Shell"
])
}
}
}
Process {
id: fetchActiveState
running: true
command: ["bash", "-c", "warp-cli status"]
stdout: StdioCollector {
id: warpStatusCollector
onStreamFinished: {
if (warpStatusCollector.text.length > 0) {
root.available = true
}
if (warpStatusCollector.text.includes("Unable")) {
registrationProc.running = true
} else if (warpStatusCollector.text.includes("Connected")) {
root.toggled = true
} else if (warpStatusCollector.text.includes("Disconnected")) {
root.toggled = false
}
}
}
}
tooltipText: Translation.tr("Cloudflare WARP (1.1.1.1)")
}
@@ -0,0 +1,29 @@
import QtQuick
import Quickshell
import qs
import qs.services
import qs.modules.common
import qs.modules.common.functions
import qs.modules.common.widgets
QuickToggleModel {
name: Translation.tr("Color picker")
hasStatusText: false
toggled: false
icon: "colorize"
mainAction: () => {
GlobalStates.sidebarRightOpen = false;
delayedActionTimer.start();
}
Timer {
id: delayedActionTimer
interval: 300
repeat: false
onTriggered: {
Quickshell.execDetached(["hyprpicker", "-a"]);
}
}
tooltipText: Translation.tr("Color picker")
}
@@ -0,0 +1,25 @@
import QtQuick
import Quickshell
import qs
import qs.services
import qs.modules.common
import qs.modules.common.functions
import qs.modules.common.widgets
QuickToggleModel {
name: Translation.tr("Dark Mode")
statusText: Appearance.m3colors.darkmode ? Translation.tr("Dark") : Translation.tr("Light")
toggled: Appearance.m3colors.darkmode
icon: "contrast"
mainAction: () => {
if (Appearance.m3colors.darkmode) {
Quickshell.execDetached([Directories.wallpaperSwitchScriptPath, "--mode", "light", "--noswitch"]);
} else {
Quickshell.execDetached([Directories.wallpaperSwitchScriptPath, "--mode", "dark", "--noswitch"]);
}
}
tooltipText: Translation.tr("Dark Mode")
}
@@ -0,0 +1,30 @@
import QtQuick
import Quickshell
import qs
import qs.services
import qs.modules.common
import qs.modules.common.functions
import qs.modules.common.widgets
QuickToggleModel {
name: Translation.tr("EasyEffects")
available: EasyEffects.available
toggled: EasyEffects.active
icon: "graphic_eq"
Component.onCompleted: {
EasyEffects.fetchActiveState()
}
mainAction: () => {
EasyEffects.toggle()
}
altAction: () => {
Quickshell.execDetached(["bash", "-c", "flatpak run com.github.wwmm.easyeffects || easyeffects"])
GlobalStates.sidebarRightOpen = false
}
tooltipText: Translation.tr("EasyEffects | Right-click to configure")
}
@@ -0,0 +1,33 @@
import QtQuick
import Quickshell
import Quickshell.Io
import qs
import qs.services
import qs.modules.common
import qs.modules.common.functions
import qs.modules.common.widgets
QuickToggleModel {
id: root
name: Translation.tr("Game mode")
toggled: toggled
icon: "gamepad"
mainAction: () => {
root.toggled = !root.toggled
if (root.toggled) {
Quickshell.execDetached(["bash", "-c", `hyprctl --batch "keyword animations:enabled 0; keyword decoration:shadow:enabled 0; keyword decoration:blur:enabled 0; keyword general:gaps_in 0; keyword general:gaps_out 0; keyword general:border_size 1; keyword decoration:rounding 0; keyword general:allow_tearing 1"`])
} else {
Quickshell.execDetached(["hyprctl", "reload"])
}
}
Process {
id: fetchActiveState
running: true
command: ["bash", "-c", `test "$(hyprctl getoption animations:enabled -j | jq ".int")" -ne 0`]
onExited: (exitCode, exitStatus) => {
root.toggled = exitCode !== 0 // Inverted because enabled = nonzero exit
}
}
tooltipText: Translation.tr("Game mode")
}
@@ -0,0 +1,18 @@
import QtQuick
import Quickshell
import qs
import qs.services
import qs.modules.common
import qs.modules.common.functions
import qs.modules.common.widgets
QuickToggleModel {
name: Translation.tr("Keep awake")
toggled: Idle.inhibit
icon: "coffee"
mainAction: () => {
Idle.toggleInhibit()
}
tooltipText: Translation.tr("Keep system awake")
}
@@ -0,0 +1,20 @@
import QtQuick
import Quickshell
import qs
import qs.services
import qs.modules.common
import qs.modules.common.functions
import qs.modules.common.widgets
QuickToggleModel {
name: Translation.tr("Audio input")
statusText: toggled ? Translation.tr("Enabled") : Translation.tr("Muted")
toggled: !Audio.source?.audio?.muted
icon: Audio.source?.audio?.muted ? "mic_off" : "mic"
mainAction: () => {
Audio.toggleMicMute()
}
hasMenu: true
tooltipText: Translation.tr("Audio input | Right-click for volume mixer & device selector")
}
@@ -0,0 +1,25 @@
import QtQuick
import Quickshell
import qs
import qs.services
import qs.modules.common
import qs.modules.common.functions
import qs.modules.common.widgets
QuickToggleModel {
toggled: SongRec.running
property bool sourceIsMonitor: SongRec.monitorSource === SongRec.MonitorSource.Monitor
name: Translation.tr("Identify Music")
statusText: toggled ? Translation.tr("Listening...") : sourceIsMonitor ? Translation.tr("System sound") : Translation.tr("Microphone")
icon: toggled ? "music_cast" : (sourceIsMonitor ? "music_note" : "frame_person_mic")
tooltipText: Translation.tr("Recognize music | Right-click to toggle source")
mainAction: () => {
SongRec.toggleRunning()
}
altAction: () => {
SongRec.toggleMonitorSource()
}
}
@@ -0,0 +1,16 @@
import QtQuick
import qs.services
import qs.modules.common
import qs.modules.common.functions
import qs.modules.common.widgets
QuickToggleModel {
name: Translation.tr("Internet")
statusText: Network.networkName
tooltipText: Translation.tr("%1 | Right-click to configure").arg(Network.networkName)
icon: Network.materialSymbol
toggled: Network.wifiStatus !== "disabled"
mainAction: () => Network.toggleWifi()
hasMenu: true
}
@@ -0,0 +1,28 @@
import QtQuick
import Quickshell
import qs
import qs.services
import qs.modules.common
import qs.modules.common.functions
import qs.modules.common.widgets
QuickToggleModel {
property bool auto: Config.options.light.night.automatic
name: Translation.tr("Night Light")
statusText: (auto ? Translation.tr("Auto, ") : "") + (toggled ? Translation.tr("Active") : Translation.tr("Inactive"))
toggled: Hyprsunset.active
icon: auto ? "night_sight_auto" : "bedtime"
mainAction: () => {
Hyprsunset.toggle()
}
hasMenu: true
Component.onCompleted: {
Hyprsunset.fetchState()
}
tooltipText: Translation.tr("Night Light | Right-click to configure")
}
@@ -0,0 +1,20 @@
import QtQuick
import Quickshell
import qs
import qs.services
import qs.modules.common
import qs.modules.common.functions
import qs.modules.common.widgets
QuickToggleModel {
name: Translation.tr("Notifications")
statusText: toggled ? Translation.tr("Show") : Translation.tr("Silent")
toggled: !Notifications.silent
icon: toggled ? "notifications_active" : "notifications_paused"
mainAction: () => {
Notifications.silent = !Notifications.silent;
}
tooltipText: Translation.tr("Show notifications")
}
@@ -0,0 +1,19 @@
import QtQuick
import Quickshell
import qs
import qs.services
import qs.modules.common
import qs.modules.common.functions
import qs.modules.common.widgets
QuickToggleModel {
name: Translation.tr("Virtual Keyboard")
toggled: GlobalStates.oskOpen
icon: toggled ? "keyboard_hide" : "keyboard"
mainAction: () => {
GlobalStates.oskOpen = !GlobalStates.oskOpen
}
tooltipText: Translation.tr("On-screen keyboard")
}
@@ -0,0 +1,39 @@
import QtQuick
import Quickshell
import Quickshell.Services.UPower
import qs
import qs.services
import qs.modules.common
import qs.modules.common.functions
import qs.modules.common.widgets
QuickToggleModel {
name: Translation.tr("Power Profile")
toggled: PowerProfiles.profile !== PowerProfile.Balanced
icon: switch(PowerProfiles.profile) {
case PowerProfile.PowerSaver: return "energy_savings_leaf"
case PowerProfile.Balanced: return "settings_slow_motion"
case PowerProfile.Performance: return "local_fire_department"
}
statusText: switch(PowerProfiles.profile) {
case PowerProfile.PowerSaver: return "Power Saver"
case PowerProfile.Balanced: return "Balanced"
case PowerProfile.Performance: return "Performance"
}
mainAction: () => {
if (PowerProfiles.hasPerformanceProfile) {
switch(PowerProfiles.profile) {
case PowerProfile.PowerSaver: PowerProfiles.profile = PowerProfile.Balanced
break;
case PowerProfile.Balanced: PowerProfiles.profile = PowerProfile.Performance
break;
case PowerProfile.Performance: PowerProfiles.profile = PowerProfile.PowerSaver
break;
}
} else {
PowerProfiles.profile = PowerProfiles.profile == PowerProfile.Balanced ? PowerProfile.PowerSaver : PowerProfile.Balanced
}
}
tooltipText: Translation.tr("Click to cycle through power profiles")
}
@@ -0,0 +1,22 @@
import QtQuick
QtObject {
// Textual info
required property string name
property string statusText
property string tooltipText: ""
property string icon: "close"
// State
property bool hasStatusText: true
property bool available: true
property bool toggled: false
// Interactions
required property var mainAction
property bool hasMenu: false
property var altAction: null
// Allow stuff like Processes to be declared freely
default property list<QtObject> data
}
@@ -0,0 +1,29 @@
import QtQuick
import Quickshell
import qs
import qs.services
import qs.modules.common
import qs.modules.common.functions
import qs.modules.common.widgets
QuickToggleModel {
name: Translation.tr("Screen snip")
hasStatusText: false
toggled: false
icon: "screenshot_region"
mainAction: () => {
GlobalStates.sidebarRightOpen = false;
delayedActionTimer.start();
}
Timer {
id: delayedActionTimer
interval: 300
repeat: false
onTriggered: {
Quickshell.execDetached(["qs", "-p", Quickshell.shellPath(""), "ipc", "call", "region", "screenshot"]);
}
}
tooltipText: Translation.tr("Screen snip")
}
@@ -0,0 +1,9 @@
import QtQuick
Rectangle {
property double diameter
implicitWidth: diameter
implicitHeight: diameter
radius: diameter / 2
}