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
->m_queuedFullRedraw
= TRUE
;
110 win
->GtkUpdateSize();
114 //-----------------------------------------------------------------------------
116 //-----------------------------------------------------------------------------
118 static gint
gtk_frame_delete_callback( GtkWidget
*WXUNUSED(widget
), GdkEvent
*WXUNUSED(event
), wxTopLevelWindowGTK
*win
)
121 wxapp_install_idle_handler();
123 if (win
->IsEnabled() &&
124 (g_openDialogs
== 0 || (win
->GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
) ||
132 //-----------------------------------------------------------------------------
134 //-----------------------------------------------------------------------------
137 gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*WXUNUSED(event
), wxTopLevelWindowGTK
*win
)
140 wxapp_install_idle_handler();
142 if (!win
->m_hasVMT
|| !win
->IsShown())
147 gdk_window_get_root_origin( win
->m_widget
->window
, &x
, &y
);
151 wxMoveEvent
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() );
152 mevent
.SetEventObject( win
);
153 win
->GetEventHandler()->ProcessEvent( mevent
);
158 //-----------------------------------------------------------------------------
159 // "realize" from m_widget
160 //-----------------------------------------------------------------------------
162 // we cannot MWM hints and icons before the widget has been realized,
163 // so we do this directly after realization
166 gtk_frame_realized_callback( GtkWidget
* WXUNUSED(widget
),
167 wxTopLevelWindowGTK
*win
)
170 wxapp_install_idle_handler();
172 // All this is for Motif Window Manager "hints" and is supposed to be
173 // recognized by other WM as well. Not tested.
174 gdk_window_set_decorations(win
->m_widget
->window
,
175 (GdkWMDecoration
)win
->m_gdkDecor
);
176 gdk_window_set_functions(win
->m_widget
->window
,
177 (GdkWMFunction
)win
->m_gdkFunc
);
179 // GTK's shrinking/growing policy
180 if ((win
->m_gdkFunc
& GDK_FUNC_RESIZE
) == 0)
181 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1);
183 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1);
186 wxIconBundle iconsOld
= win
->GetIcons();
187 if ( iconsOld
.GetIcon(-1).Ok() )
189 win
->SetIcon( wxNullIcon
);
190 win
->SetIcons( iconsOld
);
194 //-----------------------------------------------------------------------------
195 // "map_event" from m_widget
196 //-----------------------------------------------------------------------------
199 gtk_frame_map_callback( GtkWidget
* WXUNUSED(widget
),
200 GdkEvent
* WXUNUSED(event
),
201 wxTopLevelWindow
*win
)
203 win
->SetIconizeState(FALSE
);
206 //-----------------------------------------------------------------------------
207 // "unmap_event" from m_widget
208 //-----------------------------------------------------------------------------
211 gtk_frame_unmap_callback( GtkWidget
* WXUNUSED(widget
),
212 GdkEvent
* WXUNUSED(event
),
213 wxTopLevelWindow
*win
)
215 win
->SetIconizeState(TRUE
);
218 //-----------------------------------------------------------------------------
219 // "expose_event" of m_client
220 //-----------------------------------------------------------------------------
222 static int gtk_window_expose_callback( GtkWidget
*widget
, GdkEventExpose
*gdk_event
, wxWindow
*win
)
224 GtkPizza
*pizza
= GTK_PIZZA(widget
);
226 gtk_paint_flat_box (win
->m_widget
->style
,
227 pizza
->bin_window
, GTK_STATE_NORMAL
,
237 //-----------------------------------------------------------------------------
238 // "draw" of m_client
239 //-----------------------------------------------------------------------------
243 static void gtk_window_draw_callback( GtkWidget
*widget
, GdkRectangle
*rect
, wxWindow
*win
)
245 GtkPizza
*pizza
= GTK_PIZZA(widget
);
247 gtk_paint_flat_box (win
->m_widget
->style
,
248 pizza
->bin_window
, GTK_STATE_NORMAL
,
258 // ----------------------------------------------------------------------------
259 // wxTopLevelWindowGTK itself
260 // ----------------------------------------------------------------------------
262 //-----------------------------------------------------------------------------
263 // InsertChild for wxTopLevelWindowGTK
264 //-----------------------------------------------------------------------------
266 /* Callback for wxTopLevelWindowGTK. This very strange beast has to be used because
267 * C++ has no virtual methods in a constructor. We have to emulate a
268 * virtual function here as wxWidgets requires different ways to insert
269 * a child in container classes. */
271 static void wxInsertChildInTopLevelWindow( wxTopLevelWindowGTK
* parent
, wxWindow
* child
)
273 wxASSERT( GTK_IS_WIDGET(child
->m_widget
) );
275 if (!parent
->m_insertInClientArea
)
277 // these are outside the client area
278 wxTopLevelWindowGTK
* frame
= (wxTopLevelWindowGTK
*) parent
;
279 gtk_pizza_put( GTK_PIZZA(frame
->m_mainWidget
),
280 GTK_WIDGET(child
->m_widget
),
288 // these are inside the client area
289 gtk_pizza_put( GTK_PIZZA(parent
->m_wxwindow
),
290 GTK_WIDGET(child
->m_widget
),
297 // resize on OnInternalIdle
298 parent
->GtkUpdateSize();
301 // ----------------------------------------------------------------------------
302 // wxTopLevelWindowGTK creation
303 // ----------------------------------------------------------------------------
305 void wxTopLevelWindowGTK::Init()
310 m_mainWidget
= (GtkWidget
*) NULL
;
311 m_insertInClientArea
= TRUE
;
312 m_isIconized
= FALSE
;
313 m_fsIsShowing
= FALSE
;
314 m_themeEnabled
= TRUE
;
315 m_gdkDecor
= m_gdkFunc
= 0;
319 bool wxTopLevelWindowGTK::Create( wxWindow
*parent
,
321 const wxString
& title
,
323 const wxSize
& sizeOrig
,
325 const wxString
&name
)
327 // always create a frame of some reasonable, even if arbitrary, size (at
328 // least for MSW compatibility)
329 wxSize size
= sizeOrig
;
330 size
.x
= WidthDefault(size
.x
);
331 size
.y
= HeightDefault(size
.y
);
333 wxTopLevelWindows
.Append( this );
335 m_needParent
= FALSE
;
337 if (!PreCreation( parent
, pos
, size
) ||
338 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
340 wxFAIL_MSG( wxT("wxTopLevelWindowGTK creation failed") );
346 m_insertCallback
= (wxInsertChildFunction
) wxInsertChildInTopLevelWindow
;
348 // NB: m_widget may be !=NULL if it was created by derived class' Create,
349 // e.g. in wxTaskBarIconAreaGTK
350 if (m_widget
== NULL
)
352 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
354 if (style
& wxFRAME_TOOL_WINDOW
)
355 win_type
= GTK_WINDOW_POPUP
;
357 if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
)
359 // there is no more GTK_WINDOW_DIALOG in 2.0
361 win_type
= GTK_WINDOW_TOPLEVEL
;
363 win_type
= GTK_WINDOW_DIALOG
;
367 m_widget
= gtk_window_new( win_type
);
370 if (m_parent
&& (((GTK_IS_WINDOW(m_parent
->m_widget
)) &&
371 (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
)) ||
372 (style
& wxFRAME_FLOAT_ON_PARENT
)))
374 gtk_window_set_transient_for( GTK_WINDOW(m_widget
), GTK_WINDOW(m_parent
->m_widget
) );
378 gtk_window_set_wmclass( GTK_WINDOW(m_widget
), wxGTK_CONV( name
), wxGTK_CONV( name
) );
380 gtk_window_set_title( GTK_WINDOW(m_widget
), wxGTK_CONV( title
) );
381 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
383 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
384 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
386 // m_mainWidget holds the toolbar, the menubar and the client area
387 m_mainWidget
= gtk_pizza_new();
388 gtk_widget_show( m_mainWidget
);
389 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
390 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
392 if (m_miniEdge
== 0) // wxMiniFrame has its own version.
394 // For m_mainWidget themes
395 gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "expose_event",
396 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
398 gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "draw",
399 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
403 // m_wxwindow only represents the client area without toolbar and menubar
404 m_wxwindow
= gtk_pizza_new();
405 gtk_widget_show( m_wxwindow
);
406 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
408 // we donm't allow the frame to get the focus as otherwise
409 // the frame will grab it at arbitrary focus changes
410 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
412 if (m_parent
) m_parent
->AddChild( this );
414 // the user resized the frame by dragging etc.
415 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
416 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
420 if ((m_x
!= -1) || (m_y
!= -1))
421 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
423 gtk_window_set_default_size( GTK_WINDOW(m_widget
), m_width
, m_height
);
425 // we cannot set MWM hints and icons before the widget has
426 // been realized, so we do this directly after realization
427 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
428 GTK_SIGNAL_FUNC(gtk_frame_realized_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 // map and unmap for iconized state
435 gtk_signal_connect( GTK_OBJECT(m_widget
), "map_event",
436 GTK_SIGNAL_FUNC(gtk_frame_map_callback
), (gpointer
)this );
437 gtk_signal_connect( GTK_OBJECT(m_widget
), "unmap_event",
438 GTK_SIGNAL_FUNC(gtk_frame_unmap_callback
), (gpointer
)this );
440 // the only way to get the window size is to connect to this event
441 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
442 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
444 // disable native tab traversal
445 gtk_signal_connect( GTK_OBJECT(m_widget
), "focus",
446 GTK_SIGNAL_FUNC(gtk_frame_focus_callback
), (gpointer
)this );
449 if ((m_miniEdge
> 0) || (style
& wxSIMPLE_BORDER
) || (style
& wxNO_BORDER
))
456 m_gdkDecor
= (long) GDK_DECOR_BORDER
;
457 m_gdkFunc
= (long) GDK_FUNC_MOVE
;
459 // All this is for Motif Window Manager "hints" and is supposed to be
460 // recognized by other WMs as well.
461 if ((style
& wxCAPTION
) != 0)
463 m_gdkDecor
|= GDK_DECOR_TITLE
;
465 if ((style
& wxCLOSE_BOX
) != 0)
467 m_gdkFunc
|= GDK_FUNC_CLOSE
;
469 if ((style
& wxSYSTEM_MENU
) != 0)
471 m_gdkDecor
|= GDK_DECOR_MENU
;
473 if ((style
& wxMINIMIZE_BOX
) != 0)
475 m_gdkFunc
|= GDK_FUNC_MINIMIZE
;
476 m_gdkDecor
|= GDK_DECOR_MINIMIZE
;
478 if ((style
& wxMAXIMIZE_BOX
) != 0)
480 m_gdkFunc
|= GDK_FUNC_MAXIMIZE
;
481 m_gdkDecor
|= GDK_DECOR_MAXIMIZE
;
483 if ((style
& wxRESIZE_BORDER
) != 0)
485 m_gdkFunc
|= GDK_FUNC_RESIZE
;
486 m_gdkDecor
|= GDK_DECOR_RESIZEH
;
493 wxTopLevelWindowGTK::~wxTopLevelWindowGTK()
497 wxASSERT_MSG( FALSE
, _T("Window still grabbed"));
501 m_isBeingDeleted
= TRUE
;
503 // it may also be GtkScrolledWindow in the case of an MDI child
504 if (GTK_IS_WINDOW(m_widget
))
506 gtk_window_set_focus( GTK_WINDOW(m_widget
), NULL
);
512 bool wxTopLevelWindowGTK::ShowFullScreen(bool show
, long style
)
514 if (show
== m_fsIsShowing
) return FALSE
; // return what?
516 m_fsIsShowing
= show
;
518 GdkWindow
*window
= m_widget
->window
;
519 wxX11FullScreenMethod method
=
520 wxGetFullScreenMethodX11((WXDisplay
*)GDK_DISPLAY(),
521 (WXWindow
)GDK_ROOT_WINDOW());
525 m_fsSaveFlag
= style
;
526 GetPosition( &m_fsSaveFrame
.x
, &m_fsSaveFrame
.y
);
527 GetSize( &m_fsSaveFrame
.width
, &m_fsSaveFrame
.height
);
529 int screen_width
,screen_height
;
530 wxDisplaySize( &screen_width
, &screen_height
);
532 gint client_x
, client_y
, root_x
, root_y
;
535 if (method
!= wxX11_FS_WMSPEC
)
537 // don't do it always, Metacity hates it
538 m_fsSaveGdkFunc
= m_gdkFunc
;
539 m_fsSaveGdkDecor
= m_gdkDecor
;
540 m_gdkFunc
= m_gdkDecor
= 0;
541 gdk_window_set_decorations(window
, (GdkWMDecoration
)0);
542 gdk_window_set_functions(window
, (GdkWMFunction
)0);
545 gdk_window_get_origin (m_widget
->window
, &root_x
, &root_y
);
546 gdk_window_get_geometry (m_widget
->window
, &client_x
, &client_y
,
547 &width
, &height
, NULL
);
549 gdk_window_move_resize (m_widget
->window
, -client_x
, -client_y
,
550 screen_width
+ 1, screen_height
+ 1);
552 wxSetFullScreenStateX11((WXDisplay
*)GDK_DISPLAY(),
553 (WXWindow
)GDK_ROOT_WINDOW(),
554 (WXWindow
)GDK_WINDOW_XWINDOW(window
),
555 show
, &m_fsSaveFrame
, method
);
559 if (method
!= wxX11_FS_WMSPEC
)
561 // don't do it always, Metacity hates it
562 m_gdkFunc
= m_fsSaveGdkFunc
;
563 m_gdkDecor
= m_fsSaveGdkDecor
;
564 gdk_window_set_decorations(window
, (GdkWMDecoration
)m_gdkDecor
);
565 gdk_window_set_functions(window
, (GdkWMFunction
)m_gdkFunc
);
568 wxSetFullScreenStateX11((WXDisplay
*)GDK_DISPLAY(),
569 (WXWindow
)GDK_ROOT_WINDOW(),
570 (WXWindow
)GDK_WINDOW_XWINDOW(window
),
571 show
, &m_fsSaveFrame
, method
);
573 SetSize(m_fsSaveFrame
.x
, m_fsSaveFrame
.y
,
574 m_fsSaveFrame
.width
, m_fsSaveFrame
.height
);
581 // ----------------------------------------------------------------------------
582 // overridden wxWindow methods
583 // ----------------------------------------------------------------------------
585 bool wxTopLevelWindowGTK::Show( bool show
)
587 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
589 if (show
&& !m_sizeSet
)
591 /* by calling GtkOnSize here, we don't have to call
592 either after showing the frame, which would entail
593 much ugly flicker or from within the size_allocate
594 handler, because GTK 1.1.X forbids that. */
596 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
599 return wxWindow::Show( show
);
602 void wxTopLevelWindowGTK::DoMoveWindow(int WXUNUSED(x
), int WXUNUSED(y
), int WXUNUSED(width
), int WXUNUSED(height
) )
604 wxFAIL_MSG( wxT("DoMoveWindow called for wxTopLevelWindowGTK") );
607 void wxTopLevelWindowGTK::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
609 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
611 // this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow
612 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
622 int old_width
= m_width
;
623 int old_height
= m_height
;
625 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
627 if (x
!= -1) m_x
= x
;
628 if (y
!= -1) m_y
= y
;
635 if (width
!= -1) m_width
= width
;
636 if (height
!= -1) m_height
= height
;
639 if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
641 if (width == -1) m_width = 80;
644 if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
646 if (height == -1) m_height = 26;
650 int minWidth
= GetMinWidth(),
651 minHeight
= GetMinHeight(),
652 maxWidth
= GetMaxWidth(),
653 maxHeight
= GetMaxHeight();
656 // GPE's window manager doesn't like size hints
657 // at all, esp. when the user has to use the
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();
747 // GPE's window manager doesn't like size hints
748 // at all, esp. when the user has to use the
756 if ((minWidth
!= -1) && (m_width
< minWidth
)) m_width
= minWidth
;
757 if ((minHeight
!= -1) && (m_height
< minHeight
)) m_height
= minHeight
;
758 if ((maxWidth
!= -1) && (m_width
> maxWidth
)) m_width
= maxWidth
;
759 if ((maxHeight
!= -1) && (m_height
> maxHeight
)) m_height
= maxHeight
;
764 gint flag
= 0; // GDK_HINT_POS;
767 if ((minWidth
!= -1) || (minHeight
!= -1)) flag
|= GDK_HINT_MIN_SIZE
;
768 if ((maxWidth
!= -1) || (maxHeight
!= -1)) flag
|= GDK_HINT_MAX_SIZE
;
770 geom
.min_width
= minWidth
;
771 geom
.min_height
= minHeight
;
773 // Because of the way we set GDK_HINT_MAX_SIZE above, if either of
774 // maxHeight or maxWidth is set, we must set them both, else the
775 // remaining -1 will be taken literally.
777 // I'm certain this also happens elsewhere, and is the probable
778 // cause of other such things as:
779 // Gtk-WARNING **: gtk_widget_size_allocate():
780 // attempt to allocate widget with width 65535 and height 600
781 // but I don't have time to track them all now..
783 // Really we need to encapulate all this height/width business and
784 // stop any old method from ripping at the members directly and
785 // scattering -1's without regard for who might resolve them later.
787 geom
.max_width
= ( maxHeight
== -1 ) ? maxWidth
788 : ( maxWidth
== -1 ) ? wxGetDisplaySize().GetWidth()
791 geom
.max_height
= ( maxWidth
== -1 ) ? maxHeight
// ( == -1 here )
792 : ( maxHeight
== -1 ) ? wxGetDisplaySize().GetHeight()
795 gtk_window_set_geometry_hints( GTK_WINDOW(m_widget
),
798 (GdkWindowHints
) flag
);
800 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
801 * menubar, the toolbar and the client area, which is represented by
803 * this hurts in the eye, but I don't want to call SetSize()
804 * because I don't want to call any non-native functions here. */
806 int client_x
= m_miniEdge
;
807 int client_y
= m_miniEdge
+ m_miniTitle
;
808 int client_w
= m_width
- 2*m_miniEdge
;
809 int client_h
= m_height
- 2*m_miniEdge
- m_miniTitle
;
811 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
813 client_x
, client_y
, client_w
, client_h
);
817 // If there is no m_mainWidget between m_widget and m_wxwindow there
818 // is no need to set the size or position of m_wxwindow.
823 // send size event to frame
824 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
825 event
.SetEventObject( this );
826 GetEventHandler()->ProcessEvent( event
);
831 void wxTopLevelWindowGTK::OnInternalIdle()
833 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
835 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
837 // we'll come back later
839 wxapp_install_idle_handler();
843 // set the focus if not done yet and if we can already do it
844 if ( GTK_WIDGET_REALIZED(m_wxwindow
) )
846 if ( g_delayedFocus
&&
847 wxGetTopLevelParent((wxWindow
*)g_delayedFocus
) == this )
849 wxLogTrace(_T("focus"),
850 _T("Setting focus from wxTLW::OnIdle() to %s(%s)"),
851 g_delayedFocus
->GetClassInfo()->GetClassName(),
852 g_delayedFocus
->GetLabel().c_str());
854 g_delayedFocus
->SetFocus();
855 g_delayedFocus
= NULL
;
859 wxWindow::OnInternalIdle();
862 // ----------------------------------------------------------------------------
864 // ----------------------------------------------------------------------------
866 void wxTopLevelWindowGTK::SetTitle( const wxString
&title
)
868 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
871 gtk_window_set_title( GTK_WINDOW(m_widget
), wxGTK_CONV( title
) );
874 void wxTopLevelWindowGTK::DoSetIcon( const wxIcon
&icon
)
879 if (!m_widget
->window
)
882 wxMask
*mask
= icon
.GetMask();
883 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
884 if (mask
) bm
= mask
->GetBitmap();
886 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);
889 void wxTopLevelWindowGTK::SetIcon( const wxIcon
&icon
)
891 SetIcons( wxIconBundle( icon
) );
894 void wxTopLevelWindowGTK::SetIcons( const wxIconBundle
&icons
)
896 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
897 GdkWindow
* window
= m_widget
->window
;
899 wxTopLevelWindowBase::SetIcons( icons
);
901 DoSetIcon( icons
.GetIcon( -1 ) );
904 wxSetIconsX11( (WXDisplay
*)GDK_WINDOW_XDISPLAY( window
),
905 (WXWindow
)GDK_WINDOW_XWINDOW( window
), icons
);
909 // ----------------------------------------------------------------------------
910 // frame state: maximized/iconized/normal
911 // ----------------------------------------------------------------------------
913 void wxTopLevelWindowGTK::Maximize(bool maximize
)
917 gtk_window_maximize( GTK_WINDOW( m_widget
) );
919 gtk_window_unmaximize( GTK_WINDOW( m_widget
) );
921 wxFAIL_MSG( _T("not implemented") );
925 bool wxTopLevelWindowGTK::IsMaximized() const
927 // wxFAIL_MSG( _T("not implemented") );
929 // This is an approximation
933 void wxTopLevelWindowGTK::Restore()
936 // "Present" seems similar enough to "restore"
937 gtk_window_present( GTK_WINDOW( m_widget
) );
939 wxFAIL_MSG( _T("not implemented") );
943 void wxTopLevelWindowGTK::Iconize( bool iconize
)
947 gtk_window_iconify( GTK_WINDOW( m_widget
) );
949 gtk_window_deiconify( GTK_WINDOW( m_widget
) );
953 GdkWindow
*window
= m_widget
->window
;
955 // you should do it later, for example from OnCreate() handler
956 wxCHECK_RET( window
, _T("frame not created yet - can't iconize") );
958 XIconifyWindow( GDK_WINDOW_XDISPLAY( window
),
959 GDK_WINDOW_XWINDOW( window
),
960 DefaultScreen( GDK_DISPLAY() ) );
965 bool wxTopLevelWindowGTK::IsIconized() const
970 void wxTopLevelWindowGTK::SetIconizeState(bool iconize
)
972 if ( iconize
!= m_isIconized
)
974 m_isIconized
= iconize
;
975 (void)SendIconizeEvent(iconize
);
979 void wxTopLevelWindowGTK::AddGrab()
984 gtk_grab_add( m_widget
);
986 gtk_grab_remove( m_widget
);
990 void wxTopLevelWindowGTK::RemoveGrab()
1001 static bool do_shape_combine_region(GdkWindow
* window
, const wxRegion
& region
)
1005 if (region
.IsEmpty())
1007 gdk_window_shape_combine_mask(window
, NULL
, 0, 0);
1012 gdk_window_shape_combine_region(window
, region
.GetRegion(), 0, 0);
1014 wxBitmap bmp
= region
.ConvertToBitmap();
1015 bmp
.SetMask(new wxMask(bmp
, *wxBLACK
));
1016 GdkBitmap
* mask
= bmp
.GetMask()->GetBitmap();
1017 gdk_window_shape_combine_mask(window
, mask
, 0, 0);
1026 bool wxTopLevelWindowGTK::SetShape(const wxRegion
& region
)
1028 wxCHECK_MSG( HasFlag(wxFRAME_SHAPED
), FALSE
,
1029 _T("Shaped windows must be created with the wxFRAME_SHAPED style."));
1031 GdkWindow
*window
= NULL
;
1034 window
= GTK_PIZZA(m_wxwindow
)->bin_window
;
1035 do_shape_combine_region(window
, region
);
1037 window
= m_widget
->window
;
1038 return do_shape_combine_region(window
, region
);