What changed, and why it matters
This commit removes the 'Reboot' button from the device's Login screen on models that have no battery. It also hides the empty status bar on the Login menu when there is no wallet loaded and no battery. The change is a user-interface cleanup, not a fix for an exploitable security flaw. It slightly reduces the chance a user accidentally reboots instead of shutting down on a battery-less device, which could matter for secure erase assumptions on some hardware.
No immediate security action required. Treat as a normal UX/maintenance change. Review whether removing reboot from Login on battery-less devices matches expected secure-boot/secure-erase workflows, but no patch or advisory is indicated.
Security signals we found
UI surface reduction: removes a power-action entry from an unauthenticated/pre-login screen on battery-less devices
Behavioral change: battery-less devices can no longer reboot from Login menu; only shutdown remains on Home menu
No cryptographic, memory-safety, or authorization changes
Evidence from the diff
The patch changes Login menu construction so the Shutdown/Reboot entry is appended only when kboard.has_battery is true. On battery-less devices the Login page no longer offers any reboot action. It also adjusts Menu to disable the status bar and use DEFAULT_PADDING instead of STATUS_BAR_HEIGHT when ctx.wallet is None and has_battery is false, and expands the first touch region to the top of the screen in that case. A performance-related cache (kboard.has_battery set once by PowerManager) is added. There is no cryptographic, input-validation, or privilege change.
Changed components
src/krux/pages/login.pysrc/krux/pages/__init__.pysrc/krux/pages/home_pages/home.pysrc/krux/kboard.pysrc/krux/power.pyInspect captured patch +32 / −28
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b36e7ce..f418fa9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,7 @@ The Maix Bit device has long been discouraged due to its poor-quality camera. St
### Other Bug Fixes and Improvements
- Touchscreen test added in Tools for detection check
- wbits for deflate-decompress window set to 10 bits to match KEF spec.
+- Remove "Reboot" option and status bar, when empty, from Login menu
# Changelog 25.09.0 - September 2025
diff --git a/src/krux/kboard.py b/src/krux/kboard.py
index 828abea..8393912 100644
--- a/src/krux/kboard.py
+++ b/src/krux/kboard.py
@@ -35,6 +35,7 @@ class KBoard:
self.is_tzt = board.config["type"] == "tzt"
self.is_wonder_k = board.config["type"] == "wonder_k"
self.is_m5stickv = board.config["type"] == "m5stickv"
+ self.has_battery = False # Varible to be set by PowerManager
self.has_touchscreen = board.config["krux"]["display"].get("touch", False)
self.has_minimal_display = self.is_m5stickv or self.is_cube
self.can_control_brightness = any(
diff --git a/src/krux/pages/__init__.py b/src/krux/pages/__init__.py
index 8c560f4..1094987 100644
--- a/src/krux/pages/__init__.py
+++ b/src/krux/pages/__init__.py
@@ -631,14 +631,17 @@ class Menu:
if back_label:
back_label = t("Back") if back_label == "Back" else back_label
self.menu += [("< " + back_label, back_status)]
- self.disable_statusbar = disable_statusbar
+ self.disable_statusbar = disable_statusbar or (
+ self.ctx.wallet is None and not kboard.has_battery
+ )
if offset is None:
- # Default offset for status bar
- self.menu_offset = STATUS_BAR_HEIGHT
+ self.menu_offset = (
+ STATUS_BAR_HEIGHT if not self.disable_statusbar else DEFAULT_PADDING
+ )
else:
- # Always diasble status bar if menu has non standard offset
+ # Always disable status bar if menu has non standard offset
self.disable_statusbar = True
- self.menu_offset = offset
+ self.menu_offset = offset if offset >= 0 else DEFAULT_PADDING
max_viewable = min(
self.ctx.display.max_menu_lines(self.menu_offset, self.menu), len(self.menu)
)
@@ -794,7 +797,7 @@ class Menu:
)
self.draw_network_indicator()
self.draw_wallet_indicator()
- if self.ctx.power_manager.has_battery():
+ if kboard.has_battery:
_thread.start_new_thread(self.draw_battery_indicator, ())
# self.draw_ram_indicator()
@@ -918,6 +921,9 @@ class Menu:
y_keypad_map = [
int(n * height_multiplier) + self.menu_offset for n in y_keypad_map
]
+ # Expand first region to fill the screen if there's nothing above it
+ if y_keypad_map[0] < STATUS_BAR_HEIGHT:
+ y_keypad_map[0] = 0
# Expand last region to fill the screen
y_keypad_map[-1] = self.ctx.display.height()
self.ctx.input.touch.y_regions = y_keypad_map
diff --git a/src/krux/pages/home_pages/home.py b/src/krux/pages/home_pages/home.py
index 637f498..2354fca 100644
--- a/src/krux/pages/home_pages/home.py
+++ b/src/krux/pages/home_pages/home.py
@@ -34,15 +34,14 @@ from ...qr import FORMAT_NONE, FORMAT_PMOFN
from ...krux_settings import t, Settings
from ...format import replace_decimal_separator
from ...key import TYPE_SINGLESIG
+from ...kboard import kboard
class Home(Page):
"""Home is the main menu page of the app"""
def __init__(self, ctx):
- shtn_reboot_label = (
- t("Shutdown") if ctx.power_manager.has_battery() else t("Reboot")
- )
+ shtn_reboot_label = t("Shutdown") if kboard.has_battery else t("Reboot")
super().__init__(
ctx,
Menu(
diff --git a/src/krux/pages/login.py b/src/krux/pages/login.py
index 0a054a7..e1a0b54 100644
--- a/src/krux/pages/login.py
+++ b/src/krux/pages/login.py
@@ -53,6 +53,7 @@ from ..key import (
NAME_MULTISIG,
)
from ..krux_settings import t
+from ..kboard import kboard
DIGITS_HEX = "0123456789ABCDEF"
@@ -70,28 +71,24 @@ class Login(Page):
SETTINGS_MENU_INDEX = 2
def __init__(self, ctx):
- shtn_reboot_label = (
- t("Shutdown") if ctx.power_manager.has_battery() else t("Reboot")
- )
+ login_menu_items = [
+ (t("Load Mnemonic"), self.load_key),
+ (
+ t("New Mnemonic"),
+ (self.new_key if not Settings().security.hide_mnemonic else None),
+ ),
+ (t("Settings"), self.settings),
+ (t("Tools"), self.tools),
+ (t("About"), self.about),
+ ]
+ if kboard.has_battery:
+ login_menu_items.append((t("Shutdown"), ctx.power_manager.shutdown))
+
super().__init__(
ctx,
Menu(
ctx,
- [
- (t("Load Mnemonic"), self.load_key),
- (
- t("New Mnemonic"),
- (
- self.new_key
- if not Settings().security.hide_mnemonic
- else None
- ),
- ),
- (t("Settings"), self.settings),
- (t("Tools"), self.tools),
- (t("About"), self.about),
- (shtn_reboot_label, self.shutdown),
- ],
+ login_menu_items,
back_label=None,
),
)
@@ -866,7 +863,6 @@ class Login(Page):
"""Handler for the 'about' menu item"""
import board
- from ..kboard import kboard
from ..metadata import VERSION
from ..qr import FORMAT_NONE
diff --git a/src/krux/power.py b/src/krux/power.py
index ea21cec..6de6b9b 100644
--- a/src/krux/power.py
+++ b/src/krux/power.py
@@ -42,6 +42,7 @@ class PowerManager:
self.pmu.enable_adcs(True)
if kboard.is_m5stickv:
self.pmu.enable_pek_button_monitor()
+ kboard.has_battery = self.has_battery()
except Exception as e:
print(e)
Why this scored 19/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.