Something went wrong. Try again.
The cutest scrollable window manager for Windows
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101const WindowManager = @This();
pub const Error = error{NoMonitors};
allocator: std.mem.Allocator,window_hook: WindowHook,keyboard_hook: KeyboardHook,screens: std.ArrayList(Screen) = .empty,config: Configuration = .default,
pub fn init(allocator: std.mem.Allocator) !WindowManager { log.debug("getting the window manager ready", .{});
const window_hook: WindowHook = try .start(); errdefer window_hook.stop();
const keyboard_hook: KeyboardHook = try .start(); errdefer keyboard_hook.stop();
return .{ .allocator = allocator, .window_hook = window_hook, .keyboard_hook = keyboard_hook };}
fn findScreen(wm: *WindowManager, monitor: Monitor) ?*Screen { for (wm.screens.items) |*screen| { if (screen.monitor.handle == monitor.handle) return screen; } return null;}
pub fn deinit(wm: *WindowManager) void { wm.keyboard_hook.stop(); wm.window_hook.stop(); for (wm.screens.items) |*screen| screen.deinit(wm.allocator); wm.screens.deinit(wm.allocator);}
pub fn start(wm: *WindowManager) !void { try wm.discoverScreens(); try wm.registerWindows();
log.info("mimi is ready, listening for messages", .{}); pumpMessages();}
fn discoverScreens(wm: *WindowManager) !void { var monitors: std.ArrayList(Monitor) = .empty; defer monitors.deinit(wm.allocator);
log.debug("looking for monitors", .{}); try Monitor.enumerate(wm.allocator, &monitors); log.info("found {d} monitor(s)", .{monitors.items.len});
if (monitors.items.len == 0) { log.err("no monitors found, mimi can't run without a display", .{}); return Error.NoMonitors; }
try wm.screens.ensureTotalCapacityPrecise(wm.allocator, monitors.items.len); for (monitors.items) |monitor| { wm.screens.appendAssumeCapacity(.init(monitor)); }}
fn registerWindows(wm: *WindowManager) !void { var windows: std.ArrayList(Window) = .empty; defer windows.deinit(wm.allocator);
log.debug("looking for open windows", .{}); try Window.enumerate(wm.allocator, &windows); log.info("found {d} open window(s)", .{windows.items.len});
for (windows.items) |window| { const screen: *Screen = wm.findScreen(window.monitor()) orelse { log.debug("window on unknown monitor, skipping", .{}); continue; }; try screen.windows.append(wm.allocator, window); }}
fn pumpMessages() void { var msg: win32.ui.windows_and_messaging.MSG = undefined; while (win32.ui.windows_and_messaging.GetMessageW(&msg, null, 0, 0) != 0) { _ = win32.ui.windows_and_messaging.TranslateMessage(&msg); _ = win32.ui.windows_and_messaging.DispatchMessageW(&msg); }}
const log = std.log.scoped(.window_manager);
const Configuration = @import("Configuration.zig");const KeyboardHook = @import("KeyboardHook.zig");const WindowHook = @import("WindowHook.zig");
const Screen = @import("Screen.zig");const Window = @import("Window.zig");const Monitor = @import("Monitor.zig");
const win32 = @import("win32");const std = @import("std");