Skip to content

sync: from linuxdeepin/dde-session-shell #448

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

deepin-ci-robot
Copy link
Contributor

@deepin-ci-robot deepin-ci-robot commented Jul 17, 2025

Synchronize source files from linuxdeepin/dde-session-shell.

Source-pull-request: linuxdeepin/dde-session-shell#30

Summary by Sourcery

Sync source from linuxdeepin/dde-session-shell, integrating new authentication workflows and plugins

New Features:

  • Add password-extend login plugin support in AuthPassword
  • Introduce MFASequenceControl to drive multi-factor authentication sequences
  • Implement gesture-based login and reset as a new login-gesture plugin
  • Display a shutdown overlay via ShutdownBlackWidget during suspend/resume and shutdown

Bug Fixes:

  • Resolve focus and keyboard grabbing issues on login and lock screens
  • Correct margin and spacing inconsistencies in multiple widgets

Enhancements:

  • Refine AuthPassword UI with spacing, auth state label and edit-blocking logic
  • Extend PluginManager with getLoginPlugin, getFirstLoginPlugin and message parsing
  • Improve LockWorker to detect wake-up timing and manage black screen mode
  • Enhance SessionBaseModel to filter logged-in users via DisplayManager and emit shutdown black widget events
  • Add auth-result reminder timer and more detailed logging in DeepinAuthFramework
  • Polish various UI components (FullScreenBackground, AuthFace, DLineEditEx, UserPanel, LockContent, SFAWidget) for focus, spacing and behavior consistency

Build:

  • Update CMakeLists to include signal_bridge, gesture plugin directories and translation scripts
  • Enhance lupdate scripts to cover interface, source and tests directories

Synchronize source files from linuxdeepin/dde-session-shell.

Source-pull-request: linuxdeepin/dde-session-shell#30
@deepin-ci-robot
Copy link
Contributor Author

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: deepin-ci-robot

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Copy link

sourcery-ai bot commented Jul 17, 2025

Reviewer's Guide

This PR brings upstream synchronizations to dde-session-shell, adding extensible plugin support (including a new PasswordExtendLoginType), a SignalBridge for extra-info propagation, a new gesture-login plugin suite, a MFASequenceControl for sequencing multi-factor auth, and UI/workflow improvements across authentication widgets and session management.

Sequence diagram for extra info propagation via SignalBridge

sequenceDiagram
    participant AuthPassword
    participant AssistLoginWidget
    participant SignalBridge
    participant LockWorker
    participant DeepinAuthFramework

    AuthPassword->>AssistLoginWidget: User triggers action (e.g., password + extra info)
    AssistLoginWidget->>SignalBridge: emit requestSendExtraInfo(info)
    SignalBridge->>LockWorker: requestSendExtraInfo(account, authType, info)
    LockWorker->>DeepinAuthFramework: sendExtraInfo(account, authType, info)
    DeepinAuthFramework-->>LockWorker: (DBus call to SetExtraInfo)
Loading

ER diagram for plugin types and relationships

