diff --git a/.config/eww##hostname.normandy/eww.scss b/.config/eww##hostname.normandy/eww.scss deleted file mode 100644 index d6aeebc..0000000 --- a/.config/eww##hostname.normandy/eww.scss +++ /dev/null @@ -1,115 +0,0 @@ -@import 'colors'; - -* { - all: unset; -} - -.root { - color: $foreground; - font-family: "Source Code Pro"; - font-size: 7.5pt; - background-color: rgba(0,0,0,0); - // Probably needs to change - &.bar { - margin: 10px; - margin-bottom: 0px; - } - - &.side { - margin: 10px; - margin-right: 0px; - } -} - -.gauge { - color: $foreground; -} - -.gauge-hole { - color: $wallpaper; -} - -.gauge-gutter { - color: $bg0; -} - -.icon { - font-family: "Font Awesome 5 Free Solid"; -} - -.invisible { - color: $wallpaper; -} - -.highlight { - color: $red; -} - -.offline { - color: $bg1; -} - -.special { - color: $blue; -} - -.green { - color: $green; -} - -.message-overlay { - background-color: $wallpaper; -} - -.nebula { - font-family: "Nebula"; - font-size: 1.2em; - &.big, .big { - font-size: 2.4em; - } - &.bigger, .bigger { - font-size: 2.9em; - } - &.medium, .medium { - font-size: 1.6em; - } - &.medium-big, .medium-big { - font-size: 2em; - } - -} - -.big .normal, .bigger .normal { - font-size: 1rem; -} - -// sway module - -.sway--ws { - - .fill { - background-color: $foreground; - } - color: $bg1; - - &.sway--active { - color: $foreground; - } - - &.sway--visible { - color: $blue; - } - - &.sway--focused { - } -} - -// clock module - -.clock--time { - font-size: 20pt; -} - -.clock--date { - font-size: 9pt; -} diff --git a/.config/eww##hostname.normandy/eww.yuck b/.config/eww##hostname.normandy/eww.yuck deleted file mode 100644 index add6034..0000000 --- a/.config/eww##hostname.normandy/eww.yuck +++ /dev/null @@ -1,130 +0,0 @@ -;; Include modules -(include "./modules/workspaces/workspaces.yuck") -(include "./modules/clock/clock.yuck") -(include "./modules/system/system.yuck") -(include "./modules/network/network.yuck") -(include "./modules/volume/volume.yuck") -(include "./modules/timer/timer.yuck") - -;; Windows -(defwidget leftbar--left [] - (box :orientation "h" - :halign "start" - :space-evenly false - :spacing 20 - :class "leftbox" - (system-name))) - - -(defwidget leftbar--center [] - (box :orientation "h" - :halign "center" - :space-evenly false - :spacing 0 - :class "centerbox" - (met) - )) - -(defwidget leftbar--right [] - (box :orientation "h" - :halign "end" - :space-evenly false - :spacing 20 - :class "rightbox" - (sway-workspace :group "left") - (sway-workspaces :group "left"))) - -(defwidget rightbar--left [] - (box :orientation "h" - :halign "start" - :space-evenly false - :spacing 20 - :class "leftbox" - (sway-workspaces :group "right") - (sway-workspace :group "right"))) - -(defwidget rightbar--hypr-left [] - (box :orientation "h" - :halign "start" - :space-evenly false - :spacing 20 - :class "leftbox" - (hypr-workspaces :group "main") - (hypr-workspace :group "main"))) - -(defwidget rightbar--center [] - (box :orientation "h" - :halign "center" - :space-evenly false - :spacing 0 - :class "centerbox" - (met) - )) - -(defwidget rightbar--right [] - (box :orientation "h" - :halign "end" - :space-evenly false - :spacing 20 - :class "leftbox" - (system-name))) - -(defwidget sidebar [] - (box :orientation "v" - :valign "start" - :space-evenly false - :spacing 20 - :class "bar root" - (sideclock) - (network-details) - (system-gauges) - )) - -(defwindow leftbar - :monitor 1 - :geometry (geometry :width "100%" - :height "36px" - :anchor "top center") - :exclusive true - :focusable false - :stacking "fg" - (centerbox :orientation "h" :class "bar root" - (leftbar--left) - (leftbar--center) - (leftbar--right))) - -(defwindow rightbar - :monitor 0 - :geometry (geometry :width "100%" - :height "26px" - :anchor "top center") - :exclusive true - :focusable false - :stacking "fg" - (centerbox :orientation "h" :class "bar root" - (rightbar--left) - (rightbar--center) - (rightbar--right))) - -(defwindow hypr-mainbar - :monitor 0 - :geometry (geometry :width "100%" - :height "36px" - :anchor "top center") - :exclusive true - :focusable false - :stacking "overlay" - (centerbox :orientation "h" :class "bar root" - (rightbar--hypr-left) - (rightbar--center) - (rightbar--right))) - -(defwindow sidebar - :monitor 1 - :geometry (geometry :width "210px" - :height "1044px" - :anchor "left bottom") - :exclusive true - :focusable false - :stacking "fg" - (sidebar)) diff --git a/.config/eww##hostname.normandy/modules/angles/angles.yuck b/.config/eww##hostname.normandy/modules/angles/angles.yuck deleted file mode 100644 index c424577..0000000 --- a/.config/eww##hostname.normandy/modules/angles/angles.yuck +++ /dev/null @@ -1,11 +0,0 @@ -(defwidget left-angle [] - (image :path "/home/ezri/.config/eww.new/modules/angles/left.png" - :width 150 - :height 36)) - -(defwidget right-angle [] - (image :path "/home/ezri/.config/eww.new/modules/angles/right.png" - :width 150 - :height 36)) - - diff --git a/.config/eww##hostname.normandy/modules/angles/left.png b/.config/eww##hostname.normandy/modules/angles/left.png deleted file mode 100644 index f79354d..0000000 Binary files a/.config/eww##hostname.normandy/modules/angles/left.png and /dev/null differ diff --git a/.config/eww##hostname.normandy/modules/angles/right.png b/.config/eww##hostname.normandy/modules/angles/right.png deleted file mode 100644 index 10a158d..0000000 Binary files a/.config/eww##hostname.normandy/modules/angles/right.png and /dev/null differ diff --git a/.config/eww##hostname.normandy/modules/audio.py b/.config/eww##hostname.normandy/modules/audio.py deleted file mode 100755 index e68f3b8..0000000 --- a/.config/eww##hostname.normandy/modules/audio.py +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env python3 - -import asyncio -import signal -from contextlib import suppress -import pulsectl_asyncio -import json - -async def get_values(pulse): - sink = await pulse.get_sink_by_name("@DEFAULT_SINK@") - result = { - "mute": sink.mute == 1, - "volume": f"{int(sink.volume.value_flat * 100):2}" - } - print(json.dumps(result), flush=True) - return result - -async def listen(): - async with pulsectl_asyncio.PulseAsync("volume-monitor") as pulse: - await get_values(pulse) - async for _ in pulse.subscribe_events('sink'): - await get_values(pulse) - -async def main(): - listen_task = asyncio.create_task(listen()) - - for sig in (signal.SIGTERM, signal.SIGHUP, signal.SIGINT): - loop.add_signal_handler(sig, listen_task.cancel) - - with suppress(asyncio.CancelledError): - await listen_task - -loop = asyncio.get_event_loop() -loop.run_until_complete(main()) diff --git a/.config/eww##hostname.normandy/modules/audio.yuck b/.config/eww##hostname.normandy/modules/audio.yuck deleted file mode 100644 index 435c693..0000000 --- a/.config/eww##hostname.normandy/modules/audio.yuck +++ /dev/null @@ -1,17 +0,0 @@ -(deflisten audio-data - `~/.config/eww/modules/audio.py`) - -(defwidget volume [align] - (box :orientation "h" - :halign align - :class "module volume ${audio-data['mute'] ? 'muted' : ''}" - :space-evenly false - :spacing 0 - (revealer :transition "none" - :reveal {!audio-data["mute"]} - "") - (revealer :transition "none" - :reveal {audio-data["mute"]} - "") - ' ${audio-data["volume"]}%')) - diff --git a/.config/eww##hostname.normandy/modules/clock/clock.yuck b/.config/eww##hostname.normandy/modules/clock/clock.yuck deleted file mode 100644 index 3b4ed67..0000000 --- a/.config/eww##hostname.normandy/modules/clock/clock.yuck +++ /dev/null @@ -1,67 +0,0 @@ -(defpoll clock--data :interval "500ms" - `date +'{"hour": "%H", "minute": "%M", "second": "%S", "year": "%Y", "day": "%d", "month": "%m", "dow": "%A", "month_name": "%B", "unix": "%s"}'`) - -(defvar clock--show "clock") - -(defwidget clock [] - (box :class "module text" - :spacing 0 - :orientation "v" - (label :class "special" - :text "${clock--data['hour']}:${clock--data['minute']}") - (label :text "${clock--data['year']}-${clock--data['month']}-${clock--data['day']}"))) - -(defwidget sideclock [] - (button :onclick "echo -n $(date +%Y-%d-%m) | wl-copy" - :onrightclick "echo -n $(date +%s) | wl-copy && eww update clock--show=unixtime && sleep 2 && eww update clock--show=clock" - (overlay - (box :class "module text nebula" - :spacing 0 - :space-evenly false - :orientation "v" - (centerbox :class "bigger nebula" - :space-evenly false - :width 150 - :halign "center" - :orientation "h" - (box :halign "start" "${clock--data.hour}") - (box :halign "center" ":") - (box :halign "end" "${clock--data.minute}")) - (label :text "${clock--data.dow}" - :class "special") - (label :text "${clock--data.month_name} ${clock--data.day}")) - (box - :height 100 - (revealer :transition "crossfade" - :reveal {clock--show == "unixtime"} - :duration {clock--show == "unixtime" ? "2s" : "500ms"} - (box :width 200 - :height 50 - :class "message-overlay nebula special" - (box - :space-evenly false - :spacing 0 - :halign "center" - :valign "center" - :orientation "v" - "Copied UNIX" - "timestamp" - )))) - (box - :height 100 - (revealer :transition "crossfade" - :reveal {clock--show == "date"} - :duration {clock--show == "date" ? "2s" : "500ms"} - (box :width 200 - :height 50 - :class "message-overlay nebula special" - (box - :space-evenly false - :spacing 0 - :halign "center" - :valign "center" - :orientation "v" - "Copied" - "current date" - - ))))))) diff --git a/.config/eww##hostname.normandy/modules/i3.json b/.config/eww##hostname.normandy/modules/i3.json deleted file mode 100644 index 311ccb0..0000000 --- a/.config/eww##hostname.normandy/modules/i3.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "1": { - "name": "1", - "use": "terminal", - "groups": ["left"] - }, - "2": { - "name": "2", - "use": "code", - "groups": ["left"] - }, - "3": { - "name": "3", - "use": "web", - "groups": ["left"] - }, - "4": { - "groups": ["left"], - "name": "4", - "use": "project" - }, - "5": { - "groups": ["left"], - "name": "5", - "use": "vms" - }, - "6": { - "groups": ["left"], - "name": "6", - "use": "documents" - }, - "7": { - "groups": ["left"], - "name": "7", - "use": "media" - }, - "8": { - "groups": ["left"], - "name": "8", - "use": "discord" - }, - "9": { - "groups": ["left"], - "name": "9", - "use": "zoom" - }, - "10": { - "groups": ["left"], - "name": "10", - "use": "config" - }, - "11": { - "groups": ["right"], - "name": "1", - "use": "terminal" - }, - "12": { - "groups": ["right"], - "name": "2", - "use": "code" - }, - "13": { - "groups": ["right"], - "name": "3", - "use": "web" - }, - "14": { - "groups": ["right"], - "name": "4", - "use": "project" - }, - "15": { - "groups": ["right"], - "name": "5", - "use": "misc" - }, - "16": { - "groups": ["right"], - "name": "6", - "use": "documents" - }, - "17": { - "groups": ["right"], - "name": "7", - "use": "media" - }, - "18": { - "groups": ["right"], - "name": "8", - "use": "slack" - }, - "19": { - "groups": ["right"], - "name": "9", - "use": "email" - }, - "20": { - "groups": ["right"], - "name": "10", - "use": "config" - } -} diff --git a/.config/eww##hostname.normandy/modules/i3.py b/.config/eww##hostname.normandy/modules/i3.py deleted file mode 100755 index 794ef93..0000000 --- a/.config/eww##hostname.normandy/modules/i3.py +++ /dev/null @@ -1,114 +0,0 @@ -#!/usr/bin/env python3 - -import asyncio -import json -import os -from i3ipc.aio import Connection -from i3ipc import Event -from typing import List - -class WorkspaceConfig: - - i3_index: str - sorting_index: int - display_index: str - display_name: str - display_groups: List[str] - - def __init__(self, i3_index: str, dictionary: dict): - self.i3_index = i3_index - self.sorting_index = dictionary.get("sort", int(i3_index)) - self.display_index = dictionary["name"] - self.display_name = dictionary.get("use", "???") - self.display_groups = dictionary.get("groups", ['default']) - - @classmethod - def parse_file(cls: type, filename: str): - result = [] - dictionary: dict = None - - with open(filename, 'r') as file: - dictionary = json.load(file) - - for index, data in dictionary.items(): - result.append(cls(index, data)) - - result.sort(key=lambda config: config.sorting_index) - - return result - -class WorkspaceStatus: - - config: WorkspaceConfig - expanded: bool - state: str - active: bool - - def __init__(self, config, state = None): - self.config = config - self.state = state or "" - self.active = state != None - self.expanded = state == "focused" or state == "visible" - - def dict_dump(self): - return { - "i3_index": self.config.i3_index, - "name": self.config.display_index, - "purpose": self.config.display_name, - "expand": self.expanded, - "state": self.state, - "active": self.active - } - -config = WorkspaceConfig.parse_file(f"{os.environ['HOME']}/.config/eww/modules/i3.json") - -groups = [] - -for ws in config: - for group in ws.display_groups: - if not group in groups: - groups.append(group) - -data = { - "ws": {}, - "mode": "default" -} - -def write_data(): - global data - print(json.dumps(data), flush=True) - -async def workspace_event(self: Connection, _): - global config, data - - ws_i3_dict = { ws.name: ws for ws in await self.get_workspaces()} - status = [] - for ws_def in config: - ws_i3 = ws_i3_dict.get(ws_def.i3_index, None) - if ws_i3: - state = ws_i3.focused and "focused" or ws_i3.visible and "visible" or ws_i3.urgent and "urgent" or "unfocused" - status.append(WorkspaceStatus(ws_def, state)) - else: - status.append(WorkspaceStatus(ws_def)) - - for group in groups: - data['ws'][group] = [ ws.dict_dump() for ws in filter(lambda ws: group in ws.config.display_groups, status) ] - # data['ws']['left'] = [ ws.dict_dump() for ws in filter(lambda ws: ws.config.sorting_index in range(1, 11), status) ] - # data['ws']['right'] = [ ws.dict_dump() for ws in filter(lambda ws: ws.config.sorting_index in range(11, 21), status) ] - write_data() - -async def mode_event(self: Connection, event): - global data - data['mode'] = event.change; - write_data() - -async def main(): - i3 = await Connection(auto_reconnect = True).connect() - - i3.on(Event.WORKSPACE_FOCUS, workspace_event) - i3.on(Event.WORKSPACE_URGENT, workspace_event) - i3.on(Event.MODE, mode_event) - await workspace_event(i3, None) - await i3.main() - -asyncio.run(main()) diff --git a/.config/eww##hostname.normandy/modules/i3.yuck b/.config/eww##hostname.normandy/modules/i3.yuck deleted file mode 100644 index 210a05a..0000000 --- a/.config/eww##hostname.normandy/modules/i3.yuck +++ /dev/null @@ -1,47 +0,0 @@ -(defwidget workspace [description] - (revealer :transition "slideright" - :reveal {description["active"]} - :duration "500ms" - (button :onclick "i3-msg workspace ${description['i3_index']}" - (box :orientation "h" - :halign "start" - :class '${description["state"]} workspace' - :space-evenly false - :spacing 1 - (revealer :transition "slideleft" :reveal {description["state"] == "urgent"} :duration "500ms" - " ") - {description["name"]} - (revealer :transition "slideright" :reveal {description["expand"]} :duration "500ms" - ': ${description["purpose"]}'))))) - -(deflisten i3-data :initial "[]" - `~/.config/eww/modules/i3.py`) - -(defwidget i3-mode [align] - (box :orientation "h" - :halign align - :space-evenly false - :spacing 0 - :class "module i3-mode" - :visible {i3-data["mode"] != "default"} - "mode: ${i3-data['mode']}")) - - -(defwidget i3 [align group] - (box :orientation "h" - :halign align - :space-evenly false - :spacing 0 - :class "module i3" - (workspace :description {i3-data["ws"][group][0]}) - (workspace :description {i3-data["ws"][group][1]}) - (workspace :description {i3-data["ws"][group][2]}) - (workspace :description {i3-data["ws"][group][3]}) - (workspace :description {i3-data["ws"][group][4]}) - (workspace :description {i3-data["ws"][group][5]}) - (workspace :description {i3-data["ws"][group][6]}) - (workspace :description {i3-data["ws"][group][7]}) - (workspace :description {i3-data["ws"][group][8]}) - (workspace :description {i3-data["ws"][group][9]}) -)) - diff --git a/.config/eww##hostname.normandy/modules/mpris.py b/.config/eww##hostname.normandy/modules/mpris.py deleted file mode 100755 index 7b4b0c4..0000000 --- a/.config/eww##hostname.normandy/modules/mpris.py +++ /dev/null @@ -1,111 +0,0 @@ -#!/usr/bin/env python3 - -import gi -import os -import sys -import json -import time - -try: - gi.require_version('Playerctl', '2.0') -except: - sys.exit(1) - -from gi.repository import Playerctl, GLib - -title_maxlen = 30; -artist_maxlen = 30; - -class Status: - - def __init__(self): - self.running = False - self.playing = False - self.title = None - self.artist = None - self.album = None - self.album_artist = None - - def _dict_dump(self): - return { - "running": self.running, - "playing": self.playing, - "title": self.title, - "artist": self.artist, - "album": self.album, - "album_artist": self.album_artist - } - - def __str__(self): - return json.dumps(self._dict_dump()) - -class StatusDisplay: - - def __init__(self): - self._player = None - - def show(self): - self._init_player() - - main = GLib.MainLoop() - main.run() - - def _get_status(self, playing = None): - if self._player: - status = Status() - status.running = self._player.props.playback_status != 2 - if playing == None: - status.playing = self._player.props.playback_status == 0 - else: - status.playing = playing - status.title = self._player.get_title() or "" - status.artist = self._player.get_artist() or "" - status.album = self._player.get_album() or "" - - if len(status.title) > title_maxlen: - status.title = status.title[:title_maxlen-1] + '…' - if len(status.artist) > artist_maxlen: - status.artist = status.artist[:artist_maxlen-1] + '…' - - return status - else: - return Status() - - def _print_status(self, status): - print(status, flush=True) - - def _init_player(self): - - success = False - - while not success: - try: - self._player = Playerctl.Player() - self._player.connect('metadata', self._on_update) - self._player.connect('play', self._on_play) - self._player.connect('pause', self._on_pause) - self._player.connect('exit', self._on_exit) - - self._print_status(self._get_status()) - - success = True - except: - - self._print_status(Status()) - time.sleep(2) - - def _on_update(self, *args): - self._print_status(self._get_status()) - - def _on_play(self, *args): - self._print_status(self._get_status(playing=True)) - - def _on_pause(self, *args): - self._print_status(self._get_status(playing=False)) - - def _on_exit(self, player): - del self._player - self._player = None - self._init_player() - -StatusDisplay().show() diff --git a/.config/eww##hostname.normandy/modules/mpris.yuck b/.config/eww##hostname.normandy/modules/mpris.yuck deleted file mode 100644 index 51bc293..0000000 --- a/.config/eww##hostname.normandy/modules/mpris.yuck +++ /dev/null @@ -1,17 +0,0 @@ -(deflisten mpris-data - `~/.config/eww/modules/mpris.py`) - -(defwidget mpris [align] - (box :orientation "h" - :halign align - :class "module mpris ${mpris-data['running'] ? '' : 'offline'} ${mpris-data['playing'] ? 'playing' : 'paused'}" - :space-evenly false - :spacing 0 - (label :class "fontawesome" - :text "") - (revealer :transition "none" - :reveal {!mpris-data['running']} - " players offline") - (revealer :transition "none" - :reveal {mpris-data['running']} - " ${mpris-data['title']} by ${mpris-data['artist']}"))) diff --git a/.config/eww##hostname.normandy/modules/network/network.py b/.config/eww##hostname.normandy/modules/network/network.py deleted file mode 100755 index 4b71007..0000000 --- a/.config/eww##hostname.normandy/modules/network/network.py +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env python3 - -import subprocess -import json -import sys -from time import sleep - -TRUSTED_NETWORKS = ['honnouji', 'honnouji_2.4'] - -def wifi(): - ssid_cmd = subprocess.run(['iwgetid', '-r'], capture_output = True) - if ssid_cmd.returncode != 0: - return {"connected": False, "ssid": None} - return {"connected": True, "ssid": ssid_cmd.stdout.decode('utf-8').strip()} - -def netdev(device: str): - ip_cmd = subprocess.run(['ip', '-j', 'addr', 'show', device], capture_output = True) - if ip_cmd.returncode != 0: - sys.stderr.write(ip_cmd.stdout.decode('utf-8')) - return {"exists": False, "online": False} - ip_data = json.loads(ip_cmd.stdout.decode('utf-8'))[0] - ip4_addr = "" - ip4_prefix_length = 24 - addr4_info = list(filter(lambda addr: addr.get("family") == "inet", ip_data["addr_info"])) - if len(addr4_info) >= 1: - ip4_addr = addr4_info[0]["local"] - ip4_prefix_length = addr4_info[0]["prefixlen"] - online = ip_data["operstate"] == "UP" or ip4_addr != "" - connecting = ip_data["operstate"] != "DOWN" and (ip4_addr == "" or not online) - return { - "exists": True, - "online": online, - "connecting": connecting, - "offline": not online and not connecting, - "ip4_addr": ip4_addr, - "ip4_prefix": ip4_prefix_length - } - -def trusted(ssid: str | None): - # Don't throw up an "INSECURE" alert when offline - if not ssid: - return True - return ssid in TRUSTED_NETWORKS - -while True: - insight = netdev('insight') - wlan0 = netdev('wlan0') - wifi_data = wifi() - connected = insight['exists'] and insight['online'] or wifi_data['connected'] - networks = { - "insight": insight, - "wlan0": netdev("wlan0"), - "ezrinet": netdev("ezrinet"), - "wg-mullvad": netdev("wg-mullvad"), - } - result = { - 'connected': connected, - "network": networks, - 'wifi': wifi_data, - "trusted": True, - "ip4_addrs": [ network.get('ip4_addr') for network in networks.values() if network.get('ip4_addr', "") != "" ] - } - print(json.dumps(result), flush=True) - sleep(1) diff --git a/.config/eww##hostname.normandy/modules/network/network.yuck b/.config/eww##hostname.normandy/modules/network/network.yuck deleted file mode 100644 index cf95775..0000000 --- a/.config/eww##hostname.normandy/modules/network/network.yuck +++ /dev/null @@ -1,194 +0,0 @@ -(deflisten network--data - `~/.config/eww/modules/network/network.py`) - -(defwidget network--wlan [device] - (box :orientation "h" - :halign "start" - :space-evenly false - :spacing 0 - (label :class "offline" - :visible {network--data["network"][device]["offline"]} - :text "offline") - (label :visible {network--data["network"][device]["connecting"]} - :class "highlight" - :text "connecting...") - (label :visible {network--data["network"][device]["online"]} - :class "special" - :text "${network--data['wifi']['ssid']}"))) - -(defwidget network--lan [device] - (box :orientation "h" - :halign "start" - :space-evenly false - :spacing 0 - (label :class "offline" - :visible {network--data["network"][device]["offline"]} - :text "offline") - (label :visible {network--data["network"][device]["connecting"]} - :class "highlight" - :text "connecting...") - (label :visible {network--data["network"][device]["online"] && !network--data.network[device].connecting} - :class "special" - :text "${network--data['network'][device]['ip4_addr']}/${network--data['network'][device]['ip4_prefix']}"))) - -(defwidget network--proxy-vpn [device ?required] - (box :orientation "h" - :halign "start" - :space-evenly false - :spacing 0 - :visible {network--data["network"][device]["exists"] || required} - (label :class "highlight" - :text "- insecure" - :visible {! network--data["network"][device]["exists"]}) - (label :class "green" - :text "- secured" - :visible {network--data["network"][device]["exists"]}))) - -(defwidget proxy-network [device] - (box :orientation "v" - :halign "start" - :space-evenly false - :spacing 0 - (label :class "green" - :text "connected" - :visible {network--data.network[device].exists}) - (label :class "offline" - :text "offline" - :visible {!network--data.network[device].exists}) - "proxy vpn")) - -(defwidget vpn-network [] - (box :orientation "v" - :halign "start" - :space-evenly false - :spacing 0 - (label :class "highlight" - :text "offline" - :visible {! network--data["network"]["ezrinet"]["exists"] || ! network--data["connected"]}) - (label :class "green" - :text "connected" - :visible {network--data["network"]["ezrinet"]["exists"] && network--data["connected"]}) - "personal network")) - -(defwidget network [] - (box :orientation "v" - :halign "start" - :space-evenly false - :spacing 0 - (box :orientation "h" - :halign "center" - :space-evenly false - :spacing 10 - (network--lan :device "insight") - (network--proxy-vpn :device "wg-mullvad" :required {!network--data.trusted})) - "communications")) - -(defwidget network-details [] - (box :orientation "v" - :halign "start" - :class "module" - :space-evenly false - :spacing 5 - :width 200 - (box :orientation "h" - :halign "center" - :class "nebula" - :spacing 10 - :space-evenly false - (label :text "Comms" - :class "medium special")) - (centerbox :orientation "h" - :halign "start" - :class "nebula" - :spacing 10 - :width 200 - :space-evenly false - (box :halign "start" - "Status:") - "" - (box :halign "end" - (label :text "Online" - :class "green" - :visible {network--data.connected}) - (label :text "Offline" - :class "highlight" - :visible {!network--data.connected}))) - (centerbox :orientation "h" - :halign "start" - :class "nebula" - :spacing 10 - :width 200 - :space-evenly false - (box :halign "start" - "VPN:") - "" - (box :halign "end" - (label :text "Connected" - :class "green" - :visible {network--data.network.ezrinet.online && network--data.connected}) - (label :text "Offline" - :class "highlight" - :visible {!network--data.network.ezrinet.exists}))) - (centerbox :orientation "h" - :halign "start" - :class "nebula" - :spacing 10 - :width 200 - :space-evenly false - (box :halign "start" - "Proxy:") - "" - (box :halign "end" - (label :text "Connected" - :class "green" - :visible {network--data.network.wg-mullvad.online}) - (label :text "Offline" - :class "highlight" - :visible {!network--data.network.wg-mullvad.exists}))) - (centerbox :orientation "h" - :halign "start" - :class "nebula" - :spacing 10 - :width 200 - :space-evenly false - (box :halign "start" - "Wi-Fi:") - "" - (box :halign "end" - (label :text {network--data.wifi.ssid} - :limit-width 12 - :class "green" - :visible {network--data.wifi.connected}) - (label :text "Offline" - :class "offline" - :visible {!network--data.wifi.connected}))) - (centerbox :orientation "h" - :halign "start" - :spacing 10 - :width 200 - :class "nebula" - :space-evenly false - (box :valign "start" - :halign "start" - "Addrs:") - "" - (box :valign "start" - :halign "end" - :visible {network--data.connected} - :orientation "v" - (for addr in {network--data.ip4_addrs} - (box :class "special" - :halign "end" - {addr})) - (box :visible {!network--data.connected} - :class "offline" - "none"))) - ;; (box :orientation "h" - ;; :halign "start" - ;; :class "nebula" - ;; :spacing 10 - ;; :space-evenly false - ;; (label :text "Addr:") - ;; (label :text {network--data.network[device].ip4_addr} - ;; :class "medium special")))) - )) diff --git a/.config/eww##hostname.normandy/modules/reboot.sh b/.config/eww##hostname.normandy/modules/reboot.sh deleted file mode 100755 index bd2cb1c..0000000 --- a/.config/eww##hostname.normandy/modules/reboot.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env zsh - -installed="$(file /boot/vmlinuz-linux | cut -d',' -f2 | cut -d' ' -f3)" -running="$(uname -r)" - -if [[ $installed == $running ]]; then - echo "false" -else - echo "true" -fi diff --git a/.config/eww##hostname.normandy/modules/system.py b/.config/eww##hostname.normandy/modules/system.py deleted file mode 100755 index 9de78ec..0000000 --- a/.config/eww##hostname.normandy/modules/system.py +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env python3 - -from time import sleep -import subprocess -import json - -def static(**kwargs): - def decorate(func): - for k in kwargs: - setattr(func, k, kwargs[k]) - return func - return decorate - -@static(idle = 0, total = 0) -def cpu_util(): - with open('/proc/stat') as file: - fields = [float(column) for column in file.readline().strip().split()[1:]] - idle = fields[3] - total = sum(fields) - idle_delta = idle - cpu_util.idle - total_delta = total - cpu_util.total - utilization = 100 * (1 - idle_delta / total_delta) - cpu_util.idle = idle - cpu_util.total = total - return f"{int(utilization):2}" - -def wifi(): - ssid_cmd = subprocess.run(['iwgetid', '-r'], capture_output = True) - if ssid_cmd.returncode != 0: - return {"connected": False, "ssid": ""} - return {"connected": True, "ssid": ssid_cmd.stdout.decode('utf-8').strip()} - -def netdev(device: str): - ip_cmd = subprocess.run(['ip', '-j', 'addr', 'show', device], capture_output = True) - if ip_cmd.returncode != 0: - return {"exists": False} - ip_data = json.loads(ip_cmd.stdout.decode('utf-8'))[0] - online = ip_data["operstate"] == "UP" - ip4_addr = "" - ip4_prefix_length = 24 - addr4_info = list(filter(lambda addr: addr.get("family") == "inet", ip_data["addr_info"])) - if len(addr4_info) >= 1: - ip4_addr = addr4_info[0]["local"] - ip4_prefix_length = addr4_info[0]["prefixlen"] - connecting = ip_data["operstate"] != "DOWN" and (ip4_addr == "" or not online) - return { - "exists": True, - "online": online, - "connecting": connecting, - "ip4_addr": ip4_addr, - "ip4_prefix": ip4_prefix_length - } - -# Prime cpu_util() with starting values -cpu_util() -sleep(0.1) - -while True: - result = { - "cpu": cpu_util(), - "network": { - "br0": netdev("br0") - } - } - print(json.dumps(result), flush=True) - sleep(1) diff --git a/.config/eww##hostname.normandy/modules/system.yuck b/.config/eww##hostname.normandy/modules/system.yuck deleted file mode 100644 index 3d55486..0000000 --- a/.config/eww##hostname.normandy/modules/system.yuck +++ /dev/null @@ -1,79 +0,0 @@ -(deflisten system-data - `~/.config/eww/modules/system.py`) -(defpoll reboot-needed :interval "10s" - :initial false - `~/.config/eww/modules/reboot.sh`) - -(defwidget reboot [align] - (box :orientation "h" - :halign align - :class "module reboot" - :space-evenly false - :spacing 0 - :visible {reboot-needed} - (button :onclick "~/.local/bin/i3-reboot" - :timeout "60s" - " reboot required"))) - -(defwidget memory [align] - (box :orientation "h" - :halign align - :class "module memory" - :space-evenly false - :spacing 0 - ' ${round(EWW_RAM["used_mem"]/1024/1024, 2)} GiB')) - -(defwidget cpu [align] - (box :orientation "h" - :halign align - :class "module cpu" - :space-evenly false - :spacing 0 - ' ${system-data["cpu"]}%')) - -(defwidget wlan-dev [align device] - (box :orientation "h" - :halign align - :class "module wlan-dev network ${system-data['network'][device]['online'] ? 'online' : 'offline'} ${system-data['network'][device]['connecting'] ? 'connecting' : ''}" - :space-evenly false - :spacing 0 - "" - (revealer :transition "slideright" - :reveal {!system-data["network"][device]["online"] && !system-data["network"][device]["connecting"]} - :duration "500ms" - " offline") - (revealer :transition "slideright" - :reveal {system-data["network"][device]["connecting"]} - :duration "500ms" - " connecting...") - (revealer :transition "slideright" - :reveal {system-data["network"][device]["online"] && system-data["network"][device]["ip4_addr"] != ""} - :duration "500ms" - ' ${system-data["wifi"]["ssid"]}') -)) - -(defwidget lan-dev [align device] - (box :orientation "h" - :halign align - :class "module lan-dev network ${system-data['network'][device]['online'] ? 'online' : 'offline'} ${system-data['network'][device]['connecting'] ? 'connecting' : ''}" - :space-evenly false - :spacing 0 - (revealer :transition "none" - :reveal {!system-data["network"][device]["online"] && !system-data["network"][device]["connecting"]} - "") - (revealer :transition "none" - :reveal {system-data["network"][device]["online"] || system-data["network"][device]["connecting"]} - "") - (revealer :transition "slideright" - :reveal {!system-data["network"][device]["online"] && !system-data["network"][device]["connecting"]} - :duration "500ms" - " offline") - (revealer :transition "slideright" - :reveal {system-data["network"][device]["connecting"]} - :duration "500ms" - " connecting...") - (revealer :transition "slideright" - :reveal {system-data["network"][device]["online"] && system-data["network"][device]["ip4_addr"] != ""} - :duration "500ms" - ' ${system-data["network"][device]["ip4_addr"]}') -)) diff --git a/.config/eww##hostname.normandy/modules/system/system.py b/.config/eww##hostname.normandy/modules/system/system.py deleted file mode 100755 index 372ae10..0000000 --- a/.config/eww##hostname.normandy/modules/system/system.py +++ /dev/null @@ -1,111 +0,0 @@ -#!/usr/bin/env python3 - -from time import sleep -import json -import psutil -import subprocess -import os -import sys - -amdgpuinfo_installed = False -# Try to import GPU info -try: - import pyamdgpuinfo as gpuinfo - amdgpuinfo_installed = True -except: - pass - -def cpu(): - util = psutil.cpu_percent(percpu=False) - per_core = psutil.cpu_percent(percpu=True) - return { - "avg_display": f"{int(util):2}", - "avg": util, - "cores": [ { "value": core, "display": f"{int(core):2}" } for core in per_core ], - "cores_display": "".join([ f"{int(core):3}" for core in per_core ]), - "core_count": len(per_core) - } - -def gpu(): - if not amdgpuinfo_installed or gpuinfo.detect_gpus() <= 0: - return { - "available": False, - "load": 0, - "power_state": 0, - "memory": 0 - } - gpu = gpuinfo.get_gpu(0) - return { - "available": True, - "load": gpu.query_load(), - "power_state": gpu.query_power(), - "memory": gpu.query_vram_usage() / gpu.memory_info['vram_size'] - } - -def sensor(chip: str): - return { temp.label: temp.current for temp in psutil.sensors_temperatures().get(chip) } - -def memory(): - mem = psutil.virtual_memory() - return { - "total": mem.total, - "available": mem.available, - "percent": mem.percent, - "used": mem.used, - "free": mem.free, - "active": mem.active, - "inactive": mem.inactive, - "buffers": mem.buffers, - "cached": mem.cached, - "shared": mem.shared, - "slab": mem.slab - } - -def swap(): - swap = psutil.swap_memory() - return { - "total": swap.total, - "used": swap.used, - "free": swap.free, - "percent": swap.percent - } - -def reboot(): - running = os.uname().release - version_proc = subprocess.run(["pacman", "-Q", "linux"], capture_output=True) - installed = version_proc.stdout.strip().decode('utf-8').split(' ')[1] - return running != installed - -def get_processes(): - return [ process for process in psutil.process_iter() ] - -def cpu_top(processes): - # Get the top 5 CPU usage processes - try: - result = [ { 'name': ps.name(), 'cpu': ps.cpu_percent() } for ps in processes ] - result.sort(key=lambda ps : -ps.get('cpu')) - return result[0:5] - except: - print("[ ERR ] missing process", file=sys.stderr) - -def mem_top(processes): - try: - result = [ { 'name': ps.name(), 'memory': ps.memory_info().rss } for ps in processes ] - result.sort(key=lambda ps : -ps.get('memory')) - return result[0:5] - except: - print("[ ERR ] missing process", file=sys.stderr) - -sensor_list = ['nvme', 'k10temp', 'amdgpu'] - -while True: - result = { - "cpu": cpu(), - "gpu": gpu(), - "sensors": { chip: sensor(chip) for chip in sensor_list }, - "memory": memory(), - "swap": swap(), - "reboot": reboot(), - } - print(json.dumps(result), flush=True) - sleep(1) diff --git a/.config/eww##hostname.normandy/modules/system/system.yuck b/.config/eww##hostname.normandy/modules/system/system.yuck deleted file mode 100644 index 85e3e01..0000000 --- a/.config/eww##hostname.normandy/modules/system/system.yuck +++ /dev/null @@ -1,276 +0,0 @@ -(defpoll system--hostname :interval "30s" - `hostnamectl hostname --pretty`) - -(deflisten system--data :initial "{}" - `~/.config/eww/modules/system/system.py`) - -(defwidget system-battery [battery] - (box :orientation "v" - :halign "start" - :class "module text" - :space-evenly false - :spacing 0 - (label :class {EWW_BATTERY[battery].status == 'Charging' || EWW_BATTERY[battery].status == 'Full' ? 'green' : EWW_BATTERY[battery].capacity <= 25 ? 'highlight' : 'special'} - :text "${EWW_BATTERY[battery].capacity}%") - (label :text "${EWW_BATTERY[battery].status == 'Charging' || EWW_BATTERY[battery].status == 'Full' ? 'external' : 'internal'} power"))) - -(defwidget system-name [] - (label :halign "center" - :valign "center" - :class "module text big nebula" - :text {system--hostname})) - -(defwidget system-cpu-avg [] - (box :orientation "v" - :halign "start" - :class "module text" - :space-evenly false - :spacing 0 - (label :class {system--data.cpu.avg > 90 ? 'highlight' : 'special'} - :text "${system--data.cpu.avg_display}%") - (label :text "cpu utilization"))) - -(defwidget system--cpu-core [core] - (label :class {core.value > 90 ? "highlight" : "special"} - :text "${core.display}%")) - -(defwidget system-cpu-percore [] - (box :orientation "v" - :halign "start" - :class "module text" - :space-evenly false - ;; (box :orientation "h" - ;; :halign "center" - ;; :space-evenly false - ;; (for core in {system--data.cpu.cores} - ;; (system--cpu-core :core core))) - (label :class "special" - :text {system--data.cpu.cores_display}) - (label :text "per-core cpu utilization") - )) - -(defwidget system-memory [] - (box :orientation "v" - :halign "start" - :class "module text" - :space-evenly false - (label :class {system--data.memory.percent > 85 ? "highlight" : "special"} - :text "${round(system--data.memory.used / 1024 / 1024 / 1024, 2)} / ${round(system--data.memory.total / 1024 / 1024 / 1024, 2)} GiB") - (label :text "system memory"))) - -(defwidget system--gauge [value ?threshold] - (overlay :width 80 - :height 80 - (circular-progress :value 75 - :class "gauge-gutter" - :start-at 37.5 - :thickness 2) - (circular-progress :value {value * 0.75} - :class 'gauge ${value > (threshold ?: 80) ? "highlight" : ""}' - :start-at 37.5 - :thickness 2))) - -(defwidget system-gauges [] - (box :orientation "h" - :space-evenly false - :width 200 - :halign "start" - :spacing 10 - (box :orientation "v" - :space-evenly false - :spacing 20 - :width 95 - :halign "start" - (system--cpu-gauge) - (system--gpu-gauge) - ) - (box :orientation "v" - :space-evenly false - :spacing 20 - :width 95 - :halign "end" - (system--memory-gauge) - (system--vram-gauge)))) - -(defwidget system--memory-gauge [] - (box :orientation "v" - :halign "end" - :width 95 - :space-evenly false - :spacing 10 - :class "nebula" - (label :text "RAM" - :class "medium special") - (box :halign "center" - (overlay - (system--gauge :value {system--data.memory.percent}) - (transform - :translate-y "-2px" - (box :halign "center" - :valign "center" - :orientation "h" - :space-evenly false - (label :text "%" - :class "invisible") - (label :text {round(system--data.memory.percent, 0)} - :class "medium special") - (transform - :translate-y "3px" - (label :text "%" - :class "offline")))))))) - -(defwidget system--cpu-gauge [] - (box :orientation "v" - :halign "start" - :width 95 - :space-evenly false - :spacing 10 - :class "nebula" - (label :text "CPU" - :class "medium special") - (box :halign "center" - (overlay - (system--gauge :value {system--data.cpu.avg}) - (transform - :translate-y "-2px" - (box :halign "center" - :valign "center" - :orientation "h" - :space-evenly false - (label :text "%" - :class "invisible") - (label :text {system--data.cpu.avg_display} - :class "medium special") - (transform - :translate-y "3px" - (label :text "%" - :class "offline")))))) - ;; (box :orientation "v" - ;; :halign "end" - ;; :valign "start" - ;; :width 100 - ;; :space-evenly false - ;; (for ps in {system--data.cpu_top} - ;; (centerbox :width 100 - ;; :orientation "h" - ;; (box :halign "start" - ;; (label :text {ps.name} - ;; :limit-width 7)) - ;; "" - ;; (box :halign "end" - ;; (label :text '${round(ps.cpu, 0)}%'))) - ;; ) - )) - -(defwidget system--gpu-gauge [] - (box :orientation "v" - :halign "start" - :width 95 - :space-evenly false - :spacing 10 - :class "nebula" - (label :text "GPU" - :class "medium special") - (box :halign "center" - (overlay - (system--gauge :value {system--data.gpu.load * 100}) - (transform - :translate-y "-2px" - (box :halign "center" - :valign "center" - :orientation "h" - :space-evenly false - (label :text "%" - :class "invisible") - (label :text {round(system--data.gpu.load * 100, 0)} - :class "medium special") - (transform - :translate-y "3px" - (label :text "%" - :class "offline")))))))) - -(defwidget system--vram-gauge [] - (box :orientation "v" - :halign "start" - :width 95 - :space-evenly false - :spacing 10 - :class "nebula" - (label :text "VRAM" - :class "medium special") - (box :halign "center" - (overlay - (system--gauge :value {system--data.gpu.memory * 100}) - (transform - :translate-y "-2px" - (box :halign "center" - :valign "center" - :orientation "h" - :space-evenly false - (label :text "%" - :class "invisible") - (label :text {round(system--data.gpu.memory * 100, 0)} - :class "medium special") - (transform - :translate-y "3px" - (label :text "%" - :class "offline")))))))) - - - -(defwidget system--gauge-generic [value value-fmt big-text little-text ?subscript ?threshold] - (box :orientation "h" - :halign "start" - :class "module gauge-widget" - :space-evenly true - :spacing 0 - (overlay :width 100 - (circular-progress :value 100 - :class "gauge-hole" - :start-at 0 - :thickness 50 - ) - (circular-progress :value 80 - :class "gauge-gutter" - :start-at 35 - :thickness 2) - (circular-progress :value {value * 0.8} - :class 'gauge ${value > (threshold ?: 80) ? "highlight" : ""}' - :start-at 35 - :thickness 2) - (transform :translate-y "-5px" - :translate-x "3px" - (box :halign "center" - :valign "center" - :class "big nebula" - :space-evenly false - "${value-fmt}" - (box :class "normal offline" - :halign "start" - :valign "end" - (transform :translate-y "-2px" - :translate-x "1px" - {subscript}))))) - (transform :translate-y "-5px" - (box :orientation "v" - :halign "center" - :valign "center" - :space-evenly false - (label :text {big-text} - :class "big nebula") - (label :text {little-text} - :class "nebula special"))))) - -;; (defwidget system-cpu-gauge [] -;; (system--gauge-generic :value {system--data.cpu.avg} -;; :value-fmt {system--data.cpu.avg_display} -;; :big-text "CPU" -;; :little-text "usage" -;; :subscript "%")) - -;; (defwidget system-memory-gauge [] -;; (system--gauge-generic :value {system--data.memory.percent} -;; :value-fmt {round(system--data.memory.percent, 0)} -;; :big-text "RAM" -;; :little-text "${round(system--data.memory.used / 1024 / 1024 / 1024, 1)} GiB" -;; :subscript "%")) diff --git a/.config/eww##hostname.normandy/modules/timer/timer.py b/.config/eww##hostname.normandy/modules/timer/timer.py deleted file mode 100755 index 931a503..0000000 --- a/.config/eww##hostname.normandy/modules/timer/timer.py +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env python3 - -import datetime -import os -import json -from time import sleep -import sys - -def get_time(): - try: - with open(f'{os.environ["HOME"]}/.timer', 'rb') as timestamp_file: - return datetime.datetime.fromtimestamp(int.from_bytes(timestamp_file.read(8), 'little')) - except Exception as exc: - return None - -while True: - now = datetime.datetime.now() - end = get_time() - if end is None: - print(json.dumps({ - 'hours': '00', - 'minutes': '00', - 'seconds': '00', - 'future': False, - 'timer': False - }), flush=True) - sleep(0.5) - continue - delta = int((now - get_time()).total_seconds()) - future = False - if delta < 0: - future = True - delta = -delta - hours = int(delta / 3600) - minutes = int((delta % 3600) / 60) - seconds = delta % 60 - print(json.dumps({ - 'hours': hours, - 'minutes': f'{minutes:02}', - 'seconds': f'{seconds:02}', - 'future': future, - 'timer': True - }), flush=True) - sleep(0.5) diff --git a/.config/eww##hostname.normandy/modules/timer/timer.yuck b/.config/eww##hostname.normandy/modules/timer/timer.yuck deleted file mode 100644 index 76afba1..0000000 --- a/.config/eww##hostname.normandy/modules/timer/timer.yuck +++ /dev/null @@ -1,29 +0,0 @@ -(deflisten timer--data :initial '{"timer": false}' - `~/.config/eww/modules/timer/timer.py`) - -(defwidget timer--gauge [value green] - (overlay :width 180 - :height 180 - (circular-progress :value 75 - :class "gauge-gutter" - :start-at 37.5 - :thickness 2) - (circular-progress :value {value * 0.75} - :class 'gauge ${green ? "green" : ""}' - :start-at 37.5 - :thickness 2))) - - -(defwidget met [] - (box :orientation "h" - :halign "center" - :space-evenly false - :spacing 5 - :class "nebula medium" - :visible {timer--data.timer} - "Baldur's Gate 3: " - (label :text 'T${timer--data.future ? "-" : "+"}' - :class {timer--data.future ? "highlight" : "green"}) - (label :text '${timer--data.hours}:${timer--data.minutes}:${timer--data.seconds}' - :class "special"))) - diff --git a/.config/eww##hostname.normandy/modules/volume/volume.yuck b/.config/eww##hostname.normandy/modules/volume/volume.yuck deleted file mode 100644 index 31ef72c..0000000 --- a/.config/eww##hostname.normandy/modules/volume/volume.yuck +++ /dev/null @@ -1,28 +0,0 @@ -(deflisten volume--data - `~/.config/eww/modules/volume/volume.py`) - -(defwidget volume-h [] - (box :orientation "h" - :halign "start" - :class "module ${volume--data['mute'] ? 'offline' : ''}" - :space-evenly false - :spacing 0 - (label :visible {!volume--data["mute"]} :text "") - (label :visible { volume--data["mute"]} :text "") - (label :text " ${volume--data['volume']}"))) - -(defwidget audio [] - (box :orientation "v" - :halign "center" - :class "module text" - :space-evenly false - :spacing 0 - (box :orientation "h" - :halign "center" - :space-evenly false - :spacing 15 - (label :class {volume--data.output.mute ? "offline" : "special"} - :text "${volume--data.output.volume}%") - (label :class {volume--data.input.mute ? "offline" : "special"} - :text "${volume--data.input.volume}%")) - "audio system")) diff --git a/.config/eww##hostname.normandy/modules/workspaces/sway.py b/.config/eww##hostname.normandy/modules/workspaces/sway.py deleted file mode 100755 index e1c426e..0000000 --- a/.config/eww##hostname.normandy/modules/workspaces/sway.py +++ /dev/null @@ -1,184 +0,0 @@ -#!/usr/bin/env python3 - -import asyncio -import json -import os -import sys -from i3ipc.aio import Connection -from i3ipc import Event -from typing import List, Dict, Any, Union, Tuple - -WorkspaceTree = Dict[str, Dict[str, List['Workspace']]] -WorkspaceList = Dict[str, 'Workspace'] - -class Workspace: - - index: str = None - name: str = None - exec_cmd: str = None - group: str = None - - active: bool = False - visible: bool = False - focused: bool = False - alerted: bool = False - - def __init__(self, dictionary: Dict[str, Union[str, int]], group: str): - self.index = str(dictionary.get('index')) - self.name = dictionary.get('name') - self.exec_cmd = dictionary.get('exec') - self.group = group - - self.active = dictionary.get('active', False) - self.visible = dictionary.get('visible', False) - self.focused = dictionary.get('focused', False) - self.alerted = dictionary.get('alerted', False) - - def update_state(self, state_update: Any): - self.active = True - self.visible = state_update.visible - self.focused = state_update.focused - self.alerted = state_update.urgent - - def deactivate(self): - self.active = False - self.visible = False - self.focused = False - self.alerted = False - - @classmethod - def parse_file(cls: type, filename: str) -> Tuple[WorkspaceTree, WorkspaceList]: - - result = {} - - initial: dict = None - with open(filename, 'r') as file: - initial = json.load(file) - - workspaces: WorkspaceList = {} - - def find_workspace(workspace: Dict[str, Union[str, int]], group: str) -> 'Workspace': - index = str(workspace.get('index')) - if index in workspaces: - return workspaces[index] - else: - workspaces[index] = cls(workspace, group) - return workspaces[index] - - result = { - context: { - group: [ - find_workspace(workspace, group) for workspace in workspaces - ] for group, workspaces in groups.items() - } for context, groups in initial.items() - } - - return result, workspaces - - @staticmethod - def full_dictify(tree: WorkspaceTree): - return { - context: { - group: [ - workspace.dictify() for workspace in workspaces - ] for group, workspaces in groups.items() - } for context, groups in tree.items() - } - - def dictify(self): - - return { - 'index': self.index, - 'name': self.name, - 'exec': self.exec_cmd, - 'active': self.active, - 'visible': self.visible, - 'focused': self.focused, - 'alerted': self.alerted - } - -workspace_tree, workspace_list = Workspace.parse_file(f"{os.environ['HOME']}/.config/sway/workspaces.json") - -data = { - "ws": {}, - "mode": "default", - "current": {}, - "context": "personal", - "visible": {}, -} - -def write_data(): - global data - print(json.dumps(data), flush=True) - -async def workspace_event(self: Connection, _): - global workspace_tree, workspace_list, data - - ws_sway_dict = { ws.name: ws for ws in await self.get_workspaces()} - - touched = [] - - for index, ws_data in ws_sway_dict.items(): - - # Update data for all active workspaces - ws_state = workspace_list.get(index) - if ws_state is None: - # If the workspace isn't configured, note it and handle gracefully - print(f"Warning: found unconfigured workspace {index}", file=sys.stderr, flush=True) - if ws_data.focused: - data['current'] = { - 'index': index, - 'name': 'undefined', - 'exec': 'alacritty', - 'active': True, - 'visible': True, - 'focused': True, - 'alerted': False - } - else: - # Otherwise, 'touch' it and update the status data - touched.append(index) - ws_state.update_state(ws_data) - if ws_state.focused: - data['current'] = ws_state.dictify() - if ws_state.visible: - data['visible'][ws_state.group] = ws_state.dictify() - - # 'Deactivate' any untouched workspaces - inactives = [ - v for k, v in workspace_list.items() if v.active and k not in touched - ] - - for workspace in inactives: - workspace.deactivate() - - # Create an 'unknown' workspace object for each group that doesn't yet have a listed visible workspace - for group in workspace_tree[data['context'] or 'personal'].keys(): - if group not in data['visible']: - data['visible'][group] = { - 'index': 'U', - 'name': 'undefined', - 'exec': 'alacritty', - 'active': True, - 'visible': True, - 'focused': False, - 'alerted': False - } - - data['ws'] = Workspace.full_dictify(workspace_tree) - write_data() - -async def mode_event(self: Connection, event): - global data - data['mode'] = event.change - write_data() - -async def main(): - sway = await Connection(auto_reconnect = True).connect() - - sway.on(Event.WORKSPACE, workspace_event) - sway.on(Event.MODE, mode_event) - await workspace_event(sway, None) - await sway.main() - -asyncio.run(main()) diff --git a/.config/eww##hostname.normandy/modules/workspaces/workspaces.yuck b/.config/eww##hostname.normandy/modules/workspaces/workspaces.yuck deleted file mode 100644 index 780cc93..0000000 --- a/.config/eww##hostname.normandy/modules/workspaces/workspaces.yuck +++ /dev/null @@ -1,75 +0,0 @@ -(deflisten sway--data :initial '{mode: "default"}' - `~/.config/eww/modules/workspaces/sway.py`) - -(defvar hypr--data '{}') - -(defwidget sway--workspace [ws] - (button :onclick "swaymsg workspace ${ws['index']}" - (circular-progress - :class 'indicator-circle sway--ws ${ws.active ? "sway--active" : ""} ${ws.visible ? "sway--visible" : ""} ${ws.focused ? "sway--focused" : ""} ${ws.alerted ? "sway--alerted" : ""}' - :value 100 - :start-at 0 - :clockwise true - :width 16 - :thickness 1 - (box :class 'fill' :visible {ws.visible})))) - -(defwidget hypr--workspace [ws] - (button :onclick "hyprmsg dispatch workspace ${ws['index']}" - (circular-progress - :class 'indicator-circle sway--ws ${ws.active ? "sway--active" : ""} ${ws.visible ? "sway--visible" : ""} ${ws.focused ? "sway--focused": ""}' - :value 100 - :start-at 0 - :clockwise true - :width 15 - :thickness 1 - (box :class 'fill' :visible {ws.focused})))) - -(defwidget sway-mode [] - (box :orientation "v" - :halign "center" - :space-evenly false - :spacing 0 - :class "module text" - :visible {hypr--data.mode != "default"} - (label :class "special" - :text "${hypr--data.mode}") - "sway mode")) - -(defwidget sway-workspace [group] - (box :orientation "v" - :halign "center" - :valign "center" - :space-evenly false - :spacing 0 - :class 'module text nebula medium' - (label :class '${sway--data.visible[group].focused ? "special" : "offline"}' - :text '${sway--data.visible[group].name}'))) - -(defwidget hypr-workspace [group] - (box :orientation "v" - :halign "center" - :space-evenly false - :spacing 0 - :class 'module text' - (label :class '${hypr--data.visible[group].focused ? "special" : "offline"}' - :text '${hypr--data.visible[group].name}') - (label :text "current workspace"))) - -(defwidget sway-workspaces [group] - (box :orientation "h" - :halign "start" - :space-evenly false - :spacing 5 - :class "sway--root" - (for workspace in {sway--data.ws[sway--data.context ?: "personal"][group]} - (sway--workspace :ws workspace)))) - -(defwidget hypr-workspaces [group] - (box :orientation "h" - :halign "start" - :space-evenly false - :spacing 5 - :class "sway--root" - (for workspace in {hypr--data.ws[hypr--data.context ?: "personal"][group]} - (hypr--workspace :ws workspace)))) diff --git a/.config/eww##hostname.rocinante/.python-version b/.config/eww##hostname.rocinante/.python-version deleted file mode 100644 index bba70ea..0000000 --- a/.config/eww##hostname.rocinante/.python-version +++ /dev/null @@ -1 +0,0 @@ -eww-modules diff --git a/.config/eww##hostname.rocinante/colors.scss b/.config/eww##hostname.rocinante/colors.scss deleted file mode 100644 index a62e408..0000000 --- a/.config/eww##hostname.rocinante/colors.scss +++ /dev/null @@ -1,13 +0,0 @@ -$wallpaper: #1e1e1e; -$foreground: #9a7c9d; - -$bg0: #2d272f; -$bg1: #3f3242; - -$red: #cf6a4c; -$green: #8f9d6a; -$yellow: #f9ee98; -$blue: #7587a6; -$magenta: #9b859d; -$cyan: #afc4db; -$white: #a7a7a7; diff --git a/.config/eww##hostname.rocinante/eww.scss b/.config/eww##hostname.rocinante/eww.scss deleted file mode 100644 index 4612533..0000000 --- a/.config/eww##hostname.rocinante/eww.scss +++ /dev/null @@ -1,90 +0,0 @@ -@import 'colors'; - -* { - all: unset; -} - -.reservepower.reservepower { - color: $red; -} - -.root { - color: $foreground; - font-family: "Source Code Pro"; - font-size: 9pt; - background-color: rgba(0,0,0,0); - // Probably needs to change - &.bar { - margin: 10px; - margin-bottom: 0px; - } - - &.side { - margin: 10px; - margin-right: 0px; - } -} - -.icon { - font-family: "Font Awesome 5 Free Solid"; -} - -.highlight { - color: $red; -} - -.offline { - color: $bg1; -} - -.special { - color: $blue; -} - -.green { - color: $green; -} - -.big { - font-size: 1.8rem; - font-family: "Nebula"; -} - -// sway module - -.sway--ws { - - .fill { - background-color: $foreground; - } - color: $bg1; - - &.sway--active { - color: $foreground; - } - - &.sway--visible { - color: $blue; - } - - &.sway--focused { - } -} - -.reservepower .sway--ws.sway--active { - color: $red; -} - -.reservepower .sway--ws .fill { - background-color: $red; -} - -// clock module - -.clock--time { - font-size: 20pt; -} - -.clock--date { - font-size: 9pt; -} diff --git a/.config/eww##hostname.rocinante/eww.yuck b/.config/eww##hostname.rocinante/eww.yuck deleted file mode 100644 index aba401f..0000000 --- a/.config/eww##hostname.rocinante/eww.yuck +++ /dev/null @@ -1,183 +0,0 @@ -;; Include modules -(include "./modules/workspaces/workspaces.yuck") -(include "./modules/clock/clock.yuck") -(include "./modules/system/system.yuck") -(include "./modules/network/network.yuck") -(include "./modules/volume/volume.yuck") - -(defvar power-state "normal") - -;; Windows -(defwidget leftbar--left [] - (box :orientation "h" - :halign "start" - :space-evenly false - :spacing 10 - :class "leftbox" - (vpn-network) - (network))) - -(defwidget leftbar--center [] - (box :orientation "h" - :halign "center" - :space-evenly false - :spacing 0 - :class "centerbox" - (system-name))) - -(defwidget leftbar--right [] - (box :orientation "h" - :halign "end" - :space-evenly false - :spacing 10 - :class "rightbox" - (sway-workspace :group "left") - (sway-workspaces :group "left"))) - -(defwidget rightbar--left [] - (box :orientation "h" - :halign "start" - :space-evenly false - :spacing 20 - :class "leftbox" - (sway-workspaces :group "right") - (sway-workspace :group "right"))) - -(defwidget rightbar--hypr-left [] - (box :orientation "h" - :halign "start" - :space-evenly false - :spacing 20 - :class "leftbox" - (hypr-workspaces :group "main") - (hypr-workspace :group "main"))) - -(defwidget rightbar--center [] - (box :orientation "h" - :halign "center" - :space-evenly false - :spacing 0 - :class "centerbox" - (system-name))) - -(defwidget rightbar--right [] - (box :orientation "h" - :halign "end" - :space-evenly false - :spacing 20 - :class "leftbox" - (system-battery :battery "BAT1") - (audio) - (clock))) - -(defwidget builtinbar--left [] - (box :orientation "h" - :halign "start" - :space-evenly false - :spacing 20 - :class "leftbox" - (sway-workspaces :group "builtin") - (sway-workspace :group "builtin"))) - -(defwidget builtinbar--center [] - (box :orientation "h" - :halign "center" - :space-evenly false - :spacing 0 - :class "centerbox" - (system-name))) - -(defwidget builtinbar--right [] - (box :orientation "h" - :halign "end" - :space-evenly false - :spacing 20 - :class "rightbox" - (vpn-network) - (network) - (system-battery :battery "BAT1") - (audio) - (clock))) - -(defwindow builtinbar - :monitor 0 - :geometry (geometry :width "100%" - :height "36px" - :anchor "top center") - :exclusive true - :focusable false - :stacking "fg" - (centerbox :orientation "h" :class "bar root ${power-state == "critical" ? 'reservepower' : ''}" - (builtinbar--left) - (builtinbar--center) - (builtinbar--right))) - -(defwindow side - :monitor 0 - :geometry (geometry :width "36px" - :height "100%" - :anchor "center left") - :exclusive true - :focusable false - :stacking "fg" - (centerbox :orientation "v" :class "bar root" :width 36 - (sway-workspaces-v :group "main") - "" - "")) - -(defwidget sidebar [] - (box :orientation "v" - :valign "start" - :space-evenly false - :spacing 0 - :class "bar root" - (clock))) - -(defwindow leftbar - :monitor 0 - :geometry (geometry :width "100%" - :height "36px" - :anchor "top center") - :exclusive true - :focusable false - :stacking "fg" - (centerbox :orientation "h" :class "bar root" - (leftbar--left) - (leftbar--center) - (leftbar--right))) - -(defwindow rightbar - :monitor 1 - :geometry (geometry :width "100%" - :height "55px" - :anchor "top center") - :exclusive true - :focusable false - :stacking "fg" - (centerbox :orientation "h" :class "bar root" - (rightbar--left) - (rightbar--center) - (rightbar--right))) - -(defwindow hypr-mainbar - :monitor 0 - :geometry (geometry :width "100%" - :height "36px" - :anchor "top center") - :exclusive true - :focusable false - :stacking "overlay" - (centerbox :orientation "h" :class "bar root" - (rightbar--hypr-left) - (rightbar--center) - (rightbar--right))) - -(defwindow sidebar - :monitor 1 - :geometry (geometry :width "210px" - :height "1044px" - :anchor "left bottom") - :exclusive true - :focusable false - :stacking "fg" - (sidebar)) diff --git a/.config/eww##hostname.rocinante/modules/angles/angles.yuck b/.config/eww##hostname.rocinante/modules/angles/angles.yuck deleted file mode 100644 index c424577..0000000 --- a/.config/eww##hostname.rocinante/modules/angles/angles.yuck +++ /dev/null @@ -1,11 +0,0 @@ -(defwidget left-angle [] - (image :path "/home/ezri/.config/eww.new/modules/angles/left.png" - :width 150 - :height 36)) - -(defwidget right-angle [] - (image :path "/home/ezri/.config/eww.new/modules/angles/right.png" - :width 150 - :height 36)) - - diff --git a/.config/eww##hostname.rocinante/modules/angles/left.png b/.config/eww##hostname.rocinante/modules/angles/left.png deleted file mode 100644 index f79354d..0000000 Binary files a/.config/eww##hostname.rocinante/modules/angles/left.png and /dev/null differ diff --git a/.config/eww##hostname.rocinante/modules/angles/right.png b/.config/eww##hostname.rocinante/modules/angles/right.png deleted file mode 100644 index 10a158d..0000000 Binary files a/.config/eww##hostname.rocinante/modules/angles/right.png and /dev/null differ diff --git a/.config/eww##hostname.rocinante/modules/clock/clock.yuck b/.config/eww##hostname.rocinante/modules/clock/clock.yuck deleted file mode 100644 index 6e9adb1..0000000 --- a/.config/eww##hostname.rocinante/modules/clock/clock.yuck +++ /dev/null @@ -1,10 +0,0 @@ -(defpoll clock--data :interval "500ms" - `date +'{"hour": "%H", "minute": "%M", "second": "%S", "year": "%Y", "day": "%d", "month": "%m", "dow": "%A", "month_name": "%B"}'`) - -(defwidget clock [] - (box :class "module text" - :spacing 0 - :orientation "v" - (label :class "special" - :text "${clock--data['hour']}:${clock--data['minute']}") - (label :text "${clock--data['year']}-${clock--data['month']}-${clock--data['day']}"))) diff --git a/.config/eww##hostname.rocinante/modules/system/system.py b/.config/eww##hostname.rocinante/modules/system/system.py deleted file mode 100755 index 116bfb5..0000000 --- a/.config/eww##hostname.rocinante/modules/system/system.py +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env python3 - -from time import sleep -import json -import psutil -import subprocess -import os - -def cpu(): - util = psutil.cpu_percent(percpu=False) - per_core = psutil.cpu_percent(percpu=True) - return { - "avg_display": f"{int(util):2}", - "avg": util, - "cores": per_core, - "core_count": len(per_core) - } - -def sensor(chip: str): - return { temp.label: temp.current for temp in psutil.sensors_temperatures()[chip] } - -def memory(): - mem = psutil.virtual_memory() - return { - 'used': mem.used, - 'available': mem.available, - 'total': mem.total, - 'percent': mem.percent - } - -def swap(): - mem = psutil.swap_memory() - return { - 'used': mem.used, - 'total': mem.total, - 'percent': mem.percent - } - -def reboot(): - running = os.uname().release - file_proc = subprocess.run("file /boot/vmlinuz-linux | cut -d',' -f2 | cut -d' ' -f3", shell=True, capture_output=True) - installed = file_proc.stdout.strip().decode('utf-8') - return running != installed - -sensor_list = ['coretemp'] - -while True: - result = { - "cpu": cpu(), - "sensors": { chip: sensor(chip) for chip in sensor_list }, - "memory": memory(), - "swap": swap(), - "reboot": reboot() - } - print(json.dumps(result), flush=True) - sleep(1) diff --git a/.config/eww##hostname.rocinante/modules/system/system.yuck b/.config/eww##hostname.rocinante/modules/system/system.yuck deleted file mode 100644 index 3a008b4..0000000 --- a/.config/eww##hostname.rocinante/modules/system/system.yuck +++ /dev/null @@ -1,20 +0,0 @@ -(defpoll system--hostname :interval "30s" - `bash -c 'eval $(cat /etc/machine-info); echo $PRETTY_HOSTNAME'`) - -(defvar system--battery-text "") - -(defwidget system-battery [battery] - (box :orientation "v" - :halign "start" - :class "module text" - :space-evenly false - :spacing 0 - (label :class {EWW_BATTERY[battery].status == 'Charging' || EWW_BATTERY[battery].status == 'Full' ? 'green' : EWW_BATTERY[battery].capacity <= 30 ? 'highlight' : 'special'} - :text "${EWW_BATTERY[battery].capacity}%") - (label :text "${EWW_BATTERY[battery].status == 'Charging' || EWW_BATTERY[battery].capacity == 100 ? 'external' : EWW_BATTERY[battery].capacity <= 15 ? 'emergency' : EWW_BATTERY[battery].capacity <= 30 ? 'reserve' : 'internal'} power"))) - -(defwidget system-name [] - (label :halign "center" - :valign "center" - :class "module text big" - :text {system--hostname})) diff --git a/.config/eww##hostname.rocinante/modules/volume/volume.py b/.config/eww##hostname.rocinante/modules/volume/volume.py deleted file mode 100755 index 8bc8bd9..0000000 --- a/.config/eww##hostname.rocinante/modules/volume/volume.py +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env python3 - -import asyncio -import signal -from contextlib import suppress -import pulsectl_asyncio -import json -import sys -import os - -async def get_values(pulse): - sink = None - try: - sink = await pulse.get_sink_by_name("@DEFAULT_SINK@") - source = await pulse.get_source_by_name("@DEFAULT_SOURCE@") - except: - # reload the script in the event of an exception - os.execv(sys.argv[0], sys.argv) - sink_result = { - "mute": sink.mute == 1, - "volume": f"{int(sink.volume.value_flat * 100):2}" - } - source_result = { - "mute": source.mute == 1, - "volume": f"{int(source.volume.value_flat * 100):2}" - } - result = { - "output": sink_result, - "input": source_result - } - print(json.dumps(result), flush=True) - return result - -async def listen(): - async with pulsectl_asyncio.PulseAsync("volume-monitor") as pulse: - await get_values(pulse) - async for _ in pulse.subscribe_events('all'): - await get_values(pulse) - -async def main(): - listen_task = asyncio.create_task(listen()) - - for sig in (signal.SIGTERM, signal.SIGHUP, signal.SIGINT): - loop.add_signal_handler(sig, listen_task.cancel) - - with suppress(asyncio.CancelledError): - await listen_task - -loop = asyncio.get_event_loop() -loop.run_until_complete(main()) diff --git a/.config/eww##hostname.rocinante/modules/volume/volume.yuck b/.config/eww##hostname.rocinante/modules/volume/volume.yuck deleted file mode 100644 index 31ef72c..0000000 --- a/.config/eww##hostname.rocinante/modules/volume/volume.yuck +++ /dev/null @@ -1,28 +0,0 @@ -(deflisten volume--data - `~/.config/eww/modules/volume/volume.py`) - -(defwidget volume-h [] - (box :orientation "h" - :halign "start" - :class "module ${volume--data['mute'] ? 'offline' : ''}" - :space-evenly false - :spacing 0 - (label :visible {!volume--data["mute"]} :text "") - (label :visible { volume--data["mute"]} :text "") - (label :text " ${volume--data['volume']}"))) - -(defwidget audio [] - (box :orientation "v" - :halign "center" - :class "module text" - :space-evenly false - :spacing 0 - (box :orientation "h" - :halign "center" - :space-evenly false - :spacing 15 - (label :class {volume--data.output.mute ? "offline" : "special"} - :text "${volume--data.output.volume}%") - (label :class {volume--data.input.mute ? "offline" : "special"} - :text "${volume--data.input.volume}%")) - "audio system")) diff --git a/.config/eww##hostname.rocinante/modules/workspaces/hyprland.py b/.config/eww##hostname.rocinante/modules/workspaces/hyprland.py deleted file mode 100755 index a332f07..0000000 --- a/.config/eww##hostname.rocinante/modules/workspaces/hyprland.py +++ /dev/null @@ -1,213 +0,0 @@ -#!/usr/bin/env python3 - -import asyncio -import json -import os -import sys - -WorkspaceTree = dict[str, dict[str, list['Workspace']]] -WorkspaceList = dict[str, 'Workspace'] - -socketdir = f"/tmp/hypr/{os.environ['HYPRLAND_INSTANCE_SIGNATURE']}" -socket1 = f"{socketdir}/.socket.sock" -socket2 = f"{socketdir}/.socket2.sock" - -listened_events = ['workspace', 'movewindow', 'createworkspace', 'destroyworkspace'] - -class Workspace: - - index: str = None - name: str = None - exec_cmd: str = None - group: str = None - - active: bool = False - visible: bool = False - focused: bool = False - alerted: bool = False - - def __init__(self, dictionary: dict[str, str | int], group: str): - self.index = str(dictionary.get('index')) - self.name = dictionary.get('name') - self.exec_cmd = dictionary.get('exec') - self.group = group - - self.active = dictionary.get('active', False) - self.visible = dictionary.get('visible', False) - self.focused = dictionary.get('focused', False) - self.alerted = dictionary.get('alerted', False) - - def update_state(self, state_update, monitor_dict): - self.active = True - self.visible = monitor_dict[state_update['monitor']]['activeWorkspace']['name'] == state_update['name'] - self.focused = self.visible and monitor_dict[state_update['monitor']]['focused'] - self.alerted = False - - def deactivate(self): - self.active = False - self.visible = False - self.focused = False - self.alerted = False - - @classmethod - def parse_file(cls: type, filename: str) -> tuple[WorkspaceTree, WorkspaceList]: - - result = {} - - initial: dict = None - with open(filename, 'r') as file: - initial = json.load(file) - - workspaces: WorkspaceList = {} - - def find_workspace(workspace: dict[str, str|int], group: str) -> 'Workspace': - index = str(workspace.get('index')) - if index in workspaces: - return workspaces[index] - else: - workspaces[index] = cls(workspace, group) - return workspaces[index] - - result = { - context: { - group: [ - find_workspace(workspace, group) for workspace in workspaces - ] for group, workspaces in groups.items() - } for context, groups in initial.items() - } - - return result, workspaces - - @staticmethod - def full_dictify(tree: WorkspaceTree): - return { - context: { - group: [ - workspace.dictify() for workspace in workspaces - ] for group, workspaces in groups.items() - } for context, groups in tree.items() - } - - def dictify(self): - - return { - 'index': self.index, - 'name': self.name, - 'exec': self.exec_cmd, - 'active': self.active, - 'visible': self.visible, - 'focused': self.focused, - 'alerted': self.alerted - } - -workspace_tree, workspace_list = Workspace.parse_file(f"{os.environ['HOME']}/.config/hypr/workspaces.json") - -data = { - "ws": {}, - "current": {}, - "context": "personal", - "visible": {}, - } - -def write_data(): - global data - print(json.dumps(data), flush=True) - -async def get_workspace_data(): - request = b"[[BATCH]] j/workspaces; j/monitors" - reader = None - writer = None - data = None - try: - reader, writer = await asyncio.open_unix_connection(socket1) - writer.write(request) - await writer.drain() - data = await reader.read() - finally: - if writer is not None: - writer.close() - if data is None: - return; - - workspace_data = None - monitor_data = None - try: - workspace_data, monitor_data = data.decode().split("}][{") - workspace_data += "}]" - monitor_data = "[{" + monitor_data - except ValueError: - print("Error unpacking response", file=sys.stderr) - return - - return [json.loads(workspace_data), json.loads(monitor_data)] - -async def update_workspaces(): - global workspace_tree, workspace_list, data - - workspaces, monitors = await get_workspace_data() - - ws_hypr_dict = { ws["name"]: ws for ws in workspaces } - monitor_dict = { monitor["name"]: monitor for monitor in monitors } - - touched = [] - - for index, ws_data in ws_hypr_dict.items(): - - # Update data for all active workspaces - ws_state = workspace_list.get(index) - if ws_state is None: - # If the workspace isn't configured, note it and handle gracefully - print(f"Warning: found unconfigured workspace {index}", file=sys.stderr, flush=True) - if monitor_dict[ws_data['monitor']]['activeWorkspace']['name'] == ws_data['name']: - data['current'] = { - 'index': index, - 'name': 'undefined', - 'exec': 'alacritty', - 'active': True, - 'visible': True, - 'focused': True, - 'alerted': False - } - else: - # Otherwise, 'touch' it and update status data - touched.append(index) - ws_state.update_state(ws_data, monitor_dict) - if ws_state.focused: - data['current'] = ws_state.dictify() - if ws_state.visible: - data['visible'][ws_state.group] = ws_state.dictify() - - inactives = [ - v for k, v in workspace_list.items() if v.active and k not in touched - ] - - for workspace in inactives: - workspace.deactivate() - - # Create an 'unknown' workspace object for each group that doesn't yet have a listed visible workspace - for group in workspace_tree[data['context'] or 'personal'].keys(): - if group not in data['visible']: - data['visible'][group] = { - 'index': 'U', - 'name': 'undefined', - 'exec': 'alacritty', - 'active': True, - 'visible': True, - 'focused': False, - 'alerted': False - } - data['ws'] = Workspace.full_dictify(workspace_tree) - write_data() - -async def main(): - reader, writer = await asyncio.open_unix_connection(socket2) - - await update_workspaces() - - while True: - event = (await reader.readline()).decode() - eventType, eventData = event.split(">>") - if eventType in listened_events: - await update_workspaces() - -asyncio.run(main()) diff --git a/.config/eww##hostname.rocinante/modules/workspaces/sway.py b/.config/eww##hostname.rocinante/modules/workspaces/sway.py deleted file mode 100755 index e1c426e..0000000 --- a/.config/eww##hostname.rocinante/modules/workspaces/sway.py +++ /dev/null @@ -1,184 +0,0 @@ -#!/usr/bin/env python3 - -import asyncio -import json -import os -import sys -from i3ipc.aio import Connection -from i3ipc import Event -from typing import List, Dict, Any, Union, Tuple - -WorkspaceTree = Dict[str, Dict[str, List['Workspace']]] -WorkspaceList = Dict[str, 'Workspace'] - -class Workspace: - - index: str = None - name: str = None - exec_cmd: str = None - group: str = None - - active: bool = False - visible: bool = False - focused: bool = False - alerted: bool = False - - def __init__(self, dictionary: Dict[str, Union[str, int]], group: str): - self.index = str(dictionary.get('index')) - self.name = dictionary.get('name') - self.exec_cmd = dictionary.get('exec') - self.group = group - - self.active = dictionary.get('active', False) - self.visible = dictionary.get('visible', False) - self.focused = dictionary.get('focused', False) - self.alerted = dictionary.get('alerted', False) - - def update_state(self, state_update: Any): - self.active = True - self.visible = state_update.visible - self.focused = state_update.focused - self.alerted = state_update.urgent - - def deactivate(self): - self.active = False - self.visible = False - self.focused = False - self.alerted = False - - @classmethod - def parse_file(cls: type, filename: str) -> Tuple[WorkspaceTree, WorkspaceList]: - - result = {} - - initial: dict = None - with open(filename, 'r') as file: - initial = json.load(file) - - workspaces: WorkspaceList = {} - - def find_workspace(workspace: Dict[str, Union[str, int]], group: str) -> 'Workspace': - index = str(workspace.get('index')) - if index in workspaces: - return workspaces[index] - else: - workspaces[index] = cls(workspace, group) - return workspaces[index] - - result = { - context: { - group: [ - find_workspace(workspace, group) for workspace in workspaces - ] for group, workspaces in groups.items() - } for context, groups in initial.items() - } - - return result, workspaces - - @staticmethod - def full_dictify(tree: WorkspaceTree): - return { - context: { - group: [ - workspace.dictify() for workspace in workspaces - ] for group, workspaces in groups.items() - } for context, groups in tree.items() - } - - def dictify(self): - - return { - 'index': self.index, - 'name': self.name, - 'exec': self.exec_cmd, - 'active': self.active, - 'visible': self.visible, - 'focused': self.focused, - 'alerted': self.alerted - } - -workspace_tree, workspace_list = Workspace.parse_file(f"{os.environ['HOME']}/.config/sway/workspaces.json") - -data = { - "ws": {}, - "mode": "default", - "current": {}, - "context": "personal", - "visible": {}, -} - -def write_data(): - global data - print(json.dumps(data), flush=True) - -async def workspace_event(self: Connection, _): - global workspace_tree, workspace_list, data - - ws_sway_dict = { ws.name: ws for ws in await self.get_workspaces()} - - touched = [] - - for index, ws_data in ws_sway_dict.items(): - - # Update data for all active workspaces - ws_state = workspace_list.get(index) - if ws_state is None: - # If the workspace isn't configured, note it and handle gracefully - print(f"Warning: found unconfigured workspace {index}", file=sys.stderr, flush=True) - if ws_data.focused: - data['current'] = { - 'index': index, - 'name': 'undefined', - 'exec': 'alacritty', - 'active': True, - 'visible': True, - 'focused': True, - 'alerted': False - } - else: - # Otherwise, 'touch' it and update the status data - touched.append(index) - ws_state.update_state(ws_data) - if ws_state.focused: - data['current'] = ws_state.dictify() - if ws_state.visible: - data['visible'][ws_state.group] = ws_state.dictify() - - # 'Deactivate' any untouched workspaces - inactives = [ - v for k, v in workspace_list.items() if v.active and k not in touched - ] - - for workspace in inactives: - workspace.deactivate() - - # Create an 'unknown' workspace object for each group that doesn't yet have a listed visible workspace - for group in workspace_tree[data['context'] or 'personal'].keys(): - if group not in data['visible']: - data['visible'][group] = { - 'index': 'U', - 'name': 'undefined', - 'exec': 'alacritty', - 'active': True, - 'visible': True, - 'focused': False, - 'alerted': False - } - - data['ws'] = Workspace.full_dictify(workspace_tree) - write_data() - -async def mode_event(self: Connection, event): - global data - data['mode'] = event.change - write_data() - -async def main(): - sway = await Connection(auto_reconnect = True).connect() - - sway.on(Event.WORKSPACE, workspace_event) - sway.on(Event.MODE, mode_event) - await workspace_event(sway, None) - await sway.main() - -asyncio.run(main()) diff --git a/.config/eww##hostname.rocinante/modules/workspaces/workspaces.yuck b/.config/eww##hostname.rocinante/modules/workspaces/workspaces.yuck deleted file mode 100644 index 0acaf87..0000000 --- a/.config/eww##hostname.rocinante/modules/workspaces/workspaces.yuck +++ /dev/null @@ -1,89 +0,0 @@ -(deflisten sway--data :initial '{mode: "default"}' - `~/.config/eww/modules/workspaces/sway.py`) - -(deflisten hypr--data :initial '{}' - `~/.config/eww/modules/workspaces/hyprland.py`) - -(defwidget sway--workspace [ws] - (button :onclick "swaymsg workspace ${ws['index']}" - (overlay :width 20 - :height 20 - (circular-progress - :class 'indicator-circle sway--ws ${ws.active ? "sway--active" : ""} ${ws.visible ? "sway--visible" : ""} ${ws.focused ? "sway--focused" : ""} ${ws.alerted ? "sway--alerted" : ""}' - :value 100 - :start-at 0 - :clockwise true - :width 20 - :thickness 1 - (box :class 'fill' :visible {ws.focused})) - ))) - -(defwidget hypr--workspace [ws] - (button :onclick "hyprmsg dispatch workspace ${ws['index']}" - (circular-progress - :class 'indicator-circle sway--ws ${ws.active ? "sway--active" : ""} ${ws.visible ? "sway--visible" : ""} ${ws.focused ? "sway--focused": ""}' - :value 100 - :start-at 0 - :clockwise true - :width 20 - :thickness 1 - (box :class 'fill' :visible {ws.focused})))) - -(defwidget sway-mode [] - (box :orientation "v" - :halign "center" - :space-evenly false - :spacing 0 - :class "module text" - :visible {sway--data.mode != "default"} - (label :class "special" - :text "${hypr--data.mode}") - "sway mode")) - -(defwidget sway-workspace [group] - (box :orientation "v" - :halign "center" - :space-evenly false - :spacing 0 - :class 'module text' - (label :class '${sway--data.visible[group].focused ? "special" : "offline"}' - :text '${sway--data.visible[group].name}') - (label :text "current workspace"))) - -(defwidget hypr-workspace [group] - (box :orientation "v" - :halign "center" - :space-evenly false - :spacing 0 - :class 'module text' - (label :class '${hypr--data.visible[group].focused ? "special" : "offline"}' - :text '${hypr--data.visible[group].name}') - (label :text "current workspace"))) - -(defwidget sway-workspaces [group] - (box :orientation "h" - :halign "start" - :space-evenly false - :spacing 5 - :class "sway--root" - (for workspace in {sway--data.ws[sway--data.context ?: "personal"][group]} - (sway--workspace :ws workspace)))) - -(defwidget sway-workspaces-v [group] - (box :orientation "v" - :halign "center" - :valign "start" - :space-evenly false - :spacing 5 - :class "sway--root" - (for workspace in {sway--data.ws[sway--data.context ?: "personal"][group]} - (sway--workspace :ws workspace)))) - -(defwidget hypr-workspaces [group] - (box :orientation "h" - :halign "start" - :space-evenly false - :spacing 5 - :class "sway--root" - (for workspace in {hypr--data.ws[hypr--data.context ?: "personal"][group]} - (hypr--workspace :ws workspace)))) diff --git a/.config/eww##hostname.rocinante/modules/workspaces/workspaces.yuck~ b/.config/eww##hostname.rocinante/modules/workspaces/workspaces.yuck~ deleted file mode 100644 index 2aa84a6..0000000 --- a/.config/eww##hostname.rocinante/modules/workspaces/workspaces.yuck~ +++ /dev/null @@ -1,89 +0,0 @@ -(deflisten sway--data :initial '{mode: "default"}' - `~/.config/eww/modules/sway.py`) - -(deflisten hypr--data :initial '{}' - `~/.config/eww/modules/workspaces/hyprland.py`) - -(defwidget sway--workspace [ws] - (button :onclick "swaymsg workspace ${ws['index']}" - (overlay :width 20 - :height 20 - (circular-progress - :class 'indicator-circle sway--ws ${ws.active ? "sway--active" : ""} ${ws.visible ? "sway--visible" : ""} ${ws.focused ? "sway--focused" : ""} ${ws.alerted ? "sway--alerted" : ""}' - :value 100 - :start-at 0 - :clockwise true - :width 20 - :thickness 1 - (box :class 'fill' :visible {ws.focused})) - ))) - -(defwidget hypr--workspace [ws] - (button :onclick "hyprmsg dispatch workspace ${ws['index']}" - (circular-progress - :class 'indicator-circle sway--ws ${ws.active ? "sway--active" : ""} ${ws.visible ? "sway--visible" : ""} ${ws.focused ? "sway--focused": ""}' - :value 100 - :start-at 0 - :clockwise true - :width 20 - :thickness 1 - (box :class 'fill' :visible {ws.focused})))) - -(defwidget sway-mode [] - (box :orientation "v" - :halign "center" - :space-evenly false - :spacing 0 - :class "module text" - :visible {sway--data.mode != "default"} - (label :class "special" - :text "${hypr--data.mode}") - "sway mode")) - -(defwidget sway-workspace [group] - (box :orientation "v" - :halign "center" - :space-evenly false - :spacing 0 - :class 'module text' - (label :class '${sway--data.visible[group].focused ? "special" : "offline"}' - :text '${sway--data.visible[group].name}') - (label :text "current workspace"))) - -(defwidget hypr-workspace [group] - (box :orientation "v" - :halign "center" - :space-evenly false - :spacing 0 - :class 'module text' - (label :class '${hypr--data.visible[group].focused ? "special" : "offline"}' - :text '${hypr--data.visible[group].name}') - (label :text "current workspace"))) - -(defwidget sway-workspaces [group] - (box :orientation "h" - :halign "start" - :space-evenly false - :spacing 5 - :class "sway--root" - (for workspace in {sway--data.ws[sway--data.context ?: "personal"][group]} - (sway--workspace :ws workspace)))) - -(defwidget sway-workspaces-v [group] - (box :orientation "v" - :halign "center" - :valign "start" - :space-evenly false - :spacing 5 - :class "sway--root" - (for workspace in {sway--data.ws[sway--data.context ?: "personal"][group]} - (sway--workspace :ws workspace)))) - -(defwidget hypr-workspaces [group] - (box :orientation "h" - :halign "start" - :space-evenly false - :spacing 5 - :class "sway--root" - (for workspace in {hypr--data.ws[hypr--data.context ?: "personal"][group]} - (hypr--workspace :ws workspace)))) diff --git a/.config/eww##hostname.tycho/.python-version b/.config/eww##hostname.tycho/.python-version deleted file mode 100644 index bba70ea..0000000 --- a/.config/eww##hostname.tycho/.python-version +++ /dev/null @@ -1 +0,0 @@ -eww-modules diff --git a/.config/eww##hostname.tycho/colors.scss b/.config/eww##hostname.tycho/colors.scss deleted file mode 100644 index a62e408..0000000 --- a/.config/eww##hostname.tycho/colors.scss +++ /dev/null @@ -1,13 +0,0 @@ -$wallpaper: #1e1e1e; -$foreground: #9a7c9d; - -$bg0: #2d272f; -$bg1: #3f3242; - -$red: #cf6a4c; -$green: #8f9d6a; -$yellow: #f9ee98; -$blue: #7587a6; -$magenta: #9b859d; -$cyan: #afc4db; -$white: #a7a7a7; diff --git a/.config/eww##hostname.tycho/eww.yuck b/.config/eww##hostname.tycho/eww.yuck deleted file mode 100644 index a743232..0000000 --- a/.config/eww##hostname.tycho/eww.yuck +++ /dev/null @@ -1,170 +0,0 @@ -;; Include modules -(include "./modules/workspaces/workspaces.yuck") -(include "./modules/clock/clock.yuck") -(include "./modules/system/system.yuck") -(include "./modules/network/network.yuck") -(include "./modules/volume/volume.yuck") -(include "./modules/aggietime/aggietime.yuck") -(include "./modules/weather/weather.yuck") -(include "./modules/timer/timer.yuck") -(include "./modules/mpris/mpris.yuck") - -;; Windows -(defwidget leftbar--left - [] - (box :orientation "h" - :halign "start" - :space-evenly false - :spacing 20 - :class "leftbox" - (clock) - (network) - (vpn-network) - (aggietime-shift))) - - -(defwidget leftbar--center - [] - (box :orientation "h" - :halign "center" - :space-evenly false - :spacing 0 - :class "centerbox" - (system-name))) - -(defwidget leftbar--right - [] - (box :orientation "h" - :halign "end" - :space-evenly false - :spacing 20 - :class "rightbox" - (sway-workspace :group "left") - (sway-workspaces :group "left"))) - -(defwidget rightbar--left - [] - (box :orientation "h" - :halign "start" - :space-evenly false - :spacing 20 - :class "leftbox" - (sway-workspaces :group "right") - (sway-workspace :group "right"))) - -(defwidget rightbar--hypr-left - [] - (box :orientation "h" - :halign "start" - :space-evenly false - :spacing 20 - :class "leftbox" - (hypr-workspaces :group "main") - (hypr-workspace :group "main"))) - -(defwidget rightbar--center - [] - (box :orientation "h" - :halign "center" - :space-evenly false - :spacing 0 - :class "centerbox" - (system-name))) - -(defwidget rightbar--right - [] - (box :orientation "h" - :halign "end" - :space-evenly false - :spacing 20 - :class "leftbox" - (mpris) - (system-memory) - (system-cpu-avg) - (clock))) - -(defwidget sidebar - [] - (box :orientation "v" - :valign "start" - :space-evenly false - :spacing 0 - :class "bar root" - (clock))) - -(defwindow leftbar - :monitor 0 - :geometry (geometry :width "100%" - :height "36px" - :anchor "top center"):exclusive - true - :focusable false - :stacking "fg" - (centerbox :orientation "h" - :class "bar root" - (leftbar--left) - (leftbar--center) - (leftbar--right))) - -(defwindow rightbar - :monitor 1 - :geometry (geometry :width "100%" - :height "26px" - :anchor "top center"):exclusive - true - :focusable false - :stacking "fg" - (centerbox :orientation "h" - :class "bar root" - (rightbar--left) - (rightbar--center) - (rightbar--right))) - -(defwindow network-status - :monitor 0 - :geometry (geometry :width "200px" - :height "0px" - :x "80px" - :y "0px" - :anchor "top left") - :exclusive false - :focusable false - :stacking "overlay" - (box :orientation "v" - :class "bar root bg" - :visible {network--show-details} - (network-detail))) - -(defwindow lock-overlay-1 - :monitor 1 - :geometry (geometry :width "50%" - :height "50%" - :anchor "center"):exclusive - false - :focusable false - :stacking "overlay" - "testing") - -(defwindow hypr-mainbar - :monitor 0 - :geometry (geometry :width "100%" - :height "36px" - :anchor "top center"):exclusive - true - :focusable false - :stacking "overlay" - (centerbox :orientation "h" - :class "bar root" - (rightbar--hypr-left) - (rightbar--center) - (rightbar--right))) - -(defwindow sidebar - :monitor 0 - :geometry (geometry :width "210px" - :height "1044px" - :anchor "left bottom"):exclusive - true - :focusable false - :stacking "fg" - (sidebar)) diff --git a/.config/eww##hostname.tycho/eww.yuck~ b/.config/eww##hostname.tycho/eww.yuck~ deleted file mode 100644 index 314cec4..0000000 --- a/.config/eww##hostname.tycho/eww.yuck~ +++ /dev/null @@ -1,128 +0,0 @@ -;; Include modules -(include "./modules/workspaces/workspaces.yuck") -(include "./modules/clock/clock.yuck") -(include "./modules/system/system.yuck") -(include "./modules/network/network.yuck") -(include "./modules/volume/volume.yuck") - -;; Windows -(defwidget leftbar--left [] - (box :orientation "h" - :halign "start" - :space-evenly false - :spacing 20 - :class "leftbox" - (clock) - (network) - (vpn-network))) - - -(defwidget leftbar--center [] - (box :orientation "h" - :halign "center" - :space-evenly false - :spacing 0 - :class "centerbox" - )) - -(defwidget leftbar--right [] - (box :orientation "h" - :halign "end" - :space-evenly false - :spacing 20 - :class "rightbox" - (sway-workspace :group "left") - (sway-workspaces :group "left"))) - -(defwidget rightbar--left [] - (box :orientation "h" - :halign "start" - :space-evenly false - :spacing 20 - :class "leftbox" - (sway-workspaces :group "right") - (sway-workspace :group "right"))) - -(defwidget rightbar--hypr-left [] - (box :orientation "h" - :halign "start" - :space-evenly false - :spacing 20 - :class "leftbox" - (hypr-workspaces :group "main") - (hypr-workspace :group "main"))) - -(defwidget rightbar--center [] - (box :orientation "h" - :halign "center" - :space-evenly false - :spacing 0 - :class "centerbox" - )) - -(defwidget rightbar--right [] - (box :orientation "h" - :halign "end" - :space-evenly false - :spacing 20 - :class "leftbox" - (system-memory) - (system-cpu-avg) - (clock))) - -(defwidget sidebar [] - (box :orientation "v" - :valign "start" - :space-evenly false - :spacing 0 - :class "bar root" - (clock))) - -(defwindow leftbar - :monitor 1 - :geometry (geometry :width "100%" - :height "36px" - :anchor "top center") - :exclusive true - :focusable false - :stacking "fg" - (centerbox :orientation "h" :class "bar root" - (leftbar--left) - (leftbar--center) - (leftbar--right))) - -(defwindow rightbar - :monitor 0 - :geometry (geometry :width "100%" - :height "26px" - :anchor "top center") - :exclusive true - :focusable false - :stacking "fg" - (centerbox :orientation "h" :class "bar root" - (rightbar--left) - (rightbar--center) - (rightbar--right))) - -(defwindow hypr-mainbar - :monitor 0 - :geometry (geometry :width "100%" - :height "36px" - :anchor "top center") - :exclusive true - :focusable false - :stacking "overlay" - (centerbox :orientation "h" :class "bar root" - (rightbar--hypr-left) - (rightbar--center) - (rightbar--right))) - -(defwindow sidebar - :monitor 1 - :geometry (geometry :width "210px" - :height "1044px" - :anchor "left bottom") - :exclusive true - :focusable false - :stacking "fg" - (sidebar)) diff --git a/.config/eww##hostname.tycho/modules/aggietime/aggietime.yuck b/.config/eww##hostname.tycho/modules/aggietime/aggietime.yuck deleted file mode 100644 index 48e9def..0000000 --- a/.config/eww##hostname.tycho/modules/aggietime/aggietime.yuck +++ /dev/null @@ -1,18 +0,0 @@ -(defpoll aggietime--data :interval "10s" - `~/.config/eww/modules/aggietime/aggietime.sh`) - -(defwidget aggietime-shift [] - (box :class "module text" - :spacing 0 - :orientation "v" - :visible {aggietime--data != ''} - (label :class "highlight" - :text "AggieTimeD Not Running" - :visible {aggietime--data.err}) - (label :class "special" - :visible {aggietime--data.active && !aggietime--data.err} - :text "${aggietime--data.hours}:${aggietime--data.minutes}") - (label :class "highlight" - :text "not clocked in" - :visible {!aggietime--data.active && !aggietime--data.err}) - "current shift")) diff --git a/.config/eww##hostname.tycho/modules/angles/angles.yuck b/.config/eww##hostname.tycho/modules/angles/angles.yuck deleted file mode 100644 index c424577..0000000 --- a/.config/eww##hostname.tycho/modules/angles/angles.yuck +++ /dev/null @@ -1,11 +0,0 @@ -(defwidget left-angle [] - (image :path "/home/ezri/.config/eww.new/modules/angles/left.png" - :width 150 - :height 36)) - -(defwidget right-angle [] - (image :path "/home/ezri/.config/eww.new/modules/angles/right.png" - :width 150 - :height 36)) - - diff --git a/.config/eww##hostname.tycho/modules/angles/left.png b/.config/eww##hostname.tycho/modules/angles/left.png deleted file mode 100644 index f79354d..0000000 Binary files a/.config/eww##hostname.tycho/modules/angles/left.png and /dev/null differ diff --git a/.config/eww##hostname.tycho/modules/angles/right.png b/.config/eww##hostname.tycho/modules/angles/right.png deleted file mode 100644 index 10a158d..0000000 Binary files a/.config/eww##hostname.tycho/modules/angles/right.png and /dev/null differ diff --git a/.config/eww##hostname.tycho/modules/mpris/mpris.yuck b/.config/eww##hostname.tycho/modules/mpris/mpris.yuck deleted file mode 100644 index 6499257..0000000 --- a/.config/eww##hostname.tycho/modules/mpris/mpris.yuck +++ /dev/null @@ -1,28 +0,0 @@ -(deflisten mpris--data :initial "{}" - `~/.config/eww/modules/mpris/mpris.py`) - -(defwidget mpris - [] - (box :class "module text" - :spacing 0 - :orientation "v" - (label :class {mpris--data.playing ? "special" : "offline"} - :visible {mpris--data.running} - :text "${mpris--data.title} by ${mpris--data.artist}") - (label :class "offline" - :visible {!mpris--data.running} - :text "player offline") - (label :visible {mpris--data.running} - :text "now playing from ${mpris--data.album}") - (label :visible {!mpris--data.running} - :text "player offline"))) - - -(defwidget mpris-miniplayer [] - (box :class "miniplayer" - :orientation "v" - :spacing 10 - (image :path {mpris--data.album_art} - :image-width 100 - :image-height 100) - (label))) diff --git a/.config/eww##hostname.tycho/modules/network/network.py b/.config/eww##hostname.tycho/modules/network/network.py deleted file mode 100755 index e4ec9ee..0000000 --- a/.config/eww##hostname.tycho/modules/network/network.py +++ /dev/null @@ -1,86 +0,0 @@ -#!/usr/bin/env python3 - -import subprocess -import json -import sys -from time import sleep - -TRUSTED_NETWORKS = ["honnouji", "honnouji_2.4"] - - -def wifi(): - try: - ssid_cmd = subprocess.run(["iwgetid", "-r"], capture_output=True) - if ssid_cmd.returncode != 0: - return {"connected": False, "ssid": None} - return {"connected": True, "ssid": ssid_cmd.stdout.decode("utf-8").strip()} - except: - return {"connected": False, "ssid": None} - - -def netdev(device: str): - ip_cmd = subprocess.run(["ip", "-j", "addr", "show", device], capture_output=True) - if ip_cmd.returncode != 0: - sys.stderr.write(ip_cmd.stdout.decode("utf-8")) - return { - "exists": False, - "online": False, - "connecting": False, - "offline": True, - "ip4_addr": None, - "ip4_prefix": None, - } - ip_data = json.loads(ip_cmd.stdout.decode("utf-8"))[0] - online = ip_data["operstate"] == "UP" - ip4_addr = "" - ip4_prefix_length = 24 - addr4_info = list( - filter(lambda addr: addr.get("family") == "inet", ip_data["addr_info"]) - ) - if len(addr4_info) >= 1: - ip4_addr = addr4_info[0]["local"] - ip4_prefix_length = addr4_info[0]["prefixlen"] - connecting = ip_data["operstate"] != "DOWN" and (ip4_addr == "" or not online) - return { - "exists": True, - "online": online, - "connecting": connecting, - "offline": not online and not connecting, - "ip4_addr": ip4_addr, - "ip4_prefix": ip4_prefix_length, - } - - -def trusted(ssid: str | None): - # Don't throw up an "INSECURE" alert when offline - if not ssid: - return True - return ssid in TRUSTED_NETWORKS - - -while True: - lan = netdev("lan") - wlan = netdev("wlan0") - vpn = netdev("ezrinet") - mullvad = netdev("wg-mullvad") - wifi_data = wifi() - # VPNs are routed over physical interfaces, so don't check them for online status - online = lan["online"] or wlan["online"] - configuring = (lan["connecting"] and not wlan["online"]) or ( - wlan["connecting"] and not lan["online"] - ) - result = { - "online": online, - "configuring": configuring, - "offline": not online and not configuring, - "network": { - "lan": lan, - "wlan": wlan, - "vpn": vpn, - "mullvad": mullvad, - }, - "wifi": wifi_data, - "trusted": True, - } - print(json.dumps(result), flush=True) - sleep(1) diff --git a/.config/eww##hostname.tycho/modules/network/network.yuck b/.config/eww##hostname.tycho/modules/network/network.yuck deleted file mode 100644 index 8e9d67e..0000000 --- a/.config/eww##hostname.tycho/modules/network/network.yuck +++ /dev/null @@ -1,249 +0,0 @@ -(deflisten network--data - `~/.config/eww/modules/network/new_network.py`) - -(defvar network--show-details false) - -(defwidget network-big - [] - (box :orientation "h" - :halign "start" - :valign "center" - :space-evenly false - :spacing 10 - (label :class "big nebula" - :text "comms:") - (network--interface :device "lan") - (network--interface :device "ezrinet") - (network--secure) - (network--vpn))) - -(defwidget network--interface - [device] - (box :orientation "v" - :halign "center" - :space-evenly false - :spacing 0 - (label :class "offline" - :visible {!device.online} - :text "offline") - (label :visible {device.online} - :class "special" - :text "${device.addresses[0].address}/${device.addresses[0].prefixlen}"))) - -(defwidget network-big--online - [] - (box :orientation "h" - :halign "start" - :valign "center" - :space-evenly false - :spacing 10 - (label :class "medium green nebula" - :visible {network--data.online} - :text "online") - (label :class "medium offline nebula" - :visible {network--data.offline} - :text "offline") - (label :class "medium highlight nebula" - :visible {network--data.configuring} - :text "configuring"))) - -(defwidget network-big--lan - [device] - (label :visible {network--data - [device] - .online} - :class "" - :text "${network--data.interfaces[device].addresses[0].address}/${network--data.interfaces[device].addresses[0].prefixlen}")) - -(defwidget network--wlan - [device] - (box :orientation "h" - :halign "start" - :space-evenly false - :spacing 0 - (label :class "offline" - :visible {network--data - ["network"] - [device] - ["offline"] - } - :text "offline") - (label :visible {network--data - ["network"] - [device] - ["connecting"] - } - :class "highlight" - :text "connecting...") - (label :visible {network--data - ["network"] - [device] - ["online"] - } - :class "special" - :text "${network--data['wifi']['ssid']}"))) - -(defwidget network--lan - [device] - (box :orientation "h" - :halign "start" - :space-evenly false - :spacing 0 - (label :class "offline" - :visible {!device.online} - :text "offline") - (label :visible {device.online} - :class {network--data.last_update.unix < clock--data.unix - 30 ? "highlight" : "special"} - :text "${device.addresses[0].address}/${device.addresses[0].prefixlen}"))) - -(defwidget network--secure - [] - (box :orientation "h" - :halign "start" - :space-evenly false - :spacing 0 - (label :class "highlight" - :text "- insecure" - :visible {! - network--data.secure }) - (label :class "green" - :text "- secured via ${network--data.secure_msg}" - :visible {network--data.secure}))) - -(defwidget vpn-network - [] - (box :orientation "v" - :halign "start" - :space-evenly false - :spacing 0 - :visible {network--data - != - ''} - (label :class "highlight" - :text "offline" - :visible {! - network--data.interfaces.ezrinet.online }) - (label :class "green" - :text "connected" - :visible {network--data.interfaces.ezrinet.online}) - "personal network")) - -(defwidget network - [] - (button :onclick "eww update network--show-details=${!network--show-details}" - (box :orientation "v" - :halign "start" - :space-evenly false - :spacing 0 - :visible {network--data != ''} - (box :orientation "h" - :halign "center" - :space-evenly false - :spacing 10 - (network--lan :device {network--data.default_interface})) - "communications"))) - -(defwidget network--public-ip - [] - (centerbox :orientation "h" - :halign "start" - :width 200 - (box :halign "start" - "public ip:") - "" - (box :halign "end" - :spacing 0 - :space-evenly false - (label :class "highlight" - :text "offline" - :visible {!network--data.online}) - (label :class "highlight" - :text "no response" - :visible {network--data.online && !network--data.have_public_ip}) - (label :class "special" - :text {network--data.public_ip.ip} - :visible {network--data.online && network--data.have_public_ip})))) - -(defwidget network--default-route - [] - (centerbox :orientation "h" - :halign "start" - :width 200 - (box :halign "start" - "route on:") - "" - (box :halign "end" - :spacing 0 - :space-evenly false - (label :class "highlight" - :text "offline" - :visible {!network--data.online}) - (label :class "highlight" - :text "no route" - :visible {network--data.online && !network--data.have_default_route}) - (label :class "special" - :text {network--data.default_route} - :visible {network--data.online && network--data.have_default_route})))) - -(defwidget network--gateway - [] - (centerbox :orientation "h" - :halign "start" - :width 200 - (box :halign "start" - "gateway:") - "" - (box :halign "end" - :spacing 0 - :space-evenly false - (label :class "highlight" - :text "no response" - :visible {!network--data.have_gateway}) - (label :class "special" - :text {network--data.gateway} - :visible {network--data.have_gateway})))) - -(defwidget network--status-summary - [] - (centerbox :orientation "h" - :halign "start" - :width 200 - (box :halign "start" - "status:") - "" - (box :halign "end" - :spacing 0 - :space-evenly false - (label :class "highlight" - :text "offline" - :visible {!network--data.online}) - (label :class "special" - :text "online" - :visible {network--data.online && !network--data.secure}) - (label :class "green" - :text {network--data.secure_msg == "usu" ? "vpn online" : "secure"} - :visible {network--data.online && network--data.secure})))) - - -(defwidget network-detail - [] - (box :orientation "v" - :halign "start" - :space-evenly false - :spacing 0 - (network--status-summary) - (network--public-ip) - (network--default-route) - (network--gateway) - (centerbox :orientation "h" - :halign "start" - :width 200 - (box :halign "start" - "last update:") - "" - (box :halign "end" - :spacing 0 - :space-evenly false - (label :class {network--data.last_update.unix < clock--data.unix - 30 ? "highlight" : "special"} - :text "${network--data.last_update.month}-${network--data.last_update.day} ${network--data.last_update.hour}:${network--data.last_update.minute}:${network--data.last_update.second}"))) - )) diff --git a/.config/eww##hostname.tycho/modules/system/system.yuck b/.config/eww##hostname.tycho/modules/system/system.yuck deleted file mode 100644 index f6b2e4f..0000000 --- a/.config/eww##hostname.tycho/modules/system/system.yuck +++ /dev/null @@ -1,59 +0,0 @@ -(deflisten system--data :initial "{}" - `~/.config/eww/modules/system/system.py`) - -(defwidget system-battery [battery] - (box :orientation "v" - :halign "start" - :class "module text" - :space-evenly false - :spacing 0 - (label :class {EWW_BATTERY[battery].status == 'Charging' || EWW_BATTERY[battery].status == 'Full' ? 'green' : EWW_BATTERY[battery].capacity <= 25 ? 'highlight' : 'special'} - :text "${EWW_BATTERY[battery].capacity}%") - (label :text "${EWW_BATTERY[battery].status == 'Charging' || EWW_BATTERY[battery].status == 'Full' ? 'external' : 'internal'} power"))) - -(defwidget system-name [] - (label :halign "center" - :valign "center" - :class "module text big nebula" - :text {system--data.hostname})) - -(defwidget system-cpu-avg [] - (box :orientation "v" - :halign "start" - :class "module text" - :space-evenly false - :spacing 0 - (label :class {system--data.cpu.avg > 90 ? 'highlight' : 'special'} - :text "${system--data.cpu.avg_display}%") - (label :text "cpu utilization"))) - -(defwidget system--cpu-core [core] - (label :class {core.value > 90 ? "highlight" : "special"} - :text "${core.display}%")) - -(defwidget system-cpu-percore [] - (box :orientation "v" - :halign "start" - :class "module text" - :space-evenly false - ;; (box :orientation "h" - ;; :halign "center" - ;; :space-evenly false - ;; (for core in {system--data.cpu.cores} - ;; (system--cpu-core :core core))) - (label :class "special" - :text {system--data.cpu.cores_display}) - (label :text "per-core cpu utilization") - )) - -(defwidget system-memory [] - (box :orientation "v" - :halign "start" - :class "module text" - :space-evenly false - (label :class {system--data.memory.percent > 85 ? "highlight" : "special"} - :text "${round(system--data.memory.used / 1024 / 1024 / 1024, 2)} / ${round(system--data.memory.total / 1024 / 1024 / 1024, 2)} GiB") - (label :text "system memory"))) - - - diff --git a/.config/eww##hostname.tycho/modules/timer/timer.yuck b/.config/eww##hostname.tycho/modules/timer/timer.yuck deleted file mode 100644 index b6240bc..0000000 --- a/.config/eww##hostname.tycho/modules/timer/timer.yuck +++ /dev/null @@ -1,11 +0,0 @@ -(deflisten timer--text :initial 'loading...' - `~/.config/eww/modules/timer/timer.py`) - -(defwidget timer [] - (box :class "module text" - :spacing 0 - :orientation "v" - (label :class "special" - :text {timer--text}) - (label :text "baldur's gate 3"))) - diff --git a/.config/eww##hostname.tycho/modules/volume/volume.py b/.config/eww##hostname.tycho/modules/volume/volume.py deleted file mode 100755 index 8bc8bd9..0000000 --- a/.config/eww##hostname.tycho/modules/volume/volume.py +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env python3 - -import asyncio -import signal -from contextlib import suppress -import pulsectl_asyncio -import json -import sys -import os - -async def get_values(pulse): - sink = None - try: - sink = await pulse.get_sink_by_name("@DEFAULT_SINK@") - source = await pulse.get_source_by_name("@DEFAULT_SOURCE@") - except: - # reload the script in the event of an exception - os.execv(sys.argv[0], sys.argv) - sink_result = { - "mute": sink.mute == 1, - "volume": f"{int(sink.volume.value_flat * 100):2}" - } - source_result = { - "mute": source.mute == 1, - "volume": f"{int(source.volume.value_flat * 100):2}" - } - result = { - "output": sink_result, - "input": source_result - } - print(json.dumps(result), flush=True) - return result - -async def listen(): - async with pulsectl_asyncio.PulseAsync("volume-monitor") as pulse: - await get_values(pulse) - async for _ in pulse.subscribe_events('all'): - await get_values(pulse) - -async def main(): - listen_task = asyncio.create_task(listen()) - - for sig in (signal.SIGTERM, signal.SIGHUP, signal.SIGINT): - loop.add_signal_handler(sig, listen_task.cancel) - - with suppress(asyncio.CancelledError): - await listen_task - -loop = asyncio.get_event_loop() -loop.run_until_complete(main()) diff --git a/.config/eww##hostname.tycho/modules/volume/volume.yuck b/.config/eww##hostname.tycho/modules/volume/volume.yuck deleted file mode 100644 index 31ef72c..0000000 --- a/.config/eww##hostname.tycho/modules/volume/volume.yuck +++ /dev/null @@ -1,28 +0,0 @@ -(deflisten volume--data - `~/.config/eww/modules/volume/volume.py`) - -(defwidget volume-h [] - (box :orientation "h" - :halign "start" - :class "module ${volume--data['mute'] ? 'offline' : ''}" - :space-evenly false - :spacing 0 - (label :visible {!volume--data["mute"]} :text "") - (label :visible { volume--data["mute"]} :text "") - (label :text " ${volume--data['volume']}"))) - -(defwidget audio [] - (box :orientation "v" - :halign "center" - :class "module text" - :space-evenly false - :spacing 0 - (box :orientation "h" - :halign "center" - :space-evenly false - :spacing 15 - (label :class {volume--data.output.mute ? "offline" : "special"} - :text "${volume--data.output.volume}%") - (label :class {volume--data.input.mute ? "offline" : "special"} - :text "${volume--data.input.volume}%")) - "audio system")) diff --git a/.config/eww##hostname.tycho/modules/weather/weather.yuck b/.config/eww##hostname.tycho/modules/weather/weather.yuck deleted file mode 100644 index 06b4b76..0000000 --- a/.config/eww##hostname.tycho/modules/weather/weather.yuck +++ /dev/null @@ -1,17 +0,0 @@ -;; -*- lisp -*- - -;; This is NOT lisp. It is "yuck", a lisp-like language that is used -;; to configure eww. It is a subset of lisp, with some extra features -;; that make it more suitable for configuration. - -(defpoll weather--data :interval "30m" - `curl wttr.in/84321?format=j1 | jq -c `) - -(defwidget weather - [] - (box :class "module text" - :spacing 0 - :orientation "v" - (label :class "special" - :text "${weather--data.current_condition[0].weatherDesc[0].value} ${weather--data.current_condition[0].temp_F}°F") - (label :text "current weather"))) diff --git a/.config/eww##hostname.tycho/modules/workspaces/hyprland.py b/.config/eww##hostname.tycho/modules/workspaces/hyprland.py deleted file mode 100755 index a332f07..0000000 --- a/.config/eww##hostname.tycho/modules/workspaces/hyprland.py +++ /dev/null @@ -1,213 +0,0 @@ -#!/usr/bin/env python3 - -import asyncio -import json -import os -import sys - -WorkspaceTree = dict[str, dict[str, list['Workspace']]] -WorkspaceList = dict[str, 'Workspace'] - -socketdir = f"/tmp/hypr/{os.environ['HYPRLAND_INSTANCE_SIGNATURE']}" -socket1 = f"{socketdir}/.socket.sock" -socket2 = f"{socketdir}/.socket2.sock" - -listened_events = ['workspace', 'movewindow', 'createworkspace', 'destroyworkspace'] - -class Workspace: - - index: str = None - name: str = None - exec_cmd: str = None - group: str = None - - active: bool = False - visible: bool = False - focused: bool = False - alerted: bool = False - - def __init__(self, dictionary: dict[str, str | int], group: str): - self.index = str(dictionary.get('index')) - self.name = dictionary.get('name') - self.exec_cmd = dictionary.get('exec') - self.group = group - - self.active = dictionary.get('active', False) - self.visible = dictionary.get('visible', False) - self.focused = dictionary.get('focused', False) - self.alerted = dictionary.get('alerted', False) - - def update_state(self, state_update, monitor_dict): - self.active = True - self.visible = monitor_dict[state_update['monitor']]['activeWorkspace']['name'] == state_update['name'] - self.focused = self.visible and monitor_dict[state_update['monitor']]['focused'] - self.alerted = False - - def deactivate(self): - self.active = False - self.visible = False - self.focused = False - self.alerted = False - - @classmethod - def parse_file(cls: type, filename: str) -> tuple[WorkspaceTree, WorkspaceList]: - - result = {} - - initial: dict = None - with open(filename, 'r') as file: - initial = json.load(file) - - workspaces: WorkspaceList = {} - - def find_workspace(workspace: dict[str, str|int], group: str) -> 'Workspace': - index = str(workspace.get('index')) - if index in workspaces: - return workspaces[index] - else: - workspaces[index] = cls(workspace, group) - return workspaces[index] - - result = { - context: { - group: [ - find_workspace(workspace, group) for workspace in workspaces - ] for group, workspaces in groups.items() - } for context, groups in initial.items() - } - - return result, workspaces - - @staticmethod - def full_dictify(tree: WorkspaceTree): - return { - context: { - group: [ - workspace.dictify() for workspace in workspaces - ] for group, workspaces in groups.items() - } for context, groups in tree.items() - } - - def dictify(self): - - return { - 'index': self.index, - 'name': self.name, - 'exec': self.exec_cmd, - 'active': self.active, - 'visible': self.visible, - 'focused': self.focused, - 'alerted': self.alerted - } - -workspace_tree, workspace_list = Workspace.parse_file(f"{os.environ['HOME']}/.config/hypr/workspaces.json") - -data = { - "ws": {}, - "current": {}, - "context": "personal", - "visible": {}, - } - -def write_data(): - global data - print(json.dumps(data), flush=True) - -async def get_workspace_data(): - request = b"[[BATCH]] j/workspaces; j/monitors" - reader = None - writer = None - data = None - try: - reader, writer = await asyncio.open_unix_connection(socket1) - writer.write(request) - await writer.drain() - data = await reader.read() - finally: - if writer is not None: - writer.close() - if data is None: - return; - - workspace_data = None - monitor_data = None - try: - workspace_data, monitor_data = data.decode().split("}][{") - workspace_data += "}]" - monitor_data = "[{" + monitor_data - except ValueError: - print("Error unpacking response", file=sys.stderr) - return - - return [json.loads(workspace_data), json.loads(monitor_data)] - -async def update_workspaces(): - global workspace_tree, workspace_list, data - - workspaces, monitors = await get_workspace_data() - - ws_hypr_dict = { ws["name"]: ws for ws in workspaces } - monitor_dict = { monitor["name"]: monitor for monitor in monitors } - - touched = [] - - for index, ws_data in ws_hypr_dict.items(): - - # Update data for all active workspaces - ws_state = workspace_list.get(index) - if ws_state is None: - # If the workspace isn't configured, note it and handle gracefully - print(f"Warning: found unconfigured workspace {index}", file=sys.stderr, flush=True) - if monitor_dict[ws_data['monitor']]['activeWorkspace']['name'] == ws_data['name']: - data['current'] = { - 'index': index, - 'name': 'undefined', - 'exec': 'alacritty', - 'active': True, - 'visible': True, - 'focused': True, - 'alerted': False - } - else: - # Otherwise, 'touch' it and update status data - touched.append(index) - ws_state.update_state(ws_data, monitor_dict) - if ws_state.focused: - data['current'] = ws_state.dictify() - if ws_state.visible: - data['visible'][ws_state.group] = ws_state.dictify() - - inactives = [ - v for k, v in workspace_list.items() if v.active and k not in touched - ] - - for workspace in inactives: - workspace.deactivate() - - # Create an 'unknown' workspace object for each group that doesn't yet have a listed visible workspace - for group in workspace_tree[data['context'] or 'personal'].keys(): - if group not in data['visible']: - data['visible'][group] = { - 'index': 'U', - 'name': 'undefined', - 'exec': 'alacritty', - 'active': True, - 'visible': True, - 'focused': False, - 'alerted': False - } - data['ws'] = Workspace.full_dictify(workspace_tree) - write_data() - -async def main(): - reader, writer = await asyncio.open_unix_connection(socket2) - - await update_workspaces() - - while True: - event = (await reader.readline()).decode() - eventType, eventData = event.split(">>") - if eventType in listened_events: - await update_workspaces() - -asyncio.run(main()) diff --git a/.config/eww##hostname.normandy/.python-version b/.config/eww/.python-version similarity index 100% rename from .config/eww##hostname.normandy/.python-version rename to .config/eww/.python-version diff --git a/.config/eww##hostname.normandy/colors.scss b/.config/eww/colors.scss similarity index 100% rename from .config/eww##hostname.normandy/colors.scss rename to .config/eww/colors.scss diff --git a/.config/eww/eww.scss b/.config/eww/eww.scss new file mode 100644 index 0000000..6bebf27 --- /dev/null +++ b/.config/eww/eww.scss @@ -0,0 +1,108 @@ +@import "colors"; + +* { + all: unset; +} + +.reservepower.reservepower { + color: $red; +} + +.root { + color: $foreground; + font-family: "Source Code Pro"; + font-size: 9pt; + background-color: rgba(0, 0, 0, 0); + // Probably needs to change + &.bar { + margin: 10px; + margin-bottom: 0px; + } + + &.side { + margin: 10px; + margin-right: 0px; + } + + &.bg { + background-color: $bg0; + padding: 10px; + } + + .nebula { + font-family: "Nebula"; + font-size: 1.2em; + &.big, + .big { + font-size: 2em; + } + &.medium, + .medium { + font-size: 1.6em; + } + &.small, + .small { + font-size: 1.4em; + } + } +} + +.icon { + font-family: "Font Awesome 5 Free Solid"; +} + +.highlight { + color: $red; +} + +.offline { + color: $bg1; +} + +.special { + color: $blue; +} + +.green { + color: $green; +} + +.big { + font-size: 12pt; +} + +// sway module + +.sway--ws { + color: $bg1; + + &.sway--active { + color: $foreground; + } + + &.sway--visible .fill { + background-color: $foreground; + } + + &.sway--focused .fill { + background-color: $foreground; + } +} + +.reservepower .sway--ws.sway--active { + color: $red; +} + +.reservepower .sway--ws .fill { + background-color: $red; +} + +// clock module + +.clock--time { + font-size: 20pt; +} + +.clock--date { + font-size: 9pt; +} diff --git a/.config/eww##hostname.tycho/eww.scss b/.config/eww/eww.scss.bak similarity index 100% rename from .config/eww##hostname.tycho/eww.scss rename to .config/eww/eww.scss.bak diff --git a/.config/eww/eww.yuck b/.config/eww/eww.yuck new file mode 120000 index 0000000..a4ad913 --- /dev/null +++ b/.config/eww/eww.yuck @@ -0,0 +1 @@ +eww.yuck##hostname.tycho \ No newline at end of file diff --git a/.config/eww/eww.yuck##hostname.rocinante b/.config/eww/eww.yuck##hostname.rocinante new file mode 100644 index 0000000..3bf502a --- /dev/null +++ b/.config/eww/eww.yuck##hostname.rocinante @@ -0,0 +1,24 @@ +;; -*-lisp-*- Include modules +(include "./modules/workspaces.yuck") +(include "./modules/clock.yuck") +(include "./modules/system.yuck") +(include "./modules/network.yuck") +(include "./modules/volume.yuck") +(include "./modules/aggietime.yuck") +(include "./modules/timer.yuck") +(include "./modules/mpris.yuck") + +(include "./windows.yuck") + +(defwindow builtinbar + :monitor 0 + :geometry (geometry :width "100%" + :height "36px" + :anchor "top center") + :exclusive true + :focusable false + :stacking "fg" + (centerbox :orientation "h" :class "bar root ${power--state == 'critical' ? 'reservepower' : ''}" + (rocinante-builtinbar--left) + (rocinante-builtinbar--center) + (rocinante-builtinbar--right))) diff --git a/.config/eww/eww.yuck##hostname.tycho b/.config/eww/eww.yuck##hostname.tycho new file mode 100644 index 0000000..653c5f8 --- /dev/null +++ b/.config/eww/eww.yuck##hostname.tycho @@ -0,0 +1,55 @@ +;; -*-lisp-*- Include modules +(include "./modules/workspaces.yuck") +(include "./modules/clock.yuck") +(include "./modules/system.yuck") +(include "./modules/network.yuck") +(include "./modules/volume.yuck") +(include "./modules/aggietime.yuck") +(include "./modules/timer.yuck") +(include "./modules/mpris.yuck") + +(include "./windows.yuck") + +(defwindow leftbar + :monitor 0 + :geometry (geometry :width "100%" + :height "36px" + :anchor "top center"):exclusive + true + :focusable false + :stacking "fg" + (centerbox :orientation "h" + :class "bar root" + (tycho-leftbar--left) + (tycho-leftbar--center) + (tycho-leftbar--right))) + +(defwindow rightbar + :monitor 1 + :geometry (geometry :width "100%" + :height "26px" + :anchor "top center"):exclusive + true + :focusable false + :stacking "fg" + (centerbox :orientation "h" + :class "bar root" + (tycho-rightbar--left) + (tycho-rightbar--center) + (tycho-rightbar--right))) + +(defwindow network-status + :monitor 0 + :geometry (geometry :width "200px" + :height "0px" + :x "80px" + :y "0px" + :anchor "top left") + :exclusive false + :focusable false + :stacking "overlay" + (box :orientation "v" + :class "bar root bg" + :visible {network--show-details} + (network-detail))) + diff --git a/.config/eww/modules/aggietime.yuck b/.config/eww/modules/aggietime.yuck new file mode 100644 index 0000000..a08212f --- /dev/null +++ b/.config/eww/modules/aggietime.yuck @@ -0,0 +1,19 @@ +;; -*-lisp-*- +(defpoll aggietime--data :interval "10s" + `~/.config/eww/scripts/aggietime.sh`) + +(defwidget aggietime-shift [] + (box :class "module text" + :spacing 0 + :orientation "v" + :visible {aggietime--data != ''} + (label :class "highlight" + :text "AggieTimeD Not Running" + :visible {aggietime--data.err}) + (label :class "special" + :visible {aggietime--data.active && !aggietime--data.err} + :text "${aggietime--data.hours}:${aggietime--data.minutes}") + (label :class "highlight" + :text "not clocked in" + :visible {!aggietime--data.active && !aggietime--data.err}) + "current shift")) diff --git a/.config/eww##hostname.tycho/modules/clock/clock.yuck b/.config/eww/modules/clock.yuck similarity index 50% rename from .config/eww##hostname.tycho/modules/clock/clock.yuck rename to .config/eww/modules/clock.yuck index f6df637..20f96b3 100644 --- a/.config/eww##hostname.tycho/modules/clock/clock.yuck +++ b/.config/eww/modules/clock.yuck @@ -1,10 +1,11 @@ +;; -*-lisp-*- (defpoll clock--data :interval "500ms" - `date +'{"hour": "%H", "minute": "%M", "second": "%S", "year": "%Y", "day": "%d", "month": "%m", "dow": "%A", "month_name": "%B", "unix": %s}'`) + `date +'{"hour": "%H", "minute": "%M", "second": "%S", "year": "%Y", "day": "%d", "month": "%m", "dow": "%A", "month_name": "%B", "unix": %s}'`) (defwidget clock [] (box :class "module text" :spacing 0 :orientation "v" (label :class "special" - :text "${clock--data.hour}:${clock--data.minute}:${clock--data.second}") + :text "${clock--data.hour}:${clock--data.minute}:${clock--data.second}") (label :text "${clock--data.year}-${clock--data.month}-${clock--data.day}"))) diff --git a/.config/eww/modules/mpris.yuck b/.config/eww/modules/mpris.yuck new file mode 100644 index 0000000..d655ea3 --- /dev/null +++ b/.config/eww/modules/mpris.yuck @@ -0,0 +1,29 @@ +;; -*-lisp-*- +(deflisten mpris--data :initial "{}" + `~/.config/eww/scripts/mpris.py`) + +(defwidget mpris2 + [] + (box :class "module text" + :spacing 0 + :orientation "v" + (label :class {mpris--data.playing ? "special" : "offline"} + :visible {mpris--data.running} + :text "${mpris--data.title} by ${mpris--data.artist}") + (label :class "offline" + :visible {!mpris--data.running} + :text "player offline") + (label :visible {mpris--data.running} + :text "now playing from ${mpris--data.album}") + (label :visible {!mpris--data.running} + :text "player offline"))) + + +(defwidget mpris-miniplayer [] + (box :class "miniplayer" + :orientation "v" + :spacing 10 + (image :path {mpris--data.album_art} + :image-width 100 + :image-height 100) + (label))) diff --git a/.config/eww/modules/network.yuck b/.config/eww/modules/network.yuck new file mode 120000 index 0000000..5de3e96 --- /dev/null +++ b/.config/eww/modules/network.yuck @@ -0,0 +1 @@ +network.yuck##hostname.tycho \ No newline at end of file diff --git a/.config/eww##hostname.rocinante/modules/network/network.yuck b/.config/eww/modules/network.yuck##hostname.rocinante similarity index 56% rename from .config/eww##hostname.rocinante/modules/network/network.yuck rename to .config/eww/modules/network.yuck##hostname.rocinante index c43aee6..dca9b60 100644 --- a/.config/eww##hostname.rocinante/modules/network/network.yuck +++ b/.config/eww/modules/network.yuck##hostname.rocinante @@ -1,5 +1,6 @@ +;; -*-lisp-*- (deflisten network--data - `~/.config/eww/modules/network/network.py`) + `~/.config/eww/scripts/network.py`) (defwidget network--wlan [device] (box :orientation "h" @@ -7,18 +8,18 @@ :space-evenly false :spacing 10 (label :class "offline" - :visible {network--data["network"][device]["offline"]} - :text "offline") + :visible {network--data["network"][device]["offline"]} + :text "offline") (label :visible {network--data["network"][device]["connecting"]} - :class "highlight" - :text "connecting...") + :class "highlight" + :text "connecting...") (label :visible {network--data["network"][device]["online"] && !network--data.network[device].connecting} - :class "special" - :text "${network--data['wifi']['ssid']}") + :class "special" + :text "${network--data['wifi']['ssid']}") (label :visible {!network--data.connection.internet && network--data.network[device].online} - :class "highlight" - :text "- no internet" - ))) + :class "highlight" + :text "- no internet" + ))) (defwidget network--lan [device] (box :orientation "h" @@ -26,14 +27,14 @@ :space-evenly false :spacing 0 (label :class "offline" - :visible {network--data["network"][device]["offline"]} - :text "offline") + :visible {network--data["network"][device]["offline"]} + :text "offline") (label :visible {network--data["network"][device]["connecting"]} - :class "highlight" - :text "connecting...") + :class "highlight" + :text "connecting...") (label :visible {network--data["network"][device]["online"] && !network--data.network[device].connecting} - :class "special" - :text "${network--data['network'][device]['ip4_addr']}/${network--data['network'][device]['ip4_prefix']}"))) + :class "special" + :text "${network--data['network'][device]['ip4_addr']}/${network--data['network'][device]['ip4_prefix']}"))) (defwidget network--proxy-vpn [device ?required] (box :orientation "h" @@ -42,11 +43,11 @@ :spacing 0 :visible {network--data.connection.internet && (network--data["network"][device]["exists"] || required)} (label :class "highlight" - :text "- insecure" - :visible {! network--data["network"][device]["exists"]}) + :text "- insecure" + :visible {! network--data["network"][device]["exists"]}) (label :class "green" - :text "- secured" - :visible {network--data["network"][device]["exists"]}))) + :text "- secured" + :visible {network--data["network"][device]["exists"]}))) (defwidget vpn-network [] (box :orientation "v" @@ -54,11 +55,11 @@ :space-evenly false :spacing 0 (label :class "highlight" - :text "offline" - :visible {!network--data.connection.ezrinet}) + :text "offline" + :visible {!network--data.connection.ezrinet}) (label :class "green" - :text "connected" - :visible {network--data.connection.ezrinet}) + :text "connected" + :visible {network--data.connection.ezrinet}) "personal network")) (defwidget network [] @@ -67,10 +68,10 @@ :space-evenly false :spacing 0 (box :orientation "h" - :halign "center" - :space-evenly false - :spacing 10 - (network--wlan :device "wlan0") - (network--proxy-vpn :device "wg-mullvad" :required {!network--data.trusted})) + :halign "center" + :space-evenly false + :spacing 10 + (network--wlan :device "wlan0") + (network--proxy-vpn :device "wg-mullvad" :required {!network--data.trusted})) "communications")) diff --git a/.config/eww/modules/network.yuck##hostname.tycho b/.config/eww/modules/network.yuck##hostname.tycho new file mode 100644 index 0000000..6fede46 --- /dev/null +++ b/.config/eww/modules/network.yuck##hostname.tycho @@ -0,0 +1,236 @@ +;; -*-lisp-*- +(deflisten network--data + `~/.config/eww/scripts/network.py`) + +(defvar network--show-details false) + +(defwidget network--interface + [device] + (box :orientation "v" + :halign "center" + :space-evenly false + :spacing 0 + (label :class "offline" + :visible {!device.online} + :text "offline") + (label :visible {device.online} + :class "special" + :text "${device.addresses[0].address}/${device.addresses[0].prefixlen}"))) + +(defwidget network-big--online + [] + (box :orientation "h" + :halign "start" + :valign "center" + :space-evenly false + :spacing 10 + (label :class "medium green nebula" + :visible {network--data.online} + :text "online") + (label :class "medium offline nebula" + :visible {network--data.offline} + :text "offline") + (label :class "medium highlight nebula" + :visible {network--data.configuring} + :text "configuring"))) + +(defwidget network-big--lan + [device] + (label :visible {network--data + [device] + .online} + :class "" + :text "${network--data.interfaces[device].addresses[0].address}/${network--data.interfaces[device].addresses[0].prefixlen}")) + +(defwidget network--wlan + [device] + (box :orientation "h" + :halign "start" + :space-evenly false + :spacing 0 + (label :class "offline" + :visible {network--data + ["network"] + [device] + ["offline"] + } + :text "offline") + (label :visible {network--data + ["network"] + [device] + ["connecting"] + } + :class "highlight" + :text "connecting...") + (label :visible {network--data + ["network"] + [device] + ["online"] + } + :class "special" + :text "${network--data['wifi']['ssid']}"))) + +(defwidget network--lan + [device] + (box :orientation "h" + :halign "start" + :space-evenly false + :spacing 0 + (label :class "offline" + :visible {!device.online} + :text "offline") + (label :visible {device.online} + :class {network--data.last_update.unix < clock--data.unix - 30 ? "highlight" : "special"} + :text "${device.addresses[0].address}/${device.addresses[0].prefixlen}"))) + +(defwidget network--secure + [] + (box :orientation "h" + :halign "start" + :space-evenly false + :spacing 0 + (label :class "highlight" + :text "- insecure" + :visible {! + network--data.secure }) + (label :class "green" + :text "- secured via ${network--data.secure_msg}" + :visible {network--data.secure}))) + +(defwidget vpn-network + [] + (box :orientation "v" + :halign "start" + :space-evenly false + :spacing 0 + :visible {network--data + != + ''} + (label :class "highlight" + :text "offline" + :visible {! + network--data.interfaces.ezrinet.online }) + (label :class "green" + :text "connected" + :visible {network--data.interfaces.ezrinet.online}) + "personal network")) + +(defwidget network + [] + (button :onclick "eww update network--show-details=${!network--show-details}" + (box :orientation "v" + :halign "start" + :space-evenly false + :spacing 0 + :visible {network--data != ''} + (box :orientation "h" + :halign "center" + :space-evenly false + :spacing 10 + (network--lan :device {network--data.default_interface})) + "communications"))) + +(defwidget network--public-ip + [] + (centerbox :orientation "h" + :halign "start" + :width 200 + (box :halign "start" + "public ip:") + "" + (box :halign "end" + :spacing 0 + :space-evenly false + (label :class "highlight" + :text "offline" + :visible {!network--data.online}) + (label :class "highlight" + :text "no response" + :visible {network--data.online && !network--data.have_public_ip}) + (label :class "special" + :text {network--data.public_ip.ip} + :visible {network--data.online && network--data.have_public_ip})))) + +(defwidget network--default-route + [] + (centerbox :orientation "h" + :halign "start" + :width 200 + (box :halign "start" + "route on:") + "" + (box :halign "end" + :spacing 0 + :space-evenly false + (label :class "highlight" + :text "offline" + :visible {!network--data.online}) + (label :class "highlight" + :text "no route" + :visible {network--data.online && !network--data.have_default_route}) + (label :class "special" + :text {network--data.default_route} + :visible {network--data.online && network--data.have_default_route})))) + +(defwidget network--gateway + [] + (centerbox :orientation "h" + :halign "start" + :width 200 + (box :halign "start" + "gateway:") + "" + (box :halign "end" + :spacing 0 + :space-evenly false + (label :class "highlight" + :text "no response" + :visible {!network--data.have_gateway}) + (label :class "special" + :text {network--data.gateway} + :visible {network--data.have_gateway})))) + +(defwidget network--status-summary + [] + (centerbox :orientation "h" + :halign "start" + :width 200 + (box :halign "start" + "status:") + "" + (box :halign "end" + :spacing 0 + :space-evenly false + (label :class "highlight" + :text "offline" + :visible {!network--data.online}) + (label :class "special" + :text "online" + :visible {network--data.online && !network--data.secure}) + (label :class "green" + :text {network--data.secure_msg == "usu" ? "vpn online" : "secure"} + :visible {network--data.online && network--data.secure})))) + + +(defwidget network-detail + [] + (box :orientation "v" + :halign "start" + :space-evenly false + :spacing 0 + (network--status-summary) + (network--public-ip) + (network--default-route) + (network--gateway) + (centerbox :orientation "h" + :halign "start" + :width 200 + (box :halign "start" + "last update:") + "" + (box :halign "end" + :spacing 0 + :space-evenly false + (label :class {network--data.last_update.unix < clock--data.unix - 30 ? "highlight" : "special"} + :text "${network--data.last_update.month}-${network--data.last_update.day} ${network--data.last_update.hour}:${network--data.last_update.minute}:${network--data.last_update.second}"))) + )) diff --git a/.config/eww/modules/system.yuck b/.config/eww/modules/system.yuck new file mode 100644 index 0000000..070e594 --- /dev/null +++ b/.config/eww/modules/system.yuck @@ -0,0 +1,60 @@ +;; -*-lisp-*- +(deflisten system--data :initial "{}" + `~/.config/eww/scripts/system.py`) + +(defwidget system-battery [battery] + (box :orientation "v" + :halign "start" + :class "module text" + :space-evenly false + :spacing 0 + (label :class {EWW_BATTERY[battery].status == 'Charging' || EWW_BATTERY[battery].status == 'Full' ? 'green' : EWW_BATTERY[battery].capacity <= 25 ? 'highlight' : 'special'} + :text "${EWW_BATTERY[battery].capacity}%") + (label :text "${EWW_BATTERY[battery].status == 'Charging' || EWW_BATTERY[battery].status == 'Full' ? 'external' : 'internal'} power"))) + +(defwidget system-name [] + (label :halign "center" + :valign "center" + :class "module text big nebula" + :text {system--data.hostname})) + +(defwidget system-cpu-avg [] + (box :orientation "v" + :halign "start" + :class "module text" + :space-evenly false + :spacing 0 + (label :class {system--data.cpu.avg > 90 ? 'highlight' : 'special'} + :text "${system--data.cpu.avg_display}%") + (label :text "cpu utilization"))) + +(defwidget system--cpu-core [core] + (label :class {core.value > 90 ? "highlight" : "special"} + :text "${core.display}%")) + +(defwidget system-cpu-percore [] + (box :orientation "v" + :halign "start" + :class "module text" + :space-evenly false + ;; (box :orientation "h" + ;; :halign "center" + ;; :space-evenly false + ;; (for core in {system--data.cpu.cores} + ;; (system--cpu-core :core core))) + (label :class "special" + :text {system--data.cpu.cores_display}) + (label :text "per-core cpu utilization") + )) + +(defwidget system-memory [] + (box :orientation "v" + :halign "start" + :class "module text" + :space-evenly false + (label :class {system--data.memory.percent > 85 ? "highlight" : "special"} + :text "${round(system--data.memory.used / 1024 / 1024 / 1024, 2)} / ${round(system--data.memory.total / 1024 / 1024 / 1024, 2)} GiB") + (label :text "system memory"))) + + + diff --git a/.config/eww/modules/timer.yuck b/.config/eww/modules/timer.yuck new file mode 100644 index 0000000..cabf47b --- /dev/null +++ b/.config/eww/modules/timer.yuck @@ -0,0 +1,12 @@ +;; -*-lisp-*- +(deflisten timer--text :initial 'loading...' + `~/.config/eww/scripts/timer.py`) + +(defwidget timer [] + (box :class "module text" + :spacing 0 + :orientation "v" + (label :class "special" + :text {timer--text}) + (label :text "baldur's gate 3"))) + diff --git a/.config/eww/modules/volume.yuck b/.config/eww/modules/volume.yuck new file mode 100644 index 0000000..80efe83 --- /dev/null +++ b/.config/eww/modules/volume.yuck @@ -0,0 +1,29 @@ +;; -*-lisp-*- +(deflisten volume--data + `~/.config/eww/scripts/volume.py`) + +(defwidget volume-h [] + (box :orientation "h" + :halign "start" + :class "module ${volume--data['mute'] ? 'offline' : ''}" + :space-evenly false + :spacing 0 + (label :visible {!volume--data["mute"]} :text "") + (label :visible { volume--data["mute"]} :text "") + (label :text " ${volume--data['volume']}"))) + +(defwidget audio [] + (box :orientation "v" + :halign "center" + :class "module text" + :space-evenly false + :spacing 0 + (box :orientation "h" + :halign "center" + :space-evenly false + :spacing 15 + (label :class {volume--data.output.mute ? "offline" : "special"} + :text "${volume--data.output.volume}%") + (label :class {volume--data.input.mute ? "offline" : "special"} + :text "${volume--data.input.volume}%")) + "audio system")) diff --git a/.config/eww/modules/weather.yuck b/.config/eww/modules/weather.yuck new file mode 100644 index 0000000..73fd27f --- /dev/null +++ b/.config/eww/modules/weather.yuck @@ -0,0 +1,13 @@ +;; -*-lisp-*- + +(defpoll weather--data :interval "30m" + `curl wttr.in/84321?format=j1 | jq -c `) + +(defwidget weather + [] + (box :class "module text" + :spacing 0 + :orientation "v" + (label :class "special" + :text "${weather--data.current_condition[0].weatherDesc[0].value} ${weather--data.current_condition[0].temp_F}°F") + (label :text "current weather"))) diff --git a/.config/eww##hostname.tycho/modules/workspaces/workspaces.yuck b/.config/eww/modules/workspaces.yuck similarity index 56% rename from .config/eww##hostname.tycho/modules/workspaces/workspaces.yuck rename to .config/eww/modules/workspaces.yuck index 52a9cee..ede6b3b 100644 --- a/.config/eww##hostname.tycho/modules/workspaces/workspaces.yuck +++ b/.config/eww/modules/workspaces.yuck @@ -1,29 +1,30 @@ +;; -*-lisp-*- (deflisten sway--data :initial '{"mode": "default"}' - `~/.config/eww/modules/workspaces/sway.py`) + `~/.config/eww/scripts/sway.py`) (defvar hypr--data '{}') (defwidget sway--workspace [ws] (button :onclick "swaymsg workspace ${ws['index']}" - (circular-progress - :class 'indicator-circle sway--ws ${ws.active ? "sway--active" : ""} ${ws.visible ? "sway--visible" : ""} ${ws.focused ? "sway--focused" : ""} ${ws.alerted ? "sway--alerted" : ""}' - :value 100 - :start-at 0 - :clockwise true - :width 16 - :thickness 1 - (box :class 'fill' )))) + (circular-progress + :class 'indicator-circle sway--ws ${ws.active ? "sway--active" : ""} ${ws.visible ? "sway--visible" : ""} ${ws.focused ? "sway--focused" : ""} ${ws.alerted ? "sway--alerted" : ""}' + :value 100 + :start-at 0 + :clockwise true + :width 16 + :thickness 1 + (box :class 'fill' )))) (defwidget hypr--workspace [ws] (button :onclick "hyprmsg dispatch workspace ${ws['index']}" - (circular-progress - :class 'indicator-circle sway--ws ${ws.active ? "sway--active" : ""} ${ws.visible ? "sway--visible" : ""} ${ws.focused ? "sway--focused": ""}' - :value 100 - :start-at 0 - :clockwise true - :width 15 - :thickness 1 - (box :class 'fill' :visible {ws.focused})))) + (circular-progress + :class 'indicator-circle sway--ws ${ws.active ? "sway--active" : ""} ${ws.visible ? "sway--visible" : ""} ${ws.focused ? "sway--focused": ""}' + :value 100 + :start-at 0 + :clockwise true + :width 15 + :thickness 1 + (box :class 'fill' :visible {ws.focused})))) (defwidget sway-mode [] (box :orientation "v" @@ -33,18 +34,18 @@ :class "module text" :visible {sway--data != '' && sway--data.mode != "default"} (label :class "special" - :text "${hypr--data.mode}") + :text "${hypr--data.mode}") "sway mode")) (defwidget sway-workspace [group] (box :orientation "v" :halign "center" - :valign "center" + :valign "center" :space-evenly false :spacing 0 :class 'module text' (label :class '${sway--data.visible[group].focused ? "special" : "offline"} nebula medium small' - :text '${sway--data.visible[group].name}'))) + :text '${sway--data.visible[group].name}'))) ; (label :text "current workspace"))) (defwidget hypr-workspace [group] @@ -54,18 +55,18 @@ :spacing 0 :class 'module text' (label :class '${hypr--data.visible[group].focused ? "special" : "offline"}' - :text '${hypr--data.visible[group].name}') + :text '${hypr--data.visible[group].name}') (label :text "current workspace"))) (defwidget sway-workspaces [group] - (box :orientation "h" - :halign "start" - :visible {sway--data != ''} - :space-evenly false - :spacing 5 - :class "sway--root" - (for workspace in {sway--data.ws[sway--data.context ?: "personal"][group]} - (sway--workspace :ws workspace)))) + (box :orientation "h" + :halign "start" + :visible {sway--data != ''} + :space-evenly false + :spacing 5 + :class "sway--root" + (for workspace in {sway--data.ws[sway--data.context ?: "personal"][group]} + (sway--workspace :ws workspace)))) (defwidget hypr-workspaces [group] (box :orientation "h" @@ -74,4 +75,4 @@ :spacing 5 :class "sway--root" (for workspace in {hypr--data.ws[hypr--data.context ?: "personal"][group]} - (hypr--workspace :ws workspace)))) + (hypr--workspace :ws workspace)))) diff --git a/.config/eww##hostname.tycho/modules/aggietime/aggietime.sh b/.config/eww/scripts/aggietime.sh similarity index 100% rename from .config/eww##hostname.tycho/modules/aggietime/aggietime.sh rename to .config/eww/scripts/aggietime.sh diff --git a/.config/eww##hostname.normandy/modules/workspaces/hyprland.py b/.config/eww/scripts/hyprland.py similarity index 100% rename from .config/eww##hostname.normandy/modules/workspaces/hyprland.py rename to .config/eww/scripts/hyprland.py diff --git a/.config/eww##hostname.tycho/modules/mpris/mpris.py b/.config/eww/scripts/mpris.py similarity index 100% rename from .config/eww##hostname.tycho/modules/mpris/mpris.py rename to .config/eww/scripts/mpris.py diff --git a/.config/eww/scripts/network.py b/.config/eww/scripts/network.py new file mode 120000 index 0000000..3533c0f --- /dev/null +++ b/.config/eww/scripts/network.py @@ -0,0 +1 @@ +network.py##hostname.tycho \ No newline at end of file diff --git a/.config/eww##hostname.rocinante/modules/network/network.py b/.config/eww/scripts/network.py##hostname.rocinante similarity index 100% rename from .config/eww##hostname.rocinante/modules/network/network.py rename to .config/eww/scripts/network.py##hostname.rocinante diff --git a/.config/eww##hostname.tycho/modules/network/new_network.py b/.config/eww/scripts/network.py##hostname.tycho similarity index 97% rename from .config/eww##hostname.tycho/modules/network/new_network.py rename to .config/eww/scripts/network.py##hostname.tycho index ae72061..dca8109 100755 --- a/.config/eww##hostname.tycho/modules/network/new_network.py +++ b/.config/eww/scripts/network.py##hostname.tycho @@ -218,7 +218,6 @@ last_request = None last_first_hop = None while True: - start = now() try: online = ping("1.1.1.1") except: @@ -278,10 +277,3 @@ while True: ), flush=True, ) - - end = now() - delta = end - start - if delta > 5: - print("Warning: took longer than 5 seconds to run", file=sys.stderr, flush=True) - else: - sleep(5 - delta) diff --git a/.config/eww##hostname.tycho/modules/workspaces/sway.py b/.config/eww/scripts/sway.py similarity index 100% rename from .config/eww##hostname.tycho/modules/workspaces/sway.py rename to .config/eww/scripts/sway.py diff --git a/.config/eww##hostname.tycho/modules/system/system.py b/.config/eww/scripts/system.py similarity index 100% rename from .config/eww##hostname.tycho/modules/system/system.py rename to .config/eww/scripts/system.py diff --git a/.config/eww##hostname.tycho/modules/timer/timer.py b/.config/eww/scripts/timer.py similarity index 100% rename from .config/eww##hostname.tycho/modules/timer/timer.py rename to .config/eww/scripts/timer.py diff --git a/.config/eww##hostname.normandy/modules/volume/volume.py b/.config/eww/scripts/volume.py similarity index 100% rename from .config/eww##hostname.normandy/modules/volume/volume.py rename to .config/eww/scripts/volume.py diff --git a/.config/eww/windows.yuck b/.config/eww/windows.yuck new file mode 100644 index 0000000..ad5e3ef --- /dev/null +++ b/.config/eww/windows.yuck @@ -0,0 +1,150 @@ +;;;; -*-lisp-*- ;;;; +;; Top-Level Module Definitions ;; +;;;; ;;;; + + +;;; ;;; +;; Bars for Rocinante ;; +;;; ;;; + +(defwidget rocinante-builtinbar--left [] + (box :orientation "h" + :halign "start" + :space-evenly false + :spacing 20 + :class "leftbox" + (sway-workspaces :group "builtin") + (sway-workspace :group "builtin"))) + +(defwidget rocinante-builtinbar--center [] + (box :orientation "h" + :halign "center" + :space-evenly false + :spacing 20 + :class "centerbox" + (system-name))) + +(defwidget rocinante-builtinbar--right [] + (box :orientation "h" + :halign "end" + :space-evenly false + :spacing 20 + :class "rightbox" + (vpn-network) + (network) + (system-battery :battery "BAT1") + (audio) + (clock))) + + +;;; ;;; +;; Bars for S.S.V. Normandy ;; +;;; ;;; + +(defwidget normandy-leftbar--left [] + (box :orientation "h" + :halign "start" + :space-evenly false + :spacing 20 + :class "leftbox" + (system-name))) + +(defwidget normandy-leftbar--right [] + (box :orientation "h" + :halign "end" + :space-evenly false + :spacing 20 + :class "rightbox" + (sway-workspace :group "left") + (sway-workspaces :group "left"))) + +(defwidget normandy-rightbar--left [] + (box :orientation "h" + :halign "start" + :space-evenly false + :spacing 20 + :class "leftbox" + (sway-workspace :group "right") + (sway-workspaces :group "right"))) + +(defwidget normandy-rightbar--right [] + (box :orientation "h" + :halign "end" + :space-evenly false + :spacing 20 + :class "rightbox" + (system-name))) + +(defwidget normandy-sidebar [] + (box :orientation "v" + :valign "start" + :space-evenly false + :spacing 20 + :class "sidebar" + (sideclock) + (network-sidebar-details) + (cpu-mem-gauges) + (gpu-gauges))) + + +;;; ;;; +;; Bars for Tycho Station ;; +;;; ;;; + +(defwidget tycho-leftbar--left [] + (box :orientation "h" + :halign "start" + :space-evenly false + :spacing 20 + :class "leftbox" + (clock) + (network) + (vpn-network) + (aggietime-shift))) + +(defwidget tycho-leftbar--center [] + (box :orientation "h" + :halign "end" + :space-evenly false + :spacing 20 + :class "centerbox" + (system-name))) + +(defwidget tycho-leftbar--right [] + (box :orientation "h" + :halign "end" + :space-evenly false + :spacing 20 + :class "rightbox" + (sway-workspace :group "left") + (sway-workspaces :group "left"))) + +(defwidget tycho-rightbar--left [] + (box :orientation "h" + :halign "start" + :space-evenly false + :spacing 20 + :class "leftbox" + (sway-workspaces :group "right") + (sway-workspace :group "right"))) + +(defwidget tycho-rightbar--center [] + (box :orientation "h" + :halign "end" + :space-evenly false + :spacing 20 + :class "centerbox" + (system-name))) + +(defwidget tycho-rightbar--right [] + (box :orientation "h" + :halign "end" + :space-evenly false + :spacing 20 + :class "rightbox" + (mpris2) + (system-memory) + (system-cpu-avg) + (clock))) + +