feat(ags): make custom onscreen keyboard
This commit is contained in:
parent
8f779d37c5
commit
d56edd5484
14 changed files with 589 additions and 1 deletions
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
nixpkgs.overlays = [
|
nixpkgs.overlays = [
|
||||||
(import ./blueberry.nix)
|
(import ./blueberry.nix)
|
||||||
|
(import ./squeekboard.nix)
|
||||||
neovim-flake.overlay
|
neovim-flake.overlay
|
||||||
|
|
||||||
(final: prev: {
|
(final: prev: {
|
||||||
|
|
41
common/overlays/patches/remove-panel.patch
Normal file
41
common/overlays/patches/remove-panel.patch
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
From 10be06ebc72ec8f516003577dabcedb60fe05982 Mon Sep 17 00:00:00 2001
|
||||||
|
From: matt1432 <matt@nelim.org>
|
||||||
|
Date: Sat, 18 Nov 2023 20:26:50 -0500
|
||||||
|
Subject: [PATCH] remove panel
|
||||||
|
|
||||||
|
---
|
||||||
|
src/panel.c | 6 +++---
|
||||||
|
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/panel.c b/src/panel.c
|
||||||
|
index a9942c8..333727e 100644
|
||||||
|
--- a/src/panel.c
|
||||||
|
+++ b/src/panel.c
|
||||||
|
@@ -75,13 +75,13 @@ panel_manager_request_widget (struct panel_manager *self, struct wl_output *outp
|
||||||
|
PHOSH_TYPE_LAYER_SURFACE,
|
||||||
|
"layer-shell", squeek_wayland->layer_shell,
|
||||||
|
"wl-output", output,
|
||||||
|
- "height", height,
|
||||||
|
+ "height", 1,
|
||||||
|
"anchor", ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM
|
||||||
|
| ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT
|
||||||
|
| ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT,
|
||||||
|
"layer", ZWLR_LAYER_SHELL_V1_LAYER_TOP,
|
||||||
|
"kbd-interactivity", FALSE,
|
||||||
|
- "exclusive-zone", height,
|
||||||
|
+
|
||||||
|
"namespace", "osk",
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
@@ -100,7 +100,7 @@ panel_manager_request_widget (struct panel_manager *self, struct wl_output *outp
|
||||||
|
gtk_window_set_icon_name (GTK_WINDOW(self->window), "squeekboard");
|
||||||
|
gtk_window_set_keep_above (GTK_WINDOW(self->window), TRUE);
|
||||||
|
} else {
|
||||||
|
- panel_manager_resize(self, height);
|
||||||
|
+ panel_manager_resize(self, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!self->widget) {
|
||||||
|
--
|
||||||
|
2.42.0
|
||||||
|
|
7
common/overlays/squeekboard.nix
Normal file
7
common/overlays/squeekboard.nix
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
final: prev: {
|
||||||
|
squeekboard = prev.squeekboard.overrideAttrs (o: {
|
||||||
|
patches = (o.patches or [ ]) ++ [
|
||||||
|
./patches/remove-panel.patch
|
||||||
|
];
|
||||||
|
});
|
||||||
|
}
|
|
@ -39,6 +39,8 @@
|
||||||
"imports": "readonly",
|
"imports": "readonly",
|
||||||
"print": "readonly",
|
"print": "readonly",
|
||||||
"console": "readonly",
|
"console": "readonly",
|
||||||
"logError": "readonly"
|
"logError": "readonly",
|
||||||
|
"setTimeout": "readonly",
|
||||||
|
"setInterval": "readonly"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ extends: stylelint-config-standard-scss
|
||||||
ignoreFiles: "**/*.js"
|
ignoreFiles: "**/*.js"
|
||||||
rules:
|
rules:
|
||||||
selector-type-no-unknown: null
|
selector-type-no-unknown: null
|
||||||
|
selector-class-pattern: null
|
||||||
declaration-empty-line-before: null
|
declaration-empty-line-before: null
|
||||||
no-descending-specificity: null
|
no-descending-specificity: null
|
||||||
selector-pseudo-class-no-unknown: null
|
selector-pseudo-class-no-unknown: null
|
||||||
|
|
|
@ -30,6 +30,7 @@ export default {
|
||||||
'calendar': 500,
|
'calendar': 500,
|
||||||
'notification-center': 500,
|
'notification-center': 500,
|
||||||
'osd': 500,
|
'osd': 500,
|
||||||
|
'osk': 500,
|
||||||
'overview': 500,
|
'overview': 500,
|
||||||
'powermenu': 500,
|
'powermenu': 500,
|
||||||
'quick-settings': 500,
|
'quick-settings': 500,
|
||||||
|
@ -43,6 +44,7 @@ export default {
|
||||||
Calendar(),
|
Calendar(),
|
||||||
NotifCenter(),
|
NotifCenter(),
|
||||||
OSD(),
|
OSD(),
|
||||||
|
OSK(),
|
||||||
Overview(),
|
Overview(),
|
||||||
Powermenu(),
|
Powermenu(),
|
||||||
QSettings(),
|
QSettings(),
|
||||||
|
|
99
devices/wim/config/ags/js/on-screen-keyboard/gesture.js
Normal file
99
devices/wim/config/ags/js/on-screen-keyboard/gesture.js
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
import Hyprland from 'resource:///com/github/Aylur/ags/service/hyprland.js';
|
||||||
|
import Gtk from 'gi://Gtk';
|
||||||
|
|
||||||
|
|
||||||
|
export default window => {
|
||||||
|
const gesture = Gtk.GestureDrag.new(window);
|
||||||
|
|
||||||
|
gesture.signals = [];
|
||||||
|
window.killGestureSigs = () => {
|
||||||
|
gesture.signals.forEach(id => gesture.disconnect(id));
|
||||||
|
gesture.signals = [];
|
||||||
|
};
|
||||||
|
|
||||||
|
window.setSlideUp = () => {
|
||||||
|
console.log(window.get_allocated_height());
|
||||||
|
|
||||||
|
window.killGestureSigs();
|
||||||
|
|
||||||
|
// Begin drag
|
||||||
|
gesture.signals.push(
|
||||||
|
gesture.connect('drag-begin', () => {
|
||||||
|
Hyprland.sendMessage('j/cursorpos').then(out => {
|
||||||
|
gesture.startY = JSON.parse(out).y;
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Update drag
|
||||||
|
gesture.signals.push(
|
||||||
|
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;
|
||||||
|
|
||||||
|
window.child.setCss(`
|
||||||
|
margin-bottom: ${offset}px;
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
// End drag
|
||||||
|
gesture.signals.push(
|
||||||
|
gesture.connect('drag-end', () => {
|
||||||
|
window.child.setCss(`
|
||||||
|
transition: margin-bottom 0.5s ease-in-out;
|
||||||
|
margin-bottom: 0px;
|
||||||
|
`);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
window.setSlideDown = () => {
|
||||||
|
window.killGestureSigs();
|
||||||
|
|
||||||
|
// Begin drag
|
||||||
|
gesture.signals.push(
|
||||||
|
gesture.connect('drag-begin', () => {
|
||||||
|
Hyprland.sendMessage('j/cursorpos').then(out => {
|
||||||
|
gesture.startY = JSON.parse(out).y;
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Update drag
|
||||||
|
gesture.signals.push(
|
||||||
|
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;
|
||||||
|
|
||||||
|
window.child.setCss(`
|
||||||
|
margin-bottom: ${offset}px;
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
// End drag
|
||||||
|
gesture.signals.push(
|
||||||
|
gesture.connect('drag-end', () => {
|
||||||
|
window.child.setCss(`
|
||||||
|
transition: margin-bottom 0.5s ease-in-out;
|
||||||
|
margin-bottom: 0px;
|
||||||
|
`);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
window.setSlideDown();
|
||||||
|
|
||||||
|
return window;
|
||||||
|
};
|
104
devices/wim/config/ags/js/on-screen-keyboard/keyboard-layouts.js
Normal file
104
devices/wim/config/ags/js/on-screen-keyboard/keyboard-layouts.js
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
// TODO: right Ctrl https://handwiki.org/wiki/images/4/41/KB_Canadian_Multilingual_Standard.svg
|
||||||
|
|
||||||
|
export const defaultOskLayout = 'qwerty_custom';
|
||||||
|
export const oskLayouts = {
|
||||||
|
qwerty_custom: {
|
||||||
|
name: 'QWERTY - Custom',
|
||||||
|
name_short: 'CSA',
|
||||||
|
comment: 'Like physical keyboard',
|
||||||
|
// A normal key looks like this: {label: "a", labelShift: "A", shape: "normal", keycode: 30, type: "normal"}
|
||||||
|
// A modkey looks like this: {label: "Ctrl", shape: "control", keycode: 29, type: "modkey"}
|
||||||
|
// key types are: normal, tab, caps, shift, control, fn (normal w/ half height), space, expand
|
||||||
|
keys: [
|
||||||
|
[
|
||||||
|
{ keytype: 'normal', label: 'Esc', shape: 'fn', keycode: 1 },
|
||||||
|
{ keytype: 'normal', label: 'F1', shape: 'fn', keycode: 59 },
|
||||||
|
{ keytype: 'normal', label: 'F2', shape: 'fn', keycode: 60 },
|
||||||
|
{ keytype: 'normal', label: 'F3', shape: 'fn', keycode: 61 },
|
||||||
|
{ keytype: 'normal', label: 'F4', shape: 'fn', keycode: 62 },
|
||||||
|
{ keytype: 'normal', label: 'F5', shape: 'fn', keycode: 63 },
|
||||||
|
{ keytype: 'normal', label: 'F6', shape: 'fn', keycode: 64 },
|
||||||
|
{ keytype: 'normal', label: 'F7', shape: 'fn', keycode: 65 },
|
||||||
|
{ keytype: 'normal', label: 'F8', shape: 'fn', keycode: 66 },
|
||||||
|
{ keytype: 'normal', label: 'F9', shape: 'fn', keycode: 67 },
|
||||||
|
{ keytype: 'normal', label: 'F10', shape: 'fn', keycode: 68 },
|
||||||
|
{ keytype: 'normal', label: 'F11', shape: 'fn', keycode: 87 },
|
||||||
|
{ keytype: 'normal', label: 'F12', shape: 'fn', keycode: 88 },
|
||||||
|
{ keytype: 'normal', label: 'Home', shape: 'fn', keycode: 110 },
|
||||||
|
{ keytype: 'normal', label: 'End', shape: 'fn', keycode: 115 },
|
||||||
|
{ keytype: 'normal', label: 'Del', shape: 'fn', keycode: 111 },
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ keytype: 'normal', label: '/', labelShift: '\\', labelAltGr: '|', shape: 'normal', keycode: 41 },
|
||||||
|
{ keytype: 'normal', label: '1', labelShift: '!', shape: 'normal', keycode: 2 },
|
||||||
|
{ keytype: 'normal', label: '2', labelShift: '@', shape: 'normal', keycode: 3 },
|
||||||
|
{ keytype: 'normal', label: '3', labelShift: '#', labelAltGr: '¤', shape: 'normal', keycode: 4 },
|
||||||
|
{ keytype: 'normal', label: '4', labelShift: '$', shape: 'normal', keycode: 5 },
|
||||||
|
{ keytype: 'normal', label: '5', labelShift: '%', shape: 'normal', keycode: 6 },
|
||||||
|
{ keytype: 'normal', label: '6', labelShift: '?', shape: 'normal', keycode: 7 },
|
||||||
|
{ keytype: 'normal', label: '7', labelShift: '&', labelAltGr: '{', shape: 'normal', keycode: 8 },
|
||||||
|
{ keytype: 'normal', label: '8', labelShift: '*', labelAltGr: '}', shape: 'normal', keycode: 9 },
|
||||||
|
{ keytype: 'normal', label: '9', labelShift: '(', labelAltGr: '[', shape: 'normal', keycode: 10 },
|
||||||
|
{ keytype: 'normal', label: '0', labelShift: ')', labelAltGr: ']', shape: 'normal', keycode: 11 },
|
||||||
|
{ keytype: 'normal', label: '-', labelShift: '_', shape: 'normal', keycode: 12 },
|
||||||
|
{ keytype: 'normal', label: '=', labelShift: '+', labelAltGr: '¬', shape: 'normal', keycode: 13 },
|
||||||
|
{ keytype: 'normal', label: 'Backspace', shape: 'expand', keycode: 14 },
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ keytype: 'normal', label: 'Tab', shape: 'tab', keycode: 15 },
|
||||||
|
{ keytype: 'normal', label: 'q', labelShift: 'Q', shape: 'normal', keycode: 16 },
|
||||||
|
{ keytype: 'normal', label: 'w', labelShift: 'W', shape: 'normal', keycode: 17 },
|
||||||
|
{ keytype: 'normal', label: 'e', labelShift: 'E', labelAltGr: '€', shape: 'normal', keycode: 18 },
|
||||||
|
{ keytype: 'normal', label: 'r', labelShift: 'R', shape: 'normal', keycode: 19 },
|
||||||
|
{ keytype: 'normal', label: 't', labelShift: 'T', shape: 'normal', keycode: 20 },
|
||||||
|
{ keytype: 'normal', label: 'y', labelShift: 'Y', shape: 'normal', keycode: 21 },
|
||||||
|
{ keytype: 'normal', label: 'u', labelShift: 'U', shape: 'normal', keycode: 22 },
|
||||||
|
{ keytype: 'normal', label: 'i', labelShift: 'I', shape: 'normal', keycode: 23 },
|
||||||
|
{ keytype: 'normal', label: 'o', labelShift: 'O', shape: 'normal', keycode: 24 },
|
||||||
|
{ keytype: 'normal', label: 'p', labelShift: 'P', shape: 'normal', keycode: 25 },
|
||||||
|
{ keytype: 'normal', label: '^', labelShift: '"', labelAltGr: '`', shape: 'normal', keycode: 26 },
|
||||||
|
{ keytype: 'normal', label: 'ç', labelShift: 'Ç', labelAltGr: '~', shape: 'normal', keycode: 27 },
|
||||||
|
{ keytype: 'normal', label: 'à', labelShift: 'À', shape: 'expand', keycode: 43 },
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ keytype: 'normal', label: 'Caps', shape: 'caps', keycode: 58 },
|
||||||
|
{ keytype: 'normal', label: 'a', labelShift: 'A', shape: 'normal', keycode: 30 },
|
||||||
|
{ keytype: 'normal', label: 's', labelShift: 'S', shape: 'normal', keycode: 31 },
|
||||||
|
{ keytype: 'normal', label: 'd', labelShift: 'D', shape: 'normal', keycode: 32 },
|
||||||
|
{ keytype: 'normal', label: 'f', labelShift: 'F', shape: 'normal', keycode: 33 },
|
||||||
|
{ keytype: 'normal', label: 'g', labelShift: 'G', shape: 'normal', keycode: 34 },
|
||||||
|
{ keytype: 'normal', label: 'h', labelShift: 'H', shape: 'normal', keycode: 35 },
|
||||||
|
{ keytype: 'normal', label: 'j', labelShift: 'J', shape: 'normal', keycode: 36 },
|
||||||
|
{ keytype: 'normal', label: 'k', labelShift: 'K', shape: 'normal', keycode: 37 },
|
||||||
|
{ keytype: 'normal', label: 'l', labelShift: 'L', shape: 'normal', keycode: 38 },
|
||||||
|
{ keytype: 'normal', label: ';', labelShift: ':', labelAltGr: '°', shape: 'normal', keycode: 39 },
|
||||||
|
{ keytype: 'normal', label: 'è', labelShift: 'È', shape: 'normal', keycode: 40 },
|
||||||
|
{ keytype: 'normal', label: 'Enter', shape: 'expand', keycode: 28 },
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ keytype: 'modkey', label: 'Shift', shape: 'shift', keycode: 42 },
|
||||||
|
{ keytype: 'normal', label: 'z', labelShift: 'Z', labelAltGr: '«', shape: 'normal', keycode: 44 },
|
||||||
|
{ keytype: 'normal', label: 'x', labelShift: 'X', labelAltGr: '»', shape: 'normal', keycode: 45 },
|
||||||
|
{ keytype: 'normal', label: 'c', labelShift: 'C', shape: 'normal', keycode: 46 },
|
||||||
|
{ keytype: 'normal', label: 'v', labelShift: 'V', shape: 'normal', keycode: 47 },
|
||||||
|
{ keytype: 'normal', label: 'b', labelShift: 'B', shape: 'normal', keycode: 48 },
|
||||||
|
{ keytype: 'normal', label: 'n', labelShift: 'N', shape: 'normal', keycode: 49 },
|
||||||
|
{ keytype: 'normal', label: 'm', labelShift: 'M', shape: 'normal', keycode: 50 },
|
||||||
|
{ keytype: 'normal', label: ',', labelShift: "'", labelAltGr: '<', shape: 'normal', keycode: 51 },
|
||||||
|
{ keytype: 'normal', label: '.', labelShift: '"', labelAltGr: '>', shape: 'normal', keycode: 52 },
|
||||||
|
{ keytype: 'normal', label: 'é', labelShift: 'É', shape: 'normal', keycode: 53 },
|
||||||
|
{ keytype: 'modkey', label: 'Shift', shape: 'expand', keycode: 54 },
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ keytype: 'modkey', label: 'Ctrl', shape: 'control', keycode: 29 },
|
||||||
|
{ keytype: 'modkey', label: 'Super', shape: 'normal', keycode: 125 },
|
||||||
|
{ keytype: 'modkey', label: 'Alt', shape: 'normal', keycode: 56 },
|
||||||
|
{ keytype: 'normal', label: 'Space', shape: 'space', keycode: 57 },
|
||||||
|
{ keytype: 'normal', label: 'Space', shape: 'space', keycode: 57 },
|
||||||
|
{ keytype: 'modkey', label: 'AltGr', shape: 'normal', keycode: 100 },
|
||||||
|
{ keytype: 'normal', label: 'PrtSc', shape: 'fn', keycode: 99 },
|
||||||
|
{ keytype: 'modkey', label: 'Ctrl', shape: 'control', keycode: 97 },
|
||||||
|
],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
56
devices/wim/config/ags/js/on-screen-keyboard/keyboard.js
Normal file
56
devices/wim/config/ags/js/on-screen-keyboard/keyboard.js
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
import { Box, CenterBox } from 'resource:///com/github/Aylur/ags/widget.js';
|
||||||
|
import Separator from '../misc/separator.js';
|
||||||
|
|
||||||
|
import Key from './keys.js';
|
||||||
|
|
||||||
|
import { defaultOskLayout, oskLayouts } from './keyboard-layouts.js';
|
||||||
|
const keyboardLayout = defaultOskLayout;
|
||||||
|
const keyboardJson = oskLayouts[keyboardLayout];
|
||||||
|
|
||||||
|
const L_KEY_PER_ROW = [8, 7, 6, 6, 6, 4];
|
||||||
|
|
||||||
|
|
||||||
|
export default () => CenterBox({
|
||||||
|
class_name: 'osk',
|
||||||
|
hexpand: true,
|
||||||
|
start_widget: Box({
|
||||||
|
class_name: 'left-side side',
|
||||||
|
hpack: 'start',
|
||||||
|
vertical: true,
|
||||||
|
children: keyboardJson.keys.map((row, rowIndex) => Box({
|
||||||
|
vertical: true,
|
||||||
|
children: [
|
||||||
|
Box({
|
||||||
|
class_name: 'row',
|
||||||
|
children: row.map((key, keyIndex) => {
|
||||||
|
return keyIndex < L_KEY_PER_ROW[rowIndex] ? Key(key) : null;
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
Separator(4, { vertical: true }),
|
||||||
|
],
|
||||||
|
})),
|
||||||
|
}),
|
||||||
|
|
||||||
|
center_widget: Box({
|
||||||
|
hpack: 'center',
|
||||||
|
}),
|
||||||
|
|
||||||
|
end_widget: Box({
|
||||||
|
class_name: 'right-side side',
|
||||||
|
hpack: 'end',
|
||||||
|
vertical: true,
|
||||||
|
children: keyboardJson.keys.map((row, rowIndex) => Box({
|
||||||
|
vertical: true,
|
||||||
|
children: [
|
||||||
|
Box({
|
||||||
|
hpack: 'end',
|
||||||
|
class_name: 'row',
|
||||||
|
children: row.map((key, keyIndex) => {
|
||||||
|
return keyIndex >= L_KEY_PER_ROW[rowIndex] ? Key(key) : null;
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
Separator(4, { vertical: true }),
|
||||||
|
],
|
||||||
|
})),
|
||||||
|
}),
|
||||||
|
});
|
171
devices/wim/config/ags/js/on-screen-keyboard/keys.js
Normal file
171
devices/wim/config/ags/js/on-screen-keyboard/keys.js
Normal file
|
@ -0,0 +1,171 @@
|
||||||
|
import Variable from 'resource:///com/github/Aylur/ags/variable.js';
|
||||||
|
import Brightness from '../../services/brightness.js';
|
||||||
|
import { Box, EventBox, Label } from 'resource:///com/github/Aylur/ags/widget.js';
|
||||||
|
import { execAsync } from 'resource:///com/github/Aylur/ags/utils.js';
|
||||||
|
|
||||||
|
import Gtk from 'gi://Gtk';
|
||||||
|
|
||||||
|
import Separator from '../misc/separator.js';
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
const LCtrl = Variable(false);
|
||||||
|
const AltGr = Variable(false);
|
||||||
|
const RCtrl = Variable(false);
|
||||||
|
|
||||||
|
const Caps = Variable(false);
|
||||||
|
Brightness.connect('caps', (_, state) => Caps.value = state);
|
||||||
|
|
||||||
|
// Assume both shifts are the same for key.labelShift
|
||||||
|
const LShift = Variable(false);
|
||||||
|
const RShift = Variable(false);
|
||||||
|
|
||||||
|
const Shift = Variable(false);
|
||||||
|
LShift.connect('changed', () => Shift.value = LShift.value || RShift.value);
|
||||||
|
RShift.connect('changed', () => Shift.value = LShift.value || RShift.value);
|
||||||
|
|
||||||
|
|
||||||
|
export default key => {
|
||||||
|
if (key.keytype === 'normal')
|
||||||
|
return RegularKey(key);
|
||||||
|
else
|
||||||
|
return ModKey(key);
|
||||||
|
};
|
||||||
|
|
||||||
|
const ModKey = key => {
|
||||||
|
let Mod;
|
||||||
|
if (key.label === 'Super')
|
||||||
|
Mod = Super;
|
||||||
|
|
||||||
|
// Differentiate left and right mods
|
||||||
|
else if (key.label === 'Shift' && key.keycode === 42)
|
||||||
|
Mod = LShift;
|
||||||
|
|
||||||
|
else if (key.label === 'Alt' && key.keycode === 56)
|
||||||
|
Mod = LAlt;
|
||||||
|
|
||||||
|
else if (key.label === 'Ctrl' && key.keycode === 29)
|
||||||
|
Mod = LCtrl;
|
||||||
|
|
||||||
|
else if (key.label === 'Shift')
|
||||||
|
Mod = RShift;
|
||||||
|
|
||||||
|
else if (key.label === 'AltGr')
|
||||||
|
Mod = AltGr;
|
||||||
|
|
||||||
|
else if (key.label === 'Ctrl')
|
||||||
|
Mod = RCtrl;
|
||||||
|
|
||||||
|
const button = EventBox({
|
||||||
|
cursor: 'pointer',
|
||||||
|
class_name: 'key',
|
||||||
|
onPrimaryClickRelease: self => {
|
||||||
|
console.log('mod toggled');
|
||||||
|
|
||||||
|
execAsync(`ydotool key ${key.keycode}:${Mod.value ? 0 : 1}`);
|
||||||
|
self.child.toggleClassName('active', !Mod.value);
|
||||||
|
Mod.value = !Mod.value;
|
||||||
|
},
|
||||||
|
connections: [[NormalClick, self => {
|
||||||
|
Mod.value = false;
|
||||||
|
self.child.toggleClassName('active', false);
|
||||||
|
execAsync(`ydotool key ${key.keycode}:0`);
|
||||||
|
}]],
|
||||||
|
child: Label({
|
||||||
|
class_name: `mod ${key.label}`,
|
||||||
|
label: key.label,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
return Box({
|
||||||
|
children: [
|
||||||
|
button,
|
||||||
|
Separator(4),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const RegularKey = key => {
|
||||||
|
const widget = EventBox({
|
||||||
|
cursor: 'pointer',
|
||||||
|
class_name: 'key',
|
||||||
|
child: Label({
|
||||||
|
class_name: `normal ${key.label}`,
|
||||||
|
label: key.label,
|
||||||
|
connections: [
|
||||||
|
[Shift, self => {
|
||||||
|
if (!key.labelShift)
|
||||||
|
return;
|
||||||
|
|
||||||
|
self.label = Shift.value ? key.labelShift : key.label;
|
||||||
|
}],
|
||||||
|
|
||||||
|
[Caps, self => {
|
||||||
|
if (key.label === 'Caps') {
|
||||||
|
self.toggleClassName('active', Caps.value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!key.labelShift)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (key.label.match(/[A-Za-z]/))
|
||||||
|
self.label = Caps.value ? key.labelShift : key.label;
|
||||||
|
}],
|
||||||
|
|
||||||
|
[AltGr, self => {
|
||||||
|
if (!key.labelAltGr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
self.toggleClassName('altgr', AltGr.value);
|
||||||
|
self.label = AltGr.value ? key.labelAltGr : key.label;
|
||||||
|
}],
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const gesture = Gtk.GestureLongPress.new(widget);
|
||||||
|
gesture.delay_factor = 1.0;
|
||||||
|
|
||||||
|
// Long press
|
||||||
|
widget.connectTo(gesture, () => {
|
||||||
|
const pointer = gesture.get_point(null);
|
||||||
|
const x = pointer[1];
|
||||||
|
const y = pointer[2];
|
||||||
|
|
||||||
|
if ((!x || !y) || x === 0 && y === 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
console.log('Not implemented yet');
|
||||||
|
|
||||||
|
// TODO: popup menu for accents
|
||||||
|
}, 'pressed');
|
||||||
|
|
||||||
|
// onPrimaryClickRelease
|
||||||
|
widget.connectTo(gesture, () => {
|
||||||
|
const pointer = gesture.get_point(null);
|
||||||
|
const x = pointer[1];
|
||||||
|
const y = pointer[2];
|
||||||
|
|
||||||
|
if ((!x || !y) || x === 0 && y === 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
console.log('key clicked');
|
||||||
|
|
||||||
|
execAsync(`ydotool key ${key.keycode}:1`);
|
||||||
|
execAsync(`ydotool key ${key.keycode}:0`);
|
||||||
|
NormalClick.value = true;
|
||||||
|
}, 'cancelled');
|
||||||
|
|
||||||
|
return Box({
|
||||||
|
children: [
|
||||||
|
widget,
|
||||||
|
Separator(4),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
};
|
29
devices/wim/config/ags/js/on-screen-keyboard/main.js
Normal file
29
devices/wim/config/ags/js/on-screen-keyboard/main.js
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
import { execAsync } from 'resource:///com/github/Aylur/ags/utils.js';
|
||||||
|
|
||||||
|
import Gesture from './gesture.js';
|
||||||
|
import Keyboard from './keyboard.js';
|
||||||
|
import PopupWindow from '../misc/popup.js';
|
||||||
|
|
||||||
|
|
||||||
|
// ydotool stuff
|
||||||
|
execAsync('ydotoold').catch(print);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Window
|
||||||
|
export default () => Gesture(PopupWindow({
|
||||||
|
name: 'osk',
|
||||||
|
exclusivity: 'exclusive',
|
||||||
|
anchor: ['left', 'bottom', 'right'],
|
||||||
|
onClose: releaseAllKeys,
|
||||||
|
closeOnUnfocus: 'none',
|
||||||
|
connections: [[Tablet, self => {
|
||||||
|
self.visible = Tablet.oskState;
|
||||||
|
}, 'osk-toggled']],
|
||||||
|
child: Keyboard(),
|
||||||
|
}));
|
|
@ -21,3 +21,4 @@ undershoot {
|
||||||
@import "./widgets/overview";
|
@import "./widgets/overview";
|
||||||
@import "./widgets/applauncher";
|
@import "./widgets/applauncher";
|
||||||
@import "./widgets/osd";
|
@import "./widgets/osd";
|
||||||
|
@import "./widgets/osk";
|
||||||
|
|
73
devices/wim/config/ags/scss/widgets/osk.scss
Normal file
73
devices/wim/config/ags/scss/widgets/osk.scss
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
.osk {
|
||||||
|
margin-left: 4px;
|
||||||
|
|
||||||
|
.side {
|
||||||
|
.key {
|
||||||
|
&:active label {
|
||||||
|
background-color: $contrast-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
background-color: $bg;
|
||||||
|
border: 0.08rem solid $darkbg;
|
||||||
|
border-radius: 0.7rem;
|
||||||
|
min-height: 3rem;
|
||||||
|
|
||||||
|
transition: background-color 0.2s ease-in-out,
|
||||||
|
border-color 0.2s ease-in-out;
|
||||||
|
|
||||||
|
&.normal, &.Super {
|
||||||
|
min-width: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.Tab, &.Backspace {
|
||||||
|
min-width: 7rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.Enter, &.Caps {
|
||||||
|
min-width: 8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.Shift {
|
||||||
|
min-width: 9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.Space {
|
||||||
|
min-width: 20rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.PrtSc, &.AltGr {
|
||||||
|
min-width: 3.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background-color: $darkbg;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.altgr {
|
||||||
|
border: 0.08rem solid blue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.right-side {
|
||||||
|
.key .mod {
|
||||||
|
&.Ctrl {
|
||||||
|
min-width: 2.4rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.left-side {
|
||||||
|
.key .mod {
|
||||||
|
&.Alt {
|
||||||
|
min-width: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.Ctrl {
|
||||||
|
min-width: 4rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -53,6 +53,7 @@ in {
|
||||||
|
|
||||||
home.packages = with pkgs; [
|
home.packages = with pkgs; [
|
||||||
# ags
|
# ags
|
||||||
|
ydotool
|
||||||
sassc
|
sassc
|
||||||
coloryou
|
coloryou
|
||||||
libnotify
|
libnotify
|
||||||
|
|
Loading…
Reference in a new issue