]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk/toplevel.cpp
Applied patch from Bo, WIP
[wxWidgets.git] / src / gtk / toplevel.cpp
index b97cae23634caf99a203986422fed8ab87c89557..3b7ad49c9653fa73ebd9d6ad8edf12ad25b11d2c 100644 (file)
@@ -112,8 +112,6 @@ static gboolean gtk_frame_focus_in_callback( GtkWidget *widget,
                                          GdkEvent *WXUNUSED(event),
                                          wxTopLevelWindowGTK *win )
 {
-    // don't need to install idle handler, its done from "event" signal
-
     switch ( g_sendActivateEvent )
     {
         case -1:
@@ -173,8 +171,6 @@ static gboolean gtk_frame_focus_out_callback( GtkWidget *widget,
                                           GdkEventFocus *WXUNUSED(gdk_event),
                                           wxTopLevelWindowGTK *win )
 {
-    // don't need to install idle handler, its done from "event" signal
-
     // if the focus goes out of our app alltogether, OnIdle() will send
     // wxActivateEvent, otherwise gtk_window_focus_in_callback() will reset
     // g_sendActivateEvent to -1
@@ -205,9 +201,6 @@ static gboolean gtk_frame_focus_out_callback( GtkWidget *widget,
 extern "C" {
 static void gtk_frame_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxTopLevelWindowGTK *win )
 {
-    if (g_isIdle)
-        wxapp_install_idle_handler();
-
     if (!win->m_hasVMT)
         return;
 
@@ -260,8 +253,6 @@ gtk_frame_delete_callback( GtkWidget *WXUNUSED(widget),
                            GdkEvent *WXUNUSED(event),
                            wxTopLevelWindowGTK *win )
 {
-    // don't need to install idle handler, its done from "event" signal
-
     if (win->IsEnabled() &&
         (g_openDialogs == 0 || (win->GetExtraStyle() & wxTOPLEVEL_EX_DIALOG) ||
          win->IsGrabbed()))
@@ -278,23 +269,19 @@ gtk_frame_delete_callback( GtkWidget *WXUNUSED(widget),
 
 extern "C" {
 static gboolean
-gtk_frame_configure_callback( GtkWidget *WXUNUSED(widget),
+gtk_frame_configure_callback( GtkWidget* widget,
                               GdkEventConfigure *WXUNUSED(event),
                               wxTopLevelWindowGTK *win )
 {
-    // don't need to install idle handler, its done from "event" signal
-
     if (!win->m_hasVMT || !win->IsShown())
         return FALSE;
 
+    wxPoint point;
+    gtk_window_get_position((GtkWindow*)widget, &point.x, &point.y);
 
-    int x = 0;
-    int y = 0;
-    gdk_window_get_root_origin( win->m_widget->window, &x, &y );
-    win->m_x = x;
-    win->m_y = y;
-
-    wxMoveEvent mevent( wxPoint(win->m_x,win->m_y), win->GetId() );
+    win->m_x = point.x;
+    win->m_y = point.y;
+    wxMoveEvent mevent(point, win->GetId());
     mevent.SetEventObject( win );
     win->GetEventHandler()->ProcessEvent( mevent );
 
@@ -314,9 +301,6 @@ static void
 gtk_frame_realized_callback( GtkWidget * WXUNUSED(widget),
                              wxTopLevelWindowGTK *win )
 {
-    if (g_isIdle)
-        wxapp_install_idle_handler();
-
     // All this is for Motif Window Manager "hints" and is supposed to be
     // recognized by other WM as well. Not tested.
     gdk_window_set_decorations(win->m_widget->window,
@@ -332,7 +316,7 @@ gtk_frame_realized_callback( GtkWidget * WXUNUSED(widget),
 
     // reset the icon
     wxIconBundle iconsOld = win->GetIcons();
-    if ( iconsOld.GetIcon(-1).Ok() )
+    if ( !iconsOld.IsEmpty() )
     {
         win->SetIcon( wxNullIcon );
         win->SetIcons( iconsOld );
@@ -345,12 +329,13 @@ gtk_frame_realized_callback( GtkWidget * WXUNUSED(widget),
 //-----------------------------------------------------------------------------
 
 extern "C" {
-static void
+static gboolean
 gtk_frame_map_callback( GtkWidget * WXUNUSED(widget),
                         GdkEvent * WXUNUSED(event),
                         wxTopLevelWindow *win )
 {
     win->SetIconizeState(false);
+    return false;
 }
 }
 
@@ -359,12 +344,13 @@ gtk_frame_map_callback( GtkWidget * WXUNUSED(widget),
 //-----------------------------------------------------------------------------
 
 extern "C" {
-static void
+static gboolean
 gtk_frame_unmap_callback( GtkWidget * WXUNUSED(widget),
                           GdkEvent * WXUNUSED(event),
                           wxTopLevelWindow *win )
 {
     win->SetIconizeState(true);
+    return false;
 }
 }
 
@@ -392,46 +378,6 @@ gtk_window_expose_callback( GtkWidget *widget,
 }
 }
 
-// ----------------------------------------------------------------------------
-// wxTopLevelWindowGTK itself
-// ----------------------------------------------------------------------------
-
-//-----------------------------------------------------------------------------
-// InsertChild for wxTopLevelWindowGTK
-//-----------------------------------------------------------------------------
-
-/* Callback for wxTopLevelWindowGTK. This very strange beast has to be used because
- * C++ has no virtual methods in a constructor. We have to emulate a
- * virtual function here as wxWidgets requires different ways to insert
- * a child in container classes. */
-
-static void wxInsertChildInTopLevelWindow( wxTopLevelWindowGTK* parent, wxWindow* child )
-{
-    wxASSERT( GTK_IS_WIDGET(child->m_widget) );
-
-    if (!parent->m_insertInClientArea)
-    {
-        // these are outside the client area
-        wxTopLevelWindowGTK* frame = (wxTopLevelWindowGTK*) parent;
-        gtk_pizza_put( GTK_PIZZA(frame->m_mainWidget),
-                         GTK_WIDGET(child->m_widget),
-                         child->m_x,
-                         child->m_y,
-                         child->m_width,
-                         child->m_height );
-    }
-    else
-    {
-        // these are inside the client area
-        gtk_pizza_put( GTK_PIZZA(parent->m_wxwindow),
-                         GTK_WIDGET(child->m_widget),
-                         child->m_x,
-                         child->m_y,
-                         child->m_width,
-                         child->m_height );
-    }
-}
-
 // ----------------------------------------------------------------------------
 // wxTopLevelWindowGTK creation
 // ----------------------------------------------------------------------------
@@ -442,10 +388,8 @@ void wxTopLevelWindowGTK::Init()
     m_miniEdge = 0;
     m_miniTitle = 0;
     m_mainWidget = (GtkWidget*) NULL;
-    m_insertInClientArea = true;
     m_isIconized = false;
     m_fsIsShowing = false;
-    m_fsSaveFlag = 0;
     m_themeEnabled = true;
     m_gdkDecor = m_gdkFunc = 0;
     m_grabbed = false;
@@ -469,8 +413,6 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent,
 
     wxTopLevelWindows.Append( this );
 
-    m_needParent = false;
-
     if (!PreCreation( parent, pos, size ) ||
         !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
     {
@@ -480,8 +422,6 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent,
 
     m_title = title;
 
-    m_insertCallback = (wxInsertChildFunction) wxInsertChildInTopLevelWindow;
-
     // NB: m_widget may be !=NULL if it was created by derived class' Create,
     //     e.g. in wxTaskBarIconAreaGTK
     if (m_widget == NULL)
@@ -608,7 +548,7 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent,
     g_signal_connect (m_widget, "unmap_event",
                       G_CALLBACK (gtk_frame_unmap_callback), this);
 
-    // the only way to get the window size is to connect to this event
+    // for wxMoveEvent
     g_signal_connect (m_widget, "configure_event",
                       G_CALLBACK (gtk_frame_configure_callback), this);
 
@@ -707,7 +647,7 @@ bool wxTopLevelWindowGTK::EnableCloseButton( bool enable )
     return true;
 }
 
-bool wxTopLevelWindowGTK::ShowFullScreen(bool show, long style )
+bool wxTopLevelWindowGTK::ShowFullScreen(bool show, long)
 {
     if (show == m_fsIsShowing)
         return false; // return what?
@@ -726,15 +666,9 @@ bool wxTopLevelWindowGTK::ShowFullScreen(bool show, long style )
     if ( (method == wxX11_FS_WMSPEC) && !gtk_check_version(2,2,0) )
     {
         if (show)
-        {
-            m_fsSaveFlag = style;
             gtk_window_fullscreen( GTK_WINDOW( m_widget ) );
-        }
         else
-        {
-            m_fsSaveFlag = 0;
             gtk_window_unfullscreen( GTK_WINDOW( m_widget ) );
-        }
     }
     else
 #endif // GTK+ >= 2.2.0
@@ -743,7 +677,6 @@ bool wxTopLevelWindowGTK::ShowFullScreen(bool show, long style )
 
         if (show)
         {
-            m_fsSaveFlag = style;
             GetPosition( &m_fsSaveFrame.x, &m_fsSaveFrame.y );
             GetSize( &m_fsSaveFrame.width, &m_fsSaveFrame.height );
 
@@ -777,7 +710,6 @@ bool wxTopLevelWindowGTK::ShowFullScreen(bool show, long style )
         }
         else // hide
         {
-            m_fsSaveFlag = 0;
             if (method != wxX11_FS_WMSPEC)
             {
                 // don't do it always, Metacity hates it
@@ -799,7 +731,7 @@ bool wxTopLevelWindowGTK::ShowFullScreen(bool show, long style )
 
     // documented behaviour is to show the window if it's still hidden when
     // showing it full screen
-    if ( show && !IsShown() )
+    if (show)
         Show();
 
     return true;
@@ -814,7 +746,7 @@ bool wxTopLevelWindowGTK::Show( bool show )
     wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
 
     if (show == IsShown())
-        return true;
+        return false;
 
     if (show && !m_sizeSet)
     {
@@ -826,13 +758,17 @@ bool wxTopLevelWindowGTK::Show( bool show )
         GtkOnSize();
     }
 
-    // This seems no longer to be needed and the call
-    // itself is deprecated.
-    //
-    //if (show)
-    //    gtk_widget_set_uposition( m_widget, m_x, m_y );
+    wxTopLevelWindowBase::Show(show);
+
+    if (!show)
+    {
+        // make sure window has a non-default position, so when it is shown
+        // again, it won't be repositioned by WM as if it were a new window
+        // Note that this must be done _after_ the window is hidden.
+        gtk_window_move((GtkWindow*)m_widget, m_x, m_y);
+    }
 
-    return wxWindow::Show( show );
+    return true;
 }
 
 void wxTopLevelWindowGTK::Raise()
@@ -869,23 +805,7 @@ void wxTopLevelWindowGTK::GTKDoSetSize(int width, int height)
     if ( height != -1 )
         m_height = height;
 
-    // GPE's window manager doesn't like size hints at all, esp. when the user
-    // has to use the virtual keyboard, so don't constrain size there
-#ifndef __WXGPE__
-    int minWidth = GetMinWidth(),
-        minHeight = GetMinHeight(),
-        maxWidth = GetMaxWidth(),
-        maxHeight = GetMaxHeight();
-
-    if ( minWidth != -1 && m_width < minWidth )
-        m_width = minWidth;
-    if ( minHeight != -1 && m_height < minHeight )
-        m_height = minHeight;
-    if ( maxWidth != -1 && m_width > maxWidth )
-        m_width = maxWidth;
-    if ( maxHeight != -1 && m_height > maxHeight )
-        m_height = maxHeight;
-#endif // __WXGPE__
+    ConstrainSize();
 
     if ( m_width != old_width || m_height != old_height )
     {
@@ -1005,11 +925,6 @@ void wxTopLevelWindowGTK::DoGetClientSize( int *width, int *height ) const
     }
 }
 
-void wxTopLevelWindowGTK::DoSetClientSize( int width, int height )
-{
-    GTKDoSetSize(width + m_miniEdge*2, height  + m_miniEdge*2 + m_miniTitle);
-}
-
 void wxTopLevelWindowGTK::DoSetSizeHints( int minW, int minH,
                                           int maxW, int maxH,
                                           int incW, int incH )
@@ -1051,55 +966,13 @@ void wxTopLevelWindowGTK::GtkOnSize()
 
     if ( m_wxwindow == NULL ) return;
 
-    /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
-       wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
-       set in wxFrame::Create so it is used to check what kind of frame we
-       have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
-       skip the part which handles m_frameMenuBar, m_frameToolBar and (most
-       importantly) m_mainWidget */
-
-    int minWidth = GetMinWidth(),
-        minHeight = GetMinHeight(),
-        maxWidth = GetMaxWidth(),
-        maxHeight = GetMaxHeight();
-
-#ifdef __WXGPE__
-    // GPE's window manager doesn't like size hints
-    // at all, esp. when the user has to use the
-    // virtual keyboard.
-    minWidth = -1;
-    minHeight = -1;
-    maxWidth = -1;
-    maxHeight = -1;
-#endif
-
-    if ((minWidth != -1) && (m_width < minWidth)) m_width = minWidth;
-    if ((minHeight != -1) && (m_height < minHeight)) m_height = minHeight;
-    if ((maxWidth != -1) && (m_width > maxWidth)) m_width = maxWidth;
-    if ((maxHeight != -1) && (m_height > maxHeight)) m_height = maxHeight;
+    ConstrainSize();
 
     if (m_mainWidget)
     {
-        // m_mainWidget holds the menubar, the toolbar and the client area,
-        // which is represented by m_wxwindow.
-        int client_x = m_miniEdge;
-        int client_y = m_miniEdge + m_miniTitle;
-        int client_w = m_width - 2*m_miniEdge;
-        int client_h = m_height - 2*m_miniEdge - m_miniTitle;
-        if (client_w < 0)
-            client_w = 0;
-        if (client_h < 0)
-            client_h = 0;
-
-        // Let the parent perform the resize
         gtk_pizza_set_size( GTK_PIZZA(m_mainWidget),
                               m_wxwindow,
-                              client_x, client_y, client_w, client_h );
-    }
-    else
-    {
-        // If there is no m_mainWidget between m_widget and m_wxwindow there
-        // is no need to set the size or position of m_wxwindow.
+                              0, 0, m_width, m_height);
     }
 
     m_sizeSet = true;
@@ -1119,8 +992,6 @@ void wxTopLevelWindowGTK::OnInternalIdle()
         GtkOnSize();
 
         // we'll come back later
-        if (g_isIdle)
-            wxapp_install_idle_handler();
         return;
     }
 
@@ -1173,17 +1044,6 @@ void wxTopLevelWindowGTK::SetTitle( const wxString &title )
     gtk_window_set_title( GTK_WINDOW(m_widget), wxGTK_CONV( title ) );
 }
 
-void wxTopLevelWindowGTK::SetIcon( const wxIcon &icon )
-{
-    // passing wxNullIcon to SetIcon() is possible (it means that we shouldn't
-    // have any icon), but adding an invalid icon to wxIconBundle is not
-    wxIconBundle icons;
-    if ( icon.Ok() )
-        icons.AddIcon(icon);
-
-    SetIcons(icons);
-}
-
 void wxTopLevelWindowGTK::SetIcons( const wxIconBundle &icons )
 {
     wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
@@ -1256,7 +1116,7 @@ void wxTopLevelWindowGTK::AddGrab()
     {
         m_grabbed = true;
         gtk_grab_add( m_widget );
-        wxEventLoop().Run();
+        wxGUIEventLoop().Run();
         gtk_grab_remove( m_widget );
     }
 }