1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Robert Roebling 
   6 // Copyright:   (c) 1998 Robert Roebling 
   7 // Licence:     wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  10 // ============================================================================ 
  12 // ============================================================================ 
  14 // ---------------------------------------------------------------------------- 
  16 // ---------------------------------------------------------------------------- 
  19     #pragma implementation "toplevel.h" 
  23 #define XIconifyWindow XICONIFYWINDOW 
  29 #include "wx/dialog.h" 
  30 #include "wx/control.h" 
  32 #include "wx/dcclient.h" 
  33 #include "wx/gtk/private.h" 
  39 #include <gdk/gdkkeysyms.h> 
  42 #include "wx/gtk/win_gtk.h" 
  44 #include "wx/unix/utilsx11.h" 
  47 #include <X11/Xatom.h> 
  49 // ---------------------------------------------------------------------------- 
  51 // ---------------------------------------------------------------------------- 
  53 extern void wxapp_install_idle_handler(); 
  56 // ---------------------------------------------------------------------------- 
  58 // ---------------------------------------------------------------------------- 
  60 extern wxList         wxPendingDelete
; 
  62 extern int            g_openDialogs
; 
  63 extern wxWindowGTK   
*g_delayedFocus
; 
  65 //----------------------------------------------------------------------------- 
  66 // "focus" from m_window 
  67 //----------------------------------------------------------------------------- 
  69 static gint 
gtk_frame_focus_callback( GtkWidget 
*widget
, GtkDirectionType 
WXUNUSED(d
), wxWindow 
*WXUNUSED(win
) ) 
  72         wxapp_install_idle_handler(); 
  74     // This disables GTK's tab traversal 
  75     gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus" ); 
  79 //----------------------------------------------------------------------------- 
  81 //----------------------------------------------------------------------------- 
  83 static void gtk_frame_size_callback( GtkWidget 
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxTopLevelWindowGTK 
*win 
) 
  86         wxapp_install_idle_handler(); 
  91     if ((win
->m_width 
!= alloc
->width
) || (win
->m_height 
!= alloc
->height
)) 
  94         wxPrintf( "OnSize from " ); 
  95         if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
  96            wxPrintf( win->GetClassInfo()->GetClassName() ); 
  97         wxPrintf( " %d %d %d %d\n", (int)alloc->x, 
 100                                 (int)alloc->height ); 
 103         win
->m_width 
= alloc
->width
; 
 104         win
->m_height 
= alloc
->height
; 
 105         win
->m_queuedFullRedraw 
= TRUE
; 
 106         win
->GtkUpdateSize(); 
 110 //----------------------------------------------------------------------------- 
 112 //----------------------------------------------------------------------------- 
 114 static gint 
gtk_frame_delete_callback( GtkWidget 
*WXUNUSED(widget
), GdkEvent 
*WXUNUSED(event
), wxTopLevelWindowGTK 
*win 
) 
 117         wxapp_install_idle_handler(); 
 119     if (win
->IsEnabled() && 
 120         (g_openDialogs 
== 0 || (win
->GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
) || 
 128 //----------------------------------------------------------------------------- 
 130 //----------------------------------------------------------------------------- 
 133 gtk_frame_configure_callback( GtkWidget 
*WXUNUSED(widget
), GdkEventConfigure 
*WXUNUSED(event
), wxTopLevelWindowGTK 
*win 
) 
 136         wxapp_install_idle_handler(); 
 138     if (!win
->m_hasVMT 
|| !win
->IsShown()) 
 143     gdk_window_get_root_origin( win
->m_widget
->window
, &x
, &y 
); 
 147     wxMoveEvent 
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() ); 
 148     mevent
.SetEventObject( win 
); 
 149     win
->GetEventHandler()->ProcessEvent( mevent 
); 
 154 //----------------------------------------------------------------------------- 
 155 // "realize" from m_widget 
 156 //----------------------------------------------------------------------------- 
 158 // we cannot MWM hints and icons before the widget has been realized, 
 159 // so we do this directly after realization 
 162 gtk_frame_realized_callback( GtkWidget 
* WXUNUSED(widget
), 
 163                              wxTopLevelWindowGTK 
*win 
) 
 166         wxapp_install_idle_handler(); 
 168     // All this is for Motif Window Manager "hints" and is supposed to be 
 169     // recognized by other WM as well. Not tested. 
 170     gdk_window_set_decorations(win
->m_widget
->window
, 
 171                                (GdkWMDecoration
)win
->m_gdkDecor
); 
 172     gdk_window_set_functions(win
->m_widget
->window
, 
 173                                (GdkWMFunction
)win
->m_gdkFunc
); 
 175     // GTK's shrinking/growing policy 
 176     if ((win
->m_gdkFunc 
& GDK_FUNC_RESIZE
) == 0) 
 177         gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1); 
 179         gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1); 
 182     wxIconBundle iconsOld 
