1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Robert Roebling 
   6 // Copyright:   (c) 1998 Robert Roebling 
   7 // Licence:     wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  10 // ============================================================================ 
  12 // ============================================================================ 
  14 // ---------------------------------------------------------------------------- 
  16 // ---------------------------------------------------------------------------- 
  18 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  19     #pragma implementation "toplevel.h" 
  22 // For compilers that support precompilation, includes "wx.h". 
  23 #include "wx/wxprec.h" 
  26 #define XIconifyWindow XICONIFYWINDOW 
  32 #include "wx/dialog.h" 
  33 #include "wx/control.h" 
  35 #include "wx/dcclient.h" 
  36 #include "wx/gtk/private.h" 
  42 #include <gdk/gdkkeysyms.h> 
  45 #include "wx/gtk/win_gtk.h" 
  47 #include "wx/unix/utilsx11.h" 
  50 #include <X11/Xatom.h> 
  52 // ---------------------------------------------------------------------------- 
  54 // ---------------------------------------------------------------------------- 
  56 extern void wxapp_install_idle_handler(); 
  59 // ---------------------------------------------------------------------------- 
  61 // ---------------------------------------------------------------------------- 
  63 extern wxList         wxPendingDelete
; 
  65 extern int            g_openDialogs
; 
  66 extern wxWindowGTK   
*g_delayedFocus
; 
  68 //----------------------------------------------------------------------------- 
  69 // "focus" from m_window 
  70 //----------------------------------------------------------------------------- 
  72 static gint 
gtk_frame_focus_callback( GtkWidget 
*widget
, GtkDirectionType 
WXUNUSED(d
), wxWindow 
*WXUNUSED(win
) ) 
  75         wxapp_install_idle_handler(); 
  77     // This disables GTK's tab traversal 
  78     gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus" ); 
  82 //----------------------------------------------------------------------------- 
  84 //----------------------------------------------------------------------------- 
  86 static void gtk_frame_size_callback( GtkWidget 
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxTopLevelWindowGTK 
*win 
) 
  89         wxapp_install_idle_handler(); 
  94     if ((win
->m_width 
!= alloc
->width
) || (win
->m_height 
!= alloc
->height
)) 
  97         wxPrintf( "OnSize from " ); 
  98         if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
  99            wxPrintf( win->GetClassInfo()->GetClassName() ); 
 100         wxPrintf( " %d %d %d %d\n", (int)alloc->x, 
 103                                 (int)alloc->height ); 
 106         win
->m_width 
= alloc
->width
; 
 107         win
->m_height 
= alloc
->height
; 
 108         win
->m_queuedFullRedraw 
= TRUE
; 
 109         win
->GtkUpdateSize(); 
 113 //----------------------------------------------------------------------------- 
 115 //----------------------------------------------------------------------------- 
 117 static gint 
gtk_frame_delete_callback( GtkWidget 
*WXUNUSED(widget
), GdkEvent 
*WXUNUSED(event
), wxTopLevelWindowGTK 
*win 
) 
 120         wxapp_install_idle_handler(); 
 122     if (win
->IsEnabled() && 
 123         (g_openDialogs 
== 0 || (win
->GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
) || 
 131 //----------------------------------------------------------------------------- 
 133 //----------------------------------------------------------------------------- 
 136 gtk_frame_configure_callback( GtkWidget 
*WXUNUSED(widget
), GdkEventConfigure 
*WXUNUSED(event
), wxTopLevelWindowGTK 
*win 
) 
 139         wxapp_install_idle_handler(); 
 141     if (!win
->m_hasVMT 
|| !win
->IsShown()) 
 146     gdk_window_get_root_origin( win
->m_widget
->window
, &x
, &y 
); 
 150     wxMoveEvent 
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() ); 
 151     mevent
.SetEventObject( win 
); 
 152     win
->GetEventHandler()->ProcessEvent( mevent 
); 
 157 //----------------------------------------------------------------------------- 
 158 // "realize" from m_widget 
 159 //----------------------------------------------------------------------------- 
 161 // we cannot MWM hints and icons before the widget has been realized, 
 162 // so we do this directly after realization 
 165 gtk_frame_realized_callback( GtkWidget 
* WXUNUSED(widget
), 
 166                              wxTopLevelWindowGTK 
*win 
) 
 169         wxapp_install_idle_handler(); 
 171     // All this is for Motif Window Manager "hints" and is supposed to be 
 172     // recognized by other WM as well. Not tested. 
 173     gdk_window_set_decorations(win
->m_widget
->window
, 
 174                                (GdkWMDecoration
)win
->m_gdkDecor
); 
 175     gdk_window_set_functions(win
->m_widget
->window
, 
 176                                (GdkWMFunction
)win
->m_gdkFunc
); 
 178     // GTK's shrinking/growing policy 
 179     if ((win
->m_gdkFunc 
& GDK_FUNC_RESIZE
) == 0) 
 180         gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1); 
 182         gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1); 
 185     wxIconBundle iconsOld 
