From 39fdb0fd6f44760b171bee9403448ffbf626eba7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 17 Sep 2025 13:17:02 +0000 Subject: [PATCH 1/2] Initial plan From 0dd35f88e0984549194a2bd4ac8f9c3713f499a9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 17 Sep 2025 13:27:02 +0000 Subject: [PATCH 2/2] Fix Linux compilation errors in platform-specific code Co-authored-by: lijy91 <3889523+lijy91@users.noreply.github.com> --- src/platform/linux/display_manager_linux.cpp | 4 ++ src/platform/linux/keyboard_monitor_linux.cpp | 14 ++-- src/platform/linux/menu_linux.cpp | 71 +++++-------------- src/platform/linux/tray_icon_linux.cpp | 26 ++----- src/platform/linux/window_manager_linux.cpp | 14 ++-- 5 files changed, 40 insertions(+), 89 deletions(-) diff --git a/src/platform/linux/display_manager_linux.cpp b/src/platform/linux/display_manager_linux.cpp index d47f862..7b9d0e3 100644 --- a/src/platform/linux/display_manager_linux.cpp +++ b/src/platform/linux/display_manager_linux.cpp @@ -38,6 +38,10 @@ DisplayManager::DisplayManager() { std::cout << "DisplayManager initialized" << std::endl; } +DisplayManager::~DisplayManager() { + // Destructor implementation +} + std::vector DisplayManager::GetAll() { // Empty implementation std::vector displayList; diff --git a/src/platform/linux/keyboard_monitor_linux.cpp b/src/platform/linux/keyboard_monitor_linux.cpp index 54f0c5e..c58b2fc 100644 --- a/src/platform/linux/keyboard_monitor_linux.cpp +++ b/src/platform/linux/keyboard_monitor_linux.cpp @@ -37,7 +37,7 @@ class KeyboardMonitor::Impl { uint32_t GetModifierState(); }; -KeyboardMonitor::KeyboardMonitor() : impl_(std::make_unique(this)), event_dispatcher_() {} +KeyboardMonitor::KeyboardMonitor() : impl_(std::make_unique(this)) {} KeyboardMonitor::~KeyboardMonitor() { Stop(); @@ -156,16 +156,16 @@ void KeyboardMonitor::Impl::MonitoringLoop() { if (xi_event->evtype == XI_KeyPress) { KeyPressedEvent key_event(xi_event->detail); - monitor_->DispatchEvent(key_event); + monitor_->EmitSync(key_event); ModifierKeysChangedEvent modifier_event(GetModifierState()); - monitor_->DispatchEvent(modifier_event); + monitor_->EmitSync(modifier_event); } else if (xi_event->evtype == XI_KeyRelease) { KeyReleasedEvent key_event(xi_event->detail); - monitor_->DispatchEvent(key_event); + monitor_->EmitSync(key_event); ModifierKeysChangedEvent modifier_event(GetModifierState()); - monitor_->DispatchEvent(modifier_event); + monitor_->EmitSync(modifier_event); } XFreeEventData(display_, &event.xcookie); @@ -216,8 +216,4 @@ bool KeyboardMonitor::IsMonitoring() const { return impl_->monitoring_; } -void KeyboardMonitor::DispatchEvent(const Event& event) { - event_dispatcher_.DispatchSync(event); -} - } // namespace nativeapi \ No newline at end of file diff --git a/src/platform/linux/menu_linux.cpp b/src/platform/linux/menu_linux.cpp index 01b6cd8..07e2030 100644 --- a/src/platform/linux/menu_linux.cpp +++ b/src/platform/linux/menu_linux.cpp @@ -16,49 +16,36 @@ class MenuItem::Impl { std::string tooltip_; }; -MenuItem::MenuItem() : pimpl_(new Impl(nullptr)) { - id = -1; -} - MenuItem::MenuItem(void* menu_item) : pimpl_(new Impl((GtkWidget*)menu_item)) { - id = -1; } MenuItem::~MenuItem() { - delete pimpl_; } -void MenuItem::SetIcon(std::string icon) { +void MenuItem::SetIcon(const std::string& icon) { pimpl_->icon_ = icon; // TODO: Implement icon setting for GTK menu item } -std::string MenuItem::GetIcon() { +std::string MenuItem::GetIcon() const { return pimpl_->icon_; } -void MenuItem::SetTitle(std::string title) { - pimpl_->title_ = title; - if (pimpl_->gtk_menu_item_) { - gtk_menu_item_set_label(GTK_MENU_ITEM(pimpl_->gtk_menu_item_), title.c_str()); - } -} - -std::string MenuItem::GetTitle() { - return pimpl_->title_; -} - -void MenuItem::SetTooltip(std::string tooltip) { +void MenuItem::SetTooltip(const std::string& tooltip) { pimpl_->tooltip_ = tooltip; if (pimpl_->gtk_menu_item_) { gtk_widget_set_tooltip_text(pimpl_->gtk_menu_item_, tooltip.c_str()); } } -std::string MenuItem::GetTooltip() { +std::string MenuItem::GetTooltip() const { return pimpl_->tooltip_; } +void* MenuItem::GetNativeItem() const { + return (void*)pimpl_->gtk_menu_item_; +} + // Private implementation class for Menu class Menu::Impl { public: @@ -67,54 +54,30 @@ class Menu::Impl { GtkWidget* gtk_menu_; }; -Menu::Menu() : pimpl_(new Impl(gtk_menu_new())) { - id = -1; -} - Menu::Menu(void* menu) : pimpl_(new Impl((GtkWidget*)menu)) { - id = -1; } Menu::~Menu() { if (pimpl_->gtk_menu_) { g_object_unref(pimpl_->gtk_menu_); } - delete pimpl_; -} - -void Menu::AddItem(MenuItem item) { - if (pimpl_->gtk_menu_ && item.pimpl_->gtk_menu_item_) { - gtk_menu_shell_append(GTK_MENU_SHELL(pimpl_->gtk_menu_), item.pimpl_->gtk_menu_item_); - } } -void Menu::RemoveItem(MenuItem item) { - if (pimpl_->gtk_menu_ && item.pimpl_->gtk_menu_item_) { - gtk_container_remove(GTK_CONTAINER(pimpl_->gtk_menu_), item.pimpl_->gtk_menu_item_); +void Menu::AddItem(std::shared_ptr item) { + if (pimpl_->gtk_menu_ && item && item->GetNativeItem()) { + gtk_menu_shell_append(GTK_MENU_SHELL(pimpl_->gtk_menu_), (GtkWidget*)item->GetNativeItem()); } } -void Menu::AddSeparator() { - if (pimpl_->gtk_menu_) { - GtkWidget* separator = gtk_separator_menu_item_new(); - gtk_menu_shell_append(GTK_MENU_SHELL(pimpl_->gtk_menu_), separator); +bool Menu::RemoveItem(std::shared_ptr item) { + if (pimpl_->gtk_menu_ && item && item->GetNativeItem()) { + gtk_container_remove(GTK_CONTAINER(pimpl_->gtk_menu_), (GtkWidget*)item->GetNativeItem()); + return true; } + return false; } -MenuItem Menu::CreateItem(std::string title) { - GtkWidget* menu_item = gtk_menu_item_new_with_label(title.c_str()); - MenuItem item(menu_item); - item.SetTitle(title); - return item; -} - -MenuItem Menu::CreateItem(std::string title, std::string icon) { - MenuItem item = CreateItem(title); - item.SetIcon(icon); - return item; -} - -void* Menu::GetNativeMenu() { +void* Menu::GetNativeMenu() const { return (void*)pimpl_->gtk_menu_; } diff --git a/src/platform/linux/tray_icon_linux.cpp b/src/platform/linux/tray_icon_linux.cpp index 5d5217a..2602341 100644 --- a/src/platform/linux/tray_icon_linux.cpp +++ b/src/platform/linux/tray_icon_linux.cpp @@ -12,10 +12,10 @@ namespace nativeapi { // Private implementation class class TrayIcon::Impl { public: - Impl(GtkStatusIcon* tray) : gtk_status_icon_(tray), title_(""), tooltip_("") {} + Impl(GtkStatusIcon* tray) : gtk_status_icon_(tray), title_(""), tooltip_(""), context_menu_(nullptr) {} GtkStatusIcon* gtk_status_icon_; - Menu context_menu_; // Store menu object to keep it alive + std::shared_ptr context_menu_; // Store menu shared_ptr to keep it alive std::string title_; // GTK StatusIcon doesn't have title, so we store it std::string tooltip_; }; @@ -113,15 +113,15 @@ std::string TrayIcon::GetTooltip() { } void TrayIcon::SetContextMenu(std::shared_ptr menu) { - // Store the menu object to keep it alive - pimpl_->context_menu_ = *menu; + // Store the menu shared_ptr to keep it alive + pimpl_->context_menu_ = menu; // Note: Full GTK integration would need to connect popup-menu signal // and show the GTK menu from the Menu object's GetNativeMenu() } std::shared_ptr TrayIcon::GetContextMenu() { - return std::make_shared(pimpl_->context_menu_); + return pimpl_->context_menu_; } Rectangle TrayIcon::GetBounds() { @@ -166,20 +166,8 @@ bool TrayIcon::IsVisible() { return false; } -void TrayIcon::SetOnLeftClick(std::function callback) { - // This method is deprecated - use event listeners instead -} - -void TrayIcon::SetOnRightClick(std::function callback) { - // This method is deprecated - use event listeners instead -} - -void TrayIcon::SetOnDoubleClick(std::function callback) { - // This method is deprecated - use event listeners instead -} - bool TrayIcon::ShowContextMenu(double x, double y) { - if (!pimpl_->context_menu_.GetNativeMenu()) { + if (!pimpl_->context_menu_ || !pimpl_->context_menu_->GetNativeMenu()) { return false; } @@ -189,7 +177,7 @@ bool TrayIcon::ShowContextMenu(double x, double y) { } bool TrayIcon::ShowContextMenu() { - if (!pimpl_->context_menu_.GetNativeMenu()) { + if (!pimpl_->context_menu_ || !pimpl_->context_menu_->GetNativeMenu()) { return false; } diff --git a/src/platform/linux/window_manager_linux.cpp b/src/platform/linux/window_manager_linux.cpp index 00a2bd3..2575bf2 100644 --- a/src/platform/linux/window_manager_linux.cpp +++ b/src/platform/linux/window_manager_linux.cpp @@ -12,10 +12,10 @@ namespace nativeapi { // Private implementation for Linux (stub for now) -class WindowManager::WindowManagerImpl { +class WindowManager::Impl { public: - WindowManagerImpl(WindowManager* manager) : manager_(manager) {} - ~WindowManagerImpl() {} + Impl(WindowManager* manager) : manager_(manager) {} + ~Impl() {} void SetupEventMonitoring() { // TODO: Implement Linux-specific event monitoring using GTK signals @@ -29,7 +29,7 @@ class WindowManager::WindowManagerImpl { WindowManager* manager_; }; -WindowManager::WindowManager() : impl_(std::make_unique(this)) { +WindowManager::WindowManager() : pimpl_(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()) { @@ -56,15 +56,15 @@ WindowManager::~WindowManager() { } void WindowManager::SetupEventMonitoring() { - impl_->SetupEventMonitoring(); + pimpl_->SetupEventMonitoring(); } void WindowManager::CleanupEventMonitoring() { - impl_->CleanupEventMonitoring(); + pimpl_->CleanupEventMonitoring(); } void WindowManager::DispatchWindowEvent(const Event& event) { - event_dispatcher_.DispatchSync(event); + EmitSync(event); } std::shared_ptr WindowManager::Get(WindowID id) {