]> git.saurik.com Git - wxWidgets.git/blame - src/gtk1/toplevel.cpp
guard against errors like in wxStringBase::AllocBeforeWrite code (1123226)
[wxWidgets.git] / src / gtk1 / toplevel.cpp
CommitLineData
7d9f12f3
VS
1/////////////////////////////////////////////////////////////////////////////
2// Name: toplevel.cpp
3// Purpose:
4// Author: Robert Roebling
5// Id: $Id$
6// Copyright: (c) 1998 Robert Roebling
65571936 7// Licence: wxWindows licence
7d9f12f3
VS
8/////////////////////////////////////////////////////////////////////////////
9
10// ============================================================================
11// declarations
12// ============================================================================
13
14// ----------------------------------------------------------------------------
15// headers
16// ----------------------------------------------------------------------------
17
14f355c2 18#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
7d9f12f3
VS
19 #pragma implementation "toplevel.h"
20#endif
21
14f355c2
VS
22// For compilers that support precompilation, includes "wx.h".
23#include "wx/wxprec.h"
24
7d9f12f3
VS
25#ifdef __VMS
26#define XIconifyWindow XICONIFYWINDOW
27#endif
28
29#include "wx/defs.h"
30
e1bf3ad3 31#include "wx/toplevel.h"
2b5f62a0 32#include "wx/log.h"
7d9f12f3
VS
33#include "wx/dialog.h"
34#include "wx/control.h"
35#include "wx/app.h"
36#include "wx/dcclient.h"
fab591c5 37#include "wx/gtk/private.h"
8166ab43 38#include "wx/timer.h"
ca06ee0d 39#include "wx/settings.h"
7d9f12f3
VS
40
41#include <glib.h>
42#include <gdk/gdk.h>
43#include <gtk/gtk.h>
44#include <gdk/gdkkeysyms.h>
45#include <gdk/gdkx.h>
46
47#include "wx/gtk/win_gtk.h"
48
f618020a
MB
49#include "wx/unix/utilsx11.h"
50
8a9650ea
RR
51// XA_CARDINAL
52#include <X11/Xatom.h>
53
7d9f12f3
VS
54// ----------------------------------------------------------------------------
55// idle system
56// ----------------------------------------------------------------------------
57
58extern void wxapp_install_idle_handler();
59extern bool g_isIdle;
7d9f12f3 60
7d9f12f3
VS
61// ----------------------------------------------------------------------------
62// data
63// ----------------------------------------------------------------------------
64
06fda9e8 65extern wxList wxPendingDelete;
d7fa7eaa 66
06fda9e8
RR
67extern int g_openDialogs;
68extern wxWindowGTK *g_delayedFocus;
69
70// the frame that is currently active (i.e. its child has focus). It is
71// used to generate wxActivateEvents
72static wxTopLevelWindowGTK *g_activeFrame = (wxTopLevelWindowGTK*) NULL;
73static wxTopLevelWindowGTK *g_lastActiveFrame = (wxTopLevelWindowGTK*) NULL;
74
75// if we detect that the app has got/lost the focus, we set this variable to
76// either TRUE or FALSE and an activate event will be sent during the next
77// OnIdle() call and it is reset to -1: this value means that we shouldn't
78// send any activate events at all
79static int g_sendActivateEvent = -1;
80
81//-----------------------------------------------------------------------------
82// "focus_in_event"
83//-----------------------------------------------------------------------------
84
85static gint gtk_frame_focus_in_callback( GtkWidget *widget,
86 GdkEvent *WXUNUSED(event),
87 wxTopLevelWindowGTK *win )
88{
89 if (g_isIdle)
90 wxapp_install_idle_handler();
576f7127 91
06fda9e8
RR
92 switch ( g_sendActivateEvent )
93 {
94 case -1:
95 // we've got focus from outside, synthetize wxActivateEvent
96 g_sendActivateEvent = 1;
97 break;
98
99 case 0:
100 // another our window just lost focus, it was already ours before
101 // - don't send any wxActivateEvent
102 g_sendActivateEvent = -1;
103 break;
104 }
105
106 g_activeFrame = win;
107 g_lastActiveFrame = g_activeFrame;
108
109 // wxPrintf( wxT("active: %s\n"), win->GetTitle().c_str() );
110
111 wxLogTrace(wxT("activate"), wxT("Activating frame %p (from focus_in)"), g_activeFrame);
112 wxActivateEvent event(wxEVT_ACTIVATE, TRUE, g_activeFrame->GetId());
113 event.SetEventObject(g_activeFrame);
114 g_activeFrame->GetEventHandler()->ProcessEvent(event);
115
576f7127 116 return FALSE;
06fda9e8
RR
117}
118
119//-----------------------------------------------------------------------------
120// "focus_out_event"
121//-----------------------------------------------------------------------------
122
123static gint gtk_frame_focus_out_callback( GtkWidget *widget,
124 GdkEventFocus *WXUNUSED(gdk_event),
125 wxTopLevelWindowGTK *win )
126{
127 if (g_isIdle)
128 wxapp_install_idle_handler();
129
130 // if the focus goes out of our app alltogether, OnIdle() will send
131 // wxActivateEvent, otherwise gtk_window_focus_in_callback() will reset
132 // g_sendActivateEvent to -1
133 g_sendActivateEvent = 0;
134
135 // wxASSERT_MSG( (g_activeFrame == win), wxT("TLW deactivatd although it wasn't active") );
136
137 // wxPrintf( wxT("inactive: %s\n"), win->GetTitle().c_str() );
06fda9e8 138
cc0c05cd
JS
139 if (g_activeFrame)
140 {
141 wxLogTrace(wxT("activate"), wxT("Activating frame %p (from focus_in)"), g_activeFrame);
142 wxActivateEvent event(wxEVT_ACTIVATE, FALSE, g_activeFrame->GetId());
143 event.SetEventObject(g_activeFrame);
144 g_activeFrame->GetEventHandler()->ProcessEvent(event);
145
146 g_activeFrame = NULL;
147 }
06fda9e8 148
576f7127 149 return FALSE;
06fda9e8 150}
7d9f12f3 151
7d9f12f3
VS
152//-----------------------------------------------------------------------------
153// "focus" from m_window
154//-----------------------------------------------------------------------------
155
156static gint gtk_frame_focus_callback( GtkWidget *widget, GtkDirectionType WXUNUSED(d), wxWindow *WXUNUSED(win) )
157{
158 if (g_isIdle)
159 wxapp_install_idle_handler();
160
161 // This disables GTK's tab traversal
162 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "focus" );
163 return TRUE;
164}
165
166//-----------------------------------------------------------------------------
167// "size_allocate"
168//-----------------------------------------------------------------------------
169
170static void gtk_frame_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxTopLevelWindowGTK *win )
171{
172 if (g_isIdle)
173 wxapp_install_idle_handler();
174
175 if (!win->m_hasVMT)
176 return;
177
178 if ((win->m_width != alloc->width) || (win->m_height != alloc->height))
179 {
180/*
181 wxPrintf( "OnSize from " );
182 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
183 wxPrintf( win->GetClassInfo()->GetClassName() );
184 wxPrintf( " %d %d %d %d\n", (int)alloc->x,
185 (int)alloc->y,
186 (int)alloc->width,
187 (int)alloc->height );
188*/
189
190 win->m_width = alloc->width;
191 win->m_height = alloc->height;
7d9f12f3
VS
192 win->GtkUpdateSize();
193 }
194}
195
196//-----------------------------------------------------------------------------
197// "delete_event"
198//-----------------------------------------------------------------------------
199
200static gint gtk_frame_delete_callback( GtkWidget *WXUNUSED(widget), GdkEvent *WXUNUSED(event), wxTopLevelWindowGTK *win )
201{
202 if (g_isIdle)
203 wxapp_install_idle_handler();
204
205 if (win->IsEnabled() &&
5152b0e5
JS
206 (g_openDialogs == 0 || (win->GetExtraStyle() & wxTOPLEVEL_EX_DIALOG) ||
207 win->IsGrabbed()))
7d9f12f3
VS
208 win->Close();
209
210 return TRUE;
211}
212
213
214//-----------------------------------------------------------------------------
215// "configure_event"
216//-----------------------------------------------------------------------------
217
218static gint
7d9f12f3 219gtk_frame_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigure *WXUNUSED(event), wxTopLevelWindowGTK *win )
7d9f12f3
VS
220{
221 if (g_isIdle)
222 wxapp_install_idle_handler();
223
48f72114 224 if (!win->m_hasVMT || !win->IsShown())
7d9f12f3
VS
225 return FALSE;
226
32f2ebbf 227
7d9f12f3
VS
228 int x = 0;
229 int y = 0;
230 gdk_window_get_root_origin( win->m_widget->window, &x, &y );
231 win->m_x = x;
232 win->m_y = y;
7d9f12f3
VS
233
234 wxMoveEvent mevent( wxPoint(win->m_x,win->m_y), win->GetId() );
235 mevent.SetEventObject( win );
236 win->GetEventHandler()->ProcessEvent( mevent );
237
238 return FALSE;
239}
240
241//-----------------------------------------------------------------------------
242// "realize" from m_widget
243//-----------------------------------------------------------------------------
244
e1f14d22
RR
245// we cannot MWM hints and icons before the widget has been realized,
246// so we do this directly after realization
7d9f12f3
VS
247
248static void
6aeb6f2a
VZ
249gtk_frame_realized_callback( GtkWidget * WXUNUSED(widget),
250 wxTopLevelWindowGTK *win )
7d9f12f3
VS
251{
252 if (g_isIdle)
253 wxapp_install_idle_handler();
254
e1f14d22
RR
255 // All this is for Motif Window Manager "hints" and is supposed to be
256 // recognized by other WM as well. Not tested.
82c9f85c 257 gdk_window_set_decorations(win->m_widget->window,
f819b4a3 258 (GdkWMDecoration)win->m_gdkDecor);
82c9f85c 259 gdk_window_set_functions(win->m_widget->window,
f819b4a3 260 (GdkWMFunction)win->m_gdkFunc);
7d9f12f3 261
e1f14d22 262 // GTK's shrinking/growing policy
f819b4a3 263 if ((win->m_gdkFunc & GDK_FUNC_RESIZE) == 0)
7d9f12f3
VS
264 gtk_window_set_policy(GTK_WINDOW(win->m_widget), 0, 0, 1);
265 else
266 gtk_window_set_policy(GTK_WINDOW(win->m_widget), 1, 1, 1);
267
e1f14d22 268 // reset the icon
7efaed4d 269 wxIconBundle iconsOld = win->GetIcons();
6aeb6f2a 270 if ( iconsOld.GetIcon(-1).Ok() )
7d9f12f3 271 {
7d9f12f3 272 win->SetIcon( wxNullIcon );
7efaed4d 273 win->SetIcons( iconsOld );
7d9f12f3 274 }
7d9f12f3
VS
275}
276
277//-----------------------------------------------------------------------------
278// "map_event" from m_widget
279//-----------------------------------------------------------------------------
280
281static void
282gtk_frame_map_callback( GtkWidget * WXUNUSED(widget),
283 GdkEvent * WXUNUSED(event),
284 wxTopLevelWindow *win )
285{
286 win->SetIconizeState(FALSE);
287}
288
289//-----------------------------------------------------------------------------
290// "unmap_event" from m_widget
291//-----------------------------------------------------------------------------
292
293static void
294gtk_frame_unmap_callback( GtkWidget * WXUNUSED(widget),
295 GdkEvent * WXUNUSED(event),
296 wxTopLevelWindow *win )
297{
298 win->SetIconizeState(TRUE);
299}
300
301//-----------------------------------------------------------------------------
302// "expose_event" of m_client
303//-----------------------------------------------------------------------------
304
305static int gtk_window_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindow *win )
306{
307 GtkPizza *pizza = GTK_PIZZA(widget);
308
90350682
VZ
309 gtk_paint_flat_box (win->m_widget->style,
310 pizza->bin_window, GTK_STATE_NORMAL,
311 GTK_SHADOW_NONE,
312 &gdk_event->area,
313 win->m_widget,
314 (char *)"base",
315 0, 0, -1, -1);
7d9f12f3 316
cba9ef7f 317 return FALSE;
7d9f12f3
VS
318}
319
320//-----------------------------------------------------------------------------
321// "draw" of m_client
322//-----------------------------------------------------------------------------
323
52d6235d 324#ifndef __WXGTK20__
7d9f12f3
VS
325
326static void gtk_window_draw_callback( GtkWidget *widget, GdkRectangle *rect, wxWindow *win )
327{
328 GtkPizza *pizza = GTK_PIZZA(widget);
329
90350682
VZ
330 gtk_paint_flat_box (win->m_widget->style,
331 pizza->bin_window, GTK_STATE_NORMAL,
332 GTK_SHADOW_NONE,
333 rect,
334 win->m_widget,
335 (char *)"base",
336 0, 0, -1, -1);
7d9f12f3
VS
337}
338
52d6235d
VZ
339#endif // GTK+ 1.x
340
7d9f12f3
VS
341// ----------------------------------------------------------------------------
342// wxTopLevelWindowGTK itself
343// ----------------------------------------------------------------------------
344
345//-----------------------------------------------------------------------------
346// InsertChild for wxTopLevelWindowGTK
347//-----------------------------------------------------------------------------
348
349/* Callback for wxTopLevelWindowGTK. This very strange beast has to be used because
350 * C++ has no virtual methods in a constructor. We have to emulate a
77ffb593 351 * virtual function here as wxWidgets requires different ways to insert
7d9f12f3
VS
352 * a child in container classes. */
353
354static void wxInsertChildInTopLevelWindow( wxTopLevelWindowGTK* parent, wxWindow* child )
355{
356 wxASSERT( GTK_IS_WIDGET(child->m_widget) );
357
358 if (!parent->m_insertInClientArea)
359 {
e1f14d22 360 // these are outside the client area
7d9f12f3
VS
361 wxTopLevelWindowGTK* frame = (wxTopLevelWindowGTK*) parent;
362 gtk_pizza_put( GTK_PIZZA(frame->m_mainWidget),
363 GTK_WIDGET(child->m_widget),
364 child->m_x,
365 child->m_y,
366 child->m_width,
367 child->m_height );
368 }
369 else
370 {
e1f14d22 371 // these are inside the client area
7d9f12f3
VS
372 gtk_pizza_put( GTK_PIZZA(parent->m_wxwindow),
373 GTK_WIDGET(child->m_widget),
e4b7b2b0
VS
374 child->m_x,
375 child->m_y,
7d9f12f3
VS
376 child->m_width,
377 child->m_height );
378 }
379
e1f14d22 380 // resize on OnInternalIdle
7d9f12f3
VS
381 parent->GtkUpdateSize();
382}
383
384// ----------------------------------------------------------------------------
385// wxTopLevelWindowGTK creation
386// ----------------------------------------------------------------------------
387
388void wxTopLevelWindowGTK::Init()
389{
390 m_sizeSet = FALSE;
391 m_miniEdge = 0;
392 m_miniTitle = 0;
393 m_mainWidget = (GtkWidget*) NULL;
394 m_insertInClientArea = TRUE;
7d9f12f3
VS
395 m_isIconized = FALSE;
396 m_fsIsShowing = FALSE;
397 m_themeEnabled = TRUE;
f819b4a3 398 m_gdkDecor = m_gdkFunc = 0;
5152b0e5 399 m_grabbed = FALSE;
7d9f12f3
VS
400}
401
402bool wxTopLevelWindowGTK::Create( wxWindow *parent,
f819b4a3
VS
403 wxWindowID id,
404 const wxString& title,
405 const wxPoint& pos,
406 const wxSize& sizeOrig,
407 long style,
408 const wxString &name )
7d9f12f3
VS
409{
410 // always create a frame of some reasonable, even if arbitrary, size (at
411 // least for MSW compatibility)
412 wxSize size = sizeOrig;
1111cedc 413 size.x = WidthDefault(size.x);
66202a7e 414 size.y = HeightDefault(size.y);
7d9f12f3
VS
415
416 wxTopLevelWindows.Append( this );
417
418 m_needParent = FALSE;
6aeb6f2a 419
7d9f12f3
VS
420 if (!PreCreation( parent, pos, size ) ||
421 !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
422 {
423 wxFAIL_MSG( wxT("wxTopLevelWindowGTK creation failed") );
424 return FALSE;
425 }
426
427 m_title = title;
428
429 m_insertCallback = (wxInsertChildFunction) wxInsertChildInTopLevelWindow;
430
63c5efa3
VS
431 // NB: m_widget may be !=NULL if it was created by derived class' Create,
432 // e.g. in wxTaskBarIconAreaGTK
433 if (m_widget == NULL)
434 {
63c5efa3
VS
435 if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG)
436 {
9e691f46 437#ifdef __WXGTK20__
4d8d6490
VS
438 m_widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
439 // Tell WM that this is a dialog window and make it center
440 // on parent by default (this is what GtkDialog ctor does):
441 gtk_window_set_type_hint(GTK_WINDOW(m_widget),
442 GDK_WINDOW_TYPE_HINT_DIALOG);
443 gtk_window_set_position(GTK_WINDOW(m_widget),
444 GTK_WIN_POS_CENTER_ON_PARENT);
9e691f46 445#else
4d8d6490 446 m_widget = gtk_window_new(GTK_WINDOW_DIALOG);
9e691f46 447#endif
63c5efa3 448 }
4d8d6490
VS
449 else
450 {
37780c64 451 m_widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
606ce80c 452#if GTK_CHECK_VERSION(2,1,0)
37780c64 453 if (style & wxFRAME_TOOL_WINDOW)
11475235 454 {
37780c64
VS
455 gtk_window_set_type_hint(GTK_WINDOW(m_widget),
456 GDK_WINDOW_TYPE_HINT_UTILITY);
11475235
KH
457
458 // On some WMs, like KDE, a TOOL_WINDOW will still show
459 // on the taskbar, but on Gnome a TOOL_WINDOW will not.
460 // For consistency between WMs and with Windows, we
461 // should set the NO_TASKBAR flag which will apply
462 // the set_skip_taskbar_hint if it is available,
463 // ensuring no taskbar entry will appear.
464 style |= wxFRAME_NO_TASKBAR;
465 }
cf49c955 466#endif
37780c64 467
4d8d6490 468 }
63c5efa3 469 }
7d9f12f3 470
e25c7537
VS
471 wxWindow *topParent = wxGetTopLevelParent(m_parent);
472 if (topParent && (((GTK_IS_WINDOW(topParent->m_widget)) &&
50819679
JS
473 (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG)) ||
474 (style & wxFRAME_FLOAT_ON_PARENT)))
7cd95599 475 {
e25c7537
VS
476 gtk_window_set_transient_for( GTK_WINDOW(m_widget),
477 GTK_WINDOW(topParent->m_widget) );
7cd95599 478 }
7d9f12f3 479
2be125e6
VS
480#if GTK_CHECK_VERSION(2,2,0)
481 if (style & wxFRAME_NO_TASKBAR)
482 {
483 gtk_window_set_skip_taskbar_hint(GTK_WINDOW(m_widget), TRUE);
484 }
485#endif
486
7d9f12f3 487 if (!name.IsEmpty())
fab591c5 488 gtk_window_set_wmclass( GTK_WINDOW(m_widget), wxGTK_CONV( name ), wxGTK_CONV( name ) );
7d9f12f3 489
fab591c5 490 gtk_window_set_title( GTK_WINDOW(m_widget), wxGTK_CONV( title ) );
7d9f12f3
VS
491 GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS );
492
493 gtk_signal_connect( GTK_OBJECT(m_widget), "delete_event",
494 GTK_SIGNAL_FUNC(gtk_frame_delete_callback), (gpointer)this );
495
e1f14d22 496 // m_mainWidget holds the toolbar, the menubar and the client area
7d9f12f3
VS
497 m_mainWidget = gtk_pizza_new();
498 gtk_widget_show( m_mainWidget );
499 GTK_WIDGET_UNSET_FLAGS( m_mainWidget, GTK_CAN_FOCUS );
500 gtk_container_add( GTK_CONTAINER(m_widget), m_mainWidget );
501
cba9ef7f
RR
502 if (m_miniEdge == 0) // wxMiniFrame has its own version.
503 {
504 // For m_mainWidget themes
505 gtk_signal_connect( GTK_OBJECT(m_mainWidget), "expose_event",
7d9f12f3 506 GTK_SIGNAL_FUNC(gtk_window_expose_callback), (gpointer)this );
4e5a4c69 507#ifndef __WXGTK20__
cba9ef7f 508 gtk_signal_connect( GTK_OBJECT(m_mainWidget), "draw",
7d9f12f3 509 GTK_SIGNAL_FUNC(gtk_window_draw_callback), (gpointer)this );
4e5a4c69 510#endif
cba9ef7f 511 }
7d9f12f3 512
e1f14d22 513 // m_wxwindow only represents the client area without toolbar and menubar
7d9f12f3
VS
514 m_wxwindow = gtk_pizza_new();
515 gtk_widget_show( m_wxwindow );
516 gtk_container_add( GTK_CONTAINER(m_mainWidget), m_wxwindow );
517
e1f14d22
RR
518 // we donm't allow the frame to get the focus as otherwise
519 // the frame will grab it at arbitrary focus changes
7d9f12f3
VS
520 GTK_WIDGET_UNSET_FLAGS( m_wxwindow, GTK_CAN_FOCUS );
521
522 if (m_parent) m_parent->AddChild( this );
523
e1f14d22 524 // the user resized the frame by dragging etc.
7d9f12f3
VS
525 gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate",
526 GTK_SIGNAL_FUNC(gtk_frame_size_callback), (gpointer)this );
527
528 PostCreation();
529
530 if ((m_x != -1) || (m_y != -1))
531 gtk_widget_set_uposition( m_widget, m_x, m_y );
6aeb6f2a 532
e1f14d22 533 gtk_window_set_default_size( GTK_WINDOW(m_widget), m_width, m_height );
7d9f12f3 534
e1f14d22
RR
535 // we cannot set MWM hints and icons before the widget has
536 // been realized, so we do this directly after realization
7d9f12f3
VS
537 gtk_signal_connect( GTK_OBJECT(m_widget), "realize",
538 GTK_SIGNAL_FUNC(gtk_frame_realized_callback), (gpointer) this );
539
e1f14d22 540 // the only way to get the window size is to connect to this event
7d9f12f3
VS
541 gtk_signal_connect( GTK_OBJECT(m_widget), "configure_event",
542 GTK_SIGNAL_FUNC(gtk_frame_configure_callback), (gpointer)this );
543
e1f14d22 544 // map and unmap for iconized state
7d9f12f3
VS
545 gtk_signal_connect( GTK_OBJECT(m_widget), "map_event",
546 GTK_SIGNAL_FUNC(gtk_frame_map_callback), (gpointer)this );
547 gtk_signal_connect( GTK_OBJECT(m_widget), "unmap_event",
548 GTK_SIGNAL_FUNC(gtk_frame_unmap_callback), (gpointer)this );
549
e1f14d22 550 // the only way to get the window size is to connect to this event
7d9f12f3
VS
551 gtk_signal_connect( GTK_OBJECT(m_widget), "configure_event",
552 GTK_SIGNAL_FUNC(gtk_frame_configure_callback), (gpointer)this );
553
e1f14d22 554 // disable native tab traversal
7d9f12f3
VS
555 gtk_signal_connect( GTK_OBJECT(m_widget), "focus",
556 GTK_SIGNAL_FUNC(gtk_frame_focus_callback), (gpointer)this );
557
06fda9e8
RR
558 // activation
559 gtk_signal_connect( GTK_OBJECT(m_widget), "focus_in_event",
560 GTK_SIGNAL_FUNC(gtk_frame_focus_in_callback), (gpointer)this );
561 gtk_signal_connect( GTK_OBJECT(m_widget), "focus_out_event",
562 GTK_SIGNAL_FUNC(gtk_frame_focus_out_callback), (gpointer)this );
563
e1f14d22 564 // decorations
f819b4a3
VS
565 if ((m_miniEdge > 0) || (style & wxSIMPLE_BORDER) || (style & wxNO_BORDER))
566 {
567 m_gdkDecor = 0;
568 m_gdkFunc = 0;
569 }
570 else
571 {
572 m_gdkDecor = (long) GDK_DECOR_BORDER;
573 m_gdkFunc = (long) GDK_FUNC_MOVE;
82c9f85c 574
f819b4a3 575 // All this is for Motif Window Manager "hints" and is supposed to be
e1f14d22 576 // recognized by other WMs as well.
f819b4a3 577 if ((style & wxCAPTION) != 0)
c3d8ee42 578 {
f819b4a3 579 m_gdkDecor |= GDK_DECOR_TITLE;
c3d8ee42 580 }
850c6ed4 581 if ((style & wxCLOSE_BOX) != 0)
f819b4a3
VS
582 {
583 m_gdkFunc |= GDK_FUNC_CLOSE;
c3d8ee42
VS
584 }
585 if ((style & wxSYSTEM_MENU) != 0)
586 {
f819b4a3
VS
587 m_gdkDecor |= GDK_DECOR_MENU;
588 }
589 if ((style & wxMINIMIZE_BOX) != 0)
590 {
591 m_gdkFunc |= GDK_FUNC_MINIMIZE;
592 m_gdkDecor |= GDK_DECOR_MINIMIZE;
593 }
594 if ((style & wxMAXIMIZE_BOX) != 0)
595 {
596 m_gdkFunc |= GDK_FUNC_MAXIMIZE;
597 m_gdkDecor |= GDK_DECOR_MAXIMIZE;
598 }
599 if ((style & wxRESIZE_BORDER) != 0)
600 {
601 m_gdkFunc |= GDK_FUNC_RESIZE;
602 m_gdkDecor |= GDK_DECOR_RESIZEH;
603 }
604 }
605
7d9f12f3
VS
606 return TRUE;
607}
608
609wxTopLevelWindowGTK::~wxTopLevelWindowGTK()
610{
5152b0e5
JS
611 if (m_grabbed)
612 {
83afe211 613 wxASSERT_MSG( FALSE, _T("Window still grabbed"));
5152b0e5
JS
614 RemoveGrab();
615 }
1cbee0b4 616
7d9f12f3 617 m_isBeingDeleted = TRUE;
6aeb6f2a 618
710968c3
VZ
619 // it may also be GtkScrolledWindow in the case of an MDI child
620 if (GTK_IS_WINDOW(m_widget))
621 {
622 gtk_window_set_focus( GTK_WINDOW(m_widget), NULL );
623 }
06fda9e8
RR
624
625 if (g_activeFrame == this)
626 g_activeFrame = NULL;
627 if (g_lastActiveFrame == this)
628 g_lastActiveFrame = NULL;
7d9f12f3
VS
629}
630
8a9650ea 631
8a9650ea 632
7d9f12f3
VS
633bool wxTopLevelWindowGTK::ShowFullScreen(bool show, long style )
634{
8a8997c3
VZ
635 if (show == m_fsIsShowing)
636 return FALSE; // return what?
7d9f12f3
VS
637
638 m_fsIsShowing = show;
feb1c9fb 639
1542ea39 640 wxX11FullScreenMethod method =
8166ab43
VS
641 wxGetFullScreenMethodX11((WXDisplay*)GDK_DISPLAY(),
642 (WXWindow)GDK_ROOT_WINDOW());
1542ea39 643
feb1c9fb
VS
644#if GTK_CHECK_VERSION(2,2,0)
645 // NB: gtk_window_fullscreen() uses freedesktop.org's WMspec extensions
646 // to switch to fullscreen, which is not always available. We must
647 // check if WM supports the spec and use legacy methods if it
648 // doesn't.
649 if (method == wxX11_FS_WMSPEC)
7d9f12f3 650 {
feb1c9fb
VS
651 if (show)
652 gtk_window_fullscreen( GTK_WINDOW( m_widget ) );
653 else
654 gtk_window_unfullscreen( GTK_WINDOW( m_widget ) );
8a8997c3
VZ
655
656 return TRUE;
7d9f12f3
VS
657 }
658 else
8a8997c3 659#endif // GTK+ >= 2.2.0
7d9f12f3 660 {
feb1c9fb
VS
661 GdkWindow *window = m_widget->window;
662
663 if (show)
8166ab43 664 {
feb1c9fb
VS
665 m_fsSaveFlag = style;
666 GetPosition( &m_fsSaveFrame.x, &m_fsSaveFrame.y );
667 GetSize( &m_fsSaveFrame.width, &m_fsSaveFrame.height );
668
669 int screen_width,screen_height;
670 wxDisplaySize( &screen_width, &screen_height );
671
672 gint client_x, client_y, root_x, root_y;
673 gint width, height;
674
675 if (method != wxX11_FS_WMSPEC)
676 {
677 // don't do it always, Metacity hates it
678 m_fsSaveGdkFunc = m_gdkFunc;
679 m_fsSaveGdkDecor = m_gdkDecor;
680 m_gdkFunc = m_gdkDecor = 0;
681 gdk_window_set_decorations(window, (GdkWMDecoration)0);
682 gdk_window_set_functions(window, (GdkWMFunction)0);
683 }
684
685 gdk_window_get_origin (m_widget->window, &root_x, &root_y);
686 gdk_window_get_geometry (m_widget->window, &client_x, &client_y,
687 &width, &height, NULL);
688
689 gdk_window_move_resize (m_widget->window, -client_x, -client_y,
690 screen_width + 1, screen_height + 1);
691
692 wxSetFullScreenStateX11((WXDisplay*)GDK_DISPLAY(),
693 (WXWindow)GDK_ROOT_WINDOW(),
694 (WXWindow)GDK_WINDOW_XWINDOW(window),
695 show, &m_fsSaveFrame, method);
696 }
697 else
698 {
699 if (method != wxX11_FS_WMSPEC)
700 {
701 // don't do it always, Metacity hates it
702 m_gdkFunc = m_fsSaveGdkFunc;
703 m_gdkDecor = m_fsSaveGdkDecor;
704 gdk_window_set_decorations(window, (GdkWMDecoration)m_gdkDecor);
705 gdk_window_set_functions(window, (GdkWMFunction)m_gdkFunc);
706 }
707
708 wxSetFullScreenStateX11((WXDisplay*)GDK_DISPLAY(),
709 (WXWindow)GDK_ROOT_WINDOW(),
710 (WXWindow)GDK_WINDOW_XWINDOW(window),
711 show, &m_fsSaveFrame, method);
712
713 SetSize(m_fsSaveFrame.x, m_fsSaveFrame.y,
714 m_fsSaveFrame.width, m_fsSaveFrame.height);
8166ab43 715 }
7d9f12f3 716 }
8166ab43 717
7d9f12f3
VS
718 return TRUE;
719}
720
721// ----------------------------------------------------------------------------
722// overridden wxWindow methods
723// ----------------------------------------------------------------------------
724
725bool wxTopLevelWindowGTK::Show( bool show )
726{
82b978d7 727 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
7d9f12f3
VS
728
729 if (show && !m_sizeSet)
730 {
731 /* by calling GtkOnSize here, we don't have to call
732 either after showing the frame, which would entail
733 much ugly flicker or from within the size_allocate
734 handler, because GTK 1.1.X forbids that. */
735
736 GtkOnSize( m_x, m_y, m_width, m_height );
737 }
32f2ebbf
RR
738
739 if (show)
740 gtk_widget_set_uposition( m_widget, m_x, m_y );
741
7d9f12f3
VS
742 return wxWindow::Show( show );
743}
744
a2ac55f5
RR
745void wxTopLevelWindowGTK::Raise()
746{
747#ifdef __WXGTK20__
748 gtk_window_present( GTK_WINDOW( m_widget ) );
749#else
750 wxWindow::Raise();
751#endif
752}
753
7d9f12f3
VS
754void wxTopLevelWindowGTK::DoMoveWindow(int WXUNUSED(x), int WXUNUSED(y), int WXUNUSED(width), int WXUNUSED(height) )
755{
756 wxFAIL_MSG( wxT("DoMoveWindow called for wxTopLevelWindowGTK") );
757}
758
759void wxTopLevelWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags )
760{
82b978d7
RD
761 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
762
e1f14d22 763 // this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow
7d9f12f3
VS
764 wxASSERT_MSG( (m_wxwindow != NULL), wxT("invalid frame") );
765
e1f14d22 766 // avoid recursions
7d9f12f3
VS
767 if (m_resizing)
768 return;
769 m_resizing = TRUE;
770
771 int old_x = m_x;
772 int old_y = m_y;
773
774 int old_width = m_width;
775 int old_height = m_height;
776
777 if ((sizeFlags & wxSIZE_ALLOW_MINUS_ONE) == 0)
778 {
779 if (x != -1) m_x = x;
780 if (y != -1) m_y = y;
7d9f12f3
VS
781 }
782 else
783 {
784 m_x = x;
785 m_y = y;
7d9f12f3 786 }
d44c23ce
RR
787 if (width != -1) m_width = width;
788 if (height != -1) m_height = height;
7d9f12f3
VS
789
790/*
791 if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
792 {
793 if (width == -1) m_width = 80;
794 }
795
796 if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
797 {
798 if (height == -1) m_height = 26;
799 }
800*/
801
e7dda1ff
VS
802 int minWidth = GetMinWidth(),
803 minHeight = GetMinHeight(),
804 maxWidth = GetMaxWidth(),
805 maxHeight = GetMaxHeight();
806
62be94e1
RR
807#ifdef __WXGPE__
808 // GPE's window manager doesn't like size hints
809 // at all, esp. when the user has to use the
810 // virtual keyboard.
811 minWidth = -1;
812 minHeight = -1;
813 maxWidth = -1;
814 maxHeight = -1;
815#endif
ca06ee0d 816
e7dda1ff
VS
817 if ((minWidth != -1) && (m_width < minWidth)) m_width = minWidth;
818 if ((minHeight != -1) && (m_height < minHeight)) m_height = minHeight;
819 if ((maxWidth != -1) && (m_width > maxWidth)) m_width = maxWidth;
820 if ((maxHeight != -1) && (m_height > maxHeight)) m_height = maxHeight;
7d9f12f3
VS
821
822 if ((m_x != -1) || (m_y != -1))
823 {
824 if ((m_x != old_x) || (m_y != old_y))
825 {
826 gtk_widget_set_uposition( m_widget, m_x, m_y );
827 }
828 }
829
830 if ((m_width != old_width) || (m_height != old_height))
831 {
e1f14d22
RR
832 if (m_widget->window)
833 gdk_window_resize( m_widget->window, m_width, m_height );
834 else
835 gtk_window_set_default_size( GTK_WINDOW(m_widget), m_width, m_height );
7d9f12f3
VS
836
837 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
838 done either directly before the frame is shown or in idle time
839 so that different calls to SetSize() don't lead to flicker. */
840 m_sizeSet = FALSE;
841 }
842
843 m_resizing = FALSE;
844}
845
846void wxTopLevelWindowGTK::DoGetClientSize( int *width, int *height ) const
847{
82b978d7
RD
848 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
849
7d9f12f3
VS
850 wxWindow::DoGetClientSize( width, height );
851 if (height)
852 {
e1f14d22 853 // mini edge
7d9f12f3
VS
854 *height -= m_miniEdge*2 + m_miniTitle;
855 }
856 if (width)
857 {
858 *width -= m_miniEdge*2;
859 }
860}
861
862void wxTopLevelWindowGTK::DoSetClientSize( int width, int height )
863{
82b978d7 864 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
7d9f12f3 865
82c9f85c 866 DoSetSize(-1, -1,
7d9f12f3
VS
867 width + m_miniEdge*2, height + m_miniEdge*2 + m_miniTitle, 0);
868}
869
870void wxTopLevelWindowGTK::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y),
82c9f85c 871 int width, int height )
7d9f12f3
VS
872{
873 // due to a bug in gtk, x,y are always 0
874 // m_x = x;
875 // m_y = y;
876
e1f14d22 877 // avoid recursions
7d9f12f3
VS
878 if (m_resizing) return;
879 m_resizing = TRUE;
880
881 if ( m_wxwindow == NULL ) return;
882
883 m_width = width;
884 m_height = height;
885
0d53fc34 886 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
7d9f12f3 887 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
0d53fc34 888 set in wxFrame::Create so it is used to check what kind of frame we
7d9f12f3
VS
889 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
890 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
891 importantly) m_mainWidget */
892
e7dda1ff
VS
893 int minWidth = GetMinWidth(),
894 minHeight = GetMinHeight(),
895 maxWidth = GetMaxWidth(),
896 maxHeight = GetMaxHeight();
897
62be94e1
RR
898#ifdef __WXGPE__
899 // GPE's window manager doesn't like size hints
900 // at all, esp. when the user has to use the
901 // virtual keyboard.
902 minWidth = -1;
903 minHeight = -1;
904 maxWidth = -1;
905 maxHeight = -1;
906#endif
ca06ee0d 907
e7dda1ff
VS
908 if ((minWidth != -1) && (m_width < minWidth)) m_width = minWidth;
909 if ((minHeight != -1) && (m_height < minHeight)) m_height = minHeight;
910 if ((maxWidth != -1) && (m_width > maxWidth)) m_width = maxWidth;
911 if ((maxHeight != -1) && (m_height > maxHeight)) m_height = maxHeight;
7d9f12f3
VS
912
913 if (m_mainWidget)
914 {
e1f14d22 915 // set size hints
801225c1
RL
916 gint flag = 0; // GDK_HINT_POS;
917 GdkGeometry geom;
918
e7dda1ff
VS
919 if ((minWidth != -1) || (minHeight != -1)) flag |= GDK_HINT_MIN_SIZE;
920 if ((maxWidth != -1) || (maxHeight != -1)) flag |= GDK_HINT_MAX_SIZE;
801225c1 921
e7dda1ff
VS
922 geom.min_width = minWidth;
923 geom.min_height = minHeight;
801225c1
RL
924
925 // Because of the way we set GDK_HINT_MAX_SIZE above, if either of
926 // maxHeight or maxWidth is set, we must set them both, else the
927 // remaining -1 will be taken literally.
928
929 // I'm certain this also happens elsewhere, and is the probable
930 // cause of other such things as:
931 // Gtk-WARNING **: gtk_widget_size_allocate():
932 // attempt to allocate widget with width 65535 and height 600
933 // but I don't have time to track them all now..
1cbee0b4 934 //
801225c1
RL
935 // Really we need to encapulate all this height/width business and
936 // stop any old method from ripping at the members directly and
937 // scattering -1's without regard for who might resolve them later.
938
939 geom.max_width = ( maxHeight == -1 ) ? maxWidth
940 : ( maxWidth == -1 ) ? wxGetDisplaySize().GetWidth()
941 : maxWidth ;
942
943 geom.max_height = ( maxWidth == -1 ) ? maxHeight // ( == -1 here )
944 : ( maxHeight == -1 ) ? wxGetDisplaySize().GetHeight()
945 : maxHeight ;
946
7d9f12f3
VS
947 gtk_window_set_geometry_hints( GTK_WINDOW(m_widget),
948 (GtkWidget*) NULL,
949 &geom,
950 (GdkWindowHints) flag );
951
952 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
953 * menubar, the toolbar and the client area, which is represented by
954 * m_wxwindow.
955 * this hurts in the eye, but I don't want to call SetSize()
956 * because I don't want to call any non-native functions here. */
957
958 int client_x = m_miniEdge;
959 int client_y = m_miniEdge + m_miniTitle;
960 int client_w = m_width - 2*m_miniEdge;
961 int client_h = m_height - 2*m_miniEdge - m_miniTitle;
801225c1 962
7d9f12f3
VS
963 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget),
964 m_wxwindow,
965 client_x, client_y, client_w, client_h );
966 }
967 else
968 {
e1f14d22
RR
969 // If there is no m_mainWidget between m_widget and m_wxwindow there
970 // is no need to set the size or position of m_wxwindow.
7d9f12f3
VS
971 }
972
973 m_sizeSet = TRUE;
974
975 // send size event to frame
976 wxSizeEvent event( wxSize(m_width,m_height), GetId() );
977 event.SetEventObject( this );
978 GetEventHandler()->ProcessEvent( event );
979
980 m_resizing = FALSE;
981}
982
983void wxTopLevelWindowGTK::OnInternalIdle()
984{
985 if (!m_sizeSet && GTK_WIDGET_REALIZED(m_wxwindow))
986 {
987 GtkOnSize( m_x, m_y, m_width, m_height );
988
989 // we'll come back later
990 if (g_isIdle)
991 wxapp_install_idle_handler();
992 return;
993 }
994
6aeb6f2a
VZ
995 // set the focus if not done yet and if we can already do it
996 if ( GTK_WIDGET_REALIZED(m_wxwindow) )
997 {
cc06fe74
MB
998 if ( g_delayedFocus &&
999 wxGetTopLevelParent((wxWindow*)g_delayedFocus) == this )
6aeb6f2a 1000 {
2b5f62a0
VZ
1001 wxLogTrace(_T("focus"),
1002 _T("Setting focus from wxTLW::OnIdle() to %s(%s)"),
1003 g_delayedFocus->GetClassInfo()->GetClassName(),
1004 g_delayedFocus->GetLabel().c_str());
1005
6aeb6f2a
VZ
1006 g_delayedFocus->SetFocus();
1007 g_delayedFocus = NULL;
1008 }
1009 }
1010
7d9f12f3 1011 wxWindow::OnInternalIdle();
06fda9e8
RR
1012
1013 // Synthetize activate events.
1014 if ( g_sendActivateEvent != -1 )
1015 {
1016 bool activate = g_sendActivateEvent != 0;
1017
576f7127
RR
1018 // if (!activate) wxPrintf( wxT("de") );
1019 // wxPrintf( wxT("activate\n") );
1020
06fda9e8
RR
1021 // do it only once
1022 g_sendActivateEvent = -1;
1023
1024 wxTheApp->SetActive(activate, (wxWindow *)g_lastActiveFrame);
1025 }
7d9f12f3
VS
1026}
1027
7d9f12f3
VS
1028// ----------------------------------------------------------------------------
1029// frame title/icon
1030// ----------------------------------------------------------------------------
1031
1032void wxTopLevelWindowGTK::SetTitle( const wxString &title )
1033{
82b978d7
RD
1034 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
1035
7d9f12f3 1036 m_title = title;
fab591c5 1037 gtk_window_set_title( GTK_WINDOW(m_widget), wxGTK_CONV( title ) );
7d9f12f3
VS
1038}
1039
f618020a
MB
1040void wxTopLevelWindowGTK::SetIcon( const wxIcon &icon )
1041{
1042 SetIcons( wxIconBundle( icon ) );
1043}
1044
1045void wxTopLevelWindowGTK::SetIcons( const wxIconBundle &icons )
1046{
82b978d7 1047 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
f618020a
MB
1048
1049 wxTopLevelWindowBase::SetIcons( icons );
1050
87e53e2a
VS
1051#ifdef __WXGTK20__
1052 GList *list = NULL;
1053 size_t max = icons.m_icons.GetCount();
1054
1055 for (size_t i = 0; i < max; i++)
52d6235d 1056 {
87e53e2a
VS
1057 if (icons.m_icons[i].Ok())
1058 {
1059 list = g_list_prepend(list, icons.m_icons[i].GetPixbuf());
1060 }
1061 }
1062 gtk_window_set_icon_list(GTK_WINDOW(m_widget), list);
1063 g_list_free(list);
1064
1065#else // !__WXGTK20__
1066 GdkWindow* window = m_widget->window;
1067 if (!window)
1068 return;
1069
1070 wxIcon icon = icons.GetIcon(-1);
1071 if (icon.Ok())
1072 {
1073 wxMask *mask = icon.GetMask();
1074 GdkBitmap *bm = (GdkBitmap *) NULL;
1075 if (mask) bm = mask->GetBitmap();
1076
1077 gdk_window_set_icon( m_widget->window, (GdkWindow *) NULL, icon.GetPixmap(), bm );
52d6235d 1078 }
87e53e2a
VS
1079
1080 wxSetIconsX11( (WXDisplay*)GDK_WINDOW_XDISPLAY( window ),
1081 (WXWindow)GDK_WINDOW_XWINDOW( window ), icons );
1082#endif // !__WXGTK20__
f618020a
MB
1083}
1084
7d9f12f3
VS
1085// ----------------------------------------------------------------------------
1086// frame state: maximized/iconized/normal
1087// ----------------------------------------------------------------------------
1088
8805e155 1089void wxTopLevelWindowGTK::Maximize(bool maximize)
7d9f12f3 1090{
8805e155
RR
1091#ifdef __WXGTK20__
1092 if (maximize)
1093 gtk_window_maximize( GTK_WINDOW( m_widget ) );
1094 else
1095 gtk_window_unmaximize( GTK_WINDOW( m_widget ) );
1096#else
7d9f12f3 1097 wxFAIL_MSG( _T("not implemented") );
8805e155 1098#endif
7d9f12f3
VS
1099}
1100
1101bool wxTopLevelWindowGTK::IsMaximized() const
1102{
d8e1fe80
VS
1103#ifdef __WXGTK20__
1104 if(!m_widget->window)
1105 return false;
1106
1107 return gdk_window_get_state(m_widget->window) & GDK_WINDOW_STATE_MAXIMIZED;
1108#else
7d9f12f3
VS
1109 // wxFAIL_MSG( _T("not implemented") );
1110
1111 // This is an approximation
1112 return FALSE;
d8e1fe80 1113#endif
7d9f12f3
VS
1114}
1115
1116void wxTopLevelWindowGTK::Restore()
1117{
387fd89d 1118#ifdef __WXGTK20__
8805e155
RR
1119 // "Present" seems similar enough to "restore"
1120 gtk_window_present( GTK_WINDOW( m_widget ) );
1121#else
7d9f12f3 1122 wxFAIL_MSG( _T("not implemented") );
8805e155 1123#endif
7d9f12f3
VS
1124}
1125
1126void wxTopLevelWindowGTK::Iconize( bool iconize )
1127{
8805e155
RR
1128#ifdef __WXGTK20__
1129 if (iconize)
1130 gtk_window_iconify( GTK_WINDOW( m_widget ) );
1131 else
1132 gtk_window_deiconify( GTK_WINDOW( m_widget ) );
1133#else
7d9f12f3
VS
1134 if (iconize)
1135 {
1136 GdkWindow *window = m_widget->window;
1137
1138 // you should do it later, for example from OnCreate() handler
1139 wxCHECK_RET( window, _T("frame not created yet - can't iconize") );
1140
1141 XIconifyWindow( GDK_WINDOW_XDISPLAY( window ),
1142 GDK_WINDOW_XWINDOW( window ),
1143 DefaultScreen( GDK_DISPLAY() ) );
1144 }
8805e155 1145#endif
7d9f12f3
VS
1146}
1147
1148bool wxTopLevelWindowGTK::IsIconized() const
1149{
1150 return m_isIconized;
1151}
1152
1153void wxTopLevelWindowGTK::SetIconizeState(bool iconize)
1154{
1155 if ( iconize != m_isIconized )
1156 {
1157 m_isIconized = iconize;
1158 (void)SendIconizeEvent(iconize);
1159 }
1160}
1161
5152b0e5
JS
1162void wxTopLevelWindowGTK::AddGrab()
1163{
1164 if (!m_grabbed)
1165 {
1166 m_grabbed = TRUE;
1167 gtk_grab_add( m_widget );
1168 gtk_main();
1169 gtk_grab_remove( m_widget );
1170 }
1171}
1172
1173void wxTopLevelWindowGTK::RemoveGrab()
1174{
1175 if (m_grabbed)
1176 {
1177 gtk_main_quit();
1178 m_grabbed = FALSE;
1179 }
1180}
801225c1 1181
1542ea39
RD
1182
1183// helper
1184static bool do_shape_combine_region(GdkWindow* window, const wxRegion& region)
1185{
1186 if (window)
1187 {
1188 if (region.IsEmpty())
1189 {
1190 gdk_window_shape_combine_mask(window, NULL, 0, 0);
1191 }
1192 else
1193 {
1194#ifdef __WXGTK20__
1195 gdk_window_shape_combine_region(window, region.GetRegion(), 0, 0);
1196#else
1197 wxBitmap bmp = region.ConvertToBitmap();
819451b6 1198 bmp.SetMask(new wxMask(bmp, *wxBLACK));
1542ea39
RD
1199 GdkBitmap* mask = bmp.GetMask()->GetBitmap();
1200 gdk_window_shape_combine_mask(window, mask, 0, 0);
1201#endif
1202 return TRUE;
1203 }
1204 }
1205 return FALSE;
1206}
1207
1208
1209bool wxTopLevelWindowGTK::SetShape(const wxRegion& region)
1210{
6a7e6411
RD
1211 wxCHECK_MSG( HasFlag(wxFRAME_SHAPED), FALSE,
1212 _T("Shaped windows must be created with the wxFRAME_SHAPED style."));
1213
1542ea39
RD
1214 GdkWindow *window = NULL;
1215 if (m_wxwindow)
1216 {
1217 window = GTK_PIZZA(m_wxwindow)->bin_window;
1218 do_shape_combine_region(window, region);
1219 }
1220 window = m_widget->window;
1221 return do_shape_combine_region(window, region);
1222}
1223
6b30a44e 1224bool wxTopLevelWindowGTK::IsActive()
35ff90a0 1225{
06fda9e8 1226 return (this == (wxTopLevelWindowGTK*)g_activeFrame);
35ff90a0
RR
1227}
1228