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"
38 #include <gdk/gdkkeysyms.h>
41 #include "wx/gtk/win_gtk.h"
43 #include "wx/unix/utilsx11.h"
46 #include <X11/Xatom.h>
48 // ----------------------------------------------------------------------------
50 // ----------------------------------------------------------------------------
52 extern void wxapp_install_idle_handler();
55 // ----------------------------------------------------------------------------
57 // ----------------------------------------------------------------------------
59 extern wxList wxPendingDelete
;
61 extern int g_openDialogs
;
62 extern wxWindowGTK
*g_delayedFocus
;
64 //-----------------------------------------------------------------------------
65 // "focus" from m_window
66 //-----------------------------------------------------------------------------
68 static gint
gtk_frame_focus_callback( GtkWidget
*widget
, GtkDirectionType
WXUNUSED(d
), wxWindow
*WXUNUSED(win
) )
71 wxapp_install_idle_handler();
73 // This disables GTK's tab traversal
74 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus" );
78 //-----------------------------------------------------------------------------
80 //-----------------------------------------------------------------------------
82 static void gtk_frame_size_callback( GtkWidget
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxTopLevelWindowGTK
*win
)
85 wxapp_install_idle_handler();
90 if ((win
->m_width
!= alloc
->width
) || (win
->m_height
!= alloc
->height
))
93 wxPrintf( "OnSize from " );
94 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
95 wxPrintf( win->GetClassInfo()->GetClassName() );
96 wxPrintf( " %d %d %d %d\n", (int)alloc->x,
102 win
->m_width
= alloc
->width
;
103 win
->m_height
= alloc
->height
;
104 win
->m_queuedFullRedraw
= TRUE
;
105 win
->GtkUpdateSize();
109 //-----------------------------------------------------------------------------
111 //-----------------------------------------------------------------------------
113 static gint
gtk_frame_delete_callback( GtkWidget
*WXUNUSED(widget
), GdkEvent
*WXUNUSED(event
), wxTopLevelWindowGTK
*win
)
116 wxapp_install_idle_handler();
118 if (win
->IsEnabled() &&
119 (g_openDialogs
== 0 || (win
->GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
) ||
127 //-----------------------------------------------------------------------------
129 //-----------------------------------------------------------------------------
132 gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*WXUNUSED(event
), wxTopLevelWindowGTK
*win
)
135 wxapp_install_idle_handler();
137 if (!win
->m_hasVMT
|| !win
->IsShown())
142 gdk_window_get_root_origin( win
->m_widget
->window
, &x
, &y
);
146 wxMoveEvent
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() );
147 mevent
.SetEventObject( win
);
148 win
->GetEventHandler()->ProcessEvent( mevent
);
153 //-----------------------------------------------------------------------------
154 // "realize" from m_widget
155 //-----------------------------------------------------------------------------
157 // we cannot MWM hints and icons before the widget has been realized,
158 // so we do this directly after realization
161 gtk_frame_realized_callback( GtkWidget
* WXUNUSED(widget
),
162 wxTopLevelWindowGTK
*win
)
165 wxapp_install_idle_handler();
167 // All this is for Motif Window Manager "hints" and is supposed to be
168 // recognized by other WM as well. Not tested.
169 gdk_window_set_decorations(win
->m_widget
->window
,
170 (GdkWMDecoration
)win
->m_gdkDecor
);
171 gdk_window_set_functions(win
->m_widget
->window
,
172 (GdkWMFunction
)win
->m_gdkFunc
);
174 // GTK's shrinking/growing policy
175 if ((win
->m_gdkFunc
& GDK_FUNC_RESIZE
) == 0)
176 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1);
178 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1);
181 wxIconBundle iconsOld
= win
->GetIcons();
182 if ( iconsOld
.GetIcon(-1).Ok() )
184 win
->SetIcon( wxNullIcon
);
185 win
->SetIcons( iconsOld
);
189 //-----------------------------------------------------------------------------
190 // "map_event" from m_widget
191 //-----------------------------------------------------------------------------
194 gtk_frame_map_callback( GtkWidget
* WXUNUSED(widget
),
195 GdkEvent
* WXUNUSED(event
),
196 wxTopLevelWindow
*win
)
198 win
->SetIconizeState(FALSE
);
201 //-----------------------------------------------------------------------------
202 // "unmap_event" from m_widget
203 //-----------------------------------------------------------------------------
206 gtk_frame_unmap_callback( GtkWidget
* WXUNUSED(widget
),
207 GdkEvent
* WXUNUSED(event
),
208 wxTopLevelWindow
*win
)
210 win
->SetIconizeState(TRUE
);
213 //-----------------------------------------------------------------------------
214 // "expose_event" of m_client
215 //-----------------------------------------------------------------------------
217 static int gtk_window_expose_callback( GtkWidget
*widget
, GdkEventExpose
*gdk_event
, wxWindow
*win
)
219 GtkPizza
*pizza
= GTK_PIZZA(widget
);
221 gtk_paint_flat_box (win
->m_widget
->style
,
222 pizza
->bin_window
, GTK_STATE_NORMAL
,
232 //-----------------------------------------------------------------------------
233 // "draw" of m_client
234 //-----------------------------------------------------------------------------
238 static void gtk_window_draw_callback( GtkWidget
*widget
, GdkRectangle
*rect
, wxWindow
*win
)
240 GtkPizza
*pizza
= GTK_PIZZA(widget
);
242 gtk_paint_flat_box (win
->m_widget
->style
,
243 pizza
->bin_window
, GTK_STATE_NORMAL
,
253 // ----------------------------------------------------------------------------
254 // wxTopLevelWindowGTK itself
255 // ----------------------------------------------------------------------------
257 //-----------------------------------------------------------------------------
258 // InsertChild for wxTopLevelWindowGTK
259 //-----------------------------------------------------------------------------
261 /* Callback for wxTopLevelWindowGTK. This very strange beast has to be used because
262 * C++ has no virtual methods in a constructor. We have to emulate a
263 * virtual function here as wxWindows requires different ways to insert
264 * a child in container classes. */
266 static void wxInsertChildInTopLevelWindow( wxTopLevelWindowGTK
* parent
, wxWindow
* child
)
268 wxASSERT( GTK_IS_WIDGET(child
->m_widget
) );
270 if (!parent
->m_insertInClientArea
)
272 // these are outside the client area
273 wxTopLevelWindowGTK
* frame
= (wxTopLevelWindowGTK
*) parent
;
274 gtk_pizza_put( GTK_PIZZA(frame
->m_mainWidget
),
275 GTK_WIDGET(child
->m_widget
),
283 // these are inside the client area
284 gtk_pizza_put( GTK_PIZZA(parent
->m_wxwindow
),
285 GTK_WIDGET(child
->m_widget
),
292 // resize on OnInternalIdle
293 parent
->GtkUpdateSize();
296 // ----------------------------------------------------------------------------
297 // wxTopLevelWindowGTK creation
298 // ----------------------------------------------------------------------------
300 void wxTopLevelWindowGTK::Init()
305 m_mainWidget
= (GtkWidget
*) NULL
;
306 m_insertInClientArea
= TRUE
;
307 m_isIconized
= FALSE
;
308 m_fsIsShowing
= FALSE
;
309 m_themeEnabled
= TRUE
;
310 m_gdkDecor
= m_gdkFunc
= 0;
314 bool wxTopLevelWindowGTK::Create( wxWindow
*parent
,
316 const wxString
& title
,
318 const wxSize
& sizeOrig
,
320 const wxString
&name
)
322 // always create a frame of some reasonable, even if arbitrary, size (at
323 // least for MSW compatibility)
324 wxSize size
= sizeOrig
;
325 if ( size
.x
== -1 || size
.y
== -1 )
327 wxSize sizeDpy
= wxGetDisplaySize();
329 size
.x
= sizeDpy
.x
/ 3;
331 size
.y
= sizeDpy
.y
/ 5;
334 wxTopLevelWindows
.Append( this );
336 m_needParent
= FALSE
;
338 if (!PreCreation( parent
, pos
, size
) ||
339 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
341 wxFAIL_MSG( wxT("wxTopLevelWindowGTK creation failed") );
347 m_insertCallback
= (wxInsertChildFunction
) wxInsertChildInTopLevelWindow
;
349 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
351 if (style
& wxFRAME_TOOL_WINDOW
)
352 win_type
= GTK_WINDOW_POPUP
;
354 if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
)
356 // there is no more GTK_WINDOW_DIALOG in 2.0
358 win_type
= GTK_WINDOW_TOPLEVEL
;
360 win_type
= GTK_WINDOW_DIALOG
;
364 m_widget
= gtk_window_new( win_type
);
366 if (m_parent
&& (((GTK_IS_WINDOW(m_parent
->m_widget
)) &&
367 (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
)) ||
368 (style
& wxFRAME_FLOAT_ON_PARENT
)))
370 gtk_window_set_transient_for( GTK_WINDOW(m_widget
), GTK_WINDOW(m_parent
->m_widget
) );
374 gtk_window_set_wmclass( GTK_WINDOW(m_widget
), wxGTK_CONV( name
), wxGTK_CONV( name
) );
376 gtk_window_set_title( GTK_WINDOW(m_widget
), wxGTK_CONV( title
) );
377 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
379 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
380 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
382 // m_mainWidget holds the toolbar, the menubar and the client area
383 m_mainWidget
= gtk_pizza_new();
384 gtk_widget_show( m_mainWidget
);
385 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
386 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
388 // for m_mainWidget themes
389 gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "expose_event",
390 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
392 gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "draw",
393 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
396 // m_wxwindow only represents the client area without toolbar and menubar
397 m_wxwindow
= gtk_pizza_new();
398 gtk_widget_show( m_wxwindow
);
399 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
401 // we donm't allow the frame to get the focus as otherwise
402 // the frame will grab it at arbitrary focus changes
403 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
405 if (m_parent
) m_parent
->AddChild( this );
407 // the user resized the frame by dragging etc.
408 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
409 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
413 if ((m_x
!= -1) || (m_y
!= -1))
414 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
416 gtk_window_set_default_size( GTK_WINDOW(m_widget
), m_width
, m_height
);
418 // we cannot set MWM hints and icons before the widget has
419 // been realized, so we do this directly after realization
420 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
421 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
423 // the only way to get the window size is to connect to this event
424 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
425 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
427 // map and unmap for iconized state
428 gtk_signal_connect( GTK_OBJECT(m_widget
), "map_event",
429 GTK_SIGNAL_FUNC(gtk_frame_map_callback
), (gpointer
)this );
430 gtk_signal_connect( GTK_OBJECT(m_widget
), "unmap_event",
431 GTK_SIGNAL_FUNC(gtk_frame_unmap_callback
), (gpointer
)this );
433 // the only way to get the window size is to connect to this event
434 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
435 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
437 // disable native tab traversal
438 gtk_signal_connect( GTK_OBJECT(m_widget
), "focus",
439 GTK_SIGNAL_FUNC(gtk_frame_focus_callback
), (gpointer
)this );
442 if ((m_miniEdge
> 0) || (style
& wxSIMPLE_BORDER
) || (style
& wxNO_BORDER
))
449 m_gdkDecor
= (long) GDK_DECOR_BORDER
;
450 m_gdkFunc
= (long) GDK_FUNC_MOVE
;
452 // All this is for Motif Window Manager "hints" and is supposed to be
453 // recognized by other WMs as well.
454 if ((style
& wxCAPTION
) != 0)
455 m_gdkDecor
|= GDK_DECOR_TITLE
;
456 if ((style
& wxSYSTEM_MENU
) != 0)
458 m_gdkFunc
|= GDK_FUNC_CLOSE
;
459 m_gdkDecor
|= GDK_DECOR_MENU
;
461 if ((style
& wxMINIMIZE_BOX
) != 0)
463 m_gdkFunc
|= GDK_FUNC_MINIMIZE
;
464 m_gdkDecor
|= GDK_DECOR_MINIMIZE
;
466 if ((style
& wxMAXIMIZE_BOX
) != 0)
468 m_gdkFunc
|= GDK_FUNC_MAXIMIZE
;
469 m_gdkDecor
|= GDK_DECOR_MAXIMIZE
;
471 if ((style
& wxRESIZE_BORDER
) != 0)
473 m_gdkFunc
|= GDK_FUNC_RESIZE
;
474 m_gdkDecor
|= GDK_DECOR_RESIZEH
;
481 wxTopLevelWindowGTK::~wxTopLevelWindowGTK()
485 wxASSERT_MSG( FALSE
, _T("Window still grabbed"));
489 m_isBeingDeleted
= TRUE
;
491 // it may also be GtkScrolledWindow in the case of an MDI child
492 if (GTK_IS_WINDOW(m_widget
))
494 gtk_window_set_focus( GTK_WINDOW(m_widget
), NULL
);
499 // X11 ICCCM values for window layers
500 #define WIN_LAYER_NORMAL 4
501 #define WIN_LAYER_ABOVE_DOCK 10
503 // X11 window manager property name
504 #define XA_WIN_LAYER "_WIN_LAYER"
506 // X11 window manager property name atom
507 static Atom gs_XA_WIN_LAYER
= 0;
510 static void wx_win_hints_set_layer(GtkWidget
*window
, int layer
)
514 GdkWindowPrivate
*priv
;
517 prev_error
= gdk_error_warnings
;
518 gdk_error_warnings
= 0;
519 priv
= (GdkWindowPrivate
*)(GTK_WIDGET(window
)->window
);
521 if (GTK_WIDGET_MAPPED(window
))
523 xev
.type
= ClientMessage
;
524 xev
.xclient
.type
= ClientMessage
;
525 xev
.xclient
.window
= priv
->xwindow
;
526 xev
.xclient
.message_type
= gs_XA_WIN_LAYER
;
527 xev
.xclient
.format
= 32;
528 xev
.xclient
.data
.l
[0] = (long)layer
;
529 xev
.xclient
.data
.l
[1] = gdk_time_get();
531 XSendEvent(GDK_DISPLAY(), GDK_ROOT_WINDOW(), False
,
532 SubstructureNotifyMask
, (XEvent
*) &xev
);
539 XChangeProperty(GDK_DISPLAY(), priv
->xwindow
, gs_XA_WIN_LAYER
,
540 XA_CARDINAL
, 32, PropModeReplace
, (unsigned char *)data
, 1);
542 gdk_error_warnings
= prev_error
;
546 bool wxTopLevelWindowGTK::ShowFullScreen(bool show
, long style
)
548 if (show
== m_fsIsShowing
) return FALSE
; // return what?
550 if (gs_XA_WIN_LAYER
== 0)
552 // Initialose X11 Atom only once
553 gs_XA_WIN_LAYER
= XInternAtom( GDK_DISPLAY(), XA_WIN_LAYER
, False
);
556 m_fsIsShowing
= show
;
560 m_fsSaveGdkFunc
= m_gdkFunc
;
561 m_fsSaveGdkDecor
= m_gdkDecor
;
562 m_fsSaveFlag
= style
;
563 GetPosition( &m_fsSaveFrame
.x
, &m_fsSaveFrame
.y
);
564 GetSize( &m_fsSaveFrame
.width
, &m_fsSaveFrame
.height
);
566 int screen_width
,screen_height
;
567 wxDisplaySize( &screen_width
, &screen_height
);
569 gint client_x
, client_y
, root_x
, root_y
;
572 gdk_window_get_origin (m_widget
->window
, &root_x
, &root_y
);
573 gdk_window_get_geometry (m_widget
->window
, &client_x
, &client_y
,
574 &width
, &height
, NULL
);
576 wx_win_hints_set_layer( m_widget
, WIN_LAYER_ABOVE_DOCK
);
578 gdk_window_move_resize (m_widget
->window
, -client_x
, -client_y
,
579 screen_width
+ 1, screen_height
+ 1);
583 wx_win_hints_set_layer( m_widget
, WIN_LAYER_NORMAL
);
585 SetSize( m_fsSaveFrame
.x
, m_fsSaveFrame
.y
, m_fsSaveFrame
.width
, m_fsSaveFrame
.height
);
591 // ----------------------------------------------------------------------------
592 // overridden wxWindow methods
593 // ----------------------------------------------------------------------------
595 bool wxTopLevelWindowGTK::Show( bool show
)
597 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
599 if (show
&& !m_sizeSet
)
601 /* by calling GtkOnSize here, we don't have to call
602 either after showing the frame, which would entail
603 much ugly flicker or from within the size_allocate
604 handler, because GTK 1.1.X forbids that. */
606 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
609 return wxWindow::Show( show
);
612 void wxTopLevelWindowGTK::DoMoveWindow(int WXUNUSED(x
), int WXUNUSED(y
), int WXUNUSED(width
), int WXUNUSED(height
) )
614 wxFAIL_MSG( wxT("DoMoveWindow called for wxTopLevelWindowGTK") );
617 void wxTopLevelWindowGTK::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
619 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
621 // this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow
622 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
632 int old_width
= m_width
;
633 int old_height
= m_height
;
635 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
637 if (x
!= -1) m_x
= x
;
638 if (y
!= -1) m_y
= y
;
645 if (width
!= -1) m_width
= width
;
646 if (height
!= -1) m_height
= height
;
649 if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
651 if (width == -1) m_width = 80;
654 if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
656 if (height == -1) m_height = 26;
660 int minWidth
= GetMinWidth(),
661 minHeight
= GetMinHeight(),
662 maxWidth
= GetMaxWidth(),
663 maxHeight
= GetMaxHeight();
665 if ((minWidth
!= -1) && (m_width
< minWidth
)) m_width
= minWidth
;
666 if ((minHeight
!= -1) && (m_height
< minHeight
)) m_height
= minHeight
;
667 if ((maxWidth
!= -1) && (m_width
> maxWidth
)) m_width
= maxWidth
;
668 if ((maxHeight
!= -1) && (m_height
> maxHeight
)) m_height
= maxHeight
;
670 if ((m_x
!= -1) || (m_y
!= -1))
672 if ((m_x
!= old_x
) || (m_y
!= old_y
))
674 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
678 if ((m_width
!= old_width
) || (m_height
!= old_height
))
680 if (m_widget
->window
)
681 gdk_window_resize( m_widget
->window
, m_width
, m_height
);
683 gtk_window_set_default_size( GTK_WINDOW(m_widget
), m_width
, m_height
);
685 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
686 done either directly before the frame is shown or in idle time
687 so that different calls to SetSize() don't lead to flicker. */
694 void wxTopLevelWindowGTK::DoGetClientSize( int *width
, int *height
) const
696 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
698 wxWindow::DoGetClientSize( width
, height
);
702 *height
-= m_miniEdge
*2 + m_miniTitle
;
706 *width
-= m_miniEdge
*2;
710 void wxTopLevelWindowGTK::DoSetClientSize( int width
, int height
)
712 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
715 width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
, 0);
718 void wxTopLevelWindowGTK::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
),
719 int width
, int height
)
721 // due to a bug in gtk, x,y are always 0
726 if (m_resizing
) return;
729 if ( m_wxwindow
== NULL
) return;
734 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
735 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
736 set in wxFrame::Create so it is used to check what kind of frame we
737 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
738 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
739 importantly) m_mainWidget */
741 int minWidth
= GetMinWidth(),
742 minHeight
= GetMinHeight(),
743 maxWidth
= GetMaxWidth(),
744 maxHeight
= GetMaxHeight();
746 if ((minWidth
!= -1) && (m_width
< minWidth
)) m_width
= minWidth
;
747 if ((minHeight
!= -1) && (m_height
< minHeight
)) m_height
= minHeight
;
748 if ((maxWidth
!= -1) && (m_width
> maxWidth
)) m_width
= maxWidth
;
749 if ((maxHeight
!= -1) && (m_height
> maxHeight
)) m_height
= maxHeight
;
754 gint flag
= 0; // GDK_HINT_POS;
757 if ((minWidth
!= -1) || (minHeight
!= -1)) flag
|= GDK_HINT_MIN_SIZE
;
758 if ((maxWidth
!= -1) || (maxHeight
!= -1)) flag
|= GDK_HINT_MAX_SIZE
;
760 geom
.min_width
= minWidth
;
761 geom
.min_height
= minHeight
;
763 // Because of the way we set GDK_HINT_MAX_SIZE above, if either of
764 // maxHeight or maxWidth is set, we must set them both, else the
765 // remaining -1 will be taken literally.
767 // I'm certain this also happens elsewhere, and is the probable
768 // cause of other such things as:
769 // Gtk-WARNING **: gtk_widget_size_allocate():
770 // attempt to allocate widget with width 65535 and height 600
771 // but I don't have time to track them all now..
773 // Really we need to encapulate all this height/width business and
774 // stop any old method from ripping at the members directly and
775 // scattering -1's without regard for who might resolve them later.
777 geom
.max_width
= ( maxHeight
== -1 ) ? maxWidth
778 : ( maxWidth
== -1 ) ? wxGetDisplaySize().GetWidth()
781 geom
.max_height
= ( maxWidth
== -1 ) ? maxHeight
// ( == -1 here )
782 : ( maxHeight
== -1 ) ? wxGetDisplaySize().GetHeight()
785 gtk_window_set_geometry_hints( GTK_WINDOW(m_widget
),
788 (GdkWindowHints
) flag
);
790 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
791 * menubar, the toolbar and the client area, which is represented by
793 * this hurts in the eye, but I don't want to call SetSize()
794 * because I don't want to call any non-native functions here. */
796 int client_x
= m_miniEdge
;
797 int client_y
= m_miniEdge
+ m_miniTitle
;
798 int client_w
= m_width
- 2*m_miniEdge
;
799 int client_h
= m_height
- 2*m_miniEdge
- m_miniTitle
;
801 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
803 client_x
, client_y
, client_w
, client_h
);
807 // If there is no m_mainWidget between m_widget and m_wxwindow there
808 // is no need to set the size or position of m_wxwindow.
813 // send size event to frame
814 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
815 event
.SetEventObject( this );
816 GetEventHandler()->ProcessEvent( event
);
821 void wxTopLevelWindowGTK::OnInternalIdle()
823 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
825 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
827 // we'll come back later
829 wxapp_install_idle_handler();
833 // set the focus if not done yet and if we can already do it
834 if ( GTK_WIDGET_REALIZED(m_wxwindow
) )
836 if ( g_delayedFocus
&&
837 wxGetTopLevelParent((wxWindow
*)g_delayedFocus
) == this )
839 wxLogTrace(_T("focus"),
840 _T("Setting focus from wxTLW::OnIdle() to %s(%s)"),
841 g_delayedFocus
->GetClassInfo()->GetClassName(),
842 g_delayedFocus
->GetLabel().c_str());
844 g_delayedFocus
->SetFocus();
845 g_delayedFocus
= NULL
;
849 wxWindow::OnInternalIdle();
852 // ----------------------------------------------------------------------------
854 // ----------------------------------------------------------------------------
856 void wxTopLevelWindowGTK::SetTitle( const wxString
&title
)
858 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
861 gtk_window_set_title( GTK_WINDOW(m_widget
), wxGTK_CONV( title
) );
864 void wxTopLevelWindowGTK::DoSetIcon( const wxIcon
&icon
)
869 if (!m_widget
->window
)
872 wxMask
*mask
= icon
.GetMask();
873 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
874 if (mask
) bm
= mask
->GetBitmap();
876 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);
879 void wxTopLevelWindowGTK::SetIcon( const wxIcon
&icon
)
881 SetIcons( wxIconBundle( icon
) );
884 void wxTopLevelWindowGTK::SetIcons( const wxIconBundle
&icons
)
886 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
887 GdkWindow
* window
= m_widget
->window
;
889 wxTopLevelWindowBase::SetIcons( icons
);
891 DoSetIcon( icons
.GetIcon( -1 ) );
894 wxSetIconsX11( (WXDisplay
*)GDK_WINDOW_XDISPLAY( window
),
895 (WXWindow
)GDK_WINDOW_XWINDOW( window
), icons
);
899 // ----------------------------------------------------------------------------
900 // frame state: maximized/iconized/normal
901 // ----------------------------------------------------------------------------
903 void wxTopLevelWindowGTK::Maximize(bool maximize
)
907 gtk_window_maximize( GTK_WINDOW( m_widget
) );
909 gtk_window_unmaximize( GTK_WINDOW( m_widget
) );
911 wxFAIL_MSG( _T("not implemented") );
915 bool wxTopLevelWindowGTK::IsMaximized() const
917 // wxFAIL_MSG( _T("not implemented") );
919 // This is an approximation
923 void wxTopLevelWindowGTK::Restore()
926 // "Present" seems similar enough to "restore"
927 gtk_window_present( GTK_WINDOW( m_widget
) );
929 wxFAIL_MSG( _T("not implemented") );
933 void wxTopLevelWindowGTK::Iconize( bool iconize
)
937 gtk_window_iconify( GTK_WINDOW( m_widget
) );
939 gtk_window_deiconify( GTK_WINDOW( m_widget
) );
943 GdkWindow
*window
= m_widget
->window
;
945 // you should do it later, for example from OnCreate() handler
946 wxCHECK_RET( window
, _T("frame not created yet - can't iconize") );
948 XIconifyWindow( GDK_WINDOW_XDISPLAY( window
),
949 GDK_WINDOW_XWINDOW( window
),
950 DefaultScreen( GDK_DISPLAY() ) );
955 bool wxTopLevelWindowGTK::IsIconized() const
960 void wxTopLevelWindowGTK::SetIconizeState(bool iconize
)
962 if ( iconize
!= m_isIconized
)
964 m_isIconized
= iconize
;
965 (void)SendIconizeEvent(iconize
);
969 void wxTopLevelWindowGTK::AddGrab()
974 gtk_grab_add( m_widget
);
976 gtk_grab_remove( m_widget
);
980 void wxTopLevelWindowGTK::RemoveGrab()