= win
->GetIcons(); 
 183     if ( iconsOld
.GetIcon(-1).Ok() ) 
 185         win
->SetIcon( wxNullIcon 
); 
 186         win
->SetIcons( iconsOld 
); 
 190 //----------------------------------------------------------------------------- 
 191 // "map_event" from m_widget 
 192 //----------------------------------------------------------------------------- 
 195 gtk_frame_map_callback( GtkWidget 
* WXUNUSED(widget
), 
 196                         GdkEvent 
* WXUNUSED(event
), 
 197                         wxTopLevelWindow 
*win 
) 
 199     win
->SetIconizeState(FALSE
); 
 202 //----------------------------------------------------------------------------- 
 203 // "unmap_event" from m_widget 
 204 //----------------------------------------------------------------------------- 
 207 gtk_frame_unmap_callback( GtkWidget 
* WXUNUSED(widget
), 
 208                           GdkEvent 
* WXUNUSED(event
), 
 209                           wxTopLevelWindow 
*win 
) 
 211     win
->SetIconizeState(TRUE
); 
 214 //----------------------------------------------------------------------------- 
 215 // "expose_event" of m_client 
 216 //----------------------------------------------------------------------------- 
 218 static int gtk_window_expose_callback( GtkWidget 
*widget
, GdkEventExpose 
*gdk_event
, wxWindow 
*win 
) 
 220     GtkPizza 
