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 //----------------------------------------------------------------------------- 
  85 static gint 
gtk_frame_focus_in_callback( GtkWidget 
*widget
, 
  86                                          GdkEvent 
*WXUNUSED(event
), 
  87                                          wxTopLevelWindowGTK 
*win 
) 
  90         wxapp_install_idle_handler(); 
  92     switch ( g_sendActivateEvent 
) 
  95             // we've got focus from outside, synthetize wxActivateEvent 
  96             g_sendActivateEvent 
= 1; 
 100             // another our window just lost focus, it was already ours before 
 101             // - don't send any wxActivateEvent 
 102             g_sendActivateEvent 
= -1; 
 107     g_lastActiveFrame 
= g_activeFrame
; 
 109     // wxPrintf( wxT("active: %s\n"), win->GetTitle().c_str() ); 
 111     wxLogTrace(wxT("activate"), wxT("Activating frame %p (from focus_in)"), g_activeFrame
); 
 112     wxActivateEvent 
event(wxEVT_ACTIVATE
, TRUE
, g_activeFrame
->GetId()); 
 113     event
.SetEventObject(g_activeFrame
); 
 114     g_activeFrame
->GetEventHandler()->ProcessEvent(event
); 
 119 //----------------------------------------------------------------------------- 
 121 //----------------------------------------------------------------------------- 
 123 static gint 
gtk_frame_focus_out_callback( GtkWidget 
*widget
,  
 124                                           GdkEventFocus 
*WXUNUSED(gdk_event
),  
 125                                           wxTopLevelWindowGTK 
*win 
) 
 128         wxapp_install_idle_handler(); 
 130     // if the focus goes out of our app alltogether, OnIdle() will send 
 131     // wxActivateEvent, otherwise gtk_window_focus_in_callback() will reset 
 132     // g_sendActivateEvent to -1 
 133     g_sendActivateEvent 
= 0; 
 135     // wxASSERT_MSG( (g_activeFrame == win), wxT("TLW deactivatd although it wasn't active") ); 
 137     // wxPrintf( wxT("inactive: %s\n"), win->GetTitle().c_str() ); 
 141         wxLogTrace(wxT("activate"), wxT("Activating frame %p (from focus_in)"), g_activeFrame
); 
 142         wxActivateEvent 
event(wxEVT_ACTIVATE
, FALSE
, g_activeFrame
->GetId()); 
 143         event
.SetEventObject(g_activeFrame
); 
 144         g_activeFrame
->GetEventHandler()->ProcessEvent(event
); 
 146         g_activeFrame 
= NULL
; 
 152 //----------------------------------------------------------------------------- 
 153 // "focus" from m_window 
 154 //----------------------------------------------------------------------------- 
 156 static gint 
gtk_frame_focus_callback( GtkWidget 
*widget
, GtkDirectionType 
WXUNUSED(d
), wxWindow 
*WXUNUSED(win
) ) 
 159         wxapp_install_idle_handler(); 
 161     // This disables GTK's tab traversal 
 162     gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus" ); 
 166 //----------------------------------------------------------------------------- 
 168 //----------------------------------------------------------------------------- 
 170 static void gtk_frame_size_callback( GtkWidget 
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxTopLevelWindowGTK 
*win 
) 
 173         wxapp_install_idle_handler(); 
 178     if ((win
->m_width 
!= alloc
->width
) || (win
->m_height 
!= alloc
->height
)) 
 181         wxPrintf( "OnSize from " ); 
 182         if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 183            wxPrintf( win->GetClassInfo()->GetClassName() ); 
 184         wxPrintf( " %d %d %d %d\n", (int)alloc->x, 
 187                                 (int)alloc->height ); 
 190         win
->m_width 
= alloc
->width
; 
 191         win
->m_height 
= alloc
->height
; 
 192         win
->GtkUpdateSize(); 
 196 //----------------------------------------------------------------------------- 
 198 //----------------------------------------------------------------------------- 
 200 static gint 
