zig vs c++ vs python vs js:控制x11鼠标移动,移动窗口

执行速度:zig≈c++(纳秒级) > python (0.2ms) > js (1ms)
最好不要C ABI,增加一层麻烦。

如果你用python游戏框架,就用python最方便。
如果你要写html,就用js。
如果mach,就zig。
如果虚幻ue4、ue5,就c++

ps: 脚本语言,pyscript应该代替js。脚本语言应该对人类友好。
静态语言,zig或rust应该替代c++,在兼顾对人类友好的同时,对机器友好,优化也好
汇编语言,zig可以调用C的__asm__{}
ps2: anaconda推动pyscript,顺便也可以重新实现一个现代浏览器。(ladybird)

cursor

zig

Debug输出大小: 2.3MB
ReleaseSmall输出大小:11.3kB

const std = @import("std");
const x11 = @cImport({
    @cInclude("X11/Xlib.h");
});

// Converts between numeric types: .Enum, .Int and .Float.
pub inline fn as(comptime T: type, from: anytype) T {
    switch (@typeInfo(@TypeOf(from))) {
        .Enum => {
            switch (@typeInfo(T)) {
                .Int => return @intFromEnum(from),
                else => @compileError(@typeName(@TypeOf(from)) ++ " can't be converted to " ++ @typeName(T)),
            }
        },
        .Int => {
            switch (@typeInfo(T)) {
                .Enum => return @enumFromInt(from),
                .Int => return @intCast(from),
                .Float => return @floatFromInt(from),
                else => @compileError(@typeName(@TypeOf(from)) ++ " can't be converted to " ++ @typeName(T)),
            }
        },
        .Float => {
            switch (@typeInfo(T)) {
                .Float => return @floatCast(from),
                .Int => return @intFromFloat(from),
                else => @compileError(@typeName(@TypeOf(from)) ++ " can't be converted to " ++ @typeName(T)),
            }
        },
        else => @compileError(@typeName(@TypeOf(from) ++ " is not supported.")),
    }
}

pub fn main() !void {
    // const allocator = std.heap.page_allocator;
    const display = x11.XOpenDisplay(null);
    if (display == null) {
        std.debug.print("Failed to open display\n", .{});
        return;
    }
    defer _ = x11.XCloseDisplay(display);

    const screen = x11.XDefaultScreen(display);
    const root_window = x11.XRootWindow(display, screen);

    const height = x11.DisplayHeight(display, screen);
    const width = x11.DisplayWidth(display, screen);
    std.debug.print("Screen size: {}x{}\n", .{ width, height });

    const m = as(f32, height) / as(f32, width);

    var i: i32 = 0;
    while (i < width) : (i += 1) {
        const j = as(i32, as(f32, i) * m);
        _ = x11.XWarpPointer(display, x11.None, root_window, 0, 0, 0, 0, i, j);
        _ = x11.XFlush(display);
        std.time.sleep(50 * std.time.ns_per_us);
    }
}
// zig build-exe src/x11_control_mouse_cursor.zig -lX11 -lc -O ReleaseSmall
// -I .: 添加当前目录作为包含路径,这对于包含项目内的其他文件很有用。

c++

c++ source: https://gist.github.com/aliva/3372331
输出大小:16.8 kB

#include <X11/Xlib.h>
#include <iostream>
#include <unistd.h>

int main(void) {
    Display* dpy = XOpenDisplay(0);
    int scr = XDefaultScreen(dpy);
    Window root_window = XRootWindow(dpy, scr);

    int height = DisplayHeight(dpy, scr);
    int width  = DisplayWidth(dpy, scr);
    std::cout << "Screen size : " << width << "x" << height << std::endl;

    float m = (float)height/(float)width;

    int j;
    for(int i=0; i<width; i++){
        j = m*i;
        XWarpPointer(dpy, None, root_window, 0, 0, 0, 0, i, j);
        XFlush(dpy);
        usleep(50);
    }
}
// g++ x11_control_mouse_cursor.cpp -o x11_ctrl_cursor -lX11

python

可以跨平台。在我的锐龙5800 CPU上,最短动画间隔是0.0002s左右,即0.2ms。

# pip install pyautogui
import time
import pyautogui as agui

agui.FAILSAFE=False
agui.PAUSE = 0.00001
agui.moveTo(1, 1)


t_start=time.time()
t_cur=time.time()
mx=my=1
while True:
    # print(time.time()-t_cur,end='\t')
    t_cur=time.time()
    x,y=agui.position()
    X,Y=agui.size()
    if t_cur-t_start>20: # sec
        break
    if x>=X-1:
        mx=-1
    elif x<=1:
        mx=1
    if y>=Y-1:
        my=-1
    elif y<=1:
        my=1
    agui.move(mx, my)
# time.sleep(0.5)

# when duration is used, ignoring agui.duration
# X,Y=agui.size()
# agui.moveTo(1,1)
# agui.moveTo(X-1, Y-1, duration=1.0)

window

python

import pywinctl as pwc

win = pwc.getWindowsWithTitle("cpp")[0]

mx=my=1
if win is not None:
    print("ACTIVE WINDOW", win.title, win.size,win.size)
    while True:
        x,y = win.position
        w,h = win.size
        if x+w > 1920*0.9:
            mx = -1
        elif x < 5:
            mx = 1

        if y+h > 1080*0.98:
            my = -1
        elif y < 5:
            my = 1
        win.moveTo(x + mx, y + my*2)
        # win.resizeRel(mx,my)

        # win.topleft = (win.left + 20, win.top + 20)
        # print("FINAL POSITION", win.position)
else:
    print("NOT FOUND")

chrome, html5

浏览器限制不能移动光标,但能移动弹出的窗口
https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_win_moveto

let wind;

function openWin() {
  wind=window.open("", "", "width=400, height=200");
}
async function moveWin() {
  for (i=0; i<100; i++) {
    await new Promise(r => {
      // const x = wind.screenX;
      // const y = wind.screenY;
      wind.moveBy(5, 3);
      setTimeout(r, 1); // 动画最短间隔1ms毫秒
    });
  }
}

// chrome.windows.update(windowId, {focused: true})
posted @ 2024-07-22 17:19  Nolca  阅读(20)  评论(0编辑  收藏  举报