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