gtk_frame_delete_callback( GtkWidget 
*WXUNUSED(widget
), GdkEvent 
*WXUNUSED(event
), wxTopLevelWindowGTK 
*win 
) 
 203         wxapp_install_idle_handler(); 
 205     if (win
->IsEnabled() && 
 206         (g_openDialogs 
== 0 || (win
->GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
) || 
 214 //----------------------------------------------------------------------------- 
 216 //----------------------------------------------------------------------------- 
 219 gtk_frame_configure_callback( GtkWidget 
*WXUNUSED(widget
), GdkEventConfigure 
*WXUNUSED(event
), wxTopLevelWindowGTK 
*win 
) 
 222         wxapp_install_idle_handler(); 
 224     if (!win
->m_hasVMT 
|| !win
->IsShown()) 
 230     gdk_window_get_root_origin( win
->m_widget
->window
, &x
, &y 
); 
 234     wxMoveEvent 
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() ); 
 235     mevent
.SetEventObject( win 
); 
 236     win
->GetEventHandler()->ProcessEvent( mevent 
); 
 241 //----------------------------------------------------------------------------- 
 242 // "realize" from m_widget 
 243 //----------------------------------------------------------------------------- 
 245 // we cannot MWM hints and icons before the widget has been realized, 
 246 // so we do this directly after realization 
 249 gtk_frame_realized_callback( GtkWidget 
* WXUNUSED(widget
), 
 250                              wxTopLevelWindowGTK 
*win 
) 
 253         wxapp_install_idle_handler(); 
 255     // All this is for Motif Window Manager "hints" and is supposed to be 
 256     // recognized by other WM as well. Not tested. 
 257     gdk_window_set_decorations(win
->m_widget
->window
, 
 258                                (GdkWMDecoration
)win
->m_gdkDecor
); 
 259     gdk_window_set_functions(win
->m_widget
->window
, 
 260                                (GdkWMFunction
)win
->m_gdkFunc
); 
 262     // GTK's shrinking/growing policy 
 263     if ((win
->m_gdkFunc 
& GDK_FUNC_RESIZE
) == 0) 
 264         gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1); 
 266         gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1); 
 269     wxIconBundle iconsOld 
= win
->GetIcons(); 
 270     if ( iconsOld
.GetIcon(-1).Ok() ) 
 272         win
->SetIcon( wxNullIcon 
); 
 273         win
->SetIcons( iconsOld 
); 
 277 //----------------------------------------------------------------------------- 
 278 // "map_event" from m_widget 
 279 //----------------------------------------------------------------------------- 
 282 gtk_frame_map_callback( GtkWidget 
* WXUNUSED(widget
), 
 283                         GdkEvent 
* WXUNUSED(event
), 
 284                         wxTopLevelWindow 
*win 
) 
 286     win
->SetIconizeState(FALSE
); 
 289 //----------------------------------------------------------------------------- 
 290 // "unmap_event" from m_widget 
 291 //----------------------------------------------------------------------------- 
 294 gtk_frame_unmap_callback( GtkWidget 
* WXUNUSED(widget
), 
 295                           GdkEvent 
* WXUNUSED(event
), 
 296                           wxTopLevelWindow 
*win 
) 
 298     win
->SetIconizeState(TRUE
); 
 301 //----------------------------------------------------------------------------- 
 302 // "expose_event" of m_client 
 303 //----------------------------------------------------------------------------- 
 305 static int gtk_window_expose_callback( GtkWidget 
*widget
, GdkEventExpose 
*gdk_event
, wxWindow 
*win 
) 
 307     GtkPizza 
