]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk/toplevel.cpp
fix icc warning about printf() format mismatch
[wxWidgets.git] / src / gtk / toplevel.cpp
index 5e5af4d54f6d1fa41599ffda1bc001c7ffd8c54b..d50dd65fcf4e8bcdd3b8d3f2c483951d316c27e9 100644 (file)
@@ -15,9 +15,8 @@
 // headers
 // ----------------------------------------------------------------------------
 
 // headers
 // ----------------------------------------------------------------------------
 
-#ifdef __GNUG__
-    #pragma implementation "toplevel.h"
-#endif
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
 
 #ifdef __VMS
 #define XIconifyWindow XICONIFYWINDOW
 
 #ifdef __VMS
 #define XIconifyWindow XICONIFYWINDOW
 
 #include "wx/defs.h"
 
 
 #include "wx/defs.h"
 
+#include "wx/toplevel.h"
+#include "wx/log.h"
 #include "wx/dialog.h"
 #include "wx/control.h"
 #include "wx/app.h"
 #include "wx/dcclient.h"
 #include "wx/dialog.h"
 #include "wx/control.h"
 #include "wx/app.h"
 #include "wx/dcclient.h"
+#include "wx/gtk/private.h"
+#include "wx/timer.h"
+#include "wx/settings.h"
+#include "wx/evtloop.h"
 
 #include <glib.h>
 #include <gdk/gdk.h>
 
 #include <glib.h>
 #include <gdk/gdk.h>
 
 #include "wx/gtk/win_gtk.h"
 
 
 #include "wx/gtk/win_gtk.h"
 
+#include "wx/unix/utilsx11.h"
+
+// XA_CARDINAL
+#include <X11/Xatom.h>
+
 // ----------------------------------------------------------------------------
 // idle system
 // ----------------------------------------------------------------------------
 
 extern void wxapp_install_idle_handler();
 extern bool g_isIdle;
 // ----------------------------------------------------------------------------
 // idle system
 // ----------------------------------------------------------------------------
 
 extern void wxapp_install_idle_handler();
 extern bool g_isIdle;
-extern int g_openDialogs;
 
 // ----------------------------------------------------------------------------
 
 // ----------------------------------------------------------------------------
-// event tables
+// data
 // ----------------------------------------------------------------------------
 
 // ----------------------------------------------------------------------------
 
-#ifndef __WXUNIVERSAL__
-    IMPLEMENT_DYNAMIC_CLASS(wxTopLevelWindow, wxWindow)
+extern wxList           wxPendingDelete;
+
+extern int              g_openDialogs;
+extern wxWindowGTK     *g_delayedFocus;
+
+// the frame that is currently active (i.e. its child has focus). It is
+// used to generate wxActivateEvents
+static wxTopLevelWindowGTK *g_activeFrame = (wxTopLevelWindowGTK*) NULL;
+static wxTopLevelWindowGTK *g_lastActiveFrame = (wxTopLevelWindowGTK*) NULL;
+
+// if we detect that the app has got/lost the focus, we set this variable to
+// either TRUE or FALSE and an activate event will be sent during the next
+// OnIdle() call and it is reset to -1: this value means that we shouldn't
+// send any activate events at all
+static int g_sendActivateEvent = -1;
+
+//-----------------------------------------------------------------------------
+// RequestUserAttention related functions
+//-----------------------------------------------------------------------------
+
+extern "C" {
+static void wxgtk_window_set_urgency_hint (GtkWindow *win,
+                                           gboolean setting)
+{
+    wxASSERT_MSG( GTK_WIDGET_REALIZED(win), wxT("wxgtk_window_set_urgency_hint: GdkWindow not realized") );
+    GdkWindow *window = GTK_WIDGET(win)->window;
+    XWMHints *wm_hints;
+
+    wm_hints = XGetWMHints(GDK_WINDOW_XDISPLAY(window), GDK_WINDOW_XWINDOW(window));
+
+    if (!wm_hints)
+        wm_hints = XAllocWMHints();
+
+    if (setting)
+        wm_hints->flags |= XUrgencyHint;
+    else
+        wm_hints->flags &= ~XUrgencyHint;
+
+    XSetWMHints(GDK_WINDOW_XDISPLAY(window), GDK_WINDOW_XWINDOW(window), wm_hints);
+    XFree(wm_hints);
+}
+
+static gint gtk_frame_urgency_timer_callback( wxTopLevelWindowGTK *win )
+{
+#if defined(__WXGTK20__) && GTK_CHECK_VERSION(2,7,0)
+    if(!gtk_check_version(2,7,0))
+        gtk_window_set_urgency_hint(GTK_WINDOW( win->m_widget ), FALSE);
+    else
 #endif
 #endif
+        wxgtk_window_set_urgency_hint(GTK_WINDOW( win->m_widget ), FALSE);
 
 
-// ----------------------------------------------------------------------------
-// data
-// ----------------------------------------------------------------------------
+    win->m_urgency_hint = -2;
+    return FALSE;
+}
+}
 
 
-extern wxList wxPendingDelete;
+//-----------------------------------------------------------------------------
+// "focus_in_event"
+//-----------------------------------------------------------------------------
 
 
-// ----------------------------------------------------------------------------
-// debug
-// ----------------------------------------------------------------------------
+extern "C" {
+static gint gtk_frame_focus_in_callback( GtkWidget *widget,
+                                         GdkEvent *WXUNUSED(event),
+                                         wxTopLevelWindowGTK *win )
+{
+    if (g_isIdle)
+        wxapp_install_idle_handler();
 
 
-#ifdef __WXDEBUG__
+    switch ( g_sendActivateEvent )
+    {
+        case -1:
+            // we've got focus from outside, synthetize wxActivateEvent
+            g_sendActivateEvent = 1;
+            break;
 
 
-extern void debug_focus_in( GtkWidget* widget, const wxChar* name, const wxChar *window );
+        case 0:
+            // another our window just lost focus, it was already ours before
+            // - don't send any wxActivateEvent
+            g_sendActivateEvent = -1;
+            break;
+    }
+
+    g_activeFrame = win;
+    g_lastActiveFrame = g_activeFrame;
 
 
+    // wxPrintf( wxT("active: %s\n"), win->GetTitle().c_str() );
+
+    // MR: wxRequestUserAttention related block
+    switch( win->m_urgency_hint )
+    {
+        default:
+            gtk_timeout_remove( win->m_urgency_hint );
+            // no break, fallthrough to remove hint too
+        case -1:
+#if defined(__WXGTK20__) && GTK_CHECK_VERSION(2,7,0)
+            if(!gtk_check_version(2,7,0))
+                gtk_window_set_urgency_hint(GTK_WINDOW( widget ), FALSE);
+            else
 #endif
 #endif
+            {
+                wxgtk_window_set_urgency_hint(GTK_WINDOW( widget ), FALSE);
+            }
 
 
-// ============================================================================
-// implementation
-// ============================================================================
+            win->m_urgency_hint = -2;
+            break;
 
 
-// ----------------------------------------------------------------------------
-// GTK callbacks
-// ----------------------------------------------------------------------------
+        case -2: break;
+    }
+
+    wxLogTrace(wxT("activate"), wxT("Activating frame %p (from focus_in)"), g_activeFrame);
+    wxActivateEvent event(wxEVT_ACTIVATE, true, g_activeFrame->GetId());
+    event.SetEventObject(g_activeFrame);
+    g_activeFrame->GetEventHandler()->ProcessEvent(event);
+
+    return FALSE;
+}
+}
+
+//-----------------------------------------------------------------------------
+// "focus_out_event"
+//-----------------------------------------------------------------------------
+
+extern "C" {
+static gint gtk_frame_focus_out_callback( GtkWidget *widget,
+                                          GdkEventFocus *WXUNUSED(gdk_event),
+                                          wxTopLevelWindowGTK *win )
+{
+    if (g_isIdle)
+        wxapp_install_idle_handler();
+
+    // 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
+    g_sendActivateEvent = 0;
+
+    // wxASSERT_MSG( (g_activeFrame == win), wxT("TLW deactivatd although it wasn't active") );
+
+    // wxPrintf( wxT("inactive: %s\n"), win->GetTitle().c_str() );
+
+    if (g_activeFrame)
+    {
+        wxLogTrace(wxT("activate"), wxT("Activating frame %p (from focus_in)"), g_activeFrame);
+        wxActivateEvent event(wxEVT_ACTIVATE, false, g_activeFrame->GetId());
+        event.SetEventObject(g_activeFrame);
+        g_activeFrame->GetEventHandler()->ProcessEvent(event);
+
+        g_activeFrame = NULL;
+    }
+
+    return FALSE;
+}
+}
 
 //-----------------------------------------------------------------------------
 // "focus" from m_window
 //-----------------------------------------------------------------------------
 
 
 //-----------------------------------------------------------------------------
 // "focus" from m_window
 //-----------------------------------------------------------------------------
 
