Skip to content

fix: resolve tray submenu display position issue at screen top-left#1567

Merged
18202781743 merged 1 commit intolinuxdeepin:masterfrom
18202781743:master
Apr 23, 2026
Merged

fix: resolve tray submenu display position issue at screen top-left#1567
18202781743 merged 1 commit intolinuxdeepin:masterfrom
18202781743:master

Conversation

@18202781743
Copy link
Copy Markdown
Contributor

@18202781743 18202781743 commented Apr 23, 2026

  1. Fix incorrect property usage in submenu geometry calculation - use
    requestedWidth/requestedHeight instead of width/height
  2. Ensure submenu dimensions are properly set from requested values
    before geometry adjustment
  3. Use setWindowGeometry() to properly position and size the submenu
    window with calculated coordinates

Log: Fixed tray tray submenu appearing at screen top-left corner

Influence:

  1. Test submenu display position with various application tray icons
  2. Verify submenu positioning when screen resolution changes
  3. Test submenu behavior with different popup sizes
  4. Confirm submenu stays within visible screen boundaries
  5. Verify multiple submenu cascade functionality

fix: 修复托盘子菜单显示在屏幕左上角的问题

  1. 修复子菜单几何计算中使用错误的属性 - 改用requestedWidth/
    requestedHeight替代width/height
  2. 确保在几何调整前使用请求尺寸正确设置子菜单尺寸
  3. 使用setWindowGeometry()通过计算坐标正确定位和设置子菜单窗口尺寸

Log: 修复托盘子菜单显示在屏幕左上角的问题

Influence:

  1. 测试不同应用托盘图标点击后的子菜单位置
  2. 验证屏幕分辨率变化时子菜单位置是否正确
  3. 测试不同大小弹出菜单的显示行为
  4. 确认子菜单始终显示在屏幕可视区域内
  5. 验证多层子菜单的级联显示功能

Summary by Sourcery

Bug Fixes:

  • Correct tray submenu geometry calculations by using requested dimensions and applying them via window geometry APIs to keep the submenu within visible screen area.

1. Fix incorrect property usage in submenu geometry calculation - use
`requestedWidth`/`requestedHeight` instead of `width`/`height`
2. Ensure submenu dimensions are properly set from requested values
before geometry adjustment
3. Use `setWindowGeometry()` to properly position and size the submenu
window with calculated coordinates

Log: Fixed tray tray submenu appearing at screen top-left corner

Influence:
1. Test submenu display position with various application tray icons
2. Verify submenu positioning when screen resolution changes
3. Test submenu behavior with different popup sizes
4. Confirm submenu stays within visible screen boundaries
5. Verify multiple submenu cascade functionality

fix: 修复托盘子菜单显示在屏幕左上角的问题

1. 修复子菜单几何计算中使用错误的属性 - 改用`requestedWidth`/
`requestedHeight`替代`width`/`height`
2. 确保在几何调整前使用请求尺寸正确设置子菜单尺寸
3. 使用`setWindowGeometry()`通过计算坐标正确定位和设置子菜单窗口尺寸

Log: 修复托盘子菜单显示在屏幕左上角的问题

Influence:
1. 测试不同应用托盘图标点击后的子菜单位置
2. 验证屏幕分辨率变化时子菜单位置是否正确
3. 测试不同大小弹出菜单的显示行为
4. 确认子菜单始终显示在屏幕可视区域内
5. 验证多层子菜单的级联显示功能
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Apr 23, 2026

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Adjusts tray submenu geometry calculation to use requested dimensions and applies positioning via setWindowGeometry to prevent the submenu from appearing at the screen’s top-left corner, while updating the file copyright header years.

Sequence diagram for updated tray submenu geometry and positioning

