1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
10 // ============================================================================
12 // ============================================================================
14 // ----------------------------------------------------------------------------
16 // ----------------------------------------------------------------------------
18 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
19 #pragma implementation "toplevel.h"
22 // For compilers that support precompilation, includes "wx.h".
23 #include "wx/wxprec.h"
26 #define XIconifyWindow XICONIFYWINDOW
32 #include "wx/dialog.h"
33 #include "wx/control.h"
35 #include "wx/dcclient.h"
36 #include "wx/gtk/private.h"
38 #include "wx/settings.h"
43 #include <gdk/gdkkeysyms.h>
46 #include "wx/gtk/win_gtk.h"
48 #include "wx/unix/utilsx11.h"
51 #include <X11/Xatom.h>
53 // ----------------------------------------------------------------------------
55 // ----------------------------------------------------------------------------
57 extern void wxapp_install_idle_handler();
60 // ----------------------------------------------------------------------------
62 // ----------------------------------------------------------------------------
64 extern wxList wxPendingDelete
;
66 extern int g_openDialogs
;
67 extern wxWindowGTK
*g_delayedFocus
;
69 //-----------------------------------------------------------------------------
70 // "focus" from m_window
71 //-----------------------------------------------------------------------------
73 static gint
gtk_frame_focus_callback( GtkWidget
*widget
, GtkDirectionType
WXUNUSED(d
), wxWindow
*WXUNUSED(win
) )
76 wxapp_install_idle_handler();
78 // This disables GTK's tab traversal
79 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus" );
83 //-----------------------------------------------------------------------------
85 //-----------------------------------------------------------------------------
87 static void gtk_frame_size_callback( GtkWidget
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxTopLevelWindowGTK
*win
)
90 wxapp_install_idle_handler();
95 if ((win
->m_width
!= alloc
->width
) || (win
->m_height
!= alloc
->height
))
98 wxPrintf( "OnSize from " );
99 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
100 wxPrintf( win->GetClassInfo()->GetClassName() );
101 wxPrintf( " %d %d %d %d\n", (int)alloc->x,
104 (int)alloc->height );
107 win
->m_width
= alloc
->width
;
108 win
->m_height
= alloc
->height
;
109 win
->GtkUpdateSize();
113 //-----------------------------------------------------------------------------
115 //-----------------------------------------------------------------------------
117 static gint
gtk_frame_delete_callback( GtkWidget
*WXUNUSED(widget
), GdkEvent
*WXUNUSED(event
), wxTopLevelWindowGTK
*win
)
120 wxapp_install_idle_handler();
122 if (win
->IsEnabled() &&
123 (g_openDialogs
== 0 || (win
->GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
) ||
131 //-----------------------------------------------------------------------------
133 //-----------------------------------------------------------------------------
136 gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*WXUNUSED(event
), wxTopLevelWindowGTK
*win
)
139 wxapp_install_idle_handler();
141 if (!win
->m_hasVMT
|| !win
->IsShown())
146 gdk_window_get_root_origin( win
->m_widget
->window
, &x
, &y
);
150 wxMoveEvent
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() );
151 mevent
.SetEventObject( win
);
152 win
->GetEventHandler()->ProcessEvent( mevent
);
157 //-----------------------------------------------------------------------------
158 // "realize" from m_widget
159 //-----------------------------------------------------------------------------
161 // we cannot MWM hints and icons before the widget has been realized,
162 // so we do this directly after realization
165 gtk_frame_realized_callback( GtkWidget
* WXUNUSED(widget
),
166 wxTopLevelWindowGTK
*win
)
169 wxapp_install_idle_handler();
171 // All this is for Motif Window Manager "hints" and is supposed to be
172 // recognized by other WM as well. Not tested.
173 gdk_window_set_decorations(win
->m_widget
->window
,
174 (GdkWMDecoration
)win
->m_gdkDecor
);
175 gdk_window_set_functions(win
->m_widget
->window
,
176 (GdkWMFunction
)win
->m_gdkFunc
);
178 // GTK's shrinking/growing policy
179 if ((win
->m_gdkFunc
& GDK_FUNC_RESIZE
) == 0)
180 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1);
182 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1);
185 wxIconBundle iconsOld
= win
->GetIcons();
186 if ( iconsOld
.GetIcon(-1).Ok() )
188 win
->SetIcon( wxNullIcon
);
189 win
->SetIcons( iconsOld
);
193 //-----------------------------------------------------------------------------
194 // "map_event" from m_widget
195 //-----------------------------------------------------------------------------
198 gtk_frame_map_callback( GtkWidget
* WXUNUSED(widget
),
199 GdkEvent
* WXUNUSED(event
),
200 wxTopLevelWindow
*win
)
202 win
->SetIconizeState(FALSE
);
205 //-----------------------------------------------------------------------------
206 // "unmap_event" from m_widget
207 //-----------------------------------------------------------------------------
210 gtk_frame_unmap_callback( GtkWidget
* WXUNUSED(widget
),
211 GdkEvent
* WXUNUSED(event
),
212 wxTopLevelWindow
*win
)
214 win
->SetIconizeState(TRUE
);
217 //-----------------------------------------------------------------------------
218 // "expose_event" of m_client
219 //-----------------------------------------------------------------------------
221 static int gtk_window_expose_callback( GtkWidget
*widget
, GdkEventExpose
*gdk_event
, wxWindow
*win
)
223 GtkPizza
*pizza
= GTK_PIZZA(widget
);
225 gtk_paint_flat_box (win
->m_widget
->style
,
226 pizza
->bin_window
, GTK_STATE_NORMAL
,
236 //-----------------------------------------------------------------------------
237 // "draw" of m_client
238 //-----------------------------------------------------------------------------
242 static void gtk_window_draw_callback( GtkWidget
*widget
, GdkRectangle
*rect
, wxWindow
*win
)
244 GtkPizza
*pizza
= GTK_PIZZA(widget
);
246 gtk_paint_flat_box (win
->m_widget
->style
,
247 pizza
->bin_window
, GTK_STATE_NORMAL
,
257 // ----------------------------------------------------------------------------
258 // wxTopLevelWindowGTK itself
259 // ----------------------------------------------------------------------------
261 //-----------------------------------------------------------------------------
262 // InsertChild for wxTopLevelWindowGTK
263 //-----------------------------------------------------------------------------
265 /* Callback for wxTopLevelWindowGTK. This very strange beast has to be used because
266 * C++ has no virtual methods in a constructor. We have to emulate a
267 * virtual function here as wxWidgets requires different ways to insert
268 * a child in container classes. */
270 static void wxInsertChildInTopLevelWindow( wxTopLevelWindowGTK
* parent
, wxWindow
* child
)
272 wxASSERT( GTK_IS_WIDGET(child
->m_widget
) );
274 if (!parent
->m_insertInClientArea
)
276 // these are outside the client area
277 wxTopLevelWindowGTK
* frame
= (wxTopLevelWindowGTK
*) parent
;
278 gtk_pizza_put( GTK_PIZZA(frame
->m_mainWidget
),
279 GTK_WIDGET(child
->m_widget
),
287 // these are inside the client area
288 gtk_pizza_put( GTK_PIZZA(parent
->m_wxwindow
),
289 GTK_WIDGET(child
->m_widget
),
296 // resize on OnInternalIdle
297 parent
->GtkUpdateSize();
300 // ----------------------------------------------------------------------------
301 // wxTopLevelWindowGTK creation
302 // ----------------------------------------------------------------------------
304 void wxTopLevelWindowGTK::Init()
309 m_mainWidget
= (GtkWidget
*) NULL
;
310 m_insertInClientArea
= TRUE
;
311 m_isIconized
= FALSE
;
312 m_fsIsShowing
= FALSE
;
313 m_themeEnabled
= TRUE
;
314 m_gdkDecor
= m_gdkFunc
= 0;
318 bool wxTopLevelWindowGTK::Create( wxWindow
*parent
,
320 const wxString
& title
,
322 const wxSize
& sizeOrig
,
324 const wxString
&name
)
326 // always create a frame of some reasonable, even if arbitrary, size (at
327 // least for MSW compatibility)
328 wxSize size
= sizeOrig
;
329 size
.x
= WidthDefault(size
.x
);
330 size
.y
= HeightDefault(size
.y
);
332 wxTopLevelWindows
.Append( this );
334 m_needParent
= FALSE
;
336 if (!PreCreation( parent
, pos
, size
) ||
337 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
339 wxFAIL_MSG( wxT("wxTopLevelWindowGTK creation failed") );
345 m_insertCallback
= (wxInsertChildFunction
) wxInsertChildInTopLevelWindow
;
347 // NB: m_widget may be !=NULL if it was created by derived class' Create,
348 // e.g. in wxTaskBarIconAreaGTK
349 if (m_widget
== NULL
)
351 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
352 if (style
& wxFRAME_TOOL_WINDOW
)
353 win_type
= GTK_WINDOW_POPUP
;
355 if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
)
358 m_widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
359 // Tell WM that this is a dialog window and make it center
360 // on parent by default (this is what GtkDialog ctor does):
361 gtk_window_set_type_hint(GTK_WINDOW(m_widget
),
362 GDK_WINDOW_TYPE_HINT_DIALOG
);
363 gtk_window_set_position(GTK_WINDOW(m_widget
),
364 GTK_WIN_POS_CENTER_ON_PARENT
);
366 m_widget
= gtk_window_new(GTK_WINDOW_DIALOG
);
371 m_widget
= gtk_window_new(win_type
);
375 if (m_parent
&& (((GTK_IS_WINDOW(m_parent
->m_widget
)) &&
376 (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
)) ||
377 (style
& wxFRAME_FLOAT_ON_PARENT
)))
379 gtk_window_set_transient_for( GTK_WINDOW(m_widget
), GTK_WINDOW(m_parent
->m_widget
) );
382 #if GTK_CHECK_VERSION(2,2,0)
383 if (style
& wxFRAME_NO_TASKBAR
)
385 gtk_window_set_skip_taskbar_hint(GTK_WINDOW(m_widget
), TRUE
);
390 gtk_window_set_wmclass( GTK_WINDOW(m_widget
), wxGTK_CONV( name
), wxGTK_CONV( name
) );
392 gtk_window_set_title( GTK_WINDOW(m_widget
), wxGTK_CONV( title
) );
393 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
395 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
396 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
398 // m_mainWidget holds the toolbar, the menubar and the client area
399 m_mainWidget
= gtk_pizza_new();
400 gtk_widget_show( m_mainWidget
);
401 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
402 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
404 if (m_miniEdge
== 0) // wxMiniFrame has its own version.
406 // For m_mainWidget themes
407 gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "expose_event",
408 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
410 gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "draw",
411 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
415 // m_wxwindow only represents the client area without toolbar and menubar
416 m_wxwindow
= gtk_pizza_new();
417 gtk_widget_show( m_wxwindow
);
418 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
420 // we donm't allow the frame to get the focus as otherwise
421 // the frame will grab it at arbitrary focus changes
422 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
424 if (m_parent
) m_parent
->AddChild( this );
426 // the user resized the frame by dragging etc.
427 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
428 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
432 if ((m_x
!= -1) || (m_y
!= -1))
433 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
435 gtk_window_set_default_size( GTK_WINDOW(m_widget
), m_width
, m_height
);
437 // we cannot set MWM hints and icons before the widget has
438 // been realized, so we do this directly after realization
439 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
440 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
442 // the only way to get the window size is to connect to this event
443 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
444 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
446 // map and unmap for iconized state
447 gtk_signal_connect( GTK_OBJECT(m_widget
), "map_event",
448 GTK_SIGNAL_FUNC(gtk_frame_map_callback
), (gpointer
)this );
449 gtk_signal_connect( GTK_OBJECT(m_widget
), "unmap_event",
450 GTK_SIGNAL_FUNC(gtk_frame_unmap_callback
), (gpointer
)this );
452 // the only way to get the window size is to connect to this event
453 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
454 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
456 // disable native tab traversal
457 gtk_signal_connect( GTK_OBJECT(m_widget
), "focus",
458 GTK_SIGNAL_FUNC(gtk_frame_focus_callback
), (gpointer
)this );
461 if ((m_miniEdge
> 0) || (style
& wxSIMPLE_BORDER
) || (style
& wxNO_BORDER
))
468 m_gdkDecor
= (long) GDK_DECOR_BORDER
;
469 m_gdkFunc
= (long) GDK_FUNC_MOVE
;
471 // All this is for Motif Window Manager "hints" and is supposed to be
472 // recognized by other WMs as well.
473 if ((style
& wxCAPTION
) != 0)
475 m_gdkDecor
|= GDK_DECOR_TITLE
;
477 if ((style
& wxCLOSE_BOX
) != 0)
479 m_gdkFunc
|= GDK_FUNC_CLOSE
;
481 if ((style
& wxSYSTEM_MENU
) != 0)
483 m_gdkDecor
|= GDK_DECOR_MENU
;
485 if ((style
& wxMINIMIZE_BOX
) != 0)
487 m_gdkFunc
|= GDK_FUNC_MINIMIZE
;
488 m_gdkDecor
|= GDK_DECOR_MINIMIZE
;
490 if ((style
& wxMAXIMIZE_BOX
) != 0)
492 m_gdkFunc
|= GDK_FUNC_MAXIMIZE
;
493 m_gdkDecor
|= GDK_DECOR_MAXIMIZE
;
495 if ((style
& wxRESIZE_BORDER
) != 0)
497 m_gdkFunc
|= GDK_FUNC_RESIZE
;
498 m_gdkDecor
|= GDK_DECOR_RESIZEH
;
505 wxTopLevelWindowGTK::~wxTopLevelWindowGTK()
509 wxASSERT_MSG( FALSE
, _T("Window still grabbed"));
513 m_isBeingDeleted
= TRUE
;
515 // it may also be GtkScrolledWindow in the case of an MDI child
516 if (GTK_IS_WINDOW(m_widget
))
518 gtk_window_set_focus( GTK_WINDOW(m_widget
), NULL
);
524 bool wxTopLevelWindowGTK::ShowFullScreen(bool show
, long style
)
526 if (show
== m_fsIsShowing
) return FALSE
; // return what?
528 m_fsIsShowing
= show
;
530 GdkWindow
*window
= m_widget
->window
;
531 wxX11FullScreenMethod method
=
532 wxGetFullScreenMethodX11((WXDisplay
*)GDK_DISPLAY(),
533 (WXWindow
)GDK_ROOT_WINDOW());
537 m_fsSaveFlag
= style
;
538 GetPosition( &m_fsSaveFrame
.x
, &m_fsSaveFrame
.y
);
539 GetSize( &m_fsSaveFrame
.width
, &m_fsSaveFrame
.height
);
541 int screen_width
,screen_height
;
542 wxDisplaySize( &screen_width
, &screen_height
);
544 gint client_x
, client_y
, root_x
, root_y
;
547 if (method
!= wxX11_FS_WMSPEC
)
549 // don't do it always, Metacity hates it
550 m_fsSaveGdkFunc
= m_gdkFunc
;
551 m_fsSaveGdkDecor
= m_gdkDecor
;
552 m_gdkFunc
= m_gdkDecor
= 0;
553 gdk_window_set_decorations(window
, (GdkWMDecoration
)0);
554 gdk_window_set_functions(window
, (GdkWMFunction
)0);
557 gdk_window_get_origin (m_widget
->window
, &root_x
, &root_y
);
558 gdk_window_get_geometry (m_widget
->window
, &client_x
, &client_y
,
559 &width
, &height
, NULL
);
561 gdk_window_move_resize (m_widget
->window
, -client_x
, -client_y
,
562 screen_width
+ 1, screen_height
+ 1);
564 wxSetFullScreenStateX11((WXDisplay
*)GDK_DISPLAY(),
565 (WXWindow
)GDK_ROOT_WINDOW(),
566 (WXWindow
)GDK_WINDOW_XWINDOW(window
),
567 show
, &m_fsSaveFrame
, method
);
571 if (method
!= wxX11_FS_WMSPEC
)
573 // don't do it always, Metacity hates it
574 m_gdkFunc
= m_fsSaveGdkFunc
;
575 m_gdkDecor
= m_fsSaveGdkDecor
;
576 gdk_window_set_decorations(window
, (GdkWMDecoration
)m_gdkDecor
);
577 gdk_window_set_functions(window
, (GdkWMFunction
)m_gdkFunc
);
580 wxSetFullScreenStateX11((WXDisplay
*)GDK_DISPLAY(),
581 (WXWindow
)GDK_ROOT_WINDOW(),
582 (WXWindow
)GDK_WINDOW_XWINDOW(window
),
583 show
, &m_fsSaveFrame
, method
);
585 SetSize(m_fsSaveFrame
.x
, m_fsSaveFrame
.y
,
586 m_fsSaveFrame
.width
, m_fsSaveFrame
.height
);
593 // ----------------------------------------------------------------------------
594 // overridden wxWindow methods
595 // ----------------------------------------------------------------------------
597 bool wxTopLevelWindowGTK::Show( bool show
)
599 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
601 if (show
&& !m_sizeSet
)
603 /* by calling GtkOnSize here, we don't have to call
604 either after showing the frame, which would entail
605 much ugly flicker or from within the size_allocate
606 handler, because GTK 1.1.X forbids that. */
608 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
611 return wxWindow::Show( show
);
614 void wxTopLevelWindowGTK::DoMoveWindow(int WXUNUSED(x
), int WXUNUSED(y
), int WXUNUSED(width
), int WXUNUSED(height
) )
616 wxFAIL_MSG( wxT("DoMoveWindow called for wxTopLevelWindowGTK") );
619 void wxTopLevelWindowGTK::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
621 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
623 // this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow
624 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
634 int old_width
= m_width
;
635 int old_height
= m_height
;
637 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
639 if (x
!= -1) m_x
= x
;
640 if (y
!= -1) m_y
= y
;
647 if (width
!= -1) m_width
= width
;
648 if (height
!= -1) m_height
= height
;
651 if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
653 if (width == -1) m_width = 80;
656 if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
658 if (height == -1) m_height = 26;
662 int minWidth
= GetMinWidth(),
663 minHeight
= GetMinHeight(),
664 maxWidth
= GetMaxWidth(),
665 maxHeight
= GetMaxHeight();
668 // GPE's window manager doesn't like size hints
669 // at all, esp. when the user has to use the
677 if ((minWidth
!= -1) && (m_width
< minWidth
)) m_width
= minWidth
;
678 if ((minHeight
!= -1) && (m_height
< minHeight
)) m_height
= minHeight
;
679 if ((maxWidth
!= -1) && (m_width
> maxWidth
)) m_width
= maxWidth
;
680 if ((maxHeight
!= -1) && (m_height
> maxHeight
)) m_height
= maxHeight
;
682 if ((m_x
!= -1) || (m_y
!= -1))
684 if ((m_x
!= old_x
) || (m_y
!= old_y
))
686 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
690 if ((m_width
!= old_width
) || (m_height
!= old_height
))
692 if (m_widget
->window
)
693 gdk_window_resize( m_widget
->window
, m_width
, m_height
);
695 gtk_window_set_default_size( GTK_WINDOW(m_widget
), m_width
, m_height
);
697 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
698 done either directly before the frame is shown or in idle time
699 so that different calls to SetSize() don't lead to flicker. */
706 void wxTopLevelWindowGTK::DoGetClientSize( int *width
, int *height
) const
708 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
710 wxWindow::DoGetClientSize( width
, height
);
714 *height
-= m_miniEdge
*2 + m_miniTitle
;
718 *width
-= m_miniEdge
*2;
722 void wxTopLevelWindowGTK::DoSetClientSize( int width
, int height
)
724 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
727 width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
, 0);
730 void wxTopLevelWindowGTK::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
),
731 int width
, int height
)
733 // due to a bug in gtk, x,y are always 0
738 if (m_resizing
) return;
741 if ( m_wxwindow
== NULL
) return;
746 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
747 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
748 set in wxFrame::Create so it is used to check what kind of frame we
749 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
750 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
751 importantly) m_mainWidget */
753 int minWidth
= GetMinWidth(),
754 minHeight
= GetMinHeight(),
755 maxWidth
= GetMaxWidth(),
756 maxHeight
= GetMaxHeight();
759 // GPE's window manager doesn't like size hints
760 // at all, esp. when the user has to use the
768 if ((minWidth
!= -1) && (m_width
< minWidth
)) m_width
= minWidth
;
769 if ((minHeight
!= -1) && (m_height
< minHeight
)) m_height
= minHeight
;
770 if ((maxWidth
!= -1) && (m_width
> maxWidth
)) m_width
= maxWidth
;
771 if ((maxHeight
!= -1) && (m_height
> maxHeight
)) m_height
= maxHeight
;
776 gint flag
= 0; // GDK_HINT_POS;
779 if ((minWidth
!= -1) || (minHeight
!= -1)) flag
|= GDK_HINT_MIN_SIZE
;
780 if ((maxWidth
!= -1) || (maxHeight
!= -1)) flag
|= GDK_HINT_MAX_SIZE
;
782 geom
.min_width
= minWidth
;
783 geom
.min_height
= minHeight
;
785 // Because of the way we set GDK_HINT_MAX_SIZE above, if either of
786 // maxHeight or maxWidth is set, we must set them both, else the
787 // remaining -1 will be taken literally.
789 // I'm certain this also happens elsewhere, and is the probable
790 // cause of other such things as:
791 // Gtk-WARNING **: gtk_widget_size_allocate():
792 // attempt to allocate widget with width 65535 and height 600
793 // but I don't have time to track them all now..
795 // Really we need to encapulate all this height/width business and
796 // stop any old method from ripping at the members directly and
797 // scattering -1's without regard for who might resolve them later.
799 geom
.max_width
= ( maxHeight
== -1 ) ? maxWidth
800 : ( maxWidth
== -1 ) ? wxGetDisplaySize().GetWidth()
803 geom
.max_height
= ( maxWidth
== -1 ) ? maxHeight
// ( == -1 here )
804 : ( maxHeight
== -1 ) ? wxGetDisplaySize().GetHeight()
807 gtk_window_set_geometry_hints( GTK_WINDOW(m_widget
),
810 (GdkWindowHints
) flag
);
812 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
813 * menubar, the toolbar and the client area, which is represented by
815 * this hurts in the eye, but I don't want to call SetSize()
816 * because I don't want to call any non-native functions here. */
818 int client_x
= m_miniEdge
;
819 int client_y
= m_miniEdge
+ m_miniTitle
;
820 int client_w
= m_width
- 2*m_miniEdge
;
821 int client_h
= m_height
- 2*m_miniEdge
- m_miniTitle
;
823 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
825 client_x
, client_y
, client_w
, client_h
);
829 // If there is no m_mainWidget between m_widget and m_wxwindow there
830 // is no need to set the size or position of m_wxwindow.
835 // send size event to frame
836 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
837 event
.SetEventObject( this );
838 GetEventHandler()->ProcessEvent( event
);
843 void wxTopLevelWindowGTK::OnInternalIdle()
845 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
847 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
849 // we'll come back later
851 wxapp_install_idle_handler();
855 // set the focus if not done yet and if we can already do it
856 if ( GTK_WIDGET_REALIZED(m_wxwindow
) )
858 if ( g_delayedFocus
&&
859 wxGetTopLevelParent((wxWindow
*)g_delayedFocus
) == this )
861 wxLogTrace(_T("focus"),
862 _T("Setting focus from wxTLW::OnIdle() to %s(%s)"),
863 g_delayedFocus
->GetClassInfo()->GetClassName(),
864 g_delayedFocus
->GetLabel().c_str());
866 g_delayedFocus
->SetFocus();
867 g_delayedFocus
= NULL
;
871 wxWindow::OnInternalIdle();
874 // ----------------------------------------------------------------------------
876 // ----------------------------------------------------------------------------
878 void wxTopLevelWindowGTK::SetTitle( const wxString
&title
)
880 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
883 gtk_window_set_title( GTK_WINDOW(m_widget
), wxGTK_CONV( title
) );
886 void wxTopLevelWindowGTK::DoSetIcon( const wxIcon
&icon
)
891 if (!m_widget
->window
)
894 wxMask
*mask
= icon
.GetMask();
895 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
896 if (mask
) bm
= mask
->GetBitmap();
898 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);
901 void wxTopLevelWindowGTK::SetIcon( const wxIcon
&icon
)
903 SetIcons( wxIconBundle( icon
) );
906 void wxTopLevelWindowGTK::SetIcons( const wxIconBundle
&icons
)
908 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
909 GdkWindow
* window
= m_widget
->window
;
911 wxTopLevelWindowBase::SetIcons( icons
);
913 DoSetIcon( icons
.GetIcon( -1 ) );
916 wxSetIconsX11( (WXDisplay
*)GDK_WINDOW_XDISPLAY( window
),
917 (WXWindow
)GDK_WINDOW_XWINDOW( window
), icons
);
921 // ----------------------------------------------------------------------------
922 // frame state: maximized/iconized/normal
923 // ----------------------------------------------------------------------------
925 void wxTopLevelWindowGTK::Maximize(bool maximize
)
929 gtk_window_maximize( GTK_WINDOW( m_widget
) );
931 gtk_window_unmaximize( GTK_WINDOW( m_widget
) );
933 wxFAIL_MSG( _T("not implemented") );
937 bool wxTopLevelWindowGTK::IsMaximized() const
939 // wxFAIL_MSG( _T("not implemented") );
941 // This is an approximation
945 void wxTopLevelWindowGTK::Restore()
948 // "Present" seems similar enough to "restore"
949 gtk_window_present( GTK_WINDOW( m_widget
) );
951 wxFAIL_MSG( _T("not implemented") );
955 void wxTopLevelWindowGTK::Iconize( bool iconize
)
959 gtk_window_iconify( GTK_WINDOW( m_widget
) );
961 gtk_window_deiconify( GTK_WINDOW( m_widget
) );
965 GdkWindow
*window
= m_widget
->window
;
967 // you should do it later, for example from OnCreate() handler
968 wxCHECK_RET( window
, _T("frame not created yet - can't iconize") );
970 XIconifyWindow( GDK_WINDOW_XDISPLAY( window
),
971 GDK_WINDOW_XWINDOW( window
),
972 DefaultScreen( GDK_DISPLAY() ) );
977 bool wxTopLevelWindowGTK::IsIconized() const
982 void wxTopLevelWindowGTK::SetIconizeState(bool iconize
)
984 if ( iconize
!= m_isIconized
)
986 m_isIconized
= iconize
;
987 (void)SendIconizeEvent(iconize
);
991 void wxTopLevelWindowGTK::AddGrab()
996 gtk_grab_add( m_widget
);
998 gtk_grab_remove( m_widget
);
1002 void wxTopLevelWindowGTK::RemoveGrab()
1013 static bool do_shape_combine_region(GdkWindow
* window
, const wxRegion
& region
)
1017 if (region
.IsEmpty())
1019 gdk_window_shape_combine_mask(window
, NULL
, 0, 0);
1024 gdk_window_shape_combine_region(window
, region
.GetRegion(), 0, 0);
1026 wxBitmap bmp
= region
.ConvertToBitmap();
1027 bmp
.SetMask(new wxMask(bmp
, *wxBLACK
));
1028 GdkBitmap
* mask
= bmp
.GetMask()->GetBitmap();
1029 gdk_window_shape_combine_mask(window
, mask
, 0, 0);
1038 bool wxTopLevelWindowGTK::SetShape(const wxRegion
& region
)
1040 wxCHECK_MSG( HasFlag(wxFRAME_SHAPED
), FALSE
,
1041 _T("Shaped windows must be created with the wxFRAME_SHAPED style."));
1043 GdkWindow
*window
= NULL
;
1046 window
= GTK_PIZZA(m_wxwindow
)->bin_window
;
1047 do_shape_combine_region(window
, region
);
1049 window
= m_widget
->window
;
1050 return do_shape_combine_region(window
, region
);