This Emacs Lisp library displays a virtual keyboard (also known as an on-screen keyboard or software keyboard) within Emacs.
The following image is a screenshot of Emacs for Android (Native App).
The keyboard displayed above is the virtual keyboard created by this library.
Tapping the keyboard icon in the toolbar toggles the display of this virtual keyboard.
By the way, at the bottom is the flick input panel from ATOK, a Japanese IME app. While it’s possible to switch to a full keyboard like Hacker’s Keyboard, flick input is better for Japanese typing and switching between keyboards is cumbersome. So I created this library to display both simultaneously.
Display only special keys and use alongside the existing on-screen keyboard:
Disable the native on-screen keyboard and use only vkbd:
Display in a child frame (not very user-friendly):
Keyboard menu:
The buttons in the title bar are, from left to right: close, menu, switch to 10x7 layout, switch to special-keys-only layout, and toggle native on-screen keyboard disable (Android only). Of course, these are customizable:
Of course, it can also be used in desktop environments:
- Emacs 30.1 or later
- Graphics display environment
Place the .el files of this library in a location on your load-path.
To display the virtual keyboard, load vkbd.el and type:
M-x vkbd-open-global-keyboard
To add a button to toggle the keyboard to the toolbar, add the following code to your init.el:
(autoload 'vkbd-tool-bar-mode "vkbd-tool-bar" nil t)
(vkbd-tool-bar-mode)Or simply type:
M-x vkbd-tool-bar-mode
The following keyboard layouts are provided as presets. You can also create new layouts.
Limited to 10 columns wide, it can be comfortably operated even on vertically-oriented displays like smartphones. All ASCII symbols can be entered without shift.
Based on vkbd-layout-10x9, reduced to 7 rows. Most symbols require shift to enter, but some can be entered without shift. Also, Ins and Del keys are omitted.
Based on vkbd-layout-10x7 with one additional column. Allows entering more symbols without shift while maintaining compactness.
US keyboard-like layout. The width is wide, so it may not fit within the parent frame without size adjustment.
Japanese keyboard-like layout. The width is wide, so it may not fit within the parent frame without size adjustment.
Layout containing only special keys, intended for use with existing keyboards.
Note: The modifier lock feature does not work correctly when used with existing keyboards.
Type M-x customize-group vkbd
Global keyboard settings:
vkbd-global-keyboard-options: Settings applied only to the global keyboard object (You can see the available properties withM-x customize-variable vkbd-global-keyboard-options)vkbd-global-keyboard-user-data-storage: Storage location for user data (such as frame position) applied only to the global keyboard
Layout settings::
vkbd-layout-list: All layout listvkbd-default-keyboard-layout: Default layoutvkbd-user-key-type-alist: Alist of user-defined key typesvkbd-user-key-text-alist: Alist of display strings for key types
Text style settings:
- Variables:
vkbd-text-key-width: Key width (in characters)vkbd-text-key-line-height: Key line’s line-height text propertyvkbd-text-key-raise: Vertical position of charactersvkbd-text-key-centering-method: Text centering methodvkbd-text-column-separator-width: Width of spacing between columns (horizontal spacing between keys)vkbd-text-row-separator-height: Height of spacing between rows (vertical spacing between keys)vkbd-keyboard-buffer-line-spacing:line-spacingvalue in keyboard buffersvkbd-text-title-button-separator-width: Width of spacing between buttons on the title bar (horizontal spacing between buttons)
- Faces
vkbd-text-keyboard: Entire keyboardvkbd-text-key-common: Key areavkbd-text-key: Normal keyvkbd-text-key-pressed: Pressed keyvkbd-text-key-locked: Locked keyvkbd-text-key-invisible: Invisible key (used to adjust key positions)vkbd-text-column-separator: Spacing between columns (horizontal)vkbd-text-row-separator: Spacing between rows (vertical)vkbd-text-title-bar: Entire title barvkbd-text-title-button: Title bar buttonsvkbd-text-title-button-separator: Spacing between buttons (horizontal)vkbd-text-title-caption: Title bar text
Title bar:
vkbd-title-bar-formatvkbd-title-button-close-captionvkbd-title-button-close-formatvkbd-title-button-menu-captionvkbd-title-button-menu-formatvkbd-title-button-extras
Key repeat:
vkbd-key-repeat-enabledvkbd-key-repeat-delayvkbd-key-repeat-interval
Frame settings:
vkbd-keyboard-frame-parameters: Frame parameters (note that changes may not be immediately reflected due to frame reuse)vkbd-recycle-frames: Whether to pool and reuse frames (you can delete all pooled frames with M-x vkbd-delete-all-unused-frames)vkbd-keyboard-frame-keep-visible-margins: Margins to keep visible when dragging the virtual keyboard frame
Buffer settings:
vkbd-keyboard-buffer-local-variables: Buffer local constant variables
Style settings:
vkbd-default-keyboard-style(currently only text01 style is available)
Input mechanisms:
vkbd-replace-read-functions
The easiest way to adjust the overall keyboard height is to change the
:height of the vkbd-text-keyboard face.You can also change the font
parameter in vkbd-keyboard-frame-parameters.
To change only the key height without changing the text size on the keys, adjust
the :height of vkbd-text-column-separator or vkbd-text-key-line-height variable.
(setq vkbd-user-key-text-alist
'((up . "^") (lft . "<-") (rit . "->") (dwn . "v")
(ctl . "Ctl") (shf . "Shift") (met . "Meta")
(C- . "Ctl") (S- . "Shift") (M- . "Meta")))Starting with Emacs 30, a mechanism to control on-screen keyboards has been added to Emacs.
On-Screen Keyboards (GNU Emacs Lisp Reference Manual)
vkbd.el allows you to either use vkbd alongside the native on-screen keyboard or use vkbd exclusively.
The vkbd-toggle-native-osk command can be used to disable the native on-screen keyboard. When running on Android, this command is added as a button on vkbd’s title bar.
If you want to replace the native on-screen keyboard with vkbd, you can use the global minor mode vkbd-replace-osk-mode. Emacs has a feature that automatically displays the on-screen keyboard when an editable area is touched, and with this mode enabled, vkbd-open-global-keyboard is executed instead of showing the native on-screen keyboard.
You can create multiple keyboards with arbitrary settings from Emacs Lisp using code like this:
(setq my-keyboard
(vkbd-make-keyboard
'(:title
"My ABCDE Keyboard"
:layout ((?a ?b ?c ?d ?e)
(?A ?B ?C ?D ?E))
:title-extra-buttons nil)))
(vkbd-keyboard-live-p my-keyboard) ;; => t
(vkbd-delete-keyboard my-keyboard)There are several known situations where this library’s virtual keyboard does not work properly.
When using frame display mode for the virtual keyboard, input acceptance may be interrupted or input may not work correctly due to frame switching events. Such issues have been observed with transient.el (Magit, etc.) and set-transient-map (text-scale-adjust, etc.). Window display mode is less prone to malfunctions caused by focus switching.
When using window display mode, the virtual keyboard may be hidden by other side windows, making input impossible. For example, which-key-mode and transient.el (Magit, etc.) display side windows at the bottom of the frame by default. If this library’s virtual keyboard is also displayed in a side window at the bottom, they will try to occupy the same location, causing the keyboard to be partially or completely hidden and potentially preventing input. When using window display mode, it may be better to set the side window position to the top.
There are likely other problematic cases as well. In some situations, key input may not be accepted and you may become unable to escape from that situation.
On Android, quickly pressing the volume down button twice will trigger a quit. Please remember this.
This software is licensed under GPLv3. You are free to use, modify and distribute this software.
This is a small token of appreciation for Emacs, the wonderful software that I’ve been able to use freely. Regarding Emacs-related work, I have no intention of asserting copyright in a restrictive way. Feel free to use it however you like-or don’t use it at all but reference the code, borrow ideas, or just let it inspire you in some way. I simply hope it contributes to making Emacs more useful for everyone.
If you wish to register this software in any package archive, please fork this repository, make the necessary modifications to fit the package archive’s requirements, and submit the registration on your own. Also continue with the necessary maintenance. You don’t need my permission.
I also welcome you to publish your improved version. If that works better than mine, I might start using it too. I may suddenly be unable to develop, and I cannot guarantee any continued development. This software is the result of what I want, so please add what you want yourself.
I am not proficient in English, so please do not expect continuous communication in English. I have spent a long time using translation software to write this text, but I am not confident that the intended meaning is accurately conveyed. I don’t think it has ended up with the opposite meaning, but subtle nuances may be missing.