+extern "C" {
 static gint gtk_frame_focus_callback( GtkWidget *widget, GtkDirectionType WXUNUSED(d), wxWindow *WXUNUSED(win) )
 {
     if (g_isIdle)
 static gint gtk_frame_focus_callback( GtkWidget *widget, GtkDirectionType WXUNUSED(d), wxWindow *WXUNUSED(win) )
 {
     if (g_isIdle)
@@ -91,11 +226,13 @@ static gint gtk_frame_focus_callback( GtkWidget *widget, GtkDirectionType WXUNUS
     gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "focus" );
     return TRUE;
 }
     gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "focus" );
     return TRUE;
 }
+}
 
 //-----------------------------------------------------------------------------
 // "size_allocate"
 //-----------------------------------------------------------------------------
 
 
 //-----------------------------------------------------------------------------
 // "size_allocate"
 //-----------------------------------------------------------------------------
 
+extern "C" {
 static void gtk_frame_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxTopLevelWindowGTK *win )
 {
     if (g_isIdle)
 static void gtk_frame_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxTopLevelWindowGTK *win )
 {
     if (g_isIdle)
@@ -118,55 +255,51 @@ static void gtk_frame_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation*
 
         win->m_width = alloc->width;
         win->m_height = alloc->height;
 
         win->m_width = alloc->width;
         win->m_height = alloc->height;
-        win->m_queuedFullRedraw = TRUE;
         win->GtkUpdateSize();
     }
 }
         win->GtkUpdateSize();
     }
 }
+}
 
 //-----------------------------------------------------------------------------
 // "delete_event"
 //-----------------------------------------------------------------------------
 
 
 //-----------------------------------------------------------------------------
 // "delete_event"
 //-----------------------------------------------------------------------------
 
+extern "C" {
 static gint gtk_frame_delete_callback( GtkWidget *WXUNUSED(widget), GdkEvent *WXUNUSED(event), wxTopLevelWindowGTK *win )
 {
     if (g_isIdle)
         wxapp_install_idle_handler();
 
     if (win->IsEnabled() &&
 static gint gtk_frame_delete_callback( GtkWidget *WXUNUSED(widget), GdkEvent *WXUNUSED(event), wxTopLevelWindowGTK *win )
 {
     if (g_isIdle)
         wxapp_install_idle_handler();
 
     if (win->IsEnabled() &&
-        (g_openDialogs == 0 || (win->GetExtraStyle() & wxTLW_EX_DIALOG)))
+        (g_openDialogs == 0 || (win->GetExtraStyle() & wxTOPLEVEL_EX_DIALOG) ||
+         win->IsGrabbed()))
         win->Close();
 
     return TRUE;
 }
         win->Close();
 
     return TRUE;
 }
+}
 
 
 //-----------------------------------------------------------------------------
 // "configure_event"
 //-----------------------------------------------------------------------------
 
 
 
 //-----------------------------------------------------------------------------
 // "configure_event"
 //-----------------------------------------------------------------------------
 
+extern "C" {
 static gint
 static gint
-#if (GTK_MINOR_VERSION > 0)
 gtk_frame_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigure *WXUNUSED(event), wxTopLevelWindowGTK *win )
 gtk_frame_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigure *WXUNUSED(event), wxTopLevelWindowGTK *win )
-#else
-gtk_frame_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigure *event, wxTopLevelWindowGTK *win )
-#endif
 {
     if (g_isIdle)
         wxapp_install_idle_handler();
 
 {
     if (g_isIdle)
         wxapp_install_idle_handler();
 
-    if (!win->m_hasVMT)
+    if (!win->m_hasVMT || !win->IsShown())
         return FALSE;
 
         return FALSE;
 
-#if (GTK_MINOR_VERSION > 0)
+
     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;
     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;
-#else
-    win->m_x = event->x;
-    win->m_y = event->y;
-#endif
 
     wxMoveEvent mevent( wxPoint(win->m_x,win->m_y), win->GetId() );
     mevent.SetEventObject( win );
 
     wxMoveEvent mevent( wxPoint(win->m_x,win->m_y), win->GetId() );
     mevent.SetEventObject( win );
@@ -174,107 +307,65 @@ gtk_frame_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigure *ev
 
     return FALSE;
 }
 
     return FALSE;
 }
+}
 
 //-----------------------------------------------------------------------------
 // "realize" from m_widget
 //-----------------------------------------------------------------------------
 
 
 //-----------------------------------------------------------------------------
 // "realize" from m_widget
 //-----------------------------------------------------------------------------
 
-/* we cannot MWM hints and icons before the widget has been realized,
-   so we do this directly after realization */
+// we cannot MWM hints and icons before the widget has been realized,
+// so we do this directly after realization
 
 
+extern "C" {
 static void
 static void
-gtk_frame_realized_callback( GtkWidget * WXUNUSED(widget), wxTopLevelWindowGTK *win )
+gtk_frame_realized_callback( GtkWidget * WXUNUSED(widget),
+                             wxTopLevelWindowGTK *win )
 {
     if (g_isIdle)
         wxapp_install_idle_handler();
 
 {
     if (g_isIdle)
         wxapp_install_idle_handler();
 
-    if ((win->m_miniEdge > 0) || (win->HasFlag(wxSIMPLE_BORDER)) || (win->HasFlag(wxNO_BORDER)))
-    {
-        /* This is a mini-frame or a borderless frame. */
-        gdk_window_set_decorations( win->m_widget->window, (GdkWMDecoration)0 );
-        gdk_window_set_functions( win->m_widget->window, (GdkWMFunction)0 );
-    }
-    else
-    {
-        /* All this is for Motif Window Manager "hints" and is supposed to be
-           recognized by other WM as well. Not tested. */
-        long decor = (long) GDK_DECOR_BORDER;
-        long func = (long) GDK_FUNC_MOVE;
-
-        if ((win->GetWindowStyle() & wxCAPTION) != 0)
-            decor |= GDK_DECOR_TITLE;
-        if ((win->GetWindowStyle() & wxSYSTEM_MENU) != 0)
-        {
-            decor |= GDK_DECOR_MENU;
-            func |= GDK_FUNC_CLOSE;
-        }
-        if ((win->GetWindowStyle() & wxMINIMIZE_BOX) != 0)
-        {
-            func |= GDK_FUNC_MINIMIZE;
-            decor |= GDK_DECOR_MINIMIZE;
-        }
-        if ((win->GetWindowStyle() & wxMAXIMIZE_BOX) != 0)
-        {
-            func |= GDK_FUNC_MAXIMIZE;
-            decor |= GDK_DECOR_MAXIMIZE;
-        }
-        if ((win->GetWindowStyle() & wxRESIZE_BORDER) != 0)
-        {
-           func |= GDK_FUNC_RESIZE;
-           decor |= GDK_DECOR_RESIZEH;
-        }
-
-        gdk_window_set_decorations( win->m_widget->window, (GdkWMDecoration)decor);
-        gdk_window_set_functions( win->m_widget->window, (GdkWMFunction)func);
-    }
+    // 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,
+                               (GdkWMDecoration)win->m_gdkDecor);
+    gdk_window_set_functions(win->m_widget->window,
+                               (GdkWMFunction)win->m_gdkFunc);
 
 
-    /* GTK's shrinking/growing policy */
-    if ((win->GetWindowStyle() & wxRESIZE_BORDER) == 0)
+    // GTK's shrinking/growing policy
+    if ((win->m_gdkFunc & GDK_FUNC_RESIZE) == 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);
     else
         gtk_window_set_policy(GTK_WINDOW(win->m_widget), 1, 1, 1);
 
-    /* reset the icon */
-    wxIcon iconOld = win->GetIcon();
-    if ( iconOld != wxNullIcon )
+    // reset the icon
+    wxIconBundle iconsOld = win->GetIcons();
+    if ( iconsOld.GetIcon(-1).Ok() )
     {
     {
-        wxIcon icon( iconOld );
         win->SetIcon( wxNullIcon );
         win->SetIcon( wxNullIcon );
-        win->SetIcon( icon );
-    }
-
-    /* we set the focus to the child that accepts the focus. this
-       doesn't really have to be done in "realize" but why not? */
-    wxWindowList::Node *node = win->GetChildren().GetFirst();
-    while (node)
-    {
-        wxWindow *child = node->GetData();
-        if (child->AcceptsFocus())
-        {
-            child->SetFocus();
-            break;
-        }
-
-        node = node->GetNext();
+        win->SetIcons( iconsOld );
     }
 }
     }
 }
