Add mostly final ags config
This commit is contained in:
parent
c310042564
commit
bce65f6835
23 changed files with 999 additions and 156 deletions
|
@ -13,7 +13,7 @@ include_toc: true
|
|||
|
||||
#### Programs
|
||||
|
||||
# TODO: add a file manager
|
||||
# TODO: add a file manager and desktop manager
|
||||
|
||||
| Name | Type |
|
||||
| -----------------: | :------------------ |
|
||||
|
@ -23,6 +23,7 @@ include_toc: true
|
|||
| Neovim | Text editor |
|
||||
| Firefox | Web browser |
|
||||
| qBittorrent | Torrent client |
|
||||
| mpv | Video player |
|
||||
| LibreOffice | Office suite |
|
||||
| GIMP | Photo editor |
|
||||
| Inkscape | Vector image editor |
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{ pkgs, config, inputs, ... }: {
|
||||
{ pkgs, config, ... }: {
|
||||
home = {
|
||||
username = "avery";
|
||||
homeDirectory = "/home/avery";
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
users = {
|
||||
defaultUserShell = pkgs.zsh;
|
||||
users.avery = {
|
||||
description = "Avery";
|
||||
extraGroups = [ "wheel" ];
|
||||
isNormalUser = true;
|
||||
hashedPasswordFile = config.sops.secrets.avery_password.path;
|
||||
|
|
|
@ -67,7 +67,7 @@
|
|||
typeset -g POWERLEVEL9K_EMPTY_LINE_RIGHT_PROMPT_FIRST_SEGMENT_START_SYMBOL='%{%}'
|
||||
fi
|
||||
|
||||
typeset -g POWERLEVEL9K_BACKGROUND="#181825"
|
||||
typeset -g POWERLEVEL9K_BACKGROUND="black"
|
||||
|
||||
typeset -g POWERLEVEL9K_LEFT_SUBSEGMENT_SEPARATOR=''
|
||||
typeset -g POWERLEVEL9K_RIGHT_SUBSEGMENT_SEPARATOR=''
|
||||
|
@ -93,11 +93,11 @@
|
|||
typeset -g POWERLEVEL9K_PROMPT_CHAR_LEFT_PROMPT_FIRST_SEGMENT_START_SYMBOL=
|
||||
typeset -g POWERLEVEL9K_PROMPT_CHAR_LEFT_{LEFT,RIGHT}_WHITESPACE=
|
||||
|
||||
typeset -g POWERLEVEL9K_DIR_FOREGROUND="#89dceb"
|
||||
typeset -g POWERLEVEL9K_DIR_FOREGROUND="blue"
|
||||
typeset -g POWERLEVEL9K_SHORTEN_STRATEGY=truncate_to_unique
|
||||
typeset -g POWERLEVEL9K_SHORTEN_DELIMITER=
|
||||
typeset -g POWERLEVEL9K_DIR_SHORTENED_FOREGROUND="#89dceb"
|
||||
typeset -g POWERLEVEL9K_DIR_ANCHOR_FOREGROUND="#74c7ec"
|
||||
typeset -g POWERLEVEL9K_DIR_SHORTENED_FOREGROUND="blue"
|
||||
typeset -g POWERLEVEL9K_DIR_ANCHOR_FOREGROUND="blue"
|
||||
typeset -g POWERLEVEL9K_DIR_ANCHOR_BOLD=true
|
||||
local anchor_files=(
|
||||
.bzr
|
||||
|
@ -544,7 +544,7 @@
|
|||
typeset -g POWERLEVEL9K_WIFI_FOREGROUND=68
|
||||
|
||||
|
||||
typeset -g POWERLEVEL9K_TIME_FOREGROUND="#cdd6f4"
|
||||
typeset -g POWERLEVEL9K_TIME_FOREGROUND="white"
|
||||
typeset -g POWERLEVEL9K_TIME_FORMAT='%D{%H:%M:%S}'
|
||||
typeset -g POWERLEVEL9K_TIME_UPDATE_ON_COMMAND=false
|
||||
typeset -g POWERLEVEL9K_TIME_PREFIX='%F{#bac2de}at '
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
width="108"
|
||||
height="108"
|
||||
viewBox="0 0 108 108"
|
||||
sodipodi:docname="gpu-symbolic.svg"
|
||||
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs1" />
|
||||
<sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#6f6f6f"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
showgrid="false"
|
||||
inkscape:zoom="7.3397687"
|
||||
inkscape:cx="55.110729"
|
||||
inkscape:cy="64.034716"
|
||||
inkscape:window-width="2508"
|
||||
inkscape:window-height="1432"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg1" />
|
||||
<g
|
||||
id="g2"
|
||||
transform="matrix(0.99893805,0,0,0.99893805,-8.5128578,-11.201106)">
|
||||
<circle
|
||||
style="display:inline;fill:#ffffff;stroke-width:0.58613"
|
||||
id="circle2"
|
||||
cx="83.544762"
|
||||
cy="66.08548"
|
||||
r="9.1276808" />
|
||||
<path
|
||||
id="rect21"
|
||||
style="fill:#ffffff;stroke-width:0.995843"
|
||||
d="m 30.796875,34.894531 c -6.696118,0 -12.085937,5.391773 -12.085937,12.087891 v 38.207031 c 0,6.696118 5.389819,12.085938 12.085937,12.085938 h 73.753905 c 6.69612,0 12.08594,-5.38982 12.08594,-12.085938 V 46.982422 c 0,-6.696118 -5.38982,-12.087891 -12.08594,-12.087891 z M 83.544922,50.511719 A 15.572804,15.572804 0 0 1 99.117188,66.085938 15.572804,15.572804 0 0 1 83.544922,81.658203 15.572804,15.572804 0 0 1 67.972656,66.085938 15.572804,15.572804 0 0 1 83.544922,50.511719 Z" />
|
||||
<rect
|
||||
style="fill:#ffffff;stroke-width:0.658796"
|
||||
id="rect22"
|
||||
width="42.856728"
|
||||
height="62.381294"
|
||||
x="18.710653"
|
||||
y="34.894833"
|
||||
rx="0" />
|
||||
<rect
|
||||
style="fill:#ffffff;stroke-width:0.933947"
|
||||
id="rect23"
|
||||
width="7.2571454"
|
||||
height="17.917709"
|
||||
x="18.711"
|
||||
y="90.456131"
|
||||
ry="2" />
|
||||
<rect
|
||||
style="fill:#ffffff;stroke-width:0.966324"
|
||||
id="rect24"
|
||||
width="48.787354"
|
||||
height="13.831649"
|
||||
x="51.524902"
|
||||
y="93.012451"
|
||||
ry="1.8675644" />
|
||||
<rect
|
||||
style="fill:#ffffff"
|
||||
id="rect1"
|
||||
width="8.3176746"
|
||||
height="15.143582"
|
||||
x="18.711"
|
||||
y="22.167"
|
||||
ry="2" />
|
||||
<rect
|
||||
style="fill:#ffffff;stroke-width:0.887038"
|
||||
id="rect2"
|
||||
width="15.388794"
|
||||
height="8.3993673"
|
||||
x="8.5219078"
|
||||
y="22.167"
|
||||
ry="2" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.8 KiB |
|
@ -1,10 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 576 512"
|
||||
viewBox="0 0 576 576"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
sodipodi:docname="memory-symbolic.svg"
|
||||
sodipodi:docname="ram-custom-symbolic.svg"
|
||||
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)"
|
||||
width="576"
|
||||
height="576"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
@ -13,25 +15,25 @@
|
|||
id="defs1" />
|
||||
<sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#ffffff"
|
||||
pagecolor="#000000"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="0.18793403"
|
||||
inkscape:cx="-106.42032"
|
||||
inkscape:cy="1069.5242"
|
||||
inkscape:window-width="1254"
|
||||
inkscape:window-height="714"
|
||||
inkscape:zoom="1.5034722"
|
||||
inkscape:cx="192.55427"
|
||||
inkscape:cy="351.85219"
|
||||
inkscape:window-width="2508"
|
||||
inkscape:window-height="1432"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg1" />
|
||||
<!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.-->
|
||||
<path
|
||||
d="M64 64C28.7 64 0 92.7 0 128l0 7.4c0 6.8 4.4 12.6 10.1 16.3C23.3 160.3 32 175.1 32 192s-8.7 31.7-21.9 40.3C4.4 236 0 241.8 0 248.6L0 320l576 0 0-71.4c0-6.8-4.4-12.6-10.1-16.3C552.7 223.7 544 208.9 544 192s8.7-31.7 21.9-40.3c5.7-3.7 10.1-9.5 10.1-16.3l0-7.4c0-35.3-28.7-64-64-64L64 64zM576 352L0 352l0 64c0 17.7 14.3 32 32 32l48 0 0-32c0-8.8 7.2-16 16-16s16 7.2 16 16l0 32 96 0 0-32c0-8.8 7.2-16 16-16s16 7.2 16 16l0 32 96 0 0-32c0-8.8 7.2-16 16-16s16 7.2 16 16l0 32 96 0 0-32c0-8.8 7.2-16 16-16s16 7.2 16 16l0 32 48 0c17.7 0 32-14.3 32-32l0-64zM192 160l0 64c0 17.7-14.3 32-32 32s-32-14.3-32-32l0-64c0-17.7 14.3-32 32-32s32 14.3 32 32zm128 0l0 64c0 17.7-14.3 32-32 32s-32-14.3-32-32l0-64c0-17.7 14.3-32 32-32s32 14.3 32 32zm128 0l0 64c0 17.7-14.3 32-32 32s-32-14.3-32-32l0-64c0-17.7 14.3-32 32-32s32 14.3 32 32z"
|
||||
d="M 64,96 C 28.7,96 0,124.7 0,160 v 7.4 c 0,6.8 4.4,12.6 10.1,16.3 13.2,8.6 21.9,23.4 21.9,40.3 0,16.9 -8.7,31.7 -21.9,40.3 C 4.4,268 0,273.8 0,280.6 V 352 H 576 V 280.6 C 576,273.8 571.6,268 565.9,264.3 552.7,255.7 544,240.9 544,224 c 0,-16.9 8.7,-31.7 21.9,-40.3 5.7,-3.7 10.1,-9.5 10.1,-16.3 V 160 C 576,124.7 547.3,96 512,96 Z M 576,384 H 0 v 64 c 0,17.7 14.3,32 32,32 h 48 v -32 c 0,-8.8 7.2,-16 16,-16 8.8,0 16,7.2 16,16 v 32 h 96 v -32 c 0,-8.8 7.2,-16 16,-16 8.8,0 16,7.2 16,16 v 32 h 96 v -32 c 0,-8.8 7.2,-16 16,-16 8.8,0 16,7.2 16,16 v 32 h 96 v -32 c 0,-8.8 7.2,-16 16,-16 8.8,0 16,7.2 16,16 v 32 h 48 c 17.7,0 32,-14.3 32,-32 z M 192,192 v 64 c 0,17.7 -14.3,32 -32,32 -17.7,0 -32,-14.3 -32,-32 v -64 c 0,-17.7 14.3,-32 32,-32 17.7,0 32,14.3 32,32 z m 128,0 v 64 c 0,17.7 -14.3,32 -32,32 -17.7,0 -32,-14.3 -32,-32 v -64 c 0,-17.7 14.3,-32 32,-32 17.7,0 32,14.3 32,32 z m 128,0 v 64 c 0,17.7 -14.3,32 -32,32 -17.7,0 -32,-14.3 -32,-32 v -64 c 0,-17.7 14.3,-32 32,-32 17.7,0 32,14.3 32,32 z"
|
||||
id="path1"
|
||||
style="fill:#ffffff" />
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 2.2 KiB |
|
@ -1,13 +1,17 @@
|
|||
import cpu from "./services/cpu.js";
|
||||
import ram from "./services/ram.js";
|
||||
import { ProfilePicture } from "./widgets/bar/profile-picture.js";
|
||||
import {
|
||||
ProcessorUsage,
|
||||
MemoryUsage,
|
||||
graphics_card_usage,
|
||||
volume_widget,
|
||||
} from "./widgets/bar/system-stats.js";
|
||||
import { extended_bar } from "./widgets/bar-extended/extended-bar.js";
|
||||
import { launcher } from "./widgets/launcher/launcher.js";
|
||||
const { speaker } = await Service.import("audio");
|
||||
import { popup_clock } from "./widgets/popup-clock/popup-clock.js";
|
||||
import { date } from "./state.js";
|
||||
const mpris = await Service.import("mpris");
|
||||
const sway = await Service.import("sway");
|
||||
const players = mpris.bind("players");
|
||||
const date = Variable("", {
|
||||
poll: [1000, 'date "+%H %M %S %b %e"'],
|
||||
});
|
||||
|
||||
App.addIcons(`${App.configDir}/assets`);
|
||||
|
||||
|
@ -43,67 +47,6 @@ function Workspaces() {
|
|||
});
|
||||
}
|
||||
|
||||
function ProcessorUsage() {
|
||||
return Widget.Box({
|
||||
class_name: "system-stats",
|
||||
css: cpu.bind("current-usage").as((usage) => {
|
||||
let level = (usage * 100).toFixed(0);
|
||||
return `
|
||||
background: linear-gradient(
|
||||
90deg, rgba(26, 27, 38, 0.6) ${level}%, rgba(26, 27, 38, 0.4) ${level}%
|
||||
)`;
|
||||
}),
|
||||
children: [
|
||||
Widget.Icon({
|
||||
class_names: ["system-stats-icon"],
|
||||
icon: "microchip-symbolic",
|
||||
size: 16,
|
||||
}),
|
||||
Widget.Label({
|
||||
class_names: ["system-stats-text"],
|
||||
hexpand: true,
|
||||
label: cpu.bind("current-usage").as((usage) => {
|
||||
return `${(usage * 100).toFixed(0)}%`;
|
||||
}),
|
||||
}),
|
||||
],
|
||||
vertical: true,
|
||||
});
|
||||
}
|
||||
|
||||
function MemoryUsage() {
|
||||
return Widget.Box({
|
||||
class_name: "system-stats",
|
||||
css: ram.bind("current-usage-percentage").as((usage) => {
|
||||
let level = (usage * 100).toFixed(0);
|
||||
return `
|
||||
background: linear-gradient(
|
||||
90deg, rgba(26, 27, 38, 0.6) ${level}%, rgba(26, 27, 38, 0.4) ${level}%
|
||||
)`;
|
||||
}),
|
||||
children: [
|
||||
Widget.Icon({
|
||||
class_names: ["system-stats-icon"],
|
||||
icon: "ram-custom-symbolic",
|
||||
size: 16,
|
||||
}),
|
||||
Widget.Label({
|
||||
class_names: ["system-stats-text"],
|
||||
hexpand: true,
|
||||
label: ram.bind("current-usage-percentage").as((usage) => {
|
||||
return `${(usage * 100).toFixed(0)}%`;
|
||||
}),
|
||||
}),
|
||||
],
|
||||
tooltip_text: ram.bind("current-usage").as((usage) => {
|
||||
let usageGb = (usage / 1024 ** 2).toFixed(2);
|
||||
let totalGb = (ram.total_available / 1024 ** 2).toFixed(2);
|
||||
return `${usageGb}/${totalGb}GB (${(ram.current_usage_percentage * 100).toFixed(2)}%)`;
|
||||
}),
|
||||
vertical: true,
|
||||
});
|
||||
}
|
||||
|
||||
function CurrentSong(player) {
|
||||
return Widget.Box({
|
||||
class_name: "music-indicator",
|
||||
|
@ -155,57 +98,6 @@ function CTest() {
|
|||
});
|
||||
}
|
||||
|
||||
function ProfilePicture() {
|
||||
return Widget.Box({
|
||||
class_name: "profile-picture",
|
||||
css: "background-image: url('/home/avery/.face.icon'); background-size: cover",
|
||||
});
|
||||
}
|
||||
|
||||
function VolumeWidget() {
|
||||
return Widget.Box({
|
||||
class_name: "volume-widget",
|
||||
children: [
|
||||
Widget.Icon({
|
||||
icon: speaker.bind("volume").as((l) => {
|
||||
let level = l.toFixed(2) * 100;
|
||||
if (level == 0) {
|
||||
return "audio-volume-muted";
|
||||
} else if (level > 0 && level <= 30) {
|
||||
return "audio-volume-low";
|
||||
} else if (level > 30 && level <= 70) {
|
||||
return "audio-volume-medium";
|
||||
} else {
|
||||
return "audio-volume-high";
|
||||
}
|
||||
}),
|
||||
size: 10,
|
||||
}),
|
||||
Widget.Box({
|
||||
class_name: "volume-box",
|
||||
css: speaker.bind("volume").as((l) => {
|
||||
let level = l.toFixed(2) * 100;
|
||||
if (level >= 0 && level <= 100) {
|
||||
return `
|
||||
background: linear-gradient(
|
||||
90deg, #7aa2f7 ${level}%, #24283b ${level}%
|
||||
);
|
||||
`;
|
||||
} else if (level > 100 && level <= 200) {
|
||||
return `
|
||||
background: linear-gradient(
|
||||
90deg, #f7768e ${level - 100}%, #7aa2f7 ${level - 100}%
|
||||
);
|
||||
`;
|
||||
} else {
|
||||
return "background: #f7768e";
|
||||
}
|
||||
}),
|
||||
hpack: "fill",
|
||||
}),
|
||||
],
|
||||
});
|
||||
}
|
||||
function ClockWidget() {
|
||||
return Widget.Box({
|
||||
children: [
|
||||
|
@ -239,11 +131,14 @@ const barContainer = Widget.Box({
|
|||
spacing: 6,
|
||||
vertical: true,
|
||||
children: [
|
||||
ProfilePicture(),
|
||||
Workspaces(),
|
||||
Widget.Box({ expand: true, vpack: "fill" }), // Separator
|
||||
CTest(),
|
||||
ProcessorUsage(),
|
||||
MemoryUsage(),
|
||||
graphics_card_usage,
|
||||
volume_widget,
|
||||
ClockWidget(),
|
||||
],
|
||||
});
|
||||
|
@ -252,6 +147,7 @@ const bar = Widget.Window({
|
|||
name: "bar",
|
||||
anchor: ["left", "top", "bottom"],
|
||||
exclusivity: "exclusive",
|
||||
margins: [4, 0, 4, 4],
|
||||
child: barContainer,
|
||||
});
|
||||
|
||||
|
@ -266,5 +162,5 @@ Utils.monitorFile(
|
|||
|
||||
App.config({
|
||||
style: "./style.css",
|
||||
windows: [bar, launcher],
|
||||
windows: [bar, extended_bar, launcher, popup_clock],
|
||||
});
|
||||
|
|
|
@ -1,16 +1,25 @@
|
|||
class CPUService extends Service {
|
||||
static {
|
||||
Service.register(this, {}, { "current-usage": ["float", "r"] });
|
||||
Service.register(
|
||||
this,
|
||||
{},
|
||||
{ "current-usage": ["float", "r"], temperature: ["float", "r"] },
|
||||
);
|
||||
}
|
||||
|
||||
#previousIdle = 0.0;
|
||||
#previousTotal = 0.0;
|
||||
#currentUsage = 0.0;
|
||||
#temperature = 0.0;
|
||||
|
||||
get current_usage() {
|
||||
return this.#currentUsage;
|
||||
}
|
||||
|
||||
get temperature() {
|
||||
return this.#temperature;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.#update();
|
||||
|
@ -20,6 +29,10 @@ class CPUService extends Service {
|
|||
}
|
||||
|
||||
#update() {
|
||||
this.#temperature =
|
||||
Utils.exec(
|
||||
"sh -c 'cat /sys/devices/pci0000:00/0000:00:18.3/hwmon/hwmon1/temp1_input'",
|
||||
) / 1000;
|
||||
const currentValues = Utils.exec(
|
||||
"sh -c 'cat /proc/stat | grep cpu | head -n 1 | tr -s \" \"'",
|
||||
)
|
||||
|
@ -33,6 +46,7 @@ class CPUService extends Service {
|
|||
this.#previousIdle = idle;
|
||||
this.#previousTotal = total;
|
||||
this.changed("current-usage");
|
||||
this.changed("temperature");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
class GPUService extends Service {
|
||||
static {
|
||||
Service.register(
|
||||
this,
|
||||
{},
|
||||
{ "current-usage": ["float", "r"], temperature: ["float", "r"] },
|
||||
);
|
||||
}
|
||||
|
||||
#currentUsage = 0;
|
||||
#temperature = 0;
|
||||
|
||||
get current_usage() {
|
||||
return this.#currentUsage;
|
||||
}
|
||||
|
||||
get temperature() {
|
||||
return this.#temperature;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.#update();
|
||||
const interval = setInterval(() => {
|
||||
this.#update();
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
#update() {
|
||||
this.#currentUsage = Utils.exec(
|
||||
"sh -c 'cat /sys/class/drm/card?/device/gpu_busy_percent'",
|
||||
);
|
||||
this.#temperature =
|
||||
Utils.exec(
|
||||
"sh -c 'cat /sys/class/drm/card?/device/hwmon/hwmon?/temp1_input'",
|
||||
) / 1000;
|
||||
this.changed("current-usage");
|
||||
this.changed("temperature");
|
||||
}
|
||||
}
|
||||
|
||||
const gpu = new GPUService();
|
||||
export default gpu;
|
55
hosts/totsugeki/home-manager/desktop/ags/config/state.js
Normal file
55
hosts/totsugeki/home-manager/desktop/ags/config/state.js
Normal file
|
@ -0,0 +1,55 @@
|
|||
export const date = Variable("", {
|
||||
poll: [1000, 'date "+%H %M %S %Y-%m-%d"'],
|
||||
});
|
||||
|
||||
class User {
|
||||
constructor(user_string) {
|
||||
var split_string = user_string.split(":");
|
||||
this.username = split_string[0];
|
||||
this.uid = split_string[2];
|
||||
this.gid = split_string[3];
|
||||
this.real_name = split_string[4];
|
||||
if (this.real_name == "") {
|
||||
this.real_name = this.username;
|
||||
}
|
||||
this.home_directory = split_string[5];
|
||||
}
|
||||
}
|
||||
|
||||
var is_bar_extended = false;
|
||||
var current_menu = "bar";
|
||||
|
||||
// TODO(maybe): watch for changes to real name
|
||||
var uid = Utils.exec("sh -c 'echo $UID'");
|
||||
export const CURRENT_USER = new User(
|
||||
Utils.exec(`grep -P '\\w+:x:${uid}' /etc/passwd`),
|
||||
);
|
||||
export const HOSTNAME = Utils.exec("hostname");
|
||||
|
||||
export function on_window_event(_, window_name, visible) {
|
||||
console.log(`is ${window_name} visible => ${visible}`);
|
||||
console.log(`current menu is ${current_menu}`);
|
||||
console.log(`is bar extended => ${is_bar_extended}`);
|
||||
if (window_name != "bar" && visible) {
|
||||
var previous_menu = current_menu;
|
||||
current_menu = window_name;
|
||||
if (previous_menu != "bar") {
|
||||
App.getWindow(previous_menu).visible = false;
|
||||
}
|
||||
App.getWindow("bar").css = "opacity: 0";
|
||||
if (window_name == "bar_extended") {
|
||||
is_bar_extended = true;
|
||||
}
|
||||
} else if (window_name != "bar" && !visible) {
|
||||
if (
|
||||
(window_name == "bar_extended" && current_menu == "bar_extended") ||
|
||||
!is_bar_extended
|
||||
) {
|
||||
is_bar_extended = false;
|
||||
current_menu = "bar";
|
||||
App.getWindow("bar").css = "opacity: 1";
|
||||
} else if (window_name != "bar_extended" && is_bar_extended) {
|
||||
App.getWindow("bar_extended").visible = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,11 +11,15 @@ window {
|
|||
.bar {
|
||||
background-color: @bg;
|
||||
border-radius: 8px;
|
||||
margin: 4px 0px 4px 4px;
|
||||
padding: 4px 4px;
|
||||
min-width: 32px;
|
||||
}
|
||||
|
||||
.extended_bar,
|
||||
.launcher {
|
||||
min-width: 360px;
|
||||
}
|
||||
|
||||
.volume-widget {
|
||||
margin: 4px;
|
||||
}
|
||||
|
@ -30,7 +34,7 @@ window {
|
|||
border-radius: 8px;
|
||||
background-color: @bg;
|
||||
font-weight: bold;
|
||||
font-family: "Iosevka Nerd Font";
|
||||
font-family: monospace;
|
||||
font-size: 1.2em;
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
@ -67,8 +71,8 @@ window {
|
|||
background-color: @bg;
|
||||
border-radius: 8px;
|
||||
color: white;
|
||||
font-family: "Iosevka Nerd Font";
|
||||
font-weight: bold;
|
||||
font-family: monospace;
|
||||
font-weight: 700;
|
||||
font-size: 0.95em;
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
@ -77,7 +81,7 @@ window {
|
|||
background-color: @bg;
|
||||
border-radius: 8px;
|
||||
color: #c0caf5;
|
||||
font-family: "Iosevka Nerd Font";
|
||||
font-family: monospace;
|
||||
font-weight: bold;
|
||||
font-size: 1em;
|
||||
min-height: 20px;
|
||||
|
@ -89,13 +93,11 @@ window {
|
|||
}
|
||||
|
||||
.occupied {
|
||||
border-radius: 8px;
|
||||
min-width: 24px;
|
||||
}
|
||||
|
||||
.active {
|
||||
color: @bg-noa;
|
||||
border-radius: 8px;
|
||||
min-width: 32px;
|
||||
}
|
||||
|
||||
|
@ -158,7 +160,6 @@ window {
|
|||
|
||||
.launcher-search:focus {
|
||||
border: 2px solid white;
|
||||
|
||||
outline: none;
|
||||
}
|
||||
|
||||
|
@ -180,6 +181,117 @@ window {
|
|||
}
|
||||
|
||||
.application_name {
|
||||
font-size: 1.4em;
|
||||
font-size: 1.2em;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extended bar
|
||||
*/
|
||||
|
||||
.profile_block {
|
||||
background-color: @bg;
|
||||
background-blend-mode: darken;
|
||||
border-radius: 8px;
|
||||
color: white;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.username {
|
||||
font-weight: 600;
|
||||
font-size: 1.4em;
|
||||
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
|
||||
.hostname {
|
||||
font-weight: 600;
|
||||
font-size: 1.1em;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.workspace-button-big {
|
||||
color: white;
|
||||
font-family: "sans-serif";
|
||||
font-weight: 400;
|
||||
padding: 4px 8px;
|
||||
}
|
||||
|
||||
.active {
|
||||
color: @bg-noa;
|
||||
}
|
||||
|
||||
.workspace-name {
|
||||
font-weight: 500;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
.clock-big {
|
||||
font-size: 1.4em;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.system-stats-big {
|
||||
padding: 4px 8px;
|
||||
}
|
||||
|
||||
.system-stats-title {
|
||||
font-family: sans-serif;
|
||||
font-size: 1.2em;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.currently-playing-big {
|
||||
background-color: @bg;
|
||||
border-radius: 8px;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.album-art-big {
|
||||
border-radius: 8px;
|
||||
min-width: 72px;
|
||||
min-height: 72px;
|
||||
}
|
||||
|
||||
.currently-playing-title {
|
||||
color: white;
|
||||
font-size: 1.2em;
|
||||
font-weight: 700;
|
||||
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.currently-playing-artists {
|
||||
color: white;
|
||||
font-weight: 600;
|
||||
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
calendar {
|
||||
background-color: @bg;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
color: rgb(220, 220, 220);
|
||||
font-family: sans-serif;
|
||||
font-weight: 500;
|
||||
padding: 1px;
|
||||
}
|
||||
|
||||
calendar .header,
|
||||
calendar .highlight {
|
||||
background-color: @normal;
|
||||
color: white;
|
||||
}
|
||||
|
||||
calendar .button {
|
||||
background-color: transparent;
|
||||
color: white;
|
||||
}
|
||||
|
||||
calendar:selected {
|
||||
background-color: rgba(255, 255, 255, 0.8);
|
||||
color: black;
|
||||
}
|
||||
|
||||
calendar:indeterminate {
|
||||
color: rgb(90, 90, 90);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
import { date } from "../../state.js";
|
||||
|
||||
function BlinkingDots() {
|
||||
return Widget.Label({
|
||||
class_name: "blinking-dots",
|
||||
label: ":",
|
||||
});
|
||||
}
|
||||
|
||||
export function Clock() {
|
||||
return Widget.Box({
|
||||
children: [
|
||||
Widget.Box({ hexpand: true, hpack: "fill" }), // Separator
|
||||
Widget.Box({
|
||||
children: [
|
||||
Widget.Label({
|
||||
label: date.bind().as((d) => {
|
||||
return d.split(" ")[0];
|
||||
}),
|
||||
}),
|
||||
BlinkingDots(),
|
||||
Widget.Label({
|
||||
label: date.bind().as((d) => {
|
||||
return d.split(" ")[1];
|
||||
}),
|
||||
}),
|
||||
BlinkingDots(),
|
||||
Widget.Label({
|
||||
label: date.bind().as((d) => {
|
||||
return d.split(" ")[2];
|
||||
}),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
Widget.Box({ hexpand: true, hpack: "fill" }), // Separator
|
||||
],
|
||||
class_names: ["clock", "clock-big"],
|
||||
hpack: "fill",
|
||||
spacing: 8,
|
||||
});
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
const mpris = await Service.import("mpris");
|
||||
const players = mpris.bind("players");
|
||||
|
||||
// TODO: rework
|
||||
export const currently_playing_controller = Widget.Box({
|
||||
vertical: true,
|
||||
visible: players.as((p) => p.length > 0),
|
||||
children: players.as((p) => p.map(CurrentlyPlaying)),
|
||||
});
|
||||
|
||||
function CurrentlyPlaying(player) {
|
||||
return Widget.Box({
|
||||
class_name: "currently-playing-big",
|
||||
css: player.bind("cover_path").as((url) => {
|
||||
if (url == undefined) {
|
||||
return "";
|
||||
}
|
||||
console.log(url);
|
||||
return `
|
||||
background-image: url('${url}');
|
||||
background-blend-mode: darken;
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
`;
|
||||
}),
|
||||
spacing: 4,
|
||||
children: [
|
||||
Widget.Box({
|
||||
class_name: "album-art-big",
|
||||
css: player.bind("cover_path").as((url) => {
|
||||
if (url == undefined) {
|
||||
return `
|
||||
background-color: rgba(0, 0, 0, 0.2);
|
||||
background-image: url('${App.configDir}/assets/music-symbolic.svg');
|
||||
background-size: 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
`;
|
||||
}
|
||||
return `background-image: url('${url}'); background-size: cover;`;
|
||||
}),
|
||||
}),
|
||||
Widget.Box({
|
||||
children: [
|
||||
Widget.Label({
|
||||
class_name: "currently-playing-title",
|
||||
label: player.bind("track-title"),
|
||||
xalign: 0.5,
|
||||
hexpand: true,
|
||||
truncate: "end",
|
||||
}),
|
||||
Widget.Label({
|
||||
class_name: "currently-playing-artists",
|
||||
label: player.bind("track-artists").as((artists) => {
|
||||
return artists.join(", ");
|
||||
}),
|
||||
xalign: 0.5,
|
||||
hexpand: true,
|
||||
truncate: "end",
|
||||
}),
|
||||
],
|
||||
vpack: "center",
|
||||
vertical: true,
|
||||
}),
|
||||
// Widget.Icon({
|
||||
// class_name: "playback-status",
|
||||
// icon: player.bind("play-back-status").as((status) => {
|
||||
// if (status == "Playing") {
|
||||
// return "media-playback-start";
|
||||
// } else if (status == "Paused") {
|
||||
// return "media-playback-pause";
|
||||
// }
|
||||
// return "";
|
||||
// }),
|
||||
// }),
|
||||
],
|
||||
});
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
import { Clock } from "./big-clock.js";
|
||||
import { currently_playing_controller } from "./currently-playing.js";
|
||||
import { ProfileBlock } from "./profile-block.js";
|
||||
import {
|
||||
graphics_card_usage,
|
||||
memory_usage,
|
||||
processor_usage,
|
||||
volume_widget,
|
||||
} from "./system-stats-big.js";
|
||||
import { workspaces } from "./workspaces.js";
|
||||
import { on_window_event } from "../../state.js";
|
||||
|
||||
export const extended_bar = Widget.Window({
|
||||
name: "bar_extended",
|
||||
anchor: ["left", "top", "bottom"],
|
||||
margins: [4, 0, 4, 4],
|
||||
child: Widget.Box({
|
||||
class_names: ["bar", "extended_bar"],
|
||||
vpack: "fill",
|
||||
spacing: 6,
|
||||
vertical: true,
|
||||
children: [
|
||||
ProfileBlock(),
|
||||
workspaces,
|
||||
Widget.Box({ expand: true, vpack: "fill" }), // Separator
|
||||
currently_playing_controller,
|
||||
processor_usage,
|
||||
memory_usage,
|
||||
graphics_card_usage,
|
||||
volume_widget,
|
||||
Widget.Calendar({}),
|
||||
Clock(),
|
||||
],
|
||||
}),
|
||||
exclusivity: "ignore",
|
||||
visible: false,
|
||||
layer: "overlay",
|
||||
setup: (self) => {
|
||||
self.hook(App, (_, window_name, visible) => {
|
||||
if (window_name == self.name) {
|
||||
on_window_event(_, window_name, visible);
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
|
@ -0,0 +1,54 @@
|
|||
import { ProfilePicture } from "../bar/profile-picture.js";
|
||||
import { CURRENT_USER, HOSTNAME } from "../../state.js";
|
||||
|
||||
const CURRENT_WALLPAPER_PATH =
|
||||
"/home/avery/.local/share/wallpapers/.current_path";
|
||||
|
||||
const wallpaperPath = Variable(Utils.readFile(CURRENT_WALLPAPER_PATH));
|
||||
|
||||
const wallpaperMonitor = Utils.monitorFile(
|
||||
CURRENT_WALLPAPER_PATH,
|
||||
(file, event) => {
|
||||
if (event === 1) {
|
||||
wallpaperPath.value = Utils.readFile(file);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
export function ProfileBlock() {
|
||||
return Widget.Box({
|
||||
class_name: "profile_block",
|
||||
css: wallpaperPath.bind().as((path) => {
|
||||
path =
|
||||
path
|
||||
.replace("\n", "")
|
||||
.replace("/", "\\/")
|
||||
.replace("wallpapers", "wallpaper_thumbnails") + ".jpg";
|
||||
return `
|
||||
background-image: url('${path}');
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
`;
|
||||
}),
|
||||
spacing: 8,
|
||||
children: [
|
||||
ProfilePicture(40),
|
||||
Widget.Box({
|
||||
vertical: true,
|
||||
vpack: "center",
|
||||
children: [
|
||||
Widget.Label({
|
||||
class_name: "username",
|
||||
label: CURRENT_USER.real_name,
|
||||
xalign: 0,
|
||||
}),
|
||||
Widget.Label({
|
||||
class_name: "hostname",
|
||||
label: HOSTNAME,
|
||||
xalign: 0,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
});
|
||||
}
|
|
@ -0,0 +1,155 @@
|
|||
import cpu from "../../services/cpu.js";
|
||||
import ram from "../../services/ram.js";
|
||||
import gpu from "../../services/gpu.js";
|
||||
const { speaker } = await Service.import("audio");
|
||||
|
||||
const PROCESSOR_NAME = Utils.exec(
|
||||
'bash -c \'cat /proc/cpuinfo | grep "model name" | head -n 1 | cut -d ":" -f 2 | cut -d " " -f 3,4,5\'',
|
||||
);
|
||||
const GRAPHICS_CARD_NAME = "Radeon RX 6700 XT";
|
||||
|
||||
export const processor_usage = Widget.Box({
|
||||
class_names: ["system-stats", "system-stats-big"],
|
||||
css: cpu.bind("current-usage").as((usage) => {
|
||||
let level = (usage * 100).toFixed(0);
|
||||
return `
|
||||
background: linear-gradient(
|
||||
90deg, rgba(26, 27, 38, 0.8) ${level}%, rgba(26, 27, 38, 0.4) ${level}%
|
||||
)`;
|
||||
}),
|
||||
spacing: 6,
|
||||
children: [
|
||||
Widget.Icon({
|
||||
class_names: ["system-stats-icon"],
|
||||
icon: "microchip-symbolic",
|
||||
size: 16,
|
||||
}),
|
||||
Widget.Label({
|
||||
class_name: "system-stats-title",
|
||||
label: PROCESSOR_NAME,
|
||||
}),
|
||||
Widget.Label({
|
||||
class_name: "system-stats-text-big",
|
||||
hexpand: true,
|
||||
xalign: 1,
|
||||
label: cpu.bind("current-usage").as((usage) => {
|
||||
return `${(usage * 100).toFixed(0)}% (${cpu.temperature.toFixed(0)}ºC)`;
|
||||
}),
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
export const memory_usage = Widget.Box({
|
||||
class_names: ["system-stats", "system-stats-big"],
|
||||
css: ram.bind("current-usage-percentage").as((usage) => {
|
||||
let level = (usage * 100).toFixed(0);
|
||||
return `
|
||||
background: linear-gradient(
|
||||
90deg, rgba(26, 27, 38, 0.8) ${level}%, rgba(26, 27, 38, 0.4) ${level}%
|
||||
)`;
|
||||
}),
|
||||
spacing: 6,
|
||||
children: [
|
||||
Widget.Icon({
|
||||
class_names: ["system-stats-icon"],
|
||||
icon: "ram-custom-symbolic",
|
||||
size: 16,
|
||||
}),
|
||||
Widget.Label({
|
||||
class_name: "system-stats-title",
|
||||
label: "Memoria",
|
||||
}),
|
||||
Widget.Label({
|
||||
class_name: "system-stats-text-big",
|
||||
hexpand: true,
|
||||
xalign: 1,
|
||||
label: ram.bind("current-usage").as((usage) => {
|
||||
let usageGb = (usage / 1024 ** 2).toFixed(2);
|
||||
let totalGb = (ram.total_available / 1024 ** 2).toFixed(2);
|
||||
return `${usageGb}/${totalGb}GiB (${(ram.current_usage_percentage * 100).toFixed(2)}%)`;
|
||||
}),
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
export const graphics_card_usage = Widget.Box({
|
||||
class_names: ["system-stats", "system-stats-big"],
|
||||
css: gpu.bind("current-usage").as((usage) => {
|
||||
var level = Number(usage).toFixed(0);
|
||||
return `
|
||||
background: linear-gradient(
|
||||
90deg, rgba(26, 27, 38, 0.8) ${level}%, rgba(26, 27, 38, 0.4) ${level}%
|
||||
)`;
|
||||
}),
|
||||
spacing: 6,
|
||||
children: [
|
||||
Widget.Icon({
|
||||
class_names: ["system-stats-icon"],
|
||||
icon: "gpu-symbolic",
|
||||
size: 16,
|
||||
}),
|
||||
Widget.Label({
|
||||
class_name: "system-stats-title",
|
||||
label: GRAPHICS_CARD_NAME,
|
||||
}),
|
||||
Widget.Label({
|
||||
class_name: "system-stats-text-big",
|
||||
hexpand: true,
|
||||
xalign: 1,
|
||||
label: gpu.bind("current-usage").as((usage) => {
|
||||
return `${Number(usage).toFixed(0)}% (${gpu.temperature.toFixed(0)}ºC)`;
|
||||
}),
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
export const volume_widget = Widget.Box({
|
||||
class_names: ["system-stats", "system-stats-big"],
|
||||
css: speaker.bind("volume").as((l) => {
|
||||
let level = l.toFixed(2) * 100;
|
||||
if (level >= 0 && level <= 100) {
|
||||
return `
|
||||
background: linear-gradient(
|
||||
90deg, rgba(26, 27, 38, 0.8) ${level}%, rgba(26, 27, 38, 0.4) ${level}%
|
||||
);`;
|
||||
} else if (level > 100 && level <= 200) {
|
||||
return `
|
||||
background: linear-gradient(
|
||||
90deg, rgba(226, 27, 38, 0.4) ${level - 100}%, rgba(26, 27, 38, 0.8) ${level - 100}%
|
||||
);`;
|
||||
} else {
|
||||
return "background: rgba(226, 27, 38, 0.4)";
|
||||
}
|
||||
}),
|
||||
spacing: 6,
|
||||
children: [
|
||||
Widget.Icon({
|
||||
class_names: ["system-stats-icon"],
|
||||
icon: speaker.bind("volume").as((l) => {
|
||||
let level = l.toFixed(2) * 100;
|
||||
if (level == 0) {
|
||||
return "audio-volume-muted";
|
||||
} else if (level > 0 && level <= 30) {
|
||||
return "audio-volume-low";
|
||||
} else if (level > 30 && level <= 70) {
|
||||
return "audio-volume-medium";
|
||||
} else {
|
||||
return "audio-volume-high";
|
||||
}
|
||||
}),
|
||||
size: 16,
|
||||
}),
|
||||
Widget.Label({
|
||||
class_name: "system-stats-title",
|
||||
label: "Volumen",
|
||||
}),
|
||||
Widget.Label({
|
||||
class_name: "system-stats-text-big",
|
||||
hexpand: true,
|
||||
xalign: 1,
|
||||
label: speaker.bind("volume").as((l) => {
|
||||
return `${(l * 100).toFixed(0)}%`;
|
||||
}),
|
||||
}),
|
||||
],
|
||||
});
|
|
@ -0,0 +1,81 @@
|
|||
const sway = await Service.import("sway");
|
||||
|
||||
function getWorkspaceWindows(node) {
|
||||
var nodes = [];
|
||||
node.nodes.concat(node.floating_nodes).forEach((child_node) => {
|
||||
if (
|
||||
child_node.app_id != undefined ||
|
||||
child_node.window_properties != undefined
|
||||
) {
|
||||
nodes.push(child_node);
|
||||
} else {
|
||||
nodes = nodes.concat(getWorkspaceWindows(child_node));
|
||||
}
|
||||
});
|
||||
return nodes;
|
||||
}
|
||||
|
||||
export const workspaces = Widget.Box({
|
||||
children: Array.from({ length: 10 }, (_, i) => {
|
||||
i += 1;
|
||||
return Widget.Box({
|
||||
class_names: ["workspace-button", "workspace-button-big"],
|
||||
spacing: 16,
|
||||
children: [
|
||||
Widget.Label({
|
||||
class_name: "workspace-name",
|
||||
label: `Escritorio ${i.toString()}`,
|
||||
}),
|
||||
Widget.Box({
|
||||
children: [
|
||||
Widget.Label({
|
||||
label: "dummy",
|
||||
hexpand: true,
|
||||
xalign: 1,
|
||||
truncate: "end",
|
||||
setup: (label) => {
|
||||
label.hook(sway, (label) => {
|
||||
const ws = sway.getWorkspace(`${i}`);
|
||||
if (ws === undefined) {
|
||||
label.visible = false;
|
||||
return;
|
||||
}
|
||||
var nodes = getWorkspaceWindows(ws);
|
||||
if (nodes.length == 1) {
|
||||
label.label = nodes[0].name;
|
||||
label.visible = true;
|
||||
} else if (nodes.length > 0) {
|
||||
label.label = `${nodes.length} ventanas abiertas`;
|
||||
label.visible = true;
|
||||
} else {
|
||||
label.label = "No hay ventanas abiertas";
|
||||
label.visible = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
setup: (btn) => {
|
||||
btn.hook(
|
||||
sway,
|
||||
(btn) => {
|
||||
const ws = sway.getWorkspace(`${i}`);
|
||||
btn.toggleClassName(
|
||||
"occupied",
|
||||
ws?.nodes.length + ws?.floating_nodes.length > 0,
|
||||
);
|
||||
},
|
||||
"notify::workspaces",
|
||||
);
|
||||
|
||||
btn.hook(sway.active.workspace, (btn) => {
|
||||
btn.toggleClassName("active", sway.active.workspace.name == i);
|
||||
});
|
||||
},
|
||||
});
|
||||
}),
|
||||
spacing: 4,
|
||||
vertical: true,
|
||||
});
|
|
@ -0,0 +1,12 @@
|
|||
// TODO: user-agnostic, reload if changed
|
||||
export function ProfilePicture(size = 32) {
|
||||
return Widget.Box({
|
||||
class_name: "profile-picture",
|
||||
css: `
|
||||
background-image: url('/home/avery/.face.icon');
|
||||
background-size: cover;
|
||||
min-width: ${size}px;
|
||||
min-height: ${size}px;
|
||||
`,
|
||||
});
|
||||
}
|
|
@ -0,0 +1,141 @@
|
|||
import cpu from "../../services/cpu.js";
|
||||
import gpu from "../../services/gpu.js";
|
||||
import ram from "../../services/ram.js";
|
||||
const { speaker } = await Service.import("audio");
|
||||
|
||||
export function ProcessorUsage() {
|
||||
return Widget.Box({
|
||||
class_name: "system-stats",
|
||||
css: cpu.bind("current-usage").as((usage) => {
|
||||
let level = (usage * 100).toFixed(0);
|
||||
return `
|
||||
background: linear-gradient(
|
||||
90deg, rgba(26, 27, 38, 0.8) ${level}%, rgba(26, 27, 38, 0.4) ${level}%
|
||||
)`;
|
||||
}),
|
||||
spacing: 2,
|
||||
children: [
|
||||
Widget.Icon({
|
||||
class_names: ["system-stats-icon"],
|
||||
icon: "microchip-symbolic",
|
||||
size: 16,
|
||||
}),
|
||||
Widget.Label({
|
||||
class_names: ["system-stats-text"],
|
||||
hexpand: true,
|
||||
label: cpu.bind("current-usage").as((usage) => {
|
||||
return `${(usage * 100).toFixed(0)}%`;
|
||||
}),
|
||||
}),
|
||||
],
|
||||
vertical: true,
|
||||
});
|
||||
}
|
||||
|
||||
export function MemoryUsage() {
|
||||
return Widget.Box({
|
||||
class_name: "system-stats",
|
||||
css: ram.bind("current-usage-percentage").as((usage) => {
|
||||
let level = (usage * 100).toFixed(0);
|
||||
return `
|
||||
background: linear-gradient(
|
||||
90deg, rgba(26, 27, 38, 0.8) ${level}%, rgba(26, 27, 38, 0.4) ${level}%
|
||||
)`;
|
||||
}),
|
||||
spacing: 2,
|
||||
children: [
|
||||
Widget.Icon({
|
||||
class_names: ["system-stats-icon"],
|
||||
icon: "ram-custom-symbolic",
|
||||
size: 16,
|
||||
}),
|
||||
Widget.Label({
|
||||
class_names: ["system-stats-text"],
|
||||
hexpand: true,
|
||||
label: ram.bind("current-usage-percentage").as((usage) => {
|
||||
return `${(usage * 100).toFixed(0)}%`;
|
||||
}),
|
||||
}),
|
||||
],
|
||||
tooltip_text: ram.bind("current-usage").as((usage) => {
|
||||
let usageGb = (usage / 1024 ** 2).toFixed(2);
|
||||
let totalGb = (ram.total_available / 1024 ** 2).toFixed(2);
|
||||
return `${usageGb}/${totalGb}GiB (${(ram.current_usage_percentage * 100).toFixed(2)}%)`;
|
||||
}),
|
||||
vertical: true,
|
||||
});
|
||||
}
|
||||
|
||||
export const graphics_card_usage = Widget.Box({
|
||||
class_name: "system-stats",
|
||||
css: gpu.bind("current-usage").as((usage) => {
|
||||
var level = Number(usage).toFixed(0);
|
||||
return `
|
||||
background: linear-gradient(
|
||||
90deg, rgba(26, 27, 38, 0.8) ${level}%, rgba(26, 27, 38, 0.4) ${level}%
|
||||
)`;
|
||||
}),
|
||||
spacing: 2,
|
||||
children: [
|
||||
Widget.Icon({
|
||||
class_names: ["system-stats-icon"],
|
||||
icon: "gpu-symbolic",
|
||||
size: 16,
|
||||
}),
|
||||
Widget.Label({
|
||||
class_names: ["system-stats-text"],
|
||||
hexpand: true,
|
||||
label: gpu.bind("current-usage").as((usage) => {
|
||||
return `${Number(usage).toFixed(0)}%`;
|
||||
}),
|
||||
}),
|
||||
],
|
||||
vertical: true,
|
||||
});
|
||||
|
||||
export const volume_widget = Widget.Box({
|
||||
class_name: "system-stats",
|
||||
css: speaker.bind("volume").as((l) => {
|
||||
let level = l.toFixed(2) * 100;
|
||||
if (level >= 0 && level <= 100) {
|
||||
return `
|
||||
background: linear-gradient(
|
||||
90deg, rgba(26, 27, 38, 0.8) ${level}%, rgba(26, 27, 38, 0.4) ${level}%
|
||||
);`;
|
||||
} else if (level > 100 && level <= 200) {
|
||||
return `
|
||||
background: linear-gradient(
|
||||
90deg, rgba(226, 27, 38, 0.4) ${level - 100}%, rgba(26, 27, 38, 0.8) ${level - 100}%
|
||||
);`;
|
||||
} else {
|
||||
return "background: rgba(226, 27, 38, 0.4)";
|
||||
}
|
||||
}),
|
||||
spacing: 2,
|
||||
vertical: true,
|
||||
children: [
|
||||
Widget.Icon({
|
||||
class_names: ["system-stats-icon"],
|
||||
icon: speaker.bind("volume").as((l) => {
|
||||
let level = l.toFixed(2) * 100;
|
||||
if (level == 0) {
|
||||
return "audio-volume-muted";
|
||||
} else if (level > 0 && level <= 30) {
|
||||
return "audio-volume-low";
|
||||
} else if (level > 30 && level <= 70) {
|
||||
return "audio-volume-medium";
|
||||
} else {
|
||||
return "audio-volume-high";
|
||||
}
|
||||
}),
|
||||
size: 16,
|
||||
}),
|
||||
Widget.Label({
|
||||
class_name: "system-stats-text",
|
||||
hexpand: true,
|
||||
label: speaker.bind("volume").as((l) => {
|
||||
return `${(l * 100).toFixed(0)}%`;
|
||||
}),
|
||||
}),
|
||||
],
|
||||
});
|
|
@ -10,7 +10,7 @@ export const Application = (application) =>
|
|||
children: [
|
||||
Widget.Icon({
|
||||
icon: application.icon_name || "",
|
||||
size: 32,
|
||||
size: 24,
|
||||
}),
|
||||
Widget.Label({
|
||||
class_name: "application_name",
|
||||
|
@ -20,6 +20,6 @@ export const Application = (application) =>
|
|||
truncate: "end",
|
||||
}),
|
||||
],
|
||||
spacing: 8,
|
||||
spacing: 4,
|
||||
}),
|
||||
});
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
import { Application } from "./application.js";
|
||||
import { on_window_event } from "../../state.js";
|
||||
const { query } = await Service.import("applications");
|
||||
|
||||
const Launcher = ({ width = 500, height = 600, spacing = 4 }) => {
|
||||
const Launcher = () => {
|
||||
let applications = query("").map(Application);
|
||||
|
||||
const list = Widget.Box({
|
||||
css: "background-color: transparent",
|
||||
vertical: true,
|
||||
spacing,
|
||||
spacing: 4,
|
||||
children: applications,
|
||||
});
|
||||
|
||||
|
@ -54,20 +55,20 @@ const Launcher = ({ width = 500, height = 600, spacing = 4 }) => {
|
|||
return Widget.Box({
|
||||
class_name: "launcher",
|
||||
vertical: true,
|
||||
spacing,
|
||||
spacing: 4,
|
||||
children: [
|
||||
searchBox,
|
||||
Widget.Scrollable({
|
||||
hscroll: "never",
|
||||
css: `min-width: ${width}px; min-height: ${height}px;`,
|
||||
child: list,
|
||||
vexpand: true,
|
||||
}),
|
||||
],
|
||||
setup: (self) =>
|
||||
self.hook(App, (_, windowName, visible) => {
|
||||
if (windowName == "launcher" && visible) {
|
||||
self.hook(App, (_, window_name, visible) => {
|
||||
if (window_name == "launcher" && visible) {
|
||||
repopulate();
|
||||
applications[0].grab_focus(); // Scrolls application list to top
|
||||
searchBox.text = "";
|
||||
searchBox.grab_focus();
|
||||
}
|
||||
|
@ -77,11 +78,20 @@ const Launcher = ({ width = 500, height = 600, spacing = 4 }) => {
|
|||
|
||||
export const launcher = Widget.Window({
|
||||
name: "launcher",
|
||||
setup: (self) =>
|
||||
anchor: ["left", "top", "bottom"],
|
||||
setup: (self) => {
|
||||
self.hook(App, (_, window_name, visible) => {
|
||||
if (window_name == self.name) {
|
||||
on_window_event(_, window_name, visible);
|
||||
}
|
||||
});
|
||||
self.keybind("Escape", () => {
|
||||
App.closeWindow("launcher");
|
||||
}),
|
||||
});
|
||||
},
|
||||
visible: false,
|
||||
margins: [4, 0, 4, 4],
|
||||
exclusivity: "ignore",
|
||||
keymode: "exclusive",
|
||||
child: Launcher({}),
|
||||
});
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
import { Clock } from "../bar-extended/big-clock.js";
|
||||
|
||||
export const popup_clock = Widget.Window({
|
||||
name: "popup_clock",
|
||||
visible: false,
|
||||
anchor: ["right", "top"],
|
||||
margins: [16, 16, 0, 0],
|
||||
layer: "overlay",
|
||||
child: Clock(),
|
||||
});
|
|
@ -1,4 +1,5 @@
|
|||
{ ... }: {
|
||||
{ pkgs, ... }: {
|
||||
home.packages = with pkgs; [ pciutils ];
|
||||
programs.ags = {
|
||||
enable = true;
|
||||
# configDir = ./widgets;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue