]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/nativewin.cpp
Second part of #15224 fix: AddRows, AddColumns (dghart)
[wxWidgets.git] / src / gtk / nativewin.cpp
CommitLineData
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
44extern "C" GdkFilterReturn
45wxNativeContainerWindowFilter(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 65bool 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
94bool 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
119void 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
137wxNativeContainerWindow::~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}