= win
->GetIcons(); 
 186     if ( iconsOld
.GetIcon(-1).Ok() ) 
 188         win
->SetIcon( wxNullIcon 
); 
 189         win
->SetIcons( iconsOld 
); 
 193 //----------------------------------------------------------------------------- 
 194 // "map_event" from m_widget 
 195 //----------------------------------------------------------------------------- 
 198 gtk_frame_map_callback( GtkWidget 
* WXUNUSED(widget
), 
 199                         GdkEvent 
* WXUNUSED(event
), 
 200                         wxTopLevelWindow 
*win 
) 
 202     win
->SetIconizeState(FALSE
); 
 205 //----------------------------------------------------------------------------- 
 206 // "unmap_event" from m_widget 
 207 //----------------------------------------------------------------------------- 
 210 gtk_frame_unmap_callback( GtkWidget 
* WXUNUSED(widget
), 
 211                           GdkEvent 
* WXUNUSED(event
), 
 212                           wxTopLevelWindow 
*win 
) 
 214     win
->SetIconizeState(TRUE
); 
 217 //----------------------------------------------------------------------------- 
 218 // "expose_event" of m_client 
 219 //----------------------------------------------------------------------------- 
 221 static int gtk_window_expose_callback( GtkWidget 
*widget
, GdkEventExpose 
*gdk_event
, wxWindow 
*win 
) 
 223     GtkPizza 
