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