# ZShell
@@ -8,6 +8,10 @@ ZShell is a Hyprland-focused desktop shell built with Quickshell + Qt6/QML.
It includes a configurable top bar, launcher, notifications daemon + sidebar, wallpaper and dynamic color pipeline, lock screen, OSD widgets, dashboard, dock, desktop icons, and a separate greetd-compatible greeter.
+
+
+
+
## Highlights
- Multi-window shell layout driven by `Drawers/Windows.qml` and panel/interactions wrappers
@@ -218,14 +222,14 @@ Action-driven flows (`>` prefix by default) include calculator, wallpaper picker
### `shell` — daemon management
-| Command | Description |
-|---------|-------------|
-| `start` | Start the shell daemon (pass `--no-daemon` to run in foreground) |
-| `kill` | Kill the running shell daemon |
-| `restart` | Kill then restart the daemon |
-| `lock` | Lock the session via IPC |
-| `show` | Show the shell window via IPC |
-| `log` | Print daemon logs |
+| Command | Description |
+| --------- | ---------------------------------------------------------------- |
+| `start` | Start the shell daemon (pass `--no-daemon` to run in foreground) |
+| `kill` | Kill the running shell daemon |
+| `restart` | Kill then restart the daemon |
+| `lock` | Lock the session via IPC |
+| `show` | Show the shell window via IPC |
+| `log` | Print daemon logs |
### `scheme` — color scheme generation
diff --git a/assets/logo.png b/assets/logo.png
new file mode 100644
index 0000000..ec06df1
Binary files /dev/null and b/assets/logo.png differ
diff --git a/assets/logo.svg b/assets/logo.svg
new file mode 100644
index 0000000..453b18e
--- /dev/null
+++ b/assets/logo.svg
@@ -0,0 +1,68 @@
+
+
+
+
diff --git a/network-dev/wifi-sim.sh b/network-dev/wifi-sim.sh
deleted file mode 100755
index 58512c4..0000000
--- a/network-dev/wifi-sim.sh
+++ /dev/null
@@ -1,445 +0,0 @@
-#!/bin/bash
-
-# =============================================================================
-
-# wifi-sim.sh — Virtual WiFi environment for development & testing
-
-#
-
-# Creates 3 dummy networks using mac80211_hwsim + hostapd + dnsmasq:
-
-# - FreeWifi (open, strong signal, ch 1)
-
-# - OfficeNetwork (open, medium signal, ch 6)
-
-# - HomeNetwork (WPA2, weak signal, ch 11)
-
-#
-
-# Usage:
-
-# sudo ./wifi-sim.sh start
-
-# sudo ./wifi-sim.sh stop
-
-# sudo ./wifi-sim.sh status
-
-# =============================================================================
-
-set -euo pipefail
-
-# --- User configuration ------------------------------------------------------
-
-SSID_STRONG="FreeWifi" # Open network, strong signal
-SSID_MEDIUM="OfficeNetwork" # Open network, medium signal
-SSID_SECURE="HomeNetwork" # WPA2 network, weak signal
-WIFI_PASSWORD="testpassword123"
-
-# TX power levels in mBm (millibel-milliwatts). Higher = stronger signal.
-
-# These affect the RSSI reported to scanning clients.
-
-TXPOWER_STRONG=3000 # 30 dBm
-TXPOWER_MEDIUM=1500 # 15 dBm
-TXPOWER_WEAK=100 # 1 dBm
-
-# Per-network IP plan for DHCP.
-
-AP1_IP="10.10.1.1"
-AP1_RANGE_START="10.10.1.50"
-AP1_RANGE_END="10.10.1.150"
-
-AP2_IP="10.10.2.1"
-AP2_RANGE_START="10.10.2.50"
-AP2_RANGE_END="10.10.2.150"
-
-AP3_IP="10.10.3.1"
-AP3_RANGE_START="10.10.3.50"
-AP3_RANGE_END="10.10.3.150"
-
-RUN_DIR="/tmp/wifi-sim"
-
-# --- Helpers -----------------------------------------------------------------
-
-die() {
- echo "ERROR: $*" >&2
- exit 1
-}
-
-info() {
- echo "[*] $*"
-}
-
-ok() {
- echo "[+] $*"
-}
-
-require_cmds() {
- local missing=()
- for cmd in "$@"; do
- command -v "$cmd" &>/dev/null || missing+=("$cmd")
- done
- if [[ ${#missing[@]} -gt 0 ]]; then
- die "Missing required tools: ${missing[*]}
-Install with: sudo apt install hostapd dnsmasq wpasupplicant iw"
- fi
-}
-
-get_phy_for_iface() {
- iw dev "$1" info | awk '/wiphy/{print "phy"$2}'
-}
-
-start_dnsmasq() {
- local name="$1"
- local iface="$2"
- local gw_ip="$3"
- local dhcp_start="$4"
- local dhcp_end="$5"
-
- dnsmasq \
- --interface="$iface" \
- --bind-interfaces \
- --except-interface=lo \
- --port=0 \
- --no-resolv \
- --no-hosts \
- --dhcp-authoritative \
- --dhcp-range="${dhcp_start},${dhcp_end},255.255.255.0,12h" \
- --dhcp-option=3,"$gw_ip" \
- --dhcp-option=6,"$gw_ip" \
- --pid-file="$RUN_DIR/${name}.dnsmasq.pid" \
- --dhcp-leasefile="$RUN_DIR/${name}.leases" \
- >"$RUN_DIR/${name}.dnsmasq.log" 2>&1 ||
- {
- cat "$RUN_DIR/${name}.dnsmasq.log"
- die "dnsmasq failed for $name. See log above."
- }
-
-}
-
-stop_pidfile() {
- local pidfile="$1"
- local label="$2"
-
- if [[ -f "$pidfile" ]]; then
- local pid
- pid="$(cat "$pidfile")"
- if kill "$pid" 2>/dev/null; then
- info "Stopped $label (PID $pid)"
- fi
- rm -f "$pidfile"
- fi
-
-}
-
-remove_iface_addr() {
- local iface="$1"
- local cidr="$2"
- ip addr del "$cidr" dev "$iface" 2>/dev/null || true
-}
-
-# --- Start -------------------------------------------------------------------
-
-cmd_start() {
- [[ $EUID -ne 0 ]] && die "Please run as root: sudo $0 start"
- require_cmds hostapd dnsmasq iw ip
-
- if [[ -d "$RUN_DIR" && -f "$RUN_DIR/interfaces" ]]; then
- die "wifi-sim appears to already be running. Run 'sudo $0 stop' first."
- fi
- mkdir -p "$RUN_DIR"
-
- # Snapshot existing wlan interfaces so we can identify the new ones
- info "Snapshotting existing interfaces..."
- BEFORE=($(iw dev 2>/dev/null | awk '/Interface/{print $2}' | grep -v '^hwsim' || true))
-
- # Load the kernel module with 4 radios (3 APs + 1 client)
- info "Loading mac80211_hwsim (4 radios)..."
- if lsmod | grep -q mac80211_hwsim; then
- die "mac80211_hwsim is already loaded. Run 'sudo $0 stop' or 'sudo rmmod mac80211_hwsim' first."
- fi
- modprobe mac80211_hwsim radios=4
- sleep 1
-
- # Find the interfaces created by our modprobe
- AFTER=($(iw dev 2>/dev/null | awk '/Interface/{print $2}' | grep -v '^hwsim'))
- NEW_IFACES=()
- for iface in "${AFTER[@]}"; do
- [[ ! " ${BEFORE[*]:-} " =~ " $iface " ]] && NEW_IFACES+=("$iface")
- done
-
- if [[ ${#NEW_IFACES[@]} -lt 4 ]]; then
- rmmod mac80211_hwsim 2>/dev/null || true
- die "Expected 4 new wlan interfaces, found ${#NEW_IFACES[@]}. Check 'dmesg' for errors."
- fi
-
- AP1="${NEW_IFACES[0]}" # Will host SSID_STRONG
- AP2="${NEW_IFACES[1]}" # Will host SSID_MEDIUM
- AP3="${NEW_IFACES[2]}" # Will host SSID_SECURE
- CLIENT="${NEW_IFACES[3]}" # Client-side interface for your code to use
-
- info "Interfaces assigned: AP1=$AP1 AP2=$AP2 AP3=$AP3 Client=$CLIENT"
- echo "$AP1 $AP2 $AP3 $CLIENT" >"$RUN_DIR/interfaces"
-
- # Prevent NetworkManager from fighting us over the AP interfaces.
- # Leave the client managed so your app can use NetworkManager normally.
- if command -v nmcli &>/dev/null && nmcli general status &>/dev/null 2>&1; then
- info "Marking AP interfaces as unmanaged in NetworkManager..."
- for iface in "$AP1" "$AP2" "$AP3"; do
- nmcli device set "$iface" managed no 2>/dev/null || true
- done
-
- nmcli device set "$CLIENT" managed yes 2>/dev/null || true
- fi
-
- # Set TX power on each physical radio to simulate signal strength differences.
- # mac80211_hwsim factors TX power into the RSSI reported to scanning clients.
- info "Setting TX power levels for signal strength simulation..."
- PHY1=$(get_phy_for_iface "$AP1")
- PHY2=$(get_phy_for_iface "$AP2")
- PHY3=$(get_phy_for_iface "$AP3")
-
- iw phy "$PHY1" set txpower fixed "$TXPOWER_STRONG"
- iw phy "$PHY2" set txpower fixed "$TXPOWER_MEDIUM"
- iw phy "$PHY3" set txpower fixed "$TXPOWER_WEAK"
-
- # --- hostapd config: AP1 (open, strong, channel 1) -----------------------
- cat >"$RUN_DIR/ap1.conf" <"$RUN_DIR/ap2.conf" <"$RUN_DIR/ap3.conf" <"$RUN_DIR/ap1.log" 2>&1 ||
- {
- cat "$RUN_DIR/ap1.log"
- die "hostapd failed for AP1. See log above."
- }
-
- hostapd -B -P "$RUN_DIR/ap2.pid" "$RUN_DIR/ap2.conf" \
- >"$RUN_DIR/ap2.log" 2>&1 ||
- {
- cat "$RUN_DIR/ap2.log"
- die "hostapd failed for AP2. See log above."
- }
-
- hostapd -B -P "$RUN_DIR/ap3.pid" "$RUN_DIR/ap3.conf" \
- >"$RUN_DIR/ap3.log" 2>&1 ||
- {
- cat "$RUN_DIR/ap3.log"
- die "hostapd failed for AP3. See log above."
- }
-
- # Give each AP a gateway IP and start DHCP on each one.
- info "Configuring AP addresses and DHCP servers..."
- ip link set "$AP1" up
- ip link set "$AP2" up
- ip link set "$AP3" up
-
- ip addr add "$AP1_IP/24" dev "$AP1"
- ip addr add "$AP2_IP/24" dev "$AP2"
- ip addr add "$AP3_IP/24" dev "$AP3"
-
- start_dnsmasq "ap1" "$AP1" "$AP1_IP" "$AP1_RANGE_START" "$AP1_RANGE_END"
- start_dnsmasq "ap2" "$AP2" "$AP2_IP" "$AP2_RANGE_START" "$AP2_RANGE_END"
- start_dnsmasq "ap3" "$AP3" "$AP3_IP" "$AP3_RANGE_START" "$AP3_RANGE_END"
-
- # Bring up the client interface so it's ready to scan/connect
- ip link set "$CLIENT" up
-
- # --- Summary -------------------------------------------------------------
- ok "Virtual WiFi environment is up!"
- echo ""
- echo " Networks:"
- echo " ┌──────────────────┬──────────┬────────┬─────────────┐"
- echo " │ SSID │ Security │ Signal │ Interface │"
- echo " ├──────────────────┼──────────┼────────┼─────────────┤"
- printf " │ %-16s │ %-8s │ %-6s │ %-11s │\n" "$SSID_STRONG" "Open" "Strong" "$AP1"
- printf " │ %-16s │ %-8s │ %-6s │ %-11s │\n" "$SSID_MEDIUM" "Open" "Medium" "$AP2"
- printf " │ %-16s │ %-8s │ %-6s │ %-11s │\n" "$SSID_SECURE" "WPA2" "Weak" "$AP3"
- echo " └──────────────────┴──────────┴────────┴─────────────┘"
- echo ""
- echo " WPA2 password : $WIFI_PASSWORD"
- echo " Client iface : $CLIENT (use this in your code)"
- echo ""
- echo " Gateway IPs / DHCP:"
- echo " $SSID_STRONG -> $AP1_IP/24"
- echo " $SSID_MEDIUM -> $AP2_IP/24"
- echo " $SSID_SECURE -> $AP3_IP/24"
- echo ""
- echo " Useful commands:"
- echo " Scan for networks : sudo iw dev $CLIENT scan | grep -E 'SSID|signal'"
- echo " Connect (open) : sudo iw dev $CLIENT connect \"$SSID_STRONG\""
- echo " Connect (WPA2) : sudo nmcli device wifi connect \"$SSID_SECURE\" password \"$WIFI_PASSWORD\" ifname \"$CLIENT\""
- echo " Stop simulation : sudo $0 stop"
- echo ""
- echo " Logs: $RUN_DIR/ap{1,2,3}.log and $RUN_DIR/ap{1,2,3}.dnsmasq.log"
-
-}
-
-# --- Stop --------------------------------------------------------------------
-
-cmd_stop() {
- [[ $EUID -ne 0 ]] && die "Please run as root: sudo $0 stop"
-
- info "Stopping virtual WiFi environment..."
- local had_something=false
-
- # Stop dnsmasq instances first.
- for ap in ap1 ap2 ap3; do
- PID_FILE="$RUN_DIR/$ap.dnsmasq.pid"
- if [[ -f "$PID_FILE" ]]; then
- PID=$(cat "$PID_FILE")
- if kill "$PID" 2>/dev/null; then
- info "Stopped dnsmasq for $ap (PID $PID)"
- fi
- rm -f "$PID_FILE"
- had_something=true
- fi
- done
-
- # Kill hostapd processes via PID files
- for ap in ap1 ap2 ap3; do
- PID_FILE="$RUN_DIR/$ap.pid"
- if [[ -f "$PID_FILE" ]]; then
- PID=$(cat "$PID_FILE")
- if kill "$PID" 2>/dev/null; then
- info "Stopped hostapd for $ap (PID $PID)"
- fi
- rm -f "$PID_FILE"
- had_something=true
- fi
- done
-
- # Restore addresses if we still know the interface names.
- if [[ -f "$RUN_DIR/interfaces" ]]; then
- read -r AP1 AP2 AP3 CLIENT <"$RUN_DIR/interfaces"
-
- remove_iface_addr "$AP1" "$AP1_IP/24"
- remove_iface_addr "$AP2" "$AP2_IP/24"
- remove_iface_addr "$AP3" "$AP3_IP/24"
-
- if command -v nmcli &>/dev/null; then
- for iface in "$AP1" "$AP2" "$AP3" "$CLIENT"; do
- nmcli device set "$iface" managed yes 2>/dev/null || true
- done
- fi
- fi
-
- # Unload the kernel module (also destroys all virtual interfaces)
- if lsmod | grep -q mac80211_hwsim; then
- info "Unloading mac80211_hwsim..."
- rmmod mac80211_hwsim && had_something=true
- fi
-
- # Clean up runtime directory
- rm -rf "$RUN_DIR"
-
- if $had_something; then
- ok "Virtual WiFi environment stopped."
- else
- echo "Nothing was running."
- fi
-
-}
-
-# --- Status ------------------------------------------------------------------
-
-cmd_status() {
- if [[ ! -f "$RUN_DIR/interfaces" ]]; then
- echo "wifi-sim is not running."
- return
- fi
-
- read -r AP1 AP2 AP3 CLIENT <"$RUN_DIR/interfaces"
- echo "wifi-sim is running."
- echo ""
- echo " Interfaces:"
- for iface in "$AP1" "$AP2" "$AP3" "$CLIENT"; do
- STATE=$(ip link show "$iface" 2>/dev/null | awk '/state/{print $9}' || echo "unknown")
- CHANNEL=$(iw dev "$iface" info 2>/dev/null | awk '/channel/{print $2}' || echo "?")
- printf " %-10s state=%-4s channel=%s\n" "$iface" "$STATE" "$CHANNEL"
- done
- echo ""
- echo " Processes:"
- for ap in ap1 ap2 ap3; do
- PID_FILE="$RUN_DIR/$ap.pid"
- if [[ -f "$PID_FILE" ]]; then
- PID=$(cat "$PID_FILE")
- if kill -0 "$PID" 2>/dev/null; then
- echo " hostapd ($ap) PID=$PID running"
- else
- echo " hostapd ($ap) PID=$PID DEAD (check $RUN_DIR/$ap.log)"
- fi
- fi
-
- DNSMASQ_PID_FILE="$RUN_DIR/$ap.dnsmasq.pid"
- if [[ -f "$DNSMASQ_PID_FILE" ]]; then
- PID=$(cat "$DNSMASQ_PID_FILE")
- if kill -0 "$PID" 2>/dev/null; then
- echo " dnsmasq ($ap) PID=$PID running"
- else
- echo " dnsmasq ($ap) PID=$PID DEAD (check $RUN_DIR/$ap.dnsmasq.log)"
- fi
- fi
- done
-}
-
-# --- Entry point -------------------------------------------------------------
-
-case "${1:-help}" in
-start) cmd_start ;;
-stop) cmd_stop ;;
-status) cmd_status ;;
-*)
- echo "Usage: sudo $0 {start|stop|status}"
- echo ""
- echo " start Load mac80211_hwsim and bring up 3 virtual APs with DHCP"
- echo " stop Tear down all virtual interfaces and unload module"
- echo " status Show current state of interfaces and processes"
- echo ""
- echo "Networks created on start:"
- printf " %-16s open, strong signal\n" "$SSID_STRONG"
- printf " %-16s open, medium signal\n" "$SSID_MEDIUM"
- printf " %-16s WPA2, weak signal (password: $WIFI_PASSWORD)\n" "$SSID_SECURE"
- ;;
-esac