Add ags config and enable ags

This commit is contained in:
ferrreo 2023-08-20 15:08:27 +01:00
parent 4fb8b50e1f
commit cdaccf1526
30 changed files with 1738 additions and 1 deletions

View File

@ -0,0 +1,17 @@
const { App } = ags;
const { exec } = ags.Utils;
import { bar } from './windows/bar.js';
import { calendar } from './windows/calendar.js';
exec('sassc ' + App.configDir + '/scss/main.scss ' + App.configDir + '/style.css');
App.resetCss();
App.applyCss(`${App.configDir}/style.css`);
export default {
style: App.configDir + '/style.css',
stackTraceOnError: true,
windows: [
bar,
calendar,
],
}

View File

@ -0,0 +1,56 @@
const { Widget } = ags;
const { lookUpIcon } = ags.Utils;
import { gohypr } from '../services/gohypr.js';
const substitutes = [
{ from: 'code-url-handler', to: 'code' },
];
export const ActiveWindow = () => Widget.Box({
valign: 'center',
halign: 'fill',
className: 'active-window',
children: [
Widget.Icon({
className: 'progicon progiconicon',
connections: [[gohypr, icon => {
if (!gohypr.state) {
return;
}
let classIcon = gohypr.state.activewindow.class;
let titleIcon = gohypr.state.activewindow.title;
substitutes.forEach(({ from, to }) => {
if (classIcon === from)
classIcon = to;
if (titleIcon === from)
titleIcon = to;
});
const hasTitleIcon = lookUpIcon(titleIcon, 128);
const hasClassIcon = lookUpIcon(classIcon, 128);
if (hasClassIcon)
icon.icon_name = classIcon;
if (hasTitleIcon)
icon.icon_name = titleIcon;
icon.visible = hasTitleIcon || hasClassIcon;
}]],
}),
Widget.Label({
className: 'txt txt-norm progicon',
justify: 'left',
halign: 'start',
maxWidthChars: 40,
ellipsize: 3,
connections: [[gohypr, label => {
if (!gohypr.state) {
return;
}
label.label = gohypr.state.activewindow.title || '';
}]]
})
],
});

View File

@ -0,0 +1,14 @@
const { Widget } = ags;
import { Visualiser } from "../widgets/visualiser.js";
import { MediaInfo } from "../widgets/mediainfo.js";
export const Music = () => Widget.Box({
className: 'bar-music',
children: [Widget.Box({
className: 'bar-group-margin bar-sides',
children: [
Visualiser(),
MediaInfo()
]
})]
});

View File

@ -0,0 +1,32 @@
const { Widget, App } = ags;
import { Cpu } from "../widgets/cpu.js";
import { CpuTemp } from "../widgets/cputemp.js";
import { Mem } from "../widgets/mem.js";
import { Clock } from "../widgets/clock.js";
import { Weather } from '../widgets/weather.js';
import { Batt } from '../widgets/batt.js';
export const System = () => Widget.EventBox({
onPrimaryClick: () => App.toggleWindow('calendar'),
onHover: (eventbox) => eventbox.toggleClassName('hovered', true),
onHoverLost: (eventbox) => eventbox.toggleClassName('hovered', false),
className: 'bar-system',
child: Widget.Box({
className: 'bar-group-margin bar-sides',
halign: 'end',
children: [
Widget.Box({
className: 'bar-group-pad-system spacing-h-15',
halign: 'end',
children: [
Cpu(),
CpuTemp(),
Mem(),
Batt(),
Weather(),
Clock()
],
}),
]
})
});

View File

@ -0,0 +1,47 @@
const { Widget } = ags;
const { execAsync } = ags.Utils;
import { gohypr } from '../services/gohypr.js';
export const Workspaces = () => Widget.EventBox({
onScrollUp: () => execAsync('hyprctl dispatch workspace -1'),
onScrollDown: () => execAsync('hyprctl dispatch workspace +1'),
child: Widget.Box({
children: [
Widget.Box({
halign: 'center',
children: [Widget.Box({
children: Array.from({ length: 10 }, (_, i) => i + 1).map(i => (Widget.Button({
className: 'bar-ws-button',
onClicked: () => execAsync(`hyprctl dispatch workspace ${i}`).catch(print),
child: Widget.Label({
valign: 'center',
label: `${i}`,
className: 'bar-ws',
connections: [
[gohypr, label => {
if (!gohypr.state) {
return;
}
const { workspaces, activeworkspace } = gohypr.state;
let thisSpace;
for (const wk of workspaces) {
if (wk.id == i) {
thisSpace = wk;
break;
}
}
label.toggleClassName('bar-ws-active', i == activeworkspace);
label.toggleClassName('bar-ws-occupied', thisSpace?.populated || i == activeworkspace);
label.toggleClassName('bar-ws-empty', !thisSpace?.populated);
label.toggleClassName('bar-ws-left', !thisSpace?.leftPopulated && activeworkspace != i - 1);
label.toggleClassName('bar-ws-right', !thisSpace?.rightPopulated && activeworkspace != i + 1);
}],
],
}),
}))),
})]
}),
]
})
});

View File

