在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
相关产品推荐
相关产品推荐

