Skip to content

Conversation

@pengfeixx
Copy link
Contributor

@pengfeixx pengfeixx commented Jan 13, 2026

Fix the abnormal display of network panel height

Log: Fix the abnormal display of network panel height
pms: BUG-311381

Summary by Sourcery

Fix layout handling for the dock network panel to ensure correct height and geometry when the panel is shown or hidden.

Bug Fixes:

  • Ensure the dock network panel recalculates its content height on show and hide to prevent abnormal height display.
  • Reset internal minimum height and update sizes when the panel is hidden so that the next show starts from a correct collapsed state.
  • Trigger geometry updates in the network view when it becomes visible to keep layout in sync with the dock container.

Fix the abnormal display of network panel height

Log: Fix the abnormal display of network panel height
pms: BUG-311381
@sourcery-ai
Copy link

sourcery-ai bot commented Jan 13, 2026

Reviewer's Guide

Adjusts network dock panel sizing behavior by recalculating sizes on show/hide events and ensuring the NetView layout geometry is updated when shown, to fix abnormal panel height display.

Sequence diagram for network panel show and hide sizing logic

sequenceDiagram
  actor User
  participant DockContentWidget
  participant NetView

  User->>DockContentWidget: open_panel
  activate DockContentWidget
  DockContentWidget->>DockContentWidget: showEvent(event)
  DockContentWidget->>DockContentWidget: updateSize()
  DockContentWidget->>DockContentWidget: base_QWidget_showEvent(event)
  DockContentWidget->>DockContentWidget: queue_updateSize_and_resize()
  deactivate DockContentWidget

  User->>NetView: show_panel_window
  activate NetView
  NetView->>NetView: showEvent(event)
  NetView->>NetView: maybe_exec_ToggleExpand()
  NetView->>NetView: updateGeometries()
  deactivate NetView

  User->>DockContentWidget: close_panel
  activate DockContentWidget
  DockContentWidget->>DockContentWidget: hideEvent(event)
  DockContentWidget->>DockContentWidget: base_QWidget_hideEvent(event)
  DockContentWidget->>DockContentWidget: m_minHeight = -1
  DockContentWidget->>DockContentWidget: queue_updateSize_collapsed()
  deactivate DockContentWidget
Loading

Updated class diagram for DockContentWidget and NetView sizing behavior

classDiagram
  class DockContentWidget {
    +QVBoxLayout* m_mainLayout
    +NetView* m_netView
    +QPushButton* m_netSetBtn
    +QPushButton* m_netCheckBtn
    +int m_minHeight
    +void setMargins(QMargins margin)
    +void setMinHeight(int minHeight)
    +void updateSize()
    +void showEvent(QShowEvent* event)
    +void hideEvent(QHideEvent* event)
  }

  class NetView {
    +void showEvent(QShowEvent* event)
    +void hideEvent(QHideEvent* event)
    +void updateGeometries()
  }

  DockContentWidget --> NetView : contains
Loading

File-Level Changes

Change Details Files
Refine DockContentWidget lifecycle handling to recalculate and reset network panel height on show/hide.
  • Expose updateSize as a Qt slot so it can be invoked via QMetaObject::invokeMethod and signal/slot mechanisms.
  • Override showEvent to call updateSize immediately, then queue another update and a resize after the widget is shown to account for final layout/geometry.
  • Override hideEvent to reset m_minHeight, and queue an updateSize call so the widget collapses to the correct base height for the next show.
dock-network-plugin/dockcontentwidget.h
Ensure NetView updates its internal layout geometries when the window is shown.
  • Call updateGeometries() in NetView::showEvent after handling m_shouldUpdateExpand to recompute layout and item sizes when the view becomes visible.
net-view/window/netview.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

@deepin-ci-robot
Copy link

deepin pr auto review

代码审查意见

整体评价

这段代码主要对DockContentWidget类添加了showEvent和hideEvent方法,并在NetView类中添加了updateGeometries调用,目的是优化窗口显示时的尺寸计算和更新。代码整体逻辑清晰,但有一些可以改进的地方。

具体审查意见