*pizza 
= GTK_PIZZA(widget
); 
 309     gtk_paint_flat_box (win
->m_widget
->style
, 
 310                         pizza
->bin_window
, GTK_STATE_NORMAL
, 
 320 //----------------------------------------------------------------------------- 
 321 // "draw" of m_client 
 322 //----------------------------------------------------------------------------- 
 326 static void gtk_window_draw_callback( GtkWidget 
*widget
, GdkRectangle 
*rect
, wxWindow 
*win 
) 
 328     GtkPizza 
*pizza 
= GTK_PIZZA(widget
); 
 330     gtk_paint_flat_box (win
->m_widget
->style
, 
 331                         pizza
->bin_window
, GTK_STATE_NORMAL
, 
 341 // ---------------------------------------------------------------------------- 
 342 // wxTopLevelWindowGTK itself 
 343 // ---------------------------------------------------------------------------- 
 345 //----------------------------------------------------------------------------- 
 346 // InsertChild for wxTopLevelWindowGTK 
 347 //----------------------------------------------------------------------------- 
 349 /* Callback for wxTopLevelWindowGTK. This very strange beast has to be used because 
 350  * C++ has no virtual methods in a constructor. We have to emulate a 
 351  * virtual function here as wxWidgets requires different ways to insert 
 352  * a child in container classes. */ 
 354 static void wxInsertChildInTopLevelWindow( wxTopLevelWindowGTK
* parent
, wxWindow
* child 
) 
 356     wxASSERT( GTK_IS_WIDGET(child
->m_widget
) ); 
 358     if (!parent
->m_insertInClientArea
) 
 360         // these are outside the client area 
 361         wxTopLevelWindowGTK
* frame 
= (wxTopLevelWindowGTK
*) parent
; 
 362         gtk_pizza_put( GTK_PIZZA(frame
->m_mainWidget
), 
 363                          GTK_WIDGET(child
->m_widget
), 
 371         // these are inside the client area 
 372         gtk_pizza_put( GTK_PIZZA(parent
->m_wxwindow
), 
 373                          GTK_WIDGET(child
->m_widget
), 
 380     // resize on OnInternalIdle 
 381     parent
->GtkUpdateSize(); 
 384 // ---------------------------------------------------------------------------- 
 385 // wxTopLevelWindowGTK creation 
 386 // ---------------------------------------------------------------------------- 
 388 void wxTopLevelWindowGTK::Init() 
 393     m_mainWidget 
= (GtkWidget
*) NULL
; 
 394     m_insertInClientArea 
= TRUE
; 
 395     m_isIconized 
= FALSE
; 
 396     m_fsIsShowing 
= FALSE
; 
 397     m_themeEnabled 
= TRUE
; 
 398     m_gdkDecor 
= m_gdkFunc 
= 0; 
 402 bool wxTopLevelWindowGTK::Create( wxWindow 
*parent
, 
 404                                   const wxString
& title
, 
 406                                   const wxSize
& sizeOrig
, 
 408                                   const wxString 
&name 
) 
 410     // always create a frame of some reasonable, even if arbitrary, size (at 
 411     // least for MSW compatibility) 
 412     wxSize size 
= sizeOrig
; 
 413     size
.x 
= WidthDefault(size
.x
); 
 414     size
.y 
= HeightDefault(size
.y
); 
 416     wxTopLevelWindows
.Append( this ); 
 418     m_needParent 
= FALSE
; 
 420     if (!PreCreation( parent
, pos
, size 
) || 
 421         !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name 
)) 
 423         wxFAIL_MSG( wxT("wxTopLevelWindowGTK creation failed") ); 
 429     m_insertCallback 
= (wxInsertChildFunction
) wxInsertChildInTopLevelWindow
; 
 431     // NB: m_widget may be !=NULL if it was created by derived class' Create, 
 432     //     e.g. in wxTaskBarIconAreaGTK 
 433     if (m_widget 
== NULL
) 
 435         if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
) 
 438             m_widget 
= gtk_window_new(GTK_WINDOW_TOPLEVEL
); 
 439             // Tell WM that this is a dialog window and make it center 
 440             // on parent by default (this is what GtkDialog ctor does): 
 441             gtk_window_set_type_hint(GTK_WINDOW(m_widget
), 
 442                                      GDK_WINDOW_TYPE_HINT_DIALOG
); 
 443             gtk_window_set_position(GTK_WINDOW(m_widget
), 
 444                                     GTK_WIN_POS_CENTER_ON_PARENT
); 
 446             m_widget 
= gtk_window_new(GTK_WINDOW_DIALOG
); 
 451             m_widget 
= gtk_window_new(GTK_WINDOW_TOPLEVEL
); 
 452 #if GTK_CHECK_VERSION(2,1,0) 
 453             if (style 
& wxFRAME_TOOL_WINDOW
) 
 455                 gtk_window_set_type_hint(GTK_WINDOW(m_widget
), 
 456                                          GDK_WINDOW_TYPE_HINT_UTILITY
); 
 458                 // On some WMs, like KDE, a TOOL_WINDOW will still show 
 459                 // on the taskbar, but on Gnome a TOOL_WINDOW will not. 
 460                 // For consistency between WMs and with Windows, we  
 461                 // should set the NO_TASKBAR flag which will apply 
 462                 // the set_skip_taskbar_hint if it is available, 
 463                 // ensuring no taskbar entry will appear. 
 464                 style 
|= wxFRAME_NO_TASKBAR
; 
 471     wxWindow 
*topParent 
= wxGetTopLevelParent(m_parent
); 
 472     if (topParent 
&& (((GTK_IS_WINDOW(topParent
->m_widget
)) && 
 473                       (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
)) || 
 474                      (style 
& wxFRAME_FLOAT_ON_PARENT
))) 
 476         gtk_window_set_transient_for( GTK_WINDOW(m_widget
), 
 477                                       GTK_WINDOW(topParent
->m_widget
) ); 
 480 #if GTK_CHECK_VERSION(2,2,0) 
 481     if (style 
& wxFRAME_NO_TASKBAR
) 
 483         gtk_window_set_skip_taskbar_hint(GTK_WINDOW(m_widget
), TRUE
); 
 488         gtk_window_set_wmclass( GTK_WINDOW(m_widget
), wxGTK_CONV( name 
), wxGTK_CONV( name 
) ); 
 490     gtk_window_set_title( GTK_WINDOW(m_widget
), wxGTK_CONV( title 
) ); 
 491     GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS 
); 
 493     gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event", 
 494         GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this ); 
 496     // m_mainWidget holds the toolbar, the menubar and the client area 
 497     m_mainWidget 
= gtk_pizza_new(); 
 498     gtk_widget_show( m_mainWidget 
); 
 499     GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS 
); 
 500     gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget 
); 
 502     if (m_miniEdge 
== 0) // wxMiniFrame has its own version. 
 504        // For m_mainWidget themes 
 505        gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "expose_event", 
 506                 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this ); 
 508        gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "draw", 
 509                 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this ); 
 513     // m_wxwindow only represents the client area without toolbar and menubar 
 514     m_wxwindow 
