1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/gtk1/toplevel.cpp 
   4 // Author:      Robert Roebling 
   6 // Copyright:   (c) 1998 Robert Roebling 
   7 // Licence:     wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  10 // ============================================================================ 
  12 // ============================================================================ 
  14 // ---------------------------------------------------------------------------- 
  16 // ---------------------------------------------------------------------------- 
  18 // For compilers that support precompilation, includes "wx.h". 
  19 #include "wx/wxprec.h" 
  22 #define XIconifyWindow XICONIFYWINDOW 
  27 #include "wx/toplevel.h" 
  29 #include "wx/dialog.h" 
  30 #include "wx/control.h" 
  32 #include "wx/dcclient.h" 
  33 #include "wx/gtk1/private.h" 
  35 #include "wx/settings.h" 
  36 #include "wx/evtloop.h" 
  41 #include <gdk/gdkkeysyms.h> 
  44 #include "wx/gtk1/win_gtk.h" 
  46 #include "wx/unix/utilsx11.h" 
  49 #include <X11/Xatom.h> 
  51 // ---------------------------------------------------------------------------- 
  53 // ---------------------------------------------------------------------------- 
  55 extern void wxapp_install_idle_handler(); 
  58 // ---------------------------------------------------------------------------- 
  60 // ---------------------------------------------------------------------------- 
  62 extern wxList           wxPendingDelete
; 
  64 extern int              g_openDialogs
; 
  65 extern wxWindowGTK     
*g_delayedFocus
; 
  67 // the frame that is currently active (i.e. its child has focus). It is 
  68 // used to generate wxActivateEvents 
  69 static wxTopLevelWindowGTK 
*g_activeFrame 
= (wxTopLevelWindowGTK
*) NULL
; 
  70 static wxTopLevelWindowGTK 
*g_lastActiveFrame 
= (wxTopLevelWindowGTK
*) NULL
; 
  72 // if we detect that the app has got/lost the focus, we set this variable to 
  73 // either TRUE or FALSE and an activate event will be sent during the next 
  74 // OnIdle() call and it is reset to -1: this value means that we shouldn't 
  75 // send any activate events at all 
  76 static int g_sendActivateEvent 
