From 0bd3b8eca1d6ef2749797f34216493fce0edd8d6 Mon Sep 17 00:00:00 2001 From: Robert Roebling Date: Sun, 23 Jan 2005 22:39:03 +0000 Subject: [PATCH] Enable UpdateUI events in wxTaskBarIcon. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@31572 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/gtk/taskbarpriv.h | 6 +++ include/wx/gtk1/taskbarpriv.h | 6 +++ src/gtk/taskbar.cpp | 75 +++++++++++++++++++++++++++++++++++ src/gtk/window.cpp | 7 +++- src/gtk1/taskbar.cpp | 75 +++++++++++++++++++++++++++++++++++ src/gtk1/window.cpp | 7 +++- src/unix/taskbarx11.cpp | 4 ++ 7 files changed, 178 insertions(+), 2 deletions(-) diff --git a/include/wx/gtk/taskbarpriv.h b/include/wx/gtk/taskbarpriv.h index 117e4cd04b..03d2093f7e 100644 --- a/include/wx/gtk/taskbarpriv.h +++ b/include/wx/gtk/taskbarpriv.h @@ -26,6 +26,12 @@ public: // Returns true if SYSTRAY protocol is supported by the desktop bool IsProtocolSupported(); + + wxEvtHandler *m_invokingWindow; + +#if wxUSE_MENUS_NATIVE + virtual bool DoPopupMenu( wxMenu *menu, int x, int y ); +#endif // wxUSE_MENUS_NATIVE }; #endif // _WX_TASKBARPRIV_H_ diff --git a/include/wx/gtk1/taskbarpriv.h b/include/wx/gtk1/taskbarpriv.h index 117e4cd04b..03d2093f7e 100644 --- a/include/wx/gtk1/taskbarpriv.h +++ b/include/wx/gtk1/taskbarpriv.h @@ -26,6 +26,12 @@ public: // Returns true if SYSTRAY protocol is supported by the desktop bool IsProtocolSupported(); + + wxEvtHandler *m_invokingWindow; + +#if wxUSE_MENUS_NATIVE + virtual bool DoPopupMenu( wxMenu *menu, int x, int y ); +#endif // wxUSE_MENUS_NATIVE }; #endif // _WX_TASKBARPRIV_H_ diff --git a/src/gtk/taskbar.cpp b/src/gtk/taskbar.cpp index be0e53af49..cc61da167e 100644 --- a/src/gtk/taskbar.cpp +++ b/src/gtk/taskbar.cpp @@ -19,6 +19,7 @@ #include "wx/gtk/taskbarpriv.h" #include "wx/log.h" #include "wx/frame.h" +#include "wx/menu.h" #include @@ -26,6 +27,8 @@ #include #if GTK_CHECK_VERSION(2, 1, 0) +#include "gtk/gtk.h" + #include "eggtrayicon.h" wxTaskBarIconAreaBase::wxTaskBarIconAreaBase() @@ -44,6 +47,8 @@ wxTaskBarIconAreaBase::wxTaskBarIconAreaBase() wxDEFAULT_FRAME_STYLE | wxFRAME_NO_TASKBAR | wxSIMPLE_BORDER | wxFRAME_SHAPED, wxEmptyString /*eggtray doesn't like setting wmclass*/); + + m_invokingWindow = NULL; } bool wxTaskBarIconAreaBase::IsProtocolSupported() @@ -66,5 +71,75 @@ bool wxTaskBarIconAreaBase::IsProtocolSupported() return (bool)s_supported; } +//----------------------------------------------------------------------------- +// Pop-up menu stuff +//----------------------------------------------------------------------------- + +extern "C" void gtk_pop_hide_callback( GtkWidget *widget, bool* is_waiting ); + +extern void SetInvokingWindow( wxMenu *menu, wxWindow* win ); + +extern "C" void wxPopupMenuPositionCallback( GtkMenu *menu, + gint *x, gint *y, + gboolean * WXUNUSED(whatever), + gpointer user_data ); + +bool wxTaskBarIconAreaBase::DoPopupMenu( wxMenu *menu, int x, int y ) +{ + wxCHECK_MSG( m_widget != NULL, false, wxT("invalid window") ); + + wxCHECK_MSG( menu != NULL, false, wxT("invalid popup-menu") ); + + // NOTE: if you change this code, you need to update + // the same code in window.cpp as well. This + // is ugly code duplication, I know, + + SetInvokingWindow( menu, this ); + + menu->UpdateUI( m_invokingWindow ); + + bool is_waiting = true; + + gulong handler = gtk_signal_connect( GTK_OBJECT(menu->m_menu), + "hide", + GTK_SIGNAL_FUNC(gtk_pop_hide_callback), + (gpointer)&is_waiting ); + + wxPoint pos; + gpointer userdata; + GtkMenuPositionFunc posfunc; + if ( x == -1 && y == -1 ) + { + // use GTK's default positioning algorithm + userdata = NULL; + posfunc = NULL; + } + else + { + pos = ClientToScreen(wxPoint(x, y)); + userdata = &pos; + posfunc = wxPopupMenuPositionCallback; + } + + gtk_menu_popup( + GTK_MENU(menu->m_menu), + (GtkWidget *) NULL, // parent menu shell + (GtkWidget *) NULL, // parent menu item + posfunc, // function to position it + userdata, // client data + 0, // button used to activate it + gtk_get_current_event_time() + ); + + while (is_waiting) + { + gtk_main_iteration(); + } + + gtk_signal_disconnect(GTK_OBJECT(menu->m_menu), handler); + + return true; +} + #endif // __WXGTK20__ #endif // GTK_CHECK_VERSION(2, 1, 0) diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index c2de0e2f97..1f90bd83f2 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -4237,9 +4237,10 @@ void gtk_pop_hide_callback( GtkWidget *WXUNUSED(widget), bool* is_waiting ) *is_waiting = FALSE; } -static void SetInvokingWindow( wxMenu *menu, wxWindowGTK *win ) +void SetInvokingWindow( wxMenu *menu, wxWindow* win ) { menu->SetInvokingWindow( win ); + wxMenuItemList::compatibility_iterator node = menu->GetMenuItems().GetFirst(); while (node) { @@ -4280,6 +4281,10 @@ bool wxWindowGTK::DoPopupMenu( wxMenu *menu, int x, int y ) wxCHECK_MSG( menu != NULL, false, wxT("invalid popup-menu") ); + // NOTE: if you change this code, you need to update + // the same code in taskbar.cpp as well. This + // is ugly code duplication, I know, + SetInvokingWindow( menu, this ); menu->UpdateUI(); diff --git a/src/gtk1/taskbar.cpp b/src/gtk1/taskbar.cpp index be0e53af49..cc61da167e 100644 --- a/src/gtk1/taskbar.cpp +++ b/src/gtk1/taskbar.cpp @@ -19,6 +19,7 @@ #include "wx/gtk/taskbarpriv.h" #include "wx/log.h" #include "wx/frame.h" +#include "wx/menu.h" #include @@ -26,6 +27,8 @@ #include #if GTK_CHECK_VERSION(2, 1, 0) +#include "gtk/gtk.h" + #include "eggtrayicon.h" wxTaskBarIconAreaBase::wxTaskBarIconAreaBase() @@ -44,6 +47,8 @@ wxTaskBarIconAreaBase::wxTaskBarIconAreaBase() wxDEFAULT_FRAME_STYLE | wxFRAME_NO_TASKBAR | wxSIMPLE_BORDER | wxFRAME_SHAPED, wxEmptyString /*eggtray doesn't like setting wmclass*/); + + m_invokingWindow = NULL; } bool wxTaskBarIconAreaBase::IsProtocolSupported() @@ -66,5 +71,75 @@ bool wxTaskBarIconAreaBase::IsProtocolSupported() return (bool)s_supported; } +//----------------------------------------------------------------------------- +// Pop-up menu stuff +//----------------------------------------------------------------------------- + +extern "C" void gtk_pop_hide_callback( GtkWidget *widget, bool* is_waiting ); + +extern void SetInvokingWindow( wxMenu *menu, wxWindow* win ); + +extern "C" void wxPopupMenuPositionCallback( GtkMenu *menu, + gint *x, gint *y, + gboolean * WXUNUSED(whatever), + gpointer user_data ); + +bool wxTaskBarIconAreaBase::DoPopupMenu( wxMenu *menu, int x, int y ) +{ + wxCHECK_MSG( m_widget != NULL, false, wxT("invalid window") ); + + wxCHECK_MSG( menu != NULL, false, wxT("invalid popup-menu") ); + + // NOTE: if you change this code, you need to update + // the same code in window.cpp as well. This + // is ugly code duplication, I know, + + SetInvokingWindow( menu, this ); + + menu->UpdateUI( m_invokingWindow ); + + bool is_waiting = true; + + gulong handler = gtk_signal_connect( GTK_OBJECT(menu->m_menu), + "hide", + GTK_SIGNAL_FUNC(gtk_pop_hide_callback), + (gpointer)&is_waiting ); + + wxPoint pos; + gpointer userdata; + GtkMenuPositionFunc posfunc; + if ( x == -1 && y == -1 ) + { + // use GTK's default positioning algorithm + userdata = NULL; + posfunc = NULL; + } + else + { + pos = ClientToScreen(wxPoint(x, y)); + userdata = &pos; + posfunc = wxPopupMenuPositionCallback; + } + + gtk_menu_popup( + GTK_MENU(menu->m_menu), + (GtkWidget *) NULL, // parent menu shell + (GtkWidget *) NULL, // parent menu item + posfunc, // function to position it + userdata, // client data + 0, // button used to activate it + gtk_get_current_event_time() + ); + + while (is_waiting) + { + gtk_main_iteration(); + } + + gtk_signal_disconnect(GTK_OBJECT(menu->m_menu), handler); + + return true; +} + #endif // __WXGTK20__ #endif // GTK_CHECK_VERSION(2, 1, 0) diff --git a/src/gtk1/window.cpp b/src/gtk1/window.cpp index c2de0e2f97..1f90bd83f2 100644 --- a/src/gtk1/window.cpp +++ b/src/gtk1/window.cpp @@ -4237,9 +4237,10 @@ void gtk_pop_hide_callback( GtkWidget *WXUNUSED(widget), bool* is_waiting ) *is_waiting = FALSE; } -static void SetInvokingWindow( wxMenu *menu, wxWindowGTK *win ) +void SetInvokingWindow( wxMenu *menu, wxWindow* win ) { menu->SetInvokingWindow( win ); + wxMenuItemList::compatibility_iterator node = menu->GetMenuItems().GetFirst(); while (node) { @@ -4280,6 +4281,10 @@ bool wxWindowGTK::DoPopupMenu( wxMenu *menu, int x, int y ) wxCHECK_MSG( menu != NULL, false, wxT("invalid popup-menu") ); + // NOTE: if you change this code, you need to update + // the same code in taskbar.cpp as well. This + // is ugly code duplication, I know, + SetInvokingWindow( menu, this ); menu->UpdateUI(); diff --git a/src/unix/taskbarx11.cpp b/src/unix/taskbarx11.cpp index cf94b21583..1ff4e81348 100644 --- a/src/unix/taskbarx11.cpp +++ b/src/unix/taskbarx11.cpp @@ -131,6 +131,10 @@ wxTaskBarIconArea::wxTaskBarIconArea(wxTaskBarIcon *icon, const wxBitmap &bmp) _T("using legacy KDE1,2 and GNOME 1.2 methods")); SetLegacyWMProperties(); } + +#ifdef __WXGTK20__ + m_invokingWindow = icon; +#endif // Set initial size to bitmap size (tray manager may and often will // change it): -- 2.45.2