oxwm

https://git.tonybtw.com/oxwm.git git://git.tonybtw.com/oxwm.git
3,401 bytes raw
1
const std = @import("std");
2
const xlib = @import("xlib.zig");
3
4
pub const Atoms = struct {
5
    // ICCCM atoms
6
    wm_protocols: xlib.Atom,
7
    wm_delete: xlib.Atom,
8
    wm_state: xlib.Atom,
9
    wm_take_focus: xlib.Atom,
10
11
    // EWHM atoms
12
    net_supported: xlib.Atom,
13
    net_wm_name: xlib.Atom,
14
    net_wm_state: xlib.Atom,
15
    net_wm_check: xlib.Atom,
16
    net_wm_state_fullscreen: xlib.Atom,
17
    net_active_window: xlib.Atom,
18
    net_wm_window_type: xlib.Atom,
19
    net_wm_window_type_dialog: xlib.Atom,
20
    net_client_list: xlib.Atom,
21
22
    /// Intern all atoms and set up the EWMH check window on `root`.
23
    ///
24
    /// `check_window` is a 1×1 invisible window created solely to satisfy
25
    /// the _NET_SUPPORTING_WM_CHECK convention. The caller owns it and
26
    /// should destroy it on shutdown via `XDestroyWindow`.
27
    pub fn init(display: *xlib.Display, root: xlib.Window) struct {
28
        atoms: Atoms,
29
        check_window: xlib.Window,
30
    } {
31
        const intern = struct {
32
            fn call(dpy: *xlib.Display, name: [*:0]const u8) xlib.Atom {
33
                return xlib.XInternAtom(dpy, name, xlib.False);
34
            }
35
        }.call;
36
37
        const atoms = Atoms{
38
            .wm_protocols = intern(display, "WM_PROTOCOLS"),
39
            .wm_delete = intern(display, "WM_DELETE_WINDOW"),
40
            .wm_state = intern(display, "WM_STATE"),
41
            .wm_take_focus = intern(display, "WM_TAKE_FOCUS"),
42
43
            .net_supported = intern(display, "_NET_SUPPORTED"),
44
            .net_wm_name = intern(display, "_NET_WM_NAME"),
45
            .net_wm_state = intern(display, "_NET_WM_STATE"),
46
            .net_wm_check = intern(display, "_NET_SUPPORTING_WM_CHECK"),
47
            .net_wm_state_fullscreen = intern(display, "_NET_WM_STATE_FULLSCREEN"),
48
            .net_active_window = intern(display, "_NET_ACTIVE_WINDOW"),
49
            .net_wm_window_type = intern(display, "_NET_WM_WINDOW_TYPE"),
50
            .net_wm_window_type_dialog = intern(display, "_NET_WM_WINDOW_TYPE_DIALOG"),
51
            .net_client_list = intern(display, "_NET_CLIENT_LIST"),
52
        };
53
54
        const utf8_string = intern(display, "UTF8_STRING");
55
56
        // Create the EWMH check window.
57
        var check_win = xlib.XCreateSimpleWindow(display, root, 0, 0, 1, 1, 0, 0, 0);
58
59
        _ = xlib.XChangeProperty(display, check_win, atoms.net_wm_check, xlib.XA_WINDOW, 32, xlib.PropModeReplace, @ptrCast(&check_win), 1);
60
        _ = xlib.XChangeProperty(display, check_win, atoms.net_wm_name, utf8_string, 8, xlib.PropModeReplace, "oxwm", 4);
61
        _ = xlib.XChangeProperty(display, root, atoms.net_wm_check, xlib.XA_WINDOW, 32, xlib.PropModeReplace, @ptrCast(&check_win), 1);
62
63
        // Advertise supported EWMH hints on the root window.
64
        var net_atoms = [_]xlib.Atom{
65
            atoms.net_supported,
66
            atoms.net_wm_name,
67
            atoms.net_wm_state,
68
            atoms.net_wm_check,
69
            atoms.net_wm_state_fullscreen,
70
            atoms.net_active_window,
71
            atoms.net_wm_window_type,
72
            atoms.net_wm_window_type_dialog,
73
            atoms.net_client_list,
74
        };
75
        _ = xlib.XChangeProperty(display, root, atoms.net_supported, xlib.XA_ATOM, 32, xlib.PropModeReplace, @ptrCast(&net_atoms), net_atoms.len);
76
77
        _ = xlib.XDeleteProperty(display, root, atoms.net_client_list);
78
79
        return .{ .atoms = atoms, .check_window = check_win };
80
    }
81
};