@ -0,0 +1,38 @@
[general]
mode = normal
framerate = 15
autosens = 0
;overshoot = 10
sensitivity = 750
bars = 15
[input]
method = pulse
source = auto
[output]
method = raw
raw_target = /dev/stdout
data_format = ascii
channels = mono
mono_option = average
[color]
gradient = 1
gradient_color_1 = '#99B5DE'
gradient_color_2 = '#92CBF6'
gradient_color_3 = '#ACD7F7'
gradient_color_4 = '#B0E2F7'
gradient_color_5 = '#DFEDF5'
gradient_color_6 = '#FDEBD4'
gradient_color_7 = '#E7D2D7'
gradient_color_8 = '#C1838E'
[smoothing]
monstercat = 1
gravity = 1000000
noise_reduction = 0.34

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,466 @@
// Made to be pixel-perfect with 11pt font size
// 1rem = 11pt = 14.6666666667px
.bar-bg {
min-height: 3.81818181817rem;
margin: 0.27272727272rem 0.546rem;
border-radius: 26px;
background-color: mix(shade($colorbarbg, 45%), $primary, 97%);
background-image: linear-gradient(135deg, shade($onSecondary, 47%) 18%, rgba(0, 0, 0, 0) 18%, rgba(0, 0, 0, 0) 37%, shade($onSecondary, 47%) 37%, shade($onSecondary, 47%) 63%, rgba(0, 0, 0, 0) 63%, rgba(0, 0, 0, 0) 85%, shade($onSecondary, 47%) 85%);
box-shadow: 0px 2px 3px rgba(0, 0, 0, 0.5);
animation-name: flyin-top;
animation-duration: 250ms;
animation-timing-function: cubic-bezier(0.05, 0.7, 0.1, 1);
animation-iteration-count: 1;
}
.bar-sidespace {
min-width: 1.5rem;
}
.bar-group-margin {
padding: 0.2rem;
}
.bar-group {
background-color: mix($t_surface, $t_onSurface, 90%);
border-top: 1px solid mix($t_surface, $t_onSurface, 80%);
border-left: 1px solid mix($t_surface, $t_onSurface, 80%);
border-right: 1px solid mix($t_surface, $t_onSurface, 85%);
border-bottom: 1px solid mix($t_surface, $t_onSurface, 85%);
}
.bar-group-pad {
padding: 0rem 1.023rem;
}
.bar-group-pad-less {
padding: 0rem 0.681rem;
}
.bar-group-pad-system {
padding-left: 1.023rem;
padding-right: 0.547rem;
}
.bar-group-pad-music {
padding-right: 1.023rem;
padding-left: 0.273rem;
margin-left: 1.023rem;
}
.bar-group-pad-left {
padding-left: 1.364rem;
padding-right: 0.681rem;
}
.bar-group-pad-right {
padding-left: 0.681rem;
padding-right: 1.364rem;
}
.bar-group-pad-leftonly {
padding-left: 0.681rem;
}
.bar-group-pad-rightonly {
padding-right: 0.681rem;
}
.bar-group-standalone {
border-radius: 1.364rem;
}
.bar-group-round {
border-radius: 10rem;
}
.bar-group-middle {
border-radius: 0.477rem;
}
.bar-group-left {
border-radius: 0.477rem;
border-top-left-radius: 1.364rem;
border-bottom-left-radius: 1.364rem;
margin-left: 1.092rem;
}
.bar-group-right {
border-radius: 0.477rem;
border-top-right-radius: 1.364rem;
border-bottom-right-radius: 1.364rem;
margin-right: 1.092rem;
}
.bar-ws-width {
min-width: 18.382rem;
}
.bar-separator {
min-width: 0.341rem;
min-height: 0.341rem;
background-color: mix($t_surface, $t_onSurface, 90%);
border-radius: 999px;
margin: 0rem 0.341rem;
}
.bar-ws {
min-height: 1.770rem;
min-width: 1.770rem;
font-size: 1.091rem;
}
.bar-ws-button:hover {
.bar-ws-empty {
color: $primary;
}
.bar-ws-occupied {
background-color: $primaryContainer;
color: $onPrimaryContainer;
}
.bar-ws-active {
background-color: $primary;
color: $onPrimary;
}
}
.bar-ws-empty {
color: $onBackground;
}
.bar-ws-occupied {
background-color: $secondaryContainer;
color: $onSecondaryContainer;
}
.bar-ws-active {
background-color: $primary;
color: $onPrimary;
border-radius: 999px;
transition: 100ms cubic-bezier(0, 1, 0, 1);
}
.bar-ws-left {
border-top-left-radius: 999px;
border-bottom-left-radius: 999px;
}
.bar-ws-right {
border-top-right-radius: 999px;
border-bottom-right-radius: 999px;
}
.bar-batt {
border-radius: 999px;
padding: 0rem 0.341rem;
background-color: $onPrimaryContainer;
color: $primaryContainer;
}
.bar-sidemodule {
min-width: 25.227rem;
}
.bar-batt-low {
background-color: $error;
color: $onError;
}
.bar-batt-prog-low {
background-color: $error;
color: $onError;
}
.bar-music-playstate {
min-height: 1.5rem;
min-width: 1.5rem;
border-radius: 10rem;
background-color: $t_surface;
color: $onSurface;
margin-left: 2rem;
}
.bar-music {
margin-left: 2rem;
}
.bar-music-label-container {
min-width: 18.770rem;
}
.bar-music-playstate-playing {
min-height: 1.5rem;
min-width: 1.5rem;
border-radius: 10rem;
background-color: $t_surface;
color: $onSurface;
margin-left: 2rem;
}
.bar-music-playstate-txt {
@include icon-material;
font-size: 1.4545rem;
margin: -0.1rem 0rem;
}
.bar-music-coverbox {
box-shadow: $onPrimary 0px 0px 2rem -0.3rem;
border: $onPrimaryDark 2px solid;
background-position: center;
background-repeat: no-repeat;
background-size: 125%;
min-height: 3rem;
min-width: 3rem;
border-radius: 0.75rem;
}
.bar-music-extended-bg {
border-radius: 1.364rem;
min-width: 34.091rem;
}
.bar-music-extended-ctl-bg {
border-radius: 1.364rem;
background-color: rgba(30, 30, 30, 0.6);
}
.bar-music-bottom-bg {
border-radius: 1.364rem;
min-width: 34.091rem;
}
.bar-music-bottom-ctl-bg {
border-radius: 1.364rem;
background-color: rgba(30, 30, 30, 0.6);
}
.bar-music-extended-textbox {
margin: 1.023rem;
}
.bar-music-bottom-cover {
border-radius: 10rem;
}
.bar-music-hide-false {
@include md3_decel;
transition-duration: 100ms;
opacity: 1;
}
.bar-music-hide-true {
@include md3_accel;
transition-duration: 100ms;
opacity: 0;
}
.bar-music-btn {
font-size: 1.364rem;
border-radius: 10rem;
min-height: 2.591rem;
min-width: 2.591rem;
}
.bar-music-btn:hover {
background-color: $hovercolor;
}
.bar-prog-batt {
min-height: 0.955rem;
min-width: 0.068rem;
padding: 0rem;
border-radius: 10rem;
trough {
min-height: 0.954rem;
min-width: 0.068rem;
border-radius: 10rem;
background-color: $onPrimaryContainer;
}
progress {
min-height: 0.680rem;
min-width: 0.680rem;
margin: 0rem 0.137rem;
border-radius: 10rem;
background-color: $primaryContainer;
}
}
.bar-prog-batt-low {
min-height: 0.954rem;
min-width: 0.068rem;
padding: 0rem;
border-radius: 10rem;
trough {
min-height: 0.954rem;
min-width: 0.068rem;
border-radius: 10rem;
background-color: $onErrorContainer;
}
progress {
min-height: 0.680rem;
min-width: 0.680rem;
margin: 0rem 0.137rem;
border-radius: 10rem;
background-color: $errorContainer;
}
}
.bar-batt-chargestate {
border-radius: 10rem;
background-color: transparent;
background-color: $primaryContainer;
}
.bar-batt-chargestate-charging {
border-radius: 10rem;
min-width: 0.681rem;
min-height: 0.681rem;
}
.bar-batt-chargestate-low {
background-color: $errorContainer;
}
.bar-batt-percentage {
font-size: 1rem;
margin-top: -0.068rem;
font-weight: 500;
}
.corner {
background-color: $t_background;
border-radius: 1.5rem;
}
.bar-space-button {
padding: 0.341rem;
box {
border-radius: 999px;
padding: 0rem 0.682rem;
}
}
.bar-space-button:hover {
box {
background-color: $hovercolor;
}
}
.bar-space-button:active {
box {
background-color: $activecolor;
}
}
.bar-space-button-leftmost {
box {
margin: 0rem 1.5rem;
}
}
.bar-space-area-rightmost>box {
padding-right: 2.386rem;
}
.progicon {
margin-right: 0.75rem;
}
.progiconicon {
font-size: 32px;
}
.calendar {
background-color: $colorbarbg;
border: 0.2rem solid $t_secondaryContainer;
border-radius: 1rem;
color: $onBackground;
padding: .2em;
font-family: 'Torus';
margin: 1rem;
}
calendar {
padding: 0.5rem;
* {
padding: 0.1rem;
color: $primary;
}
:selected {
color: $onPrimary;
font-weight: bolder;
background-color: $primary;
border-radius: 0.5rem;
}
.header {
color: $onBackground;
}
.button {
color: $onBackground;
}
:indeterminate {
color: $onBackground;
}
}
.bar-system .bar-sides {
transition: 500ms cubic-bezier(0.05, 0.7, 0.1, 1);
margin: 0.25rem;
border-radius: 1.5rem;
padding: 0 1rem;
}
.hovered.bar-system .bar-sides {
background-image: linear-gradient(45deg, rgba(0, 0, 0, 0) 60%, tint($surfaceVariant, 10%) 60%);
background-size: 400% auto;
background-color: $surfaceVariant;
background-position: 60% 50%;
}
tooltip {
background-color: $background;
color: $onBackground;
border-radius: 5rem;
padding: 1rem;
margin: 1rem;
border: 1px solid $onBackground;
}
.musicbox {
margin-top: -5rem;
margin-bottom: 0.01rem;
margin-left: 1rem;
}
.musicbox-bar {
min-height: 0.155rem;
min-width: 1rem;
padding: 0rem;
border-radius: 10rem;
trough {
background-color: transparent;
}
progress {
min-height: 0.155rem;
min-width: 2rem;
margin: 0rem 0.137rem;
border-top-left-radius: 10rem;
border-top-right-radius: 10rem;
background-color: $secondaryContainer;
}
}

