1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/gtk/toplevel.cpp 
   4 // Author:      Robert Roebling 
   6 // Copyright:   (c) 1998 Robert Roebling 
   7 // Licence:     wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  10 // For compilers that support precompilation, includes "wx.h". 
  11 #include "wx/wxprec.h" 
  13 // ============================================================================ 
  15 // ============================================================================ 
  17 // ---------------------------------------------------------------------------- 
  19 // ---------------------------------------------------------------------------- 
  22 #define XIconifyWindow XICONIFYWINDOW 
  25 #include "wx/toplevel.h" 
  34 #include "wx/gtk/private.h" 
  35 #include "wx/evtloop.h" 
  36 #include "wx/sysopt.h" 
  41 #include "wx/gtk/private/win_gtk.h" 
  43 #include "wx/unix/utilsx11.h" 
  46 #include <X11/Xatom.h> 
  49     #include <hildon-widgets/hildon-program.h> 
  50     #include <hildon-widgets/hildon-window.h> 
  51 #endif // wxUSE_LIBHILDON 
  54     #include <hildon/hildon.h> 
  55 #endif // wxUSE_LIBHILDON2 
  57 // ---------------------------------------------------------------------------- 
  59 // ---------------------------------------------------------------------------- 
  61 // this is incremented while a modal dialog is shown 
  62 int wxOpenModalDialogsCount 
= 0; 
  64 // the frame that is currently active (i.e. its child has focus). It is 
  65 // used to generate wxActivateEvents 
  66 static wxTopLevelWindowGTK 
*g_activeFrame 
= NULL
; 
  67 static wxTopLevelWindowGTK 
*g_lastActiveFrame 
= NULL
; 
  69 // if we detect that the app has got/lost the focus, we set this variable to 
  70 // either TRUE or FALSE and an activate event will be sent during the next 
  71 // OnIdle() call and it is reset to -1: this value means that we shouldn't 
  72 // send any activate events at all 
  73 static int g_sendActivateEvent 