*pizza 
= GTK_PIZZA(widget
); 
 225     gtk_paint_flat_box (win
->m_widget
->style
, 
 226                         pizza
->bin_window
, GTK_STATE_NORMAL
, 
 236 //----------------------------------------------------------------------------- 
 237 // "draw" of m_client 
 238 //----------------------------------------------------------------------------- 
 242 static void gtk_window_draw_callback( GtkWidget 
*widget
, GdkRectangle 
*rect
, wxWindow 
*win 
) 
 244     GtkPizza 
*pizza 
= GTK_PIZZA(widget
); 
 246     gtk_paint_flat_box (win
->m_widget
->style
, 
 247                         pizza
->bin_window
, GTK_STATE_NORMAL
, 
 257 // ---------------------------------------------------------------------------- 
 258 // wxTopLevelWindowGTK itself 
 259 // ---------------------------------------------------------------------------- 
 261 //----------------------------------------------------------------------------- 
 262 // InsertChild for wxTopLevelWindowGTK 
 263 //----------------------------------------------------------------------------- 
 265 /* Callback for wxTopLevelWindowGTK. This very strange beast has to be used because 
 266  * C++ has no virtual methods in a constructor. We have to emulate a 
 267  * virtual function here as wxWindows requires different ways to insert 
 268  * a child in container classes. */ 
 270 static void wxInsertChildInTopLevelWindow( wxTopLevelWindowGTK
* parent
, wxWindow
* child 
) 
 272     wxASSERT( GTK_IS_WIDGET(child
->m_widget
) ); 
 274     if (!parent
->m_insertInClientArea
) 
 276         // these are outside the client area 
 277         wxTopLevelWindowGTK
* frame 
= (wxTopLevelWindowGTK
*) parent
; 
 278         gtk_pizza_put( GTK_PIZZA(frame
->m_mainWidget
), 
 279                          GTK_WIDGET(child
->m_widget
), 
 287         // these are inside the client area 
 288         gtk_pizza_put( GTK_PIZZA(parent
->m_wxwindow
), 
 289                          GTK_WIDGET(child
->m_widget
), 
 296     // resize on OnInternalIdle 
 297     parent
->GtkUpdateSize(); 
 300 // ---------------------------------------------------------------------------- 
 301 // wxTopLevelWindowGTK creation 
 302 // ---------------------------------------------------------------------------- 
 304 void wxTopLevelWindowGTK::Init() 
 309     m_mainWidget 
= (GtkWidget
*) NULL
; 
 310     m_insertInClientArea 
= TRUE
; 
 311     m_isIconized 
= FALSE
; 
 312     m_fsIsShowing 
= FALSE
; 
 313     m_themeEnabled 
= TRUE
; 
 314     m_gdkDecor 
= m_gdkFunc 
= 0; 
 318 bool wxTopLevelWindowGTK::Create( wxWindow 
*parent
, 
 320                                   const wxString
& title
, 
 322                                   const wxSize
& sizeOrig
, 
 324                                   const wxString 
&name 
) 
 326     // always create a frame of some reasonable, even if arbitrary, size (at 
 327     // least for MSW compatibility) 
 328     wxSize size 
= sizeOrig
; 
 329     if ( size
.x 
== -1 || size
.y 
== -1 ) 
 331         wxSize sizeDpy 
= wxGetDisplaySize(); 
 333             size
.x 
= sizeDpy
.x 
/ 3; 
 335             size
.y 
= sizeDpy
.y 
/ 5; 
 338     wxTopLevelWindows
.Append( this ); 
 340     m_needParent 
= FALSE
; 
 342     if (!PreCreation( parent
, pos
, size 
) || 
 343         !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name 
)) 
 345         wxFAIL_MSG( wxT("wxTopLevelWindowGTK creation failed") ); 
 351     m_insertCallback 
= (wxInsertChildFunction
) wxInsertChildInTopLevelWindow
; 
 353     GtkWindowType win_type 
= GTK_WINDOW_TOPLEVEL
; 
 355     if (style 
& wxFRAME_TOOL_WINDOW
) 
 356         win_type 
= GTK_WINDOW_POPUP
; 
 358     if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
) 
 360         // there is no more GTK_WINDOW_DIALOG in 2.0 
 362         win_type 
= GTK_WINDOW_TOPLEVEL
; 
 364         win_type 
= GTK_WINDOW_DIALOG
; 
 368     m_widget 
= gtk_window_new( win_type 
); 
 370     if (m_parent 
&& (((GTK_IS_WINDOW(m_parent
->m_widget
)) && 
 371                       (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
)) || 
 372                      (style 
& wxFRAME_FLOAT_ON_PARENT
))) 
 374         gtk_window_set_transient_for( GTK_WINDOW(m_widget
), GTK_WINDOW(m_parent
->m_widget
) ); 
 378         gtk_window_set_wmclass( GTK_WINDOW(m_widget
), wxGTK_CONV( name 
), wxGTK_CONV( name 
) ); 
 380     gtk_window_set_title( GTK_WINDOW(m_widget
), wxGTK_CONV( title 
) ); 
 381     GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS 
); 
 383     gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event", 
 384         GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this ); 
 386     // m_mainWidget holds the toolbar, the menubar and the client area 
 387     m_mainWidget 
= gtk_pizza_new(); 
 388     gtk_widget_show( m_mainWidget 
); 
 389     GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS 
); 
 390     gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget 
); 
 392     if (m_miniEdge 
== 0) // wxMiniFrame has its own version. 
 394        // For m_mainWidget themes 
 395        gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "expose_event", 
 396                 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this ); 
 398        gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "draw", 
 399                 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this ); 
 403     // m_wxwindow only represents the client area without toolbar and menubar 
 404     m_wxwindow 
