Skip to content

feat: improve tray menu and notification panel interaction#1513

Open
qxp930712 wants to merge 1 commit intolinuxdeepin:masterfrom
qxp930712:master
Open

feat: improve tray menu and notification panel interaction#1513
qxp930712 wants to merge 1 commit intolinuxdeepin:masterfrom
qxp930712:master

Conversation

@qxp930712
Copy link

@qxp930712 qxp930712 commented Mar 19, 2026

Added tray menu state tracking and automatic panel management to prevent conflicts between tray menus and notification panel. The changes include:

  1. Added autoCloseOnDeactivate property to PanelMenu for conditional auto-close behavior
  2. Implemented tray menu state tracking in MenuHelper with hasTrayMenuOpen property
  3. Added delayed menu opening with timers to handle panel transitions smoothly
  4. Modified notification center panel to respect tray menu state and prevent overlapping
  5. Added automatic notification panel closing when opening app item menus or tray menus

Log: Improved tray menu behavior and fixed conflicts with notification panel

Influence:

  1. Test opening tray menus while notification panel is visible - should auto-close notification panel
  2. Verify notification panel cannot be opened when tray menu is active
  3. Test app item menu opening behavior with notification panel
  4. Check tray menu auto-close behavior when losing focus
  5. Verify all menu types properly track their open/close state
  6. Test timing of menu openings and panel transitions
  7. Verify notification panel visibility respects tray menu state

PMS: BUG--284867

Summary by Sourcery

Coordinate tray menus with the notification center panel to avoid overlapping and conflicting behaviors.

New Features:

  • Track whether any tray menu is open via MenuHelper and expose tray menu state to the notification center panel.
  • Add configurable auto-close-on-deactivate behavior to panel menus to support controlled focus handling.

Bug Fixes:

  • Prevent the notification panel from opening or remaining visible while a tray menu is active, eliminating overlapping UI states.
  • Ensure opening tray or app item menus automatically closes the notification panel to avoid conflicts.

Enhancements:

  • Introduce delayed tray menu opening and temporary auto-close suppression to allow smoother transitions between tray menus and the notification panel.
  • Reset tray menu state consistently when tray menus are hidden or lose focus.

Added tray menu state tracking and automatic panel management to
prevent conflicts between tray menus and notification panel. The changes
include:
1. Added autoCloseOnDeactivate property to PanelMenu for conditional
auto-close behavior
2. Implemented tray menu state tracking in MenuHelper with
hasTrayMenuOpen property
3. Added delayed menu opening with timers to handle panel transitions
smoothly
4. Modified notification center panel to respect tray menu state and
prevent overlapping
5. Added automatic notification panel closing when opening app item
menus or tray menus

Log: Improved tray menu behavior and fixed conflicts with notification
panel

Influence:
1. Test opening tray menus while notification panel is visible - should
auto-close notification panel
2. Verify notification panel cannot be opened when tray menu is active
3. Test app item menu opening behavior with notification panel
4. Check tray menu auto-close behavior when losing focus
5. Verify all menu types properly track their open/close state
6. Test timing of menu openings and panel transitions
7. Verify notification panel visibility respects tray menu state

PMS: BUG--284867
@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: qxp930712

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

@sourcery-ai
Copy link

sourcery-ai bot commented Mar 19, 2026

Reviewer's Guide

Implements coordinated state tracking between tray menus and the notification center to avoid overlapping UIs, by delaying tray menu opening, conditionally auto-closing menus on deactivation, and blocking or closing the notification panel when tray menus or app item menus are active.

Sequence diagram for opening a tray menu while notification panel is visible

