2024-11-25 17:26:48 -05:00
|
|
|
import { execAsync, idle } from 'astal';
|
2024-11-25 12:09:03 -05:00
|
|
|
import { Gtk } from 'astal/gtk3';
|
|
|
|
|
2024-11-25 17:26:48 -05:00
|
|
|
import Tablet from '../../services/tablet';
|
2024-11-25 12:09:03 -05:00
|
|
|
import { hyprMessage } from '../../lib';
|
|
|
|
|
|
|
|
import OskWindow from './osk-window';
|
|
|
|
|
|
|
|
|
|
|
|
const KEY_N = 249;
|
|
|
|
const HIDDEN_MARGIN = 340;
|
|
|
|
|
|
|
|
const releaseAllKeys = () => {
|
|
|
|
const keycodes = Array.from(Array(KEY_N).keys());
|
|
|
|
|
|
|
|
execAsync([
|
|
|
|
'ydotool', 'key',
|
|
|
|
...keycodes.map((keycode) => `${keycode}:0`),
|
|
|
|
]).catch(print);
|
|
|
|
};
|
|
|
|
|
|
|
|
export default (window: OskWindow) => {
|
2024-11-25 17:26:48 -05:00
|
|
|
const tablet = Tablet.get_default();
|
2024-11-25 12:09:03 -05:00
|
|
|
|
|
|
|
let signals = [] as number[];
|
|
|
|
|
2024-11-25 17:26:48 -05:00
|
|
|
const gesture = Gtk.GestureDrag.new(window);
|
|
|
|
|
|
|
|
window.get_child().css = `
|
|
|
|
margin-bottom: -${HIDDEN_MARGIN}px;
|
|
|
|
`;
|
|
|
|
|
|
|
|
window.hook(tablet, 'notify::osk-state', () => {
|
|
|
|
if (tablet.oskState) {
|
2024-11-25 12:09:03 -05:00
|
|
|
window.setSlideDown();
|
|
|
|
|
|
|
|
window.get_child().css = `
|
|
|
|
transition: margin-bottom 0.7s cubic-bezier(0.36, 0, 0.66, -0.56);
|
|
|
|
margin-bottom: 0px;
|
|
|
|
`;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
releaseAllKeys();
|
2024-11-25 17:26:48 -05:00
|
|
|
|
2024-11-25 12:09:03 -05:00
|
|
|
window.setSlideUp();
|
|
|
|
|
|
|
|
window.get_child().css = `
|
|
|
|
transition: margin-bottom 0.7s cubic-bezier(0.36, 0, 0.66, -0.56);
|
|
|
|
margin-bottom: -${HIDDEN_MARGIN}px;
|
|
|
|
`;
|
|
|
|
}
|
2024-11-25 17:26:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
idle(() => {
|
|
|
|
tablet.oskState = false;
|
|
|
|
});
|
2024-11-25 12:09:03 -05:00
|
|
|
|
|
|
|
window.killGestureSigs = () => {
|
|
|
|
signals.forEach((id) => {
|
|
|
|
gesture.disconnect(id);
|
|
|
|
});
|
|
|
|
signals = [];
|
|
|
|
window.startY = null;
|
|
|
|
};
|
|
|
|
|
|
|
|
window.setSlideUp = () => {
|
|
|
|
window.killGestureSigs();
|
|
|
|
|
|
|
|
// Begin drag
|
|
|
|
signals.push(
|
|
|
|
gesture.connect('drag-begin', () => {
|
|
|
|
hyprMessage('j/cursorpos').then((out) => {
|
|
|
|
window.startY = JSON.parse(out).y;
|
|
|
|
});
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
|
|
|
|
// Update drag
|
|
|
|
signals.push(
|
|
|
|
gesture.connect('drag-update', () => {
|
|
|
|
hyprMessage('j/cursorpos').then((out) => {
|
|
|
|
if (!window.startY) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const currentY = JSON.parse(out).y;
|
|
|
|
const offset = window.startY - currentY;
|
|
|
|
|
|
|
|
if (offset < 0) {
|
|
|
|
window.get_child().css = `
|
|
|
|
transition: margin-bottom 0.5s ease-in-out;
|
|
|
|
margin-bottom: -${HIDDEN_MARGIN}px;
|
|
|
|
`;
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2024-11-25 13:15:13 -05:00
|
|
|
if (offset > HIDDEN_MARGIN) {
|
|
|
|
window.get_child().css = `
|
|
|
|
margin-bottom: 0px;
|
|
|
|
`;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
window.get_child().css = `
|
|
|
|
margin-bottom: ${offset - HIDDEN_MARGIN}px;
|
|
|
|
`;
|
|
|
|
}
|
2024-11-25 12:09:03 -05:00
|
|
|
});
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
|
|
|
|
// End drag
|
|
|
|
signals.push(
|
|
|
|
gesture.connect('drag-end', () => {
|
|
|
|
hyprMessage('j/cursorpos').then((out) => {
|
|
|
|
if (!window.startY) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const currentY = JSON.parse(out).y;
|
|
|
|
const offset = window.startY - currentY;
|
|
|
|
|
|
|
|
if (offset > HIDDEN_MARGIN) {
|
|
|
|
window.get_child().css = `
|
|
|
|
transition: margin-bottom 0.5s ease-in-out;
|
|
|
|
margin-bottom: 0px;
|
|
|
|
`;
|
2024-11-25 17:26:48 -05:00
|
|
|
tablet.oskState = true;
|
2024-11-25 12:09:03 -05:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
window.get_child().css = `
|
|
|
|
transition: margin-bottom 0.5s ease-in-out;
|
|
|
|
margin-bottom: -${HIDDEN_MARGIN}px;
|
|
|
|
`;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
window.setSlideDown = () => {
|
|
|
|
window.killGestureSigs();
|
|
|
|
|
|
|
|
// Begin drag
|
|
|
|
signals.push(
|
|
|
|
gesture.connect('drag-begin', () => {
|
|
|
|
hyprMessage('j/cursorpos').then((out) => {
|
|
|
|
window.startY = JSON.parse(out).y;
|
|
|
|
});
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
|
|
|
|
// Update drag
|
|
|
|
signals.push(
|
|
|
|
gesture.connect('drag-update', () => {
|
|
|
|
hyprMessage('j/cursorpos').then((out) => {
|
|
|
|
if (!window.startY) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const currentY = JSON.parse(out).y;
|
|
|
|
const offset = window.startY - currentY;
|
|
|
|
|
|
|
|
if (offset > 0) {
|
|
|
|
window.get_child().css = `
|
|
|
|
transition: margin-bottom 0.5s ease-in-out;
|
|
|
|
margin-bottom: 0px;
|
|
|
|
`;
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
window.get_child().css = `
|
|
|
|
margin-bottom: ${offset}px;
|
|
|
|
`;
|
|
|
|
});
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
|
|
|
|
// End drag
|
|
|
|
signals.push(
|
|
|
|
gesture.connect('drag-end', () => {
|
|
|
|
hyprMessage('j/cursorpos').then((out) => {
|
|
|
|
if (!window.startY) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const currentY = JSON.parse(out).y;
|
|
|
|
const offset = window.startY - currentY;
|
|
|
|
|
|
|
|
if (offset < -(HIDDEN_MARGIN * 2 / 3)) {
|
|
|
|
window.get_child().css = `
|
|
|
|
transition: margin-bottom 0.5s ease-in-out;
|
|
|
|
margin-bottom: -${HIDDEN_MARGIN}px;
|
|
|
|
`;
|
|
|
|
|
2024-11-25 17:26:48 -05:00
|
|
|
tablet.oskState = false;
|
2024-11-25 12:09:03 -05:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
window.get_child().css = `
|
|
|
|
transition: margin-bottom 0.5s ease-in-out;
|
|
|
|
margin-bottom: 0px;
|
|
|
|
`;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
return window;
|
|
|
|
};
|