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