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 
  31 #include "wx/toplevel.h" 
  33 #include "wx/dialog.h" 
  34 #include "wx/control.h" 
  36 #include "wx/dcclient.h" 
  37 #include "wx/gtk/private.h" 
  39 #include "wx/settings.h" 
  44 #include <gdk/gdkkeysyms.h> 
  47 #include "wx/gtk/win_gtk.h" 
  49 #include "wx/unix/utilsx11.h" 
  52 #include <X11/Xatom.h> 
  54 // ---------------------------------------------------------------------------- 
  56 // ---------------------------------------------------------------------------- 
  58 extern void wxapp_install_idle_handler(); 
  61 // ---------------------------------------------------------------------------- 
  63 // ---------------------------------------------------------------------------- 
  65 extern wxList           wxPendingDelete
; 
  67 extern int              g_openDialogs
; 
  68 extern wxWindowGTK     
*g_delayedFocus
; 
  70 // the frame that is currently active (i.e. its child has focus). It is 
  71 // used to generate wxActivateEvents 
  72 static wxTopLevelWindowGTK 
*g_activeFrame 
= (wxTopLevelWindowGTK
*) NULL
; 
  73 static wxTopLevelWindowGTK 
*g_lastActiveFrame 
= (wxTopLevelWindowGTK
*) NULL
; 
  75 // if we detect that the app has got/lost the focus, we set this variable to 
  76 // either TRUE or FALSE and an activate event will be sent during the next 
  77 // OnIdle() call and it is reset to -1: this value means that we shouldn't 
  78 // send any activate events at all 
  79 static int              g_sendActivateEvent 
= -1; 
  81 //----------------------------------------------------------------------------- 
  83 //----------------------------------------------------------------------------- 
  86 static gint 
gtk_frame_focus_in_callback( GtkWidget 
*widget
, 
  87                                          GdkEvent 
*WXUNUSED(event
), 
  88                                          wxTopLevelWindowGTK 
*win 
) 
  91         wxapp_install_idle_handler(); 
  93     switch ( g_sendActivateEvent 
) 
  96             // we've got focus from outside, synthetize wxActivateEvent 
  97             g_sendActivateEvent 
= 1; 
 101             // another our window just lost focus, it was already ours before 
 102             // - don't send any wxActivateEvent 
 103             g_sendActivateEvent 
= -1; 
 108     g_lastActiveFrame 
= g_activeFrame
; 
 110     // wxPrintf( wxT("active: %s\n"), win->GetTitle().c_str() ); 
 112     wxLogTrace(wxT("activate"), wxT("Activating frame %p (from focus_in)"), g_activeFrame
); 
 113     wxActivateEvent 
event(wxEVT_ACTIVATE
, TRUE
, g_activeFrame
->GetId()); 
 114     event
.SetEventObject(g_activeFrame
); 
 115     g_activeFrame
->GetEventHandler()->ProcessEvent(event
); 
 121 //----------------------------------------------------------------------------- 
 123 //----------------------------------------------------------------------------- 
 126 static gint 
gtk_frame_focus_out_callback( GtkWidget 
*widget
,  
 127                                           GdkEventFocus 
*WXUNUSED(gdk_event
),  
 128                                           wxTopLevelWindowGTK 
*win 
) 
 131         wxapp_install_idle_handler(); 
 133     // if the focus goes out of our app alltogether, OnIdle() will send 
 134     // wxActivateEvent, otherwise gtk_window_focus_in_callback() will reset 
 135     // g_sendActivateEvent to -1 
 136     g_sendActivateEvent 
= 0; 
 138     // wxASSERT_MSG( (g_activeFrame == win), wxT("TLW deactivatd although it wasn't active") ); 
 140     // wxPrintf( wxT("inactive: %s\n"), win->GetTitle().c_str() ); 
 144         wxLogTrace(wxT("activate"), wxT("Activating frame %p (from focus_in)"), g_activeFrame
); 
 145         wxActivateEvent 
event(wxEVT_ACTIVATE
, FALSE
, g_activeFrame
->GetId()); 
 146         event
.SetEventObject(g_activeFrame
); 
 147         g_activeFrame
->GetEventHandler()->ProcessEvent(event
); 
 149         g_activeFrame 
= NULL
; 
 156 //----------------------------------------------------------------------------- 
 157 // "focus" from m_window 
 158 //----------------------------------------------------------------------------- 
 161 static gint 
gtk_frame_focus_callback( GtkWidget 
*widget
, GtkDirectionType 
WXUNUSED(d
), wxWindow 
*WXUNUSED(win
) ) 
 164         wxapp_install_idle_handler(); 
 166     // This disables GTK's tab traversal 
 167     gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus" ); 
 172 //----------------------------------------------------------------------------- 
 174 //----------------------------------------------------------------------------- 
 177 static void gtk_frame_size_callback( GtkWidget 
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxTopLevelWindowGTK 
*win 
) 
 180         wxapp_install_idle_handler(); 
 185     if ((win
->m_width 
!= alloc
->width
) || (win
->m_height 
!= alloc
->height
)) 
 188         wxPrintf( "OnSize from " ); 
 189         if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 190            wxPrintf( win->GetClassInfo()->GetClassName() ); 
 191         wxPrintf( " %d %d %d %d\n", (int)alloc->x, 
 194                                 (int)alloc->height ); 
 197         win
->m_width 
= alloc
->width
; 
 198         win
->m_height 
= alloc
->height
; 
 199         win
->GtkUpdateSize(); 
 204 //----------------------------------------------------------------------------- 
 206 //----------------------------------------------------------------------------- 
 209 static gint 
gtk_frame_delete_callback( GtkWidget 
*WXUNUSED(widget
), GdkEvent 
*WXUNUSED(event
), wxTopLevelWindowGTK 
*win 
) 
 212         wxapp_install_idle_handler(); 
 214     if (win
->IsEnabled() && 
 215         (g_openDialogs 
== 0 || (win
->GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
) || 
 224 //----------------------------------------------------------------------------- 
 226 //----------------------------------------------------------------------------- 
 230 gtk_frame_configure_callback( GtkWidget 
*WXUNUSED(widget
), GdkEventConfigure 
*WXUNUSED(event
), wxTopLevelWindowGTK 
*win 
) 
 233         wxapp_install_idle_handler(); 
 235     if (!win
->m_hasVMT 
|| !win
->IsShown()) 
 241     gdk_window_get_root_origin( win
->m_widget
->window
, &x
, &y 
); 
 245     wxMoveEvent 
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() ); 
 246     mevent
.SetEventObject( win 
); 
 247     win
->GetEventHandler()->ProcessEvent( mevent 
); 
 253 //----------------------------------------------------------------------------- 
 254 // "realize" from m_widget 
 255 //----------------------------------------------------------------------------- 
 257 // we cannot MWM hints and icons before the widget has been realized, 
 258 // so we do this directly after realization 
 262 gtk_frame_realized_callback( GtkWidget 
* WXUNUSED(widget
), 
 263                              wxTopLevelWindowGTK 
*win 
) 
 266         wxapp_install_idle_handler(); 
 268     // All this is for Motif Window Manager "hints" and is supposed to be 
 269     // recognized by other WM as well. Not tested. 
 270     gdk_window_set_decorations(win
->m_widget
->window
, 
 271                                (GdkWMDecoration
)win
->m_gdkDecor
); 
 272     gdk_window_set_functions(win
->m_widget
->window
, 
 273                                (GdkWMFunction
)win
->m_gdkFunc
); 
 275     // GTK's shrinking/growing policy 
 276     if ((win
->m_gdkFunc 
& GDK_FUNC_RESIZE
) == 0) 
 277         gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1); 
 279         gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1); 
 282     wxIconBundle iconsOld 
= win
->GetIcons(); 
 283     if ( iconsOld
.GetIcon(-1).Ok() ) 
 285         win
->SetIcon( wxNullIcon 
); 
 286         win
->SetIcons( iconsOld 
); 
 291 //----------------------------------------------------------------------------- 
 292 // "map_event" from m_widget 
 293 //----------------------------------------------------------------------------- 
 297 gtk_frame_map_callback( GtkWidget 
* WXUNUSED(widget
), 
 298                         GdkEvent 
* WXUNUSED(event
), 
 299                         wxTopLevelWindow 
*win 
) 
 301     win
->SetIconizeState(FALSE
); 
 305 //----------------------------------------------------------------------------- 
 306 // "unmap_event" from m_widget 
 307 //----------------------------------------------------------------------------- 
 311 gtk_frame_unmap_callback( GtkWidget 
* WXUNUSED(widget
), 
 312                           GdkEvent 
* WXUNUSED(event
), 
 313                           wxTopLevelWindow 
*win 
) 
 315     win
->SetIconizeState(TRUE
); 
 319 //----------------------------------------------------------------------------- 
 320 // "expose_event" of m_client 
 321 //----------------------------------------------------------------------------- 
 324 static int gtk_window_expose_callback( GtkWidget 
*widget
, GdkEventExpose 
*gdk_event
, wxWindow 
*win 
) 
 326     GtkPizza 
