diff --git a/src/shell/lockscreen/lock_surface.cpp b/src/shell/lockscreen/lock_surface.cpp index 9b98e95a87..6b2265becf 100644 --- a/src/shell/lockscreen/lock_surface.cpp +++ b/src/shell/lockscreen/lock_surface.cpp @@ -500,6 +500,28 @@ LockSurface::LockSurface(WaylandConnection& connection, ConfigService* config) : }) ); + m_loginContentRow->addChild( + ui::button({ + .out = &m_passwordRevealButton, + .text = "", + .glyph = "eye", + .glyphSize = 16.0F, + .variant = ButtonVariant::Ghost, + .onClick = + [this]() { + if (m_passwordField == nullptr) { + return; + } + m_passwordRevealed = !m_passwordRevealed; + m_passwordField->setPasswordMode(!m_passwordRevealed); + if (m_passwordRevealButton != nullptr) { + m_passwordRevealButton->setGlyph(m_passwordRevealed ? "eye-off" : "eye"); + } + }, + .configure = [](Button& button) { button.setZIndex(2); }, + }) + ); + m_loginContentRow->addChild( ui::button({ .out = &m_loginButton, @@ -630,6 +652,16 @@ void LockSurface::setLockedState(bool locked) { } m_locked = locked; if (m_locked) { + // Never carry a revealed password across lock cycles. + if (m_passwordRevealed) { + m_passwordRevealed = false; + if (m_passwordField != nullptr) { + m_passwordField->setPasswordMode(true); + } + if (m_passwordRevealButton != nullptr) { + m_passwordRevealButton->setGlyph("eye"); + } + } focusPasswordField(); } else { m_inputDispatcher.setFocus(nullptr); @@ -926,6 +958,9 @@ void LockSurface::layoutScene(std::uint32_t width, std::uint32_t height) { m_widgetLayer->setVisible(false); m_loginPanel->setVisible(false); m_passwordField->setVisible(false); + if (m_passwordRevealButton != nullptr) { + m_passwordRevealButton->setVisible(false); + } m_loginButton->setVisible(false); if (m_infoRow != nullptr) { m_infoRow->setVisible(false); @@ -951,6 +986,9 @@ void LockSurface::layoutScene(std::uint32_t width, std::uint32_t height) { m_loginPanel->setVisible(loginVisible); m_loginContentRow->setVisible(loginVisible); m_passwordField->setVisible(loginVisible); + if (m_passwordRevealButton != nullptr) { + m_passwordRevealButton->setVisible(loginVisible); + } m_loginButton->setVisible(loginVisible && loginStyle.showLoginButton); const bool regular = loginVisible && loginStyle.layout == lockscreen_login_box::LayoutMode::Regular; @@ -1218,6 +1256,12 @@ void LockSurface::layoutScene(std::uint32_t width, std::uint32_t height) { m_loginButton->setGlyphSize(sessionGlyphSize); } + if (m_passwordRevealButton != nullptr) { + m_passwordRevealButton->setRadius(Style::scaledRadius(loginStyle.inputRadius)); + m_passwordRevealButton->setSize(controlHeight, controlHeight); + m_passwordRevealButton->setGlyphSize(sessionGlyphSize); + } + m_loginPanel->arrange(renderer, LayoutRect{panelX, panelY, panelWidth, panelHeight}); // Auth panel: sibling above/below the login box (flips below when near the top edge). @@ -1264,6 +1308,9 @@ void LockSurface::layoutScene(std::uint32_t width, std::uint32_t height) { void LockSurface::updateCopy() { m_passwordField->setValue(m_password); m_passwordField->setEnabled(!m_authenticating); + if (m_passwordRevealButton != nullptr) { + m_passwordRevealButton->setEnabled(!m_authenticating); + } if (m_loginButton != nullptr) { m_loginButton->setEnabled(!m_authenticating); } diff --git a/src/shell/lockscreen/lock_surface.h b/src/shell/lockscreen/lock_surface.h index 76a27cbd48..1a5e92842b 100644 --- a/src/shell/lockscreen/lock_surface.h +++ b/src/shell/lockscreen/lock_surface.h @@ -151,6 +151,8 @@ class LockSurface : public Surface { Label* m_authLabel = nullptr; Flex* m_loginContentRow = nullptr; Input* m_passwordField = nullptr; + Button* m_passwordRevealButton = nullptr; + bool m_passwordRevealed = false; Button* m_loginButton = nullptr; Button* m_layoutChip = nullptr; Flex* m_sessionRow = nullptr;