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