= -1; 
  75 //----------------------------------------------------------------------------- 
  76 // RequestUserAttention related functions 
  77 //----------------------------------------------------------------------------- 
  80 static void wxgtk_window_set_urgency_hint (GtkWindow 
*win
, 
  83     wxASSERT_MSG( GTK_WIDGET_REALIZED(win
), wxT("wxgtk_window_set_urgency_hint: GdkWindow not realized") ); 
  84     GdkWindow 
*window 
= GTK_WIDGET(win
)->window
; 
  87     wm_hints 
= XGetWMHints(GDK_WINDOW_XDISPLAY(window
), GDK_WINDOW_XWINDOW(window
)); 
  90         wm_hints 
= XAllocWMHints(); 
  93         wm_hints
->flags 
|= XUrgencyHint
; 
  95         wm_hints
->flags 
&= ~XUrgencyHint
; 
  97     XSetWMHints(GDK_WINDOW_XDISPLAY(window
), GDK_WINDOW_XWINDOW(window
), wm_hints
); 
 101 static gboolean 
gtk_frame_urgency_timer_callback( wxTopLevelWindowGTK 
*win 
) 
 103 #if GTK_CHECK_VERSION(2,7,0) 
 104     if(!gtk_check_version(2,7,0)) 
 105         gtk_window_set_urgency_hint(GTK_WINDOW( win
->m_widget 
), FALSE
); 
 108         wxgtk_window_set_urgency_hint(GTK_WINDOW( win
->m_widget 
), FALSE
); 
 110     win
->m_urgency_hint 
= -2; 
 115 //----------------------------------------------------------------------------- 
 117 //----------------------------------------------------------------------------- 
 120 static gboolean 
gtk_frame_focus_in_callback( GtkWidget 
*widget
, 
 121                                          GdkEvent 
*WXUNUSED(event
), 
 122                                          wxTopLevelWindowGTK 
*win 
) 
 124     switch ( g_sendActivateEvent 
) 
 127             // we've got focus from outside, synthetize wxActivateEvent 
 128             g_sendActivateEvent 
= 1; 
 132             // another our window just lost focus, it was already ours before 
 133             // - don't send any wxActivateEvent 
 134             g_sendActivateEvent 
= -1; 
 139     g_lastActiveFrame 
= g_activeFrame
; 
 141     // wxPrintf( wxT("active: %s\n"), win->GetTitle().c_str() ); 
 143     // MR: wxRequestUserAttention related block 
 144     switch( win
->m_urgency_hint 
) 
 147             g_source_remove( win
->m_urgency_hint 
); 
 148             // no break, fallthrough to remove hint too 
 150 #if GTK_CHECK_VERSION(2,7,0) 
 151             if(!gtk_check_version(2,7,0)) 
 152                 gtk_window_set_urgency_hint(GTK_WINDOW( widget 
), FALSE
); 
 156                 wxgtk_window_set_urgency_hint(GTK_WINDOW( widget 
), FALSE
); 
 159             win
->m_urgency_hint 
= -2; 
 165     wxLogTrace(wxT("activate"), wxT("Activating frame %p (from focus_in)"), g_activeFrame
); 
 166     wxActivateEvent 
event(wxEVT_ACTIVATE
, true, g_activeFrame
->GetId()); 
 167     event
.SetEventObject(g_activeFrame
); 
 168     g_activeFrame
->HandleWindowEvent(event
); 
 174 //----------------------------------------------------------------------------- 
 176 //----------------------------------------------------------------------------- 
 180 gboolean 
gtk_frame_focus_out_callback(GtkWidget 
* WXUNUSED(widget
), 
 181                                       GdkEventFocus 
*WXUNUSED(gdk_event
), 
 182                                       wxTopLevelWindowGTK 
* WXUNUSED(win
)) 
 184     // if the focus goes out of our app alltogether, OnIdle() will send 
 185     // wxActivateEvent, otherwise gtk_window_focus_in_callback() will reset 
 186     // g_sendActivateEvent to -1 
 187     g_sendActivateEvent 
= 0; 
 189     // wxASSERT_MSG( (g_activeFrame == win), wxT("TLW deactivatd although it wasn't active") ); 
 191     // wxPrintf( wxT("inactive: %s\n"), win->GetTitle().c_str() ); 
 195         wxLogTrace(wxT("activate"), wxT("Activating frame %p (from focus_in)"), g_activeFrame
); 
 196         wxActivateEvent 
event(wxEVT_ACTIVATE
, false, g_activeFrame
->GetId()); 
 197         event
.SetEventObject(g_activeFrame
); 
 198         g_activeFrame
->HandleWindowEvent(event
); 
 200         g_activeFrame 
= NULL
; 
 207 //----------------------------------------------------------------------------- 
 208 // "size_allocate" from m_wxwindow 
 209 //----------------------------------------------------------------------------- 
 213 size_allocate(GtkWidget
*, GtkAllocation
* alloc
, wxTopLevelWindowGTK
* win
) 
 215     if (win
->m_oldClientWidth  
!= alloc
->width 
|| 
 216         win
->m_oldClientHeight 
!= alloc
->height
) 
 218         win
->m_oldClientWidth  
= alloc
->width
; 
 219         win
->m_oldClientHeight 
= alloc
->height
; 
 221         wxSize 
size(win
->m_widget
->allocation
.width
, 
 222                     win
->m_widget
->allocation
.height
); 
 223         size 
+= win
->m_decorSize
; 
 224         win
->m_width  
= size
.x
; 
 225         win
->m_height 
= size
.y
; 
 227         if (!win
->IsIconized()) 
 229             wxSizeEvent 
event(size
, win
->GetId()); 
 230             event
.SetEventObject(win
); 
 231             win
->HandleWindowEvent(event
); 
 233         // else the window is currently unmapped, don't generate size events 
 238 // ---------------------------------------------------------------------------- 
 240 // ---------------------------------------------------------------------------- 
 244 void wxgtk_tlw_size_request_callback(GtkWidget 
* WXUNUSED(widget
), 
 245                                      GtkRequisition 
*requisition
, 
 246                                      wxTopLevelWindowGTK 
*win
) 
 248     // we must return the size of the window without WM decorations, otherwise 
 249     // GTK+ gets confused, so don't call just GetSize() here 
 250     win
->GTKDoGetSize(&requisition
->width
, &requisition
->height
); 
 254 //----------------------------------------------------------------------------- 
 256 //----------------------------------------------------------------------------- 
 260 gtk_frame_delete_callback( GtkWidget 
*WXUNUSED(widget
), 
 261                            GdkEvent 
*WXUNUSED(event
), 
 262                            wxTopLevelWindowGTK 
*win 
) 
 264     if (win
->IsEnabled() && 
 265         (wxOpenModalDialogsCount 
== 0 || (win
->GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
) || 
 273 //----------------------------------------------------------------------------- 
 275 //----------------------------------------------------------------------------- 
 279 gtk_frame_configure_callback( GtkWidget
* widget
, 
 280                               GdkEventConfigure 
*WXUNUSED(event
), 
 281                               wxTopLevelWindowGTK 
*win 
) 
 283     if (!win
->m_hasVMT 
|| !win
->IsShown()) 
 287     gtk_window_get_position((GtkWindow
*)widget
, &point
.x
, &point
.y
); 
 291     wxMoveEvent 
mevent(point
, win
->GetId()); 
 292     mevent
.SetEventObject( win 
); 
 293     win
->HandleWindowEvent( mevent 
); 
 299 //----------------------------------------------------------------------------- 
 300 // "realize" from m_widget 
 301 //----------------------------------------------------------------------------- 
 303 // we cannot the WM hints and icons before the widget has been realized, 
 304 // so we do this directly after realization 
 308 gtk_frame_realized_callback( GtkWidget 
* WXUNUSED(widget
), 
 309                              wxTopLevelWindowGTK 
*win 
) 
 311     gdk_window_set_decorations(win
->m_widget
->window
, 
 312                                (GdkWMDecoration
)win
->m_gdkDecor
); 
 313     gdk_window_set_functions(win
->m_widget
->window
, 
 314                                (GdkWMFunction
)win
->m_gdkFunc
); 
 316     // GTK's shrinking/growing policy 
 317     if ( !(win
->m_gdkFunc 
& GDK_FUNC_RESIZE
) ) 
 318         gtk_window_set_resizable(GTK_WINDOW(win
->m_widget
), FALSE
); 
 320         gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1); 
 322     const wxIconBundle
& icons 
= win
->GetIcons(); 
 323     if (icons
.GetIconCount()) 
 324         win
->SetIcons(icons
); 
 326     if (win
->HasFlag(wxFRAME_SHAPED
)) 
 327         win
->SetShape(win
->m_shape
); // it will really set the window shape now 
 331 //----------------------------------------------------------------------------- 
 332 // "map_event" from m_widget 
 333 //----------------------------------------------------------------------------- 
 337 gtk_frame_map_callback( GtkWidget
*, 
 338                         GdkEvent 
* WXUNUSED(event
), 
 339                         wxTopLevelWindow 
*win 
) 
 341     const bool wasIconized 
= win
->IsIconized(); 
 342     win
->SetIconizeState(false); 
 345         // Because GetClientSize() returns (0,0) when IsIconized() is true, 
 346         // a size event must be generated, just in case GetClientSize() was 
 347         // called while iconized. This specifically happens when restoring a 
 348         // tlw that was "rolled up" with some WMs. 
 349         // Queue a resize rather than sending size event directly to allow 
 350         // children to be made visible first. 
 351         win
->m_oldClientWidth 
= 0; 
 352         gtk_widget_queue_resize(win
->m_wxwindow
); 
 354     // it is possible for m_isShown to be false here, see bug #9909 
 355     if (win
->wxWindowBase::Show(true)) 
 357         wxShowEvent 
eventShow(win
->GetId(), true); 
 358         eventShow
.SetEventObject(win
); 
 359         win
->GetEventHandler()->ProcessEvent(eventShow
); 
 362 #if GTK_CHECK_VERSION(2,6,0) 
 363     if (!gtk_check_version(2,6,0)) 
 365         // restore focus-on-map setting in case ShowWithoutActivating() was called 
 366         gtk_window_set_focus_on_map(GTK_WINDOW(win
->m_widget
), true); 
 374 //----------------------------------------------------------------------------- 
 375 // "unmap_event" from m_widget 
 376 //----------------------------------------------------------------------------- 
 380 gtk_frame_unmap_callback( GtkWidget 
* WXUNUSED(widget
), 
 381                           GdkEvent 
* WXUNUSED(event
), 
 382                           wxTopLevelWindow 
*win 
) 
 384     // hiding the window doesn't count as minimizing it 
 386         win
->SetIconizeState(true); 
 391 //----------------------------------------------------------------------------- 
 393 bool wxGetFrameExtents(GdkWindow
* window
, int* left
, int* right
, int* top
, int* bottom
) 
 395     static GdkAtom property 
= gdk_atom_intern("_NET_FRAME_EXTENTS", false); 
 396     Atom xproperty 
= gdk_x11_atom_to_xatom_for_display( 
 397                         gdk_drawable_get_display(window
), property
); 
 400     gulong nitems
, bytes_after
; 
 402     Status status 
= XGetWindowProperty( 
 403         gdk_x11_drawable_get_xdisplay(window
), 
 404         gdk_x11_drawable_get_xid(window
), 
 406         0, 4, false, XA_CARDINAL
, 
 407         &type
, &format
, &nitems
, &bytes_after
, &data
); 
 408     const bool success 
= status 
== Success 
&& data 
&& nitems 
== 4; 
 411         long* p 
= (long*)data
; 
 412         if (left
)   *left   
= int(p
[0]); 
 413         if (right
)  *right  
= int(p
[1]); 
 414         if (top
)    *top    
= int(p
[2]); 
 415         if (bottom
) *bottom 
= int(p
[3]); 
 422 //----------------------------------------------------------------------------- 
 423 // "property_notify_event" from m_widget 
 424 //----------------------------------------------------------------------------- 
 427 static gboolean 
property_notify_event( 
 428     GtkWidget
*, GdkEventProperty
* event
, wxTopLevelWindowGTK
* win
) 
 430     // Watch for changes to _NET_FRAME_EXTENTS property 
 431     static GdkAtom property 
= gdk_atom_intern("_NET_FRAME_EXTENTS", false); 
 432     if (event
->state 
== GDK_PROPERTY_NEW_VALUE 
&& event
->atom 
== property
) 
 434         wxSize decorSize 
= win
->m_decorSize
; 
 435         int left
, right
, top
, bottom
; 
 436         if (wxGetFrameExtents(event
->window
, &left
, &right
, &top
, &bottom
)) 
 437             decorSize
.Set(left 
+ right
, top 
+ bottom
); 
 439         win
->GTKUpdateDecorSize(decorSize
); 
 445 // ---------------------------------------------------------------------------- 
 446 // wxTopLevelWindowGTK creation 
 447 // ---------------------------------------------------------------------------- 
 449 void wxTopLevelWindowGTK::Init() 
 452     m_isIconized 
= false; 
 453     m_fsIsShowing 
= false; 
 454     m_themeEnabled 
= true; 
 459     m_deferShowAllowed 
= true; 
 460     m_updateDecorSize 
= true; 
 465 bool wxTopLevelWindowGTK::Create( wxWindow 
*parent
, 
 467                                   const wxString
& title
, 
 469                                   const wxSize
& sizeOrig
, 
 471                                   const wxString 
&name 
) 
 473     // always create a frame of some reasonable, even if arbitrary, size (at 
 474     // least for MSW compatibility) 
 475     wxSize size 
= sizeOrig
; 
 476     size
.x 
= WidthDefault(size
.x
); 
 477     size
.y 
= HeightDefault(size
.y
); 
 479     wxTopLevelWindows
.Append( this ); 
 481     if (!PreCreation( parent
, pos
, size 
) || 
 482         !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name 
)) 
 484         wxFAIL_MSG( wxT("wxTopLevelWindowGTK creation failed") ); 
 490     // NB: m_widget may be !=NULL if it was created by derived class' Create, 
 491     //     e.g. in wxTaskBarIconAreaGTK 
 492     if (m_widget 
== NULL
) 
 494 #if wxUSE_LIBHILDON || wxUSE_LIBHILDON2 
 495         // we must create HildonWindow and not a normal GtkWindow as the latter 
 496         // doesn't look correctly in Maemo environment and it must also be 
 497         // registered with the main program object 
 498         m_widget 
= hildon_window_new(); 
 499         hildon_program_add_window(wxTheApp
->GetHildonProgram(), 
 500                                   HILDON_WINDOW(m_widget
)); 
 501 #else // !wxUSE_LIBHILDON || !wxUSE_LIBHILDON2 
 502         m_widget 
= gtk_window_new(GTK_WINDOW_TOPLEVEL
); 
 503         if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
) 
 505             // Tell WM that this is a dialog window and make it center 
 506             // on parent by default (this is what GtkDialog ctor does): 
 507             gtk_window_set_type_hint(GTK_WINDOW(m_widget
), 
 508                                      GDK_WINDOW_TYPE_HINT_DIALOG
); 
 509             gtk_window_set_position(GTK_WINDOW(m_widget
), 
 510                                     GTK_WIN_POS_CENTER_ON_PARENT
); 
 514             if (style 
& wxFRAME_TOOL_WINDOW
) 
 516                 gtk_window_set_type_hint(GTK_WINDOW(m_widget
), 
 517                                          GDK_WINDOW_TYPE_HINT_UTILITY
); 
 519                 // On some WMs, like KDE, a TOOL_WINDOW will still show 
 520                 // on the taskbar, but on Gnome a TOOL_WINDOW will not. 
 521                 // For consistency between WMs and with Windows, we 
 522                 // should set the NO_TASKBAR flag which will apply 
 523                 // the set_skip_taskbar_hint if it is available, 
 524                 // ensuring no taskbar entry will appear. 
 525                 style 
|= wxFRAME_NO_TASKBAR
; 
 528 #endif // wxUSE_LIBHILDON || wxUSE_LIBHILDON2/!wxUSE_LIBHILDON || !wxUSE_LIBHILDON2 
 530         g_object_ref(m_widget
); 
 533     wxWindow 
*topParent 
= wxGetTopLevelParent(m_parent
); 
 534     if (topParent 
&& (((GTK_IS_WINDOW(topParent
->m_widget
)) && 
 535                        (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
)) || 
 536                        (style 
& wxFRAME_FLOAT_ON_PARENT
))) 
 538         gtk_window_set_transient_for( GTK_WINDOW(m_widget
), 
 539                                       GTK_WINDOW(topParent
->m_widget
) ); 
 542     if (style 
& wxFRAME_NO_TASKBAR
) 
 544         gtk_window_set_skip_taskbar_hint(GTK_WINDOW(m_widget
), TRUE
); 
 547     if (style 
& wxSTAY_ON_TOP
) 
 549         gtk_window_set_keep_above(GTK_WINDOW(m_widget
), TRUE
); 
 551     if (style 
& wxMAXIMIZE
) 
 552         gtk_window_maximize(GTK_WINDOW(m_widget
)); 
 556         gtk_window_set_role( GTK_WINDOW(m_widget
), wxGTK_CONV( name 
) ); 
 559     gtk_window_set_title( GTK_WINDOW(m_widget
), wxGTK_CONV( title 
) ); 
 560     GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS 
); 
 562     g_signal_connect (m_widget
, "delete_event", 
 563                       G_CALLBACK (gtk_frame_delete_callback
), this); 
 565     // m_mainWidget is a GtkVBox, holding the bars and client area (m_wxwindow) 
 566     m_mainWidget 
