Ken Van Hoeylandt b9a96ca26d
UX improvements (#686)
- Introduce "side" mode for system bar, versus classic statusbar on top with launcher bar below
- Automatic system bar mode detection with override by Kconfig/device.properties and secondary override by user via Appereance settings app
- Open a quick-settings menu from the status bar for available Wi-Fi, Bluetooth, GPS, and power controls.
- Apps can display overlays with backdrop or Escape-key dismissal.
- Added focus-container support and improved keyboard navigation, including Fn+Enter on Cardputer devices.
- Power-off controls are available on supported device cards.
- Updated status-bar layouts, simulator display dimensions, and toolbar navigation styling.
- I²C scanning now supports selecting individual buses to rescan.
- SD-card mount status is no longer shown in the status bar.
2026-10-11 00:32:27 +02:00
..
2026-10-11 00:32:27 +02:00
2026-10-11 00:32:27 +02:00
2026-10-07 23:00:09 +02:00
2026-10-11 00:32:27 +02:00
2026-10-07 23:00:09 +02:00
2026-10-11 00:32:27 +02:00
2026-10-07 23:00:09 +02:00
2026-10-11 00:32:27 +02:00
2026-10-05 00:00:08 +02:00

lvgl-module

This module manages the lifecycle of the LVGL library within the Tactility ecosystem.

What the library does

The lvgl-module provides:

  • Lifecycle Management: Handles initialization and termination of the LVGL library.
  • Task Management: Manages the LVGL main loop task.
  • Thread-Safety: Provides mutex-based locking mechanisms (lvgl_lock, lvgl_unlock) to ensure safe access to LVGL APIs from multiple tasks.
  • Font Access: Provides a unified interface to access pre-configured text and icon fonts.

Different types of fonts

The module supports two main categories of fonts:

Text Fonts

Text uses the Adwaita Sans font in three sizes:

  • FONT_SIZE_SMALL
  • FONT_SIZE_DEFAULT
  • FONT_SIZE_LARGE

Until Tactility registers these fonts with lvgl_set_text_font(), the getters return LVGL's built-in default font (Montserrat).

Icon Fonts

Icons are provided by the Material Symbols font, divided into three usage-specific sets:

  • Statusbar Icons: Optimized for the system status bar.
  • Launcher Icons: Sized for application launchers.
  • Shared Icons: General purpose icons used across the system.

How to update the fonts

All font sizes derive from one default text size: font.defaultSize in device.properties (CONFIG_TT_FONT_DEFAULT_SIZE, 14 on the simulator). Tactility calculates the other text and icon sizes from it in Tactility/Source/lvgl/FontSizes.cpp.

Text fonts are rasterized on device at startup from Data/system/fonts/AdwaitaSans.ttf and cached as .bin files in the data path. Tactility/Fonts/generate.py creates that TTF subset from Tactility/Fonts/AdwaitaSans-Regular.ttf (requires pip install fonttools).

Icon fonts are rasterized on device at startup from Data/system/fonts/MaterialSymbolsRounded.ttf (a subset with only the used icons) and cached as .bin files in the data path, so any icon size works. The icons per font are listed by name and resolved through Data/system/fonts/MaterialSymbolsRounded.codepoints. To add an icon, add its name to generate-icons.py and run it (requires pip install fonttools). This regenerates the TTF subset, the codepoints file and the name lists.

Custom memory allocator

LVGL's malloc/realloc/free can be routed through a custom backend instead of its built-in pool or plain malloc. Three things are required:

1. Select the backend. On ESP32, via Kconfig (sdkconfig):

CONFIG_LV_USE_CUSTOM_MALLOC=y

On Simulator/POSIX, ESP-IDF's Kconfig doesn't apply - select it in lv_conf.h instead:

#define LV_USE_STDLIB_MALLOC LV_STDLIB_CUSTOM

2. Force the module into the link. LVGL's own init code calls back into the functions above a reverse reference a normal single-pass static-archive link can't resolve on its own:

tactility_add_module(lvgl-module
    ...
    WHOLE_ARCHIVE
)

Without WHOLE_ARCHIVE, or without step 1 selecting the custom backend, ESP-IDF's LVGL component compiles its own allocator using these same symbol names - whichever one the linker happens to pull in first silently wins, with no error and no guarantee it's the intended one.

License

This module is licensed under the Apache v2.0 license.