*pizza 
= GTK_PIZZA(widget
); 
 328     gtk_paint_flat_box (win
->m_widget
->style
, 
 329                         pizza
->bin_window
, GTK_STATE_NORMAL
, 
 340 //----------------------------------------------------------------------------- 
 341 // "draw" of m_client 
 342 //----------------------------------------------------------------------------- 
 347 static void gtk_window_draw_callback( GtkWidget 
*widget
, GdkRectangle 
*rect
, wxWindow 
*win 
) 
 349     GtkPizza 
*pizza 
= GTK_PIZZA(widget
); 
 351     gtk_paint_flat_box (win
->m_widget
->style
, 
 352                         pizza
->bin_window
, GTK_STATE_NORMAL
, 
 363 // ---------------------------------------------------------------------------- 
 364 // wxTopLevelWindowGTK itself 
 365 // ---------------------------------------------------------------------------- 
 367 //----------------------------------------------------------------------------- 
 368 // InsertChild for wxTopLevelWindowGTK 
 369 //----------------------------------------------------------------------------- 
 371 /* Callback for wxTopLevelWindowGTK. This very strange beast has to be used because 
 372  * C++ has no virtual methods in a constructor. We have to emulate a 
 373  * virtual function here as wxWidgets requires different ways to insert 
 374  * a child in container classes. */ 
 376 static void wxInsertChildInTopLevelWindow( wxTopLevelWindowGTK
* parent
, wxWindow
* child 
) 
 378     wxASSERT( GTK_IS_WIDGET(child
->m_widget
) ); 
 380     if (!parent
->m_insertInClientArea
) 
 382         // these are outside the client area 
 383         wxTopLevelWindowGTK
* frame 
= (wxTopLevelWindowGTK
*) parent
; 
 384         gtk_pizza_put( GTK_PIZZA(frame
->m_mainWidget
), 
 385                          GTK_WIDGET(child
->m_widget
), 
 393         // these are inside the client area 
 394         gtk_pizza_put( GTK_PIZZA(parent
->m_wxwindow
), 
 395                          GTK_WIDGET(child
->m_widget
), 
 402     // resize on OnInternalIdle 
 403     parent
->GtkUpdateSize(); 
 406 // ---------------------------------------------------------------------------- 
 407 // wxTopLevelWindowGTK creation 
 408 // ---------------------------------------------------------------------------- 
 410 void wxTopLevelWindowGTK::Init() 
 415     m_mainWidget 
= (GtkWidget
*) NULL
; 
 416     m_insertInClientArea 
= TRUE
; 
 417     m_isIconized 
= FALSE
; 
 418     m_fsIsShowing 
= FALSE
; 
 419     m_themeEnabled 
= TRUE
; 
 420     m_gdkDecor 
= m_gdkFunc 
= 0; 
 424 bool wxTopLevelWindowGTK::Create( wxWindow 
*parent
, 
 426                                   const wxString
& title
, 
 428                                   const wxSize
& sizeOrig
, 
 430                                   const wxString 
&name 
) 
 432     // always create a frame of some reasonable, even if arbitrary, size (at 
 433     // least for MSW compatibility) 
 434     wxSize size 
= sizeOrig
; 
 435     size
.x 
= WidthDefault(size
.x
); 
 436     size
.y 
= HeightDefault(size
.y
); 
 438     wxTopLevelWindows
.Append( this ); 
 440     m_needParent 
= FALSE
; 
 442     if (!PreCreation( parent
, pos
, size 
) || 
 443         !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name 
)) 
 445         wxFAIL_MSG( wxT("wxTopLevelWindowGTK creation failed") ); 
 451     m_insertCallback 
= (wxInsertChildFunction
) wxInsertChildInTopLevelWindow
; 
 453     // NB: m_widget may be !=NULL if it was created by derived class' Create, 
 454     //     e.g. in wxTaskBarIconAreaGTK 
 455     if (m_widget 
== NULL
) 
 457         if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
) 
 460             m_widget 
= gtk_window_new(GTK_WINDOW_TOPLEVEL
); 
 461             // Tell WM that this is a dialog window and make it center 
 462             // on parent by default (this is what GtkDialog ctor does): 
 463             gtk_window_set_type_hint(GTK_WINDOW(m_widget
), 
 464                                      GDK_WINDOW_TYPE_HINT_DIALOG
); 
 465             gtk_window_set_position(GTK_WINDOW(m_widget
), 
 466                                     GTK_WIN_POS_CENTER_ON_PARENT
); 
 468             m_widget 
= gtk_window_new(GTK_WINDOW_DIALOG
); 
 473             m_widget 
= gtk_window_new(GTK_WINDOW_TOPLEVEL
); 
 474 #if GTK_CHECK_VERSION(2,1,0) 
 475             if (style 
& wxFRAME_TOOL_WINDOW
) 
 477                 gtk_window_set_type_hint(GTK_WINDOW(m_widget
), 
 478                                          GDK_WINDOW_TYPE_HINT_UTILITY
); 
 480                 // On some WMs, like KDE, a TOOL_WINDOW will still show 
 481                 // on the taskbar, but on Gnome a TOOL_WINDOW will not. 
 482                 // For consistency between WMs and with Windows, we  
 483                 // should set the NO_TASKBAR flag which will apply 
 484                 // the set_skip_taskbar_hint if it is available, 
 485                 // ensuring no taskbar entry will appear. 
 486                 style 
|= wxFRAME_NO_TASKBAR
; 
 493     wxWindow 
*topParent 
= wxGetTopLevelParent(m_parent
); 
 494     if (topParent 
&& (((GTK_IS_WINDOW(topParent
->m_widget
)) && 
 495                       (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
)) || 
 496                      (style 
& wxFRAME_FLOAT_ON_PARENT
))) 
 498         gtk_window_set_transient_for( GTK_WINDOW(m_widget
), 
 499                                       GTK_WINDOW(topParent
->m_widget
) ); 
 502 #if GTK_CHECK_VERSION(2,2,0) 
 503     if (style 
& wxFRAME_NO_TASKBAR
) 
 505         gtk_window_set_skip_taskbar_hint(GTK_WINDOW(m_widget
), TRUE
); 
 509 #if GTK_CHECK_VERSION(2,4,0) 
 510     if (!gtk_check_version(2,4,0)) 
 512         if (style 
& wxSTAY_ON_TOP
) 
 514             gtk_window_set_keep_above(GTK_WINDOW(m_widget
), TRUE
); 
 520         gtk_window_set_wmclass( GTK_WINDOW(m_widget
), wxGTK_CONV( name 
), wxGTK_CONV( name 
) ); 
 522     gtk_window_set_title( GTK_WINDOW(m_widget
), wxGTK_CONV( title 
) ); 
 523     GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS 
); 
 525     gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event", 
 526         GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this ); 
 528     // m_mainWidget holds the toolbar, the menubar and the client area 
 529     m_mainWidget 
