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

在Zig中使用XCB编写窗口管理器的两个问题求助

使用Zig+XCB编写窗口管理器遇到的问题

我在Arch Linux系统上,尝试使用Zig语言结合XCB编写一个带有事件循环(可处理按键等事件)的简易窗口管理器,且已安装所有必要库。

代码文件

main.zig

const std = @import("std");
const print = std.debug.print;
const xcb = @cImport({
    @cInclude("xcb/xcb.h");
});

pub fn main() !void {
    const conn: ?*xcb.xcb_connection_t = xcb.xcb_connect(null, null);
    defer xcb.xcb_disconnect(conn);

    if (conn == null or xcb.xcb_connection_has_error(conn) != 0) {
        print("Failed to connect to X server\n", .{});
        return error.XConnectionFailed;
    }

    const xcbsetup = xcb.xcb_get_setup(conn);
    if (xcbsetup == null) {
        print("Failed to get XCB setup\n", .{});
        return error.XCBSetupFailed;
    }

    const screen_iter = xcb.xcb_setup_roots_iterator(xcbsetup);
    if (screen_iter.rem == 0) {
        print("No screens found\n", .{});
        return error.NoScreens;
    }

    const screen: *xcb.xcb_screen_t = screen_iter.data;

    const win = xcb.xcb_generate_id(conn);
    // const event_mask = xcb.XCB_EVENT_MASK_KEY_PRESS;

    //  Event masks: capturing all possible events
    const event_mask = xcb.XCB_EVENT_MASK_EXPOSURE |
        xcb.XCB_EVENT_MASK_KEY_PRESS |
        xcb.XCB_EVENT_MASK_KEY_RELEASE |
        xcb.XCB_EVENT_MASK_BUTTON_PRESS |
        xcb.XCB_EVENT_MASK_BUTTON_RELEASE |
        xcb.XCB_EVENT_MASK_POINTER_MOTION |
        xcb.XCB_EVENT_MASK_ENTER_WINDOW |
        xcb.XCB_EVENT_MASK_LEAVE_WINDOW |
        xcb.XCB_EVENT_MASK_FOCUS_CHANGE |
        xcb.XCB_EVENT_MASK_STRUCTURE_NOTIFY;

    const value_list = [_]u32{event_mask};

    _ = xcb.xcb_create_window(
        conn,
        xcb.XCB_COPY_FROM_PARENT,
        win,
        screen.root,
        0,
        0, // x, y
        400,
        300, // width, height
        10, // border width
        xcb.XCB_WINDOW_CLASS_INPUT_OUTPUT,
        screen.root_visual,
        xcb.XCB_CW_EVENT_MASK,
        &value_list,
    );

    _ = xcb.xcb_map_window(conn, win);
    _ = xcb.xcb_flush(conn);

    while (true) {
        const event = xcb.xcb_wait_for_event(conn);
        if (event == null) {
            print("Error waiting for event\n", .{});
            continue;
        }

        switch (event.*.response_type) {
            xcb.XCB_KEY_PRESS => {
                const key_event: *xcb.xcb_key_press_event_t = @ptrCast(event);
                print("Key pressed: code = {}, state = {}\n", .{ key_event.detail, key_event.state });
            },
            else => {
                print("Unhandled event of type {}.\n", .{event.*.response_type});
            },
        }

        // Free the event
        // xcb.xcb_free_event(conn, event);
    }
}

build.zig

const std = @import("std");

pub fn build(b: *std.Build) void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

    const exe = b.addExecutable(.{
        .name = "blakewm",
        .root_source_file = b.path("src/main.zig"),
        .target = target,
        .optimize = optimize,
    });

    exe.linkSystemLibrary("xcb");
    b.installArtifact(exe);
}

build.zig.zon无特殊内容,无需展示。

遇到的问题

  • 不清楚在事件循环中如何释放事件(C示例中使用free(ev));
  • 使用zig build编译后,通过命令Xephyr -ac -br -noreset -screen 800x600 :1 & sleep 1; DISPLAY=:1 ./zig-out/bin/blakewm运行程序时出现段错误,无法正常输出按键信息,错误信息如下:
The XKEYBOARD keymap compiler (xkbcomp) reports:
> Warning:          Could not resolve keysym XF86RefreshRateToggle
> Warning:          Could not resolve keysym XF86Accessibility
> Warning:          Could not resolve keysym XF86DoNotDisturb
Errors from xkbcomp are not fatal to the X server
Segmentation fault at address 0x0
???:?:?: 0x0 in ??? (???)
./runb.sh: line 1:  2898 Aborted                 (core dumped) DISPLAY=:1 ./zig-out/bin/blakewm

runb.sh仅包含上述Xephyr调用命令,用于简化测试操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 00:17:33