From 8110bb2773b6c841029a51eca7971f42a36f480c Mon Sep 17 00:00:00 2001 From: srdusr <99972264+srdusr@users.noreply.github.com> Date: Tue, 2 Apr 2024 00:58:00 +0200 Subject: Rewrite srdwm in Rust: working X11 and Wayland backends, Lua config The C++ prototype (moved to legacy-cpp/) was mostly a design skeleton: X11 and Windows backends were partially real, Wayland created the wlroots object graph but never wired a single event listener, macOS was stub except monitor enumeration, and the Lua engine's srd.bind() stored a key-combo string but never the actual closure. See docs/PRIOR_ART.md for the full audit. This replaces it with a Cargo workspace: - srdwm-core: platform-independent window/workspace/monitor state, a real master-stack tiling layout, and SmartPlacement grid/cascade/ snap-to-edge placement - fixing several bugs in the C++ version (hardcoded 2-column grid, cascade that never cascaded, snap-to-edge that always returned a fixed rect). 35 unit tests. - srdwm-config: the srd Lua API via mlua, implementing the surface docs/DEFAULTS.md always documented but the C++ engine never actually built (srd.window.close()/focus(direction), srd.workspace.next(), real keybinding closures, require("srd") support). 10 unit tests. - srdwm-x11: a real reparenting WM with a drawn title bar (buttons, drag, resize), verified live under Xephyr - frame placement and client offset match srdwm-core's computed geometry exactly, and the decoration renders correctly on screen. - srdwm-wayland: a from-scratch smithay compositor (the C++ version had nothing working to port from) - runs via the winit backend, tracks xdg-shell toplevels through the same WindowManager and hit-testing code X11 uses, verified to start/render/run without crashing. Decorations are solid-color (no text yet); see docs/IMPLEMENTATION_STATUS.md for exact scope. - srdwm-windows / srdwm-macos: structured, cfg-gated designs informed by komorebi/glazewm and yabai/AeroSpace respectively (see docs/PRIOR_ART.md), honestly marked as unbuilt/unverified since this sandbox has no Windows or macOS target. --- src/layouts/layout_engine.cc | 188 ------------------------------------------- 1 file changed, 188 deletions(-) delete mode 100644 src/layouts/layout_engine.cc (limited to 'src/layouts/layout_engine.cc') diff --git a/src/layouts/layout_engine.cc b/src/layouts/layout_engine.cc deleted file mode 100644 index f6bc20f..0000000 --- a/src/layouts/layout_engine.cc +++ /dev/null @@ -1,188 +0,0 @@ -#include "layout_engine.h" -#include -#include - -LayoutEngine::LayoutEngine() { - std::cout << "LayoutEngine: Initializing..." << std::endl; -} - -LayoutEngine::~LayoutEngine() { - std::cout << "LayoutEngine: Shutting down..." << std::endl; -} - -// Layout management -bool LayoutEngine::set_layout(int monitor_id, LayoutType layout_type) { - active_layouts_[monitor_id] = layout_type; - std::cout << "LayoutEngine: Set layout " << layout_type_to_string(layout_type) - << " for monitor " << monitor_id << std::endl; - return true; -} - -bool LayoutEngine::set_layout(int monitor_id, const std::string& layout_name) { - LayoutType layout_type = string_to_layout_type(layout_name); - if (layout_type != LayoutType::TILING && layout_type != LayoutType::DYNAMIC && layout_type != LayoutType::FLOATING) { - std::cerr << "LayoutEngine: Unknown layout type: " << layout_name << std::endl; - return false; - } - return set_layout(monitor_id, layout_type); -} - -LayoutType LayoutEngine::get_layout(int monitor_id) const { - auto it = active_layouts_.find(monitor_id); - if (it != active_layouts_.end()) { - return it->second; - } - return LayoutType::DYNAMIC; // Default layout -} - -std::string LayoutEngine::get_layout_name(int monitor_id) const { - return layout_type_to_string(get_layout(monitor_id)); -} - -// Layout configuration -bool LayoutEngine::configure_layout(const std::string& layout_name, const std::map& config) { - layout_configs_[layout_name] = config; - std::cout << "LayoutEngine: Configured layout '" << layout_name << "' with " - << config.size() << " parameters" << std::endl; - return true; -} - -bool LayoutEngine::register_custom_layout(const std::string& name, std::function&, const Monitor&)> layout_func) { - custom_layouts_[name] = layout_func; - std::cout << "LayoutEngine: Registered custom layout '" << name << "'" << std::endl; - return true; -} - -// SRDWindow management -void LayoutEngine::add_window(SRDWindow* window) { - if (window && std::find(windows_.begin(), windows_.end(), window) == windows_.end()) { - windows_.push_back(window); - std::cout << "LayoutEngine: Added window " << window->getId() << std::endl; - } -} - -void LayoutEngine::remove_window(SRDWindow* window) { - auto it = std::find(windows_.begin(), windows_.end(), window); - if (it != windows_.end()) { - windows_.erase(it); - std::cout << "LayoutEngine: Removed window " << window->getId() << std::endl; - } -} - -void LayoutEngine::update_window(SRDWindow* window) { - // Trigger rearrangement for the monitor this window is on - // For now, just log the update - std::cout << "LayoutEngine: Updated window " << window->getId() << std::endl; -} - -// Monitor management -void LayoutEngine::add_monitor(const Monitor& monitor) { - // Check if monitor already exists - auto it = std::find_if(monitors_.begin(), monitors_.end(), - [&](const Monitor& m) { return m.id == monitor.id; }); - if (it == monitors_.end()) { - monitors_.push_back(monitor); - // Set default layout for new monitor - active_layouts_[monitor.id] = LayoutType::DYNAMIC; - std::cout << "LayoutEngine: Added monitor " << monitor.id << std::endl; - } -} - -void LayoutEngine::remove_monitor(int monitor_id) { - auto it = std::find_if(monitors_.begin(), monitors_.end(), - [monitor_id](const Monitor& m) { return m.id == monitor_id; }); - if (it != monitors_.end()) { - monitors_.erase(it); - active_layouts_.erase(monitor_id); - std::cout << "LayoutEngine: Removed monitor " << monitor_id << std::endl; - } -} - -void LayoutEngine::update_monitor(const Monitor& monitor) { - auto it = std::find_if(monitors_.begin(), monitors_.end(), - [&](const Monitor& m) { return m.id == monitor.id; }); - if (it != monitors_.end()) { - *it = monitor; - std::cout << "LayoutEngine: Updated monitor " << monitor.id << std::endl; - } -} - -// Arrangement -void LayoutEngine::arrange_on_monitor(const Monitor& monitor) { - if (active_layouts_.count(monitor.id)) { - LayoutType current_layout_type = active_layouts_[monitor.id]; - std::vector windows_on_monitor = get_windows_on_monitor(monitor.id); - - std::cout << "LayoutEngine: Arranging " << windows_on_monitor.size() - << " windows on monitor " << monitor.id - << " with layout " << layout_type_to_string(current_layout_type) << std::endl; - - if (current_layout_type == LayoutType::TILING) { - tiling_layout_.arrange_windows(windows_on_monitor, monitor); - } else if (current_layout_type == LayoutType::DYNAMIC) { - dynamic_layout_.arrange_windows(windows_on_monitor, monitor); - } else if (current_layout_type == LayoutType::FLOATING) { - // Floating layout - windows keep their current positions - std::cout << "LayoutEngine: Floating layout - no arrangement needed" << std::endl; - } - } -} - -void LayoutEngine::arrange_all_monitors() { - for (const auto& monitor : monitors_) { - arrange_on_monitor(monitor); - } -} - -// Utility -std::vector LayoutEngine::get_available_layouts() const { - return {"tiling", "dynamic", "floating"}; -} - -std::vector LayoutEngine::get_windows_on_monitor(int monitor_id) const { - std::vector windows_on_monitor; - - // Find the monitor - auto monitor_it = std::find_if(monitors_.begin(), monitors_.end(), - [monitor_id](const Monitor& m) { return m.id == monitor_id; }); - if (monitor_it == monitors_.end()) { - return windows_on_monitor; - } - - // Get windows that are on this monitor - for (SRDWindow* window : windows_) { - if (is_window_on_monitor(window, *monitor_it)) { - windows_on_monitor.push_back(window); - } - } - - return windows_on_monitor; -} - -// Helper methods -LayoutType LayoutEngine::string_to_layout_type(const std::string& name) const { - if (name == "tiling") return LayoutType::TILING; - if (name == "dynamic") return LayoutType::DYNAMIC; - if (name == "floating") return LayoutType::FLOATING; - return LayoutType::DYNAMIC; // Default -} - -std::string LayoutEngine::layout_type_to_string(LayoutType type) const { - switch (type) { - case LayoutType::TILING: return "tiling"; - case LayoutType::DYNAMIC: return "dynamic"; - case LayoutType::FLOATING: return "floating"; - default: return "dynamic"; - } -} - -bool LayoutEngine::is_window_on_monitor(const SRDWindow* window, const Monitor& monitor) const { - if (!window) return false; - - // Simple check: window center is within monitor bounds - int window_center_x = window->getX() + window->getWidth() / 2; - int window_center_y = window->getY() + window->getHeight() / 2; - - return window_center_x >= monitor.x && window_center_x < monitor.x + monitor.width && - window_center_y >= monitor.y && window_center_y < monitor.y + monitor.height; -} -- cgit v1.2.3