From: Robert Roebling Date: Sun, 6 Feb 2005 18:24:02 +0000 (+0000) Subject: I think I found out how GTK+ want popup windows X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/f7204798e2b7db9e5ebd94c327ed0fef72b18862 I think I found out how GTK+ want popup windows to be handled... git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@31804 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/src/common/popupcmn.cpp b/src/common/popupcmn.cpp index 85124079c6..0c94b3838d 100644 --- a/src/common/popupcmn.cpp +++ b/src/common/popupcmn.cpp @@ -85,16 +85,7 @@ public: } protected: - // event handlers -#ifdef __WXMSW__ - // Under MSW, we catch the kill focus event void OnKillFocus(wxFocusEvent& event); -#else - // Under GTK+, event a transient popup window - // is a toplevel window so we need to catch - // deactivate events - void OnActivate(wxActivateEvent &event); -#endif void OnKeyDown(wxKeyEvent& event); private: @@ -113,11 +104,7 @@ BEGIN_EVENT_TABLE(wxPopupWindowHandler, wxEvtHandler) END_EVENT_TABLE() BEGIN_EVENT_TABLE(wxPopupFocusHandler, wxEvtHandler) -#ifdef __WXMSW__ EVT_KILL_FOCUS(wxPopupFocusHandler::OnKillFocus) -#else - EVT_ACTIVATE(wxPopupFocusHandler::OnActivate) -#endif EVT_KEY_DOWN(wxPopupFocusHandler::OnKeyDown) END_EVENT_TABLE() @@ -258,7 +245,7 @@ void wxPopupTransientWindow::Popup(wxWindow *winFocus) delete m_handlerPopup; m_handlerPopup = new wxPopupWindowHandler(this); - m_child->CaptureMouse(); + // m_child->CaptureMouse(); m_child->PushEventHandler(m_handlerPopup); m_focus = winFocus ? winFocus : this; @@ -474,7 +461,6 @@ void wxPopupWindowHandler::OnLeftDown(wxMouseEvent& event) // wxPopupFocusHandler // ---------------------------------------------------------------------------- -#ifdef __WXMSW__ void wxPopupFocusHandler::OnKillFocus(wxFocusEvent& event) { // when we lose focus we always disappear - unless it goes to the popup (in @@ -489,13 +475,6 @@ void wxPopupFocusHandler::OnKillFocus(wxFocusEvent& event) m_popup->DismissAndNotify(); } -#else -void wxPopupFocusHandler::OnActivate(wxActivateEvent &event) -{ - if (event.GetActive()) - m_popup->DismissAndNotify(); -} -#endif void wxPopupFocusHandler::OnKeyDown(wxKeyEvent& event) { diff --git a/src/gtk/popupwin.cpp b/src/gtk/popupwin.cpp index 3a4cb03db0..4e9908879b 100644 --- a/src/gtk/popupwin.cpp +++ b/src/gtk/popupwin.cpp @@ -34,6 +34,39 @@ extern void wxapp_install_idle_handler(); extern bool g_isIdle; +//----------------------------------------------------------------------------- +// "button_press" +//----------------------------------------------------------------------------- + +static gint gtk_popup_button_press (GtkWidget *widget, GdkEvent *gdk_event, wxPopupWindow* win ) +{ + GtkWidget *child = gtk_get_event_widget (gdk_event); + + /* We don't ask for button press events on the grab widget, so + * if an event is reported directly to the grab widget, it must + * be on a window outside the application (and thus we remove + * the popup window). Otherwise, we check if the widget is a child + * of the grab widget, and only remove the popup window if it + * is not. + */ + if (child != widget) + { + while (child) + { + if (child == widget) + return FALSE; + child = child->parent; + } + } + + wxFocusEvent event( wxEVT_KILL_FOCUS, win->GetId() ); + event.SetEventObject( win ); + + (void)win->GetEventHandler()->ProcessEvent( event ); + + return TRUE; +} + //----------------------------------------------------------------------------- // "focus" from m_window //----------------------------------------------------------------------------- @@ -103,11 +136,7 @@ gtk_dialog_realized_callback( GtkWidget * WXUNUSED(widget), wxPopupWindow *win ) gdk_window_set_decorations( win->m_widget->window, (GdkWMDecoration)decor); gdk_window_set_functions( win->m_widget->window, (GdkWMFunction)func); - /* GTK's shrinking/growing policy */ - if ((win->GetWindowStyle() & wxRESIZE_BORDER) == 0) - gtk_window_set_policy(GTK_WINDOW(win->m_widget), 0, 0, 1); - else - gtk_window_set_policy(GTK_WINDOW(win->m_widget), 1, 1, 1); + gtk_window_set_policy(GTK_WINDOW(win->m_widget), 0, 0, 1); return FALSE; } @@ -193,14 +222,17 @@ bool wxPopupWindow::Create( wxWindow *parent, int style ) gtk_signal_connect( GTK_OBJECT(m_widget), "realize", GTK_SIGNAL_FUNC(gtk_dialog_realized_callback), (gpointer) this ); - /* the user resized the frame by dragging etc. */ + // the user resized the frame by dragging etc. gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate", GTK_SIGNAL_FUNC(gtk_dialog_size_callback), (gpointer)this ); - /* disable native tab traversal */ + // disable native tab traversal gtk_signal_connect( GTK_OBJECT(m_widget), "focus", GTK_SIGNAL_FUNC(gtk_dialog_focus_callback), (gpointer)this ); + g_signal_connect (GTK_OBJECT(m_widget), "button_press_event", + G_CALLBACK(gtk_popup_button_press), (gpointer)this ); + return TRUE; } diff --git a/src/gtk1/popupwin.cpp b/src/gtk1/popupwin.cpp index 3a4cb03db0..4e9908879b 100644 --- a/src/gtk1/popupwin.cpp +++ b/src/gtk1/popupwin.cpp @@ -34,6 +34,39 @@ extern void wxapp_install_idle_handler(); extern bool g_isIdle; +//----------------------------------------------------------------------------- +// "button_press" +//----------------------------------------------------------------------------- + +static gint gtk_popup_button_press (GtkWidget *widget, GdkEvent *gdk_event, wxPopupWindow* win ) +{ + GtkWidget *child = gtk_get_event_widget (gdk_event); + + /* We don't ask for button press events on the grab widget, so + * if an event is reported directly to the grab widget, it must + * be on a window outside the application (and thus we remove + * the popup window). Otherwise, we check if the widget is a child + * of the grab widget, and only remove the popup window if it + * is not. + */ + if (child != widget) + { + while (child) + { + if (child == widget) + return FALSE; + child = child->parent; + } + } + + wxFocusEvent event( wxEVT_KILL_FOCUS, win->GetId() ); + event.SetEventObject( win ); + + (void)win->GetEventHandler()->ProcessEvent( event ); + + return TRUE; +} + //----------------------------------------------------------------------------- // "focus" from m_window //----------------------------------------------------------------------------- @@ -103,11 +136,7 @@ gtk_dialog_realized_callback( GtkWidget * WXUNUSED(widget), wxPopupWindow *win ) gdk_window_set_decorations( win->m_widget->window, (GdkWMDecoration)decor); gdk_window_set_functions( win->m_widget->window, (GdkWMFunction)func); - /* GTK's shrinking/growing policy */ - if ((win->GetWindowStyle() & wxRESIZE_BORDER) == 0) - gtk_window_set_policy(GTK_WINDOW(win->m_widget), 0, 0, 1); - else - gtk_window_set_policy(GTK_WINDOW(win->m_widget), 1, 1, 1); + gtk_window_set_policy(GTK_WINDOW(win->m_widget), 0, 0, 1); return FALSE; } @@ -193,14 +222,17 @@ bool wxPopupWindow::Create( wxWindow *parent, int style ) gtk_signal_connect( GTK_OBJECT(m_widget), "realize", GTK_SIGNAL_FUNC(gtk_dialog_realized_callback), (gpointer) this ); - /* the user resized the frame by dragging etc. */ + // the user resized the frame by dragging etc. gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate", GTK_SIGNAL_FUNC(gtk_dialog_size_callback), (gpointer)this ); - /* disable native tab traversal */ + // disable native tab traversal gtk_signal_connect( GTK_OBJECT(m_widget), "focus", GTK_SIGNAL_FUNC(gtk_dialog_focus_callback), (gpointer)this ); + g_signal_connect (GTK_OBJECT(m_widget), "button_press_event", + G_CALLBACK(gtk_popup_button_press), (gpointer)this ); + return TRUE; }