From 8e7991606e21ced1efe404fa3990dad286859f01 Mon Sep 17 00:00:00 2001 From: Robert Fisk Date: Sat, 10 Aug 2024 05:38:46 -0400 Subject: [PATCH 1/4] Improve CannedMessageModule usability - Don't let Screen timer jump away from CannedMessageModule frame - Correctly timeout CannedMessageModule with INACTIVATE_AFTER_MS - Don't reset half-typed messages on timeout --- src/graphics/Screen.cpp | 7 +++++++ src/modules/CannedMessageModule.cpp | 14 ++++---------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 68fdba2078..a6b4f9cbe1 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -45,6 +45,7 @@ along with this program. If not, see . #include "mesh/generated/meshtastic/deviceonly.pb.h" #include "meshUtils.h" #include "modules/AdminModule.h" +#include "modules/CannedMessageModule.h" #include "modules/ExternalNotificationModule.h" #include "modules/TextMessageModule.h" #include "sleep.h" @@ -2317,6 +2318,12 @@ void Screen::handleOnPress() if (scanAndSelectInput != nullptr && scanAndSelectInput->dismissCannedMessageFrame()) return; + // Don't transition away from canned messages if it is active + if (cannedMessageModule->shouldDraw()) { + lastScreenTransition = millis(); + return; + } + // If screen was off, just wake it, otherwise advance to next frame // If we are in a transition, the press must have bounced, drop it. if (ui->getUiState()->frameState == FIXED) { diff --git a/src/modules/CannedMessageModule.cpp b/src/modules/CannedMessageModule.cpp index 87a3e89273..ab8f368ae0 100644 --- a/src/modules/CannedMessageModule.cpp +++ b/src/modules/CannedMessageModule.cpp @@ -360,12 +360,9 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event) if (validEvent) { requestFocus(); // Tell Screen::setFrames to move to our module's frame, next time it runs - // Let runOnce to be called immediately. - if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_SELECT) { - setIntervalFromNow(0); // on fast keypresses, this isn't fast enough. - } else { - runOnce(); - } + // Run CannedMessageModule thread now from callee thread context, + // and also schedule it to run later in its own context with the requested delay. + setIntervalFromNow(runOnce()); } return 0; @@ -423,11 +420,8 @@ int32_t CannedMessageModule::runOnce() this->notifyObservers(&e); } else if (((this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT)) && ((millis() - this->lastTouchMillis) > INACTIVATE_AFTER_MS)) { - // Reset module + // Don't reset module, just hide the frame e.action = UIFrameEvent::Action::REGENERATE_FRAMESET; // We want to change the list of frames shown on-screen - this->currentMessageIndex = -1; - this->freetext = ""; // clear freetext - this->cursor = 0; #if !defined(T_WATCH_S3) && !defined(RAK14014) this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE; From 21d246ab7c91fc3747bcf22ec42d1602964ca9a1 Mon Sep 17 00:00:00 2001 From: Robert Fisk Date: Sun, 11 Aug 2024 05:11:28 -0400 Subject: [PATCH 2/4] Fix more canned message timeout issues: - Reliably timout when showing canned message list - Don't inconsistently clear freetext when scrolling canned message list --- src/modules/CannedMessageModule.cpp | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/modules/CannedMessageModule.cpp b/src/modules/CannedMessageModule.cpp index ab8f368ae0..456c4ad9a5 100644 --- a/src/modules/CannedMessageModule.cpp +++ b/src/modules/CannedMessageModule.cpp @@ -419,9 +419,10 @@ int32_t CannedMessageModule::runOnce() this->notifyObservers(&e); } else if (((this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT)) && - ((millis() - this->lastTouchMillis) > INACTIVATE_AFTER_MS)) { + ((millis() - this->lastTouchMillis) >= INACTIVATE_AFTER_MS)) { // Don't reset module, just hide the frame e.action = UIFrameEvent::Action::REGENERATE_FRAMESET; // We want to change the list of frames shown on-screen + this->currentMessageIndex = -1; #if !defined(T_WATCH_S3) && !defined(RAK14014) this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE; @@ -474,8 +475,6 @@ int32_t CannedMessageModule::runOnce() } else if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_UP) { if (this->messagesCount > 0) { this->currentMessageIndex = getPrevIndex(); - this->freetext = ""; // clear freetext - this->cursor = 0; #if !defined(T_WATCH_S3) && !defined(RAK14014) this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE; @@ -487,8 +486,6 @@ int32_t CannedMessageModule::runOnce() } else if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_DOWN) { if (this->messagesCount > 0) { this->currentMessageIndex = this->getNextIndex(); - this->freetext = ""; // clear freetext - this->cursor = 0; #if !defined(T_WATCH_S3) && !defined(RAK14014) this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE; @@ -638,13 +635,9 @@ int32_t CannedMessageModule::runOnce() if (screen) screen->removeFunctionSymbal("Fn"); } - - this->lastTouchMillis = millis(); - this->notifyObservers(&e); - return INACTIVATE_AFTER_MS; } - if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) { + if (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT || this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) { this->lastTouchMillis = millis(); this->notifyObservers(&e); return INACTIVATE_AFTER_MS; From 27f00cd1565fb4535c4e0cc6dc53cb1cff9597f2 Mon Sep 17 00:00:00 2001 From: Robert Fisk Date: Sun, 11 Aug 2024 06:50:53 -0400 Subject: [PATCH 3/4] Improve popup message handling - Restore old canned message state after displaying message - Don't clear freetext/state after displaying message --- src/modules/CannedMessageModule.cpp | 15 ++++++--------- src/modules/CannedMessageModule.h | 1 + 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/modules/CannedMessageModule.cpp b/src/modules/CannedMessageModule.cpp index 456c4ad9a5..34b0ccc5e1 100644 --- a/src/modules/CannedMessageModule.cpp +++ b/src/modules/CannedMessageModule.cpp @@ -406,17 +406,12 @@ int32_t CannedMessageModule::runOnce() if ((this->runState == CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_ACK_NACK_RECEIVED) || (this->runState == CANNED_MESSAGE_RUN_STATE_MESSAGE)) { // TODO: might have some feedback of sending state - this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE; + if (this->runState == CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE) { + this->restoreOldState = CANNED_MESSAGE_RUN_STATE_INACTIVE; + } + this->runState = this->restoreOldState; temporaryMessage = ""; e.action = UIFrameEvent::Action::REGENERATE_FRAMESET; // We want to change the list of frames shown on-screen - this->currentMessageIndex = -1; - this->freetext = ""; // clear freetext - this->cursor = 0; - -#if !defined(T_WATCH_S3) && !defined(RAK14014) - this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE; -#endif - this->notifyObservers(&e); } else if (((this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT)) && ((millis() - this->lastTouchMillis) >= INACTIVATE_AFTER_MS)) { @@ -721,6 +716,7 @@ void CannedMessageModule::showTemporaryMessage(const String &message) UIFrameEvent e; e.action = UIFrameEvent::Action::REGENERATE_FRAMESET; // We want to change the list of frames shown on-screen notifyObservers(&e); + this->restoreOldState = this->runState; runState = CANNED_MESSAGE_RUN_STATE_MESSAGE; // run this loop again in 2 seconds, next iteration will clear the display setIntervalFromNow(2000); @@ -1088,6 +1084,7 @@ ProcessMessage CannedMessageModule::handleReceived(const meshtastic_MeshPacket & UIFrameEvent e; e.action = UIFrameEvent::Action::REGENERATE_FRAMESET; // We want to change the list of frames shown on-screen requestFocus(); // Tell Screen::setFrames that our module's frame should be shown, even if not "first" in the frameset + this->restoreOldState = this->runState; this->runState = CANNED_MESSAGE_RUN_STATE_ACK_NACK_RECEIVED; this->incoming = service->getNodenumFromRequestId(mp.decoded.request_id); meshtastic_Routing decoded = meshtastic_Routing_init_default; diff --git a/src/modules/CannedMessageModule.h b/src/modules/CannedMessageModule.h index 368574c40c..4723c057d2 100644 --- a/src/modules/CannedMessageModule.h +++ b/src/modules/CannedMessageModule.h @@ -131,6 +131,7 @@ class CannedMessageModule : public SinglePortModule, public Observable Date: Wed, 14 Aug 2024 04:16:05 -0400 Subject: [PATCH 4/4] Additional checks for closing Scan&Select canned frame --- src/graphics/Screen.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index a6b4f9cbe1..d2d6047b4c 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -2315,7 +2315,9 @@ void Screen::handleOnPress() { // If Canned Messages is using the "Scan and Select" input, dismiss the canned message frame when user button is pressed // Minimize impact as a courtesy, as "scan and select" may be used as default config for some boards - if (scanAndSelectInput != nullptr && scanAndSelectInput->dismissCannedMessageFrame()) + // (Fall-through if using auto carousel, to prevent unexpected closing of canned message frame) + if (scanAndSelectInput != nullptr && !config.display.auto_screen_carousel_secs && + scanAndSelectInput->dismissCannedMessageFrame()) return; // Don't transition away from canned messages if it is active