= -1; 
  78 //----------------------------------------------------------------------------- 
  79 // RequestUserAttention related functions 
  80 //----------------------------------------------------------------------------- 
  83 static void wxgtk_window_set_urgency_hint (GtkWindow 
*win
, 
  86     wxASSERT_MSG( GTK_WIDGET_REALIZED(win
), wxT("wxgtk_window_set_urgency_hint: GdkWindow not realized") ); 
  87     GdkWindow 
*window 
= GTK_WIDGET(win
)->window
; 
  90     wm_hints 
= XGetWMHints(GDK_WINDOW_XDISPLAY(window
), GDK_WINDOW_XWINDOW(window
)); 
  93         wm_hints 
= XAllocWMHints(); 
  96         wm_hints
->flags 
|= XUrgencyHint
; 
  98         wm_hints
->flags 
&= ~XUrgencyHint
; 
 100     XSetWMHints(GDK_WINDOW_XDISPLAY(window
), GDK_WINDOW_XWINDOW(window
), wm_hints
); 
 104 static gint 
gtk_frame_urgency_timer_callback( wxTopLevelWindowGTK 
*win 
) 
 106     wxgtk_window_set_urgency_hint(GTK_WINDOW( win
->m_widget 
), FALSE
); 
 108     win
->m_urgency_hint 
= -2; 
 113 //----------------------------------------------------------------------------- 
 115 //----------------------------------------------------------------------------- 
 118 static gint 
gtk_frame_focus_in_callback( GtkWidget 
*widget
, 
 119                                          GdkEvent 
*WXUNUSED(event
), 
 120                                          wxTopLevelWindowGTK 
*win 
) 
 123         wxapp_install_idle_handler(); 
 125     switch ( g_sendActivateEvent 
) 
 128             // we've got focus from outside, synthetize wxActivateEvent 
 129             g_sendActivateEvent 
= 1; 
 133             // another our window just lost focus, it was already ours before 
 134             // - don't send any wxActivateEvent 
 135             g_sendActivateEvent 
= -1; 
 140     g_lastActiveFrame 
= g_activeFrame
; 
 142     // wxPrintf( wxT("active: %s\n"), win->GetTitle().c_str() ); 
 144     // MR: wxRequestUserAttention related block 
 145     switch( win
->m_urgency_hint 
) 
 148             gtk_timeout_remove( win
->m_urgency_hint 
); 
 149             // no break, fallthrough to remove hint too 
 151             wxgtk_window_set_urgency_hint(GTK_WINDOW( widget 
), FALSE
); 
 153             win
->m_urgency_hint 
= -2; 
 159     wxLogTrace(wxT("activate"), wxT("Activating frame %p (from focus_in)"), g_activeFrame
); 
 160     wxActivateEvent 
event(wxEVT_ACTIVATE
, true, g_activeFrame
->GetId()); 
 161     event
.SetEventObject(g_activeFrame
); 
 162     g_activeFrame
->GetEventHandler()->ProcessEvent(event
); 
 168 //----------------------------------------------------------------------------- 
 170 //----------------------------------------------------------------------------- 
 173 static gint 
gtk_frame_focus_out_callback( GtkWidget 
*widget
, 
 174                                           GdkEventFocus 
*WXUNUSED(gdk_event
), 
 175                                           wxTopLevelWindowGTK 
*win 
) 
 178         wxapp_install_idle_handler(); 
 180     // if the focus goes out of our app alltogether, OnIdle() will send 
 181     // wxActivateEvent, otherwise gtk_window_focus_in_callback() will reset 
 182     // g_sendActivateEvent to -1 
 183     g_sendActivateEvent 
= 0; 
 185     // wxASSERT_MSG( (g_activeFrame == win), wxT("TLW deactivatd although it wasn't active") ); 
 187     // wxPrintf( wxT("inactive: %s\n"), win->GetTitle().c_str() ); 
 191         wxLogTrace(wxT("activate"), wxT("Activating frame %p (from focus_in)"), g_activeFrame
); 
 192         wxActivateEvent 
event(wxEVT_ACTIVATE
, false, g_activeFrame
->GetId()); 
 193         event
.SetEventObject(g_activeFrame
); 
 194         g_activeFrame
->GetEventHandler()->ProcessEvent(event
); 
 196         g_activeFrame 
= NULL
; 
 203 //----------------------------------------------------------------------------- 
 204 // "focus" from m_window 
 205 //----------------------------------------------------------------------------- 
 208 static gint 
gtk_frame_focus_callback( GtkWidget 
*widget
, GtkDirectionType 
WXUNUSED(d
), wxWindow 
*WXUNUSED(win
) ) 
 211         wxapp_install_idle_handler(); 
 213     // This disables GTK's tab traversal 
 214     gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus" ); 
 219 //----------------------------------------------------------------------------- 
 221 //----------------------------------------------------------------------------- 
 224 static void gtk_frame_size_callback( GtkWidget 
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxTopLevelWindowGTK 
*win 
) 
 227         wxapp_install_idle_handler(); 
 232     if ((win
->m_width 
!= alloc
->width
) || (win
->m_height 
!= alloc
->height
)) 
 235         wxPrintf( "OnSize from " ); 
 236         if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 237            wxPrintf( win->GetClassInfo()->GetClassName() ); 
 238         wxPrintf( " %d %d %d %d\n", (int)alloc->x, 
 241                                 (int)alloc->height ); 
 244         win
->m_width 
= alloc
->width
; 
 245         win
->m_height 
= alloc
->height
; 
 246         win
->GtkUpdateSize(); 
 251 //----------------------------------------------------------------------------- 
 253 //----------------------------------------------------------------------------- 
 256 static gint 
gtk_frame_delete_callback( GtkWidget 
*WXUNUSED(widget
), GdkEvent 
*WXUNUSED(event
), wxTopLevelWindowGTK 
*win 
) 
 259         wxapp_install_idle_handler(); 
 261     if (win
->IsEnabled() && 
 262         (g_openDialogs 
== 0 || (win
->GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
) || 
 271 //----------------------------------------------------------------------------- 
 273 //----------------------------------------------------------------------------- 
 277 gtk_frame_configure_callback( GtkWidget 
*WXUNUSED(widget
), GdkEventConfigure 
*WXUNUSED(event
), wxTopLevelWindowGTK 
*win 
) 
 280         wxapp_install_idle_handler(); 
 282     if (!win
->m_hasVMT 
|| !win
->IsShown()) 
 288     gdk_window_get_root_origin( win
->m_widget
->window
, &x
, &y 
); 
 292     wxMoveEvent 
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() ); 
 293     mevent
.SetEventObject( win 
); 
 294     win
->GetEventHandler()->ProcessEvent( mevent 
); 
 300 //----------------------------------------------------------------------------- 
 301 // "realize" from m_widget 
 302 //----------------------------------------------------------------------------- 
 304 // we cannot MWM hints and icons before the widget has been realized, 
 305 // so we do this directly after realization 
 309 gtk_frame_realized_callback( GtkWidget 
* WXUNUSED(widget
), 
 310                              wxTopLevelWindowGTK 
*win 
) 
 313         wxapp_install_idle_handler(); 
 315     // All this is for Motif Window Manager "hints" and is supposed to be 
 316     // recognized by other WM as well. Not tested. 
 317     gdk_window_set_decorations(win
->m_widget
->window
, 
 318                                (GdkWMDecoration
)win
->m_gdkDecor
); 
 319     gdk_window_set_functions(win
->m_widget
->window
, 
 320                                (GdkWMFunction
)win
->m_gdkFunc
); 
 322     // GTK's shrinking/growing policy 
 323     if ((win
->m_gdkFunc 
& GDK_FUNC_RESIZE
) == 0) 
 324         gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1); 
 326         gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1); 
 329     wxIconBundle iconsOld 
= win
->GetIcons(); 
 330     if ( iconsOld
.GetIcon(-1).Ok() ) 
 332         win
->SetIcon( wxNullIcon 
); 
 333         win
->SetIcons( iconsOld 
); 
 338 //----------------------------------------------------------------------------- 
 339 // "map_event" from m_widget 
 340 //----------------------------------------------------------------------------- 
 344 gtk_frame_map_callback( GtkWidget 
* WXUNUSED(widget
), 
 345                         GdkEvent 
* WXUNUSED(event
), 
 346                         wxTopLevelWindow 
*win 
) 
 348     win