View File

@ -0,0 +1,34 @@
$transparentize_amount: 0.1;
$transparentize_surface_amount: 0.41;
$t_primary: transparentize($primary, $transparentize_amount);
$t_onPrimary: transparentize($onPrimary, $transparentize_amount);
$t_primaryContainer: transparentize($primaryContainer, $transparentize_amount);
$t_onPrimaryContainer: transparentize($onPrimaryContainer, $transparentize_amount);
$t_secondary: transparentize($secondary, $transparentize_amount);
$t_onSecondary: transparentize($onSecondary, $transparentize_amount);
$t_secondaryContainer: transparentize($secondaryContainer, $transparentize_amount);
$t_onSecondaryContainer: transparentize($onSecondaryContainer, $transparentize_amount);
$t_tertiary: transparentize($tertiary, $transparentize_amount);
$t_onTertiary: transparentize($onTertiary, $transparentize_amount);
$t_tertiaryContainer: transparentize($tertiaryContainer, $transparentize_amount);
$t_onTertiaryContainer: transparentize($onTertiaryContainer, $transparentize_amount);
$t_error: transparentize($error, $transparentize_amount);
$t_onError: transparentize($onError, $transparentize_amount);
$t_errorContainer: transparentize($errorContainer, $transparentize_amount);
$t_onErrorContainer: transparentize($onErrorContainer, $transparentize_amount);
$t_colorbarbg: transparentize($colorbarbg, $transparentize_amount);
$t_background: transparentize($background, $transparentize_amount);
$t_onBackground: transparentize($onBackground, $transparentize_amount);
$t_surface: transparentize($surface, $transparentize_surface_amount);
$t_onSurface: transparentize($onSurface, $transparentize_surface_amount);
$t_surfaceVariant: transparentize($surfaceVariant, $transparentize_surface_amount);
$t_onSurfaceVariant: transparentize($onSurfaceVariant, $transparentize_surface_amount);
$t_outline: transparentize($outline, $transparentize_amount);
$t_shadow: transparentize($shadow, $transparentize_amount);
$t_inverseSurface: transparentize($inverseSurface, $transparentize_amount);
$t_inverseOnSurface: transparentize($inverseOnSurface, $transparentize_amount);
$t_inversePrimary: transparentize($inversePrimary, $transparentize_amount);
$hovercolor: mix($t_surface, $t_onSurface, 0.5);
$activecolor: mix($t_surface, $t_onSurface, 0.3);