sequenceDiagram
    actor User
    participant TrayIcon
    participant SurfaceSubPopup
    participant menuWindow
    participant Screen

    User ->> TrayIcon: click
    TrayIcon ->> SurfaceSubPopup: openSubmenu
    SurfaceSubPopup ->> menuWindow: updateGeometryer()

    alt requested size too small
        SurfaceSubPopup ->> menuWindow: read requestedWidth, requestedHeight
        SurfaceSubPopup ->> menuWindow: set width = requestedWidth
        SurfaceSubPopup ->> menuWindow: set height = requestedHeight
        SurfaceSubPopup -->> menuWindow: return
    else normal geometry calculation
        SurfaceSubPopup ->> menuWindow: read requestedWidth, requestedHeight
        SurfaceSubPopup ->> Screen: read virtualX, virtualY, width, height
        SurfaceSubPopup ->> SurfaceSubPopup: compute bounding rect with margins
        SurfaceSubPopup ->> SurfaceSubPopup: compute pos from xOffset, yOffset
        SurfaceSubPopup ->> SurfaceSubPopup: newX = selectValue(pos.x, bounding.left, bounding.right - requestedWidth)
        SurfaceSubPopup ->> SurfaceSubPopup: newY = selectValue(pos.y, bounding.top, bounding.bottom - requestedHeight)
        SurfaceSubPopup ->> menuWindow: setWindowGeometry(newX, newY, requestedWidth, requestedHeight)
    end

    menuWindow -->> User: submenu displayed near tray icon within screen bounds
Loading

Flow diagram for updated submenu geometry calculation

flowchart TD
    A[updateGeometryer called] --> B{requestedWidth <= 10 or requestedHeight <= 10}
    B -->|yes| C[Set menuWindow.width = requestedWidth]
    C --> D[Set menuWindow.height = requestedHeight]
    D --> E[Return]
    B -->|no| F[Read screen virtualX, virtualY, width, height]
    F --> G[Compute bounding rect with margins]
    G --> H[Compute pos from xOffset and yOffset]
    H --> I[Compute newX using selectValue with requestedWidth]
    I --> J[Compute newY using selectValue with requestedHeight]
    J --> K["Call menuWindow.setWindowGeometry(newX, newY, requestedWidth, requestedHeight)"]
    K --> L[Submenu window positioned within screen bounds]
Loading

File-Level Changes

Change Details Files
Correct submenu geometry calculation to use requested dimensions and apply them via window geometry API so the submenu is positioned within screen bounds instead of defaulting to top-left.
  • Replace width/height checks with requestedWidth/requestedHeight when validating submenu size before geometry updates.
  • Ensure menuWindow.width and menuWindow.height are set from requestedWidth/requestedHeight when the requested size is small or unset and bail out early.
  • Use requestedWidth/requestedHeight instead of current width/height when computing constrained x/y within the screen bounding rectangle.
  • Call menuWindow.setWindowGeometry(newX, newY, menuWindow.requestedWidth, menuWindow.requestedHeight) instead of assigning x/y directly to apply both position and size atomically.
  • Update SPDX copyright header years to 2024 - 2026.
panels/dock/tray/SurfaceSubPopup.qml

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
Copy Markdown

deepin pr auto review

这段代码的修改主要涉及窗口几何计算和尺寸更新逻辑。以下是对该diff的详细审查和改进建议:

1. 语法逻辑审查

修改分析:

  • 将版权年份从2024扩展到2026,这是合理的维护性修改。
  • menuWindow.width/height改为menuWindow.requestedWidth/requestedHeight,这是更准确的属性引用。
  • 新增了显式设置窗口尺寸的代码行。
  • 改用setWindowGeometry方法统一设置窗口位置和大小。

潜在问题:

  • if条件判断后直接设置widthheight,但缺少对requestedWidth/requestedHeight有效性的二次验证。
  • selectValue函数的实现未在diff中显示,需要确保它能正确处理边界情况。

2. 代码质量改进建议

  1. 添加参数验证:
if (menuWindow.requestedWidth <= 10 || menuWindow.requestedHeight <= 10) {
    if (menuWindow.requestedWidth > 0 && menuWindow.requestedHeight > 0) {
        menuWindow.width = menuWindow.requestedWidth
        menuWindow.height = menuWindow.requestedHeight
    }
    return
}
  1. 提取边界计算逻辑:
function calculateBounds() {
    let margins = 10
    return Qt.rect(
        menuWindow.screen.virtualX + margins,
        menuWindow.screen.virtualY + margins,
        menuWindow.screen.width - margins * 2,
        menuWindow.screen.height - margins * 2
    )
}
  1. 使用常量定义魔数:
