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