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" 
  39 #ifdef GDK_WINDOWING_X11 
  43 #include "wx/gtk/private/win_gtk.h" 
  45 #ifdef GDK_WINDOWING_X11 
  47 #include "wx/unix/utilsx11.h" 
  50 #include <X11/Xatom.h> 
  52 #endif // GDK_WINDOWING_X11 
  55     #include <hildon-widgets/hildon-program.h> 
  56     #include <hildon-widgets/hildon-window.h> 
  57 #endif // wxUSE_LIBHILDON 
  60     #include <hildon/hildon.h> 
  61 #endif // wxUSE_LIBHILDON2 
  63 // ---------------------------------------------------------------------------- 
  65 // ---------------------------------------------------------------------------- 
  67 // this is incremented while a modal dialog is shown 
  68 int wxOpenModalDialogsCount 
= 0; 
  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 
= NULL
; 
  73 static wxTopLevelWindowGTK 
*g_lastActiveFrame 
= 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 // Whether _NET_REQUEST_FRAME_EXTENTS support is working 
  82 //   0 == not tested yet, 1 == working, 2 == broken 
  83 static int gs_requestFrameExtentsStatus
; 
  85 //----------------------------------------------------------------------------- 
  86 // RequestUserAttention related functions 
  87 //----------------------------------------------------------------------------- 
  90 static void wxgtk_window_set_urgency_hint (GtkWindow 
*win
, 
  93 #if GTK_CHECK_VERSION(2,7,0) 
  94     if (gtk_check_version(2,7,0) == NULL
) 
  95         gtk_window_set_urgency_hint(win
, setting
); 
  99 #ifdef GDK_WINDOWING_X11 
 100         GdkWindow
* window 
= gtk_widget_get_window(GTK_WIDGET(win
)); 
 101         wxCHECK_RET(window
, "wxgtk_window_set_urgency_hint: GdkWindow not realized"); 
 103         Display
* dpy 
= GDK_WINDOW_XDISPLAY(window
); 
 104         Window xid 
= GDK_WINDOW_XID(window
); 
 105         XWMHints
* wm_hints 
= XGetWMHints(dpy
, xid
); 
 108             wm_hints 
= XAllocWMHints(); 
 111             wm_hints
->flags 
|= XUrgencyHint
; 
 113             wm_hints
->flags 
&= ~XUrgencyHint
; 
 115         XSetWMHints(dpy
, xid
, wm_hints
); 
 117 #endif // GDK_WINDOWING_X11 
 120 #define gtk_window_set_urgency_hint wxgtk_window_set_urgency_hint 
 124 static gboolean 
gtk_frame_urgency_timer_callback( wxTopLevelWindowGTK 
*win 
) 
 126     gtk_window_set_urgency_hint(GTK_WINDOW(win
->m_widget
), false); 
 128     win
->m_urgency_hint 
= -2; 
 133 //----------------------------------------------------------------------------- 
 135 //----------------------------------------------------------------------------- 
 138 static gboolean 
gtk_frame_focus_in_callback( GtkWidget 
*widget
, 
 139                                          GdkEvent 
*WXUNUSED(event
), 
 140                                          wxTopLevelWindowGTK 
*win 
) 
 142     switch ( g_sendActivateEvent 
) 
 145             // we've got focus from outside, synthetize wxActivateEvent 
 146             g_sendActivateEvent 
= 1; 
 150             // another our window just lost focus, it was already ours before 
 151             // - don't send any wxActivateEvent 
 152             g_sendActivateEvent 
= -1; 
 157     g_lastActiveFrame 
= g_activeFrame
; 
 159     // wxPrintf( wxT("active: %s\n"), win->GetTitle().c_str() ); 
 161     // MR: wxRequestUserAttention related block 
 162     switch( win
->m_urgency_hint 
) 
 165             g_source_remove( win
->m_urgency_hint 
); 
 166             // no break, fallthrough to remove hint too 
 168             gtk_window_set_urgency_hint(GTK_WINDOW(widget
), false); 
 169             win
->m_urgency_hint 
= -2; 
 175     wxLogTrace(wxT("activate"), wxT("Activating frame %p (from focus_in)"), g_activeFrame
); 
 176     wxActivateEvent 
event(wxEVT_ACTIVATE
, true, g_activeFrame
->GetId()); 
 177     event
.SetEventObject(g_activeFrame
); 
 178     g_activeFrame
->HandleWindowEvent(event
); 
 184 //----------------------------------------------------------------------------- 
 186 //----------------------------------------------------------------------------- 
 190 gboolean 
gtk_frame_focus_out_callback(GtkWidget 
* WXUNUSED(widget
), 
 191                                       GdkEventFocus 
*WXUNUSED(gdk_event
), 
 192                                       wxTopLevelWindowGTK 
* WXUNUSED(win
)) 
 194     // if the focus goes out of our app altogether, OnIdle() will send 
 195     // wxActivateEvent, otherwise gtk_window_focus_in_callback() will reset 
 196     // g_sendActivateEvent to -1 
 197     g_sendActivateEvent 
= 0; 
 199     // wxASSERT_MSG( (g_activeFrame == win), wxT("TLW deactivatd although it wasn't active") ); 
 201     // wxPrintf( wxT("inactive: %s\n"), win->GetTitle().c_str() ); 
 205         wxLogTrace(wxT("activate"), wxT("Activating frame %p (from focus_in)"), g_activeFrame
); 
 206         wxActivateEvent 
event(wxEVT_ACTIVATE
, false, g_activeFrame
->GetId()); 
 207         event
.SetEventObject(g_activeFrame
); 
 208         g_activeFrame
->HandleWindowEvent(event
); 
 210         g_activeFrame 
= NULL
; 
 217 //----------------------------------------------------------------------------- 
 218 // "size_allocate" from m_wxwindow 
 219 //----------------------------------------------------------------------------- 
 223 size_allocate(GtkWidget
*, GtkAllocation
* alloc
, wxTopLevelWindowGTK
* win
) 
 225     if (win
->m_oldClientWidth  
!= alloc
->width 
|| 
 226         win
->m_oldClientHeight 
!= alloc
->height
) 
 228         win
->m_oldClientWidth  
= alloc
->width
; 
 229         win
->m_oldClientHeight 
= alloc
->height
; 
 232         gtk_widget_get_allocation(win
->m_widget
, &a
); 
 233         wxSize 
size(a
.width
, a
.height
); 
 234         size 
+= win
->m_decorSize
; 
 235         win
->m_width  
= size
.x
; 
 236         win
->m_height 
= size
.y
; 
 238         if (!win
->IsIconized()) 
 240             wxSizeEvent 
event(size
, win
->GetId()); 
 241             event
.SetEventObject(win
); 
 242             win
->HandleWindowEvent(event
); 
 244         // else the window is currently unmapped, don't generate size events 
 249 //----------------------------------------------------------------------------- 
 251 //----------------------------------------------------------------------------- 
 255 gtk_frame_delete_callback( GtkWidget 
*WXUNUSED(widget
), 
 256                            GdkEvent 
*WXUNUSED(event
), 
 257                            wxTopLevelWindowGTK 
*win 
) 
 259     if (win
->IsEnabled() && 
 260         (wxOpenModalDialogsCount 
== 0 || (win
->GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
) || 
 268 //----------------------------------------------------------------------------- 
 270 //----------------------------------------------------------------------------- 
 274 gtk_frame_configure_callback( GtkWidget
* widget
, 
 275                               GdkEventConfigure 
*WXUNUSED(event
), 
 276                               wxTopLevelWindowGTK 
*win 
) 
 278     if (!win
->m_hasVMT 
|| !win
->IsShown()) 
 282     gtk_window_get_position((GtkWindow
*)widget
, &point
.x
, &point
.y
); 
 286     wxMoveEvent 
mevent(point
, win
->GetId()); 
 287     mevent
.SetEventObject( win 
); 
 288     win
->HandleWindowEvent( mevent 
); 
 294 //----------------------------------------------------------------------------- 
 295 // "realize" from m_widget 
 296 //----------------------------------------------------------------------------- 
 298 // we cannot the WM hints and icons before the widget has been realized, 
 299 // so we do this directly after realization 
 301 void wxTopLevelWindowGTK::GTKHandleRealized() 
 303     wxNonOwnedWindow::GTKHandleRealized(); 
 305     gdk_window_set_decorations(gtk_widget_get_window(m_widget
), 
 306                                (GdkWMDecoration
)m_gdkDecor
); 
 307     gdk_window_set_functions(gtk_widget_get_window(m_widget
), 
 308                                (GdkWMFunction
)m_gdkFunc
); 
 310     // GTK's shrinking/growing policy 
 311     if ( !(m_gdkFunc 
& GDK_FUNC_RESIZE
) ) 
 312         gtk_window_set_resizable(GTK_WINDOW(m_widget
), FALSE
); 
 313 #if !GTK_CHECK_VERSION(3,0,0) && !defined(GTK_DISABLE_DEPRECATED) 
 315         gtk_window_set_policy(GTK_WINDOW(m_widget
), 1, 1, 1); 
 318     const wxIconBundle
& icons 
= GetIcons(); 
 319     if (icons
.GetIconCount()) 
 323 //----------------------------------------------------------------------------- 
 324 // "map_event" from m_widget 
 325 //----------------------------------------------------------------------------- 
 329 gtk_frame_map_callback( GtkWidget
*, 
 330                         GdkEvent 
* WXUNUSED(event
), 
 331                         wxTopLevelWindow 
*win 
) 
 333     const bool wasIconized 
= win
->IsIconized(); 
 336         // Because GetClientSize() returns (0,0) when IsIconized() is true, 
 337         // a size event must be generated, just in case GetClientSize() was 
 338         // called while iconized. This specifically happens when restoring a 
 339         // tlw that was "rolled up" with some WMs. 
 340         // Queue a resize rather than sending size event directly to allow 
 341         // children to be made visible first. 
 342         win
->m_oldClientWidth 
= 0; 
 343         gtk_widget_queue_resize(win
->m_wxwindow
); 
 345     // it is possible for m_isShown to be false here, see bug #9909 
 346     if (win
->wxWindowBase::Show(true)) 
 348         wxShowEvent 
eventShow(win
->GetId(), true); 
 349         eventShow
.SetEventObject(win
); 
 350         win
->GetEventHandler()->ProcessEvent(eventShow
); 
 353 #if GTK_CHECK_VERSION(2,6,0) 
 354     if (!gtk_check_version(2,6,0)) 
 356         // restore focus-on-map setting in case ShowWithoutActivating() was called 
 357         gtk_window_set_focus_on_map(GTK_WINDOW(win
->m_widget
), true); 
 365 //----------------------------------------------------------------------------- 
 366 // "window-state-event" from m_widget 
 367 //----------------------------------------------------------------------------- 
 371 gtk_frame_window_state_callback( GtkWidget
* WXUNUSED(widget
), 
 372                           GdkEventWindowState 
*event
, 
 373                           wxTopLevelWindow 
*win 
) 
 375     if (event
->changed_mask 
& GDK_WINDOW_STATE_ICONIFIED
) 
 376         win
->SetIconizeState((event
->new_window_state 
& GDK_WINDOW_STATE_ICONIFIED
) != 0); 
 378     // if maximized bit changed and it is now set 
 379     if (event
->changed_mask 
& event
->new_window_state 
& GDK_WINDOW_STATE_MAXIMIZED
) 
 381         wxMaximizeEvent 
event(win
->GetId()); 
 382         event
.SetEventObject(win
); 
 383         win
->HandleWindowEvent(event
); 
 390 //----------------------------------------------------------------------------- 
 392 bool wxGetFrameExtents(GdkWindow
* window
, int* left
, int* right
, int* top
, int* bottom
) 
 394 #ifdef GDK_WINDOWING_X11 
 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]); 
 425 //----------------------------------------------------------------------------- 
 426 // "property_notify_event" from m_widget 
 427 //----------------------------------------------------------------------------- 
 430 static gboolean 
property_notify_event( 
 431     GtkWidget
*, GdkEventProperty
* event
, wxTopLevelWindowGTK
* win
) 
 433     // Watch for changes to _NET_FRAME_EXTENTS property 
 434     static GdkAtom property 
= gdk_atom_intern("_NET_FRAME_EXTENTS", false); 
 435     if (event
->state 
== GDK_PROPERTY_NEW_VALUE 
&& event
->atom 
== property
) 
 437         if (win
->m_netFrameExtentsTimerId
) 
 439             // WM support for _NET_REQUEST_FRAME_EXTENTS is working 
 440             gs_requestFrameExtentsStatus 
= 1; 
 441             g_source_remove(win
->m_netFrameExtentsTimerId
); 
 442             win
->m_netFrameExtentsTimerId 
= 0; 
 445         wxSize decorSize 
= win
->m_decorSize
; 
 446         int left
, right
, top
, bottom
; 
 447         if (wxGetFrameExtents(event
->window
, &left
, &right
, &top
, &bottom
)) 
 448             decorSize
.Set(left 
+ right
, top 
+ bottom
); 
 450         win
->GTKUpdateDecorSize(decorSize
); 
 457 static gboolean 
request_frame_extents_timeout(void* data
) 
 459     // WM support for _NET_REQUEST_FRAME_EXTENTS is broken 
 460     gs_requestFrameExtentsStatus 
= 2; 
 462     wxTopLevelWindowGTK
* win 
= static_cast<wxTopLevelWindowGTK
*>(data
); 
 463     win
->m_netFrameExtentsTimerId 
= 0; 
 464     wxSize decorSize 
= win
->m_decorSize
; 
 465     int left
, right
, top
, bottom
; 
 466     if (wxGetFrameExtents(gtk_widget_get_window(win
->m_widget
), &left
, &right
, &top
, &bottom
)) 
 467         decorSize
.Set(left 
+ right
, top 
+ bottom
); 
 468     win
->GTKUpdateDecorSize(decorSize
); 
 474 // ---------------------------------------------------------------------------- 
 475 // wxTopLevelWindowGTK creation 
 476 // ---------------------------------------------------------------------------- 
 478 void wxTopLevelWindowGTK::Init() 
 481     m_isIconized 
= false; 
 482     m_fsIsShowing 
= false; 
 483     m_themeEnabled 
= true; 
 488     m_deferShowAllowed 
= true; 
 489     m_updateDecorSize 
= true; 
 490     m_netFrameExtentsTimerId 
= 0; 
 495 bool wxTopLevelWindowGTK::Create( wxWindow 
*parent
, 
 497                                   const wxString
& title
, 
 499                                   const wxSize
& sizeOrig
, 
 501                                   const wxString 
&name 
) 
 503     // always create a frame of some reasonable, even if arbitrary, size (at 
 504     // least for MSW compatibility) 
 505     wxSize size 
= sizeOrig
; 
 506     size
.x 
= WidthDefault(size
.x
); 
 507     size
.y 
= HeightDefault(size
.y
); 
 509     wxTopLevelWindows
.Append( this ); 
 511     if (!PreCreation( parent
, pos
, size 
) || 
 512         !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name 
)) 
 514         wxFAIL_MSG( wxT("wxTopLevelWindowGTK creation failed") ); 
 520     // NB: m_widget may be !=NULL if it was created by derived class' Create, 
 521     //     e.g. in wxTaskBarIconAreaGTK 
 522     if (m_widget 
== NULL
) 
 524 #if wxUSE_LIBHILDON || wxUSE_LIBHILDON2 
 525         // we must create HildonWindow and not a normal GtkWindow as the latter 
 526         // doesn't look correctly in Maemo environment and it must also be 
 527         // registered with the main program object 
 528         m_widget 
