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/msgdlg.h"
34 #include "wx/control.h"
36 #include "wx/dcclient.h"
37 #include "wx/gtk/private.h"
39 #include "wx/settings.h"
44 #include <gdk/gdkkeysyms.h>
47 #include "wx/gtk/win_gtk.h"
49 #include "wx/unix/utilsx11.h"
52 #include <X11/Xatom.h>
54 // ----------------------------------------------------------------------------
56 // ----------------------------------------------------------------------------
58 extern void wxapp_install_idle_handler();
61 // ----------------------------------------------------------------------------
63 // ----------------------------------------------------------------------------
65 extern wxList wxPendingDelete
;
67 extern int g_openDialogs
;
68 extern wxWindowGTK
*g_delayedFocus
;
70 //-----------------------------------------------------------------------------
71 // "focus" from m_window
72 //-----------------------------------------------------------------------------
74 static gint
gtk_frame_focus_callback( GtkWidget
*widget
, GtkDirectionType
WXUNUSED(d
), wxWindow
*WXUNUSED(win
) )
77 wxapp_install_idle_handler();
79 // This disables GTK's tab traversal
80 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus" );
84 //-----------------------------------------------------------------------------
86 //-----------------------------------------------------------------------------
88 static void gtk_frame_size_callback( GtkWidget
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxTopLevelWindowGTK
*win
)
91 wxapp_install_idle_handler();
96 if ((win
->m_width
!= alloc
->width
) || (win
->m_height
!= alloc
->height
))
99 wxPrintf( "OnSize from " );
100 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
101 wxPrintf( win->GetClassInfo()->GetClassName() );
102 wxPrintf( " %d %d %d %d\n", (int)alloc->x,
105 (int)alloc->height );
108 win
->m_width
= alloc
->width
;
109 win
->m_height
= alloc
->height
;
110 win
->m_queuedFullRedraw
= TRUE
;
111 win
->GtkUpdateSize();
115 //-----------------------------------------------------------------------------
117 //-----------------------------------------------------------------------------
119 static gint
gtk_frame_delete_callback( GtkWidget
*WXUNUSED(widget
), GdkEvent
*WXUNUSED(event
), wxTopLevelWindowGTK
*win
)
122 wxapp_install_idle_handler();
124 if (win
->IsEnabled() &&
125 (g_openDialogs
== 0 || (win
->GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
) ||
133 //-----------------------------------------------------------------------------
135 //-----------------------------------------------------------------------------
138 gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*WXUNUSED(event
), wxTopLevelWindowGTK
*win
)
141 wxapp_install_idle_handler();
143 if (!win
->m_hasVMT
|| !win
->IsShown())
148 gdk_window_get_root_origin( win
->m_widget
->window
, &x
, &y
);
152 wxMoveEvent
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() );
153 mevent
.SetEventObject( win
);
154 win
->GetEventHandler()->ProcessEvent( mevent
);
159 //-----------------------------------------------------------------------------
160 // "realize" from m_widget
161 //-----------------------------------------------------------------------------
163 // we cannot MWM hints and icons before the widget has been realized,
164 // so we do this directly after realization
167 gtk_frame_realized_callback( GtkWidget
* WXUNUSED(widget
),
168 wxTopLevelWindowGTK
*win
)
171 wxapp_install_idle_handler();
173 // All this is for Motif Window Manager "hints" and is supposed to be
174 // recognized by other WM as well. Not tested.
175 gdk_window_set_decorations(win
->m_widget
->window
,
176 (GdkWMDecoration
)win
->m_gdkDecor
);
177 gdk_window_set_functions(win
->m_widget
->window
,
178 (GdkWMFunction
)win
->m_gdkFunc
);
180 // GTK's shrinking/growing policy
181 if ((win
->m_gdkFunc
& GDK_FUNC_RESIZE
) == 0)
182 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1);
184 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1);
187 wxIconBundle iconsOld
= win
->GetIcons();
188 if ( iconsOld
.GetIcon(-1).Ok() )
190 win
->SetIcon( wxNullIcon
);
191 win
->SetIcons( iconsOld
);
195 //-----------------------------------------------------------------------------
196 // "map_event" from m_widget
197 //-----------------------------------------------------------------------------
200 gtk_frame_map_callback( GtkWidget
* WXUNUSED(widget
),
201 GdkEvent
* WXUNUSED(event
),
202 wxTopLevelWindow
*win
)
204 win
->SetIconizeState(FALSE
);
207 //-----------------------------------------------------------------------------
208 // "unmap_event" from m_widget
209 //-----------------------------------------------------------------------------
212 gtk_frame_unmap_callback( GtkWidget
* WXUNUSED(widget
),
213 GdkEvent
* WXUNUSED(event
),
214 wxTopLevelWindow
*win
)
216 win
->SetIconizeState(TRUE
);
219 //-----------------------------------------------------------------------------
220 // "expose_event" of m_client
221 //-----------------------------------------------------------------------------
223 static int gtk_window_expose_callback( GtkWidget
*widget
, GdkEventExpose
*gdk_event
, wxWindow
*win
)
225 GtkPizza
*pizza
= GTK_PIZZA(widget
);
227 gtk_paint_flat_box (win
->m_widget
->style
,
228 pizza
->bin_window
, GTK_STATE_NORMAL
,
238 //-----------------------------------------------------------------------------
239 // "draw" of m_client
240 //-----------------------------------------------------------------------------
244 static void gtk_window_draw_callback( GtkWidget
*widget
, GdkRectangle
*rect
, wxWindow
*win
)
246 GtkPizza
*pizza
= GTK_PIZZA(widget
);
248 gtk_paint_flat_box (win
->m_widget
->style
,
249 pizza
->bin_window
, GTK_STATE_NORMAL
,
259 // ----------------------------------------------------------------------------
260 // wxTopLevelWindowGTK itself
261 // ----------------------------------------------------------------------------
263 //-----------------------------------------------------------------------------
264 // InsertChild for wxTopLevelWindowGTK
265 //-----------------------------------------------------------------------------
267 /* Callback for wxTopLevelWindowGTK. This very strange beast has to be used because
268 * C++ has no virtual methods in a constructor. We have to emulate a
269 * virtual function here as wxWindows requires different ways to insert
270 * a child in container classes. */
272 static void wxInsertChildInTopLevelWindow( wxTopLevelWindowGTK
* parent
, wxWindow
* child
)
274 wxASSERT( GTK_IS_WIDGET(child
->m_widget
) );
276 if (!parent
->m_insertInClientArea
)
278 // these are outside the client area
279 wxTopLevelWindowGTK
* frame
= (wxTopLevelWindowGTK
*) parent
;
280 gtk_pizza_put( GTK_PIZZA(frame
->m_mainWidget
),
281 GTK_WIDGET(child
->m_widget
),
289 // these are inside the client area
290 gtk_pizza_put( GTK_PIZZA(parent
->m_wxwindow
),
291 GTK_WIDGET(child
->m_widget
),
298 // resize on OnInternalIdle
299 parent
->GtkUpdateSize();
302 // ----------------------------------------------------------------------------
303 // wxTopLevelWindowGTK creation
304 // ----------------------------------------------------------------------------
306 void wxTopLevelWindowGTK::Init()
311 m_mainWidget
= (GtkWidget
*) NULL
;
312 m_insertInClientArea
= TRUE
;
313 m_isIconized
= FALSE
;
314 m_fsIsShowing
= FALSE
;
315 m_themeEnabled
= TRUE
;
316 m_gdkDecor
= m_gdkFunc
= 0;
320 bool wxTopLevelWindowGTK::Create( wxWindow
*parent
,
322 const wxString
& title
,
324 const wxSize
& sizeOrig
,
326 const wxString
&name
)
328 // always create a frame of some reasonable, even if arbitrary, size (at
329 // least for MSW compatibility)
330 wxSize size
= sizeOrig
;
331 size
.x
= WidthDefault(size
.x
);
332 size
.y
= HeightDefault(size
.y
);
334 wxTopLevelWindows
.Append( this );
336 m_needParent
= FALSE
;
338 if (!PreCreation( parent
, pos
, size
) ||
339 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
341 wxFAIL_MSG( wxT("wxTopLevelWindowGTK creation failed") );
347 m_insertCallback
= (wxInsertChildFunction
) wxInsertChildInTopLevelWindow
;
349 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
351 if (style
& wxFRAME_TOOL_WINDOW
)
352 win_type
= GTK_WINDOW_POPUP
;
354 if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
)
356 // there is no more GTK_WINDOW_DIALOG in 2.0
358 win_type
= GTK_WINDOW_TOPLEVEL
;
360 win_type
= GTK_WINDOW_DIALOG
;
364 m_widget
= gtk_window_new( win_type
);
366 if (m_parent
&& (((GTK_IS_WINDOW(m_parent
->m_widget
)) &&
367 (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
)) ||
368 (style
& wxFRAME_FLOAT_ON_PARENT
)))
370 gtk_window_set_transient_for( GTK_WINDOW(m_widget
), GTK_WINDOW(m_parent
->m_widget
) );
374 gtk_window_set_wmclass( GTK_WINDOW(m_widget
), wxGTK_CONV( name
), wxGTK_CONV( name
) );
376 gtk_window_set_title( GTK_WINDOW(m_widget
), wxGTK_CONV( title
) );
377 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
379 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
380 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
382 // m_mainWidget holds the toolbar, the menubar and the client area
383 m_mainWidget
= gtk_pizza_new();
384 gtk_widget_show( m_mainWidget
);
385 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
386 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
388 if (m_miniEdge
== 0) // wxMiniFrame has its own version.
390 // For m_mainWidget themes
391 gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "expose_event",
392 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
394 gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "draw",
395 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
399 // m_wxwindow only represents the client area without toolbar and menubar
400 m_wxwindow
= gtk_pizza_new();
401 gtk_widget_show( m_wxwindow
);
402 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
404 // we donm't allow the frame to get the focus as otherwise
405 // the frame will grab it at arbitrary focus changes
406 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
408 if (m_parent
) m_parent
->AddChild( this );
410 // the user resized the frame by dragging etc.
411 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
412 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
416 if ((m_x
!= -1) || (m_y
!= -1))
417 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
419 gtk_window_set_default_size( GTK_WINDOW(m_widget
), m_width
, m_height
);
421 // we cannot set MWM hints and icons before the widget has
422 // been realized, so we do this directly after realization
423 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
424 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
426 // the only way to get the window size is to connect to this event
427 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
428 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
430 // map and unmap for iconized state
431 gtk_signal_connect( GTK_OBJECT(m_widget
), "map_event",
432 GTK_SIGNAL_FUNC(gtk_frame_map_callback
), (gpointer
)this );
433 gtk_signal_connect( GTK_OBJECT(m_widget
), "unmap_event",
434 GTK_SIGNAL_FUNC(gtk_frame_unmap_callback
), (gpointer
)this );
436 // the only way to get the window size is to connect to this event
437 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
438 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
440 // disable native tab traversal
441 gtk_signal_connect( GTK_OBJECT(m_widget
), "focus",
442 GTK_SIGNAL_FUNC(gtk_frame_focus_callback
), (gpointer
)this );
445 if ((m_miniEdge
> 0) || (style
& wxSIMPLE_BORDER
) || (style
& wxNO_BORDER
))
452 m_gdkDecor
= (long) GDK_DECOR_BORDER
;
453 m_gdkFunc
= (long) GDK_FUNC_MOVE
;
455 // All this is for Motif Window Manager "hints" and is supposed to be
456 // recognized by other WMs as well.
457 if ((style
& wxCAPTION
) != 0)
459 m_gdkDecor
|= GDK_DECOR_TITLE
;
461 if ((style
& wxCLOSE_BOX
) != 0)
463 m_gdkFunc
|= GDK_FUNC_CLOSE
;
465 if ((style
& wxSYSTEM_MENU
) != 0)
467 m_gdkDecor
|= GDK_DECOR_MENU
;
469 if ((style
& wxMINIMIZE_BOX
) != 0)
471 m_gdkFunc
|= GDK_FUNC_MINIMIZE
;
472 m_gdkDecor
|= GDK_DECOR_MINIMIZE
;
474 if ((style
& wxMAXIMIZE_BOX
) != 0)
476 m_gdkFunc
|= GDK_FUNC_MAXIMIZE
;
477 m_gdkDecor
|= GDK_DECOR_MAXIMIZE
;
479 if ((style
& wxRESIZE_BORDER
) != 0)
481 m_gdkFunc
|= GDK_FUNC_RESIZE
;
482 m_gdkDecor
|= GDK_DECOR_RESIZEH
;
489 wxTopLevelWindowGTK::~wxTopLevelWindowGTK()
493 wxASSERT_MSG( FALSE
, _T("Window still grabbed"));
497 m_isBeingDeleted
= TRUE
;
499 // it may also be GtkScrolledWindow in the case of an MDI child
500 if (GTK_IS_WINDOW(m_widget
))
502 gtk_window_set_focus( GTK_WINDOW(m_widget
), NULL
);
508 bool wxTopLevelWindowGTK::ShowFullScreen(bool show
, long style
)
510 if (show
== m_fsIsShowing
) return FALSE
; // return what?
512 m_fsIsShowing
= show
;
514 GdkWindow
*window
= m_widget
->window
;
515 wxX11FullScreenMethod method
=
516 wxGetFullScreenMethodX11((WXDisplay
*)GDK_DISPLAY(),
517 (WXWindow
)GDK_ROOT_WINDOW());
521 m_fsSaveFlag
= style
;
522 GetPosition( &m_fsSaveFrame
.x
, &m_fsSaveFrame
.y
);
523 GetSize( &m_fsSaveFrame
.width
, &m_fsSaveFrame
.height
);
525 int screen_width
,screen_height
;
526 wxDisplaySize( &screen_width
, &screen_height
);
528 gint client_x
, client_y
, root_x
, root_y
;
531 if (method
!= wxX11_FS_WMSPEC
)
533 // don't do it always, Metacity hates it
534 m_fsSaveGdkFunc
= m_gdkFunc
;
535 m_fsSaveGdkDecor
= m_gdkDecor
;
536 m_gdkFunc
= m_gdkDecor
= 0;
537 gdk_window_set_decorations(window
, (GdkWMDecoration
)0);
538 gdk_window_set_functions(window
, (GdkWMFunction
)0);
541 gdk_window_get_origin (m_widget
->window
, &root_x
, &root_y
);
542 gdk_window_get_geometry (m_widget
->window
, &client_x
, &client_y
,
543 &width
, &height
, NULL
);
545 gdk_window_move_resize (m_widget
->window
, -client_x
, -client_y
,
546 screen_width
+ 1, screen_height
+ 1);
548 wxSetFullScreenStateX11((WXDisplay
*)GDK_DISPLAY(),
549 (WXWindow
)GDK_ROOT_WINDOW(),
550 (WXWindow
)GDK_WINDOW_XWINDOW(window
),
551 show
, &m_fsSaveFrame
, method
);
555 if (method
!= wxX11_FS_WMSPEC
)
557 // don't do it always, Metacity hates it
558 m_gdkFunc
= m_fsSaveGdkFunc
;
559 m_gdkDecor
= m_fsSaveGdkDecor
;
560 gdk_window_set_decorations(window
, (GdkWMDecoration
)m_gdkDecor
);
561 gdk_window_set_functions(window
, (GdkWMFunction
)m_gdkFunc
);
564 wxSetFullScreenStateX11((WXDisplay
*)GDK_DISPLAY(),
565 (WXWindow
)GDK_ROOT_WINDOW(),
566 (WXWindow
)GDK_WINDOW_XWINDOW(window
),
567 show
, &m_fsSaveFrame
, method
);
569 SetSize(m_fsSaveFrame
.x
, m_fsSaveFrame
.y
,
570 m_fsSaveFrame
.width
, m_fsSaveFrame
.height
);
577 // ----------------------------------------------------------------------------
578 // overridden wxWindow methods
579 // ----------------------------------------------------------------------------
581 bool wxTopLevelWindowGTK::Show( bool show
)
583 wxCHECK_VALID_WIDGET(FALSE
);
585 if (show
&& !m_sizeSet
)
587 /* by calling GtkOnSize here, we don't have to call
588 either after showing the frame, which would entail
589 much ugly flicker or from within the size_allocate
590 handler, because GTK 1.1.X forbids that. */
592 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
595 return wxWindow::Show( show
);
598 void wxTopLevelWindowGTK::DoMoveWindow(int WXUNUSED(x
), int WXUNUSED(y
), int WXUNUSED(width
), int WXUNUSED(height
) )
600 wxFAIL_MSG( wxT("DoMoveWindow called for wxTopLevelWindowGTK") );
603 void wxTopLevelWindowGTK::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
605 wxCHECK_VALID_WIDGET_RET();
607 // this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow
608 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
618 int old_width
= m_width
;
619 int old_height
= m_height
;
621 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
623 if (x
!= -1) m_x
= x
;
624 if (y
!= -1) m_y
= y
;
631 if (width
!= -1) m_width
= width
;
632 if (height
!= -1) m_height
= height
;
635 if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
637 if (width == -1) m_width = 80;
640 if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
642 if (height == -1) m_height = 26;
646 int minWidth
= GetMinWidth(),
647 minHeight
= GetMinHeight(),
648 maxWidth
= GetMaxWidth(),
649 maxHeight
= GetMaxHeight();
652 // GPE's window manager doesn't like size hints
653 // at all, esp. when the user has to use the
661 if ((minWidth
!= -1) && (m_width
< minWidth
)) m_width
= minWidth
;
662 if ((minHeight
!= -1) && (m_height
< minHeight
)) m_height
= minHeight
;
663 if ((maxWidth
!= -1) && (m_width
> maxWidth
)) m_width
= maxWidth
;
664 if ((maxHeight
!= -1) && (m_height
> maxHeight
)) m_height
= maxHeight
;
666 if ((m_x
!= -1) || (m_y
!= -1))
668 if ((m_x
!= old_x
) || (m_y
!= old_y
))
670 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
674 if ((m_width
!= old_width
) || (m_height
!= old_height
))
676 if (m_widget
->window
)
677 gdk_window_resize( m_widget
->window
, m_width
, m_height
);
679 gtk_window_set_default_size( GTK_WINDOW(m_widget
), m_width
, m_height
);
681 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
682 done either directly before the frame is shown or in idle time
683 so that different calls to SetSize() don't lead to flicker. */
690 void wxTopLevelWindowGTK::DoGetClientSize( int *width
, int *height
) const
692 wxCHECK_VALID_WIDGET_RET();
694 wxWindow::DoGetClientSize( width
, height
);
698 *height
-= m_miniEdge
*2 + m_miniTitle
;
702 *width
-= m_miniEdge
*2;
706 void wxTopLevelWindowGTK::DoSetClientSize( int width
, int height
)
708 wxCHECK_VALID_WIDGET_RET();
711 width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
, 0);
714 void wxTopLevelWindowGTK::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
),
715 int width
, int height
)
717 // due to a bug in gtk, x,y are always 0
722 if (m_resizing
) return;
725 if ( m_wxwindow
== NULL
) return;
730 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
731 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
732 set in wxFrame::Create so it is used to check what kind of frame we
733 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
734 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
735 importantly) m_mainWidget */
737 int minWidth
= GetMinWidth(),
738 minHeight
= GetMinHeight(),
739 maxWidth
= GetMaxWidth(),
740 maxHeight
= GetMaxHeight();
743 // GPE's window manager doesn't like size hints
744 // at all, esp. when the user has to use the
752 if ((minWidth
!= -1) && (m_width
< minWidth
)) m_width
= minWidth
;
753 if ((minHeight
!= -1) && (m_height
< minHeight
)) m_height
= minHeight
;
754 if ((maxWidth
!= -1) && (m_width
> maxWidth
)) m_width
= maxWidth
;
755 if ((maxHeight
!= -1) && (m_height
> maxHeight
)) m_height
= maxHeight
;
760 gint flag
= 0; // GDK_HINT_POS;
763 if ((minWidth
!= -1) || (minHeight
!= -1)) flag
|= GDK_HINT_MIN_SIZE
;
764 if ((maxWidth
!= -1) || (maxHeight
!= -1)) flag
|= GDK_HINT_MAX_SIZE
;
766 geom
.min_width
= minWidth
;
767 geom
.min_height
= minHeight
;
769 // Because of the way we set GDK_HINT_MAX_SIZE above, if either of
770 // maxHeight or maxWidth is set, we must set them both, else the
771 // remaining -1 will be taken literally.
773 // I'm certain this also happens elsewhere, and is the probable
774 // cause of other such things as:
775 // Gtk-WARNING **: gtk_widget_size_allocate():
776 // attempt to allocate widget with width 65535 and height 600
777 // but I don't have time to track them all now..
779 // Really we need to encapulate all this height/width business and
780 // stop any old method from ripping at the members directly and
781 // scattering -1's without regard for who might resolve them later.
783 geom
.max_width
= ( maxHeight
== -1 ) ? maxWidth
784 : ( maxWidth
== -1 ) ? wxGetDisplaySize().GetWidth()
787 geom
.max_height
= ( maxWidth
== -1 ) ? maxHeight
// ( == -1 here )
788 : ( maxHeight
== -1 ) ? wxGetDisplaySize().GetHeight()
791 gtk_window_set_geometry_hints( GTK_WINDOW(m_widget
),
794 (GdkWindowHints
) flag
);
796 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
797 * menubar, the toolbar and the client area, which is represented by
799 * this hurts in the eye, but I don't want to call SetSize()
800 * because I don't want to call any non-native functions here. */
802 int client_x
= m_miniEdge
;
803 int client_y
= m_miniEdge
+ m_miniTitle
;
804 int client_w
= m_width
- 2*m_miniEdge
;
805 int client_h
= m_height
- 2*m_miniEdge
- m_miniTitle
;
807 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
809 client_x
, client_y
, client_w
, client_h
);
813 // If there is no m_mainWidget between m_widget and m_wxwindow there
814 // is no need to set the size or position of m_wxwindow.
819 // send size event to frame
820 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
821 event
.SetEventObject( this );
822 GetEventHandler()->ProcessEvent( event
);
827 void wxTopLevelWindowGTK::OnInternalIdle()
829 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
831 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
833 // we'll come back later
835 wxapp_install_idle_handler();
839 // set the focus if not done yet and if we can already do it
840 if ( GTK_WIDGET_REALIZED(m_wxwindow
) )
842 if ( g_delayedFocus
&&
843 wxGetTopLevelParent((wxWindow
*)g_delayedFocus
) == this )
845 wxLogTrace(_T("focus"),
846 _T("Setting focus from wxTLW::OnIdle() to %s(%s)"),
847 g_delayedFocus
->GetClassInfo()->GetClassName(),
848 g_delayedFocus
->GetLabel().c_str());
850 g_delayedFocus
->SetFocus();
851 g_delayedFocus
= NULL
;
855 wxWindow::OnInternalIdle();
858 // ----------------------------------------------------------------------------
860 // ----------------------------------------------------------------------------
862 void wxTopLevelWindowGTK::SetTitle( const wxString
&title
)
864 wxCHECK_VALID_WIDGET_RET();
867 gtk_window_set_title( GTK_WINDOW(m_widget
), wxGTK_CONV( title
) );
870 void wxTopLevelWindowGTK::DoSetIcon( const wxIcon
&icon
)
875 if (!m_widget
->window
)
878 wxMask
*mask
= icon
.GetMask();
879 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
880 if (mask
) bm
= mask
->GetBitmap();
882 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);
885 void wxTopLevelWindowGTK::SetIcon( const wxIcon
&icon
)
887 SetIcons( wxIconBundle( icon
) );
890 void wxTopLevelWindowGTK::SetIcons( const wxIconBundle
&icons
)
892 wxCHECK_VALID_WIDGET_RET();
893 GdkWindow
* window
= m_widget
->window
;
895 wxTopLevelWindowBase::SetIcons( icons
);
897 DoSetIcon( icons
.GetIcon( -1 ) );
900 wxSetIconsX11( (WXDisplay
*)GDK_WINDOW_XDISPLAY( window
),
901 (WXWindow
)GDK_WINDOW_XWINDOW( window
), icons
);
905 // ----------------------------------------------------------------------------
906 // frame state: maximized/iconized/normal
907 // ----------------------------------------------------------------------------
909 void wxTopLevelWindowGTK::Maximize(bool maximize
)
913 gtk_window_maximize( GTK_WINDOW( m_widget
) );
915 gtk_window_unmaximize( GTK_WINDOW( m_widget
) );
917 wxFAIL_MSG( _T("not implemented") );
921 bool wxTopLevelWindowGTK::IsMaximized() const
923 // wxFAIL_MSG( _T("not implemented") );
925 // This is an approximation
929 void wxTopLevelWindowGTK::Restore()
932 // "Present" seems similar enough to "restore"
933 gtk_window_present( GTK_WINDOW( m_widget
) );
935 wxFAIL_MSG( _T("not implemented") );
939 void wxTopLevelWindowGTK::Iconize( bool iconize
)
943 gtk_window_iconify( GTK_WINDOW( m_widget
) );
945 gtk_window_deiconify( GTK_WINDOW( m_widget
) );
949 GdkWindow
*window
= m_widget
->window
;
951 // you should do it later, for example from OnCreate() handler
952 wxCHECK_RET( window
, _T("frame not created yet - can't iconize") );
954 XIconifyWindow( GDK_WINDOW_XDISPLAY( window
),
955 GDK_WINDOW_XWINDOW( window
),
956 DefaultScreen( GDK_DISPLAY() ) );
961 bool wxTopLevelWindowGTK::IsIconized() const
966 void wxTopLevelWindowGTK::SetIconizeState(bool iconize
)
968 if ( iconize
!= m_isIconized
)
970 m_isIconized
= iconize
;
971 (void)SendIconizeEvent(iconize
);
975 void wxTopLevelWindowGTK::AddGrab()
980 gtk_grab_add( m_widget
);
982 gtk_grab_remove( m_widget
);
986 void wxTopLevelWindowGTK::RemoveGrab()
997 static bool do_shape_combine_region(GdkWindow
* window
, const wxRegion
& region
)
1001 if (region
.IsEmpty())
1003 gdk_window_shape_combine_mask(window
, NULL
, 0, 0);
1008 gdk_window_shape_combine_region(window
, region
.GetRegion(), 0, 0);
1010 wxBitmap bmp
= region
.ConvertToBitmap();
1011 bmp
.SetMask(new wxMask(bmp
, *wxBLACK
));
1012 GdkBitmap
* mask
= bmp
.GetMask()->GetBitmap();
1013 gdk_window_shape_combine_mask(window
, mask
, 0, 0);
1022 bool wxTopLevelWindowGTK::SetShape(const wxRegion
& region
)
1024 wxCHECK_MSG( HasFlag(wxFRAME_SHAPED
), FALSE
,
1025 _T("Shaped windows must be created with the wxFRAME_SHAPED style."));
1027 GdkWindow
*window
= NULL
;
1030 window
= GTK_PIZZA(m_wxwindow
)->bin_window
;
1031 do_shape_combine_region(window
, region
);
1033 window
= m_widget
->window
;
1034 return do_shape_combine_region(window
, region
);