= gtk_pizza_new(); 
 405     gtk_widget_show( m_wxwindow 
); 
 406     gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow 
); 
 408     // we donm't allow the frame to get the focus as otherwise 
 409     // the frame will grab it at arbitrary focus changes 
 410     GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS 
); 
 412     if (m_parent
) m_parent
->AddChild( this ); 
 414     // the user resized the frame by dragging etc. 
 415     gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate", 
 416         GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this ); 
 420     if ((m_x 
!= -1) || (m_y 
!= -1)) 
 421         gtk_widget_set_uposition( m_widget
, m_x
, m_y 
); 
 423     gtk_window_set_default_size( GTK_WINDOW(m_widget
), m_width
, m_height 
); 
 425     //  we cannot set MWM hints and icons before the widget has 
 426     //  been realized, so we do this directly after realization 
 427     gtk_signal_connect( GTK_OBJECT(m_widget
), "realize", 
 428                         GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this ); 
 430     // the only way to get the window size is to connect to this event 
 431     gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event", 
 432         GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this ); 
 434     // map and unmap for iconized state 
 435     gtk_signal_connect( GTK_OBJECT(m_widget
), "map_event", 
 436         GTK_SIGNAL_FUNC(gtk_frame_map_callback
), (gpointer
)this ); 
 437     gtk_signal_connect( GTK_OBJECT(m_widget
), "unmap_event", 
 438         GTK_SIGNAL_FUNC(gtk_frame_unmap_callback
), (gpointer
)this ); 
 440     // the only way to get the window size is to connect to this event 
 441     gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event", 
 442         GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this ); 
 444     // disable native tab traversal 
 445     gtk_signal_connect( GTK_OBJECT(m_widget
), "focus", 
 446         GTK_SIGNAL_FUNC(gtk_frame_focus_callback
), (gpointer
)this ); 
 449     if ((m_miniEdge 
> 0) || (style 
& wxSIMPLE_BORDER
) || (style 
& wxNO_BORDER
)) 
 456         m_gdkDecor 
= (long) GDK_DECOR_BORDER
; 
 457         m_gdkFunc 
= (long) GDK_FUNC_MOVE
; 
 459         // All this is for Motif Window Manager "hints" and is supposed to be 
 460         // recognized by other WMs as well. 
 461         if ((style 
& wxCAPTION
) != 0) 
 463             m_gdkDecor 
|= GDK_DECOR_TITLE
; 
 465         if ((style 
& wxCLOSE_BOX
) != 0) 
 467             m_gdkFunc 
|= GDK_FUNC_CLOSE
; 
 469         if ((style 
& wxSYSTEM_MENU
) != 0) 
 471             m_gdkDecor 
|= GDK_DECOR_MENU
; 
 473         if ((style 
& wxMINIMIZE_BOX
) != 0) 
 475             m_gdkFunc 
|= GDK_FUNC_MINIMIZE
; 
 476             m_gdkDecor 
|= GDK_DECOR_MINIMIZE
; 
 478         if ((style 
& wxMAXIMIZE_BOX
) != 0) 
 480             m_gdkFunc 
|= GDK_FUNC_MAXIMIZE
; 
 481             m_gdkDecor 
|= GDK_DECOR_MAXIMIZE
; 
 483         if ((style 
& wxRESIZE_BORDER
) != 0) 
 485            m_gdkFunc 
|= GDK_FUNC_RESIZE
; 
 486            m_gdkDecor 
|= GDK_DECOR_RESIZEH
; 
 493 wxTopLevelWindowGTK::~wxTopLevelWindowGTK() 
 497         wxASSERT_MSG( FALSE
, _T("Window still grabbed")); 
 501     m_isBeingDeleted 
= TRUE
; 
 503     // it may also be GtkScrolledWindow in the case of an MDI child 
 504     if (GTK_IS_WINDOW(m_widget
)) 
 506         gtk_window_set_focus( GTK_WINDOW(m_widget
), NULL 
); 
 512 bool wxTopLevelWindowGTK::ShowFullScreen(bool show
, long style 
) 
 514     if (show 
== m_fsIsShowing
) return FALSE
; // return what? 
 516     m_fsIsShowing 
= show
; 
 518     GdkWindow 
*window 
= m_widget
->window
; 
 519     wxX11FullScreenMethod method 
= 
 520         wxGetFullScreenMethodX11((WXDisplay
*)GDK_DISPLAY(), 
 521                                  (WXWindow
)GDK_ROOT_WINDOW()); 
 525         m_fsSaveFlag 