= hildon_window_new(); 
 529         hildon_program_add_window(wxTheApp
->GetHildonProgram(), 
 530                                   HILDON_WINDOW(m_widget
)); 
 531 #else // !wxUSE_LIBHILDON || !wxUSE_LIBHILDON2 
 532         m_widget 
= gtk_window_new(GTK_WINDOW_TOPLEVEL
); 
 533         if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
) 
 535             // Tell WM that this is a dialog window and make it center 
 536             // on parent by default (this is what GtkDialog ctor does): 
 537             gtk_window_set_type_hint(GTK_WINDOW(m_widget
), 
 538                                      GDK_WINDOW_TYPE_HINT_DIALOG
); 
 539             gtk_window_set_position(GTK_WINDOW(m_widget
), 
 540                                     GTK_WIN_POS_CENTER_ON_PARENT
); 
 544             if (style 
& wxFRAME_TOOL_WINDOW
) 
 546                 gtk_window_set_type_hint(GTK_WINDOW(m_widget
), 
 547                                          GDK_WINDOW_TYPE_HINT_UTILITY
); 
 549                 // On some WMs, like KDE, a TOOL_WINDOW will still show 
 550                 // on the taskbar, but on Gnome a TOOL_WINDOW will not. 
 551                 // For consistency between WMs and with Windows, we 
 552                 // should set the NO_TASKBAR flag which will apply 
 553                 // the set_skip_taskbar_hint if it is available, 
 554                 // ensuring no taskbar entry will appear. 
 555                 style 
