optimization
This commit is contained in:
1 parent
7289ca07fe
commit
5be5a41789
14 files changed
+353
-277
No files matched your search
@@ -7,12 +7,11 @@ import { Info } from "./info";
|
||||
import { Apps } from "./apps";
|
||||
import { MaterialIcon } from "icons";
|
||||
import { Weather } from "./weather";
|
||||
import { current_tab, current_window, set_current_window } from "./variables";
|
||||
const hyprland = await Service.import("hyprland");
|
||||
import Gtk from "gi://Gtk?version=3.0";
|
||||
|
||||
globalThis.OpenSettings = OpenSettings;
|
||||
let current_window;
|
||||
const current_tab = Variable("network");
|
||||
|
||||
export async function OpenSettings(cur_tab: string = "network") {
|
||||
if (current_window) {
|
||||
@@ -43,7 +42,7 @@ function Settings(cur_tab: string) {
|
||||
wallpaper: Page(Wallpapers(), "Wallpapers"),
|
||||
info: Page(Info(), "Info"),
|
||||
apps: Page(Apps(), "Apps"),
|
||||
"weather": Page(Weather(), "Weather")
|
||||
weather: Page(Weather(), "Weather")
|
||||
}
|
||||
});
|
||||
const Row = (name: string, label: string, icon: string = "image-missing") =>
|
||||
@@ -122,7 +121,7 @@ export const SettingsWindow = (cur_tab: string) => {
|
||||
class_name: "settings",
|
||||
child: Settings(cur_tab),
|
||||
setup(win: any) {
|
||||
current_window = win;
|
||||
set_current_window(win);
|
||||
win.keybind("Escape", () => {
|
||||
win.close();
|
||||
});
|
||||
@@ -133,7 +132,7 @@ export const SettingsWindow = (cur_tab: string) => {
|
||||
window.on("delete-event", () => {
|
||||
// @ts-ignore
|
||||
window.destroy();
|
||||
current_window = undefined;
|
||||
set_current_window(undefined);
|
||||
return true;
|
||||
});
|
||||
return window;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import Gtk from "gi://Gtk?version=3.0";
|
||||
import { timeout } from "resource:///com/github/Aylur/ags/utils.js";
|
||||
import { Variable as VariableType } from "types/variable";
|
||||
import { MaterialIcon } from "icons";
|
||||
const systemtray = await Service.import("systemtray");
|
||||
const network = await Service.import("network");
|
||||
import { current_tab, saved_networks, current_window } from "./variables";
|
||||
|
||||
const MATERIAL_SYMBOL_SIGNAL_STRENGTH = {
|
||||
"network-wireless-signal-excellent-symbolic": "signal_wifi_4_bar",
|
||||
@@ -23,10 +23,9 @@ type AccessPoint = {
|
||||
iconName: string | undefined;
|
||||
};
|
||||
|
||||
const network = await Service.import("network");
|
||||
|
||||
const _scan_timer = Variable(undefined, {
|
||||
poll: [15000, WifiScan]
|
||||
Utils.interval(1500, () => {
|
||||
if (current_tab.value != "network" || !current_window?.visible) return;
|
||||
WifiScan();
|
||||
});
|
||||
|
||||
const network_state = {
|
||||
@@ -43,21 +42,11 @@ const network_state = {
|
||||
failed: "Connection failed"
|
||||
};
|
||||
|
||||
const saved_networks: VariableType<string[]> = Variable([], {
|
||||
poll: [
|
||||
5000,
|
||||
() => {
|
||||
const _saved = Utils.exec(`${App.configDir}/scripts/network.sh --saved`);
|
||||
return _saved.split("\n");
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
function WifiScan() {
|
||||
try {
|
||||
network.wifi?.scan();
|
||||
} catch (error) {
|
||||
print(error)
|
||||
print(error);
|
||||
}
|
||||
// await Utils.execAsync("nmcli device wifi rescan").catch(print)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Variable as VariableType } from "types/variable";
|
||||
|
||||
export let current_window;
|
||||
export function set_current_window(value: any) {
|
||||
current_window = value;
|
||||
}
|
||||
|
||||
export const current_tab = Variable("network");
|
||||
export const saved_networks: VariableType<string[]> = Variable([], {
|
||||
poll: [
|
||||
5000,
|
||||
() => {
|
||||
if (current_tab.value != "network" || !current_window?.visible) return saved_networks?.value || [];
|
||||
const _saved = Utils.exec(`${App.configDir}/scripts/network.sh --saved`);
|
||||
return _saved.split("\n");
|
||||
}
|
||||
]
|
||||
});
|
||||
@@ -37,7 +37,7 @@ const WeatherKey = () =>
|
||||
on_accept: (self) => {
|
||||
if (self.text!.length == 32) {
|
||||
self.css = "border: 2px solid; border-color: #66BB6A";
|
||||
Utils.timeout(100, () => {
|
||||
Utils.timeout(1000, () => {
|
||||
self.css = "border: 2px solid; border-color: transparent";
|
||||
});
|
||||
conf.set_value("weather", self.text!);
|
||||
@@ -82,7 +82,7 @@ const WeatherLocationKey = () =>
|
||||
text: conf.config.weather_location_id,
|
||||
on_accept: (self) => {
|
||||
self.css = "border: 2px solid; border-color: #66BB6A";
|
||||
Utils.timeout(100, () => {
|
||||
Utils.timeout(1000, () => {
|
||||
self.css = "border: 2px solid; border-color: transparent";
|
||||
});
|
||||
conf.set_value("weather_location_id", self.text!);
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import { LabelProps } from "types/widgets/label";
|
||||
|
||||
const _icons_folder = `${App.configDir}/assets/icons`;
|
||||
|
||||
export const MaterialIcon = (icon: string, size: string = "24px", props?: LabelProps) =>
|
||||
Widget.Label({
|
||||
label: icon,
|
||||
|
||||
+10
-19
@@ -29,43 +29,34 @@ const Windows = () => [
|
||||
forMonitors(BarCornerTopLeft),
|
||||
forMonitors(BarCornerTopRight),
|
||||
sideright,
|
||||
sideleft,
|
||||
cheatsheet,
|
||||
sideleft,
|
||||
forMonitors(popups)
|
||||
];
|
||||
|
||||
const CLOSE_ANIM_TIME = 210;
|
||||
const closeWindowDelays = {};
|
||||
for (let i = 0; i < (Gdk.Display.get_default()?.get_n_monitors() || 1); i++) {
|
||||
closeWindowDelays[`osk${i}`] = CLOSE_ANIM_TIME;
|
||||
}
|
||||
|
||||
App.config({
|
||||
windows: Windows().flat(1),
|
||||
// @ts-ignore
|
||||
closeWindowDelay: closeWindowDelays,
|
||||
onConfigParsed: function () {}
|
||||
});
|
||||
|
||||
function ReloadCSS() {
|
||||
App.resetCss();
|
||||
App.applyCss(`${GLib.get_home_dir()}/.config/gtk-3.0/gtk.css`);
|
||||
App.applyCss(`${App.configDir}/style.css`);
|
||||
App.applyCss(`${App.configDir}/style-apps.css`);
|
||||
}
|
||||
|
||||
function ReloadGtkCSS() {
|
||||
App.applyCss(`${GLib.get_home_dir()}/.config/gtk-3.0/gtk.css`);
|
||||
ReloadCSS();
|
||||
function ReloadColors() {
|
||||
App.applyCss(`${GLib.get_home_dir()}/.cache/material/colors.css`);
|
||||
}
|
||||
|
||||
Utils.monitorFile(`${App.configDir}/style.css`, ReloadCSS);
|
||||
Utils.monitorFile(`${GLib.get_home_dir()}/.cache/material/colors.css`, ReloadCSS);
|
||||
|
||||
Utils.monitorFile(`${App.configDir}/style-apps.css`, ReloadCSS);
|
||||
|
||||
Utils.monitorFile(`${GLib.get_home_dir()}/.cache/material/colors.json`, ReloadCSS);
|
||||
|
||||
Utils.monitorFile(`${GLib.get_home_dir()}/.config/gtk-3.0/gtk.css`, ReloadGtkCSS);
|
||||
forMonitorsAsync(Bar);
|
||||
ReloadGtkCSS();
|
||||
ReloadCSS();
|
||||
|
||||
start_battery_warning_service()
|
||||
globalThis.ReloadCSS = ReloadCSS;
|
||||
globalThis.ReloadColors = ReloadColors;
|
||||
|
||||
start_battery_warning_service();
|
||||
+91
-66
@@ -4,13 +4,12 @@ const systemtray = await Service.import("systemtray");
|
||||
const audio = await Service.import("audio");
|
||||
const network = await Service.import("network");
|
||||
const { GLib, Gio } = imports.gi;
|
||||
const encoder = new TextEncoder();
|
||||
const decoder = new TextDecoder();
|
||||
import { OpenSettings } from "apps/settings/main.ts";
|
||||
import { enableClickThrough } from "./misc/clickthrough.js";
|
||||
import { RoundedCorner } from "./misc/cairo_roundedcorner.js";
|
||||
import { Client, Workspace } from "types/service/hyprland.js";
|
||||
const { Box, Button, EventBox } = Widget;
|
||||
import Button from "types/widgets/button.js";
|
||||
import Icon from "types/widgets/icon.js";
|
||||
import { FileEnumerator, FileInfo } from "types/@girs/gio-2.0/gio-2.0.cjs";
|
||||
const mpris = await Service.import("mpris");
|
||||
@@ -19,20 +18,12 @@ import Gtk from "gi://Gtk?version=3.0";
|
||||
import { MaterialIcon } from "icons.js";
|
||||
import config from "services/configuration.ts";
|
||||
import { toggleAppsWindow, toggleMediaWindow } from "./sideleft/main.js";
|
||||
import { Variable as VariableType } from "types/variable";
|
||||
|
||||
|
||||
function checkKeymap() {
|
||||
const layout = Utils.execAsync(`hyprctl devices -j | jq -r '.keyboards[] | select(.main == true) | .active_keymap' | tail -n1 | cut -c1-2 | tr 'A-Z' 'a-z'`)
|
||||
.then(out => { return out })
|
||||
.catch(err => { print(err); return "en" });
|
||||
return layout;
|
||||
}
|
||||
|
||||
const keyboard_layout = Variable("en")
|
||||
keyboard_layout.setValue(await checkKeymap())
|
||||
const keyboard_layout = Variable("none");
|
||||
hyprland.connect("keyboard-layout", (hyprland, keyboardname, layoutname) => {
|
||||
keyboard_layout.setValue(layoutname.trim().toLowerCase().substr(0, 2))
|
||||
})
|
||||
keyboard_layout.setValue(layoutname.trim().toLowerCase().substr(0, 2));
|
||||
});
|
||||
|
||||
const MATERIAL_SYMBOL_SIGNAL_STRENGTH = {
|
||||
"network-wireless-signal-excellent-symbolic": "signal_wifi_4_bar",
|
||||
@@ -42,13 +33,26 @@ const MATERIAL_SYMBOL_SIGNAL_STRENGTH = {
|
||||
"network-wireless-signal-none-symbolic": "signal_wifi_0_bar"
|
||||
};
|
||||
|
||||
const time = Variable("", {
|
||||
poll: [1000, 'date "+%I:%M %p"']
|
||||
});
|
||||
const time = Variable("");
|
||||
const date = Variable("");
|
||||
|
||||
const date = Variable("", {
|
||||
poll: [1000, 'date "+%Y-%m-%d"']
|
||||
});
|
||||
function getCurrentDateAndTime() {
|
||||
const _date = new Date();
|
||||
|
||||
const year = _date.getFullYear();
|
||||
const month = String(_date.getMonth() + 1).padStart(2, "0");
|
||||
const day = String(_date.getDate()).padStart(2, "0");
|
||||
|
||||
const hours = String(_date.getHours()).padStart(2, "0");
|
||||
const minutes = String(_date.getMinutes()).padStart(2, "0");
|
||||
|
||||
const formattedDate = `${year}-${month}-${day}`;
|
||||
const formattedTime = `${hours}:${minutes}`;
|
||||
|
||||
if (time.value != formattedTime) time.setValue(formattedTime);
|
||||
if (date.value != formattedDate) date.setValue(formattedDate);
|
||||
}
|
||||
Utils.interval(1000, getCurrentDateAndTime);
|
||||
|
||||
function getIconNameFromClass(windowClass: string) {
|
||||
let formattedClass = windowClass.replace(/\s+/g, "-").toLowerCase();
|
||||
@@ -92,45 +96,72 @@ function getIconNameFromClass(windowClass: string) {
|
||||
return Utils.lookUpIcon(icon) ? icon : "image-missing";
|
||||
}
|
||||
|
||||
function workspaces_ids_are_equal(arr1: Workspace[] | undefined, arr2: Workspace[] | undefined): boolean {
|
||||
if (!arr1 || !arr2) return false;
|
||||
if (arr1.length !== arr2.length) return false;
|
||||
|
||||
return arr1.every((value, index) => {
|
||||
return value.id === arr2[index].id;
|
||||
});
|
||||
}
|
||||
|
||||
const dispatch = (ws: string) => hyprland.messageAsync(`dispatch workspace ${ws}`).catch(print);
|
||||
|
||||
function Workspaces() {
|
||||
const activeId = hyprland.active.workspace.bind("id");
|
||||
let workspaceButtons = new Map();
|
||||
let workspaceButtons = new Map<Number, any>();
|
||||
let _old_workspaces: Workspace[];
|
||||
const workspaceButtonsArray: VariableType<Button<any, any>[] | any> = Variable([]);
|
||||
|
||||
function createWorkspaceButton(id: Number) {
|
||||
const button = Widget.Button({
|
||||
return Widget.Button({
|
||||
on_clicked: () => dispatch(`${id}`),
|
||||
child: Widget.Label(`${id}`),
|
||||
class_name: activeId.as((i) => `${i === id ? "active" : ""}`)
|
||||
attribute: { id: id },
|
||||
class_name: "workspace"
|
||||
});
|
||||
return button;
|
||||
}
|
||||
|
||||
function updateWorkspaceButtons(workspaces: Workspace[]): Array<Button<any, any>> {
|
||||
function updateWorkspaceButtons() {
|
||||
const workspaces = hyprland.workspaces;
|
||||
if (workspaces_ids_are_equal(workspaces, _old_workspaces)) {
|
||||
return;
|
||||
}
|
||||
workspaces.sort((a, b) => a.id - b.id);
|
||||
|
||||
const updatedButtons = new Map();
|
||||
const updatedButtons = new Map<Number, any>();
|
||||
|
||||
workspaces.forEach(({ id }) => {
|
||||
if (workspaceButtons.has(id)) {
|
||||
updatedButtons.set(id, workspaceButtons.get(id));
|
||||
} else {
|
||||
updatedButtons.set(id, createWorkspaceButton(id));
|
||||
if (!workspaceButtons.has(id)) {
|
||||
workspaceButtons.set(id, createWorkspaceButton(id));
|
||||
}
|
||||
updatedButtons.set(id, workspaceButtons.get(id));
|
||||
});
|
||||
if (workspaceButtons != updatedButtons) workspaceButtons = updatedButtons;
|
||||
|
||||
return Array.from(workspaceButtons.values());
|
||||
workspaceButtons = updatedButtons;
|
||||
_old_workspaces = workspaces;
|
||||
workspaceButtonsArray.setValue(Array.from(workspaceButtons.values()));
|
||||
}
|
||||
|
||||
const workspaceButtonsArray = hyprland.bind("workspaces").as(updateWorkspaceButtons);
|
||||
function activeWorkspace() {
|
||||
workspaceButtons.forEach((workspace, key) => {
|
||||
workspace.toggleClassName("active", workspace.attribute.id == hyprland.active.workspace.id);
|
||||
});
|
||||
}
|
||||
|
||||
updateWorkspaceButtons();
|
||||
activeWorkspace();
|
||||
hyprland.connect("notify::workspaces", () => {
|
||||
activeWorkspace();
|
||||
updateWorkspaceButtons();
|
||||
});
|
||||
hyprland.connect("notify::active", () => {
|
||||
activeWorkspace();
|
||||
});
|
||||
|
||||
return Widget.EventBox({
|
||||
onScrollUp: () => dispatch("+1"),
|
||||
onScrollDown: () => dispatch("-1"),
|
||||
child: Widget.Box({
|
||||
children: workspaceButtonsArray,
|
||||
children: workspaceButtonsArray.bind(),
|
||||
class_name: "workspaces"
|
||||
})
|
||||
});
|
||||
@@ -222,7 +253,6 @@ function BatteryLabel() {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function SysTray() {
|
||||
return Widget.Box({
|
||||
class_name: "tray",
|
||||
@@ -360,21 +390,15 @@ function MediaPlayer() {
|
||||
return button;
|
||||
}
|
||||
|
||||
|
||||
function KeyboardLayout() {
|
||||
const widget = Widget.Button({
|
||||
const widget = Widget.Label({
|
||||
class_name: "keyboard",
|
||||
//visible: keyboard_layout.bind().as((c) => c != "none"),
|
||||
label: keyboard_layout.bind(),
|
||||
on_primary_click_release: () => {
|
||||
Utils.execAsync(`${GLib.get_home_dir()}/dotfiles/hypr/scripts/RunCMD.sh kb_changer`);
|
||||
},
|
||||
|
||||
visible: keyboard_layout.bind().as((c) => c != "none"),
|
||||
label: keyboard_layout.bind()
|
||||
});
|
||||
return widget;
|
||||
}
|
||||
|
||||
|
||||
function OpenSideBar() {
|
||||
const button = Widget.Button({
|
||||
class_name: "filled_tonal_button",
|
||||
@@ -402,29 +426,30 @@ function TaskBar() {
|
||||
const currentClientIds = clients.map((client) => client.pid);
|
||||
globalWidgets = globalWidgets.filter((widget) => currentClientIds.includes(widget.attribute.pid));
|
||||
|
||||
clients.forEach((item) => {
|
||||
let widget = globalWidgets.find((w) => w.attribute.pid === item.pid);
|
||||
if (item.class == "kitty") {
|
||||
return;
|
||||
}
|
||||
clients.forEach((client) => {
|
||||
if (client.class === "Alacritty") return;
|
||||
|
||||
let widget = globalWidgets.find((w) => w.attribute.pid === client.pid);
|
||||
if (widget) {
|
||||
widget.tooltip_markup = item.title;
|
||||
widget.tooltip_markup = client.title;
|
||||
} else {
|
||||
let icon: string | undefined;
|
||||
if (item.class == "com.github.Aylur.ags") {
|
||||
if (item.initialTitle == "Settings") {
|
||||
icon = "emblem-system-symbolic";
|
||||
} else if (item.initialTitle == "Emoji Picker") {
|
||||
icon = "face-smile-symbolic";
|
||||
}
|
||||
} else icon = getIconNameFromClass(item.class);
|
||||
if (client.class === "com.github.Aylur.ags") {
|
||||
icon =
|
||||
client.initialTitle === "Settings"
|
||||
? "emblem-system-symbolic"
|
||||
: client.initialTitle === "Emoji Picker"
|
||||
? "face-smile-symbolic"
|
||||
: undefined;
|
||||
} else {
|
||||
icon = getIconNameFromClass(client.class);
|
||||
}
|
||||
|
||||
widget = Widget.Button({
|
||||
attribute: { pid: item.pid },
|
||||
child: Widget.Icon({ icon: icon }),
|
||||
tooltip_markup: item.title,
|
||||
on_clicked: (self) => {
|
||||
focus(item);
|
||||
}
|
||||
attribute: { pid: client.pid },
|
||||
child: Widget.Icon({ icon }),
|
||||
tooltip_markup: client.title,
|
||||
on_clicked: () => focus(client)
|
||||
});
|
||||
globalWidgets.push(widget);
|
||||
}
|
||||
@@ -510,7 +535,7 @@ function Right() {
|
||||
class_name: "modules-right",
|
||||
hpack: "end",
|
||||
spacing: 8,
|
||||
children: [/*Recorder,*/ volumeIndicator(), KeyboardLayout(), BatteryLabel(), SysTray(), Applets(), Clock(), OpenSideBar()]
|
||||
children: [volumeIndicator(), KeyboardLayout(), BatteryLabel(), SysTray(), Applets(), Clock(), OpenSideBar()]
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { weather } from "variables";
|
||||
import { MaterialIcon } from "icons.ts";
|
||||
import { type WeatherJson } from "variables";
|
||||
import { Variable as VariableType } from "types/variable";
|
||||
import configuration from "services/configuration.ts";
|
||||
import { sideleft } from "./main";
|
||||
|
||||
// prettier-ignore
|
||||
const MATERIAL_ICONS = {
|
||||
@@ -15,6 +17,28 @@ const MATERIAL_ICONS = {
|
||||
"13d": "weather_snowy", "13n": "weather_snowy",
|
||||
"40d": "air", "40n": "air"
|
||||
};
|
||||
|
||||
// @ts-expect-error
|
||||
export const weather: VariableType<WeatherJson> = Variable({ no_data: true });
|
||||
const reload = () => {
|
||||
if (configuration.config.weather != "" && configuration.config.weather_location_id != "")
|
||||
Utils.execAsync(
|
||||
`${App.configDir}/scripts/weather.sh weather ${configuration.config.weather} ${configuration.config.weather_location_id}`
|
||||
)
|
||||
.then((out) => {
|
||||
weather.setValue(JSON.parse(out));
|
||||
})
|
||||
.catch(print);
|
||||
};
|
||||
const _reload = () => {
|
||||
if (sideleft?.visible) reload();
|
||||
};
|
||||
Utils.interval(1500, _reload);
|
||||
configuration.connect("changed", _reload);
|
||||
App.connect("window-toggled", (_, window_name, visible) => {
|
||||
if (window_name == "sideleft" && visible) reload();
|
||||
});
|
||||
|
||||
const ICON_COLORS = {
|
||||
mist: "#B0BEC5",
|
||||
clear_day: "#FFEB3B",
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
const notifications = await Service.import("notifications");
|
||||
const network = await Service.import("network");
|
||||
const bluetooth = await Service.import("bluetooth");
|
||||
import { OpenSettings } from "apps/settings/main.ts";
|
||||
import { WINDOW_NAME } from "./main.ts";
|
||||
import { bluetooth_enabled, idle_inhibitor, night_light, theme } from "variables.ts";
|
||||
import { idle_inhibitor, night_light, theme } from "variables.ts";
|
||||
import { MaterialIcon } from "icons.ts";
|
||||
|
||||
import Gtk from "gi://Gtk?version=3.0";
|
||||
@@ -10,32 +11,32 @@ import Gtk from "gi://Gtk?version=3.0";
|
||||
const currentPage = Variable(0);
|
||||
|
||||
function WifiIndicator() {
|
||||
const ssid = Widget.Label({
|
||||
label: "Unknown",
|
||||
visible: false,
|
||||
class_name: "ssid",
|
||||
xalign: 0,
|
||||
vpack: "center",
|
||||
truncate: "end"
|
||||
});
|
||||
const name = Widget.Box({
|
||||
vertical: true,
|
||||
vpack: "center",
|
||||
children: [
|
||||
Widget.Box([
|
||||
Widget.Label({
|
||||
label: "Internet",
|
||||
vpack: "center"
|
||||
})
|
||||
]),
|
||||
ssid
|
||||
]
|
||||
});
|
||||
return Widget.Box({
|
||||
css: "padding-left: 15px; padding-right: 15px; padding-top: 5px; padding-bottom: 5px;",
|
||||
children: [
|
||||
MaterialIcon("signal_wifi_4_bar", "20px"),
|
||||
Widget.Box({
|
||||
visible: network.wifi.bind("enabled"),
|
||||
orientation: Gtk.Orientation.VERTICAL,
|
||||
children: [
|
||||
Widget.Box([
|
||||
Widget.Label({
|
||||
label: "Internet"
|
||||
})
|
||||
]),
|
||||
Widget.Label({
|
||||
label: network.wifi.bind("ssid").as((ssid) => ssid || "Unknown"),
|
||||
class_name: "ssid",
|
||||
xalign: 0,
|
||||
vpack: "center",
|
||||
truncate: "end"
|
||||
})
|
||||
]
|
||||
}),
|
||||
Widget.Label({
|
||||
visible: network.wifi.bind("enabled").as((enabled) => !enabled),
|
||||
label: "Internet"
|
||||
}),
|
||||
name,
|
||||
Widget.Box({
|
||||
hpack: "end",
|
||||
hexpand: true,
|
||||
@@ -43,7 +44,13 @@ function WifiIndicator() {
|
||||
class_name: "material_icon icon arrow"
|
||||
})
|
||||
})
|
||||
]
|
||||
],
|
||||
setup: (self) => {
|
||||
self.hook(network, () => {
|
||||
ssid.label = network.wifi.ssid || "Unknown";
|
||||
ssid.visible = !!network.wifi.ssid;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -106,9 +113,7 @@ function Page1() {
|
||||
children: [
|
||||
Widget.Button({
|
||||
hexpand: true,
|
||||
class_name: network.wifi
|
||||
.bind("enabled")
|
||||
.as((enabled) => (enabled ? "management_button active" : "management_button")),
|
||||
class_name: "management_button",
|
||||
child: NetworkIndicator(),
|
||||
on_primary_click_release: () => {
|
||||
network.toggleWifi();
|
||||
@@ -116,26 +121,33 @@ function Page1() {
|
||||
on_secondary_click_release: () => {
|
||||
App.closeWindow(WINDOW_NAME);
|
||||
OpenSettings("network");
|
||||
},
|
||||
setup: (self) => {
|
||||
if (network.wifi)
|
||||
self.hook(network.wifi, () => {
|
||||
self.toggleClassName("active", network.wifi.enabled);
|
||||
});
|
||||
}
|
||||
}),
|
||||
Widget.Button({
|
||||
hexpand: true,
|
||||
class_name: bluetooth_enabled
|
||||
.bind()
|
||||
.as((state) => (state.trim() == "yes" ? "management_button active" : "management_button")),
|
||||
class_name: "management_button",
|
||||
child: IconAndName({
|
||||
label: "Bluetooth",
|
||||
icon: "bluetooth",
|
||||
arrow: true
|
||||
}),
|
||||
on_primary_click_release: () => {
|
||||
Utils.execAsync(`${App.configDir}/scripts/bluetooth.sh --toggle`).then((out) => {
|
||||
bluetooth_enabled.setValue(out);
|
||||
});
|
||||
bluetooth.toggle();
|
||||
},
|
||||
on_secondary_click_release: () => {
|
||||
OpenSettings("bluetooth");
|
||||
App.closeWindow(WINDOW_NAME);
|
||||
},
|
||||
setup: (self) => {
|
||||
self.hook(bluetooth, () => {
|
||||
self.toggleClassName("active", bluetooth.enabled);
|
||||
});
|
||||
}
|
||||
})
|
||||
]
|
||||
@@ -147,9 +159,7 @@ function Page1() {
|
||||
children: [
|
||||
Widget.Button({
|
||||
hexpand: true,
|
||||
class_name: theme.bind().as((str) => {
|
||||
return str.trim() == "dark" ? "management_button active" : "management_button";
|
||||
}),
|
||||
class_name: "management_button",
|
||||
on_clicked: () => {
|
||||
Utils.execAsync(`${App.configDir}/scripts/dark-theme.sh --toggle`).catch(print);
|
||||
theme.setValue(theme.value.trim() == "dark" ? "light" : "dark");
|
||||
@@ -157,22 +167,31 @@ function Page1() {
|
||||
child: IconAndName({
|
||||
label: "Dark theme",
|
||||
icon: "contrast"
|
||||
})
|
||||
}),
|
||||
setup: (self) => {
|
||||
self.hook(theme, () => {
|
||||
self.toggleClassName("active", theme.value.trim() == "dark");
|
||||
});
|
||||
}
|
||||
}),
|
||||
Widget.Button({
|
||||
hexpand: true,
|
||||
class_name: notifications.bind("dnd").as((bool) => {
|
||||
return bool ? "management_button active" : "management_button";
|
||||
}),
|
||||
class_name: "management_button",
|
||||
on_clicked: () => {
|
||||
notifications.dnd = notifications.dnd ? false : true;
|
||||
notifications.dnd = !notifications.dnd;
|
||||
},
|
||||
child: IconAndName({
|
||||
label: "Do Not Disturb",
|
||||
icon: notifications
|
||||
.bind("dnd")
|
||||
.as((bool) => (bool ? "do_not_disturb_on" : "do_not_disturb_off"))
|
||||
})
|
||||
icon: "do_not_disturb_off"
|
||||
}),
|
||||
setup: (self) => {
|
||||
notifications.connect("notify::dnd", (_) => {
|
||||
self.toggleClassName("active", notifications.dnd);
|
||||
self.child.children[0].label = notifications.dnd
|
||||
? "do_not_disturb_on"
|
||||
: "do_not_disturb_off";
|
||||
});
|
||||
}
|
||||
})
|
||||
]
|
||||
}),
|
||||
@@ -183,9 +202,7 @@ function Page1() {
|
||||
children: [
|
||||
Widget.Button({
|
||||
hexpand: true,
|
||||
class_name: idle_inhibitor
|
||||
.bind()
|
||||
.as((bool) => (bool ? "management_button active" : "management_button")),
|
||||
class_name: "management_button",
|
||||
child: IconAndName({
|
||||
label: "Idle inhibitor",
|
||||
icon: "schedule"
|
||||
@@ -200,15 +217,16 @@ function Page1() {
|
||||
]).catch(print);
|
||||
else Utils.execAsync("pkill -f wayland-idle-inhibitor.py").catch(print);
|
||||
},
|
||||
setup: () => {
|
||||
setup: (self) => {
|
||||
idle_inhibitor.setValue(!!Utils.exec("pidof wayland-idle-inhibitor.py"));
|
||||
self.hook(idle_inhibitor, () => {
|
||||
self.toggleClassName("active", idle_inhibitor.value);
|
||||
});
|
||||
}
|
||||
}),
|
||||
Widget.Button({
|
||||
hexpand: true,
|
||||
class_name: night_light
|
||||
.bind()
|
||||
.as((mode) => (mode ? "management_button active" : "management_button")),
|
||||
class_name: "management_button",
|
||||
child: IconAndName({
|
||||
label: "Night Light",
|
||||
icon: "nightlight"
|
||||
@@ -217,20 +235,16 @@ function Page1() {
|
||||
night_light.setValue(!night_light.value);
|
||||
Utils.execAsync(`${App.configDir}/scripts/night-light.sh --toggle`)
|
||||
.then((out) => {
|
||||
if (out.trim() == "enabled") night_light.setValue(true);
|
||||
else if (out.trim() == "disabled") night_light.setValue(false);
|
||||
night_light.setValue(out.trim() == "enabled");
|
||||
})
|
||||
.catch((err) => {
|
||||
night_light.setValue(!night_light.value);
|
||||
});
|
||||
},
|
||||
setup: () => {
|
||||
Utils.execAsync(`${App.configDir}/scripts/night-light.sh --get`)
|
||||
.then((out) => {
|
||||
if (out.trim() == "enabled") night_light.setValue(true);
|
||||
else if (out.trim() == "disabled") night_light.setValue(false);
|
||||
})
|
||||
.catch(print);
|
||||
setup: (self) => {
|
||||
self.hook(night_light, () => {
|
||||
self.toggleClassName("active", night_light.value);
|
||||
});
|
||||
}
|
||||
})
|
||||
]
|
||||
@@ -288,8 +302,13 @@ const createDotButton = (index: number) =>
|
||||
Widget.Button({
|
||||
label: "●",
|
||||
onClicked: () => currentPage.setValue(index),
|
||||
class_name: currentPage.bind().as((v) => (v == index ? "dotbutton active" : "dotbutton")),
|
||||
hexpand: false
|
||||
class_name: "dotbutton",
|
||||
hexpand: false,
|
||||
setup: (self) => {
|
||||
self.hook(currentPage, () => {
|
||||
self.toggleClassName("active", currentPage.value == index);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
export function Management() {
|
||||
|
||||
@@ -3,7 +3,6 @@ import { SystemBox } from "./system.ts";
|
||||
let shown = Variable("Messages");
|
||||
import Gtk from "gi://Gtk?version=3.0";
|
||||
import { MaterialIcon } from "icons.ts";
|
||||
import { enableClickThrough } from "modules/misc/clickthrough.js";
|
||||
|
||||
type ButtonType = {
|
||||
page: string;
|
||||
@@ -13,8 +12,9 @@ type ButtonType = {
|
||||
|
||||
function Button({ page, label, icon }: ButtonType) {
|
||||
return Widget.Button({
|
||||
class_name: shown.bind().as((_page) => (_page == page ? "navigation_button active" : "navigation_button")),
|
||||
class_name: "navigation_button",
|
||||
hexpand: true,
|
||||
attribute: { page: page },
|
||||
child: Widget.Box({
|
||||
orientation: Gtk.Orientation.VERTICAL,
|
||||
class_name: "container_outer",
|
||||
@@ -72,7 +72,14 @@ export function Navigation() {
|
||||
label: "System",
|
||||
icon: "info"
|
||||
})
|
||||
]
|
||||
],
|
||||
setup: (self) => {
|
||||
self.hook(shown, () => {
|
||||
for (const button of self.children) {
|
||||
button.toggleClassName("active", button.attribute.page == shown.value);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
return Widget.Box({
|
||||
vexpand: true,
|
||||
|
||||
@@ -1,15 +1,8 @@
|
||||
import {
|
||||
cpu_cores,
|
||||
cpu_name,
|
||||
kernel_name,
|
||||
amount_of_ram,
|
||||
gpu_name,
|
||||
cur_uptime,
|
||||
current_brightness
|
||||
} from "variables.ts";
|
||||
import { cpu_cores, cpu_name, kernel_name, amount_of_ram, gpu_name, cur_uptime } from "variables.ts";
|
||||
import Gtk from "gi://Gtk?version=3.0";
|
||||
import { Variable as VariableType } from "types/variable";
|
||||
import backlight_service from "services/backlight.ts";
|
||||
import { sideright } from "./main";
|
||||
|
||||
type InfoType = {
|
||||
cpu: string;
|
||||
@@ -51,23 +44,40 @@ async function SystemInfo(): Promise<InfoType> {
|
||||
};
|
||||
}
|
||||
|
||||
const usage = Variable(
|
||||
{
|
||||
cpu: "0",
|
||||
ram: "0",
|
||||
swap: "0",
|
||||
cpu_temp: "0"
|
||||
} as unknown as Promise<InfoType>,
|
||||
{
|
||||
poll: [
|
||||
1000,
|
||||
async () => {
|
||||
const result = await SystemInfo().then((result) => result);
|
||||
return result;
|
||||
}
|
||||
]
|
||||
}
|
||||
);
|
||||
function checkBrightness() {
|
||||
const get = Utils.execAsync(`${App.configDir}/scripts/brightness.sh --get`)
|
||||
.then((out) => Number(out.trim()))
|
||||
.catch(print);
|
||||
return get;
|
||||
}
|
||||
|
||||
export const current_brightness = Variable(100, {
|
||||
poll: [
|
||||
500,
|
||||
() => {
|
||||
if (sideright?.visible) return checkBrightness();
|
||||
else return current_brightness?.value || 100;
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
const usage_default = {
|
||||
cpu: "0",
|
||||
ram: "0",
|
||||
swap: "0",
|
||||
cpu_temp: "0"
|
||||
};
|
||||
|
||||
const usage = Variable(usage_default);
|
||||
Utils.interval(1000, async () => {
|
||||
Utils.idle(() => {
|
||||
if (sideright?.visible) {
|
||||
SystemInfo().then((result) => {
|
||||
usage.setValue(result);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const Usage = (name: string, var_name: keyof InfoType, class_name: string | undefined) => {
|
||||
const usage_progress_bar = Widget.ProgressBar({
|
||||
@@ -132,7 +142,7 @@ export function SystemBox() {
|
||||
draw_value: false,
|
||||
class_name: "system_scale backlight",
|
||||
// @ts-ignore
|
||||
value: backlight_service.bind("screen_value").as(n => n * 100),
|
||||
value: backlight_service.bind("screen_value").as((n) => n * 100),
|
||||
on_change: (self) => {
|
||||
backlight_service.screen_value = self.value / 100;
|
||||
},
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
#!/bin/bash
|
||||
# I tried to make it smooth, but it didn't work
|
||||
|
||||
wl_gammarelay() {
|
||||
if ! busctl --user list | grep rs.wl.gammarelay; then
|
||||
systemctl --user restart wl-gammarelay.service
|
||||
fi
|
||||
}
|
||||
wl_gammarelay >/dev/null
|
||||
|
||||
LOCKFILE=/tmp/brightness.lock
|
||||
|
||||
@@ -9,19 +13,12 @@ get_brightness() {
|
||||
}
|
||||
|
||||
set_brightness() {
|
||||
# if [ -e "$LOCKFILE" ] && kill -0 "$(cat $LOCKFILE)"; then
|
||||
# exit 0
|
||||
# fi
|
||||
# trap "rm -f $LOCKFILE; exit" INT TERM EXIT
|
||||
# echo $$ > "$LOCKFILE"
|
||||
if (( $(echo "$1 < 0.05" | bc -l) )); then
|
||||
if (($(echo "$1 < 0.05" | bc -l))); then
|
||||
BRIGHTNESS=0.05
|
||||
else
|
||||
BRIGHTNESS=$1
|
||||
fi
|
||||
busctl --user -- set-property rs.wl-gammarelay / rs.wl.gammarelay Brightness d $BRIGHTNESS
|
||||
# rm -f "$LOCKFILE"
|
||||
# trap - INT TERM EXIT
|
||||
}
|
||||
|
||||
set() {
|
||||
@@ -46,6 +43,6 @@ get() {
|
||||
|
||||
if [[ "$1" == "--set" ]]; then
|
||||
set $2
|
||||
elif [[ "$1" == "--get" ]]; then
|
||||
elif [[ "$1" == "--get" ]]; then
|
||||
get
|
||||
fi
|
||||
@@ -15,12 +15,15 @@ variables_dict: dict[str, str] = {}
|
||||
|
||||
category_pattern = r"\n#! @(\w+): (.+)"
|
||||
variable_pattern = r"\n\$(\w+)\s*=\s*(.*)"
|
||||
text = ""
|
||||
bindings: dict[str, dict[str, str]] = {}
|
||||
|
||||
|
||||
def extract_category_and_description(line: str) -> tuple[str | None, str | None, tuple | None]:
|
||||
pattern2 = r'bind\s*=\s*.*! @description:\s*"((?:[^"]|\\")*)"\s*;\s*@(\w+);\s*@replace\s*"([^"]*)"\s*>\s*"([^"]*)";.*'
|
||||
pattern = r'bind\s*=\s*.*! @description:\s*"((?:[^"]|\\")*)"\s*;\s*@(\w+);.*'
|
||||
def extract_category_and_description(
|
||||
line: str
|
||||
) -> tuple[str | None, str | None, tuple | None]:
|
||||
pattern2 = r'bind\s*=\s*.*! @description:\s*"((?:[^"]|\\")*)"\s*;\s*@(\w+);\s*@replace\s*"([^"]*)"\s*>\s*"([^"]*)";.*' # noqa
|
||||
pattern = r'bind\s*=\s*.*! @description:\s*"((?:[^"]|\\")*)"\s*;\s*@(\w+);.*' # noqa
|
||||
|
||||
match = re.search(pattern, line)
|
||||
match2 = re.search(pattern2, line)
|
||||
@@ -66,11 +69,22 @@ def load_categories(content: str):
|
||||
|
||||
for key, value in matches:
|
||||
categories_dict[key] = value
|
||||
if value not in bindings:
|
||||
bindings[value] = {}
|
||||
bindings[value] = {}
|
||||
return content
|
||||
|
||||
|
||||
def load_sources(file: str):
|
||||
with open(file) as f:
|
||||
content = f.read()
|
||||
for line in content.split("\n"):
|
||||
line = line.replace(" = ", "=")
|
||||
if not line.startswith("source="):
|
||||
continue
|
||||
file = os.path.expanduser(line.replace("source=", ""))
|
||||
if file not in files:
|
||||
files.append(file)
|
||||
|
||||
|
||||
def load_variables(content: str):
|
||||
matches = re.findall(variable_pattern, content)
|
||||
|
||||
@@ -80,12 +94,13 @@ def load_variables(content: str):
|
||||
content_lines = content.split("\n")
|
||||
content_lines = [
|
||||
line for line in content_lines if not line.startswith("$")
|
||||
]
|
||||
]
|
||||
content = "\n".join(content_lines)
|
||||
return content
|
||||
|
||||
|
||||
def load_file(file: str):
|
||||
global text
|
||||
with open(file) as f:
|
||||
content = f.read()
|
||||
|
||||
@@ -94,34 +109,42 @@ def load_file(file: str):
|
||||
|
||||
# remove comments
|
||||
content = re.sub(r'^#.*$\n', '', content, flags=re.MULTILINE)
|
||||
return content
|
||||
text += f"\n{content}"
|
||||
|
||||
|
||||
def load():
|
||||
global bindings
|
||||
global text, bindings
|
||||
text = re.sub(r"\$(\w+)", replace_variable, text)
|
||||
for line in text.split('\n'):
|
||||
if not line.replace(" ", "").startswith("bind="):
|
||||
continue
|
||||
|
||||
description, category, replace = extract_category_and_description(line)
|
||||
if category is None or description is None:
|
||||
continue
|
||||
|
||||
binding = extract_binding(line)
|
||||
if binding is None:
|
||||
continue
|
||||
|
||||
category_name = categories_dict[category]
|
||||
if category_name not in bindings:
|
||||
bindings[category_name] = {}
|
||||
|
||||
if replace is not None:
|
||||
binding = binding.replace(*replace)
|
||||
|
||||
bindings[category_name][binding.strip()] = description.strip()
|
||||
|
||||
|
||||
while True:
|
||||
old_list = files
|
||||
for file in files:
|
||||
content = load_file(file)
|
||||
for line in content.split('\n'):
|
||||
if not line.replace(" ", "").startswith("bind="):
|
||||
continue
|
||||
|
||||
description, category, replace = extract_category_and_description(line)
|
||||
if category is None or description is None:
|
||||
continue
|
||||
|
||||
binding = extract_binding(line)
|
||||
if binding is None:
|
||||
continue
|
||||
|
||||
category_name = categories_dict[category]
|
||||
if category_name not in bindings:
|
||||
bindings[category_name] = {}
|
||||
|
||||
if replace is not None:
|
||||
binding = binding.replace(*replace)
|
||||
|
||||
bindings[category_name][binding.strip()] = description.strip()
|
||||
|
||||
load_sources(file)
|
||||
if old_list == files:
|
||||
break
|
||||
|
||||
for file in files:
|
||||
load_file(file)
|
||||
load()
|
||||
print(json.dumps(bindings, indent=4))
|
||||
+7
-31
@@ -1,6 +1,4 @@
|
||||
import { Variable as VariableType } from "types/variable";
|
||||
const GLib = imports.gi.GLib;
|
||||
import configuration from "services/configuration.ts";
|
||||
|
||||
export type WeatherJson = {
|
||||
coord: {
|
||||
@@ -61,32 +59,21 @@ export type WeatherJson = {
|
||||
export const theme = Variable("dark");
|
||||
export const main_color = Variable("#000000");
|
||||
export const current_wallpaper = Variable(`${GLib.get_home_dir()}/Pictures/wallpapers/default.png`);
|
||||
// @ts-expect-error
|
||||
export const weather: VariableType<WeatherJson> = Variable({ no_data: true });
|
||||
const reload = () => {
|
||||
if (configuration.config.weather != "" && configuration.config.weather_location_id != "")
|
||||
Utils.execAsync(
|
||||
`${App.configDir}/scripts/weather.sh weather ${configuration.config.weather} ${configuration.config.weather_location_id}`
|
||||
)
|
||||
.then((out) => {
|
||||
weather.setValue(JSON.parse(out));
|
||||
})
|
||||
.catch(print);
|
||||
};
|
||||
Utils.interval(150, reload);
|
||||
configuration.connect("changed", reload);
|
||||
|
||||
export const idle_inhibitor = Variable(false);
|
||||
export const cur_uptime = Variable("error");
|
||||
Utils.interval(5000, () => {
|
||||
Utils.interval(60000, () => {
|
||||
Utils.execAsync(`${App.configDir}/scripts/system.sh --uptime`)
|
||||
.then((out) => cur_uptime.setValue(out))
|
||||
.catch(print);
|
||||
});
|
||||
export const night_light = Variable(false);
|
||||
export const bluetooth_enabled = Variable("off", {
|
||||
poll: [1000, `${App.configDir}/scripts/bluetooth.sh --get`]
|
||||
});
|
||||
Utils.execAsync(`${App.configDir}/scripts/night-light.sh --get`)
|
||||
.then((out) => {
|
||||
if (out.trim() == "enabled") night_light.setValue(true);
|
||||
else if (out.trim() == "disabled") night_light.setValue(false);
|
||||
})
|
||||
.catch(print);
|
||||
export const theme_settings = {
|
||||
color: Variable("none"),
|
||||
scheme: Variable("tonalSpot")
|
||||
@@ -103,17 +90,6 @@ export const current_os = await Utils.execAsync(`${App.configDir}/scripts/system
|
||||
export const settings_file = `${GLib.get_home_dir()}/dotfiles/.settings/settings.json`;
|
||||
export const wallpaper_cache_file = `${GLib.get_home_dir()}/.cache/current_wallpaper`;
|
||||
|
||||
function checkBrightness() {
|
||||
const get = Utils.execAsync(`${App.configDir}/scripts/brightness.sh --get`)
|
||||
.then((out) => Number(out.trim()))
|
||||
.catch(print);
|
||||
return get;
|
||||
}
|
||||
|
||||
export const current_brightness = Variable(100, {
|
||||
poll: [500, checkBrightness]
|
||||
});
|
||||
|
||||
function readSettingsFile() {
|
||||
Utils.readFileAsync(settings_file)
|
||||
.then((out) => {
|
||||
|
||||
Reference in new issue
Block a user