Merge pull request 'Refactor initialization and Context struct' (#2) from context-refactor into main
Reviewed-on: https://codeberg.org/bwbuhse/beansprout/pulls/2
This commit is contained in:
commit
46938c238a
8 changed files with 187 additions and 118 deletions
66
src/Context.zig
Normal file
66
src/Context.zig
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
// SPDX-FileCopyrightText: 2026 Ben Buhse <me@benbuhse.email>
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
/// Context to pass Wayland info around.
|
||||||
|
const Context = @This();
|
||||||
|
|
||||||
|
initialized: bool,
|
||||||
|
|
||||||
|
// Wayland globals
|
||||||
|
wl_display: *wl.Display,
|
||||||
|
wl_registry: *wl.Registry,
|
||||||
|
wl_compositor: *wl.Compositor,
|
||||||
|
|
||||||
|
// Wayland globals that we have structs for
|
||||||
|
wm: *WindowManager,
|
||||||
|
xkb_bindings: *XkbBindings,
|
||||||
|
|
||||||
|
// WM Configuration
|
||||||
|
config: Config,
|
||||||
|
|
||||||
|
pub fn create(
|
||||||
|
wl_display: *wl.Display,
|
||||||
|
wl_registry: *wl.Registry,
|
||||||
|
wl_compositor: *wl.Compositor,
|
||||||
|
river_window_manager_v1: *river.WindowManagerV1,
|
||||||
|
river_xkb_bindings_v1: *river.XkbBindingsV1,
|
||||||
|
config: Config,
|
||||||
|
) !*Context {
|
||||||
|
const context = try utils.allocator.create(Context);
|
||||||
|
errdefer context.destroy();
|
||||||
|
|
||||||
|
context.* = .{
|
||||||
|
.initialized = false,
|
||||||
|
.wl_display = wl_display,
|
||||||
|
.wl_registry = wl_registry,
|
||||||
|
.wl_compositor = wl_compositor,
|
||||||
|
.wm = try WindowManager.create(context, river_window_manager_v1),
|
||||||
|
.xkb_bindings = try XkbBindings.create(context, river_xkb_bindings_v1),
|
||||||
|
.config = config,
|
||||||
|
};
|
||||||
|
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn destroy(context: *Context) void {
|
||||||
|
context.xkb_bindings.destroy();
|
||||||
|
context.wm.destroy();
|
||||||
|
|
||||||
|
utils.allocator.destroy(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const wayland = @import("wayland");
|
||||||
|
const river = wayland.client.river;
|
||||||
|
const wl = wayland.client.wl;
|
||||||
|
|
||||||
|
const utils = @import("utils.zig");
|
||||||
|
const Config = @import("Config.zig");
|
||||||
|
const WindowManager = @import("WindowManager.zig");
|
||||||
|
const XkbBindings = @import("XkbBindings.zig");
|
||||||
|
|
||||||
|
const log = std.log.scoped(.Context);
|
||||||
|
|
@ -30,7 +30,7 @@ fn outputListener(river_output_v1: *river.OutputV1, event: river.OutputV1.Event,
|
||||||
switch (event) {
|
switch (event) {
|
||||||
.removed => {
|
.removed => {
|
||||||
river_output_v1.destroy();
|
river_output_v1.destroy();
|
||||||
output.context.allocator.destroy(output);
|
utils.allocator.destroy(output);
|
||||||
},
|
},
|
||||||
.wl_output => {
|
.wl_output => {
|
||||||
// log.debug("initializing new river_output_v1 corresponding to wl_output: {d}", .{ev.name});
|
// log.debug("initializing new river_output_v1 corresponding to wl_output: {d}", .{ev.name});
|
||||||
|
|
@ -61,6 +61,7 @@ const wayland = @import("wayland");
|
||||||
const wl = wayland.client.wl;
|
const wl = wayland.client.wl;
|
||||||
const river = wayland.client.river;
|
const river = wayland.client.river;
|
||||||
|
|
||||||
const Context = @import("main.zig").Context;
|
const utils = @import("utils.zig");
|
||||||
|
const Context = @import("Context.zig");
|
||||||
|
|
||||||
const log = std.log.scoped(.Output);
|
const log = std.log.scoped(.Output);
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ fn seatListener(river_seat_v1: *river.SeatV1, event: river.SeatV1.Event, seat: *
|
||||||
switch (event) {
|
switch (event) {
|
||||||
.removed => {
|
.removed => {
|
||||||
river_seat_v1.destroy();
|
river_seat_v1.destroy();
|
||||||
seat.context.allocator.destroy(seat);
|
utils.allocator.destroy(seat);
|
||||||
},
|
},
|
||||||
.wl_seat => {
|
.wl_seat => {
|
||||||
// log.debug("initializing new river_seat_v1 corresponding to wl_seat: {d}", .{ev.name});
|
// log.debug("initializing new river_seat_v1 corresponding to wl_seat: {d}", .{ev.name});
|
||||||
|
|
@ -66,7 +66,8 @@ const wayland = @import("wayland");
|
||||||
const wl = wayland.client.wl;
|
const wl = wayland.client.wl;
|
||||||
const river = wayland.client.river;
|
const river = wayland.client.river;
|
||||||
|
|
||||||
const Context = @import("main.zig").Context;
|
const utils = @import("utils.zig");
|
||||||
|
const Context = @import("Context.zig");
|
||||||
const Window = @import("Window.zig");
|
const Window = @import("Window.zig");
|
||||||
|
|
||||||
const log = std.log.scoped(.Seat);
|
const log = std.log.scoped(.Seat);
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ fn windowListener(river_window_v1: *river.WindowV1, event: river.WindowV1.Event,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
window.link.remove();
|
window.link.remove();
|
||||||
window.context.allocator.destroy(window);
|
utils.allocator.destroy(window);
|
||||||
},
|
},
|
||||||
.dimensions => |ev| {
|
.dimensions => |ev| {
|
||||||
// The protocol requires these are strictly greather than zero.
|
// The protocol requires these are strictly greather than zero.
|
||||||
|
|
@ -172,6 +172,7 @@ const wayland = @import("wayland");
|
||||||
const wl = wayland.client.wl;
|
const wl = wayland.client.wl;
|
||||||
const river = wayland.client.river;
|
const river = wayland.client.river;
|
||||||
|
|
||||||
const Context = @import("main.zig").Context;
|
const utils = @import("utils.zig");
|
||||||
|
const Context = @import("Context.zig");
|
||||||
|
|
||||||
const log = std.log.scoped(.Window);
|
const log = std.log.scoped(.Window);
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,31 @@ windows: wl.list.Head(Window, .link),
|
||||||
|
|
||||||
window_count: u8 = 0,
|
window_count: u8 = 0,
|
||||||
|
|
||||||
|
pub fn create(context: *Context, window_manager_v1: *river.WindowManagerV1) !*WindowManager {
|
||||||
|
const wm = try utils.allocator.create(WindowManager);
|
||||||
|
errdefer wm.destroy();
|
||||||
|
|
||||||
|
wm.* = .{
|
||||||
|
.context = context,
|
||||||
|
.window_manager_v1 = window_manager_v1,
|
||||||
|
.seats = undefined, // we will initialize these shortly
|
||||||
|
.outputs = undefined,
|
||||||
|
.windows = undefined,
|
||||||
|
};
|
||||||
|
|
||||||
|
wm.seats.init();
|
||||||
|
wm.outputs.init();
|
||||||
|
wm.windows.init();
|
||||||
|
|
||||||
|
wm.window_manager_v1.setListener(*WindowManager, windowManagerV1Listener, wm);
|
||||||
|
|
||||||
|
return wm;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn destroy(wm: *WindowManager) void {
|
||||||
|
utils.allocator.destroy(wm);
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the next window in the list, wrapping to first if at end
|
/// Get the next window in the list, wrapping to first if at end
|
||||||
pub fn getNextWindow(wm: *WindowManager, current: *Window) ?*Window {
|
pub fn getNextWindow(wm: *WindowManager, current: *Window) ?*Window {
|
||||||
var it = wm.windows.iterator(.forward);
|
var it = wm.windows.iterator(.forward);
|
||||||
|
|
@ -40,23 +65,6 @@ pub fn getPrevWindow(wm: *WindowManager, current: *Window) ?*Window {
|
||||||
return wm.windows.last();
|
return wm.windows.last();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(wm: *WindowManager, context: *Context, window_manager_v1: *river.WindowManagerV1) void {
|
|
||||||
assert(wm == &context.wm);
|
|
||||||
wm.* = .{
|
|
||||||
.context = context,
|
|
||||||
.window_manager_v1 = window_manager_v1,
|
|
||||||
.seats = undefined, // we will initialize this shortly
|
|
||||||
.outputs = undefined,
|
|
||||||
.windows = undefined,
|
|
||||||
};
|
|
||||||
|
|
||||||
wm.seats.init();
|
|
||||||
wm.outputs.init();
|
|
||||||
wm.windows.init();
|
|
||||||
|
|
||||||
wm.window_manager_v1.setListener(*WindowManager, windowManagerV1Listener, wm);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Calculate primary/stack layout positions for all windows.
|
/// Calculate primary/stack layout positions for all windows.
|
||||||
/// - Single window: fullscreen
|
/// - Single window: fullscreen
|
||||||
/// - Multiple windows: stack (45% left, vertically tiled), primary (55% right)
|
/// - Multiple windows: stack (45% left, vertically tiled), primary (55% right)
|
||||||
|
|
@ -137,12 +145,15 @@ fn windowManagerV1Listener(window_manager_v1: *river.WindowManagerV1, event: riv
|
||||||
// mark it as cold.
|
// mark it as cold.
|
||||||
@branchHint(.cold);
|
@branchHint(.cold);
|
||||||
context.initialized = true;
|
context.initialized = true;
|
||||||
context.xkb_bindings.addBinding(xkbcommon.Keysym.t, .{ .mod4 = true }, .{ .spawn = &.{"foot"} });
|
|
||||||
context.xkb_bindings.addBinding(xkbcommon.Keysym.j, .{ .mod4 = true }, .focus_next);
|
const seat = wm.seats.first() orelse @panic("No river_seat_v1 found");
|
||||||
context.xkb_bindings.addBinding(xkbcommon.Keysym.k, .{ .mod4 = true }, .focus_prev);
|
const river_seat_v1 = seat.seat_v1;
|
||||||
context.xkb_bindings.addBinding(xkbcommon.Keysym.f, .{ .mod4 = true }, .fullscreen);
|
context.xkb_bindings.addBinding(river_seat_v1, xkbcommon.Keysym.t, .{ .mod4 = true }, .{ .spawn = &.{"foot"} });
|
||||||
context.xkb_bindings.addBinding(xkbcommon.Keysym.q, .{ .mod4 = true, .shift = true }, .close_window);
|
context.xkb_bindings.addBinding(river_seat_v1, xkbcommon.Keysym.j, .{ .mod4 = true }, .focus_next);
|
||||||
context.xkb_bindings.addBinding(xkbcommon.Keysym.e, .{ .mod4 = true, .shift = true }, .exit);
|
context.xkb_bindings.addBinding(river_seat_v1, xkbcommon.Keysym.k, .{ .mod4 = true }, .focus_prev);
|
||||||
|
context.xkb_bindings.addBinding(river_seat_v1, xkbcommon.Keysym.f, .{ .mod4 = true }, .fullscreen);
|
||||||
|
context.xkb_bindings.addBinding(river_seat_v1, xkbcommon.Keysym.q, .{ .mod4 = true, .shift = true }, .close_window);
|
||||||
|
context.xkb_bindings.addBinding(river_seat_v1, xkbcommon.Keysym.e, .{ .mod4 = true, .shift = true }, .exit);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
@ -190,19 +201,19 @@ fn windowManagerV1Listener(window_manager_v1: *river.WindowManagerV1, event: riv
|
||||||
},
|
},
|
||||||
.output => |ev| {
|
.output => |ev| {
|
||||||
log.debug("3", .{});
|
log.debug("3", .{});
|
||||||
var output = context.allocator.create(Output) catch @panic("out-of-memory; exiting.");
|
var output = utils.allocator.create(Output) catch @panic("out-of-memory; exiting.");
|
||||||
output.init(context, ev.id);
|
output.init(context, ev.id);
|
||||||
wm.outputs.append(output);
|
wm.outputs.append(output);
|
||||||
},
|
},
|
||||||
.seat => |ev| {
|
.seat => |ev| {
|
||||||
log.debug("4", .{});
|
log.debug("4", .{});
|
||||||
var seat = context.allocator.create(Seat) catch @panic("out-of-memory; exiting.");
|
var seat = utils.allocator.create(Seat) catch @panic("out-of-memory; exiting.");
|
||||||
seat.init(context, ev.id);
|
seat.init(context, ev.id);
|
||||||
wm.seats.append(seat);
|
wm.seats.append(seat);
|
||||||
},
|
},
|
||||||
.window => |ev| {
|
.window => |ev| {
|
||||||
log.debug("5", .{});
|
log.debug("5", .{});
|
||||||
var window = context.allocator.create(Window) catch @panic("out-of-memory; exiting.");
|
var window = utils.allocator.create(Window) catch @panic("out-of-memory; exiting.");
|
||||||
window.init(context, ev.id);
|
window.init(context, ev.id);
|
||||||
wm.windows.append(window);
|
wm.windows.append(window);
|
||||||
wm.window_count += 1;
|
wm.window_count += 1;
|
||||||
|
|
@ -223,7 +234,8 @@ const river = wayland.client.river;
|
||||||
|
|
||||||
const xkbcommon = @import("xkbcommon");
|
const xkbcommon = @import("xkbcommon");
|
||||||
|
|
||||||
const Context = @import("main.zig").Context;
|
const utils = @import("utils.zig");
|
||||||
|
const Context = @import("Context.zig");
|
||||||
const Output = @import("Output.zig");
|
const Output = @import("Output.zig");
|
||||||
const Seat = @import("Seat.zig");
|
const Seat = @import("Seat.zig");
|
||||||
const Window = @import("Window.zig");
|
const Window = @import("Window.zig");
|
||||||
|
|
|
||||||
|
|
@ -97,10 +97,10 @@ xkb_bindings_v1: *river.XkbBindingsV1,
|
||||||
|
|
||||||
bindings: wl.list.Head(XkbBinding, .link),
|
bindings: wl.list.Head(XkbBinding, .link),
|
||||||
|
|
||||||
xkb_bindings_seat_v1: ?*river.XkbBindingsSeatV1 = null,
|
pub fn create(context: *Context, xkb_bindings_v1: *river.XkbBindingsV1) !*XkbBindings {
|
||||||
|
const xkb_bindings = try utils.allocator.create(XkbBindings);
|
||||||
|
errdefer xkb_bindings.destroy();
|
||||||
|
|
||||||
pub fn init(xkb_bindings: *XkbBindings, context: *Context, xkb_bindings_v1: *river.XkbBindingsV1) void {
|
|
||||||
assert(xkb_bindings == &context.xkb_bindings);
|
|
||||||
xkb_bindings.* = .{
|
xkb_bindings.* = .{
|
||||||
.context = context,
|
.context = context,
|
||||||
.xkb_bindings_v1 = xkb_bindings_v1,
|
.xkb_bindings_v1 = xkb_bindings_v1,
|
||||||
|
|
@ -108,21 +108,21 @@ pub fn init(xkb_bindings: *XkbBindings, context: *Context, xkb_bindings_v1: *riv
|
||||||
};
|
};
|
||||||
|
|
||||||
xkb_bindings.bindings.init();
|
xkb_bindings.bindings.init();
|
||||||
|
|
||||||
|
return xkb_bindings;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getSeat(xkb_bindings: *XkbBindings) *river.SeatV1 {
|
pub fn destroy(xkb_bindings: *XkbBindings) void {
|
||||||
const seat = xkb_bindings.context.wm.seats.first() orelse @panic("No seat available");
|
xkb_bindings.destroy();
|
||||||
return seat.seat_v1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn addBinding(xkb_bindings: *XkbBindings, keysym: u32, modifiers: river.SeatV1.Modifiers, command: Command) void {
|
pub fn addBinding(xkb_bindings: *XkbBindings, river_seat_v1: *river.SeatV1, keysym: u32, modifiers: river.SeatV1.Modifiers, command: Command) void {
|
||||||
const seat_v1 = xkb_bindings.getSeat();
|
const xkb_binding_v1 = xkb_bindings.xkb_bindings_v1.getXkbBinding(river_seat_v1, keysym, modifiers) catch |err| {
|
||||||
const xkb_binding_v1 = xkb_bindings.xkb_bindings_v1.getXkbBinding(seat_v1, keysym, modifiers) catch |err| {
|
log.err("Failed to get river xkb binding: {}", .{err});
|
||||||
log.err("Failed to get xkb binding: {}", .{err});
|
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
const xkb_binding = xkb_bindings.context.allocator.create(XkbBinding) catch @panic("out-of-memory");
|
const xkb_binding = utils.allocator.create(XkbBinding) catch @panic("out-of-memory");
|
||||||
xkb_binding.init(xkb_binding_v1, command, xkb_bindings.context);
|
xkb_binding.init(xkb_binding_v1, command, xkb_bindings.context);
|
||||||
xkb_bindings.bindings.append(xkb_binding);
|
xkb_bindings.bindings.append(xkb_binding);
|
||||||
|
|
||||||
|
|
@ -138,7 +138,8 @@ const river = wayland.client.river;
|
||||||
|
|
||||||
const xkbcommon = @import("xkbcommon");
|
const xkbcommon = @import("xkbcommon");
|
||||||
|
|
||||||
const Context = @import("main.zig").Context;
|
const utils = @import("utils.zig");
|
||||||
|
const Context = @import("Context.zig");
|
||||||
const Seat = @import("Seat.zig");
|
const Seat = @import("Seat.zig");
|
||||||
|
|
||||||
const log = std.log.scoped(.XkbBindings);
|
const log = std.log.scoped(.XkbBindings);
|
||||||
|
|
|
||||||
131
src/main.zig
131
src/main.zig
|
|
@ -2,95 +2,52 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/// Context to pass some info around.
|
/// Wayland globals that we need to bind to
|
||||||
pub const Context = struct {
|
const Globals = struct {
|
||||||
allocator: mem.Allocator,
|
wl_compositor: ?*wl.Compositor = null,
|
||||||
|
river_window_manager_v1: ?*river.WindowManagerV1 = null,
|
||||||
initialized: bool,
|
river_xkb_bindings_v1: ?*river.XkbBindingsV1 = null,
|
||||||
|
|
||||||
display: *wl.Display,
|
|
||||||
registry: *wl.Registry,
|
|
||||||
|
|
||||||
compositor: ?*wl.Compositor = null,
|
|
||||||
shm: ?*wl.Shm = null,
|
|
||||||
|
|
||||||
wm: WindowManager,
|
|
||||||
xkb_bindings: XkbBindings,
|
|
||||||
|
|
||||||
config: Config,
|
|
||||||
|
|
||||||
fn registryListener(registry: *wl.Registry, event: wl.Registry.Event, context: *Context) void {
|
|
||||||
switch (event) {
|
|
||||||
.global => |ev| {
|
|
||||||
if (mem.orderZ(u8, ev.interface, wl.Compositor.interface.name) == .eq) {
|
|
||||||
if (ev.version < 4) versionNotSupported(wl.Compositor, ev.version, 4);
|
|
||||||
context.compositor = registry.bind(ev.name, wl.Compositor, 4) catch |e| {
|
|
||||||
log.err("Failed to bind to compositor: {any}", .{@errorName(e)});
|
|
||||||
std.posix.exit(1);
|
|
||||||
};
|
|
||||||
} else if (mem.orderZ(u8, ev.interface, wl.Shm.interface.name) == .eq) {
|
|
||||||
context.shm = registry.bind(ev.name, wl.Shm, 1) catch |e| {
|
|
||||||
log.err("Failed to bind to shm: {any}", .{@errorName(e)});
|
|
||||||
std.posix.exit(1);
|
|
||||||
};
|
|
||||||
} else if (mem.orderZ(u8, ev.interface, river.WindowManagerV1.interface.name) == .eq) {
|
|
||||||
const window_manager_v1 = registry.bind(ev.name, river.WindowManagerV1, 3) catch |e| {
|
|
||||||
log.err("Failed to bind to window_manager_v1: {any}", .{@errorName(e)});
|
|
||||||
std.posix.exit(1);
|
|
||||||
};
|
|
||||||
context.wm.init(context, window_manager_v1);
|
|
||||||
} else if (mem.orderZ(u8, ev.interface, river.XkbBindingsV1.interface.name) == .eq) {
|
|
||||||
const xkb_bindings_v1 = registry.bind(ev.name, river.XkbBindingsV1, 2) catch |e| {
|
|
||||||
log.err("Failed to bind to xkb_bindings_v1: {any}", .{@errorName(e)});
|
|
||||||
std.posix.exit(1);
|
|
||||||
};
|
|
||||||
context.xkb_bindings.init(context, xkb_bindings_v1);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// We don't need .global_remove
|
|
||||||
.global_remove => {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const usage: []const u8 =
|
|
||||||
\\usage: beansprout [options]
|
|
||||||
\\
|
|
||||||
\\ -i, --image <PATH> TODO TODO TODO TODO
|
|
||||||
\\ -h, --help TODO TODO TODO TODO
|
|
||||||
\\ -V, --version TODO TODO TODO TODO
|
|
||||||
\\
|
|
||||||
;
|
|
||||||
|
|
||||||
pub fn main() !void {
|
pub fn main() !void {
|
||||||
const allocator = std.heap.c_allocator;
|
const wayland_display_var = try utils.allocator.dupeZ(u8, process.getEnvVarOwned(utils.allocator, "WAYLAND_DISPLAY") catch {
|
||||||
|
log.err("Error getting WAYLAND_DISPLAY environment variable. Exiing", .{});
|
||||||
|
std.posix.exit(1);
|
||||||
|
});
|
||||||
|
defer utils.allocator.free(wayland_display_var);
|
||||||
|
|
||||||
const wl_display = wl.Display.connect(null) catch {
|
const wl_display = wl.Display.connect(null) catch {
|
||||||
log.err("Error connecting to Wayland server. Exiting", .{});
|
log.err("Error connecting to Wayland server. Exiting", .{});
|
||||||
std.posix.exit(1);
|
std.posix.exit(1);
|
||||||
};
|
};
|
||||||
|
defer wl_display.disconnect();
|
||||||
|
|
||||||
const registry = try wl_display.getRegistry();
|
const wl_registry = try wl_display.getRegistry();
|
||||||
|
|
||||||
var context: Context = .{
|
var globals: Globals = .{};
|
||||||
.allocator = allocator,
|
wl_registry.setListener(*Globals, registryListener, &globals);
|
||||||
.initialized = false,
|
|
||||||
.display = wl_display,
|
|
||||||
.registry = registry,
|
|
||||||
.wm = undefined,
|
|
||||||
.xkb_bindings = undefined,
|
|
||||||
// Hardcoded config for now
|
|
||||||
.config = .{ .border_width = 2, .border_color_focused = utils.parseRgbaComptime("0x89b4fa"), .border_color_unfocused = utils.parseRgbaComptime("0x1e1e2e") },
|
|
||||||
};
|
|
||||||
|
|
||||||
registry.setListener(*Context, Context.registryListener, &context);
|
const errno = wl_display.roundtrip();
|
||||||
|
|
||||||
const errno = context.display.roundtrip();
|
|
||||||
if (errno != .SUCCESS) {
|
if (errno != .SUCCESS) {
|
||||||
log.err("Initial roundtrip failed: E{s}", .{@tagName(errno)});
|
log.err("Initial roundtrip failed: E{s}", .{@tagName(errno)});
|
||||||
std.posix.exit(1);
|
std.posix.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const wl_compositor = globals.wl_compositor orelse interfaceNotAdvertised(wl.Compositor);
|
||||||
|
const river_window_manager_v1 = globals.river_window_manager_v1 orelse interfaceNotAdvertised(river.WindowManagerV1);
|
||||||
|
const river_xkb_bindings_v1 = globals.river_xkb_bindings_v1 orelse interfaceNotAdvertised(river.XkbBindingsV1);
|
||||||
|
|
||||||
|
const context = try Context.create(
|
||||||
|
wl_display,
|
||||||
|
wl_registry,
|
||||||
|
wl_compositor,
|
||||||
|
river_window_manager_v1,
|
||||||
|
river_xkb_bindings_v1,
|
||||||
|
// Hardcoded config for now
|
||||||
|
.{ .border_width = 2, .border_color_focused = utils.parseRgbaComptime("0x89b4fa"), .border_color_unfocused = utils.parseRgbaComptime("0x1e1e2e") },
|
||||||
|
);
|
||||||
|
defer context.destroy();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (wl_display.dispatch() != .SUCCESS) {
|
if (wl_display.dispatch() != .SUCCESS) {
|
||||||
log.err("wayland display dispatch failed", .{});
|
log.err("wayland display dispatch failed", .{});
|
||||||
|
|
@ -101,6 +58,32 @@ pub fn main() !void {
|
||||||
log.info("Exiting beansprout", .{});
|
log.info("Exiting beansprout", .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn registryListener(registry: *wl.Registry, event: wl.Registry.Event, globals: *Globals) void {
|
||||||
|
switch (event) {
|
||||||
|
.global => |ev| {
|
||||||
|
if (mem.orderZ(u8, ev.interface, wl.Compositor.interface.name) == .eq) {
|
||||||
|
if (ev.version < 4) versionNotSupported(wl.Compositor, ev.version, 4);
|
||||||
|
globals.wl_compositor = registry.bind(ev.name, wl.Compositor, 4) catch |e| {
|
||||||
|
log.err("Failed to bind to compositor: {any}", .{@errorName(e)});
|
||||||
|
std.posix.exit(1);
|
||||||
|
};
|
||||||
|
} else if (mem.orderZ(u8, ev.interface, river.WindowManagerV1.interface.name) == .eq) {
|
||||||
|
globals.river_window_manager_v1 = registry.bind(ev.name, river.WindowManagerV1, 3) catch |e| {
|
||||||
|
log.err("Failed to bind to window_manager_v1: {any}", .{@errorName(e)});
|
||||||
|
std.posix.exit(1);
|
||||||
|
};
|
||||||
|
} else if (mem.orderZ(u8, ev.interface, river.XkbBindingsV1.interface.name) == .eq) {
|
||||||
|
globals.river_xkb_bindings_v1 = registry.bind(ev.name, river.XkbBindingsV1, 2) catch |e| {
|
||||||
|
log.err("Failed to bind to xkb_bindings_v1: {any}", .{@errorName(e)});
|
||||||
|
std.posix.exit(1);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// We don't need .global_remove
|
||||||
|
.global_remove => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Actually use this...
|
// TODO: Actually use this...
|
||||||
fn interfaceNotAdvertised(comptime WaylandGlobal: type) noreturn {
|
fn interfaceNotAdvertised(comptime WaylandGlobal: type) noreturn {
|
||||||
log.err("{s} not advertised. Exiting", .{WaylandGlobal.interface.name});
|
log.err("{s} not advertised. Exiting", .{WaylandGlobal.interface.name});
|
||||||
|
|
@ -114,6 +97,7 @@ fn versionNotSupported(comptime WaylandGlobal: type, have_version: u32, need_ver
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const mem = std.mem;
|
const mem = std.mem;
|
||||||
|
const process = std.process;
|
||||||
|
|
||||||
const wayland = @import("wayland");
|
const wayland = @import("wayland");
|
||||||
const river = wayland.client.river;
|
const river = wayland.client.river;
|
||||||
|
|
@ -121,6 +105,7 @@ const wl = wayland.client.wl;
|
||||||
|
|
||||||
const utils = @import("utils.zig");
|
const utils = @import("utils.zig");
|
||||||
const Config = @import("Config.zig");
|
const Config = @import("Config.zig");
|
||||||
|
const Context = @import("Context.zig");
|
||||||
const WindowManager = @import("WindowManager.zig");
|
const WindowManager = @import("WindowManager.zig");
|
||||||
const XkbBindings = @import("XkbBindings.zig");
|
const XkbBindings = @import("XkbBindings.zig");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
pub const allocator = std.heap.c_allocator;
|
||||||
|
|
||||||
pub const RiverColor = struct {
|
pub const RiverColor = struct {
|
||||||
red: u32,
|
red: u32,
|
||||||
green: u32,
|
green: u32,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue