Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
a5b893d
Update OSD.ts
NotMephisto Jun 28, 2025
d94268c
Update Status.ts
NotMephisto Jun 28, 2025
cdc7f50
Update Network.ts
NotMephisto Jun 28, 2025
7b58af3
Update Sound.ts
NotMephisto Jun 28, 2025
122268a
Update Sound.ts
NotMephisto Jun 28, 2025
706adeb
Update Media.ts
NotMephisto Jun 28, 2025
fc49d91
Update Page.ts
NotMephisto Jun 28, 2025
6ac17f5
Update style.scss
NotMephisto Jun 28, 2025
4895a63
Update _control-center.scss
NotMephisto Jun 28, 2025
6f0b478
Update BigMedia.ts
NotMephisto Jun 28, 2025
d0a0ae7
Update NotifHistory.ts
NotMephisto Jun 28, 2025
d7c7fe7
Merge branch 'ryo' into ryo
NotMephisto Jun 28, 2025
dc5bd7c
Update app.ts
NotMephisto Jun 28, 2025
771d6e5
Fixing calls
NotMephisto Jul 1, 2025
4e836ae
Fixed default call
NotMephisto Jul 1, 2025
9467814
ops
NotMephisto Jul 1, 2025
ce39f57
Add Keyboard Layout connection for OSD
NotMephisto Jul 1, 2025
6767d9b
Add Layout Widget
NotMephisto Jul 1, 2025
b3de49d
Update _osd.scss
NotMephisto Jul 1, 2025
56187be
Update Sound.ts
NotMephisto Jul 1, 2025
a649158
Merge branch 'retrozinndev:ryo' into ryo
NotMephisto Jul 1, 2025
b111be5
Ops
NotMephisto Jul 1, 2025
0d9b703
Adjusted width_requedst value
NotMephisto Jul 1, 2025
52999b9
Add hours, identify in `Big Media`
NotMephisto Jul 4, 2025
f44150d
Add Live stream scenario in Media player
NotMephisto Jul 4, 2025
fd44116
Now the icon is obtained in a simpler and faster way
NotMephisto Jul 4, 2025
427f926
Fixed copying text with quotes
NotMephisto Jul 4, 2025
42ef725
Update OSD.ts
NotMephisto Jul 4, 2025
d11a782
Update app.ts
NotMephisto Jul 4, 2025
74a0137
Update Sound.ts
NotMephisto Jul 4, 2025
f812171
Update Media.ts
NotMephisto Jul 4, 2025
93c33a9
Update app.ts
NotMephisto Jul 5, 2025
4fed944
Create player.ts
NotMephisto Jul 6, 2025
327ab4a
Update Media.ts
NotMephisto Jul 6, 2025
93affe2
Update BigMedia.ts
NotMephisto Jul 6, 2025
96b30ab
Update BigMedia.ts
NotMephisto Jul 6, 2025
f8fe9c8
Using coverArt() instead of artUrl()
NotMephisto Jul 13, 2025
5131e82
Update app.ts
NotMephisto Jul 16, 2025
d321312
Update CenterWindow.ts
NotMephisto Jul 16, 2025
04da046
Update player.ts
NotMephisto Jul 16, 2025
1b7bf0c
Fixed this#[emitter] is null when LastClient in a state of abstraction
NotMephisto Jul 20, 2025
8ae87d6
Update BigMedia.ts
NotMephisto Jul 22, 2025
c1807e4
Add Slider for BigMedia
NotMephisto Jul 22, 2025
0146c6c
Update player.ts
NotMephisto Jul 22, 2025
5713069
Delete comments
NotMephisto Jul 22, 2025
d98bba5
Update Slider.ts
NotMephisto Jul 22, 2025
230670e
Cleaning up code
NotMephisto Jul 22, 2025
cb5cf8e
Update Slider.ts
NotMephisto Jul 23, 2025
d0a35a0
Update BigMedia.ts
NotMephisto Jul 23, 2025
8564bf7
Update OSD.ts
NotMephisto Jul 23, 2025
8a7e177
Update Slider.ts
NotMephisto Jul 23, 2025
07ef645
Update Slider.ts
NotMephisto Jul 23, 2025
bb95de7
Update Slider.ts
NotMephisto Jul 24, 2025
41e7e40
Fixed keymode settings for PopupWindow
NotMephisto Jul 25, 2025
9337e32
Overall optimization & new sliders
NotMephisto Jul 26, 2025
7fc4dff
Delete ags/widget/center-window/Slider.ts
NotMephisto Jul 26, 2025
44cdd7e
Update PopupWindow.ts
NotMephisto Jul 26, 2025
8465f77
Update Slider.ts
NotMephisto Jul 26, 2025
9cdcbaf
Rework Slider
NotMephisto Jul 27, 2025
deedfe5
Polishing the appearance of sliders...
NotMephisto Jul 27, 2025
5c93506
Just polishing the code, nothing special
NotMephisto Jul 28, 2025
2a3c8bf
Ops..
NotMephisto Jul 28, 2025
43d34b7
Updated the widget creation logic
NotMephisto Aug 3, 2025
d931d2b
Updated the widget creation logic
NotMephisto Aug 3, 2025
f1c9abe
Change some connections for property work `Media.ts` and `BigMedia.ts`
NotMephisto Aug 3, 2025
c347e2c
Fixed Progress Label
NotMephisto Aug 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 42 additions & 15 deletions ags/app.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import AstalNotifd from "gi://AstalNotifd";
import AstalHyprland from "gi://AstalHyprland";
import AstalMpris from "gi://AstalMpris";