+}
 
 //-----------------------------------------------------------------------------
 // "map_event" from m_widget
 //-----------------------------------------------------------------------------
 
 
 //-----------------------------------------------------------------------------
 // "map_event" from m_widget
 //-----------------------------------------------------------------------------
 
+extern "C" {
 static void
 gtk_frame_map_callback( GtkWidget * WXUNUSED(widget),
                         GdkEvent * WXUNUSED(event),
                         wxTopLevelWindow *win )
 {
 static void
 gtk_frame_map_callback( GtkWidget * WXUNUSED(widget),
                         GdkEvent * WXUNUSED(event),
                         wxTopLevelWindow *win )
 {
-    win->SetIconizeState(FALSE);
+    win->SetIconizeState(false);
+}
 }
 
 //-----------------------------------------------------------------------------
 // "unmap_event" from m_widget
 //-----------------------------------------------------------------------------
 
 }
 
 //-----------------------------------------------------------------------------
 // "unmap_event" from m_widget
 //-----------------------------------------------------------------------------
 
+extern "C" {
 static void
 gtk_frame_unmap_callback( GtkWidget * WXUNUSED(widget),
                           GdkEvent * WXUNUSED(event),
 static void
 gtk_frame_unmap_callback( GtkWidget * WXUNUSED(widget),
                           GdkEvent * WXUNUSED(event),
@@ -282,34 +373,52 @@ gtk_frame_unmap_callback( GtkWidget * WXUNUSED(widget),
 {
     win->SetIconizeState(TRUE);
 }
 {
     win->SetIconizeState(TRUE);
 }
+}
 
 //-----------------------------------------------------------------------------
 // "expose_event" of m_client
 //-----------------------------------------------------------------------------
 
 
 //-----------------------------------------------------------------------------
 // "expose_event" of m_client
 //-----------------------------------------------------------------------------
 
+extern "C" {
 static int gtk_window_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindow *win )
 {
     GtkPizza *pizza = GTK_PIZZA(widget);
 
 static int gtk_window_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindow *win )
 {
     GtkPizza *pizza = GTK_PIZZA(widget);
 
-    gtk_paint_flat_box (win->m_widget->style, pizza->bin_window, GTK_STATE_NORMAL,
-                GTK_SHADOW_NONE, &gdk_event->area, win->m_widget, "base", 0, 0, -1, -1);
+    gtk_paint_flat_box (win->m_widget->style,
+                        pizza->bin_window, GTK_STATE_NORMAL,
+                        GTK_SHADOW_NONE,
+                        &gdk_event->area,
+                        win->m_widget,
+                        (char *)"base",
+                        0, 0, -1, -1);
 
 
-    return TRUE;
+    return FALSE;
+}
 }
 
 //-----------------------------------------------------------------------------
 // "draw" of m_client
 //-----------------------------------------------------------------------------
 
 }
 
 //-----------------------------------------------------------------------------
 // "draw" of m_client
 //-----------------------------------------------------------------------------
 
+#ifndef __WXGTK20__
 
 
+extern "C" {
 static void gtk_window_draw_callback( GtkWidget *widget, GdkRectangle *rect, wxWindow *win )
 {
     GtkPizza *pizza = GTK_PIZZA(widget);
 
 static void gtk_window_draw_callback( GtkWidget *widget, GdkRectangle *rect, wxWindow *win )
 {
     GtkPizza *pizza = GTK_PIZZA(widget);
 
-    gtk_paint_flat_box (win->m_widget->style, pizza->bin_window, GTK_STATE_NORMAL,
-                GTK_SHADOW_NONE, rect, win->m_widget, "base", 0, 0, -1, -1);
+    gtk_paint_flat_box (win->m_widget->style,
+                        pizza->bin_window, GTK_STATE_NORMAL,
+                        GTK_SHADOW_NONE,
+                        rect,
+                        win->m_widget,
+                        (char *)"base",
+                        0, 0, -1, -1);
+}
 }
 
 }
 
+#endif // GTK+ 1.x
+
 // ----------------------------------------------------------------------------
 // wxTopLevelWindowGTK itself
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 // wxTopLevelWindowGTK itself
 // ----------------------------------------------------------------------------
@@ -320,7 +429,7 @@ static void gtk_window_draw_callback( GtkWidget *widget, GdkRectangle *rect, wxW
 
 /* 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
 
 /* 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 wxWindows requires different ways to insert
+ * virtual function here as wxWidgets requires different ways to insert
  * a child in container classes. */
 
 static void wxInsertChildInTopLevelWindow( wxTopLevelWindowGTK* parent, wxWindow* child )
  * a child in container classes. */
 
 static void wxInsertChildInTopLevelWindow( wxTopLevelWindowGTK* parent, wxWindow* child )
@@ -329,7 +438,7 @@ static void wxInsertChildInTopLevelWindow( wxTopLevelWindowGTK* parent, wxWindow
 
     if (!parent->m_insertInClientArea)
     {
 
     if (!parent->m_insertInClientArea)
     {
-        /* these are outside the client area */
+        // these are outside the client area
         wxTopLevelWindowGTK* frame = (wxTopLevelWindowGTK*) parent;
         gtk_pizza_put( GTK_PIZZA(frame->m_mainWidget),
                          GTK_WIDGET(child->m_widget),
         wxTopLevelWindowGTK* frame = (wxTopLevelWindowGTK*) parent;
         gtk_pizza_put( GTK_PIZZA(frame->m_mainWidget),
                          GTK_WIDGET(child->m_widget),
@@ -340,7 +449,7 @@ static void wxInsertChildInTopLevelWindow( wxTopLevelWindowGTK* parent, wxWindow
     }
     else
     {
     }
     else
     {
-        /* these are inside the client area */
+        // these are inside the client area
         gtk_pizza_put( GTK_PIZZA(parent->m_wxwindow),
                          GTK_WIDGET(child->m_widget),
                          child->m_x,
         gtk_pizza_put( GTK_PIZZA(parent->m_wxwindow),
                          GTK_WIDGET(child->m_widget),
                          child->m_x,
@@ -349,7 +458,7 @@ static void wxInsertChildInTopLevelWindow( wxTopLevelWindowGTK* parent, wxWindow
                          child->m_height );
     }
 
                          child->m_height );
     }
 
-    /* resize on OnInternalIdle */
+    // resize on OnInternalIdle
     parent->GtkUpdateSize();
 }
 
     parent->GtkUpdateSize();
 }
 
@@ -359,110 +468,158 @@ static void wxInsertChildInTopLevelWindow( wxTopLevelWindowGTK* parent, wxWindow
 
 void wxTopLevelWindowGTK::Init()
 {
 
 void wxTopLevelWindowGTK::Init()
 {
-    m_sizeSet = FALSE;
+    m_sizeSet = false;
     m_miniEdge = 0;
     m_miniTitle = 0;
     m_mainWidget = (GtkWidget*) NULL;
     m_miniEdge = 0;
     m_miniTitle = 0;
     m_mainWidget = (GtkWidget*) NULL;
-    m_insertInClientArea = TRUE;
-    m_isFrame = TRUE;
-    m_isIconized = FALSE;
-    m_fsIsShowing = FALSE;
-    m_themeEnabled = TRUE;
+    m_insertInClientArea = true;
+    m_isIconized = false;
+    m_fsIsShowing = false;
+    m_themeEnabled = true;
+    m_gdkDecor = m_gdkFunc = 0;
+    m_grabbed = false;
+
+    m_urgency_hint = -2;
 }
 
 bool wxTopLevelWindowGTK::Create( wxWindow *parent,
 }
 
 bool wxTopLevelWindowGTK::Create( wxWindow *parent,
-                      wxWindowID id,
-                      const wxString& title,
-                      const wxPoint& pos,
-                      const wxSize& sizeOrig,
-                      long style,
-                      const wxString &name )
+                                  wxWindowID id,
+                                  const wxString& title,
+                                  const wxPoint& pos,
+                                  const wxSize& sizeOrig,
+                                  long style,
+                                  const wxString &name )
 {
     // always create a frame of some reasonable, even if arbitrary, size (at
     // least for MSW compatibility)
     wxSize size = sizeOrig;
 {
     // always create a frame of some reasonable, even if arbitrary, size (at
     // least for MSW compatibility)
     wxSize size = sizeOrig;
-    if ( size.x == -1 || size.y == -1 )
-    {
-        wxSize sizeDpy = wxGetDisplaySize();
-        if ( size.x == -1 )
-            size.x = sizeDpy.x / 3;
-        if ( size.y == -1 )
-            size.y = sizeDpy.y / 5;
-    }
+    size.x = WidthDefault(size.x);
+    size.y = HeightDefault(size.y);
 
     wxTopLevelWindows.Append( this );
 
 
     wxTopLevelWindows.Append( this );
 
-    m_needParent = FALSE;
+    m_needParent = false;
 
     if (!PreCreation( parent, pos, size ) ||
         !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
     {
         wxFAIL_MSG( wxT("wxTopLevelWindowGTK creation failed") );
 
     if (!PreCreation( parent, pos, size ) ||
         !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
     {
         wxFAIL_MSG( wxT("wxTopLevelWindowGTK creation failed") );
-        return FALSE;
+        return false;
     }
 
     m_title = title;
 
     m_insertCallback = (wxInsertChildFunction) wxInsertChildInTopLevelWindow;
 
     }
 
     m_title = title;
 
     m_insertCallback = (wxInsertChildFunction) wxInsertChildInTopLevelWindow;
 
-    GtkWindowType win_type = GTK_WINDOW_TOPLEVEL;
-
-    if (style & wxFRAME_TOOL_WINDOW)
-        win_type = GTK_WINDOW_POPUP;
-        
-    if (GetExtraStyle() & wxTLW_EX_DIALOG)
-        win_type = GTK_WINDOW_DIALOG;
-
-    m_widget = gtk_window_new( win_type );
+    // NB: m_widget may be !=NULL if it was created by derived class' Create,
+    //     e.g. in wxTaskBarIconAreaGTK
+    if (m_widget == NULL)
+    {
+        if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG)
+        {
+#ifdef __WXGTK20__
+            m_widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+            // Tell WM that this is a dialog window and make it center
+            // on parent by default (this is what GtkDialog ctor does):
+            gtk_window_set_type_hint(GTK_WINDOW(m_widget),
+                                     GDK_WINDOW_TYPE_HINT_DIALOG);
+            gtk_window_set_position(GTK_WINDOW(m_widget),
+                                    GTK_WIN_POS_CENTER_ON_PARENT);
+#else
+            m_widget = gtk_window_new(GTK_WINDOW_DIALOG);
+#endif
+        }
+        else
+        {
+            m_widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+#if GTK_CHECK_VERSION(2,1,0)
+            if (!gtk_check_version(2,1,0))
+            {
+                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;
+                }
+            }
+#endif
+        }
+    }
 
 
-    if ((m_parent) && (HasFlag(wxFRAME_FLOAT_ON_PARENT)) && (GTK_IS_WINDOW(m_parent->m_widget)))
-        gtk_window_set_transient_for( GTK_WINDOW(m_widget), GTK_WINDOW(m_parent->m_widget) );
+    wxWindow *topParent = wxGetTopLevelParent(m_parent);
+    if (topParent && (((GTK_IS_WINDOW(topParent->m_widget)) &&
+                       (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG)) ||
+                       (style & wxFRAME_FLOAT_ON_PARENT)))
+    {
+        gtk_window_set_transient_for( GTK_WINDOW(m_widget),
+                                      GTK_WINDOW(topParent->m_widget) );
+    }
 
 
-    if (!name.IsEmpty())
-        gtk_window_set_wmclass( GTK_WINDOW(m_widget), name.mb_str(), name.mb_str() );
+#if GTK_CHECK_VERSION(2,2,0)
+    if (!gtk_check_version(2,2,0))
+    {
+        if (style & wxFRAME_NO_TASKBAR)
+        {
+            gtk_window_set_skip_taskbar_hint(GTK_WINDOW(m_widget), TRUE);
+        }
+    }
+#endif
 
 
-#ifdef __WXDEBUG__
-    debug_focus_in( m_widget, wxT("wxTopLevelWindowGTK::m_widget"), name );
+#if GTK_CHECK_VERSION(2,4,0)
+    if (!gtk_check_version(2,4,0))
+    {
+        if (style & wxSTAY_ON_TOP)
+        {
+            gtk_window_set_keep_above(GTK_WINDOW(m_widget), TRUE);
+        }
+    }
 #endif
 
 #endif
 
-    gtk_window_set_title( GTK_WINDOW(m_widget), title.mbc_str() );
+    if (!name.empty())
+        gtk_window_set_wmclass( GTK_WINDOW(m_widget), wxGTK_CONV( name ), wxGTK_CONV( name ) );
+
+    gtk_window_set_title( GTK_WINDOW(m_widget), wxGTK_CONV( title ) );
     GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS );
 
     gtk_signal_connect( GTK_OBJECT(m_widget), "delete_event",
         GTK_SIGNAL_FUNC(gtk_frame_delete_callback), (gpointer)this );
 
     GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS );
 
     gtk_signal_connect( GTK_OBJECT(m_widget), "delete_event",
         GTK_SIGNAL_FUNC(gtk_frame_delete_callback), (gpointer)this );
 
-    /* m_mainWidget holds the toolbar, the menubar and the client area */
+    // m_mainWidget holds the toolbar, the menubar and the client area
     m_mainWidget = gtk_pizza_new();
     gtk_widget_show( m_mainWidget );
     GTK_WIDGET_UNSET_FLAGS( m_mainWidget, GTK_CAN_FOCUS );
     gtk_container_add( GTK_CONTAINER(m_widget), m_mainWidget );
 
     m_mainWidget = gtk_pizza_new();
     gtk_widget_show( m_mainWidget );
     GTK_WIDGET_UNSET_FLAGS( m_mainWidget, GTK_CAN_FOCUS );
     gtk_container_add( GTK_CONTAINER(m_widget), m_mainWidget );
 
-    /* for m_mainWidget themes */
-    gtk_signal_connect( GTK_OBJECT(m_mainWidget), "expose_event",
+    if (m_miniEdge == 0) // wxMiniFrame has its own version.
+    {
+       // For m_mainWidget themes
+       gtk_signal_connect( GTK_OBJECT(m_mainWidget), "expose_event",
                 GTK_SIGNAL_FUNC(gtk_window_expose_callback), (gpointer)this );
                 GTK_SIGNAL_FUNC(gtk_window_expose_callback), (gpointer)this );
-    gtk_signal_connect( GTK_OBJECT(m_mainWidget), "draw",
+#ifndef __WXGTK20__
+       gtk_signal_connect( GTK_OBJECT(m_mainWidget), "draw",
                 GTK_SIGNAL_FUNC(gtk_window_draw_callback), (gpointer)this );
                 GTK_SIGNAL_FUNC(gtk_window_draw_callback), (gpointer)this );
-
-#ifdef __WXDEBUG__
-    debug_focus_in( m_mainWidget, wxT("wxTopLevelWindowGTK::m_mainWidget"), name );
 #endif
 #endif
+    }
 
 
-    /* m_wxwindow only represents the client area without toolbar and menubar */
+    // m_wxwindow only represents the client area without toolbar and menubar
     m_wxwindow = gtk_pizza_new();
     gtk_widget_show( m_wxwindow );
     gtk_container_add( GTK_CONTAINER(m_mainWidget), m_wxwindow );
 
     m_wxwindow = gtk_pizza_new();
     gtk_widget_show( m_wxwindow );
     gtk_container_add( GTK_CONTAINER(m_mainWidget), m_wxwindow );
 
-#ifdef __WXDEBUG__
-    debug_focus_in( m_wxwindow, wxT("wxTopLevelWindowGTK::m_wxwindow"), name );
-#endif
-
-    /* we donm't allow the frame to get the focus as otherwise
-       the frame will grab it at arbitrary focus changes. */
+    // we donm't allow the frame to get the focus as otherwise
+    // the frame will grab it at arbitrary focus changes
     GTK_WIDGET_UNSET_FLAGS( m_wxwindow, GTK_CAN_FOCUS );
 
     if (m_parent) m_parent->AddChild( this );
 
     GTK_WIDGET_UNSET_FLAGS( m_wxwindow, GTK_CAN_FOCUS );
 
     if (m_parent) m_parent->AddChild( 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_frame_size_callback), (gpointer)this );
 
     gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate",
         GTK_SIGNAL_FUNC(gtk_frame_size_callback), (gpointer)this );
 
@@ -470,90 +627,192 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent,
 
     if ((m_x != -1) || (m_y != -1))
         gtk_widget_set_uposition( m_widget, m_x, m_y );
 
     if ((m_x != -1) || (m_y != -1))
         gtk_widget_set_uposition( m_widget, m_x, m_y );
-    gtk_widget_set_usize( m_widget, m_width, m_height );
 
 
-    /*  we cannot set MWM hints and icons before the widget has
-        been realized, so we do this directly after realization */
+    gtk_window_set_default_size( GTK_WINDOW(m_widget), m_width, m_height );
+
+    //  we cannot set MWM hints and icons before the widget has
+    //  been realized, so we do this directly after realization
     gtk_signal_connect( GTK_OBJECT(m_widget), "realize",
                         GTK_SIGNAL_FUNC(gtk_frame_realized_callback), (gpointer) this );
 
     gtk_signal_connect( GTK_OBJECT(m_widget), "realize",
                         GTK_SIGNAL_FUNC(gtk_frame_realized_callback), (gpointer) this );
 
-    /* the only way to get the window size is to connect to this event */
-    gtk_signal_connect( GTK_OBJECT(m_widget), "configure_event",
-        GTK_SIGNAL_FUNC(gtk_frame_configure_callback), (gpointer)this );
-
-    /* map and unmap for iconized state */
+    // map and unmap for iconized state
     gtk_signal_connect( GTK_OBJECT(m_widget), "map_event",
         GTK_SIGNAL_FUNC(gtk_frame_map_callback), (gpointer)this );
     gtk_signal_connect( GTK_OBJECT(m_widget), "unmap_event",
         GTK_SIGNAL_FUNC(gtk_frame_unmap_callback), (gpointer)this );
 
     gtk_signal_connect( GTK_OBJECT(m_widget), "map_event",
         GTK_SIGNAL_FUNC(gtk_frame_map_callback), (gpointer)this );
     gtk_signal_connect( GTK_OBJECT(m_widget), "unmap_event",
         GTK_SIGNAL_FUNC(gtk_frame_unmap_callback), (gpointer)this );
 
-    /* the only way to get the window size is to connect to this event */
+    // the only way to get the window size is to connect to this event
     gtk_signal_connect( GTK_OBJECT(m_widget), "configure_event",
         GTK_SIGNAL_FUNC(gtk_frame_configure_callback), (gpointer)this );
 
     gtk_signal_connect( GTK_OBJECT(m_widget), "configure_event",
         GTK_SIGNAL_FUNC(gtk_frame_configure_callback), (gpointer)this );
 
-    /* disable native tab traversal */
+    // disable native tab traversal
     gtk_signal_connect( GTK_OBJECT(m_widget), "focus",
         GTK_SIGNAL_FUNC(gtk_frame_focus_callback), (gpointer)this );
 
     gtk_signal_connect( GTK_OBJECT(m_widget), "focus",
         GTK_SIGNAL_FUNC(gtk_frame_focus_callback), (gpointer)this );
 
-    return TRUE;
+    // activation
+    gtk_signal_connect( GTK_OBJECT(m_widget), "focus_in_event",
+        GTK_SIGNAL_FUNC(gtk_frame_focus_in_callback), (gpointer)this );
+    gtk_signal_connect( GTK_OBJECT(m_widget), "focus_out_event",
+        GTK_SIGNAL_FUNC(gtk_frame_focus_out_callback), (gpointer)this );
+
+    // decorations
+    if ((m_miniEdge > 0) || (style & wxSIMPLE_BORDER) || (style & wxNO_BORDER))
+    {
+        m_gdkDecor = 0;
+        m_gdkFunc = 0;
+    }
+    else
+    {
+        m_gdkDecor = (long) GDK_DECOR_BORDER;
+        m_gdkFunc = (long) GDK_FUNC_MOVE;
+
+        // All this is for Motif Window Manager "hints" and is supposed to be
+        // recognized by other WMs as well.
+        if ((style & wxCAPTION) != 0)
+        {
+            m_gdkDecor |= GDK_DECOR_TITLE;
+        }
+        if ((style & wxCLOSE_BOX) != 0)
+        {
+            m_gdkFunc |= GDK_FUNC_CLOSE;
+        }
+        if ((style & wxSYSTEM_MENU) != 0)
+        {
+            m_gdkDecor |= GDK_DECOR_MENU;
+        }
+        if ((style & wxMINIMIZE_BOX) != 0)
+        {
+            m_gdkFunc |= GDK_FUNC_MINIMIZE;
+            m_gdkDecor |= GDK_DECOR_MINIMIZE;
+        }
+        if ((style & wxMAXIMIZE_BOX) != 0)
+        {
+            m_gdkFunc |= GDK_FUNC_MAXIMIZE;
+            m_gdkDecor |= GDK_DECOR_MAXIMIZE;
+        }
+        if ((style & wxRESIZE_BORDER) != 0)
+        {
+           m_gdkFunc |= GDK_FUNC_RESIZE;
+           m_gdkDecor |= GDK_DECOR_RESIZEH;
+        }
+    }
+
+    return true;
 }
 
 wxTopLevelWindowGTK::~wxTopLevelWindowGTK()
 {
 }
 
 wxTopLevelWindowGTK::~wxTopLevelWindowGTK()
 {
-    m_isBeingDeleted = TRUE;
-
-    wxTopLevelWindows.DeleteObject( this );
+    if (m_grabbed)
+    {
+        wxASSERT_MSG( FALSE, _T("Window still grabbed"));
+        RemoveGrab();
+    }
 
 
-    if (wxTheApp->GetTopWindow() == this)
-        wxTheApp->SetTopWindow( (wxWindow*) NULL );
+    m_isBeingDeleted = true;
 
 
-    if ((wxTopLevelWindows.Number() == 0) &&
-        (wxTheApp->GetExitOnFrameDelete()))
+    // it may also be GtkScrolledWindow in the case of an MDI child
+    if (GTK_IS_WINDOW(m_widget))
     {
     {
-        wxTheApp->ExitMainLoop();
+        gtk_window_set_focus( GTK_WINDOW(m_widget), NULL );
     }
     }
+
+    if (g_activeFrame == this)
+        g_activeFrame = NULL;
+    if (g_lastActiveFrame == this)
+        g_lastActiveFrame = NULL;
 }
 
 }
 
+
+
 bool wxTopLevelWindowGTK::ShowFullScreen(bool show, long style )
 {
 bool wxTopLevelWindowGTK::ShowFullScreen(bool show, long style )
 {
-    if (show == m_fsIsShowing) return FALSE; // return what?
+    if (show == m_fsIsShowing)
+        return false; // return what?
 
     m_fsIsShowing = show;
 
 
     m_fsIsShowing = show;
 
-    if (show)
-    {
-        m_fsSaveStyle = m_windowStyle;
-        m_fsSaveFlag = style;
-        GetPosition( &m_fsSaveFrame.x, &m_fsSaveFrame.y );
-        GetSize( &m_fsSaveFrame.width, &m_fsSaveFrame.height );
+    wxX11FullScreenMethod method =
+        wxGetFullScreenMethodX11((WXDisplay*)GDK_DISPLAY(),
+                                 (WXWindow)GDK_ROOT_WINDOW());
 
 
-        gtk_widget_hide( m_widget );
-        gtk_widget_unrealize( m_widget );
-
-        m_windowStyle = wxSIMPLE_BORDER;
-
-        int x;
-        int y;
-        wxDisplaySize( &x, &y );
-        SetSize( 0, 0, x, y );
-
-        gtk_widget_realize( m_widget );
-        gtk_widget_show( m_widget );
+#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 (show)
+            gtk_window_fullscreen( GTK_WINDOW( m_widget ) );
+        else
+            gtk_window_unfullscreen( GTK_WINDOW( m_widget ) );
     }
     else
     }
     else
+#endif // GTK+ >= 2.2.0
     {
     {
-        gtk_widget_hide( m_widget );
-        gtk_widget_unrealize( m_widget );
+        GdkWindow *window = m_widget->window;
 
 
-        m_windowStyle = m_fsSaveStyle;
-
-        SetSize( m_fsSaveFrame.x, m_fsSaveFrame.y, m_fsSaveFrame.width, m_fsSaveFrame.height );
-
-        gtk_widget_realize( m_widget );
-        gtk_widget_show( m_widget );
+        if (show)
+        {
+            m_fsSaveFlag = style;
+            GetPosition( &m_fsSaveFrame.x, &m_fsSaveFrame.y );
+            GetSize( &m_fsSaveFrame.width, &m_fsSaveFrame.height );
+
+            int screen_width,screen_height;
+            wxDisplaySize( &screen_width, &screen_height );
+
+            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);
+            }
+
+            gdk_window_get_origin (m_widget->window, &root_x, &root_y);
+            gdk_window_get_geometry (m_widget->window, &client_x, &client_y,
+                         &width, &height, NULL);
+
+            gdk_window_move_resize (m_widget->window, -client_x, -client_y,
+                        screen_width + 1, screen_height + 1);
+
+            wxSetFullScreenStateX11((WXDisplay*)GDK_DISPLAY(),
+                                    (WXWindow)GDK_ROOT_WINDOW(),
+                                    (WXWindow)GDK_WINDOW_XWINDOW(window),
+                                    show, &m_fsSaveFrame, method);
+        }
+        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);
+            }
+
+            wxSetFullScreenStateX11((WXDisplay*)GDK_DISPLAY(),
+                                    (WXWindow)GDK_ROOT_WINDOW(),
+                                    (WXWindow)GDK_WINDOW_XWINDOW(window),
+                                    show, &m_fsSaveFrame, method);
+
+            SetSize(m_fsSaveFrame.x, m_fsSaveFrame.y,
+                    m_fsSaveFrame.width, m_fsSaveFrame.height);
+        }
     }
 
     }
 