*pizza 
= GTK_PIZZA(widget
); 
 222     gtk_paint_flat_box (win
->m_widget
->style
, 
 223                         pizza
->bin_window
, GTK_STATE_NORMAL
, 
 233 //----------------------------------------------------------------------------- 
 234 // "draw" of m_client 
 235 //----------------------------------------------------------------------------- 
 239 static void gtk_window_draw_callback( GtkWidget 
*widget
, GdkRectangle 
*rect
, wxWindow 
*win 
) 
 241     GtkPizza 
*pizza 
= GTK_PIZZA(widget
); 
 243     gtk_paint_flat_box (win
->m_widget
->style
, 
 244                         pizza
->bin_window
, GTK_STATE_NORMAL
, 
 254 // ---------------------------------------------------------------------------- 
 255 // wxTopLevelWindowGTK itself 
 256 // ---------------------------------------------------------------------------- 
 258 //----------------------------------------------------------------------------- 
 259 // InsertChild for wxTopLevelWindowGTK 
 260 //----------------------------------------------------------------------------- 
 262 /* Callback for wxTopLevelWindowGTK. This very strange beast has to be used because 
 263  * C++ has no virtual methods in a constructor. We have to emulate a 
 264  * virtual function here as wxWindows requires different ways to insert 
 265  * a child in container classes. */ 
 267 static void wxInsertChildInTopLevelWindow( wxTopLevelWindowGTK
* parent
, wxWindow
* child 
) 
 269     wxASSERT( GTK_IS_WIDGET(child
->m_widget
) ); 
 271     if (!parent
->m_insertInClientArea
) 
 273         // these are outside the client area 
 274         wxTopLevelWindowGTK
* frame 
= (wxTopLevelWindowGTK
*) parent
; 
 275         gtk_pizza_put( GTK_PIZZA(frame
->m_mainWidget
), 
 276                          GTK_WIDGET(child
->m_widget
), 
 284         // these are inside the client area 
 285         gtk_pizza_put( GTK_PIZZA(parent
->m_wxwindow
), 
 286                          GTK_WIDGET(child
->m_widget
), 
 293     // resize on OnInternalIdle 
 294     parent
->GtkUpdateSize(); 
 297 // ---------------------------------------------------------------------------- 
 298 // wxTopLevelWindowGTK creation 
 299 // ---------------------------------------------------------------------------- 
 301 void wxTopLevelWindowGTK::Init() 
 306     m_mainWidget 
= (GtkWidget
*) NULL
; 
 307     m_insertInClientArea 
= TRUE
; 
 308     m_isIconized 
= FALSE
; 
 309     m_fsIsShowing 
= FALSE
; 
 310     m_themeEnabled 
= TRUE
; 
 311     m_gdkDecor 
= m_gdkFunc 
= 0; 
 315 bool wxTopLevelWindowGTK::Create( wxWindow 
*parent
, 
 317                                   const wxString
& title
, 
 319                                   const wxSize
& sizeOrig
, 
 321                                   const wxString 
&name 
) 
 323     // always create a frame of some reasonable, even if arbitrary, size (at 
 324     // least for MSW compatibility) 
 325     wxSize size 
= sizeOrig
; 
 326     if ( size
.x 
== -1 || size
.y 
== -1 ) 
 328         wxSize sizeDpy 
= wxGetDisplaySize(); 
 330             size
.x 
= sizeDpy
.x 
/ 3; 
 332             size
.y 
= sizeDpy
.y 
/ 5; 
 335     wxTopLevelWindows
.Append( this ); 
 337     m_needParent 
= FALSE
; 
 339     if (!PreCreation( parent
, pos
, size 
) || 
 340         !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name 
)) 
 342         wxFAIL_MSG( wxT("wxTopLevelWindowGTK creation failed") ); 
 348     m_insertCallback 
= (wxInsertChildFunction
) wxInsertChildInTopLevelWindow
; 
 350     GtkWindowType win_type 
= GTK_WINDOW_TOPLEVEL
; 
 352     if (style 
& wxFRAME_TOOL_WINDOW
) 
 353         win_type 
= GTK_WINDOW_POPUP
; 
 355     if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
) 
 357         // there is no more GTK_WINDOW_DIALOG in 2.0 
 359         win_type 
= GTK_WINDOW_TOPLEVEL
; 
 361         win_type 
= GTK_WINDOW_DIALOG
; 
 365     m_widget 
= gtk_window_new( win_type 
); 
 367     if (m_parent 
&& (((GTK_IS_WINDOW(m_parent
->m_widget
)) && 
 368                       (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
)) || 
 369                      (style 
& wxFRAME_FLOAT_ON_PARENT
))) 
 371         gtk_window_set_transient_for( GTK_WINDOW(m_widget
), GTK_WINDOW(m_parent
->m_widget
) ); 
 375         gtk_window_set_wmclass( GTK_WINDOW(m_widget
), wxGTK_CONV( name 
), wxGTK_CONV( name 
) ); 
 377     gtk_window_set_title( GTK_WINDOW(m_widget
), wxGTK_CONV( title 
) ); 
 378     GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS 
); 
 380     gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event", 
 381         GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this ); 
 383     // m_mainWidget holds the toolbar, the menubar and the client area 
 384     m_mainWidget 
= gtk_pizza_new(); 
 385     gtk_widget_show( m_mainWidget 
); 
 386     GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS 
); 
 387     gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget 
); 
 389     if (m_miniEdge 
== 0) // wxMiniFrame has its own version. 
 391        // For m_mainWidget themes 
 392        gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "expose_event", 
 393                 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this ); 
 395        gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "draw", 
 396                 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this ); 
 400     // m_wxwindow only represents the client area without toolbar and menubar 
 401     m_wxwindow 
