]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk/toplevel.cpp
rebaked after timer/socket changes
[wxWidgets.git] / src / gtk / toplevel.cpp
index 28503b6538653de13306bf2bdb14ef85ae1690bd..76c8b4ce1cc6a9accdaf37efa1df915128da0bf7 100644 (file)
 // XA_CARDINAL
 #include <X11/Xatom.h>
 
+#if wxUSE_LIBHILDON
+    #include <hildon-widgets/hildon-program.h>
+    #include <hildon-widgets/hildon-window.h>
+#endif // wxUSE_LIBHILDON
+
 // ----------------------------------------------------------------------------
 // data
 // ----------------------------------------------------------------------------
 
-extern int              g_openDialogs;
+// this is incremented while a modal dialog is shown
+int wxOpenModalDialogsCount = 0;
+
 extern wxWindowGTK     *g_delayedFocus;
 
 // the frame that is currently active (i.e. its child has focus). It is
@@ -270,7 +277,7 @@ gtk_frame_delete_callback( GtkWidget *WXUNUSED(widget),
                            wxTopLevelWindowGTK *win )
 {
     if (win->IsEnabled() &&
-        (g_openDialogs == 0 || (win->GetExtraStyle() & wxTOPLEVEL_EX_DIALOG) ||
+        (wxOpenModalDialogsCount == 0 || (win->GetExtraStyle() & wxTOPLEVEL_EX_DIALOG) ||
          win->IsGrabbed()))
         win->Close();
 
@@ -366,13 +373,25 @@ gtk_frame_map_callback( GtkWidget* widget,
             win->m_width = rect.width;
             win->m_height = rect.height;
             decorSize = size;
-            wxSizeEvent event(win->GetSize(), win->GetId());
-            event.SetEventObject(win);
-            win->GetEventHandler()->ProcessEvent(event);
         }
     }
 
+    const bool wasIconized = win->IsIconized();
+
     win->SetIconizeState(false);
+
+    if (wasIconized)
+    {
+        // Because GetClientSize() returns (0,0) when IsIconized() is true,
+        // a size event must be generated, just in case GetClientSize() was
+        // called while iconized. This specifically happens when restoring a
+        // tlw that was "rolled up" with some WMs.
+        // Queue a resize rather than sending size event directly to allow
+        // children to be made visible first.
+        win->m_oldClientWidth = 0;
+        gtk_widget_queue_resize(win->m_wxwindow);
+    }
+
     return false;
 }
 }
@@ -405,18 +424,8 @@ static gboolean property_notify_event(
     if (event->state == GDK_PROPERTY_NEW_VALUE && event->atom == property &&
         win->IsDecorCacheable() && !win->IsFullScreen())
     {
-        Atom xproperty;
-#if GTK_CHECK_VERSION(2, 2, 0)
-        if (gtk_check_version(2, 2, 0) == NULL)
-        {
-            xproperty = gdk_x11_atom_to_xatom_for_display(
-                gdk_drawable_get_display(event->window), property);
-        }
-        else
-#endif
-        {
-            xproperty = gdk_x11_atom_to_xatom(property);
-        }
+        Atom xproperty = gdk_x11_atom_to_xatom_for_display(
+                            gdk_drawable_get_display(event->window), property);
         Atom type;
         int format;
         gulong nitems, bytes_after;
@@ -440,9 +449,8 @@ static gboolean property_notify_event(
                 if (win->m_width  < 0) win->m_width  = 0;
                 if (win->m_height < 0) win->m_height = 0;
                 decorSize = size;
-                wxSizeEvent event(win->GetSize(), win->GetId());
-                event.SetEventObject(win);
-                win->GetEventHandler()->ProcessEvent(event);
+                win->m_oldClientWidth = 0;
+                gtk_widget_queue_resize(win->m_wxwindow);
             }
         }
         if (data)
@@ -452,6 +460,11 @@ static gboolean property_notify_event(
 }
 }
 