|= wxFRAME_NO_TASKBAR
; 
 558 #endif // wxUSE_LIBHILDON || wxUSE_LIBHILDON2/!wxUSE_LIBHILDON || !wxUSE_LIBHILDON2 
 560         g_object_ref(m_widget
); 
 563     wxWindow 
*topParent 
= wxGetTopLevelParent(m_parent
); 
 564     if (topParent 
&& (((GTK_IS_WINDOW(topParent
->m_widget
)) && 
 565                        (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
)) || 
 566                        (style 
& wxFRAME_FLOAT_ON_PARENT
))) 
 568         gtk_window_set_transient_for( GTK_WINDOW(m_widget
), 
 569                                       GTK_WINDOW(topParent
->m_widget
) ); 
 572     if (style 
& wxFRAME_NO_TASKBAR
) 
 574         gtk_window_set_skip_taskbar_hint(GTK_WINDOW(m_widget
), TRUE
); 
 577     if (style 
& wxSTAY_ON_TOP
) 
 579         gtk_window_set_keep_above(GTK_WINDOW(m_widget
), TRUE
); 
 581     if (style 
& wxMAXIMIZE
) 
 582         gtk_window_maximize(GTK_WINDOW(m_widget
)); 
 586         gtk_window_set_role( GTK_WINDOW(m_widget
), wxGTK_CONV( name 
) ); 
 589     gtk_window_set_title( GTK_WINDOW(m_widget
), wxGTK_CONV( title 
) ); 
 590     gtk_widget_set_can_focus(m_widget
, false); 
 592     g_signal_connect (m_widget
, "delete_event", 
 593                       G_CALLBACK (gtk_frame_delete_callback
), this); 
 595     // m_mainWidget is a GtkVBox, holding the bars and client area (m_wxwindow) 
 596     m_mainWidget 