= gtk_pizza_new(); 
 515     gtk_widget_show( m_wxwindow 
); 
 516     gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow 
); 
 518     // we donm't allow the frame to get the focus as otherwise 
 519     // the frame will grab it at arbitrary focus changes 
 520     GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS 
); 
 522     if (m_parent
) m_parent
->AddChild( this ); 
 524     // the user resized the frame by dragging etc. 
 525     gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate", 
 526         GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this ); 
 530     if ((m_x 
!= -1) || (m_y 
!= -1)) 
 531         gtk_widget_set_uposition( m_widget
, m_x
, m_y 
); 
 533     gtk_window_set_default_size( GTK_WINDOW(m_widget
), m_width
, m_height 
); 
 535     //  we cannot set MWM hints and icons before the widget has 
 536     //  been realized, so we do this directly after realization 
 537     gtk_signal_connect( GTK_OBJECT(m_widget
), "realize", 
 538                         GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this ); 
 540     // the only way to get the window size is to connect to this event 
 541     gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event", 
 542         GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this ); 
 544     // map and unmap for iconized state 
 545     gtk_signal_connect( GTK_OBJECT(m_widget
), "map_event", 
 546         GTK_SIGNAL_FUNC(gtk_frame_map_callback
), (gpointer
)this ); 
 547     gtk_signal_connect( GTK_OBJECT(m_widget
), "unmap_event", 
 548         GTK_SIGNAL_FUNC(gtk_frame_unmap_callback
), (gpointer
)this ); 
 550     // the only way to get the window size is to connect to this event 
 551     gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event", 
 552         GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this ); 
 554     // disable native tab traversal 
 555     gtk_signal_connect( GTK_OBJECT(m_widget
), "focus", 
 556         GTK_SIGNAL_FUNC(gtk_frame_focus_callback
), (gpointer
)this ); 
 559     gtk_signal_connect( GTK_OBJECT(m_widget
), "focus_in_event", 
 560         GTK_SIGNAL_FUNC(gtk_frame_focus_in_callback
), (gpointer
)this ); 
 561     gtk_signal_connect( GTK_OBJECT(m_widget
), "focus_out_event", 
 562         GTK_SIGNAL_FUNC(gtk_frame_focus_out_callback
), (gpointer
)this ); 
 565     if ((m_miniEdge 
> 0) || (style 
& wxSIMPLE_BORDER
) || (style 
& wxNO_BORDER
)) 
 572         m_gdkDecor 
= (long) GDK_DECOR_BORDER
; 
 573         m_gdkFunc 
= (long) GDK_FUNC_MOVE
; 
 575         // All this is for Motif Window Manager "hints" and is supposed to be 
 576         // recognized by other WMs as well. 
 577         if ((style 
& wxCAPTION
) != 0) 
 579             m_gdkDecor 
|= GDK_DECOR_TITLE
; 
 581         if ((style 
& wxCLOSE_BOX
) != 0) 
 583             m_gdkFunc 
|= GDK_FUNC_CLOSE
; 
 585         if ((style 
& wxSYSTEM_MENU
) != 0) 
 587             m_gdkDecor 
|= GDK_DECOR_MENU
; 
 589         if ((style 
& wxMINIMIZE_BOX
) != 0) 
 591             m_gdkFunc 
|= GDK_FUNC_MINIMIZE
; 
 592             m_gdkDecor 
|= GDK_DECOR_MINIMIZE
; 
 594         if ((style 
& wxMAXIMIZE_BOX
) != 0) 
 596             m_gdkFunc 
|= GDK_FUNC_MAXIMIZE
; 
 597             m_gdkDecor 
|= GDK_DECOR_MAXIMIZE
; 
 599         if ((style 
& wxRESIZE_BORDER
) != 0) 
 601            m_gdkFunc 
|= GDK_FUNC_RESIZE
; 
 602            m_gdkDecor 
|= GDK_DECOR_RESIZEH
; 
 609 wxTopLevelWindowGTK::~wxTopLevelWindowGTK() 
 613         wxASSERT_MSG( FALSE
, _T("Window still grabbed")); 
 617     m_isBeingDeleted 
= TRUE
; 
 619     // it may also be GtkScrolledWindow in the case of an MDI child 
 620     if (GTK_IS_WINDOW(m_widget
)) 
 622         gtk_window_set_focus( GTK_WINDOW(m_widget
), NULL 
); 
 625     if (g_activeFrame 
== this) 
 626         g_activeFrame 
= NULL
; 
 627     if (g_lastActiveFrame 
== this) 
 628         g_lastActiveFrame 
= NULL
; 
 633 bool wxTopLevelWindowGTK::ShowFullScreen(bool show
, long style 
) 
 635     if (show 
== m_fsIsShowing
) 
 636         return FALSE
; // return what? 
 638     m_fsIsShowing 
= show
; 
 640     wxX11FullScreenMethod method 
= 
 641         wxGetFullScreenMethodX11((WXDisplay
*)GDK_DISPLAY(), 
 642                                  (WXWindow
)GDK_ROOT_WINDOW()); 
 644 #if GTK_CHECK_VERSION(2,2,0) 
 645     // NB: gtk_window_fullscreen() uses freedesktop.org's WMspec extensions 
 646     //     to switch to fullscreen, which is not always available. We must 
 647     //     check if WM supports the spec and use legacy methods if it 
 649     if (method 
== wxX11_FS_WMSPEC
) 
 652             gtk_window_fullscreen( GTK_WINDOW( m_widget 
) ); 
 654             gtk_window_unfullscreen( GTK_WINDOW( m_widget 
) ); 
 659 #endif // GTK+ >= 2.2.0 
 661         GdkWindow 
*window 
= m_widget
->window
; 
 665             m_fsSaveFlag 
= style
; 
 666             GetPosition( &m_fsSaveFrame
.x
, &m_fsSaveFrame
.y 
); 
 667             GetSize( &m_fsSaveFrame
.width
, &m_fsSaveFrame
.height 
); 
 669             int screen_width
,screen_height
; 
 670             wxDisplaySize( &screen_width
, &screen_height 
); 
 672             gint client_x
, client_y
, root_x
, root_y
; 
 675             if (method 
!= wxX11_FS_WMSPEC
) 
 677                 // don't do it always, Metacity hates it 
 678                 m_fsSaveGdkFunc 
= m_gdkFunc
; 
 679                 m_fsSaveGdkDecor 
= m_gdkDecor
; 
 680                 m_gdkFunc 
= m_gdkDecor 
= 0; 
 681                 gdk_window_set_decorations(window
, (GdkWMDecoration
)0); 
 682                 gdk_window_set_functions(window
, (GdkWMFunction
)0); 
 685             gdk_window_get_origin (m_widget
->window
, &root_x
, &root_y
); 
 686             gdk_window_get_geometry (m_widget
->window
, &client_x
, &client_y
, 
 687                          &width
, &height
, NULL
); 
 689             gdk_window_move_resize (m_widget
->window
, -client_x
, -client_y
, 
 690                         screen_width 
+ 1, screen_height 
+ 1); 
 692             wxSetFullScreenStateX11((WXDisplay
*)GDK_DISPLAY(), 
 693                                     (WXWindow
)GDK_ROOT_WINDOW(), 
 694                                     (WXWindow
)GDK_WINDOW_XWINDOW(window
), 
 695                                     show
, &m_fsSaveFrame
, method
); 
 699             if (method 
!= wxX11_FS_WMSPEC
) 
 701                 // don't do it always, Metacity hates it 
 702                 m_gdkFunc 
= m_fsSaveGdkFunc
; 
 703                 m_gdkDecor 
= m_fsSaveGdkDecor
; 
 704                 gdk_window_set_decorations(window
, (GdkWMDecoration
)m_gdkDecor
); 
 705                 gdk_window_set_functions(window
, (GdkWMFunction
)m_gdkFunc
); 
 708             wxSetFullScreenStateX11((WXDisplay
*)GDK_DISPLAY(), 
 709                                     (WXWindow
)GDK_ROOT_WINDOW(), 
 710                                     (WXWindow
)GDK_WINDOW_XWINDOW(window
), 
 711                                     show
, &m_fsSaveFrame
, method
); 
 713             SetSize(m_fsSaveFrame
.x
, m_fsSaveFrame
.y
, 
 714                     m_fsSaveFrame
.width
, m_fsSaveFrame
.height
); 
 721 // ---------------------------------------------------------------------------- 
 722 // overridden wxWindow methods 
 723 // ---------------------------------------------------------------------------- 
 725 bool wxTopLevelWindowGTK::Show( bool show 
) 
 727     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 729     if (show 
&& !m_sizeSet
) 
 731         /* by calling GtkOnSize here, we don't have to call 
 732            either after showing the frame, which would entail 
 733            much ugly flicker or from within the size_allocate 
 734            handler, because GTK 1.1.X forbids that. */ 
 736         GtkOnSize( m_x
, m_y
, m_width
, m_height 
); 
 740         gtk_widget_set_uposition( m_widget
, m_x
, m_y 
); 
 742     return wxWindow::Show( show 
); 
 745 void wxTopLevelWindowGTK::Raise() 
 748     gtk_window_present( GTK_WINDOW( m_widget 
) ); 
 754 void wxTopLevelWindowGTK::DoMoveWindow(int WXUNUSED(x
), int WXUNUSED(y
), int WXUNUSED(width
), int WXUNUSED(height
) ) 
 756     wxFAIL_MSG( wxT("DoMoveWindow called for wxTopLevelWindowGTK") ); 
 759 void wxTopLevelWindowGTK::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags 
) 
 761     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 763     // this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow 
 764     wxASSERT_MSG( (m_wxwindow 
!= NULL
), wxT("invalid frame") ); 
 774     int old_width 
= m_width
; 
 775     int old_height 
= m_height
; 
 777     if ((sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
) == 0) 
 779         if (x 
!= -1) m_x 
= x
; 
 780         if (y 
!= -1) m_y 
= y
; 
 787     if (width 
!= -1) m_width 
= width
; 
 788     if (height 
!= -1) m_height 
= height
; 
 791     if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH) 
 793         if (width == -1) m_width = 80; 
 796     if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT) 
 798        if (height == -1) m_height = 26; 
 802     int minWidth 
= GetMinWidth(), 
 803         minHeight 
= GetMinHeight(), 
 804         maxWidth 
= GetMaxWidth(), 
 805         maxHeight 
= GetMaxHeight(); 
 808     // GPE's window manager doesn't like size hints 
 809     // at all, esp. when the user has to use the 
 817     if ((minWidth 
!= -1) && (m_width 
< minWidth
)) m_width 
= minWidth
; 
 818     if ((minHeight 
!= -1) && (m_height 
< minHeight
)) m_height 
= minHeight
; 
 819     if ((maxWidth 
!= -1) && (m_width 
> maxWidth
)) m_width 
= maxWidth
; 
 820     if ((maxHeight 
!= -1) && (m_height 
> maxHeight
)) m_height 
= maxHeight
; 
 822     if ((m_x 
!= -1) || (m_y 
!= -1)) 
 824         if ((m_x 
!= old_x
) || (m_y 
!= old_y
)) 
 826             gtk_widget_set_uposition( m_widget
, m_x
, m_y 
); 
 830     if ((m_width 
!= old_width
) || (m_height 
!= old_height
)) 
 832         if (m_widget
->window
) 
 833             gdk_window_resize( m_widget
->window
, m_width
, m_height 
); 
 835             gtk_window_set_default_size( GTK_WINDOW(m_widget
), m_width
, m_height 
); 
 837         /* we set the size in GtkOnSize, i.e. mostly the actual resizing is 
 838            done either directly before the frame is shown or in idle time 
 839            so that different calls to SetSize() don't lead to flicker. */ 
 846 void wxTopLevelWindowGTK::DoGetClientSize( int *width
, int *height 
) const 
 848     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 850     wxWindow::DoGetClientSize( width
, height 
); 
 854         *height 
-= m_miniEdge
*2 + m_miniTitle
; 
 858         *width 
-= m_miniEdge
*2; 
 862 void wxTopLevelWindowGTK::DoSetClientSize( int width
, int height 
) 
 864     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 867               width 
+ m_miniEdge
*2, height  
+ m_miniEdge
*2 + m_miniTitle
, 0); 
 870 void wxTopLevelWindowGTK::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), 
 871                                      int width
, int height 
) 
 873     // due to a bug in gtk, x,y are always 0 
 878     if (m_resizing
) return; 
 881     if ( m_wxwindow 
== NULL 
) return; 
 886     /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses 
 887        wxWindow::Create to create it's GTK equivalent. m_mainWidget is only 
 888        set in wxFrame::Create so it is used to check what kind of frame we 
 889        have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we 
 890        skip the part which handles m_frameMenuBar, m_frameToolBar and (most 
 891        importantly) m_mainWidget */ 
 893     int minWidth 
= GetMinWidth(), 
 894         minHeight 
= GetMinHeight(), 
 895         maxWidth 
= GetMaxWidth(), 
 896         maxHeight 
= GetMaxHeight(); 
 899     // GPE's window manager doesn't like size hints 
 900     // at all, esp. when the user has to use the 
 908     if ((minWidth 
!= -1) && (m_width 
< minWidth
)) m_width 
= minWidth
; 
 909     if ((minHeight 
!= -1) && (m_height 
< minHeight
)) m_height 
= minHeight
; 
 910     if ((maxWidth 
!= -1) && (m_width 
> maxWidth
)) m_width 
= maxWidth
; 
 911     if ((maxHeight 
!= -1) && (m_height 
> maxHeight
)) m_height 
= maxHeight
; 
 916         gint            flag 
= 0; // GDK_HINT_POS; 
 919         if ((minWidth 
!= -1) || (minHeight 
!= -1)) flag 
|= GDK_HINT_MIN_SIZE
; 
 920         if ((maxWidth 
!= -1) || (maxHeight 
!= -1)) flag 
|= GDK_HINT_MAX_SIZE
; 
 922         geom