1. 语法与逻辑问题

  1. DockContentWidget::showEvent中的lambda表达式

    QMetaObject::invokeMethod(this, [this]() {
        updateSize();
        resize(size());
    }, Qt::QueuedConnection);
    • 问题:直接调用resize(size())没有实际效果,因为size()返回的是当前尺寸,设置回相同尺寸不会改变任何东西。
    • 建议:如果目的是强制更新布局,应该使用updateGeometry()adjustSize()
      QMetaObject::invokeMethod(this, [this]() {
          updateSize();
          adjustSize(); // 或 updateGeometry()
      }, Qt::QueuedConnection);
  2. DockContentWidget::hideEvent中的updateSize调用

    QMetaObject::invokeMethod(this, "updateSize", Qt::QueuedConnection);
    • 问题:使用字符串形式的函数名调用不够安全,编译器无法检查函数名是否正确。
    • 建议:使用函数指针或lambda表达式:
      QMetaObject::invokeMethod(this, [this]() {
          updateSize();
      }, Qt::QueuedConnection);

2. 代码质量

  1. 魔法数字

    auto h = Dock::DOCK_POPUP_WIDGET_MAX_HEIGHT - 20 - m_mainLayout->contentsMargins().top() - ...
    • 问题:20是一个魔法数字,不清楚其含义。
    • 建议:定义一个有意义的常量:
      static constexpr int POPUP_WIDGET_HEIGHT_MARGIN = 20;
      auto h = Dock::DOCK_POPUP_WIDGET_MAX_HEIGHT - POPUP_WIDGET_HEIGHT_MARGIN - ...
  2. 复杂的条件表达式

    • 问题:updateSize()中的高度计算表达式过于复杂,可读性差。
    • 建议:拆分为多个步骤:
      void updateSize() {
          const int baseHeight = Dock::DOCK_POPUP_WIDGET_MAX_HEIGHT - POPUP_WIDGET_HEIGHT_MARGIN;
          const int marginHeight = m_mainLayout->contentsMargins().top();
          const int buttonHeight = m_netSetBtn->height() + (m_netCheckBtn->isVisible() ? (m_netCheckBtn->height() + 10) : 0);
          const int availableHeight = baseHeight - marginHeight - buttonHeight;
          m_netView->setMaxHeight(availableHeight);
      }

3. 代码性能

  1. 多次调用updateSize

    • 问题:在showEvent中调用了两次updateSize(),一次直接调用,一次通过QueuedConnection。
    • 建议:评估是否需要两次调用,如果可以合并为一次,将提高性能。
  2. 频繁的布局计算

    • 问题:每次显示/隐藏都会触发尺寸计算,如果频繁显示/隐藏可能会造成性能问题。
    • 建议:考虑添加标志位,只在必要时更新尺寸。

4. 代码安全

  1. 空指针检查

    • 问题:代码中没有检查m_netView、m_mainLayout等指针是否为空。
    • 建议:添加空指针检查:
      void updateSize() {
          if (!m_netView || !m_mainLayout || !m_netSetBtn) {
              return;
          }
          // 其余代码...
      }
  2. 线程安全

    • 问题:如果这些方法可能从不同线程调用,需要考虑线程安全问题。
    • 建议:确保这些方法只在主线程调用,或添加适当的线程保护。

修改建议

综合以上问题,建议修改如下:

// dockcontentwidget.h
class DockContentWidget : public QWidget
{
    // ... 其他代码 ...
    
    static constexpr int POPUP_WIDGET_HEIGHT_MARGIN = 20;
    static constexpr int BUTTON_SPACING = 10;
    
public Q_SLOTS:
    void updateSize() {
        if (!m_netView || !m_mainLayout || !m_netSetBtn) {
            return;
        }
        
        const int baseHeight = Dock::DOCK_POPUP_WIDGET_MAX_HEIGHT - POPUP_WIDGET_HEIGHT_MARGIN;
        const int marginHeight = m_mainLayout->contentsMargins().top();
        const int buttonHeight = m_netSetBtn->height() + (m_netCheckBtn->isVisible() ? (m_netCheckBtn->height() + BUTTON_SPACING) : 0);
        const int availableHeight = baseHeight - marginHeight - buttonHeight;
        m_netView->setMaxHeight(availableHeight);
    }
    
protected:
    void showEvent(QShowEvent *event) override
    {
        QWidget::showEvent(event);
        updateSize();
        QMetaObject::invokeMethod(this, [this]() {
            updateSize();
            adjustSize();
        }, Qt::QueuedConnection);
    }