= gtk_pizza_new(); 
 530     gtk_widget_show( m_mainWidget 
); 
 531     GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS 
); 
 532     gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget 
); 
 534     if (m_miniEdge 
== 0) // wxMiniFrame has its own version. 
 536        // For m_mainWidget themes 
 537        gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "expose_event", 
 538                 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this ); 
 540        gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "draw", 
 541                 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this ); 
 545     // m_wxwindow only represents the client area without toolbar and menubar 
 546     m_wxwindow 
= gtk_pizza_new(); 
 547     gtk_widget_show( m_wxwindow 
); 
 548     gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow 
); 
 550     // we donm't allow the frame to get the focus as otherwise 
 551     // the frame will grab it at arbitrary focus changes 
 552     GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS 
); 
 554     if (m_parent
) m_parent
->AddChild( this ); 
 556     // the user resized the frame by dragging etc. 
 557     gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate", 
 558         GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this ); 
 562     if ((m_x 
!= -1) || (m_y 
!= -1)) 
 563         gtk_widget_set_uposition( m_widget
, m_x
, m_y 
); 
 565     gtk_window_set_default_size( GTK_WINDOW(m_widget
), m_width
, m_height 
); 
 567     //  we cannot set MWM hints and icons before the widget has 
 568     //  been realized, so we do this directly after realization 
 569     gtk_signal_connect( GTK_OBJECT(m_widget
), "realize", 
 570                         GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this ); 
 572     // the only way to get the window size is to connect to this event 
 573     gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event", 
 574         GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this ); 
 576     // map and unmap for iconized state 
 577     gtk_signal_connect( GTK_OBJECT(m_widget
), "map_event", 
 578         GTK_SIGNAL_FUNC(gtk_frame_map_callback
), (gpointer
)this ); 
 579     gtk_signal_connect( GTK_OBJECT(m_widget
), "unmap_event", 
 580         GTK_SIGNAL_FUNC(gtk_frame_unmap_callback
), (gpointer
)this ); 
 582     // the only way to get the window size is to connect to this event 
 583     gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event", 
 584         GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this ); 
 586     // disable native tab traversal 
 587     gtk_signal_connect( GTK_OBJECT(m_widget
), "focus", 
 588         GTK_SIGNAL_FUNC(gtk_frame_focus_callback
), (gpointer
)this ); 
 591     gtk_signal_connect( GTK_OBJECT(m_widget
), "focus_in_event", 
 592         GTK_SIGNAL_FUNC(gtk_frame_focus_in_callback
), (gpointer
)this ); 
 593     gtk_signal_connect( GTK_OBJECT(m_widget
), "focus_out_event", 
 594         GTK_SIGNAL_FUNC(gtk_frame_focus_out_callback
), (gpointer
)this ); 
 597     if ((m_miniEdge 
> 0) || (style 
& wxSIMPLE_BORDER
) || (style 
& wxNO_BORDER
)) 
 604         m_gdkDecor 
= (long) GDK_DECOR_BORDER
; 
 605         m_gdkFunc 
= (long) GDK_FUNC_MOVE
; 
 607         // All this is for Motif Window Manager "hints" and is supposed to be 
 608         // recognized by other WMs as well. 
 609         if ((style 
& wxCAPTION
) != 0) 
 611             m_gdkDecor 
|= GDK_DECOR_TITLE
; 
 613         if ((style 
& wxCLOSE_BOX
) != 0) 
 615             m_gdkFunc 
|= GDK_FUNC_CLOSE
; 
 617         if ((style 
& wxSYSTEM_MENU
) != 0) 
 619             m_gdkDecor 
|= GDK_DECOR_MENU
; 
 621         if ((style 
& wxMINIMIZE_BOX
) != 0) 
 623             m_gdkFunc 
|= GDK_FUNC_MINIMIZE
; 
 624             m_gdkDecor 
|= GDK_DECOR_MINIMIZE
; 
 626         if ((style 
& wxMAXIMIZE_BOX
) != 0) 
 628             m_gdkFunc 
|= GDK_FUNC_MAXIMIZE
; 
 629             m_gdkDecor 