-    return TRUE;
+    // documented behaviour is to show the window if it's still hidden when
+    // showing it full screen
+    if ( show && !IsShown() )
+        Show();
+
+    return true;
 }
 
 // ----------------------------------------------------------------------------
 }
 
 // ----------------------------------------------------------------------------
@@ -574,9 +833,21 @@ bool wxTopLevelWindowGTK::Show( bool show )
         GtkOnSize( m_x, m_y, m_width, m_height );
     }
 
         GtkOnSize( m_x, m_y, m_width, m_height );
     }
 
+    if (show)
+        gtk_widget_set_uposition( m_widget, m_x, m_y );
+
     return wxWindow::Show( show );
 }
 
     return wxWindow::Show( show );
 }
 
+void wxTopLevelWindowGTK::Raise()
+{
+#ifdef __WXGTK20__
+    gtk_window_present( GTK_WINDOW( m_widget ) );
+#else
+    wxWindow::Raise();
+#endif
+}
+
 void wxTopLevelWindowGTK::DoMoveWindow(int WXUNUSED(x), int WXUNUSED(y), int WXUNUSED(width), int WXUNUSED(height) )
 {
     wxFAIL_MSG( wxT("DoMoveWindow called for wxTopLevelWindowGTK") );
 void wxTopLevelWindowGTK::DoMoveWindow(int WXUNUSED(x), int WXUNUSED(y), int WXUNUSED(width), int WXUNUSED(height) )
 {
     wxFAIL_MSG( wxT("DoMoveWindow called for wxTopLevelWindowGTK") );
@@ -586,13 +857,13 @@ void wxTopLevelWindowGTK::DoSetSize( int x, int y, int width, int height, int si
 {
     wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
 
 {
     wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
 
-    /* this shouldn't happen: wxFrameGTK, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
+    // this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow
     wxASSERT_MSG( (m_wxwindow != NULL), wxT("invalid frame") );
 
     wxASSERT_MSG( (m_wxwindow != NULL), wxT("invalid frame") );
 
-    /* avoid recursions */
+    // avoid recursions
     if (m_resizing)
         return;
     if (m_resizing)
         return;
-    m_resizing = TRUE;
+    m_resizing = true;
 
     int old_x = m_x;
     int old_y = m_y;
 
     int old_x = m_x;
     int old_y = m_y;
@@ -604,16 +875,14 @@ void wxTopLevelWindowGTK::DoSetSize( int x, int y, int width, int height, int si
     {
         if (x != -1) m_x = x;
         if (y != -1) m_y = y;
     {
         if (x != -1) m_x = x;
         if (y != -1) m_y = y;
-        if (width != -1) m_width = width;
-        if (height != -1) m_height = height;
     }
     else
     {
         m_x = x;
         m_y = y;
     }
     else
     {
         m_x = x;
         m_y = y;
-        m_width = width;
-        m_height = height;
     }
     }
+    if (width != -1) m_width = width;
+    if (height != -1) m_height = height;
 
 /*
     if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
 
 /*
     if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
@@ -627,10 +896,25 @@ void wxTopLevelWindowGTK::DoSetSize( int x, int y, int width, int height, int si
     }
 */
 
     }
 */
 
-    if ((m_minWidth != -1) && (m_width < m_minWidth)) m_width = m_minWidth;
-    if ((m_minHeight != -1) && (m_height < m_minHeight)) m_height = m_minHeight;
-    if ((m_maxWidth != -1) && (m_width > m_maxWidth)) m_width = m_maxWidth;
-    if ((m_maxHeight != -1) && (m_height > m_maxHeight)) m_height = m_maxHeight;
+    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;
 
     if ((m_x != -1) || (m_y != -1))
     {
 
     if ((m_x != -1) || (m_y != -1))
     {
@@ -642,15 +926,18 @@ void wxTopLevelWindowGTK::DoSetSize( int x, int y, int width, int height, int si
 
     if ((m_width != old_width) || (m_height != old_height))
     {
 
     if ((m_width != old_width) || (m_height != old_height))
     {
-        gtk_widget_set_usize( m_widget, m_width, m_height );
+        if (m_widget->window)
+            gdk_window_resize( m_widget->window, m_width, m_height );
+        else
+            gtk_window_set_default_size( GTK_WINDOW(m_widget), m_width, m_height );
 
         /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
            done either directly before the frame is shown or in idle time
            so that different calls to SetSize() don't lead to flicker. */
 
         /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
            done either directly before the frame is shown or in idle time
            so that different calls to SetSize() don't lead to flicker. */
-        m_sizeSet = FALSE;
+        m_sizeSet = false;
     }
 
     }
 
-    m_resizing = FALSE;
+    m_resizing = false;
 }
 
 void wxTopLevelWindowGTK::DoGetClientSize( int *width, int *height ) const
 }
 
 void wxTopLevelWindowGTK::DoGetClientSize( int *width, int *height ) const
@@ -660,7 +947,7 @@ void wxTopLevelWindowGTK::DoGetClientSize( int *width, int *height ) const
     wxWindow::DoGetClientSize( width, height );
     if (height)
     {
     wxWindow::DoGetClientSize( width, height );
     if (height)
     {
-        /* mini edge */
+        // mini edge
         *height -= m_miniEdge*2 + m_miniTitle;
     }
     if (width)
         *height -= m_miniEdge*2 + m_miniTitle;
     }
     if (width)
@@ -673,49 +960,87 @@ void wxTopLevelWindowGTK::DoSetClientSize( int width, int height )
 {
     wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
 
 {
     wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
 
-    DoSetSize(-1, -1, 
+    DoSetSize(-1, -1,
               width + m_miniEdge*2, height  + m_miniEdge*2 + m_miniTitle, 0);
 }
 
 void wxTopLevelWindowGTK::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y),
               width + m_miniEdge*2, height  + m_miniEdge*2 + m_miniTitle, 0);
 }
 
 void wxTopLevelWindowGTK::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y),
-                         int width, int height )
+                                     int width, int height )
 {
     // due to a bug in gtk, x,y are always 0
     // m_x = x;
     // m_y = y;
 
 {
     // due to a bug in gtk, x,y are always 0
     // m_x = x;
     // m_y = y;
 
-    /* avoid recursions */
+    // avoid recursions
     if (m_resizing) return;
     if (m_resizing) return;
-    m_resizing = TRUE;
+    m_resizing = true;
 
     if ( m_wxwindow == NULL ) return;
 
     m_width = width;
     m_height = height;
 
 
     if ( m_wxwindow == NULL ) return;
 
     m_width = width;
     m_height = height;
 
-    /* wxMDIChildFrame derives from wxFrameGTK but it _is_ a wxWindow as it uses
+    /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
        wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
        wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
-       set in wxFrameGTK::Create so it is used to check what kind of frame we
+       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 */
 
        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 */
 
-    if ((m_minWidth != -1) && (m_width < m_minWidth)) m_width = m_minWidth;
-    if ((m_minHeight != -1) && (m_height < m_minHeight)) m_height = m_minHeight;
-    if ((m_maxWidth != -1) && (m_width > m_maxWidth)) m_width = m_maxWidth;
-    if ((m_maxHeight != -1) && (m_height > m_maxHeight)) m_height = m_maxHeight;
+    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;
 
     if (m_mainWidget)
     {
 
     if (m_mainWidget)
     {
-        /* set size hints */
-        gint flag = 0; // GDK_HINT_POS;
-        if ((m_minWidth != -1) || (m_minHeight != -1)) flag |= GDK_HINT_MIN_SIZE;
-        if ((m_maxWidth != -1) || (m_maxHeight != -1)) flag |= GDK_HINT_MAX_SIZE;
-        GdkGeometry geom;
-        geom.min_width = m_minWidth;
-        geom.min_height = m_minHeight;
-        geom.max_width = m_maxWidth;
-        geom.max_height = m_maxHeight;
+        // set size hints
+        gint            flag = 0; // GDK_HINT_POS;
+        GdkGeometry     geom;
+
+        if ((minWidth != -1) || (minHeight != -1)) flag |= GDK_HINT_MIN_SIZE;
+        if ((maxWidth != -1) || (maxHeight != -1)) flag |= GDK_HINT_MAX_SIZE;
+
+        geom.min_width = minWidth;
+        geom.min_height = minHeight;
+
+            // Because of the way we set GDK_HINT_MAX_SIZE above, if either of
+            // maxHeight or maxWidth is set, we must set them both, else the
+            // remaining -1 will be taken literally.
+
+            // I'm certain this also happens elsewhere, and is the probable
+            // cause of other such things as:
+            // Gtk-WARNING **: gtk_widget_size_allocate():
+            //       attempt to allocate widget with width 65535 and height 600
+            // but I don't have time to track them all now..
+            //
+            // Really we need to encapulate all this height/width business and
+            // stop any old method from ripping at the members directly and
+            // scattering -1's without regard for who might resolve them later.
+
+        geom.max_width = ( maxHeight == -1 ) ? maxWidth
+                         : ( maxWidth == -1 ) ? wxGetDisplaySize().GetWidth()
+                           : maxWidth ;
+
+        geom.max_height = ( maxWidth == -1 ) ? maxHeight    // ( == -1 here )
+                          : ( maxHeight == -1 ) ? wxGetDisplaySize().GetHeight()
+                            : maxHeight ;
+
         gtk_window_set_geometry_hints( GTK_WINDOW(m_widget),
                                        (GtkWidget*) NULL,
                                        &geom,
         gtk_window_set_geometry_hints( GTK_WINDOW(m_widget),
                                        (GtkWidget*) NULL,
                                        &geom,
@@ -731,24 +1056,25 @@ void wxTopLevelWindowGTK::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y),
         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;
         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;
+
         gtk_pizza_set_size( GTK_PIZZA(m_mainWidget),
                               m_wxwindow,
                               client_x, client_y, client_w, client_h );
     }
     else
     {
         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. */
+        // 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.
     }
 
     }
 
-    m_sizeSet = TRUE;
+    m_sizeSet = true;
 
     // send size event to frame
     wxSizeEvent event( wxSize(m_width,m_height), GetId() );
     event.SetEventObject( this );
     GetEventHandler()->ProcessEvent( event );
 
 
     // send size event to frame
     wxSizeEvent event( wxSize(m_width,m_height), GetId() );
     event.SetEventObject( this );
     GetEventHandler()->ProcessEvent( event );
 
-    m_resizing = FALSE;
+    m_resizing = false;
 }
 
 void wxTopLevelWindowGTK::OnInternalIdle()
 }
 
 void wxTopLevelWindowGTK::OnInternalIdle()
@@ -763,9 +1089,38 @@ void wxTopLevelWindowGTK::OnInternalIdle()
         return;
     }
 
         return;
     }
 
+    // set the focus if not done yet and if we can already do it
+    if ( GTK_WIDGET_REALIZED(m_wxwindow) )
+    {
+        if ( g_delayedFocus &&
+             wxGetTopLevelParent((wxWindow*)g_delayedFocus) == this )
+        {
+            wxLogTrace(_T("focus"),
+                       _T("Setting focus from wxTLW::OnIdle() to %s(%s)"),
+                       g_delayedFocus->GetClassInfo()->GetClassName(),
+                       g_delayedFocus->GetLabel().c_str());
+
+            g_delayedFocus->SetFocus();
+            g_delayedFocus = NULL;
+        }
+    }
+
     wxWindow::OnInternalIdle();
     wxWindow::OnInternalIdle();
-}
 
 
+    // Synthetize activate events.
+    if ( g_sendActivateEvent != -1 )
+    {
+        bool activate = g_sendActivateEvent != 0;
+
+        // if (!activate) wxPrintf( wxT("de") );
+        // wxPrintf( wxT("activate\n") );
+
+        // do it only once
+        g_sendActivateEvent = -1;
+
+        wxTheApp->SetActive(activate, (wxWindow *)g_lastActiveFrame);
+    }
+}
 
 // ----------------------------------------------------------------------------
 // frame title/icon
 
 // ----------------------------------------------------------------------------
 // frame title/icon
