]>
Commit | Line | Data |
---|---|---|
dfba244c VZ |
1 | /////////////////////////////////////////////////////////////////////////////// |
2 | // Name: src/gtk/nativewin.cpp | |
3 | // Purpose: wxNativeWindow implementation | |
4 | // Author: Vadim Zeitlin | |
5 | // Created: 2008-03-05 | |
dfba244c VZ |
6 | // Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwindows.org> |
7 | // Licence: wxWindows licence | |
8 | /////////////////////////////////////////////////////////////////////////////// | |
9 | ||
10 | // ============================================================================ | |
11 | // declarations | |
12 | // ============================================================================ | |
13 | ||
14 | // ---------------------------------------------------------------------------- | |
15 | // headers | |
16 | // ---------------------------------------------------------------------------- | |
17 | ||
18 | // for compilers that support precompilation, includes "wx.h". | |
19 | #include "wx/wxprec.h" | |
20 | ||
21 | #ifdef __BORLANDC__ | |
22 | #pragma hdrstop | |
23 | #endif | |
24 | ||
25 | #ifndef WX_PRECOMP | |
26 | #endif // WX_PRECOMP | |
27 | ||
28 | #include "wx/nativewin.h" | |
29 | ||
30 | #include <gtk/gtk.h> | |
385e8575 | 31 | #include "wx/gtk/private/gtk2-compat.h" |
dfba244c | 32 | |
2aee749c | 33 | #ifdef GDK_WINDOWING_X11 |
9dc44eff | 34 | #include <gdk/gdkx.h> |
2aee749c VZ |
35 | #endif |
36 | ||
dfba244c VZ |
37 | // ============================================================================ |
38 | // implementation | |
39 | // ============================================================================ | |
40 | ||
2aee749c VZ |
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 | ||
27547285 | 65 | bool wxNativeContainerWindow::Create(wxNativeContainerWindowHandle win) |
dfba244c | 66 | { |
2aee749c VZ |
67 | wxCHECK( win, false ); |
68 | ||
dfba244c VZ |
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); | |
385e8575 | 74 | gdk_window_reparent(gtk_widget_get_window(m_widget), win, 0, 0); |
dfba244c | 75 | |
2aee749c VZ |
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 | |
385e8575 | 82 | gdk_window_add_filter(gtk_widget_get_window(m_widget), wxNativeContainerWindowFilter, this); |
2aee749c VZ |
83 | #endif // GDK_WINDOWING_X11 |
84 | ||
dfba244c VZ |
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(); | |
27547285 VZ |
90 | |
91 | return true; | |
dfba244c VZ |
92 | } |
93 | ||
94 | bool wxNativeContainerWindow::Create(wxNativeContainerWindowId anid) | |
95 | { | |
96 | bool rc; | |
9dc44eff | 97 | #ifdef __WXGTK3__ |
a73251a8 | 98 | #ifdef GDK_WINDOWING_X11 |
9dc44eff | 99 | GdkWindow * const win = gdk_x11_window_foreign_new_for_display(gdk_display_get_default(), anid); |
a73251a8 VZ |
100 | #else |
101 | GdkWindow * const win = NULL; | |
102 | #endif | |
9dc44eff | 103 | #else |
dfba244c | 104 | GdkWindow * const win = gdk_window_foreign_new(anid); |
9dc44eff | 105 | #endif |
dfba244c VZ |
106 | if ( win ) |
107 | { | |
108 | rc = Create(win); | |
109 | g_object_unref(win); | |
110 | } | |
111 | else // invalid native window id | |
112 | { | |
113 | rc = false; | |
114 | } | |
115 | ||
116 | return rc; | |
117 | } | |
118 | ||
2aee749c VZ |
119 | void wxNativeContainerWindow::OnNativeDestroyed() |
120 | { | |
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 | |
8ab75332 | 127 | GTKDisconnect(m_widget); |
2aee749c VZ |
128 | m_widget = NULL; |
129 | ||
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 | |
134 | delete this; | |
135 | } | |
136 | ||
dfba244c VZ |
137 | wxNativeContainerWindow::~wxNativeContainerWindow() |
138 | { | |
2aee749c VZ |
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() | |
dfba244c | 143 | } |