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