nixos-configs/modules/ags/config/ts/on-screen-keyboard/gesture.ts

158 lines
4.6 KiB
TypeScript
Raw Normal View History

const Hyprland = await Service.import('hyprland');
const { execAsync, timeout } = Utils;
2023-12-21 01:25:59 -05:00
const { Gtk } = imports.gi;
import Tablet from '../../services/tablet.ts';
const KEY_N = 249;
const HIDDEN_MARGIN = 340;
const ANIM_DURATION = 700;
2024-01-13 11:15:08 -05:00
// Types
2024-01-29 20:56:56 -05:00
import { BoxGeneric } from 'global-types';
2024-01-13 11:15:08 -05:00
const releaseAllKeys = () => {
const keycodes = Array.from(Array(KEY_N).keys());
execAsync([
'ydotool', 'key',
...keycodes.map((keycode) => `${keycode}:0`),
]).catch(print);
};
2024-01-29 20:56:56 -05:00
export default (window) => {
const gesture = Gtk.GestureDrag.new(window);
2024-01-29 20:56:56 -05:00
const child = window.child as BoxGeneric;
2024-01-13 11:15:08 -05:00
child.setCss(`margin-bottom: -${HIDDEN_MARGIN}px;`);
2024-01-13 11:15:08 -05:00
let signals = [] as Array<number>;
2023-12-21 01:25:59 -05:00
window.attribute = {
2024-01-22 10:23:32 -05:00
startY: null,
2024-01-13 11:15:08 -05:00
setVisible: (state: boolean) => {
2023-12-21 01:25:59 -05:00
if (state) {
window.visible = true;
window.attribute.setSlideDown();
2024-01-13 11:15:08 -05:00
child.setCss(`
2023-12-21 01:25:59 -05:00
transition: margin-bottom 0.7s
cubic-bezier(0.36, 0, 0.66, -0.56);
margin-bottom: 0px;
`);
}
else {
timeout(ANIM_DURATION + 10, () => {
if (!Tablet.tabletMode) {
window.visible = false;
}
});
2023-12-21 01:25:59 -05:00
releaseAllKeys();
window.attribute.setSlideUp();
2024-01-13 11:15:08 -05:00
child.setCss(`
2023-12-21 01:25:59 -05:00
transition: margin-bottom 0.7s
cubic-bezier(0.36, 0, 0.66, -0.56);
margin-bottom: -${HIDDEN_MARGIN}px;
`);
2023-12-21 01:25:59 -05:00
}
},
2023-12-21 01:25:59 -05:00
killGestureSigs: () => {
signals.forEach((id) => {
gesture.disconnect(id);
});
signals = [];
2024-01-22 10:23:32 -05:00
window.attribute.startY = null;
2023-12-21 01:25:59 -05:00
},
setSlideUp: () => {
window.attribute.killGestureSigs();
// Begin drag
signals.push(
gesture.connect('drag-begin', () => {
2024-02-11 02:18:59 -05:00
Hyprland.messageAsync('j/cursorpos').then((out) => {
2024-01-22 10:23:32 -05:00
window.attribute.startY = JSON.parse(out).y;
2023-12-21 01:25:59 -05:00
});
}),
);
// Update drag
signals.push(
gesture.connect('drag-update', () => {
2024-02-11 02:18:59 -05:00
Hyprland.messageAsync('j/cursorpos').then((out) => {
2023-12-21 01:25:59 -05:00
const currentY = JSON.parse(out).y;
2024-01-22 10:23:32 -05:00
const offset = window.attribute.startY - currentY;
2023-12-21 01:25:59 -05:00
if (offset < 0) {
return;
}
2024-01-29 20:56:56 -05:00
(window.child as BoxGeneric).setCss(`
2023-12-21 01:25:59 -05:00
margin-bottom: ${offset - HIDDEN_MARGIN}px;
`);
});
}),
);
// End drag
signals.push(
gesture.connect('drag-end', () => {
2024-01-29 20:56:56 -05:00
(window.child as BoxGeneric).setCss(`
2023-12-21 01:25:59 -05:00
transition: margin-bottom 0.5s ease-in-out;
margin-bottom: -${HIDDEN_MARGIN}px;
`);
2023-12-21 01:25:59 -05:00
}),
);
},
setSlideDown: () => {
window.attribute.killGestureSigs();
// Begin drag
signals.push(
gesture.connect('drag-begin', () => {
2024-02-11 02:18:59 -05:00
Hyprland.messageAsync('j/cursorpos').then((out) => {
2024-01-22 10:23:32 -05:00
window.attribute.startY = JSON.parse(out).y;
2023-12-21 01:25:59 -05:00
});
}),
);
// Update drag
signals.push(
gesture.connect('drag-update', () => {
2024-02-11 02:18:59 -05:00
Hyprland.messageAsync('j/cursorpos').then((out) => {
2023-12-21 01:25:59 -05:00
const currentY = JSON.parse(out).y;
2024-01-22 10:23:32 -05:00
const offset = window.attribute.startY - currentY;
2023-12-21 01:25:59 -05:00
if (offset > 0) {
return;
}
2024-01-29 20:56:56 -05:00
(window.child as BoxGeneric).setCss(`
2023-12-21 01:25:59 -05:00
margin-bottom: ${offset}px;
`);
});
}),
);
// End drag
signals.push(
gesture.connect('drag-end', () => {
2024-01-29 20:56:56 -05:00
(window.child as BoxGeneric).setCss(`
2023-12-21 01:25:59 -05:00
transition: margin-bottom 0.5s ease-in-out;
margin-bottom: 0px;
`);
}),
);
},
};
return window;
};