View File

@ -0,0 +1,357 @@
// Common colors
$hovercolor: rgba(128, 128, 128, 0.4);
$activecolor: rgba(128, 128, 128, 0.7);
// Common rules
@mixin mainfont {
font-family: 'Torus', 'Product Sans', 'Bahnschrift', 'Inter';
// font-weight: 500;
}
@mixin icon-material {
font-family: 'Material Symbols Rounded';
}
@mixin icon-nerd {
font-family: 'JetBrainsMono Nerd Font';
}
@mixin techfont {
font-family: 'JetBrains Mono Nerd Font';
}
@mixin subtext {
color: rgb(160, 160, 160);
}
@mixin elevation-safe {
background: $surface;
color: $onSurface;
box-shadow: 0px 2px 3px rgba(0, 0, 0, 0.69);
margin: 7px;
}
@mixin elevation2 {
background: $surface;
color: $onSurface;
box-shadow: 0px 2px 3px $shadow;
margin: 7px;
}
@mixin elevation3 {
background: $surfaceVariant;
color: $onSurfaceVariant;
// box-shadow: 0px 2px 5px mix($shadow, rgba(0,0,0,0), 40%);
box-shadow: 0px 2px 5px $shadow;
margin: 7px;
}
@mixin md3_decel {
transition: 250ms cubic-bezier(0.05, 0.7, 0.1, 1);
}
@mixin md3_accel {
transition: 180ms cubic-bezier(0.3, 0, 0.8, 0.15);
}
@mixin noanim {
transition: 0ms;
}
@mixin anim-enter {
transition: 200ms cubic-bezier(0.05, 0.7, 0.1, 1);
}
@mixin anim-exit {
transition: 150ms cubic-bezier(0.3, 0, 0.8, 0.15);
}
@mixin m3-button {
border-radius: 50rem;
}
@keyframes flyin-top {
from {
margin-top: -2.795rem;
}
to {
margin-top: 0rem;
}
}
@keyframes flyin-bottom {
from {
margin-top: 4.841rem;
margin-bottom: -4.841rem;
}
to {
margin-bottom: 0rem;
margin-top: 0rem;
}
}
@function tint($color, $percentage) {
@return mix(rgb(245, 250, 255), $color, $percentage);
}
@function shade($color, $percentage) {
@return mix(rgb(0, 0, 0), $color, $percentage);
}
.no-anim {
@include noanim;
}
.txt {
color: $onBackground;
}
.txt-shadow {
text-shadow: 1px 2px 8px rgba(0, 0, 0, 0.69);
margin: 10px;
}
.txt-badonkers {
@include mainfont;
font-size: 3rem;
}
.txt-tiddies {
@include mainfont;
font-size: 2.7273rem;
}
.txt-hugeass {
@include mainfont;
font-size: 1.8182rem;
}
.txt-larger {
@include mainfont;
font-size: 1.6363rem;
}
.txt-large {
//16pt
@include mainfont;
font-size: 1.4545rem;
}
.txt-norm {
//14pt
@include mainfont;
font-size: 1.2727rem;
}
.txt-small {
//12pt
@include mainfont;
font-size: 1.0909rem;
}
.txt-smallie {
//11pt
@include mainfont;
font-size: 1rem;
}
.txt-smaller {
//10pt
@include mainfont;
font-size: 0.9091rem;
}
.txt-smaller-offset {
margin-top: -0.136rem;
}
.txt-tiny {
@include mainfont;
font-size: 0.7273rem;
}
.txt-subtxt {
color: mix($onBackground, $background, 80%);
}
.txt-bold {
font-weight: 500;
}
.icon-material {
@include icon-material;
}
.separator {
border-radius: 50rem;
background-color: $onSurface;
margin: 0rem 0.682rem;
min-width: 0.545rem;
min-height: 0.545rem;
}
tooltip {
background-color: $surfaceVariant;
color: $onSurfaceVariant;
border-radius: 50rem;
border: 1px solid $onSurfaceVariant;
}
$overlay1: mix($onSurface, rgba(0, 0, 0, 0), 25%);
$overlay2: mix($onSurface, rgba(0, 0, 0, 0), 40%);
.spacing-v-15>box {
margin-bottom: 1.023rem;
}
.spacing-v-15>box:last-child {
margin-bottom: 0rem;
}
.spacing-v-15>scrolledwindow {
margin-bottom: 1.023rem;
}
.spacing-v-15>scrolledwindow:last-child {
margin-bottom: 0rem;
}
.spacing-v-15>revealer {
margin-bottom: 1.023rem;
}
.spacing-v-15>revealer:last-child {
margin-bottom: 0rem;
}
.spacing-v-15>label {
margin-bottom: 1.023rem;
}
.spacing-v-15>label:last-child {
margin-bottom: 0rem;
}
.spacing-h-15>box {
margin-right: 1.023rem;
}
.spacing-h-15>box:last-child {
margin-right: 0rem;
}
.spacing-h-15>label {
margin-right: 1.023rem;
}
.spacing-h-15>label:last-child {
margin-right: 0rem;
}
.spacing-h-15>button {
margin-right: 1.023rem;
}
.spacing-h-15>button:last-child {
margin-right: 0rem;
}
.spacing-v-5>box {
margin-bottom: 0.341rem;
}
.spacing-v-5>box:last-child {
margin-bottom: 0rem;
}
.spacing-v-5>label {
margin-bottom: 0.341rem;
}
.spacing-v-5>label:last-child {
margin-bottom: 0rem;
}
.spacing-v-5>button {
margin-bottom: 0.341rem;
}
.spacing-v-5>button:last-child {
margin-bottom: 0rem;
}
.spacing-h-5>box {
margin-right: 0.341rem;
}
.spacing-h-5>box:last-child {
margin-right: 0rem;
}
.spacing-h-5>label {
margin-right: 0.341rem;
}
.spacing-h-5>label:last-child {
margin-right: 0rem;
}
.spacing-h-5>widget>box {
margin-right: 0.341rem;
}
.spacing-h-5>widget:last-child>box {
margin-right: 0rem;
}
.spacing-v-minus5>box {
margin-bottom: -0.341rem;
}
.spacing-v-minus5>box:last-child {
margin-bottom: 0rem;
}
.spacing-v-minus5>label {
margin-bottom: -0.341rem;
}
.spacing-v-minus5>label:last-child {
margin-bottom: 0rem;
}
.spacing-h-10>box {
margin-right: 0.682rem;
}
.spacing-h-10>box:last-child {
margin-right: 0rem;
}
.spacing-h-10>label {
margin-right: 0.682rem;
}
.spacing-h-10>label:last-child {
margin-right: 0rem;
}
.spacing-h-10>widget {
margin-right: 0.682rem;
}
.spacing-h-10>widget:last-child {
margin-right: 0rem;
}
.anim-enter {
@include anim-enter;
}
.anim-exit {
@include anim-exit;
}