= gtk_vbox_new(false, 0); 
 597     gtk_widget_show( m_mainWidget 
); 
 598     gtk_widget_set_can_focus(m_mainWidget
, false); 
 599     gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget 
); 
 601     // m_wxwindow is the client area 
 602     m_wxwindow 
= wxPizza::New(); 
 603     gtk_widget_show( m_wxwindow 
); 
 604     gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow 
); 
 606     // we donm't allow the frame to get the focus as otherwise 
 607     // the frame will grab it at arbitrary focus changes 
 608     gtk_widget_set_can_focus(m_wxwindow
, false); 
 610     if (m_parent
) m_parent
->AddChild( this ); 
 612     g_signal_connect(m_wxwindow
, "size_allocate", 
 613         G_CALLBACK(size_allocate
), this); 
 617 #if !GTK_CHECK_VERSION(3,0,0) && !defined(GTK_DISABLE_DEPRECATED) 
 618     if ((m_x 
!= -1) || (m_y 
!= -1)) 
 619         gtk_widget_set_uposition( m_widget
, m_x
, m_y 
); 
 622     // for some reported size corrections 
 623     g_signal_connect (m_widget
, "map_event", 
 624                       G_CALLBACK (gtk_frame_map_callback
), this); 
 626     // for iconized state 
 627     g_signal_connect (m_widget
, "window_state_event", 
 628                       G_CALLBACK (gtk_frame_window_state_callback
), this); 
 632     g_signal_connect (m_widget
, "configure_event", 
 633                       G_CALLBACK (gtk_frame_configure_callback
), this); 
 636     g_signal_connect_after (m_widget
, "focus_in_event", 
 637                       G_CALLBACK (gtk_frame_focus_in_callback
), this); 
 638     g_signal_connect_after (m_widget
, "focus_out_event", 
 639                       G_CALLBACK (gtk_frame_focus_out_callback
), this); 
 641     gtk_widget_add_events(m_widget
, GDK_PROPERTY_CHANGE_MASK
); 
 642     g_signal_connect(m_widget
, "property_notify_event", 
 643         G_CALLBACK(property_notify_event
), this); 
 645     // translate wx decorations styles into Motif WM hints (they are recognized 
 646     // by other WMs as well) 
 648     // always enable moving the window as we have no separate flag for enabling 
 650     m_gdkFunc 
= GDK_FUNC_MOVE
; 
 652     if ( style 
& wxCLOSE_BOX 
) 
 653         m_gdkFunc 
|= GDK_FUNC_CLOSE
; 
 655     if ( style 
& wxMINIMIZE_BOX 
) 
 656         m_gdkFunc 
|= GDK_FUNC_MINIMIZE
; 
 658     if ( style 
& wxMAXIMIZE_BOX 
) 
 659         m_gdkFunc 
|= GDK_FUNC_MAXIMIZE
; 
 661     if ( (style 
& wxSIMPLE_BORDER
) || (style 
& wxNO_BORDER
) ) 
 667         m_gdkDecor 
= GDK_DECOR_BORDER
; 
 669         if ( style 
& wxCAPTION 
) 
 670             m_gdkDecor 
|= GDK_DECOR_TITLE
; 
 672         if ( style 
& wxSYSTEM_MENU 
) 
 673             m_gdkDecor 
|= GDK_DECOR_MENU
; 
 675         if ( style 
& wxMINIMIZE_BOX 
) 
 676             m_gdkDecor 
|= GDK_DECOR_MINIMIZE
; 
 678         if ( style 
& wxMAXIMIZE_BOX 
) 
 679             m_gdkDecor 
|= GDK_DECOR_MAXIMIZE
; 
 681         if ( style 
& wxRESIZE_BORDER 
) 
 683            m_gdkFunc 
|= GDK_FUNC_RESIZE
; 
 684            m_gdkDecor 
|= GDK_DECOR_RESIZEH
; 
 688     // GTK sometimes chooses very small size if max size hint is not explicitly set 
 689     DoSetSizeHints(m_minWidth
, m_minHeight
, m_maxWidth
, m_maxHeight
, -1, -1); 
 691     m_decorSize 
= GetCachedDecorSize(); 
 693     GTKDoGetSize(&w
, &h
); 
 694     gtk_window_set_default_size(GTK_WINDOW(m_widget
), w
, h
); 
 699 wxTopLevelWindowGTK::~wxTopLevelWindowGTK() 
 701     if ( m_netFrameExtentsTimerId 
) 
 703         // Don't let the timer callback fire as the window pointer passed to it 
 704         // will become invalid very soon. 
 705         g_source_remove(m_netFrameExtentsTimerId
); 
 708 #if wxUSE_LIBHILDON || wxUSE_LIBHILDON2 
 709     // it can also be a (standard) dialog 
 710     if ( HILDON_IS_WINDOW(m_widget
) ) 
 712         hildon_program_remove_window(wxTheApp
->GetHildonProgram(), 
 713                                      HILDON_WINDOW(m_widget
)); 
 715 #endif // wxUSE_LIBHILDON || wxUSE_LIBHILDON2 
 719         wxFAIL_MSG(wxT("Window still grabbed")); 
 725     // it may also be GtkScrolledWindow in the case of an MDI child 
 726     if (GTK_IS_WINDOW(m_widget
)) 
 728         gtk_window_set_focus( GTK_WINDOW(m_widget
), NULL 
); 
 731     if (g_activeFrame 
== this) 
 732         g_activeFrame 
= NULL
; 
 733     if (g_lastActiveFrame 
== this) 
 734         g_lastActiveFrame 
= NULL
; 
 737 bool wxTopLevelWindowGTK::EnableCloseButton( bool enable 
) 
 740         m_gdkFunc 
|= GDK_FUNC_CLOSE
; 
 742         m_gdkFunc 
&= ~GDK_FUNC_CLOSE
; 
 744     GdkWindow
* window 
= gtk_widget_get_window(m_widget
); 
 746         gdk_window_set_functions(window
, (GdkWMFunction
)m_gdkFunc
); 
 751 bool wxTopLevelWindowGTK::ShowFullScreen(bool show
, long) 
 753     if (show 
== m_fsIsShowing
) 
 754         return false; // return what? 
 756     m_fsIsShowing 
= show
; 
 758 #ifdef GDK_WINDOWING_X11 
 759     wxX11FullScreenMethod method 
= 
 760         wxGetFullScreenMethodX11((WXDisplay
*)GDK_DISPLAY(), 
 761                                  (WXWindow
)GDK_ROOT_WINDOW()); 
 763     // NB: gtk_window_fullscreen() uses freedesktop.org's WMspec extensions 
 764     //     to switch to fullscreen, which is not always available. We must 
 765     //     check if WM supports the spec and use legacy methods if it 
 767     if ( method 
== wxX11_FS_WMSPEC 
) 
 768 #endif // GDK_WINDOWING_X11 
 771             gtk_window_fullscreen( GTK_WINDOW( m_widget 
) ); 
 773             gtk_window_unfullscreen( GTK_WINDOW( m_widget 
) ); 
 775 #ifdef GDK_WINDOWING_X11 
 778         GdkWindow
* window 
= gtk_widget_get_window(m_widget
); 
 782             GetPosition( &m_fsSaveFrame
.x
, &m_fsSaveFrame
.y 
); 
 783             GetSize( &m_fsSaveFrame
.width
, &m_fsSaveFrame
.height 
); 
 785             int screen_width
,screen_height
; 
 786             wxDisplaySize( &screen_width
, &screen_height 
); 
 788             gint client_x
, client_y
, root_x
, root_y
; 
 791             m_fsSaveGdkFunc 
= m_gdkFunc
; 
 792             m_fsSaveGdkDecor 
= m_gdkDecor
; 
 793             m_gdkFunc 
= m_gdkDecor 
= 0; 
 794             gdk_window_set_decorations(window
, (GdkWMDecoration
)0); 
 795             gdk_window_set_functions(window
, (GdkWMFunction
)0); 
 797             gdk_window_get_origin(window
, &root_x
, &root_y
); 
 798             gdk_window_get_geometry(window
, &client_x
, &client_y
, &width
, &height
, NULL
); 
 800             gdk_window_move_resize( 
 801                 window
, -client_x
, -client_y
, screen_width 
+ 1, screen_height 
+ 1); 
 803             wxSetFullScreenStateX11((WXDisplay
*)GDK_DISPLAY(), 
 804                                     (WXWindow
)GDK_ROOT_WINDOW(), 
 805                                     (WXWindow
)GDK_WINDOW_XWINDOW(window
), 
 806                                     show
, &m_fsSaveFrame
, method
); 
 810             m_gdkFunc 
= m_fsSaveGdkFunc
; 
 811             m_gdkDecor 
= m_fsSaveGdkDecor
; 
 812             gdk_window_set_decorations(window
, (GdkWMDecoration
)m_gdkDecor
); 
 813             gdk_window_set_functions(window
, (GdkWMFunction
)m_gdkFunc
); 
 815             wxSetFullScreenStateX11((WXDisplay
*)GDK_DISPLAY(), 
 816                                     (WXWindow
)GDK_ROOT_WINDOW(), 
 817                                     (WXWindow
)GDK_WINDOW_XWINDOW(window
), 
 818                                     show
, &m_fsSaveFrame
, method
); 
 820             SetSize(m_fsSaveFrame
.x
, m_fsSaveFrame
.y
, 
 821                     m_fsSaveFrame
.width
, m_fsSaveFrame
.height
); 
 824 #endif // GDK_WINDOWING_X11 
 826     // documented behaviour is to show the window if it's still hidden when 
 827     // showing it full screen 
 834 // ---------------------------------------------------------------------------- 
 835 // overridden wxWindow methods 
 836 // ---------------------------------------------------------------------------- 
 838 void wxTopLevelWindowGTK::Refresh( bool WXUNUSED(eraseBackground
), const wxRect 
*WXUNUSED(rect
) ) 
 840     wxCHECK_RET( m_widget
, wxT("invalid frame") ); 
 842     gtk_widget_queue_draw( m_widget 
); 
 844     GdkWindow
* window 
= NULL
; 
 846         window 
= gtk_widget_get_window(m_wxwindow
); 
 848         gdk_window_invalidate_rect(window
, NULL
, true); 
 851 bool wxTopLevelWindowGTK::Show( bool show 
) 
 853     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 855     bool deferShow 
= show 
&& !m_isShown 
&& m_deferShow
; 
 858         deferShow 
= gs_requestFrameExtentsStatus 
!= 2 && 
 859             m_deferShowAllowed 
&& !gtk_widget_get_realized(m_widget
); 
 862             deferShow 
= g_signal_handler_find(m_widget
, 
 863                 GSignalMatchType(G_SIGNAL_MATCH_ID 
| G_SIGNAL_MATCH_DATA
), 
 864                 g_signal_lookup("property_notify_event", GTK_TYPE_WIDGET
), 
 865                 0, NULL
, NULL
, this) != 0; 
 867         GdkScreen
* screen 
= NULL
; 
 870 #ifdef GDK_WINDOWING_X11 
 871             screen 
= gtk_widget_get_screen(m_widget
); 
 872             GdkAtom atom 
= gdk_atom_intern("_NET_REQUEST_FRAME_EXTENTS", false); 
 873             deferShow 
= gdk_x11_screen_supports_net_wm_hint(screen
, atom
) != 0; 
 877             // If _NET_REQUEST_FRAME_EXTENTS not supported, don't allow changes 
 878             // to m_decorSize, it breaks saving/restoring window size with 
 879             // GetSize()/SetSize() because it makes window bigger between each 
 881             m_updateDecorSize 
= deferShow
; 
 884         m_deferShow 