= style
; 
 526         GetPosition( &m_fsSaveFrame
.x
, &m_fsSaveFrame
.y 
); 
 527         GetSize( &m_fsSaveFrame
.width
, &m_fsSaveFrame
.height 
); 
 529         int screen_width
,screen_height
; 
 530         wxDisplaySize( &screen_width
, &screen_height 
); 
 532                 gint client_x
, client_y
, root_x
, root_y
; 
 535         if (method 
!= wxX11_FS_WMSPEC
) 
 537             // don't do it always, Metacity hates it 
 538             m_fsSaveGdkFunc 
= m_gdkFunc
; 
 539             m_fsSaveGdkDecor 
= m_gdkDecor
; 
 540             m_gdkFunc 
= m_gdkDecor 
= 0; 
 541             gdk_window_set_decorations(window
, (GdkWMDecoration
)0); 
 542             gdk_window_set_functions(window
, (GdkWMFunction
)0); 
 545                 gdk_window_get_origin (m_widget
->window
, &root_x
, &root_y
); 
 546                 gdk_window_get_geometry (m_widget
->window
, &client_x
, &client_y
, 
 547                                          &width
, &height
, NULL
); 
 549                 gdk_window_move_resize (m_widget
->window
, -client_x
, -client_y
, 
 550                                         screen_width 
+ 1, screen_height 
+ 1); 
 552         wxSetFullScreenStateX11((WXDisplay
*)GDK_DISPLAY(), 
 553                                 (WXWindow
)GDK_ROOT_WINDOW(), 
 554                                 (WXWindow
)GDK_WINDOW_XWINDOW(window
), 
 555                                 show
, &m_fsSaveFrame
, method
); 
 559         if (method 
!= wxX11_FS_WMSPEC
) 
 561             // don't do it always, Metacity hates it 
 562             m_gdkFunc 
= m_fsSaveGdkFunc
; 
 563             m_gdkDecor 
= m_fsSaveGdkDecor
; 
 564             gdk_window_set_decorations(window
, (GdkWMDecoration
)m_gdkDecor
); 
 565             gdk_window_set_functions(window
, (GdkWMFunction
)m_gdkFunc
); 
 568         wxSetFullScreenStateX11((WXDisplay
*)GDK_DISPLAY(), 
 569                                 (WXWindow
)GDK_ROOT_WINDOW(), 
 570                                 (WXWindow
)GDK_WINDOW_XWINDOW(window
), 
 571                                 show
, &m_fsSaveFrame
, method
); 
 573         SetSize(m_fsSaveFrame
.x
, m_fsSaveFrame
.y
, 
 574                 m_fsSaveFrame
.width
, m_fsSaveFrame
.height
); 
 581 // ---------------------------------------------------------------------------- 
 582 // overridden wxWindow methods 
 583 // ---------------------------------------------------------------------------- 
 585 bool wxTopLevelWindowGTK::Show( bool show 
) 
 587     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 589     if (show 
&& !m_sizeSet
) 
 591         /* by calling GtkOnSize here, we don't have to call 
 592            either after showing the frame, which would entail 
 593            much ugly flicker or from within the size_allocate 
 594            handler, because GTK 1.1.X forbids that. */ 
 596         GtkOnSize( m_x
, m_y
, m_width
, m_height 
); 
 599     return wxWindow::Show( show 
); 
 602 void wxTopLevelWindowGTK::DoMoveWindow(int WXUNUSED(x
), int WXUNUSED(y
), int WXUNUSED(width
), int WXUNUSED(height
) ) 
 604     wxFAIL_MSG( wxT("DoMoveWindow called for wxTopLevelWindowGTK") ); 
 607 void wxTopLevelWindowGTK::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags 
) 
 609     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 611     // this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow 
 612     wxASSERT_MSG( (m_wxwindow 
!= NULL
), wxT("invalid frame") ); 
 622     int old_width 
= m_width
; 
 623     int old_height 
