-
Notifications
You must be signed in to change notification settings - Fork 237
[IMP] Disable screensaver during SeedQR transcription #740
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
[IMP] Disable screensaver during SeedQR transcription #740
Conversation
src/seedsigner/controller.py
Outdated
|
||
@property | ||
def active_view(self) -> Optional[View]: | ||
return self.back_stack[-1].view if self.back_stack else None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a slight conceptual mismatch for me for the MainMenuView
, perhaps elsewhere, too:
MainMenuView
is currently running. Literally the activeView
.BackStack
will be empty.- So this
active_view()
will returnNone
, implying that there is no activeView
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right — there's a mismatch. I initially considered active_view as a separate property, since in most frontend/UI frameworks, the view manager typically keeps track of the current view, while a back stack handles history (like breadcrumbs). That’s why I assumed the controller, acting as a view manager, should explicitly manage active_view.
However, for simplicity, I aligned it with back_stack. But because the controller clears the stack before displaying MainMenuView, active_view() ends up returning None, which feels inconsistent.
To fix this, I’ll return MainMenuView when the stack is empty — that keeps the logic clean without introducing extra state tracking. Let me know if that sounds good; I’m happy to make the change.
Side note: I haven’t worked much with resource-constrained systems like Pi Zero, so open to suggestions if explicitly tracking active_view has performance implications.
src/seedsigner/views/seed_views.py
Outdated
@@ -1567,7 +1567,8 @@ def __init__(self, seed_num: int, seedqr_format: str, initial_block_x: int = 0, | |||
self.seedqr_format = seedqr_format | |||
self.seed = self.controller.get_seed(seed_num) | |||
self.initial_block_x = initial_block_x | |||
self.initial_block_y = initial_block_y | |||
self.initial_block_y = initial_block_y | |||
self.allow_screensaver = False |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know the rationale for this setting/override is pretty self-evident already, but I always try to add a comment to remind myself of any unusual setting or decision.
I would explicitly explain why it's important to not let the screensaver run here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will add a comment .
I think exposing the The real question is just "Hey, |
Sure, I will implement a method in the controller. |
80ccbfa
to
393bbd1
Compare
Thanks for the review! |
src/seedsigner/controller.py
Outdated
@@ -466,3 +466,21 @@ def handle_exception(self, e) -> Destination: | |||
exception_msg, | |||
] | |||
return Destination(UnhandledExceptionView, view_args={"error": error}, clear_history=True) | |||
|
|||
@property | |||
def active_view(self) -> View: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned in a previous comment, I would not expose this.
I would just do this retrieval within the can_run_screensaver()
method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, I understand. I explain my reasoning behind why a active_view property might be needed. But python doesn't have access specifier. So, I removed the property and merged the logic with can_run_screensaver
src/seedsigner/controller.py
Outdated
from seedsigner.views import MainMenuView | ||
return self.back_stack[-1].view if self.back_stack else MainMenuView() | ||
|
||
def can_run_screensaver(self) -> bool: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would make this a property.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor nit: Saying that you "can do" something is more often about ability ("can you lift that weight?") whereas a phrase like "is allowed" has a different connotation (e.g. "can you light a match at a gas station?" Well, yes, it's physically possible but is it allowed?).
So if I were to read controller.can_run_screensaver == False
it feels like: Car.can_start_engine == False
, that means something's broken on my car.
I'm not sure what a better name would be...
screensaver_start_is_allowed
?
(I admit that I do fuss quite a bit about how we name things)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My name preference would be something like is_screensaver_startable
or is_screensaver_start_allowed
. Following the naming convention of is_screensaver_running
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am pretty bad at naming stuff. Also I have to admit that I am not satisfied with the name I have chosen either.
As newtonick suggested, is_screensaver_start_allowed
seems a good choice.
From the PR description:
What discussion? PRs should ideally be completely self-contained (fully explain the problem and/or rationale for the change) or at least point to where some deeper discussion occurred (though even then the PR description shouldn't assume that the reader is already familiar with the prior discussion). |
It might be a slightly difficult test to write (anything is possible with enough Leveraging the flow-based test structure should get you most of the way there. There's at least one test somewhere in there that runs a flow-based test sequence and then verifies the status of the If that ends up being too difficult, at least a |
I will update the pr description and will try to add the test cases. |
I have pushed a commit that tests the sreensaver start status when SeedTranscribeSeedQRZoomedInView is the current view in the flow. But I have questions regarding back_stack destination is handled, initial_destination. Questions
|
Disables the screensaver entirely while the SeedQR transcription routine is active. Any view can be configured to allow or disallow screensaver activation.
…to is_screensaver_start_allowed
…s when the current view is SeedTranscribeSeedQRZoomedInView
e62be31
to
c85de09
Compare
That being said, I probably could have streamlined the logic to add the current View to the Adding it to the I can't recall if there was a specific reason for doing it this way or maybe I just got myself into a sub-optimal solution while being confused by the loop + stack logic.
Again, it's never a user-facing scenario. Strictly for the test suite. |
tests/test_flows_seed.py
Outdated
@@ -476,6 +476,26 @@ def load_right_seed_into_decoder(view: View): | |||
FlowStep(seed_views.SeedOptionsView), | |||
]) | |||
|
|||
# TODO: ideally this test should be part of controller related test? move it there |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's fine to leave this flow test here to explicitly test that the screensaver cannot start during the interactive transcription process.
purpose of the questions were to determine if i should leave "is_screensaver_start_allowed" method and the "test" as it is or consider the initial_destination in the method. As per my understanding current implementation is ok as initial_destination is only for test suite. |
Description
This PR addresses part of the discussed SoB idea in the
seedsigner dev
group providing a solution for the issue of the screensaver interrupting the seed QR transcribing process. Views now have a property that indicates whether the screensaver is allowed while the view is running. As a result, the screensaver will not start when users are transcribing the QR. This improves usability, especially when transcribing 21×21 SeedQRs, where the screensaver previously interrupted the flow. A future update may introduce a long timeout wipe or reboot as a fallback for inactivity.This pull request is categorized as a:
Checklist
pytest
and made sure all unit tests pass before sumbitting the PRIf you modified or added functionality/workflow, did you add new unit tests?
I have tested this PR on the following platforms/os:
Note: Keep your changes limited in scope; if you uncover other issues or improvements along the way, ideally submit those as a separate PR. The more complicated the PR the harder to review, test, and merge.