= deferShow
; 
 888         // Initial show. If WM supports _NET_REQUEST_FRAME_EXTENTS, defer 
 889         // calling gtk_widget_show() until _NET_FRAME_EXTENTS property 
 890         // notification is received, so correct frame extents are known. 
 891         // This allows resizing m_widget to keep the overall size in sync with 
 892         // what wxWidgets expects it to be without an obvious change in the 
 893         // window size immediately after it becomes visible. 
 895         // Realize m_widget, so m_widget->window can be used. Realizing normally 
 896         // causes the widget tree to be size_allocated, which generates size 
 897         // events in the wrong order. However, the size_allocates will not be 
 898         // done if the allocation is not the default (1,1). 
 900         gtk_widget_get_allocation(m_widget
, &alloc
); 
 901         const int alloc_width 
= alloc
.width
; 
 902         if (alloc_width 
== 1) 
 905             gtk_widget_set_allocation(m_widget
, &alloc
); 
 907         gtk_widget_realize(m_widget
); 
 908         if (alloc_width 
== 1) 
 911             gtk_widget_set_allocation(m_widget
, &alloc
); 
 914 #ifdef GDK_WINDOWING_X11 
 915         // send _NET_REQUEST_FRAME_EXTENTS 
 916         XClientMessageEvent xevent
; 
 917         memset(&xevent
, 0, sizeof(xevent
)); 
 918         xevent
.type 
= ClientMessage
; 
 919         GdkWindow
* window 
= gtk_widget_get_window(m_widget
); 
 920         xevent
.window 
= gdk_x11_drawable_get_xid(window
); 
 921         xevent
.message_type 
= gdk_x11_atom_to_xatom_for_display( 
 922             gdk_drawable_get_display(window
), 
 923             gdk_atom_intern("_NET_REQUEST_FRAME_EXTENTS", false)); 
 925         Display
