mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-07-26 14:58:12 +00:00
fix(ui): don't draw the new-message alert over a full-screen keyboard
UITask::newMsg() (fired for every incoming DM/channel message) triggers a 3s "Msg: <sender>" overlay drawn on top of whatever screen is current -- including the shared KeyboardWidget when it's occupying the full screen for text entry (message compose, room/repeater password, channel name, device name, admin custom command, ...). A message arriving mid-typing blanked out the letter grid for the full 3s with no way to see what was being typed. KeyboardWidget now tracks whether it was actually rendered this frame (_visible, set at the top of render(), cleared by the new beginFrame()). UITask's render loop calls _kb.beginFrame() before curr->render() and skips the alert overlay when the keyboard turned out to be what got drawn -- covers every screen that shares _kb, not just message compose. The alert itself is unaffected (still fires, still expires after 3s) -- it just doesn't draw over the keyboard. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -280,6 +280,15 @@ struct KeyboardWidget {
|
|||||||
// next letter, then reverts) — Hold-Enter on Shift toggles caps_lock, which
|
// next letter, then reverts) — Hold-Enter on Shift toggles caps_lock, which
|
||||||
// keeps it on for a whole run of capitals instead.
|
// keeps it on for a whole run of capitals instead.
|
||||||
bool caps_lock = false;
|
bool caps_lock = false;
|
||||||
|
// Set by render() every time it's actually called; UITask clears it before
|
||||||
|
// curr->render() each frame (beginFrame()) so it reflects only "was the
|
||||||
|
// keyboard the thing on screen this frame" -- lets the alert overlay (new
|
||||||
|
// message toast) skip drawing over a full-screen keyboard, regardless of
|
||||||
|
// which screen (Messages/Bot/Settings/Admin/...) currently owns it.
|
||||||
|
bool _visible = false;
|
||||||
|
void beginFrame() { _visible = false; }
|
||||||
|
bool isVisible() const { return _visible; }
|
||||||
|
|
||||||
char _ph_buf[KB_PH_MAX][KB_PH_LEN];
|
char _ph_buf[KB_PH_MAX][KB_PH_LEN];
|
||||||
int _ph_count;
|
int _ph_count;
|
||||||
PopupMenu _ph_menu;
|
PopupMenu _ph_menu;
|
||||||
@@ -438,6 +447,7 @@ struct KeyboardWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int render(DisplayDriver& display) {
|
int render(DisplayDriver& display) {
|
||||||
|
_visible = true;
|
||||||
// A stale mid-cycle T9 press (no further input since) finalizes on its own —
|
// A stale mid-cycle T9 press (no further input since) finalizes on its own —
|
||||||
// the character is already committed to buf, this just stops a later Enter
|
// the character is already committed to buf, this just stops a later Enter
|
||||||
// on the same cell from being treated as a continued cycle.
|
// on the same cell from being treated as a continued cycle.
|
||||||
|
|||||||
@@ -2284,8 +2284,15 @@ void UITask::loop() {
|
|||||||
_next_refresh = millis() + Features::LOCKSCREEN_REFRESH_MS;
|
_next_refresh = millis() + Features::LOCKSCREEN_REFRESH_MS;
|
||||||
} else if (!_locked && millis() >= _next_refresh && curr) {
|
} else if (!_locked && millis() >= _next_refresh && curr) {
|
||||||
_display->startFrame();
|
_display->startFrame();
|
||||||
|
_kb.beginFrame();
|
||||||
int delay_millis = curr->render(*_display);
|
int delay_millis = curr->render(*_display);
|
||||||
if (millis() < _alert_expiry) { // alert overlay on top of any screen
|
// Skip the alert overlay (new-message toast) while the keyboard is the
|
||||||
|
// thing actually on screen this frame -- it's shared across Messages/
|
||||||
|
// Bot/Settings/Admin/etc., so this covers every screen that uses it for
|
||||||
|
// full-screen text entry, not just message compose. Otherwise a message
|
||||||
|
// arriving mid-typing blanks out the letter grid for 3s with no way to
|
||||||
|
// see what's being typed.
|
||||||
|
if (millis() < _alert_expiry && !_kb.isVisible()) { // alert overlay on top of any (non-keyboard) screen
|
||||||
renderAlertOverlay();
|
renderAlertOverlay();
|
||||||
// Keep refreshing the underlying screen at its own cadence (capped at the
|
// Keep refreshing the underlying screen at its own cadence (capped at the
|
||||||
// alert's expiry) so layouts that settle over a frame — e.g. the message-
|
// alert's expiry) so layouts that settle over a frame — e.g. the message-
|
||||||
|
|||||||
Reference in New Issue
Block a user