|= GDK_DECOR_MAXIMIZE
; 
 631         if ((style 
& wxRESIZE_BORDER
) != 0) 
 633            m_gdkFunc 
|= GDK_FUNC_RESIZE
; 
 634            m_gdkDecor 
|= GDK_DECOR_RESIZEH
; 
 641 wxTopLevelWindowGTK::~wxTopLevelWindowGTK() 
 645         wxASSERT_MSG( FALSE
, _T("Window still grabbed")); 
 649     m_isBeingDeleted 
= TRUE
; 
 651     // it may also be GtkScrolledWindow in the case of an MDI child 
 652     if (GTK_IS_WINDOW(m_widget
)) 
 654         gtk_window_set_focus( GTK_WINDOW(m_widget
), NULL 
); 
 657     if (g_activeFrame 
== this) 
 658         g_activeFrame 
= NULL
; 
 659     if (g_lastActiveFrame 
== this) 
 660         g_lastActiveFrame 
= NULL
; 
 665 bool wxTopLevelWindowGTK::ShowFullScreen(bool show
, long style 
) 
 667     if (show 
== m_fsIsShowing
) 
 668         return FALSE
; // return what? 
 670     m_fsIsShowing 
= show
; 
 672     wxX11FullScreenMethod method 
= 
 673         wxGetFullScreenMethodX11((WXDisplay
*)GDK_DISPLAY(), 
 674                                  (WXWindow
)GDK_ROOT_WINDOW()); 
 676 #if GTK_CHECK_VERSION(2,2,0) 
 677     // NB: gtk_window_fullscreen() uses freedesktop.org's WMspec extensions 
 678     //     to switch to fullscreen, which is not always available. We must 
 679     //     check if WM supports the spec and use legacy methods if it 
 681     if (method 
== wxX11_FS_WMSPEC
) 
 684             gtk_window_fullscreen( GTK_WINDOW( m_widget 
) ); 
 686             gtk_window_unfullscreen( GTK_WINDOW( m_widget 
) ); 
 691 #endif // GTK+ >= 2.2.0 
 693         GdkWindow 
*window 
= m_widget
->window
; 
 697             m_fsSaveFlag 
= style
; 
 698             GetPosition( &m_fsSaveFrame
.x
, &m_fsSaveFrame
.y 
); 
 699             GetSize( &m_fsSaveFrame
.width
, &m_fsSaveFrame
.height 
); 
 701             int screen_width
,screen_height
; 
 702             wxDisplaySize( &screen_width
, &screen_height 
); 
 704             gint client_x
, client_y
, root_x
, root_y
; 
 707             if (method 
!= wxX11_FS_WMSPEC
) 
 709                 // don't do it always, Metacity hates it 
 710                 m_fsSaveGdkFunc 
= m_gdkFunc
; 
 711                 m_fsSaveGdkDecor 
= m_gdkDecor
; 
 712                 m_gdkFunc 
= m_gdkDecor 
= 0; 
 713                 gdk_window_set_decorations(window
, (GdkWMDecoration
)0); 
 714                 gdk_window_set_functions(window
, (GdkWMFunction
)0); 
 717             gdk_window_get_origin (m_widget
->window
, &root_x
, &root_y
); 
 718             gdk_window_get_geometry (m_widget
->window
, &client_x
, &client_y
, 
 719                          &width
, &height
, NULL
); 
 721             gdk_window_move_resize (m_widget
->window
, -client_x
, -client_y
, 
 722                         screen_width 
+ 1, screen_height 
+ 1); 
 724             wxSetFullScreenStateX11((WXDisplay
*)GDK_DISPLAY(), 
 725                                     (WXWindow
)GDK_ROOT_WINDOW(), 
 726                                     (WXWindow
)GDK_WINDOW_XWINDOW(window
), 
 727                                     show
, &m_fsSaveFrame
, method
); 
 731             if (method 
!= wxX11_FS_WMSPEC
) 
 733                 // don't do it always, Metacity hates it 
 734                 m_gdkFunc 
= m_fsSaveGdkFunc
; 
 735                 m_gdkDecor 
