1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/gtk/popupwin.cpp 
   4 // Author:      Robert Roebling 
   6 // Copyright:   (c) 1998 Robert Roebling 
   7 // Licence:     wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  10 // For compilers that support precompilation, includes "wx.h". 
  11 #include "wx/wxprec.h" 
  15 #include "wx/popupwin.h" 
  22 #include "wx/gtk/private/win_gtk.h" 
  24 //----------------------------------------------------------------------------- 
  26 //----------------------------------------------------------------------------- 
  29 static gint 
gtk_popup_button_press (GtkWidget 
*widget
, GdkEvent 
*gdk_event
, wxPopupWindow
* win 
) 
  31     GtkWidget 
*child 
= gtk_get_event_widget (gdk_event
); 
  33     /* Ignore events sent out before we connected to the signal */ 
  34     if (win
->m_time 
>= ((GdkEventButton
*)gdk_event
)->time
) 
  37     /*  We don't ask for button press events on the grab widget, so 
  38      *  if an event is reported directly to the grab widget, it must 
  39      *  be on a window outside the application (and thus we remove 
  40      *  the popup window). Otherwise, we check if the widget is a child 
  41      *  of the grab widget, and only remove the popup window if it 
  49             child 
= child
->parent
; 
  53     wxFocusEvent 
event( wxEVT_KILL_FOCUS
, win
->GetId() ); 
  54     event
.SetEventObject( win 
); 
  56     (void)win
->HandleWindowEvent( event 
); 
  62 //----------------------------------------------------------------------------- 
  64 //----------------------------------------------------------------------------- 
  67 bool gtk_dialog_delete_callback( GtkWidget 
*WXUNUSED(widget
), GdkEvent 
*WXUNUSED(event
), wxPopupWindow 
*win 
) 
  76 void wxPopupWindow::AddChildGTK(wxWindowGTK
* child
) 
  78     gtk_widget_set_size_request( 
  79         child
->m_widget
, child
->m_width
, child
->m_height
); 
  81         GTK_FIXED(m_wxwindow
), child
->m_widget
, child
->m_x
, child
->m_y
); 
  84 //----------------------------------------------------------------------------- 
  86 //----------------------------------------------------------------------------- 
  88 #ifdef __WXUNIVERSAL__ 
  89 BEGIN_EVENT_TABLE(wxPopupWindow
,wxPopupWindowBase
) 
  90     EVT_SIZE(wxPopupWindow::OnSize
) 
  94 wxPopupWindow::~wxPopupWindow() 
  98 bool wxPopupWindow::Create( wxWindow 
*parent
, int style 
) 
 100     if (!PreCreation( parent
, wxDefaultPosition
, wxDefaultSize 
) || 
 101         !CreateBase( parent
, -1, wxDefaultPosition
, wxDefaultSize
, style
, wxDefaultValidator
, wxT("popup") )) 
 103         wxFAIL_MSG( wxT("wxPopupWindow creation failed") ); 
 107     // Unlike windows, top level windows are created hidden by default. 
 110     // All dialogs should really have this style 
 111     m_windowStyle 
|= wxTAB_TRAVERSAL
; 
 113     m_widget 
= gtk_window_new( GTK_WINDOW_POPUP 
); 
 114     g_object_ref( m_widget 
); 
 116     gtk_widget_set_name( m_widget
, "wxPopupWindow" ); 
 117     // wxPopupWindow is used for different windows as well 
 118     // gtk_window_set_type_hint( GTK_WINDOW(m_widget), GDK_WINDOW_TYPE_HINT_COMBO ); 
 120     GtkWidget 
*toplevel 
= gtk_widget_get_toplevel( parent
->m_widget 
); 
 121     if (GTK_IS_WINDOW (toplevel
)) 
 123 #if GTK_CHECK_VERSION(2,10,0) 
 124         if (!gtk_check_version(2,10,0)) 
 125             gtk_window_group_add_window (gtk_window_get_group (GTK_WINDOW (toplevel
)), GTK_WINDOW (m_widget
)); 
 128         gtk_window_set_transient_for (GTK_WINDOW (m_widget
), GTK_WINDOW (toplevel
)); 
 130     gtk_window_set_resizable (GTK_WINDOW (m_widget
), FALSE
); 
 131     gtk_window_set_screen (GTK_WINDOW (m_widget
), gtk_widget_get_screen (GTK_WIDGET (parent
->m_widget
))); 
 133     g_signal_connect (m_widget
, "delete_event", 
 134                       G_CALLBACK (gtk_dialog_delete_callback
), this); 
 136     m_wxwindow 
= wxPizza::New(m_windowStyle
); 
 137     gtk_widget_show( m_wxwindow 
); 
 139     gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow 
); 
 141     if (m_parent
) m_parent
->AddChild( this ); 
 145     m_time 
= gtk_get_current_event_time(); 
 147     g_signal_connect (m_widget
, "button_press_event", 
 148                       G_CALLBACK (gtk_popup_button_press
), this); 
 153 void wxPopupWindow::DoMoveWindow(int WXUNUSED(x
), int WXUNUSED(y
), int WXUNUSED(width
), int WXUNUSED(height
) ) 
 155     wxFAIL_MSG( wxT("DoMoveWindow called for wxPopupWindow") ); 
 158 void wxPopupWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags 
) 
 160     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid dialog") ); 
 161     wxASSERT_MSG( (m_wxwindow 
!= NULL
), wxT("invalid dialog") ); 
 166     int old_width 
= m_width
; 
 167     int old_height 
= m_height
; 
 169     if (x 
!= -1 || (sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
)) 
 171     if (y 
!= -1 || (sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
)) 
 180     if ((m_x 
!= -1) || (m_y 
!= -1)) 
 182         if ((m_x 
!= old_x
) || (m_y 
!= old_y
)) 
 184             gtk_window_move( GTK_WINDOW(m_widget
), m_x
, m_y 
); 
 188     if ((m_width 
!= old_width
) || (m_height 
!= old_height
)) 
 190         // gtk_window_resize does not work for GTK_WINDOW_POPUP 
 191         gtk_widget_set_size_request( m_widget
, m_width
, m_height 
); 
 192         wxSizeEvent 
event(GetSize(), GetId()); 
 193         event
.SetEventObject(this); 
 194         HandleWindowEvent(event
); 
 198 void wxPopupWindow::SetFocus() 
 200     // set the focus to the first child who wants it 
 201     wxWindowList::compatibility_iterator node 
= GetChildren().GetFirst(); 
 204         wxWindow 
*child 
= node
->GetData(); 
 205         node 
= node
->GetNext(); 
 207         if ( child
->CanAcceptFocus() && !child
->IsTopLevel() ) 
 214     wxPopupWindowBase::SetFocus(); 
 217 bool wxPopupWindow::Show( bool show 
) 
 219     if (show 
&& !IsShown()) 
 221         wxSizeEvent 
event(GetSize(), GetId()); 
 222         event
.SetEventObject(this); 
 223         HandleWindowEvent(event
); 
 226     bool ret 
= wxWindow::Show( show 
); 
 231 #endif // wxUSE_POPUPWIN