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
This commit is contained in:
@@ -85,16 +85,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// event handlers
|
|
||||||
#ifdef __WXMSW__
|
|
||||||
// Under MSW, we catch the kill focus event
|
|
||||||
void OnKillFocus(wxFocusEvent& 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);
|
void OnKeyDown(wxKeyEvent& event);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -113,11 +104,7 @@ BEGIN_EVENT_TABLE(wxPopupWindowHandler, wxEvtHandler)
|
|||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
BEGIN_EVENT_TABLE(wxPopupFocusHandler, wxEvtHandler)
|
BEGIN_EVENT_TABLE(wxPopupFocusHandler, wxEvtHandler)
|
||||||
#ifdef __WXMSW__
|
|
||||||
EVT_KILL_FOCUS(wxPopupFocusHandler::OnKillFocus)
|
EVT_KILL_FOCUS(wxPopupFocusHandler::OnKillFocus)
|
||||||
#else
|
|
||||||
EVT_ACTIVATE(wxPopupFocusHandler::OnActivate)
|
|
||||||
#endif
|
|
||||||
EVT_KEY_DOWN(wxPopupFocusHandler::OnKeyDown)
|
EVT_KEY_DOWN(wxPopupFocusHandler::OnKeyDown)
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
@@ -258,7 +245,7 @@ void wxPopupTransientWindow::Popup(wxWindow *winFocus)
|
|||||||
delete m_handlerPopup;
|
delete m_handlerPopup;
|
||||||
m_handlerPopup = new wxPopupWindowHandler(this);
|
m_handlerPopup = new wxPopupWindowHandler(this);
|
||||||
|
|
||||||
m_child->CaptureMouse();
|
// m_child->CaptureMouse();
|
||||||
m_child->PushEventHandler(m_handlerPopup);
|
m_child->PushEventHandler(m_handlerPopup);
|
||||||
|
|
||||||
m_focus = winFocus ? winFocus : this;
|
m_focus = winFocus ? winFocus : this;
|
||||||
@@ -474,7 +461,6 @@ void wxPopupWindowHandler::OnLeftDown(wxMouseEvent& event)
|
|||||||
// wxPopupFocusHandler
|
// wxPopupFocusHandler
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
#ifdef __WXMSW__
|
|
||||||
void wxPopupFocusHandler::OnKillFocus(wxFocusEvent& event)
|
void wxPopupFocusHandler::OnKillFocus(wxFocusEvent& event)
|
||||||
{
|
{
|
||||||
// when we lose focus we always disappear - unless it goes to the popup (in
|
// 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();
|
m_popup->DismissAndNotify();
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
void wxPopupFocusHandler::OnActivate(wxActivateEvent &event)
|
|
||||||
{
|
|
||||||
if (event.GetActive())
|
|
||||||
m_popup->DismissAndNotify();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void wxPopupFocusHandler::OnKeyDown(wxKeyEvent& event)
|
void wxPopupFocusHandler::OnKeyDown(wxKeyEvent& event)
|
||||||
{
|
{
|
||||||
|
@@ -34,6 +34,39 @@
|
|||||||
extern void wxapp_install_idle_handler();
|
extern void wxapp_install_idle_handler();
|
||||||
extern bool g_isIdle;
|
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
|
// "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_decorations( win->m_widget->window, (GdkWMDecoration)decor);
|
||||||
gdk_window_set_functions( win->m_widget->window, (GdkWMFunction)func);
|
gdk_window_set_functions( win->m_widget->window, (GdkWMFunction)func);
|
||||||
|
|
||||||
/* GTK's shrinking/growing policy */
|
gtk_window_set_policy(GTK_WINDOW(win->m_widget), 0, 0, 1);
|
||||||
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);
|
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -193,14 +222,17 @@ bool wxPopupWindow::Create( wxWindow *parent, int style )
|
|||||||
gtk_signal_connect( GTK_OBJECT(m_widget), "realize",
|
gtk_signal_connect( GTK_OBJECT(m_widget), "realize",
|
||||||
GTK_SIGNAL_FUNC(gtk_dialog_realized_callback), (gpointer) this );
|
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_connect( GTK_OBJECT(m_widget), "size_allocate",
|
||||||
GTK_SIGNAL_FUNC(gtk_dialog_size_callback), (gpointer)this );
|
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_connect( GTK_OBJECT(m_widget), "focus",
|
||||||
GTK_SIGNAL_FUNC(gtk_dialog_focus_callback), (gpointer)this );
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -34,6 +34,39 @@
|
|||||||
extern void wxapp_install_idle_handler();
|
extern void wxapp_install_idle_handler();
|
||||||
extern bool g_isIdle;
|
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
|
// "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_decorations( win->m_widget->window, (GdkWMDecoration)decor);
|
||||||
gdk_window_set_functions( win->m_widget->window, (GdkWMFunction)func);
|
gdk_window_set_functions( win->m_widget->window, (GdkWMFunction)func);
|
||||||
|
|
||||||
/* GTK's shrinking/growing policy */
|
gtk_window_set_policy(GTK_WINDOW(win->m_widget), 0, 0, 1);
|
||||||
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);
|
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -193,14 +222,17 @@ bool wxPopupWindow::Create( wxWindow *parent, int style )
|
|||||||
gtk_signal_connect( GTK_OBJECT(m_widget), "realize",
|
gtk_signal_connect( GTK_OBJECT(m_widget), "realize",
|
||||||
GTK_SIGNAL_FUNC(gtk_dialog_realized_callback), (gpointer) this );
|
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_connect( GTK_OBJECT(m_widget), "size_allocate",
|
||||||
GTK_SIGNAL_FUNC(gtk_dialog_size_callback), (gpointer)this );
|
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_connect( GTK_OBJECT(m_widget), "focus",
|
||||||
GTK_SIGNAL_FUNC(gtk_dialog_focus_callback), (gpointer)this );
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user