Adds a new touch control mode that swaps the left/right tap zones, allowing users to navigate forward by tapping the left side and backward by tapping the right side. The inverted behavior is applied when the TOUCH_READER_INVERTED_TAP setting is selected.
Introduces a new setting 'tapForReaderMenu' that allows users to disable the center-third tap gesture for opening the reader menu. This option is only shown on devices with a capacitive Home key, since those devices can still access the menu via long-press. On devices without a Home key, the tap gesture remains the primary access method and cannot be disabled.
Adds a new long-press menu option that opens the reader menu. This option is conditionally available only on boards with a Home key. The new option allows users to configure long-press to open the reader menu directly, which is useful for devices with capacitive Home keys that provide long-press actions.
On devices with capacitive touch, external power rails for touch and frontlight are not cycled during software reset. Instead of restarting, cleanly shut down WiFi and SNTP in place to preserve peripheral state. Also handle Home gesture alongside Back button for exit responsiveness in the web server activity.
Adds PWR_CONFIRM option to short power button settings, allowing the power button to act as a confirm button on capacitive touch devices. Includes special handling for X4 Pro's frontlight double-click window to avoid conflicts.
Implements long-press detection for the Home key on devices without a front Confirm button. The long-press triggers the user-configured action (bookmark, KOSync, dictionary, or disabled) similar to the Confirm button long-press behavior.
Add frontlight state check to sleep exclusion conditions to avoid visible flashing caused by LEDC PWM suspension during light sleep cycles. This prevents the ESP from entering light sleep when the frontlight is on, similar to existing WiFi and USB exclusions.
X4 Pro uses a different button (DOWN instead of UP) and requires shorter debounce time (20ms vs 500ms) for recovery mode detection. The DOWN button is used to avoid GPIO0 boot-strap pin conflicts on X4 Pro hardware.
The tap zone for opening the reader menu now checks both horizontal and vertical bounds, restricting it to the center third of the screen in both dimensions. Previously only horizontal bounds were checked, allowing taps anywhere vertically in the middle third horizontally to open the menu.
X4 Pro wakes on any power button press, so it should bypass the hold-duration verification like boards without a power button. This ensures the wake is treated as valid immediately.
platform-espressif32's own penv bootstrap isn't reliably installing
its required python packages in this runner image, so pin the full
list (littlefs-python, fatfs-ng, and friends) explicitly instead of
discovering missing modules one build at a time.
pioarduino's espressif32 builder imports littlefs unconditionally,
which was never installed alongside platformio-core, breaking every
build and cppcheck job.
Introduce displayBaseWithRefreshCycle to handle B/W base layer display differently for panels that combine grayscale bases vs those that don't. Panels with combined bases defer activation to avoid visible flashing when grayscale pass re-drives text. Also add cleanup call to flush deferred activations for combined-base panels.
Implements a new rendering path for Paper Mono displays that defers base activation so grayscale planes can be combined with the base in a single waveform. This prevents visible flashing that occurs when the base is displayed separately and the gray pass re-drives the text body. The feature is controlled by combinesGrayscaleBase() checks throughout the rendering pipeline.
Consolidates duplicate build jobs into a single matrix-based job that builds firmware for default, sticky, x4pro, and papermono boards. Adds a new release workflow that builds all board variants with release-specific environments when tags are pushed. Artifacts are named to match OtaUpdater's expected format (firmware.bin for C3, firmware-<board>.bin for others).
The list() function now handles per-row sizing for wrapped items automatically, so manual scaling of row height by line count is no longer needed. Updated comments to reflect that wrapped labels grow only their own row while dense height is preserved for other rows.
When a list label can wrap to multiple lines, scale the entire row height by the label's maxLines instead of flooring against the raw font line-height. This preserves the theme's proportional padding for dense rows and prevents wrapped text from bleeding into the next row. Applied to UiListActivity, UiTabListActivity, and WifiSelectionActivity (list/tab/wifi selection screens) replacing the previous wrappedMin floor logic with rowHeight *= maxLines for labelText.maxLines > 1.
Add a lightOnChanged flag to FrontlightPanelActivity (src/activities/util/FrontlightPanelActivity.h) and initialize it in onEnter. Set the flag whenever the user toggles the light or adjustments implicitly turn it on. onExit now only updates SETTINGS.frontlightOn when lightOnChanged is true; brightness/warmth continue to be persisted as before. This avoids overwriting the saved "was on" preference with the live hardware state when the user didn't interact with the control.
Floor list row heights to the label's required lines where labels may wrap. UiListActivity, UiTabListActivity and WifiSelectionActivity now compute a wrappedMin = lineHeight * maxLines and increase rowHeight if needed to prevent the second wrapped line from bleeding into the next row. Also update SettingsActivity's language selection flow to save settings and rebuild the settings lists on return so row labels reflect the new language immediately.
Clear rowItems before bounds checking to prevent accessing stale row indices. The interaction table can deliver row indices captured before list modifications, so validate the index is within current list bounds before proceeding.
Add optional setting to restore frontlight on/off state after wake (brightness/warmth always restored). Implement double-click power button to toggle frontlight on X4 Pro. Silent reboots preserve light state regardless of setting to avoid unexpected darkness.
Implements HalFrontlight wrapper around SDK frontlight manager with brightness, warmth, and on/off controls. Adds display inversion methods to HalDisplay. Includes special power management for PaperMono device using M5PM1 PMIC for shutdown. Adds corresponding UI strings for night mode and frontlight settings.
Implements Home key detection through the touch controller for X4 Pro hardware. The Home gesture now checks for a capacitive Home key tap if available, falling back to the bottom-edge swipe gesture on devices without the key. Also adds X4 Pro device detection and display controller probing.
When users cancel (via Back button/gesture) from menu-launched sub-screens like text settings or footnotes, return them to the reader menu instead of the reading surface. This provides more intuitive navigation flow. Home gesture exits are unaffected as ActivityManager handles the stack.
Prebuild and cache ListItem/label buffers for list screens to eliminate repeated per-render heap allocations. Many activities were changed to build rowItems/rowLabels/rowValues once (on construction, onEnter(), or when data changes) and reuse them during paint: OpdsBookBrowser, RecentBooks, NetworkModeSelection, EndOfBookOptions, EpubReaderFootnotes, EpubReaderMenu, XtcReaderChapterSelection, FontDownload, KOReaderSettings, LanguageSelect, OpdsServerList, OpdsSettings, Settings, StatusBarSettings, and TextSettings. Added rebuildRowItems()/rowsDirty_ flags and fixed-capacity arrays where appropriate (NetworkModeSelection, KOReader, etc.). Behavior unchanged; this reduces CPU and heap churn during repaints.
Updates the touch/UI contribution guide to recommend activity-owned row caches for FUI list screens. It adds a concrete rebuildRows pattern, points contributors to FileBrowserActivity for the real-world implementation, and explains why per-render std::vector allocations are avoidable and harmful to steady-state rendering.
Restore the pre-FreeInkUI list density for non-touch hardware by selecting denser theme metrics where appropriate.
- Added optional hasSubtitle parameter to UiListActivity::syncListViewport and UiTabListActivity::syncTabListViewport so callers can choose subtitle-aware row heights.
- When mappedInput/gpio reports no touch, activities now override props.rowHeight with UITheme metrics (listRowHeight or listWithSubtitleRowHeight) so lists show more rows on X3/X4 devices.
- Updated callers across activities (RecentBooks, Network/WiFi screens, bookmarks, font/opds lists, reader actions, etc.) and added necessary includes.
This keeps touch-target sizing for touch devices while restoring denser layouts on non-touch hardware.
Introduce cached row buffers to avoid composing strings and allocating ListItems on every repaint. Added networkStatuses/networkRowItems + rebuildNetworkRowItems() (WifiSelectionActivity.cpp/.h), bookmarkSubtitles/bookmarkRowItems + rebuildBookmarkRowItems() (EpubReaderBookmarksActivity.cpp/.h), and tocLabels/tocRowItems + buildTocRowItems() (EpubReaderChapterSelectionActivity.cpp/.h). buildScreen() now reuses these cached arrays; caches are rebuilt when underlying data changes (scan results, bookmark delete, onEnter for TOC). Reduces per-frame allocations and CPU work during cursor moves/taps.
Add cached per-row buffers (rowNames, rowExtensions, rowItems) and rebuildRowItems() to FileBrowserActivity. loadFiles() now populates/clears the cache and error paths call rebuildRowItems(); buildScreen() reuses cached rowItems and invalidates them on theme change. Caches are cleared in onExit(). Changes in src/activities/home/FileBrowserActivity.h and .cpp. This prevents allocating hundreds of strings/ListItem objects on every repaint for large directories, reducing heap churn and improving UI responsiveness.
Explicitly apply themed popup border styles in the Wi‑Fi prompt and generic option popup dialogs. This restores the missing frame around option dialogs by setting the same border color, thickness, and corner radius used by the theme metrics, matching the prior OptionPopup rendering and keeping the UI consistent.
Rename 'items' to 'entries' to distinguish activity data from transient render items. Add comments explaining that 'entries' holds loaded data while 'rows' is the per-render vector of ListItems passed to the UI component.
Remove OMIT_FONTS conditional and always use UI_FONT_ID for titles instead of NOTOSANS_14_FONT_ID. UI fonts provide better script coverage (Hebrew, CJK) for book and directory titles, matching the font used in develop's drawHeader.
Mandate FreeInkUI components for all new screens. The old touch bridge helpers (rowTouch, colTouch, wasTapInRect, manual rect contains checks) are now legacy-only and must not appear in new code. Document the four supported host patterns: UiListActivity, UiTabListActivity, UiAppHost, and OptionPopup.
Add assertions for tab navigation bounds checking. Fix confirm button handling to only swallow release when button is actually pressed, preventing touch input from being incorrectly consumed. Add fromButton parameter to distinguish physical button presses from touch taps. Hide action hints when recent books list is empty. Add atomic synchronization for end-of-book options menu to prevent race conditions. Handle case where section is dropped during pending page turn.
Extract common UI app hosting logic into UiAppHost base class. UiListActivity now inherits from UiAppHost instead of duplicating the render target, FreeInkApp, and uiReady handshake logic. Simplifies touch routing by delegating to parent class and renames routeTouch to routeListTouch to avoid name hiding.
Refactor OtaUpdateActivity to use the standard ConfirmPopup component instead of custom touch rectangle handling and button rendering. Also configure WifiSelectionActivity to use vertical options layout with multi-line text wrapping to prevent label truncation.
Refactor WiFi save and forget prompts to use the FreeInkApp dialog system instead of custom touch handling and rendering. Moves prompt logic into event handlers that interact with the dialog action system, simplifying the code and improving consistency with the UI framework.
CrossPoint runs on touch devices (Seeed Sticky, M5Paper, LilyGo T5) alongside the button-only Xteink X3/X4. Every screen must work with both input styles.
CrossPoint runs on touch devices (Seeed Sticky, M5Paper, M5Stack PaperMono, LilyGo T5, Xteink X4 Pro) alongside the button-only Xteink X3/X4. Every screen must work with both input styles.
**There is one supported way to build a new screen: FreeInkUI, hosted through the firmware base classes below.** Touch hit-testing, tap highlighting, long-press, swipe scrolling, and button focus navigation all come from the shared stack; you never hand-roll coordinate math.
@@ -18,7 +18,7 @@ The old bridge helpers (`rowTouch`, `colTouch`, `wasTapInRect`, manual rect `con
| A modal picker or confirm inside a legacy activity | `OptionPopup` (or push `ConfirmationActivity`) | [`OtaUpdateActivity`](../../src/activities/settings/OtaUpdateActivity.cpp) |
| A Yes/No prompt inside a FUI screen | build `fui::optionDialog` into the screen | `WifiSelectionActivity::buildPromptDialog` |
All four paths route input through the same SDK interaction table, so touch and physical buttons fire the same actions with no per-screen coordinate code.
All of these paths route input through the same SDK interaction table, so touch and physical buttons fire the same actions with no per-screen coordinate code.
// Restore the saved on/off state after a normal boot or wake. Brightness and
// warmth are always remembered even when this is disabled.
uint8_tfrontlightRestoreOnWake=0;
// Language setting (Language enum index, default 0 = EN)
uint8_tlanguage=0;
// Quick Resume: keep current content visible with moon icon instead of showing a static sleep screen.
Loaded 20 of 53 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.