From 85a9b91aad8817f41b35c0c6df9ea87b7103fc4f Mon Sep 17 00:00:00 2001 From: matt1432 Date: Mon, 25 Nov 2024 17:25:27 -0500 Subject: [PATCH] feat(ags osk): add spam typing on long press --- .../widgets/on-screen-keyboard/_index.scss | 3 +- .../widgets/on-screen-keyboard/gesture.ts | 28 ++-- .../widgets/on-screen-keyboard/keyboard.tsx | 2 +- .../widgets/on-screen-keyboard/keys.tsx | 149 +++++++++--------- .../widgets/on-screen-keyboard/main.tsx | 21 +-- .../widgets/on-screen-keyboard/osk-window.tsx | 1 - 6 files changed, 96 insertions(+), 108 deletions(-) diff --git a/nixosModules/ags/config/widgets/on-screen-keyboard/_index.scss b/nixosModules/ags/config/widgets/on-screen-keyboard/_index.scss index bcb82491..6d1749ca 100644 --- a/nixosModules/ags/config/widgets/on-screen-keyboard/_index.scss +++ b/nixosModules/ags/config/widgets/on-screen-keyboard/_index.scss @@ -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 { diff --git a/nixosModules/ags/config/widgets/on-screen-keyboard/gesture.ts b/nixosModules/ags/config/widgets/on-screen-keyboard/gesture.ts index 27681122..730b0eca 100644 --- a/nixosModules/ags/config/widgets/on-screen-keyboard/gesture.ts +++ b/nixosModules/ags/config/widgets/on-screen-keyboard/gesture.ts @@ -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 = ` diff --git a/nixosModules/ags/config/widgets/on-screen-keyboard/keyboard.tsx b/nixosModules/ags/config/widgets/on-screen-keyboard/keyboard.tsx index 57f08cde..b204f3dc 100644 --- a/nixosModules/ags/config/widgets/on-screen-keyboard/keyboard.tsx +++ b/nixosModules/ags/config/widgets/on-screen-keyboard/keyboard.tsx @@ -115,8 +115,8 @@ export default () => ( return ( {...keys} diff --git a/nixosModules/ags/config/widgets/on-screen-keyboard/keys.tsx b/nixosModules/ags/config/widgets/on-screen-keyboard/keys.tsx index bd70ae31..270bdb45 100644 --- a/nixosModules/ags/config/widgets/on-screen-keyboard/keys.tsx +++ b/nixosModules/ags/config/widgets/on-screen-keyboard/keys.tsx @@ -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 = ( { - 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} @@ -147,66 +116,63 @@ const ModKey = (key: Key) => { }; const RegularKey = (key: Key) => { + const IsActive = Variable(false); + const IsLongPressing = Variable(false); + + IsLongPressing.subscribe((v) => { + console.log(v); + }); + const widget = ( { + IsLongPressing.set(false); + IsActive.set(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(); + }; - execAsync(`ydotool key ${key.keycode}:1`); - execAsync(`ydotool key ${key.keycode}:0`); - NormalClick.set(true); + widget.hook(gesture, 'begin', () => { + IsActive.set(true); + }); + + widget.hook(gesture, 'cancelled', () => { + onClick(() => { + execAsync(`ydotool key ${key.keycode}:1`); + execAsync(`ydotool key ${key.keycode}:0`); + + 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 ( diff --git a/nixosModules/ags/config/widgets/on-screen-keyboard/main.tsx b/nixosModules/ags/config/widgets/on-screen-keyboard/main.tsx index 2eafdb1f..c4a7b1f2 100644 --- a/nixosModules/ags/config/widgets/on-screen-keyboard/main.tsx +++ b/nixosModules/ags/config/widgets/on-screen-keyboard/main.tsx @@ -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(( { > - ) as OskWindow; - - window.hook(tablet, 'notify::osk-state', (self, state) => { - self.setVisible(state); - }); - - idle(() => { - window.setVisible(false); - }); - - return Gesture(window); + ) as OskWindow); }; diff --git a/nixosModules/ags/config/widgets/on-screen-keyboard/osk-window.tsx b/nixosModules/ags/config/widgets/on-screen-keyboard/osk-window.tsx index 3d0c7960..baa98db2 100644 --- a/nixosModules/ags/config/widgets/on-screen-keyboard/osk-window.tsx +++ b/nixosModules/ags/config/widgets/on-screen-keyboard/osk-window.tsx @@ -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;