= gtk_vbox_new(false, 0); 
 567     gtk_widget_show( m_mainWidget 
); 
 568     GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS 
); 
 569     gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget 
); 
 571     // m_wxwindow is the client area 
 572     m_wxwindow 
= wxPizza::New(); 
 573     gtk_widget_show( m_wxwindow 
); 
 574     gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow 
); 
 576     // we donm't allow the frame to get the focus as otherwise 
 577     // the frame will grab it at arbitrary focus changes 
 578     GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS 
); 
 580     if (m_parent
) m_parent
->AddChild( this ); 
 582     g_signal_connect(m_wxwindow
, "size_allocate", 
 583         G_CALLBACK(size_allocate
), this); 
 585     g_signal_connect (m_widget
, "size_request", 
 586                       G_CALLBACK (wxgtk_tlw_size_request_callback
), this); 
 589     if ((m_x 
!= -1) || (m_y 
!= -1)) 
 590         gtk_widget_set_uposition( m_widget
, m_x
, m_y 
); 
 592     //  we cannot set MWM hints and icons before the widget has 
 593     //  been realized, so we do this directly after realization 
 594     g_signal_connect (m_widget
, "realize", 
 595                       G_CALLBACK (gtk_frame_realized_callback
), this); 
 597     // map and unmap for iconized state 
 598     g_signal_connect (m_widget
, "map_event", 
 599                       G_CALLBACK (gtk_frame_map_callback
), this); 
 600     g_signal_connect (m_widget
, "unmap_event", 
 601                       G_CALLBACK (gtk_frame_unmap_callback
), this); 
 604     g_signal_connect (m_widget
, "configure_event", 
 605                       G_CALLBACK (gtk_frame_configure_callback
), this); 
 608     g_signal_connect_after (m_widget
, "focus_in_event", 
 609                       G_CALLBACK (gtk_frame_focus_in_callback
), this); 
 610     g_signal_connect_after (m_widget
, "focus_out_event", 
 611                       G_CALLBACK (gtk_frame_focus_out_callback
), this); 
 613     gtk_widget_add_events(m_widget
, GDK_PROPERTY_CHANGE_MASK
); 
 614     g_signal_connect(m_widget
, "property_notify_event", 
 615         G_CALLBACK(property_notify_event
), this); 
 617     // translate wx decorations styles into Motif WM hints (they are recognized 
 618     // by other WMs as well) 
 620     // always enable moving the window as we have no separate flag for enabling 
 622     m_gdkFunc 
= GDK_FUNC_MOVE
; 
 624     if ( style 
& wxCLOSE_BOX 
) 
 625         m_gdkFunc 
|= GDK_FUNC_CLOSE
; 
 627     if ( style 
& wxMINIMIZE_BOX 
) 
 628         m_gdkFunc 
|= GDK_FUNC_MINIMIZE
; 
 630     if ( style 
& wxMAXIMIZE_BOX 
) 
 631         m_gdkFunc 
|= GDK_FUNC_MAXIMIZE
; 
 633     if ( (style 
& wxSIMPLE_BORDER
) || (style 
& wxNO_BORDER
) ) 
 639         m_gdkDecor 
= GDK_DECOR_BORDER
; 
 641         if ( style 
& wxCAPTION 
) 
 642             m_gdkDecor 
|= GDK_DECOR_TITLE
; 
 644         if ( style 
& wxSYSTEM_MENU 
) 
 645             m_gdkDecor 
|= GDK_DECOR_MENU
; 
 647         if ( style 
& wxMINIMIZE_BOX 
) 
 648             m_gdkDecor 
|= GDK_DECOR_MINIMIZE
; 
 650         if ( style 
& wxMAXIMIZE_BOX 
) 
 651             m_gdkDecor 
|= GDK_DECOR_MAXIMIZE
; 
 653         if ( style 
& wxRESIZE_BORDER 
) 
 655            m_gdkFunc 
|= GDK_FUNC_RESIZE
; 
 656            m_gdkDecor 
|= GDK_DECOR_RESIZEH
; 
 660     m_decorSize 
= GetCachedDecorSize(); 
 662     GTKDoGetSize(&w
, &h
); 
 663     gtk_window_set_default_size(GTK_WINDOW(m_widget
), w
, h
); 
 668 wxTopLevelWindowGTK::~wxTopLevelWindowGTK() 
 670 #if wxUSE_LIBHILDON || wxUSE_LIBHILDON2 
 671     // it can also be a (standard) dialog 
 672     if ( HILDON_IS_WINDOW(m_widget
) ) 
 674         hildon_program_remove_window(wxTheApp
->GetHildonProgram(), 
 675                                      HILDON_WINDOW(m_widget
)); 
 677 #endif // wxUSE_LIBHILDON || wxUSE_LIBHILDON2 
 681         wxFAIL_MSG(wxT("Window still grabbed")); 
 687     // it may also be GtkScrolledWindow in the case of an MDI child 
 688     if (GTK_IS_WINDOW(m_widget
)) 
 690         gtk_window_set_focus( GTK_WINDOW(m_widget
), NULL 
); 
 693     if (g_activeFrame 
== this) 
 694         g_activeFrame 
= NULL
; 
 695     if (g_lastActiveFrame 
== this) 
 696         g_lastActiveFrame 
= NULL
; 
 699 bool wxTopLevelWindowGTK::EnableCloseButton( bool enable 
) 
 702         m_gdkFunc 
|= GDK_FUNC_CLOSE
; 
 704         m_gdkFunc 
&= ~GDK_FUNC_CLOSE
; 
 706     if (GTK_WIDGET_REALIZED(m_widget
) && (m_widget
->window
)) 
 707         gdk_window_set_functions( m_widget
->window
, (GdkWMFunction
)m_gdkFunc 
); 
 712 bool wxTopLevelWindowGTK::ShowFullScreen(bool show
, long) 
 714     if (show 
== m_fsIsShowing
) 
 715         return false; // return what? 
 717     m_fsIsShowing 
= show
; 
 719     wxX11FullScreenMethod method 
= 
 720         wxGetFullScreenMethodX11((WXDisplay
*)GDK_DISPLAY(), 
 721                                  (WXWindow
)GDK_ROOT_WINDOW()); 
 723     // NB: gtk_window_fullscreen() uses freedesktop.org's WMspec extensions 
 724     //     to switch to fullscreen, which is not always available. We must 
 725     //     check if WM supports the spec and use legacy methods if it 
 727     if ( method 
== wxX11_FS_WMSPEC 
) 
 730             gtk_window_fullscreen( GTK_WINDOW( m_widget 
) ); 
 732             gtk_window_unfullscreen( GTK_WINDOW( m_widget 
) ); 
 736         GdkWindow 
*window 
= m_widget
->window
; 
 740             GetPosition( &m_fsSaveFrame
.x
, &m_fsSaveFrame
.y 
); 
 741             GetSize( &m_fsSaveFrame
.width
, &m_fsSaveFrame
.height 
); 
 743             int screen_width
,screen_height
; 
 744             wxDisplaySize( &screen_width
, &screen_height 
); 
 746             gint client_x
, client_y
, root_x
, root_y
; 
 749             m_fsSaveGdkFunc 
= m_gdkFunc
; 
 750             m_fsSaveGdkDecor 
= m_gdkDecor
; 
 751             m_gdkFunc 
= m_gdkDecor 
= 0; 
 752             gdk_window_set_decorations(window
, (GdkWMDecoration
)0); 
 753             gdk_window_set_functions(window
, (GdkWMFunction
)0); 
 755             gdk_window_get_origin (m_widget
->window
, &root_x
, &root_y
); 
 756             gdk_window_get_geometry (m_widget
->window
, &client_x
, &client_y
, 
 757                          &width
, &height
, NULL
); 
 759             gdk_window_move_resize (m_widget
->window
, -client_x
, -client_y
, 
 760                         screen_width 
+ 1, screen_height 
+ 1); 
 762             wxSetFullScreenStateX11((WXDisplay
*)GDK_DISPLAY(), 
 763                                     (WXWindow
)GDK_ROOT_WINDOW(), 
 764                                     (WXWindow
)GDK_WINDOW_XWINDOW(window
), 
 765                                     show
, &m_fsSaveFrame
, method
); 
 769             m_gdkFunc 
= m_fsSaveGdkFunc
; 
 770             m_gdkDecor 
= m_fsSaveGdkDecor
; 
 771             gdk_window_set_decorations(window
, (GdkWMDecoration
)m_gdkDecor
); 
 772             gdk_window_set_functions(window
, (GdkWMFunction
)m_gdkFunc
); 
 774             wxSetFullScreenStateX11((WXDisplay
*)GDK_DISPLAY(), 
 775                                     (WXWindow
)GDK_ROOT_WINDOW(), 
 776                                     (WXWindow
)GDK_WINDOW_XWINDOW(window
), 
 777                                     show
, &m_fsSaveFrame
, method
); 
 779             SetSize(m_fsSaveFrame
.x
, m_fsSaveFrame
.y
, 
 780                     m_fsSaveFrame
.width
, m_fsSaveFrame
.height
); 
 784     // documented behaviour is to show the window if it's still hidden when 
 785     // showing it full screen 
 792 // ---------------------------------------------------------------------------- 
 793 // overridden wxWindow methods 
 794 // ---------------------------------------------------------------------------- 
 796 void wxTopLevelWindowGTK::Refresh( bool WXUNUSED(eraseBackground
), const wxRect 
*WXUNUSED(rect
) ) 
 798     wxCHECK_RET( m_widget
, wxT("invalid frame") ); 
 800     gtk_widget_queue_draw( m_widget 
); 
 802     if (m_wxwindow 
&& m_wxwindow
->window
) 
 803         gdk_window_invalidate_rect( m_wxwindow
->window
, NULL
, TRUE 
); 
 806 bool wxTopLevelWindowGTK::Show( bool show 
) 
 808     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 810     bool deferShow 
= show 
&& !m_isShown 
&& m_deferShow
; 
 813         deferShow 
= m_deferShowAllowed 
&& !GTK_WIDGET_REALIZED(m_widget
); 
 816             deferShow 
= g_signal_handler_find(m_widget
, 
 817                 GSignalMatchType(G_SIGNAL_MATCH_ID 
| G_SIGNAL_MATCH_DATA
), 
 818                 g_signal_lookup("property_notify_event", GTK_TYPE_WIDGET
), 
 819                 0, NULL
, NULL
, this) != 0; 
 821         GdkScreen
* screen 
= NULL
; 
 824             screen 
= gtk_widget_get_screen(m_widget
); 
 825             GdkAtom atom 
= gdk_atom_intern("_NET_REQUEST_FRAME_EXTENTS", false); 
 826             deferShow 
= gdk_x11_screen_supports_net_wm_hint(screen
, atom
) != 0; 
 827             // If _NET_REQUEST_FRAME_EXTENTS not supported, don't allow changes 
 828             // to m_decorSize, it breaks saving/restoring window size with 
 829             // GetSize()/SetSize() because it makes window bigger between each 
 831             m_updateDecorSize 
= deferShow
; 
 835             // Fluxbox support for _NET_REQUEST_FRAME_EXTENTS is broken 
 836             const char* name 
= gdk_x11_screen_get_window_manager_name(screen
); 
 837             deferShow 
= strcmp(name
, "Fluxbox") != 0; 
 838             m_updateDecorSize 
= deferShow
; 
 841         m_deferShow 
= deferShow
; 
 845         // Initial show. If WM supports _NET_REQUEST_FRAME_EXTENTS, defer 
 846         // calling gtk_widget_show() until _NET_FRAME_EXTENTS property 
 847         // notification is received, so correct frame extents are known. 
 848         // This allows resizing m_widget to keep the overall size in sync with 
 849         // what wxWidgets expects it to be without an obvious change in the 
 850         // window size immediately after it becomes visible. 
 852         // Realize m_widget, so m_widget->window can be used. Realizing normally 
 853         // causes the widget tree to be size_allocated, which generates size 
 854         // events in the wrong order. However, the size_allocates will not be 
 855         // done if the allocation is not the default (1,1). 
 856         const int alloc_width 
