X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/4d8d6490dac1d447196b111ea009b23d4fce9e67..7b25d8e7bd0eca9f0f6efe62b3721d14c394dac9:/src/gtk1/toplevel.cpp diff --git a/src/gtk1/toplevel.cpp b/src/gtk1/toplevel.cpp index 62cf1e50b7..a622a7e248 100644 --- a/src/gtk1/toplevel.cpp +++ b/src/gtk1/toplevel.cpp @@ -61,10 +61,92 @@ extern bool g_isIdle; // data // ---------------------------------------------------------------------------- -extern wxList wxPendingDelete; +extern wxList wxPendingDelete; -extern int g_openDialogs; -extern wxWindowGTK *g_delayedFocus; +extern int g_openDialogs; +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; +static wxTopLevelWindowGTK *g_lastActiveFrame = (wxTopLevelWindowGTK*) 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 +// OnIdle() call and it is reset to -1: this value means that we shouldn't +// send any activate events at all +static int g_sendActivateEvent = -1; + +//----------------------------------------------------------------------------- +// "focus_in_event" +//----------------------------------------------------------------------------- + +static gint gtk_frame_focus_in_callback( GtkWidget *widget, + GdkEvent *WXUNUSED(event), + wxTopLevelWindowGTK *win ) +{ + if (g_isIdle) + wxapp_install_idle_handler(); + + switch ( g_sendActivateEvent ) + { + case -1: + // we've got focus from outside, synthetize wxActivateEvent + g_sendActivateEvent = 1; + break; + + case 0: + // another our window just lost focus, it was already ours before + // - don't send any wxActivateEvent + g_sendActivateEvent = -1; + break; + } + + g_activeFrame = win; + g_lastActiveFrame = g_activeFrame; + + // wxPrintf( wxT("active: %s\n"), win->GetTitle().c_str() ); + + wxLogTrace(wxT("activate"), wxT("Activating frame %p (from focus_in)"), g_activeFrame); + wxActivateEvent event(wxEVT_ACTIVATE, TRUE, g_activeFrame->GetId()); + event.SetEventObject(g_activeFrame); + g_activeFrame->GetEventHandler()->ProcessEvent(event); + + return FALSE; +} + +//----------------------------------------------------------------------------- +// "focus_out_event" +//----------------------------------------------------------------------------- + +static gint gtk_frame_focus_out_callback( GtkWidget *widget, + GdkEventFocus *WXUNUSED(gdk_event), + wxTopLevelWindowGTK *win ) +{ + if (g_isIdle) + wxapp_install_idle_handler(); + + // if the focus goes out of our app alltogether, OnIdle() will send + // wxActivateEvent, otherwise gtk_window_focus_in_callback() will reset + // g_sendActivateEvent to -1 + g_sendActivateEvent = 0; + + // wxASSERT_MSG( (g_activeFrame == win), wxT("TLW deactivatd although it wasn't active") ); + + // wxPrintf( wxT("inactive: %s\n"), win->GetTitle().c_str() ); + + if (g_activeFrame) + { + wxLogTrace(wxT("activate"), wxT("Activating frame %p (from focus_in)"), g_activeFrame); + wxActivateEvent event(wxEVT_ACTIVATE, FALSE, g_activeFrame->GetId()); + event.SetEventObject(g_activeFrame); + g_activeFrame->GetEventHandler()->ProcessEvent(event); + + g_activeFrame = NULL; + } + + return FALSE; +} //----------------------------------------------------------------------------- // "focus" from m_window @@ -106,7 +188,6 @@ static void gtk_frame_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* win->m_width = alloc->width; win->m_height = alloc->height; - win->m_queuedFullRedraw = TRUE; win->GtkUpdateSize(); } } @@ -349,10 +430,6 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent, // e.g. in wxTaskBarIconAreaGTK if (m_widget == NULL) { - GtkWindowType win_type = GTK_WINDOW_TOPLEVEL; - if (style & wxFRAME_TOOL_WINDOW) - win_type = GTK_WINDOW_POPUP; - if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG) { #ifdef __WXGTK20__ @@ -369,16 +446,31 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent, } else { - m_widget = gtk_window_new(win_type); + m_widget = gtk_window_new(GTK_WINDOW_TOPLEVEL); +#ifdef __WXGTK20__ + if (style & wxFRAME_TOOL_WINDOW) + gtk_window_set_type_hint(GTK_WINDOW(m_widget), + GDK_WINDOW_TYPE_HINT_UTILITY); +#endif + } } - if (m_parent && (((GTK_IS_WINDOW(m_parent->m_widget)) && + wxWindow *topParent = wxGetTopLevelParent(m_parent); + if (topParent && (((GTK_IS_WINDOW(topParent->m_widget)) && (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG)) || (style & wxFRAME_FLOAT_ON_PARENT))) { - gtk_window_set_transient_for( GTK_WINDOW(m_widget), GTK_WINDOW(m_parent->m_widget) ); + gtk_window_set_transient_for( GTK_WINDOW(m_widget), + GTK_WINDOW(topParent->m_widget) ); + } + +#if GTK_CHECK_VERSION(2,2,0) + if (style & wxFRAME_NO_TASKBAR) + { + gtk_window_set_skip_taskbar_hint(GTK_WINDOW(m_widget), TRUE); } +#endif if (!name.IsEmpty()) gtk_window_set_wmclass( GTK_WINDOW(m_widget), wxGTK_CONV( name ), wxGTK_CONV( name ) ); @@ -451,6 +543,12 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent, gtk_signal_connect( GTK_OBJECT(m_widget), "focus", GTK_SIGNAL_FUNC(gtk_frame_focus_callback), (gpointer)this ); + // activation + gtk_signal_connect( GTK_OBJECT(m_widget), "focus_in_event", + GTK_SIGNAL_FUNC(gtk_frame_focus_in_callback), (gpointer)this ); + gtk_signal_connect( GTK_OBJECT(m_widget), "focus_out_event", + GTK_SIGNAL_FUNC(gtk_frame_focus_out_callback), (gpointer)this ); + // decorations if ((m_miniEdge > 0) || (style & wxSIMPLE_BORDER) || (style & wxNO_BORDER)) { @@ -511,6 +609,11 @@ wxTopLevelWindowGTK::~wxTopLevelWindowGTK() { gtk_window_set_focus( GTK_WINDOW(m_widget), NULL ); } + + if (g_activeFrame == this) + g_activeFrame = NULL; + if (g_lastActiveFrame == this) + g_lastActiveFrame = NULL; } @@ -863,6 +966,20 @@ void wxTopLevelWindowGTK::OnInternalIdle() } wxWindow::OnInternalIdle(); + + // Synthetize activate events. + if ( g_sendActivateEvent != -1 ) + { + bool activate = g_sendActivateEvent != 0; + + // if (!activate) wxPrintf( wxT("de") ); + // wxPrintf( wxT("activate\n") ); + + // do it only once + g_sendActivateEvent = -1; + + wxTheApp->SetActive(activate, (wxWindow *)g_lastActiveFrame); + } } // ---------------------------------------------------------------------------- @@ -877,21 +994,6 @@ void wxTopLevelWindowGTK::SetTitle( const wxString &title ) gtk_window_set_title( GTK_WINDOW(m_widget), wxGTK_CONV( title ) ); } -void wxTopLevelWindowGTK::DoSetIcon( const wxIcon &icon ) -{ - if ( !icon.Ok() ) - return; - - if (!m_widget->window) - return; - - wxMask *mask = icon.GetMask(); - GdkBitmap *bm = (GdkBitmap *) NULL; - if (mask) bm = mask->GetBitmap(); - - gdk_window_set_icon( m_widget->window, (GdkWindow *) NULL, icon.GetPixmap(), bm ); -} - void wxTopLevelWindowGTK::SetIcon( const wxIcon &icon ) { SetIcons( wxIconBundle( icon ) ); @@ -900,16 +1002,41 @@ void wxTopLevelWindowGTK::SetIcon( const wxIcon &icon ) void wxTopLevelWindowGTK::SetIcons( const wxIconBundle &icons ) { wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") ); - GdkWindow* window = m_widget->window; wxTopLevelWindowBase::SetIcons( icons ); - DoSetIcon( icons.GetIcon( -1 ) ); - if ( window ) +#ifdef __WXGTK20__ + GList *list = NULL; + size_t max = icons.m_icons.GetCount(); + + for (size_t i = 0; i < max; i++) { - wxSetIconsX11( (WXDisplay*)GDK_WINDOW_XDISPLAY( window ), - (WXWindow)GDK_WINDOW_XWINDOW( window ), icons ); + if (icons.m_icons[i].Ok()) + { + list = g_list_prepend(list, icons.m_icons[i].GetPixbuf()); + } } + gtk_window_set_icon_list(GTK_WINDOW(m_widget), list); + g_list_free(list); + +#else // !__WXGTK20__ + GdkWindow* window = m_widget->window; + if (!window) + return; + + wxIcon icon = icons.GetIcon(-1); + if (icon.Ok()) + { + wxMask *mask = icon.GetMask(); + GdkBitmap *bm = (GdkBitmap *) NULL; + if (mask) bm = mask->GetBitmap(); + + gdk_window_set_icon( m_widget->window, (GdkWindow *) NULL, icon.GetPixmap(), bm ); + } + + wxSetIconsX11( (WXDisplay*)GDK_WINDOW_XDISPLAY( window ), + (WXWindow)GDK_WINDOW_XWINDOW( window ), icons ); +#endif // !__WXGTK20__ } // ---------------------------------------------------------------------------- @@ -930,15 +1057,22 @@ void wxTopLevelWindowGTK::Maximize(bool maximize) bool wxTopLevelWindowGTK::IsMaximized() const { +#ifdef __WXGTK20__ + if(!m_widget->window) + return false; + + return gdk_window_get_state(m_widget->window) & GDK_WINDOW_STATE_MAXIMIZED; +#else // wxFAIL_MSG( _T("not implemented") ); // This is an approximation return FALSE; +#endif } void wxTopLevelWindowGTK::Restore() { -#ifdef __GTK20__ +#ifdef __WXGTK20__ // "Present" seems similar enough to "restore" gtk_window_present( GTK_WINDOW( m_widget ) ); #else @@ -1044,4 +1178,8 @@ bool wxTopLevelWindowGTK::SetShape(const wxRegion& region) return do_shape_combine_region(window, region); } -// vi:sts=4:sw=4:et +bool wxTopLevelWindowGTK::IsActive() +{ + return (this == (wxTopLevelWindowGTK*)g_activeFrame); +} +