forked from Shinonome/dots-hyprland
Initial commit
This commit is contained in:
@@ -0,0 +1,175 @@
|
||||
const { GLib, Gdk, Gtk } = imports.gi;
|
||||
import { App, Service, Utils, Widget } from '../../imports.js';
|
||||
import Hyprland from 'resource:///com/github/Aylur/ags/service/hyprland.js';
|
||||
const { Box, EventBox, Button, Revealer } = Widget;
|
||||
const { execAsync, exec } = Utils;
|
||||
import { MaterialIcon } from '../../lib/materialicon.js';
|
||||
import { separatorLine } from '../../lib/separator.js';
|
||||
import { defaultOskLayout, oskLayouts } from '../../data/keyboardlayouts.js';
|
||||
import { setupCursorHoverGrab } from '../../lib/cursorhover.js';
|
||||
|
||||
const keyboardLayout = defaultOskLayout;
|
||||
const keyboardJson = oskLayouts[keyboardLayout];
|
||||
execAsync(`ydotoold`).catch(print); // Start ydotool daemon
|
||||
|
||||
function releaseAllKeys() {
|
||||
const keycodes = Array.from(Array(249).keys());
|
||||
execAsync([`ydotool`, `key`, ...keycodes.map(keycode => `${keycode}:0`)])
|
||||
.then(console.log('Released all keys'))
|
||||
.catch(print);
|
||||
}
|
||||
var modsPressed = false;
|
||||
|
||||
const topDecor = Box({
|
||||
vertical: true,
|
||||
children: [
|
||||
Box({
|
||||
hpack: 'center',
|
||||
className: 'osk-dragline',
|
||||
homogeneous: true,
|
||||
children: [EventBox({
|
||||
setup: setupCursorHoverGrab,
|
||||
})]
|
||||
})
|
||||
]
|
||||
});
|
||||
|
||||
const keyboardControlButton = (icon, text, runFunction) => Button({
|
||||
className: 'osk-control-button spacing-h-10',
|
||||
onClicked: () => runFunction(),
|
||||
child: Widget.Box({
|
||||
children: [
|
||||
MaterialIcon(icon, 'norm'),
|
||||
Widget.Label({
|
||||
label: `${text}`,
|
||||
}),
|
||||
]
|
||||
})
|
||||
})
|
||||
|
||||
const keyboardControls = Box({
|
||||
vertical: true,
|
||||
className: 'spacing-v-5',
|
||||
children: [
|
||||
Button({
|
||||
className: 'osk-control-button txt-norm icon-material',
|
||||
onClicked: () => {
|
||||
releaseAllKeys();
|
||||
App.toggleWindow('osk');
|
||||
},
|
||||
label: 'keyboard_hide',
|
||||
}),
|
||||
Button({
|
||||
className: 'osk-control-button txt-norm',
|
||||
label: `${keyboardJson['name_short']}`,
|
||||
}),
|
||||
Button({
|
||||
className: 'osk-control-button txt-norm icon-material',
|
||||
onClicked: () => { // TODO: Proper clipboard widget, since fuzzel doesn't receive mouse inputs
|
||||
execAsync([`bash`, `-c`, "pkill fuzzel || cliphist list | fuzzel --no-fuzzy --dmenu | cliphist decode | wl-copy"]).catch(print);
|
||||
},
|
||||
label: 'assignment',
|
||||
}),
|
||||
]
|
||||
})
|
||||
|
||||
const keyboardItself = (kbJson) => {
|
||||
return Box({
|
||||
vertical: true,
|
||||
className: 'spacing-v-5',
|
||||
children: kbJson.keys.map(row => Box({
|
||||
vertical: false,
|
||||
className: 'spacing-h-5',
|
||||
children: row.map(key => {
|
||||
return Button({
|
||||
className: `osk-key osk-key-${key.shape}`,
|
||||
hexpand: (key.shape == "space" || key.shape == "expand"),
|
||||
label: key.label,
|
||||
setup: (button) => {
|
||||
let pressed = false;
|
||||
if (key.keytype == "normal") {
|
||||
button.connect('pressed', () => { // mouse down
|
||||
execAsync(`ydotool key ${key.keycode}:1`);
|
||||
});
|
||||
button.connect('clicked', () => { // release
|
||||
execAsync(`ydotool key ${key.keycode}:0`);
|
||||
});
|
||||
}
|
||||
else if (key.keytype == "modkey") {
|
||||
button.connect('pressed', () => { // release
|
||||
if (pressed) {
|
||||
execAsync(`ydotool key ${key.keycode}:0`);
|
||||
button.toggleClassName('osk-key-active', false);
|
||||
pressed = false;
|
||||
}
|
||||
else {
|
||||
execAsync(`ydotool key ${key.keycode}:1`);
|
||||
button.toggleClassName('osk-key-active', true);
|
||||
pressed = true;
|
||||
modsPressed = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
const keyboardWindow = Box({
|
||||
vexpand: true,
|
||||
hexpand: true,
|
||||
vertical: true,
|
||||
className: 'osk-window spacing-v-5',
|
||||
children: [
|
||||
topDecor,
|
||||
Box({
|
||||
className: 'osk-body spacing-h-10',
|
||||
children: [
|
||||
keyboardControls,
|
||||
separatorLine,
|
||||
keyboardItself(keyboardJson),
|
||||
],
|
||||
})
|
||||
],
|
||||
connections: [[App, (box, name, visible) => { // Update on open
|
||||
if (name == 'osk' && visible) {
|
||||
keyboardWindow.setCss(`margin-bottom: -0px;`);
|
||||
}
|
||||
}],],
|
||||
});
|
||||
|
||||
const gestureEvBox = EventBox({ child: keyboardWindow })
|
||||
const gesture = Gtk.GestureDrag.new(gestureEvBox);
|
||||
gesture.connect('drag-begin', () => {
|
||||
Hyprland.sendMessage('j/cursorpos').then((out) => {
|
||||
gesture.startY = JSON.parse(out).y;
|
||||
}).catch(print);
|
||||
});
|
||||
gesture.connect('drag-update', () => {
|
||||
Hyprland.sendMessage('j/cursorpos').then((out) => {
|
||||
const currentY = JSON.parse(out).y;
|
||||
const offset = gesture.startY - currentY;
|
||||
|
||||
if (offset > 0) return;
|
||||
|
||||
keyboardWindow.setCss(`
|
||||
margin-bottom: ${offset}px;
|
||||
`);
|
||||
}).catch(print);
|
||||
});
|
||||
gesture.connect('drag-end', () => {
|
||||
var offset = gesture.get_offset()[2];
|
||||
if (offset > 50) {
|
||||
App.closeWindow('osk');
|
||||
}
|
||||
else {
|
||||
keyboardWindow.setCss(`
|
||||
transition: margin-bottom 170ms cubic-bezier(0.05, 0.7, 0.1, 1);
|
||||
margin-bottom: 0px;
|
||||
`);
|
||||
}
|
||||
})
|
||||
|
||||
export default () => gestureEvBox;
|
||||
Reference in New Issue
Block a user