= gtk_pizza_new(); 
 402     gtk_widget_show( m_wxwindow 
); 
 403     gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow 
); 
 405     // we donm't allow the frame to get the focus as otherwise 
 406     // the frame will grab it at arbitrary focus changes 
 407     GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS 
); 
 409     if (m_parent
) m_parent
->AddChild( this ); 
 411     // the user resized the frame by dragging etc. 
 412     gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate", 
 413         GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this ); 
 417     if ((m_x 
!= -1) || (m_y 
!= -1)) 
 418         gtk_widget_set_uposition( m_widget
, m_x
, m_y 
); 
 420     gtk_window_set_default_size( GTK_WINDOW(m_widget
), m_width
, m_height 
); 
 422     //  we cannot set MWM hints and icons before the widget has 
 423     //  been realized, so we do this directly after realization 
 424     gtk_signal_connect( GTK_OBJECT(m_widget
), "realize", 
 425                         GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this ); 
 427     // the only way to get the window size is to connect to this event 
 428     gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event", 
 429         GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this ); 
 431     // map and unmap for iconized state 
 432     gtk_signal_connect( GTK_OBJECT(m_widget
), "map_event", 
 433         GTK_SIGNAL_FUNC(gtk_frame_map_callback
), (gpointer
)this ); 
 434     gtk_signal_connect( GTK_OBJECT(m_widget
), "unmap_event", 
 435         GTK_SIGNAL_FUNC(gtk_frame_unmap_callback
), (gpointer
)this ); 
 437     // the only way to get the window size is to connect to this event 
 438     gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event", 
 439         GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this ); 
 441     // disable native tab traversal 
 442     gtk_signal_connect( GTK_OBJECT(m_widget
), "focus", 
 443         GTK_SIGNAL_FUNC(gtk_frame_focus_callback
), (gpointer
)this ); 
 446     if ((m_miniEdge 
> 0) || (style 
& wxSIMPLE_BORDER
) || (style 
& wxNO_BORDER
)) 
 453         m_gdkDecor 
= (long) GDK_DECOR_BORDER
; 
 454         m_gdkFunc 
= (long) GDK_FUNC_MOVE
; 
 456         // All this is for Motif Window Manager "hints" and is supposed to be 
 457         // recognized by other WMs as well. 
 458         if ((style 
& wxCAPTION
) != 0) 
 460             m_gdkDecor 
|= GDK_DECOR_TITLE
; 
 462         if ((style 
& wxCLOSE_BOX
) != 0) 
 464             m_gdkFunc 
|= GDK_FUNC_CLOSE
; 
 466         if ((style 
& wxSYSTEM_MENU
) != 0) 
 468             m_gdkDecor 
|= GDK_DECOR_MENU
; 
 470         if ((style 
& wxMINIMIZE_BOX
) != 0) 
 472             m_gdkFunc 
|= GDK_FUNC_MINIMIZE
; 
 473             m_gdkDecor 
|= GDK_DECOR_MINIMIZE
; 
 475         if ((style 
& wxMAXIMIZE_BOX
) != 0) 
 477             m_gdkFunc 
|= GDK_FUNC_MAXIMIZE
; 
 478             m_gdkDecor 
|= GDK_DECOR_MAXIMIZE
; 
 480         if ((style 
& wxRESIZE_BORDER
) != 0) 
 482            m_gdkFunc 
|= GDK_FUNC_RESIZE
; 
 483            m_gdkDecor 
|= GDK_DECOR_RESIZEH
; 
 490 wxTopLevelWindowGTK::~wxTopLevelWindowGTK() 
 494         wxASSERT_MSG( FALSE
, _T("Window still grabbed")); 
 498     m_isBeingDeleted 
= TRUE
; 
 500     // it may also be GtkScrolledWindow in the case of an MDI child 
 501     if (GTK_IS_WINDOW(m_widget
)) 
 503         gtk_window_set_focus( GTK_WINDOW(m_widget
), NULL 
); 
 509 bool wxTopLevelWindowGTK::ShowFullScreen(bool show
, long style 
) 
 511     if (show 
== m_fsIsShowing
) return FALSE
; // return what? 
 513     m_fsIsShowing 
= show
; 
 515     GdkWindow 
*window 
= m_widget
->window
; 
 516     wxX11FullScreenMethod method 
= 
 517         wxGetFullScreenMethodX11((WXDisplay
*)GDK_DISPLAY(), 
 518                                  (WXWindow
)GDK_ROOT_WINDOW()); 
 522         m_fsSaveFlag 
