Compare commits
No commits in common. "e2d8754f813e21cc779186b726cbee0859d1b086" and "6fe0e49378b9dc5374027e199c6adebbc67f2538" have entirely different histories.
e2d8754f81
...
6fe0e49378
9 changed files with 68 additions and 261 deletions
|
@ -7,11 +7,11 @@ export default async() => {
|
||||||
const AppLauncher = (await import('../widgets/applauncher/main')).default;
|
const AppLauncher = (await import('../widgets/applauncher/main')).default;
|
||||||
const Bar = (await import('../widgets/bar/wim')).default;
|
const Bar = (await import('../widgets/bar/wim')).default;
|
||||||
const BgFade = (await import('../widgets/bg-fade/main')).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 Clipboard = (await import('../widgets/clipboard/main')).default;
|
||||||
const Corners = (await import('../widgets/corners/main')).default;
|
const Corners = (await import('../widgets/corners/main')).default;
|
||||||
const IconBrowser = (await import('../widgets/icon-browser/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 OSD = (await import('../widgets/osd/main')).default;
|
||||||
const PowerMenu = (await import('../widgets/powermenu/main')).default;
|
const PowerMenu = (await import('../widgets/powermenu/main')).default;
|
||||||
const Screenshot = (await import('../widgets/screenshot/main')).default;
|
const Screenshot = (await import('../widgets/screenshot/main')).default;
|
||||||
|
|
|
@ -11,10 +11,11 @@ const SCREEN_ICONS: Record<number, string> = {
|
||||||
|
|
||||||
const INTERVAL = 500;
|
const INTERVAL = 500;
|
||||||
|
|
||||||
|
|
||||||
@register()
|
@register()
|
||||||
class Brightness extends GObject.Object {
|
class Brightness extends GObject.Object {
|
||||||
declare private _kbd: string | undefined;
|
declare private _kbd: string;
|
||||||
declare private _caps: string | undefined;
|
declare private _caps: string;
|
||||||
|
|
||||||
declare private _screen: number;
|
declare private _screen: number;
|
||||||
|
|
||||||
|
@ -50,28 +51,15 @@ class Brightness extends GObject.Object {
|
||||||
return this._screenIcon;
|
return this._screenIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
public hasKbd = false;
|
declare private _kbdMax: number;
|
||||||
declare private _kbdMax: number | undefined;
|
declare private _kbdLevel: number;
|
||||||
declare private _kbdLevel: number | undefined;
|
|
||||||
|
|
||||||
@property(Number)
|
@property(Number)
|
||||||
get kbdLevel() {
|
get kbdLevel() {
|
||||||
if (!this._kbdMax) {
|
|
||||||
console.error('[get kbdLevel] No Keyboard brightness');
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this._kbdLevel;
|
return this._kbdLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
set kbdLevel(value) {
|
set kbdLevel(value) {
|
||||||
if (!this._kbdMax || !value) {
|
|
||||||
console.error('[set kbdLevel] No Keyboard brightness');
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value < 0 || value > this._kbdMax) {
|
if (value < 0 || value > this._kbdMax) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -106,22 +94,19 @@ class Brightness extends GObject.Object {
|
||||||
* @param o.kbd name of kbd in brightnessctl
|
* @param o.kbd name of kbd in brightnessctl
|
||||||
* @param o.caps name of caps_lock 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 {
|
try {
|
||||||
if (kbd) {
|
this._monitorKbdState();
|
||||||
this.hasKbd = true;
|
this._kbdMax = Number(await execAsync(`brightnessctl -d ${this._kbd} m`));
|
||||||
this._kbd = kbd;
|
|
||||||
this._monitorKbdState();
|
|
||||||
this._kbdMax = Number(await execAsync(`brightnessctl -d ${this._kbd} m`));
|
|
||||||
}
|
|
||||||
|
|
||||||
this._caps = caps;
|
|
||||||
this._screen = Number(await execAsync('brightnessctl g')) /
|
this._screen = Number(await execAsync('brightnessctl g')) /
|
||||||
Number(await execAsync('brightnessctl m'));
|
Number(await execAsync('brightnessctl m'));
|
||||||
this.notify('screen');
|
this.notify('screen');
|
||||||
}
|
}
|
||||||
catch (_e) {
|
catch (_e) {
|
||||||
console.error('missing dependency: brightnessctl');
|
console.error('missing dependancy: brightnessctl');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,18 +124,16 @@ class Brightness extends GObject.Object {
|
||||||
|
|
||||||
private _monitorKbdState() {
|
private _monitorKbdState() {
|
||||||
const timer = interval(INTERVAL, () => {
|
const timer = interval(INTERVAL, () => {
|
||||||
execAsync(`brightnessctl -d ${this._kbd} g`)
|
execAsync(`brightnessctl -d ${this._kbd} g`).then(
|
||||||
.then(
|
(out) => {
|
||||||
(out) => {
|
if (parseInt(out) !== this._kbdLevel) {
|
||||||
if (parseInt(out) !== this._kbdLevel) {
|
this._kbdLevel = parseInt(out);
|
||||||
this._kbdLevel = parseInt(out);
|
this.notify('kbd-level');
|
||||||
this.notify('kbd-level');
|
}
|
||||||
}
|
},
|
||||||
},
|
).catch(() => {
|
||||||
)
|
timer?.cancel();
|
||||||
.catch(() => {
|
});
|
||||||
timer?.cancel();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
|
|
@ -1,8 +1,10 @@
|
||||||
import { bind, Variable } from 'astal';
|
import { bind, Variable } from 'astal';
|
||||||
import { Gtk } from 'astal/gtk3';
|
import { Astal, Gtk } from 'astal/gtk3';
|
||||||
|
|
||||||
import GLib from 'gi://GLib';
|
import GLib from 'gi://GLib';
|
||||||
|
|
||||||
|
import PopupWindow from '../misc/popup-window';
|
||||||
|
|
||||||
|
|
||||||
const Divider = () => (
|
const Divider = () => (
|
||||||
<box
|
<box
|
||||||
|
@ -63,7 +65,7 @@ const Time = () => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default () => {
|
const DateWidget = () => {
|
||||||
const cal = new Gtk.Calendar({
|
const cal = new Gtk.Calendar({
|
||||||
show_day_names: true,
|
show_day_names: true,
|
||||||
show_heading: true,
|
show_heading: true,
|
||||||
|
@ -84,3 +86,12 @@ export default () => {
|
||||||
</box>
|
</box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<PopupWindow
|
||||||
|
name="calendar"
|
||||||
|
anchor={Astal.WindowAnchor.TOP}
|
||||||
|
>
|
||||||
|
<DateWidget />
|
||||||
|
</PopupWindow>
|
||||||
|
);
|
||||||
|
|
|
@ -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>
|
|
||||||
);
|
|
|
@ -2,10 +2,9 @@ import { App, Astal, Gtk, Widget } from 'astal/gtk3';
|
||||||
import { property, register } from 'astal/gobject';
|
import { property, register } from 'astal/gobject';
|
||||||
import { Binding, idle } from 'astal';
|
import { Binding, idle } from 'astal';
|
||||||
|
|
||||||
import { hyprMessage } from '../../lib';
|
import { get_hyprland_monitor, hyprMessage } from '../../lib';
|
||||||
|
|
||||||
/* Types */
|
/* Types */
|
||||||
import AstalHyprland from 'gi://AstalHyprland';
|
|
||||||
type CloseType = 'none' | 'stay' | 'released' | 'clicked';
|
type CloseType = 'none' | 'stay' | 'released' | 'clicked';
|
||||||
type HyprTransition = 'slide' | 'slide top' | 'slide bottom' | 'slide left' |
|
type HyprTransition = 'slide' | 'slide top' | 'slide bottom' | 'slide left' |
|
||||||
'slide right' | 'popin' | 'fade';
|
'slide right' | 'popin' | 'fade';
|
||||||
|
@ -81,22 +80,15 @@ export class PopupWindow extends Widget.Window {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
async set_x_pos(
|
set_x_pos(
|
||||||
alloc: Gtk.Allocation,
|
alloc: Gtk.Allocation,
|
||||||
side = 'right' as 'left' | 'right',
|
side = 'right' as 'left' | 'right',
|
||||||
) {
|
) {
|
||||||
const monitor = this.gdkmonitor ??
|
const monitor = this.gdkmonitor ??
|
||||||
this.get_display().get_monitor_at_point(alloc.x, alloc.y);
|
this.get_display().get_monitor_at_point(alloc.x, alloc.y);
|
||||||
|
|
||||||
// FIXME: switch back to this when it's fixed upstream
|
// @ts-expect-error this should exist
|
||||||
// const transform = get_hyprland_monitor(monitor)?.transform;
|
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;
|
|
||||||
|
|
||||||
let width: number;
|
let width: number;
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ const setTime = (time: number): string => GLib.DateTime
|
||||||
const NotifIcon = ({ notifObj }: {
|
const NotifIcon = ({ notifObj }: {
|
||||||
notifObj: AstalNotifd.Notification
|
notifObj: AstalNotifd.Notification
|
||||||
}) => {
|
}) => {
|
||||||
let icon: string | undefined;
|
let icon: string;
|
||||||
|
|
||||||
if (notifObj.get_image() && notifObj.get_image() !== '') {
|
if (notifObj.get_image() && notifObj.get_image() !== '') {
|
||||||
icon = notifObj.get_image();
|
icon = notifObj.get_image();
|
||||||
|
@ -36,7 +36,7 @@ const NotifIcon = ({ notifObj }: {
|
||||||
else {
|
else {
|
||||||
icon = Applications.fuzzy_query(
|
icon = Applications.fuzzy_query(
|
||||||
notifObj.get_app_name(),
|
notifObj.get_app_name(),
|
||||||
)[0]?.get_icon_name();
|
)[0].get_icon_name();
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -48,16 +48,14 @@ const NotifIcon = ({ notifObj }: {
|
||||||
min-height: 78px;
|
min-height: 78px;
|
||||||
`}
|
`}
|
||||||
>
|
>
|
||||||
{icon && (
|
<icon
|
||||||
<icon
|
icon={icon}
|
||||||
icon={icon}
|
css="font-size: 58px;"
|
||||||
css="font-size: 58px;"
|
halign={Gtk.Align.CENTER}
|
||||||
halign={Gtk.Align.CENTER}
|
hexpand
|
||||||
hexpand
|
valign={Gtk.Align.CENTER}
|
||||||
valign={Gtk.Align.CENTER}
|
vexpand
|
||||||
vexpand
|
/>
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</box>
|
</box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -138,30 +138,26 @@ export default () => {
|
||||||
</box>
|
</box>
|
||||||
</box>
|
</box>
|
||||||
|
|
||||||
{
|
<box
|
||||||
Brightness.hasKbd && (
|
name="keyboard"
|
||||||
<box
|
css="margin-bottom: 80px;"
|
||||||
name="keyboard"
|
|
||||||
css="margin-bottom: 80px;"
|
|
||||||
|
|
||||||
setup={(self) => {
|
setup={(self) => {
|
||||||
self.hook(Brightness, 'notify::kbd-level', () => {
|
self.hook(Brightness, 'notify::kbd-level', () => {
|
||||||
popup('keyboard');
|
popup('keyboard');
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<box className="osd-item widget">
|
<box className="osd-item widget">
|
||||||
<icon icon="keyboard-brightness-symbolic" />
|
<icon icon="keyboard-brightness-symbolic" />
|
||||||
|
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
fraction={bind(Brightness, 'kbdLevel').as((v) => (v ?? 0) / 2)}
|
fraction={bind(Brightness, 'kbdLevel').as((v) => v / 2)}
|
||||||
sensitive={bind(Brightness, 'kbdLevel').as((v) => v !== 0)}
|
sensitive={bind(Brightness, 'kbdLevel').as((v) => v !== 0)}
|
||||||
valign={Gtk.Align.CENTER}
|
valign={Gtk.Align.CENTER}
|
||||||
/>
|
/>
|
||||||
</box>
|
</box>
|
||||||
</box>
|
</box>
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
<box
|
<box
|
||||||
name="caps"
|
name="caps"
|
||||||
|
|
Loading…
Reference in a new issue