1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-01-24 21:42:51 -05:00

Modularlize the shell

This commit is contained in:
bbedward
2025-07-10 16:40:04 -04:00
parent 7cdeba1625
commit 40b2a3af1e
28 changed files with 5260 additions and 4906 deletions

127
Services/AudioService.qml Normal file
View File

@@ -0,0 +1,127 @@
import QtQuick
import Quickshell
import Quickshell.Io
pragma Singleton
pragma ComponentBehavior: Bound
Singleton {
id: root
property int volumeLevel: 50
property var audioSinks: []
property string currentAudioSink: ""
// Real Audio Control
Process {
id: volumeChecker
command: ["bash", "-c", "pactl get-sink-volume @DEFAULT_SINK@ | grep -o '[0-9]*%' | head -1 | tr -d '%'"]
running: true
stdout: SplitParser {
splitMarker: "\n"
onRead: (data) => {
if (data.trim()) {
root.volumeLevel = Math.min(100, parseInt(data.trim()) || 50)
}
}
}
}
Process {
id: audioSinkLister
command: ["bash", "-c", "pactl list sinks | grep -E '^Sink #|device.description|Name:' | paste - - - | sed 's/Sink #//g' | sed 's/Name: //g' | sed 's/device.description = //g' | sed 's/\"//g'"]
running: true
stdout: StdioCollector {
onStreamFinished: {
if (text.trim()) {
let sinks = []
let lines = text.trim().split('\n')
for (let line of lines) {
let parts = line.split('\t')
if (parts.length >= 3) {
let id = parts[0].trim()
let name = parts[1].trim()
let description = parts[2].trim()
// Use description as display name if available, fallback to name processing
let displayName = description
if (!description || description === name) {
if (name.includes("analog-stereo")) displayName = "Built-in Speakers"
else if (name.includes("bluez")) displayName = "Bluetooth Audio"
else if (name.includes("usb")) displayName = "USB Audio"
else if (name.includes("hdmi")) displayName = "HDMI Audio"
else if (name.includes("easyeffects")) displayName = "EasyEffects"
else displayName = name
}
sinks.push({
id: id,
name: name,
displayName: displayName,
active: false // Will be determined by default sink
})
}
}
root.audioSinks = sinks
defaultSinkChecker.running = true
}
}
}
}
Process {
id: defaultSinkChecker
command: ["pactl", "get-default-sink"]
running: false
stdout: SplitParser {
splitMarker: "\n"
onRead: (data) => {
if (data.trim()) {
root.currentAudioSink = data.trim()
console.log("Default audio sink:", root.currentAudioSink)
// Update active status in audioSinks
let updatedSinks = []
for (let sink of root.audioSinks) {
updatedSinks.push({
id: sink.id,
name: sink.name,
displayName: sink.displayName,
active: sink.name === root.currentAudioSink
})
}
root.audioSinks = updatedSinks
}
}
}
}
function setVolume(percentage) {
let volumeSetProcess = Qt.createQmlObject('
import Quickshell.Io
Process {
command: ["pactl", "set-sink-volume", "@DEFAULT_SINK@", "' + percentage + '%"]
running: true
onExited: volumeChecker.running = true
}
', root)
}
function setAudioSink(sinkName) {
let sinkSetProcess = Qt.createQmlObject('
import Quickshell.Io
Process {
command: ["pactl", "set-default-sink", "' + sinkName + '"]
running: true
onExited: {
defaultSinkChecker.running = true
audioSinkLister.running = true
}
}
', root)
}
}

View File

@@ -0,0 +1,121 @@
import QtQuick
import Quickshell
import Quickshell.Io
pragma Singleton
pragma ComponentBehavior: Bound
Singleton {
id: root
property bool bluetoothEnabled: false
property bool bluetoothAvailable: false
property var bluetoothDevices: []
// Real Bluetooth Management
Process {
id: bluetoothStatusChecker
command: ["bluetoothctl", "show"]
running: true
stdout: StdioCollector {
onStreamFinished: {
root.bluetoothAvailable = text.trim() !== "" && !text.includes("No default controller")
root.bluetoothEnabled = text.includes("Powered: yes")
console.log("Bluetooth available:", root.bluetoothAvailable, "enabled:", root.bluetoothEnabled)
if (root.bluetoothEnabled && root.bluetoothAvailable) {
bluetoothDeviceScanner.running = true
} else {
root.bluetoothDevices = []
}
}
}
}
Process {
id: bluetoothDeviceScanner
command: ["bash", "-c", "bluetoothctl devices | while read -r line; do if [[ $line =~ Device\\ ([0-9A-F:]+)\\ (.+) ]]; then mac=\"${BASH_REMATCH[1]}\"; name=\"${BASH_REMATCH[2]}\"; if [[ ! $name =~ ^/org/bluez ]]; then info=$(bluetoothctl info $mac); connected=$(echo \"$info\" | grep 'Connected:' | grep -q 'yes' && echo 'true' || echo 'false'); battery=$(echo \"$info\" | grep 'Battery Percentage' | grep -o '([0-9]*)' | tr -d '()'); echo \"$mac|$name|$connected|${battery:-}\"; fi; fi; done"]
running: false
stdout: StdioCollector {
onStreamFinished: {
if (text.trim()) {
let devices = []
let lines = text.trim().split('\n')
for (let line of lines) {
if (line.trim()) {
let parts = line.split('|')
if (parts.length >= 3) {
let mac = parts[0].trim()
let name = parts[1].trim()
let connected = parts[2].trim() === 'true'
let battery = parts[3] ? parseInt(parts[3]) : -1
// Skip if name is still a technical path
if (name.startsWith('/org/bluez') || name.includes('hci0')) {
continue
}
// Determine device type from name
let type = "bluetooth"
let nameLower = name.toLowerCase()
if (nameLower.includes("headphone") || nameLower.includes("airpod") || nameLower.includes("headset") || nameLower.includes("arctis")) type = "headset"
else if (nameLower.includes("mouse")) type = "mouse"
else if (nameLower.includes("keyboard")) type = "keyboard"
else if (nameLower.includes("phone") || nameLower.includes("iphone") || nameLower.includes("samsung")) type = "phone"
else if (nameLower.includes("watch")) type = "watch"
else if (nameLower.includes("speaker")) type = "speaker"
devices.push({
mac: mac,
name: name,
type: type,
connected: connected,
battery: battery
})
}
}
}
root.bluetoothDevices = devices
console.log("Found", devices.length, "Bluetooth devices")
}
}
}
}
function scanDevices() {
if (root.bluetoothEnabled && root.bluetoothAvailable) {
bluetoothDeviceScanner.running = true
}
}
function toggleBluetoothDevice(mac) {
console.log("Toggling Bluetooth device:", mac)
let device = root.bluetoothDevices.find(d => d.mac === mac)
if (device) {
let action = device.connected ? "disconnect" : "connect"
let toggleProcess = Qt.createQmlObject('
import Quickshell.Io
Process {
command: ["bluetoothctl", "' + action + '", "' + mac + '"]
running: true
onExited: bluetoothDeviceScanner.running = true
}
', root)
}
}
function toggleBluetooth() {
let action = root.bluetoothEnabled ? "off" : "on"
let toggleProcess = Qt.createQmlObject('
import Quickshell.Io
Process {
command: ["bluetoothctl", "power", "' + action + '"]
running: true
onExited: bluetoothStatusChecker.running = true
}
', root)
}
}

View File

@@ -0,0 +1,107 @@
import QtQuick
import Quickshell
import Quickshell.Io
pragma Singleton
pragma ComponentBehavior: Bound
Singleton {
id: root
property int brightnessLevel: 75
property bool brightnessAvailable: false
// Check if brightness control is available
Process {
id: brightnessAvailabilityChecker
command: ["bash", "-c", "if command -v brightnessctl > /dev/null; then echo 'brightnessctl'; elif command -v xbacklight > /dev/null; then echo 'xbacklight'; else echo 'none'; fi"]
running: true
stdout: SplitParser {
splitMarker: "\n"
onRead: (data) => {
if (data.trim()) {
let method = data.trim()
if (method === "brightnessctl" || method === "xbacklight") {
root.brightnessAvailable = true
brightnessChecker.running = true
} else {
root.brightnessAvailable = false
console.log("Brightness control not available - no brightnessctl or xbacklight found")
}
}
}
}
}
// Brightness Control
Process {
id: brightnessChecker
command: ["bash", "-c", "if command -v brightnessctl > /dev/null; then brightnessctl get; elif command -v xbacklight > /dev/null; then xbacklight -get | cut -d. -f1; else echo 75; fi"]
running: false
stdout: SplitParser {
splitMarker: "\n"
onRead: (data) => {
if (data.trim()) {
let brightness = parseInt(data.trim()) || 75
// brightnessctl returns absolute value, need to convert to percentage
if (brightness > 100) {
brightnessMaxChecker.running = true
} else {
root.brightnessLevel = brightness
}
}
}
}
}
Process {
id: brightnessMaxChecker
command: ["brightnessctl", "max"]
running: false
stdout: SplitParser {
splitMarker: "\n"
onRead: (data) => {
if (data.trim()) {
let maxBrightness = parseInt(data.trim()) || 100
brightnessCurrentChecker.property("maxBrightness", maxBrightness)
brightnessCurrentChecker.running = true
}
}
}
}
Process {
id: brightnessCurrentChecker
property int maxBrightness: 100
command: ["brightnessctl", "get"]
running: false
stdout: SplitParser {
splitMarker: "\n"
onRead: (data) => {
if (data.trim()) {
let currentBrightness = parseInt(data.trim()) || 75
root.brightnessLevel = Math.round((currentBrightness / maxBrightness) * 100)
}
}
}
}
function setBrightness(percentage) {
if (!root.brightnessAvailable) {
console.warn("Brightness control not available")
return
}
let brightnessSetProcess = Qt.createQmlObject('
import Quickshell.Io
Process {
command: ["bash", "-c", "if command -v brightnessctl > /dev/null; then brightnessctl set ' + percentage + '%; elif command -v xbacklight > /dev/null; then xbacklight -set ' + percentage + '; fi"]
running: true
onExited: brightnessChecker.running = true
}
', root)
}
}

View File

@@ -0,0 +1,26 @@
import QtQuick
import Quickshell
import Quickshell.Io
pragma Singleton
pragma ComponentBehavior: Bound
Singleton {
id: root
// Color Picker Process
Process {
id: colorPickerProcess
command: ["hyprpicker", "-a"]
running: false
onExited: (exitCode) => {
if (exitCode !== 0) {
console.warn("Color picker failed. Make sure hyprpicker is installed: yay -S hyprpicker")
}
}
}
function pickColor() {
colorPickerProcess.running = true
}
}

View File

@@ -1,11 +1,10 @@
pragma Singleton
pragma ComponentBehavior: Bound
import QtQml.Models
import QtQuick
import QtQml.Models
import Quickshell
import Quickshell.Io
import Quickshell.Services.Mpris
pragma Singleton
pragma ComponentBehavior: Bound
/**
* A service that provides easy access to the active Mpris player.

159
Services/NetworkService.qml Normal file
View File

@@ -0,0 +1,159 @@
import QtQuick
import Quickshell
import Quickshell.Io
pragma Singleton
pragma ComponentBehavior: Bound
Singleton {
id: root
property string networkStatus: "disconnected" // "ethernet", "wifi", "disconnected"
property string ethernetIP: ""
property string wifiIP: ""
property bool wifiAvailable: false
property bool wifiEnabled: true
// Real Network Management
Process {
id: networkStatusChecker
command: ["bash", "-c", "nmcli -t -f DEVICE,TYPE,STATE device | grep -E '(ethernet|wifi)' && echo '---' && ip link show | grep -E '^[0-9]+:.*ethernet.*state UP'"]
running: true
stdout: StdioCollector {
onStreamFinished: {
if (text.trim()) {
console.log("Network status full output:", text.trim())
let hasEthernet = text.includes("ethernet:connected")
let hasWifi = text.includes("wifi:connected")
let ethernetCableUp = text.includes("state UP")
// Check if ethernet cable is physically connected but not managed
if (hasEthernet || ethernetCableUp) {
root.networkStatus = "ethernet"
ethernetIPChecker.running = true
console.log("Setting network status to ethernet (cable connected)")
} else if (hasWifi) {
root.networkStatus = "wifi"
wifiIPChecker.running = true
console.log("Setting network status to wifi")
} else {
root.networkStatus = "disconnected"
root.ethernetIP = ""
root.wifiIP = ""
console.log("Setting network status to disconnected")
}
// Always check WiFi radio status
wifiRadioChecker.running = true
} else {
root.networkStatus = "disconnected"
root.ethernetIP = ""
root.wifiIP = ""
console.log("No network output, setting to disconnected")
}
}
}
}
Process {
id: wifiRadioChecker
command: ["nmcli", "radio", "wifi"]
running: false
stdout: SplitParser {
splitMarker: "\n"
onRead: (data) => {
let response = data.trim()
root.wifiAvailable = response === "enabled" || response === "disabled"
root.wifiEnabled = response === "enabled"
console.log("WiFi available:", root.wifiAvailable, "enabled:", root.wifiEnabled)
}
}
}
Process {
id: ethernetIPChecker
command: ["bash", "-c", "ip route get 1.1.1.1 | grep -oP 'src \\K\\S+' | head -1"]
running: false
stdout: SplitParser {
splitMarker: "\n"
onRead: (data) => {
if (data.trim()) {
root.ethernetIP = data.trim()
console.log("Ethernet IP:", root.ethernetIP)
}
}
}
}
Process {
id: wifiIPChecker
command: ["bash", "-c", "nmcli -t -f IP4.ADDRESS dev show $(nmcli -t -f DEVICE,TYPE device | grep wifi | cut -d: -f1 | head -1) | cut -d: -f2 | cut -d/ -f1"]
running: false
stdout: SplitParser {
splitMarker: "\n"
onRead: (data) => {
if (data.trim()) {
root.wifiIP = data.trim()
console.log("WiFi IP:", root.wifiIP)
}
}
}
}
function toggleNetworkConnection(type) {
if (type === "ethernet") {
// Toggle ethernet connection
if (root.networkStatus === "ethernet") {
// Disconnect ethernet
let disconnectProcess = Qt.createQmlObject('
import Quickshell.Io
Process {
command: ["bash", "-c", "nmcli device disconnect $(nmcli -t -f DEVICE,TYPE device | grep ethernet | cut -d: -f1 | head -1)"]
running: true
onExited: networkStatusChecker.running = true
}
', root)
} else {
// Connect ethernet with proper nmcli device connect
let connectProcess = Qt.createQmlObject('
import Quickshell.Io
Process {
command: ["bash", "-c", "nmcli device connect $(nmcli -t -f DEVICE,TYPE device | grep ethernet | cut -d: -f1 | head -1)"]
running: true
onExited: networkStatusChecker.running = true
}
', root)
}
} else if (type === "wifi") {
// Connect to WiFi if disconnected
if (root.networkStatus !== "wifi" && root.wifiEnabled) {
let connectProcess = Qt.createQmlObject('
import Quickshell.Io
Process {
command: ["bash", "-c", "nmcli device connect $(nmcli -t -f DEVICE,TYPE device | grep wifi | cut -d: -f1 | head -1)"]
running: true
onExited: networkStatusChecker.running = true
}
', root)
}
}
}
function toggleWifiRadio() {
let action = root.wifiEnabled ? "off" : "on"
let toggleProcess = Qt.createQmlObject('
import Quickshell.Io
Process {
command: ["nmcli", "radio", "wifi", "' + action + '"]
running: true
onExited: {
networkStatusChecker.running = true
}
}
', root)
}
}

View File

@@ -1,85 +0,0 @@
pragma Singleton
import QtQuick
import Quickshell
import Quickshell.Io
QtObject {
id: osService
property string osLogo: ""
property string osName: ""
Process {
id: osDetector
command: ["lsb_release", "-i", "-s"]
running: true
stdout: SplitParser {
splitMarker: "\n"
onRead: (data) => {
if (data.trim()) {
let osId = data.trim().toLowerCase()
console.log("Detected OS:", osId)
setOSInfo(osId)
}
}
}
onExited: (exitCode) => {
if (exitCode !== 0) {
osDetectorFallback.running = true
}
}
}
Process {
id: osDetectorFallback
command: ["sh", "-c", "cat /etc/os-release | grep '^ID=' | cut -d'=' -f2 | tr -d '\"'"]
running: false
stdout: SplitParser {
splitMarker: "\n"
onRead: (data) => {
if (data.trim()) {
let osId = data.trim().toLowerCase()
console.log("Detected OS (fallback):", osId)
setOSInfo(osId)
}
}
}
onExited: (exitCode) => {
if (exitCode !== 0) {
osService.osLogo = ""
osService.osName = "Linux"
console.log("OS detection failed, using generic icon")
}
}
}
function setOSInfo(osId) {
if (osId.includes("arch")) {
osService.osLogo = "\uf303"
osService.osName = "Arch Linux"
} else if (osId.includes("ubuntu")) {
osService.osLogo = "\uf31b"
osService.osName = "Ubuntu"
} else if (osId.includes("fedora")) {
osService.osLogo = "\uf30a"
osService.osName = "Fedora"
} else if (osId.includes("debian")) {
osService.osLogo = "\uf306"
osService.osName = "Debian"
} else if (osId.includes("opensuse")) {
osService.osLogo = "\uef6d"
osService.osName = "openSUSE"
} else if (osId.includes("manjaro")) {
osService.osLogo = "\uf312"
osService.osName = "Manjaro"
} else {
osService.osLogo = "\uf033"
osService.osName = "Linux"
}
}
}

View File

@@ -0,0 +1,110 @@
import QtQuick
import Quickshell
import Quickshell.Io
pragma Singleton
pragma ComponentBehavior: Bound
Singleton {
id: root
property string osLogo: ""
property string osName: ""
// OS Detection
Process {
id: osDetector
command: ["lsb_release", "-i", "-s"]
running: true
stdout: SplitParser {
splitMarker: "\n"
onRead: (data) => {
if (data.trim()) {
let osId = data.trim().toLowerCase()
console.log("Detected OS:", osId)
// Set OS-specific Nerd Font icons and names
if (osId.includes("arch")) {
root.osLogo = "\uf303" // Arch Linux Nerd Font icon
root.osName = "Arch Linux"
console.log("Set Arch logo:", root.osLogo)
} else if (osId.includes("ubuntu")) {
root.osLogo = "\uf31b" // Ubuntu Nerd Font icon
root.osName = "Ubuntu"
} else if (osId.includes("fedora")) {
root.osLogo = "\uf30a" // Fedora Nerd Font icon
root.osName = "Fedora"
} else if (osId.includes("debian")) {
root.osLogo = "\uf306" // Debian Nerd Font icon
root.osName = "Debian"
} else if (osId.includes("opensuse")) {
root.osLogo = "\uef6d" // openSUSE Nerd Font icon
root.osName = "openSUSE"
} else if (osId.includes("manjaro")) {
root.osLogo = "\uf312" // Manjaro Nerd Font icon
root.osName = "Manjaro"
} else {
root.osLogo = "\uf033" // Generic Linux Nerd Font icon
root.osName = "Linux"
}
}
}
}
onExited: (exitCode) => {
if (exitCode !== 0) {
// Fallback: try checking /etc/os-release
osDetectorFallback.running = true
}
}
}
// Fallback OS detection
Process {
id: osDetectorFallback
command: ["sh", "-c", "grep '^ID=' /etc/os-release | cut -d'=' -f2 | tr -d '\"'"]
running: false
stdout: SplitParser {
splitMarker: "\n"
onRead: (data) => {
if (data.trim()) {
let osId = data.trim().toLowerCase()
console.log("Detected OS (fallback):", osId)
if (osId.includes("arch")) {
root.osLogo = "\uf303"
root.osName = "Arch Linux"
} else if (osId.includes("ubuntu")) {
root.osLogo = "\uf31b"
root.osName = "Ubuntu"
} else if (osId.includes("fedora")) {
root.osLogo = "\uf30a"
root.osName = "Fedora"
} else if (osId.includes("debian")) {
root.osLogo = "\uf306"
root.osName = "Debian"
} else if (osId.includes("opensuse")) {
root.osLogo = "\uef6d"
root.osName = "openSUSE"
} else if (osId.includes("manjaro")) {
root.osLogo = "\uf312"
root.osName = "Manjaro"
} else {
root.osLogo = "\uf033"
root.osName = "Linux"
}
}
}
}
onExited: (exitCode) => {
if (exitCode !== 0) {
// Ultimate fallback - use generic apps icon (empty logo means fallback to "apps")
root.osLogo = ""
root.osName = "Linux"
console.log("OS detection failed, using generic icon")
}
}
}
}

View File

@@ -1,11 +1,11 @@
pragma Singleton
import QtQuick
import Quickshell
import Quickshell.Io
pragma Singleton
pragma ComponentBehavior: Bound
QtObject {
id: weatherService
Singleton {
id: root
property var weather: ({
available: false,
@@ -32,7 +32,7 @@ QtObject {
try {
let parsedData = JSON.parse(text.trim())
if (parsedData.current && parsedData.location) {
weatherService.weather = {
root.weather = {
available: true,
temp: parseInt(parsedData.current.temp_C || 0),
tempF: parseInt(parsedData.current.temp_F || 0),
@@ -45,15 +45,15 @@ QtObject {
uv: parseInt(parsedData.current.uvIndex || 0),
pressure: parseInt(parsedData.current.pressure || 0)
}
console.log("Weather updated:", weatherService.weather.city, weatherService.weather.temp + "°C")
console.log("Weather updated:", root.weather.city, root.weather.temp + "°C")
}
} catch (e) {
console.warn("Failed to parse weather data:", e.message)
weatherService.weather.available = false
root.weather.available = false
}
} else {
console.warn("No valid weather data received")
weatherService.weather.available = false
root.weather.available = false
}
}
}
@@ -61,7 +61,7 @@ QtObject {
onExited: (exitCode) => {
if (exitCode !== 0) {
console.warn("Weather fetch failed with exit code:", exitCode)
weatherService.weather.available = false
root.weather.available = false
}
}
}

172
Services/WifiService.qml Normal file
View File

@@ -0,0 +1,172 @@
import QtQuick
import Quickshell
import Quickshell.Io
pragma Singleton
pragma ComponentBehavior: Bound
Singleton {
id: root
property string currentWifiSSID: ""
property string wifiSignalStrength: "excellent" // "excellent", "good", "fair", "poor"
property var wifiNetworks: []
property var savedWifiNetworks: []
Process {
id: currentWifiInfo
command: ["bash", "-c", "nmcli -t -f ssid,signal connection show --active | grep -v '^--' | grep -v '^$'"]
running: false
stdout: SplitParser {
splitMarker: "\n"
onRead: (data) => {
if (data.trim()) {
let parts = data.split(":")
if (parts.length >= 2 && parts[0].trim() !== "") {
root.currentWifiSSID = parts[0].trim()
let signal = parseInt(parts[1]) || 100
if (signal >= 75) root.wifiSignalStrength = "excellent"
else if (signal >= 50) root.wifiSignalStrength = "good"
else if (signal >= 25) root.wifiSignalStrength = "fair"
else root.wifiSignalStrength = "poor"
console.log("Active WiFi:", root.currentWifiSSID, "Signal:", signal + "%")
}
}
}
}
}
Process {
id: wifiScanner
command: ["nmcli", "-t", "-f", "SSID,SIGNAL,SECURITY", "dev", "wifi"]
running: false
stdout: StdioCollector {
onStreamFinished: {
if (text.trim()) {
let networks = []
let lines = text.trim().split('\n')
for (let line of lines) {
let parts = line.split(':')
if (parts.length >= 3 && parts[0].trim() !== "") {
let ssid = parts[0].trim()
let signal = parseInt(parts[1]) || 0
let security = parts[2].trim()
// Skip duplicates
if (!networks.find(n => n.ssid === ssid)) {
networks.push({
ssid: ssid,
signal: signal,
secured: security !== "",
connected: ssid === root.currentWifiSSID,
signalStrength: signal >= 75 ? "excellent" :
signal >= 50 ? "good" :
signal >= 25 ? "fair" : "poor"
})
}
}
}
// Sort by signal strength
networks.sort((a, b) => b.signal - a.signal)
root.wifiNetworks = networks
console.log("Found", networks.length, "WiFi networks")
}
}
}
}
Process {
id: savedWifiScanner
command: ["nmcli", "-t", "-f", "NAME", "connection", "show"]
running: false
stdout: StdioCollector {
onStreamFinished: {
if (text.trim()) {
let saved = []
let lines = text.trim().split('\n')
for (let line of lines) {
if (line.trim() && !line.includes("ethernet") && !line.includes("lo")) {
saved.push({
ssid: line.trim(),
saved: true
})
}
}
root.savedWifiNetworks = saved
console.log("Found", saved.length, "saved WiFi networks")
}
}
}
}
function scanWifi() {
wifiScanner.running = true
savedWifiScanner.running = true
currentWifiInfo.running = true
}
function connectToWifi(ssid) {
console.log("Connecting to WiFi:", ssid)
let connectProcess = Qt.createQmlObject('
import Quickshell.Io
Process {
command: ["nmcli", "dev", "wifi", "connect", "' + ssid + '"]
running: true
onExited: (exitCode) => {
console.log("WiFi connection result:", exitCode)
if (exitCode === 0) {
console.log("Connected to WiFi successfully")
} else {
console.log("WiFi connection failed")
}
scanWifi()
}
}
', root)
}
function connectToWifiWithPassword(ssid, password) {
console.log("Connecting to WiFi with password:", ssid)
let connectProcess = Qt.createQmlObject('
import Quickshell.Io
Process {
command: ["nmcli", "dev", "wifi", "connect", "' + ssid + '", "password", "' + password + '"]
running: true
onExited: (exitCode) => {
console.log("WiFi connection with password result:", exitCode)
if (exitCode === 0) {
console.log("Connected to WiFi with password successfully")
} else {
console.log("WiFi connection with password failed")
}
scanWifi()
}
}
', root)
}
function forgetWifiNetwork(ssid) {
console.log("Forgetting WiFi network:", ssid)
let forgetProcess = Qt.createQmlObject('
import Quickshell.Io
Process {
command: ["nmcli", "connection", "delete", "' + ssid + '"]
running: true
onExited: (exitCode) => {
console.log("WiFi forget result:", exitCode)
scanWifi()
}
}
', root)
}
}

View File

@@ -1 +1,9 @@
singleton MprisController 1.0 MprisController.qml
singleton MprisController 1.0 MprisController.qml
singleton OSDetectorService 1.0 OSDetectorService.qml
singleton ColorPickerService 1.0 ColorPickerService.qml
singleton WeatherService 1.0 WeatherService.qml
singleton NetworkService 1.0 NetworkService.qml
singleton WifiService 1.0 WifiService.qml
singleton AudioService 1.0 AudioService.qml
singleton BluetoothService 1.0 BluetoothService.qml
singleton BrightnessService 1.0 BrightnessService.qml