= m_height
; 
 625     if ((sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
) == 0) 
 627         if (x 
!= -1) m_x 
= x
; 
 628         if (y 
!= -1) m_y 
= y
; 
 635     if (width 
!= -1) m_width 
= width
; 
 636     if (height 
!= -1) m_height 
= height
; 
 639     if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH) 
 641         if (width == -1) m_width = 80; 
 644     if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT) 
 646        if (height == -1) m_height = 26; 
 650     int minWidth 
= GetMinWidth(), 
 651         minHeight 
= GetMinHeight(), 
 652         maxWidth 
= GetMaxWidth(), 
 653         maxHeight 
= GetMaxHeight(); 
 655     if ((minWidth 
!= -1) && (m_width 
< minWidth
)) m_width 
= minWidth
; 
 656     if ((minHeight 
!= -1) && (m_height 
< minHeight
)) m_height 
= minHeight
; 
 657     if ((maxWidth 
!= -1) && (m_width 
> maxWidth
)) m_width 
= maxWidth
; 
 658     if ((maxHeight 
!= -1) && (m_height 
> maxHeight
)) m_height 
= maxHeight
; 
 660     if ((m_x 
!= -1) || (m_y 
!= -1)) 
 662         if ((m_x 
!= old_x
) || (m_y 
!= old_y
)) 
 664             gtk_widget_set_uposition( m_widget
, m_x
, m_y 
); 
 668     if ((m_width 
!= old_width
) || (m_height 
!= old_height
)) 
 670         if (m_widget
->window
) 
 671             gdk_window_resize( m_widget
->window
, m_width
, m_height 
); 
 673             gtk_window_set_default_size( GTK_WINDOW(m_widget
), m_width
, m_height 
); 
 675         /* we set the size in GtkOnSize, i.e. mostly the actual resizing is 
 676            done either directly before the frame is shown or in idle time 
 677            so that different calls to SetSize() don't lead to flicker. */ 
 684 void wxTopLevelWindowGTK::DoGetClientSize( int *width
, int *height 
) const 
 686     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 688     wxWindow::DoGetClientSize( width
, height 
); 
 692         *height 
-= m_miniEdge
*2 + m_miniTitle
; 
 696         *width 
-= m_miniEdge
*2; 
 700 void wxTopLevelWindowGTK::DoSetClientSize( int width
, int height 
) 
 702     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 705               width 
+ m_miniEdge
*2, height  
+ m_miniEdge
*2 + m_miniTitle
, 0); 
 708 void wxTopLevelWindowGTK::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), 
 709                                      int width
, int height 
) 
 711     // due to a bug in gtk, x,y are always 0 
 716     if (m_resizing
) return; 
 719     if ( m_wxwindow 
== NULL 
) return; 
 724     /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses 
 725        wxWindow::Create to create it's GTK equivalent. m_mainWidget is only 
 726        set in wxFrame::Create so it is used to check what kind of frame we 
 727        have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we 
 728        skip the part which handles m_frameMenuBar, m_frameToolBar and (most 
 729        importantly) m_mainWidget */ 
 731     int minWidth 
= GetMinWidth(), 
 732         minHeight 
= GetMinHeight(), 
 733         maxWidth 
= GetMaxWidth(), 
 734         maxHeight 
= GetMaxHeight(); 
 736     if ((minWidth 
!= -1) && (m_width 
< minWidth
)) m_width 
= minWidth
; 
 737     if ((minHeight 
!= -1) && (m_height 
< minHeight
)) m_height 
= minHeight
; 
 738     if ((maxWidth 
!= -1) && (m_width 
> maxWidth
)) m_width 
= maxWidth
; 
 739     if ((maxHeight 
!= -1) && (m_height 
> maxHeight
)) m_height 
= maxHeight
; 
 744         gint            flag 
= 0; // GDK_HINT_POS; 
 747         if ((minWidth 
!= -1) || (minHeight 
!= -1)) flag 
|= GDK_HINT_MIN_SIZE
; 
 748         if ((maxWidth 
!= -1) || (maxHeight 
!= -1)) flag 
|= GDK_HINT_MAX_SIZE
; 
 750         geom
.min_width 
= minWidth
; 
 751         geom
