The driver is written in python and does not necessarily run as a systemd service (How to start DialPad without systemd service?). It contains the common DialPad layouts, you can pick up the right one during the install process. Default settings aim to be the most convenient for the majority. All possible customizations can be found here.
If you find this project useful, please do not forget to give it a People already did!
- Support for own icons in
.svgformat - Double-clicking by left mouse button unlocks / locks the element position allowing it to be moved across the screen
- Driver during installation collects anonymous data with goal improve driver (e.g. automatic layout detection; data are publicly available here, you can provide used config using
$ bash install_config_send_anonymous_report.sh) - Driver (including backlighting if hardware supported) installed for the current user
- Driver creates own virtual environment of currently installed version of
Python3 - Multiple pre-created DialPad layouts with the possibility of creating custom layouts or improving existing ones (circle_diameter, center_button_diameter, circle_center_x..)
- Customization through 2-way sync configuration file (when
$ bash ./install.shis run, changes previously made in the config file will not be overwritten without user permission, similarly when$ bash ./uninstall.shis run the config file will be kept. In either case, when the config file or parts of it do not exist they will be automatically created or completed with default values) - Automatic DialPad layout detection
- Activation/deactivation of DialPad by pressing and holding the top-right icon (activation time by default is 1s)
- Optional co-activator key requirement (
Shift,Control,Alt) to prevent accidental DialPad activation - Recognize of currently focused app by binary path (e.g.
/usr/share/code/code) or part of the title (during finding the first matched shortcut wins sovisual studio codedefined aftercodewill be never be matched) - For each configured app a possibility to define single-function or multi-function mode (when is app not recognized is used
Noneblock) - Single-function mode (distinction of shortcuts for each app is possible only by key modifier like
Shift; for each shortcut is possible to useclockwise,counterclockwiseorcenter) - Adding events with
EV_KEYwhich contain press and release events (e.g. key volume up, down and mute:EV_KEY.KEY_VOLUMEUP, EV_KEY.KEY_VOLUMEDOWN, EV_KEY.KEY_MUTE)
...
app_shortcuts = {
...
"none": {
"center": [
{"key": EV_KEY.KEY_MUTE, "trigger": "release", "duration": 1, "modifier": EV_KEY.KEY_LEFTSHIFT}
],
"clockwise": [
{"key": [EV_REL.REL_WHEEL, EV_REL.REL_WHEEL_HI_RES], "value": [1, 120], "trigger": "immediate", "title": "Scroll"},
# works even better with `dconf write /org/gnome/desktop/sound/allow-volume-above-100-percent true`
{"key": EV_KEY.KEY_VOLUMEUP, "trigger": "immediate", "modifier": EV_KEY.KEY_LEFTSHIFT, "value": "pactl get-sink-volume @DEFAULT_SINK@ | grep -oP '\d+%' | head -n 1 | tr -d '%'", "unit": "%", "title": "Volume"}
],
"counterclockwise": [
{"key": [EV_REL.REL_WHEEL, EV_REL.REL_WHEEL_HI_RES], "value": [-1, -120], "trigger": "immediate", "title": "Scroll"},
# works even better with `dconf write /org/gnome/desktop/sound/allow-volume-above-100-percent true`
{"key": EV_KEY.KEY_VOLUMEDOWN, "trigger": "immediate", "modifier": EV_KEY.KEY_LEFTSHIFT, "value": "pactl get-sink-volume @DEFAULT_SINK@ | grep -oP '\d+%' | head -n 1 | tr -d '%'", "unit": "%", "title": "Volume"}
]
}
}
- Multi-function mode (not possible to use
centerbecause middle button is used as configuration button / return button between functions; by default is grid of circle rendered for 5 appsslices_minimum_count=5) - Using
EV_RELwith values (e.g. scrolling:EV_REL.REL_WHEEL, EV_REL.REL_WHEEL_HI_RESand values:-1, -120)
"Scroll": {
"icon": "/usr/share/icons/elementary/status/symbolic/rotation-allowed-symbolic.svg",
"clockwise": [
{"key": [EV_REL.REL_WHEEL, EV_REL.REL_WHEEL_HI_RES], "value": [1, 120], "trigger": "immediate"},
],
"counterclockwise": [
{"key": [EV_REL.REL_WHEEL, EV_REL.REL_WHEEL_HI_RES], "value": [-1, -120], "trigger": "immediate"},
]
},
- Using
commandfor toggling instead of sending any key - Have icon displayed according to current state determined by
valuecommand
"Notifications": {
"value": "dconf read /io/elementary/notifications/do-not-disturb",
"icons": {
"true": "/usr/share/icons/elementary/status/symbolic/notification-disabled-symbolic.svg",
"false": "/usr/share/icons/elementary/status/symbolic/notification-symbolic.svg"
},
# toggle do-not-disturb ("command" with toggle effect is preferred if exists over going into and clockwise/counterclockwise)
"command": 'dconf write /io/elementary/notifications/do-not-disturb "$( [ "$(dconf read /io/elementary/notifications/do-not-disturb)" = "true" ] && echo false || echo true )"',
},
- Possibility to trigger both types
EV_RELandEV_KEYonreleaseorimmediately - Using for a less continous function with increasing
treshold(e.g. editing changes undo and redo)
"Edit": {
"icon": "/usr/share/icons/elementary/status/symbolic/media-playlist-repeat-symbolic-rtl.svg",
"treshold": 180,
"clockwise": [
{"key": [EV_KEY.KEY_LEFTCTRL, EV_KEY.KEY_Y], "trigger": "immediate"}
],
"counterclockwise": [
{"key": [EV_KEY.KEY_LEFTCTRL, EV_KEY.KEY_Z], "trigger": "immediate"}
]
},
- Possibility to temporary force using not app specific shortcut without removing app specific shortcuts from layout (
config_supress_app_specifics_shortcuts) - Disabling the Touchpad (e.g. Fn+special key) disables by default the DialPad as well (can be disabled)
Get the latest stable or dev version using git:
$ git clone https://github.com/asus-linux-drivers/asus-dialpad-driver
$ cd asus-dialpad-driver
# now you are using master branch with the latest changes which may be not stable
# jump to the latest release of stable version:
$ git checkout v2.0.1or customized install:
# ENV VARS (with the defaults)
INSTALL_DIR_PATH="/usr/share/asus-dialpad-driver"
LOGS_DIR_PATH="/var/log/asus-dialpad-driver" # only for install and uninstall logs
INSTALL_UDEV_DIR_PATH="/usr/lib/udev"
# e.g. for BazziteOS (https://github.com/asus-linux-drivers/asus-numberpad-driver/issues/198)
$ INSTALL_DIR_PATH="/home/$USER/.local/share/asus-dialpad-driver"\
INSTALL_UDEV_DIR_PATH="/etc/udev"\
bash install.sh
or run separately parts of the install script.
Try found Touchpad with DialPad:
$ bash install_device_check.shAdd a user to the groups i2c,input,uinput:
$ bash install_user_groups.shRun driver now and every time that user logs in (do NOT run as $ sudo, works via systemctl --user):
$ bash install_service.shor for NixOS you can use flakes for the installation of this driver.
Important
In case the layout isn't provided, the "proartp16" DialPad layout is used.
The default value for runtimeDir is
/run/usr/1000/, for waylandDisplay iswayland-0and wayland istrue.
Enabling
ignoreWaylandDisplayEnvremoves the explicit declaration ofWAYLAND_DISPLAYin the service, allowing it to function correctly when switching between desktop environments or window managers that may have differentWAYLAND_DISPLAYenvironment variables.
The driver installation (NixOS)
This repo contains a Flake that exposes a NixOS Module that manages and offers options for asus-dialpad-driver. To use it, add the flake as an input to your flake.nix file and enable the module:
# flake.nix
{
inputs = {
# ---Snip---
asus-dialpad-driver = {
url = "github:asus-linux-drivers/asus-dialpad-driver";
inputs.nixpkgs.follows = "nixpkgs";
};
# ---Snip---
}
outputs = {nixpkgs, asus-dialpad-driver, ...} @ inputs: {
nixosConfigurations.HOSTNAME = nixpkgs.lib.nixosSystem {
specialArgs = { inherit inputs; };
modules = [
./configuration.nix
asus-dialpad-driver.nixosModules.default
];
};
}
}Then you can enable the program in your configuration.nix file:
# configuration.nix
{inputs, pkgs, ...}: {
# ---Snip---
# Enable Asus DialPad Service
services.asus-dialpad-driver = {
enable = true;
layout = "default";
wayland = true;
ignoreWaylandDisplayEnv = false;
runtimeDir = "/run/user/1000/";
waylandDisplay = "wayland-0";
};
# ---Snip---
}The key for the caclulator toggling script should be associated with XF86Calculator, allowing it to toggle any calculator application, not just the one specified in the configuration. This means that the key binding can be used to manage various calculator applications across different key binding configurations. For e.g.:
"XF86Calculator".action = sh -c "if pidof gnome-calculator > /dev/null; then kill $(pidof gnome-calculator); else gnome-calculator; fi";
To uninstall run
$ bash uninstall.sh
# ENV VARS (with the defaults)
INSTALL_DIR_PATH="/usr/share/asus-dialpad-driver"
CONFIG_FILE_DIR_PATH="$INSTALL_DIR_PATH"
CONFIG_FILE_NAME="dialpad_dev"
LOGS_DIR_PATH="/var/log/asus-dialpad-driver" # only for install and uninstall logs
SERVICE_INSTALL_DIR_PATH="$HOME/.config/systemd/user"
INSTALL_UDEV_DIR_PATH="/usr/lib/udev"
# e.g. for BazziteOS (https://github.com/asus-linux-drivers/asus-numberpad-driver/issues/198)
$ INSTALL_DIR_PATH="/home/$USER/.local/share/asus-dialpad-driver"\
INSTALL_UDEV_DIR_PATH="/etc/udev/"\
bash uninstall.shor run separately parts of the uninstall script
$ bash uninstall_service.sh
$ bash uninstall_user_groups.shLayouts below are named by laptop models, but the name is not important. What is important is their visual appearance because they are repeated on multiple laptop models across series. The install script should recognize the correct one automatically for your laptop. If yours was not recognized, please create issue.
| Name | Description | Image |
|---|---|---|
asusvivobook16x |
not nested | ![]() |
proartp16 |
nested | ![]() |
zenbookpro14 |
nested | ![]() |
How to start DialPad without systemd service?
- install in standard way using
bash install.shand answer no to the question about usingsystemd - layout name is required as first argument and as second argument can be optionally passed path to directory where will be autocreated config
dialpad_dev(default is current working directory):
/usr/share/asus-dialpad-driver/.env/bin/python3 /usr/share/asus-dialpad-driver/dialpad.py <asusvivobook16x|proartp16|..>
How to install the driver when is used pyenv for managing multiple Python versions?
$ git clone https://github.com/asus-linux-drivers/asus-dialpad-driver
$ cd asus-dialpad-driver
$ # pyenv install Ubuntu 22.04
$ apt install -y make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev xz-utils tk-dev libffi-dev liblzma-dev python3-openssl git
$ curl https://pyenv.run | bash
# install & change to the Python version for which one do you want to install the driver
$ CC=clang pyenv install 3.9.4
$ pyenv global 3.9.4 # change as global
$ # pyenv local 3.9.4 # will create file .python-version inside source dir so next (re)install will be used automatically saved Python version in this file
# install the driver
$ bash install.sh
# change to the standardly (previously) used Python version
$ pyenv global system
How can DialPad be activated via CLI?
- directly just change
enabledin the appropriate lines of the config file:
# enabling DialPad via command line
sed -i "s/enabled = 0/enabled = 1/g" dialpad_dev
sed -i "s/enabled = 0/enabled = 1/g" /usr/share/asus-dialpad-driver/dialpad_dev
# disabling
sed -i "s/enabled = 1/enabled = 0/g" dialpad_dev
sed -i "s/enabled = 1/enabled = 0/g" /usr/share/asus-dialpad-driver/dialpad_dev
During the install process bash ./install.sh, you're required to select your keyboard layout:
...
1) asusvivobook16x.py
2) proartp16.py
3) zenbookpro14.py
4) Quit
Please enter your choice
...
| Option | Required | Default | Description |
|---|---|---|---|
| Position of DialPad | |||
circle_diameter |
Required | in px | |
center_button_diameter |
Required | in px | |
circle_center_x |
Required | in px | |
circle_center_y |
Required | in px | |
| Associated apps | |||
app_shortcuts |
Optional | Yes |
To prevent accidental DialPad activation while using the touchpad, you can configure a co-activator key. This requires holding a modifier key like Alt while touching the top right icon to activate the DialPad.
During installation, you will be prompted to select a co-activator key:
Select co-activator key:
1) None
2) Shift
3) Control
4) Alt
6) Quit
The co-activator is configured by modifying the top_right_icon_coactivator_key in your config file. When a co-activator is set, the top_right_icon_coactivator_key value becomes:
...
top_right_icon_coactivator_key = Alt
Attributes which do not depend on a specific DialPad keyboard can be changed according to the table below in the config dialpad_dev in the installed driver location /usr/share/asus-dialpad-driver. See the example below showing the default attibutes:
[main]
disable_due_inactivity_time = 0
touchpad_disables_dialpad = 1
activation_time = 1
enabled = 0
socket_enabled = 1
top_right_icon_coactivator_key = Alt
default_treshold = 90
slices_minimum_count = 5
| Option | Required | Default | Description |
|---|---|---|---|
| System | |||
enabled |
0 |
DialPad running status (enabled/disabled) | |
disable_due_inactivity_time |
0 [s] |
DialPad is automatically disabled when no event received for this interval decimal numbers allowed (e.g. 60.0 [s] is one minute, 0 set up by default disables this functionality) |
|
touchpad_disables_dialpad |
1 |
when Touchpad is disabled DialPad is disabled aswell | |
| User Interface | |||
socket_enabled |
0 |
DialPad is sending to the socket what is the user doing (enabled/disabled) | |
socket_send_progress_above_treshold |
120 |
Is send progress when command value is not defined and angle is above this |
|
| Layout | |||
slices_minimum_count |
5 |
minimum count of slices in the circle for multi-functional mode | |
default_treshold |
90 [angle] |
this angle is considered as one step when moving with finger around | |
suppress_app_specifics_shortcuts |
0 |
app specific shortcuts are ignored when is specific window with app opened | |
| Top right icon | |||
activation_time |
1.0 [seconds] |
amount of time you have to hold top_right_icon |
|
top_right_icon_coactivator_key |
`` | empty default means no co-activator keys are required (valid values are Shift, Control or Alt delimeted by space)this works only for activation by touching the top right icon |
At first check systemd service logs:
$ journalctl --user -u asus_dialpad_driver@$USER.service
For further debugging stop installed systemd services:
systemctl --user stop asus_dialpad_driver@ldrahnik.service
systemctl --user disable asus_dialpad_driver@ldrahnik.service
systemctl --user stop asus_dialpad_driver_ui@ldrahnik.service
systemctl --user disable asus_dialpad_driver_ui@ldrahnik.service
systemctl --user stop asus_numberpad_driver@ldrahnik.service
systemctl --user disable asus_numberpad_driver@ldrahnik.service
And listen on socket using socat (e.g. $ sudo apt install socat):
Is necessary to have enabled in config socket_enabled.
$ socat - UNIX-RECV:/tmp/dialpad.sock
{"ts": 1767791846.2734825, "enabled": true}
{"ts": 1767791846.3734825, "input": "center", "value": 1}
{"ts": 1767791846.3737416, "input": "center", "value": 0}
{"ts": 1767791846.461517, "input": "counterclockwise", "value": "62", "title": "Volume"}
{"ts": 1767791846.6073422, "input": "counterclockwise", "value": "58", "title": "Volume"}
{"ts": 1767791846.698195, "input": "counterclockwise", "value": "56", "title": "Volume"}
{"ts": 1767791846.814567, "input": "center", "value": 1}
{"ts": 1767791846.8146207, "input": "center", "value": 0}
{"ts": 1767791846.8976963, "input": "counterclockwise", "value": "54", "title": "Volume"}
{"ts": 1767791846.9604836, "input": "counterclockwise", "value": "52", "title": "Volume"}
{"ts": 1767791847.161212, "input": "counterclockwise", "value": "50", "title": "Volume"}
{"ts": 1767791847.3800304, "input": "clockwise", "value": "52", "title": "Volume"}
{"ts": 1767791847.5570402, "input": "clockwise", "value": "54", "title": "Volume"}
{"ts": 1767791847.6351395, "input": "center", "value": 1}
{"ts": 1767791847.6357095, "input": "center", "value": 0}
{"ts": 1767791847.7126362, "input": "clockwise", "value": "56", "title": "Volume"}
{"ts": 1767791847.789433, "input": "clockwise", "value": "58", "title": "Volume"}
{"ts": 1767791846.2734825, "enabled": false}
or use log level DEBUG:
$ source /usr/share/asus-dialpad-driver/.env/bin/activate
(.env) $ LOG=DEBUG python3 dialpad_ui.py
Listening on /tmp/dialpad.sock
2026-01-15 12:34:23,980 DEBUG {'ts': 1768476870.9540725, 'enabled': True}
2026-01-15 12:34:26,281 DEBUG {'ts': 1768476866.2752297, 'titles': ['Volume', 'Scroll', 'Brightness'], 'icons': ['/usr/share/icons/elementary/status/symbolic/audio-volume-medium-symbolic.svg', '/usr/share/icons/elementary/status/symbolic/rotation-allowed-symbolic.svg', '/usr/share/icons/elementary/status/symbolic/display-brightness-symbolic.svg'], 'title': None}
2026-01-15 12:34:27,481 DEBUG {'ts': 1768476867.4463465, 'enabled': False}
- I do not know any
- [c] Set of tools for handling ASUS Dial and simmilar designware hardware under Linux (https://github.com/fredaime/openwheel)
Why was this project created? Because linux does not support integration of DialPad into a Touchpad
Stargazer evolution for the project
Buy me a coffee
Do you think my effort put into open source is useful for you / others? Please put a star in the GitHub repository. Every star makes me proud. Any contribution is also welcome. Would you like to reward me more? There now exists a way : you can invite me for a coffee! I would really appreciate that!
For this ko-fi.com/ldrahnik is preferred instead of buymeacoffee.com/ldrahnik because of zero commissions.





