feat(ags osk): add spam typing on long press
All checks were successful
Discord / discord commits (push) Has been skipped

This commit is contained in:
matt1432 2024-11-25 17:25:27 -05:00
parent f445db75c1
commit 85a9b91aad
6 changed files with 96 additions and 108 deletions

View file

@ -32,8 +32,7 @@
border-radius: 0.7rem;
min-height: 3rem;
transition: background-color 0.2s ease-in-out,
border-color 0.2s ease-in-out;
transition: background-color 0.2s ease-in-out, border-color 0.2s ease-in-out;
&.normal,
&.Super {

View file

@ -1,6 +1,7 @@
import { execAsync } from 'astal';
import { execAsync, idle } from 'astal';
import { Gtk } from 'astal/gtk3';
import Tablet from '../../services/tablet';
import { hyprMessage } from '../../lib';
import OskWindow from './osk-window';
@ -19,14 +20,18 @@ const releaseAllKeys = () => {
};
export default (window: OskWindow) => {
const gesture = Gtk.GestureDrag.new(window);
window.get_child().css = `margin-bottom: -${HIDDEN_MARGIN}px;`;
const tablet = Tablet.get_default();
let signals = [] as number[];
window.setVisible = (state: boolean) => {
if (state) {
const gesture = Gtk.GestureDrag.new(window);
window.get_child().css = `
margin-bottom: -${HIDDEN_MARGIN}px;
`;
window.hook(tablet, 'notify::osk-state', () => {
if (tablet.oskState) {
window.setSlideDown();
window.get_child().css = `
@ -36,6 +41,7 @@ export default (window: OskWindow) => {
}
else {
releaseAllKeys();
window.setSlideUp();
window.get_child().css = `
@ -43,7 +49,11 @@ export default (window: OskWindow) => {
margin-bottom: -${HIDDEN_MARGIN}px;
`;
}
};
});
idle(() => {
tablet.oskState = false;
});
window.killGestureSigs = () => {
signals.forEach((id) => {
@ -115,7 +125,7 @@ export default (window: OskWindow) => {
transition: margin-bottom 0.5s ease-in-out;
margin-bottom: 0px;
`;
window.setVisible(true);
tablet.oskState = true;
}
else {
window.get_child().css = `
@ -184,7 +194,7 @@ export default (window: OskWindow) => {
margin-bottom: -${HIDDEN_MARGIN}px;
`;
window.setVisible(false);
tablet.oskState = false;
}
else {
window.get_child().css = `

View file

@ -115,8 +115,8 @@ export default () => (
return (
<box vertical>
<box
halign={Gtk.Align.END}
className="row"
halign={Gtk.Align.END}
>
{...keys}
</box>

View file

@ -1,11 +1,13 @@
import { execAsync, Variable } from 'astal';
import { Gdk, Gtk, Widget } from 'astal/gtk3';
import { bind, execAsync, interval, Variable } from 'astal';
import { Gtk, Widget } from 'astal/gtk3';
import Brightness from '../../services/brightness';
import Separator from '../misc/separator';
/* Types */
import AstalIO from 'gi://AstalIO';
interface Key {
keytype: string
label: string
@ -16,7 +18,6 @@ interface Key {
}
const display = Gdk.Display.get_default();
const brightness = Brightness.get_default();
const SPACING = 4;
@ -24,10 +25,6 @@ const LSHIFT_CODE = 42;
const LALT_CODE = 56;
const LCTRL_CODE = 29;
// Keep track of when a non modifier key
// is clicked to release all modifiers
const NormalClick = Variable(false);
// Keep track of modifier statuses
const Super = Variable(false);
const LAlt = Variable(false);
@ -97,42 +94,14 @@ const ModKey = (key: Key) => {
const button = (
<eventbox
className="key"
cursor="pointer"
onButtonReleaseEvent={() => {
console.log('mod toggled');
onButtonPressEvent={() => {
execAsync(`ydotool key ${key.keycode}:${Mod.get() ? 0 : 1}`);
label.toggleClassName('active', !Mod.get());
Mod.set(!Mod.get());
}}
setup={(self) => {
self.hook(NormalClick, () => {
Mod.set(false);
label.toggleClassName('active', false);
execAsync(`ydotool key ${key.keycode}:0`);
});
// OnHover
self.connect('enter-notify-event', () => {
if (!display) {
return;
}
self.window.set_cursor(Gdk.Cursor.new_from_name(
display,
'pointer',
));
self.toggleClassName('hover', true);
});
// OnHoverLost
self.connect('leave-notify-event', () => {
self.window.set_cursor(null);
self.toggleClassName('hover', false);
});
}}
>
{label}
</eventbox>
@ -147,65 +116,62 @@ const ModKey = (key: Key) => {
};
const RegularKey = (key: Key) => {
const IsActive = Variable(false);
const IsLongPressing = Variable(false);
IsLongPressing.subscribe((v) => {
console.log(v);
});
const widget = (
<eventbox
className="key"
cursor="pointer"
onButtonReleaseEvent={() => {
IsLongPressing.set(false);
IsActive.set(false);
}}
>
<label
className={`normal ${key.label}`}
className={bind(IsActive).as((v) => [
'normal',
key.label,
(v ? 'active' : ''),
].join(' '))}
label={key.label}
setup={(self) => {
self
.hook(Shift, () => {
if (!key.labelShift) {
return;
if (key.labelShift) {
self.label = Shift.get() ?
key.labelShift :
key.label;
}
self.label = Shift.get() ? key.labelShift : key.label;
})
.hook(Caps, () => {
if (key.label === 'Caps') {
self.toggleClassName('active', Caps.get());
IsActive.set(Caps.get());
return;
}
if (!key.labelShift) {
return;
}
if (key.label.match(/[A-Za-z]/)) {
if (key.labelShift && key.label.match(/[A-Za-z]/)) {
self.label = Caps.get() ?
key.labelShift :
key.label;
}
})
.hook(AltGr, () => {
if (!key.labelAltGr) {
return;
}
if (key.labelAltGr) {
self.toggleClassName('altgr', AltGr.get());
self.label = AltGr.get() ? key.labelAltGr : key.label;
});
// OnHover
self.connect('enter-notify-event', () => {
if (!display) {
return;
self.label = AltGr.get() ?
key.labelAltGr :
key.label;
}
self.window.set_cursor(Gdk.Cursor.new_from_name(
display,
'pointer',
));
self.toggleClassName('hover', true);
});
// OnHoverLost
self.connect('leave-notify-event', () => {
self.window.set_cursor(null);
self.toggleClassName('hover', false);
});
}}
/>
@ -216,8 +182,7 @@ const RegularKey = (key: Key) => {
gesture.delay_factor = 1.0;
// OnPrimaryClickRelease
widget.hook(gesture, 'cancelled', () => {
const onClick = (callback: () => void) => {
const pointer = gesture.get_point(null);
const x = pointer[1];
const y = pointer[2];
@ -226,11 +191,41 @@ const RegularKey = (key: Key) => {
return;
}
console.log('key clicked');
callback();
};
widget.hook(gesture, 'begin', () => {
IsActive.set(true);
});
widget.hook(gesture, 'cancelled', () => {
onClick(() => {
execAsync(`ydotool key ${key.keycode}:1`);
execAsync(`ydotool key ${key.keycode}:0`);
NormalClick.set(true);
IsActive.set(false);
});
});
// Long Press
widget.hook(gesture, 'pressed', () => {
onClick(() => {
IsLongPressing.set(true);
});
});
let spamClick: AstalIO.Time | undefined;
IsLongPressing.subscribe((v) => {
if (v) {
spamClick = interval(100, () => {
execAsync(`ydotool key ${key.keycode}:1`);
execAsync(`ydotool key ${key.keycode}:0`);
});
}
else {
spamClick?.cancel();
}
});
return (

View file

@ -1,20 +1,15 @@
import { execAsync, idle } from 'astal';
import { execAsync } from 'astal';
import { Astal } from 'astal/gtk3';
import Tablet from '../../services/tablet';
import OskWindow from './osk-window';
import Gesture from './gesture';
import Keyboard from './keyboard';
export default () => {
// Start ydotool daemon
execAsync('ydotoold').catch(print);
const tablet = Tablet.get_default();
const window = (
return Gesture((
<OskWindow
name="osk"
namespace="noanim-osk"
@ -29,15 +24,5 @@ export default () => {
>
<Keyboard />
</OskWindow>
) as OskWindow;
window.hook(tablet, 'notify::osk-state', (self, state) => {
self.setVisible(state);
});
idle(() => {
window.setVisible(false);
});
return Gesture(window);
) as OskWindow);
};

View file

@ -6,7 +6,6 @@ import { register } from 'astal/gobject';
export default class OskWindow extends Widget.Window {
public startY: number | null = null;
declare public setVisible: (state: boolean) => void;
declare public killGestureSigs: () => void;
declare public setSlideUp: () => void;
declare public setSlideDown: () => void;