= style
; 
 523         GetPosition( &m_fsSaveFrame
.x
, &m_fsSaveFrame
.y 
); 
 524         GetSize( &m_fsSaveFrame
.width
, &m_fsSaveFrame
.height 
); 
 526         int screen_width
,screen_height
; 
 527         wxDisplaySize( &screen_width
, &screen_height 
); 
 529                 gint client_x
, client_y
, root_x
, root_y
; 
 532         if (method 
!= wxX11_FS_WMSPEC
) 
 534             // don't do it always, Metacity hates it 
 535             m_fsSaveGdkFunc 
= m_gdkFunc
; 
 536             m_fsSaveGdkDecor 
= m_gdkDecor
; 
 537             m_gdkFunc 
= m_gdkDecor 
= 0; 
 538             gdk_window_set_decorations(window
, (GdkWMDecoration
)0); 
 539             gdk_window_set_functions(window
, (GdkWMFunction
)0); 
 542                 gdk_window_get_origin (m_widget
->window
, &root_x
, &root_y
); 
 543                 gdk_window_get_geometry (m_widget
->window
, &client_x
, &client_y
, 
 544                                          &width
, &height
, NULL
); 
 546                 gdk_window_move_resize (m_widget
->window
, -client_x
, -client_y
, 
 547                                         screen_width 
+ 1, screen_height 
+ 1); 
 549         wxSetFullScreenStateX11((WXDisplay
*)GDK_DISPLAY(), 
 550                                 (WXWindow
)GDK_ROOT_WINDOW(), 
 551                                 (WXWindow
)GDK_WINDOW_XWINDOW(window
), 
 552                                 show
, &m_fsSaveFrame
, method
); 
 556         if (method 
!= wxX11_FS_WMSPEC
) 
 558             // don't do it always, Metacity hates it 
 559             m_gdkFunc 
= m_fsSaveGdkFunc
; 
 560             m_gdkDecor 
= m_fsSaveGdkDecor
; 
 561             gdk_window_set_decorations(window
, (GdkWMDecoration
)m_gdkDecor
); 
 562             gdk_window_set_functions(window
, (GdkWMFunction
)m_gdkFunc
); 
 565         wxSetFullScreenStateX11((WXDisplay
*)GDK_DISPLAY(), 
 566                                 (WXWindow
)GDK_ROOT_WINDOW(), 
 567                                 (WXWindow
)GDK_WINDOW_XWINDOW(window
), 
 568                                 show
, &m_fsSaveFrame
, method
); 
 570         SetSize(m_fsSaveFrame
.x
, m_fsSaveFrame
.y
, 
 571                 m_fsSaveFrame
.width
, m_fsSaveFrame
.height
); 
 578 // ---------------------------------------------------------------------------- 
 579 // overridden wxWindow methods 
 580 // ---------------------------------------------------------------------------- 
 582 bool wxTopLevelWindowGTK::Show( bool show 
) 
 584     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 586     if (show 
&& !m_sizeSet
) 
 588         /* by calling GtkOnSize here, we don't have to call 
 589            either after showing the frame, which would entail 
 590            much ugly flicker or from within the size_allocate 
 591            handler, because GTK 1.1.X forbids that. */ 
 593         GtkOnSize( m_x
, m_y
, m_width
, m_height 
); 
 596     return wxWindow::Show( show 
); 
 599 void wxTopLevelWindowGTK::DoMoveWindow(int WXUNUSED(x
), int WXUNUSED(y
), int WXUNUSED(width
), int WXUNUSED(height
) ) 
 601     wxFAIL_MSG( wxT("DoMoveWindow called for wxTopLevelWindowGTK") ); 
 604 void wxTopLevelWindowGTK::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags 
) 
 606     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 608     // this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow 
 609     wxASSERT_MSG( (m_wxwindow 
!= NULL
), wxT("invalid frame") ); 
 619     int old_width 
= m_width
; 
 620     int old_height 