+BEGIN_EVENT_TABLE(wxTopLevelWindowGTK, wxTopLevelWindowBase)
+    EVT_SYS_COLOUR_CHANGED(wxTopLevelWindowGTK::OnSysColourChanged)
+END_EVENT_TABLE()
+
+
 // ----------------------------------------------------------------------------
 // wxTopLevelWindowGTK creation
 // ----------------------------------------------------------------------------
@@ -497,6 +510,14 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent,
     //     e.g. in wxTaskBarIconAreaGTK
     if (m_widget == NULL)
     {
+#if wxUSE_LIBHILDON
+        // we must create HildonWindow and not a normal GtkWindow as the latter
+        // doesn't look correctly in Maemo environment and it must also be
+        // registered with the main program object
+        m_widget = hildon_window_new();
+        hildon_program_add_window(wxTheApp->GetHildonProgram(),
+                                  HILDON_WINDOW(m_widget));
+#else // !wxUSE_LIBHILDON
         m_widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
         if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG)
         {
@@ -509,25 +530,21 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent,
         }
         else
         {
-#if GTK_CHECK_VERSION(2,1,0)
-            if (!gtk_check_version(2,1,0))
+            if (style & wxFRAME_TOOL_WINDOW)
             {
-                if (style & wxFRAME_TOOL_WINDOW)
-                {
-                    gtk_window_set_type_hint(GTK_WINDOW(m_widget),
-                                             GDK_WINDOW_TYPE_HINT_UTILITY);
-
-                    // On some WMs, like KDE, a TOOL_WINDOW will still show
-                    // on the taskbar, but on Gnome a TOOL_WINDOW will not.
-                    // For consistency between WMs and with Windows, we
-                    // should set the NO_TASKBAR flag which will apply
-                    // the set_skip_taskbar_hint if it is available,
-                    // ensuring no taskbar entry will appear.
-                    style |= wxFRAME_NO_TASKBAR;
-                }
+                gtk_window_set_type_hint(GTK_WINDOW(m_widget),
+                                         GDK_WINDOW_TYPE_HINT_UTILITY);
+
+                // On some WMs, like KDE, a TOOL_WINDOW will still show
+                // on the taskbar, but on Gnome a TOOL_WINDOW will not.
+                // For consistency between WMs and with Windows, we
+                // should set the NO_TASKBAR flag which will apply
+                // the set_skip_taskbar_hint if it is available,
+                // ensuring no taskbar entry will appear.
+                style |= wxFRAME_NO_TASKBAR;
             }
-#endif
         }
+#endif // wxUSE_LIBHILDON/!wxUSE_LIBHILDON
     }
 
     wxWindow *topParent = wxGetTopLevelParent(m_parent);
@@ -539,25 +556,15 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent,
                                       GTK_WINDOW(topParent->m_widget) );
     }
 
-#if GTK_CHECK_VERSION(2,2,0)
-    if (!gtk_check_version(2,2,0))
+    if (style & wxFRAME_NO_TASKBAR)
     {
-        if (style & wxFRAME_NO_TASKBAR)
-        {
-            gtk_window_set_skip_taskbar_hint(GTK_WINDOW(m_widget), TRUE);
-        }
+        gtk_window_set_skip_taskbar_hint(GTK_WINDOW(m_widget), TRUE);
     }
-#endif
 
-#ifdef __WXGTK24__
-    if (!gtk_check_version(2,4,0))
+    if (style & wxSTAY_ON_TOP)
     {
-        if (style & wxSTAY_ON_TOP)
-        {
-            gtk_window_set_keep_above(GTK_WINDOW(m_widget), TRUE);
-        }
+        gtk_window_set_keep_above(GTK_WINDOW(m_widget), TRUE);
     }
-#endif
 
 #if 0
     if (!name.empty())