View File

@ -0,0 +1,29 @@
$primary: #c6c0ff;
$onPrimary: #260f98;
$onPrimaryDark: #190b5f;
$primaryContainer: #3e31ad;
$onPrimaryContainer: #e5dfff;
$secondary: #c7c3dc;
$onSecondary: #302e42;
$secondaryContainer: #464459;
$onSecondaryContainer: #e3dff8;
$tertiary: #ebb8d0;
$onTertiary: #472638;
$tertiaryContainer: #613b4f;
$onTertiaryContainer: #ffd8ea;
$error: #ffb4a9;
$onError: #680003;
$errorContainer: #930006;
$onErrorContainer: #ffb4a9;
$colorbarbg: #1c1b1f;
$background: #1c1b1f;
$onBackground: #e5e1e6;
$surface: #1c1b1f;
$onSurface: #e5e1e6;
$surfaceVariant: #47464e;
$onSurfaceVariant: #c9c5d0;
$outline: #928f9a;
$shadow: #000000;
$inverseSurface: #e5e1e6;
$inverseOnSurface: #313033;
$inversePrimary: #564cc5;

View File

@ -0,0 +1,12 @@
// Reset
* {
all: unset;
}
// Colors
@import './material'; // Material colors
@import './colors'; // Global color definitions. Uses material colors as base.
@import './lib'; // Global mixins and functions
// Components
@import './bar';

View File

