diff options
| author | Aargh Rai <aargh.rai+git@gmail.com> | 2025-12-08 16:58:52 +0530 |
|---|---|---|
| committer | Aargh Rai <aargh.rai+git@gmail.com> | 2025-12-08 16:58:52 +0530 |
| commit | af844bbc44741a971614175248cc29505d1acbd1 (patch) | |
| tree | d75c8dc30e7f0f0596b5f087ad3697678a042e3e | |
| parent | 15bed9293ad7fb0b54cef68cdbf1a0549ec7aa97 (diff) | |
replaced wofi with custom app menu + right side apps bar + organization of qml files
27 files changed, 928 insertions, 410 deletions
@@ -60,7 +60,6 @@ Check ./sync.sh to find where each directory is sourced from - nvim using NvChad - tmux - yazi for file exploring -- wofi for app menu ### Hyprland Low battery warning notifications @@ -101,7 +100,7 @@ IF YOU ARE NOT LEFT HANDED, change this in hypr/hyprland/input.conf:input:left_h |Win + L|Lock| |Win + E|Spawn File Explorer (yazi)| |Win + F|Make active window floating| -|Win + R|**Spawn App Menu** (wofi)| +|Win + R|**Spawn App Menu**| |Win + P|Pseudo ??? (I don't know what this is used for)| |Win + J|Toggle window split| |Ctrl + Shift + Escape|Spawn Task Manager (btop)| diff --git a/home-manager/home.nix b/home-manager/home.nix index 4597ed9..4d219e6 100644 --- a/home-manager/home.nix +++ b/home-manager/home.nix @@ -31,7 +31,6 @@ let "nvim" "quickshell" "tmux" - "wofi" "yazi" ]; diff --git a/hypr/hyprland/keybinds.conf b/hypr/hyprland/keybinds.conf index af743a2..51ef1b1 100644 --- a/hypr/hyprland/keybinds.conf +++ b/hypr/hyprland/keybinds.conf @@ -8,7 +8,8 @@ bind = $mainMod SHIFT, L, exit, bind = $mainMod, L, exec, hyprlock bind = $mainMod, E, exec, $fileManager bind = $mainMod, F, togglefloating, -bind = $mainMod, R, exec, $menu +#bind = $mainMod, R, exec, $menu +bind = $mainMod, R, global, quickshell:toggleLauncher bind = $mainMod, P, pseudo, # dwindle bind = $mainMod, J, togglesplit, # dwindle bind = CTRL SHIFT, escape, exec, $taskManager diff --git a/hypr/hyprland/vars.conf b/hypr/hyprland/vars.conf index 519ec93..ec28f62 100644 --- a/hypr/hyprland/vars.conf +++ b/hypr/hyprland/vars.conf @@ -1,4 +1,3 @@ $terminal = foot $fileManager = foot -e yazi -$menu = wofi -a --show drun $taskManager = foot -e btop --force-utf diff --git a/nixos/desktop-environment.nix b/nixos/desktop-environment.nix index 5523cb7..47c7f19 100644 --- a/nixos/desktop-environment.nix +++ b/nixos/desktop-environment.nix @@ -10,7 +10,6 @@ programs.dconf.enable = true; environment.systemPackages = with pkgs; [ quickshell.packages.${pkgs.system}.quickshell - wofi adwaita-icon-theme swaybg wl-clipboard diff --git a/quickshell/AppLauncher.qml b/quickshell/AppLauncher.qml new file mode 100644 index 0000000..a1b5ab2 --- /dev/null +++ b/quickshell/AppLauncher.qml @@ -0,0 +1,248 @@ +import QtQuick +import QtQuick.Controls +import Quickshell +import Quickshell.Io + +Rectangle { + id: appLauncher + + width: 400 + height: 600 + color: shellRoot.black + radius: 16 + border.width: 3 + border.color: shellRoot.blue + antialiasing: true + + property bool isVisible: false + property int selectedIndex: -1 + property int hoverIndex: -1 + + signal requestClose() + + focus: true + + Keys.onEscapePressed: requestClose() + + Keys.onUpPressed: { + hoverIndex = -1 + if (selectedIndex === -1) { + selectedIndex = appListModel.count - 1 + } else if (selectedIndex > 0) { + selectedIndex-- + } + listView.positionViewAtIndex(selectedIndex, ListView.Contain) + } + + Keys.onDownPressed: { + hoverIndex = -1 + if (selectedIndex === -1) { + selectedIndex = 0 + } else if (selectedIndex < appListModel.count - 1) { + selectedIndex++ + } + listView.positionViewAtIndex(selectedIndex, ListView.Contain) + } + + Keys.onReturnPressed: { + if (selectedIndex >= 0 && selectedIndex < appListModel.count) { + launchApp(appListModel.get(selectedIndex).appCommand) + } + } + + Keys.onEnterPressed: { + if (selectedIndex >= 0 && selectedIndex < appListModel.count) { + launchApp(appListModel.get(selectedIndex).appCommand) + } + } + + // Reset selection when widget becomes visible + onIsVisibleChanged: { + if (isVisible) { + selectedIndex = -1 // Start with nothing selected + hoverIndex = -1 // Reset hover on open + appLauncher.forceActiveFocus() + // Reload apps every time the launcher opens + loadApps() + } + } + + // Process to load apps + Process { + id: appLoader + running: false // Don't auto-start, we'll trigger it manually + command: ["sh", "-c", "~/.config/quickshell/scripts/list-apps.sh"] + + stdout: SplitParser { + onRead: data => { + const lines = data.split('\n') + for (const line of lines) { + if (line.trim().length === 0) continue + + const parts = line.split('|') + if (parts.length >= 4) { + appListModel.append({ + appName: parts[0], + appDescription: parts[1], + appIcon: parts[2], + appCommand: parts[3] + }) + } + } + console.log("Loaded", appListModel.count, "applications") + } + } + + onRunningChanged: { + // When process finishes, reset it for next run + if (!running) { + appLoader.running = false + } + } + } + + // Function to load/reload applications + function loadApps() { + // Clear existing apps + appListModel.clear() + // Start the process to reload + appLoader.running = true + } + + // Load apps initially when component is created + Component.onCompleted: { + loadApps() + } + + Column { + anchors.fill: parent + anchors.margins: 12 + spacing: 8 + + // Header + Rectangle { + width: parent.width + height: 36 + color: "transparent" + + Text { + anchors.centerIn: parent + text: "Applications" + font.family: shellRoot.fontFamily + font.pixelSize: 14 + font.weight: Font.Medium + color: shellRoot.white + } + + // Close button + Rectangle { + width: 28 + height: 28 + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + radius: 6 + color: closeMouseArea.containsMouse ? shellRoot.red : "transparent" + + Text { + anchors.centerIn: parent + text: "✕" + font.family: shellRoot.fontFamily + font.pixelSize: 16 + font.weight: Font.Bold + color: closeMouseArea.containsMouse ? shellRoot.red : shellRoot.orange + } + + MouseArea { + id: closeMouseArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: appLauncher.requestClose() + } + } + } + + // Apps list + ListView { + id: listView + width: parent.width + height: parent.height - 44 + spacing: 8 + clip: true + + model: ListModel { + id: appListModel + // Apps will be loaded dynamically from the script + } + + delegate: Rectangle { + width: listView.width + height: 30 + color: { + if (appLauncher.hoverIndex === index) return shellRoot.lightgray + if (appLauncher.hoverIndex === -1 && index === shellRoot.selectedIndex) return shellRoot.lightgray + return shellRoot.gray + } + radius: 12 + border.width: 2 + border.color: { + if (appLauncher.hoverIndex === index || (shellRoot.hoverIndex === -1 && index === shellRoot.selectedIndex)) return shellRoot.blue + return "transparent" + } + + Row { + anchors.fill: parent + anchors.leftMargin: 12 + anchors.rightMargin: 12 + anchors.topMargin: 8 + anchors.bottomMargin: 8 + spacing: 12 + + Text { + width: parent.width - 62 + anchors.centerIn: parent + text: model.appName + font.family: shellRoot.fontFamily + font.pixelSize: 14 + font.weight: Font.Medium + color: { + if (appLauncher.hoverIndex === index) return shellRoot.blue + if (appLauncher.hoverIndex === -1 && index === shellRoot.selectedIndex) return shellRoot.blue + return shellRoot.purple + } + elide: Text.ElideRight + } + } + + MouseArea { + id: mouseArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + + onEntered: { + appLauncher.hoverIndex = index + } + onExited: { + appLauncher.hoverIndex = -1 + } + + onClicked: { + launchApp(model.appCommand) + } + } + } + } + } + + function launchApp(command) { + console.log("Launching app:", command) + // Close the launcher first + appLauncher.requestClose() + + // Use a small delay before launching to ensure the window closes properly + Qt.callLater(() => { + Quickshell.execDetached(["sh", "-c", command + " &"]) + }) + } +} diff --git a/quickshell/IconButton.qml b/quickshell/IconButton.qml new file mode 100644 index 0000000..96c4c7f --- /dev/null +++ b/quickshell/IconButton.qml @@ -0,0 +1,41 @@ +import QtQuick + +MouseArea { + id: iconButton + + property string icon: "" + property string tooltip: "" + + width: 32 + height: 32 + + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + enabled: true + z: 10 + + Rectangle { + anchors.fill: parent + color: "transparent" + radius: 6 + + Behavior on color { + ColorAnimation { duration: 200 } + } + + Text { + id: iconText + anchors.centerIn: parent + text: iconButton.icon + font.family: shellRoot.fontFamily + font.pixelSize: 22 + color: shellRoot.white + + Component.onCompleted: { + console.log("IconButton text:", iconButton.icon, "length:", iconButton.icon.length) + } + } + } + + +} diff --git a/quickshell/Procs.qml b/quickshell/Procs.qml new file mode 100644 index 0000000..5819a34 --- /dev/null +++ b/quickshell/Procs.qml @@ -0,0 +1,111 @@ +import Quickshell +import Quickshell.Io +import QtQuick + +Scope { + Timer { + interval: 2000 + running: true + repeat: true + onTriggered: { + cpuProc.running = true + memProc.running = true + brightnessProc.running = true + volumeProc.running = true + batteryProc.running = true + networkProc.running = true + temperatureProc.running = true + } + } + + Process { + id: cpuProc + command: ["sh", "-c", "head -1 /proc/stat"] + + stdout: SplitParser { + onRead: data => { + var p = data.trim().split(/\s+/) + var idle = parseInt(p[4]) + parseInt(p[5]) + var total = p.slice(1, 8).reduce((a, b) => a + parseInt(b), 0) + if (lastCpuTotal > 0) { + cpuUsage = Math.round(100 * (1 - (idle - lastCpuIdle) / (total - lastCpuTotal))) + } + lastCpuTotal = total + lastCpuIdle = idle + } + } + Component.onCompleted: running = true + } + + Process { + id: memProc + command: ["sh", "-c", "free | grep Mem"] + stdout: SplitParser { + onRead: data => { + var parts = data.trim().split(/\s+/) + var total = parseInt(parts[1]) || 1 + var used = parseInt(parts[2]) || 0 + memUsage = Math.round(100 * used / total) + } + } + Component.onCompleted: running = true + } + + Process { + id: temperatureProc + command: ["sh", "-c", "~/.config/quickshell/scripts/cpu_temp.sh"] + stdout: SplitParser { + onRead: data => { + cpu_temperature = parseInt(data.trim()) || 13; + } + } + Component.onCompleted: running = true + } + + Process { + id: brightnessProc + command: ["sh", "-c", "~/.config/quickshell/scripts/brightness.sh"] + stdout: SplitParser { + onRead: data => { + var parts = data.trim().split(/\s+/) + brightness = parseInt(parts[0]) || 100 + temperature = parseInt(parts[1]) || 6000 + } + } + Component.onCompleted: running = true + } + + Process { + id: volumeProc + command: ["sh", "-c", "~/.config/quickshell/scripts/volume.sh"] + stdout: SplitParser { + onRead: data => { + volume = parseInt(data.trim()) || 13; + } + } + Component.onCompleted: running = true + } + + Process { + id: batteryProc + command: ["sh", "-c", "~/.config/quickshell/scripts/battery.sh"] + stdout: SplitParser { + onRead: data => { + battery = parseInt(data.trim()) || 13; + } + } + Component.onCompleted: running = true + } + + Process { + id: networkProc + command: ["sh", "-c", "~/.config/quickshell/scripts/network.sh"] + stdout: SplitParser { + onRead: data => { + var parts = data.trim().split(/\s+/) + wifiName = parts[0]; + } + } + Component.onCompleted: running = true + } +} diff --git a/quickshell/items/DataBus.qml b/quickshell/items/DataBus.qml new file mode 100644 index 0000000..ef9f952 --- /dev/null +++ b/quickshell/items/DataBus.qml @@ -0,0 +1,23 @@ +import QtQuick +import QtQuick.Layouts + +RowLayout { + spacing: 0 + Text { + text: " Data Bus:" + color: shellRoot.white + font { + family: shellRoot.fontFamily + pixelSize: shellRoot.fontSize + } + } + Text { + text: cpuUsage + color: shellRoot.orange + font { + family: shellRoot.fontFamily + pixelSize: shellRoot.fontSize + bold: true + } + } +} diff --git a/quickshell/items/Electrons.qml b/quickshell/items/Electrons.qml new file mode 100644 index 0000000..f3164a0 --- /dev/null +++ b/quickshell/items/Electrons.qml @@ -0,0 +1,23 @@ +import QtQuick +import QtQuick.Layouts + +RowLayout { + spacing: 0 + Text { + text: " Electrons:" + color: shellRoot.white + font { + family: shellRoot.fontFamily + pixelSize: shellRoot.fontSize + } + } + Text { + text: battery + color: (battery <= redBatteryPoint) ? shellRoot.red : ((battery <= orangeBatteryPoint) ? shellRoot.orange : shellRoot.green) + font { + family: shellRoot.fontFamily + pixelSize: shellRoot.fontSize + bold: true + } + } +} diff --git a/quickshell/items/Latch.qml b/quickshell/items/Latch.qml new file mode 100644 index 0000000..5cc6487 --- /dev/null +++ b/quickshell/items/Latch.qml @@ -0,0 +1,23 @@ +import QtQuick +import QtQuick.Layouts + +RowLayout { + spacing: 0 + Text { + text: " Latch:" + color: shellRoot.white + font { + family: shellRoot.fontFamily + pixelSize: shellRoot.fontSize + } + } + Text { + text: memUsage + color: shellRoot.orange + font { + family: shellRoot.fontFamily + pixelSize: shellRoot.fontSize + bold: true + } + } +} diff --git a/quickshell/items/Photons.qml b/quickshell/items/Photons.qml new file mode 100644 index 0000000..0ba94ee --- /dev/null +++ b/quickshell/items/Photons.qml @@ -0,0 +1,32 @@ +import QtQuick +import QtQuick.Layouts + +RowLayout { + spacing: 0 + Text { + text: " Photons:" + color: shellRoot.white + font { + family: shellRoot.fontFamily + pixelSize: shellRoot.fontSize + } + } + Text { + text: brightness + color: shellRoot.orange + font { + family: shellRoot.fontFamily + pixelSize: shellRoot.fontSize + bold: true + } + } + Text { + text: "(" + temperature + "K)" + color: shellRoot.red + font { + family: shellRoot.fontFamily + pixelSize: shellRoot.fontSize + bold: true + } + } +} diff --git a/quickshell/items/Radiation.qml b/quickshell/items/Radiation.qml new file mode 100644 index 0000000..e2a6c09 --- /dev/null +++ b/quickshell/items/Radiation.qml @@ -0,0 +1,23 @@ +import QtQuick +import QtQuick.Layouts + +RowLayout { + spacing: 0 + Text { + text: " Radiation:" + color: shellRoot.white + font { + family: shellRoot.fontFamily + pixelSize: shellRoot.fontSize + } + } + Text { + text: cpu_temperature + "K" + color: shellRoot.orange + font { + family: shellRoot.fontFamily + pixelSize: shellRoot.fontSize + bold: true + } + } +} diff --git a/quickshell/items/Radio.qml b/quickshell/items/Radio.qml new file mode 100644 index 0000000..b3ee8e6 --- /dev/null +++ b/quickshell/items/Radio.qml @@ -0,0 +1,28 @@ +import QtQuick +import QtQuick.Layouts + +RowLayout { + spacing: 0 + Text { + text: " Radio:" + color: shellRoot.white + font { + family: shellRoot.fontFamily + pixelSize: shellRoot.fontSize + } + } + Text { + text: wifiName + color: wifiName == "Offline" ? shellRoot.red : shellRoot.green + font { + family: shellRoot.fontFamily + pixelSize: shellRoot.fontSize + bold: true + } + + MouseArea { + anchors.fill: parent + onClicked: networkManagerProc.running = true + } + } +} diff --git a/quickshell/items/Spin.qml b/quickshell/items/Spin.qml new file mode 100644 index 0000000..72e6105 --- /dev/null +++ b/quickshell/items/Spin.qml @@ -0,0 +1,45 @@ +import QtQuick +import QtQuick.Layouts + +RowLayout { + spacing: 0 + Text { + text: " Spin:" + color: shellRoot.white + font { + family: shellRoot.fontFamily + pixelSize: shellRoot.fontSize + } + } + Text { + property var formatMode: "HH:mm:ss" + + id: clock + text: Qt.formatDateTime(new Date(), clock.formatMode) + color: shellRoot.purple + font { + family: shellRoot.fontFamily + pixelSize: shellRoot.fontSize + bold: true + } + + Timer { + interval: 1000 + running: true + repeat: true + onTriggered: clock.text = Qt.formatDateTime(new Date(), clock.formatMode) + } + + MouseArea { + anchors.fill: parent + onClicked: { + if (clock.formatMode === "HH:mm:ss") { + clock.formatMode = "yyyy/MM/dd, dddd" + } else { + clock.formatMode = "HH:mm:ss" + } + clock.text = Qt.formatDateTime(new Date(), clock.formatMode) + } + } + } +} diff --git a/quickshell/items/Waves.qml b/quickshell/items/Waves.qml new file mode 100644 index 0000000..05e42e2 --- /dev/null +++ b/quickshell/items/Waves.qml @@ -0,0 +1,23 @@ +import QtQuick +import QtQuick.Layouts + +RowLayout { + spacing: 0 + Text { + text: " Waves:" + color: shellRoot.white + font { + family: shellRoot.fontFamily + pixelSize: shellRoot.fontSize + } + } + Text { + text: volume + color: shellRoot.green + font { + family: shellRoot.fontFamily + pixelSize: shellRoot.fontSize + bold: true + } + } +} diff --git a/quickshell/items/Workspace.qml b/quickshell/items/Workspace.qml new file mode 100644 index 0000000..f793850 --- /dev/null +++ b/quickshell/items/Workspace.qml @@ -0,0 +1,22 @@ +import QtQuick +import Quickshell.Hyprland + +Repeater { + model: 5 + + Text { + property bool isActive: Hyprland.focusedWorkspace?.id === (index + 1) + + text: index + 1 + color: isActive ? shellRoot.green : shellRoot.white + font { + pixelSize: shellRoot.fontSize; + bold: true; + } + + MouseArea { + anchors.fill: parent + onClicked: Hyprland.dispatch("workspace " + (index + 1)) + } + } +} diff --git a/quickshell/battery.sh b/quickshell/scripts/battery.sh index c7d4302..c7d4302 100755 --- a/quickshell/battery.sh +++ b/quickshell/scripts/battery.sh diff --git a/quickshell/brightness.sh b/quickshell/scripts/brightness.sh index ccb2bc2..ccb2bc2 100755 --- a/quickshell/brightness.sh +++ b/quickshell/scripts/brightness.sh diff --git a/quickshell/cpu_temp.sh b/quickshell/scripts/cpu_temp.sh index de73d7d..de73d7d 100755 --- a/quickshell/cpu_temp.sh +++ b/quickshell/scripts/cpu_temp.sh diff --git a/quickshell/scripts/list-apps.sh b/quickshell/scripts/list-apps.sh new file mode 100755 index 0000000..bac48b6 --- /dev/null +++ b/quickshell/scripts/list-apps.sh @@ -0,0 +1,115 @@ +#!/bin/sh +# List desktop applications for the launcher + +# Blacklist - apps to hide (add desktop file basenames here) +BLACKLIST=( + # "xfce4-about.desktop" + # "avahi-discover.desktop" + # "bssh.desktop" + # "bvnc.desktop" + # "qv4l2.desktop" + # "qvidcap.desktop" + # "lstopo.desktop" + # "uuctl.desktop" + # "codium.desktop" # Hide regular VSCodium (keep Wayland version) + # "xgps.desktop" # Hide Xgps + # "xgpsspeed.desktop" # Hide Xgpsspeed +) + +# Search paths for .desktop files (local first so overrides work) +XDG_DATA_DIRS="${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" +IFS=':' read -ra SEARCH_PATHS <<< "$XDG_DATA_DIRS" + +# Function to find icon path +find_icon() { + local icon_name="$1" + + # If it's already a path, return it + if [[ "$icon_name" == /* ]]; then + echo "$icon_name" + return + fi + + # Common icon sizes to try + local sizes=(48 32 64 128 256) + + # Icon theme paths + local icon_paths=( + "$HOME/.local/share/icons" + "$HOME/.icons" + "/usr/share/icons" + "/usr/share/pixmaps" + ) + + # Try to find the icon + for path in "${icon_paths[@]}"; do + # Try with extensions + for ext in png svg xpm; do + # Direct match in pixmaps + if [ -f "$path/$icon_name.$ext" ]; then + echo "$path/$icon_name.$ext" + return + fi + + # Try in hicolor theme with different sizes + for size in "${sizes[@]}"; do + if [ -f "$path/hicolor/${size}x${size}/apps/$icon_name.$ext" ]; then + echo "$path/hicolor/${size}x${size}/apps/$icon_name.$ext" + return + fi + done + done + done + + # If not found, just return the icon name + echo "$icon_name" +} + +# Collect all desktop files and process, avoiding duplicates +# We use process substitution to avoid subshell issues with arrays +declare -A seen_apps + +for dir in "${SEARCH_PATHS[@]}"; do + [ ! -d "$dir" ] && continue + + while IFS= read -r desktop_file; do + basename_file=$(basename "$desktop_file") + + # Skip duplicates (local overrides system) + [[ -n "${seen_apps[$basename_file]}" ]] && continue + seen_apps[$basename_file]=1 + + # Skip blacklisted + skip=0 + for blacklisted in "${BLACKLIST[@]}"; do + if [[ "$basename_file" == "$blacklisted" ]]; then + skip=1 + break + fi + done + [[ $skip -eq 1 ]] && continue + + # Skip if NoDisplay=true + grep -q "^NoDisplay=true" "$desktop_file" 2>/dev/null && continue + + # Extract fields + name=$(grep "^Name=" "$desktop_file" | head -1 | cut -d= -f2-) + comment=$(grep "^Comment=" "$desktop_file" | head -1 | cut -d= -f2-) + icon=$(grep "^Icon=" "$desktop_file" | head -1 | cut -d= -f2-) + exec=$(grep "^Exec=" "$desktop_file" | head -1 | cut -d= -f2- | sed 's/%[uUfF]//g' | sed 's/%[cdnNvmki]//g') + + # Skip if no name or exec + [ -z "$name" ] && continue + [ -z "$exec" ] && continue + + # Default comment if empty + [ -z "$comment" ] && comment="Application" + + # Find icon path + icon_path=$(find_icon "$icon") + + # Output in format: name|comment|icon_path|exec + echo "$name|$comment|$icon_path|$exec" + + done < <(find -L "$dir" -name "*.desktop" -type f 2>/dev/null) +done | sort -u diff --git a/quickshell/network.sh b/quickshell/scripts/network.sh index f50707e..f50707e 100755 --- a/quickshell/network.sh +++ b/quickshell/scripts/network.sh diff --git a/quickshell/volume.sh b/quickshell/scripts/volume.sh index 3059255..3059255 100755 --- a/quickshell/volume.sh +++ b/quickshell/scripts/volume.sh diff --git a/quickshell/shell.qml b/quickshell/shell.qml index 1ad2eb4..307dece 100644 --- a/quickshell/shell.qml +++ b/quickshell/shell.qml @@ -1,3 +1,4 @@ +import "./items" import Quickshell import Quickshell.Wayland import Quickshell.Hyprland @@ -5,13 +6,15 @@ import Quickshell.Io import QtQuick import QtQuick.Layouts -PanelWindow { - id: root +ShellRoot { + id: shellRoot property int redBatteryPoint: 15 property int orangeBatteryPoint: 30 property color black: "#000000" + property color gray: "#202020" + property color lightgray: "#404040" property color white: "#ffffff" property color green: "#28CD41" property color red: "#FF4040" @@ -21,351 +24,175 @@ PanelWindow { property string fontFamily: "JetBrainsMono Nerd Font" property int fontSize: 18 - property int cpuUsage: 0 - property int lastCpuTotal: 0 - property int lastCpuIdle: 0 - - Process { - id: cpuProc - command: ["sh", "-c", "head -1 /proc/stat"] - - stdout: SplitParser { - onRead: data => { - var p = data.trim().split(/\s+/) - var idle = parseInt(p[4]) + parseInt(p[5]) - var total = p.slice(1, 8).reduce((a, b) => a + parseInt(b), 0) - if (lastCpuTotal > 0) { - cpuUsage = Math.round(100 * (1 - (idle - lastCpuIdle) / (total - lastCpuTotal))) - } - lastCpuTotal = total - lastCpuIdle = idle - } - } - Component.onCompleted: running = true - } - - property int memUsage: 0 - Process { - id: memProc - command: ["sh", "-c", "free | grep Mem"] - stdout: SplitParser { - onRead: data => { - var parts = data.trim().split(/\s+/) - var total = parseInt(parts[1]) || 1 - var used = parseInt(parts[2]) || 0 - memUsage = Math.round(100 * used / total) - } - } - Component.onCompleted: running = true - } - - property int cpu_temperature: 6000 - Process { - id: temperatureProc - command: ["sh", "-c", "~/.config/quickshell/cpu_temp.sh"] - stdout: SplitParser { - onRead: data => { - cpu_temperature = parseInt(data.trim()) || 13; - } - } - Component.onCompleted: running = true - } - - property int brightness: 100 - property int temperature: 6000 - Process { - id: brightnessProc - command: ["sh", "-c", "~/.config/quickshell/brightness.sh"] - stdout: SplitParser { - onRead: data => { - var parts = data.trim().split(/\s+/) - brightness = parseInt(parts[0]) || 100 - temperature = parseInt(parts[1]) || 6000 - } - } - Component.onCompleted: running = true - } - - property int volume: 12 - Process { - id: volumeProc - command: ["sh", "-c", "~/.config/quickshell/volume.sh"] - stdout: SplitParser { - onRead: data => { - volume = parseInt(data.trim()) || 13; - } - } - Component.onCompleted: running = true - } - - property int battery: 12 - Process { - id: batteryProc - command: ["sh", "-c", "~/.config/quickshell/battery.sh"] - stdout: SplitParser { - onRead: data => { - battery = parseInt(data.trim()) || 13; - } + property bool appLauncherVisible: false + + // focus: true + // Keys.onPressed: (event) => { + // if (event.key === Qt.Key_R && event.modifiers & Qt.MetaModifier) { + // Quickshell.execDetached(["notify-send", "ok"]) + // appLauncherVisible = true; + // } + // } + // Component.onCompleted: { + // Hyprland.rawSignals = true; + // } + // Connections { + // target: Hyprland + // + // function onEvent(sig) { + // Quickshell.execDetached(["notify-send", "ok"]) + // console.log("Raw = ", sig); + // } + // } + GlobalShortcut { + id: launcherShortcut + name: "toggleLauncher" + onPressed: { + appLauncherVisible = true } - Component.onCompleted: running = true } - property string wifiName: "Offline" - Process { - id: networkProc - command: ["sh", "-c", "~/.config/quickshell/network.sh"] - stdout: SplitParser { - onRead: data => { - var parts = data.trim().split(/\s+/) - wifiName = parts[0]; - } - } - Component.onCompleted: running = true - } - - Timer { - interval: 2000 - running: true - repeat: true - onTriggered: { - cpuProc.running = true - memProc.running = true - brightnessProc.running = true - volumeProc.running = true - batteryProc.running = true - networkProc.running = true - temperatureProc.running = true - } - } - Process { - id: networkManagerProc - command: ["foot", "-e", "nmtui"] - Component.onCompleted: running = false - } - - anchors.top: true - anchors.left: true - anchors.right: true - implicitHeight: 32 - color: root.black - - RowLayout { - anchors.fill: parent - anchors.margins: 0 - - Repeater { - model: 5 - - Text { - property bool isActive: Hyprland.focusedWorkspace?.id === (index + 1) - - text: index + 1 - color: isActive ? root.green : root.white - font { - pixelSize: root.fontSize; - bold: true; - } - - MouseArea { - anchors.fill: parent - onClicked: Hyprland.dispatch("workspace " + (index + 1)) - } - } - } - Item { Layout.fillWidth: true } - RowLayout { - spacing: 0 - Text { - text: " Radio:" - color: root.white - font { - family: root.fontFamily - pixelSize: root.fontSize - } - } - Text { - text: wifiName - color: wifiName == "Offline" ? root.red : root.green - font { - family: root.fontFamily - pixelSize: root.fontSize - bold: true - } - - MouseArea { - anchors.fill: parent - onClicked: networkManagerProc.running = true - } - } - } - RowLayout { - spacing: 0 - Text { - text: " Electrons:" - color: root.white - font { - family: root.fontFamily - pixelSize: root.fontSize - } - } - Text { - text: battery - color: (battery <= redBatteryPoint) ? root.red : ((battery <= orangeBatteryPoint) ? root.orange : root.green) - font { - family: root.fontFamily - pixelSize: root.fontSize - bold: true - } - } - } - RowLayout { - spacing: 0 - Text { - text: " Waves:" - color: root.white - font { - family: root.fontFamily - pixelSize: root.fontSize - } - } - Text { - text: volume - color: root.green - font { - family: root.fontFamily - pixelSize: root.fontSize - bold: true - } - } - } - RowLayout { - spacing: 0 - Text { - text: " Photons:" - color: root.white - font { - family: root.fontFamily - pixelSize: root.fontSize - } - } - Text { - text: brightness - color: root.orange - font { - family: root.fontFamily - pixelSize: root.fontSize - bold: true - } - } - Text { - text: "(" + temperature + "K)" - color: root.red - font { - family: root.fontFamily - pixelSize: root.fontSize - bold: true - } - } - } - RowLayout { - spacing: 0 - Text { - text: " Radiation:" - color: root.white - font { - family: root.fontFamily - pixelSize: root.fontSize - } - } - Text { - text: cpu_temperature + "K" - color: root.orange - font { - family: root.fontFamily - pixelSize: root.fontSize - bold: true - } - } - } - RowLayout { - spacing: 0 - Text { - text: " Data Bus:" - color: root.white - font { - family: root.fontFamily - pixelSize: root.fontSize - } - } - Text { - text: cpuUsage - color: root.orange - font { - family: root.fontFamily - pixelSize: root.fontSize - bold: true - } - } - } - RowLayout { - spacing: 0 - Text { - text: " Latch:" - color: root.white - font { - family: root.fontFamily - pixelSize: root.fontSize - } - } - Text { - text: memUsage - color: root.orange - font { - family: root.fontFamily - pixelSize: root.fontSize - bold: true + Variants { + model: Quickshell.screens + PanelWindow { + id: root + + property int cpuUsage: 0 + property int lastCpuTotal: 0 + property int lastCpuIdle: 0 + property int memUsage: 0 + property int cpu_temperature: 6000 + property int brightness: 100 + property int temperature: 6000 + property int volume: 12 + property int battery: 12 + property string wifiName: "Offline" + + Procs {} + Process { + id: networkManagerProc + command: ["foot", "-e", "nmtui"] + Component.onCompleted: running = false + } + + anchors.top: true + anchors.left: true + anchors.right: true + implicitHeight: 32 + color: shellRoot.black + + RowLayout { + anchors.fill: parent + anchors.margins: 0 + anchors.leftMargin: 10 + anchors.rightMargin: 10 + + Workspace {} + Item { Layout.fillWidth: true } + Radio {} + Electrons {} + Waves {} + Photons {} + Radiation {} + DataBus {} + Latch {} + Spin {} + } + + PanelWindow { + id: apps + + anchors.top: true + anchors.right: true + anchors.bottom: true + implicitWidth: 32 + color: shellRoot.black + + ColumnLayout { + IconButton { + icon: "" + tooltip: "Firefox" + onClicked: Quickshell.execDetached(["firefox"]) + } + IconButton { + icon: "" + tooltip: "Dolphin" + onClicked: Quickshell.execDetached(["dolphin"]) + } + IconButton { + icon: "" + tooltip: "Vscode" + onClicked: Quickshell.execDetached(["code"]) + } + IconButton { + icon: "" + tooltip: "Localsend" + onClicked: Quickshell.execDetached(["localsend_app"]) + } + IconButton { + icon: "" + tooltip: "Bitwarden" + onClicked: Quickshell.execDetached(["bitwarden"]) + } + IconButton { + icon: "" + tooltip: "GIMP" + onClicked: Quickshell.execDetached(["gimp"]) + } + IconButton { + icon: "" + tooltip: "Obsidian" + onClicked: Quickshell.execDetached(["obsidian"]) + } + IconButton { + icon: "" + tooltip: "Discord" + onClicked: Quickshell.execDetached(["discord"]) + } + IconButton { + icon: "" + tooltip: "VLC" + onClicked: Quickshell.execDetached(["vlc"]) + } } } } - RowLayout { - spacing: 0 - Text { - text: " Spin:" - color: root.white - font { - family: root.fontFamily - pixelSize: root.fontSize - } - } - Text { - property var formatMode: "HH:mm:ss" - - id: clock - text: Qt.formatDateTime(new Date(), clock.formatMode) - color: root.purple - font { - family: root.fontFamily - pixelSize: root.fontSize - bold: true - } - - Timer { - interval: 1000 - running: true - repeat: true - onTriggered: clock.text = Qt.formatDateTime(new Date(), clock.formatMode) - } - - MouseArea { - anchors.fill: parent - onClicked: { - if (clock.formatMode === "HH:mm:ss") { - clock.formatMode = "yyyy/MM/dd, dddd" - } else { - clock.formatMode = "HH:mm:ss" - } - clock.text = Qt.formatDateTime(new Date(), clock.formatMode) - } + } + Variants { + model: Quickshell.screens + + PanelWindow { + visible: shellRoot.appLauncherVisible + + anchors { + top: true + left: true + } + + margins { + top: Screen.height/2 - 300 + left: Screen.width/2 - 200 + } + + implicitWidth: 400 + implicitHeight: 600 + + color: "transparent" + exclusiveZone: 0 + + WlrLayershell.layer: WlrLayer.Overlay + WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand + + Behavior on height { + NumberAnimation { duration: 200; easing.type: Easing.OutCubic } + } + + AppLauncher { + anchors.fill: parent + isVisible: shellRoot.appLauncherVisible + + onRequestClose: { + shellRoot.appLauncherVisible = false } } } diff --git a/wofi/colors b/wofi/colors deleted file mode 100644 index 1c6bb43..0000000 --- a/wofi/colors +++ /dev/null @@ -1,2 +0,0 @@ -#F0EDEC -#2C363C diff --git a/wofi/config b/wofi/config deleted file mode 100644 index 4e868f0..0000000 --- a/wofi/config +++ /dev/null @@ -1,8 +0,0 @@ -show=drun -allow_images=true -insensitive=true -lines=10 -width=600 -prompt=Search... -hide_scroll=true -term=foot diff --git a/wofi/style.css b/wofi/style.css deleted file mode 100644 index 15e1f4a..0000000 --- a/wofi/style.css +++ /dev/null @@ -1,53 +0,0 @@ -#window { - border: 3px solid rgba(--wofi-rgb-color1, 0.94); - background-color: rgba(--wofi-rgb-color1, 0.94); - font-size: 18px; - font-family: "JetbrainsMono Nerd Font"; -} - -#outer-box { - margin: 3px; -} - -#input { - border: 0; - border-radius: 0; - background-color: transparent; - color: --wofi-color0; - margin: 3px; -} - -#input image:first-child { - margin-left: -100px; -} - -#input image:last-child { - margin-right: -100px; -} - -#input:focus { - border-radius: 0; -} - -#entry { - color: --wofi-color0; -} - -#entry:selected { - background-color: rgba(--wofi-rgb-color0, 0.94); -} - -#text:selected { - color: --wofi-color1; -} - -#img { - margin-right: 5px; - margin-left: 3px; - margin-top: 3px; - margin-bottom: 3px; -} - -#text { - margin-left: 3px; -} |
