refactor(ags): move lockscreen.ts out of the root dir
All checks were successful
Discord / discord commits (push) Has been skipped
All checks were successful
Discord / discord commits (push) Has been skipped
This commit is contained in:
parent
800eee46f2
commit
092626a7db
5 changed files with 216 additions and 218 deletions
|
@ -16,6 +16,8 @@ export default tseslint.config(
|
||||||
eslint.configs.recommended,
|
eslint.configs.recommended,
|
||||||
jsdoc.configs['flat/recommended-typescript'],
|
jsdoc.configs['flat/recommended-typescript'],
|
||||||
|
|
||||||
|
{ ignores: ['js'] },
|
||||||
|
|
||||||
{
|
{
|
||||||
plugins: {
|
plugins: {
|
||||||
jsdoc,
|
jsdoc,
|
||||||
|
|
|
@ -32,7 +32,7 @@ export const transpileTypeScript = async(host) => {
|
||||||
// Let bun see tsconfig.json
|
// Let bun see tsconfig.json
|
||||||
`cd ${App.configDir};` +
|
`cd ${App.configDir};` +
|
||||||
|
|
||||||
`bun build ${App.configDir}/${host}.ts ` +
|
`bun build ${App.configDir}/${host === 'lockscreen' ? 'ts/lockscreen/main' : host}.ts ` +
|
||||||
'--external resource:///* ' +
|
'--external resource:///* ' +
|
||||||
'--external gi://* ' +
|
'--external gi://* ' +
|
||||||
'--external cairo ' +
|
'--external cairo ' +
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
import LaunchLockscreen from './ts/lockscreen/main.ts';
|
|
||||||
|
|
||||||
|
|
||||||
LaunchLockscreen();
|
|
||||||
|
|
||||||
App.config({
|
|
||||||
icons: './icons',
|
|
||||||
});
|
|
211
modules/ags/config/ts/lockscreen/lock.ts
Normal file
211
modules/ags/config/ts/lockscreen/lock.ts
Normal file
|
@ -0,0 +1,211 @@
|
||||||
|
const { Box, Entry, Label, Window } = Widget;
|
||||||
|
|
||||||
|
import Gdk from 'gi://Gdk?version=3.0';
|
||||||
|
import Gtk from 'gi://Gtk?version=3.0';
|
||||||
|
import Lock from 'gi://GtkSessionLock?version=0.1';
|
||||||
|
|
||||||
|
// This file is generated by Nix
|
||||||
|
import Vars from './vars.ts';
|
||||||
|
|
||||||
|
import Separator from '../misc/separator.ts';
|
||||||
|
import { get_hyprland_monitor_desc } from '../lib.ts';
|
||||||
|
|
||||||
|
/* Types */
|
||||||
|
import { Box as AgsBox } from 'types/widgets/box';
|
||||||
|
|
||||||
|
|
||||||
|
const lock = Lock.prepare_lock();
|
||||||
|
const windows: Map<Gdk.Monitor, Gtk.Window> = new Map();
|
||||||
|
const blurBGs: AgsBox<Gtk.Widget, { geometry: { w: number, h: number }; }>[] = [];
|
||||||
|
|
||||||
|
const transition_duration = 1000;
|
||||||
|
const WINDOW_MARGINS = -2;
|
||||||
|
const ENTRY_SPACING = 20;
|
||||||
|
const CLOCK_SPACING = 60;
|
||||||
|
|
||||||
|
const bgCSS = ({ w = 1, h = 1 } = {}) => `
|
||||||
|
border: 2px solid rgba(189, 147, 249, 0.8);
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
min-height: ${h}px;
|
||||||
|
min-width: ${w}px;
|
||||||
|
transition: min-height ${transition_duration / 2}ms,
|
||||||
|
min-width ${transition_duration / 2}ms;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const unlock = () => {
|
||||||
|
blurBGs.forEach((b) => {
|
||||||
|
b.css = bgCSS({
|
||||||
|
w: b.attribute.geometry.w,
|
||||||
|
h: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
Utils.timeout(transition_duration / 2, () => {
|
||||||
|
b.css = bgCSS({
|
||||||
|
w: 1,
|
||||||
|
h: 1,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
Utils.timeout(transition_duration, () => {
|
||||||
|
lock.unlock_and_destroy();
|
||||||
|
Gdk.Display.get_default()?.sync();
|
||||||
|
App.quit();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const Clock = () => Label({ class_name: 'clock' })
|
||||||
|
.poll(1000, (self) => {
|
||||||
|
self.label = (new Date().toLocaleString([], {
|
||||||
|
hour: 'numeric',
|
||||||
|
minute: 'numeric',
|
||||||
|
hour12: true,
|
||||||
|
}) ?? '')
|
||||||
|
.replace('a.m.', 'AM')
|
||||||
|
.replace('p.m.', 'PM');
|
||||||
|
});
|
||||||
|
|
||||||
|
const PasswordPrompt = (monitor: Gdk.Monitor, visible: boolean) => {
|
||||||
|
const rev = Box({
|
||||||
|
css: bgCSS(),
|
||||||
|
attribute: {
|
||||||
|
geometry: {} as { w: number, h: number },
|
||||||
|
},
|
||||||
|
|
||||||
|
setup: (self) => Utils.idle(() => {
|
||||||
|
self.attribute.geometry = {
|
||||||
|
w: monitor.geometry.width,
|
||||||
|
h: monitor.geometry.height,
|
||||||
|
};
|
||||||
|
|
||||||
|
self.css = bgCSS({
|
||||||
|
w: self.attribute.geometry.w,
|
||||||
|
h: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
Utils.timeout(transition_duration / 2, () => {
|
||||||
|
self.css = bgCSS({
|
||||||
|
w: self.attribute.geometry.w,
|
||||||
|
h: self.attribute.geometry.h,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
blurBGs.push(rev);
|
||||||
|
|
||||||
|
Window({
|
||||||
|
name: `blur-bg-${monitor.get_model()}`,
|
||||||
|
gdkmonitor: monitor,
|
||||||
|
layer: 'overlay',
|
||||||
|
anchor: ['top', 'bottom', 'right', 'left'],
|
||||||
|
margins: [WINDOW_MARGINS],
|
||||||
|
exclusivity: 'ignore',
|
||||||
|
|
||||||
|
child: Box({
|
||||||
|
hexpand: false,
|
||||||
|
vexpand: false,
|
||||||
|
hpack: 'center',
|
||||||
|
vpack: 'center',
|
||||||
|
child: rev,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const label = Label('Enter password:');
|
||||||
|
|
||||||
|
return new Gtk.Window({
|
||||||
|
child: visible ?
|
||||||
|
Box({
|
||||||
|
vertical: true,
|
||||||
|
vpack: 'center',
|
||||||
|
hpack: 'center',
|
||||||
|
spacing: 16,
|
||||||
|
|
||||||
|
children: [
|
||||||
|
Clock(),
|
||||||
|
|
||||||
|
Separator(CLOCK_SPACING, { vertical: true }),
|
||||||
|
|
||||||
|
Box({
|
||||||
|
hpack: 'center',
|
||||||
|
class_name: 'avatar',
|
||||||
|
}),
|
||||||
|
|
||||||
|
Box({
|
||||||
|
class_name: 'entry-box',
|
||||||
|
vertical: true,
|
||||||
|
children: [
|
||||||
|
label,
|
||||||
|
|
||||||
|
Separator(ENTRY_SPACING, { vertical: true }),
|
||||||
|
|
||||||
|
Entry({
|
||||||
|
hpack: 'center',
|
||||||
|
xalign: 0.5,
|
||||||
|
visibility: false,
|
||||||
|
placeholder_text: 'password',
|
||||||
|
|
||||||
|
on_accept: (self) => {
|
||||||
|
self.sensitive = false;
|
||||||
|
|
||||||
|
Utils.authenticate(self.text ?? '')
|
||||||
|
.then(() => unlock())
|
||||||
|
.catch((e) => {
|
||||||
|
self.text = '';
|
||||||
|
label.label = e.message;
|
||||||
|
self.sensitive = true;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}).on('realize', (entry) => entry.grab_focus()),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}) :
|
||||||
|
Box(),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const createWindow = (monitor: Gdk.Monitor) => {
|
||||||
|
const hyprDesc = get_hyprland_monitor_desc(monitor);
|
||||||
|
const entryVisible = Vars.mainMonitor === hyprDesc || Vars.dupeLockscreen;
|
||||||
|
const win = PasswordPrompt(monitor, entryVisible);
|
||||||
|
|
||||||
|
windows.set(monitor, win);
|
||||||
|
};
|
||||||
|
|
||||||
|
const lock_screen = () => {
|
||||||
|
const display = Gdk.Display.get_default();
|
||||||
|
|
||||||
|
for (let m = 0; m < (display?.get_n_monitors() ?? 0); m++) {
|
||||||
|
const monitor = display?.get_monitor(m);
|
||||||
|
|
||||||
|
if (monitor) {
|
||||||
|
createWindow(monitor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
display?.connect('monitor-added', (_, monitor) => {
|
||||||
|
createWindow(monitor);
|
||||||
|
});
|
||||||
|
lock.lock_lock();
|
||||||
|
windows.forEach((win, monitor) => {
|
||||||
|
lock.new_surface(win, monitor);
|
||||||
|
win.show();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const on_finished = () => {
|
||||||
|
lock.destroy();
|
||||||
|
Gdk.Display.get_default()?.sync();
|
||||||
|
App.quit();
|
||||||
|
};
|
||||||
|
|
||||||
|
lock.connect('finished', on_finished);
|
||||||
|
|
||||||
|
if (Vars.hasFprintd) {
|
||||||
|
globalThis.authFinger = () => Utils.authenticate('')
|
||||||
|
.then(() => unlock())
|
||||||
|
.catch(logError);
|
||||||
|
globalThis.authFinger();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default () => lock_screen();
|
|
@ -1,211 +1,4 @@
|
||||||
const { Box, Entry, Label, Window } = Widget;
|
import LaunchLockscreen from './lock.ts';
|
||||||
|
|
||||||
import Gdk from 'gi://Gdk?version=3.0';
|
|
||||||
import Gtk from 'gi://Gtk?version=3.0';
|
|
||||||
import Lock from 'gi://GtkSessionLock?version=0.1';
|
|
||||||
|
|
||||||
// This file is generated by Nix
|
|
||||||
import Vars from './vars.ts';
|
|
||||||
|
|
||||||
import Separator from '../misc/separator.ts';
|
|
||||||
import { get_hyprland_monitor_desc } from '../lib.ts';
|
|
||||||
|
|
||||||
/* Types */
|
|
||||||
import { Box as AgsBox } from 'types/widgets/box';
|
|
||||||
|
|
||||||
|
|
||||||
const lock = Lock.prepare_lock();
|
LaunchLockscreen();
|
||||||
const windows: Map<Gdk.Monitor, Gtk.Window> = new Map();
|
|
||||||
const blurBGs: AgsBox<Gtk.Widget, { geometry: { w: number, h: number }; }>[] = [];
|
|
||||||
|
|
||||||
const transition_duration = 1000;
|
|
||||||
const WINDOW_MARGINS = -2;
|
|
||||||
const ENTRY_SPACING = 20;
|
|
||||||
const CLOCK_SPACING = 60;
|
|
||||||
|
|
||||||
const bgCSS = ({ w = 1, h = 1 } = {}) => `
|
|
||||||
border: 2px solid rgba(189, 147, 249, 0.8);
|
|
||||||
background: rgba(0, 0, 0, 0.2);
|
|
||||||
min-height: ${h}px;
|
|
||||||
min-width: ${w}px;
|
|
||||||
transition: min-height ${transition_duration / 2}ms,
|
|
||||||
min-width ${transition_duration / 2}ms;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const unlock = () => {
|
|
||||||
blurBGs.forEach((b) => {
|
|
||||||
b.css = bgCSS({
|
|
||||||
w: b.attribute.geometry.w,
|
|
||||||
h: 1,
|
|
||||||
});
|
|
||||||
|
|
||||||
Utils.timeout(transition_duration / 2, () => {
|
|
||||||
b.css = bgCSS({
|
|
||||||
w: 1,
|
|
||||||
h: 1,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
Utils.timeout(transition_duration, () => {
|
|
||||||
lock.unlock_and_destroy();
|
|
||||||
Gdk.Display.get_default()?.sync();
|
|
||||||
App.quit();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const Clock = () => Label({ class_name: 'clock' })
|
|
||||||
.poll(1000, (self) => {
|
|
||||||
self.label = (new Date().toLocaleString([], {
|
|
||||||
hour: 'numeric',
|
|
||||||
minute: 'numeric',
|
|
||||||
hour12: true,
|
|
||||||
}) ?? '')
|
|
||||||
.replace('a.m.', 'AM')
|
|
||||||
.replace('p.m.', 'PM');
|
|
||||||
});
|
|
||||||
|
|
||||||
const PasswordPrompt = (monitor: Gdk.Monitor, visible: boolean) => {
|
|
||||||
const rev = Box({
|
|
||||||
css: bgCSS(),
|
|
||||||
attribute: {
|
|
||||||
geometry: {} as { w: number, h: number },
|
|
||||||
},
|
|
||||||
|
|
||||||
setup: (self) => Utils.idle(() => {
|
|
||||||
self.attribute.geometry = {
|
|
||||||
w: monitor.geometry.width,
|
|
||||||
h: monitor.geometry.height,
|
|
||||||
};
|
|
||||||
|
|
||||||
self.css = bgCSS({
|
|
||||||
w: self.attribute.geometry.w,
|
|
||||||
h: 1,
|
|
||||||
});
|
|
||||||
|
|
||||||
Utils.timeout(transition_duration / 2, () => {
|
|
||||||
self.css = bgCSS({
|
|
||||||
w: self.attribute.geometry.w,
|
|
||||||
h: self.attribute.geometry.h,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
blurBGs.push(rev);
|
|
||||||
|
|
||||||
Window({
|
|
||||||
name: `blur-bg-${monitor.get_model()}`,
|
|
||||||
gdkmonitor: monitor,
|
|
||||||
layer: 'overlay',
|
|
||||||
anchor: ['top', 'bottom', 'right', 'left'],
|
|
||||||
margins: [WINDOW_MARGINS],
|
|
||||||
exclusivity: 'ignore',
|
|
||||||
|
|
||||||
child: Box({
|
|
||||||
hexpand: false,
|
|
||||||
vexpand: false,
|
|
||||||
hpack: 'center',
|
|
||||||
vpack: 'center',
|
|
||||||
child: rev,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
const label = Label('Enter password:');
|
|
||||||
|
|
||||||
return new Gtk.Window({
|
|
||||||
child: visible ?
|
|
||||||
Box({
|
|
||||||
vertical: true,
|
|
||||||
vpack: 'center',
|
|
||||||
hpack: 'center',
|
|
||||||
spacing: 16,
|
|
||||||
|
|
||||||
children: [
|
|
||||||
Clock(),
|
|
||||||
|
|
||||||
Separator(CLOCK_SPACING, { vertical: true }),
|
|
||||||
|
|
||||||
Box({
|
|
||||||
hpack: 'center',
|
|
||||||
class_name: 'avatar',
|
|
||||||
}),
|
|
||||||
|
|
||||||
Box({
|
|
||||||
class_name: 'entry-box',
|
|
||||||
vertical: true,
|
|
||||||
children: [
|
|
||||||
label,
|
|
||||||
|
|
||||||
Separator(ENTRY_SPACING, { vertical: true }),
|
|
||||||
|
|
||||||
Entry({
|
|
||||||
hpack: 'center',
|
|
||||||
xalign: 0.5,
|
|
||||||
visibility: false,
|
|
||||||
placeholder_text: 'password',
|
|
||||||
|
|
||||||
on_accept: (self) => {
|
|
||||||
self.sensitive = false;
|
|
||||||
|
|
||||||
Utils.authenticate(self.text ?? '')
|
|
||||||
.then(() => unlock())
|
|
||||||
.catch((e) => {
|
|
||||||
self.text = '';
|
|
||||||
label.label = e.message;
|
|
||||||
self.sensitive = true;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}).on('realize', (entry) => entry.grab_focus()),
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
}) :
|
|
||||||
Box(),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const createWindow = (monitor: Gdk.Monitor) => {
|
|
||||||
const hyprDesc = get_hyprland_monitor_desc(monitor);
|
|
||||||
const entryVisible = Vars.mainMonitor === hyprDesc || Vars.dupeLockscreen;
|
|
||||||
const win = PasswordPrompt(monitor, entryVisible);
|
|
||||||
|
|
||||||
windows.set(monitor, win);
|
|
||||||
};
|
|
||||||
|
|
||||||
const lock_screen = () => {
|
|
||||||
const display = Gdk.Display.get_default();
|
|
||||||
|
|
||||||
for (let m = 0; m < (display?.get_n_monitors() ?? 0); m++) {
|
|
||||||
const monitor = display?.get_monitor(m);
|
|
||||||
|
|
||||||
if (monitor) {
|
|
||||||
createWindow(monitor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
display?.connect('monitor-added', (_, monitor) => {
|
|
||||||
createWindow(monitor);
|
|
||||||
});
|
|
||||||
lock.lock_lock();
|
|
||||||
windows.forEach((win, monitor) => {
|
|
||||||
lock.new_surface(win, monitor);
|
|
||||||
win.show();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const on_finished = () => {
|
|
||||||
lock.destroy();
|
|
||||||
Gdk.Display.get_default()?.sync();
|
|
||||||
App.quit();
|
|
||||||
};
|
|
||||||
|
|
||||||
lock.connect('finished', on_finished);
|
|
||||||
|
|
||||||
if (Vars.hasFprintd) {
|
|
||||||
globalThis.authFinger = () => Utils.authenticate('')
|
|
||||||
.then(() => unlock())
|
|
||||||
.catch(logError);
|
|
||||||
globalThis.authFinger();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export default () => lock_screen();
|
|
||||||
|
|
Loading…
Reference in a new issue