You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux系统下基于Dart实现剪贴板变更监控的方案问询

在Linux下用Dart监控剪贴板变更

这里提供两种不依赖第三方Dart剪贴板包的实现方案,基于Linux原生工具和系统API:


方案1:轮询xclip命令(快速实现)

这种方式简单直接,通过定期调用xclip获取剪贴板内容,对比历史值判断是否变更。

前置依赖

确保系统已安装xclip:

  • Debian/Ubuntu: sudo apt install xclip
  • Fedora/RHEL: sudo dnf install xclip

Dart代码示例

import 'dart:io';
import 'dart:async';

void main() {
  startClipboardMonitor();
}

void startClipboardMonitor() {
  String? lastContent;
  // 调整检查间隔,平衡响应速度和系统开销
  Timer.periodic(const Duration(milliseconds: 500), (timer) async {
    try {
      final processResult = await Process.run(
        'xclip',
        ['-selection', 'clipboard', '-o'],
        runInShell: true,
      );

      if (processResult.exitCode != 0) {
        print('获取剪贴板失败: ${processResult.stderr}');
        return;
      }

      final currentContent = processResult.stdout.toString().trim();
      if (currentContent != lastContent && currentContent.isNotEmpty) {
        lastContent = currentContent;
        // 触发自定义操作
        onClipboardChanged(currentContent);
      }
    } catch (e) {
      print('监控出错: $e');
    }
  });
}

void onClipboardChanged(String content) {
  print('剪贴板已更新:');
  print(content);
  // 在这里添加你的业务逻辑,比如解析内容、调用接口等
}

注意事项

  • 间隔时间:建议设置在300-1000ms之间,避免过于频繁的系统调用
  • 空内容处理:判断currentContent.isNotEmpty避免剪贴板清空时重复触发
  • 权限:确保程序有执行xclip的权限

方案2:监听X11剪贴板事件(高效无轮询)

如果需要实时监控且不想有轮询开销,可以直接和X11服务器交互,监听剪贴板的选择变更事件。这种方式需要用Dart的ffi调用Xlib库。

步骤说明

  1. 添加ffi依赖到pubspec.yaml:

    dependencies:
      ffi: ^2.1.0
    
  2. Dart代码示例(核心框架)

    import 'dart:ffi';
    import 'package:ffi/ffi.dart';
    
    // 绑定Xlib核心函数
    typedef XOpenDisplayC = Pointer<Void> Function(Pointer<Utf8>);
    typedef XOpenDisplayDart = Pointer<Void> Function(Pointer<Utf8>);
    
    typedef XNextEventC = Void Function(Pointer<Void>, Pointer<Void>);
    typedef XNextEventDart = void Function(Pointer<Void>, Pointer<Void>);
    
    typedef XDefaultRootWindowC = Int32 Function(Pointer<Void>);
    typedef XDefaultRootWindowDart = int Function(Pointer<Void>);
    
    typedef XSelectInputC = Void Function(Pointer<Void>, Int32, Int64);
    typedef XSelectInputDart = void Function(Pointer<Void>, int, int);
    
    // X11事件掩码常量
    const int PropertyChangeMask = 0x00002000;
    
    void main() {
      final xlib = DynamicLibrary.open('libX11.so.6');
    
      // 初始化Xlib函数
      final xOpenDisplay = xlib.lookupFunction<XOpenDisplayC, XOpenDisplayDart>('XOpenDisplay');
      final xNextEvent = xlib.lookupFunction<XNextEventC, XNextEventDart>('XNextEvent');
      final xDefaultRootWindow = xlib.lookupFunction<XDefaultRootWindowC, XDefaultRootWindowDart>('XDefaultRootWindow');
      final xSelectInput = xlib.lookupFunction<XSelectInputC, XSelectInputDart>('XSelectInput');
    
      final display = xOpenDisplay(nullptr);
      if (display == nullptr) {
        print('无法连接到X11显示');
        return;
      }
    
      final rootWindow = xDefaultRootWindow(display);
      // 监听根窗口的属性变化事件(剪贴板变更会触发这类事件)
      xSelectInput(display, rootWindow, PropertyChangeMask);
    
      print('开始实时监听剪贴板...');
    
      // 分配内存存储X11事件
      final eventBuffer = malloc.allocate<Void>(128); // XEvent结构体大小约128字节
      while (true) {
        xNextEvent(display, eventBuffer);
        // 解析事件,判断是否为剪贴板相关的属性变更
        // 完整实现需要解析event.type和对应的property原子值
        checkAndHandleClipboardChange();
      }
    }
    
    Future<void> checkAndHandleClipboardChange() async {
      // 触发变更时,用xclip获取最新内容
      final result = await Process.run('xclip', ['-selection', 'clipboard', '-o'], runInShell: true);
      if (result.exitCode == 0) {
        final content = result.stdout.toString().trim();
        if (content.isNotEmpty) {
          print('剪贴板实时更新: $content');
          // 执行自定义操作
        }
      }
    }
    

注意事项

  • 完整实现需要解析X11的PropertyNotify事件,判断是否是剪贴板相关的属性变更(需要通过XInternAtom获取CLIPBOARD原子值)
  • 该方案无轮询开销,响应实时,但需要对X11的选择机制有基础了解
  • 不同Linux发行版的Xlib库路径可能不同,libX11.so.6是通用路径

内容的提问来源于stack exchange,提问作者Bhaskar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 16:35:11