@@ -776,52 +1131,103 @@ void wxTopLevelWindowGTK::SetTitle( const wxString &title )
     wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
 
     m_title = title;
     wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
 
     m_title = title;
-    gtk_window_set_title( GTK_WINDOW(m_widget), title.mbc_str() );
+    gtk_window_set_title( GTK_WINDOW(m_widget), wxGTK_CONV( title ) );
 }
 
 void wxTopLevelWindowGTK::SetIcon( const wxIcon &icon )
 }
 
 void wxTopLevelWindowGTK::SetIcon( const wxIcon &icon )
+{
+    SetIcons( wxIconBundle( icon ) );
+}
+
+void wxTopLevelWindowGTK::SetIcons( const wxIconBundle &icons )
 {
     wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
 
 {
     wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
 
-    wxTopLevelWindowBase::SetIcon(icon);
+    wxTopLevelWindowBase::SetIcons( icons );
 
 
-    if ( !m_icon.Ok() )
-        return;
+#ifdef __WXGTK20__
+    GList *list = NULL;
+    size_t max = icons.m_icons.GetCount();
+
+    for (size_t i = 0; i < max; i++)
+    {
+        if (icons.m_icons[i].Ok())
+        {
+            list = g_list_prepend(list, icons.m_icons[i].GetPixbuf());
+        }
+    }
+    gtk_window_set_icon_list(GTK_WINDOW(m_widget), list);
+    g_list_free(list);
 
 
-    if (!m_widget->window)
+#else // !__WXGTK20__
+    GdkWindow* window = m_widget->window;
+    if (!window)
         return;
 
         return;
 
-    wxMask *mask = icon.GetMask();
-    GdkBitmap *bm = (GdkBitmap *) NULL;
-    if (mask) bm = mask->GetBitmap();
+    wxIcon icon = icons.GetIcon(-1);
+    if (icon.Ok())
+    {
+        wxMask *mask = icon.GetMask();
+        GdkBitmap *bm = (GdkBitmap *) NULL;
+        if (mask) bm = mask->GetBitmap();
+
+        gdk_window_set_icon( m_widget->window, (GdkWindow *) NULL, icon.GetPixmap(), bm );
+    }
 
 
-    gdk_window_set_icon( m_widget->window, (GdkWindow *) NULL, icon.GetPixmap(), bm );
+    wxSetIconsX11( (WXDisplay*)GDK_WINDOW_XDISPLAY( window ),
+                   (WXWindow)GDK_WINDOW_XWINDOW( window ), icons );
+#endif // !__WXGTK20__
 }
 
 // ----------------------------------------------------------------------------
 // frame state: maximized/iconized/normal
 // ----------------------------------------------------------------------------
 
 }
 
 // ----------------------------------------------------------------------------
 // frame state: maximized/iconized/normal
 // ----------------------------------------------------------------------------
 
