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