sequenceDiagram
    actor User
    participant TrayIcon as TrayIcon_QML
    participant SurfacePopup as SurfacePopup_QML
    participant TrayMenu as PanelMenu_tray
    participant MenuHelper as MenuHelper_QML
    participant NotifyPanel as NotificationCenterPanel
    participant NotifyWindow as notification_main_qml

    User->>TrayIcon: click()
    TrayIcon->>SurfacePopup: onTrayActivated()
    SurfacePopup->>NotifyPanel: DS.applet(notificationcenter)
    alt notification panel visible
        SurfacePopup->>NotifyPanel: close()
        NotifyPanel->>NotifyWindow: set Panel.visible false
        NotifyPanel->>NotifyWindow: visible = Panel.visible && !Panel.hasTrayMenuOpen
    end

    SurfacePopup->>TrayMenu: setup bindings(menuX, menuY)
    SurfacePopup->>TrayMenu: set autoCloseOnDeactivate false
    SurfacePopup->>MenuHelper: set hasTrayMenuOpen true
    SurfacePopup->>NotifyPanel: setHasTrayMenuOpen(true)

    SurfacePopup->>SurfacePopup: pendingTrayMenu = TrayMenu
    SurfacePopup->>SurfacePopup: trayMenuOpenTimer.restart()
    SurfacePopup->>SurfacePopup: restoreAutoCloseTimer.restart()

    SurfacePopup-->>TrayMenu: trayMenuOpenTimer.onTriggered
    TrayMenu->>TrayMenu: open()

    SurfacePopup-->>TrayMenu: restoreAutoCloseTimer.onTriggered
    TrayMenu->>TrayMenu: autoCloseOnDeactivate = true

    TrayMenu-->>MenuHelper: aboutToHide()
    MenuHelper->>MenuHelper: activeMenu = null
    MenuHelper->>MenuHelper: hasTrayMenuOpen = false
    MenuHelper-->>NotifyPanel: setHasTrayMenuOpen(false)
    NotifyPanel->>NotifyWindow: visible = Panel.visible && !Panel.hasTrayMenuOpen
Loading

Sequence diagram for blocking notification panel when tray menu is open

sequenceDiagram
    actor User
    participant PanelToggle as PanelToggle_UI
    participant NotifyPanel as NotificationCenterPanel
    participant NotifyWindow as notification_main_qml
    participant MenuHelper as MenuHelper_QML

    Note over MenuHelper,NotifyPanel: Precondition: MenuHelper.hasTrayMenuOpen = true

    User->>PanelToggle: click()
    PanelToggle->>NotifyPanel: setVisible(true)

    alt tray menu is open
        NotifyPanel->>NotifyPanel: if m_hasTrayMenuOpen is true
        NotifyPanel-->>PanelToggle: return without changing m_visible
        NotifyPanel->>NotifyWindow: visible remains Panel.visible && !Panel.hasTrayMenuOpen
    else no tray menu open
        NotifyPanel->>NotifyPanel: m_visible = true
        NotifyPanel->>NotifyWindow: visible = Panel.visible && !Panel.hasTrayMenuOpen
    end
Loading

Updated class diagram for menu and notification panel coordination

classDiagram
    class PanelMenu {
        +bool autoCloseOnDeactivate
        +string windowTitle
        +int width
        +int height
        +QtObject menuWindow
        +QtObject control
        +onActiveChanged()
    }

    class MenuHelper {
        +QtObject activeMenu
        +bool hasTrayMenuOpen
        +menuClosed()
        +onAboutToHide()
    }

    class NotificationCenterPanel {
        +bool m_visible
        +bool m_hasTrayMenuOpen
        +NotificationCenterProxy* m_proxy
        +NotificationCenterPanel(QObject* parent)
        +~NotificationCenterPanel()
        +bool visible() const
        +void setVisible(bool newVisible)
        +void close()
        +bool hasTrayMenuOpen() const
        +void setHasTrayMenuOpen(bool hasOpen)
        +void setBubblePanelEnabled(bool enabled)
        +visibleChanged()
        +hasTrayMenuOpenChanged()
    }

    class SurfacePopup_QML {
        +var pendingTrayMenu
        +Timer trayMenuOpenTimer
        +Timer restoreAutoCloseTimer
        +onMenuVisibleChanged()
        +onActiveChanged()
        +openTrayMenu()
    }

    class TrayItemSurfacePopup_QML {
        +bool popupVisible
        +var pendingTrayMenu
        +Timer trayMenuOpenTimer
        +Timer restoreAutoCloseTimer
        +onMenuVisibleChanged()
        +onActiveChanged()
        +openTrayItemMenu()
    }

    class AppItem_QML {
        +requestAppItemMenu()
    }

    class NotificationMainQML {
        +bool visible
        +int contentPadding
    }

    SurfacePopup_QML --> PanelMenu : uses as tray menu
    TrayItemSurfacePopup_QML --> PanelMenu : uses as tray menu
    SurfacePopup_QML --> MenuHelper : updates hasTrayMenuOpen
    TrayItemSurfacePopup_QML --> MenuHelper : updates hasTrayMenuOpen
    SurfacePopup_QML --> NotificationCenterPanel : setHasTrayMenuOpen()
    TrayItemSurfacePopup_QML --> NotificationCenterPanel : setHasTrayMenuOpen()
    NotificationCenterPanel --> NotificationMainQML : exposes Panel.visible
    NotificationMainQML --> NotificationCenterPanel : depends on hasTrayMenuOpen
    AppItem_QML --> NotificationCenterPanel : close() before menu
    MenuHelper --> PanelMenu : manages activeMenu
Loading