= m_fsSaveGdkDecor
; 
 736                 gdk_window_set_decorations(window
, (GdkWMDecoration
)m_gdkDecor
); 
 737                 gdk_window_set_functions(window
, (GdkWMFunction
)m_gdkFunc
); 
 740             wxSetFullScreenStateX11((WXDisplay
*)GDK_DISPLAY(), 
 741                                     (WXWindow
)GDK_ROOT_WINDOW(), 
 742                                     (WXWindow
)GDK_WINDOW_XWINDOW(window
), 
 743                                     show
, &m_fsSaveFrame
, method
); 
 745             SetSize(m_fsSaveFrame
.x
, m_fsSaveFrame
.y
, 
 746                     m_fsSaveFrame
.width
, m_fsSaveFrame
.height
); 
 753 // ---------------------------------------------------------------------------- 
 754 // overridden wxWindow methods 
 755 // ---------------------------------------------------------------------------- 
 757 bool wxTopLevelWindowGTK::Show( bool show 
) 
 759     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 761     if (show 
&& !m_sizeSet
) 
 763         /* by calling GtkOnSize here, we don't have to call 
 764            either after showing the frame, which would entail 
 765            much ugly flicker or from within the size_allocate 
 766            handler, because GTK 1.1.X forbids that. */ 
 768         GtkOnSize( m_x
, m_y
, m_width
, m_height 
); 
 772         gtk_widget_set_uposition( m_widget
, m_x
, m_y 
); 
 774     return wxWindow::Show( show 
); 
 777 void wxTopLevelWindowGTK::Raise() 
 780     gtk_window_present( GTK_WINDOW( m_widget 
) ); 
 786 void wxTopLevelWindowGTK::DoMoveWindow(int WXUNUSED(x
), int WXUNUSED(y
), int WXUNUSED(width
), int WXUNUSED(height
) ) 
 788     wxFAIL_MSG( wxT("DoMoveWindow called for wxTopLevelWindowGTK") ); 
 791 void wxTopLevelWindowGTK::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags 
) 
 793     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 795     // this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow 
 796     wxASSERT_MSG( (m_wxwindow 
!= NULL
), wxT("invalid frame") ); 
 806     int old_width 
= m_width
; 
 807     int old_height 
= m_height
; 
 809     if ((sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
) == 0) 
 811         if (x 
!= -1) m_x 
= x
; 
 812         if (y 
!= -1) m_y 
= y
; 
 819     if (width 
!= -1) m_width 
= width
; 
 820     if (height 
!= -1) m_height 
= height
; 
 823     if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH) 
 825         if (width == -1) m_width = 80; 
 828     if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT) 
 830        if (height == -1) m_height = 26; 
 834     int minWidth 
= GetMinWidth(), 
 835         minHeight 
= GetMinHeight(), 
 836         maxWidth 
= GetMaxWidth(), 
 837         maxHeight 
= GetMaxHeight(); 
 840     // GPE's window manager doesn't like size hints 
 841     // at all, esp. when the user has to use the 
 849     if ((minWidth 
!= -1) && (m_width 
< minWidth
)) m_width 
= minWidth
; 
 850     if ((minHeight 
!= -1) && (m_height 
< minHeight
)) m_height 
= minHeight
; 
 851     if ((maxWidth 
!= -1) && (m_width 
> maxWidth
)) m_width 
= maxWidth
; 
 852     if ((maxHeight 
!= -1) && (m_height 
> maxHeight
)) m_height 
= maxHeight
; 
 854     if ((m_x 
!= -1) || (m_y 
!= -1)) 
 856         if ((m_x 
!= old_x
) || (m_y 
!= old_y
)) 
 858             gtk_widget_set_uposition( m_widget
, m_x
, m_y 
); 
 862     if ((m_width 
!= old_width
) || (m_height 
!= old_height
)) 
 864         if (m_widget
->window
) 
 865             gdk_window_resize( m_widget
->window
, m_width
, m_height 
); 
 867             gtk_window_set_default_size( GTK_WINDOW(m_widget
), m_width
, m_height 
); 
 869         /* we set the size in GtkOnSize, i.e. mostly the actual resizing is 
 870            done either directly before the frame is shown or in idle time 
 871            so that different calls to SetSize() don't lead to flicker. */ 
 878 void wxTopLevelWindowGTK::DoGetClientSize( int *width
, int *height 
) const 
 880     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 882     wxWindow::DoGetClientSize( width
, height 
); 
 886         *height 
-= m_miniEdge
*2 + m_miniTitle
; 
 890         *width 
-= m_miniEdge
*2; 
 894 void wxTopLevelWindowGTK::DoSetClientSize( int width
, int height 
) 
 896     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 899               width 
+ m_miniEdge
*2, height  
+ m_miniEdge
*2 + m_miniTitle
, 0); 
 902 void wxTopLevelWindowGTK::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), 
 903                                      int width
, int height 
) 
 905     // due to a bug in gtk, x,y are always 0 
 910     if (m_resizing
) return; 
 913     if ( m_wxwindow 
== NULL 
) return; 
 918     /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses 
 919        wxWindow::Create to create it's GTK equivalent. m_mainWidget is only 
 920        set in wxFrame::Create so it is used to check what kind of frame we 
 921        have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we 
 922        skip the part which handles m_frameMenuBar, m_frameToolBar and (most 
 923        importantly) m_mainWidget */ 
 925     int minWidth 
= GetMinWidth(), 
 926         minHeight 
= GetMinHeight(), 
 927         maxWidth 
= GetMaxWidth(), 
 928         maxHeight 
= GetMaxHeight(); 
 931     // GPE's window manager doesn't like size hints 
 932     // at all, esp. when the user has to use the 
 940     if ((minWidth 
!= -1) && (m_width 
< minWidth
)) m_width 
= minWidth
; 
 941     if ((minHeight 
!= -1) && (m_height 
< minHeight
)) m_height 
= minHeight
; 
 942     if ((maxWidth 
!= -1) && (m_width 
> maxWidth
)) m_width 
= maxWidth
; 
 943     if ((maxHeight 
!= -1) && (m_height 
> maxHeight
)) m_height 
= maxHeight
; 
 948         gint            flag 