    void hideEvent(QHideEvent *event) override
    {
        QWidget::hideEvent(event);
        m_minHeight = -1;
        QMetaObject::invokeMethod(this, [this]() {
            updateSize();
        }, Qt::QueuedConnection);
    }
    
    // ... 其他代码 ...
};

总结

这段代码主要改进了窗口显示时的尺寸计算和更新逻辑,但存在一些可以优化的地方,包括:

  1. 修复无效的resize调用
  2. 提高代码可读性,消除魔法数字
  3. 添加必要的空指针检查
  4. 优化性能,避免不必要的重复计算

以上修改将使代码更健壮、更易维护,同时保持原有功能。

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 - I've found 2 issues, and left some high level feedback:

  • In DockContentWidget::showEvent you call updateSize() immediately and again in a queued lambda; consider whether both are required or add a brief inline comment to clarify the need for the second call to avoid future confusion about potential redundant work.
  • For the queued calls to updateSize in DockContentWidget (both in showEvent and hideEvent), prefer using the function-pointer overload of QMetaObject::invokeMethod (e.g. &DockContentWidget::updateSize) instead of the string-based version for better type safety and compile-time checking.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In DockContentWidget::showEvent you call updateSize() immediately and again in a queued lambda; consider whether both are required or add a brief inline comment to clarify the need for the second call to avoid future confusion about potential redundant work.
- For the queued calls to updateSize in DockContentWidget (both in showEvent and hideEvent), prefer using the function-pointer overload of QMetaObject::invokeMethod (e.g. &DockContentWidget::updateSize) instead of the string-based version for better type safety and compile-time checking.

## Individual Comments

### Comment 1
<location> `dock-network-plugin/dockcontentwidget.h:107-111` </location>
<code_context>
+        }, Qt::QueuedConnection);
+    }
+
+    void hideEvent(QHideEvent *event) override
+    {
+        QWidget::hideEvent(event);
+        m_minHeight = -1;
+        // 隐藏时更新尺寸为折叠状态,确保下次显示时初始尺寸正确
+        QMetaObject::invokeMethod(this, "updateSize", Qt::QueuedConnection);
+    }
+
</code_context>

<issue_to_address>
**suggestion:** Mixed styles of QMetaObject::invokeMethod reduce type safety and consistency.

In `showEvent` you use the functor-based overload, but `hideEvent` uses the string-based one, which is less type-safe and more fragile during refactors. Please update `hideEvent` to the functor form as well, e.g. `QMetaObject::invokeMethod(this, [this]{ updateSize(); }, Qt::QueuedConnection);`.

```suggestion
        QWidget::hideEvent(event);
        m_minHeight = -1;
        // 隐藏时更新尺寸为折叠状态,确保下次显示时初始尺寸正确
        QMetaObject::invokeMethod(this, [this]() {
            updateSize();
        }, Qt::QueuedConnection);
    }
```
</issue_to_address>

### Comment 2
<location> `dock-network-plugin/dockcontentwidget.h:95` </location>
<code_context>
         return QWidget::eventFilter(watch, event);
     }

+    void showEvent(QShowEvent *event) override
+    {
+        updateSize();
</code_context>

<issue_to_address>
**issue (complexity):** Consider extracting the deferred sizing behavior into a shared helper to centralize logic and avoid string-based invokeMethod usage while preserving current show/hide behavior.

You can reduce the new complexity by centralizing the deferred sizing logic and avoiding the string-based `invokeMethod` while keeping behavior (immediate + deferred updates, min-height reset, resize) intact.

### 1. Centralize deferred sizing

Extract the queued sizing logic to a small helper, used from both `showEvent` and `hideEvent`. This removes duplication and makes the async behavior explicit:

```c++
private:
    bool m_deferredUpdateScheduled = false;

    void scheduleDeferredUpdateSize(bool doResize)
    {
        if (m_deferredUpdateScheduled)
            return;

        m_deferredUpdateScheduled = true;
        QMetaObject::invokeMethod(this, [this, doResize]() {
            m_deferredUpdateScheduled = false;
            updateSize();
            if (doResize)
                resize(size());
        }, Qt::QueuedConnection);
    }
```

### 2. Simplify `showEvent` and `hideEvent` with the helper

Reuse the helper so the control flow is easy to follow and you no longer need the string-based overload:

```c++
void showEvent(QShowEvent *event) override
{
    updateSize();                    // keep immediate update
    QWidget::showEvent(event);
    scheduleDeferredUpdateSize(true); // deferred update + resize
}

void hideEvent(QHideEvent *event) override
{
    QWidget::hideEvent(event);
    m_minHeight = -1;
    // 隐藏时更新尺寸为折叠状态,确保下次显示时初始尺寸正确
    scheduleDeferredUpdateSize(false); // deferred update only
}
```

This keeps all current behavior (immediate sizing on show, deferred re-sizes, min-height reset on hide) but removes duplicated lambdas, avoids string-based `invokeMethod`, and makes the deferred sizing semantics clear and centralized.
</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.

Comment on lines +107 to +111
QWidget::hideEvent(event);
m_minHeight = -1;
// 隐藏时更新尺寸为折叠状态,确保下次显示时初始尺寸正确
QMetaObject::invokeMethod(this, "updateSize", Qt::QueuedConnection);
}
Copy link