erDiagram
    PLUGIN_BASE ||--o{ LOGIN_PLUGIN : provides
    PLUGIN_BASE ||--o{ TRAY_PLUGIN : provides
    LOGIN_PLUGIN ||--o{ ASSIST_LOGIN_WIDGET : used_by
    LOGIN_PLUGIN ||--o{ PASSWORD_EXTEND_LOGIN_TYPE : subtype
    LOGIN_PLUGIN ||--o{ GESTURE_LOGIN_PLUGIN : subtype
    PLUGIN_MANAGER ||--o{ LOGIN_PLUGIN : manages
    PLUGIN_MANAGER ||--o{ TRAY_PLUGIN : manages
Loading

Class diagram for new and updated authentication plugin types

classDiagram
    class PluginBase {
        +ModuleType type()
    }
    class LoginPlugin {
        +authStateChanged(type, state, prompt)
        +readyToAuth()
        +updateConfig()
        +notifyAuthFactorsChanged(authFactors)
    }
    class PluginManager {
        +getFullManagedLoginPlugin()
        +getAssistloginPlugin()
        +getFirstLoginPlugin(type)
        +getLoginPlugin(authType)
        +broadcastAuthFactors(authFactors)
        +getProperties(messageObj)
        +parseMessage(message)
    }
    class AssistLoginWidget {
        +setModule(LoginPlugin*)
        +setAuthState(state, result)
        +pluginType()
        +readyToAuth()
        +updateVisible()
        +extraInfo()
    }
    class AuthCustom {
        +setModule(LoginPlugin*)
        +setAuthState(state, result)
        +setLimitsInfo(limitsInfo)
        +notifyAuthState(authType, state)
        +updateUnlockPrompt()
    }
    class AuthPassword {
        +assistLoginWidget()
        +onReadyToAuthChanged(ready)
    }
    PluginBase <|-- LoginPlugin
    PluginManager o-- LoginPlugin
    AssistLoginWidget o-- LoginPlugin
    AuthCustom o-- LoginPlugin
    AuthPassword o-- AssistLoginWidget
Loading

Class diagram for new gesture login plugin components

classDiagram
    class WayPointModel {
        +instance()
        +currentPoints()
        +isGestureEnabled()
        +getToken()
        +setUserName(name)
        +setCurrentMode(mode)
        +onPathArrived(index)
        +onUserInputDone()
        +clearPath()
    }
    class GestureDialog {
        +GestureDialog(ResetPatternController*, QWidget*)
        +onInputFinished()
    }
    class Manager {
        +start()
        +exit(retCode)
        +free()
    }
    class ResetPatternController
    class ModuleWidget
    class GesturePannel
    GestureDialog o-- ResetPatternController
    GestureDialog o-- ModuleWidget
    ModuleWidget o-- GesturePannel
    Manager o-- GestureDialog
Loading

Class diagram for MFASequenceControl and related MFAWidget changes

classDiagram
    class MFASequenceControl {
        +instance()
        +setAuthType(type)
        +onAuthStatusChanged(type, state, message)
        +insertIsolateAuthWidget(type, widget)
        +currentAuthWidget()
        +currentAuthType()
    }
    class MFAWidget {
        +setAuthType(type)
        +setAuthState(type, state, message)
        +initGestureAuth()
        +getAuthWidget()
    }
    MFAWidget o-- MFASequenceControl
Loading

Class diagram for updated SessionBaseModel and FullScreenBackground

classDiagram
    class SessionBaseModel {
        +setShutdownMode(is_black)
        +shutdownkModeChanged(bool)
        +m_enableShutdownBlackWidget: bool
    }
    class FullScreenBackground {
        +m_shutdownBlackWidget: ShutdownBlackWidget*
    }
    SessionBaseModel <|-- FullScreenBackground
Loading

File-Level Changes

Change Details Files
Enhance AuthPassword to support extended password plugins
  • Introduce DSS_PLUGIN_TYPE alias for plugin types
  • Insert m_authStateLabel and adjust UI/spacings
  • Load first login plugin of PasswordExtendLoginType and handle focus/signal blocking
  • Refine lineEdit connection lambdas to respect plugin ready state
  • Add onReadyToAuthChanged to reroute input events
src/session-widgets/auth_password.cpp
src/session-widgets/auth_password.h
src/session-widgets/assist_login_widget.cpp
src/session-widgets/assist_login_widget.h
src/global_util/plugin_manager/plugin_manager.cpp
src/global_util/plugin_manager/plugin_manager.h
Introduce SignalBridge for extra info signaling
  • Create SignalBridge singleton header
  • Emit requestSendExtraInfo from AssistLoginWidget on plugin success
  • Connect SignalBridge::requestSendExtraInfo to sendExtraInfo in LockWorker, GreeterWorker, AuthPassword
src/global_util/signal_bridge.h
src/dde-lock/lockworker.cpp
src/lightdm-deepin-greeter/greeterworker.cpp
src/session-widgets/auth_password.cpp
src/session-widgets/auth_password.h
src/session-widgets/assist_login_widget.cpp
Extend PluginManager for new plugin types and messaging
  • Add getLoginPlugin(authType) and getFirstLoginPlugin(type) APIs
  • Include PasswordExtendLoginType in createPlugin logic
  • Implement parseMessage() and getProperties() for JSON messages
src/global_util/plugin_manager/plugin_manager.cpp
src/global_util/plugin_manager/plugin_manager.h
Add gesture-login plugin module
  • Introduce plugins/login-gesture library and executable with CMake support
  • Implement WayPointModel, GesturePannel, and gesture auth/reset workers
  • Provide login-plugin interface and reset-dialog UI
plugins/login-gesture/**
Add MFASequenceControl for multi-factor auth flows
  • Implement mfasequencecontrol to parse DConfig sequences
  • Allow isolating custom auth widgets and emitting UI change signals
  • Hook sequence control into MFAWidget and AuthCustom flows
src/session-widgets/mfasequencecontrol.cpp
src/session-widgets/mfasequencecontrol.h
src/session-widgets/mfa_widget.cpp
src/session-widgets/mfa_widget.h
src/session-widgets/auth_custom.cpp
src/session-widgets/auth_custom.h
Enhance shutdown and black-screen handling
  • Introduce ShutdownBlackWidget and integrate with FullScreenBackground
  • Emit shutdownkModeChanged in SessionBaseModel and bind in FullScreenBackground
  • Add wake-up timer in LockWorker to exit black mode early
src/widgets/shutdown_black_widget.h
src/widgets/shutdown_black_widget.cpp
src/widgets/fullscreenbackground.h
src/widgets/fullscreenbackground.cpp
src/session-widgets/sessionbasemodel.cpp
src/dde-lock/lockworker.cpp

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @deepin-ci-robot - I've reviewed your changes and found some issues that need to be addressed.

  • This PR merges a huge upstream sync along with a new gesture-login plugin; consider breaking it into smaller, focused PRs (core sync vs. new plugin) to simplify review and reduce integration risk.
  • There are many hard-coded numbers for timings and layout spacings—defining these as named constants would improve readability and make future adjustments easier.
  • The logic for sending extraInfo/readyToAuth signals is duplicated across several widgets—extracting a shared helper or base class for plugin communication could reduce code duplication and ensure consistent behavior.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- This PR merges a huge upstream sync along with a new gesture-login plugin; consider breaking it into smaller, focused PRs (core sync vs. new plugin) to simplify review and reduce integration risk.
- There are many hard-coded numbers for timings and layout spacings—defining these as named constants would improve readability and make future adjustments easier.
- The logic for sending extraInfo/readyToAuth signals is duplicated across several widgets—extracting a shared helper or base class for plugin communication could reduce code duplication and ensure consistent behavior.

## Individual Comments

### Comment 1
<location> `src/session-widgets/auth_password.cpp:151` </location>
<code_context>
     }

+    // 密码框下面增加一个认证界面
+    auto extendPlugin = PluginManager::instance()->getFirstLoginPlugin(dss::module::BaseModuleInterface::PasswordExtendLoginType);
+    if (extendPlugin) {
+        m_assistLoginWidget = new AssistLoginWidget(this);
</code_context>

<issue_to_address>
Potential for multiple AssistLoginWidget instances may cause confusion.

Assigning both plugin widgets to m_assistLoginWidget can cause ambiguity and incorrect signal/slot connections. Use separate member variables or a container to clearly distinguish between plugin instances.
</issue_to_address>

### Comment 2
<location> `src/session-widgets/auth_password.cpp:171` </location>
<code_context>
 {
     AuthModule::initConnections();
+
+    auto blockEditSig = [this]() -> bool {
+        return m_assistLoginWidget
+               && m_assistLoginWidget->isVisible()
</code_context>

<issue_to_address>
blockEditSig lambda may not distinguish between multiple assist login widgets.

Currently, m_assistLoginWidget only references the last created widget, which may cause blockEditSig to behave incorrectly when multiple assist login widgets exist. Please update the logic to handle multiple widgets appropriately.
</issue_to_address>

### Comment 3
<location> `src/session-widgets/auth_password.cpp:205` </location>
<code_context>
-    connect(m_lineEdit, &DLineEditEx::returnPressed, this, [this] {
-        if (!m_lineEdit->lineEdit()->isReadOnly()) // 避免用户在验证的时候反复点击
-            emit requestAuthenticate();
+    connect(m_lineEdit, &DLineEditEx::returnPressed, this, [this, blockEditSig] {
+        if (!m_lineEdit->lineEdit()->isReadOnly()) { // 避免用户在验证的时候反复点击
+            if (!blockEditSig()) {
</code_context>

<issue_to_address>
Setting focus proxy to m_assistLoginWidget may not work if multiple widgets exist.

setFocusProxy(m_assistLoginWidget) will only apply to the most recently assigned widget, which may cause unexpected focus behavior. Please ensure focus is managed correctly for all assist login widgets.
</issue_to_address>

### Comment 4
<location> `src/session-widgets/assist_login_widget.cpp:56` </location>
<code_context>

+dss::module::BaseModuleInterface::ModuleType AssistLoginWidget::pluginType() const
+{
+    if (m_module)
+        return m_module->type();
+
</code_context>

<issue_to_address>
pluginType() returns LoginType by default, which may mask errors.

Returning LoginType when m_module is null may hide initialization issues. Consider returning a sentinel value to better detect misconfigurations.

Suggested implementation:

```cpp
dss::module::BaseModuleInterface::ModuleType AssistLoginWidget::pluginType() const
{
    if (m_module)
        return m_module->type();
    return DSS_PLUGIN_TYPE::Unknown;

```

If `Unknown` is not already a value in the `ModuleType` enum, you will need to add it to the enum definition in the appropriate header file (likely `base_module_interface.h` or similar):

```cpp
enum class ModuleType {
    LoginType,
    // ... other types ...
    Unknown
};
```
</issue_to_address>

### Comment 5
<location> `src/session-widgets/assist_login_widget.cpp:129` </location>
<code_context>
+    qCDebug(DDE_SHELL) << Q_FUNC_INFO << m_currentAuthData.result;
+    const QString &account = callbackData.account;
+    const QString &token = callbackData.token;
+    if (DSS_PLUGIN_TYPE::PasswordExtendLoginType == pluginType()) {
+        qCInfo(DDE_SHELL) << "Request send extra info, result: " << callbackData.result;
+        m_extraInfo = token;
</code_context>

<issue_to_address>
Overloading setAuthData for PasswordExtendLoginType may cause confusion.

Document the unique handling for PasswordExtendLoginType in setAuthData, and verify that other plugin types do not need similar logic.
</issue_to_address>

### Comment 6
<location> `src/widgets/dlineeditex.cpp:160` </location>
<code_context>
     if ((watched == this || watched == this->lineEdit())
         && event->type() == QEvent::InputMethodQuery) {
         return true;
+    } else if ((watched == this || watched == this->lineEdit())
+                && event->type() == QEvent::KeyPress
+                && m_enableTableKeyEvent) {
</code_context>

<issue_to_address>
Tab key triggers returnPressed, which may be unexpected for users.

Confirm that overriding Tab to emit returnPressed is intentional and does not hinder keyboard navigation or accessibility.
</issue_to_address>

<suggested_fix>
<<<<<<< SEARCH
        if (keyEvent->key() == Qt::Key_Tab
            && keyEvent->modifiers() == Qt::NoModifier
            && !this->text().isEmpty()) {
            emit this->returnPressed();
            return true;
        }
=======
        // Do not emit returnPressed() on Tab to preserve standard keyboard navigation and accessibility.
        if (keyEvent->key() == Qt::Key_Tab
            && keyEvent->modifiers() == Qt::NoModifier) {
            // Allow normal Tab key processing (focus navigation)
            return false;
        }
        if (keyEvent->key() == Qt::Key_Return
            && keyEvent->modifiers() == Qt::NoModifier
            && !this->text().isEmpty()) {
            emit this->returnPressed();
            return true;
        }
>>>>>>> REPLACE

</suggested_fix>

### Comment 7
<location> `src/session-widgets/auth_face.cpp:76` </location>
<code_context>
  */
 void AuthFace::setAuthState(const AuthCommon::AuthState state, const QString &result)
 {
+    static bool startFilterTimer = false;
     m_state = state;
     switch (state) {
</code_context>

<issue_to_address>
Using a static variable for startFilterTimer may cause issues with multiple AuthFace instances.

A static variable here means all AuthFace instances share the same startFilterTimer, which can lead to incorrect behavior. Use a member variable to ensure each instance manages its own state.
</issue_to_address>

### Comment 8
<location> `src/widgets/shutdown_black_widget.cpp:69` </location>
<code_context>
+    setVisible(false);
+    setWindowFlags(Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint);
+
+    QCursor cursor(Qt::BlankCursor);
+    this->setCursor(cursor);
+
+    installEventFilter(this);
</code_context>

<issue_to_address>
Cursor handling may not restore original cursor state.

Currently, the cursor is only restored in setBlackMode and not in debug mode, which may cause issues if the widget is shown or hidden multiple times. Please ensure the original cursor is always restored, regardless of build type.

Suggested implementation:

```cpp
ShutdownBlackWidget::ShutdownBlackWidget(QWidget *parent)
    : QWidget(parent)
    , m_cursor(cursor())
{
    signal(SIGTERM, handleSIGTERM);
    setObjectName(QStringLiteral("ShutdownBlackWidget"));
    setAccessibleName(QStringLiteral("ShutdownBlackWidget"));
    setVisible(false);
    setWindowFlags(Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint);

    // Store the original cursor in m_cursor (already done in initializer list)
    // Do not set blank cursor here; do it only when showing the widget

    installEventFilter(this);
}

```

```cpp
void ShutdownBlackWidget::setBlackMode(const bool isBlackMode)
{
    qInfo() << "ShutdownBlackWidget setBlackMode : " << isBlackMode;
    setVisible(isBlackMode);
    if (isBlackMode) {
        // Set blank cursor when showing the widget
        QCursor blankCursor(Qt::BlankCursor);
        this->setCursor(blankCursor);
        show();
    } else {
        // Always restore the original cursor when hiding the widget
        this->setCursor(m_cursor);
        hide();
    }
#ifndef QT_DEBUG

```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@@ -146,6 +147,16 @@ void AuthPassword::initUI()
m_lineEdit->show();
}

// 密码框下面增加一个认证界面
auto extendPlugin = PluginManager::instance()->getFirstLoginPlugin(dss::module::BaseModuleInterface::PasswordExtendLoginType);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Potential for multiple AssistLoginWidget instances may cause confusion.

Assigning both plugin widgets to m_assistLoginWidget can cause ambiguity and incorrect signal/slot connections. Use separate member variables or a container to clearly distinguish between plugin instances.

@@ -156,20 +167,27 @@
void AuthPassword::initConnections()
{
AuthModule::initConnections();

auto blockEditSig = [this]() -> bool {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): blockEditSig lambda may not distinguish between multiple assist login widgets.

Currently, m_assistLoginWidget only references the last created widget, which may cause blockEditSig to behave incorrectly when multiple assist login widgets exist. Please update the logic to handle multiple widgets appropriately.

connect(m_lineEdit, &DLineEditEx::returnPressed, this, [this] {
if (!m_lineEdit->lineEdit()->isReadOnly()) // 避免用户在验证的时候反复点击
emit requestAuthenticate();
connect(m_lineEdit, &DLineEditEx::returnPressed, this, [this, blockEditSig] {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Setting focus proxy to m_assistLoginWidget may not work if multiple widgets exist.

setFocusProxy(m_assistLoginWidget) will only apply to the most recently assigned widget, which may cause unexpected focus behavior. Please ensure focus is managed correctly for all assist login widgets.

}
}

dss::module::BaseModuleInterface::ModuleType AssistLoginWidget::pluginType() const
{
if (m_module)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): pluginType() returns LoginType by default, which may mask errors.

Returning LoginType when m_module is null may hide initialization issues. Consider returning a sentinel value to better detect misconfigurations.

Suggested implementation:

dss::module::BaseModuleInterface::ModuleType AssistLoginWidget::pluginType() const
{
    if (m_module)
        return m_module->type();
    return DSS_PLUGIN_TYPE::Unknown;

If Unknown is not already a value in the ModuleType enum, you will need to add it to the enum definition in the appropriate header file (likely base_module_interface.h or similar):

enum class ModuleType {
    LoginType,
    // ... other types ...
    Unknown
};

qCDebug(DDE_SHELL) << Q_FUNC_INFO << m_currentAuthData.result;
const QString &account = callbackData.account;
const QString &token = callbackData.token;
if (DSS_PLUGIN_TYPE::PasswordExtendLoginType == pluginType()) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: Overloading setAuthData for PasswordExtendLoginType may cause confusion.

Document the unique handling for PasswordExtendLoginType in setAuthData, and verify that other plugin types do not need similar logic.

Comment on lines +164 to +169
if (keyEvent->key() == Qt::Key_Tab
&& keyEvent->modifiers() == Qt::NoModifier
&& !this->text().isEmpty()) {
emit this->returnPressed();
return true;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Tab key triggers returnPressed, which may be unexpected for users.

Confirm that overriding Tab to emit returnPressed is intentional and does not hinder keyboard navigation or accessibility.

Suggested change
if (keyEvent->key() == Qt::Key_Tab
&& keyEvent->modifiers() == Qt::NoModifier
&& !this->text().isEmpty()) {
emit this->returnPressed();
return true;
}
// Do not emit returnPressed() on Tab to preserve standard keyboard navigation and accessibility.
if (keyEvent->key() == Qt::Key_Tab
&& keyEvent->modifiers() == Qt::NoModifier) {
// Allow normal Tab key processing (focus navigation)
return false;
}
if (keyEvent->key() == Qt::Key_Return
&& keyEvent->modifiers() == Qt::NoModifier
&& !this->text().isEmpty()) {
emit this->returnPressed();
return true;
}

@@ -68,6 +73,7 @@ void AuthFace::reset()
*/
void AuthFace::setAuthState(const AuthCommon::AuthState state, const QString &result)
{
static bool startFilterTimer = false;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Using a static variable for startFilterTimer may cause issues with multiple AuthFace instances.

A static variable here means all AuthFace instances share the same startFilterTimer, which can lead to incorrect behavior. Use a member variable to ensure each instance manages its own state.

Comment on lines +69 to +70
QCursor cursor(Qt::BlankCursor);
this->setCursor(cursor);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): Cursor handling may not restore original cursor state.

Currently, the cursor is only restored in setBlackMode and not in debug mode, which may cause issues if the widget is shown or hidden multiple times. Please ensure the original cursor is always restored, regardless of build type.

Suggested implementation:

ShutdownBlackWidget::ShutdownBlackWidget(QWidget *parent)
    : QWidget(parent)
    , m_cursor(cursor())
{
    signal(SIGTERM, handleSIGTERM);
    setObjectName(QStringLiteral("ShutdownBlackWidget"));
    setAccessibleName(QStringLiteral("ShutdownBlackWidget"));
    setVisible(false);
    setWindowFlags(Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint);

    // Store the original cursor in m_cursor (already done in initializer list)
    // Do not set blank cursor here; do it only when showing the widget

    installEventFilter(this);
}
void ShutdownBlackWidget::setBlackMode(const bool isBlackMode)
{
    qInfo() << "ShutdownBlackWidget setBlackMode : " << isBlackMode;
    setVisible(isBlackMode);
    if (isBlackMode) {
        // Set blank cursor when showing the widget
        QCursor blankCursor(Qt::BlankCursor);
        this->setCursor(blankCursor);
        show();
    } else {
        // Always restore the original cursor when hiding the widget
        this->setCursor(m_cursor);
        hide();
    }
#ifndef QT_DEBUG

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant