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
))
368 gtk_window_set_transient_for( GTK_WINDOW(m_widget
), GTK_WINDOW(m_parent
->m_widget
) );
372 gtk_window_set_wmclass( GTK_WINDOW(m_widget
), wxGTK_CONV( name
), wxGTK_CONV( name
) );
374 gtk_window_set_title( GTK_WINDOW(m_widget
), wxGTK_CONV( title
) );
375 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
377 gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event",
378 GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this );
380 // m_mainWidget holds the toolbar, the menubar and the client area
381 m_mainWidget
= gtk_pizza_new();
382 gtk_widget_show( m_mainWidget
);
383 GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS
);
384 gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget
);
386 // for m_mainWidget themes
387 gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "expose_event",
388 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
390 gtk_signal_connect( GTK_OBJECT(m_mainWidget
), "draw",
391 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
394 // m_wxwindow only represents the client area without toolbar and menubar
395 m_wxwindow
= gtk_pizza_new();
396 gtk_widget_show( m_wxwindow
);
397 gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow
);
399 // we donm't allow the frame to get the focus as otherwise
400 // the frame will grab it at arbitrary focus changes
401 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
403 if (m_parent
) m_parent
->AddChild( this );
405 // the user resized the frame by dragging etc.
406 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
407 GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this );
411 if ((m_x
!= -1) || (m_y
!= -1))
412 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
414 gtk_window_set_default_size( GTK_WINDOW(m_widget
), m_width
, m_height
);
416 // we cannot set MWM hints and icons before the widget has
417 // been realized, so we do this directly after realization
418 gtk_signal_connect( GTK_OBJECT(m_widget
), "realize",
419 GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this );
421 // the only way to get the window size is to connect to this event
422 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
423 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
425 // map and unmap for iconized state
426 gtk_signal_connect( GTK_OBJECT(m_widget
), "map_event",
427 GTK_SIGNAL_FUNC(gtk_frame_map_callback
), (gpointer
)this );
428 gtk_signal_connect( GTK_OBJECT(m_widget
), "unmap_event",
429 GTK_SIGNAL_FUNC(gtk_frame_unmap_callback
), (gpointer
)this );
431 // the only way to get the window size is to connect to this event
432 gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event",
433 GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this );
435 // disable native tab traversal
436 gtk_signal_connect( GTK_OBJECT(m_widget
), "focus",
437 GTK_SIGNAL_FUNC(gtk_frame_focus_callback
), (gpointer
)this );
440 if ((m_miniEdge
> 0) || (style
& wxSIMPLE_BORDER
) || (style
& wxNO_BORDER
))
447 m_gdkDecor
= (long) GDK_DECOR_BORDER
;
448 m_gdkFunc
= (long) GDK_FUNC_MOVE
;
450 // All this is for Motif Window Manager "hints" and is supposed to be
451 // recognized by other WMs as well.
452 if ((style
& wxCAPTION
) != 0)
453 m_gdkDecor
|= GDK_DECOR_TITLE
;
454 if ((style
& wxSYSTEM_MENU
) != 0)
456 m_gdkFunc
|= GDK_FUNC_CLOSE
;
457 m_gdkDecor
|= GDK_DECOR_MENU
;
459 if ((style
& wxMINIMIZE_BOX
) != 0)
461 m_gdkFunc
|= GDK_FUNC_MINIMIZE
;
462 m_gdkDecor
|= GDK_DECOR_MINIMIZE
;
464 if ((style
& wxMAXIMIZE_BOX
) != 0)
466 m_gdkFunc
|= GDK_FUNC_MAXIMIZE
;
467 m_gdkDecor
|= GDK_DECOR_MAXIMIZE
;
469 if ((style
& wxRESIZE_BORDER
) != 0)
471 m_gdkFunc
|= GDK_FUNC_RESIZE
;
472 m_gdkDecor
|= GDK_DECOR_RESIZEH
;
479 wxTopLevelWindowGTK::~wxTopLevelWindowGTK()
483 wxASSERT_MSG( FALSE
, "Window still grabbed");
487 m_isBeingDeleted
= TRUE
;
489 // it may also be GtkScrolledWindow in the case of an MDI child
490 if (GTK_IS_WINDOW(m_widget
))
492 gtk_window_set_focus( GTK_WINDOW(m_widget
), NULL
);
495 wxTopLevelWindows
.DeleteObject( this );
497 if (wxTheApp
->GetTopWindow() == this)
498 wxTheApp
->SetTopWindow( (wxWindow
*) NULL
);
500 if ((wxTopLevelWindows
.Number() == 0) &&
501 (wxTheApp
->GetExitOnFrameDelete()))
503 wxTheApp
->ExitMainLoop();
508 // X11 ICCCM values for window layers
509 #define WIN_LAYER_NORMAL 4
510 #define WIN_LAYER_ABOVE_DOCK 10
512 // X11 window manager property name
513 #define XA_WIN_LAYER "_WIN_LAYER"
515 // X11 window manager property name atom
516 static Atom gs_XA_WIN_LAYER
= 0;
519 static void wx_win_hints_set_layer(GtkWidget
*window
, int layer
)
523 GdkWindowPrivate
*priv
;
526 prev_error
= gdk_error_warnings
;
527 gdk_error_warnings
= 0;
528 priv
= (GdkWindowPrivate
*)(GTK_WIDGET(window
)->window
);
530 if (GTK_WIDGET_MAPPED(window
))
532 xev
.type
= ClientMessage
;
533 xev
.xclient
.type
= ClientMessage
;
534 xev
.xclient
.window
= priv
->xwindow
;
535 xev
.xclient
.message_type
= gs_XA_WIN_LAYER
;
536 xev
.xclient
.format
= 32;
537 xev
.xclient
.data
.l
[0] = (long)layer
;
538 xev
.xclient
.data
.l
[1] = gdk_time_get();
540 XSendEvent(GDK_DISPLAY(), GDK_ROOT_WINDOW(), False
,
541 SubstructureNotifyMask
, (XEvent
*) &xev
);
548 XChangeProperty(GDK_DISPLAY(), priv
->xwindow
, gs_XA_WIN_LAYER
,
549 XA_CARDINAL
, 32, PropModeReplace
, (unsigned char *)data
, 1);
551 gdk_error_warnings
= prev_error
;
555 bool wxTopLevelWindowGTK::ShowFullScreen(bool show
, long style
)
557 if (show
== m_fsIsShowing
) return FALSE
; // return what?
559 if (gs_XA_WIN_LAYER
== 0)
561 // Initialose X11 Atom only once
562 gs_XA_WIN_LAYER
= XInternAtom( GDK_DISPLAY(), XA_WIN_LAYER
, False
);
565 m_fsIsShowing
= show
;
569 m_fsSaveGdkFunc
= m_gdkFunc
;
570 m_fsSaveGdkDecor
= m_gdkDecor
;
571 m_fsSaveFlag
= style
;
572 GetPosition( &m_fsSaveFrame
.x
, &m_fsSaveFrame
.y
);
573 GetSize( &m_fsSaveFrame
.width
, &m_fsSaveFrame
.height
);
575 int screen_width
,screen_height
;
576 wxDisplaySize( &screen_width
, &screen_height
);
578 gint client_x
, client_y
, root_x
, root_y
;
581 gdk_window_get_origin (m_widget
->window
, &root_x
, &root_y
);
582 gdk_window_get_geometry (m_widget
->window
, &client_x
, &client_y
,
583 &width
, &height
, NULL
);
585 wx_win_hints_set_layer( m_widget
, WIN_LAYER_ABOVE_DOCK
);
587 gdk_window_move_resize (m_widget
->window
, -client_x
, -client_y
,
588 screen_width
+ 1, screen_height
+ 1);
592 wx_win_hints_set_layer( m_widget
, WIN_LAYER_NORMAL
);
594 SetSize( m_fsSaveFrame
.x
, m_fsSaveFrame
.y
, m_fsSaveFrame
.width
, m_fsSaveFrame
.height
);
600 // ----------------------------------------------------------------------------
601 // overridden wxWindow methods
602 // ----------------------------------------------------------------------------
604 bool wxTopLevelWindowGTK::Show( bool show
)
606 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
608 if (show
&& !m_sizeSet
)
610 /* by calling GtkOnSize here, we don't have to call
611 either after showing the frame, which would entail
612 much ugly flicker or from within the size_allocate
613 handler, because GTK 1.1.X forbids that. */
615 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
618 return wxWindow::Show( show
);
621 void wxTopLevelWindowGTK::DoMoveWindow(int WXUNUSED(x
), int WXUNUSED(y
), int WXUNUSED(width
), int WXUNUSED(height
) )
623 wxFAIL_MSG( wxT("DoMoveWindow called for wxTopLevelWindowGTK") );
626 void wxTopLevelWindowGTK::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
628 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
630 // this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow
631 wxASSERT_MSG( (m_wxwindow
!= NULL
), wxT("invalid frame") );
641 int old_width
= m_width
;
642 int old_height
= m_height
;
644 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
646 if (x
!= -1) m_x
= x
;
647 if (y
!= -1) m_y
= y
;
654 if (width
!= -1) m_width
= width
;
655 if (height
!= -1) m_height
= height
;
658 if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
660 if (width == -1) m_width = 80;
663 if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
665 if (height == -1) m_height = 26;
669 int minWidth
= GetMinWidth(),
670 minHeight
= GetMinHeight(),
671 maxWidth
= GetMaxWidth(),
672 maxHeight
= GetMaxHeight();
674 if ((minWidth
!= -1) && (m_width
< minWidth
)) m_width
= minWidth
;
675 if ((minHeight
!= -1) && (m_height
< minHeight
)) m_height
= minHeight
;
676 if ((maxWidth
!= -1) && (m_width
> maxWidth
)) m_width
= maxWidth
;
677 if ((maxHeight
!= -1) && (m_height
> maxHeight
)) m_height
= maxHeight
;
679 if ((m_x
!= -1) || (m_y
!= -1))
681 if ((m_x
!= old_x
) || (m_y
!= old_y
))
683 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
687 if ((m_width
!= old_width
) || (m_height
!= old_height
))
689 if (m_widget
->window
)
690 gdk_window_resize( m_widget
->window
, m_width
, m_height
);
692 gtk_window_set_default_size( GTK_WINDOW(m_widget
), m_width
, m_height
);
694 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
695 done either directly before the frame is shown or in idle time
696 so that different calls to SetSize() don't lead to flicker. */
703 void wxTopLevelWindowGTK::DoGetClientSize( int *width
, int *height
) const
705 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
707 wxWindow::DoGetClientSize( width
, height
);
711 *height
-= m_miniEdge
*2 + m_miniTitle
;
715 *width
-= m_miniEdge
*2;
719 void wxTopLevelWindowGTK::DoSetClientSize( int width
, int height
)
721 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
724 width
+ m_miniEdge
*2, height
+ m_miniEdge
*2 + m_miniTitle
, 0);
727 void wxTopLevelWindowGTK::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
),
728 int width
, int height
)
730 // due to a bug in gtk, x,y are always 0
735 if (m_resizing
) return;
738 if ( m_wxwindow
== NULL
) return;
743 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
744 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
745 set in wxFrame::Create so it is used to check what kind of frame we
746 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
747 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
748 importantly) m_mainWidget */
750 int minWidth
= GetMinWidth(),
751 minHeight
= GetMinHeight(),
752 maxWidth
= GetMaxWidth(),
753 maxHeight
= GetMaxHeight();
755 if ((minWidth
!= -1) && (m_width
< minWidth
)) m_width
= minWidth
;
756 if ((minHeight
!= -1) && (m_height
< minHeight
)) m_height
= minHeight
;
757 if ((maxWidth
!= -1) && (m_width
> maxWidth
)) m_width
= maxWidth
;
758 if ((maxHeight
!= -1) && (m_height
> maxHeight
)) m_height
= maxHeight
;
763 gint flag
= 0; // GDK_HINT_POS;
766 if ((minWidth
!= -1) || (minHeight
!= -1)) flag
|= GDK_HINT_MIN_SIZE
;
767 if ((maxWidth
!= -1) || (maxHeight
!= -1)) flag
|= GDK_HINT_MAX_SIZE
;
769 geom
.min_width
= minWidth
;
770 geom
.min_height
= minHeight
;
772 // Because of the way we set GDK_HINT_MAX_SIZE above, if either of
773 // maxHeight or maxWidth is set, we must set them both, else the
774 // remaining -1 will be taken literally.
776 // I'm certain this also happens elsewhere, and is the probable
777 // cause of other such things as:
778 // Gtk-WARNING **: gtk_widget_size_allocate():
779 // attempt to allocate widget with width 65535 and height 600
780 // but I don't have time to track them all now..
782 // Really we need to encapulate all this height/width business and
783 // stop any old method from ripping at the members directly and
784 // scattering -1's without regard for who might resolve them later.
786 geom
.max_width
= ( maxHeight
== -1 ) ? maxWidth
787 : ( maxWidth
== -1 ) ? wxGetDisplaySize().GetWidth()
790 geom
.max_height
= ( maxWidth
== -1 ) ? maxHeight
// ( == -1 here )
791 : ( maxHeight
== -1 ) ? wxGetDisplaySize().GetHeight()
794 gtk_window_set_geometry_hints( GTK_WINDOW(m_widget
),
797 (GdkWindowHints
) flag
);
799 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
800 * menubar, the toolbar and the client area, which is represented by
802 * this hurts in the eye, but I don't want to call SetSize()
803 * because I don't want to call any non-native functions here. */
805 int client_x
= m_miniEdge
;
806 int client_y
= m_miniEdge
+ m_miniTitle
;
807 int client_w
= m_width
- 2*m_miniEdge
;
808 int client_h
= m_height
- 2*m_miniEdge
- m_miniTitle
;
810 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
),
812 client_x
, client_y
, client_w
, client_h
);
816 // If there is no m_mainWidget between m_widget and m_wxwindow there
817 // is no need to set the size or position of m_wxwindow.
822 // send size event to frame
823 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
824 event
.SetEventObject( this );
825 GetEventHandler()->ProcessEvent( event
);
830 void wxTopLevelWindowGTK::OnInternalIdle()
832 if (!m_sizeSet
&& GTK_WIDGET_REALIZED(m_wxwindow
))
834 GtkOnSize( m_x
, m_y
, m_width
, m_height
);
836 // we'll come back later
838 wxapp_install_idle_handler();
842 // set the focus if not done yet and if we can already do it
843 if ( GTK_WIDGET_REALIZED(m_wxwindow
) )
845 if ( g_delayedFocus
&&
846 wxGetTopLevelParent((wxWindow
*)g_delayedFocus
) == this )
848 g_delayedFocus
->SetFocus();
849 g_delayedFocus
= NULL
;
853 wxWindow::OnInternalIdle();
856 // ----------------------------------------------------------------------------
858 // ----------------------------------------------------------------------------
860 void wxTopLevelWindowGTK::SetTitle( const wxString
&title
)
862 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
865 gtk_window_set_title( GTK_WINDOW(m_widget
), wxGTK_CONV( title
) );
868 void wxTopLevelWindowGTK::DoSetIcon( const wxIcon
&icon
)
873 if (!m_widget
->window
)
876 wxMask
*mask
= icon
.GetMask();
877 GdkBitmap
*bm
= (GdkBitmap
*) NULL
;
878 if (mask
) bm
= mask
->GetBitmap();
880 gdk_window_set_icon( m_widget
->window
, (GdkWindow
*) NULL
, icon
.GetPixmap(), bm
);
883 void wxTopLevelWindowGTK::SetIcon( const wxIcon
&icon
)
885 SetIcons( wxIconBundle( icon
) );
888 void wxTopLevelWindowGTK::SetIcons( const wxIconBundle
&icons
)
890 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid frame") );
891 GdkWindow
* window
= m_widget
->window
;
893 wxTopLevelWindowBase::SetIcons( icons
);
895 DoSetIcon( icons
.GetIcon( -1 ) );
898 wxSetIconsX11( (WXDisplay
*)GDK_WINDOW_XDISPLAY( window
),
899 (WXWindow
)GDK_WINDOW_XWINDOW( window
), icons
);
903 // ----------------------------------------------------------------------------
904 // frame state: maximized/iconized/normal
905 // ----------------------------------------------------------------------------
907 void wxTopLevelWindowGTK::Maximize(bool WXUNUSED(maximize
))
909 wxFAIL_MSG( _T("not implemented") );
912 bool wxTopLevelWindowGTK::IsMaximized() const
914 // wxFAIL_MSG( _T("not implemented") );
916 // This is an approximation
920 void wxTopLevelWindowGTK::Restore()
922 wxFAIL_MSG( _T("not implemented") );
925 void wxTopLevelWindowGTK::Iconize( bool iconize
)
929 GdkWindow
*window
= m_widget
->window
;
931 // you should do it later, for example from OnCreate() handler
932 wxCHECK_RET( window
, _T("frame not created yet - can't iconize") );
934 XIconifyWindow( GDK_WINDOW_XDISPLAY( window
),
935 GDK_WINDOW_XWINDOW( window
),
936 DefaultScreen( GDK_DISPLAY() ) );
940 bool wxTopLevelWindowGTK::IsIconized() const
945 void wxTopLevelWindowGTK::SetIconizeState(bool iconize
)
947 if ( iconize
!= m_isIconized
)
949 m_isIconized
= iconize
;
950 (void)SendIconizeEvent(iconize
);
954 void wxTopLevelWindowGTK::AddGrab()
959 gtk_grab_add( m_widget
);
961 gtk_grab_remove( m_widget
);
965 void wxTopLevelWindowGTK::RemoveGrab()