#pragma once #include #include #include #include #include #include #include "alvin/error.hpp" #include "alvin/types.hpp" namespace alvin { // Opaque, backend-defined handle: a Hyprland client address, an HWND, ... struct WindowId { std::uint64_t value = 0; friend bool operator==(const WindowId&, const WindowId&) = default; }; struct WindowInfo { WindowId id; std::string title; std::string appId; // Wayland app_id / X11 class / Win32 executable name Rect bounds; // global desktop coordinates std::int64_t pid = 0; bool focused = false; bool visible = true; bool minimized = false; bool fullscreen = false; std::string workspace; // compositor-specific; empty when not applicable }; enum class WindowBackend { Auto, Hyprland, // Hyprland IPC socket Win32, }; std::string_view toString(WindowBackend backend) noexcept; // Querying and focusing top-level windows. Wayland deliberately hides this // from normal clients, so each compositor needs its own implementation. class WindowManager { public: static Result> create(WindowBackend backend = WindowBackend::Auto); virtual ~WindowManager() = default; WindowManager(const WindowManager&) = delete; WindowManager& operator=(const WindowManager&) = delete; virtual WindowBackend backend() const = 0; virtual Result> list() = 0; virtual Result> active() = 0; virtual Status focus(WindowId id) = 0; // First window whose title or appId contains `needle` (case-insensitive). Result> find(std::string_view needle); protected: WindowManager() = default; }; } // namespace alvin