Script to switch to tablet mode in linux based on KIONIX Accelerometers in base and display which does not work due identity matrix used as fallback despite correct matrix being defined in 60-sensor.hwdb.
Moreover, for KIONIX accelerometers in base and display, SW_TABLET_MODE
is explicitly disabled as can be seen in Linux Kernel dual_accel_detect.h
Use tablet_mode.c as middle ground between performance and accuracy, table_mode_reduced.c for performance, tablet_mode_pitch_comp.c for accuracy.
Event-driven approach is not possible as it triggers are not supported by sensor driver. poll
and inotify
are not efficient due to volatility of raw sensor data. Hence, while-loop with nanosleep is used to avoid busy-wait
git clone https://github.com/MadhiasM/TeclastF6ProTabletMode.git
make
gcc -o tablet_mode tablet_mode.c -lsystemd
sudo cp tablet_mode /usr/local/bin/tablet_mode
sudo nano /etc/systemd/system/tablet-mode.service
Paste:
[Unit]
Description=Custom Tablet Mode Switch
After=multi-user.target
[Service]
ExecStart=/usr/local/bin/tablet_mode
Restart=always
User=root
[Install]
WantedBy=multi-user.target
sudo systemctl enable tablet-mode.service
sudo systemctl start tablet-mode.service
(only if needed when you won't to suspend the service or replace/update it)
sudo systemctl stop tablet-mode.service
- Automate steps below using bash script
- Clean up code, remove commented out stuff
- Update README.md
- Create makefile for compile, deploy, enable service etc
- Custom OSDWindow Toast when enabling/disabing
- Provide different approaches
- Using determinant between y- & z-axis reading the full vectors
- Using angle between y- & z-axis with atan2 reading the full vectors
- Using reduced input by just reading needed values (x can be neglected)
- Return screen orientation to normal when leaving tablet mode (will keep last orientation currently) (State machine: on transition from enable to disable: return to normal orientation. Don't trigger this if already disabled (from disabled to disabled)
- Fix mouse or keyboard sometimes not being reactivated. (sporadic)
- Increase efficiency (write/read/cpu cycles)?
- Provide different approaches for execution events
- Polling using while-loop with nanosleep
- Event-based using inotify for event-driven architecture instead of while loop with nanosleep
- Catch error if return -1
- log errors
- Increase robustness in diagonal or 90° sideways situations or fully folded. Here the accuracy is very low
- Adjust hysteresis threshold based on X-acceleration? (if X-acceleration is high, hystresis value will be small, thus appropriate threshold might be better)
- Time hysteresis (if enable conditions are met: test again
$4$ times) - Low Pass Filter (if needed) on accel values
- PID?
- Improve robustness if laptop is rotated 90° to the left or right (determinant will be close to 0 and thus can fluke to above 0). hysteresis is added as workaround, but will prevent tablet mode when rotatet 90° sideways. In this case, maybe take vectors into account in more detail?
- For example: if determinant close to 0, then check if y and z acceleration of base and display are similar?? (but that is the same for 0 and 360 degrees)? not sure...
- Hysteresis might solve this already?
- Prevent wrapping from -180 to 180 If Y and Z acceleration are close to 0, then it is indistinguishable from a physical viewpoint due to noisy signals
- Some sort of fallback / safe state to trigger disable tablet mode if something weird is detected? To be able to get control of keyboard again
- Break from while loop if error occurs to stop service (then close all devices)
- Improve behaviour when laptop wakes up from sleep. If state changes while in sleep, it is not registered
- Add both hysteresis and roll angle threshold as
IFDEF
makros to be able to quickly comment out this check
- Retrieve from device config in 60-sensor.hwdb or udev rules instead of hardcoding
- Use libudev with Overview or udev_device_get_sysattr_value
-
get_mount_matrix_udev.c
work in progress, but it does not show the same mount matrix asudevadm info -n /dev/iio:device0
(ACCEL_MOUNT_MATRIX
). Showingin_accel_mount_matrix
(identity), as insys/bus/iio/devices/iio\:device*/