1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
10 // ============================================================================
12 // ============================================================================
14 // ----------------------------------------------------------------------------
16 // ----------------------------------------------------------------------------
19 #pragma implementation "toplevel.h"
23 #define XIconifyWindow XICONIFYWINDOW
29 #include "wx/dialog.h"
30 #include "wx/control.h"
32 #include "wx/dcclient.h"
33 #include "wx/gtk/private.h"
39 #include <gdk/gdkkeysyms.h>
42 #include "wx/gtk/win_gtk.h"
44 #include "wx/unix/utilsx11.h"
47 #include <X11/Xatom.h>
49 // ----------------------------------------------------------------------------
51 // ----------------------------------------------------------------------------
53 extern void wxapp_install_idle_handler();
56 // ----------------------------------------------------------------------------
58 // ----------------------------------------------------------------------------
60 extern wxList wxPendingDelete
;
62 extern int g_openDialogs
;
63 extern wxWindowGTK
*g_delayedFocus
;
65 //-----------------------------------------------------------------------------
66 // "focus" from m_window
67 //-----------------------------------------------------------------------------
69 static gint
gtk_frame_focus_callback( GtkWidget
*widget
, GtkDirectionType
WXUNUSED(d
), wxWindow
*WXUNUSED(win
) )
72 wxapp_install_idle_handler();
74 // This disables GTK's tab traversal
75 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus" );
79 //-----------------------------------------------------------------------------
81 //-----------------------------------------------------------------------------
83 static void gtk_frame_size_callback( GtkWidget
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxTopLevelWindowGTK
*win
)
86 wxapp_install_idle_handler();
91 if ((win
->m_width
!= alloc
->width
) || (win
->m_height
!= alloc
->height
))
94 wxPrintf( "OnSize from " );
95 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
96 wxPrintf( win->GetClassInfo()->GetClassName() );
97 wxPrintf( " %d %d %d %d\n", (int)alloc->x,
100 (int)alloc->height );
103 win
->m_width
= alloc
->width
;
104 win
->m_height
= alloc
->height
;
105 win
->m_queuedFullRedraw
= TRUE
;
106 win
->GtkUpdateSize();
110 //-----------------------------------------------------------------------------
112 //-----------------------------------------------------------------------------
114 static gint
gtk_frame_delete_callback( GtkWidget
*WXUNUSED(widget
), GdkEvent
*WXUNUSED(event
), wxTopLevelWindowGTK
*win
)
117 wxapp_install_idle_handler();
119 if (win
->IsEnabled() &&
120 (g_openDialogs
== 0 || (win
->GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
) ||
128 //-----------------------------------------------------------------------------
130 //-----------------------------------------------------------------------------
133 gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*WXUNUSED(event
), wxTopLevelWindowGTK
*win
)
136 wxapp_install_idle_handler();
138 if (!win
->m_hasVMT
|| !win
->IsShown())
143 gdk_window_get_root_origin( win
->m_widget
->window
, &x
, &y
);
147 wxMoveEvent
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() );
148 mevent
.SetEventObject( win
);
149 win
->GetEventHandler()->ProcessEvent( mevent
);
154 //-----------------------------------------------------------------------------
155 // "realize" from m_widget
156 //-----------------------------------------------------------------------------
158 // we cannot MWM hints and icons before the widget has been realized,
159 // so we do this directly after realization
162 gtk_frame_realized_callback( GtkWidget
* WXUNUSED(widget
),
163 wxTopLevelWindowGTK
*win
)
166 wxapp_install_idle_handler();
168 // All this is for Motif Window Manager "hints" and is supposed to be
169 // recognized by other WM as well. Not tested.
170 gdk_window_set_decorations(win
->m_widget
->window
,
171 (GdkWMDecoration
)win
->m_gdkDecor
);
172 gdk_window_set_functions(win
->m_widget
->window
,
173 (GdkWMFunction
)win
->m_gdkFunc
);
175 // GTK's shrinking/growing policy
176 if ((win
->m_gdkFunc
& GDK_FUNC_RESIZE
) == 0)
177 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1);
179 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1);
182 wxIconBundle iconsOld
= win
->GetIcons();
183 if ( iconsOld
.GetIcon(-1).Ok() )
185 win
->SetIcon( wxNullIcon
);
186 win
->SetIcons( iconsOld
);
190 //-----------------------------------------------------------------------------
191 // "map_event" from m_widget
192 //-----------------------------------------------------------------------------
195 gtk_frame_map_callback( GtkWidget
* WXUNUSED(widget
),
196 GdkEvent
* WXUNUSED(event
),
197 wxTopLevelWindow
*win
)
199 win
->SetIconizeState(FALSE
);
202 //-----------------------------------------------------------------------------
203 // "unmap_event" from m_widget
204 //-----------------------------------------------------------------------------
207 gtk_frame_unmap_callback( GtkWidget
* WXUNUSED(widget
),
208 GdkEvent
* WXUNUSED(event
),
209 wxTopLevelWindow
*win
)
211 win
->SetIconizeState(TRUE
);
214 //-----------------------------------------------------------------------------
215 // "expose_event" of m_client
216 //-----------------------------------------------------------------------------
218 static int gtk_window_expose_callback( GtkWidget
*widget
, GdkEventExpose
*gdk_event
, wxWindow
*win
)
220 GtkPizza
*pizza
= GTK_PIZZA(widget
);
222 gtk_paint_flat_box (win
->m_widget
->style
,
223 pizza
->bin_window
, GTK_STATE_NORMAL
,
233 //-----------------------------------------------------------------------------
234 // "draw" of m_client
235 //-----------------------------------------------------------------------------
239 static void gtk_window_draw_callback( GtkWidget
*widget
, GdkRectangle
*rect
, wxWindow
*win
)
241 GtkPizza
*pizza
= GTK_PIZZA(widget
);
243 gtk_paint_flat_box (win
->m_widget
->style
,
244 pizza
->bin_window
, GTK_STATE_NORMAL
,
254 // ----------------------------------------------------------------------------
255 // wxTopLevelWindowGTK itself
256 // ----------------------------------------------------------------------------
258 //-----------------------------------------------------------------------------
259 // InsertChild for wxTopLevelWindowGTK
260 //-----------------------------------------------------------------------------
262 /* Callback for wxTopLevelWindowGTK. This very strange beast has to be used because
263 * C++ has no virtual methods in a constructor. We have to emulate a
264 * virtual function here as wxWindows requires different ways to insert
265 * a child in container classes. */
267 static void wxInsertChildInTopLevelWindow( wxTopLevelWindowGTK
* parent
, wxWindow
* child
)
269 wxASSERT( GTK_IS_WIDGET(child
->m_widget
) );
271 if (!parent
->m_insertInClientArea
)
273 // these are outside the client area
274 wxTopLevelWindowGTK
* frame
= (wxTopLevelWindowGTK
*) parent
;
275 gtk_pizza_put( GTK_PIZZA(frame
->m_mainWidget
),
276 GTK_WIDGET(child
->m_widget
),
284 // these are inside the client area
285 gtk_pizza_put( GTK_PIZZA(parent
->m_wxwindow
),
286 GTK_WIDGET(child
->m_widget
),
293 // resize on OnInternalIdle
294 parent
->GtkUpdateSize();
297 // ----------------------------------------------------------------------------
298 // wxTopLevelWindowGTK creation
299 // ----------------------------------------------------------------------------
301 void wxTopLevelWindowGTK::Init()
306 m_mainWidget
= (GtkWidget
*) NULL
;
307 m_insertInClientArea
= TRUE
;
308 m_isIconized
= FALSE
;
309 m_fsIsShowing
= FALSE
;
310 m_themeEnabled
= TRUE
;
311 m_gdkDecor
= m_gdkFunc
= 0;
315 bool wxTopLevelWindowGTK::Create( wxWindow
*parent
,
317 const wxString
& title
,
319 const wxSize
& sizeOrig
,
321 const wxString
&name
)
323 // always create a frame of some reasonable, even if arbitrary, size (at
324 // least for MSW compatibility)
325 wxSize size
= sizeOrig
;
326 if ( size
.x
== -1 || size
.y
== -1 )
328 wxSize sizeDpy
= wxGetDisplaySize();
330 size
.x
= sizeDpy
.x
/ 3;
332 size
.y
= sizeDpy
.y
/ 5;
335 wxTopLevelWindows
.Append( this );
337 m_needParent
= FALSE
;
339 if (!PreCreation( parent
, pos
, size
) ||
340 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
342 wxFAIL_MSG( wxT("wxTopLevelWindowGTK creation failed") );
348 m_insertCallback
= (wxInsertChildFunction
) wxInsertChildInTopLevelWindow
;
350 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
352 if (style
& wxFRAME_TOOL_WINDOW
)
353 win_type
= GTK_WINDOW_POPUP
;
355 if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
)
357 // there is no more GTK_WINDOW_DIALOG in 2.0
359 win_type
= GTK_WINDOW_TOPLEVEL
;
361 win_type
= GTK_WINDOW_DIALOG
;
365 m_widget
= gtk_window_new( win_type
);
367 if (m_parent
&& (((GTK_IS_WINDOW(m_parent
->m_widget
)) &&
368 (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
)) ||
369 (style
& wxFRAME_FLOAT_ON_PARENT
)))
371 gtk_window_set_transient_for( GTK_WINDOW(m_widget
), GTK_WINDOW(m_parent
->m_widget
) );
375 gtk_window_set_wmclass( GTK_WINDOW(m_widget
), wxGTK_CONV( name
), wxGTK_CONV( name
) );
377 gtk_window_set_title( GTK_WINDOW(m_widget
), wxGTK_CONV( title
) );
378 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
380 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
381 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
383 // m_mainWidget holds the toolbar, the menubar and the client area
384 m_mainWidget
= gtk_pizza_new();
385 gtk_widget_show( m_mainWidget
);
386 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
387 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
389 if (m_miniEdge
== 0) // wxMiniFrame has its own version.
391 // For m_mainWidget themes
392 gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "expose_event",
393 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
395 gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "draw",
396 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
400 // m_wxwindow only represents the client area without toolbar and menubar
401 m_wxwindow
= gtk_pizza_new();
402 gtk_widget_show( m_wxwindow
);
403 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
405 // we donm't allow the frame to get the focus as otherwise
406 // the frame will grab it at arbitrary focus changes
407 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
409 if (m_parent
) m_parent
->AddChild( this );
411 // the user resized the frame by dragging etc.
412 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
413 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
417 if ((m_x
!= -1) || (m_y
!= -1))
418 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
420 gtk_window_set_default_size( GTK_WINDOW(m_widget
), m_width
, m_height
);
422 // we cannot set MWM hints and icons before the widget has
423 // been realized, so we do this directly after realization
424 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
425 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
427 // the only way to get the window size is to connect to this event
428 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
429 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
431 // map and unmap for iconized state
432 gtk_signal_connect( GTK_OBJECT(m_widget
), "map_event",
433 GTK_SIGNAL_FUNC(gtk_frame_map_callback
), (gpointer
)this );
434 gtk_signal_connect( GTK_OBJECT(m_widget
), "unmap_event",
435 GTK_SIGNAL_FUNC(gtk_frame_unmap_callback
), (gpointer
)this );
437 // the only way to get the window size is to connect to this event
438 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
439 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
441 // disable native tab traversal
442 gtk_signal_connect( GTK_OBJECT(m_widget
), "focus",
443 GTK_SIGNAL_FUNC(gtk_frame_focus_callback
), (gpointer
)this );
446 if ((m_miniEdge
> 0) || (style
& wxSIMPLE_BORDER
) || (style
& wxNO_BORDER
))
453 m_gdkDecor
= (long) GDK_DECOR_BORDER
;
454 m_gdkFunc
= (long) GDK_FUNC_MOVE
;
456 // All this is for Motif Window Manager "hints" and is supposed to be
457 // recognized by other WMs as well.
458 if ((style
& wxCAPTION
) != 0)
460 m_gdkDecor
|= GDK_DECOR_TITLE
;
462 if ((style
& wxCLOSE_BOX
) != 0)
464 m_gdkFunc
|= GDK_FUNC_CLOSE
;
466 if ((style
& wxSYSTEM_MENU
) != 0)
468 m_gdkDecor
|= GDK_DECOR_MENU
;
470 if ((style
& wxMINIMIZE_BOX
) != 0)
472 m_gdkFunc
|= GDK_FUNC_MINIMIZE
;
473 m_gdkDecor
|= GDK_DECOR_MINIMIZE
;
475 if ((style
& wxMAXIMIZE_BOX
) != 0)
477 m_gdkFunc
|= GDK_FUNC_MAXIMIZE
;
478 m_gdkDecor
|= GDK_DECOR_MAXIMIZE
;
480 if ((style
& wxRESIZE_BORDER
) != 0)
482 m_gdkFunc
|= GDK_FUNC_RESIZE
;
483 m_gdkDecor
|= GDK_DECOR_RESIZEH
;
490 wxTopLevelWindowGTK::~wxTopLevelWindowGTK()
494 wxASSERT_MSG( FALSE
, _T("Window still grabbed"));
498 m_isBeingDeleted
= TRUE
;
500 // it may also be GtkScrolledWindow in the case of an MDI child
501 if (GTK_IS_WINDOW(m_widget
))
503 gtk_window_set_focus( GTK_WINDOW(m_widget
), NULL
);
509 bool wxTopLevelWindowGTK::ShowFullScreen(bool show
, long style
)
511 if (show
== m_fsIsShowing
) return FALSE
; // return what?
513 m_fsIsShowing
= show
;
515 GdkWindow
*window
= m_widget
->window
;
516 wxX11FullScreenMethod method
=
517 wxGetFullScreenMethodX11((WXDisplay
*)GDK_DISPLAY(),
518 (WXWindow
)GDK_ROOT_WINDOW());
522 m_fsSaveFlag
= style
;
523 GetPosition( &m_fsSaveFrame
.x
, &m_fsSaveFrame
.y
);
524 GetSize( &m_fsSaveFrame
.width
, &m_fsSaveFrame
.height
);
526 int screen_width
,screen_height
;
527 wxDisplaySize( &screen_width
, &screen_height
);
529 gint client_x
, client_y
, root_x
, root_y
;
532 if (method
!= wxX11_FS_WMSPEC
)
534 // don't do it always, Metacity hates it
535 m_fsSaveGdkFunc
= m_gdkFunc
;
536 m_fsSaveGdkDecor
= m_gdkDecor
;
537 m_gdkFunc
= m_gdkDecor
= 0;
538 gdk_window_set_decorations(window
, (GdkWMDecoration
)0);
539 gdk_window_set_functions(window
, (GdkWMFunction
)0);
542 gdk_window_get_origin (m_widget
->window
, &root_x
, &root_y
);
543 gdk_window_get_geometry (m_widget
->window
, &client_x
, &client_y
,
544 &width
, &height
, NULL
);
546 gdk_window_move_resize (m_widget
->window
, -client_x
, -client_y
,
547 screen_width
+ 1, screen_height
+ 1);
549 wxSetFullScreenStateX11((WXDisplay
*)GDK_DISPLAY(),
550 (WXWindow
)GDK_ROOT_WINDOW(),
551 (WXWindow
)GDK_WINDOW_XWINDOW(window
),
552 show
, &m_fsSaveFrame
, method
);
556 if (method
!= wxX11_FS_WMSPEC
)
558 // don't do it always, Metacity hates it
559 m_gdkFunc
= m_fsSaveGdkFunc
;
560 m_gdkDecor
= m_fsSaveGdkDecor
;
561 gdk_window_set_decorations(window
, (GdkWMDecoration
)m_gdkDecor
);
562 gdk_window_set_functions(window
, (GdkWMFunction
)m_gdkFunc
);
565 wxSetFullScreenStateX11((WXDisplay
*)GDK_DISPLAY(),
566 (WXWindow
)GDK_ROOT_WINDOW(),
567 (WXWindow
)GDK_WINDOW_XWINDOW(window
),
568 show
, &m_fsSaveFrame
, method
);
570 SetSize(m_fsSaveFrame
.x
, m_fsSaveFrame
.y
,
571 m_fsSaveFrame
.width
, m_fsSaveFrame
.height
);
578 // ----------------------------------------------------------------------------
579 // overridden wxWindow methods
580 // ----------------------------------------------------------------------------
582 bool wxTopLevelWindowGTK::Show( bool show
)
584 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
586 if (show
&& !m_sizeSet
)
588 /* by calling GtkOnSize here, we don't have to call
589 either after showing the frame, which would entail
590 much ugly flicker or from within the size_allocate
591 handler, because GTK 1.1.X forbids that. */
593 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
596 return wxWindow::Show( show
);
599 void wxTopLevelWindowGTK::DoMoveWindow(int WXUNUSED(x
), int WXUNUSED(y
), int WXUNUSED(width
), int WXUNUSED(height
) )
601 wxFAIL_MSG( wxT("DoMoveWindow called for wxTopLevelWindowGTK") );
604 void wxTopLevelWindowGTK::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
606 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
608 // this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow
609 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
619 int old_width
= m_width
;
620 int old_height
= m_height
;
622 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
624 if (x
!= -1) m_x
= x
;
625 if (y
!= -1) m_y
= y
;
632 if (width
!= -1) m_width
= width
;
633 if (height
!= -1) m_height
= height
;
636 if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
638 if (width == -1) m_width = 80;
641 if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
643 if (height == -1) m_height = 26;
647 int minWidth
= GetMinWidth(),
648 minHeight
= GetMinHeight(),
649 maxWidth
= GetMaxWidth(),
650 maxHeight
= GetMaxHeight();
652 if ((minWidth
!= -1) && (m_width
< minWidth
)) m_width
= minWidth
;
653 if ((minHeight
!= -1) && (m_height
< minHeight
)) m_height
= minHeight
;
654 if ((maxWidth
!= -1) && (m_width
> maxWidth
)) m_width
= maxWidth
;
655 if ((maxHeight
!= -1) && (m_height
> maxHeight
)) m_height
= maxHeight
;
657 if ((m_x
!= -1) || (m_y
!= -1))
659 if ((m_x
!= old_x
) || (m_y
!= old_y
))
661 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
665 if ((m_width
!= old_width
) || (m_height
!= old_height
))
667 if (m_widget
->window
)
668 gdk_window_resize( m_widget
->window
, m_width
, m_height
);
670 gtk_window_set_default_size( GTK_WINDOW(m_widget
), m_width
, m_height
);
672 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
673 done either directly before the frame is shown or in idle time
674 so that different calls to SetSize() don't lead to flicker. */
681 void wxTopLevelWindowGTK::DoGetClientSize( int *width
, int *height
) const
683 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
685 wxWindow::DoGetClientSize( width
, height
);
689 *height
-= m_miniEdge
*2 + m_miniTitle
;
693 *width
-= m_miniEdge
*2;
697 void wxTopLevelWindowGTK::DoSetClientSize( int width
, int height
)
699 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
702 width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
, 0);
705 void wxTopLevelWindowGTK::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
),
706 int width
, int height
)
708 // due to a bug in gtk, x,y are always 0
713 if (m_resizing
) return;
716 if ( m_wxwindow
== NULL
) return;
721 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
722 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
723 set in wxFrame::Create so it is used to check what kind of frame we
724 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
725 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
726 importantly) m_mainWidget */
728 int minWidth
= GetMinWidth(),
729 minHeight
= GetMinHeight(),
730 maxWidth
= GetMaxWidth(),
731 maxHeight
= GetMaxHeight();
733 if ((minWidth
!= -1) && (m_width
< minWidth
)) m_width
= minWidth
;
734 if ((minHeight
!= -1) && (m_height
< minHeight
)) m_height
= minHeight
;
735 if ((maxWidth
!= -1) && (m_width
> maxWidth
)) m_width
= maxWidth
;
736 if ((maxHeight
!= -1) && (m_height
> maxHeight
)) m_height
= maxHeight
;
741 gint flag
= 0; // GDK_HINT_POS;
744 if ((minWidth
!= -1) || (minHeight
!= -1)) flag
|= GDK_HINT_MIN_SIZE
;
745 if ((maxWidth
!= -1) || (maxHeight
!= -1)) flag
|= GDK_HINT_MAX_SIZE
;
747 geom
.min_width
= minWidth
;
748 geom
.min_height
= minHeight
;
750 // Because of the way we set GDK_HINT_MAX_SIZE above, if either of
751 // maxHeight or maxWidth is set, we must set them both, else the
752 // remaining -1 will be taken literally.
754 // I'm certain this also happens elsewhere, and is the probable
755 // cause of other such things as:
756 // Gtk-WARNING **: gtk_widget_size_allocate():
757 // attempt to allocate widget with width 65535 and height 600
758 // but I don't have time to track them all now..
760 // Really we need to encapulate all this height/width business and
761 // stop any old method from ripping at the members directly and
762 // scattering -1's without regard for who might resolve them later.
764 geom
.max_width
= ( maxHeight
== -1 ) ? maxWidth
765 : ( maxWidth
== -1 ) ? wxGetDisplaySize().GetWidth()
768 geom
.max_height
= ( maxWidth
== -1 ) ? maxHeight
// ( == -1 here )
769 : ( maxHeight
== -1 ) ? wxGetDisplaySize().GetHeight()
772 gtk_window_set_geometry_hints( GTK_WINDOW(m_widget
),
775 (GdkWindowHints
) flag
);
777 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
778 * menubar, the toolbar and the client area, which is represented by
780 * this hurts in the eye, but I don't want to call SetSize()
781 * because I don't want to call any non-native functions here. */
783 int client_x
= m_miniEdge
;
784 int client_y
= m_miniEdge
+ m_miniTitle
;
785 int client_w
= m_width
- 2*m_miniEdge
;
786 int client_h
= m_height
- 2*m_miniEdge
- m_miniTitle
;
788 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
790 client_x
, client_y
, client_w
, client_h
);
794 // If there is no m_mainWidget between m_widget and m_wxwindow there
795 // is no need to set the size or position of m_wxwindow.
800 // send size event to frame
801 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
802 event
.SetEventObject( this );
803 GetEventHandler()->ProcessEvent( event
);
808 void wxTopLevelWindowGTK::OnInternalIdle()
810 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
812 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
814 // we'll come back later
816 wxapp_install_idle_handler();
820 // set the focus if not done yet and if we can already do it
821 if ( GTK_WIDGET_REALIZED(m_wxwindow
) )
823 if ( g_delayedFocus
&&
824 wxGetTopLevelParent((wxWindow
*)g_delayedFocus
) == this )
826 wxLogTrace(_T("focus"),
827 _T("Setting focus from wxTLW::OnIdle() to %s(%s)"),
828 g_delayedFocus
->GetClassInfo()->GetClassName(),
829 g_delayedFocus
->GetLabel().c_str());
831 g_delayedFocus
->SetFocus();
832 g_delayedFocus
= NULL
;
836 wxWindow::OnInternalIdle();
839 // ----------------------------------------------------------------------------
841 // ----------------------------------------------------------------------------
843 void wxTopLevelWindowGTK::SetTitle( const wxString
&title
)
845 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
848 gtk_window_set_title( GTK_WINDOW(m_widget
), wxGTK_CONV( title
) );
851 void wxTopLevelWindowGTK::DoSetIcon( const wxIcon
&icon
)
856 if (!m_widget
->window
)
859 wxMask
*mask
= icon
.GetMask();
860 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
861 if (mask
) bm
= mask
->GetBitmap();
863 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);
866 void wxTopLevelWindowGTK::SetIcon( const wxIcon
&icon
)
868 SetIcons( wxIconBundle( icon
) );
871 void wxTopLevelWindowGTK::SetIcons( const wxIconBundle
&icons
)
873 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
874 GdkWindow
* window
= m_widget
->window
;
876 wxTopLevelWindowBase::SetIcons( icons
);
878 DoSetIcon( icons
.GetIcon( -1 ) );
881 wxSetIconsX11( (WXDisplay
*)GDK_WINDOW_XDISPLAY( window
),
882 (WXWindow
)GDK_WINDOW_XWINDOW( window
), icons
);
886 // ----------------------------------------------------------------------------
887 // frame state: maximized/iconized/normal
888 // ----------------------------------------------------------------------------
890 void wxTopLevelWindowGTK::Maximize(bool maximize
)
894 gtk_window_maximize( GTK_WINDOW( m_widget
) );
896 gtk_window_unmaximize( GTK_WINDOW( m_widget
) );
898 wxFAIL_MSG( _T("not implemented") );
902 bool wxTopLevelWindowGTK::IsMaximized() const
904 // wxFAIL_MSG( _T("not implemented") );
906 // This is an approximation
910 void wxTopLevelWindowGTK::Restore()
913 // "Present" seems similar enough to "restore"
914 gtk_window_present( GTK_WINDOW( m_widget
) );
916 wxFAIL_MSG( _T("not implemented") );
920 void wxTopLevelWindowGTK::Iconize( bool iconize
)
924 gtk_window_iconify( GTK_WINDOW( m_widget
) );
926 gtk_window_deiconify( GTK_WINDOW( m_widget
) );
930 GdkWindow
*window
= m_widget
->window
;
932 // you should do it later, for example from OnCreate() handler
933 wxCHECK_RET( window
, _T("frame not created yet - can't iconize") );
935 XIconifyWindow( GDK_WINDOW_XDISPLAY( window
),
936 GDK_WINDOW_XWINDOW( window
),
937 DefaultScreen( GDK_DISPLAY() ) );
942 bool wxTopLevelWindowGTK::IsIconized() const
947 void wxTopLevelWindowGTK::SetIconizeState(bool iconize
)
949 if ( iconize
!= m_isIconized
)
951 m_isIconized
= iconize
;
952 (void)SendIconizeEvent(iconize
);
956 void wxTopLevelWindowGTK::AddGrab()
961 gtk_grab_add( m_widget
);
963 gtk_grab_remove( m_widget
);
967 void wxTopLevelWindowGTK::RemoveGrab()
978 static bool do_shape_combine_region(GdkWindow
* window
, const wxRegion
& region
)
982 if (region
.IsEmpty())
984 gdk_window_shape_combine_mask(window
, NULL
, 0, 0);
989 gdk_window_shape_combine_region(window
, region
.GetRegion(), 0, 0);
991 wxBitmap bmp
= region
.ConvertToBitmap();
992 bmp
.SetMask(new wxMask(bmp
, *wxBLACK
));
993 GdkBitmap
* mask
= bmp
.GetMask()->GetBitmap();
994 gdk_window_shape_combine_mask(window
, mask
, 0, 0);
1003 bool wxTopLevelWindowGTK::SetShape(const wxRegion
& region
)
1005 wxCHECK_MSG( HasFlag(wxFRAME_SHAPED
), FALSE
,
1006 _T("Shaped windows must be created with the wxFRAME_SHAPED style."));
1008 GdkWindow
*window
= NULL
;
1011 window
= GTK_PIZZA(m_wxwindow
)->bin_window
;
1012 do_shape_combine_region(window
, region
);
1014 window
= m_widget
->window
;
1015 return do_shape_combine_region(window
, region
);