X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e8769ed11cb9315fbf414d121490982df714b68a..ff58644a54af11b74b8e9b33a00de8496c531566:/src/gtk/toplevel.cpp diff --git a/src/gtk/toplevel.cpp b/src/gtk/toplevel.cpp index 2f08c8dedd..94b65ad038 100644 --- a/src/gtk/toplevel.cpp +++ b/src/gtk/toplevel.cpp @@ -38,7 +38,7 @@ #include #include -#include "wx/gtk/win_gtk.h" +#include "wx/gtk/private/win_gtk.h" #include "wx/unix/utilsx11.h" @@ -57,8 +57,6 @@ // this is incremented while a modal dialog is shown int wxOpenModalDialogsCount = 0; -extern wxWindowGTK *g_delayedFocus; - // the frame that is currently active (i.e. its child has focus). It is // used to generate wxActivateEvents static wxTopLevelWindowGTK *g_activeFrame = (wxTopLevelWindowGTK*) NULL; @@ -268,7 +266,6 @@ gtk_frame_delete_callback( GtkWidget *WXUNUSED(widget), } } - //----------------------------------------------------------------------------- // "configure_event" //----------------------------------------------------------------------------- @@ -327,6 +324,9 @@ gtk_frame_realized_callback( GtkWidget * WXUNUSED(widget), win->SetIcon( wxNullIcon ); win->SetIcons( iconsOld ); } + + if (win->HasFlag(wxFRAME_SHAPED)) + win->SetShape(win->m_shape); // it will really set the window shape now } } @@ -404,54 +404,7 @@ static gboolean property_notify_event( long* p = (long*)data; const wxSize decorSize = wxSize(int(p[0] + p[1]), int(p[2] + p[3])); - if (win->m_decorSize != decorSize) - { - const wxSize diff = decorSize - win->m_decorSize; - win->m_decorSize = decorSize; - bool resized = false; - if (win->m_deferShow) - { - // keep overall size unchanged by shrinking m_widget, - // if min size will allow it - const wxSize minSize = win->GetMinSize(); - int w, h; - win->GTKDoGetSize(&w, &h); - if (w >= minSize.x && h >= minSize.y) - { - gtk_window_resize(GTK_WINDOW(win->m_widget), w, h); - resized = true; - } - } - if (!resized) - { - // adjust overall size to match change in frame extents - win->m_width += diff.x; - win->m_height += diff.y; - if (win->m_width < 0) win->m_width = 0; - if (win->m_height < 0) win->m_height = 0; - if (!win->m_deferShow) - { - win->m_oldClientWidth = 0; - gtk_widget_queue_resize(win->m_wxwindow); - } - } - } - if (win->m_deferShow) - { - // gtk_widget_show() was deferred, do it now - win->m_deferShow = false; - win->GetClientSize( - &win->m_oldClientWidth, &win->m_oldClientHeight); - wxSizeEvent sizeEvent(win->GetSize(), win->GetId()); - sizeEvent.SetEventObject(win); - win->HandleWindowEvent(sizeEvent); - - gtk_widget_show(win->m_widget); - - wxShowEvent showEvent(win->GetId(), true); - showEvent.SetEventObject(win); - win->HandleWindowEvent(showEvent); - } + win->GTKUpdateDecorSize(decorSize); } if (data) XFree(data); @@ -464,7 +417,6 @@ BEGIN_EVENT_TABLE(wxTopLevelWindowGTK, wxTopLevelWindowBase) EVT_SYS_COLOUR_CHANGED(wxTopLevelWindowGTK::OnSysColourChanged) END_EVENT_TABLE() - // ---------------------------------------------------------------------------- // wxTopLevelWindowGTK creation // ---------------------------------------------------------------------------- @@ -809,8 +761,19 @@ bool wxTopLevelWindowGTK::Show( bool show ) { wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") ); - const bool wasRealized = GTK_WIDGET_REALIZED(m_widget); - bool deferShow = show && m_deferShow && !wasRealized; + bool deferShow = show && m_deferShow; + if (deferShow) + { + m_deferShow = + deferShow = !GTK_WIDGET_REALIZED(m_widget) && + gdk_x11_screen_supports_net_wm_hint( + gtk_widget_get_screen(m_widget), + gdk_atom_intern("_NET_REQUEST_FRAME_EXTENTS", false)) && + g_signal_handler_find(m_widget, + GSignalMatchType(G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DATA), + g_signal_lookup("property_notify_event", GTK_TYPE_WIDGET), + 0, NULL, NULL, this); + } if (deferShow) { // Initial show. If WM supports _NET_REQUEST_FRAME_EXTENTS, defer @@ -820,30 +783,17 @@ bool wxTopLevelWindowGTK::Show( bool show ) // what wxWidgets expects it to be without an obvious change in the // window size immediately after it becomes visible. - // Realize m_widget, so m_widget->window can be used. Realizing causes - // the widget tree to be size_allocated, which generates size events in - // the wrong order. So temporarily remove child from m_widget while - // realizing. - GtkWidget* child = GTK_BIN(m_widget)->child; - if (child) - { - g_object_ref(child); - gtk_container_remove(GTK_CONTAINER(m_widget), child); - } + // Realize m_widget, so m_widget->window can be used. Realizing normally + // causes the widget tree to be size_allocated, which generates size + // events in the wrong order. However, the size_allocates will not be + // done if the allocation is not the default (1,1). + const int alloc_width = m_widget->allocation.width; + if (alloc_width == 1) + m_widget->allocation.width = 2; gtk_widget_realize(m_widget); - if (child) - { - gtk_container_add(GTK_CONTAINER(m_widget), child); - g_object_unref(child); - } + if (alloc_width == 1) + m_widget->allocation.width = 1; - m_deferShow = - deferShow = gdk_x11_screen_supports_net_wm_hint( - gdk_drawable_get_screen(m_widget->window), - gdk_atom_intern("_NET_REQUEST_FRAME_EXTENTS", false)) != 0; - } - if (deferShow) - { // send _NET_REQUEST_FRAME_EXTENTS XClientMessageEvent xevent; memset(&xevent, 0, sizeof(xevent)); @@ -863,7 +813,7 @@ bool wxTopLevelWindowGTK::Show( bool show ) return true; } - if (show && !wasRealized) + if (show && !GTK_WIDGET_REALIZED(m_widget)) { // size_allocate signals occur in reverse order (bottom to top). // Things work better if the initial wxSizeEvents are sent (from the @@ -1023,24 +973,56 @@ void wxTopLevelWindowGTK::DoSetSizeHints( int minW, int minH, (GtkWindow*)m_widget, NULL, &hints, (GdkWindowHints)hints_mask); } -void wxTopLevelWindowGTK::OnInternalIdle() +void wxTopLevelWindowGTK::GTKUpdateDecorSize(const wxSize& decorSize) { - // set the focus if not done yet and if we can already do it - if ( GTK_WIDGET_REALIZED(m_wxwindow) ) + if (m_decorSize != decorSize) { - if ( g_delayedFocus && - wxGetTopLevelParent((wxWindow*)g_delayedFocus) == this ) + const wxSize diff = decorSize - m_decorSize; + m_decorSize = decorSize; + bool resized = false; + if (m_deferShow) { - wxLogTrace(_T("focus"), - _T("Setting focus from wxTLW::OnIdle() to %s(%s)"), - g_delayedFocus->GetClassInfo()->GetClassName(), - g_delayedFocus->GetLabel().c_str()); - - g_delayedFocus->SetFocus(); - g_delayedFocus = NULL; + // keep overall size unchanged by shrinking m_widget + int w, h; + GTKDoGetSize(&w, &h); + // but not if size would be less than minimum, it won't take effect + const wxSize minSize = GetMinSize(); + if (w >= minSize.x && h >= minSize.y) + { + gtk_window_resize(GTK_WINDOW(m_widget), w, h); + resized = true; + } + } + if (!resized) + { + // adjust overall size to match change in frame extents + m_width += diff.x; + m_height += diff.y; + if (m_width < 0) m_width = 0; + if (m_height < 0) m_height = 0; + m_oldClientWidth = 0; + gtk_widget_queue_resize(m_wxwindow); } } + if (m_deferShow) + { + // gtk_widget_show() was deferred, do it now + m_deferShow = false; + GetClientSize(&m_oldClientWidth, &m_oldClientHeight); + wxSizeEvent sizeEvent(GetSize(), GetId()); + sizeEvent.SetEventObject(this); + HandleWindowEvent(sizeEvent); + + gtk_widget_show(m_widget); + + wxShowEvent showEvent(GetId(), true); + showEvent.SetEventObject(this); + HandleWindowEvent(showEvent); + } +} +void wxTopLevelWindowGTK::OnInternalIdle() +{ wxWindow::OnInternalIdle(); // Synthetize activate events. @@ -1185,13 +1167,22 @@ bool wxTopLevelWindowGTK::SetShape(const wxRegion& region) wxCHECK_MSG( HasFlag(wxFRAME_SHAPED), false, _T("Shaped windows must be created with the wxFRAME_SHAPED style.")); - GdkWindow *window = NULL; - if (m_wxwindow) + if ( GTK_WIDGET_REALIZED(m_widget) ) { - do_shape_combine_region(m_wxwindow->window, region); + if ( m_wxwindow ) + do_shape_combine_region(m_wxwindow->window, region); + + return do_shape_combine_region(m_widget->window, region); + } + else // not realized yet + { + // store the shape to set, it will be really set once we're realized + m_shape = region; + + // we don't know if we're going to succeed or fail, be optimistic by + // default + return true; } - window = m_widget->window; - return do_shape_combine_region(window, region); } bool wxTopLevelWindowGTK::IsActive()