X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/52d6235db0c5c1d3734afc03321da8267c969d34..04354c1deb9e900f89d299a88317569d55e196bf:/src/gtk/toplevel.cpp?ds=sidebyside diff --git a/src/gtk/toplevel.cpp b/src/gtk/toplevel.cpp index a32d659c2f..eb820f7f15 100644 --- a/src/gtk/toplevel.cpp +++ b/src/gtk/toplevel.cpp @@ -46,35 +46,15 @@ extern void wxapp_install_idle_handler(); extern bool g_isIdle; -extern int g_openDialogs; - -// ---------------------------------------------------------------------------- -// event tables -// ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // data // ---------------------------------------------------------------------------- -extern wxList wxPendingDelete; - -// ---------------------------------------------------------------------------- -// debug -// ---------------------------------------------------------------------------- - -#ifdef __WXDEBUG__ - -extern void debug_focus_in( GtkWidget* widget, const wxChar* name, const wxChar *window ); +extern wxList wxPendingDelete; -#endif - -// ============================================================================ -// implementation -// ============================================================================ - -// ---------------------------------------------------------------------------- -// GTK callbacks -// ---------------------------------------------------------------------------- +extern int g_openDialogs; +extern wxWindowGTK *g_delayedFocus; //----------------------------------------------------------------------------- // "focus" from m_window @@ -131,7 +111,8 @@ static gint gtk_frame_delete_callback( GtkWidget *WXUNUSED(widget), GdkEvent *WX wxapp_install_idle_handler(); if (win->IsEnabled() && - (g_openDialogs == 0 || (win->GetExtraStyle() & wxTOPLEVEL_EX_DIALOG))) + (g_openDialogs == 0 || (win->GetExtraStyle() & wxTOPLEVEL_EX_DIALOG) || + win->IsGrabbed())) win->Close(); return TRUE; @@ -172,7 +153,8 @@ gtk_frame_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigure *WX // so we do this directly after realization static void -gtk_frame_realized_callback( GtkWidget * WXUNUSED(widget), wxTopLevelWindowGTK *win ) +gtk_frame_realized_callback( GtkWidget * WXUNUSED(widget), + wxTopLevelWindowGTK *win ) { if (g_isIdle) wxapp_install_idle_handler(); @@ -192,28 +174,11 @@ gtk_frame_realized_callback( GtkWidget * WXUNUSED(widget), wxTopLevelWindowGTK * // reset the icon wxIconBundle iconsOld = win->GetIcons(); - wxIcon tmp = iconsOld.GetIcon( -1 ); // operator != is not-const - if ( tmp != wxNullIcon ) + if ( iconsOld.GetIcon(-1).Ok() ) { - // wxIconBundle icon( iconOld ); win->SetIcon( wxNullIcon ); win->SetIcons( iconsOld ); } - - // we set the focus to the child that accepts the focus. this - // doesn't really have to be done in "realize" but why not? - wxWindowList::Node *node = win->GetChildren().GetFirst(); - while (node) - { - wxWindow *child = node->GetData(); - if (child->AcceptsFocus()) - { - child->SetFocus(); - break; - } - - node = node->GetNext(); - } } //----------------------------------------------------------------------------- @@ -334,11 +299,11 @@ void wxTopLevelWindowGTK::Init() m_miniTitle = 0; m_mainWidget = (GtkWidget*) NULL; m_insertInClientArea = TRUE; - m_isFrame = TRUE; m_isIconized = FALSE; m_fsIsShowing = FALSE; m_themeEnabled = TRUE; m_gdkDecor = m_gdkFunc = 0; + m_grabbed = FALSE; } bool wxTopLevelWindowGTK::Create( wxWindow *parent, @@ -364,7 +329,7 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent, wxTopLevelWindows.Append( this ); m_needParent = FALSE; - + if (!PreCreation( parent, pos, size ) || !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name )) { @@ -402,10 +367,6 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent, if (!name.IsEmpty()) gtk_window_set_wmclass( GTK_WINDOW(m_widget), name.mb_str(), name.mb_str() ); -#ifdef __WXDEBUG__ - debug_focus_in( m_widget, wxT("wxTopLevelWindowGTK::m_widget"), name ); -#endif - gtk_window_set_title( GTK_WINDOW(m_widget), title.mbc_str() ); GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS ); @@ -426,19 +387,11 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent, GTK_SIGNAL_FUNC(gtk_window_draw_callback), (gpointer)this ); #endif -#ifdef __WXDEBUG__ - debug_focus_in( m_mainWidget, wxT("wxTopLevelWindowGTK::m_mainWidget"), name ); -#endif - // m_wxwindow only represents the client area without toolbar and menubar m_wxwindow = gtk_pizza_new(); gtk_widget_show( m_wxwindow ); gtk_container_add( GTK_CONTAINER(m_mainWidget), m_wxwindow ); -#ifdef __WXDEBUG__ - debug_focus_in( m_wxwindow, wxT("wxTopLevelWindowGTK::m_wxwindow"), name ); -#endif - // we donm't allow the frame to get the focus as otherwise // the frame will grab it at arbitrary focus changes GTK_WIDGET_UNSET_FLAGS( m_wxwindow, GTK_CAN_FOCUS ); @@ -453,7 +406,7 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent, if ((m_x != -1) || (m_y != -1)) gtk_widget_set_uposition( m_widget, m_x, m_y ); - + gtk_window_set_default_size( GTK_WINDOW(m_widget), m_width, m_height ); // we cannot set MWM hints and icons before the widget has @@ -521,8 +474,14 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent, wxTopLevelWindowGTK::~wxTopLevelWindowGTK() { - m_isBeingDeleted = TRUE; + if (m_grabbed) + { + wxASSERT_MSG( FALSE, "Window still grabbed"); + RemoveGrab(); + } + m_isBeingDeleted = TRUE; + // it may also be GtkScrolledWindow in the case of an MDI child if (GTK_IS_WINDOW(m_widget)) { @@ -751,14 +710,37 @@ void wxTopLevelWindowGTK::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), if (m_mainWidget) { // set size hints - gint flag = 0; // GDK_HINT_POS; + gint flag = 0; // GDK_HINT_POS; + GdkGeometry geom; + if ((minWidth != -1) || (minHeight != -1)) flag |= GDK_HINT_MIN_SIZE; if ((maxWidth != -1) || (maxHeight != -1)) flag |= GDK_HINT_MAX_SIZE; - GdkGeometry geom; + geom.min_width = minWidth; geom.min_height = minHeight; - geom.max_width = maxWidth; - geom.max_height = maxHeight; + + // Because of the way we set GDK_HINT_MAX_SIZE above, if either of + // maxHeight or maxWidth is set, we must set them both, else the + // remaining -1 will be taken literally. + + // I'm certain this also happens elsewhere, and is the probable + // cause of other such things as: + // Gtk-WARNING **: gtk_widget_size_allocate(): + // attempt to allocate widget with width 65535 and height 600 + // but I don't have time to track them all now.. + // + // Really we need to encapulate all this height/width business and + // stop any old method from ripping at the members directly and + // scattering -1's without regard for who might resolve them later. + + geom.max_width = ( maxHeight == -1 ) ? maxWidth + : ( maxWidth == -1 ) ? wxGetDisplaySize().GetWidth() + : maxWidth ; + + geom.max_height = ( maxWidth == -1 ) ? maxHeight // ( == -1 here ) + : ( maxHeight == -1 ) ? wxGetDisplaySize().GetHeight() + : maxHeight ; + gtk_window_set_geometry_hints( GTK_WINDOW(m_widget), (GtkWidget*) NULL, &geom, @@ -774,6 +756,7 @@ void wxTopLevelWindowGTK::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), int client_y = m_miniEdge + m_miniTitle; int client_w = m_width - 2*m_miniEdge; int client_h = m_height - 2*m_miniEdge - m_miniTitle; + gtk_pizza_set_size( GTK_PIZZA(m_mainWidget), m_wxwindow, client_x, client_y, client_w, client_h ); @@ -806,10 +789,20 @@ void wxTopLevelWindowGTK::OnInternalIdle() return; } + // set the focus if not done yet and if we can already do it + if ( GTK_WIDGET_REALIZED(m_wxwindow) ) + { + if ( g_delayedFocus && + wxGetTopLevelParent((wxWindow*)g_delayedFocus) == this ) + { + g_delayedFocus->SetFocus(); + g_delayedFocus = NULL; + } + } + wxWindow::OnInternalIdle(); } - // ---------------------------------------------------------------------------- // frame title/icon // ---------------------------------------------------------------------------- @@ -908,3 +901,24 @@ void wxTopLevelWindowGTK::SetIconizeState(bool iconize) } } +void wxTopLevelWindowGTK::AddGrab() +{ + if (!m_grabbed) + { + m_grabbed = TRUE; + gtk_grab_add( m_widget ); + gtk_main(); + gtk_grab_remove( m_widget ); + } +} + +void wxTopLevelWindowGTK::RemoveGrab() +{ + if (m_grabbed) + { + gtk_main_quit(); + m_grabbed = FALSE; + } +} + +// vi:sts=4:sw=4:et