1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
10 // ============================================================================
12 // ============================================================================
14 // ----------------------------------------------------------------------------
16 // ----------------------------------------------------------------------------
19 #pragma implementation "toplevel.h"
23 #define XIconifyWindow XICONIFYWINDOW
28 #include "wx/dialog.h"
29 #include "wx/control.h"
31 #include "wx/dcclient.h"
32 #include "wx/gtk/private.h"
37 #include <gdk/gdkkeysyms.h>
40 #include "wx/gtk/win_gtk.h"
42 #include "wx/unix/utilsx11.h"
45 #include <X11/Xatom.h>
47 // ----------------------------------------------------------------------------
49 // ----------------------------------------------------------------------------
51 extern void wxapp_install_idle_handler();
54 // ----------------------------------------------------------------------------
56 // ----------------------------------------------------------------------------
58 extern wxList wxPendingDelete
;
60 extern int g_openDialogs
;
61 extern wxWindowGTK
*g_delayedFocus
;
63 //-----------------------------------------------------------------------------
64 // "focus" from m_window
65 //-----------------------------------------------------------------------------
67 static gint
gtk_frame_focus_callback( GtkWidget
*widget
, GtkDirectionType
WXUNUSED(d
), wxWindow
*WXUNUSED(win
) )
70 wxapp_install_idle_handler();
72 // This disables GTK's tab traversal
73 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus" );
77 //-----------------------------------------------------------------------------
79 //-----------------------------------------------------------------------------
81 static void gtk_frame_size_callback( GtkWidget
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxTopLevelWindowGTK
*win
)
84 wxapp_install_idle_handler();
89 if ((win
->m_width
!= alloc
->width
) || (win
->m_height
!= alloc
->height
))
92 wxPrintf( "OnSize from " );
93 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
94 wxPrintf( win->GetClassInfo()->GetClassName() );
95 wxPrintf( " %d %d %d %d\n", (int)alloc->x,
101 win
->m_width
= alloc
->width
;
102 win
->m_height
= alloc
->height
;
103 win
->m_queuedFullRedraw
= TRUE
;
104 win
->GtkUpdateSize();
108 //-----------------------------------------------------------------------------
110 //-----------------------------------------------------------------------------
112 static gint
gtk_frame_delete_callback( GtkWidget
*WXUNUSED(widget
), GdkEvent
*WXUNUSED(event
), wxTopLevelWindowGTK
*win
)
115 wxapp_install_idle_handler();
117 if (win
->IsEnabled() &&
118 (g_openDialogs
== 0 || (win
->GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
) ||
126 //-----------------------------------------------------------------------------
128 //-----------------------------------------------------------------------------
131 gtk_frame_configure_callback( GtkWidget
*WXUNUSED(widget
), GdkEventConfigure
*WXUNUSED(event
), wxTopLevelWindowGTK
*win
)
134 wxapp_install_idle_handler();
136 if (!win
->m_hasVMT
|| !win
->IsShown())
141 gdk_window_get_root_origin( win
->m_widget
->window
, &x
, &y
);
145 wxMoveEvent
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() );
146 mevent
.SetEventObject( win
);
147 win
->GetEventHandler()->ProcessEvent( mevent
);
152 //-----------------------------------------------------------------------------
153 // "realize" from m_widget
154 //-----------------------------------------------------------------------------
156 // we cannot MWM hints and icons before the widget has been realized,
157 // so we do this directly after realization
160 gtk_frame_realized_callback( GtkWidget
* WXUNUSED(widget
),
161 wxTopLevelWindowGTK
*win
)
164 wxapp_install_idle_handler();
166 // All this is for Motif Window Manager "hints" and is supposed to be
167 // recognized by other WM as well. Not tested.
168 gdk_window_set_decorations(win
->m_widget
->window
,
169 (GdkWMDecoration
)win
->m_gdkDecor
);
170 gdk_window_set_functions(win
->m_widget
->window
,
171 (GdkWMFunction
)win
->m_gdkFunc
);
173 // GTK's shrinking/growing policy
174 if ((win
->m_gdkFunc
& GDK_FUNC_RESIZE
) == 0)
175 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1);
177 gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1);
180 wxIconBundle iconsOld
= win
->GetIcons();
181 if ( iconsOld
.GetIcon(-1).Ok() )
183 win
->SetIcon( wxNullIcon
);
184 win
->SetIcons( iconsOld
);
188 //-----------------------------------------------------------------------------
189 // "map_event" from m_widget
190 //-----------------------------------------------------------------------------
193 gtk_frame_map_callback( GtkWidget
* WXUNUSED(widget
),
194 GdkEvent
* WXUNUSED(event
),
195 wxTopLevelWindow
*win
)
197 win
->SetIconizeState(FALSE
);
200 //-----------------------------------------------------------------------------
201 // "unmap_event" from m_widget
202 //-----------------------------------------------------------------------------
205 gtk_frame_unmap_callback( GtkWidget
* WXUNUSED(widget
),
206 GdkEvent
* WXUNUSED(event
),
207 wxTopLevelWindow
*win
)
209 win
->SetIconizeState(TRUE
);
212 //-----------------------------------------------------------------------------
213 // "expose_event" of m_client
214 //-----------------------------------------------------------------------------
216 static int gtk_window_expose_callback( GtkWidget
*widget
, GdkEventExpose
*gdk_event
, wxWindow
*win
)
218 GtkPizza
*pizza
= GTK_PIZZA(widget
);
220 gtk_paint_flat_box (win
->m_widget
->style
,
221 pizza
->bin_window
, GTK_STATE_NORMAL
,
231 //-----------------------------------------------------------------------------
232 // "draw" of m_client
233 //-----------------------------------------------------------------------------
237 static void gtk_window_draw_callback( GtkWidget
*widget
, GdkRectangle
*rect
, wxWindow
*win
)
239 GtkPizza
*pizza
= GTK_PIZZA(widget
);
241 gtk_paint_flat_box (win
->m_widget
->style
,
242 pizza
->bin_window
, GTK_STATE_NORMAL
,
252 // ----------------------------------------------------------------------------
253 // wxTopLevelWindowGTK itself
254 // ----------------------------------------------------------------------------
256 //-----------------------------------------------------------------------------
257 // InsertChild for wxTopLevelWindowGTK
258 //-----------------------------------------------------------------------------
260 /* Callback for wxTopLevelWindowGTK. This very strange beast has to be used because
261 * C++ has no virtual methods in a constructor. We have to emulate a
262 * virtual function here as wxWindows requires different ways to insert
263 * a child in container classes. */
265 static void wxInsertChildInTopLevelWindow( wxTopLevelWindowGTK
* parent
, wxWindow
* child
)
267 wxASSERT( GTK_IS_WIDGET(child
->m_widget
) );
269 if (!parent
->m_insertInClientArea
)
271 // these are outside the client area
272 wxTopLevelWindowGTK
* frame
= (wxTopLevelWindowGTK
*) parent
;
273 gtk_pizza_put( GTK_PIZZA(frame
->m_mainWidget
),
274 GTK_WIDGET(child
->m_widget
),
282 // these are inside the client area
283 gtk_pizza_put( GTK_PIZZA(parent
->m_wxwindow
),
284 GTK_WIDGET(child
->m_widget
),
291 // resize on OnInternalIdle
292 parent
->GtkUpdateSize();
295 // ----------------------------------------------------------------------------
296 // wxTopLevelWindowGTK creation
297 // ----------------------------------------------------------------------------
299 void wxTopLevelWindowGTK::Init()
304 m_mainWidget
= (GtkWidget
*) NULL
;
305 m_insertInClientArea
= TRUE
;
306 m_isIconized
= FALSE
;
307 m_fsIsShowing
= FALSE
;
308 m_themeEnabled
= TRUE
;
309 m_gdkDecor
= m_gdkFunc
= 0;
313 bool wxTopLevelWindowGTK::Create( wxWindow
*parent
,
315 const wxString
& title
,
317 const wxSize
& sizeOrig
,
319 const wxString
&name
)
321 // always create a frame of some reasonable, even if arbitrary, size (at
322 // least for MSW compatibility)
323 wxSize size
= sizeOrig
;
324 if ( size
.x
== -1 || size
.y
== -1 )
326 wxSize sizeDpy
= wxGetDisplaySize();
328 size
.x
= sizeDpy
.x
/ 3;
330 size
.y
= sizeDpy
.y
/ 5;
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 GtkWindowType win_type
= GTK_WINDOW_TOPLEVEL
;
350 if (style
& wxFRAME_TOOL_WINDOW
)
351 win_type
= GTK_WINDOW_POPUP
;
353 if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
)
355 // there is no more GTK_WINDOW_DIALOG in 2.0
357 win_type
= GTK_WINDOW_TOPLEVEL
;
359 win_type
= GTK_WINDOW_DIALOG
;
363 m_widget
= gtk_window_new( win_type
);
365 if (m_parent
&& (((GTK_IS_WINDOW(m_parent
->m_widget
)) &&
366 (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
)) ||
367 (style
& wxFRAME_FLOAT_ON_PARENT
)))
369 gtk_window_set_transient_for( GTK_WINDOW(m_widget
), GTK_WINDOW(m_parent
->m_widget
) );
373 gtk_window_set_wmclass( GTK_WINDOW(m_widget
), wxGTK_CONV( name
), wxGTK_CONV( name
) );
375 gtk_window_set_title( GTK_WINDOW(m_widget
), wxGTK_CONV( title
) );
376 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
378 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
379 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
381 // m_mainWidget holds the toolbar, the menubar and the client area
382 m_mainWidget
= gtk_pizza_new();
383 gtk_widget_show( m_mainWidget
);
384 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
385 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
387 // for m_mainWidget themes
388 gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "expose_event",
389 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
391 gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "draw",
392 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
395 // m_wxwindow only represents the client area without toolbar and menubar
396 m_wxwindow
= gtk_pizza_new();
397 gtk_widget_show( m_wxwindow
);
398 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
400 // we donm't allow the frame to get the focus as otherwise
401 // the frame will grab it at arbitrary focus changes
402 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
404 if (m_parent
) m_parent
->AddChild( this );
406 // the user resized the frame by dragging etc.
407 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
408 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
412 if ((m_x
!= -1) || (m_y
!= -1))
413 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
415 gtk_window_set_default_size( GTK_WINDOW(m_widget
), m_width
, m_height
);
417 // we cannot set MWM hints and icons before the widget has
418 // been realized, so we do this directly after realization
419 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
420 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
422 // the only way to get the window size is to connect to this event
423 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
424 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
426 // map and unmap for iconized state
427 gtk_signal_connect( GTK_OBJECT(m_widget
), "map_event",
428 GTK_SIGNAL_FUNC(gtk_frame_map_callback
), (gpointer
)this );
429 gtk_signal_connect( GTK_OBJECT(m_widget
), "unmap_event",
430 GTK_SIGNAL_FUNC(gtk_frame_unmap_callback
), (gpointer
)this );
432 // the only way to get the window size is to connect to this event
433 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
434 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
436 // disable native tab traversal
437 gtk_signal_connect( GTK_OBJECT(m_widget
), "focus",
438 GTK_SIGNAL_FUNC(gtk_frame_focus_callback
), (gpointer
)this );
441 if ((m_miniEdge
> 0) || (style
& wxSIMPLE_BORDER
) || (style
& wxNO_BORDER
))
448 m_gdkDecor
= (long) GDK_DECOR_BORDER
;
449 m_gdkFunc
= (long) GDK_FUNC_MOVE
;
451 // All this is for Motif Window Manager "hints" and is supposed to be
452 // recognized by other WMs as well.
453 if ((style
& wxCAPTION
) != 0)
454 m_gdkDecor
|= GDK_DECOR_TITLE
;
455 if ((style
& wxSYSTEM_MENU
) != 0)
457 m_gdkFunc
|= GDK_FUNC_CLOSE
;
458 m_gdkDecor
|= GDK_DECOR_MENU
;
460 if ((style
& wxMINIMIZE_BOX
) != 0)
462 m_gdkFunc
|= GDK_FUNC_MINIMIZE
;
463 m_gdkDecor
|= GDK_DECOR_MINIMIZE
;
465 if ((style
& wxMAXIMIZE_BOX
) != 0)
467 m_gdkFunc
|= GDK_FUNC_MAXIMIZE
;
468 m_gdkDecor
|= GDK_DECOR_MAXIMIZE
;
470 if ((style
& wxRESIZE_BORDER
) != 0)
472 m_gdkFunc
|= GDK_FUNC_RESIZE
;
473 m_gdkDecor
|= GDK_DECOR_RESIZEH
;
480 wxTopLevelWindowGTK::~wxTopLevelWindowGTK()
484 wxASSERT_MSG( FALSE
, _T("Window still grabbed"));
488 m_isBeingDeleted
= TRUE
;
490 // it may also be GtkScrolledWindow in the case of an MDI child
491 if (GTK_IS_WINDOW(m_widget
))
493 gtk_window_set_focus( GTK_WINDOW(m_widget
), NULL
);
498 // X11 ICCCM values for window layers
499 #define WIN_LAYER_NORMAL 4
500 #define WIN_LAYER_ABOVE_DOCK 10
502 // X11 window manager property name
503 #define XA_WIN_LAYER "_WIN_LAYER"
505 // X11 window manager property name atom
506 static Atom gs_XA_WIN_LAYER
= 0;
509 static void wx_win_hints_set_layer(GtkWidget
*window
, int layer
)
513 GdkWindowPrivate
*priv
;
516 prev_error
= gdk_error_warnings
;
517 gdk_error_warnings
= 0;
518 priv
= (GdkWindowPrivate
*)(GTK_WIDGET(window
)->window
);
520 if (GTK_WIDGET_MAPPED(window
))
522 xev
.type
= ClientMessage
;
523 xev
.xclient
.type
= ClientMessage
;
524 xev
.xclient
.window
= priv
->xwindow
;
525 xev
.xclient
.message_type
= gs_XA_WIN_LAYER
;
526 xev
.xclient
.format
= 32;
527 xev
.xclient
.data
.l
[0] = (long)layer
;
528 xev
.xclient
.data
.l
[1] = gdk_time_get();
530 XSendEvent(GDK_DISPLAY(), GDK_ROOT_WINDOW(), False
,
531 SubstructureNotifyMask
, (XEvent
*) &xev
);
538 XChangeProperty(GDK_DISPLAY(), priv
->xwindow
, gs_XA_WIN_LAYER
,
539 XA_CARDINAL
, 32, PropModeReplace
, (unsigned char *)data
, 1);
541 gdk_error_warnings
= prev_error
;
545 bool wxTopLevelWindowGTK::ShowFullScreen(bool show
, long style
)
547 if (show
== m_fsIsShowing
) return FALSE
; // return what?
549 if (gs_XA_WIN_LAYER
== 0)
551 // Initialose X11 Atom only once
552 gs_XA_WIN_LAYER
= XInternAtom( GDK_DISPLAY(), XA_WIN_LAYER
, False
);
555 m_fsIsShowing
= show
;
559 m_fsSaveGdkFunc
= m_gdkFunc
;
560 m_fsSaveGdkDecor
= m_gdkDecor
;
561 m_fsSaveFlag
= style
;
562 GetPosition( &m_fsSaveFrame
.x
, &m_fsSaveFrame
.y
);
563 GetSize( &m_fsSaveFrame
.width
, &m_fsSaveFrame
.height
);
565 int screen_width
,screen_height
;
566 wxDisplaySize( &screen_width
, &screen_height
);
568 gint client_x
, client_y
, root_x
, root_y
;
571 gdk_window_get_origin (m_widget
->window
, &root_x
, &root_y
);
572 gdk_window_get_geometry (m_widget
->window
, &client_x
, &client_y
,
573 &width
, &height
, NULL
);
575 wx_win_hints_set_layer( m_widget
, WIN_LAYER_ABOVE_DOCK
);
577 gdk_window_move_resize (m_widget
->window
, -client_x
, -client_y
,
578 screen_width
+ 1, screen_height
+ 1);
582 wx_win_hints_set_layer( m_widget
, WIN_LAYER_NORMAL
);
584 SetSize( m_fsSaveFrame
.x
, m_fsSaveFrame
.y
, m_fsSaveFrame
.width
, m_fsSaveFrame
.height
);
590 // ----------------------------------------------------------------------------
591 // overridden wxWindow methods
592 // ----------------------------------------------------------------------------
594 bool wxTopLevelWindowGTK::Show( bool show
)
596 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
598 if (show
&& !m_sizeSet
)
600 /* by calling GtkOnSize here, we don't have to call
601 either after showing the frame, which would entail
602 much ugly flicker or from within the size_allocate
603 handler, because GTK 1.1.X forbids that. */
605 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
608 return wxWindow::Show( show
);
611 void wxTopLevelWindowGTK::DoMoveWindow(int WXUNUSED(x
), int WXUNUSED(y
), int WXUNUSED(width
), int WXUNUSED(height
) )
613 wxFAIL_MSG( wxT("DoMoveWindow called for wxTopLevelWindowGTK") );
616 void wxTopLevelWindowGTK::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
618 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
620 // this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow
621 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
631 int old_width
= m_width
;
632 int old_height
= m_height
;
634 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
636 if (x
!= -1) m_x
= x
;
637 if (y
!= -1) m_y
= y
;
644 if (width
!= -1) m_width
= width
;
645 if (height
!= -1) m_height
= height
;
648 if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
650 if (width == -1) m_width = 80;
653 if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
655 if (height == -1) m_height = 26;
659 int minWidth
= GetMinWidth(),
660 minHeight
= GetMinHeight(),
661 maxWidth
= GetMaxWidth(),
662 maxHeight
= GetMaxHeight();
664 if ((minWidth
!= -1) && (m_width
< minWidth
)) m_width
= minWidth
;
665 if ((minHeight
!= -1) && (m_height
< minHeight
)) m_height
= minHeight
;
666 if ((maxWidth
!= -1) && (m_width
> maxWidth
)) m_width
= maxWidth
;
667 if ((maxHeight
!= -1) && (m_height
> maxHeight
)) m_height
= maxHeight
;
669 if ((m_x
!= -1) || (m_y
!= -1))
671 if ((m_x
!= old_x
) || (m_y
!= old_y
))
673 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
677 if ((m_width
!= old_width
) || (m_height
!= old_height
))
679 if (m_widget
->window
)
680 gdk_window_resize( m_widget
->window
, m_width
, m_height
);
682 gtk_window_set_default_size( GTK_WINDOW(m_widget
), m_width
, m_height
);
684 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
685 done either directly before the frame is shown or in idle time
686 so that different calls to SetSize() don't lead to flicker. */
693 void wxTopLevelWindowGTK::DoGetClientSize( int *width
, int *height
) const
695 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
697 wxWindow::DoGetClientSize( width
, height
);
701 *height
-= m_miniEdge
*2 + m_miniTitle
;
705 *width
-= m_miniEdge
*2;
709 void wxTopLevelWindowGTK::DoSetClientSize( int width
, int height
)
711 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
714 width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
, 0);
717 void wxTopLevelWindowGTK::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
),
718 int width
, int height
)
720 // due to a bug in gtk, x,y are always 0
725 if (m_resizing
) return;
728 if ( m_wxwindow
== NULL
) return;
733 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
734 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
735 set in wxFrame::Create so it is used to check what kind of frame we
736 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
737 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
738 importantly) m_mainWidget */
740 int minWidth
= GetMinWidth(),
741 minHeight
= GetMinHeight(),
742 maxWidth
= GetMaxWidth(),
743 maxHeight
= GetMaxHeight();
745 if ((minWidth
!= -1) && (m_width
< minWidth
)) m_width
= minWidth
;
746 if ((minHeight
!= -1) && (m_height
< minHeight
)) m_height
= minHeight
;
747 if ((maxWidth
!= -1) && (m_width
> maxWidth
)) m_width
= maxWidth
;
748 if ((maxHeight
!= -1) && (m_height
> maxHeight
)) m_height
= maxHeight
;
753 gint flag
= 0; // GDK_HINT_POS;
756 if ((minWidth
!= -1) || (minHeight
!= -1)) flag
|= GDK_HINT_MIN_SIZE
;
757 if ((maxWidth
!= -1) || (maxHeight
!= -1)) flag
|= GDK_HINT_MAX_SIZE
;
759 geom
.min_width
= minWidth
;
760 geom
.min_height
= minHeight
;
762 // Because of the way we set GDK_HINT_MAX_SIZE above, if either of
763 // maxHeight or maxWidth is set, we must set them both, else the
764 // remaining -1 will be taken literally.
766 // I'm certain this also happens elsewhere, and is the probable
767 // cause of other such things as:
768 // Gtk-WARNING **: gtk_widget_size_allocate():
769 // attempt to allocate widget with width 65535 and height 600
770 // but I don't have time to track them all now..
772 // Really we need to encapulate all this height/width business and
773 // stop any old method from ripping at the members directly and
774 // scattering -1's without regard for who might resolve them later.
776 geom
.max_width
= ( maxHeight
== -1 ) ? maxWidth
777 : ( maxWidth
== -1 ) ? wxGetDisplaySize().GetWidth()
780 geom
.max_height
= ( maxWidth
== -1 ) ? maxHeight
// ( == -1 here )
781 : ( maxHeight
== -1 ) ? wxGetDisplaySize().GetHeight()
784 gtk_window_set_geometry_hints( GTK_WINDOW(m_widget
),
787 (GdkWindowHints
) flag
);
789 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
790 * menubar, the toolbar and the client area, which is represented by
792 * this hurts in the eye, but I don't want to call SetSize()
793 * because I don't want to call any non-native functions here. */
795 int client_x
= m_miniEdge
;
796 int client_y
= m_miniEdge
+ m_miniTitle
;
797 int client_w
= m_width
- 2*m_miniEdge
;
798 int client_h
= m_height
- 2*m_miniEdge
- m_miniTitle
;
800 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
802 client_x
, client_y
, client_w
, client_h
);
806 // If there is no m_mainWidget between m_widget and m_wxwindow there
807 // is no need to set the size or position of m_wxwindow.
812 // send size event to frame
813 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
814 event
.SetEventObject( this );
815 GetEventHandler()->ProcessEvent( event
);
820 void wxTopLevelWindowGTK::OnInternalIdle()
822 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
824 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
826 // we'll come back later
828 wxapp_install_idle_handler();
832 // set the focus if not done yet and if we can already do it
833 if ( GTK_WIDGET_REALIZED(m_wxwindow
) )
835 if ( g_delayedFocus
&&
836 wxGetTopLevelParent((wxWindow
*)g_delayedFocus
) == this )
838 g_delayedFocus
->SetFocus();
839 g_delayedFocus
= NULL
;
843 wxWindow::OnInternalIdle();
846 // ----------------------------------------------------------------------------
848 // ----------------------------------------------------------------------------
850 void wxTopLevelWindowGTK::SetTitle( const wxString
&title
)
852 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
855 gtk_window_set_title( GTK_WINDOW(m_widget
), wxGTK_CONV( title
) );
858 void wxTopLevelWindowGTK::DoSetIcon( const wxIcon
&icon
)
863 if (!m_widget
->window
)
866 wxMask
*mask
= icon
.GetMask();
867 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
868 if (mask
) bm
= mask
->GetBitmap();
870 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);
873 void wxTopLevelWindowGTK::SetIcon( const wxIcon
&icon
)
875 SetIcons( wxIconBundle( icon
) );
878 void wxTopLevelWindowGTK::SetIcons( const wxIconBundle
&icons
)
880 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
881 GdkWindow
* window
= m_widget
->window
;
883 wxTopLevelWindowBase::SetIcons( icons
);
885 DoSetIcon( icons
.GetIcon( -1 ) );
888 wxSetIconsX11( (WXDisplay
*)GDK_WINDOW_XDISPLAY( window
),
889 (WXWindow
)GDK_WINDOW_XWINDOW( window
), icons
);
893 // ----------------------------------------------------------------------------
894 // frame state: maximized/iconized/normal
895 // ----------------------------------------------------------------------------
897 void wxTopLevelWindowGTK::Maximize(bool maximize
)
901 gtk_window_maximize( GTK_WINDOW( m_widget
) );
903 gtk_window_unmaximize( GTK_WINDOW( m_widget
) );
905 wxFAIL_MSG( _T("not implemented") );
909 bool wxTopLevelWindowGTK::IsMaximized() const
911 // wxFAIL_MSG( _T("not implemented") );
913 // This is an approximation
917 void wxTopLevelWindowGTK::Restore()
920 // "Present" seems similar enough to "restore"
921 gtk_window_present( GTK_WINDOW( m_widget
) );
923 wxFAIL_MSG( _T("not implemented") );
927 void wxTopLevelWindowGTK::Iconize( bool iconize
)
931 gtk_window_iconify( GTK_WINDOW( m_widget
) );
933 gtk_window_deiconify( GTK_WINDOW( m_widget
) );
937 GdkWindow
*window
= m_widget
->window
;
939 // you should do it later, for example from OnCreate() handler
940 wxCHECK_RET( window
, _T("frame not created yet - can't iconize") );
942 XIconifyWindow( GDK_WINDOW_XDISPLAY( window
),
943 GDK_WINDOW_XWINDOW( window
),
944 DefaultScreen( GDK_DISPLAY() ) );
949 bool wxTopLevelWindowGTK::IsIconized() const
954 void wxTopLevelWindowGTK::SetIconizeState(bool iconize
)
956 if ( iconize
!= m_isIconized
)
958 m_isIconized
= iconize
;
959 (void)SendIconizeEvent(iconize
);
963 void wxTopLevelWindowGTK::AddGrab()
968 gtk_grab_add( m_widget
);
970 gtk_grab_remove( m_widget
);
974 void wxTopLevelWindowGTK::RemoveGrab()