File-Level Changes

Change Details Files
Add conditional auto-close behavior to panel menus to allow temporary suppression while managing tray/tray-item menus.
  • Introduce autoCloseOnDeactivate property on PanelMenu to control whether loss of window activation triggers menu close
  • Guard the menuWindow.active-based close logic with the autoCloseOnDeactivate flag so some menus can stay open during panel transitions
frame/qml/PanelMenu.qml
Track tray menu open state globally and reset it consistently when menus close.
  • Add hasTrayMenuOpen boolean to MenuHelper and clear it when the active menu is about to hide
  • Use menuVisible and menuWindow.active signals in tray-related QML to reset MenuHelper.hasTrayMenuOpen and notification panel state when tray menus close or lose focus
panels/dock/MenuHelper.qml
panels/dock/tray/SurfacePopup.qml
panels/dock/tray/TrayItemSurfacePopup.qml
Delay tray menu opening to avoid conflicts with notification center transitions and manage notification center state when tray menus are opened or closed.
  • Add pendingTrayMenu plus trayMenuOpenTimer and restoreAutoCloseTimer in tray popup QML to open menus after a short delay and then re-enable autoCloseOnDeactivate
  • When opening tray and tray item menus, close the notification center if visible, set MenuHelper.hasTrayMenuOpen and notifyPanel.hasTrayMenuOpen, and use timers instead of immediate open() calls
panels/dock/tray/SurfacePopup.qml
panels/dock/tray/TrayItemSurfacePopup.qml
frame/qml/PanelMenu.qml
Make the notification center panel aware of tray menu state and prevent it from showing while tray menus are active.
  • Add hasTrayMenuOpen property and signal to NotificationCenterPanel, backed by m_hasTrayMenuOpen
  • Block setVisible(true) when a tray menu is open, logging the event for debugging
  • Update QML main window visibility binding to also depend on !Panel.hasTrayMenuOpen
panels/notification/center/notificationcenterpanel.h
panels/notification/center/notificationcenterpanel.cpp
panels/notification/center/package/main.qml
Ensure opening app item context menus closes the notification panel to avoid UI overlap.
  • On AppItem context menu request, close the notification center panel if it is currently visible before opening the menu via MenuHelper
panels/dock/taskmanager/package/AppItem.qml
Minor refactors and metadata updates for consistency.
  • Update SPDX copyright year ranges in modified files
  • Tidy include order and namespace brace style in notificationcenterpanel.cpp and .h
panels/dock/tray/SurfacePopup.qml
panels/dock/tray/TrayItemSurfacePopup.qml
panels/notification/center/notificationcenterpanel.cpp
panels/notification/center/notificationcenterpanel.h
panels/dock/MenuHelper.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

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:

  • The restoreAutoCloseTimer in both SurfacePopup.qml and TrayItemSurfacePopup.qml checks pendingTrayMenu, but that property is set to null in trayMenuOpenTimer before restoreAutoCloseTimer fires, so autoCloseOnDeactivate will never be restored; consider storing the menu reference separately or restoring autoCloseOnDeactivate immediately after opening instead of relying on pendingTrayMenu.
  • The tray-menu state handling (timers, pendingTrayMenu, MenuHelper.hasTrayMenuOpen, notification panel updates) is duplicated between SurfacePopup.qml and TrayItemSurfacePopup.qml; consider extracting the shared behavior into a reusable helper or component to keep the logic consistent and easier to maintain.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `restoreAutoCloseTimer` in both `SurfacePopup.qml` and `TrayItemSurfacePopup.qml` checks `pendingTrayMenu`, but that property is set to `null` in `trayMenuOpenTimer` before `restoreAutoCloseTimer` fires, so `autoCloseOnDeactivate` will never be restored; consider storing the menu reference separately or restoring `autoCloseOnDeactivate` immediately after opening instead of relying on `pendingTrayMenu`.
- The tray-menu state handling (timers, `pendingTrayMenu`, `MenuHelper.hasTrayMenuOpen`, notification panel updates) is duplicated between `SurfacePopup.qml` and `TrayItemSurfacePopup.qml`; consider extracting the shared behavior into a reusable helper or component to keep the logic consistent and easier to maintain.

## Individual Comments

