Skip to content

chore: update version to 1.2.5 - #734

Merged
re2zero merged 2 commits into
linuxdeepin:masterfrom
re2zero:version-1.2.5
Jun 4, 2026
Merged

chore: update version to 1.2.5#734
re2zero merged 2 commits into
linuxdeepin:masterfrom
re2zero:version-1.2.5

Conversation

@re2zero

@re2zero re2zero commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Summary

  • bump version to 1.2.5

Log : bump version to 1.2.5

re2zero added 2 commits June 4, 2026 20:43
… screens

When moving cursor from a low-resolution UOS screen to a high-resolution
Windows screen, the system could become completely unresponsive.

Root causes addressed:
- deskMouseMove used mouse_event 0-65535 normalization which can
  overflow (DWORD wrap) for negative or out-of-range coordinates,
  and is affected by DPI context after SetThreadDesktop
- mapToNeighbor could produce coordinates 1px beyond destination
  screen bounds when resolutions differ (e.g. kLeft path: x == dw)

Fixes:
- Replace mouse_event with SetCursorPos in deskMouseMove, keeping
  mouse_event as fallback for Vista/7 secure desktop
- Add coordinate clamp to virtual screen bounds in deskMouseMove
- Add coordinate clamp to destination screen bounds in mapToNeighbor
- bump version to 1.2.5

Log : bump version to 1.2.5

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Sorry @re2zero, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown

TAG Bot

TAG: 1.2.5
EXISTED: no
DISTRIBUTION: unstable

@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

你好!我是CodeGeeX。我仔细审查了你提供的Git Diff。这次修改的主要目的是修复在不同分辨率屏幕之间切换时鼠标冻结/越界的问题,核心策略是引入坐标钳位并优先使用 SetCursorPos 替代 mouse_event

整体来看,修改方向非常正确,有效解决了多显示器和跨分辨率场景下的坐标溢出问题。但在语法逻辑、代码性能和安全性方面,还有一些值得注意和改进的地方。

以下是详细的审查意见:

1. 语法与逻辑

问题 1.1:mouse_event 降级逻辑中的坐标系不一致
MSWindowsDesks::deskMouseMove 中,当 SetCursorPos 失败时,代码降级使用了 mouse_event。但是,降级逻辑中计算归一化坐标时,使用的是主显示器的分辨率(SM_CXSCREEN/SM_CYSCREEN),而传入的 xy 此时已经被钳位到了虚拟屏幕的坐标系(m_x, m_y 等)。
如果当前操作的屏幕不是主显示器,将虚拟屏幕坐标除以主屏幕分辨率,会导致鼠标飞到错误的位置。

问题 1.2:mouse_event 降级逻辑中的除零风险
如果 GetSystemMetrics(SM_CXSCREEN)SM_CYSCREEN 返回 0(虽然在正常桌面极少见,但在安全桌面或极端情况下可能发生),w - 1h - 1 将导致除零崩溃,或者引发浮点异常。

问题 1.3:mouse_event 归一化常量不精确
Windows API 文档指出,MOUSEEVENTF_ABSOLUTE 的归一化范围是 065535(包含),跨整个屏幕的映射应该是 65535.0f * x / w,而不是 65535.0f * x / (w - 1)。原代码的 (w - 1) 会导致最右侧/最底部的像素无法精确映射。

2. 代码性能

问题 2.1:getShape 的频繁调用开销
Server::mapToNeighbor 中,新增了 dst->getShape(dx, dy, dw, dh) 的调用。如果 getShape 是一个跨进程的 IPC 调用或需要获取系统状态的较重操作,在鼠标移动这种高频事件路径上,每次移动都调用一次可能会带来性能延迟。
建议:确认 getShape 的实现复杂度。如果较重,考虑在屏幕分辨率变更事件时缓存这些值,而不是在每次鼠标移动时实时拉取。

3. 代码安全

问题 3.1:整数溢出风险
MSWindowsDesks::deskMouseMove 的钳位逻辑中:
else if (x > m_x + m_w - 1)
如果 m_xm_w 都很大,m_x + m_w 可能会超过 SInt32(32位有符号整数)的最大值(2147483647),导致整数溢出变成负数,从而引发错误的钳位逻辑。
建议:使用更宽的类型进行运算,或者采用不依赖加法的边界检查。

4. 代码质量

问题 4.1:魔法数字
65535.0f 是一个魔法数字。虽然 Windows 开发者很熟悉它,但为了代码可读性,应该定义为常量。

问题 4.2:代码结构
Server::mapToNeighbor 中新增的代码块使用了裸花括号 { ... } 来限制局部变量的作用域。这在 C++ 中是合法的,但略显突兀。建议将这段逻辑提取为一个内联辅助函数,如 clampToScreenBounds,以提高可读性和复用性。


