This commit is contained in:
sankalp committed 2024-07-01 14:51:10 +05:45
1 parent 6b14451fe6
commit 1d69e6c2ce
17 files changed
+440 -189

No files matched your search

+78
View File
@@ -0,0 +1,78 @@
const apps_script = `python -OOO ${App.configDir}/scripts/apps.py`;
import { MaterialIcon } from "icons";
const Row = (app: string, title: string, icon: string) => Widget.EventBox({
class_name: "row",
on_primary_click: self => {
self.child.children[1]!.activate()
},
child: Widget.Box({
class_name: "row",
vpack: "start",
children: [
MaterialIcon(icon),
Widget.Box({
vertical: true,
hexpand: true,
vpack: "center",
children: [
Widget.Label({
hpack: "start",
class_name: "title",
label: title
})
]
}),
Widget.Entry({
hpack: "end",
css: "border: 2px solid; border-color: transparent;",
attribute: {
"get": (self) => {
Utils.execAsync(`${apps_script} --get ${app}`)
.then((out) => {
self.text = out;
})
.catch(print)
}
},
on_accept: self => {
Utils.execAsync(`${apps_script} --${app} ${self.text}`)
.then(() => {
self.css = "border: 2px solid; border-color: #66BB6A;"
Utils.timeout(1000, () => {
self.css = "border: 2px solid; border-color: transparent"
})
})
.catch(() => {
self.css = "border: 2px solid; border-color: @error;"
Utils.timeout(1000, () => {
self.css = "border: 2px solid; border-color: transparent"
})
self.attribute.get(self)
})
},
setup: (self) => {
self.attribute.get(self)
}
})
]
})
})
export function Apps() {
const box = Widget.Box({
vertical: true,
children: [
Row("browser", "Browser", "web"),
Row("editor", "Editor", "edit"),
Row("filemanager", "File manager", "folder"),
Row("terminal", "Terminal", "terminal")
],
})
return Widget.Scrollable({
hscroll: "never",
child: box,
vexpand: true
})
}
+11 -7
View File
@@ -3,7 +3,8 @@ import { Network } from "./network";
import { Bluetooth } from "./bluetooth";
import { Wallpapers } from "./wallpapers";
import { Info } from "./info";
import { Widget as WidgetType } from "types/widgets/widget";
import { Apps } from "./apps";
import { MaterialIcon } from "icons";
const hyprland = await Service.import("hyprland")
import Gtk from "gi://Gtk?version=3.0"
@@ -42,14 +43,15 @@ function Settings(cur_tab: string) {
"network": Page(Network(), "Network"),
"bluetooth": Page(Bluetooth(), "Bluetooth"),
"wallpaper": Page(Wallpapers(), "Wallpapers"),
"info": Page(Info(), "Info")
"info": Page(Info(), "Info"),
"apps": Page(Apps(), "Apps")
}
})
const Row = (name: string, label: string, icon: string = "image-missing") => Widget.Button({
on_clicked: () => { current_tab.setValue(name) },
child: Widget.Box({
children: [
Widget.Icon(icon),
MaterialIcon(icon),
Widget.Label(label)
]
}),
@@ -61,12 +63,14 @@ function Settings(cur_tab: string) {
class_name: "sidebar",
spacing: 2,
children: [
Row("network", "Network", "network-wireless-signal-excellent-symbolic"),
Row("bluetooth", "Bluetooth", "bluetooth-active-symbolic"),
Row("network", "Network", "signal_wifi_4_bar"),
Row("bluetooth", "Bluetooth", "bluetooth"),
Widget.Separator(),
Row("wallpaper", "Wallpapers", "folder-pictures-symbolic"),
Row("wallpaper", "Wallpapers", "image"),
Widget.Separator(),
Row("info", "Info", "dialog-information-symbolic"),
Row("apps", "Apps", "grid_view"),
Widget.Separator(),
Row("info", "Info", "info")
]
})
return Widget.Box({
+13 -4
View File
@@ -1,8 +1,17 @@
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 MATERIAL_SYMBOL_SIGNAL_STRENGTH = {
'network-wireless-signal-excellent-symbolic': "signal_wifi_4_bar",
'network-wireless-signal-good-symbolic': "network_wifi_3_bar",
'network-wireless-signal-ok-symbolic': "network_wifi_2_bar",
'network-wireless-signal-weak-symbolic': "network_wifi_1_bar",
'network-wireless-signal-none-symbolic': "signal_wifi_0_bar",
}
type AccessPoint = {
bssid: string | null;
address: string | null;
@@ -70,10 +79,10 @@ const WifiNetwork = (access_point: AccessPoint) => {
child: Widget.Box({
class_name: "wifi_network_box",
children: [
Widget.Icon({
icon: access_point.iconName,
size: 20
}),
MaterialIcon(
MATERIAL_SYMBOL_SIGNAL_STRENGTH[access_point.iconName!],
"20px"
),
// @ts-ignore
Widget.Box({
vertical: true,
+6
View File
@@ -0,0 +1,6 @@
{
"browser": "firefox",
"editor": "nvim",
"filemanager": "thunar",
"terminal": "kitty"
}
File renamed without changes.
+12
View File
@@ -0,0 +1,12 @@
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,
class_name: "icon material_icon",
css: `font-size: ${size};`,
hpack: "center",
vpack: "center",
...props
})
+33 -34
View File
@@ -17,6 +17,7 @@ const mpris = await Service.import("mpris")
const bluetooth = await Service.import("bluetooth")
const { Box, Button, EventBox } = Widget;
import Gtk from "gi://Gtk?version=3.0"
import { MaterialIcon } from "icons.js"
function checkKeymap() {
@@ -32,6 +33,14 @@ hyprland.connect("keyboard-layout", (hyprland, keyboardname, layoutname) => {
keyboard_layout.setValue(layoutname.trim().toLowerCase().substr(0, 2))
})
const MATERIAL_SYMBOL_SIGNAL_STRENGTH = {
'network-wireless-signal-excellent-symbolic': "signal_wifi_4_bar",
'network-wireless-signal-good-symbolic': "network_wifi_3_bar",
'network-wireless-signal-ok-symbolic': "network_wifi_2_bar",
'network-wireless-signal-weak-symbolic': "network_wifi_1_bar",
'network-wireless-signal-none-symbolic': "signal_wifi_0_bar",
}
const time = Variable("", {
poll: [1000, 'date "+%I:%M %p"'],
})
@@ -246,9 +255,7 @@ function AppLauncher() {
on_clicked: () => {
App.toggleWindow("applauncher")
},
child: Widget.Label(
"\uf002"
)
child: MaterialIcon("search")
})
return button
@@ -256,9 +263,11 @@ function AppLauncher() {
function Wifi() {
return Widget.Button({
class_name: "bar_wifi icon",
class_name: "bar_wifi",
on_primary_click: () => {
OpenSettings("network")
},
@@ -270,25 +279,24 @@ function Wifi() {
Utils.execAsync("nm-connection-editor").catch(print)
}
},
child: Widget.Icon({
icon: "network-wireless-offline-symbolic"
}),
child: MaterialIcon("signal_wifi_off", "16px"),
tooltip_text: 'Disabled'
}).hook(network, self => {
if (network.wifi.enabled) {
self.tooltip_text = network.wifi.ssid || 'Unknown';
self.child.icon = network.wifi.icon_name;
self.child.label = MATERIAL_SYMBOL_SIGNAL_STRENGTH[network.wifi.icon_name] || "signal_wifi_off";
} else {
self.tooltip_text = 'Disabled'
self.child.icon = "network-wireless-offline-symbolic";
self.child.label = "signal_wifi_off";
}
})
}
function Bluetooth() {
return Widget.Button({
class_name: "bar_bluetooth icon",
class_name: "bar_bluetooth",
on_primary_click: () => {
OpenSettings("bluetooth")
},
@@ -300,14 +308,12 @@ function Bluetooth() {
Utils.execAsync("blueman-manager").catch(print)
}
},
child: Widget.Icon({
icon: "bluetooth-disabled-symbolic"
}),
child: MaterialIcon("bluetooth_disabled", "18px"),
}).hook(bluetooth, self => {
if (bluetooth.enabled) {
self.child.icon = "bluetooth-active-symbolic";
self.child.icon = "bluetooth";
} else {
self.child.icon = "bluetooth-disabled-symbolic";
self.child.icon = "bluetooth_disabled";
}
})
}
@@ -328,14 +334,11 @@ function MediaPlayer() {
class_name: "filled_tonal_button awesome_icon",
on_primary_click: () => {
App.toggleWindow("media")
// Utils.execAsync(["ags", "-t", "media"])
},
on_secondary_click: () => {
Utils.execAsync(["playerctl", "play-pause"]).catch(print)
},
child: Widget.Label(
""
),
child: MaterialIcon("play_circle"),
visible: false,
tooltip_text: "Unknown"
}).hook(mpris, self => {
@@ -375,7 +378,7 @@ function OpenSideBar() {
on_secondary_click: () => {
OpenSettings()
},
label: ""
child: MaterialIcon("dock_to_left")
})
return button
@@ -432,31 +435,27 @@ if (globalWidgets.length === 0) {
function volumeIndicator() {
return Widget.EventBox({
onScrollUp: () => {
audio.speaker.volume = Math.min(audio.speaker.volume + 0.05, 1);
},
onScrollDown: () => {
audio.speaker.volume = Math.max(audio.speaker.volume - 0.05, 0);
},
onScrollUp: () => audio.speaker.volume += 0.01,
onScrollDown: () => audio.speaker.volume -= 0.01,
class_name: "filled_tonal_button volume_box",
child: Widget.Button({
on_primary_click: () => Utils.execAsync("pavucontrol").catch(print),
on_secondary_click: () => audio.speaker.is_muted = !audio.speaker.is_muted,
child: Widget.Box({
children: [
Widget.Icon().hook(audio.speaker, self => {
MaterialIcon("volume_off", "20px").hook(audio.speaker, self => {
const vol = audio.speaker.volume * 100;
const icon = [
[101, 'overamplified'],
[67, 'high'],
[34, 'medium'],
[1, 'low'],
[0, 'muted'],
[101, 'sound_detection_loud_sound'],
[67, 'volume_up'],
[34, 'volume_down'],
[1, 'volume_mute'],
[0, 'volume_off'],
].find(([threshold]) => Number(threshold) <= vol)?.[1];
if (audio.speaker.is_muted)
self.icon = `audio-volume-muted-symbolic`;
self.label = "volume_off";
else
self.icon = `audio-volume-${icon}-symbolic`;
self.label = String(icon!);
self.tooltip_text = `Volume ${Math.floor(vol)}%`;
}),
Widget.Label({
+1 -1
View File
@@ -140,7 +140,7 @@ function Emoji({ width = 500, height = 500, spacing = 12 }) {
setup: self => self.hook(App, (_, windowName, visible) => {
if (windowName !== WINDOW_NAME) return;
if (visible && emojisCache.length === 0) {
loadEmojis(`${App.configDir}/emojis.json`)
loadEmojis(`${App.configDir}/assets/emojis.json`)
.then(emojis => {
emojisCache = emojis;
list.children = emojis.map(entry => EmojiItem(entry));
+12 -11
View File
@@ -1,14 +1,15 @@
import { MprisPlayer } from 'types/service/mpris.js';
import popupwindow from './misc/popupwindow.ts';
import Label from 'types/widgets/label.js';
import { MaterialIcon } from 'icons.ts';
const mpris = await Service.import("mpris")
const players = mpris.bind("players")
const FALLBACK_ICON = "audio-x-generic-symbolic"
const PLAY_ICON = "media-playback-start-symbolic"
const PAUSE_ICON = "media-playback-pause-symbolic"
const PREV_ICON = "media-skip-backward-symbolic"
const NEXT_ICON = "media-skip-forward-symbolic"
const PLAY_ICON = "play_arrow"
const PAUSE_ICON = "pause"
const PREV_ICON = "skip_previous"
const NEXT_ICON = "skip_next"
const WINDOW_NAME = "media"
function lengthStr(length: number): string {
@@ -96,27 +97,28 @@ function Player(player: MprisPlayer) {
class_name: "play-pause",
on_clicked: () => player.playPause(),
visible: player.bind("can_play"),
child: Widget.Icon({
icon: player.bind("play_back_status").transform(s => {
child: MaterialIcon(
// @ts-ignore
player.bind("play_back_status").transform(s => {
switch (s) {
case "Playing": return PAUSE_ICON
case "Paused":
case "Stopped": return PLAY_ICON
}
}),
}),
}
), "18px"),
})
const prev = Widget.Button({
on_clicked: () => player.previous(),
visible: player.bind("can_go_prev"),
child: Widget.Icon(PREV_ICON),
child: MaterialIcon(PREV_ICON, "18px"),
})
const next = Widget.Button({
on_clicked: () => player.next(),
visible: player.bind("can_go_next"),
child: Widget.Icon(NEXT_ICON),
child: MaterialIcon(NEXT_ICON, "18px"),
})
return Widget.Box(
@@ -169,6 +171,5 @@ export const media = popupwindow({
visible: false,
keymode: "exclusive",
child: Media(),
//anchor: ["left", "top"],
anchor: ["left", "bottom"],
})
+4 -3
View File
@@ -5,6 +5,7 @@ import { timeout } from "resource:///com/github/Aylur/ags/utils.js";
import GLib from "gi://GLib";
import Pango from "gi://Pango";
import Label from "types/widgets/label";
import { MaterialIcon } from "icons";
const notifications = await Service.import("notifications")
import Gtk from "gi://Gtk?version=3.0"
@@ -73,11 +74,11 @@ export const Notification = (notification: NotificationType, dismiss = true) =>
}),
Widget.Label({
class_name: "notification-time",
label: GLib.DateTime.new_from_unix_local(notification.time).format("%I:%M %p"),
label: GLib.DateTime.new_from_unix_local(notification.time).format("%H:%M"),
}),
Widget.Button({
class_name: "standard_icon_button",
child: Widget.Icon("window-close-symbolic"),
class_name: "standard_icon_button notification-close",
child: MaterialIcon("close"),
on_clicked: () => {
if (dismiss) {
notification.dismiss();
+13 -25
View File
@@ -1,4 +1,7 @@
import { MaterialIcon } from "icons";
const { GLib } = imports.gi;
const lock_command = `hyprlock`;
const logout_command = `loginctl kill-session $XDG_SESSION_ID`;
const shutdown_command = `systemctl poweroff`;
@@ -9,10 +12,7 @@ function LockButton({ icon, ...props }) {
let clickCount = 0;
let button = Widget.Button({
tooltip_text: "Lock",
child: Widget.Label({
label: icon,
class_name: "awesome_icon"
}),
child: MaterialIcon(icon, "20px"),
class_name: "outline_button",
...props,
})
@@ -37,10 +37,7 @@ function SuspendButton({ icon, ...props }) {
let clickCount = 0;
let button = Widget.Button({
tooltip_text: "Suspend",
child: Widget.Label({
label: icon,
class_name: "awesome_icon"
}),
child: MaterialIcon(icon, "20px"),
class_name: "outline_button",
...props,
})
@@ -67,10 +64,7 @@ function LogoutButton({ icon, ...props }) {
let clickCount = 0;
let button = Widget.Button({
tooltip_text: "Logout",
child: Widget.Label({
label: icon,
class_name: "awesome_icon"
}),
child: MaterialIcon(icon, "20px"),
class_name: "outline_button",
...props,
})
@@ -95,10 +89,7 @@ function RebootButton({ icon, ...props }) {
let clickCount = 0;
let button = Widget.Button({
tooltip_text: "Reboot",
child: Widget.Label({
label: icon,
class_name: "awesome_icon"
}),
child: MaterialIcon(icon, "20px"),
class_name: "outline_button",
...props,
})
@@ -123,10 +114,7 @@ function ShutdownButton({ icon, ...props }) {
let clickCount = 0;
let button = Widget.Button({
tooltip_text: "Shutdown",
child: Widget.Label({
label: icon,
class_name: "awesome_icon"
}),
child: MaterialIcon(icon, "20px"),
class_name: "outline_button",
...props,
})
@@ -154,23 +142,23 @@ export function Buttons() {
spacing: 5,
children: [
LockButton({
icon: "",
icon: "lock",
hexpand: true,
}),
SuspendButton({
icon: "",
icon: "clear_night",
hexpand: true,
}),
LogoutButton({
icon: "",
icon: "logout",
hexpand: true,
}),
RebootButton({
icon: "",
icon: "restart_alt",
hexpand: true,
}),
ShutdownButton({
icon: "",
icon: "power_settings_new",
hexpand: true,
})
]
+59 -59
View File
@@ -5,6 +5,7 @@ const powerProfiles = await Service.import('powerprofiles')
import { OpenSettings } from "apps/settings/main.ts";
import { WINDOW_NAME } from "./main.ts"
import { bluetooth_enabled, idle_inhibitor, night_light, screen_recorder } from "variables.ts";
import { MaterialIcon } from "icons.ts";
import Gtk from "gi://Gtk?version=3.0"
@@ -16,11 +17,7 @@ function WifiIndicator() {
return Widget.Box({
css: "padding-left: 15px; padding-right: 15px; padding-top: 5px; padding-bottom: 5px;",
children: [
Widget.Label({
label: "\udb82\udd28",
class_name: "awesome_icon",
css: `font-weight: bold; font-size: 20px; margin-right: 0.60em;`,
}),
MaterialIcon("signal_wifi_4_bar", "20px"),
Widget.Box({
visible: network.wifi.bind('enabled'),
orientation: Gtk.Orientation.VERTICAL,
@@ -47,10 +44,8 @@ function WifiIndicator() {
Widget.Box({
hpack: "end",
hexpand: true,
child: Widget.Label({
label: "",
class_name: "awesome_icon",
css: `font-weight: normal; font-size: 15px;`,
child: MaterialIcon("chevron_right", "20px", {
class_name: "material_icon icon arrow"
})
})
],
@@ -60,9 +55,7 @@ function WifiIndicator() {
const WiredIndicator = () => Widget.Box({
css: "padding-left: 15px; padding-right: 15px; padding-top: 5px; padding-bottom: 5px;",
children: [
Widget.Icon({
icon: network.wired.bind('icon_name'),
}),
MaterialIcon("settings_ethernet", "20px"),
Widget.Label({
label: "Internet",
}),
@@ -83,11 +76,7 @@ function IconAndName({ label, icon, padding = "0.3em", arrow = false }) {
let box = Widget.Box({
css: "padding-left: 15px; padding-right: 15px; padding-top: 5px; padding-bottom: 5px;",
children: [
Widget.Label({
label: icon,
class_name: "awesome_icon",
css: `font-weight: bold; font-size: 20px; margin-right: ${padding};`,
}),
MaterialIcon(icon, "20px"),
Widget.Label({
label: label,
justification: "center",
@@ -98,10 +87,8 @@ function IconAndName({ label, icon, padding = "0.3em", arrow = false }) {
const arrow = Widget.Box({
hpack: "end",
hexpand: true,
child: Widget.Label({
label: "",
class_name: "awesome_icon",
css: `font-weight: normal; font-size: 15px;`,
child: MaterialIcon("chevron_right", "20px", {
class_name: "material_icon icon arrow"
})
})
// @ts-ignore
@@ -133,7 +120,10 @@ function startRecordingTimer(button) {
recordingStartTime = Date.now();
recordingInterval = setInterval(() => {
let elapsedTime = Date.now() - recordingStartTime;
button.label = formatTime(elapsedTime);
button.child = IconAndName({
label: formatTime(elapsedTime),
icon: "stop_circle"
});
}, 1000);
}
@@ -141,7 +131,11 @@ function stopRecordingTimer(button) {
clearInterval(recordingInterval);
recordingStartTime = null;
recordingInterval = null;
button.label = '󰑋 Screen Recorder';
button.label = 'Screen Recorder';
button.child = IconAndName({
label: "Screen Recorder",
icon: "screen_record"
});
}
// Widget
@@ -177,7 +171,7 @@ function Page1() {
),
child: IconAndName({
label: "Bluetooth",
icon: "󰂯",
icon: "bluetooth",
arrow: true,
}),
on_primary_click: () => {
@@ -202,7 +196,7 @@ function Page1() {
.as(bool => bool ? "management_button active" : "management_button"),
child: IconAndName({
label: "Idle inhibitor",
icon: ""
icon: "schedule"
}),
onClicked: () => {
idle_inhibitor.setValue(!idle_inhibitor.value)
@@ -223,7 +217,8 @@ function Page1() {
},
child: IconAndName({
label: "Do Not Disturb",
icon: ""
icon: notifications.bind("dnd")
.as((bool) => bool ? "do_not_disturb_on" : "do_not_disturb_off")
})
})
]
@@ -234,37 +229,42 @@ function Page1() {
hexpand: true,
children: [
Widget.Button({
hexpand: true,
class_name: screen_recorder.bind()
.as(bool => bool ? "management_button active" : "management_button"),
on_clicked: (self) => {
hexpand: true,
class_name: screen_recorder.bind()
.as(bool => bool ? "management_button active" : "management_button"),
child: IconAndName({
label: "Screen Recorder",
icon: "screen_record"
}),
onClicked: (self) => {
isScreenRecordingOn().then(isRecording => {
if (isRecording) {
stopRecordingTimer(self);
} else {
startRecordingTimer(self);
}
self.toggleClassName("active-button", !isRecording);
self.toggleClassName("recording", !isRecording);
Utils.execAsync(['bash', '-c', 'mkdir -p ~/Videos/Screenrecordings; pkill wf-recorder; if [ $? -ne 0 ]; then wf-recorder -f ~/Videos/Screenrecordings/recording_"$(date +\'%b-%d-%Y-%I:%M:%S-%P\')".mp4 -g "$(slurp)" --pixel-format yuv420p; fi'])
.catch(logError)
.then(() => {
isScreenRecordingOn().then(newIsRecording => {
if (!newIsRecording) {
stopRecordingTimer(self);
}
})
});
} else {
startRecordingTimer(self);
}
self.toggleClassName("active-button", !isRecording);
self.toggleClassName("recording", !isRecording);
Utils.execAsync(['bash', '-c', 'mkdir -p ~/Videos/Screenrecordings; pkill wf-recorder; if [ $? -ne 0 ]; then wf-recorder -f ~/Videos/Screenrecordings/recording_"$(date +\'%b-%d-%Y-%I:%M:%S-%P\')".mp4 -g "$(slurp)" --pixel-format yuv420p; fi'])
.catch(logError)
.then(() => {
isScreenRecordingOn().then(newIsRecording => {
if (!newIsRecording) {
stopRecordingTimer(self);
}
});
},
child: IconAndName({
label: "Screen Recorder",
icon: "󰑋",
setup: self => {
self.label = '󰑋 Screen Recorder';
}
})
});
});
},
setup: (self) => {
isScreenRecordingOn().then(isRecording => {
if (isRecording) {
startRecordingTimer(self);
self.addClassName("active-button");
self.addClassName("recording");
}
});
}
}),
Widget.Button({
hexpand: true,
@@ -272,7 +272,7 @@ function Page1() {
.as(mode => mode ? "management_button active" : "management_button"),
child: IconAndName({
label: "Night Light",
icon: ""
icon: "nightlight"
}),
onClicked: () => {
night_light.setValue(!night_light.value)
@@ -317,7 +317,7 @@ function Page2() {
class_name: "management_button",
child: IconAndName({
label: "Color picker",
icon: "",
icon: "colorize",
arrow: true,
}),
on_primary_click: () => {
@@ -338,11 +338,11 @@ function Page2() {
icon: powerProfiles.bind('active_profile').as(profile => {
switch (profile) {
case 'balanced':
return '';
return 'balance';
case 'performance':
return '';
return 'bolt';
default:
return '';
return 'eco';
}
})
}),
@@ -377,7 +377,7 @@ function Page2() {
class_name: "management_button",
child: IconAndName({
label: "Settings",
icon: "",
icon: "settings",
arrow: true,
}),
on_primary_click: () => {
+6 -10
View File
@@ -1,8 +1,8 @@
import { NotificationsBox } from "./notifications.ts"
import { SystemBox } from "./system.ts"
let shown = Variable("Messages");
import Gtk from "gi://Gtk?version=3.0"
import { MaterialIcon } from "icons.ts";
type ButtonType = {
@@ -22,13 +22,9 @@ function Button({ page, label, icon }: ButtonType) {
children: [
Widget.Box({
orientation: Gtk.Orientation.VERTICAL,
hpack: "end",
hpack: "center",
class_name: "container",
child: Widget.Label({
hpack: "center",
label: icon,
class_name: "awesome_icon icon"
}),
child: MaterialIcon(icon, "20px"),
}),
Widget.Label({
label: label,
@@ -63,17 +59,17 @@ export function Navigation() {
Button({
page: "Messages",
label: "Messages",
icon: ""
icon: "chat"
}),
Button({
page: "Notifications",
label: "Notifs",
icon: ""
icon: "notifications"
}),
Button({
page: "System",
label: "System",
icon: ""
icon: "info"
})
]
})
+111
View File
@@ -0,0 +1,111 @@
import argparse
import re
import os
import json
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('--browser', type=str, help="Change default browser")
group.add_argument('--filemanager', type=str, help="Change file manager")
group.add_argument('--editor', type=str, help="Change default editor")
group.add_argument('--terminal', type=str, help="Change default terminal")
group.add_argument('--get', type=str, help="Get default app", choices=["browser", "editor", "terminal", "filemanager"])
args = parser.parse_args()
config_file = os.path.expanduser("~/dotfiles/hypr/UserConfigs/Apps.conf")
json_config_file = os.path.expanduser("~/dotfiles/ags/assets/apps.json")
def read_apps_conf():
with open(config_file) as f:
return f.read().strip()
def write_apps_conf(content):
with open(config_file, 'w') as f:
f.write(content + '\n')
def read_json_config():
with open(json_config_file) as json_file:
return json.load(json_file)
def write_json_config(config):
with open(json_config_file, 'w') as json_file:
json.dump(config, json_file, indent=4)
def which(program: str):
def is_executable(fpath):
return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
fpath, fname = os.path.split(program)
if fpath:
if is_executable(program):
return program
else:
for path in os.environ["PATH"].split(os.pathsep):
path = path.strip('"')
exe_file = os.path.join(path, program)
if is_executable(exe_file):
return exe_file
raise ProgramNotFound(value)
def extract_associations(env_str):
pattern = re.compile(r'^\s*env\s*=\s*(\w+)\s*,\s*(.*?)\s*#\s*!\s*-\s*@(\w+)\s*$', re.MULTILINE) # noqa
associations = {}
matches = pattern.findall(env_str)
for key, _, association in matches:
if association not in associations:
associations[association] = []
if key not in associations[association]:
associations[association].append(key)
return associations
def replace_value(env_str, key, new_value):
pattern = re.compile(
r'^(\s*env\s*=\s*' +
re.escape(key) +
r'\s*,\s*)(.*?)\s*(#.*)?$', re.MULTILINE
)
return re.sub(pattern, r'\1' + new_value + r' \3', env_str)
class AssociationNotFound(Exception):
def __init__(self, name: str, *args: object) -> None:
error = f"{name} association not found"
super().__init__(error, *args)
class ProgramNotFound(Exception):
def __init__(self, name: str, *args: object) -> None:
error = f"{name} not found"
super().__init__(error, *args)
def change_association(key: str, value: str):
env_str = read_apps_conf()
which(value)
associations = extract_associations(env_str)
if key not in associations:
raise AssociationNotFound(key)
for key in associations[key]:
env_str = replace_value(env_str, key, value)
write_apps_conf(env_str)
def update_json_config(key: str, value: str):
config = read_json_config()
config[key] = value
write_json_config(config)
if args.get:
json_config = read_json_config()
print(json_config[args.get])
elif args.browser:
change_association("browser", args.browser)
update_json_config("browser", args.browser)
elif args.filemanager:
change_association("filemanager", args.filemanager)
update_json_config("filemanager", args.filemanager)
elif args.editor:
change_association("editor", args.editor)
update_json_config("editor", args.editor)
elif args.terminal:
change_association("terminal", args.terminal)
update_json_config("terminal", args.terminal)
+13 -4
View File
@@ -67,7 +67,7 @@
color: @onSecondaryContainer;
}
.settings .sidebar .row image {
.settings .sidebar .row .icon {
margin-right: 12px;
color: @onSurfaceVariant;
}
@@ -111,6 +111,10 @@
background-color: mix(@onSurface, @surface, 0.92)
}
.settings .row:active {
background-color: mix(@onSurface, @surface, 0.8)
}
.settings .row.focused {
background-color: mix(@onSurface, @surface, 0.8)
}
@@ -127,6 +131,11 @@
color: @onSurfaceVariant
}
.settings .row .icon {
color: @onSurfaceVariant;
margin-right: 16px;
}
.settings .bottom_bar {
background-color: @surface;
font-weight: normal;
@@ -142,7 +151,7 @@
min-width: 30px;
min-height: 32px;
border-radius: 4px;
background-color: @surfaceContainerHighest;
background-color: @surfaceContainerHigh;
}
.settings entry label, .settings combobox label {
@@ -152,12 +161,12 @@
/* Wifi */
.settings .wifi_list .row image {
.settings .wifi_list .row .icon {
color: @onSurfaceVariant;
margin-right: 16px;
}
.settings .wifi_list .row.active image {
.settings .wifi_list .row.active .icon {
color: @primary;
}
+63 -31
View File
@@ -271,6 +271,10 @@ window.notification-popups box.notifications {
color: @primary;
}
.notification-close .icon {
font-weight: 300;
}
/* -----------------------------------------------------
* Applications
* ----------------------------------------------------- */
@@ -342,25 +346,6 @@ window.notification-popups box.notifications {
* Clipboard history
* ----------------------------------------------------- */
.emoji_box {
border-radius: 24px;
background-color: @background;
border: 2px solid;
border-color: @outlineVariant;
padding: 11px;
}
.emoji_entry {
background-color: @surfaceContainerHigh;
color: @onSurface;
border: none;
outline: none;
border-radius: 100px;
margin-bottom: 16px;
padding: 5px;
padding-left: 25px;
}
.cliphistory_box {
border-radius: 24px;
background-color: @background;
@@ -416,6 +401,28 @@ window.notification-popups box.notifications {
font-weight: normal;
}
/* -----------------------------------------------------
* Emoji
* -----------------------------------------------------*/
.emoji_box {
border-radius: 24px;
background-color: @background;
border: 2px solid;
border-color: @outlineVariant;
padding: 11px;
}
.emoji_entry {
background-color: @surfaceContainerHigh;
color: @onSurface;
border: none;
outline: none;
border-radius: 100px;
margin-bottom: 16px;
padding: 5px;
padding-left: 25px;
}
/* -----------------------------------------------------
* Media player
@@ -486,10 +493,12 @@ window.notification-popups box.notifications {
min-height: 1em;
min-width: 1em;
padding: .3em;
padding-top: 0px;
padding-bottom: 0px;
color: @onSecondary;
}
.player button image {
.player button .icon {
color: @onSecondary;
}
@@ -515,7 +524,12 @@ window.notification-popups box.notifications {
border-radius: 100px;
}
.volume_box image {
.volume_box button {
padding-top: 0px;
padding-bottom: 0px;
}
.volume_box .icon {
margin-right: 5px;
}
@@ -523,6 +537,10 @@ window.notification-popups box.notifications {
font-family: "Font Awesome 6 Free";
}
.material_icon {
font-family: "Material Symbols Outlined", "Material Symbols Sharp";
}
.battery {
background-color: @surfaceContainer;
border-radius: 100px;
@@ -544,7 +562,7 @@ window.notification-popups box.notifications {
margin: 0px;
}
.bar_applets image {
.bar_applets .icon {
color: @onSurface;
}
@@ -595,7 +613,12 @@ window.notification-popups box.notifications {
}
.management_button .icon {
color: @onSurface
color: @onSurface;
margin-right: 5px;
}
.management_button .arrow {
margin-right: 0px;
}
.management_button:hover {
@@ -606,8 +629,9 @@ window.notification-popups box.notifications {
color: @onPrimary
}
.management_button.active .icon {
color: @onPrimary
.management_button.active .icon{
color: @onPrimary;
font-weight: normal;
}
.management_button.active {
@@ -682,7 +706,7 @@ window.notification-popups box.notifications {
}
.system_scale.backlight {
margin-bottom: 25px;
margin-bottom: 28px;
}
.system_scale.brightness slider {
@@ -799,6 +823,7 @@ window.notification-popups box.notifications {
.outline_button label, .outline_button .icon,
.outline_button .awesome_icon, .outline_button image {
color: @primary;
font-weight: 300;
}
.outline_button:hover {
@@ -815,11 +840,16 @@ window.notification-popups box.notifications {
background-color: @secondaryContainer;
color: @onSecondaryContainer;
border-radius: 100px;
padding: 0px;
padding-left: 6px;
padding-right: 6px;
}
.filled_tonal_button label, .filled_tonal_button .icon,
.filled_tonal_button .awesome_icon, .filled_tonal_button image {
color: @onSecondaryContainer;
font-weight: 400;
margin: 0px;
}
.filled_tonal_button:hover {
@@ -940,19 +970,19 @@ filled_button.disabled .awesome_icon, .filled_button.disabled image {
.navigation_button .container {
border-radius: 16px;
padding: 5px;
padding-left: 5px;
padding-right: 5px;
min-height: 15px;
min-width: 0px;
transition-property: min-width, color, background-color, border-color;
}
.navigation_button .icon {
font-weight: normal;
font-weight: 400;
color: @onSurface;
}
.navigation_button.active .icon {
font-weight: bold;
color: @onSecondaryContainer;
}
@@ -1048,6 +1078,7 @@ switch:checked:hover slider, switch:checked:active slider {
background-color: @primaryContainer;
}
/* -----------------------------------------------------
* Cheatsheet
* ----------------------------------------------------- */
@@ -1069,8 +1100,9 @@ switch:checked:hover slider, switch:checked:active slider {
}
.cheatsheet .category separator {
margin-top: 2px;
margin-bottom: 2px;
margin-top: 4px;
margin-bottom: 4px;
color: @outline;
}
.cheatsheet .category .row {
+5
View File
@@ -112,6 +112,11 @@ pkg=(
ttf-firacode-nerd
noto-fonts
gnu-free-fonts
ttf-material-symbols-variable-git
fontconfig
ttf-meslo-nerd
ttf-google-sans
ttf-roboto
#hyprland
hyprland