= 0; // GDK_HINT_POS; 
 951         if ((minWidth 
!= -1) || (minHeight 
!= -1)) flag 
|= GDK_HINT_MIN_SIZE
; 
 952         if ((maxWidth 
!= -1) || (maxHeight 
!= -1)) flag 
|= GDK_HINT_MAX_SIZE
; 
 954         geom
.min_width 
= minWidth
; 
 955         geom
.min_height 
= minHeight
; 
 957             // Because of the way we set GDK_HINT_MAX_SIZE above, if either of 
 958             // maxHeight or maxWidth is set, we must set them both, else the 
 959             // remaining -1 will be taken literally. 
 961             // I'm certain this also happens elsewhere, and is the probable 
 962             // cause of other such things as: 
 963             // Gtk-WARNING **: gtk_widget_size_allocate(): 
 964             //       attempt to allocate widget with width 65535 and height 600 
 965             // but I don't have time to track them all now.. 
 967             // Really we need to encapulate all this height/width business and 
 968             // stop any old method from ripping at the members directly and 
 969             // scattering -1's without regard for who might resolve them later. 
 971         geom
.max_width 
= ( maxHeight 
== -1 ) ? maxWidth
 
 972                          : ( maxWidth 
== -1 ) ? wxGetDisplaySize().GetWidth() 
 975         geom
.max_height 
= ( maxWidth 
== -1 ) ? maxHeight    
// ( == -1 here ) 
 976                           : ( maxHeight 
== -1 ) ? wxGetDisplaySize().GetHeight() 
 979         gtk_window_set_geometry_hints( GTK_WINDOW(m_widget
), 
 982                                        (GdkWindowHints
) flag 
); 
 984         /* I revert back to wxGTK's original behaviour. m_mainWidget holds the 
 985          * menubar, the toolbar and the client area, which is represented by 
 987          * this hurts in the eye, but I don't want to call SetSize() 
 988          * because I don't want to call any non-native functions here. */ 
 990         int client_x 
= m_miniEdge
; 
 991         int client_y 
= m_miniEdge 
+ m_miniTitle
; 
 992         int client_w 
= m_width 
- 2*m_miniEdge
; 
 993         int client_h 
= m_height 
- 2*m_miniEdge 
- m_miniTitle
; 
 995         gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
), 
 997                               client_x