💡 改进后的代码建议

针对以上问题,我为你重构了相关代码:

1. MSWindowsDesks::deskMouseMove 改进版

// 建议在文件顶部或函数内部定义常量
static const float kAbsoluteCoordRange = 65535.0f;

void
MSWindowsDesks::deskMouseMove(SInt32 x, SInt32 y) const
{
    // clamp coordinates to virtual screen bounds to prevent
    // overflow in mouse_event normalization and out-of-range
    // cursor positions on high-resolution or multi-monitor setups.
    // 修复整数溢出风险:将加法运算提升到 64 位整数
    long long maxX = static_cast<long long>(m_x) + m_w - 1;
    long long maxY = static_cast<long long>(m_y) + m_h - 1;
    
    if (x < m_x) { x = m_x; }
    else if (x > maxX) { x = static_cast<SInt32>(maxX); }
    
    if (y < m_y) { y = m_y; }
    else if (y > maxY) { y = static_cast<SInt32>(maxY); }

    // use SetCursorPos which accepts virtual screen pixel coordinates
    // directly, avoiding the 0-65535 normalization that mouse_event
    // requires and the DPI context mismatch after SetThreadDesktop.
    if (!SetCursorPos(x, y)) {
        // fallback to mouse_event for cases where SetCursorPos
        // is blocked (e.g. Vista/7 secure desktop).
        SInt32 w = GetSystemMetrics(SM_CXSCREEN);
        SInt32 h = GetSystemMetrics(SM_CYSCREEN);
        
        // 防御性编程:防止安全桌面等极端情况下 w 或 h 为 0 导致除零崩溃
        if (w > 0 && h > 0) {
            // 修复逻辑:mouse_event(MOUSEEVENTF_ABSOLUTE) 需要相对于主显示器的坐标
            // 如果 x, y 是虚拟屏幕坐标,需要先转换为主显示器相对坐标
            SInt32 primaryX = x - GetSystemMetrics(SM_XVIRTUALSCREEN);
            SInt32 primaryY = y - GetSystemMetrics(SM_YVIRTUALSCREEN);
            
            // 修复归一化精度:使用 w 而不是 w - 1,使得坐标能完整覆盖 0-65535
            mouse_event(MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE,
                                    (DWORD)(kAbsoluteCoordRange * primaryX / w + 0.5f),
                                    (DWORD)(kAbsoluteCoordRange * primaryY / h + 0.5f),
                                    0, 0);
        }
    }
}

2. Server::mapToNeighbor 改进版

	assert(lastGoodScreen != NULL);
	dst = lastGoodScreen;

	// clamp coordinates to destination screen bounds. when screens
	// have different resolutions, mapToNeighbor can produce values
	// outside the valid range (e.g. x == dw from the kLeft path).
	{
		SInt32 dx, dy, dw, dh;
		dst->getShape(dx, dy, dw, dh);
        // 修复整数溢出风险,使用 long long 进行边界计算
        long long maxDstX = static_cast<long long>(dx) + dw - 1;
        long long maxDstY = static_cast<long long>(dy) + dh - 1;
        
		if (x < dx) { x = dx; }
		else if (x > maxDstX) { x = static_cast<SInt32>(maxDstX); }
        
		if (y < dy) { y = dy; }
		else if (y > maxDstY) { y = static_cast<SInt32>(maxDstY); }
	}

	// if entering primary screen then be sure to move in far enough
	// to avoid the jump zone.  if entering a side that doesn't have
	// a neighbor (i.e. an asymmetrical side) then we don't need to

总结

你的修复思路非常棒,精准定位了跨屏时坐标溢出导致的鼠标冻结问题。通过上述改进,我们修复了潜在的多显示器下降级逻辑坐标错乱整数溢出除零崩溃问题,使得代码的健壮性和安全性得到了进一步提升。

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: lzwind, re2zero

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

@re2zero
re2zero merged commit d46a33b into linuxdeepin:master Jun 4, 2026
38 of 41 checks passed
@deepin-bot

deepin-bot Bot commented Jun 4, 2026

Copy link
Copy Markdown

TAG Bot

Tag created successfully

📋 Tag Details
  • Tag Name: 1.2.5
  • Tag SHA: 750b685b4058e1a942d22a72013118baf76049a0
  • Commit SHA: d46a33bdba3fd172327afe37109d036bdca484d5
  • Tag Message:
    Release dde-cooperation 1.2.5
    
    
  • Tagger:
    • Name: re2zero
  • Distribution: unstable

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