chore: restructure the project, make it not use the astal application stuff

now it's more organized and I have more control over the shell behaviour
This commit is contained in:
retrozinndev
2025-08-06 15:25:21 -03:00
parent 5a6d5b47c6
commit d549ad9596
191 changed files with 529 additions and 1000 deletions
-559
View File
@@ -1,559 +0,0 @@
# About
None of them are made by me. You can view and find their source
by expanding them below.
## Bocchi The Rock!
<details>
<summary>
<b>Kessoku Band Rooftop (cropped borders)</b>
</summary>
<img src="wallpapers/Kessoku Band Rooftop.jpeg"></img>
- Source: [Alpha Coders](https://wall.alphacoders.com/big.php?i=1319345)
</details>
<details>
<summary>
<b>Bocchi The Rock! (the wallpaper)</b>
</summary>
<img src="wallpapers/Bocchi The Rock!.png"></img>
- Source: [Twitter/X (artist only, post was deleted)](https://x.com/mofujiro_mofum2)
</details>
<details>
<summary>
<b>Ryo Yamada Maid Dress</b>
</summary>
<img src="wallpapers/Ryo Yamada Maid Dress.png"></img>
- Source: [Alpha Coders](https://wall.alphacoders.com/big.php?i=1363565)
</details>
<details>
<summary>
<b>Ryo Yamada</b>
</summary>
<img src="wallpapers/Ryo Yamada.png"></img>
- Source: [Alpha Coders](https://wall.alphacoders.com/big.php?i=1323120)
</details>
<details>
<summary>
<b>Ryo Vending Machine</b>
</summary>
<img src="wallpapers/Ryo Vending Machine.png"></img>
- Source: [Alpha Coders](https://wall.alphacoders.com/big.php?i=1293921)
</details>
<details>
<summary>
<b>Nijika Train</b>
</summary>
<img src="wallpapers/Nijika Train.jpeg"></img>
- Source: [Alpha Coders](https://wall.alphacoders.com/big.php?i=1304192)
</details>
<details>
<summary>
<b>Nijika Ijichi</b>
</summary>
<img src="wallpapers/Nijika Ijichi.jpg"></img>
- Source: [Wallpaper Flare](https://www.wallpaperflare.com/blonde-nijika-ijichi-bocchi-the-rock-anime-girls-sunset-glow-wallpaper-yjrwx)
</details>
<details>
<summary>
<b>Kita Street</b>
</summary>
<img src="wallpapers/Kita Street.jpeg"></img>
- Source: [Alpha Coders](https://wall.alphacoders.com/big.php?i=1304193)
</details>
<details>
<summary>
<b>Kita-chan!!</b>
</summary>
<img src="wallpapers/Kita-chan!!.jpg"></img>
- Source: [Alpha Coders](https://wall.alphacoders.com/big.php?i=1296783)
</details>
<details>
<summary>
<b>Kikuri Hiroi</b>
</summary>
<img src="wallpapers/Kikuri Hiroi.jpg"></img>
- Source: [Alpha Coders](https://wall.alphacoders.com/big.php?i=1295717)
</details>
<details>
<summary>
<b>Kessoku Band Reunited</b>
</summary>
<img src="wallpapers/Kessoku Band Reunited.jpg"></img>
- Source: [Wallpaper Cave](https://wallpapercave.com/w/wp11695992)
</details>
<details>
<summary>
<b>Kessoku Albums</b>
</summary>
<img src="wallpapers/Kessoku Albums.jpeg"></img>
- Source: [Alpha Coders](https://wall.alphacoders.com/big.php?i=1316133)
</details>
<details>
<summary>
<b>Hitori Gotoh College Corridor</b>
</summary>
<img src="wallpapers/Hitori Gotoh College Corridor.png"></img>
- Source: [Alpha Coders](https://wall.alphacoders.com/big.php?i=1302067)
</details>
<details>
<summary>
<b>Garden Kita</b>
</summary>
<img src="wallpapers/Garden Kita.png"></img>
- Source: [Gruvbox Wallpapers](https://gruvbox-wallpapers.pages.dev)
</details>
<!---------------- -->
## Vocaloid Wallpapers
<details>
<summary>
<b>Arch Linux Miku</b>
</summary>
<img src="wallpapers/Arch Linux Miku.jpg"></img>
- Source: [DeviantArt](https://www.deviantart.com/nesyah/art/Arch-linux-feat-Hatsune-Miku-858316759)
</details>
<details>
<summary>
<b>Gumi Bridge</b>
</summary>
<img src="wallpapers/Gumi Bridge.jpg"></img>
- Source: [Alpha Coders](https://wall.alphacoders.com/big.php?i=593482)
</details>
<details>
<summary>
<b>Gumi Forest Sunlight</b>
</summary>
<img src="wallpapers/Gumi Forest Sunlight.jpg"></img>
- Source: [Alpha Coders](https://wall.alphacoders.com/big.php?i=930443)
</details>
<details>
<summary>
<b>Miku Balloons</b>
</summary>
<img src="wallpapers/Miku Balloons.jpg"></img>
- Source: [Alpha Coders](https://wall.alphacoders.com/big.php?i=768576)
</details>
<details>
<summary>
<b>Miku Green Hair Glasses</b>
</summary>
<img src="wallpapers/Miku Green Hair Glasses.png"></img>
- Source: [Alpha Coders](https://wall.alphacoders.com/big.php?i=858278)
</details>
<details>
<summary>
<b>Kagamine Rin Yellow Tapes</b>
</summary>
<img src="wallpapers/Kagamine Rin Yellow Tapes.png"></img>
- Source: [Alpha Coders](https://wall.alphacoders.com/big.php?i=1292852)
</details>
<details>
<summary>
<b>Gumi VOCALOID</b>
</summary>
<img src="wallpapers/Gumi VOCALOID.png"></img>
- Source: [Alpha Coders](https://wall.alphacoders.com/big.php?i=768096)
</details>
<details>
<summary>
<b>Miku Stylish with Glasses</b>
</summary>
<img src="wallpapers/Miku Stylish with Glasses.jpg"></img>
- Source: [Alpha Coders](https://wall.alphacoders.com/big.php?i=1305668)
</details>
<details>
<summary>
<b>Miku Winter</b>
</summary>
<img src="wallpapers/Miku Winter.jpg"></img>
- Source: [Alpha Coders](https://wall.alphacoders.com/big.php?i=1305841)
</details>
<details>
<summary>
<b>Vocaloid Karaoke</b>
</summary>
<img src="wallpapers/Vocaloid Karaoke.jpg"></img>
- Source: [Alpha Coders](https://wall.alphacoders.com/big.php?i=770194)
</details>
<details>
<summary>
<b>Miku, Rin and Luka Chibi</b>
</summary>
<img src="wallpapers/Miku, Rin and Luka Chibi.jpg"></img>
- Source: [Alpha Coders](https://wall.alphacoders.com/big.php?i=770164)
</details>
<details>
<summary>
<b>Miku Guitar</b>
</summary>
<img src="wallpapers/Miku Guitar.jpg"></img>
- Source: [Alpha Coders](https://wall.alphacoders.com/big.php?i=867976)
</details>
<details>
<summary>
<b>Miku Garden</b>
</summary>
<img src="wallpapers/Miku Garden.jpg"></img>
- Source: [Alpha Coders](https://wall.alphacoders.com/big.php?i=1315430)
</details>
<details>
<summary>
<b>Miku Setup</b>
</summary>
<img src="wallpapers/Miku Setup.png"></img>
- Source: [Alpha Coders](https://wall.alphacoders.com/big.php?i=672757)
</details>
<details>
<summary>
<b>Miku Flower Field</b>
</summary>
<img src="wallpapers/Miku Flower Field.jpg"></img>
- Source: [Alpha Coders](https://wall.alphacoders.com/big.php?i=688123)
</details>
<details>
<summary>
<b>Miku Door</b>
</summary>
<img src="wallpapers/Miku Door.png"></img>
- Source: [Alpha Coders](https://wall.alphacoders.com/big.php?i=845583)
</details>
<details>
<summary>
<b>Miku Crying with Mask</b>
</summary>
<img src="wallpapers/Miku Crying with Mask.jpg"></img>
- Source: [Alpha Coders](https://wall.alphacoders.com/big.php?i=524092)
</details>
<details>
<summary>
<b>Miku City Sky</b>
</summary>
<img src="wallpapers/Miku City Sky.png"></img>
- Source: [Alpha Coders](https://wall.alphacoders.com/big.php?i=698444)
</details>
<details>
<summary>
<b>Miku Bush</b>
</summary>
<img src="wallpapers/Miku Bush.jpg"></img>
- Source: [Alpha Coders](https://wall.alphacoders.com/big.php?i=631739)
</details>
<details>
<summary>
<b>Hatsune Miku Birthday!</b>
</summary>
<img src="wallpapers/Hatsune Miku Birthday!.png"></img>
- Source: [Alpha Coders](https://wall.alphacoders.com/big.php?i=731810)
</details>
<details>
<summary>
<b>Hatsune Miku and Megurine Luka</b>
</summary>
<img src="wallpapers/Hatsune Miku and Megurine Luka.jpg"></img>
- Source: [Alpha Coders](https://wall.alphacoders.com/big.php?i=1313438)
</details>
<details>
<summary>
<b>Gumi Ocean Sunset</b>
</summary>
<img src="wallpapers/Gumi Ocean Sunset.jpg"></img>
- Source: [WallHaven](https://wallhaven.cc/w/we8pgx)
</details>
<details>
<summary>
<b>Gumi Street Bike</b>
</summary>
<img src="wallpapers/Gumi Street Bike.jpg"></img>
- Source: [WallHaven](https://wallhaven.cc/w/4x7e7o)
</details>
<details>
<summary>
<b>Inabakumori Kaai Yuki</b>
</summary>
<img src="wallpapers/Inabakumori Kaai Yuki.png"></img>
- Source: [WallHaven](https://wallhaven.cc/w/wed3m7)
</details>
<details>
<summary>
<b>Inabakumori Osage</b>
</summary>
<img src="wallpapers/Inabakumori Osage.jpg"></img>
- Source: [WallHaven](https://wallhaven.cc/w/o3r8z9)
</details>
<!---------------- -->
## Frieren: Beyond Journey's End
<details>
<summary>
<b>Frieren Underwater</b>
</summary>
<img src="wallpapers/Frieren Underwater.jpg"></img>
- Source: [Pixiv](https://www.pixiv.net/en/artworks/114234634)
</details>
<details>
<summary>
<b>Frieren Rain</b>
</summary>
<img src="wallpapers/Frieren Rain.jpg"></img>
- Source: [Pixiv](https://www.pixiv.net/en/artworks/114234634)
</details>
<details>
<summary>
<b>Frieren At The Funeral</b>
</summary>
<img src="wallpapers/Frieren At The Funeral.jpg"></img>
- Source: [Pixiv](https://www.pixiv.net/en/artworks/114234634)
</details>
<details>
<summary>
<b>Frieren Sunset</b>
</summary>
<img src="wallpapers/Frieren Sunset.jpeg"></img>
- Source: [Alpha Coders](https://wall.alphacoders.com/big.php?i=1354394)
</details>
<details>
<summary>
<b>Frieren Sending Kiss</b>
</summary>
<img src="wallpapers/Frieren Sending Kiss.jpeg"></img>
- Source: [Alpha Coders](https://wall.alphacoders.com/big.php?i=1344010)
</details>
<details>
<summary>
<b>Frieren Ring</b>
</summary>
<img src="wallpapers/Frieren Ring.jpeg"></img>
- Source: [Alpha Coders](https://wall.alphacoders.com/big.php?i=1351964)
</details>
<details>
<summary>
<b>Frieren Night Film</b>
</summary>
<img src="wallpapers/Frieren Night Film.jpeg"></img>
- Source: [Wallpaper Flare](https://www.wallpaperflare.com/anime-anime-girls-sousou-no-frieren-wallpaper-yvcxe)
</details>
<details>
<summary>
<b>Frieren Blue</b>
</summary>
<img src="wallpapers/Frieren Blue.jpeg"></img>
- Source: [Alpha Coders](https://wall.alphacoders.com/big.php?i=1357998)
</details>
<!---------------- -->
## Oshi no Ko
<details>
<summary>
<b>Oshi no Ko Kana Arima</b>
</summary>
<img src="wallpapers/Oshi no Ko Kana Arima.png"></img>
- Source: [WallHaven](https://wallhaven.cc/w/x6pp5z)
</details>
<!---------------- -->
## Gruvbox-styled
<details>
<summary>
<b>Balcony Girl</b>
</summary>
<img src="wallpapers/Balcony Girl.png"></img>
- Source: [Gruvbox Wallpapers](https://gruvbox-wallpapers.pages.dev)
</details>
<details>
<summary>
<b>Gruvbox Girl</b>
</summary>
<img src="wallpapers/Gruvbox Girl.png"></img>
- Source: [Gruvbox Wallpapers](https://gruvbox-wallpapers.pages.dev)
</details>
- [Gruvbox Wallpapers](https://gruvbox-wallpapers.pages.dev)
<!---------------- -->
## Genshin Impact Wallpaper(s)
Those can be get on web events in Genshin Impact, and also on [HoYoLAB](https://hoyolab.com).
<details>
<summary>
<b>Mualani!!</b>
</summary>
<img src="wallpapers/Mualani!!.jpg"></img>
- Source: Genshin Impact Web Event (not available anymore)
</details>
<!---------------- -->
## Others
<details>
<summary>
<b>Hypr-chan</b>
</summary>
<img src="wallpapers/Hypr-chan.png"></img>
- Source: [GitHub (hyprwm/Hyprland)](https://github.com/hyprwm/Hyprland)
</details>
<details>
<summary>
<b>Linux Anime Girl</b>
</summary>
<img src="wallpapers/Linux Anime Girl.png"></img>
- Source: [WallHere](https://wallhere.com/en/wallpaper/2284648)
</details>
### More sources
- [Pinterest](https://pinterest.com)
- [AlphaCoders](https://alphacoders.com/bocchi-the-rock!-wallpapers)
- [WallpaperCave](https://wallpapercave.com/bocchi-the-rock-wallpapers)
- [WallpaperFlare](https://www.wallpaperflare.com/search?wallpaper=BOCCHI+THE+ROCK%21)
-146
View File
@@ -1,146 +0,0 @@
import { Wireplumber } from "./scripts/volume";
import { handleArguments } from "./scripts/arg-handler";
import { Time, timeout } from "ags/time";
import { Runner } from "./runner/Runner";
import { PluginApps } from "./runner/plugins/apps";
import { PluginShell } from "./runner/plugins/shell";
import { PluginWebSearch } from "./runner/plugins/websearch";
import { PluginMedia } from "./runner/plugins/media";
import { Windows } from "./windows";
import { Notifications } from "./scripts/notifications";
import { PluginWallpapers } from "./runner/plugins/wallpapers";
import { Wallpaper } from "./scripts/wallpaper";
import { Stylesheet } from "./scripts/stylesheet";
import { Clipboard } from "./scripts/clipboard";
import { PluginClipboard } from "./runner/plugins/clipboard";
import { Config } from "./scripts/config";
import { Scope } from "/usr/share/ags/js/gnim/src/jsx/scope";
import App from "ags/gtk4/app"
import GObject from "ags/gobject";
import AstalNotifd from "gi://AstalNotifd";
import GLib from "gi://GLib?version=2.0";
const generalConfigDefaults = {
notifications: {
timeout_low: 4000,
timeout_normal: 6000,
timeout_critical: 0
},
night_light: {
/** whether to save night light values to disk */
save_on_shutdown: true
},
workspaces: {
/** breaks `enable_helper`, makes all workspaces show their respective ID
* by default */
always_show_id: false,
/** this is the function that shows the Workspace's IDs
* around the current workspace if one breaks the crescent order.
* It basically helps keyboard navigation between workspaces.
* ---
* Example: 1(empty, current, shows ID), 2(empty, does not appear(makes
* the previous not to be in a crescent order)), 3(not empty, shows ID) */
enable_helper: true
},
clock: {
/** use the same format as gnu's `date` command */
date_format: "%A %d, %H:%M"
},
misc: {
play_bell_on_volume_change: true
}
};
export const generalConfig = new Config<keyof typeof generalConfigDefaults,
typeof generalConfigDefaults[keyof typeof generalConfigDefaults]>(
`${GLib.get_user_config_dir()}/colorshell/config.json`, generalConfigDefaults
);
export const appScope: Scope = new Scope(null);
let osdTimer: (Time|undefined), osdTimeout = 3500;
let connections = new Map<GObject.Object, (Array<number> | number)>();
const runnerPlugins: Array<Runner.Plugin> = [
PluginApps,
PluginShell,
PluginWebSearch,
PluginMedia,
PluginWallpapers,
PluginClipboard
];
const defaultWindows: Array<string> = [ "bar" ];
App.start({
instanceName: "astal",
icons: "icons/",
requestHandler: (request: string, response: (result: any) => void): void => {
response(handleArguments(request));
},
main: (..._args: Array<string>) => {
console.log(`Colorshell: initialized instance as: "${ App.instanceName || "astal" }"`);
connections.set(App, App.connect("shutdown", () => appScope.dispose()));
Stylesheet.getDefault().compileApply();
// Init clipboard module
Clipboard.getDefault();
console.log("Initializing wallpaper handler");
Wallpaper.getDefault();
console.log("Adding runner plugins");
runnerPlugins.forEach(plugin => Runner.addPlugin(plugin));
connections.set(Wireplumber.getDefault(),
Wireplumber.getDefault().getDefaultSink().connect("notify::volume", () =>
triggerOSD())
);
connections.set(Notifications.getDefault(), [
Notifications.getDefault().connect("notification-added", (_, _notif: AstalNotifd.Notification) => {
Windows.getDefault().open("floating-notifications");
}),
Notifications.getDefault().connect("notification-removed", (_: Notifications, _id: number) => {
_.notifications.length === 0 && Windows.getDefault().close("floating-notifications");
})
]);
defaultWindows.forEach(w => Windows.getDefault().open(w));
appScope.onCleanup(() => {
console.log("Colorshell: disconnecting from GObjects because of ::shutdown");
connections.forEach((ids, obj) => Array.isArray(ids) ?
ids.forEach(id => obj.disconnect(id))
: obj.disconnect(ids));
});
}
});
function triggerOSD() {
if(Windows.getDefault().isOpen("control-center")) return;
Windows.getDefault().open("osd");
if(!osdTimer) {
osdTimer = timeout(osdTimeout, () => {
osdTimer = undefined;
Windows.getDefault().close("osd");
});
return;
}
osdTimer.cancel();
osdTimer = timeout(osdTimeout, () => {
Windows.getDefault().close("osd");
osdTimer = undefined;
});
}
-26
View File
@@ -1,26 +0,0 @@
// SCSS Variables
// Generated by 'wal'
$wallpaper: "/home/joaov/wallpapers/Frieren Rain.jpg";
// Special
$background: #25301c;
$foreground: #c8cbc6;
$cursor: #c8cbc6;
// Colors
$color0: #25301c;
$color1: #6c8251;
$color2: #7c9357;
$color3: #78846e;
$color4: #948a88;
$color5: #899869;
$color6: #98a27b;
$color7: #9ba197;
$color8: #707c66;
$color9: #91AE6D;
$color10: #A6C574;
$color11: #A0B093;
$color12: #C6B9B6;
$color13: #B7CB8D;
$color14: #CBD9A4;
$color15: #c8cbc6;
-99
View File
@@ -1,99 +0,0 @@
import { Gtk } from "ags/gtk4";
import { tr } from "../../../i18n/intl";
import { Accessor, createComputed, createState, onCleanup } from "ags";
import { variableToBoolean } from "../../../scripts/utils";
import Pango from "gi://Pango?version=1.0";
export type TileProps = {
class?: string | Accessor<string>;
icon?: string | Accessor<string>;
visible?: boolean | Accessor<boolean>;
iconSize?: number | Accessor<number>;
title: string | Accessor<string>;
description?: string | Accessor<string>;
toggleState?: boolean | Accessor<boolean>;
enableOnClickMore?: boolean | Accessor<boolean>;
onUnmap?: (self: Gtk.Box) => void;
onToggledOn: () => void;
onToggledOff: () => void;
onClickMore?: () => void;
}
export function Tile(props: TileProps): Gtk.Widget {
const subs: Array<() => void> = [];
const [toggled, setToggled] = createState(((props.toggleState instanceof Accessor) ?
props.toggleState.get()
: props.toggleState) ?? false);
(props.toggleState instanceof Accessor) && subs.push(
props.toggleState.subscribe(() =>
setToggled((props.toggleState as Accessor<boolean>).get() ?? false))
);
onCleanup(() => subs.forEach(s => s()));
return <Gtk.Box hexpand visible={props.visible} onUnmap={props.onUnmap}
canFocus focusable={false} class={
(props.class instanceof Accessor) ?
createComputed([props.class, toggled], (clss, isToggled) =>
`tile ${clss} ${isToggled ? "toggled" : ""} ${
props.onClickMore ? "has-more" : ""
}`
)
: toggled.as(isToggled =>
`tile ${props.class ? props.class : ""} ${isToggled ? "toggled" : ""} ${
props.onClickMore ? "has-more" : ""
}`
)
}>
<Gtk.Button class={"toggle-button"} onClicked={() => {
if(toggled.get()) {
setToggled(false);
props.onToggledOff?.();
return;
}
setToggled(true);
props.onToggledOn?.();
}}>
<Gtk.Box class={"content"} hexpand={true} vexpand={true}>
{props.icon && <Gtk.Image class={"icon"} iconName={props.icon} css={
(props.iconSize instanceof Accessor) ?
props.iconSize.as(size => `font-size: ${size}px;`)
: (props.iconSize ?
`font-size: ${props.iconSize ?? 16}px;`
: undefined)
} />}
<Gtk.Box orientation={Gtk.Orientation.VERTICAL} class={"text"} vexpand={true} hexpand={true}
valign={Gtk.Align.CENTER}>
<Gtk.Label class={"title"} xalign={0} halign={Gtk.Align.START} ellipsize={Pango.EllipsizeMode.END}
label={props.title} />
{props.description && <Gtk.Label class={"description"} ellipsize={Pango.EllipsizeMode.END}
visible={variableToBoolean(props.description)} xalign={0} label={
(props.description instanceof Accessor) ?
props.description.as(str => str ?? "")
: (props.description ?? "")
} halign={Gtk.Align.START}
/>}
</Gtk.Box>
</Gtk.Box>
</Gtk.Button>
<Gtk.Button class={"more icon"} iconName={"go-next-symbolic"} widthRequest={32}
visible={Boolean(props.onClickMore)} halign={Gtk.Align.END} onClicked={() => {
((props.enableOnClickMore instanceof Accessor) ?
props.enableOnClickMore.get()
: props.enableOnClickMore) && props.onToggledOn?.();
props.onClickMore?.();
}} tooltipText={tr("control_center.tiles.more")} />
</Gtk.Box> as Gtk.Widget;
}
-4
View File
@@ -1,4 +0,0 @@
# Default hyprpaper file
preload = $HOME/wallpapers/Frieren At The Funeral.jpg
wallpaper = , $HOME/wallpapers/Frieren At The Funeral.jpg
-6
View File
@@ -1,6 +0,0 @@
###############
## AUTOSTART ##
###############
# Wiki: https://wiki.hyprland.org/Configuring/Keywords/#executing
-8
View File
@@ -1,8 +0,0 @@
##############
## BINDINGS ##
##############
# Wiki: https://wiki.hyprland.org/Configuring/Binds
# Uncomment if you want to press SUPER to launch application search
# bind = $mainMod, $mainMod_L, exec, astal toggle apps-window
-6
View File
@@ -1,6 +0,0 @@
################
## DECORATION ##
################
# Wiki: https://wiki.hyprland.org/Configuring/Variables
-6
View File
@@ -1,6 +0,0 @@
#################
## ENVIRONMENT ##
#################
# Wiki: https://wiki.hyprland.org/Configuring/Keywords/#setting-the-environment
-15
View File
@@ -1,15 +0,0 @@
########################
## USER CONFIGURATION ##
########################
# This sources all user configuration files
source = ./monitors.conf
source = ./environment.conf
source = ./input.conf
source = ./bindings.conf
source = ./layout.conf
source = ./decorations.conf
source = ./autostart.conf
source = ./rules.conf
-13
View File
@@ -1,13 +0,0 @@
###########
## INPUT ##
###########
# Wiki: https://wiki.hyprland.org/Configuring/Keywords/#per-device-input-configs
##############
## GESTURES ##
##############
# Wiki: https://wiki.hyprland.org/Configuring/Variables/#gestures
-4
View File
@@ -1,4 +0,0 @@
############
## LAYOUT ##
############
# Wiki: https://wiki.hyprland.org/Configuring/Dwindle-Layout/#config
-17
View File
@@ -1,17 +0,0 @@
##############
## MONITORS ##
##############
# Wiki: https://wiki.hyprland.org/Configuring/Monitors
# Monitor
# arg0 -> monitor name(you can get monitor names with `hyprctl monitors`);
# arg1 -> resolution@hertz;
# arg2 -> positioning from the top-left corner;
# arg3 -> scaling;
# arg4 -> variable refresh rate(optional);
# - arg40 -> 1: vrr, 0: no vrr.
# Example configuration:
# monitor = HDMI-A-1, 1920x1080@60, 0x0, 1, vrr, 0
-8
View File
@@ -1,8 +0,0 @@
############################
## WINDOW & LAYER RULES ##
############################
# See https://wiki.hyprland.org/Configuring/Window-Rules for
# more information on how to do this
-2
View File
@@ -1,2 +0,0 @@
# User configuration
# Add your settings for kitty here
+1
View File
@@ -1,4 +1,5 @@
node_modules/ node_modules/
@girs/ @girs/
build/
pnpm-lock.yaml pnpm-lock.yaml
+203
View File
@@ -0,0 +1,203 @@
// fix ags needing --gtk 4
// import app from "ags/gtk4/app";
import {
PluginApps,
PluginClipboard,
PluginMedia,
PluginShell,
PluginWallpapers,
PluginWebSearch
} from "./runner/plugins";
import { Wireplumber } from "./scripts/volume";
import { handleArguments } from "./scripts/arg-handler";
import { Runner } from "./runner/Runner";
import { Windows } from "./windows";
import { Notifications } from "./scripts/notifications";
import { Wallpaper } from "./scripts/wallpaper";
import { Stylesheet } from "./scripts/stylesheet";
import { Clipboard } from "./scripts/clipboard";
import { Config } from "./scripts/config";
import { Gdk, Gtk } from "ags/gtk4";
import { createRoot, getScope } from "ags";
import { triggerOSD } from "./window/OSD";
import { programArgs, programInvocationName } from "system";
import { encoder, decoder } from "./scripts/utils";
import GObject, { register } from "ags/gobject";
import AstalNotifd from "gi://AstalNotifd";
import GLib from "gi://GLib?version=2.0";
import Gio from "gi://Gio?version=2.0";
const runnerPlugins: Array<Runner.Plugin> = [
PluginApps,
PluginShell,
PluginWebSearch,
PluginMedia,
PluginWallpapers,
PluginClipboard
];
const defaultWindows: Array<string> = [];
@register({ GTypeName: "Shell" })
export class Shell extends Gtk.Application {
private static instance: Shell;
#loop!: GLib.MainLoop;
#scope!: ReturnType<typeof getScope>;
#stylesheet: Uint8Array|undefined;
#styleProvider: Gtk.CssProvider;
get scope() { return this.#scope; }
constructor() {
super({
applicationId: "io.github.retrozinndev.colorshell",
flags: Gio.ApplicationFlags.HANDLES_COMMAND_LINE,
version: "1.1.0",
});
this.#styleProvider = Gtk.CssProvider.new();
}
public static getDefault(): Shell {
if(!this.instance)
this.instance = new Shell();
return this.instance;
}
public resetStyle(): void {
this.#stylesheet = undefined;
Gtk.StyleContext.remove_provider_for_display(
Gdk.Display.get_default()!,
this.#styleProvider
);
}
public applyStyle(stylesheet: string): void {
const previous = this.#stylesheet ? decoder.decode(this.#stylesheet) : undefined;
let final = "";
if(previous)
final = previous + "\n";
this.#stylesheet = encoder.encode(stylesheet);
final = final.concat(stylesheet);
this.#styleProvider.load_from_string(final);
Gtk.StyleContext.add_provider_for_display(
Gdk.Display.get_default()!,
this.#styleProvider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
);
}
vfunc_command_line(cmd: Gio.ApplicationCommandLine): number {
const args = cmd.get_arguments();
if(cmd.isRemote) {
cmd.print_literal(handleArguments(args));
cmd.done();
return 0;
}
this.main(args);
return 0;
}
private main(_args: Array<string>): void {
this.#loop = GLib.MainLoop.new(null, false);
const connections = new Map<GObject.Object, Array<number> | number>();
connections.set(this, this.connect("shutdown", () => this.#scope.dispose()));
createRoot(() => {
console.log(`Colorshell: initialized instance as: "colorshell"`);
this.#scope = getScope();
Stylesheet.getDefault().compileApply();
// Init clipboard module
Clipboard.getDefault();
console.log("Initializing wallpaper handler");
Wallpaper.getDefault();
console.log("Adding runner plugins");
runnerPlugins.forEach(plugin => Runner.addPlugin(plugin));
connections.set(Wireplumber.getDefault(),
Wireplumber.getDefault().getDefaultSink().connect("notify::volume", () =>
triggerOSD())
);
connections.set(Notifications.getDefault(), [
Notifications.getDefault().connect("notification-added", (_, _notif: AstalNotifd.Notification) => {
Windows.getDefault().open("floating-notifications");
}),
Notifications.getDefault().connect("notification-removed", (_: Notifications, _id: number) => {
_.notifications.length === 0 && Windows.getDefault().close("floating-notifications");
})
]);
defaultWindows.forEach(w => Windows.getDefault().open(w));
});
this.#scope.onCleanup(() => {
console.log("Colorshell: disposing connections and quitting because of ::shutdown");
connections.forEach((ids, obj) => Array.isArray(ids) ?
ids.forEach(id => obj.disconnect(id))
: obj.disconnect(ids));
});
this.#loop.run();
}
}
const generalConfigDefaults = {
notifications: {
timeout_low: 4000,
timeout_normal: 6000,
timeout_critical: 0
},
night_light: {
/** whether to save night light values to disk */
save_on_shutdown: true
},
workspaces: {
/** breaks `enable_helper`, makes all workspaces show their respective ID
* by default */
always_show_id: false,
/** this is the function that shows the Workspace's IDs
* around the current workspace if one breaks the crescent order.
* It basically helps keyboard navigation between workspaces.
* ---
* Example: 1(empty, current, shows ID), 2(empty, does not appear(makes
* the previous not to be in a crescent order)), 3(not empty, shows ID) */
enable_helper: true
},
clock: {
/** use the same format as gnu's `date` command */
date_format: "%A %d, %H:%M"
},
misc: {
play_bell_on_volume_change: true
}
};
export const generalConfig = new Config<keyof typeof generalConfigDefaults,
typeof generalConfigDefaults[keyof typeof generalConfigDefaults]>(
`${GLib.get_user_config_dir()}/colorshell/config.json`, generalConfigDefaults
);
Shell.getDefault().runAsync([ programInvocationName, ...programArgs ]);
View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Before

Width:  |  Height:  |  Size: 261 B

After

Width:  |  Height:  |  Size: 261 B

Before

Width:  |  Height:  |  Size: 803 B

After

Width:  |  Height:  |  Size: 803 B

Before

Width:  |  Height:  |  Size: 781 B

After

Width:  |  Height:  |  Size: 781 B

Before

Width:  |  Height:  |  Size: 289 B

After

Width:  |  Height:  |  Size: 289 B

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Before

Width:  |  Height:  |  Size: 928 B

After

Width:  |  Height:  |  Size: 928 B

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

@@ -204,7 +204,7 @@ function selectPreviousItem(listbox: Gtk.ListBox) {
const selectedRow = listbox.get_selected_row(); const selectedRow = listbox.get_selected_row();
const prevRow = selectedRow?.get_prev_sibling(); const prevRow = selectedRow?.get_prev_sibling();
if(!prevRow || selectedRow === listbox.get_row_at_index(0)) if(!prevRow || selectedRow === listbox.get_first_child())
return; return;
const viewport = listbox.parent as Gtk.Viewport; const viewport = listbox.parent as Gtk.Viewport;
@@ -225,12 +225,13 @@ function selectNextItem(listbox: Gtk.ListBox) {
return; return;
const viewport = listbox.parent as Gtk.Viewport; const viewport = listbox.parent as Gtk.Viewport;
const vadjustment = (viewport.parent as Gtk.ScrolledWindow).get_vadjustment(); const vadjustment = viewport.vadjustment;
const nextRowVAllocation = (nextRow.get_allocation().y + nextRow.get_allocation().height); const [, , nextRowY] = nextRow.translate_coordinates(viewport,
nextRow.get_allocation().x, nextRow.get_allocation().y);
listbox.select_row(nextRow as Gtk.ListBoxRow); listbox.select_row(nextRow as Gtk.ListBoxRow);
if(nextRowVAllocation > viewport.get_allocation().height) if(vadjustment.value < nextRowY)
vadjustment.set_value(nextRow.get_allocation().y - viewport.get_allocation().height + nextRow.get_allocation().height); vadjustment.set_value(nextRowY - vadjustment.value);
} }
export function openRunner(props: RunnerProps, placeholders?: Array<Result>): Astal.Window { export function openRunner(props: RunnerProps, placeholders?: Array<Result>): Astal.Window {
@@ -263,11 +264,13 @@ export function openRunner(props: RunnerProps, placeholders?: Array<Result>): As
case Gdk.KEY_Left: case Gdk.KEY_Left:
case Gdk.KEY_Up: case Gdk.KEY_Up:
selectPreviousItem(listbox); selectPreviousItem(listbox);
gtkEntry?.grab_focus();
return; return;
case Gdk.KEY_Right: case Gdk.KEY_Right:
case Gdk.KEY_Down: case Gdk.KEY_Down:
selectNextItem(listbox); selectNextItem(listbox);
gtkEntry?.grab_focus();
return; return;
} }
@@ -310,8 +313,8 @@ export function openRunner(props: RunnerProps, placeholders?: Array<Result>): As
hscrollbarPolicy={Gtk.PolicyType.NEVER} hexpand vexpand propagateNaturalHeight visible={false} hscrollbarPolicy={Gtk.PolicyType.NEVER} hexpand vexpand propagateNaturalHeight visible={false}
maxContentHeight={props.height}> maxContentHeight={props.height}>
<Gtk.ListBox hexpand vexpand activateOnSingleClick selectionMode={Gtk.SelectionMode.SINGLE} <Gtk.ListBox hexpand activateOnSingleClick selectionMode={Gtk.SelectionMode.SINGLE}
sensitive canFocus focusable onRowActivated={(_, row) => { onRowActivated={(_, row) => {
const child = row.get_child()!; const child = row.get_child()!;
if(child instanceof ResultWidget && !clickTimeout) { if(child instanceof ResultWidget && !clickTimeout) {
@@ -320,7 +323,8 @@ export function openRunner(props: RunnerProps, placeholders?: Array<Result>): As
child.closeOnClick && child.closeOnClick &&
Runner.close(); Runner.close();
} }
}} /> }}
/>
</Gtk.ScrolledWindow> </Gtk.ScrolledWindow>
</Gtk.Box> </Gtk.Box>
</PopupWindow> as Astal.Window </PopupWindow> as Astal.Window
+16
View File
@@ -0,0 +1,16 @@
import { PluginApps } from "./apps"
import { PluginClipboard } from "./clipboard"
import { PluginMedia } from "./media"
import { PluginShell } from "./shell"
import { PluginWallpapers } from "./wallpapers"
import { PluginWebSearch } from "./websearch"
export {
PluginApps,
PluginWebSearch,
PluginClipboard,
PluginShell,
PluginMedia,
PluginWallpapers
};
@@ -9,16 +9,12 @@ import { player, setPlayer } from "../widget/bar/Media";
import { generalConfig } from "../app"; import { generalConfig } from "../app";
import AstalIO from "gi://AstalIO"; import AstalIO from "gi://AstalIO";
import GLib from "gi://GLib?version=2.0";
import App from "ags/gtk4/app";
import AstalMpris from "gi://AstalMpris"; import AstalMpris from "gi://AstalMpris";
let wsTimeout: (AstalIO.Time|undefined); let wsTimeout: (AstalIO.Time|undefined);
export function handleArguments(request: string): any { export function handleArguments(args: Array<string>): any {
const args: Array<string> = GLib.shell_parse_argv(request)[1]!;
switch(args[0]) { switch(args[0]) {
case "help": case "help":
case "h": case "h":
@@ -39,7 +35,7 @@ export function handleArguments(request: string): any {
case "reload": case "reload":
restartInstance(); restartInstance();
return `Restarting instance with name: ${App.instanceName ?? "astal"}`; return "Restarting instance...";
case "runner": case "runner":
!Runner.instance ? !Runner.instance ?
@@ -2,13 +2,13 @@ import { timeout } from "ags/time";
import { monitorFile, readFileAsync } from "ags/file"; import { monitorFile, readFileAsync } from "ags/file";
import { Notifications } from "./notifications"; import { Notifications } from "./notifications";
import { encoder } from "./utils"; import { encoder } from "./utils";
import { Accessor } from "ags";
import GObject, { getter, register } from "ags/gobject"; import GObject, { getter, register } from "ags/gobject";
import GLib from "gi://GLib?version=2.0"; import GLib from "gi://GLib?version=2.0";
import Gio from "gi://Gio?version=2.0"; import Gio from "gi://Gio?version=2.0";
import AstalIO from "gi://AstalIO"; import AstalIO from "gi://AstalIO";
import AstalNotifd from "gi://AstalNotifd"; import AstalNotifd from "gi://AstalNotifd";
import { Accessor } from "ags";
export { Config }; export { Config };
@@ -2,14 +2,13 @@ import { monitorFile } from "ags/file";
import { execAsync } from "ags/process"; import { execAsync } from "ags/process";
import { uwsmIsActive } from "./apps"; import { uwsmIsActive } from "./apps";
import App from "ags/gtk4/app";
import Gio from "gi://Gio?version=2.0"; import Gio from "gi://Gio?version=2.0";
const monitoringPaths = [ "./scripts", "./window", "./app.ts", "env.d.ts" ]; const monitoringPaths = [ "./scripts", "./window", "./app.ts", "env.d.ts" ];
export function restartInstance(): void { export function restartInstance(): void {
execAsync(`astal -q ${ App.instanceName ?? "astal" }`); execAsync(`astal -q "colorshell"`);
Gio.Subprocess.new( Gio.Subprocess.new(
( uwsmIsActive ? ( uwsmIsActive ?
[ "uwsm", "app", "--", "ags", "run" ] [ "uwsm", "app", "--", "ags", "run" ]
@@ -1,9 +1,9 @@
import { monitorFile, readFile } from "ags/file"; import { monitorFile, readFile } from "ags/file";
import { timeout } from "ags/time"; import { timeout } from "ags/time";
import { exec, execAsync } from "ags/process"; import { exec, execAsync } from "ags/process";
import { Shell } from "../app";
import AstalIO from "gi://AstalIO"; import AstalIO from "gi://AstalIO";
import App from "ags/gtk4/app";
import Gio from "gi://Gio?version=2.0"; import Gio from "gi://Gio?version=2.0";
import GLib from "gi://GLib?version=2.0"; import GLib from "gi://GLib?version=2.0";
@@ -30,8 +30,8 @@ export class Stylesheet {
const content = readFile(cssFilePath); const content = readFile(cssFilePath);
if(content?.trim()) { if(content?.trim()) {
App.reset_css(); Shell.getDefault().resetStyle();
App.apply_css(content); Shell.getDefault().applyStyle(content);
console.log("Stylesheet: done applying stylesheet to shell"); console.log("Stylesheet: done applying stylesheet to shell");
return; return;
View File
+26
View File
@@ -0,0 +1,26 @@
// SCSS Variables
// Generated by 'wal'
$wallpaper: "/home/joaov/wallpapers/Anime Girl Drawing Sofa.jpg";
// Special
$background: #0e1721;
$foreground: #c2c5c7;
$cursor: #c2c5c7;
// Colors
$color0: #0e1721;
$color1: #393f39;
$color2: #4d4c46;
$color3: #824f36;
$color4: #6c574a;
$color5: #816956;
$color6: #4e767a;
$color7: #91959b;
$color8: #5d6772;
$color9: #4C544C;
$color10: #67665E;
$color11: #AE6A49;
$color12: #917463;
$color13: #AC8C73;
$color14: #689EA3;
$color15: #c2c5c7;

Some files were not shown because too many files have changed in this diff Show More