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"
42 #include <gdk/gdkkeysyms.h>
45 #include "wx/gtk/win_gtk.h"
47 #include "wx/unix/utilsx11.h"
50 #include <X11/Xatom.h>
52 // ----------------------------------------------------------------------------
54 // ----------------------------------------------------------------------------
56 extern void wxapp_install_idle_handler();
59 // ----------------------------------------------------------------------------
61 // ----------------------------------------------------------------------------
63 extern wxList wxPendingDelete
;
65 extern int g_openDialogs
;
66 extern wxWindowGTK
*g_delayedFocus
;
68 //-----------------------------------------------------------------------------
69 // "focus" from m_window
70 //-----------------------------------------------------------------------------
72 static gint
gtk_frame_focus_callback( GtkWidget
*widget
, GtkDirectionType
WXUNUSED(d
), wxWindow
*WXUNUSED(win
) )
75 wxapp_install_idle_handler();
77 // This disables GTK's tab traversal
78 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus" );
82 //-----------------------------------------------------------------------------
84 //-----------------------------------------------------------------------------
86 static void gtk_frame_size_callback( GtkWidget
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxTopLevelWindowGTK
*win
)
89 wxapp_install_idle_handler();
94 if ((win
->m_width
!= alloc
->width
) || (win
->m_height
!= alloc
->height
))
97 wxPrintf( "OnSize from " );
98 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
99 wxPrintf( win->GetClassInfo()->GetClassName() );
100 wxPrintf( " %d %d %d %d\n", (int)alloc->x,
103 (int)alloc->height );
106 win
->m_width
= alloc
->width
;
107 win
->m_height
= alloc
->height
;
108 win
->m_queuedFullRedraw
= TRUE
;
109 win
->GtkUpdateSize();
113 //-----------------------------------------------------------------------------
115 //-----------------------------------------------------------------------------
117 static gint
gtk_frame_delete_callback( GtkWidget
*WXUNUSED(widget
), GdkEvent
*WXUNUSED(event
), wxTopLevelWindowGTK
*win
)
120 wxapp_install_idle_handler();
122 if (win
->IsEnabled() &&
123 (g_openDialogs
== 0 || (win
->GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
) ||
131 //-----------------------------------------------------------------------------
133 //-----------------------------------------------------------------------------
136 gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*WXUNUSED(event
), wxTopLevelWindowGTK
*win
)
139 wxapp_install_idle_handler();
141 if (!win
->m_hasVMT
|| !win
->IsShown())
146 gdk_window_get_root_origin( win
->m_widget
->window
, &x
, &y
);
150 wxMoveEvent
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() );
151 mevent
.SetEventObject( win
);
152 win
->GetEventHandler()->ProcessEvent( mevent
);
157 //-----------------------------------------------------------------------------
158 // "realize" from m_widget
159 //-----------------------------------------------------------------------------
161 // we cannot MWM hints and icons before the widget has been realized,
162 // so we do this directly after realization
165 gtk_frame_realized_callback( GtkWidget
* WXUNUSED(widget
),
166 wxTopLevelWindowGTK
*win
)
169 wxapp_install_idle_handler();
171 // All this is for Motif Window Manager "hints" and is supposed to be
172 // recognized by other WM as well. Not tested.
173 gdk_window_set_decorations(win
->m_widget
->window
,
174 (GdkWMDecoration
)win
->m_gdkDecor
);
175 gdk_window_set_functions(win
->m_widget
->window
,
176 (GdkWMFunction
)win
->m_gdkFunc
);
178 // GTK's shrinking/growing policy
179 if ((win
->m_gdkFunc
& GDK_FUNC_RESIZE
) == 0)
180 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1);
182 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1);
185 wxIconBundle iconsOld
= win
->GetIcons();
186 if ( iconsOld
.GetIcon(-1).Ok() )
188 win
->SetIcon( wxNullIcon
);
189 win
->SetIcons( iconsOld
);
193 //-----------------------------------------------------------------------------
194 // "map_event" from m_widget
195 //-----------------------------------------------------------------------------
198 gtk_frame_map_callback( GtkWidget
* WXUNUSED(widget
),
199 GdkEvent
* WXUNUSED(event
),
200 wxTopLevelWindow
*win
)
202 win
->SetIconizeState(FALSE
);
205 //-----------------------------------------------------------------------------
206 // "unmap_event" from m_widget
207 //-----------------------------------------------------------------------------
210 gtk_frame_unmap_callback( GtkWidget
* WXUNUSED(widget
),
211 GdkEvent
* WXUNUSED(event
),
212 wxTopLevelWindow
*win
)
214 win
->SetIconizeState(TRUE
);
217 //-----------------------------------------------------------------------------
218 // "expose_event" of m_client
219 //-----------------------------------------------------------------------------
221 static int gtk_window_expose_callback( GtkWidget
*widget
, GdkEventExpose
*gdk_event
, wxWindow
*win
)
223 GtkPizza
*pizza
= GTK_PIZZA(widget
);
225 gtk_paint_flat_box (win
->m_widget
->style
,
226 pizza
->bin_window
, GTK_STATE_NORMAL
,
236 //-----------------------------------------------------------------------------
237 // "draw" of m_client
238 //-----------------------------------------------------------------------------
242 static void gtk_window_draw_callback( GtkWidget
*widget
, GdkRectangle
*rect
, wxWindow
*win
)
244 GtkPizza
*pizza
= GTK_PIZZA(widget
);
246 gtk_paint_flat_box (win
->m_widget
->style
,
247 pizza
->bin_window
, GTK_STATE_NORMAL
,
257 // ----------------------------------------------------------------------------
258 // wxTopLevelWindowGTK itself
259 // ----------------------------------------------------------------------------
261 //-----------------------------------------------------------------------------
262 // InsertChild for wxTopLevelWindowGTK
263 //-----------------------------------------------------------------------------
265 /* Callback for wxTopLevelWindowGTK. This very strange beast has to be used because
266 * C++ has no virtual methods in a constructor. We have to emulate a
267 * virtual function here as wxWindows requires different ways to insert
268 * a child in container classes. */
270 static void wxInsertChildInTopLevelWindow( wxTopLevelWindowGTK
* parent
, wxWindow
* child
)
272 wxASSERT( GTK_IS_WIDGET(child
->m_widget
) );
274 if (!parent
->m_insertInClientArea
)
276 // these are outside the client area
277 wxTopLevelWindowGTK
* frame
= (wxTopLevelWindowGTK
*) parent
;
278 gtk_pizza_put( GTK_PIZZA(frame
->m_mainWidget
),
279 GTK_WIDGET(child
->m_widget
),
287 // these are inside the client area
288 gtk_pizza_put( GTK_PIZZA(parent
->m_wxwindow
),
289 GTK_WIDGET(child
->m_widget
),
296 // resize on OnInternalIdle
297 parent
->GtkUpdateSize();
300 // ----------------------------------------------------------------------------
301 // wxTopLevelWindowGTK creation
302 // ----------------------------------------------------------------------------
304 void wxTopLevelWindowGTK::Init()
309 m_mainWidget
= (GtkWidget
*) NULL
;
310 m_insertInClientArea
= TRUE
;
311 m_isIconized
= FALSE
;
312 m_fsIsShowing
= FALSE
;
313 m_themeEnabled
= TRUE
;
314 m_gdkDecor
= m_gdkFunc
= 0;
318 bool wxTopLevelWindowGTK::Create( wxWindow
*parent
,
320 const wxString
& title
,
322 const wxSize
& sizeOrig
,
324 const wxString
&name
)
326 // always create a frame of some reasonable, even if arbitrary, size (at
327 // least for MSW compatibility)
328 wxSize size
= sizeOrig
;
329 if ( size
.x
== -1 || size
.y
== -1 )
331 wxSize sizeDpy
= wxGetDisplaySize();
333 size
.x
= sizeDpy
.x
/ 3;
335 size
.y
= sizeDpy
.y
/ 5;
338 wxTopLevelWindows
.Append( this );
340 m_needParent
= FALSE
;
342 if (!PreCreation( parent
, pos
, size
) ||
343 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
345 wxFAIL_MSG( wxT("wxTopLevelWindowGTK creation failed") );
351 m_insertCallback
= (wxInsertChildFunction
) wxInsertChildInTopLevelWindow
;
353 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
355 if (style
& wxFRAME_TOOL_WINDOW
)
356 win_type
= GTK_WINDOW_POPUP
;
358 if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
)
360 // there is no more GTK_WINDOW_DIALOG in 2.0
362 win_type
= GTK_WINDOW_TOPLEVEL
;
364 win_type
= GTK_WINDOW_DIALOG
;
368 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();
655 if ((minWidth
!= -1) && (m_width
< minWidth
)) m_width
= minWidth
;
656 if ((minHeight
!= -1) && (m_height
< minHeight
)) m_height
= minHeight
;
657 if ((maxWidth
!= -1) && (m_width
> maxWidth
)) m_width
= maxWidth
;
658 if ((maxHeight
!= -1) && (m_height
> maxHeight
)) m_height
= maxHeight
;
660 if ((m_x
!= -1) || (m_y
!= -1))
662 if ((m_x
!= old_x
) || (m_y
!= old_y
))
664 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
668 if ((m_width
!= old_width
) || (m_height
!= old_height
))
670 if (m_widget
->window
)
671 gdk_window_resize( m_widget
->window
, m_width
, m_height
);
673 gtk_window_set_default_size( GTK_WINDOW(m_widget
), m_width
, m_height
);
675 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
676 done either directly before the frame is shown or in idle time
677 so that different calls to SetSize() don't lead to flicker. */
684 void wxTopLevelWindowGTK::DoGetClientSize( int *width
, int *height
) const
686 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
688 wxWindow::DoGetClientSize( width
, height
);
692 *height
-= m_miniEdge
*2 + m_miniTitle
;
696 *width
-= m_miniEdge
*2;
700 void wxTopLevelWindowGTK::DoSetClientSize( int width
, int height
)
702 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
705 width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
, 0);
708 void wxTopLevelWindowGTK::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
),
709 int width
, int height
)
711 // due to a bug in gtk, x,y are always 0
716 if (m_resizing
) return;
719 if ( m_wxwindow
== NULL
) return;
724 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
725 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
726 set in wxFrame::Create so it is used to check what kind of frame we
727 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
728 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
729 importantly) m_mainWidget */
731 int minWidth
= GetMinWidth(),
732 minHeight
= GetMinHeight(),
733 maxWidth
= GetMaxWidth(),
734 maxHeight
= GetMaxHeight();
736 if ((minWidth
!= -1) && (m_width
< minWidth
)) m_width
= minWidth
;
737 if ((minHeight
!= -1) && (m_height
< minHeight
)) m_height
= minHeight
;
738 if ((maxWidth
!= -1) && (m_width
> maxWidth
)) m_width
= maxWidth
;
739 if ((maxHeight
!= -1) && (m_height
> maxHeight
)) m_height
= maxHeight
;
744 gint flag
= 0; // GDK_HINT_POS;
747 if ((minWidth
!= -1) || (minHeight
!= -1)) flag
|= GDK_HINT_MIN_SIZE
;
748 if ((maxWidth
!= -1) || (maxHeight
!= -1)) flag
|= GDK_HINT_MAX_SIZE
;
750 geom
.min_width
= minWidth
;
751 geom
.min_height
= minHeight
;
753 // Because of the way we set GDK_HINT_MAX_SIZE above, if either of
754 // maxHeight or maxWidth is set, we must set them both, else the
755 // remaining -1 will be taken literally.
757 // I'm certain this also happens elsewhere, and is the probable
758 // cause of other such things as:
759 // Gtk-WARNING **: gtk_widget_size_allocate():
760 // attempt to allocate widget with width 65535 and height 600
761 // but I don't have time to track them all now..
763 // Really we need to encapulate all this height/width business and
764 // stop any old method from ripping at the members directly and
765 // scattering -1's without regard for who might resolve them later.
767 geom
.max_width
= ( maxHeight
== -1 ) ? maxWidth
768 : ( maxWidth
== -1 ) ? wxGetDisplaySize().GetWidth()
771 geom
.max_height
= ( maxWidth
== -1 ) ? maxHeight
// ( == -1 here )
772 : ( maxHeight
== -1 ) ? wxGetDisplaySize().GetHeight()
775 gtk_window_set_geometry_hints( GTK_WINDOW(m_widget
),
778 (GdkWindowHints
) flag
);
780 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
781 * menubar, the toolbar and the client area, which is represented by
783 * this hurts in the eye, but I don't want to call SetSize()
784 * because I don't want to call any non-native functions here. */
786 int client_x
= m_miniEdge
;
787 int client_y
= m_miniEdge
+ m_miniTitle
;
788 int client_w
= m_width
- 2*m_miniEdge
;
789 int client_h
= m_height
- 2*m_miniEdge
- m_miniTitle
;
791 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
793 client_x
, client_y
, client_w
, client_h
);
797 // If there is no m_mainWidget between m_widget and m_wxwindow there
798 // is no need to set the size or position of m_wxwindow.
803 // send size event to frame
804 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
805 event
.SetEventObject( this );
806 GetEventHandler()->ProcessEvent( event
);
811 void wxTopLevelWindowGTK::OnInternalIdle()
813 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
815 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
817 // we'll come back later
819 wxapp_install_idle_handler();
823 // set the focus if not done yet and if we can already do it
824 if ( GTK_WIDGET_REALIZED(m_wxwindow
) )
826 if ( g_delayedFocus
&&
827 wxGetTopLevelParent((wxWindow
*)g_delayedFocus
) == this )
829 wxLogTrace(_T("focus"),
830 _T("Setting focus from wxTLW::OnIdle() to %s(%s)"),
831 g_delayedFocus
->GetClassInfo()->GetClassName(),
832 g_delayedFocus
->GetLabel().c_str());
834 g_delayedFocus
->SetFocus();
835 g_delayedFocus
= NULL
;
839 wxWindow::OnInternalIdle();
842 // ----------------------------------------------------------------------------
844 // ----------------------------------------------------------------------------
846 void wxTopLevelWindowGTK::SetTitle( const wxString
&title
)
848 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
851 gtk_window_set_title( GTK_WINDOW(m_widget
), wxGTK_CONV( title
) );
854 void wxTopLevelWindowGTK::DoSetIcon( const wxIcon
&icon
)
859 if (!m_widget
->window
)
862 wxMask
*mask
= icon
.GetMask();
863 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
864 if (mask
) bm
= mask
->GetBitmap();
866 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);
869 void wxTopLevelWindowGTK::SetIcon( const wxIcon
&icon
)
871 SetIcons( wxIconBundle( icon
) );
874 void wxTopLevelWindowGTK::SetIcons( const wxIconBundle
&icons
)
876 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
877 GdkWindow
* window
= m_widget
->window
;
879 wxTopLevelWindowBase::SetIcons( icons
);
881 DoSetIcon( icons
.GetIcon( -1 ) );
884 wxSetIconsX11( (WXDisplay
*)GDK_WINDOW_XDISPLAY( window
),
885 (WXWindow
)GDK_WINDOW_XWINDOW( window
), icons
);
889 // ----------------------------------------------------------------------------
890 // frame state: maximized/iconized/normal
891 // ----------------------------------------------------------------------------
893 void wxTopLevelWindowGTK::Maximize(bool maximize
)
897 gtk_window_maximize( GTK_WINDOW( m_widget
) );
899 gtk_window_unmaximize( GTK_WINDOW( m_widget
) );
901 wxFAIL_MSG( _T("not implemented") );
905 bool wxTopLevelWindowGTK::IsMaximized() const
907 // wxFAIL_MSG( _T("not implemented") );
909 // This is an approximation
913 void wxTopLevelWindowGTK::Restore()
916 // "Present" seems similar enough to "restore"
917 gtk_window_present( GTK_WINDOW( m_widget
) );
919 wxFAIL_MSG( _T("not implemented") );
923 void wxTopLevelWindowGTK::Iconize( bool iconize
)
927 gtk_window_iconify( GTK_WINDOW( m_widget
) );
929 gtk_window_deiconify( GTK_WINDOW( m_widget
) );
933 GdkWindow
*window
= m_widget
->window
;
935 // you should do it later, for example from OnCreate() handler
936 wxCHECK_RET( window
, _T("frame not created yet - can't iconize") );
938 XIconifyWindow( GDK_WINDOW_XDISPLAY( window
),
939 GDK_WINDOW_XWINDOW( window
),
940 DefaultScreen( GDK_DISPLAY() ) );
945 bool wxTopLevelWindowGTK::IsIconized() const
950 void wxTopLevelWindowGTK::SetIconizeState(bool iconize
)
952 if ( iconize
!= m_isIconized
)
954 m_isIconized
= iconize
;
955 (void)SendIconizeEvent(iconize
);
959 void wxTopLevelWindowGTK::AddGrab()
964 gtk_grab_add( m_widget
);
966 gtk_grab_remove( m_widget
);
970 void wxTopLevelWindowGTK::RemoveGrab()
981 static bool do_shape_combine_region(GdkWindow
* window
, const wxRegion
& region
)
985 if (region
.IsEmpty())
987 gdk_window_shape_combine_mask(window
, NULL
, 0, 0);
992 gdk_window_shape_combine_region(window
, region
.GetRegion(), 0, 0);
994 wxBitmap bmp
= region
.ConvertToBitmap();
995 bmp
.SetMask(new wxMask(bmp
, *wxBLACK
));
996 GdkBitmap
* mask
= bmp
.GetMask()->GetBitmap();
997 gdk_window_shape_combine_mask(window
, mask
, 0, 0);
1006 bool wxTopLevelWindowGTK::SetShape(const wxRegion
& region
)
1008 wxCHECK_MSG( HasFlag(wxFRAME_SHAPED
), FALSE
,
1009 _T("Shaped windows must be created with the wxFRAME_SHAPED style."));
1011 GdkWindow
*window
= NULL
;
1014 window
= GTK_PIZZA(m_wxwindow
)->bin_window
;
1015 do_shape_combine_region(window
, region
);
1017 window
= m_widget
->window
;
1018 return do_shape_combine_region(window
, region
);