->SetIconizeState(false); 
 352 //----------------------------------------------------------------------------- 
 353 // "unmap_event" from m_widget 
 354 //----------------------------------------------------------------------------- 
 358 gtk_frame_unmap_callback( GtkWidget 
* WXUNUSED(widget
), 
 359                           GdkEvent 
* WXUNUSED(event
), 
 360                           wxTopLevelWindow 
*win 
) 
 362     win
->SetIconizeState(true); 
 366 //----------------------------------------------------------------------------- 
 367 // "expose_event" of m_client 
 368 //----------------------------------------------------------------------------- 
 371 static int gtk_window_expose_callback( GtkWidget 
*widget
, GdkEventExpose 
*gdk_event
, wxWindow 
*win 
) 
 373     GtkPizza 
*pizza 
= GTK_PIZZA(widget
); 
 375     gtk_paint_flat_box (win
->m_widget
->style
, 
 376                         pizza
->bin_window
, GTK_STATE_NORMAL
, 
 387 //----------------------------------------------------------------------------- 
 388 // "draw" of m_client 
 389 //----------------------------------------------------------------------------- 
 392 static void gtk_window_draw_callback( GtkWidget 
*widget
, GdkRectangle 
*rect
, wxWindow 
*win 
) 
 394     GtkPizza 
*pizza 
= GTK_PIZZA(widget
); 
 396     gtk_paint_flat_box (win
->m_widget
->style
, 
 397                         pizza
->bin_window
, GTK_STATE_NORMAL
, 
 406 // ---------------------------------------------------------------------------- 
 407 // wxTopLevelWindowGTK itself 
 408 // ---------------------------------------------------------------------------- 
 410 //----------------------------------------------------------------------------- 
 411 // InsertChild for wxTopLevelWindowGTK 
 412 //----------------------------------------------------------------------------- 
 414 /* Callback for wxTopLevelWindowGTK. This very strange beast has to be used because 
 415  * C++ has no virtual methods in a constructor. We have to emulate a 
 416  * virtual function here as wxWidgets requires different ways to insert 
 417  * a child in container classes. */ 
 419 static void wxInsertChildInTopLevelWindow( wxTopLevelWindowGTK
* parent
, wxWindow
* child 
) 
 421     wxASSERT( GTK_IS_WIDGET(child
->m_widget
) ); 
 423     if (!parent
->m_insertInClientArea
) 
 425         // these are outside the client area 
 426         wxTopLevelWindowGTK
* frame 
= (wxTopLevelWindowGTK
*) parent
; 
 427         gtk_pizza_put( GTK_PIZZA(frame
->m_mainWidget
), 
 428                          GTK_WIDGET(child
->m_widget
), 
 436         // these are inside the client area 
 437         gtk_pizza_put( GTK_PIZZA(parent
->m_wxwindow
), 
 438                          GTK_WIDGET(child
->m_widget
), 
 445     // resize on OnInternalIdle 
 446     parent
->GtkUpdateSize(); 
 449 // ---------------------------------------------------------------------------- 
 450 // wxTopLevelWindowGTK creation 
 451 // ---------------------------------------------------------------------------- 
 453 void wxTopLevelWindowGTK::Init() 
 458     m_mainWidget 
= (GtkWidget
*) NULL
; 
 459     m_insertInClientArea 
= true; 
 460     m_isIconized 
= false; 
 461     m_fsIsShowing 
= false; 
 462     m_themeEnabled 
= true; 
 463     m_gdkDecor 
= m_gdkFunc 
= 0; 
 469 bool wxTopLevelWindowGTK::Create( wxWindow 
*parent
, 
 471                                   const wxString
& title
, 
 473                                   const wxSize
& sizeOrig
, 
 475                                   const wxString 
&name 
) 
 477     // always create a frame of some reasonable, even if arbitrary, size (at 
 478     // least for MSW compatibility) 
 479     wxSize size 
= sizeOrig
; 
 480     size
.x 
= WidthDefault(size
.x
); 
 481     size
.y 
= HeightDefault(size
.y
); 
 483     wxTopLevelWindows
.Append( this ); 
 485     m_needParent 
= false; 
 487     if (!PreCreation( parent
, pos
, size 
) || 
 488         !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name 
)) 
 490         wxFAIL_MSG( wxT("wxTopLevelWindowGTK creation failed") ); 
 496     m_insertCallback 
= (wxInsertChildFunction
) wxInsertChildInTopLevelWindow
; 
 498     // NB: m_widget may be !=NULL if it was created by derived class' Create, 
 499     //     e.g. in wxTaskBarIconAreaGTK 
 500     if (m_widget 
== NULL
) 
 502         if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
) 
 504             m_widget 
= gtk_window_new(GTK_WINDOW_DIALOG
); 
 508             m_widget 
= gtk_window_new(GTK_WINDOW_TOPLEVEL
); 
 509 #if GTK_CHECK_VERSION(2,1,0) 
 510             if (!gtk_check_version(2,1,0)) 
 512                 if (style 
& wxFRAME_TOOL_WINDOW
) 
 514                     gtk_window_set_type_hint(GTK_WINDOW(m_widget
), 
 515                                              GDK_WINDOW_TYPE_HINT_UTILITY
); 
 517                     // On some WMs, like KDE, a TOOL_WINDOW will still show 
 518                     // on the taskbar, but on Gnome a TOOL_WINDOW will not. 
 519                     // For consistency between WMs and with Windows, we 
 520                     // should set the NO_TASKBAR flag which will apply 
 521                     // the set_skip_taskbar_hint if it is available, 
 522                     // ensuring no taskbar entry will appear. 
 523                     style 
|= wxFRAME_NO_TASKBAR
; 
 530     wxWindow 
*topParent 
= wxGetTopLevelParent(m_parent
); 
 531     if (topParent 
&& (((GTK_IS_WINDOW(topParent
->m_widget
)) && 
 532                        (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
)) || 
 533                        (style 
& wxFRAME_FLOAT_ON_PARENT
))) 
 535         gtk_window_set_transient_for( GTK_WINDOW(m_widget
), 
 536                                       GTK_WINDOW(topParent
->m_widget
) ); 
 540         gtk_window_set_wmclass( GTK_WINDOW(m_widget
), wxGTK_CONV( name 
), wxGTK_CONV( name 
) ); 
 542     gtk_window_set_title( GTK_WINDOW(m_widget
), wxGTK_CONV( title 
) ); 
 543     GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS 
); 
 545     gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event", 
 546         GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this ); 
 548     // m_mainWidget holds the toolbar, the menubar and the client area 
 549     m_mainWidget 