.min_width 
= minWidth
; 
 923         geom
.min_height 
= minHeight
; 
 925             // Because of the way we set GDK_HINT_MAX_SIZE above, if either of 
 926             // maxHeight or maxWidth is set, we must set them both, else the 
 927             // remaining -1 will be taken literally. 
 929             // I'm certain this also happens elsewhere, and is the probable 
 930             // cause of other such things as: 
 931             // Gtk-WARNING **: gtk_widget_size_allocate(): 
 932             //       attempt to allocate widget with width 65535 and height 600 
 933             // but I don't have time to track them all now.. 
 935             // Really we need to encapulate all this height/width business and 
 936             // stop any old method from ripping at the members directly and 
 937             // scattering -1's without regard for who might resolve them later. 
 939         geom
.max_width 
= ( maxHeight 
== -1 ) ? maxWidth
 
 940                          : ( maxWidth 
== -1 ) ? wxGetDisplaySize().GetWidth() 
 943         geom
.max_height 
= ( maxWidth 
== -1 ) ? maxHeight    
// ( == -1 here ) 
 944                           : ( maxHeight 
== -1 ) ? wxGetDisplaySize().GetHeight() 
 947         gtk_window_set_geometry_hints( GTK_WINDOW(m_widget
), 
 950                                        (GdkWindowHints
) flag 
); 
 952         /* I revert back to wxGTK's original behaviour. m_mainWidget holds the 
 953          * menubar, the toolbar and the client area, which is represented by 
 955          * this hurts in the eye, but I don't want to call SetSize() 
 956          * because I don't want to call any non-native functions here. */ 
 958         int client_x 
= m_miniEdge
; 
 959         int client_y 
= m_miniEdge 
+ m_miniTitle
; 
 960         int client_w 
= m_width 
- 2*m_miniEdge
; 
 961         int client_h 
= m_height 
- 2*m_miniEdge 
- m_miniTitle
; 
 963         gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
), 
 965                               client_x
, client_y
, client_w
, client_h 
); 
 969         // If there is no m_mainWidget between m_widget and m_wxwindow there 
 970         // is no need to set the size or position of m_wxwindow. 
 975     // send size event to frame 
 976     wxSizeEvent 
event( wxSize(m_width
,m_height
), GetId() ); 
 977     event