@ -0,0 +1,30 @@
const { App, Service } = ags;
const { execAsync } = ags.Utils;
async function setupScss() {
try {
await execAsync(['sassc', `${App.configDir}/scss/main.scss`, `${App.configDir}/style.css`]);
ags.App.resetCss();
ags.App.applyCss(`${App.configDir}/style.css`);
} catch (error) {
print(error);
}
}
class ThemeService extends Service {
static { Service.register(this); }
constructor() {
super();
this.setup();
}
setup() {
setupScss();
}
}
var Theme = class Theme {
static { Service.export(this, 'Theme'); }
static instance = new ThemeService();
};

View File

@ -0,0 +1,26 @@
const { App } = ags;
import { deflisten } from './deflisten.js';
function start() {
cvjson.started = true;
cvjson.service.start();
}
function stop() {
cvjson.started = false;
cvjson.service.stop();
}
export const cvjson = {
start: start,
stop: stop,
started: true,
service: deflisten('cvjson', `${App.configDir}/programs/cvjson ${App.configDir}/programs/cava`, (line) => {
try {
return JSON.parse(line);
} catch {
return [];
}
}),
};

View File

@ -0,0 +1,83 @@
export const deflisten = function (name, command, transformer = (a) => a) {
const { Service } = ags;
const GObject = imports.gi.GObject;
const v = GObject.registerClass(
{
GTypeName: name,
Properties: {
state: GObject.ParamSpec.string(
"state",
"State",
"Read-Write string state.",
GObject.ParamFlags.READWRITE,
""
),
},
Signals: {
[`${name}-changed`]: {},
},
},
class Subclass extends Service {
get state() {
return this._state || "";
}
set state(value) {
this._state = value;
this.emit("changed");
}
get proc() {
return this._proc || null;
}
set proc(value) {
this._proc = value;
}
start = () => {
this.proc = ags.Utils.subprocess(command, (line) => {
this.state = transformer(line);
});
}
stop = () => {
this.proc.force_exit();
this.proc = null;
}
constructor() {
super();
this.proc = ags.Utils.subprocess(command, (line) => {
this.state = transformer(line);
});
}
}
);
class State {
static {
Service.export(this, name);
}
static instance = new v();
static get state() {
return State.instance.state;
}
static set state(value) {
State.instance.state = value;
}
static start() {
State.instance.start();
}
static stop () {
State.instance.stop();
}
}
return State;
}

View File

@ -0,0 +1,6 @@
const { App } = ags;
import { deflisten } from './deflisten.js';
export const gohypr = deflisten('gohypr', `${App.configDir}/programs/gohypr`, (line) => {
return JSON.parse(line);
});

View File

@ -0,0 +1,8 @@
const { App } = ags;
import { deflisten } from './deflisten.js';
const udpateDelay = "2s";
export const gostat = deflisten('gostat', `${App.configDir}/programs/gostat ${udpateDelay}`, (line) => {
return JSON.parse(line);
});

View File

@ -0,0 +1,49 @@
const { Widget } = ags;
const { Battery } = ags.Service;
export const Batt = () => Widget.Box({
halign: 'end',
tooltipText: 'Battery Remaining',
valign: 'center',
className: '',
connections: [[Battery, box => {
box.visible = Battery?.available;
}]],
children: [
Widget.Label({
halign: 'end',
valign: 'center',
className: 'txt-larger txt icon-material',
style: 'margin-right: 0.5rem; margin-top: 1px;',
label: 'battery_5_bar',
connections: [[Battery, label => {
if (Battery?.available) {
label.label = getBattery(Battery);
}
}]],
}),
Widget.Label({
halign: 'end',
valign: 'center',
className: 'txt-norm txt',
connections: [[Battery, label => {
if (Battery?.available) {
label.label = Battery?.percent + "%";
}
}]],
}),
],
});
function getBattery(batt) {
if (batt?.charging) {
return "battery_charging_full";
}
if (batt?.charged) {
return "battery_full";
}
return battIcons[Math.floor(battIcons.length * (batt?.percent / 100))];
}
const battIcons = ["battery_0_bar","battery_1_bar","battery_2_bar","battery_3_bar","battery_4_bar","battery_5_bar", "battery_6_bar"];

View File

@ -0,0 +1,61 @@
const { Widget } = ags;
export const Clock = () => Widget.Box({
vertical: true,
halign: 'end',
valign: 'center',
sensitive: true,
className: 'clock',
children: [
Widget.Label({
halign: 'end',
valign: 'center',
className: 'txt-norm txt',
connections: [[5000, label => label.label = getFormattedTime()]],
}),
Widget.Label({
halign: 'end',
valign: 'center',
className: 'txt-smallie txt',
connections: [[60000, label => label.label = getFormattedDate()]],
}),
],
});
function getFormattedTime() {
const date = new Date();
let hours = date.getHours();
let minutes = date.getMinutes();
if (hours < 10) hours = "0" + hours;
if (minutes < 10) minutes = "0" + minutes;
return `${hours}:${minutes}`
}
function getFormattedDate() {
const date = new Date();
const day = date.getDay();
const month = date.getMonth();
let dayOfMonth = date.getDate();
switch (dayOfMonth) {
case 1:
case 21:
case 31:
dayOfMonth += "st";
break;
case 2:
case 22:
dayOfMonth += "nd";
break;
case 3:
case 23:
dayOfMonth += "rd";
break;
default:
dayOfMonth += "th";
}
return `${days[day]}, ${dayOfMonth} ${months[month]}`;
}
const days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
const months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];