, client_y
, client_w
, client_h 
); 
1001         // If there is no m_mainWidget between m_widget and m_wxwindow there 
1002         // is no need to set the size or position of m_wxwindow. 
1007     // send size event to frame 
1008     wxSizeEvent 
event( wxSize(m_width
,m_height
), GetId() ); 
1009     event
.SetEventObject( this ); 
1010     GetEventHandler()->ProcessEvent( event 
); 
1015 void wxTopLevelWindowGTK::OnInternalIdle() 
1017     if (!m_sizeSet 
&& GTK_WIDGET_REALIZED(m_wxwindow
)) 
1019         GtkOnSize( m_x
, m_y
, m_width
, m_height 
); 
1021         // we'll come back later 
1023             wxapp_install_idle_handler(); 
1027     // set the focus if not done yet and if we can already do it 
1028     if ( GTK_WIDGET_REALIZED(m_wxwindow
) ) 
1030         if ( g_delayedFocus 
&& 
1031              wxGetTopLevelParent((wxWindow
*)g_delayedFocus
) == this ) 
1033             wxLogTrace(_T("focus"), 
1034                        _T("Setting focus from wxTLW::OnIdle() to %s(%s)"), 
1035                        g_delayedFocus
->GetClassInfo()->GetClassName(), 
1036                        g_delayedFocus
->GetLabel().c_str()); 
1038             g_delayedFocus
->SetFocus(); 
1039             g_delayedFocus 
= NULL
; 
1043     wxWindow::OnInternalIdle(); 
1045     // Synthetize activate events. 
1046     if ( g_sendActivateEvent 
!= -1 ) 
1048         bool activate 
= g_sendActivateEvent 
!= 0; 
1050         // if (!activate) wxPrintf( wxT("de") ); 
1051         // wxPrintf( wxT("activate\n") ); 
1054         g_sendActivateEvent 
= -1; 
1056         wxTheApp
->SetActive(activate
, (wxWindow 
*)g_lastActiveFrame
); 
1060 // ---------------------------------------------------------------------------- 
1062 // ---------------------------------------------------------------------------- 
1064 void wxTopLevelWindowGTK::SetTitle( const wxString 
&title 
) 
1066     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
1069     gtk_window_set_title( GTK_WINDOW(m_widget
), wxGTK_CONV( title 
) ); 
1072 void wxTopLevelWindowGTK::SetIcon( const wxIcon 
&icon 
) 
1074     SetIcons( wxIconBundle( icon 
) ); 
1077 void wxTopLevelWindowGTK::SetIcons( const wxIconBundle 
&icons 
) 
1079     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
1081     wxTopLevelWindowBase::SetIcons( icons 
); 
1085     size_t max 
= icons
.m_icons
.GetCount(); 
1087     for (size_t i 
= 0; i 
< max
; i
++) 
1089         if (icons
.m_icons
[i
].Ok()) 
1091             list 
= g_list_prepend(list
, icons
.m_icons
[i
].GetPixbuf()); 
1094     gtk_window_set_icon_list(GTK_WINDOW(m_widget
), list
); 
1097 #else // !__WXGTK20__ 
1098     GdkWindow
* window 
= m_widget
->window
; 
1102     wxIcon icon 
= icons
.GetIcon(-1); 
1105         wxMask 
*mask 
= icon
.GetMask(); 
1106         GdkBitmap 
*bm 
= (GdkBitmap 
*) NULL
; 
1107         if (mask
) bm 
= mask
->GetBitmap(); 
1109         gdk_window_set_icon( m_widget
->window
, (GdkWindow 
*) NULL
, icon
.GetPixmap(), bm 
); 
1112     wxSetIconsX11( (WXDisplay
*)GDK_WINDOW_XDISPLAY( window 
), 
1113                    (WXWindow
)GDK_WINDOW_XWINDOW( window 
), icons 
); 
1114 #endif // !__WXGTK20__ 
1117 // ---------------------------------------------------------------------------- 
1118 // frame state: maximized/iconized/normal 
1119 // ---------------------------------------------------------------------------- 
1121 void wxTopLevelWindowGTK::Maximize(bool maximize
) 
1125         gtk_window_maximize( GTK_WINDOW( m_widget 
) ); 
1127         gtk_window_unmaximize( GTK_WINDOW( m_widget 
) ); 
1129     wxFAIL_MSG( _T("not implemented") ); 
1133 bool wxTopLevelWindowGTK::IsMaximized() const 
1136     if(!m_widget
->window
) 
1139     return gdk_window_get_state(m_widget
->window
) & GDK_WINDOW_STATE_MAXIMIZED
; 
1141   //    wxFAIL_MSG( _T("not implemented") ); 
1143     // This is an approximation 
1148 void wxTopLevelWindowGTK::Restore() 
1151     // "Present" seems similar enough to "restore" 
1152     gtk_window_present( GTK_WINDOW( m_widget 
) ); 
1154     wxFAIL_MSG( _T("not implemented") ); 
1158 void wxTopLevelWindowGTK::Iconize( bool iconize 
) 
1162         gtk_window_iconify( GTK_WINDOW( m_widget 
) ); 
1164         gtk_window_deiconify( GTK_WINDOW( m_widget 
) ); 
1168        GdkWindow 
*window 
= m_widget
->window
; 
1170        // you should do it later, for example from OnCreate() handler 
1171        wxCHECK_RET( window
, _T("frame not created yet - can't iconize") ); 
1173        XIconifyWindow( GDK_WINDOW_XDISPLAY( window 
), 
1174                        GDK_WINDOW_XWINDOW( window 
), 
1175                        DefaultScreen( GDK_DISPLAY() ) ); 
1180 bool wxTopLevelWindowGTK::IsIconized() const 
1182     return m_isIconized
; 
1185 void wxTopLevelWindowGTK::SetIconizeState(bool iconize
) 
1187     if ( iconize 
!= m_isIconized 
) 
1189         m_isIconized 
= iconize
; 
1190         (void)SendIconizeEvent(iconize
); 
1194 void wxTopLevelWindowGTK::AddGrab() 
1199         gtk_grab_add( m_widget 
); 
1201         gtk_grab_remove( m_widget 
); 
1205 void wxTopLevelWindowGTK::RemoveGrab() 
1216 static bool do_shape_combine_region(GdkWindow
* window
, const wxRegion
& region
) 
1220         if (region
.IsEmpty()) 
1222             gdk_window_shape_combine_mask(window
, NULL
, 0, 0); 
1227         gdk_window_shape_combine_region(window
, region
.GetRegion(), 0, 0); 
1229         wxBitmap bmp 
= region
.ConvertToBitmap(); 
1230         bmp
.SetMask(new wxMask(bmp
, *wxBLACK
)); 
1231         GdkBitmap
* mask 
= bmp
.GetMask()->GetBitmap(); 
1232         gdk_window_shape_combine_mask(window
, mask
, 0, 0); 
1241 bool wxTopLevelWindowGTK::SetShape(const wxRegion
& region
) 
1243     wxCHECK_MSG( HasFlag(wxFRAME_SHAPED
), FALSE
, 
1244                  _T("Shaped windows must be created with the wxFRAME_SHAPED style.")); 
1246     GdkWindow 
*window 
= NULL
; 
1249         window 
= GTK_PIZZA(m_wxwindow
)->bin_window
; 
1250         do_shape_combine_region(window
, region
); 
1252     window 
= m_widget
->window
; 
1253     return do_shape_combine_region(window
, region
); 
1256 bool wxTopLevelWindowGTK::IsActive() 
1258     return (this == (wxTopLevelWindowGTK
*)g_activeFrame
);