.min_height 
= minHeight
; 
 753             // Because of the way we set GDK_HINT_MAX_SIZE above, if either of 
 754             // maxHeight or maxWidth is set, we must set them both, else the 
 755             // remaining -1 will be taken literally. 
 757             // I'm certain this also happens elsewhere, and is the probable 
 758             // cause of other such things as: 
 759             // Gtk-WARNING **: gtk_widget_size_allocate(): 
 760             //       attempt to allocate widget with width 65535 and height 600 
 761             // but I don't have time to track them all now.. 
 763             // Really we need to encapulate all this height/width business and 
 764             // stop any old method from ripping at the members directly and 
 765             // scattering -1's without regard for who might resolve them later. 
 767         geom
.max_width 
= ( maxHeight 
== -1 ) ? maxWidth
 
 768                          : ( maxWidth 
== -1 ) ? wxGetDisplaySize().GetWidth() 
 771         geom
.max_height 
= ( maxWidth 
== -1 ) ? maxHeight    
// ( == -1 here ) 
 772                           : ( maxHeight 
== -1 ) ? wxGetDisplaySize().GetHeight() 
 775         gtk_window_set_geometry_hints( GTK_WINDOW(m_widget
), 
 778                                        (GdkWindowHints
) flag 
); 
 780         /* I revert back to wxGTK's original behaviour. m_mainWidget holds the 
 781          * menubar, the toolbar and the client area, which is represented by 
 783          * this hurts in the eye, but I don't want to call SetSize() 
 784          * because I don't want to call any non-native functions here. */ 
 786         int client_x 
= m_miniEdge
; 
 787         int client_y 
= m_miniEdge 
+ m_miniTitle
; 
 788         int client_w 
= m_width 
- 2*m_miniEdge
; 
 789         int client_h 
= m_height 
- 2*m_miniEdge 
- m_miniTitle
; 
 791         gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
), 
 793                               client_x
, client_y
, client_w
, client_h 
); 
 797         // If there is no m_mainWidget between m_widget and m_wxwindow there 
 798         // is no need to set the size or position of m_wxwindow. 
 803     // send size event to frame 
 804     wxSizeEvent 
event( wxSize(m_width
,m_height
), GetId() ); 
 805     event
.SetEventObject( this ); 
 806     GetEventHandler()->ProcessEvent( event 
); 
 811 void wxTopLevelWindowGTK::OnInternalIdle() 
 813     if (!m_sizeSet 
&& GTK_WIDGET_REALIZED(m_wxwindow
)) 
 815         GtkOnSize( m_x
, m_y
, m_width
, m_height 
); 
 817         // we'll come back later 
 819             wxapp_install_idle_handler(); 
 823     // set the focus if not done yet and if we can already do it 
 824     if ( GTK_WIDGET_REALIZED(m_wxwindow
) ) 
 826         if ( g_delayedFocus 
&& 
 827              wxGetTopLevelParent((wxWindow
*)g_delayedFocus
) == this ) 
 829             wxLogTrace(_T("focus"), 
 830                        _T("Setting focus from wxTLW::OnIdle() to %s(%s)"), 
 831                        g_delayedFocus
->GetClassInfo()->GetClassName(), 
 832                        g_delayedFocus
->GetLabel().c_str()); 
 834             g_delayedFocus
->SetFocus(); 
 835             g_delayedFocus 
= NULL
; 
 839     wxWindow::OnInternalIdle(); 
 842 // ---------------------------------------------------------------------------- 
 844 // ---------------------------------------------------------------------------- 
 846 void wxTopLevelWindowGTK::SetTitle( const wxString 
&title 
) 
 848     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 851     gtk_window_set_title( GTK_WINDOW(m_widget
), wxGTK_CONV( title 
) ); 
 854 void wxTopLevelWindowGTK::DoSetIcon( const wxIcon 
&icon 
) 
 859     if (!m_widget
->window
) 
 862     wxMask 
*mask 
= icon
.GetMask(); 
 863     GdkBitmap 
