Linux GUI for controlling the color eInk display on the Lenovo ThinkBook Plus Gen 4 IRU.
This is a universal fork of Tinta4Plus by Jon Cox, with broader desktop environment support and a system installer.
| Desktop | Session | Status |
|---|---|---|
| GNOME | X11 | Tested |
| GNOME | Wayland | Supported (Mutter D-Bus) |
| Cinnamon | X11 | Tested (CachyOS) |
| XFCE | X11 | Tested |
| KDE Plasma | X11 | Supported |
| KDE Plasma | Wayland | Supported (kscreen) |
Only GNOME on X11 and XFCE on X11 have been properly tested. Other configurations are supported but may have issues.
Base OS:
- Ubuntu 24.04 LTS or later (including Xubuntu, Kubuntu, Linux Mint)
- Arch Linux / CachyOS (tested) — other Arch-based distros may work but are untested
- OLED: 2880x1800 on eDP-1
- eInk: 2560x1600 color on eDP-2
- eInk T-CON controller: USB (VID
048d, PID8957) - Embedded Controller: I/O ports
0x66/0x62(frontlight, brightness)
git clone https://github.com/Tinta4Plus-Universal/Tinta4Plus-Universal.git
cd Tinta4Plus-UniversalFrontlight control requires EC access, which needs Secure Boot disabled:
- Reboot and press Enter repeatedly right after power-on to get the boot menu.
- Press the appropriate F-key to enter BIOS settings.
- Navigate to Security > Secure Boot > set to Disabled.
- Save and reboot.
sudo bash installer.shThe installer will prompt you to choose between two modes:
Choose option 2 (Python scripts) when prompted. This installs the Python source files directly — easier to debug, modify, and update. The installer handles all dependencies automatically.
Choose option 1 (compiled binary) when prompted. Requires building first:
pip install pyinstaller
bash build.sh
sudo bash installer.sh- Asks you to choose between compiled binary or Python script mode.
- Detects your desktop environment (GNOME, Cinnamon, XFCE, KDE) using three fallback methods: environment variables, loginctl session query, and process detection.
- Installs apt dependencies:
- Common:
libusb-1.0-0,python3-tk - Script mode adds:
python3,python3-usb - GNOME/Cinnamon adds:
gnome-themes-extra,policykit-1-gnome(required for pkexec password dialog) - KDE adds:
kscreen,plasma-workspace - XFCE adds:
xfce4-settings
- Common:
- In script mode, installs pip packages:
portio,pyusb,sv-ttk. - Copies binaries/scripts to
/opt/tinta4plusu/and creates symlinks in/usr/local/bin/. - Installs
tinta4plusu.desktopto/usr/share/applications/andtinta4plusu-autostart.desktopto/etc/xdg/autostart/. - Optionally installs a PolicyKit policy (
org.tinta4plusu.helper.policy) to cache authentication so you don't re-enter your password every time the helper starts.
Errors during installation are trapped and logged to /tmp/tinta4plusu-install.log.
After installation, launch from the terminal or application menu:
tinta4plusuThe app also autostarts on login (via /etc/xdg/autostart/). In autostart mode, the helper daemon is not launched automatically to avoid a password prompt at login — click Connect to Helper when you need eInk control.
Click the eInk Enabled/Disabled toggle button to switch between OLED and eInk. The switching sequence:
- To eInk: enables eDP-2, powers on the T-CON, enables frontlight, sets reading mode, then disables eDP-1. On Wayland, the eInk is placed at the same position as the OLED (mirror-like) to avoid a visible extended-desktop state during the transition.
- To OLED: switches to dynamic mode, shows a privacy image on eInk (to clear sensitive content), powers off the T-CON, re-enables eDP-1, unlocks the session, then disables eDP-2.
- Reading mode: optimized for text, slower refresh, less ghosting.
- Dynamic mode: faster refresh for scrolling/interaction, more ghosting.
eInk panels accumulate ghosting (afterimages) from partial updates. You can clear it with:
- Refresh button: click "Refresh eInk (Clear Ghosts)" in the GUI.
- Periodic auto-refresh: adjust the "Refresh period" slider (0 = off, up to 60 seconds). Defaults to off.
Use the brightness slider (0-8) to control the eInk frontlight. The frontlight turns on automatically when switching to eInk and off when switching back to OLED.
These shortcuts work system-wide (via evdev in the helper daemon) when eInk is enabled:
| Shortcut | Action |
|---|---|
| Help (Fn+F9) | Refresh eInk (clear ghosts) |
| Brightness Up (Fn+F6) | Increase frontlight brightness |
| Brightness Down (Fn+F5) | Decrease frontlight brightness |
The "Display Scale" slider controls the UI scale on the eInk display (default: 1.75x). On X11 this sets the xrandr scale and panning dimensions. On Wayland (Mutter), it uses the closest supported fractional scale.
When "Auto-switch theme" is checked (default), the app switches to a high-contrast theme on eInk and back to Adwaita-dark on OLED. The GUI itself uses a dark theme (sv-ttk).
Settings (display scale, refresh period, theme auto-switch) are saved to ~/.config/Tinta4PlusU/settings.json and restored on next launch.
A standalone diagnostic tool (touch_diagnostic.py) is included to test touchscreen mapping accuracy on the eInk display. Run it while in eInk mode:
python3 touch_diagnostic.pyIt shows targets on screen and reports the offset between expected and actual touch positions.
sudo bash installer.sh --uninstallThis removes binaries/scripts from /opt/tinta4plusu, symlinks from /usr/local/bin, desktop entries, and the PolicyKit policy.
Two-process model communicating via Unix socket (/tmp/tinta4plusu.sock):
- Tinta4Plus.py — unprivileged tkinter GUI, launched as the user.
- HelperDaemon.py — privileged daemon (root via
pkexec), controls EC and USB hardware.
| Module | Role | Runs as |
|---|---|---|
Tinta4Plus.py |
Main GUI | User |
HelperDaemon.py |
Privileged daemon | Root |
DisplayManager.py |
Display switching (xrandr / Mutter D-Bus / kscreen) | User |
ThemeManager.py |
GTK/desktop theme switching (GNOME, Cinnamon, XFCE, KDE) | User |
HelperClient.py |
Socket IPC client | User |
ECController.py |
Embedded Controller I/O | Root |
EInkUSBController.py |
USB T-CON controller | Root |
WatchdogTimer.py |
Daemon watchdog (20s timeout) | Root |
touch_diagnostic.py |
Touchscreen mapping diagnostic | User |
During installation you can optionally install a PolicyKit policy (org.tinta4plusu.helper.policy) that caches authentication so you don't need to re-enter your password every time the helper starts. The first launch still requires authentication.
On GNOME and Cinnamon, the policykit-1-gnome package is required for pkexec to show a password dialog. The installer installs this automatically.
When an external monitor is connected or disconnected while eInk is active, the app automatically re-enforces eInk-only mode within a few seconds. This prevents the desktop from extending or cloning onto the eInk panel during display reconfiguration.
The hotplug monitor runs as a background thread, detects xrandr configuration changes, and disables eDP-1 (OLED) if it was re-enabled by the desktop environment.
The polkit authentication agent is not running. On GNOME/Cinnamon, install policykit-1-gnome:
sudo apt install policykit-1-gnomeThen log out and back in, or start it manually:
/usr/lib/policykit-1-gnome/polkit-gnome-authentication-agent-1 &The app forces DPMS on and unlocks the session after re-enabling eDP-1, but if the OLED stays black, close and reopen the laptop lid to wake it.
Sometimes the EC register readback differs from the written value. The frontlight is usually enabled despite the error — check visually.
If the laptop becomes unresponsive or the eInk/EC behaves erratically:
- Power off and disconnect the AC adapter.
- Press and hold the EC reset pinhole (bottom of laptop, near the fan vent) for 60 seconds.
- Press and hold the power button for 60 seconds.
- Press the power button normally to boot (may take up to 60 seconds to show anything on screen).
- Re-check BIOS to ensure Secure Boot is still disabled.
This software is experimental. No warranty is offered, express or implied.
This software was independently developed without any input, support, or documentation from eInk or Lenovo. It writes to low-level hardware (Embedded Controller, USB T-CON) and can potentially cause temporary or permanent hardware damage. It has been tested on a limited number of systems.
Do not modify ECController.py or EInkUSBController.py unless you understand the hardware implications.
Use entirely at your own risk. The authors accept no liability for any damage to your hardware or data. See the full EULA for details.
Original project by Jon Cox — Buy him a coffee
