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
28 #include "wx/dialog.h"
29 #include "wx/control.h"
31 #include "wx/dcclient.h"
36 #include <gdk/gdkkeysyms.h>
39 #include "wx/gtk/win_gtk.h"
41 #include "wx/unix/utilsx11.h"
44 #include <X11/Xatom.h>
46 // ----------------------------------------------------------------------------
48 // ----------------------------------------------------------------------------
50 extern void wxapp_install_idle_handler();
53 // ----------------------------------------------------------------------------
55 // ----------------------------------------------------------------------------
57 extern wxList wxPendingDelete
;
59 extern int g_openDialogs
;
60 extern wxWindowGTK
*g_delayedFocus
;
62 //-----------------------------------------------------------------------------
63 // "focus" from m_window
64 //-----------------------------------------------------------------------------
66 static gint
gtk_frame_focus_callback( GtkWidget
*widget
, GtkDirectionType
WXUNUSED(d
), wxWindow
*WXUNUSED(win
) )
69 wxapp_install_idle_handler();
71 // This disables GTK's tab traversal
72 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus" );
76 //-----------------------------------------------------------------------------
78 //-----------------------------------------------------------------------------
80 static void gtk_frame_size_callback( GtkWidget
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxTopLevelWindowGTK
*win
)
83 wxapp_install_idle_handler();
88 if ((win
->m_width
!= alloc
->width
) || (win
->m_height
!= alloc
->height
))
91 wxPrintf( "OnSize from " );
92 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
93 wxPrintf( win->GetClassInfo()->GetClassName() );
94 wxPrintf( " %d %d %d %d\n", (int)alloc->x,
100 win
->m_width
= alloc
->width
;
101 win
->m_height
= alloc
->height
;
102 win
->m_queuedFullRedraw
= TRUE
;
103 win
->GtkUpdateSize();
107 //-----------------------------------------------------------------------------
109 //-----------------------------------------------------------------------------
111 static gint
gtk_frame_delete_callback( GtkWidget
*WXUNUSED(widget
), GdkEvent
*WXUNUSED(event
), wxTopLevelWindowGTK
*win
)
114 wxapp_install_idle_handler();
116 if (win
->IsEnabled() &&
117 (g_openDialogs
== 0 || (win
->GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
) ||
125 //-----------------------------------------------------------------------------
127 //-----------------------------------------------------------------------------
130 gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*WXUNUSED(event
), wxTopLevelWindowGTK
*win
)
133 wxapp_install_idle_handler();
135 if (!win
->m_hasVMT
|| !win
->IsShown())
140 gdk_window_get_root_origin( win
->m_widget
->window
, &x
, &y
);
144 wxMoveEvent
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() );
145 mevent
.SetEventObject( win
);
146 win
->GetEventHandler()->ProcessEvent( mevent
);
151 //-----------------------------------------------------------------------------
152 // "realize" from m_widget
153 //-----------------------------------------------------------------------------
155 // we cannot MWM hints and icons before the widget has been realized,
156 // so we do this directly after realization
159 gtk_frame_realized_callback( GtkWidget
* WXUNUSED(widget
),
160 wxTopLevelWindowGTK
*win
)
163 wxapp_install_idle_handler();
165 // All this is for Motif Window Manager "hints" and is supposed to be
166 // recognized by other WM as well. Not tested.
167 gdk_window_set_decorations(win
->m_widget
->window
,
168 (GdkWMDecoration
)win
->m_gdkDecor
);
169 gdk_window_set_functions(win
->m_widget
->window
,
170 (GdkWMFunction
)win
->m_gdkFunc
);
172 // GTK's shrinking/growing policy
173 if ((win
->m_gdkFunc
& GDK_FUNC_RESIZE
) == 0)
174 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1);
176 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1);
179 wxIconBundle iconsOld
= win
->GetIcons();
180 if ( iconsOld
.GetIcon(-1).Ok() )
182 win
->SetIcon( wxNullIcon
);
183 win
->SetIcons( iconsOld
);
187 //-----------------------------------------------------------------------------
188 // "map_event" from m_widget
189 //-----------------------------------------------------------------------------
192 gtk_frame_map_callback( GtkWidget
* WXUNUSED(widget
),
193 GdkEvent
* WXUNUSED(event
),
194 wxTopLevelWindow
*win
)
196 win
->SetIconizeState(FALSE
);
199 //-----------------------------------------------------------------------------
200 // "unmap_event" from m_widget
201 //-----------------------------------------------------------------------------
204 gtk_frame_unmap_callback( GtkWidget
* WXUNUSED(widget
),
205 GdkEvent
* WXUNUSED(event
),
206 wxTopLevelWindow
*win
)
208 win
->SetIconizeState(TRUE
);
211 //-----------------------------------------------------------------------------
212 // "expose_event" of m_client
213 //-----------------------------------------------------------------------------
215 static int gtk_window_expose_callback( GtkWidget
*widget
, GdkEventExpose
*gdk_event
, wxWindow
*win
)
217 GtkPizza
*pizza
= GTK_PIZZA(widget
);
219 gtk_paint_flat_box (win
->m_widget
->style
,
220 pizza
->bin_window
, GTK_STATE_NORMAL
,
230 //-----------------------------------------------------------------------------
231 // "draw" of m_client
232 //-----------------------------------------------------------------------------
236 static void gtk_window_draw_callback( GtkWidget
*widget
, GdkRectangle
*rect
, wxWindow
*win
)
238 GtkPizza
*pizza
= GTK_PIZZA(widget
);
240 gtk_paint_flat_box (win
->m_widget
->style
,
241 pizza
->bin_window
, GTK_STATE_NORMAL
,
251 // ----------------------------------------------------------------------------
252 // wxTopLevelWindowGTK itself
253 // ----------------------------------------------------------------------------
255 //-----------------------------------------------------------------------------
256 // InsertChild for wxTopLevelWindowGTK
257 //-----------------------------------------------------------------------------
259 /* Callback for wxTopLevelWindowGTK. This very strange beast has to be used because
260 * C++ has no virtual methods in a constructor. We have to emulate a
261 * virtual function here as wxWindows requires different ways to insert
262 * a child in container classes. */
264 static void wxInsertChildInTopLevelWindow( wxTopLevelWindowGTK
* parent
, wxWindow
* child
)
266 wxASSERT( GTK_IS_WIDGET(child
->m_widget
) );
268 if (!parent
->m_insertInClientArea
)
270 // these are outside the client area
271 wxTopLevelWindowGTK
* frame
= (wxTopLevelWindowGTK
*) parent
;
272 gtk_pizza_put( GTK_PIZZA(frame
->m_mainWidget
),
273 GTK_WIDGET(child
->m_widget
),
281 // these are inside the client area
282 gtk_pizza_put( GTK_PIZZA(parent
->m_wxwindow
),
283 GTK_WIDGET(child
->m_widget
),
290 // resize on OnInternalIdle
291 parent
->GtkUpdateSize();
294 // ----------------------------------------------------------------------------
295 // wxTopLevelWindowGTK creation
296 // ----------------------------------------------------------------------------
298 void wxTopLevelWindowGTK::Init()
303 m_mainWidget
= (GtkWidget
*) NULL
;
304 m_insertInClientArea
= TRUE
;
305 m_isIconized
= FALSE
;
306 m_fsIsShowing
= FALSE
;
307 m_themeEnabled
= TRUE
;
308 m_gdkDecor
= m_gdkFunc
= 0;
312 bool wxTopLevelWindowGTK::Create( wxWindow
*parent
,
314 const wxString
& title
,
316 const wxSize
& sizeOrig
,
318 const wxString
&name
)
320 // always create a frame of some reasonable, even if arbitrary, size (at
321 // least for MSW compatibility)
322 wxSize size
= sizeOrig
;
323 if ( size
.x
== -1 || size
.y
== -1 )
325 wxSize sizeDpy
= wxGetDisplaySize();
327 size
.x
= sizeDpy
.x
/ 3;
329 size
.y
= sizeDpy
.y
/ 5;
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 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
349 if (style
& wxFRAME_TOOL_WINDOW
)
350 win_type
= GTK_WINDOW_POPUP
;
352 if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
)
354 // there is no more GTK_WINDOW_DIALOG in 2.0
356 win_type
= GTK_WINDOW_TOPLEVEL
;
358 win_type
= GTK_WINDOW_DIALOG
;
362 m_widget
= gtk_window_new( win_type
);
364 if (m_parent
&& (GTK_IS_WINDOW(m_parent
->m_widget
)) &&
365 (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
))
367 gtk_window_set_transient_for( GTK_WINDOW(m_widget
), GTK_WINDOW(m_parent
->m_widget
) );
371 gtk_window_set_wmclass( GTK_WINDOW(m_widget
), name
.mb_str(), name
.mb_str() );
373 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
374 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
376 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
377 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
379 // m_mainWidget holds the toolbar, the menubar and the client area
380 m_mainWidget
= gtk_pizza_new();
381 gtk_widget_show( m_mainWidget
);
382 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
383 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
385 // for m_mainWidget themes
386 gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "expose_event",
387 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
389 gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "draw",
390 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
393 // m_wxwindow only represents the client area without toolbar and menubar
394 m_wxwindow
= gtk_pizza_new();
395 gtk_widget_show( m_wxwindow
);
396 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
398 // we donm't allow the frame to get the focus as otherwise
399 // the frame will grab it at arbitrary focus changes
400 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
402 if (m_parent
) m_parent
->AddChild( this );
404 // the user resized the frame by dragging etc.
405 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
406 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
410 if ((m_x
!= -1) || (m_y
!= -1))
411 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
413 gtk_window_set_default_size( GTK_WINDOW(m_widget
), m_width
, m_height
);
415 // we cannot set MWM hints and icons before the widget has
416 // been realized, so we do this directly after realization
417 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
418 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
420 // the only way to get the window size is to connect to this event
421 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
422 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
424 // map and unmap for iconized state
425 gtk_signal_connect( GTK_OBJECT(m_widget
), "map_event",
426 GTK_SIGNAL_FUNC(gtk_frame_map_callback
), (gpointer
)this );
427 gtk_signal_connect( GTK_OBJECT(m_widget
), "unmap_event",
428 GTK_SIGNAL_FUNC(gtk_frame_unmap_callback
), (gpointer
)this );
430 // the only way to get the window size is to connect to this event
431 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
432 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
434 // disable native tab traversal
435 gtk_signal_connect( GTK_OBJECT(m_widget
), "focus",
436 GTK_SIGNAL_FUNC(gtk_frame_focus_callback
), (gpointer
)this );
439 if ((m_miniEdge
> 0) || (style
& wxSIMPLE_BORDER
) || (style
& wxNO_BORDER
))
446 m_gdkDecor
= (long) GDK_DECOR_BORDER
;
447 m_gdkFunc
= (long) GDK_FUNC_MOVE
;
449 // All this is for Motif Window Manager "hints" and is supposed to be
450 // recognized by other WMs as well.
451 if ((style
& wxCAPTION
) != 0)
452 m_gdkDecor
|= GDK_DECOR_TITLE
;
453 if ((style
& wxSYSTEM_MENU
) != 0)
455 m_gdkFunc
|= GDK_FUNC_CLOSE
;
456 m_gdkDecor
|= GDK_DECOR_MENU
;
458 if ((style
& wxMINIMIZE_BOX
) != 0)
460 m_gdkFunc
|= GDK_FUNC_MINIMIZE
;
461 m_gdkDecor
|= GDK_DECOR_MINIMIZE
;
463 if ((style
& wxMAXIMIZE_BOX
) != 0)
465 m_gdkFunc
|= GDK_FUNC_MAXIMIZE
;
466 m_gdkDecor
|= GDK_DECOR_MAXIMIZE
;
468 if ((style
& wxRESIZE_BORDER
) != 0)
470 m_gdkFunc
|= GDK_FUNC_RESIZE
;
471 m_gdkDecor
|= GDK_DECOR_RESIZEH
;
478 wxTopLevelWindowGTK::~wxTopLevelWindowGTK()
482 wxASSERT_MSG( FALSE
, "Window still grabbed");
486 m_isBeingDeleted
= TRUE
;
488 // it may also be GtkScrolledWindow in the case of an MDI child
489 if (GTK_IS_WINDOW(m_widget
))
491 gtk_window_set_focus( GTK_WINDOW(m_widget
), NULL
);
494 wxTopLevelWindows
.DeleteObject( this );
496 if (wxTheApp
->GetTopWindow() == this)
497 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
499 if ((wxTopLevelWindows
.Number() == 0) &&
500 (wxTheApp
->GetExitOnFrameDelete()))
502 wxTheApp
->ExitMainLoop();
507 // X11 ICCCM values for window layers
508 #define WIN_LAYER_NORMAL 4
509 #define WIN_LAYER_ABOVE_DOCK 10
511 // X11 window manager property name
512 #define XA_WIN_LAYER "_WIN_LAYER"
514 // X11 window manager property name atom
515 static Atom gs_XA_WIN_LAYER
= 0;
518 static void wx_win_hints_set_layer(GtkWidget
*window
, int layer
)
521 GdkWindowPrivate
*priv
;
524 prev_error
= gdk_error_warnings
;
525 gdk_error_warnings
= 0;
526 priv
= (GdkWindowPrivate
*)(GTK_WIDGET(window
)->window
);
528 if (GTK_WIDGET_MAPPED(window
))
530 xev
.type
= ClientMessage
;
531 xev
.xclient
.type
= ClientMessage
;
532 xev
.xclient
.window
= priv
->xwindow
;
533 xev
.xclient
.message_type
= gs_XA_WIN_LAYER
;
534 xev
.xclient
.format
= 32;
535 xev
.xclient
.data
.l
[0] = (long)layer
;
536 xev
.xclient
.data
.l
[1] = gdk_time_get();
538 XSendEvent(GDK_DISPLAY(), GDK_ROOT_WINDOW(), False
,
539 SubstructureNotifyMask
, (XEvent
*) &xev
);
546 XChangeProperty(GDK_DISPLAY(), priv
->xwindow
, gs_XA_WIN_LAYER
,
547 XA_CARDINAL
, 32, PropModeReplace
, (unsigned char *)data
,
550 gdk_error_warnings
= prev_error
;
553 bool wxTopLevelWindowGTK::ShowFullScreen(bool show
, long style
)
555 if (show
== m_fsIsShowing
) return FALSE
; // return what?
557 if (gs_XA_WIN_LAYER
== 0)
559 // Initialose X11 Atom only once
560 gs_XA_WIN_LAYER
= XInternAtom( GDK_DISPLAY(), XA_WIN_LAYER
, False
);
563 m_fsIsShowing
= show
;
567 m_fsSaveGdkFunc
= m_gdkFunc
;
568 m_fsSaveGdkDecor
= m_gdkDecor
;
569 m_fsSaveFlag
= style
;
570 GetPosition( &m_fsSaveFrame
.x
, &m_fsSaveFrame
.y
);
571 GetSize( &m_fsSaveFrame
.width
, &m_fsSaveFrame
.height
);
573 int screen_width
,screen_height
;
574 wxDisplaySize( &screen_width
, &screen_height
);
576 gint client_x
, client_y
, root_x
, root_y
;
579 gdk_window_get_origin (m_widget
->window
, &root_x
, &root_y
);
580 gdk_window_get_geometry (m_widget
->window
, &client_x
, &client_y
,
581 &width
, &height
, NULL
);
583 wx_win_hints_set_layer( m_widget
, WIN_LAYER_ABOVE_DOCK
);
585 gdk_window_move_resize (m_widget
->window
, -client_x
, -client_y
,
586 screen_width
+ 1, screen_height
+ 1);
590 wx_win_hints_set_layer( m_widget
, WIN_LAYER_NORMAL
);
592 SetSize( m_fsSaveFrame
.x
, m_fsSaveFrame
.y
, m_fsSaveFrame
.width
, m_fsSaveFrame
.height
);
598 // ----------------------------------------------------------------------------
599 // overridden wxWindow methods
600 // ----------------------------------------------------------------------------
602 bool wxTopLevelWindowGTK::Show( bool show
)
604 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
606 if (show
&& !m_sizeSet
)
608 /* by calling GtkOnSize here, we don't have to call
609 either after showing the frame, which would entail
610 much ugly flicker or from within the size_allocate
611 handler, because GTK 1.1.X forbids that. */
613 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
616 return wxWindow::Show( show
);
619 void wxTopLevelWindowGTK::DoMoveWindow(int WXUNUSED(x
), int WXUNUSED(y
), int WXUNUSED(width
), int WXUNUSED(height
) )
621 wxFAIL_MSG( wxT("DoMoveWindow called for wxTopLevelWindowGTK") );
624 void wxTopLevelWindowGTK::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
626 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
628 // this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow
629 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
639 int old_width
= m_width
;
640 int old_height
= m_height
;
642 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
644 if (x
!= -1) m_x
= x
;
645 if (y
!= -1) m_y
= y
;
652 if (width
!= -1) m_width
= width
;
653 if (height
!= -1) m_height
= height
;
656 if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
658 if (width == -1) m_width = 80;
661 if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
663 if (height == -1) m_height = 26;
667 int minWidth
= GetMinWidth(),
668 minHeight
= GetMinHeight(),
669 maxWidth
= GetMaxWidth(),
670 maxHeight
= GetMaxHeight();
672 if ((minWidth
!= -1) && (m_width
< minWidth
)) m_width
= minWidth
;
673 if ((minHeight
!= -1) && (m_height
< minHeight
)) m_height
= minHeight
;
674 if ((maxWidth
!= -1) && (m_width
> maxWidth
)) m_width
= maxWidth
;
675 if ((maxHeight
!= -1) && (m_height
> maxHeight
)) m_height
= maxHeight
;
677 if ((m_x
!= -1) || (m_y
!= -1))
679 if ((m_x
!= old_x
) || (m_y
!= old_y
))
681 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
685 if ((m_width
!= old_width
) || (m_height
!= old_height
))
687 if (m_widget
->window
)
688 gdk_window_resize( m_widget
->window
, m_width
, m_height
);
690 gtk_window_set_default_size( GTK_WINDOW(m_widget
), m_width
, m_height
);
692 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
693 done either directly before the frame is shown or in idle time
694 so that different calls to SetSize() don't lead to flicker. */
701 void wxTopLevelWindowGTK::DoGetClientSize( int *width
, int *height
) const
703 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
705 wxWindow::DoGetClientSize( width
, height
);
709 *height
-= m_miniEdge
*2 + m_miniTitle
;
713 *width
-= m_miniEdge
*2;
717 void wxTopLevelWindowGTK::DoSetClientSize( int width
, int height
)
719 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
722 width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
, 0);
725 void wxTopLevelWindowGTK::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
),
726 int width
, int height
)
728 // due to a bug in gtk, x,y are always 0
733 if (m_resizing
) return;
736 if ( m_wxwindow
== NULL
) return;
741 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
742 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
743 set in wxFrame::Create so it is used to check what kind of frame we
744 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
745 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
746 importantly) m_mainWidget */
748 int minWidth
= GetMinWidth(),
749 minHeight
= GetMinHeight(),
750 maxWidth
= GetMaxWidth(),
751 maxHeight
= GetMaxHeight();
753 if ((minWidth
!= -1) && (m_width
< minWidth
)) m_width
= minWidth
;
754 if ((minHeight
!= -1) && (m_height
< minHeight
)) m_height
= minHeight
;
755 if ((maxWidth
!= -1) && (m_width
> maxWidth
)) m_width
= maxWidth
;
756 if ((maxHeight
!= -1) && (m_height
> maxHeight
)) m_height
= maxHeight
;
761 gint flag
= 0; // GDK_HINT_POS;
764 if ((minWidth
!= -1) || (minHeight
!= -1)) flag
|= GDK_HINT_MIN_SIZE
;
765 if ((maxWidth
!= -1) || (maxHeight
!= -1)) flag
|= GDK_HINT_MAX_SIZE
;
767 geom
.min_width
= minWidth
;
768 geom
.min_height
= minHeight
;
770 // Because of the way we set GDK_HINT_MAX_SIZE above, if either of
771 // maxHeight or maxWidth is set, we must set them both, else the
772 // remaining -1 will be taken literally.
774 // I'm certain this also happens elsewhere, and is the probable
775 // cause of other such things as:
776 // Gtk-WARNING **: gtk_widget_size_allocate():
777 // attempt to allocate widget with width 65535 and height 600
778 // but I don't have time to track them all now..
780 // Really we need to encapulate all this height/width business and
781 // stop any old method from ripping at the members directly and
782 // scattering -1's without regard for who might resolve them later.
784 geom
.max_width
= ( maxHeight
== -1 ) ? maxWidth
785 : ( maxWidth
== -1 ) ? wxGetDisplaySize().GetWidth()
788 geom
.max_height
= ( maxWidth
== -1 ) ? maxHeight
// ( == -1 here )
789 : ( maxHeight
== -1 ) ? wxGetDisplaySize().GetHeight()
792 gtk_window_set_geometry_hints( GTK_WINDOW(m_widget
),
795 (GdkWindowHints
) flag
);
797 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
798 * menubar, the toolbar and the client area, which is represented by
800 * this hurts in the eye, but I don't want to call SetSize()
801 * because I don't want to call any non-native functions here. */
803 int client_x
= m_miniEdge
;
804 int client_y
= m_miniEdge
+ m_miniTitle
;
805 int client_w
= m_width
- 2*m_miniEdge
;
806 int client_h
= m_height
- 2*m_miniEdge
- m_miniTitle
;
808 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
810 client_x
, client_y
, client_w
, client_h
);
814 // If there is no m_mainWidget between m_widget and m_wxwindow there
815 // is no need to set the size or position of m_wxwindow.
820 // send size event to frame
821 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
822 event
.SetEventObject( this );
823 GetEventHandler()->ProcessEvent( event
);
828 void wxTopLevelWindowGTK::OnInternalIdle()
830 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
832 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
834 // we'll come back later
836 wxapp_install_idle_handler();
840 // set the focus if not done yet and if we can already do it
841 if ( GTK_WIDGET_REALIZED(m_wxwindow
) )
843 if ( g_delayedFocus
&&
844 wxGetTopLevelParent((wxWindow
*)g_delayedFocus
) == this )
846 g_delayedFocus
->SetFocus();
847 g_delayedFocus
= NULL
;
851 wxWindow::OnInternalIdle();
854 // ----------------------------------------------------------------------------
856 // ----------------------------------------------------------------------------
858 void wxTopLevelWindowGTK::SetTitle( const wxString
&title
)
860 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
863 gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() );
866 void wxTopLevelWindowGTK::DoSetIcon( const wxIcon
&icon
)
871 if (!m_widget
->window
)
874 wxMask
*mask
= icon
.GetMask();
875 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
876 if (mask
) bm
= mask
->GetBitmap();
878 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);
881 void wxTopLevelWindowGTK::SetIcon( const wxIcon
&icon
)
883 SetIcons( wxIconBundle( icon
) );
886 void wxTopLevelWindowGTK::SetIcons( const wxIconBundle
&icons
)
888 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
889 GdkWindow
* window
= m_widget
->window
;
891 wxTopLevelWindowBase::SetIcons( icons
);
893 DoSetIcon( icons
.GetIcon( -1 ) );
896 wxSetIconsX11( (WXDisplay
*)GDK_WINDOW_XDISPLAY( window
),
897 (WXWindow
)GDK_WINDOW_XWINDOW( window
), icons
);
901 // ----------------------------------------------------------------------------
902 // frame state: maximized/iconized/normal
903 // ----------------------------------------------------------------------------
905 void wxTopLevelWindowGTK::Maximize(bool WXUNUSED(maximize
))
907 wxFAIL_MSG( _T("not implemented") );
910 bool wxTopLevelWindowGTK::IsMaximized() const
912 // wxFAIL_MSG( _T("not implemented") );
914 // This is an approximation
918 void wxTopLevelWindowGTK::Restore()
920 wxFAIL_MSG( _T("not implemented") );
923 void wxTopLevelWindowGTK::Iconize( bool iconize
)
927 GdkWindow
*window
= m_widget
->window
;
929 // you should do it later, for example from OnCreate() handler
930 wxCHECK_RET( window
, _T("frame not created yet - can't iconize") );
932 XIconifyWindow( GDK_WINDOW_XDISPLAY( window
),
933 GDK_WINDOW_XWINDOW( window
),
934 DefaultScreen( GDK_DISPLAY() ) );
938 bool wxTopLevelWindowGTK::IsIconized() const
943 void wxTopLevelWindowGTK::SetIconizeState(bool iconize
)
945 if ( iconize
!= m_isIconized
)
947 m_isIconized
= iconize
;
948 (void)SendIconizeEvent(iconize
);
952 void wxTopLevelWindowGTK::AddGrab()
957 gtk_grab_add( m_widget
);
959 gtk_grab_remove( m_widget
);
963 void wxTopLevelWindowGTK::RemoveGrab()