]> git.saurik.com Git - wxWidgets.git/blob - src/gtk/nativewin.cpp
move wxWindowGTK::DoPopupMenu back to window.cpp
[wxWidgets.git] / src / gtk / nativewin.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/nativewin.cpp
3 // Purpose: wxNativeWindow implementation
4 // Author: Vadim Zeitlin
5 // Created: 2008-03-05
6 // RCS-ID: $Id$
7 // Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwindows.org>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
10
11 // ============================================================================
12 // declarations
13 // ============================================================================
14
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18
19 // for compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 #ifndef WX_PRECOMP
27 #endif // WX_PRECOMP
28
29 #include "wx/nativewin.h"
30
31 #include <gtk/gtk.h>
32
33 #ifdef GDK_WINDOWING_X11
34 #include <X11/Xlib.h>
35 #endif
36
37 // ============================================================================
38 // implementation
39 // ============================================================================
40
41 // TODO: we probably need equivalent code for other GDK platforms
42 #ifdef GDK_WINDOWING_X11
43
44 extern "C" GdkFilterReturn
45 wxNativeContainerWindowFilter(GdkXEvent *gdkxevent,
46 GdkEvent *event,
47 gpointer data)
48 {
49 XEvent * const xevent = static_cast<XEvent *>(gdkxevent);
50 if ( xevent->type == DestroyNotify )
51 {
52 // we won't need it any more
53 gdk_window_remove_filter(event->any.window,
54 wxNativeContainerWindowFilter, data);
55
56 // the underlying window got destroyed, notify the C++ object
57 static_cast<wxNativeContainerWindow *>(data)->OnNativeDestroyed();
58 }
59
60 return GDK_FILTER_CONTINUE;
61 }
62
63 #endif // GDK_WINDOWING_X11
64
65 bool wxNativeContainerWindow::Create(wxNativeContainerWindowHandle win)
66 {
67 wxCHECK( win, false );
68
69 if ( !wxTopLevelWindow::Create(NULL, wxID_ANY, "") )
70 return false;
71
72 // we need to realize the window first before reparenting it
73 gtk_widget_realize(m_widget);
74 gdk_window_reparent(m_widget->window, win, 0, 0);
75
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
81 // destroyed
82 gdk_window_add_filter(m_widget->window, wxNativeContainerWindowFilter, this);
83 #endif // GDK_WINDOWING_X11
84
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)
89 Show();
90
91 return true;
92 }
93
94 bool wxNativeContainerWindow::Create(wxNativeContainerWindowId anid)
95 {
96 bool rc;
97 GdkWindow * const win = gdk_window_foreign_new(anid);
98 if ( win )
99 {
100 rc = Create(win);
101 g_object_unref(win);
102 }
103 else // invalid native window id
104 {
105 rc = false;
106 }
107
108 return rc;
109 }
110
111 void wxNativeContainerWindow::OnNativeDestroyed()
112 {
113 // unfortunately we simply can't do anything else than leak memory here:
114 // we really need to call _gdk_window_destroy(m_widget->win, TRUE) to
115 // indicate that the native window was deleted, but we can't do this
116 // because it's a private GDK function and calling normal
117 // gdk_window_destroy() results in X errors while nulling just the window
118 // pointer and destroying m_widget results in many GTK errors
119 m_widget = NULL;
120
121 // notice that we intentionally don't use Close() nor Delete() here as our
122 // window (and the windows of all of our children) is invalid any more and
123 // any attempts to use it, as may happen with the delayed destruction, will
124 // result in GDK warnings at best and crashes or X errors at worst
125 delete this;
126 }
127
128 wxNativeContainerWindow::~wxNativeContainerWindow()
129 {
130 // nothing to do here, either we have a valid m_widget and it will be
131 // destroyed as usual (this corresponds to manual destruction of this C++
132 // object) or we are being deleted because the native window was destroyed
133 // and in this case our m_widget was set to NULL by OnNativeDestroyed()
134 }