]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/gtk/nativewin.cpp
attempt to get the 'new focus' window parameter of a focus kill event set correctly
[wxWidgets.git] / src / gtk / nativewin.cpp
... / ...
CommitLineData
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#include "wx/gtk/private/gtk2-compat.h"
33
34#ifdef GDK_WINDOWING_X11
35 #include <gdk/gdkx.h>
36#endif
37
38// ============================================================================
39// implementation
40// ============================================================================
41
42// TODO: we probably need equivalent code for other GDK platforms
43#ifdef GDK_WINDOWING_X11
44
45extern "C" GdkFilterReturn
46wxNativeContainerWindowFilter(GdkXEvent *gdkxevent,
47 GdkEvent *event,
48 gpointer data)
49{
50 XEvent * const xevent = static_cast<XEvent *>(gdkxevent);
51 if ( xevent->type == DestroyNotify )
52 {
53 // we won't need it any more
54 gdk_window_remove_filter(event->any.window,
55 wxNativeContainerWindowFilter, data);
56
57 // the underlying window got destroyed, notify the C++ object
58 static_cast<wxNativeContainerWindow *>(data)->OnNativeDestroyed();
59 }
60
61 return GDK_FILTER_CONTINUE;
62}
63
64#endif // GDK_WINDOWING_X11
65
66bool wxNativeContainerWindow::Create(wxNativeContainerWindowHandle win)
67{
68 wxCHECK( win, false );
69
70 if ( !wxTopLevelWindow::Create(NULL, wxID_ANY, "") )
71 return false;
72
73 // we need to realize the window first before reparenting it
74 gtk_widget_realize(m_widget);
75 gdk_window_reparent(gtk_widget_get_window(m_widget), win, 0, 0);
76
77#ifdef GDK_WINDOWING_X11
78 // if the native window is destroyed, our own window will be destroyed too
79 // but GTK doesn't expect it and will complain about "unexpectedly
80 // destroyed" GdkWindow, so intercept to DestroyNotify ourselves to fix
81 // this and also destroy the associated C++ object when its window is
82 // destroyed
83 gdk_window_add_filter(gtk_widget_get_window(m_widget), wxNativeContainerWindowFilter, this);
84#endif // GDK_WINDOWING_X11
85
86 // we should be initially visible as we suppose that the native window we
87 // wrap is (we could use gdk_window_is_visible() to test for this but this
88 // doesn't make much sense unless we also react to visibility changes, so
89 // just suppose it's always shown for now)
90 Show();
91
92 return true;
93}
94
95bool wxNativeContainerWindow::Create(wxNativeContainerWindowId anid)
96{
97 bool rc;
98#ifdef __WXGTK3__
99#ifdef GDK_WINDOWING_X11
100 GdkWindow * const win = gdk_x11_window_foreign_new_for_display(gdk_display_get_default(), anid);
101#else
102 GdkWindow * const win = NULL;
103#endif
104#else
105 GdkWindow * const win = gdk_window_foreign_new(anid);
106#endif
107 if ( win )
108 {
109 rc = Create(win);
110 g_object_unref(win);
111 }
112 else // invalid native window id
113 {
114 rc = false;
115 }
116
117 return rc;
118}
119
120void wxNativeContainerWindow::OnNativeDestroyed()
121{
122 // unfortunately we simply can't do anything else than leak memory here:
123 // we really need to call _gdk_window_destroy(m_widget->win, TRUE) to
124 // indicate that the native window was deleted, but we can't do this
125 // because it's a private GDK function and calling normal
126 // gdk_window_destroy() results in X errors while nulling just the window
127 // pointer and destroying m_widget results in many GTK errors
128 GTKDisconnect(m_widget);
129 m_widget = NULL;
130
131 // notice that we intentionally don't use Close() nor Delete() here as our
132 // window (and the windows of all of our children) is invalid any more and
133 // any attempts to use it, as may happen with the delayed destruction, will
134 // result in GDK warnings at best and crashes or X errors at worst
135 delete this;
136}
137
138wxNativeContainerWindow::~wxNativeContainerWindow()
139{
140 // nothing to do here, either we have a valid m_widget and it will be
141 // destroyed as usual (this corresponds to manual destruction of this C++
142 // object) or we are being deleted because the native window was destroyed
143 // and in this case our m_widget was set to NULL by OnNativeDestroyed()
144}