*bm 
= (GdkBitmap 
*) NULL
; 
 864     if (mask
) bm 
= mask
->GetBitmap(); 
 866     gdk_window_set_icon( m_widget
->window
, (GdkWindow 
*) NULL
, icon
.GetPixmap(), bm 
); 
 869 void wxTopLevelWindowGTK::SetIcon( const wxIcon 
&icon 
) 
 871     SetIcons( wxIconBundle( icon 
) ); 
 874 void wxTopLevelWindowGTK::SetIcons( const wxIconBundle 
&icons 
) 
 876     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 877     GdkWindow
* window 
= m_widget
->window
; 
 879     wxTopLevelWindowBase::SetIcons( icons 
); 
 881     DoSetIcon( icons
.GetIcon( -1 ) ); 
 884         wxSetIconsX11( (WXDisplay
*)GDK_WINDOW_XDISPLAY( window 
), 
 885                        (WXWindow
)GDK_WINDOW_XWINDOW( window 
), icons 
); 
 889 // ---------------------------------------------------------------------------- 
 890 // frame state: maximized/iconized/normal 
 891 // ---------------------------------------------------------------------------- 
 893 void wxTopLevelWindowGTK::Maximize(bool maximize
) 
 897         gtk_window_maximize( GTK_WINDOW( m_widget 
) ); 
 899         gtk_window_unmaximize( GTK_WINDOW( m_widget 
) ); 
 901     wxFAIL_MSG( _T("not implemented") ); 
 905 bool wxTopLevelWindowGTK::IsMaximized() const 
 907   //    wxFAIL_MSG( _T("not implemented") ); 
 909     // This is an approximation 
 913 void wxTopLevelWindowGTK::Restore() 
 916     // "Present" seems similar enough to "restore" 
 917     gtk_window_present( GTK_WINDOW( m_widget 
) ); 
 919     wxFAIL_MSG( _T("not implemented") ); 
 923 void wxTopLevelWindowGTK::Iconize( bool iconize 
) 
 927         gtk_window_iconify( GTK_WINDOW( m_widget 
) ); 
 929         gtk_window_deiconify( GTK_WINDOW( m_widget 
) ); 
 933        GdkWindow 
*window 
= m_widget
->window
; 
 935        // you should do it later, for example from OnCreate() handler 
 936        wxCHECK_RET( window
, _T("frame not created yet - can't iconize") ); 
 938        XIconifyWindow( GDK_WINDOW_XDISPLAY( window 
), 
 939                        GDK_WINDOW_XWINDOW( window 
), 
 940                        DefaultScreen( GDK_DISPLAY() ) ); 
 945 bool wxTopLevelWindowGTK::IsIconized() const 
 950 void wxTopLevelWindowGTK::SetIconizeState(bool iconize
) 
 952     if ( iconize 
!= m_isIconized 
) 
 954         m_isIconized 
= iconize
; 
 955         (void)SendIconizeEvent(iconize
); 
 959 void wxTopLevelWindowGTK::AddGrab() 
 964         gtk_grab_add( m_widget 
); 
 966         gtk_grab_remove( m_widget 
); 
 970 void wxTopLevelWindowGTK::RemoveGrab() 
 981 static bool do_shape_combine_region(GdkWindow
* window
, const wxRegion
& region
) 
 985         if (region
.IsEmpty()) 
 987             gdk_window_shape_combine_mask(window
, NULL
, 0, 0); 
 992         gdk_window_shape_combine_region(window
, region
.GetRegion(), 0, 0); 
 994         wxBitmap bmp 
= region
.ConvertToBitmap(); 
 995         bmp
.SetMask(new wxMask(bmp
, *wxBLACK
)); 
 996         GdkBitmap
* mask 
= bmp
.GetMask()->GetBitmap(); 
 997         gdk_window_shape_combine_mask(window
, mask
, 0, 0); 
1006 bool wxTopLevelWindowGTK::SetShape(const wxRegion
& region
) 
1008     wxCHECK_MSG( HasFlag(wxFRAME_SHAPED
), FALSE
, 
1009                  _T("Shaped windows must be created with the wxFRAME_SHAPED style.")); 
1011     GdkWindow 
*window 
= NULL
; 
1014         window 
= GTK_PIZZA(m_wxwindow
)->bin_window
; 
1015         do_shape_combine_region(window
, region
); 
1017     window 
= m_widget
->window
; 
1018     return do_shape_combine_region(window
, region
);