// the frame that is currently active (i.e. its child has focus). It is
// used to generate wxActivateEvents
-static wxTopLevelWindowGTK *g_activeFrame = (wxTopLevelWindowGTK*) NULL;
-static wxTopLevelWindowGTK *g_lastActiveFrame = (wxTopLevelWindowGTK*) NULL;
+static wxTopLevelWindowGTK *g_activeFrame = NULL;
+static wxTopLevelWindowGTK *g_lastActiveFrame = NULL;
// if we detect that the app has got/lost the focus, we set this variable to
// either TRUE or FALSE and an activate event will be sent during the next
// "realize" from m_widget
//-----------------------------------------------------------------------------
-// we cannot MWM hints and icons before the widget has been realized,
+// we cannot the WM hints and icons before the widget has been realized,
// so we do this directly after realization
extern "C" {
gtk_frame_realized_callback( GtkWidget * WXUNUSED(widget),
wxTopLevelWindowGTK *win )
{
- // All this is for Motif Window Manager "hints" and is supposed to be
- // recognized by other WM as well. Not tested.
gdk_window_set_decorations(win->m_widget->window,
(GdkWMDecoration)win->m_gdkDecor);
gdk_window_set_functions(win->m_widget->window,
(GdkWMFunction)win->m_gdkFunc);
// GTK's shrinking/growing policy
- if ((win->m_gdkFunc & GDK_FUNC_RESIZE) == 0)
+ if ( !(win->m_gdkFunc & GDK_FUNC_RESIZE) )
gtk_window_set_resizable(GTK_WINDOW(win->m_widget), FALSE);
else
gtk_window_set_policy(GTK_WINDOW(win->m_widget), 1, 1, 1);
wxTopLevelWindow *win )
{
const bool wasIconized = win->IsIconized();
-
win->SetIconizeState(false);
-
if (wasIconized)
{
// Because GetClientSize() returns (0,0) when IsIconized() is true,
win->m_oldClientWidth = 0;
gtk_widget_queue_resize(win->m_wxwindow);
}
-
+ // it is possible for m_isShown to be false here, see bug #9909
+ if (win->wxWindowBase::Show(true))
+ {
+ wxShowEvent eventShow(win->GetId(), true);
+ eventShow.SetEventObject(win);
+ win->GetEventHandler()->ProcessEvent(eventShow);
+ }
return false;
}
}
}
}
-BEGIN_EVENT_TABLE(wxTopLevelWindowGTK, wxTopLevelWindowBase)
- EVT_SYS_COLOUR_CHANGED(wxTopLevelWindowGTK::OnSysColourChanged)
-END_EVENT_TABLE()
-
// ----------------------------------------------------------------------------
// wxTopLevelWindowGTK creation
// ----------------------------------------------------------------------------
void wxTopLevelWindowGTK::Init()
{
- m_mainWidget = (GtkWidget*) NULL;
+ m_mainWidget = NULL;
m_isIconized = false;
m_fsIsShowing = false;
m_themeEnabled = true;
- m_gdkDecor = m_gdkFunc = 0;
+ m_gdkDecor =
+ m_gdkFunc = 0;
m_grabbed = false;
m_deferShow = true;
+ m_deferShowAllowed = true;
+ m_updateDecorSize = true;
m_urgency_hint = -2;
}
}
}
#endif // wxUSE_LIBHILDON/!wxUSE_LIBHILDON
+
+ g_object_ref(m_widget);
}
wxWindow *topParent = wxGetTopLevelParent(m_parent);
gtk_container_add( GTK_CONTAINER(m_widget), m_mainWidget );
// m_wxwindow is the client area
- m_wxwindow = wxPizza::New();
+ m_wxwindow = wxPizza::New(0,this);
gtk_widget_show( m_wxwindow );
gtk_container_add( GTK_CONTAINER(m_mainWidget), m_wxwindow );
g_signal_connect(m_widget, "property_notify_event",
G_CALLBACK(property_notify_event), this);
- // decorations
- if ((style & wxSIMPLE_BORDER) || (style & wxNO_BORDER))
+ // translate wx decorations styles into Motif WM hints (they are recognized
+ // by other WMs as well)
+
+ // always enable moving the window as we have no separate flag for enabling
+ // it
+ m_gdkFunc = GDK_FUNC_MOVE;
+
+ if ( style & wxCLOSE_BOX )
+ m_gdkFunc |= GDK_FUNC_CLOSE;
+
+ if ( style & wxMINIMIZE_BOX )
+ m_gdkFunc |= GDK_FUNC_MINIMIZE;
+
+ if ( style & wxMAXIMIZE_BOX )
+ m_gdkFunc |= GDK_FUNC_MAXIMIZE;
+
+ if ( (style & wxSIMPLE_BORDER) || (style & wxNO_BORDER) )
{
m_gdkDecor = 0;
- m_gdkFunc = 0;
}
- else
+ else // have border
{
m_gdkDecor = GDK_DECOR_BORDER;
- m_gdkFunc = GDK_FUNC_MOVE;
- // All this is for Motif Window Manager "hints" and is supposed to be
- // recognized by other WMs as well.
- if ((style & wxCAPTION) != 0)
- {
+ if ( style & wxCAPTION )
m_gdkDecor |= GDK_DECOR_TITLE;
- }
- if ((style & wxCLOSE_BOX) != 0)
- {
- m_gdkFunc |= GDK_FUNC_CLOSE;
- }
- if ((style & wxSYSTEM_MENU) != 0)
- {
+
+ if ( style & wxSYSTEM_MENU )
m_gdkDecor |= GDK_DECOR_MENU;
- }
- if ((style & wxMINIMIZE_BOX) != 0)
- {
- m_gdkFunc |= GDK_FUNC_MINIMIZE;
+
+ if ( style & wxMINIMIZE_BOX )
m_gdkDecor |= GDK_DECOR_MINIMIZE;
- }
- if ((style & wxMAXIMIZE_BOX) != 0)
- {
- m_gdkFunc |= GDK_FUNC_MAXIMIZE;
+
+ if ( style & wxMAXIMIZE_BOX )
m_gdkDecor |= GDK_DECOR_MAXIMIZE;
- }
- if ((style & wxRESIZE_BORDER) != 0)
+
+ if ( style & wxRESIZE_BORDER )
{
m_gdkFunc |= GDK_FUNC_RESIZE;
m_gdkDecor |= GDK_DECOR_RESIZEH;
RemoveGrab();
}
- m_isBeingDeleted = true;
+ SendDestroyEvent();
// it may also be GtkScrolledWindow in the case of an MDI child
if (GTK_IS_WINDOW(m_widget))
{
wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
- bool deferShow = show && m_deferShow && !m_isShown;
+ bool deferShow = show && !m_isShown && m_deferShow && m_deferShowAllowed;
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)) &&
+ deferShow = false;
+ if (!GTK_WIDGET_REALIZED(m_widget) &&
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);
+ 0, NULL, NULL, this))
+ {
+ if (gdk_x11_screen_supports_net_wm_hint(
+ gtk_widget_get_screen(m_widget),
+ gdk_atom_intern("_NET_REQUEST_FRAME_EXTENTS", false)))
+ {
+ deferShow = true;
+ }
+ else
+ {
+ // Don't allow changes to m_decorSize, it breaks saving/restoring
+ // window size with GetSize()/SetSize() because it makes window
+ // bigger between each restore and save.
+ m_updateDecorSize = false;
+ }
+ }
+ m_deferShow = deferShow;
}
if (deferShow)
{
{
wxCHECK_RET( m_widget, wxT("invalid frame") );
+ m_deferShowAllowed = true;
+
// deal with the position first
int old_x = m_x;
int old_y = m_y;
void wxTopLevelWindowGTK::DoSetClientSize(int width, int height)
{
- if (m_deferShow && !m_isShown)
- // Since client size is being explicitly set, don't change it later
- m_deferShow = false;
+ // Since client size is being explicitly set, don't change it later
+ m_deferShowAllowed = false;
+
wxTopLevelWindowBase::DoSetClientSize(width, height);
}
{
if (!IsMaximized() && !IsFullScreen())
GetCachedDecorSize() = decorSize;
- if (m_decorSize != decorSize)
+ if (m_updateDecorSize && m_decorSize != decorSize)
{
const wxSize diff = decorSize - m_decorSize;
m_decorSize = decorSize;
bool new_hint_value = false;
// FIXME: This is a workaround to focus handling problem
- // If RequestUserAttention is called for example right after a wxSleep, OnInternalIdle hasn't
- // yet been processed, and the internal focus system is not up to date yet.
- // wxYieldIfNeeded ensures the processing of it, but can have unwanted side effects - MR
- ::wxYieldIfNeeded();
+ // If RequestUserAttention is called for example right after a wxSleep, OnInternalIdle
+ // hasn't yet been processed, and the internal focus system is not up to date yet.
+ // YieldFor(wxEVT_CATEGORY_UI) ensures the processing of it (hopefully it
+ // won't have side effects) - MR
+ wxEventLoopBase::GetActive()->YieldFor(wxEVT_CATEGORY_UI);
if(m_urgency_hint >= 0)
g_source_remove(m_urgency_hint);
"Composite", &opcode, &event, &error);
#endif
}
-
-void wxTopLevelWindowGTK::OnSysColourChanged(wxSysColourChangedEvent& event)
-{
- // We don't know the order in which top-level windows will
- // be notified, so we need to clear the system objects
- // for each top-level window.
- extern void wxClearGtkSystemObjects();
- wxClearGtkSystemObjects();
-
- // wxWindowBase::OnSysColourChanged will propagate event
- // to children
- event.Skip();
-}