Choose a reason for hiding this comment

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

suggestion: Mixed styles of QMetaObject::invokeMethod reduce type safety and consistency.

In showEvent you use the functor-based overload, but hideEvent uses the string-based one, which is less type-safe and more fragile during refactors. Please update hideEvent to the functor form as well, e.g. QMetaObject::invokeMethod(this, [this]{ updateSize(); }, Qt::QueuedConnection);.

Suggested change
QWidget::hideEvent(event);
m_minHeight = -1;
// 隐藏时更新尺寸为折叠状态,确保下次显示时初始尺寸正确
QMetaObject::invokeMethod(this, "updateSize", Qt::QueuedConnection);
}
QWidget::hideEvent(event);
m_minHeight = -1;
// 隐藏时更新尺寸为折叠状态,确保下次显示时初始尺寸正确
QMetaObject::invokeMethod(this, [this]() {
updateSize();
}, Qt::QueuedConnection);
}

return QWidget::eventFilter(watch, event);
}

void showEvent(QShowEvent *event) override
Copy link

Choose a reason for hiding this comment

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

issue (complexity): Consider extracting the deferred sizing behavior into a shared helper to centralize logic and avoid string-based invokeMethod usage while preserving current show/hide behavior.

You can reduce the new complexity by centralizing the deferred sizing logic and avoiding the string-based invokeMethod while keeping behavior (immediate + deferred updates, min-height reset, resize) intact.

1. Centralize deferred sizing

Extract the queued sizing logic to a small helper, used from both showEvent and hideEvent. This removes duplication and makes the async behavior explicit:

private:
    bool m_deferredUpdateScheduled = false;

    void scheduleDeferredUpdateSize(bool doResize)
    {
        if (m_deferredUpdateScheduled)
            return;

        m_deferredUpdateScheduled = true;
        QMetaObject::invokeMethod(this, [this, doResize]() {
            m_deferredUpdateScheduled = false;
            updateSize();
            if (doResize)
                resize(size());
        }, Qt::QueuedConnection);
    }

2. Simplify showEvent and hideEvent with the helper

Reuse the helper so the control flow is easy to follow and you no longer need the string-based overload:

void showEvent(QShowEvent *event) override
{
    updateSize();                    // keep immediate update
    QWidget::showEvent(event);
    scheduleDeferredUpdateSize(true); // deferred update + resize
}

void hideEvent(QHideEvent *event) override
{
    QWidget::hideEvent(event);
    m_minHeight = -1;
    // 隐藏时更新尺寸为折叠状态,确保下次显示时初始尺寸正确
    scheduleDeferredUpdateSize(false); // deferred update only
}

This keeps all current behavior (immediate sizing on show, deferred re-sizes, min-height reset on hide) but removes duplicated lambdas, avoids string-based invokeMethod, and makes the deferred sizing semantics clear and centralized.

@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: caixr23, pengfeixx

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

Details 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

@pengfeixx
Copy link
Contributor Author

/forcemerge

@deepin-bot
Copy link
Contributor

deepin-bot bot commented Jan 14, 2026

This pr force merged! (status: unstable)

@deepin-bot deepin-bot bot merged commit a975448 into linuxdeepin:master Jan 14, 2026
16 of 18 checks passed
@pengfeixx pengfeixx deleted the fix-311381 branch January 14, 2026 01:24
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.

3 participants