View File

@ -0,0 +1,28 @@
const { Widget } = ags;
import { gostat } from '../services/gostat.js';
export const Cpu = () => Widget.Box({
halign: 'end',
tooltipText: 'CPU Usage',
valign: 'center',
className: '',
children: [
Widget.Label({
halign: 'end',
valign: 'center',
className: 'txt-larger txt icon-material',
style: 'margin-right: 0.5rem; margin-top: 1px;',
label: 'developer_board',
}),
Widget.Label({
halign: 'end',
valign: 'center',
className: 'txt-norm txt',
connections: [[gostat, label => {
if (gostat?.state?.cpu) {
label.label = gostat?.state?.cpu + "%";
}
}]],
}),
],
});

View File

@ -0,0 +1,28 @@
const { Widget } = ags;
import { gostat } from '../services/gostat.js';
export const CpuTemp = () => Widget.Box({
halign: 'end',
tooltipText: 'CPU Temperature',
valign: 'center',
className: '',
children: [
Widget.Label({
halign: 'end',
valign: 'center',
className: 'txt-larger txt icon-material',
style: 'margin-right: 0.25rem; margin-top: 1px;',
label: 'thermometer',
}),
Widget.Label({
halign: 'end',
valign: 'center',
className: 'txt-norm txt',
connections: [[gostat, label => {
if (gostat?.state?.cputemp) {
label.label = gostat?.state?.cputemp + "°C";
}
}]],
}),
],
});

View File

@ -0,0 +1,76 @@
const { Widget } = ags;
const { Mpris } = ags.Service;
export const MediaInfo = () => Widget.Box({
className: 'bar-group-pad-music spacing-h-10',
style: "margin-left: -16rem;",
children: [
Widget.Box({
halign: 'center',
className: 'bar-music-coverbox',
connections: [[Mpris, box => {
const mpris = Mpris.getPlayer('');
if (mpris?.coverPath) {
box.visible = true;
box.setStyle(`background-image: url('${mpris.coverPath}');`);
} else {
box.visible = false;
}
}]],
children: [
Widget.Box({
valign: 'center',
style: 'margin-left: 0.75rem;',
children: [Widget.Label({
valign: 'center',
className: 'bar-music-playstate-txt',
connections: [[Mpris, label => {
const mpris = Mpris.getPlayer('');
label.label = `${mpris?.playBackStatus == 'Playing' ? '' : ''}`;
}]],
})],
connections: [[Mpris, label => {
const mpris = Mpris.getPlayer('');
label.toggleClassName('bar-music-playstate-playing', mpris?.playBackStatus == 'Playing');
label.toggleClassName('bar-music-playstate', mpris?.playBackStatus == 'Paused');
}]],
}),
]
}),
Widget.Box({
className: 'bar-music-label-container',
vertical: true,
halign: 'start',
valign: 'center',
children: [Widget.Label({
halign: 'start',
valign: 'center',
maxWidthChars: 40,
ellipsize: 3,
className: 'bar-music-label txt txt-norm',
connections: [[Mpris, label => {
const mpris = Mpris.getPlayer('');
if (mpris)
label.label = `${mpris.trackTitle}`;
else
label.label = 'Nothing';
}]],
}),
Widget.Label({
halign: 'start',
maxWidthChars: 40,
ellipsize: 3,
valign: 'center',
className: 'bar-music-label txt txt-smallie',
connections: [[Mpris, label => {
const mpris = Mpris.getPlayer('');
if (mpris)
label.label = `${mpris.trackArtists}`;
else
label.label = 'Playing';
}]],
}),
],
})
]
});

View File

@ -0,0 +1,27 @@
const { Widget } = ags;
import { gostat } from '../services/gostat.js';
export const Mem = () => Widget.Box({
halign: 'end',
tooltipText: 'Memory Usage',
valign: 'center',
children: [
Widget.Label({
halign: 'end',
valign: 'center',
className: 'txt-larger txt icon-material',
style: 'margin-right: 0.5rem; margin-top: 1px;',
label: 'memory',
}),
Widget.Label({
halign: 'end',
valign: 'center',
className: 'txt-norm txt',
connections: [[gostat, label => {
if (gostat?.state?.mem) {
label.label = gostat?.state?.mem + "G";
}
}]],
}),
],
});

View File

@ -0,0 +1,41 @@
const { Widget } = ags;
const { Mpris } = ags.Service;
import { cvjson } from '../services/cvjson.js';
const numBars = 15;
export const Visualiser = () => Widget.Box({
className: 'musicbox',
halign: 'center',
valign: 'end',
vexpand: false,
connections: [
[Mpris, box => {
const mpris = Mpris.getPlayer('');
if (mpris?.playBackStatus == 'Playing' && !cvjson?.started) {
cvjson.start();
} else if ((!mpris?.playBackStatus || mpris?.playBackStatus != 'Playing') && cvjson?.started) {
cvjson.stop();
for (const child of box.get_children()) {
child.fraction = 0;
}
}
}],
[cvjson.service, box => {
if (!cvjson.started || !cvjson?.service?.state || cvjson?.service?.state.length < numBars) {
return;
}
let count = 0;
for (const child of box.get_children()) {
child.fraction = cvjson?.service.state[count] / 1000;
count++;
}
}],
],
children: Array.from({ length: numBars }, (_, i) => i).map(i => (Widget.ProgressBar({
vertical: true,
className: 'musicbox-bar',
value: 0,
inverted: true,
}))),
});