* display 
= gdk_x11_drawable_get_xdisplay(window
); 
 926         XSendEvent(display
, DefaultRootWindow(display
), false, 
 927             SubstructureNotifyMask 
| SubstructureRedirectMask
, 
 929 #endif // GDK_WINDOWING_X11 
 931         if (gs_requestFrameExtentsStatus 
== 0) 
 933             // if WM does not respond to request within 1 second, 
 934             // we assume support for _NET_REQUEST_FRAME_EXTENTS is not working 
 935             m_netFrameExtentsTimerId 
= 
 936                 g_timeout_add(1000, request_frame_extents_timeout
, this); 
 939         // defer calling gtk_widget_show() 
 944     if (show 
&& !gtk_widget_get_realized(m_widget
)) 
 946         // size_allocate signals occur in reverse order (bottom to top). 
 947         // Things work better if the initial wxSizeEvents are sent (from the 
 948         // top down), before the initial size_allocate signals occur. 
 949         wxSizeEvent 
event(GetSize(), GetId()); 
 950         event
.SetEventObject(this); 
 951         HandleWindowEvent(event
); 
 954     bool change 
= base_type::Show(show
); 
 958         // make sure window has a non-default position, so when it is shown 
 959         // again, it won't be repositioned by WM as if it were a new window 
 960         // Note that this must be done _after_ the window is hidden. 
 961         gtk_window_move((GtkWindow
*)m_widget
, m_x
, m_y
); 
 967 void wxTopLevelWindowGTK::ShowWithoutActivating() 
 971 #if GTK_CHECK_VERSION(2,6,0) 
 972         if (!gtk_check_version(2,6,0)) 
 973             gtk_window_set_focus_on_map(GTK_WINDOW(m_widget
), false); 
 980 void wxTopLevelWindowGTK::Raise() 
 982     gtk_window_present( GTK_WINDOW( m_widget 
) ); 
 985 void wxTopLevelWindowGTK::DoMoveWindow(int WXUNUSED(x
), int WXUNUSED(y
), int WXUNUSED(width
), int WXUNUSED(height
) ) 
 987     wxFAIL_MSG( wxT("DoMoveWindow called for wxTopLevelWindowGTK") ); 
 990 // ---------------------------------------------------------------------------- 
 992 // ---------------------------------------------------------------------------- 
 994 void wxTopLevelWindowGTK::GTKDoGetSize(int *width
, int *height
) const 
 996     wxSize 
size(m_width
, m_height
); 
 998     if (size
.x 
< 0) size
.x 
= 0; 
 999     if (size
.y 
< 0) size
.y 
= 0; 
1000 #if wxUSE_LIBHILDON2 
1010        else if (size
.y 
== 270) 
1015 #else // wxUSE_LIBHILDON2 
1016     if (width
)  *width  
= size
.x
; 
1017     if (height
) *height 
= size
.y
; 
1018 #endif // wxUSE_LIBHILDON2 /!wxUSE_LIBHILDON2 
1021 void wxTopLevelWindowGTK::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags 
) 
1023     wxCHECK_RET( m_widget
, wxT("invalid frame") ); 
1025     m_deferShowAllowed 
= true; 
1027     // deal with the position first 
1031     if ( !(sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
) ) 
1033         // -1 means "use existing" unless the flag above is specified 
1039     else // wxSIZE_ALLOW_MINUS_ONE 
1045     if ( m_x 
!= old_x 
|| m_y 
!= old_y 
) 
1047         gtk_window_move( GTK_WINDOW(m_widget
), m_x
, m_y 
); 
1050     const wxSize 
oldSize(m_width
, m_height
); 
1056     if (m_width 
!= oldSize
.x 
|| m_height 
!= oldSize
.y
) 
1059         GTKDoGetSize(&w
, &h
); 
1060         gtk_window_resize(GTK_WINDOW(m_widget
), w
, h
); 
1062         GetClientSize(&m_oldClientWidth
, &m_oldClientHeight
); 
1063         wxSizeEvent 
event(GetSize(), GetId()); 
1064         event
.SetEventObject(this); 
1065         HandleWindowEvent(event
); 
1069 void wxTopLevelWindowGTK::DoSetClientSize(int width
, int height
) 
1071     base_type::DoSetClientSize(width
, height
); 
1073     // Since client size is being explicitly set, don't change it later 
1074     // Has to be done after calling base because it calls SetSize, 
1075     // which sets this true 
1076     m_deferShowAllowed 
= false; 
1079 void wxTopLevelWindowGTK::DoGetClientSize( int *width
, int *height 
) const 
1081     wxASSERT_MSG(m_widget
, wxT("invalid frame")); 
1085         // for consistency with wxMSW, client area is supposed to be empty for 
1086         // the iconized windows 
1094         GTKDoGetSize(width
, height
); 
1098 void wxTopLevelWindowGTK::DoSetSizeHints( int minW
, int minH
, 
1100                                           int incW
, int incH 
) 
1102     base_type::DoSetSizeHints(minW
, minH
, maxW
, maxH
, incW
, incH
); 
1104     const wxSize minSize 
= GetMinSize(); 
1105     const wxSize maxSize 
= GetMaxSize(); 
1107     // always set both min and max hints, otherwise GTK will 
1108     // make assumptions we don't want about the unset values 
1109     int hints_mask 
= GDK_HINT_MIN_SIZE 
| GDK_HINT_MAX_SIZE
; 
1110     hints
.min_width 
= 1; 
1111     hints
.min_height 
= 1; 
1112     hints
.max_width 
= INT_MAX
; 
1113     hints
.max_height 
= INT_MAX
; 
1114     if (minSize
.x 
> m_decorSize
.x
) 
1115         hints
.min_width 
= minSize
.x 
- m_decorSize
.x
; 
1116     if (minSize
.y 
> m_decorSize
.y
) 
1117         hints
.min_height 
= minSize
.y 
- m_decorSize
.y
; 
1118     if (maxSize
.x 
> m_decorSize
.x
) 
1119         hints
.max_width 
= maxSize
.x 
- m_decorSize
.x
; 
1120     if (maxSize
.y 
> m_decorSize
.y
) 
1121         hints
.max_height 
= maxSize
.y 
- m_decorSize
.y
; 
1122     if (incW 
> 0 || incH 
> 0) 
1124         hints_mask 
|= GDK_HINT_RESIZE_INC
; 
1125         hints
.width_inc  
= incW 
> 0 ? incW 
: 1; 
1126         hints
.height_inc 
= incH 
> 0 ? incH 
: 1; 
1128     gtk_window_set_geometry_hints( 
1129         (GtkWindow
*)m_widget
, NULL
, &hints
, (GdkWindowHints
)hints_mask
); 
1132 void wxTopLevelWindowGTK::GTKUpdateDecorSize(const wxSize
& decorSize
) 
1134     if (!IsMaximized() && !IsFullScreen()) 
1135         GetCachedDecorSize() = decorSize
; 
1136     if (m_updateDecorSize 
&& m_decorSize 
!= decorSize
) 
1138         const wxSize diff 
= decorSize 
- m_decorSize
; 
1139         m_decorSize 
= decorSize
; 
1140         bool resized 
= false; 
1143             // keep overall size unchanged by shrinking m_widget 
1145             GTKDoGetSize(&w
, &h
); 
1146             // but not if size would be less than minimum, it won't take effect 
1147             const wxSize minSize 
= GetMinSize(); 
1148             if (w 
>= minSize
.x 
&& h 
>= minSize
.y
) 
1150                 gtk_window_resize(GTK_WINDOW(m_widget
), w
, h
); 
1156             // adjust overall size to match change in frame extents 
1159             if (m_width  
< 0) m_width  
= 0; 
1160             if (m_height 
< 0) m_height 
= 0; 
1161             m_oldClientWidth 
= 0; 
1162             gtk_widget_queue_resize(m_wxwindow
); 
1167         // gtk_widget_show() was deferred, do it now 
1168         m_deferShow 
= false; 
1169         GetClientSize(&m_oldClientWidth
, &m_oldClientHeight
); 
1170         wxSizeEvent 
sizeEvent(GetSize(), GetId()); 
1171         sizeEvent
.SetEventObject(this); 
1172         HandleWindowEvent(sizeEvent
); 
1174         gtk_widget_show(m_widget
); 
1176         wxShowEvent 
showEvent(GetId(), true); 
1177         showEvent
.SetEventObject(this); 
1178         HandleWindowEvent(showEvent
); 
1182 wxSize
& wxTopLevelWindowGTK::GetCachedDecorSize() 
1184     static wxSize size
[8]; 
1188     if (m_gdkDecor 
& (GDK_DECOR_MENU 
| GDK_DECOR_MINIMIZE 
| GDK_DECOR_MAXIMIZE 
| GDK_DECOR_TITLE
)) 
1191     if (m_gdkDecor 
& GDK_DECOR_BORDER
) 
1193     // utility window decor can be different 
1194     if (m_windowStyle 
& wxFRAME_TOOL_WINDOW
) 
1199 void wxTopLevelWindowGTK::OnInternalIdle() 
1201     wxTopLevelWindowBase::OnInternalIdle(); 
1203     // Synthetize activate events. 
1204     if ( g_sendActivateEvent 
!= -1 ) 
1206         bool activate 
= g_sendActivateEvent 
!= 0; 
1208         // if (!activate) wxPrintf( wxT("de") ); 
1209         // wxPrintf( wxT("activate\n") ); 
1212         g_sendActivateEvent 
= -1; 
1214         wxTheApp
->SetActive(activate
, (wxWindow 
*)g_lastActiveFrame
); 
1218 // ---------------------------------------------------------------------------- 
1220 // ---------------------------------------------------------------------------- 
1222 void wxTopLevelWindowGTK::SetTitle( const wxString 
&title 
) 
1224     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
1226     if ( title 
== m_title 
) 
1231     gtk_window_set_title( GTK_WINDOW(m_widget
), wxGTK_CONV( title 
) ); 
1234 void wxTopLevelWindowGTK::SetIcons( const wxIconBundle 
&icons 
) 
1236     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
1238     base_type::SetIcons(icons
); 
1240     // Setting icons before window is realized can cause a GTK assertion if 
1241     // another TLW is realized before this one, and it has this one as it's 
1242     // transient parent. The life demo exibits this problem. 
1243     if (gtk_widget_get_realized(m_widget
)) 
1246         for (size_t i 
= icons
.GetIconCount(); i
--;) 
1247             list 
= g_list_prepend(list
, icons
.GetIconByIndex(i
).GetPixbuf()); 
1248         gtk_window_set_icon_list(GTK_WINDOW(m_widget
), list
); 
1253 // ---------------------------------------------------------------------------- 
1254 // frame state: maximized/iconized/normal 
1255 // ---------------------------------------------------------------------------- 
1257 void wxTopLevelWindowGTK::Maximize(bool maximize
) 
1260         gtk_window_maximize( GTK_WINDOW( m_widget 
) ); 
1262         gtk_window_unmaximize( GTK_WINDOW( m_widget 
) ); 
1265 bool wxTopLevelWindowGTK::IsMaximized() const 
1267     GdkWindow
* window 
= NULL
; 
1269         window 
= gtk_widget_get_window(m_widget
); 
1270     return window 
&& (gdk_window_get_state(window
) & GDK_WINDOW_STATE_MAXIMIZED
); 
1273 void wxTopLevelWindowGTK::Restore() 
1275     // "Present" seems similar enough to "restore" 
1276     gtk_window_present( GTK_WINDOW( m_widget 
) ); 
1279 void wxTopLevelWindowGTK::Iconize( bool iconize 
) 
1282         gtk_window_iconify( GTK_WINDOW( m_widget 
) ); 
1284         gtk_window_deiconify( GTK_WINDOW( m_widget 
) ); 
1287 bool wxTopLevelWindowGTK::IsIconized() const 
1289     return m_isIconized
; 
1292 void wxTopLevelWindowGTK::SetIconizeState(bool iconize
) 
1294     if ( iconize 
!= m_isIconized 
) 
1296         m_isIconized 
= iconize
; 
1297         (void)SendIconizeEvent(iconize
); 
1301 void wxTopLevelWindowGTK::AddGrab() 
1306         gtk_grab_add( m_widget 
); 
1307         wxGUIEventLoop().Run(); 
1308         gtk_grab_remove( m_widget 
); 
1312 void wxTopLevelWindowGTK::RemoveGrab() 
1321 bool wxTopLevelWindowGTK::IsActive() 
1323     return (this == (wxTopLevelWindowGTK
*)g_activeFrame
); 
1326 void wxTopLevelWindowGTK::RequestUserAttention(int flags
) 
1328     bool new_hint_value 
= false; 
1330     // FIXME: This is a workaround to focus handling problem 
1331     // If RequestUserAttention is called for example right after a wxSleep, OnInternalIdle 
1332     // hasn't yet been processed, and the internal focus system is not up to date yet. 
1333     // YieldFor(wxEVT_CATEGORY_UI) ensures the processing of it (hopefully it 
1334     // won't have side effects) - MR 
1335     wxEventLoopBase::GetActive()->YieldFor(wxEVT_CATEGORY_UI
); 
1337     if(m_urgency_hint 
>= 0) 
1338         g_source_remove(m_urgency_hint
); 
1340     m_urgency_hint 
= -2; 
1342     if( gtk_widget_get_realized(m_widget
) && !IsActive() ) 
1344         new_hint_value 
= true; 
1346         if (flags 
& wxUSER_ATTENTION_INFO
) 
1348             m_urgency_hint 
= g_timeout_add(5000, (GSourceFunc
)gtk_frame_urgency_timer_callback
, this); 
1350             m_urgency_hint 
= -1; 
1354     gtk_window_set_urgency_hint(GTK_WINDOW(m_widget
), new_hint_value
); 
1357 void wxTopLevelWindowGTK::SetWindowStyleFlag( long style 
) 
1359     // Store which styles were changed 
1360     long styleChanges 
= style 
^ m_windowStyle
; 
1362     // Process wxWindow styles. This also updates the internal variable 
1363     // Therefore m_windowStyle bits carry now the _new_ style values 
1364     wxWindow::SetWindowStyleFlag(style
); 
1366     // just return for now if widget does not exist yet 
1370     if ( styleChanges 
& wxSTAY_ON_TOP 
) 
1372         gtk_window_set_keep_above(GTK_WINDOW(m_widget
), 
1373                                   m_windowStyle 
& wxSTAY_ON_TOP
); 
1376     if ( styleChanges 
& wxFRAME_NO_TASKBAR 
) 
1378         gtk_window_set_skip_taskbar_hint(GTK_WINDOW(m_widget
), 
1379                                          m_windowStyle 
& wxFRAME_NO_TASKBAR
); 
1383 bool wxTopLevelWindowGTK::SetTransparent(wxByte alpha
) 
1385     GdkWindow
* window 
= NULL
; 
1387         window 
= gtk_widget_get_window(m_widget
); 
1391 #ifdef GDK_WINDOWING_X11 
1392     Display
* dpy 
= GDK_WINDOW_XDISPLAY(window
); 
1393     Window win 
= GDK_WINDOW_XID(window
); 
1395     // Using pure Xlib to not have a GTK version check mess due to gtk2.0 not having GdkDisplay 
1397         XDeleteProperty(dpy
, win
, XInternAtom(dpy
, "_NET_WM_WINDOW_OPACITY", False
)); 
1400         long opacity 
= alpha 
* 0x1010101L
; 
1401         XChangeProperty(dpy
, win
, XInternAtom(dpy
, "_NET_WM_WINDOW_OPACITY", False
), 
1402                         XA_CARDINAL
, 32, PropModeReplace
, 
1403                         (unsigned char *) &opacity
, 1L); 
1407 #else // !GDK_WINDOWING_X11 
1409 #endif // GDK_WINDOWING_X11 / !GDK_WINDOWING_X11 
1412 bool wxTopLevelWindowGTK::CanSetTransparent() 
1414     // allow to override automatic detection as it's far from perfect 
1415     const wxString SYSOPT_TRANSPARENT 
= "gtk.tlw.can-set-transparent"; 
1416     if ( wxSystemOptions::HasOption(SYSOPT_TRANSPARENT
) ) 
1418         return wxSystemOptions::GetOptionInt(SYSOPT_TRANSPARENT
) != 0; 
1421 #if GTK_CHECK_VERSION(2,10,0) 
1422     if (!gtk_check_version(2,10,0)) 
1424         return gtk_widget_is_composited(m_widget
) != 0; 
1427 #endif // In case of lower versions than gtk+-2.10.0 we could look for _NET_WM_CM_Sn ourselves 
1432 #if 0 // Don't be optimistic here for the sake of wxAUI 
1433     int opcode
, event
, error
; 
1434     // Check for the existence of a RGBA visual instead? 
1435     return XQueryExtension(gdk_x11_get_default_xdisplay (), 
1436                            "Composite", &opcode
, &event
, &error
);