import { App } from "astal/gtk3"
import { App, Astal } from "astal/gtk3"
import { Wireplumber } from "./scripts/volume";

import { handleArguments } from "./scripts/arg-handler";
import { Time, timeout } from "astal/time";

import { OSDModes, setOSDMode } from "./window/OSD";
import { OSDModes, setOSDMode, variableHandler } from "./window/OSD";

import { Runner } from "./runner/Runner";
import { PluginApps } from "./runner/plugins/apps";
Expand All @@ -22,7 +24,11 @@ import { Stylesheet } from "./scripts/stylesheet";
import { Clipboard } from "./scripts/clipboard";
import { PluginClipboard } from "./runner/plugins/clipboard";
import { Config } from "./scripts/config";
import { AstalPlayers } from "./scripts/player";

const hyprland = AstalHyprland.get_default();
const audio = Wireplumber.getDefault();
const player = AstalPlayers.getDefault();

let osdTimer: (Time|undefined);
let connections = new Map<GObject.Object, (Array<number> | number)>();
Expand All @@ -46,6 +52,7 @@ App.start({
main: (..._args: Array<string>) => {
console.log(`Initialized astal instance as: ${ App.instanceName || "astal" }`);


console.log("Config: initializing configuration file");
Config.getDefault();

Expand All @@ -61,11 +68,37 @@ App.start({
// Init clipboard module
Clipboard.getDefault();

connections.set(Wireplumber.getDefault(), [
Wireplumber.getDefault().getDefaultSink().connect("notify::volume", () =>
triggerOSD(OSDModes.SINK))
//OSD Layout
connections.set(hyprland, [
hyprland.connect("keyboard-layout", (_, Keyboard, layout) => {
variableHandler(OSDModes.LAYOUT, layout);
triggerOSD(OSDModes.LAYOUT);
})
]);

const audioHandler = () => triggerOSD(OSDModes.SINK);
const sinkHandler = () => triggerOSD(OSDModes.SOURCE);
//OSD Wireplumber
connections.set(audio, [
audio.getDefaultSink().connect("notify::volume", audioHandler),
audio.getDefaultSink().connect("notify::mute", audioHandler),
audio.getDefaultSource().connect("notify::volume", sinkHandler),
audio.getDefaultSource().connect("notify::mute", sinkHandler),
]);

//OSD Player
/*connections.set(player, [
AstalPlayers.getDefault().activePlayer.connect("notify::title", () =>
triggerOSD(OSDModes.PLAYER)
),
player.activePlayer.connect("notify::playback-status", (s) => {
if (s.playbackStatus === AstalMpris.PlaybackStatus.PLAYING &&
hyprland.get_focused_client().get_fullscreen() === AstalHyprland.Fullscreen.FULLSCREEN &&
hyprland.get_focused_client().get_class().toLowerCase() !== player.activePlayer.get_enrty().toLowerCase())
triggerOSD(OSDModes.PLAYER);
})
])*/

connections.set(Notifications.getDefault(), [
Notifications.getDefault().connect("notification-added", (_, _notif: AstalNotifd.Notification) => {
Windows.open("floating-notifications");
Expand All @@ -91,21 +124,15 @@ App.start({
});

function triggerOSD(osdModeParam: OSDModes) {
if(Windows.isVisible("control-center")) return;
if (Windows.isVisible("control-center")) return;

Windows.open("osd");
setOSDMode(osdModeParam);

if(!osdTimer) {
setOSDMode(osdModeParam);
osdTimer = timeout(3000, () => {
osdTimer = undefined;
Windows.close("osd");
});

return;
if (osdTimer) {
osdTimer.cancel();
}

osdTimer.cancel();
osdTimer = timeout(3000, () => {
Windows.close("osd");
osdTimer = undefined;
Expand Down
3 changes: 2 additions & 1 deletion ags/scripts/clipboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ class Clipboard extends GObject.Object {
}

public async copyAsync(content: string): Promise<void> {
await execAsync(`wl-copy "${content}"`).catch((err: Gio.IOErrorEnum) => {
const sanitizedContent = content.replace(/"/g, '\\"');
await execAsync(`wl-copy "${sanitizedContent}"`).catch((err: Gio.IOErrorEnum) => {
console.error(`Clipboard: Couldn't copy text using wl-copy. Stderr:\n\t${err.message
} | Stack:\n\t\t${err.stack}`);
});
Expand Down
110 changes: 110 additions & 0 deletions ags/scripts/player.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import { GObject, register, property } from "astal";
import AstalMpris from "gi://AstalMpris";

export { AstalPlayers };

@register({ GTypeName: "AstalPlayers" })
class AstalPlayers extends GObject.Object {
private static astalMpris: AstalMpris.Mpris = AstalMpris.Mpris.get_default();
private static inst: AstalPlayers;

#players: AstalMpris.Player[] = [];
#activePlayer: AstalMpris.Player | null = null;
#playerConnections: Map<AstalMpris.Player, number[]> = new Map();

@property(AstalMpris.Player)
get activePlayer() {
return this.#activePlayer;
}

constructor() {
super();

AstalPlayers.astalMpris.connect('player-added', (_, player) => this._addPlayer(player));
AstalPlayers.astalMpris.connect('player-closed', (_, player) => this._removePlayer(player));

this.#players = AstalPlayers.astalMpris.get_players();
this.#players.forEach(player => this._addPlayerSignals(player));

this._updateActivePlayer();
}

private _addPlayer(player: AstalMpris.Player) {
if (this.#players.includes(player)) return;

this.#players.push(player);
this._addPlayerSignals(player);
this._updateActivePlayer();
}

private _addPlayerSignals(player: AstalMpris.Player) {
const handler = () => this._onPlayerStateChanged(player);

const ids = [
player.connect('notify::playback-status', handler),
//player.connect('notify::cover-art', handler),
player.connect('notify::identity', handler),
//player.connect('notify::track-id', handler),
// player.connect('notify::title', handler),
// player.connect('notify::artist', handler),
player.connect('notify::metadata', handler),
player.connect('notify::position', handler)
];

this.#playerConnections.set(player, ids);
}

private _removePlayer(player: AstalMpris.Player) {
this.#players = this.#players.filter(p => p !== player);

if (this.#playerConnections.has(player)) {
const ids = this.#playerConnections.get(player)!;
ids.forEach(id => player.disconnect(id));
this.#playerConnections.delete(player);
}

this._updateActivePlayer();
}

private _onPlayerStateChanged(player: AstalMpris.Player) {
const wasActivePlayer = this.#activePlayer;
this._updateActivePlayer();

if (this.#activePlayer === wasActivePlayer && this.#activePlayer === player) {
this.notify('active-player');
}
}

private _updateActivePlayer() {
const playingPlayer = this.#players.find(p => p.playbackStatus === AstalMpris.PlaybackStatus.PLAYING);
let newActivePlayer;

if (playingPlayer) {
newActivePlayer = playingPlayer;
} else if (this.#activePlayer && this.#players.includes(this.#activePlayer)) {
newActivePlayer = this.#activePlayer;
} else {
newActivePlayer = null;
}

if (this.#activePlayer !== newActivePlayer) {
this.#activePlayer = newActivePlayer;
this.notify('active-player');
}
}

public static getDefault(): AstalPlayers {
if (!AstalPlayers.inst) {
AstalPlayers.inst = new AstalPlayers();
}
return AstalPlayers.inst;
}

public connect(signal: string, callback: (...args: any[]) => void): number {
return super.connect(signal, callback);
}

public disconnect(id: number): void {
super.disconnect(id);
}
}
22 changes: 20 additions & 2 deletions ags/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ menu {
}
}

.button-row {
.button-row, .top-row {
& > button {
background: colors.$bg-secondary;
margin: 0 1px;
Expand All @@ -232,7 +232,7 @@ menu {
&:hover {
background: colors.$bg-tertiary;
}

&:first-child {
border-top-left-radius: 10px;
border-bottom-left-radius: 10px;
Expand All @@ -247,6 +247,24 @@ menu {
}
}

//Need some workouts///////////////
switch {
padding: 4px;
border-radius: 16px;
background: functions.toRGB(color.adjust($color: wal.$color1, $lightness: -20%));
&:checked {
background: colors.$bg-tertiary;
}
}

switch slider {
border-radius: 12px;
color: colors.$bg-primary;
background: wal.$foreground;
transition: all 0.2s ease-in-out;
}
/////////////////////////////////////

selection {
background: colors.$bg-tertiary;
}
Expand Down
9 changes: 5 additions & 4 deletions ags/style/_control-center.scss
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
font-weight: 600;
}

& > box:not(.button-row) icon {
& > box:not(.button-row):not(.top-row) icon {
font-size: 12px;
color: colors.$fg-disabled;
margin-right: 3px;
Expand All @@ -47,7 +47,7 @@
color: colors.$fg-disabled;
}

& .button-row {
& .button-row, & .top-row {
& button {
padding: 7px;
margin: {
Expand Down Expand Up @@ -169,6 +169,7 @@
}

box.history {
margin-top: 10px;
background: colors.$bg-translucent;
box-shadow: 0 0 6px 1px colors.$bg-translucent;
border-radius: 24px;
Expand All @@ -186,8 +187,8 @@ box.history {
}
}

& > .button-row {
margin-top: 12px;
& > .button-row, & > .top-row {
margin-bottom: 12px;

& button {
padding: 6px;
Expand Down
7 changes: 6 additions & 1 deletion ags/style/_osd.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@
background: funs.toRGB(color.change($color: wal.$background, $alpha: 65%));
padding: 16px;
border-radius: 24px;
min-width: 180px;
min-width: 60px;

.action {
font-size: 14px;
font-weight: 600;
}

.icon {
margin-right: 10px;
Expand Down
19 changes: 17 additions & 2 deletions ags/widget/PopupWindow.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { Binding } from "astal";
import { Binding, bind } from "astal";
import { Astal, Gdk, Gtk, Widget } from "astal/gtk3";
import { BackgroundWindow } from "./BackgroundWindow";
import AstalHyprland from "gi://AstalHyprland";
import { Windows } from "../windows";

const hyprland = AstalHyprland.get_default();

type PopupWindowSpecificProps = {
onDestroy?: (self: Widget.Window) => void;
Expand Down Expand Up @@ -51,12 +55,23 @@ export function PopupWindow(props: PopupWindowProps): Widget.Window {
winProps[key as keyof typeof winProps] = props[key as keyof typeof props];
}

let isFullscreen: boolean;

return new Widget.Window({
...winProps,
namespace: props?.namespace ?? "popup-window",
className: `popup-window ${(props.namespace instanceof Binding ?
props.namespace.get() : props.namespace) || ""}`,
keymode: Astal.Keymode.EXCLUSIVE,
keymode: bind(hyprland, 'focusedWorkspace').as(fw => {

if (Windows.isVisible('logout-menu')) return Astal.Keymode.EXCLUSIVE;

if (fw.get_last_client() === null) return Astal.Keymode.ON_DEMAND;

return fw.get_last_client().get_fullscreen() === AstalHyprland.Fullscreen.FULLSCREEN && fw.get_last_client().get_workspace() === fw
? Astal.Keymode.EXCLUSIVE
: Astal.Keymode.ON_DEMAND
}),
anchor: TOP | LEFT | RIGHT | BOTTOM,
exclusivity: props.exclusivity ?? Astal.Exclusivity.NORMAL,
halign: undefined,
Expand Down
Loading