Compare commits

..

No commits in common. "e2d8754f813e21cc779186b726cbee0859d1b086" and "6fe0e49378b9dc5374027e199c6adebbc67f2538" have entirely different histories.

9 changed files with 68 additions and 261 deletions

View file

@ -7,11 +7,11 @@ export default async() => {
const AppLauncher = (await import('../widgets/applauncher/main')).default;
const Bar = (await import('../widgets/bar/wim')).default;
const BgFade = (await import('../widgets/bg-fade/main')).default;
const Calendar = (await import('../widgets/date/wim')).default;
const Calendar = (await import('../widgets/date/main')).default;
const Clipboard = (await import('../widgets/clipboard/main')).default;
const Corners = (await import('../widgets/corners/main')).default;
const IconBrowser = (await import('../widgets/icon-browser/main')).default;
const { NotifPopups, NotifCenter } = await import('../widgets/notifs/wim');
const { NotifPopups, NotifCenter } = await import('../widgets/notifs/main');
const OSD = (await import('../widgets/osd/main')).default;
const PowerMenu = (await import('../widgets/powermenu/main')).default;
const Screenshot = (await import('../widgets/screenshot/main')).default;

View file

@ -11,10 +11,11 @@ const SCREEN_ICONS: Record<number, string> = {
const INTERVAL = 500;
@register()
class Brightness extends GObject.Object {
declare private _kbd: string | undefined;
declare private _caps: string | undefined;
declare private _kbd: string;
declare private _caps: string;
declare private _screen: number;
@ -50,28 +51,15 @@ class Brightness extends GObject.Object {
return this._screenIcon;
}
public hasKbd = false;
declare private _kbdMax: number | undefined;
declare private _kbdLevel: number | undefined;
declare private _kbdMax: number;
declare private _kbdLevel: number;
@property(Number)
get kbdLevel() {
if (!this._kbdMax) {
console.error('[get kbdLevel] No Keyboard brightness');
return -1;
}
return this._kbdLevel;
}
set kbdLevel(value) {
if (!this._kbdMax || !value) {
console.error('[set kbdLevel] No Keyboard brightness');
return;
}
if (value < 0 || value > this._kbdMax) {
return;
}
@ -106,22 +94,19 @@ class Brightness extends GObject.Object {
* @param o.kbd name of kbd in brightnessctl
* @param o.caps name of caps_lock in brightnessctl
*/
public async initService({ kbd, caps }: { kbd?: string, caps?: string }) {
public async initService({ kbd = '', caps = '' }) {
this._kbd = kbd;
this._caps = caps;
try {
if (kbd) {
this.hasKbd = true;
this._kbd = kbd;
this._monitorKbdState();
this._kbdMax = Number(await execAsync(`brightnessctl -d ${this._kbd} m`));
}
this._monitorKbdState();
this._kbdMax = Number(await execAsync(`brightnessctl -d ${this._kbd} m`));
this._caps = caps;
this._screen = Number(await execAsync('brightnessctl g')) /
Number(await execAsync('brightnessctl m'));
this.notify('screen');
}
catch (_e) {
console.error('missing dependency: brightnessctl');
console.error('missing dependancy: brightnessctl');
}
}
@ -139,18 +124,16 @@ class Brightness extends GObject.Object {
private _monitorKbdState() {
const timer = interval(INTERVAL, () => {
execAsync(`brightnessctl -d ${this._kbd} g`)
.then(
(out) => {
if (parseInt(out) !== this._kbdLevel) {
this._kbdLevel = parseInt(out);
this.notify('kbd-level');
}
},
)
.catch(() => {
timer?.cancel();
});
execAsync(`brightnessctl -d ${this._kbd} g`).then(
(out) => {
if (parseInt(out) !== this._kbdLevel) {
this._kbdLevel = parseInt(out);
this.notify('kbd-level');
}
},
).catch(() => {
timer?.cancel();
});
});
}

View file

@ -1,158 +0,0 @@
import { execAsync, subprocess } from 'astal';
import GObject, { register } from 'astal/gobject';
/* Types */
interface NotifyAction {
id: string
label: string
callback: () => void
}
interface NotifySendProps {
actions?: NotifyAction[]
appName?: string
body?: string
category?: string
hint?: string
iconName: string
replaceId?: number
title: string
urgency?: 'low' | 'normal' | 'critical'
}
const APP_NAME = 'gpu-screen-recorder';
const ICON_NAME = 'nvidia';
const escapeShellArg = (arg: string): string => `'${arg.replace(/'/g, '\'\\\'\'')}'`;
const notifySend = ({
actions = [],
appName,
body,
category,
hint,
iconName,
replaceId,
title,
urgency = 'normal',
}: NotifySendProps) => new Promise<number>((resolve) => {
let printedId = false;
const cmd = [
'notify-send',
'--print-id',
`--icon=${escapeShellArg(iconName)}`,
escapeShellArg(title),
escapeShellArg(body ?? ''),
// Optional params
appName ? `--app-name=${escapeShellArg(appName)}` : '',
category ? `--category=${escapeShellArg(category)}` : '',
hint ? `--hint=${escapeShellArg(hint)}` : '',
replaceId ? `--replace-id=${replaceId.toString()}` : '',
`--urgency=${urgency}`,
].concat(
actions.map(({ id, label }) => `--action=${escapeShellArg(id)}=${escapeShellArg(label)}`),
).join(' ');
subprocess(
cmd,
(out) => {
if (!printedId) {
resolve(parseInt(out));
printedId = true;
}
else {
actions.find((action) => action.id === out)?.callback();
}
},
(err) => {
console.error(`[Notify] ${err}`);
},
);
});
@register()
class GSR extends GObject.Object {
private _lastNotifID: number | undefined;
constructor() {
super();
subprocess(
['gsr-start'],
(path) => {
if (!this._lastNotifID) {
console.error('[GSR] ID of warning notif not found');
setTimeout(() => {
this._onSaved(path);
}, 1000);
}
else {
this._onSaved(path);
}
},
() => { /**/ },
);
}
public saveReplay() {
execAsync(['gpu-save-replay'])
.then(async() => {
this._lastNotifID = await notifySend({
appName: APP_NAME,
iconName: ICON_NAME,
title: 'Saving Replay',
body: 'Last 20 minutes',
});
})
.catch((err) => {
console.error(`[GSR save-replay] ${err}`);
});
}
private _onSaved(path: string) {
notifySend({
appName: APP_NAME,
iconName: ICON_NAME,
replaceId: this._lastNotifID,
title: 'Replay Saved',
body: `Saved to ${path}`,
actions: [
{
id: 'folder',
label: 'Open Folder',
callback: () => execAsync([
'xdg-open',
path.substring(0, path.lastIndexOf('/')),
]).catch(print),
},
{
id: 'video',
label: 'Open Video',
callback: () => execAsync(['xdg-open', path]).catch(print),
},
{
id: 'kdenlive',
label: 'Edit in kdenlive',
callback: () => execAsync([
'bash',
'-c',
`kdenlive -i ${path}`,
]).catch(print),
},
],
});
}
}
const gsrService = new GSR();
export default gsrService;

View file

@ -1,8 +1,10 @@
import { bind, Variable } from 'astal';
import { Gtk } from 'astal/gtk3';
import { Astal, Gtk } from 'astal/gtk3';
import GLib from 'gi://GLib';
import PopupWindow from '../misc/popup-window';
const Divider = () => (
<box
@ -63,7 +65,7 @@ const Time = () => {
);
};
export default () => {
const DateWidget = () => {
const cal = new Gtk.Calendar({
show_day_names: true,
show_heading: true,
@ -84,3 +86,12 @@ export default () => {
</box>
);
};
export default () => (
<PopupWindow
name="calendar"
anchor={Astal.WindowAnchor.TOP}
>
<DateWidget />
</PopupWindow>
);

View file

@ -1,15 +0,0 @@
import { Astal } from 'astal/gtk3';
import PopupWindow from '../misc/popup-window';
import DateWidget from './main';
export default () => (
<PopupWindow
name="calendar"
anchor={Astal.WindowAnchor.TOP}
>
<DateWidget />
</PopupWindow>
);

View file

@ -2,10 +2,9 @@ import { App, Astal, Gtk, Widget } from 'astal/gtk3';
import { property, register } from 'astal/gobject';
import { Binding, idle } from 'astal';
import { hyprMessage } from '../../lib';
import { get_hyprland_monitor, hyprMessage } from '../../lib';
/* Types */
import AstalHyprland from 'gi://AstalHyprland';
type CloseType = 'none' | 'stay' | 'released' | 'clicked';
type HyprTransition = 'slide' | 'slide top' | 'slide bottom' | 'slide left' |
'slide right' | 'popin' | 'fade';
@ -81,22 +80,15 @@ export class PopupWindow extends Widget.Window {
});
};
async set_x_pos(
set_x_pos(
alloc: Gtk.Allocation,
side = 'right' as 'left' | 'right',
) {
const monitor = this.gdkmonitor ??
this.get_display().get_monitor_at_point(alloc.x, alloc.y);
// FIXME: switch back to this when it's fixed upstream
// const transform = get_hyprland_monitor(monitor)?.transform;
const manufacturer = monitor.manufacturer?.replace(',', '');
const model = monitor.model?.replace(',', '');
const start = `${manufacturer} ${model}`;
const transform = (JSON.parse(await hyprMessage('j/monitors')) as AstalHyprland.Monitor[])
// @ts-expect-error this will be fixed soon
.find((m) => m.description?.startsWith(start))?.transform;
// @ts-expect-error this should exist
const transform = get_hyprland_monitor(monitor)?.transform;
let width: number;

View file

@ -24,7 +24,7 @@ const setTime = (time: number): string => GLib.DateTime
const NotifIcon = ({ notifObj }: {
notifObj: AstalNotifd.Notification
}) => {
let icon: string | undefined;
let icon: string;
if (notifObj.get_image() && notifObj.get_image() !== '') {
icon = notifObj.get_image();
@ -36,7 +36,7 @@ const NotifIcon = ({ notifObj }: {
else {
icon = Applications.fuzzy_query(
notifObj.get_app_name(),
)[0]?.get_icon_name();
)[0].get_icon_name();
}
return (
@ -48,16 +48,14 @@ const NotifIcon = ({ notifObj }: {
min-height: 78px;
`}
>
{icon && (
<icon
icon={icon}
css="font-size: 58px;"
halign={Gtk.Align.CENTER}
hexpand
valign={Gtk.Align.CENTER}
vexpand
/>
)}
<icon
icon={icon}
css="font-size: 58px;"
halign={Gtk.Align.CENTER}
hexpand
valign={Gtk.Align.CENTER}
vexpand
/>
</box>
);
};

View file

@ -138,30 +138,26 @@ export default () => {
</box>
</box>
{
Brightness.hasKbd && (
<box
name="keyboard"
css="margin-bottom: 80px;"
<box
name="keyboard"
css="margin-bottom: 80px;"
setup={(self) => {
self.hook(Brightness, 'notify::kbd-level', () => {
popup('keyboard');
});
}}
>
<box className="osd-item widget">
<icon icon="keyboard-brightness-symbolic" />
setup={(self) => {
self.hook(Brightness, 'notify::kbd-level', () => {
popup('keyboard');
});
}}
>
<box className="osd-item widget">
<icon icon="keyboard-brightness-symbolic" />
<ProgressBar
fraction={bind(Brightness, 'kbdLevel').as((v) => (v ?? 0) / 2)}
sensitive={bind(Brightness, 'kbdLevel').as((v) => v !== 0)}
valign={Gtk.Align.CENTER}
/>
</box>
</box>
)
}
<ProgressBar
fraction={bind(Brightness, 'kbdLevel').as((v) => v / 2)}
sensitive={bind(Brightness, 'kbdLevel').as((v) => v !== 0)}
valign={Gtk.Align.CENTER}
/>
</box>
</box>
<box
name="caps"