你了解这个项目吗,是GitHub上的开源项目GitHub - deskflow/deskflow: Share a single keyboard and mouse between multiple computers. · GitHub

了解。

Deskflow 是一款跨电脑共享键盘和鼠标的开源软件,可以让你用一套键鼠控制多台电脑。

例如,你的 Windows 和 Linux 电脑各自连接显示器,鼠标移到屏幕边缘就能切换到另一台电脑,键盘输入随之切换,还能共享剪贴板。

它支持 Windows、macOS 和 Linux,默认启用 TLS 加密;

它不传输屏幕画面。

我也看了你当前目录里的源码,主要结构是:

目录作用
src/appsGUI、核心程序和后台服务入口
src/lib/gui图形界面
src/lib/server、client服务端与客户端逻辑
src/lib/net网络通信
src/lib/platform各操作系统相关实现
src/unittests单元测试

本地代码采用 C++20、Qt 和 CMake。如果你准备研究源码、编译运行或者修改功能,我们可以直接基于这个目录继续。


它的原理是什么,为什么可以实现一个电脑作为服务端,让另一台电脑作为客户端,使用服务端的键盘和鼠标?

它的核心原理是:服务端捕获键鼠事件,通过网络发送给客户端,客户端再调用操作系统接口,模拟对应的键鼠操作。

传输的是“按下了哪个键、鼠标移动到哪里”等事件数据。

电脑 A:服务端                         电脑 B:客户端

物理键盘、鼠标
      ↓
操作系统接收输入
      ↓
Deskflow 捕获输入事件 ─── 网络传输 ──→ Deskflow 解析事件
                                             ↓
                                      调用系统输入接口
                                             ↓
                                      B 上的应用接收输入

服务端怎么知道你按了什么?

操作系统提供了监听键鼠输入的接口。

以 Windows 为例,Deskflow 使用 SetWindowsHookEx 安装低级键盘和鼠标钩子,监听按键按下、松开、鼠标移动、点击和滚轮等事件。

对应实现在 [MSWindowsHook.cpp (line 670)]

(D:/QtCode/deskflow-master/deskflow-master/src/lib/platform/MSWindowsHook.cpp:670)。

比如你按下 A,程序就可以获取这个按键及其修饰键状态,例如是否同时按着 Shift、Ctrl。

怎么决定控制哪台电脑?

服务端维护着各台电脑的屏幕布局,以及“当前正在控制的电脑”。

假设配置成:

[电脑 A] [电脑 B]

鼠标在 A 屏幕内时,输入作用于 A。

鼠标到达 A 的右边缘、满足切换条件后,Deskflow 将当前控制目标改为 B,并计算鼠标进入 B 屏幕的位置。

控制 B 期间,服务端会拦截需要转发的输入,避免同一次操作也作用到 A 的普通应用。

相关判断和事件分发主要在 [Server.cpp (line 1611)]

(D:/QtCode/deskflow-master/deskflow-master/src/lib/server/Server.cpp:1611)。


网络里发送的是什么?

它把事件编码成自己的协议消息,例如:

键盘:按下 A、松开 A、按下 Ctrl
鼠标:移动到 (300, 200)、左键按下、滚轮滚动

实际传输使用二进制字段,并不是上面这样的文字。

源码中的鼠标移动消息标识是 DMMV,键盘按下消息根据协议版本使用 DKDN 或 DKDL。

客户端主动连接服务端,默认使用 TCP 24800 端口。

连接建立后,服务端就可以持续向客户端发送输入事件。“客户端主动连接”并不妨碍它接收服务端发来的控制数据。


客户端为什么能让其他程序收到这些操作?

因为操作系统也提供了生成模拟输入的接口。

例如 Windows 的 SendInput 可以向系统输入流注入键盘和鼠标事件。

Deskflow 收到远端事件后,进行按键映射、坐标处理等转换,再调用这些接口。

项目中的相关实现可以看到 [MSWindowsDesks.cpp (line 93)]

(D:/QtCode/deskflow-master/deskflow-master/src/lib/platform/MSWindowsDesks.cpp:93)。

所以,当 B 上的文本编辑器获得焦点时,你在 A 的键盘上打字,B 的编辑器就能收到输入。

模拟输入仍受操作系统权限和安全规则限制。

跨平台也是相同思路:网络层传递统一的事件,各平台代码负责把事件转换成本系统的输入操作。 因此,服务端和客户端不需要使用相同的操作系统。


所以,某种程度上,我如果只希望共用一套键盘,则可以自己实现一个简单的版本。让我当前的键盘操作都发送给客户端对应的电脑,然后让它做出响应,就实现了一版简单的共用键盘软件。


对,你理解得很准确。如果只做两台电脑之间的键盘转发,完全可以自己实现一个简化版。

基本流程就是:

A 捕获键盘事件 → 网络发送 → B 接收事件 → 模拟键盘输入

以两台 Windows 电脑为例,可以用:

  • A 端:WH_KEYBOARD_LL 键盘钩子捕获事件。
  • 通信:TCP 连接,发送按键编号、按下或松开等信息。
  • B 端:调用 SendInput 注入键盘事件,交给当前获得焦点的应用处理。

是的,现有的程序太复杂了,对我来说很不友好


确实,Deskflow 要兼顾跨平台、多屏切换、剪贴板同步和各种系统差异,代码复杂度远超“把键盘输入转发到另一台电脑”这个需求。

如果你的目标是自己理解、修改和使用,可以把第一版缩小到:

  • 两台 Windows 电脑,一台连接键盘,另一台接收输入。
  • 手动填写 IP,通过 TCP 连接。
  • 用一个热键切换“控制本机 / 控制远端”。
  • 只转发键盘的按下、松开事件。
  • 断线后自动回到本机,并释放远端按键。

建议单独写一个小项目,这样输入捕获、网络通信、输入模拟三部分都能看得清楚。

先把基本功能跑通,再按实际需要增加界面或其他功能。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