]> git.saurik.com Git - wxWidgets.git/blame - src/gtk1/toplevel.cpp
Hopefully fixed library names generated by wx-config for OS/2's PM port.
[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
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)
caf3e97f 475 if (!gtk_check_version(2,1,0))
11475235 476 {
caf3e97f
KH
477 if (style & wxFRAME_TOOL_WINDOW)
478 {
479 gtk_window_set_type_hint(GTK_WINDOW(m_widget),
480 GDK_WINDOW_TYPE_HINT_UTILITY);
11475235 481
caf3e97f
KH
482 // On some WMs, like KDE, a TOOL_WINDOW will still show
483 // on the taskbar, but on Gnome a TOOL_WINDOW will not.
484 // For consistency between WMs and with Windows, we
485 // should set the NO_TASKBAR flag which will apply
486 // the set_skip_taskbar_hint if it is available,
487 // ensuring no taskbar entry will appear.
488 style |= wxFRAME_NO_TASKBAR;
489 }
11475235 490 }
cf49c955 491#endif
4d8d6490 492 }
63c5efa3 493 }
7d9f12f3 494
e25c7537
VS
495 wxWindow *topParent = wxGetTopLevelParent(m_parent);
496 if (topParent && (((GTK_IS_WINDOW(topParent->m_widget)) &&
50819679
JS
497 (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG)) ||
498 (style & wxFRAME_FLOAT_ON_PARENT)))
7cd95599 499 {
e25c7537
VS
500 gtk_window_set_transient_for( GTK_WINDOW(m_widget),
501 GTK_WINDOW(topParent->m_widget) );
7cd95599 502 }
7d9f12f3 503
2be125e6 504#if GTK_CHECK_VERSION(2,2,0)
caf3e97f 505 if (!gtk_check_version(2,2,0))
2be125e6 506 {
caf3e97f
KH
507 if (style & wxFRAME_NO_TASKBAR)
508 {
509 gtk_window_set_skip_taskbar_hint(GTK_WINDOW(m_widget), TRUE);
510 }
2be125e6
VS
511 }
512#endif
513
2fca39c9 514#if GTK_CHECK_VERSION(2,4,0)
81a3313a 515 if (!gtk_check_version(2,4,0))
2fca39c9 516 {
81a3313a
RR
517 if (style & wxSTAY_ON_TOP)
518 {
519 gtk_window_set_keep_above(GTK_WINDOW(m_widget), TRUE);
520 }
2fca39c9
KH
521 }
522#endif
523
7d9f12f3 524 if (!name.IsEmpty())
fab591c5 525 gtk_window_set_wmclass( GTK_WINDOW(m_widget), wxGTK_CONV( name ), wxGTK_CONV( name ) );
7d9f12f3 526
fab591c5 527 gtk_window_set_title( GTK_WINDOW(m_widget), wxGTK_CONV( title ) );
7d9f12f3
VS
528 GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS );
529
530 gtk_signal_connect( GTK_OBJECT(m_widget), "delete_event",
531 GTK_SIGNAL_FUNC(gtk_frame_delete_callback), (gpointer)this );
532
e1f14d22 533 // m_mainWidget holds the toolbar, the menubar and the client area
7d9f12f3
VS
534 m_mainWidget = gtk_pizza_new();
535 gtk_widget_show( m_mainWidget );
536 GTK_WIDGET_UNSET_FLAGS( m_mainWidget, GTK_CAN_FOCUS );
537 gtk_container_add( GTK_CONTAINER(m_widget), m_mainWidget );
538
cba9ef7f
RR
539 if (m_miniEdge == 0) // wxMiniFrame has its own version.
540 {
541 // For m_mainWidget themes
542 gtk_signal_connect( GTK_OBJECT(m_mainWidget), "expose_event",
7d9f12f3 543 GTK_SIGNAL_FUNC(gtk_window_expose_callback), (gpointer)this );
4e5a4c69 544#ifndef __WXGTK20__
cba9ef7f 545 gtk_signal_connect( GTK_OBJECT(m_mainWidget), "draw",
7d9f12f3 546 GTK_SIGNAL_FUNC(gtk_window_draw_callback), (gpointer)this );
4e5a4c69 547#endif
cba9ef7f 548 }
7d9f12f3 549
e1f14d22 550 // m_wxwindow only represents the client area without toolbar and menubar
7d9f12f3
VS
551 m_wxwindow = gtk_pizza_new();
552 gtk_widget_show( m_wxwindow );
553 gtk_container_add( GTK_CONTAINER(m_mainWidget), m_wxwindow );
554
e1f14d22
RR
555 // we donm't allow the frame to get the focus as otherwise
556 // the frame will grab it at arbitrary focus changes
7d9f12f3
VS
557 GTK_WIDGET_UNSET_FLAGS( m_wxwindow, GTK_CAN_FOCUS );
558
559 if (m_parent) m_parent->AddChild( this );
560
e1f14d22 561 // the user resized the frame by dragging etc.
7d9f12f3
VS
562 gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate",
563 GTK_SIGNAL_FUNC(gtk_frame_size_callback), (gpointer)this );
564
565 PostCreation();
566
567 if ((m_x != -1) || (m_y != -1))
568 gtk_widget_set_uposition( m_widget, m_x, m_y );
6aeb6f2a 569
e1f14d22 570 gtk_window_set_default_size( GTK_WINDOW(m_widget), m_width, m_height );
7d9f12f3 571
e1f14d22
RR
572 // we cannot set MWM hints and icons before the widget has
573 // been realized, so we do this directly after realization
7d9f12f3
VS
574 gtk_signal_connect( GTK_OBJECT(m_widget), "realize",
575 GTK_SIGNAL_FUNC(gtk_frame_realized_callback), (gpointer) this );
576
e1f14d22 577 // the only way to get the window size is to connect to this event
7d9f12f3
VS
578 gtk_signal_connect( GTK_OBJECT(m_widget), "configure_event",
579 GTK_SIGNAL_FUNC(gtk_frame_configure_callback), (gpointer)this );
580
e1f14d22 581 // map and unmap for iconized state
7d9f12f3
VS
582 gtk_signal_connect( GTK_OBJECT(m_widget), "map_event",
583 GTK_SIGNAL_FUNC(gtk_frame_map_callback), (gpointer)this );
584 gtk_signal_connect( GTK_OBJECT(m_widget), "unmap_event",
585 GTK_SIGNAL_FUNC(gtk_frame_unmap_callback), (gpointer)this );
586
e1f14d22 587 // the only way to get the window size is to connect to this event
7d9f12f3
VS
588 gtk_signal_connect( GTK_OBJECT(m_widget), "configure_event",
589 GTK_SIGNAL_FUNC(gtk_frame_configure_callback), (gpointer)this );
590
e1f14d22 591 // disable native tab traversal
7d9f12f3
VS
592 gtk_signal_connect( GTK_OBJECT(m_widget), "focus",
593 GTK_SIGNAL_FUNC(gtk_frame_focus_callback), (gpointer)this );
594
06fda9e8
RR
595 // activation
596 gtk_signal_connect( GTK_OBJECT(m_widget), "focus_in_event",
597 GTK_SIGNAL_FUNC(gtk_frame_focus_in_callback), (gpointer)this );
598 gtk_signal_connect( GTK_OBJECT(m_widget), "focus_out_event",
599 GTK_SIGNAL_FUNC(gtk_frame_focus_out_callback), (gpointer)this );
600
e1f14d22 601 // decorations
f819b4a3
VS
602 if ((m_miniEdge > 0) || (style & wxSIMPLE_BORDER) || (style & wxNO_BORDER))
603 {
604 m_gdkDecor = 0;
605 m_gdkFunc = 0;
606 }
607 else
608 {
609 m_gdkDecor = (long) GDK_DECOR_BORDER;
610 m_gdkFunc = (long) GDK_FUNC_MOVE;
82c9f85c 611
f819b4a3 612 // All this is for Motif Window Manager "hints" and is supposed to be
e1f14d22 613 // recognized by other WMs as well.
f819b4a3 614 if ((style & wxCAPTION) != 0)
c3d8ee42 615 {
f819b4a3 616 m_gdkDecor |= GDK_DECOR_TITLE;
c3d8ee42 617 }
850c6ed4 618 if ((style & wxCLOSE_BOX) != 0)
f819b4a3
VS
619 {
620 m_gdkFunc |= GDK_FUNC_CLOSE;
c3d8ee42
VS
621 }
622 if ((style & wxSYSTEM_MENU) != 0)
623 {
f819b4a3
VS
624 m_gdkDecor |= GDK_DECOR_MENU;
625 }
626 if ((style & wxMINIMIZE_BOX) != 0)
627 {
628 m_gdkFunc |= GDK_FUNC_MINIMIZE;
629 m_gdkDecor |= GDK_DECOR_MINIMIZE;
630 }
631 if ((style & wxMAXIMIZE_BOX) != 0)
632 {
633 m_gdkFunc |= GDK_FUNC_MAXIMIZE;
634 m_gdkDecor |= GDK_DECOR_MAXIMIZE;
635 }
636 if ((style & wxRESIZE_BORDER) != 0)
637 {
638 m_gdkFunc |= GDK_FUNC_RESIZE;
639 m_gdkDecor |= GDK_DECOR_RESIZEH;
640 }
641 }
642
7d9f12f3
VS
643 return TRUE;
644}
645
646wxTopLevelWindowGTK::~wxTopLevelWindowGTK()
647{
5152b0e5
JS
648 if (m_grabbed)
649 {
83afe211 650 wxASSERT_MSG( FALSE, _T("Window still grabbed"));
5152b0e5
JS
651 RemoveGrab();
652 }
1cbee0b4 653
7d9f12f3 654 m_isBeingDeleted = TRUE;
6aeb6f2a 655
710968c3
VZ
656 // it may also be GtkScrolledWindow in the case of an MDI child
657 if (GTK_IS_WINDOW(m_widget))
658 {
659 gtk_window_set_focus( GTK_WINDOW(m_widget), NULL );
660 }
06fda9e8
RR
661
662 if (g_activeFrame == this)
663 g_activeFrame = NULL;
664 if (g_lastActiveFrame == this)
665 g_lastActiveFrame = NULL;
7d9f12f3
VS
666}
667
8a9650ea 668
8a9650ea 669
7d9f12f3
VS
670bool wxTopLevelWindowGTK::ShowFullScreen(bool show, long style )
671{
8a8997c3
VZ
672 if (show == m_fsIsShowing)
673 return FALSE; // return what?
7d9f12f3
VS
674
675 m_fsIsShowing = show;
feb1c9fb 676
1542ea39 677 wxX11FullScreenMethod method =
8166ab43
VS
678 wxGetFullScreenMethodX11((WXDisplay*)GDK_DISPLAY(),
679 (WXWindow)GDK_ROOT_WINDOW());
1542ea39 680
feb1c9fb
VS
681#if GTK_CHECK_VERSION(2,2,0)
682 // NB: gtk_window_fullscreen() uses freedesktop.org's WMspec extensions
683 // to switch to fullscreen, which is not always available. We must
684 // check if WM supports the spec and use legacy methods if it
685 // doesn't.
686 if (method == wxX11_FS_WMSPEC)
7d9f12f3 687 {
feb1c9fb
VS
688 if (show)
689 gtk_window_fullscreen( GTK_WINDOW( m_widget ) );
690 else
691 gtk_window_unfullscreen( GTK_WINDOW( m_widget ) );
8a8997c3
VZ
692
693 return TRUE;
7d9f12f3
VS
694 }
695 else
8a8997c3 696#endif // GTK+ >= 2.2.0
7d9f12f3 697 {
feb1c9fb
VS
698 GdkWindow *window = m_widget->window;
699
700 if (show)
8166ab43 701 {
feb1c9fb
VS
702 m_fsSaveFlag = style;
703 GetPosition( &m_fsSaveFrame.x, &m_fsSaveFrame.y );
704 GetSize( &m_fsSaveFrame.width, &m_fsSaveFrame.height );
705
706 int screen_width,screen_height;
707 wxDisplaySize( &screen_width, &screen_height );
708
709 gint client_x, client_y, root_x, root_y;
710 gint width, height;
711
712 if (method != wxX11_FS_WMSPEC)
713 {
714 // don't do it always, Metacity hates it
715 m_fsSaveGdkFunc = m_gdkFunc;
716 m_fsSaveGdkDecor = m_gdkDecor;
717 m_gdkFunc = m_gdkDecor = 0;
718 gdk_window_set_decorations(window, (GdkWMDecoration)0);
719 gdk_window_set_functions(window, (GdkWMFunction)0);
720 }
721
722 gdk_window_get_origin (m_widget->window, &root_x, &root_y);
723 gdk_window_get_geometry (m_widget->window, &client_x, &client_y,
724 &width, &height, NULL);
725
726 gdk_window_move_resize (m_widget->window, -client_x, -client_y,
727 screen_width + 1, screen_height + 1);
728
729 wxSetFullScreenStateX11((WXDisplay*)GDK_DISPLAY(),
730 (WXWindow)GDK_ROOT_WINDOW(),
731 (WXWindow)GDK_WINDOW_XWINDOW(window),
732 show, &m_fsSaveFrame, method);
733 }
734 else
735 {
736 if (method != wxX11_FS_WMSPEC)
737 {
738 // don't do it always, Metacity hates it
739 m_gdkFunc = m_fsSaveGdkFunc;
740 m_gdkDecor = m_fsSaveGdkDecor;
741 gdk_window_set_decorations(window, (GdkWMDecoration)m_gdkDecor);
742 gdk_window_set_functions(window, (GdkWMFunction)m_gdkFunc);
743 }
744
745 wxSetFullScreenStateX11((WXDisplay*)GDK_DISPLAY(),
746 (WXWindow)GDK_ROOT_WINDOW(),
747 (WXWindow)GDK_WINDOW_XWINDOW(window),
748 show, &m_fsSaveFrame, method);
749
750 SetSize(m_fsSaveFrame.x, m_fsSaveFrame.y,
751 m_fsSaveFrame.width, m_fsSaveFrame.height);
8166ab43 752 }
7d9f12f3 753 }
8166ab43 754
7d9f12f3
VS
755 return TRUE;
756}
757
758// ----------------------------------------------------------------------------
759// overridden wxWindow methods
760// ----------------------------------------------------------------------------
761
762bool wxTopLevelWindowGTK::Show( bool show )
763{
82b978d7 764 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
7d9f12f3
VS
765
766 if (show && !m_sizeSet)
767 {
768 /* by calling GtkOnSize here, we don't have to call
769 either after showing the frame, which would entail
770 much ugly flicker or from within the size_allocate
771 handler, because GTK 1.1.X forbids that. */
772
773 GtkOnSize( m_x, m_y, m_width, m_height );
774 }
32f2ebbf
RR
775
776 if (show)
777 gtk_widget_set_uposition( m_widget, m_x, m_y );
778
7d9f12f3
VS
779 return wxWindow::Show( show );
780}
781
a2ac55f5
RR
782void wxTopLevelWindowGTK::Raise()
783{
784#ifdef __WXGTK20__
785 gtk_window_present( GTK_WINDOW( m_widget ) );
786#else
787 wxWindow::Raise();
788#endif
789}
790
7d9f12f3
VS
791void wxTopLevelWindowGTK::DoMoveWindow(int WXUNUSED(x), int WXUNUSED(y), int WXUNUSED(width), int WXUNUSED(height) )
792{
793 wxFAIL_MSG( wxT("DoMoveWindow called for wxTopLevelWindowGTK") );
794}
795
796void wxTopLevelWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags )
797{
82b978d7
RD
798 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
799
e1f14d22 800 // this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow
7d9f12f3
VS
801 wxASSERT_MSG( (m_wxwindow != NULL), wxT("invalid frame") );
802
e1f14d22 803 // avoid recursions
7d9f12f3
VS
804 if (m_resizing)
805 return;
806 m_resizing = TRUE;
807
808 int old_x = m_x;
809 int old_y = m_y;
810
811 int old_width = m_width;
812 int old_height = m_height;
813
814 if ((sizeFlags & wxSIZE_ALLOW_MINUS_ONE) == 0)
815 {
816 if (x != -1) m_x = x;
817 if (y != -1) m_y = y;
7d9f12f3
VS
818 }
819 else
820 {
821 m_x = x;
822 m_y = y;
7d9f12f3 823 }
d44c23ce
RR
824 if (width != -1) m_width = width;
825 if (height != -1) m_height = height;
7d9f12f3
VS
826
827/*
828 if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
829 {
830 if (width == -1) m_width = 80;
831 }
832
833 if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
834 {
835 if (height == -1) m_height = 26;
836 }
837*/
838
e7dda1ff
VS
839 int minWidth = GetMinWidth(),
840 minHeight = GetMinHeight(),
841 maxWidth = GetMaxWidth(),
842 maxHeight = GetMaxHeight();
843
62be94e1
RR
844#ifdef __WXGPE__
845 // GPE's window manager doesn't like size hints
846 // at all, esp. when the user has to use the
847 // virtual keyboard.
848 minWidth = -1;
849 minHeight = -1;
850 maxWidth = -1;
851 maxHeight = -1;
852#endif
ca06ee0d 853
e7dda1ff
VS
854 if ((minWidth != -1) && (m_width < minWidth)) m_width = minWidth;
855 if ((minHeight != -1) && (m_height < minHeight)) m_height = minHeight;
856 if ((maxWidth != -1) && (m_width > maxWidth)) m_width = maxWidth;
857 if ((maxHeight != -1) && (m_height > maxHeight)) m_height = maxHeight;
7d9f12f3
VS
858
859 if ((m_x != -1) || (m_y != -1))
860 {
861 if ((m_x != old_x) || (m_y != old_y))
862 {
863 gtk_widget_set_uposition( m_widget, m_x, m_y );
864 }
865 }
866
867 if ((m_width != old_width) || (m_height != old_height))
868 {
e1f14d22
RR
869 if (m_widget->window)
870 gdk_window_resize( m_widget->window, m_width, m_height );
871 else
872 gtk_window_set_default_size( GTK_WINDOW(m_widget), m_width, m_height );
7d9f12f3
VS
873
874 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
875 done either directly before the frame is shown or in idle time
876 so that different calls to SetSize() don't lead to flicker. */
877 m_sizeSet = FALSE;
878 }
879
880 m_resizing = FALSE;
881}
882
883void wxTopLevelWindowGTK::DoGetClientSize( int *width, int *height ) const
884{
82b978d7
RD
885 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
886
7d9f12f3
VS
887 wxWindow::DoGetClientSize( width, height );
888 if (height)
889 {
e1f14d22 890 // mini edge
7d9f12f3
VS
891 *height -= m_miniEdge*2 + m_miniTitle;
892 }
893 if (width)
894 {
895 *width -= m_miniEdge*2;
896 }
897}
898
899void wxTopLevelWindowGTK::DoSetClientSize( int width, int height )
900{
82b978d7 901 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
7d9f12f3 902
82c9f85c 903 DoSetSize(-1, -1,
7d9f12f3
VS
904 width + m_miniEdge*2, height + m_miniEdge*2 + m_miniTitle, 0);
905}
906
907void wxTopLevelWindowGTK::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y),
82c9f85c 908 int width, int height )
7d9f12f3
VS
909{
910 // due to a bug in gtk, x,y are always 0
911 // m_x = x;
912 // m_y = y;
913
e1f14d22 914 // avoid recursions
7d9f12f3
VS
915 if (m_resizing) return;
916 m_resizing = TRUE;
917
918 if ( m_wxwindow == NULL ) return;
919
920 m_width = width;
921 m_height = height;
922
0d53fc34 923 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
7d9f12f3 924 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
0d53fc34 925 set in wxFrame::Create so it is used to check what kind of frame we
7d9f12f3
VS
926 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
927 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
928 importantly) m_mainWidget */
929
e7dda1ff
VS
930 int minWidth = GetMinWidth(),
931 minHeight = GetMinHeight(),
932 maxWidth = GetMaxWidth(),
933 maxHeight = GetMaxHeight();
934
62be94e1
RR
935#ifdef __WXGPE__
936 // GPE's window manager doesn't like size hints
937 // at all, esp. when the user has to use the
938 // virtual keyboard.
939 minWidth = -1;
940 minHeight = -1;
941 maxWidth = -1;
942 maxHeight = -1;
943#endif
ca06ee0d 944
e7dda1ff
VS
945 if ((minWidth != -1) && (m_width < minWidth)) m_width = minWidth;
946 if ((minHeight != -1) && (m_height < minHeight)) m_height = minHeight;
947 if ((maxWidth != -1) && (m_width > maxWidth)) m_width = maxWidth;
948 if ((maxHeight != -1) && (m_height > maxHeight)) m_height = maxHeight;
7d9f12f3
VS
949
950 if (m_mainWidget)
951 {
e1f14d22 952 // set size hints
801225c1
RL
953 gint flag = 0; // GDK_HINT_POS;
954 GdkGeometry geom;
955
e7dda1ff
VS
956 if ((minWidth != -1) || (minHeight != -1)) flag |= GDK_HINT_MIN_SIZE;
957 if ((maxWidth != -1) || (maxHeight != -1)) flag |= GDK_HINT_MAX_SIZE;
801225c1 958
e7dda1ff
VS
959 geom.min_width = minWidth;
960 geom.min_height = minHeight;
801225c1
RL
961
962 // Because of the way we set GDK_HINT_MAX_SIZE above, if either of
963 // maxHeight or maxWidth is set, we must set them both, else the
964 // remaining -1 will be taken literally.
965
966 // I'm certain this also happens elsewhere, and is the probable
967 // cause of other such things as:
968 // Gtk-WARNING **: gtk_widget_size_allocate():
969 // attempt to allocate widget with width 65535 and height 600
970 // but I don't have time to track them all now..
1cbee0b4 971 //
801225c1
RL
972 // Really we need to encapulate all this height/width business and
973 // stop any old method from ripping at the members directly and
974 // scattering -1's without regard for who might resolve them later.
975
976 geom.max_width = ( maxHeight == -1 ) ? maxWidth
977 : ( maxWidth == -1 ) ? wxGetDisplaySize().GetWidth()
978 : maxWidth ;
979
980 geom.max_height = ( maxWidth == -1 ) ? maxHeight // ( == -1 here )
981 : ( maxHeight == -1 ) ? wxGetDisplaySize().GetHeight()
982 : maxHeight ;
983
7d9f12f3
VS
984 gtk_window_set_geometry_hints( GTK_WINDOW(m_widget),
985 (GtkWidget*) NULL,
986 &geom,
987 (GdkWindowHints) flag );
988
989 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
990 * menubar, the toolbar and the client area, which is represented by
991 * m_wxwindow.
992 * this hurts in the eye, but I don't want to call SetSize()
993 * because I don't want to call any non-native functions here. */
994
995 int client_x = m_miniEdge;
996 int client_y = m_miniEdge + m_miniTitle;
997 int client_w = m_width - 2*m_miniEdge;
998 int client_h = m_height - 2*m_miniEdge - m_miniTitle;
801225c1 999
7d9f12f3
VS
1000 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget),
1001 m_wxwindow,
1002 client_x, client_y, client_w, client_h );
1003 }
1004 else
1005 {
e1f14d22
RR
1006 // If there is no m_mainWidget between m_widget and m_wxwindow there
1007 // is no need to set the size or position of m_wxwindow.
7d9f12f3
VS
1008 }
1009
1010 m_sizeSet = TRUE;
1011
1012 // send size event to frame
1013 wxSizeEvent event( wxSize(m_width,m_height), GetId() );
1014 event.SetEventObject( this );
1015 GetEventHandler()->ProcessEvent( event );
1016
1017 m_resizing = FALSE;
1018}
1019
1020void wxTopLevelWindowGTK::OnInternalIdle()
1021{
1022 if (!m_sizeSet && GTK_WIDGET_REALIZED(m_wxwindow))
1023 {
1024 GtkOnSize( m_x, m_y, m_width, m_height );
1025
1026 // we'll come back later
1027 if (g_isIdle)
1028 wxapp_install_idle_handler();
1029 return;
1030 }
1031
6aeb6f2a
VZ
1032 // set the focus if not done yet and if we can already do it
1033 if ( GTK_WIDGET_REALIZED(m_wxwindow) )
1034 {
cc06fe74
MB
1035 if ( g_delayedFocus &&
1036 wxGetTopLevelParent((wxWindow*)g_delayedFocus) == this )
6aeb6f2a 1037 {
2b5f62a0
VZ
1038 wxLogTrace(_T("focus"),
1039 _T("Setting focus from wxTLW::OnIdle() to %s(%s)"),
1040 g_delayedFocus->GetClassInfo()->GetClassName(),
1041 g_delayedFocus->GetLabel().c_str());
1042
6aeb6f2a
VZ
1043 g_delayedFocus->SetFocus();
1044 g_delayedFocus = NULL;
1045 }
1046 }
1047
7d9f12f3 1048 wxWindow::OnInternalIdle();
06fda9e8
RR
1049
1050 // Synthetize activate events.
1051 if ( g_sendActivateEvent != -1 )
1052 {
1053 bool activate = g_sendActivateEvent != 0;
1054
576f7127
RR
1055 // if (!activate) wxPrintf( wxT("de") );
1056 // wxPrintf( wxT("activate\n") );
1057
06fda9e8
RR
1058 // do it only once
1059 g_sendActivateEvent = -1;
1060
1061 wxTheApp->SetActive(activate, (wxWindow *)g_lastActiveFrame);
1062 }
7d9f12f3
VS
1063}
1064
7d9f12f3
VS
1065// ----------------------------------------------------------------------------
1066// frame title/icon
1067// ----------------------------------------------------------------------------
1068
1069void wxTopLevelWindowGTK::SetTitle( const wxString &title )
1070{
82b978d7
RD
1071 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
1072
7d9f12f3 1073 m_title = title;
fab591c5 1074 gtk_window_set_title( GTK_WINDOW(m_widget), wxGTK_CONV( title ) );
7d9f12f3
VS
1075}
1076
f618020a
MB
1077void wxTopLevelWindowGTK::SetIcon( const wxIcon &icon )
1078{
1079 SetIcons( wxIconBundle( icon ) );
1080}
1081
1082void wxTopLevelWindowGTK::SetIcons( const wxIconBundle &icons )
1083{
82b978d7 1084 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
f618020a
MB
1085
1086 wxTopLevelWindowBase::SetIcons( icons );
1087
87e53e2a
VS
1088#ifdef __WXGTK20__
1089 GList *list = NULL;
1090 size_t max = icons.m_icons.GetCount();
1091
1092 for (size_t i = 0; i < max; i++)
52d6235d 1093 {
87e53e2a
VS
1094 if (icons.m_icons[i].Ok())
1095 {
1096 list = g_list_prepend(list, icons.m_icons[i].GetPixbuf());
1097 }
1098 }
1099 gtk_window_set_icon_list(GTK_WINDOW(m_widget), list);
1100 g_list_free(list);
1101
1102#else // !__WXGTK20__
1103 GdkWindow* window = m_widget->window;
1104 if (!window)
1105 return;
1106
1107 wxIcon icon = icons.GetIcon(-1);
1108 if (icon.Ok())
1109 {
1110 wxMask *mask = icon.GetMask();
1111 GdkBitmap *bm = (GdkBitmap *) NULL;
1112 if (mask) bm = mask->GetBitmap();
1113
1114 gdk_window_set_icon( m_widget->window, (GdkWindow *) NULL, icon.GetPixmap(), bm );
52d6235d 1115 }
87e53e2a
VS
1116
1117 wxSetIconsX11( (WXDisplay*)GDK_WINDOW_XDISPLAY( window ),
1118 (WXWindow)GDK_WINDOW_XWINDOW( window ), icons );
1119#endif // !__WXGTK20__
f618020a
MB
1120}
1121
7d9f12f3
VS
1122// ----------------------------------------------------------------------------
1123// frame state: maximized/iconized/normal
1124// ----------------------------------------------------------------------------
1125
8805e155 1126void wxTopLevelWindowGTK::Maximize(bool maximize)
7d9f12f3 1127{
8805e155
RR
1128#ifdef __WXGTK20__
1129 if (maximize)
1130 gtk_window_maximize( GTK_WINDOW( m_widget ) );
1131 else
1132 gtk_window_unmaximize( GTK_WINDOW( m_widget ) );
1133#else
7d9f12f3 1134 wxFAIL_MSG( _T("not implemented") );
8805e155 1135#endif
7d9f12f3
VS
1136}
1137
1138bool wxTopLevelWindowGTK::IsMaximized() const
1139{
d8e1fe80
VS
1140#ifdef __WXGTK20__
1141 if(!m_widget->window)
1142 return false;
1143
1144 return gdk_window_get_state(m_widget->window) & GDK_WINDOW_STATE_MAXIMIZED;
1145#else
7d9f12f3
VS
1146 // wxFAIL_MSG( _T("not implemented") );
1147
1148 // This is an approximation
1149 return FALSE;
d8e1fe80 1150#endif
7d9f12f3
VS
1151}
1152
1153void wxTopLevelWindowGTK::Restore()
1154{
387fd89d 1155#ifdef __WXGTK20__
8805e155
RR
1156 // "Present" seems similar enough to "restore"
1157 gtk_window_present( GTK_WINDOW( m_widget ) );
1158#else
7d9f12f3 1159 wxFAIL_MSG( _T("not implemented") );
8805e155 1160#endif
7d9f12f3
VS
1161}
1162
1163void wxTopLevelWindowGTK::Iconize( bool iconize )
1164{
8805e155
RR
1165#ifdef __WXGTK20__
1166 if (iconize)
1167 gtk_window_iconify( GTK_WINDOW( m_widget ) );
1168 else
1169 gtk_window_deiconify( GTK_WINDOW( m_widget ) );
1170#else
7d9f12f3
VS
1171 if (iconize)
1172 {
1173 GdkWindow *window = m_widget->window;
1174
1175 // you should do it later, for example from OnCreate() handler
1176 wxCHECK_RET( window, _T("frame not created yet - can't iconize") );
1177
1178 XIconifyWindow( GDK_WINDOW_XDISPLAY( window ),
1179 GDK_WINDOW_XWINDOW( window ),
1180 DefaultScreen( GDK_DISPLAY() ) );
1181 }
8805e155 1182#endif
7d9f12f3
VS
1183}
1184
1185bool wxTopLevelWindowGTK::IsIconized() const
1186{
1187 return m_isIconized;
1188}
1189
1190void wxTopLevelWindowGTK::SetIconizeState(bool iconize)
1191{
1192 if ( iconize != m_isIconized )
1193 {
1194 m_isIconized = iconize;
1195 (void)SendIconizeEvent(iconize);
1196 }
1197}
1198
5152b0e5
JS
1199void wxTopLevelWindowGTK::AddGrab()
1200{
1201 if (!m_grabbed)
1202 {
1203 m_grabbed = TRUE;
1204 gtk_grab_add( m_widget );
1205 gtk_main();
1206 gtk_grab_remove( m_widget );
1207 }
1208}
1209
1210void wxTopLevelWindowGTK::RemoveGrab()
1211{
1212 if (m_grabbed)
1213 {
1214 gtk_main_quit();
1215 m_grabbed = FALSE;
1216 }
1217}
801225c1 1218
1542ea39
RD
1219
1220// helper
1221static bool do_shape_combine_region(GdkWindow* window, const wxRegion& region)
1222{
1223 if (window)
1224 {
1225 if (region.IsEmpty())
1226 {
1227 gdk_window_shape_combine_mask(window, NULL, 0, 0);
1228 }
1229 else
1230 {
1231#ifdef __WXGTK20__
1232 gdk_window_shape_combine_region(window, region.GetRegion(), 0, 0);
1233#else
1234 wxBitmap bmp = region.ConvertToBitmap();
819451b6 1235 bmp.SetMask(new wxMask(bmp, *wxBLACK));
1542ea39
RD
1236 GdkBitmap* mask = bmp.GetMask()->GetBitmap();
1237 gdk_window_shape_combine_mask(window, mask, 0, 0);
1238#endif
1239 return TRUE;
1240 }
1241 }
1242 return FALSE;
1243}
1244
1245
1246bool wxTopLevelWindowGTK::SetShape(const wxRegion& region)
1247{
6a7e6411
RD
1248 wxCHECK_MSG( HasFlag(wxFRAME_SHAPED), FALSE,
1249 _T("Shaped windows must be created with the wxFRAME_SHAPED style."));
1250
1542ea39
RD
1251 GdkWindow *window = NULL;
1252 if (m_wxwindow)
1253 {
1254 window = GTK_PIZZA(m_wxwindow)->bin_window;
1255 do_shape_combine_region(window, region);
1256 }
1257 window = m_widget->window;
1258 return do_shape_combine_region(window, region);
1259}
1260
6b30a44e 1261bool wxTopLevelWindowGTK::IsActive()
35ff90a0 1262{
06fda9e8 1263 return (this == (wxTopLevelWindowGTK*)g_activeFrame);
35ff90a0
RR
1264}
1265