= gtk_pizza_new(); 
 550     gtk_widget_show( m_mainWidget 
); 
 551     GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS 
); 
 552     gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget 
); 
 554     if (m_miniEdge 
== 0) // wxMiniFrame has its own version. 
 556        // For m_mainWidget themes 
 557        gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "expose_event", 
 558                 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this ); 
 559        gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "draw", 
 560                 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this ); 
 563     // m_wxwindow only represents the client area without toolbar and menubar 
 564     m_wxwindow 
= gtk_pizza_new(); 
 565     gtk_widget_show( m_wxwindow 
); 
 566     gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow 
); 
 568     // we donm't allow the frame to get the focus as otherwise 
 569     // the frame will grab it at arbitrary focus changes 
 570     GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS 
); 
 572     if (m_parent
) m_parent
->AddChild( this ); 
 574     // the user resized the frame by dragging etc. 
 575     gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate", 
 576         GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this ); 
 580     if ((m_x 
!= -1) || (m_y 
!= -1)) 
 581         gtk_widget_set_uposition( m_widget
, m_x
, m_y 
); 
 583     gtk_window_set_default_size( GTK_WINDOW(m_widget
), m_width
, m_height 
); 
 585     //  we cannot set MWM hints and icons before the widget has 
 586     //  been realized, so we do this directly after realization 
 587     gtk_signal_connect( GTK_OBJECT(m_widget
), "realize", 
 588                         GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this ); 
 590     // map and unmap for iconized state 
 591     gtk_signal_connect( GTK_OBJECT(m_widget
), "map_event", 
 592         GTK_SIGNAL_FUNC(gtk_frame_map_callback
), (gpointer
)this ); 
 593     gtk_signal_connect( GTK_OBJECT(m_widget
), "unmap_event", 
 594         GTK_SIGNAL_FUNC(gtk_frame_unmap_callback
), (gpointer
)this ); 
 596     // the only way to get the window size is to connect to this event 
 597     gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event", 
 598         GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this ); 
 600     // disable native tab traversal 
 601     gtk_signal_connect( GTK_OBJECT(m_widget
), "focus", 
 602         GTK_SIGNAL_FUNC(gtk_frame_focus_callback
), (gpointer
)this ); 
 605     gtk_signal_connect( GTK_OBJECT(m_widget
), "focus_in_event", 
 606         GTK_SIGNAL_FUNC(gtk_frame_focus_in_callback
), (gpointer
)this ); 
 607     gtk_signal_connect( GTK_OBJECT(m_widget
), "focus_out_event", 
 608         GTK_SIGNAL_FUNC(gtk_frame_focus_out_callback
), (gpointer
)this ); 
 611     if ((m_miniEdge 
> 0) || (style 
& wxSIMPLE_BORDER
) || (style 
& wxNO_BORDER
)) 
 618         m_gdkDecor 
= (long) GDK_DECOR_BORDER
; 
 619         m_gdkFunc 
= (long) GDK_FUNC_MOVE
; 
 621         // All this is for Motif Window Manager "hints" and is supposed to be 
 622         // recognized by other WMs as well. 
 623         if ((style 
& wxCAPTION
) != 0) 
 625             m_gdkDecor 
|= GDK_DECOR_TITLE
; 
 627         if ((style 
& wxCLOSE_BOX
) != 0) 
 629             m_gdkFunc 
|= GDK_FUNC_CLOSE
; 
 631         if ((style 
& wxSYSTEM_MENU
) != 0) 
 633             m_gdkDecor 
|= GDK_DECOR_MENU
; 
 635         if ((style 
& wxMINIMIZE_BOX
) != 0) 
 637             m_gdkFunc 
|= GDK_FUNC_MINIMIZE
; 
 638             m_gdkDecor 