-void wxTopLevelWindowGTK::Maximize(bool WXUNUSED(maximize))
+void wxTopLevelWindowGTK::Maximize(bool maximize)
 {
 {
+#ifdef __WXGTK20__
+    if (maximize)
+        gtk_window_maximize( GTK_WINDOW( m_widget ) );
+    else
+        gtk_window_unmaximize( GTK_WINDOW( m_widget ) );
+#else
     wxFAIL_MSG( _T("not implemented") );
     wxFAIL_MSG( _T("not implemented") );
+#endif
 }
 
 bool wxTopLevelWindowGTK::IsMaximized() const
 {
 }
 
 bool wxTopLevelWindowGTK::IsMaximized() const
 {
+#ifdef __WXGTK20__
+    if(!m_widget->window)
+        return false;
+
+    return gdk_window_get_state(m_widget->window) & GDK_WINDOW_STATE_MAXIMIZED;
+#else
   //    wxFAIL_MSG( _T("not implemented") );
 
     // This is an approximation
   //    wxFAIL_MSG( _T("not implemented") );
 
     // This is an approximation
-    return FALSE;
+    return false;
+#endif
 }
 
 void wxTopLevelWindowGTK::Restore()
 {
 }
 
 void wxTopLevelWindowGTK::Restore()
 {
+#ifdef __WXGTK20__
+    // "Present" seems similar enough to "restore"
+    gtk_window_present( GTK_WINDOW( m_widget ) );
+#else
     wxFAIL_MSG( _T("not implemented") );
     wxFAIL_MSG( _T("not implemented") );
+#endif
 }
 
 void wxTopLevelWindowGTK::Iconize( bool iconize )
 {
 }
 
 void wxTopLevelWindowGTK::Iconize( bool iconize )
 {
+#ifdef __WXGTK20__
+    if (iconize)
+        gtk_window_iconify( GTK_WINDOW( m_widget ) );
+    else
+        gtk_window_deiconify( GTK_WINDOW( m_widget ) );
+#else
    if (iconize)
    {
        GdkWindow *window = m_widget->window;
    if (iconize)
    {
        GdkWindow *window = m_widget->window;
@@ -833,6 +1239,7 @@ void wxTopLevelWindowGTK::Iconize( bool iconize )
                        GDK_WINDOW_XWINDOW( window ),
                        DefaultScreen( GDK_DISPLAY() ) );
    }
                        GDK_WINDOW_XWINDOW( window ),
                        DefaultScreen( GDK_DISPLAY() ) );
    }
