diff --git a/src/platform/linux/window_manager_linux.cpp b/src/platform/linux/window_manager_linux.cpp index a9f07ce..00a2bd3 100644 --- a/src/platform/linux/window_manager_linux.cpp +++ b/src/platform/linux/window_manager_linux.cpp @@ -11,7 +11,25 @@ namespace nativeapi { -WindowManager::WindowManager() { +// Private implementation for Linux (stub for now) +class WindowManager::WindowManagerImpl { +public: + WindowManagerImpl(WindowManager* manager) : manager_(manager) {} + ~WindowManagerImpl() {} + + void SetupEventMonitoring() { + // TODO: Implement Linux-specific event monitoring using GTK signals + } + + void CleanupEventMonitoring() { + // TODO: Implement Linux-specific cleanup + } + +private: + WindowManager* manager_; +}; + +WindowManager::WindowManager() : impl_(std::make_unique(this)) { // Try to initialize GTK if not already initialized // In headless environments, this may fail, which is acceptable if (!gdk_display_get_default()) { @@ -29,9 +47,25 @@ WindowManager::WindowManager() { // gtk_init_check returns FALSE if initialization failed (e.g., no display) // This is acceptable for headless environments } + + SetupEventMonitoring(); +} + +WindowManager::~WindowManager() { + CleanupEventMonitoring(); +} + +void WindowManager::SetupEventMonitoring() { + impl_->SetupEventMonitoring(); } -WindowManager::~WindowManager() {} +void WindowManager::CleanupEventMonitoring() { + impl_->CleanupEventMonitoring(); +} + +void WindowManager::DispatchWindowEvent(const Event& event) { + event_dispatcher_.DispatchSync(event); +} std::shared_ptr WindowManager::Get(WindowID id) { auto it = windows_.find(id); @@ -131,4 +165,20 @@ std::shared_ptr WindowManager::GetCurrent() { return nullptr; } +std::shared_ptr WindowManager::Create(const WindowOptions& options) { + // TODO: Implement Linux window creation using GTK + // For now, return nullptr as this is a stub implementation + return nullptr; +} + +bool WindowManager::Destroy(WindowID id) { + auto it = windows_.find(id); + if (it != windows_.end()) { + // TODO: Implement proper GTK window destruction + windows_.erase(it); + return true; + } + return false; +} + } // namespace nativeapi \ No newline at end of file diff --git a/src/platform/macos/window_manager_macos.mm b/src/platform/macos/window_manager_macos.mm index 671343e..444c749 100644 --- a/src/platform/macos/window_manager_macos.mm +++ b/src/platform/macos/window_manager_macos.mm @@ -6,11 +6,198 @@ #include "../../window.h" #include "../../window_manager.h" +// Forward declaration for the delegate +@class NativeAPIWindowManagerDelegate; + +namespace nativeapi { + +// Private implementation to hide Objective-C details +class WindowManager::WindowManagerImpl { +public: + WindowManagerImpl(WindowManager* manager); + ~WindowManagerImpl(); + + void SetupEventMonitoring(); + void CleanupEventMonitoring(); + void OnWindowEvent(NSWindow* window, const std::string& event_type); + +private: + WindowManager* manager_; + NativeAPIWindowManagerDelegate* delegate_; +}; + +} // namespace nativeapi + +// Objective-C delegate class to handle NSWindow notifications +@interface NativeAPIWindowManagerDelegate : NSObject +@property (nonatomic, assign) nativeapi::WindowManager::WindowManagerImpl* impl; +- (instancetype)initWithImpl:(nativeapi::WindowManager::WindowManagerImpl*)impl; +@end + +@implementation NativeAPIWindowManagerDelegate + +- (instancetype)initWithImpl:(nativeapi::WindowManager::WindowManagerImpl*)impl { + if (self = [super init]) { + _impl = impl; + } + return self; +} + +- (void)windowDidBecomeKey:(NSNotification*)notification { + NSWindow* window = [notification object]; + if (_impl) { + _impl->OnWindowEvent(window, "focused"); + } +} + +- (void)windowDidResignKey:(NSNotification*)notification { + NSWindow* window = [notification object]; + if (_impl) { + _impl->OnWindowEvent(window, "blurred"); + } +} + +- (void)windowDidMiniaturize:(NSNotification*)notification { + NSWindow* window = [notification object]; + if (_impl) { + _impl->OnWindowEvent(window, "minimized"); + } +} + +- (void)windowDidDeminiaturize:(NSNotification*)notification { + NSWindow* window = [notification object]; + if (_impl) { + _impl->OnWindowEvent(window, "restored"); + } +} + +- (void)windowDidResize:(NSNotification*)notification { + NSWindow* window = [notification object]; + if (_impl) { + _impl->OnWindowEvent(window, "resized"); + } +} + +- (void)windowDidMove:(NSNotification*)notification { + NSWindow* window = [notification object]; + if (_impl) { + _impl->OnWindowEvent(window, "moved"); + } +} + +- (void)windowWillClose:(NSNotification*)notification { + NSWindow* window = [notification object]; + if (_impl) { + _impl->OnWindowEvent(window, "closing"); + } +} + +@end + namespace nativeapi { -WindowManager::WindowManager() {} +WindowManager::WindowManagerImpl::WindowManagerImpl(WindowManager* manager) + : manager_(manager), delegate_(nullptr) { +} + +WindowManager::WindowManagerImpl::~WindowManagerImpl() { + CleanupEventMonitoring(); +} + +void WindowManager::WindowManagerImpl::SetupEventMonitoring() { + if (!delegate_) { + delegate_ = [[NativeAPIWindowManagerDelegate alloc] initWithImpl:this]; + + NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; + [center addObserver:delegate_ + selector:@selector(windowDidBecomeKey:) + name:NSWindowDidBecomeKeyNotification + object:nil]; + [center addObserver:delegate_ + selector:@selector(windowDidResignKey:) + name:NSWindowDidResignKeyNotification + object:nil]; + [center addObserver:delegate_ + selector:@selector(windowDidMiniaturize:) + name:NSWindowDidMiniaturizeNotification + object:nil]; + [center addObserver:delegate_ + selector:@selector(windowDidDeminiaturize:) + name:NSWindowDidDeminiaturizeNotification + object:nil]; + [center addObserver:delegate_ + selector:@selector(windowDidResize:) + name:NSWindowDidResizeNotification + object:nil]; + [center addObserver:delegate_ + selector:@selector(windowDidMove:) + name:NSWindowDidMoveNotification + object:nil]; + [center addObserver:delegate_ + selector:@selector(windowWillClose:) + name:NSWindowWillCloseNotification + object:nil]; + } +} + +void WindowManager::WindowManagerImpl::CleanupEventMonitoring() { + if (delegate_) { + NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; + [center removeObserver:delegate_]; + delegate_ = nil; + } +} + +void WindowManager::WindowManagerImpl::OnWindowEvent(NSWindow* window, const std::string& event_type) { + WindowID window_id = [window windowNumber]; + + if (event_type == "focused") { + WindowFocusedEvent event(window_id); + manager_->DispatchWindowEvent(event); + } else if (event_type == "blurred") { + WindowBlurredEvent event(window_id); + manager_->DispatchWindowEvent(event); + } else if (event_type == "minimized") { + WindowMinimizedEvent event(window_id); + manager_->DispatchWindowEvent(event); + } else if (event_type == "restored") { + WindowRestoredEvent event(window_id); + manager_->DispatchWindowEvent(event); + } else if (event_type == "resized") { + NSRect frame = [window frame]; + Size new_size = {frame.size.width, frame.size.height}; + WindowResizedEvent event(window_id, new_size); + manager_->DispatchWindowEvent(event); + } else if (event_type == "moved") { + NSRect frame = [window frame]; + Point new_position = {frame.origin.x, frame.origin.y}; + WindowMovedEvent event(window_id, new_position); + manager_->DispatchWindowEvent(event); + } else if (event_type == "closing") { + WindowClosedEvent event(window_id); + manager_->DispatchWindowEvent(event); + } +} + +WindowManager::WindowManager() : impl_(std::make_unique(this)) { + SetupEventMonitoring(); +} + +WindowManager::~WindowManager() { + CleanupEventMonitoring(); +} + +void WindowManager::SetupEventMonitoring() { + impl_->SetupEventMonitoring(); +} -WindowManager::~WindowManager() {} +void WindowManager::CleanupEventMonitoring() { + impl_->CleanupEventMonitoring(); +} + +void WindowManager::DispatchWindowEvent(const Event& event) { + event_dispatcher_.DispatchSync(event); +} // Create a new window with the given options. std::shared_ptr WindowManager::Create(const WindowOptions& options) { @@ -28,9 +215,33 @@ WindowID window_id = [ns_window windowNumber]; auto window = std::make_shared((__bridge void*)ns_window); windows_[window_id] = window; + + // Dispatch window created event + WindowCreatedEvent created_event(window_id); + DispatchWindowEvent(created_event); + return window; } +// Destroy a window by its ID. Returns true if window was destroyed. +bool WindowManager::Destroy(WindowID id) { + auto it = windows_.find(id); + if (it != windows_.end()) { + // Get the NSWindow to close it + NSArray* ns_windows = [[NSApplication sharedApplication] windows]; + for (NSWindow* ns_window in ns_windows) { + if ([ns_window windowNumber] == id) { + [ns_window close]; + windows_.erase(it); + return true; + } + } + // Remove from our map even if we couldn't find the NSWindow + windows_.erase(it); + } + return false; +} + std::shared_ptr WindowManager::Get(WindowID id) { auto it = windows_.find(id); if (it != windows_.end()) { diff --git a/src/platform/windows/window_manager_windows.cpp b/src/platform/windows/window_manager_windows.cpp index c1a4450..1f86143 100644 --- a/src/platform/windows/window_manager_windows.cpp +++ b/src/platform/windows/window_manager_windows.cpp @@ -11,9 +11,43 @@ namespace nativeapi { -WindowManager::WindowManager() {} +// Private implementation for Windows (stub for now) +class WindowManager::WindowManagerImpl { +public: + WindowManagerImpl(WindowManager* manager) : manager_(manager) {} + ~WindowManagerImpl() {} + + void SetupEventMonitoring() { + // TODO: Implement Windows-specific event monitoring + } + + void CleanupEventMonitoring() { + // TODO: Implement Windows-specific cleanup + } + +private: + WindowManager* manager_; +}; -WindowManager::~WindowManager() {} +WindowManager::WindowManager() : impl_(std::make_unique(this)) { + SetupEventMonitoring(); +} + +WindowManager::~WindowManager() { + CleanupEventMonitoring(); +} + +void WindowManager::SetupEventMonitoring() { + impl_->SetupEventMonitoring(); +} + +void WindowManager::CleanupEventMonitoring() { + impl_->CleanupEventMonitoring(); +} + +void WindowManager::DispatchWindowEvent(const Event& event) { + event_dispatcher_.DispatchSync(event); +} std::shared_ptr WindowManager::Get(WindowID id) { auto it = windows_.find(id); @@ -76,6 +110,25 @@ std::vector> WindowManager::GetAll() { return result; } +std::shared_ptr WindowManager::Create(const WindowOptions& options) { + // TODO: Implement Windows window creation + // For now, return nullptr as this is a stub implementation + return nullptr; +} + +bool WindowManager::Destroy(WindowID id) { + auto it = windows_.find(id); + if (it != windows_.end()) { + HWND hwnd = reinterpret_cast(id); + if (IsWindow(hwnd)) { + DestroyWindow(hwnd); + } + windows_.erase(it); + return true; + } + return false; +} + std::shared_ptr WindowManager::GetCurrent() { HWND hwnd = GetForegroundWindow(); if (hwnd) { diff --git a/src/window_manager.h b/src/window_manager.h index f428422..5b4648d 100644 --- a/src/window_manager.h +++ b/src/window_manager.h @@ -1,13 +1,140 @@ #pragma once +#include #include #include #include +#include "event.h" +#include "event_dispatcher.h" +#include "geometry.h" #include "window.h" namespace nativeapi { +/** + * Event class for window creation + */ +class WindowCreatedEvent : public TypedEvent { + public: + explicit WindowCreatedEvent(WindowID window_id) : window_id_(window_id) {} + + WindowID GetWindowId() const { return window_id_; } + + private: + WindowID window_id_; +}; + +/** + * Event class for window closure + */ +class WindowClosedEvent : public TypedEvent { + public: + explicit WindowClosedEvent(WindowID window_id) : window_id_(window_id) {} + + WindowID GetWindowId() const { return window_id_; } + + private: + WindowID window_id_; +}; + +/** + * Event class for window focus gained + */ +class WindowFocusedEvent : public TypedEvent { + public: + explicit WindowFocusedEvent(WindowID window_id) : window_id_(window_id) {} + + WindowID GetWindowId() const { return window_id_; } + + private: + WindowID window_id_; +}; + +/** + * Event class for window focus lost + */ +class WindowBlurredEvent : public TypedEvent { + public: + explicit WindowBlurredEvent(WindowID window_id) : window_id_(window_id) {} + + WindowID GetWindowId() const { return window_id_; } + + private: + WindowID window_id_; +}; + +/** + * Event class for window minimized + */ +class WindowMinimizedEvent : public TypedEvent { + public: + explicit WindowMinimizedEvent(WindowID window_id) : window_id_(window_id) {} + + WindowID GetWindowId() const { return window_id_; } + + private: + WindowID window_id_; +}; + +/** + * Event class for window maximized + */ +class WindowMaximizedEvent : public TypedEvent { + public: + explicit WindowMaximizedEvent(WindowID window_id) : window_id_(window_id) {} + + WindowID GetWindowId() const { return window_id_; } + + private: + WindowID window_id_; +}; + +/** + * Event class for window restored + */ +class WindowRestoredEvent : public TypedEvent { + public: + explicit WindowRestoredEvent(WindowID window_id) : window_id_(window_id) {} + + WindowID GetWindowId() const { return window_id_; } + + private: + WindowID window_id_; +}; + +/** + * Event class for window moved + */ +class WindowMovedEvent : public TypedEvent { + public: + WindowMovedEvent(WindowID window_id, Point new_position) + : window_id_(window_id), new_position_(new_position) {} + + WindowID GetWindowId() const { return window_id_; } + Point GetNewPosition() const { return new_position_; } + + private: + WindowID window_id_; + Point new_position_; +}; + +/** + * Event class for window resized + */ +class WindowResizedEvent : public TypedEvent { + public: + WindowResizedEvent(WindowID window_id, Size new_size) + : window_id_(window_id), new_size_(new_size) {} + + WindowID GetWindowId() const { return window_id_; } + Size GetNewSize() const { return new_size_; } + + private: + WindowID window_id_; + Size new_size_; +}; + // WindowManager is a singleton that manages all windows on the system. class WindowManager { public: @@ -29,9 +156,45 @@ class WindowManager { // Destroy a window by its ID. Returns true if window was destroyed. bool Destroy(WindowID id); + // Event dispatcher methods for window events + template + size_t AddListener(TypedEventListener* listener) { + return event_dispatcher_.AddListener(listener); + } + + template + size_t AddListener(std::function callback) { + return event_dispatcher_.AddListener(std::move(callback)); + } + + bool RemoveListener(size_t listener_id) { + return event_dispatcher_.RemoveListener(listener_id); + } + + // Get the event dispatcher (for advanced usage) + EventDispatcher& GetEventDispatcher() { return event_dispatcher_; } + private: + // Forward declaration for platform-specific implementation + class WindowManagerImpl; + // Store window instances std::unordered_map> windows_; + + // Event dispatcher for window events + EventDispatcher event_dispatcher_; + + // Platform-specific implementation + std::unique_ptr impl_; + + // Platform-specific method to set up event monitoring + void SetupEventMonitoring(); + + // Platform-specific method to clean up event monitoring + void CleanupEventMonitoring(); + + // Internal method to dispatch window events + void DispatchWindowEvent(const Event& event); }; } // namespace nativeapi