|= GDK_DECOR_MINIMIZE
; 
 640         if ((style 
& wxMAXIMIZE_BOX
) != 0) 
 642             m_gdkFunc 
|= GDK_FUNC_MAXIMIZE
; 
 643             m_gdkDecor 
|= GDK_DECOR_MAXIMIZE
; 
 645         if ((style 
& wxRESIZE_BORDER
) != 0) 
 647            m_gdkFunc 
|= GDK_FUNC_RESIZE
; 
 648            m_gdkDecor 
|= GDK_DECOR_RESIZEH
; 
 655 wxTopLevelWindowGTK::~wxTopLevelWindowGTK() 
 659         wxASSERT_MSG( false, _T("Window still grabbed")); 
 663     m_isBeingDeleted 
= true; 
 665     // it may also be GtkScrolledWindow in the case of an MDI child 
 666     if (GTK_IS_WINDOW(m_widget
)) 
 668         gtk_window_set_focus( GTK_WINDOW(m_widget
), NULL 
); 
 671     if (g_activeFrame 
== this) 
 672         g_activeFrame 
= NULL
; 
 673     if (g_lastActiveFrame 
== this) 
 674         g_lastActiveFrame 
= NULL
; 
 679 bool wxTopLevelWindowGTK::ShowFullScreen(bool show
, long style 
) 
 681     if (show 
== m_fsIsShowing
) 
 682         return false; // return what? 
 684     m_fsIsShowing 
= show
; 
 686     wxX11FullScreenMethod method 
= 
 687         wxGetFullScreenMethodX11((WXDisplay
*)GDK_DISPLAY(), 
 688                                  (WXWindow
)GDK_ROOT_WINDOW()); 
 690 #if GTK_CHECK_VERSION(2,2,0) 
 691     // NB: gtk_window_fullscreen() uses freedesktop.org's WMspec extensions 
 692     //     to switch to fullscreen, which is not always available. We must 
 693     //     check if WM supports the spec and use legacy methods if it 
 695     if ( (method 
== wxX11_FS_WMSPEC
) && !gtk_check_version(2,2,0) ) 
 698             gtk_window_fullscreen( GTK_WINDOW( m_widget 
) ); 
 700             gtk_window_unfullscreen( GTK_WINDOW( m_widget 
) ); 
 703 #endif // GTK+ >= 2.2.0 
 705         GdkWindow 
*window 
= m_widget
->window
; 
 709             m_fsSaveFlag 
= style
; 
 710             GetPosition( &m_fsSaveFrame
.x
, &m_fsSaveFrame
.y 
); 
 711             GetSize( &m_fsSaveFrame
.width
, &m_fsSaveFrame
.height 
); 
 713             int screen_width
,screen_height
; 
 714             wxDisplaySize( &screen_width
, &screen_height 
); 
 716             gint client_x
, client_y
, root_x
, root_y
; 
 719             if (method 
!= wxX11_FS_WMSPEC
) 
 721                 // don't do it always, Metacity hates it 
 722                 m_fsSaveGdkFunc 
= m_gdkFunc
; 
 723                 m_fsSaveGdkDecor 
= m_gdkDecor
; 
 724                 m_gdkFunc 
= m_gdkDecor 
= 0; 
 725                 gdk_window_set_decorations(window
, (GdkWMDecoration
)0); 
 726                 gdk_window_set_functions(window
, (GdkWMFunction
)0); 
 729             gdk_window_get_origin (m_widget
->window
, &root_x
, &root_y
); 
 730             gdk_window_get_geometry (m_widget
->window
, &client_x
, &client_y
, 
 731                          &width
, &height
, NULL
); 
 733             gdk_window_move_resize (m_widget
->window
, -client_x
, -client_y
, 
 734                         screen_width 
+ 1, screen_height 
+ 1); 
 736             wxSetFullScreenStateX11((WXDisplay
*)GDK_DISPLAY(), 
 737                                     (WXWindow
)GDK_ROOT_WINDOW(), 
 738                                     (WXWindow
)GDK_WINDOW_XWINDOW(window
), 
 739                                     show
, &m_fsSaveFrame
, method
); 
 743             if (method 
!= wxX11_FS_WMSPEC
) 
 745                 // don't do it always, Metacity hates it 
 746                 m_gdkFunc 
= m_fsSaveGdkFunc
; 
 747                 m_gdkDecor 