= m_height
; 
 622     if ((sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
) == 0) 
 624         if (x 
!= -1) m_x 
= x
; 
 625         if (y 
!= -1) m_y 
= y
; 
 632     if (width 
!= -1) m_width 
= width
; 
 633     if (height 
!= -1) m_height 
= height
; 
 636     if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH) 
 638         if (width == -1) m_width = 80; 
 641     if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT) 
 643        if (height == -1) m_height = 26; 
 647     int minWidth 
= GetMinWidth(), 
 648         minHeight 
= GetMinHeight(), 
 649         maxWidth 
= GetMaxWidth(), 
 650         maxHeight 
= GetMaxHeight(); 
 652     if ((minWidth 
!= -1) && (m_width 
< minWidth
)) m_width 
= minWidth
; 
 653     if ((minHeight 
!= -1) && (m_height 
< minHeight
)) m_height 
= minHeight
; 
 654     if ((maxWidth 
!= -1) && (m_width 
> maxWidth
)) m_width 
= maxWidth
; 
 655     if ((maxHeight 
!= -1) && (m_height 
> maxHeight
)) m_height 
= maxHeight
; 
 657     if ((m_x 
!= -1) || (m_y 
!= -1)) 
 659         if ((m_x 
!= old_x
) || (m_y 
!= old_y
)) 
 661             gtk_widget_set_uposition( m_widget
, m_x
, m_y 
); 
 665     if ((m_width 
!= old_width
) || (m_height 
!= old_height
)) 
 667         if (m_widget
->window
) 
 668             gdk_window_resize( m_widget
->window
, m_width
, m_height 
); 
 670             gtk_window_set_default_size( GTK_WINDOW(m_widget
), m_width
, m_height 
); 
 672         /* we set the size in GtkOnSize, i.e. mostly the actual resizing is 
 673            done either directly before the frame is shown or in idle time 
 674            so that different calls to SetSize() don't lead to flicker. */ 
 681 void wxTopLevelWindowGTK::DoGetClientSize( int *width
, int *height 
) const 
 683     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 685     wxWindow::DoGetClientSize( width
, height 
); 
 689         *height 
-= m_miniEdge
*2 + m_miniTitle
; 
 693         *width 
-= m_miniEdge
*2; 
 697 void wxTopLevelWindowGTK::DoSetClientSize( int width
, int height 
) 
 699     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 702               width 
+ m_miniEdge
*2, height  
+ m_miniEdge
*2 + m_miniTitle
, 0); 
 705 void wxTopLevelWindowGTK::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), 
 706                                      int width
, int height 
) 
 708     // due to a bug in gtk, x,y are always 0 
 713     if (m_resizing
) return; 
 716     if ( m_wxwindow 
== NULL 
) return; 
 721     /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses 
 722        wxWindow::Create to create it's GTK equivalent. m_mainWidget is only 
 723        set in wxFrame::Create so it is used to check what kind of frame we 
 724        have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we 
 725        skip the part which handles m_frameMenuBar, m_frameToolBar and (most 
 726        importantly) m_mainWidget */ 
 728     int minWidth 
= GetMinWidth(), 
 729         minHeight 
= GetMinHeight(), 
 730         maxWidth 
= GetMaxWidth(), 
 731         maxHeight 
= GetMaxHeight(); 
 733     if ((minWidth 
!= -1) && (m_width 
< minWidth
)) m_width 
= minWidth
; 
 734     if ((minHeight 
!= -1) && (m_height 
< minHeight
)) m_height 
= minHeight
; 
 735     if ((maxWidth 
!= -1) && (m_width 
> maxWidth
)) m_width 
= maxWidth
; 
 736     if ((maxHeight 
!= -1) && (m_height 
> maxHeight
)) m_height 
= maxHeight
; 
 741         gint            flag 
= 0; // GDK_HINT_POS; 
 744         if ((minWidth 
!= -1) || (minHeight 
!= -1)) flag 
|= GDK_HINT_MIN_SIZE
; 
 745         if ((maxWidth 
!= -1) || (maxHeight 
!= -1)) flag 
|= GDK_HINT_MAX_SIZE
; 
 747         geom
.min_width 
= minWidth
; 
 748         geom
