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
@@ -197,16 +197,8 @@ Item { // Bar content region
implicitWidth: rightSectionRowLayout.implicitWidth
implicitHeight: Appearance.sizes.baseBarHeight
onScrollDown: {
const currentVolume = Audio.value;
const step = currentVolume < 0.1 ? 0.01 : 0.02 || 0.2;
Audio.sink.audio.volume -= step;
}
onScrollUp: {
const currentVolume = Audio.value;
const step = currentVolume < 0.1 ? 0.01 : 0.02 || 0.2;
Audio.sink.audio.volume = Math.min(1, Audio.sink.audio.volume + step);
}
onScrollDown: Audio.decrementVolume();
onScrollUp: Audio.incrementVolume();
onMovedAway: GlobalStates.osdVolumeOpen = false;
onPressed: event => {
if (event.button === Qt.LeftButton) {
@@ -1,3 +1,4 @@
import qs.modules.common.models.quickToggles
import qs.modules.common
import qs.modules.common.widgets
import qs.services
@@ -6,24 +7,7 @@ import Quickshell
AndroidQuickToggleButton {
id: root
property bool auto: Config.options.light.night.automatic
name: Translation.tr("Anti-flashbang")
toggled: Config.options.light.antiFlashbang.enable
buttonIcon: "flash_off"
mainAction: () => {
Config.options.light.antiFlashbang.enable = !Config.options.light.antiFlashbang.enable;
}
altAction: () => {
root.openMenu()
}
StyledToolTip {
text: Translation.tr("Anti-flashbang")
}
toggleModel: AntiFlashbangToggle {}
}
@@ -1,5 +1,6 @@
import qs
import qs.modules.common
import qs.modules.common.models.quickToggles
import qs.modules.common.widgets
import qs.services
import QtQuick
@@ -8,19 +9,5 @@ import Quickshell
AndroidQuickToggleButton {
id: root
name: Translation.tr("Audio output")
statusText: toggled ? Translation.tr("Unmuted") : Translation.tr("Muted")
toggled: !Audio.sink?.audio?.muted
buttonIcon: Audio.sink?.audio?.muted ? "volume_off" : "volume_up"
mainAction: () => {
Audio.sink.audio.muted = !Audio.sink.audio.muted
}
altAction: () => {
root.openMenu()
}
StyledToolTip {
text: Translation.tr("Audio output | Right-click for volume mixer & device selector")
}
toggleModel: AudioToggle {}
}
@@ -1,5 +1,6 @@
import qs.services
import qs.modules.common
import qs.modules.common.models.quickToggles
import qs.modules.common.functions
import qs.modules.common.widgets
import QtQuick
@@ -9,22 +10,5 @@ import Quickshell.Bluetooth
AndroidQuickToggleButton {
id: root
name: Translation.tr("Bluetooth")
statusText: BluetoothStatus.firstActiveDevice?.name ?? Translation.tr("No device")
available: BluetoothStatus.available
toggled: BluetoothStatus.enabled
buttonIcon: BluetoothStatus.connected ? "bluetooth_connected" : BluetoothStatus.enabled ? "bluetooth" : "bluetooth_disabled"
mainAction: () => {
Bluetooth.defaultAdapter.enabled = !Bluetooth.defaultAdapter?.enabled
}
altAction: () => {
root.openMenu()
}
StyledToolTip {
text: Translation.tr("%1 | Right-click to configure").arg(
(BluetoothStatus.firstActiveDevice?.name ?? Translation.tr("Bluetooth"))
+ (BluetoothStatus.activeDeviceCount > 1 ? ` +${BluetoothStatus.activeDeviceCount - 1}` : "")
)
}
toggleModel: BluetoothToggle {}
}
@@ -1,4 +1,5 @@
import qs.modules.common
import qs.modules.common.models.quickToggles
import qs.modules.common.widgets
import qs.services
import QtQuick
@@ -8,73 +9,5 @@ import Quickshell.Io
AndroidQuickToggleButton {
id: root
name: Translation.tr("Cloudflare WARP")
toggled: false
buttonIcon: "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.visible = 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
}
}
}
}
StyledToolTip {
text: Translation.tr("Cloudflare WARP (1.1.1.1)")
}
toggleModel: CloudflareWarpToggle {}
}
@@ -1,5 +1,6 @@
import qs
import qs.modules.common
import qs.modules.common.models.quickToggles
import qs.modules.common.widgets
import qs.services
import QtQuick
@@ -8,25 +9,5 @@ import Quickshell
AndroidQuickToggleButton {
id: root
name: Translation.tr("Color picker")
statusText: ""
toggled: false
buttonIcon: "colorize"
mainAction: () => {
GlobalStates.sidebarRightOpen = false;
delayedActionTimer.start()
}
Timer {
id: delayedActionTimer
interval: 300
repeat: false
onTriggered: {
Quickshell.execDetached(["hyprpicker", "-a"])
}
}
StyledToolTip {
text: Translation.tr("Color picker")
}
toggleModel: ColorPickerToggle {}
}
@@ -1,27 +1,10 @@
import qs.modules.common
import qs.modules.common.models.quickToggles
import qs.modules.common.widgets
import qs.services
import QtQuick
import Quickshell
AndroidQuickToggleButton {
id: root
name: Translation.tr("Dark Mode")
statusText: Appearance.m3colors.darkmode ? Translation.tr("Dark") : Translation.tr("Light")
toggled: Appearance.m3colors.darkmode
buttonIcon: "contrast"
mainAction: () => {
if (Appearance.m3colors.darkmode) {
Quickshell.execDetached([Directories.wallpaperSwitchScriptPath, "--mode", "light", "--noswitch"]);
} else {
Quickshell.execDetached([Directories.wallpaperSwitchScriptPath, "--mode", "dark", "--noswitch"]);
}
}
StyledToolTip {
text: Translation.tr("Dark Mode")
}
toggleModel: DarkModeToggle {}
}
@@ -1,33 +1,11 @@
import qs
import qs.modules.common.models.quickToggles
import qs.modules.common.widgets
import qs.services
import QtQuick
import Quickshell
AndroidQuickToggleButton {
id: root
name: Translation.tr("EasyEffects")
available: EasyEffects.available
toggled: EasyEffects.active
buttonIcon: "graphic_eq"
Component.onCompleted: {
EasyEffects.fetchActiveState()
}
mainAction: () => {
EasyEffects.toggle()
}
altAction: () => {
Quickshell.execDetached(["bash", "-c", "flatpak run com.github.wwmm.easyeffects || easyeffects"])
GlobalStates.sidebarRightOpen = false
}
StyledToolTip {
text: Translation.tr("EasyEffects | Right-click to configure")
}
toggleModel: EasyEffectsToggle {}
}
@@ -1,4 +1,5 @@
import qs.modules.common
import qs.modules.common.models.quickToggles
import qs.modules.common.widgets
import qs.services
import QtQuick
@@ -6,30 +7,5 @@ import Quickshell
import Quickshell.Io
AndroidQuickToggleButton {
id: root
name: Translation.tr("Game mode")
statusText: ""
toggled: toggled
buttonIcon: "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
}
}
StyledToolTip {
text: Translation.tr("Game mode")
}
toggleModel: GameModeToggle {}
}
@@ -1,21 +1,11 @@
import qs.services
import qs.modules.common
import qs.modules.common.models.quickToggles
import qs.modules.common.functions
import qs.modules.common.widgets
import QtQuick
AndroidQuickToggleButton {
id: root
name: Translation.tr("Keep awake")
toggled: Idle.inhibit
buttonIcon: "coffee"
mainAction: () => {
Idle.toggleInhibit()
}
StyledToolTip {
text: Translation.tr("Keep system awake")
}
toggleModel: IdleInhibitorToggle {}
}
@@ -1,26 +1,11 @@
import qs
import qs.modules.common
import qs.modules.common.models.quickToggles
import qs.modules.common.widgets
import qs.services
import QtQuick
import Quickshell
AndroidQuickToggleButton {
id: root
name: Translation.tr("Audio input")
statusText: toggled ? Translation.tr("Enabled") : Translation.tr("Muted")
toggled: !Audio.source?.audio?.muted
buttonIcon: Audio.source?.audio?.muted ? "mic_off" : "mic"
mainAction: () => {
Audio.source.audio.muted = !Audio.source.audio.muted
}
altAction: () => {
root.openMenu()
}
StyledToolTip {
text: Translation.tr("Audio input | Right-click for volume mixer & device selector")
}
toggleModel: MicToggle {}
}
@@ -1,5 +1,6 @@
import qs
import qs.modules.common
import qs.modules.common.models.quickToggles
import qs.modules.common.widgets
import QtQuick
import Quickshell
@@ -8,25 +9,5 @@ import qs.services
AndroidQuickToggleButton {
id: root
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")
buttonIcon: toggled ? "music_cast" : (sourceIsMonitor ? "music_note" : "frame_person_mic")
StyledToolTip {
text: Translation.tr("Recognize music | Right-click to toggle source")
}
mainAction: () => {
SongRec.toggleRunning()
}
altAction: () => {
SongRec.toggleMonitorSource()
}
toggleModel: MusicRecognitionToggle {}
}
@@ -1,5 +1,6 @@
import qs.services
import qs.modules.common
import qs.modules.common.models.quickToggles
import qs.modules.common.functions
import qs.modules.common.widgets
import QtQuick
@@ -7,17 +8,6 @@ import QtQuick
AndroidQuickToggleButton {
id: root
name: Translation.tr("Internet")
statusText: Network.networkName
toggled: Network.wifiStatus !== "disabled"
buttonIcon: Network.materialSymbol
mainAction: () => Network.toggleWifi()
altAction: () => {
root.openMenu()
}
StyledToolTip {
text: Translation.tr("%1 | Right-click to configure").arg(Network.networkName)
}
toggleModel: NetworkToggle {}
}
@@ -1,34 +1,11 @@
import qs.modules.common
import qs.modules.common.models.quickToggles
import qs.modules.common.widgets
import qs.services
import QtQuick
import Quickshell
AndroidQuickToggleButton {
id: root
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
buttonIcon: auto ? "night_sight_auto" : "bedtime"
mainAction: () => {
Hyprsunset.toggle()
}
altAction: () => {
root.openMenu()
}
Component.onCompleted: {
Hyprsunset.fetchState()
}
StyledToolTip {
text: Translation.tr("Night Light | Right-click to configure")
}
toggleModel: NightLightToggle {}
}
@@ -1,23 +1,11 @@
import qs
import qs.modules.common
import qs.modules.common.models.quickToggles
import qs.modules.common.widgets
import qs.services
import QtQuick
import Quickshell
AndroidQuickToggleButton {
id: root
name: Translation.tr("Notifications")
statusText: toggled ? Translation.tr("Show") : Translation.tr("Silent")
toggled: !Notifications.silent
buttonIcon: toggled ? "notifications_active" : "notifications_paused"
mainAction: () => {
Notifications.silent = !Notifications.silent;
}
StyledToolTip {
text: Translation.tr("Show notifications")
}
toggleModel: NotificationToggle {}
}
@@ -1,22 +1,11 @@
import qs
import qs.modules.common
import qs.modules.common.models.quickToggles
import qs.modules.common.widgets
import qs.services
import QtQuick
import Quickshell
AndroidQuickToggleButton {
id: root
name: Translation.tr("Virtual Keyboard")
toggled: GlobalStates.oskOpen
buttonIcon: toggled ? "keyboard_hide" : "keyboard"
mainAction: () => {
GlobalStates.oskOpen = !GlobalStates.oskOpen
}
StyledToolTip {
text: Translation.tr("On-screen keyboard")
}
toggleModel: OnScreenKeyboardToggle {}
}
@@ -1,5 +1,6 @@
import qs
import qs.modules.common
import qs.modules.common.models.quickToggles
import qs.modules.common.widgets
import qs.services
import QtQuick
@@ -7,36 +8,5 @@ import Quickshell
import Quickshell.Services.UPower
AndroidQuickToggleButton {
id: root
name: Translation.tr("Power Profile")
toggled: PowerProfiles.profile !== PowerProfile.Balanced
buttonIcon: 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
}
}
StyledToolTip {
text: Translation.tr("Click to cycle through power profiles")
}
toggleModel: PowerProfilesToggle {}
}
@@ -2,29 +2,42 @@ import QtQuick
import QtQuick.Layouts
import qs.services
import qs.modules.common
import qs.modules.common.models.quickToggles
import qs.modules.common.functions
import qs.modules.common.widgets
GroupButton {
id: root
// Info to be passed to by repeater
required property int buttonIndex
required property var buttonData
required property bool expandedSize
required property string buttonIcon
required property string name
required property var mainAction
property string statusText: toggled ? Translation.tr("Active") : Translation.tr("Inactive")
property bool available: true
required property real baseCellWidth
required property real baseCellHeight
required property real cellSpacing
required property int cellSize
// Signals
signal openMenu()
// Declared in specific toggles
property QuickToggleModel toggleModel
property string name: toggleModel?.name ?? ""
property string statusText: (toggleModel?.hasStatusText) ? (toggleModel?.statusText || (toggled ? Translation.tr("Active") : Translation.tr("Inactive"))) : ""
property string tooltipText: toggleModel?.tooltipText ?? ""
property string buttonIcon: toggleModel?.icon ?? "close"
property bool available: toggleModel?.available ?? true
toggled: toggleModel?.toggled ?? false
property var mainAction: toggleModel?.mainAction ?? null
altAction: toggleModel?.hasMenu ? (() => root.openMenu()) : (toggleModel?.altAction ?? null)
// Edit mode state
property bool editMode: false
// Sizing shenanigans
baseWidth: root.baseCellWidth * cellSize + cellSpacing * (cellSize - 1)
baseHeight: root.baseCellHeight
property bool editMode: false
enableImplicitWidthAnimation: !editMode && root.mouseArea.containsMouse
enableImplicitHeightAnimation: !editMode && root.mouseArea.containsMouse
Behavior on baseWidth {
@@ -41,8 +54,6 @@ GroupButton {
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
}
signal openMenu()
enabled: available || editMode
padding: 6
horizontalPadding: padding
@@ -226,4 +237,9 @@ GroupButton {
event.accepted = true;
}
}
StyledToolTip {
extraVisibleCondition: root.tooltipText !== ""
text: root.tooltipText
}
}
@@ -1,5 +1,6 @@
import qs
import qs.modules.common
import qs.modules.common.models.quickToggles
import qs.modules.common.widgets
import qs.services
import QtQuick
@@ -7,27 +8,5 @@ import Quickshell
import Quickshell.Hyprland
AndroidQuickToggleButton {
id: root
name: Translation.tr("Screen snip")
statusText: ""
toggled: false
buttonIcon: "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"]);
}
}
StyledToolTip {
text: Translation.tr("Screen snip")
}
toggleModel: ScreenSnipToggle {}
}
@@ -171,16 +171,8 @@ Item { // Bar content region
implicitWidth: Appearance.sizes.baseVerticalBarWidth
implicitHeight: bottomSectionColumnLayout.implicitHeight
onScrollDown: {
const currentVolume = Audio.value;
const step = currentVolume < 0.1 ? 0.01 : 0.02 || 0.2;
Audio.sink.audio.volume -= step;
}
onScrollUp: {
const currentVolume = Audio.value;
const step = currentVolume < 0.1 ? 0.01 : 0.02 || 0.2;
Audio.sink.audio.volume = Math.min(1, Audio.sink.audio.volume + step);
}
onScrollDown: Audio.decrementVolume();
onScrollUp: Audio.incrementVolume();
onMovedAway: GlobalStates.osdVolumeOpen = false;
onPressed: event => {
if (event.button === Qt.LeftButton) {