= m_fsSaveGdkDecor
; 
 748                 gdk_window_set_decorations(window
, (GdkWMDecoration
)m_gdkDecor
); 
 749                 gdk_window_set_functions(window
, (GdkWMFunction
)m_gdkFunc
); 
 752             wxSetFullScreenStateX11((WXDisplay
*)GDK_DISPLAY(), 
 753                                     (WXWindow
)GDK_ROOT_WINDOW(), 
 754                                     (WXWindow
)GDK_WINDOW_XWINDOW(window
), 
 755                                     show
, &m_fsSaveFrame
, method
); 
 757             SetSize(m_fsSaveFrame
.x
, m_fsSaveFrame
.y
, 
 758                     m_fsSaveFrame
.width
, m_fsSaveFrame
.height
); 
 762     // documented behaviour is to show the window if it's still hidden when 
 763     // showing it full screen 
 764     if ( show 
&& !IsShown() ) 
 770 // ---------------------------------------------------------------------------- 
 771 // overridden wxWindow methods 
 772 // ---------------------------------------------------------------------------- 
 774 bool wxTopLevelWindowGTK::Show( bool show 
) 
 776     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 778     if (show 
&& !m_sizeSet
) 
 780         /* by calling GtkOnSize here, we don't have to call 
 781            either after showing the frame, which would entail 
 782            much ugly flicker or from within the size_allocate 
 783            handler, because GTK 1.1.X forbids that. */ 
 785         GtkOnSize( m_x
, m_y
, m_width
, m_height 
); 
 789         gtk_widget_set_uposition( m_widget
, m_x
, m_y 
); 
 791     return wxWindow::Show( show 
); 
 794 void wxTopLevelWindowGTK::Raise() 
 799 void wxTopLevelWindowGTK::DoMoveWindow(int WXUNUSED(x
), int WXUNUSED(y
), int WXUNUSED(width
), int WXUNUSED(height
) ) 
 801     wxFAIL_MSG( wxT("DoMoveWindow called for wxTopLevelWindowGTK") ); 
 804 void wxTopLevelWindowGTK::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags 
) 
 806     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 808     // this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow 
 809     wxASSERT_MSG( (m_wxwindow 
!= NULL
), wxT("invalid frame") ); 
 819     int old_width 
= m_width
; 
 820     int old_height 
= m_height
; 
 822     if ((sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
) == 0) 
 824         if (x 
!= -1) m_x 
= x
; 
 825         if (y 
!= -1) m_y 
= y
; 
 832     if (width 
!= -1) m_width 
= width
; 
 833     if (height 
!= -1) m_height 
= height
; 
 836     if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH) 
 838         if (width == -1) m_width = 80; 
 841     if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT) 
 843        if (height == -1) m_height = 26; 
 847     int minWidth 
= GetMinWidth(), 
 848         minHeight 
= GetMinHeight(), 
 849         maxWidth 
= GetMaxWidth(), 
 850         maxHeight 
= GetMaxHeight(); 
 853     // GPE's window manager doesn't like size hints 
 854     // at all, esp. when the user has to use the 
 862     if ((minWidth 
!= -1) && (m_width 
< minWidth
)) m_width 
= minWidth
; 
 863     if ((minHeight 
!= -1) && (m_height 
< minHeight
)) m_height 
= minHeight
; 
 864     if ((maxWidth 
!= -1) && (m_width 
> maxWidth
)) m_width 
= maxWidth
; 
 865     if ((maxHeight 
!= -1) && (m_height 
> maxHeight
)) m_height 
= maxHeight
; 
 867     if ((m_x 
!= -1) || (m_y 
!= -1)) 
 869         if ((m_x 
!= old_x
) || (m_y 
!= old_y
)) 
 871             gtk_widget_set_uposition( m_widget
, m_x
, m_y 
); 
 875     if ((m_width 
!= old_width
) || (m_height 
!= old_height
)) 
 877         if (m_widget
->window
) 
 878             gdk_window_resize( m_widget
->window
, m_width
, m_height 
); 
 880             gtk_window_set_default_size( GTK_WINDOW(m_widget
), m_width
, m_height 
); 
 882         /* we set the size in GtkOnSize, i.e. mostly the actual resizing is 
 883            done either directly before the frame is shown or in idle time 
 884            so that different calls to SetSize() don't lead to flicker. */ 
 891 void wxTopLevelWindowGTK::DoGetClientSize( int *width
, int *height 
) const 
 893     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 895     wxWindow::DoGetClientSize( width
, height 
); 
 899         *height 
-= m_miniEdge
*2 + m_miniTitle
; 
 903         *width 
-= m_miniEdge
*2; 
 907 void wxTopLevelWindowGTK::DoSetClientSize( int width
, int height 
) 
 909     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 912               width 
+ m_miniEdge
*2, height  
+ m_miniEdge
*2 + m_miniTitle
, 0); 
 915 void wxTopLevelWindowGTK::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), 
 916                                      int width
, int height 
) 
 918     // due to a bug in gtk, x,y are always 0 
 923     if (m_resizing
) return; 
 926     if ( m_wxwindow 
== NULL 
) return; 
 931     /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses 
 932        wxWindow::Create to create it's GTK equivalent. m_mainWidget is only 
 933        set in wxFrame::Create so it is used to check what kind of frame we 
 934        have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we 
 935        skip the part which handles m_frameMenuBar, m_frameToolBar and (most 
 936        importantly) m_mainWidget */ 
 938     int minWidth 
= GetMinWidth(), 
 939         minHeight 
= GetMinHeight(), 
 940         maxWidth 
= GetMaxWidth(), 
 941         maxHeight 
= GetMaxHeight(); 
 944     // GPE's window manager doesn't like size hints 
 945     // at all, esp. when the user has to use the 
 953     if ((minWidth 
!= -1) && (m_width 
< minWidth
)) m_width 
= minWidth
; 
 954     if ((minHeight 
!= -1) && (m_height 
< minHeight
)) m_height 
= minHeight
; 
 955     if ((maxWidth 
!= -1) && (m_width 
> maxWidth
)) m_width 
= maxWidth
; 
 956     if ((maxHeight 
!= -1) && (m_height 
> maxHeight
)) m_height 
= maxHeight
; 
 961         gint            flag 