@@ -577,7 +584,7 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent,
     gtk_container_add( GTK_CONTAINER(m_widget), m_mainWidget );
 
     // m_wxwindow is the client area
-    m_wxwindow = gtk_pizza_new_no_scroll();
+    m_wxwindow = wxPizza::New();
     gtk_widget_show( m_wxwindow );
     gtk_container_add( GTK_CONTAINER(m_mainWidget), m_wxwindow );
 
@@ -674,6 +681,15 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent,
 
 wxTopLevelWindowGTK::~wxTopLevelWindowGTK()
 {
+#if wxUSE_LIBHILDON
+    // it can also be a (standard) dialog
+    if ( HILDON_IS_WINDOW(m_widget) )
+    {
+        hildon_program_remove_window(wxTheApp->GetHildonProgram(),
+                                     HILDON_WINDOW(m_widget));
+    }
+#endif // wxUSE_LIBHILDON
+
     if (m_grabbed)
     {
         wxFAIL_MSG(_T("Window still grabbed"));
@@ -718,12 +734,11 @@ bool wxTopLevelWindowGTK::ShowFullScreen(bool show, long)
         wxGetFullScreenMethodX11((WXDisplay*)GDK_DISPLAY(),
                                  (WXWindow)GDK_ROOT_WINDOW());
 
-#if GTK_CHECK_VERSION(2,2,0)
     // NB: gtk_window_fullscreen() uses freedesktop.org's WMspec extensions
     //     to switch to fullscreen, which is not always available. We must
     //     check if WM supports the spec and use legacy methods if it
     //     doesn't.
-    if ( (method == wxX11_FS_WMSPEC) && !gtk_check_version(2,2,0) )
+    if ( method == wxX11_FS_WMSPEC )
     {
         if (show)
             gtk_window_fullscreen( GTK_WINDOW( m_widget ) );
@@ -731,7 +746,6 @@ bool wxTopLevelWindowGTK::ShowFullScreen(bool show, long)
             gtk_window_unfullscreen( GTK_WINDOW( m_widget ) );
     }
     else
-#endif // GTK+ >= 2.2.0
     {
         GdkWindow *window = m_widget->window;
 
@@ -746,15 +760,11 @@ bool wxTopLevelWindowGTK::ShowFullScreen(bool show, long)
             gint client_x, client_y, root_x, root_y;
             gint width, height;
 
-            if (method != wxX11_FS_WMSPEC)
-            {
-                // don't do it always, Metacity hates it
-                m_fsSaveGdkFunc = m_gdkFunc;
-                m_fsSaveGdkDecor = m_gdkDecor;
-                m_gdkFunc = m_gdkDecor = 0;
-                gdk_window_set_decorations(window, (GdkWMDecoration)0);
-                gdk_window_set_functions(window, (GdkWMFunction)0);
-            }
+            m_fsSaveGdkFunc = m_gdkFunc;
+            m_fsSaveGdkDecor = m_gdkDecor;
+            m_gdkFunc = m_gdkDecor = 0;
+            gdk_window_set_decorations(window, (GdkWMDecoration)0);
+            gdk_window_set_functions(window, (GdkWMFunction)0);
 
             gdk_window_get_origin (m_widget->window, &root_x, &root_y);
             gdk_window_get_geometry (m_widget->window, &client_x, &client_y,
@@ -770,14 +780,10 @@ bool wxTopLevelWindowGTK::ShowFullScreen(bool show, long)
         }
         else // hide
         {
-            if (method != wxX11_FS_WMSPEC)
-            {
-                // don't do it always, Metacity hates it
-                m_gdkFunc = m_fsSaveGdkFunc;
-                m_gdkDecor = m_fsSaveGdkDecor;
-                gdk_window_set_decorations(window, (GdkWMDecoration)m_gdkDecor);
-                gdk_window_set_functions(window, (GdkWMFunction)m_gdkFunc);
-            }
+            m_gdkFunc = m_fsSaveGdkFunc;
+            m_gdkDecor = m_fsSaveGdkDecor;
+            gdk_window_set_decorations(window, (GdkWMDecoration)m_gdkDecor);
+            gdk_window_set_functions(window, (GdkWMFunction)m_gdkFunc);
 
             wxSetFullScreenStateX11((WXDisplay*)GDK_DISPLAY(),
                                     (WXWindow)GDK_ROOT_WINDOW(),
@@ -859,10 +865,6 @@ void wxTopLevelWindowGTK::DoSetSize( int x, int y, int width, int height, int si
 {
     wxCHECK_RET( m_widget, wxT("invalid frame") );
 
-    // this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow
-    wxASSERT_MSG( (m_wxwindow != NULL), wxT("invalid frame") );
-
-
     // deal with the position first
     int old_x = m_x;
     int old_y = m_y;
@@ -1135,8 +1137,7 @@ bool wxTopLevelWindowGTK::SetShape(const wxRegion& region)
     GdkWindow *window = NULL;
     if (m_wxwindow)
     {
-        window = GTK_PIZZA(m_wxwindow)->bin_window;
-        do_shape_combine_region(window, region);
+        do_shape_combine_region(m_wxwindow->window, region);
     }
     window = m_widget->window;
     return do_shape_combine_region(window, region);
@@ -1184,10 +1185,8 @@ void wxTopLevelWindowGTK::RequestUserAttention(int flags)
 
 void wxTopLevelWindowGTK::SetWindowStyleFlag( long style )
 {
-#if defined(__WXGTK24__) || GTK_CHECK_VERSION(2,2,0)
     // Store which styles were changed
     long styleChanges = style ^ m_windowStyle;
-#endif
 
     // Process wxWindow styles. This also updates the internal variable
     // Therefore m_windowStyle bits carry now the _new_ style values
@@ -1197,16 +1196,17 @@ void wxTopLevelWindowGTK::SetWindowStyleFlag( long style )
     if (!m_widget)
         return;
 
-#ifdef __WXGTK24__
-    if ( (styleChanges & wxSTAY_ON_TOP) && !gtk_check_version(2,4,0) )
-        gtk_window_set_keep_above(GTK_WINDOW(m_widget), m_windowStyle & wxSTAY_ON_TOP);
-#endif // GTK+ 2.4
-#if GTK_CHECK_VERSION(2,2,0)
-    if ( (styleChanges & wxFRAME_NO_TASKBAR) && !gtk_check_version(2,2,0) )
+    if ( styleChanges & wxSTAY_ON_TOP )
+    {
+        gtk_window_set_keep_above(GTK_WINDOW(m_widget),
+                                  m_windowStyle & wxSTAY_ON_TOP);
+    }
+
+    if ( styleChanges & wxFRAME_NO_TASKBAR )
     {
-        gtk_window_set_skip_taskbar_hint(GTK_WINDOW(m_widget), m_windowStyle & wxFRAME_NO_TASKBAR);
+        gtk_window_set_skip_taskbar_hint(GTK_WINDOW(m_widget),
+                                         m_windowStyle & wxFRAME_NO_TASKBAR);
     }
-#endif // GTK+ 2.2
 }
 
 /* Get the X Window between child and the root window.
@@ -1282,3 +1282,16 @@ bool wxTopLevelWindowGTK::CanSetTransparent()
                            "Composite", &opcode, &event, &error);
 #endif
 }
+
+void wxTopLevelWindowGTK::OnSysColourChanged(wxSysColourChangedEvent& event)
+{
+    // We don't know the order in which top-level windows will
+    // be notified, so we need to clear the system objects
+    // for each top-level window.
+    extern void wxClearGtkSystemObjects();
+    wxClearGtkSystemObjects();
+
+    // wxWindowBase::OnSysColourChanged will propagate event
+    // to children
+    event.Skip();
+}