.min_height 
= minHeight
; 
 750             // Because of the way we set GDK_HINT_MAX_SIZE above, if either of 
 751             // maxHeight or maxWidth is set, we must set them both, else the 
 752             // remaining -1 will be taken literally. 
 754             // I'm certain this also happens elsewhere, and is the probable 
 755             // cause of other such things as: 
 756             // Gtk-WARNING **: gtk_widget_size_allocate(): 
 757             //       attempt to allocate widget with width 65535 and height 600 
 758             // but I don't have time to track them all now.. 
 760             // Really we need to encapulate all this height/width business and 
 761             // stop any old method from ripping at the members directly and 
 762             // scattering -1's without regard for who might resolve them later. 
 764         geom
.max_width 
= ( maxHeight 
== -1 ) ? maxWidth
 
 765                          : ( maxWidth 
== -1 ) ? wxGetDisplaySize().GetWidth() 
 768         geom
.max_height 
= ( maxWidth 
== -1 ) ? maxHeight    
// ( == -1 here ) 
 769                           : ( maxHeight 
== -1 ) ? wxGetDisplaySize().GetHeight() 
 772         gtk_window_set_geometry_hints( GTK_WINDOW(m_widget
), 
 775                                        (GdkWindowHints
) flag 
); 
 777         /* I revert back to wxGTK's original behaviour. m_mainWidget holds the 
 778          * menubar, the toolbar and the client area, which is represented by 
 780          * this hurts in the eye, but I don't want to call SetSize() 
 781          * because I don't want to call any non-native functions here. */ 
 783         int client_x 
= m_miniEdge
; 
 784         int client_y 
= m_miniEdge 
+ m_miniTitle
; 
 785         int client_w 
= m_width 
- 2*m_miniEdge
; 
 786         int client_h 
= m_height 
- 2*m_miniEdge 
- m_miniTitle
; 
 788         gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
), 
 790                               client_x
, client_y
, client_w
, client_h 
); 
 794         // If there is no m_mainWidget between m_widget and m_wxwindow there 
 795         // is no need to set the size or position of m_wxwindow. 
 800     // send size event to frame 
 801     wxSizeEvent 
event( wxSize(m_width
,m_height
), GetId() ); 
 802     event
.SetEventObject( this ); 
 803     GetEventHandler()->ProcessEvent( event 
); 
 808 void wxTopLevelWindowGTK::OnInternalIdle() 
 810     if (!m_sizeSet 
&& GTK_WIDGET_REALIZED(m_wxwindow
)) 
 812         GtkOnSize( m_x
, m_y
, m_width
, m_height 
); 
 814         // we'll come back later 
 816             wxapp_install_idle_handler(); 
 820     // set the focus if not done yet and if we can already do it 
 821     if ( GTK_WIDGET_REALIZED(m_wxwindow
) ) 
 823         if ( g_delayedFocus 
&& 
 824              wxGetTopLevelParent((wxWindow
*)g_delayedFocus
) == this ) 
 826             wxLogTrace(_T("focus"), 
 827                        _T("Setting focus from wxTLW::OnIdle() to %s(%s)"), 
 828                        g_delayedFocus
->GetClassInfo()->GetClassName(), 
 829                        g_delayedFocus
->GetLabel().c_str()); 
 831             g_delayedFocus
->SetFocus(); 
 832             g_delayedFocus 
= NULL
; 
 836     wxWindow::OnInternalIdle(); 
 839 // ---------------------------------------------------------------------------- 
 841 // ---------------------------------------------------------------------------- 
 843 void wxTopLevelWindowGTK::SetTitle( const wxString 
&title 
) 
 845     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 848     gtk_window_set_title( GTK_WINDOW(m_widget
), wxGTK_CONV( title 
) ); 
 851 void wxTopLevelWindowGTK::DoSetIcon( const wxIcon 
&icon 
) 
 856     if (!m_widget
->window
) 
 859     wxMask 
*mask 
= icon
.GetMask(); 
 860     GdkBitmap 
*bm 
= (GdkBitmap 
*) NULL
; 
 861     if (mask
) bm 
= mask
->GetBitmap(); 
 863     gdk_window_set_icon( m_widget
->window
, (GdkWindow 
*) NULL
, icon
.GetPixmap(), bm 
); 
 866 void wxTopLevelWindowGTK::SetIcon( const wxIcon 
&icon 
) 
 868     SetIcons( wxIconBundle( icon 
) ); 
 871 void wxTopLevelWindowGTK::SetIcons( const wxIconBundle 
&icons 
) 
 873     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 874     GdkWindow