### Comment 1
<location path="panels/dock/tray/SurfacePopup.qml" line_range="27-25" />
<code_context>
+        onTriggered: {
+            if (pendingTrayMenu) {
+                pendingTrayMenu.open()
+                pendingTrayMenu = null
+            }
+        }
+    }
+    Timer {
+        id: restoreAutoCloseTimer
+        interval: 200
+        repeat: false
+        onTriggered: {
+            if (pendingTrayMenu) {
+                pendingTrayMenu.autoCloseOnDeactivate = true
+            }
</code_context>
<issue_to_address>
**issue (bug_risk):** autoCloseOnDeactivate is never restored because pendingTrayMenu is nulled before the restore timer runs

Because `pendingTrayMenu` is set to `null` immediately after `open()`, `restoreAutoCloseTimer`’s `if (pendingTrayMenu)` check always fails and `autoCloseOnDeactivate` is never reset for that menu. As a result, later `menuWindow.active` changes won’t auto-close the tray menu. You’ll need to either keep a separate reference for the restore timer, delay nulling `pendingTrayMenu` until after the restore runs, or restore `autoCloseOnDeactivate` in a way that doesn’t depend on `pendingTrayMenu` being non-null.
</issue_to_address>

### Comment 2
<location path="panels/dock/tray/TrayItemSurfacePopup.qml" line_range="31-29" />
<code_context>
+        onTriggered: {
+            if (pendingTrayMenu) {
+                pendingTrayMenu.open()
+                pendingTrayMenu = null
+            }
+        }
+    }
+    Timer {
+        id: restoreAutoCloseTimer
+        interval: 200
+        repeat: false
+        onTriggered: {
+            if (pendingTrayMenu) {
+                pendingTrayMenu.autoCloseOnDeactivate = true
+            }
</code_context>
<issue_to_address>
**issue (bug_risk):** Same autoCloseOnDeactivate restoration issue as in SurfacePopup.qml

Here too, `trayMenuOpenTimer` clears `pendingTrayMenu` after opening, so when `restoreAutoCloseTimer` fires, `pendingTrayMenu` is null and `autoCloseOnDeactivate` is never restored. This leaves `popupMenu.autoCloseOnDeactivate` stuck at `false`, so deactivation won’t close the menu. Please adjust the logic (as in `SurfacePopup.qml`) so the flag is always restored after the first open.
</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.

interval: 150
repeat: false
onTriggered: {
if (pendingTrayMenu) {
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): autoCloseOnDeactivate is never restored because pendingTrayMenu is nulled before the restore timer runs

Because pendingTrayMenu is set to null immediately after open(), restoreAutoCloseTimer’s if (pendingTrayMenu) check always fails and autoCloseOnDeactivate is never reset for that menu. As a result, later menuWindow.active changes won’t auto-close the tray menu. You’ll need to either keep a separate reference for the restore timer, delay nulling pendingTrayMenu until after the restore runs, or restore autoCloseOnDeactivate in a way that doesn’t depend on pendingTrayMenu being non-null.

interval: 150
repeat: false
onTriggered: {
if (pendingTrayMenu) {
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): Same autoCloseOnDeactivate restoration issue as in SurfacePopup.qml

Here too, trayMenuOpenTimer clears pendingTrayMenu after opening, so when restoreAutoCloseTimer fires, pendingTrayMenu is null and autoCloseOnDeactivate is never restored. This leaves popupMenu.autoCloseOnDeactivate stuck at false, so deactivation won’t close the menu. Please adjust the logic (as in SurfacePopup.qml) so the flag is always restored after the first open.

@deepin-ci-robot
Copy link

deepin pr auto review

这段代码主要实现了在托盘菜单打开时自动关闭通知中心面板,并防止通知中心在托盘菜单打开时显示。以下是对代码的详细审查和改进建议:

1. 代码逻辑审查

优点:

  • 实现了托盘菜单和通知中心面板的互斥显示逻辑
  • 使用了延迟机制(Timer)来处理菜单打开的时序问题
  • 添加了状态标志(hasTrayMenuOpen)来跟踪托盘菜单状态

潜在问题:

  1. 时序问题:在SurfacePopup.qmlTrayItemSurfacePopup.qml中,使用两个Timer(150ms和200ms)来处理菜单打开和自动关闭恢复的时序。这种硬编码的延迟可能在某些情况下不够可靠,特别是在系统负载较高时。

  2. 状态同步hasTrayMenuOpen状态在多个地方被设置和重置,可能导致状态不一致。例如:

    • SurfacePopup.qml的两个Connections中都重置了hasTrayMenuOpen
    • TrayItemSurfacePopup.qml中也有类似的重置逻辑
  3. 重复代码SurfacePopup.qmlTrayItemSurfacePopup.qml中有大量重复的代码块,包括Timer定义、Connections逻辑等。

2. 代码质量改进建议

  1. 减少重复代码

    • SurfacePopup.qmlTrayItemSurfacePopup.qml中的公共逻辑提取到一个基础组件或混入(mixin)中
    • 创建一个可重用的组件来处理托盘菜单的打开/关闭逻辑
  2. 状态管理改进

    • 考虑使用单一状态管理器来集中管理hasTrayMenuOpen状态
    • 确保状态变更的原子性和一致性
  3. 代码可读性

    • 为复杂的逻辑添加更多注释
    • 考虑将长函数拆分为更小的、功能单一的函数

3. 代码性能改进建议

  1. 减少不必要的属性查找

    • DS.applet("org.deepin.ds.notificationcenter")被多次调用,可以缓存结果
    • 例如:
    property var notifyPanel: DS.applet("org.deepin.ds.notificationcenter")
  2. 优化Timer使用

    • 考虑使用更可靠的事件驱动机制替代固定延迟
    • 如果必须使用Timer,考虑根据系统性能动态调整间隔

4. 代码安全改进建议

  1. 空指针检查

    • notificationcenterpanel.cpp中,applet指针在使用前应该进行空指针检查
    • 例如:
    if (!applet) {
        qWarning(notifyLog) << "Applet is null";
        return;
    }
    QMetaObject::invokeMethod(applet, "setEnabled", Qt::DirectConnection, Q_ARG(bool, enabled));
  2. 状态验证

    • 在设置hasTrayMenuOpen状态时,添加更多验证逻辑
    • 确保状态变更符合预期
  3. 错误处理

    • notificationcenterpanel.cpp中,DBUS调用应该添加错误处理
    • 例如:
    QDBusReply<void> reply = interface.call("Method");
    if (!reply.isValid()) {
        qWarning(notifyLog) << "DBus call failed:" << reply.error().message();
    }

5. 具体代码改进示例

改进SurfacePopup.qml中的重复代码

// 创建一个可重用的组件
Component {
    id: trayMenuHandler
    Timer {
        id: trayMenuOpenTimer
        interval: 150
        repeat: false
        onTriggered: {
            if (pendingTrayMenu) {
                pendingTrayMenu.open()
                pendingTrayMenu = null
            }
        }
    }
    
    Timer {
        id: restoreAutoCloseTimer
        interval: 200
        repeat: false
        onTriggered: {
            if (pendingTrayMenu) {
                pendingTrayMenu.autoCloseOnDeactivate = true
            }
        }
    }
    
    Connections {
        target: menu
        function onMenuVisibleChanged() {
            if (!menu.menuVisible) {
                MenuHelper.hasTrayMenuOpen = false
                updateNotifyPanelState(false)
            }
        }
    }
    
    Connections {
        target: menu.menuWindow
        function onActiveChanged() {
            if (menu.menuWindow && !menu.menuWindow.active && !menu.menuVisible) {
                MenuHelper.hasTrayMenuOpen = false
                updateNotifyPanelState(false)
            }
        }
    }
    
    function updateNotifyPanelState(isOpen) {
        let notifyPanel = DS.applet("org.deepin.ds.notificationcenter")
        if (notifyPanel) {
            notifyPanel.hasTrayMenuOpen = isOpen
        }
    }
}

改进notificationcenterpanel.cpp中的空指针检查

void NotificationCenterPanel::setBubblePanelEnabled(bool enabled)
{
    if (!applet) {
        qWarning(notifyLog) << "Applet is null, cannot set bubble panel enabled";
        return;
    }
    
    QMetaObject::invokeMethod(applet, "setEnabled", Qt::DirectConnection, Q_ARG(bool, enabled));
}

改进notificationcenterpanel.cpp中的状态验证

void NotificationCenterPanel::setHasTrayMenuOpen(bool hasOpen)
{
    if (m_hasTrayMenuOpen == hasOpen)
        return;
    
    // 添加状态变更的验证逻辑
    if (hasOpen && m_visible) {
        qWarning(notifyLog) << "Inconsistent state: tray menu opened while notification center is visible";
        setVisible(false);
    }
    
    m_hasTrayMenuOpen = hasOpen;
    emit hasTrayMenuOpenChanged();
}

6. 其他建议

  1. 日志记录

    • 在关键状态变更处添加更详细的日志记录,便于调试
    • 例如:
    console.log("Tray menu state changed:", hasOpen)
  2. 测试覆盖

    • 确保为新增的功能添加充分的单元测试和集成测试
    • 特别关注边界条件和异常情况
  3. 文档更新

    • 更新相关文档,说明新的行为和状态管理逻辑
    • 为新增的属性和方法添加详细的注释

这些改进将有助于提高代码的可维护性、可靠性和性能,同时减少潜在的错误和问题。

@18202781743 18202781743 requested a review from BLumia March 19, 2026 07:30
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