1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/nativewin.cpp
3 // Purpose: wxNativeWindow implementation
4 // Author: Vadim Zeitlin
6 // Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwindows.org>
7 // Licence: wxWindows licence
8 ///////////////////////////////////////////////////////////////////////////////
10 // ============================================================================
12 // ============================================================================
14 // ----------------------------------------------------------------------------
16 // ----------------------------------------------------------------------------
18 // for compilers that support precompilation, includes "wx.h".
19 #include "wx/wxprec.h"
28 #include "wx/nativewin.h"
31 #include "wx/gtk/private/gtk2-compat.h"
33 #ifdef GDK_WINDOWING_X11
37 // ============================================================================
39 // ============================================================================
41 // TODO: we probably need equivalent code for other GDK platforms
42 #ifdef GDK_WINDOWING_X11
44 extern "C" GdkFilterReturn
45 wxNativeContainerWindowFilter(GdkXEvent
*gdkxevent
,
49 XEvent
* const xevent
= static_cast<XEvent
*>(gdkxevent
);
50 if ( xevent
->type
== DestroyNotify
)
52 // we won't need it any more
53 gdk_window_remove_filter(event
->any
.window
,
54 wxNativeContainerWindowFilter
, data
);
56 // the underlying window got destroyed, notify the C++ object
57 static_cast<wxNativeContainerWindow
*>(data
)->OnNativeDestroyed();
60 return GDK_FILTER_CONTINUE
;
63 #endif // GDK_WINDOWING_X11
65 bool wxNativeContainerWindow::Create(wxNativeContainerWindowHandle win
)
67 wxCHECK( win
, false );
69 if ( !wxTopLevelWindow::Create(NULL
, wxID_ANY
, "") )
72 // we need to realize the window first before reparenting it
73 gtk_widget_realize(m_widget
);
74 gdk_window_reparent(gtk_widget_get_window(m_widget
), win
, 0, 0);
76 #ifdef GDK_WINDOWING_X11
77 // if the native window is destroyed, our own window will be destroyed too
78 // but GTK doesn't expect it and will complain about "unexpectedly
79 // destroyed" GdkWindow, so intercept to DestroyNotify ourselves to fix
80 // this and also destroy the associated C++ object when its window is
82 gdk_window_add_filter(gtk_widget_get_window(m_widget
), wxNativeContainerWindowFilter
, this);
83 #endif // GDK_WINDOWING_X11
85 // we should be initially visible as we suppose that the native window we
86 // wrap is (we could use gdk_window_is_visible() to test for this but this
87 // doesn't make much sense unless we also react to visibility changes, so
88 // just suppose it's always shown for now)
94 bool wxNativeContainerWindow::Create(wxNativeContainerWindowId anid
)
98 #ifdef GDK_WINDOWING_X11
99 GdkWindow
* const win
= gdk_x11_window_foreign_new_for_display(gdk_display_get_default(), anid
);
101 GdkWindow
* const win
= NULL
;
104 GdkWindow
* const win
= gdk_window_foreign_new(anid
);
111 else // invalid native window id
119 void wxNativeContainerWindow::OnNativeDestroyed()
121 // unfortunately we simply can't do anything else than leak memory here:
122 // we really need to call _gdk_window_destroy(m_widget->win, TRUE) to
123 // indicate that the native window was deleted, but we can't do this
124 // because it's a private GDK function and calling normal
125 // gdk_window_destroy() results in X errors while nulling just the window
126 // pointer and destroying m_widget results in many GTK errors
127 GTKDisconnect(m_widget
);
130 // notice that we intentionally don't use Close() nor Delete() here as our
131 // window (and the windows of all of our children) is invalid any more and
132 // any attempts to use it, as may happen with the delayed destruction, will
133 // result in GDK warnings at best and crashes or X errors at worst
137 wxNativeContainerWindow::~wxNativeContainerWindow()
139 // nothing to do here, either we have a valid m_widget and it will be
140 // destroyed as usual (this corresponds to manual destruction of this C++
141 // object) or we are being deleted because the native window was destroyed
142 // and in this case our m_widget was set to NULL by OnNativeDestroyed()