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