= m_widget
->allocation
.width
; 
 857         if (alloc_width 
== 1) 
 858             m_widget
->allocation
.width 
= 2; 
 859         gtk_widget_realize(m_widget
); 
 860         if (alloc_width 
== 1) 
 861             m_widget
->allocation
.width 
= 1; 
 863         // send _NET_REQUEST_FRAME_EXTENTS 
 864         XClientMessageEvent xevent
; 
 865         memset(&xevent
, 0, sizeof(xevent
)); 
 866         xevent
.type 
= ClientMessage
; 
 867         xevent
.window 
= gdk_x11_drawable_get_xid(m_widget
->window
); 
 868         xevent
.message_type 
= gdk_x11_atom_to_xatom_for_display( 
 869             gdk_drawable_get_display(m_widget
->window
), 
 870             gdk_atom_intern("_NET_REQUEST_FRAME_EXTENTS", false)); 
 872         Display
* display 
= gdk_x11_drawable_get_xdisplay(m_widget
->window
); 
 873         XSendEvent(display
, DefaultRootWindow(display
), false, 
 874             SubstructureNotifyMask 
| SubstructureRedirectMask
, 
 877         // defer calling gtk_widget_show() 
 882     if (show 
&& !GTK_WIDGET_REALIZED(m_widget
)) 
 884         // size_allocate signals occur in reverse order (bottom to top). 
 885         // Things work better if the initial wxSizeEvents are sent (from the 
 886         // top down), before the initial size_allocate signals occur. 
 887         wxSizeEvent 
event(GetSize(), GetId()); 
 888         event
.SetEventObject(this); 
 889         HandleWindowEvent(event
); 
 892     bool change 
= base_type::Show(show
); 
 896         // make sure window has a non-default position, so when it is shown 
 897         // again, it won't be repositioned by WM as if it were a new window 
 898         // Note that this must be done _after_ the window is hidden. 
 899         gtk_window_move((GtkWindow
*)m_widget
, m_x
, m_y
); 
 905 void wxTopLevelWindowGTK::ShowWithoutActivating() 
 909 #if GTK_CHECK_VERSION(2,6,0) 
 910         if (!gtk_check_version(2,6,0)) 
 911             gtk_window_set_focus_on_map(GTK_WINDOW(m_widget
), false); 
 918 void wxTopLevelWindowGTK::Raise() 
 920     gtk_window_present( GTK_WINDOW( m_widget 
) ); 
 923 void wxTopLevelWindowGTK::DoMoveWindow(int WXUNUSED(x
), int WXUNUSED(y
), int WXUNUSED(width
), int WXUNUSED(height
) ) 
 925     wxFAIL_MSG( wxT("DoMoveWindow called for wxTopLevelWindowGTK") ); 
 928 // ---------------------------------------------------------------------------- 
 930 // ---------------------------------------------------------------------------- 
 932 void wxTopLevelWindowGTK::GTKDoGetSize(int *width
, int *height
) const 
 934     wxSize 
size(m_width
, m_height
); 
 936     if (size
.x 
< 0) size
.x 
= 0; 
 937     if (size
.y 
< 0) size
.y 
= 0; 
 948        else if (size
.y 
== 270) 
 953 #else // wxUSE_LIBHILDON2 
 954     if (width
)  *width  
= size
.x
; 
 955     if (height
) *height 
= size
.y
; 
 956 #endif // wxUSE_LIBHILDON2 /!wxUSE_LIBHILDON2 
 959 void wxTopLevelWindowGTK::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags 
) 
 961     wxCHECK_RET( m_widget
, wxT("invalid frame") ); 
 963     m_deferShowAllowed 
= true; 
 965     // deal with the position first 
 969     if ( !(sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
) ) 
 971         // -1 means "use existing" unless the flag above is specified 
 977     else // wxSIZE_ALLOW_MINUS_ONE 
 983     if ( m_x 
!= old_x 
|| m_y 
!= old_y 
) 
 985         gtk_window_move( GTK_WINDOW(m_widget
), m_x
, m_y 
); 
 988     const wxSize 