View File

@ -0,0 +1,109 @@
const { Widget } = ags;
const { exec } = ags.Utils;
const city = "Stoke-On-Trent";
export const Weather = () => Widget.Box({
halign: 'end',
tooltipText: 'Weather',
valign: 'center',
style: 'margin-right: 2.5rem;',
children: [
Widget.Label({
halign: 'end',
valign: 'center',
className: 'txt-larger txt',
style: 'margin-right: 0.5rem; margin-top: 1px;',
label: '🌦',
}),
Widget.Label({
halign: 'end',
valign: 'center',
className: 'txt-norm txt',
}),
],
connections: [[900000, async box => {
try {
let weather = exec(`curl https://wttr.in/${city}?format=j1`);
weather = JSON.parse(weather);
const weatherCode = weather.current_condition[0].weatherCode;
box.children[0].label = WEATHER_SYMBOL[WWO_CODE[weatherCode]];
box.children[1].label = weather.current_condition[0].temp_C + "°C";
} catch (err) {
console.log(err);
}
}]],
});
const WWO_CODE = {
"113": "Sunny",
"116": "PartlyCloudy",
"119": "Cloudy",
"122": "VeryCloudy",
"143": "Fog",
"176": "LightShowers",
"179": "LightSleetShowers",
"182": "LightSleet",
"185": "LightSleet",
"200": "ThunderyShowers",
"227": "LightSnow",
"230": "HeavySnow",
"248": "Fog",
"260": "Fog",
"263": "LightShowers",
"266": "LightRain",
"281": "LightSleet",
"284": "LightSleet",
"293": "LightRain",
"296": "LightRain",
"299": "HeavyShowers",
"302": "HeavyRain",
"305": "HeavyShowers",
"308": "HeavyRain",
"311": "LightSleet",
"314": "LightSleet",
"317": "LightSleet",
"320": "LightSnow",
"323": "LightSnowShowers",
"326": "LightSnowShowers",
"329": "HeavySnow",
"332": "HeavySnow",
"335": "HeavySnowShowers",
"338": "HeavySnow",
"350": "LightSleet",
"353": "LightShowers",
"356": "HeavyShowers",
"359": "HeavyRain",
"362": "LightSleetShowers",
"365": "LightSleetShowers",
"368": "LightSnowShowers",
"371": "HeavySnowShowers",
"374": "LightSleetShowers",
"377": "LightSleet",
"386": "ThunderyShowers",
"389": "ThunderyHeavyRain",
"392": "ThunderySnowShowers",
"395": "HeavySnowShowers",
}
const WEATHER_SYMBOL = {
"Unknown": "✨",
"Cloudy": "☁️",
"Fog": "🌫",
"HeavyRain": "🌧",
"HeavyShowers": "🌧",
"HeavySnow": "❄️",
"HeavySnowShowers": "❄️",
"LightRain": "🌦",
"LightShowers": "🌦",
"LightSleet": "🌧",
"LightSleetShowers": "🌧",
"LightSnow": "🌨",
"LightSnowShowers": "🌨",
"PartlyCloudy": "⛅️",
"Sunny": "☀️",
"ThunderyHeavyRain": "🌩",
"ThunderyShowers": "⛈",
"ThunderySnowShowers": "⛈",
"VeryCloudy": "☁️",
}

View File

@ -0,0 +1,40 @@
const { Widget } = ags;
import { Workspaces } from "../modules/workspaces.js";
import { Music } from "../modules/music.js";
import { ActiveWindow } from "../modules/activewindow.js";
import { System } from "../modules/system.js";
const left = Widget.Box({
hexpand: false,
halign: 'start',
className: 'bar-group-left',
children: [Workspaces(), Music()],
});
const center = Widget.Box({
hexpand: true,
halign: 'center',
className: 'bar-group-center',
children: [ActiveWindow()],
});
const right = Widget.Box({
className: 'bar-group-right',
hexpand: false,
halign: 'end',
children: [System()],
});
export const bar = Widget.Window({
name: 'bar',
anchor: ['top', 'left', 'right'],
exclusive: true,
child: Widget.CenterBox({
className: 'bar-bg',
children: [
left,
center,
right
],
}),
});

View File

@ -0,0 +1,23 @@
const { Widget } = ags;
export const calendar = Widget.Window({
name: 'calendar',
anchor: ['top', 'right'],
visible: false,
exclusive: true,
child: Widget.Box({
className: 'cal',
children: [
Widget.Box({
className: 'calendar',
children: [
Widget.Box({
halign: 3,
hexpand: true,
children: [imports.gi.Gtk.Calendar.new()],
}),
],
}),
],
}),
});

View File

@ -6,7 +6,7 @@ exec-once=mako
exec-once=hyprpaper
exec-once=nm-applet
exec-once=/usr/lib/x86_64-linux-gnu/libexec/polkit-kde-authentication-agent-1
exec-once=sleep 2 && ironbar
exec-once=ags
exec-once=/etc/pika_login.sh
exec-once=swayidle timeout 300 '/usr/share/pika/lock.sh --grace 10 --fade-in 4' timeout 330 'hyprctl dispatch dpms off' resume 'hyprctl dispatch dpms on' before-sleep '/usr/share/pika/lock.sh'
exec-once=pika-installer &