1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
10 // ============================================================================
12 // ============================================================================
14 // ----------------------------------------------------------------------------
16 // ----------------------------------------------------------------------------
19 #pragma implementation "toplevel.h"
23 #define XIconifyWindow XICONIFYWINDOW
29 #include "wx/dialog.h"
30 #include "wx/control.h"
32 #include "wx/dcclient.h"
33 #include "wx/gtk/private.h"
39 #include <gdk/gdkkeysyms.h>
42 #include "wx/gtk/win_gtk.h"
44 #include "wx/unix/utilsx11.h"
47 #include <X11/Xatom.h>
49 // ----------------------------------------------------------------------------
51 // ----------------------------------------------------------------------------
53 extern void wxapp_install_idle_handler();
56 // ----------------------------------------------------------------------------
58 // ----------------------------------------------------------------------------
60 extern wxList wxPendingDelete
;
62 extern int g_openDialogs
;
63 extern wxWindowGTK
*g_delayedFocus
;
65 //-----------------------------------------------------------------------------
66 // "focus" from m_window
67 //-----------------------------------------------------------------------------
69 static gint
gtk_frame_focus_callback( GtkWidget
*widget
, GtkDirectionType
WXUNUSED(d
), wxWindow
*WXUNUSED(win
) )
72 wxapp_install_idle_handler();
74 // This disables GTK's tab traversal
75 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus" );
79 //-----------------------------------------------------------------------------
81 //-----------------------------------------------------------------------------
83 static void gtk_frame_size_callback( GtkWidget
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxTopLevelWindowGTK
*win
)
86 wxapp_install_idle_handler();
91 if ((win
->m_width
!= alloc
->width
) || (win
->m_height
!= alloc
->height
))
94 wxPrintf( "OnSize from " );
95 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
96 wxPrintf( win->GetClassInfo()->GetClassName() );
97 wxPrintf( " %d %d %d %d\n", (int)alloc->x,
100 (int)alloc->height );
103 win
->m_width
= alloc
->width
;
104 win
->m_height
= alloc
->height
;
105 win
->m_queuedFullRedraw
= TRUE
;
106 win
->GtkUpdateSize();
110 //-----------------------------------------------------------------------------
112 //-----------------------------------------------------------------------------
114 static gint
gtk_frame_delete_callback( GtkWidget
*WXUNUSED(widget
), GdkEvent
*WXUNUSED(event
), wxTopLevelWindowGTK
*win
)
117 wxapp_install_idle_handler();
119 if (win
->IsEnabled() &&
120 (g_openDialogs
== 0 || (win
->GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
) ||
128 //-----------------------------------------------------------------------------
130 //-----------------------------------------------------------------------------
133 gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*WXUNUSED(event
), wxTopLevelWindowGTK
*win
)
136 wxapp_install_idle_handler();
138 if (!win
->m_hasVMT
|| !win
->IsShown())
143 gdk_window_get_root_origin( win
->m_widget
->window
, &x
, &y
);
147 wxMoveEvent
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() );
148 mevent
.SetEventObject( win
);
149 win
->GetEventHandler()->ProcessEvent( mevent
);
154 //-----------------------------------------------------------------------------
155 // "realize" from m_widget
156 //-----------------------------------------------------------------------------
158 // we cannot MWM hints and icons before the widget has been realized,
159 // so we do this directly after realization
162 gtk_frame_realized_callback( GtkWidget
* WXUNUSED(widget
),
163 wxTopLevelWindowGTK
*win
)
166 wxapp_install_idle_handler();
168 // All this is for Motif Window Manager "hints" and is supposed to be
169 // recognized by other WM as well. Not tested.
170 gdk_window_set_decorations(win
->m_widget
->window
,
171 (GdkWMDecoration
)win
->m_gdkDecor
);
172 gdk_window_set_functions(win
->m_widget
->window
,
173 (GdkWMFunction
)win
->m_gdkFunc
);
175 // GTK's shrinking/growing policy
176 if ((win
->m_gdkFunc
& GDK_FUNC_RESIZE
) == 0)
177 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1);
179 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1);
182 wxIconBundle iconsOld
= win
->GetIcons();
183 if ( iconsOld
.GetIcon(-1).Ok() )
185 win
->SetIcon( wxNullIcon
);
186 win
->SetIcons( iconsOld
);
190 //-----------------------------------------------------------------------------
191 // "map_event" from m_widget
192 //-----------------------------------------------------------------------------
195 gtk_frame_map_callback( GtkWidget
* WXUNUSED(widget
),
196 GdkEvent
* WXUNUSED(event
),
197 wxTopLevelWindow
*win
)
199 win
->SetIconizeState(FALSE
);
202 //-----------------------------------------------------------------------------
203 // "unmap_event" from m_widget
204 //-----------------------------------------------------------------------------
207 gtk_frame_unmap_callback( GtkWidget
* WXUNUSED(widget
),
208 GdkEvent
* WXUNUSED(event
),
209 wxTopLevelWindow
*win
)
211 win
->SetIconizeState(TRUE
);
214 //-----------------------------------------------------------------------------
215 // "expose_event" of m_client
216 //-----------------------------------------------------------------------------
218 static int gtk_window_expose_callback( GtkWidget
*widget
, GdkEventExpose
*gdk_event
, wxWindow
*win
)
220 GtkPizza
*pizza
= GTK_PIZZA(widget
);
222 gtk_paint_flat_box (win
->m_widget
->style
,
223 pizza
->bin_window
, GTK_STATE_NORMAL
,
233 //-----------------------------------------------------------------------------
234 // "draw" of m_client
235 //-----------------------------------------------------------------------------
239 static void gtk_window_draw_callback( GtkWidget
*widget
, GdkRectangle
*rect
, wxWindow
*win
)
241 GtkPizza
*pizza
= GTK_PIZZA(widget
);
243 gtk_paint_flat_box (win
->m_widget
->style
,
244 pizza
->bin_window
, GTK_STATE_NORMAL
,
254 // ----------------------------------------------------------------------------
255 // wxTopLevelWindowGTK itself
256 // ----------------------------------------------------------------------------
258 //-----------------------------------------------------------------------------
259 // InsertChild for wxTopLevelWindowGTK
260 //-----------------------------------------------------------------------------
262 /* Callback for wxTopLevelWindowGTK. This very strange beast has to be used because
263 * C++ has no virtual methods in a constructor. We have to emulate a
264 * virtual function here as wxWindows requires different ways to insert
265 * a child in container classes. */
267 static void wxInsertChildInTopLevelWindow( wxTopLevelWindowGTK
* parent
, wxWindow
* child
)
269 wxASSERT( GTK_IS_WIDGET(child
->m_widget
) );
271 if (!parent
->m_insertInClientArea
)
273 // these are outside the client area
274 wxTopLevelWindowGTK
* frame
= (wxTopLevelWindowGTK
*) parent
;
275 gtk_pizza_put( GTK_PIZZA(frame
->m_mainWidget
),
276 GTK_WIDGET(child
->m_widget
),
284 // these are inside the client area
285 gtk_pizza_put( GTK_PIZZA(parent
->m_wxwindow
),
286 GTK_WIDGET(child
->m_widget
),
293 // resize on OnInternalIdle
294 parent
->GtkUpdateSize();
297 // ----------------------------------------------------------------------------
298 // wxTopLevelWindowGTK creation
299 // ----------------------------------------------------------------------------
301 void wxTopLevelWindowGTK::Init()
306 m_mainWidget
= (GtkWidget
*) NULL
;
307 m_insertInClientArea
= TRUE
;
308 m_isIconized
= FALSE
;
309 m_fsIsShowing
= FALSE
;
310 m_themeEnabled
= TRUE
;
311 m_gdkDecor
= m_gdkFunc
= 0;
315 bool wxTopLevelWindowGTK::Create( wxWindow
*parent
,
317 const wxString
& title
,
319 const wxSize
& sizeOrig
,
321 const wxString
&name
)
323 // always create a frame of some reasonable, even if arbitrary, size (at
324 // least for MSW compatibility)
325 wxSize size
= sizeOrig
;
326 if ( size
.x
== -1 || size
.y
== -1 )
328 wxSize sizeDpy
= wxGetDisplaySize();
330 size
.x
= sizeDpy
.x
/ 3;
332 size
.y
= sizeDpy
.y
/ 5;
335 wxTopLevelWindows
.Append( this );
337 m_needParent
= FALSE
;
339 if (!PreCreation( parent
, pos
, size
) ||
340 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
342 wxFAIL_MSG( wxT("wxTopLevelWindowGTK creation failed") );
348 m_insertCallback
= (wxInsertChildFunction
) wxInsertChildInTopLevelWindow
;
350 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
352 if (style
& wxFRAME_TOOL_WINDOW
)
353 win_type
= GTK_WINDOW_POPUP
;
355 if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
)
357 // there is no more GTK_WINDOW_DIALOG in 2.0
359 win_type
= GTK_WINDOW_TOPLEVEL
;
361 win_type
= GTK_WINDOW_DIALOG
;
365 m_widget
= gtk_window_new( win_type
);
367 if (m_parent
&& (((GTK_IS_WINDOW(m_parent
->m_widget
)) &&
368 (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
)) ||
369 (style
& wxFRAME_FLOAT_ON_PARENT
)))
371 gtk_window_set_transient_for( GTK_WINDOW(m_widget
), GTK_WINDOW(m_parent
->m_widget
) );
375 gtk_window_set_wmclass( GTK_WINDOW(m_widget
), wxGTK_CONV( name
), wxGTK_CONV( name
) );
377 gtk_window_set_title( GTK_WINDOW(m_widget
), wxGTK_CONV( title
) );
378 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
380 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
381 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
383 // m_mainWidget holds the toolbar, the menubar and the client area
384 m_mainWidget
= gtk_pizza_new();
385 gtk_widget_show( m_mainWidget
);
386 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
387 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
389 // for m_mainWidget themes
390 gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "expose_event",
391 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
393 gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "draw",
394 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
397 // m_wxwindow only represents the client area without toolbar and menubar
398 m_wxwindow
= gtk_pizza_new();
399 gtk_widget_show( m_wxwindow
);
400 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
402 // we donm't allow the frame to get the focus as otherwise
403 // the frame will grab it at arbitrary focus changes
404 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
406 if (m_parent
) m_parent
->AddChild( this );
408 // the user resized the frame by dragging etc.
409 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
410 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
414 if ((m_x
!= -1) || (m_y
!= -1))
415 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
417 gtk_window_set_default_size( GTK_WINDOW(m_widget
), m_width
, m_height
);
419 // we cannot set MWM hints and icons before the widget has
420 // been realized, so we do this directly after realization
421 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
422 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
424 // the only way to get the window size is to connect to this event
425 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
426 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
428 // map and unmap for iconized state
429 gtk_signal_connect( GTK_OBJECT(m_widget
), "map_event",
430 GTK_SIGNAL_FUNC(gtk_frame_map_callback
), (gpointer
)this );
431 gtk_signal_connect( GTK_OBJECT(m_widget
), "unmap_event",
432 GTK_SIGNAL_FUNC(gtk_frame_unmap_callback
), (gpointer
)this );
434 // the only way to get the window size is to connect to this event
435 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
436 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
438 // disable native tab traversal
439 gtk_signal_connect( GTK_OBJECT(m_widget
), "focus",
440 GTK_SIGNAL_FUNC(gtk_frame_focus_callback
), (gpointer
)this );
443 if ((m_miniEdge
> 0) || (style
& wxSIMPLE_BORDER
) || (style
& wxNO_BORDER
))
450 m_gdkDecor
= (long) GDK_DECOR_BORDER
;
451 m_gdkFunc
= (long) GDK_FUNC_MOVE
;
453 // All this is for Motif Window Manager "hints" and is supposed to be
454 // recognized by other WMs as well.
455 if ((style
& wxCAPTION
) != 0)
456 m_gdkDecor
|= GDK_DECOR_TITLE
;
457 if ((style
& wxSYSTEM_MENU
) != 0)
459 m_gdkFunc
|= GDK_FUNC_CLOSE
;
460 m_gdkDecor
|= GDK_DECOR_MENU
;
462 if ((style
& wxMINIMIZE_BOX
) != 0)
464 m_gdkFunc
|= GDK_FUNC_MINIMIZE
;
465 m_gdkDecor
|= GDK_DECOR_MINIMIZE
;
467 if ((style
& wxMAXIMIZE_BOX
) != 0)
469 m_gdkFunc
|= GDK_FUNC_MAXIMIZE
;
470 m_gdkDecor
|= GDK_DECOR_MAXIMIZE
;
472 if ((style
& wxRESIZE_BORDER
) != 0)
474 m_gdkFunc
|= GDK_FUNC_RESIZE
;
475 m_gdkDecor
|= GDK_DECOR_RESIZEH
;
482 wxTopLevelWindowGTK::~wxTopLevelWindowGTK()
486 wxASSERT_MSG( FALSE
, _T("Window still grabbed"));
490 m_isBeingDeleted
= TRUE
;
492 // it may also be GtkScrolledWindow in the case of an MDI child
493 if (GTK_IS_WINDOW(m_widget
))
495 gtk_window_set_focus( GTK_WINDOW(m_widget
), NULL
);
501 bool wxTopLevelWindowGTK::ShowFullScreen(bool show
, long style
)
503 if (show
== m_fsIsShowing
) return FALSE
; // return what?
505 m_fsIsShowing
= show
;
507 GdkWindow
*window
= m_widget
->window
;
508 wxX11FullScreenMethod method
=
509 wxGetFullScreenMethodX11((WXDisplay
*)GDK_DISPLAY(),
510 (WXWindow
)GDK_ROOT_WINDOW());
514 m_fsSaveFlag
= style
;
515 GetPosition( &m_fsSaveFrame
.x
, &m_fsSaveFrame
.y
);
516 GetSize( &m_fsSaveFrame
.width
, &m_fsSaveFrame
.height
);
518 int screen_width
,screen_height
;
519 wxDisplaySize( &screen_width
, &screen_height
);
521 gint client_x
, client_y
, root_x
, root_y
;
524 if (method
== wxX11_FS_GENERIC
)
526 // don't do it always, Metacity hates it
527 m_fsSaveGdkFunc
= m_gdkFunc
;
528 m_fsSaveGdkDecor
= m_gdkDecor
;
529 m_gdkFunc
= m_gdkDecor
= 0;
530 gdk_window_set_decorations(window
, (GdkWMDecoration
)0);
531 gdk_window_set_functions(window
, (GdkWMFunction
)0);
534 gdk_window_get_origin (m_widget
->window
, &root_x
, &root_y
);
535 gdk_window_get_geometry (m_widget
->window
, &client_x
, &client_y
,
536 &width
, &height
, NULL
);
538 gdk_window_move_resize (m_widget
->window
, -client_x
, -client_y
,
539 screen_width
+ 1, screen_height
+ 1);
541 wxSetFullScreenStateX11((WXDisplay
*)GDK_DISPLAY(),
542 (WXWindow
)GDK_ROOT_WINDOW(),
543 (WXWindow
)GDK_WINDOW_XWINDOW(window
),
544 show
, &m_fsSaveFrame
, method
);
548 if (method
== wxX11_FS_GENERIC
)
550 // don't do it always, Metacity hates it
551 m_gdkFunc
= m_fsSaveGdkFunc
;
552 m_gdkDecor
= m_fsSaveGdkDecor
;
553 gdk_window_set_decorations(window
, (GdkWMDecoration
)m_gdkDecor
);
554 gdk_window_set_functions(window
, (GdkWMFunction
)m_gdkFunc
);
557 wxSetFullScreenStateX11((WXDisplay
*)GDK_DISPLAY(),
558 (WXWindow
)GDK_ROOT_WINDOW(),
559 (WXWindow
)GDK_WINDOW_XWINDOW(window
),
560 show
, &m_fsSaveFrame
, method
);
562 SetSize(m_fsSaveFrame
.x
, m_fsSaveFrame
.y
,
563 m_fsSaveFrame
.width
, m_fsSaveFrame
.height
);
570 // ----------------------------------------------------------------------------
571 // overridden wxWindow methods
572 // ----------------------------------------------------------------------------
574 bool wxTopLevelWindowGTK::Show( bool show
)
576 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
578 if (show
&& !m_sizeSet
)
580 /* by calling GtkOnSize here, we don't have to call
581 either after showing the frame, which would entail
582 much ugly flicker or from within the size_allocate
583 handler, because GTK 1.1.X forbids that. */
585 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
588 return wxWindow::Show( show
);
591 void wxTopLevelWindowGTK::DoMoveWindow(int WXUNUSED(x
), int WXUNUSED(y
), int WXUNUSED(width
), int WXUNUSED(height
) )
593 wxFAIL_MSG( wxT("DoMoveWindow called for wxTopLevelWindowGTK") );
596 void wxTopLevelWindowGTK::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
598 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
600 // this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow
601 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
611 int old_width
= m_width
;
612 int old_height
= m_height
;
614 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
616 if (x
!= -1) m_x
= x
;
617 if (y
!= -1) m_y
= y
;
624 if (width
!= -1) m_width
= width
;
625 if (height
!= -1) m_height
= height
;
628 if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
630 if (width == -1) m_width = 80;
633 if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
635 if (height == -1) m_height = 26;
639 int minWidth
= GetMinWidth(),
640 minHeight
= GetMinHeight(),
641 maxWidth
= GetMaxWidth(),
642 maxHeight
= GetMaxHeight();
644 if ((minWidth
!= -1) && (m_width
< minWidth
)) m_width
= minWidth
;
645 if ((minHeight
!= -1) && (m_height
< minHeight
)) m_height
= minHeight
;
646 if ((maxWidth
!= -1) && (m_width
> maxWidth
)) m_width
= maxWidth
;
647 if ((maxHeight
!= -1) && (m_height
> maxHeight
)) m_height
= maxHeight
;
649 if ((m_x
!= -1) || (m_y
!= -1))
651 if ((m_x
!= old_x
) || (m_y
!= old_y
))
653 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
657 if ((m_width
!= old_width
) || (m_height
!= old_height
))
659 if (m_widget
->window
)
660 gdk_window_resize( m_widget
->window
, m_width
, m_height
);
662 gtk_window_set_default_size( GTK_WINDOW(m_widget
), m_width
, m_height
);
664 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
665 done either directly before the frame is shown or in idle time
666 so that different calls to SetSize() don't lead to flicker. */
673 void wxTopLevelWindowGTK::DoGetClientSize( int *width
, int *height
) const
675 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
677 wxWindow::DoGetClientSize( width
, height
);
681 *height
-= m_miniEdge
*2 + m_miniTitle
;
685 *width
-= m_miniEdge
*2;
689 void wxTopLevelWindowGTK::DoSetClientSize( int width
, int height
)
691 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
694 width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
, 0);
697 void wxTopLevelWindowGTK::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
),
698 int width
, int height
)
700 // due to a bug in gtk, x,y are always 0
705 if (m_resizing
) return;
708 if ( m_wxwindow
== NULL
) return;
713 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
714 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
715 set in wxFrame::Create so it is used to check what kind of frame we
716 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
717 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
718 importantly) m_mainWidget */
720 int minWidth
= GetMinWidth(),
721 minHeight
= GetMinHeight(),
722 maxWidth
= GetMaxWidth(),
723 maxHeight
= GetMaxHeight();
725 if ((minWidth
!= -1) && (m_width
< minWidth
)) m_width
= minWidth
;
726 if ((minHeight
!= -1) && (m_height
< minHeight
)) m_height
= minHeight
;
727 if ((maxWidth
!= -1) && (m_width
> maxWidth
)) m_width
= maxWidth
;
728 if ((maxHeight
!= -1) && (m_height
> maxHeight
)) m_height
= maxHeight
;
733 gint flag
= 0; // GDK_HINT_POS;
736 if ((minWidth
!= -1) || (minHeight
!= -1)) flag
|= GDK_HINT_MIN_SIZE
;
737 if ((maxWidth
!= -1) || (maxHeight
!= -1)) flag
|= GDK_HINT_MAX_SIZE
;
739 geom
.min_width
= minWidth
;
740 geom
.min_height
= minHeight
;
742 // Because of the way we set GDK_HINT_MAX_SIZE above, if either of
743 // maxHeight or maxWidth is set, we must set them both, else the
744 // remaining -1 will be taken literally.
746 // I'm certain this also happens elsewhere, and is the probable
747 // cause of other such things as:
748 // Gtk-WARNING **: gtk_widget_size_allocate():
749 // attempt to allocate widget with width 65535 and height 600
750 // but I don't have time to track them all now..
752 // Really we need to encapulate all this height/width business and
753 // stop any old method from ripping at the members directly and
754 // scattering -1's without regard for who might resolve them later.
756 geom
.max_width
= ( maxHeight
== -1 ) ? maxWidth
757 : ( maxWidth
== -1 ) ? wxGetDisplaySize().GetWidth()
760 geom
.max_height
= ( maxWidth
== -1 ) ? maxHeight
// ( == -1 here )
761 : ( maxHeight
== -1 ) ? wxGetDisplaySize().GetHeight()
764 gtk_window_set_geometry_hints( GTK_WINDOW(m_widget
),
767 (GdkWindowHints
) flag
);
769 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
770 * menubar, the toolbar and the client area, which is represented by
772 * this hurts in the eye, but I don't want to call SetSize()
773 * because I don't want to call any non-native functions here. */
775 int client_x
= m_miniEdge
;
776 int client_y
= m_miniEdge
+ m_miniTitle
;
777 int client_w
= m_width
- 2*m_miniEdge
;
778 int client_h
= m_height
- 2*m_miniEdge
- m_miniTitle
;
780 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
782 client_x
, client_y
, client_w
, client_h
);
786 // If there is no m_mainWidget between m_widget and m_wxwindow there
787 // is no need to set the size or position of m_wxwindow.
792 // send size event to frame
793 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
794 event
.SetEventObject( this );
795 GetEventHandler()->ProcessEvent( event
);
800 void wxTopLevelWindowGTK::OnInternalIdle()
802 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
804 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
806 // we'll come back later
808 wxapp_install_idle_handler();
812 // set the focus if not done yet and if we can already do it
813 if ( GTK_WIDGET_REALIZED(m_wxwindow
) )
815 if ( g_delayedFocus
&&
816 wxGetTopLevelParent((wxWindow
*)g_delayedFocus
) == this )
818 wxLogTrace(_T("focus"),
819 _T("Setting focus from wxTLW::OnIdle() to %s(%s)"),
820 g_delayedFocus
->GetClassInfo()->GetClassName(),
821 g_delayedFocus
->GetLabel().c_str());
823 g_delayedFocus
->SetFocus();
824 g_delayedFocus
= NULL
;
828 wxWindow::OnInternalIdle();
831 // ----------------------------------------------------------------------------
833 // ----------------------------------------------------------------------------
835 void wxTopLevelWindowGTK::SetTitle( const wxString
&title
)
837 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
840 gtk_window_set_title( GTK_WINDOW(m_widget
), wxGTK_CONV( title
) );
843 void wxTopLevelWindowGTK::DoSetIcon( const wxIcon
&icon
)
848 if (!m_widget
->window
)
851 wxMask
*mask
= icon
.GetMask();
852 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
853 if (mask
) bm
= mask
->GetBitmap();
855 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);
858 void wxTopLevelWindowGTK::SetIcon( const wxIcon
&icon
)
860 SetIcons( wxIconBundle( icon
) );
863 void wxTopLevelWindowGTK::SetIcons( const wxIconBundle
&icons
)
865 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
866 GdkWindow
* window
= m_widget
->window
;
868 wxTopLevelWindowBase::SetIcons( icons
);
870 DoSetIcon( icons
.GetIcon( -1 ) );
873 wxSetIconsX11( (WXDisplay
*)GDK_WINDOW_XDISPLAY( window
),
874 (WXWindow
)GDK_WINDOW_XWINDOW( window
), icons
);
878 // ----------------------------------------------------------------------------
879 // frame state: maximized/iconized/normal
880 // ----------------------------------------------------------------------------
882 void wxTopLevelWindowGTK::Maximize(bool maximize
)
886 gtk_window_maximize( GTK_WINDOW( m_widget
) );
888 gtk_window_unmaximize( GTK_WINDOW( m_widget
) );
890 wxFAIL_MSG( _T("not implemented") );
894 bool wxTopLevelWindowGTK::IsMaximized() const
896 // wxFAIL_MSG( _T("not implemented") );
898 // This is an approximation
902 void wxTopLevelWindowGTK::Restore()
905 // "Present" seems similar enough to "restore"
906 gtk_window_present( GTK_WINDOW( m_widget
) );
908 wxFAIL_MSG( _T("not implemented") );
912 void wxTopLevelWindowGTK::Iconize( bool iconize
)
916 gtk_window_iconify( GTK_WINDOW( m_widget
) );
918 gtk_window_deiconify( GTK_WINDOW( m_widget
) );
922 GdkWindow
*window
= m_widget
->window
;
924 // you should do it later, for example from OnCreate() handler
925 wxCHECK_RET( window
, _T("frame not created yet - can't iconize") );
927 XIconifyWindow( GDK_WINDOW_XDISPLAY( window
),
928 GDK_WINDOW_XWINDOW( window
),
929 DefaultScreen( GDK_DISPLAY() ) );
934 bool wxTopLevelWindowGTK::IsIconized() const
939 void wxTopLevelWindowGTK::SetIconizeState(bool iconize
)
941 if ( iconize
!= m_isIconized
)
943 m_isIconized
= iconize
;
944 (void)SendIconizeEvent(iconize
);
948 void wxTopLevelWindowGTK::AddGrab()
953 gtk_grab_add( m_widget
);
955 gtk_grab_remove( m_widget
);
959 void wxTopLevelWindowGTK::RemoveGrab()