Barrier 的卡顿问题解决

记录一下barrier的卡顿问题解决过程

在自己家里有一台老旧的笔记本(使用了固态,和安装了ubuntu 24.04, 在焕发第二春) 另外有一个台式机(win 11),使用了小米的24英寸的显示器

两台电脑之间希望可以使用barrier来共享键盘和鼠标

因为barrier属于开源软件,所以出现问题可以在社区中寻找答案。

在使用两台设备共享键盘和鼠标时,发现在移动到client端的屏幕时,总是出现了鼠标不跟手的情况,看起来一卡一卡的。

开启调试日志

查看日志中的信息发现

shell 复制代码
[2025-08-07T22:23:51] DEBUG2: event: MotionNotify 924,568  
[2025-08-07T22:23:51] DEBUG2: warped to 960,540  
[2025-08-07T22:23:51] DEBUG2: event: MotionNotify 924,568  
[2025-08-07T22:23:51] DEBUG2: warped to 960,540  
[2025-08-07T22:23:51] DEBUG2: event: MotionNotify 960,540  
[2025-08-07T22:23:51] DEBUG2: onMouseMoveSecondary -5,+5  
[2025-08-07T22:23:51] DEBUG2: move on pc to 538,451  

发现触发的鼠标移动事件,多个事件触发,才发送了一次给远端,所以问题的根因肯定在这里。

根据代码寻找根因:

cpp 复制代码
void
XWindowsScreen::onMouseMove(const XMotionEvent& xmotion)
{
	LOG((CLOG_DEBUG2 "event: MotionNotify %d,%d", xmotion.x_root, xmotion.y_root));

	// compute motion delta (relative to the last known
	// mouse position)
	SInt32 x = xmotion.x_root - m_xCursor;
	SInt32 y = xmotion.y_root - m_yCursor;

	// save position to compute delta of next motion
	m_xCursor = xmotion.x_root;
	m_yCursor = xmotion.y_root;

	if (xmotion.send_event) {
		// we warped the mouse.  discard events until we
		// find the matching sent event.  see
		// warpCursorNoFlush() for where the events are
		// sent.  we discard the matching sent event and
		// can be sure we've skipped the warp event.
		XEvent xevent;
		char cntr = 0;
		do {
            m_impl->XMaskEvent(m_display, PointerMotionMask, &xevent);
			if (cntr++ > 10) {
				LOG((CLOG_WARN "too many discarded events! %d", cntr));
				break;
			}
		} while (!xevent.xany.send_event);
		cntr = 0;
	}
	else if (m_isOnScreen) {
		// motion on primary screen
		sendEvent(m_events->forIPrimaryScreen().motionOnPrimary(),
							MotionInfo::alloc(m_xCursor, m_yCursor));
	}

发现上方有一些判断条件,核心与warpCursorNoFlush相关

cpp 复制代码
void
MSWindowsScreen::warpCursorNoFlush(SInt32 x, SInt32 y)
{
    // send an event that we can recognize before the mouse warp
    PostThreadMessage(GetCurrentThreadId(), BARRIER_MSG_PRE_WARP, x, y);

    // warp mouse.  hopefully this inserts a mouse motion event
    // between the previous message and the following message.
    SetCursorPos(x, y);

    // check to see if the mouse pos was set correctly
    POINT cursorPos;
    GetCursorPos(&cursorPos);

    // there is a bug or round error in SetCursorPos and GetCursorPos on
    // a high DPI setting. The check here is for Vista/7 login screen.
    // since this feature is mainly for client, so only check on client.
    if (!isPrimary()) {
        if ((cursorPos.x != x) && (cursorPos.y != y)) {
            LOG((CLOG_DEBUG "SetCursorPos did not work; using fakeMouseMove instead"));
            LOG((CLOG_DEBUG "cursor pos %d, %d expected pos %d, %d", cursorPos.x, cursorPos.y, x, y));
            // when at Vista/7 login screen, SetCursorPos does not work (which could be
            // an MS security feature). instead we can use fakeMouseMove, which calls
            // mouse_event.
            // IMPORTANT: as of implementing this function, it has an annoying side
            // effect; instead of the mouse returning to the correct exit point, it
            // returns to the center of the screen. this could have something to do with
            // the center screen warping technique used (see comments for onMouseMove
            // definition).
            fakeMouseMove(x, y);
        }
    }

    // yield the CPU.  there's a race condition when warping:
    //   a hardware mouse event occurs
    //   the mouse hook is not called because that process doesn't have the CPU
    //   we send PRE_WARP, SetCursorPos(), send POST_WARP
    //   we process all of those events and update m_x, m_y
    //   we finish our time slice
    //   the hook is called
    //   the hook sends us a mouse event from the pre-warp position
    //   we get the CPU
    //   we compute a bogus warp
    // we need the hook to process all mouse events that occur
    // before we warp before we do the warp but i'm not sure how
    // to guarantee that.  yielding the CPU here may reduce the
    // chance of undesired behavior.  we'll also check for very
    // large motions that look suspiciously like about half width
    // or height of the screen.
    ARCH->sleep(0.0);

    // send an event that we can recognize after the mouse warp
    PostThreadMessage(GetCurrentThreadId(), BARRIER_MSG_POST_WARP, 0, 0);
}

我们看到了核心的关键问题,BUG

cpp 复制代码
    // there is a bug or round error in SetCursorPos and GetCursorPos on
    // a high DPI setting. The check here is for Vista/7 login screen.
    // since this feature is mainly for client, so only check on client.

所以属于高DPI的设置中,这个SetCursorPos可能不准确,那么我们需要设置兼容性

在windows上右击barrier, 找到属性,兼容性,更改高DPI设置

选中替代高DPI缩放行为, 切换为系统增强

恢复正常.

相关推荐
狂师6 小时前
最近火爆出圈的,FDE 到底是个什么岗位?
人工智能·程序员·全栈
demo007x21 小时前
让大模型活在你的鼠标旁:我用 Tauri 2 + Rust 打造了一款“反直觉”的 AI 全局划词效率神器
macos·程序员·llm
程序员海军1 天前
AI 越来越强,为什么打工人反而越来越累、越来越内耗了?
前端·程序员·aigc
badhope1 天前
同样写 AI,为什么有的文章 549 人看、有的只有 16 人看?——我用 40 篇掘金文章的真实数据复盘
程序员
今朝唯我少年郎2 天前
Codex安全盲区代码漏洞生成实测
python·程序员
kyriewen3 天前
我用 AI 写完一个需求后才发现,最难的不是 prompt,而是验收
前端·程序员·ai编程
酷酷的逗逗乐3 天前
前端转 Agent 开发 · 第六节
前端·程序员
爱勇宝3 天前
没有 Fn 键关触控板?我做了一个双击即用的 Windows 小工具
前端·后端·程序员
程序员cxuan3 天前
跟 WebUI 说再见了,最强 DeepSeek 桌面端来了!
人工智能·后端·程序员
codigger3 天前
用 AI 写代码,你知道它会把我的代码传去哪?
ai·程序员·编程·数据安全