feat: Add button for opening IME keyboard in custom keyboard overlay (#599)

Co-authored-by: PartyDonut <PartyDonut@users.noreply.github.com>
This commit is contained in:
PartyDonut 2025-11-09 10:55:01 +01:00 committed by GitHub
parent 188f947ad7
commit 33c3dab76c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 79 additions and 19 deletions

View file

@ -1366,5 +1366,6 @@
"format": "jm"
}
}
}
},
"openImeKeyboard": "Open IME keyboard"
}

View file

@ -13,7 +13,9 @@ class KeyboardLayouts {
['4', '5', '6', '(', ')', 'ABC'],
['7', '8', '9', '@', '!', '?'],
['0', '/', '\$', '%', '+', '[', ']'],
['.', '-', '_', '"', ':']
['.', '-', '_', '"', ':'],
['{', '}', '\\', '|', '~'],
['<', '>', '\$', '*', '=']
],
},
'es': {
@ -29,7 +31,9 @@ class KeyboardLayouts {
['4', '5', '6', '(', ')', 'ABC'],
['7', '8', '9', '@', '!', '?'],
['0', '/', '\$', '%', '+', '[', ']'],
['.', '-', '_', '"', ':']
['.', '-', '_', '"', ':'],
['{', '}', '\\', '|', '~'],
['<', '>', '\$', '*', '=']
],
},
'de': {
@ -46,7 +50,9 @@ class KeyboardLayouts {
['4', '5', '6', '(', ')', 'ABC'],
['7', '8', '9', '@', '!', '?'],
['0', '/', '\$', '%', '+', '[', ']'],
['.', '-', '_', '"', ':']
['.', '-', '_', '"', ':'],
['{', '}', '\\', '|', '~'],
['<', '>', '\$', '*', '=']
],
},
'fr': {
@ -64,7 +70,9 @@ class KeyboardLayouts {
['4', '5', '6', '(', ')', 'ABC'],
['7', '8', '9', '@', '!', '?'],
['0', '/', '\$', '%', '+', '[', ']'],
['.', '-', '_', '"', ':']
['.', '-', '_', '"', ':'],
['{', '}', '\\', '|', '~'],
['<', '>', '\$', '*', '=']
],
},
'ja': {
@ -81,7 +89,9 @@ class KeyboardLayouts {
['6', '7', '8', '9', '0', 'ABC'],
['!', '@', '#', '\$', '%'],
['^', '&', '*', '(', ')'],
['-', '_', '¥', '.', ',']
['-', '_', '¥', '.', ','],
['{', '}', '\\', '|', '~'],
['<', '>', '\$', '*', '=']
],
},
'zh': {
@ -97,7 +107,9 @@ class KeyboardLayouts {
['6', '7', '8', '9', '0', 'ABC'],
['!', '@', '#', '\$', '%'],
['^', '&', '*', '(', ')'],
['-', '_', '¥', '·', '']
['-', '_', '¥', '·', ''],
['{', '}', '\\', '|', '~'],
['<', '>', '\$', '*', '=']
],
},
};

View file

@ -162,6 +162,9 @@ class _CustomKeyboardViewState extends State<_CustomKeyboardView> {
ValueNotifier<List<String>> searchQueryResults = ValueNotifier([]);
final FocusNode internalTextField = FocusNode();
final FocusNode keyboardOpenFocusNode = FocusNode();
Future<void> startUpdate(String text) async {
final newValues = await widget.searchQuery?.call(widget.controller.text) ?? [];
searchQueryResults.value = newValues;
@ -175,6 +178,15 @@ class _CustomKeyboardViewState extends State<_CustomKeyboardView> {
});
}
@override
void dispose() {
scope.dispose();
internalTextField.dispose();
keyboardOpenFocusNode.dispose();
searchQueryResults.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
if (!scope.hasFocus) {
@ -189,19 +201,54 @@ class _CustomKeyboardViewState extends State<_CustomKeyboardView> {
crossAxisAlignment: CrossAxisAlignment.stretch,
spacing: 16,
children: [
Card(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Text(
widget.keyboardType == TextInputType.visiblePassword
? List.generate(
widget.controller.text.length,
(index) => "*",
).join()
: widget.controller.text,
style: Theme.of(context).textTheme.titleLarge,
Row(
children: [
Expanded(
child: ExcludeFocusTraversal(
child: Card(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: TextField(
focusNode: internalTextField,
controller: widget.controller,
showCursor: true,
keyboardType: widget.keyboardType,
textInputAction: widget.keyboardActionType,
obscureText: widget.keyboardType == TextInputType.visiblePassword,
onChanged: (value) {
setState(() {
widget.onChanged();
startUpdate(value);
});
},
onSubmitted: (value) {
internalTextField.unfocus();
keyboardOpenFocusNode.requestFocus();
setState(() {
widget.onChanged();
startUpdate(value);
});
},
decoration: const InputDecoration(
border: InputBorder.none,
isDense: true,
contentPadding: EdgeInsets.zero,
),
style: Theme.of(context).textTheme.titleLarge,
),
),
),
),
),
),
IconButton(
focusNode: keyboardOpenFocusNode,
onPressed: () => internalTextField.requestFocus(),
tooltip: context.localized.openImeKeyboard,
icon: const Icon(
IconsaxPlusBold.keyboard_open,
),
)
],
),
if (widget.searchQuery != null)
ValueListenableBuilder(