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缩放行为, 切换为系统增强

恢复正常.

相关推荐
程序员鱼皮10 小时前
AI 最需要的 15 个开源项目,装完直接起飞!
ai·程序员·开源·编程·ai编程
uzong10 小时前
架构师底层思维能力要求-这7种尽早练习
后端·程序员·架构
我就是马云飞10 小时前
SBTI 测试挤崩服务器:一个程序员视角的技术复盘
前端·后端·程序员
陈随易10 小时前
Lerna-Lite 5.0发布解析
前端·后端·程序员
ltl2 天前
你的大脑正在发生什么:AI 时代程序员的认知心理学
程序员
SimonKing2 天前
每天白送4000万Token!这款“龙虾”AI神器,微信就能操控电脑
java·后端·程序员
KaneLogger2 天前
从传统笔记到 LLM 驱动的结构化 Wiki
人工智能·程序员·架构
修己xj2 天前
368天,每天头顶一件东西:这件“无聊”的小事,让我想通了一个道理
程序员
无限大62 天前
数字生存05:在AI时代,如何保持学习能力,不断成长
程序员
无限大62 天前
职场逻辑05:5步高效管理时间,让你的工作事半功倍
程序员