.SetEventObject( this ); 
 978     GetEventHandler()->ProcessEvent( event 
); 
 983 void wxTopLevelWindowGTK::OnInternalIdle() 
 985     if (!m_sizeSet 
&& GTK_WIDGET_REALIZED(m_wxwindow
)) 
 987         GtkOnSize( m_x
, m_y
, m_width
, m_height 
); 
 989         // we'll come back later 
 991             wxapp_install_idle_handler(); 
 995     // set the focus if not done yet and if we can already do it 
 996     if ( GTK_WIDGET_REALIZED(m_wxwindow
) ) 
 998         if ( g_delayedFocus 
&& 
 999              wxGetTopLevelParent((wxWindow
*)g_delayedFocus
) == this ) 
1001             wxLogTrace(_T("focus"), 
1002                        _T("Setting focus from wxTLW::OnIdle() to %s(%s)"), 
1003                        g_delayedFocus
->GetClassInfo()->GetClassName(), 
1004                        g_delayedFocus
->GetLabel().c_str()); 
1006             g_delayedFocus
->SetFocus(); 
1007             g_delayedFocus 
= NULL
; 
1011     wxWindow::OnInternalIdle(); 
1013     // Synthetize activate events. 
1014     if ( g_sendActivateEvent 
!= -1 ) 
1016         bool activate 
= g_sendActivateEvent 
!= 0; 
1018         // if (!activate) wxPrintf( wxT("de") ); 
1019         // wxPrintf( wxT("activate\n") ); 
1022         g_sendActivateEvent 
= -1; 
1024         wxTheApp
->SetActive(activate
, (wxWindow 
*)g_lastActiveFrame
); 
1028 // ---------------------------------------------------------------------------- 
1030 // ---------------------------------------------------------------------------- 
1032 void wxTopLevelWindowGTK::SetTitle( const wxString 
&title 
) 
1034     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
1037     gtk_window_set_title( GTK_WINDOW(m_widget
), wxGTK_CONV( title 
) ); 
1040 void wxTopLevelWindowGTK::SetIcon( const wxIcon 
&icon 
) 
1042     SetIcons( wxIconBundle( icon 
) ); 
1045 void wxTopLevelWindowGTK::SetIcons( const wxIconBundle 
&icons 
) 
1047     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
1049     wxTopLevelWindowBase::SetIcons( icons 
); 
1053     size_t max 
= icons
.m_icons
.GetCount(); 
1055     for (size_t i 
= 0; i 
< max
; i
++) 
1057         if (icons
.m_icons
[i
].Ok()) 
1059             list 
= g_list_prepend(list
, icons
.m_icons
[i
].GetPixbuf()); 
1062     gtk_window_set_icon_list(GTK_WINDOW(m_widget
), list
); 
1065 #else // !__WXGTK20__ 
1066     GdkWindow
* window 
= m_widget
->window
; 
1070     wxIcon icon 
= icons
.GetIcon(-1); 
1073         wxMask 
*mask 
= icon
.GetMask(); 
1074         GdkBitmap 
*bm 
= (GdkBitmap 
*) NULL
; 
1075         if (mask
) bm 
= mask
->GetBitmap(); 
1077         gdk_window_set_icon( m_widget
->window
, (GdkWindow 
*) NULL
, icon
.GetPixmap(), bm 
); 
1080     wxSetIconsX11( (WXDisplay
*)GDK_WINDOW_XDISPLAY( window 
), 
1081                    (WXWindow
)GDK_WINDOW_XWINDOW( window 
), icons 
); 
1082 #endif // !__WXGTK20__ 
1085 // ---------------------------------------------------------------------------- 
1086 // frame state: maximized/iconized/normal 
1087 // ---------------------------------------------------------------------------- 
1089 void wxTopLevelWindowGTK::Maximize(bool maximize
) 
1093         gtk_window_maximize( GTK_WINDOW( m_widget 
) ); 
1095         gtk_window_unmaximize( GTK_WINDOW( m_widget 
) ); 
1097     wxFAIL_MSG( _T("not implemented") ); 
1101 bool wxTopLevelWindowGTK::IsMaximized() const 
1104     if(!m_widget
->window
) 
1107     return gdk_window_get_state(m_widget
->window
) & GDK_WINDOW_STATE_MAXIMIZED
; 
1109   //    wxFAIL_MSG( _T("not implemented") ); 
1111     // This is an approximation 
1116 void wxTopLevelWindowGTK::Restore() 
1119     // "Present" seems similar enough to "restore" 
1120     gtk_window_present( GTK_WINDOW( m_widget 
) ); 
1122     wxFAIL_MSG( _T("not implemented") ); 
1126 void wxTopLevelWindowGTK::Iconize( bool iconize 
) 
1130         gtk_window_iconify( GTK_WINDOW( m_widget 
) ); 
1132         gtk_window_deiconify( GTK_WINDOW( m_widget 
) ); 
1136        GdkWindow 
*window 
= m_widget
->window
; 
1138        // you should do it later, for example from OnCreate() handler 
1139        wxCHECK_RET( window
, _T("frame not created yet - can't iconize") ); 
1141        XIconifyWindow( GDK_WINDOW_XDISPLAY( window 
), 
1142                        GDK_WINDOW_XWINDOW( window 
), 
1143                        DefaultScreen( GDK_DISPLAY() ) ); 
1148 bool wxTopLevelWindowGTK::IsIconized() const 
1150     return m_isIconized
; 
1153 void wxTopLevelWindowGTK::SetIconizeState(bool iconize
) 
1155     if ( iconize 
!= m_isIconized 
) 
1157         m_isIconized 
= iconize
; 
1158         (void)SendIconizeEvent(iconize
); 
1162 void wxTopLevelWindowGTK::AddGrab() 
1167         gtk_grab_add( m_widget 
); 
1169         gtk_grab_remove( m_widget 
); 
1173 void wxTopLevelWindowGTK::RemoveGrab() 
1184 static bool do_shape_combine_region(GdkWindow
* window
, const wxRegion
& region
) 
1188         if (region
.IsEmpty()) 
1190             gdk_window_shape_combine_mask(window
, NULL
, 0, 0); 
1195         gdk_window_shape_combine_region(window
, region
.GetRegion(), 0, 0); 
1197         wxBitmap bmp 
= region
.ConvertToBitmap(); 
1198         bmp
.SetMask(new wxMask(bmp
, *wxBLACK
)); 
1199         GdkBitmap
* mask 
= bmp
.GetMask()->GetBitmap(); 
1200         gdk_window_shape_combine_mask(window
, mask
, 0, 0); 
1209 bool wxTopLevelWindowGTK::SetShape(const wxRegion
& region
) 
1211     wxCHECK_MSG( HasFlag(wxFRAME_SHAPED
), FALSE
, 
1212                  _T("Shaped windows must be created with the wxFRAME_SHAPED style.")); 
1214     GdkWindow 
*window 
= NULL
; 
1217         window 
= GTK_PIZZA(m_wxwindow
)->bin_window
; 
1218         do_shape_combine_region(window
, region
); 
1220     window 
= m_widget
->window
; 
1221     return do_shape_combine_region(window
, region
); 
1224 bool wxTopLevelWindowGTK::IsActive() 
1226     return (this == (wxTopLevelWindowGTK
*)g_activeFrame
);