= 0; // GDK_HINT_POS; 
 964         if ((minWidth 
!= -1) || (minHeight 
!= -1)) flag 
|= GDK_HINT_MIN_SIZE
; 
 965         if ((maxWidth 
!= -1) || (maxHeight 
!= -1)) flag 
|= GDK_HINT_MAX_SIZE
; 
 967         geom
.min_width 
= minWidth
; 
 968         geom
.min_height 
= minHeight
; 
 970             // Because of the way we set GDK_HINT_MAX_SIZE above, if either of 
 971             // maxHeight or maxWidth is set, we must set them both, else the 
 972             // remaining -1 will be taken literally. 
 974             // I'm certain this also happens elsewhere, and is the probable 
 975             // cause of other such things as: 
 976             // Gtk-WARNING **: gtk_widget_size_allocate(): 
 977             //       attempt to allocate widget with width 65535 and height 600 
 978             // but I don't have time to track them all now.. 
 980             // Really we need to encapulate all this height/width business and 
 981             // stop any old method from ripping at the members directly and 
 982             // scattering -1's without regard for who might resolve them later. 
 984         geom
.max_width 
= ( maxHeight 
== -1 ) ? maxWidth
 
 985                          : ( maxWidth 
== -1 ) ? wxGetDisplaySize().GetWidth() 
 988         geom