* window 
= m_widget
->window
; 
 876     wxTopLevelWindowBase::SetIcons( icons 
); 
 878     DoSetIcon( icons
.GetIcon( -1 ) ); 
 881         wxSetIconsX11( (WXDisplay
*)GDK_WINDOW_XDISPLAY( window 
), 
 882                        (WXWindow
)GDK_WINDOW_XWINDOW( window 
), icons 
); 
 886 // ---------------------------------------------------------------------------- 
 887 // frame state: maximized/iconized/normal 
 888 // ---------------------------------------------------------------------------- 
 890 void wxTopLevelWindowGTK::Maximize(bool maximize
) 
 894         gtk_window_maximize( GTK_WINDOW( m_widget 
) ); 
 896         gtk_window_unmaximize( GTK_WINDOW( m_widget 
) ); 
 898     wxFAIL_MSG( _T("not implemented") ); 
 902 bool wxTopLevelWindowGTK::IsMaximized() const 
 904   //    wxFAIL_MSG( _T("not implemented") ); 
 906     // This is an approximation 
 910 void wxTopLevelWindowGTK::Restore() 
 913     // "Present" seems similar enough to "restore" 
 914     gtk_window_present( GTK_WINDOW( m_widget 
) ); 
 916     wxFAIL_MSG( _T("not implemented") ); 
 920 void wxTopLevelWindowGTK::Iconize( bool iconize 
) 
 924         gtk_window_iconify( GTK_WINDOW( m_widget 
) ); 
 926         gtk_window_deiconify( GTK_WINDOW( m_widget 
) ); 
 930        GdkWindow 
*window 
= m_widget
->window
; 
 932        // you should do it later, for example from OnCreate() handler 
 933        wxCHECK_RET( window
, _T("frame not created yet - can't iconize") ); 
 935        XIconifyWindow( GDK_WINDOW_XDISPLAY( window 
), 
 936                        GDK_WINDOW_XWINDOW( window 
), 
 937                        DefaultScreen( GDK_DISPLAY() ) ); 
 942 bool wxTopLevelWindowGTK::IsIconized() const 
 947 void wxTopLevelWindowGTK::SetIconizeState(bool iconize
) 
 949     if ( iconize 
!= m_isIconized 
) 
 951         m_isIconized 
= iconize
; 
 952         (void)SendIconizeEvent(iconize
); 
 956 void wxTopLevelWindowGTK::AddGrab() 
 961         gtk_grab_add( m_widget 
); 
 963         gtk_grab_remove( m_widget 
); 
 967 void wxTopLevelWindowGTK::RemoveGrab() 
 978 static bool do_shape_combine_region(GdkWindow
* window
, const wxRegion
& region
) 
 982         if (region
.IsEmpty()) 
 984             gdk_window_shape_combine_mask(window
, NULL
, 0, 0); 
 989         gdk_window_shape_combine_region(window
, region
.GetRegion(), 0, 0); 
 991         wxBitmap bmp 
= region
.ConvertToBitmap(); 
 992         bmp
.SetMask(new wxMask(bmp
, *wxBLACK
)); 
 993         GdkBitmap
* mask 
= bmp
.GetMask()->GetBitmap(); 
 994         gdk_window_shape_combine_mask(window
, mask
, 0, 0); 
1003 bool wxTopLevelWindowGTK::SetShape(const wxRegion
& region
) 
1005     wxCHECK_MSG( HasFlag(wxFRAME_SHAPED
), FALSE
, 
1006                  _T("Shaped windows must be created with the wxFRAME_SHAPED style.")); 
1008     GdkWindow 
*window 
= NULL
; 
1011         window 
= GTK_PIZZA(m_wxwindow
)->bin_window
; 
1012         do_shape_combine_region(window
, region
); 
1014     window 
= m_widget
->window
; 
1015     return do_shape_combine_region(window
, region
);