readonly property int minimumWindowSize: 10
readonly property int screenMargins: 10

3. 代码性能优化建议

  1. 缓存计算结果:
let requestedWidth = menuWindow.requestedWidth
let requestedHeight = menuWindow.requestedHeight
  1. 减少属性访问:
let screen = menuWindow.screen
let bounding = Qt.rect(
    screen.virtualX + screenMargins,
    screen.virtualY + screenMargins,
    screen.width - screenMargins * 2,
    screen.height - screenMargins * 2
)

4. 代码安全改进建议

  1. 添加空值检查:
if (!menuWindow || !menuWindow.screen) {
    console.warn("Invalid menuWindow or screen reference")
    return
}
  1. 边界值保护:
let safeWidth = Math.max(minimumWindowSize, requestedWidth)
let safeHeight = Math.max(minimumWindowSize, requestedHeight)
  1. 添加错误处理:
try {
    menuWindow.setWindowGeometry(newX, newY, safeWidth, safeHeight)
} catch (e) {
    console.error("Failed to set window geometry:", e)
}

综合改进后的代码示例:

updateGeometryer : function () {
    // 参数验证
    if (!menuWindow || !menuWindow.screen) {
        console.warn("Invalid menuWindow or screen reference")
        return
    }

    // 缓存请求尺寸
    let requestedWidth = menuWindow.requestedWidth
    let requestedHeight = menuWindow.requestedHeight

    // 最小尺寸检查
    if (requestedWidth <= minimumWindowSize || requestedHeight <= minimumWindowSize) {
        if (requestedWidth > 0 && requestedHeight > 0) {
            menuWindow.width = requestedWidth
            menuWindow.height = requestedHeight
        }
        return
    }

    // 计算安全边界
    let screen = menuWindow.screen
    let bounding = Qt.rect(
        screen.virtualX + screenMargins,
        screen.virtualY + screenMargins,
        screen.width - screenMargins * 2,
        screen.height - screenMargins * 2
    )

    // 计算新位置
    let pos = Qt.point(xOffset, yOffset)
    let newX = selectValue(pos.x, bounding.left, bounding.right - requestedWidth)
    let newY = selectValue(pos.y, bounding.top, bounding.bottom - requestedHeight)

    // 安全设置窗口几何
    try {
        menuWindow.setWindowGeometry(newX, newY, requestedWidth, requestedHeight)
    } catch (e) {
        console.error("Failed to set window geometry:", e)
    }
}

总结

原修改方向是正确的,但可以进一步改进:

  1. 增强输入验证和错误处理
  2. 提高代码可读性(使用常量、提取函数)
  3. 优化性能(缓存属性访问)
  4. 增强健壮性(边界保护)

这些改进将使代码更安全、更易维护,同时保持原有功能不变。

Copy link
Copy Markdown

@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 left some high level feedback:

  • In updateGeometryer, the early-return branch for small requestedWidth/requestedHeight now sets menuWindow.width/height but skips setWindowGeometry(), which means position is never updated in that case; consider routing all paths through a single geometry-setting call to avoid inconsistent behavior for small menus.
  • You now consistently use requestedWidth/requestedHeight for bounds clamping but still rely on screen.width/height; if the requested size exceeds the available bounding rect, selectValue can return values that place part of the menu off-screen, so you may want to explicitly clamp requestedWidth/requestedHeight against the bounding rect before calling setWindowGeometry().
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `updateGeometryer`, the early-return branch for small `requestedWidth`/`requestedHeight` now sets `menuWindow.width/height` but skips `setWindowGeometry()`, which means position is never updated in that case; consider routing all paths through a single geometry-setting call to avoid inconsistent behavior for small menus.
- You now consistently use `requestedWidth`/`requestedHeight` for bounds clamping but still rely on `screen.width/height`; if the requested size exceeds the available bounding rect, `selectValue` can return values that place part of the menu off-screen, so you may want to explicitly clamp `requestedWidth`/`requestedHeight` against the bounding rect before calling `setWindowGeometry()`.

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.

@deepin-ci-robot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: 18202781743, yixinshark

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

@18202781743 18202781743 merged commit e9c3971 into linuxdeepin:master Apr 23, 2026
11 of 12 checks passed
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