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

如何在Linux下无需X11与sudo模拟鼠标点击?(偏好Cpp/Rust)

Linux下无需依赖X11且无需sudo的鼠标点击模拟方案(C++/Rust实现)

以下是针对Wayland环境的可行方案,均满足无X11依赖、无需root权限的要求:

方案1:利用桌面环境专属D-Bus接口

不同Wayland桌面环境提供了D-Bus接口来模拟输入事件,无需额外权限。

GNOME环境(C++实现)

通过调用org.gnome.Shell的SimulateMouseEvent方法实现全局鼠标点击:

#include <dbus/dbus.h>

int main() {
    DBusConnection* conn = dbus_bus_get(DBUS_BUS_SESSION, NULL);
    if (!conn) return 1;

    DBusMessage* msg = dbus_message_new_method_call(
        "org.gnome.Shell", "/org/gnome/Shell",
        "org.gnome.Shell", "SimulateMouseEvent"
    );
    // 参数依次为:按钮类型(left/right/middle)、动作(press/release)、X坐标、Y坐标、点击次数
    const char* btn = "left";
    const char* action = "press";
    double x = 500.0;
    double y = 500.0;
    int count = 1;
    dbus_message_append_args(msg,
        DBUS_TYPE_STRING, &btn,
        DBUS_TYPE_STRING, &action,
        DBUS_TYPE_DOUBLE, &x,
        DBUS_TYPE_DOUBLE, &y,
        DBUS_TYPE_INT32, &count,
        DBUS_TYPE_INVALID
    );

    dbus_connection_send(conn, msg, NULL);
    dbus_message_unref(msg);

    // 发送释放事件
    action = "release";
    msg = dbus_message_new_method_call(
        "org.gnome.Shell", "/org/gnome/Shell",
        "org.gnome.Shell", "SimulateMouseEvent"
    );
    dbus_message_append_args(msg,
        DBUS_TYPE_STRING, &btn,
        DBUS_TYPE_STRING, &action,
        DBUS_TYPE_DOUBLE, &x,
        DBUS_TYPE_DOUBLE, &y,
        DBUS_TYPE_INT32, &count,
        DBUS_TYPE_INVALID
    );
    dbus_connection_send(conn, msg, NULL);
    dbus_message_unref(msg);
    dbus_connection_unref(conn);
    return 0;
}

编译命令:g++ -o gnome_click gnome_click.cpp $(pkg-config --cflags --libs dbus-1)

KDE环境

可调用org.kde.plasmashell或kwin的D-Bus接口实现,逻辑类似GNOME,需根据KDE的API文档调整参数。

方案2:基于Wayland虚拟输入协议(Rust实现)

部分Wayland compositor(如Sway、Hyprland等wlroots系桌面)支持zwp_virtual_input_v1协议,可创建虚拟输入设备发送事件:

use wayland_client::{Connection, QueueHandle};
use wayland_protocols::unstable::virtual_input::v1::client::{zwp_virtual_input_manager_v1, zwp_virtual_mouse_v1};

fn main() {
    let conn = Connection::connect_to_env().unwrap();
    let display = conn.display();
    let mut event_queue = conn.new_event_queue();
    let qh = event_queue.handle();

    // 获取虚拟输入管理器
    let manager = display.get_registry(&qh)
        .bind::<zwp_virtual_input_manager_v1::ZwpVirtualInputManagerV1>(1, 1)
        .unwrap();

    // 创建虚拟鼠标设备
    let virtual_mouse = manager.create_virtual_mouse(&qh);
    // 发送左键按下事件(参数1为左键,1表示按下)
    virtual_mouse.button(1, 1);
    // 发送左键释放事件(0表示释放)
    virtual_mouse.button(1, 0);

    // 同步事件到 compositor
    event_queue.sync_roundtrip(&mut (), |_, _, _| {}).unwrap();
}

注意:需确保 compositor 启用了虚拟输入支持,比如Sway需在配置文件中添加input_virtual模块。

方案3:针对自身窗口的输入模拟(C++/GTK)

如果仅需在自己程序的窗口内模拟点击,可使用GTK的原生API:

#include <gtk/gtk.h>

int main(int argc, char** argv) {
    gtk_init(&argc, &argv);
    GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_widget_show(window);

    // 模拟左键按下
    GdkEventButton press_event;
    press_event.type = GDK_BUTTON_PRESS;
    press_event.button = 1;
    press_event.x = 100.0;
    press_event.y = 100.0;
    gtk_widget_event(window, (GdkEvent*)&press_event);

    // 模拟左键释放
    GdkEventButton release_event;
    release_event.type = GDK_BUTTON_RELEASE;
    release_event.button = 1;
    release_event.x = 100.0;
    release_event.y = 100.0;
    gtk_widget_event(window, (GdkEvent*)&release_event);

    gtk_main();
    return 0;
}

编译命令:g++ -o gtk_window_click gtk_window_click.cpp $(pkg-config --cflags --libs gtk+-3.0)


注意事项

  • 上述方案均为Wayland原生实现,无X11依赖;
  • 全局模拟方案依赖具体桌面环境或 compositor 的支持,暂时没有跨所有Wayland环境的通用标准实现;
  • 自身窗口内的模拟方案兼容性最好,适用于仅需控制自身程序的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 06:10:24