oldSize(m_width
, m_height
); 
 994     if (m_width 
!= oldSize
.x 
|| m_height 
!= oldSize
.y
) 
 997         GTKDoGetSize(&w
, &h
); 
 998         gtk_window_resize(GTK_WINDOW(m_widget
), w
, h
); 
1000         GetClientSize(&m_oldClientWidth
, &m_oldClientHeight
); 
1001         wxSizeEvent 
event(GetSize(), GetId()); 
1002         event
.SetEventObject(this); 
1003         HandleWindowEvent(event
); 
1007 void wxTopLevelWindowGTK::DoSetClientSize(int width
, int height
) 
1009     base_type::DoSetClientSize(width
, height
); 
1011     // Since client size is being explicitly set, don't change it later 
1012     // Has to be done after calling base because it calls SetSize, 
1013     // which sets this true 
1014     m_deferShowAllowed 
= false; 
1017 void wxTopLevelWindowGTK::DoGetClientSize( int *width
, int *height 
) const 
1019     wxASSERT_MSG(m_widget
, wxT("invalid frame")); 
1023         // for consistency with wxMSW, client area is supposed to be empty for 
1024         // the iconized windows 
1032         GTKDoGetSize(width
, height
); 
1036 void wxTopLevelWindowGTK::DoSetSizeHints( int minW
, int minH
, 
1038                                           int incW
, int incH 
) 
1040     base_type::DoSetSizeHints(minW
, minH
, maxW
, maxH
, incW
, incH
); 
1042     const wxSize minSize 
= GetMinSize(); 
1043     const wxSize maxSize 
= GetMaxSize(); 
1046     if (minSize
.x 
> 0 || minSize
.y 
> 0) 
1048         hints_mask 
|= GDK_HINT_MIN_SIZE
; 
1049         hints
.min_width 
= minSize
.x 
- m_decorSize
.x
; 
1050         if (hints
.min_width 
< 0) 
1051             hints
.min_width 
= 0; 
1052         hints
.min_height 
= minSize
.y 
- m_decorSize
.y
; 
1053         if (hints
.min_height 
< 0) 
1054             hints
.min_height 
= 0; 
1056     if (maxSize
.x 
> 0 || maxSize
.y 
> 0) 
1058         hints_mask 
|= GDK_HINT_MAX_SIZE
; 
1059         hints
.max_width 
= maxSize
.x 
- m_decorSize
.x
; 
1060         if (hints
.max_width 
< 0) 
1061             hints
.max_width 
= INT_MAX
; 
1062         hints
.max_height 
= maxSize
.y 
- m_decorSize
.y
; 
1063         if (hints
.max_height 
< 0) 
1064             hints
.max_height 
= INT_MAX
; 
1066     if (incW 
> 0 || incH 
> 0) 
1068         hints_mask 
|= GDK_HINT_RESIZE_INC
; 
1069         hints
.width_inc  
= incW 
> 0 ? incW 
: 1; 
1070         hints
.height_inc 
= incH 
> 0 ? incH 
: 1; 
1072     gtk_window_set_geometry_hints( 
1073         (GtkWindow
*)m_widget
, NULL
, &hints
, (GdkWindowHints
)hints_mask
); 
1076 void wxTopLevelWindowGTK::GTKUpdateDecorSize(const wxSize
& decorSize
) 
1078     if (!IsMaximized() && !IsFullScreen()) 
1079         GetCachedDecorSize() = decorSize
; 
1080     if (m_updateDecorSize 
&& m_decorSize 
!= decorSize
) 
1082         const wxSize diff 
= decorSize 
- m_decorSize
; 
1083         m_decorSize 
= decorSize
; 
1084         bool resized 
= false; 
1087             // keep overall size unchanged by shrinking m_widget 
1089             GTKDoGetSize(&w
, &h
); 
1090             // but not if size would be less than minimum, it won't take effect 
1091             const wxSize minSize 
= GetMinSize(); 
1092             if (w 
>= minSize
.x 
&& h 
>= minSize
.y
) 
1094                 gtk_window_resize(GTK_WINDOW(m_widget
), w
, h
); 
1100             // adjust overall size to match change in frame extents 
1103             if (m_width  
< 0) m_width  
= 0; 
1104             if (m_height 
< 0) m_height 
= 0; 
1105             m_oldClientWidth 
= 0; 
1106             gtk_widget_queue_resize(m_wxwindow
); 
1111         // gtk_widget_show() was deferred, do it now 
1112         m_deferShow 
= false; 
1113         GetClientSize(&m_oldClientWidth
, &m_oldClientHeight
); 
1114         wxSizeEvent 
sizeEvent(GetSize(), GetId()); 
1115         sizeEvent
.SetEventObject(this); 
1116         HandleWindowEvent(sizeEvent
); 
1118         gtk_widget_show(m_widget
); 
1120         wxShowEvent 
showEvent(GetId(), true); 
1121         showEvent
.SetEventObject(this); 
1122         HandleWindowEvent(showEvent
); 
1126 wxSize
& wxTopLevelWindowGTK::GetCachedDecorSize() 
1128     static wxSize size
[8]; 
1132     if (m_gdkDecor 
& (GDK_DECOR_MENU 
| GDK_DECOR_MINIMIZE 
| GDK_DECOR_MAXIMIZE 
| GDK_DECOR_TITLE
)) 
1135     if (m_gdkDecor 
& GDK_DECOR_BORDER
) 
1137     // utility window decor can be different 
1138     if (m_windowStyle 
& wxFRAME_TOOL_WINDOW
) 
1143 void wxTopLevelWindowGTK::OnInternalIdle() 
1145     wxWindow::OnInternalIdle(); 
1147     // Synthetize activate events. 
1148     if ( g_sendActivateEvent 
!= -1 ) 
1150         bool activate 
= g_sendActivateEvent 
!= 0; 
1152         // if (!activate) wxPrintf( wxT("de") ); 
1153         // wxPrintf( wxT("activate\n") ); 
1156         g_sendActivateEvent 
= -1; 
1158         wxTheApp
->SetActive(activate
, (wxWindow 
*)g_lastActiveFrame
); 
1162 // ---------------------------------------------------------------------------- 
1164 // ---------------------------------------------------------------------------- 
1166 void wxTopLevelWindowGTK::SetTitle( const wxString 
&title 
) 
1168     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
1170     if ( title 
== m_title 
) 
1175     gtk_window_set_title( GTK_WINDOW(m_widget
), wxGTK_CONV( title 
) ); 
1178 void wxTopLevelWindowGTK::SetIcons( const wxIconBundle 
&icons 
) 
1180     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
1182     base_type::SetIcons(icons
); 
1184     // Setting icons before window is realized can cause a GTK assertion if 
1185     // another TLW is realized before this one, and it has this one as it's 
1186     // transient parent. The life demo exibits this problem. 
1187     if (GTK_WIDGET_REALIZED(m_widget
)) 
1190         for (size_t i 
= icons
.GetIconCount(); i
--;) 
1191             list 
= g_list_prepend(list
, icons
.GetIconByIndex(i
).GetPixbuf()); 
1192         gtk_window_set_icon_list(GTK_WINDOW(m_widget
), list
); 
1197 // ---------------------------------------------------------------------------- 
1198 // frame state: maximized/iconized/normal 
1199 // ---------------------------------------------------------------------------- 
1201 void wxTopLevelWindowGTK::Maximize(bool maximize
) 
1204         gtk_window_maximize( GTK_WINDOW( m_widget 
) ); 
1206         gtk_window_unmaximize( GTK_WINDOW( m_widget 
) ); 
1209 bool wxTopLevelWindowGTK::IsMaximized() const 
1211     if(!m_widget
->window
) 
1214     return gdk_window_get_state(m_widget
->window
) & GDK_WINDOW_STATE_MAXIMIZED
; 
1217 void wxTopLevelWindowGTK::Restore() 
1219     // "Present" seems similar enough to "restore" 
1220     gtk_window_present( GTK_WINDOW( m_widget 
) ); 
1223 void wxTopLevelWindowGTK::Iconize( bool iconize 
) 
1226         gtk_window_iconify( GTK_WINDOW( m_widget 
) ); 
1228         gtk_window_deiconify( GTK_WINDOW( m_widget 
) ); 
1231 bool wxTopLevelWindowGTK::IsIconized() const 
1233     return m_isIconized
; 
1236 void wxTopLevelWindowGTK::SetIconizeState(bool iconize
) 
1238     if ( iconize 
!= m_isIconized 
) 
1240         m_isIconized 
= iconize
; 
1241         (void)SendIconizeEvent(iconize
); 
1245 void wxTopLevelWindowGTK::AddGrab() 
1250         gtk_grab_add( m_widget 
); 
1251         wxGUIEventLoop().Run(); 
1252         gtk_grab_remove( m_widget 
); 
1256 void wxTopLevelWindowGTK::RemoveGrab() 
1267 static bool do_shape_combine_region(GdkWindow
* window
, const wxRegion
& region
) 
1271         if (region
.IsEmpty()) 
1273             gdk_window_shape_combine_mask(window
, NULL
, 0, 0); 
1277             gdk_window_shape_combine_region(window
, region
.GetRegion(), 0, 0); 
1285 bool wxTopLevelWindowGTK::SetShape(const wxRegion
& region
) 
1287     wxCHECK_MSG( HasFlag(wxFRAME_SHAPED
), false, 
1288                  wxT("Shaped windows must be created with the wxFRAME_SHAPED style.")); 
1290     if ( GTK_WIDGET_REALIZED(m_widget
) ) 
1293             do_shape_combine_region(m_wxwindow
->window
, region
); 
1295         return do_shape_combine_region(m_widget
->window
, region
); 
1297     else // not realized yet 
1299         // store the shape to set, it will be really set once we're realized 
1302         // we don't know if we're going to succeed or fail, be optimistic by 
1308 bool wxTopLevelWindowGTK::IsActive() 
1310     return (this == (wxTopLevelWindowGTK
*)g_activeFrame
); 
1313 void wxTopLevelWindowGTK::RequestUserAttention(int flags
) 
1315     bool new_hint_value 
= false; 
1317     // FIXME: This is a workaround to focus handling problem 
1318     // If RequestUserAttention is called for example right after a wxSleep, OnInternalIdle 
1319     // hasn't yet been processed, and the internal focus system is not up to date yet. 
1320     // YieldFor(wxEVT_CATEGORY_UI) ensures the processing of it (hopefully it 
1321     // won't have side effects) - MR 
1322     wxEventLoopBase::GetActive()->YieldFor(wxEVT_CATEGORY_UI
); 
1324     if(m_urgency_hint 
>= 0) 
1325         g_source_remove(m_urgency_hint
); 
1327     m_urgency_hint 
= -2; 
1329     if( GTK_WIDGET_REALIZED(m_widget
) && !IsActive() ) 
1331         new_hint_value 
= true; 
1333         if (flags 
& wxUSER_ATTENTION_INFO
) 
1335             m_urgency_hint 
= g_timeout_add(5000, (GSourceFunc
)gtk_frame_urgency_timer_callback
, this); 
1337             m_urgency_hint 
= -1; 
1341 #if GTK_CHECK_VERSION(2,7,0) 
1342     if(!gtk_check_version(2,7,0)) 
1343         gtk_window_set_urgency_hint(GTK_WINDOW( m_widget 
), new_hint_value
); 
1346         wxgtk_window_set_urgency_hint(GTK_WINDOW( m_widget 
), new_hint_value
); 
1349 void wxTopLevelWindowGTK::SetWindowStyleFlag( long style 
) 
1351     // Store which styles were changed 
1352     long styleChanges 
= style 
^ m_windowStyle
; 
1354     // Process wxWindow styles. This also updates the internal variable 
1355     // Therefore m_windowStyle bits carry now the _new_ style values 
1356     wxWindow::SetWindowStyleFlag(style
); 
1358     // just return for now if widget does not exist yet 
1362     if ( styleChanges 
& wxSTAY_ON_TOP 
) 
1364         gtk_window_set_keep_above(GTK_WINDOW(m_widget
), 
1365                                   m_windowStyle 
& wxSTAY_ON_TOP
); 
1368     if ( styleChanges 
& wxFRAME_NO_TASKBAR 
) 
1370         gtk_window_set_skip_taskbar_hint(GTK_WINDOW(m_widget
), 
1371                                          m_windowStyle 
& wxFRAME_NO_TASKBAR
); 
1375 /* Get the X Window between child and the root window. 
1376    This should usually be the WM managed XID */ 
1377 static Window 
wxGetTopmostWindowX11(Display 
*dpy
, Window child
) 
1379     Window root
, parent
; 
1381     unsigned int nchildren
; 
1383     XQueryTree(dpy
, child
, &root
, &parent
, &children
, &nchildren
); 
1386     while (parent 
!= root
) { 
1388         XQueryTree(dpy
, child
, &root
, &parent
, &children
, &nchildren
); 
1395 bool wxTopLevelWindowGTK::SetTransparent(wxByte alpha
) 
1397     if (!m_widget 
|| !m_widget
->window
) 
1400     Display
* dpy 
= GDK_WINDOW_XDISPLAY (m_widget
->window
); 
1401     // We need to get the X Window that has the root window as the immediate parent 
1402     // and m_widget->window as a child. This should be the X Window that the WM manages and 
1403     // from which the opacity property is checked from. 
1404     Window win 
= wxGetTopmostWindowX11(dpy
, GDK_WINDOW_XID (m_widget
->window
)); 
1407     // Using pure Xlib to not have a GTK version check mess due to gtk2.0 not having GdkDisplay 
1409         XDeleteProperty(dpy
, win
, XInternAtom(dpy
, "_NET_WM_WINDOW_OPACITY", False
)); 
1412         long opacity 
= alpha 
* 0x1010101L
; 
1413         XChangeProperty(dpy
, win
, XInternAtom(dpy
, "_NET_WM_WINDOW_OPACITY", False
), 
1414                         XA_CARDINAL
, 32, PropModeReplace
, 
1415                         (unsigned char *) &opacity
, 1L); 
1421 bool wxTopLevelWindowGTK::CanSetTransparent() 
1423     // allow to override automatic detection as it's far from perfect 
1424     const wxString SYSOPT_TRANSPARENT 
= "gtk.tlw.can-set-transparent"; 
1425     if ( wxSystemOptions::HasOption(SYSOPT_TRANSPARENT
) ) 
1427         return wxSystemOptions::GetOptionInt(SYSOPT_TRANSPARENT
) != 0; 
1430 #if GTK_CHECK_VERSION(2,10,0) 
1431     if (!gtk_check_version(2,10,0)) 
1433         return (gtk_widget_is_composited (m_widget
)); 
1436 #endif // In case of lower versions than gtk+-2.10.0 we could look for _NET_WM_CM_Sn ourselves 
1441 #if 0 // Don't be optimistic here for the sake of wxAUI 
1442     int opcode
, event
, error
; 
1443     // Check for the existence of a RGBA visual instead? 
1444     return XQueryExtension(gdk_x11_get_default_xdisplay (), 
1445                            "Composite", &opcode
, &event
, &error
);