+#endif
 }
 
 bool wxTopLevelWindowGTK::IsIconized() const
 }
 
 bool wxTopLevelWindowGTK::IsIconized() const
@@ -849,3 +1256,104 @@ void wxTopLevelWindowGTK::SetIconizeState(bool iconize)
     }
 }
 
     }
 }
 
+void wxTopLevelWindowGTK::AddGrab()
+{
+    if (!m_grabbed)
+    {
+        m_grabbed = true;
+        gtk_grab_add( m_widget );
+        wxEventLoop().Run();
+        gtk_grab_remove( m_widget );
+    }
+}
+
+void wxTopLevelWindowGTK::RemoveGrab()
+{
+    if (m_grabbed)
+    {
+        gtk_main_quit();
+        m_grabbed = false;
+    }
+}
+
+
+// helper
+static bool do_shape_combine_region(GdkWindow* window, const wxRegion& region)
+{
+    if (window)
+    {
+        if (region.IsEmpty())
+        {
+            gdk_window_shape_combine_mask(window, NULL, 0, 0);
+        }
+        else
+        {
+#ifdef __WXGTK20__
+            gdk_window_shape_combine_region(window, region.GetRegion(), 0, 0);
+#else
+            wxBitmap bmp = region.ConvertToBitmap();
+            bmp.SetMask(new wxMask(bmp, *wxBLACK));
+            GdkBitmap* mask = bmp.GetMask()->GetBitmap();
+            gdk_window_shape_combine_mask(window, mask, 0, 0);
+#endif
+            return true;
+        }
+    }
+    return false;
+}
+
+
+bool wxTopLevelWindowGTK::SetShape(const wxRegion& region)
+{
+    wxCHECK_MSG( HasFlag(wxFRAME_SHAPED), false,
+                 _T("Shaped windows must be created with the wxFRAME_SHAPED style."));
+
+    GdkWindow *window = NULL;
+    if (m_wxwindow)
+    {
+        window = GTK_PIZZA(m_wxwindow)->bin_window;
+        do_shape_combine_region(window, region);
+    }
+    window = m_widget->window;
+    return do_shape_combine_region(window, region);
+}
+
+bool wxTopLevelWindowGTK::IsActive()
+{
+    return (this == (wxTopLevelWindowGTK*)g_activeFrame);
+}
+
+void wxTopLevelWindowGTK::RequestUserAttention(int flags)
+{
+    bool new_hint_value = false;
+
+    // FIXME: This is a workaround to focus handling problem
+    // If RequestUserAttention is called for example right after a wxSleep, OnInternalIdle hasn't
+    // yet been processed, and the internal focus system is not up to date yet.
+    // wxYieldIfNeeded ensures the processing of it, but can have unwanted side effects - MR
+    ::wxYieldIfNeeded();
+
+    if(m_urgency_hint >= 0)
+        gtk_timeout_remove(m_urgency_hint);
+
+    m_urgency_hint = -2;
+
+    if( GTK_WIDGET_REALIZED(m_widget) && !IsActive() )
+    {
+        new_hint_value = true;
+
+        if (flags & wxUSER_ATTENTION_INFO)
+        {
+            m_urgency_hint = gtk_timeout_add(5000, (GtkFunction)gtk_frame_urgency_timer_callback, this);
+        } else {
+            m_urgency_hint = -1;
+        }
+    }
+
+#if defined(__WXGTK20__) && GTK_CHECK_VERSION(2,7,0)
+    if(!gtk_check_version(2,7,0))
+        gtk_window_set_urgency_hint(GTK_WINDOW( m_widget ), new_hint_value);
+    else
+#endif
+        wxgtk_window_set_urgency_hint(GTK_WINDOW( m_widget ), new_hint_value);
+}