Add Alvin library: input, capture, windows and vision
A cross-platform C++23 library with a platform-neutral public API and runtime-selected backends: - Input: Wayland virtual pointer/keyboard (Hyprland, wlroots), libei via the RemoteDesktop portal (GNOME, KDE), uinput, and Win32 SendInput - Capture: ScreenCast portal + PipeWire, and Win32 GDI - Windows: Hyprland IPC and Win32 enumeration - Monitors via wl_output/xdg-output and EnumDisplayMonitors - Optional OpenCV template matching (alvin::vision) Also adds the `alvin` CLI, Catch2 unit tests, install rules with find_package(Alvin) support, API docs (docs/API.md and the Obsidian vault), and README instructions for both ways of consuming the library. Windows backends are written but not yet compiled. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
76ff506fd0
commit
ca7e62ac8d
59 files changed
+6515
-1
No files matched your search
@@ -0,0 +1,64 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#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<std::unique_ptr<WindowManager>> create(WindowBackend backend = WindowBackend::Auto);
|
||||
|
||||
virtual ~WindowManager() = default;
|
||||
WindowManager(const WindowManager&) = delete;
|
||||
WindowManager& operator=(const WindowManager&) = delete;
|
||||
|
||||
virtual WindowBackend backend() const = 0;
|
||||
virtual Result<std::vector<WindowInfo>> list() = 0;
|
||||
virtual Result<std::optional<WindowInfo>> active() = 0;
|
||||
virtual Status focus(WindowId id) = 0;
|
||||
|
||||
// First window whose title or appId contains `needle` (case-insensitive).
|
||||
Result<std::optional<WindowInfo>> find(std::string_view needle);
|
||||
|
||||
protected:
|
||||
WindowManager() = default;
|
||||
};
|
||||
|
||||
} // namespace alvin
|
||||
Reference in new issue
Block a user