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