.max_height 
= ( maxWidth 
== -1 ) ? maxHeight    
// ( == -1 here ) 
 989                           : ( maxHeight 
== -1 ) ? wxGetDisplaySize().GetHeight() 
 992         gtk_window_set_geometry_hints( GTK_WINDOW(m_widget
), 
 995                                        (GdkWindowHints
) flag 
); 
 997         /* I revert back to wxGTK's original behaviour. m_mainWidget holds the 
 998          * menubar, the toolbar and the client area, which is represented by 
1000          * this hurts in the eye, but I don't want to call SetSize() 
1001          * because I don't want to call any non-native functions here. */ 
1003         int client_x 
= m_miniEdge
; 
1004         int client_y 
= m_miniEdge 
+ m_miniTitle
; 
1005         int client_w 
= m_width 
- 2*m_miniEdge
; 
1006         int client_h 
= m_height 
- 2*m_miniEdge 
- m_miniTitle
; 
1008         gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
), 
1010                               client_x
, client_y
, client_w
, client_h 
); 
1014         // If there is no m_mainWidget between m_widget and m_wxwindow there 
1015         // is no need to set the size or position of m_wxwindow. 
1020     // send size event to frame 
1021     wxSizeEvent 
event( wxSize(m_width
,m_height
), GetId() ); 
1022     event
.SetEventObject( this ); 
1023     GetEventHandler()->ProcessEvent( event 
); 
1028 void wxTopLevelWindowGTK::OnInternalIdle() 
1030     if (!m_sizeSet 
&& GTK_WIDGET_REALIZED(m_wxwindow
)) 
1032         GtkOnSize( m_x
, m_y
, m_width
, m_height 
); 
1034         // we'll come back later 
1036             wxapp_install_idle_handler(); 
1040     // set the focus if not done yet and if we can already do it 
1041     if ( GTK_WIDGET_REALIZED(m_wxwindow
) ) 
1043         if ( g_delayedFocus 
&& 
1044              wxGetTopLevelParent((wxWindow
*)g_delayedFocus
) == this ) 
1046             wxLogTrace(_T("focus"), 
1047                        _T("Setting focus from wxTLW::OnIdle() to %s(%s)"), 
1048                        g_delayedFocus
->GetClassInfo()->GetClassName(), 
1049                        g_delayedFocus
->GetLabel().c_str()); 
1051             g_delayedFocus
->SetFocus(); 
1052             g_delayedFocus 
= NULL
; 
1056     wxWindow::OnInternalIdle(); 
1058     // Synthetize activate events. 
1059     if ( g_sendActivateEvent 
!= -1 ) 
1061         bool activate 
= g_sendActivateEvent 
!= 0; 
1063         // if (!activate) wxPrintf( wxT("de") ); 
1064         // wxPrintf( wxT("activate\n") ); 
1067         g_sendActivateEvent 
= -1; 
1069         wxTheApp
->SetActive(activate
, (wxWindow 
*)g_lastActiveFrame
); 
1073 // ---------------------------------------------------------------------------- 
1075 // ---------------------------------------------------------------------------- 
1077 void wxTopLevelWindowGTK::SetTitle( const wxString 
&title 
) 
1079     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
1081     if ( title 
== m_title 
) 
1086     gtk_window_set_title( GTK_WINDOW(m_widget
), wxGTK_CONV( title 
) ); 
1089 void wxTopLevelWindowGTK::SetIcon( const wxIcon 
&icon 
) 
1091     SetIcons( wxIconBundle( icon 
) ); 
1094 void wxTopLevelWindowGTK::SetIcons( const wxIconBundle 
&icons 
) 
1096     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
1098     wxTopLevelWindowBase::SetIcons( icons 
); 
1100     GdkWindow
* window 
= m_widget
->window
; 
1104     wxIcon icon 
= icons
.GetIcon(-1); 
1107         wxMask 
*mask 
= icon
.GetMask(); 
1108         GdkBitmap 
*bm 
= (GdkBitmap 
*) NULL
; 
1109         if (mask
) bm 
= mask
->GetBitmap(); 
1111         gdk_window_set_icon( m_widget
->window
, (GdkWindow 
*) NULL
, icon
.GetPixmap(), bm 
); 
1114     wxSetIconsX11( (WXDisplay
*)GDK_WINDOW_XDISPLAY( window 
), 
1115                    (WXWindow
)GDK_WINDOW_XWINDOW( window 
), icons 
); 
1118 // ---------------------------------------------------------------------------- 
1119 // frame state: maximized/iconized/normal 
1120 // ---------------------------------------------------------------------------- 
1122 void wxTopLevelWindowGTK::Maximize(bool maximize
) 
1124     wxFAIL_MSG( _T("not implemented") ); 
1127 bool wxTopLevelWindowGTK::IsMaximized() const 
1129   //    wxFAIL_MSG( _T("not implemented") ); 
1131     // This is an approximation 
1135 void wxTopLevelWindowGTK::Restore() 
1137     wxFAIL_MSG( _T("not implemented") ); 
1140 void wxTopLevelWindowGTK::Iconize( bool iconize 
) 
1144        GdkWindow 
*window 
= m_widget
->window
; 
1146        // you should do it later, for example from OnCreate() handler 
1147        wxCHECK_RET( window
, _T("frame not created yet - can't iconize") ); 
1149        XIconifyWindow( GDK_WINDOW_XDISPLAY( window 
), 
1150                        GDK_WINDOW_XWINDOW( window 
), 
1151                        DefaultScreen( GDK_DISPLAY() ) ); 
1155 bool wxTopLevelWindowGTK::IsIconized() const 
1157     return m_isIconized
; 
1160 void wxTopLevelWindowGTK::SetIconizeState(bool iconize
) 
1162     if ( iconize 
!= m_isIconized 
) 
1164         m_isIconized 
= iconize
; 
1165         (void)SendIconizeEvent(iconize
); 
1169 void wxTopLevelWindowGTK::AddGrab() 
1174         gtk_grab_add( m_widget 
); 
1175         wxEventLoop().Run(); 
1176         gtk_grab_remove( m_widget 
); 
1180 void wxTopLevelWindowGTK::RemoveGrab() 
1191 static bool do_shape_combine_region(GdkWindow
* window
, const wxRegion
& region
) 
1195         if (region
.IsEmpty()) 
1197             gdk_window_shape_combine_mask(window
, NULL
, 0, 0); 
1201             wxBitmap bmp 
= region
.ConvertToBitmap(); 
1202             bmp
.SetMask(new wxMask(bmp
, *wxBLACK
)); 
1203             GdkBitmap
* mask 
= bmp
.GetMask()->GetBitmap(); 
1204             gdk_window_shape_combine_mask(window
, mask
, 0, 0); 
1212 bool wxTopLevelWindowGTK::SetShape(const wxRegion
& region
) 
1214     wxCHECK_MSG( HasFlag(wxFRAME_SHAPED
), false, 
1215                  _T("Shaped windows must be created with the wxFRAME_SHAPED style.")); 
1217     GdkWindow 
*window 
= NULL
; 
1220         window 
= GTK_PIZZA(m_wxwindow
)->bin_window
; 
1221         do_shape_combine_region(window
, region
); 
1223     window 
= m_widget
->window
; 
1224     return do_shape_combine_region(window
, region
); 
1227 bool wxTopLevelWindowGTK::IsActive() 
1229     return (this == (wxTopLevelWindowGTK
*)g_activeFrame
); 
1232 void wxTopLevelWindowGTK::RequestUserAttention(int flags
) 
1234     bool new_hint_value 
= false; 
1236     // FIXME: This is a workaround to focus handling problem 
1237     // If RequestUserAttention is called for example right after a wxSleep, OnInternalIdle hasn't 
1238     // yet been processed, and the internal focus system is not up to date yet. 
1239     // wxYieldIfNeeded ensures the processing of it, but can have unwanted side effects - MR 
1240     ::wxYieldIfNeeded(); 
1242     if(m_urgency_hint 
>= 0) 
1243         gtk_timeout_remove(m_urgency_hint
); 
1245     m_urgency_hint 
= -2; 
1247     if( GTK_WIDGET_REALIZED(m_widget
) && !IsActive() ) 
1249         new_hint_value 
= true; 
1251         if (flags 
& wxUSER_ATTENTION_INFO
) 
1253             m_urgency_hint 
= gtk_timeout_add(5000, (GtkFunction
)gtk_frame_urgency_timer_callback
, this); 
1255             m_urgency_hint 
= -1; 
1259     wxgtk_window_set_urgency_hint(GTK_WINDOW( m_widget 
), new_hint_value
); 
1262 void wxTopLevelWindowGTK::SetWindowStyleFlag( long style 
) 
1264     // Process wxWindow styles. This also updates the internal variable 
1265     // Therefore m_windowStyle bits carry now the _new_ style values 
1266     wxWindow::SetWindowStyleFlag(style
);