X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/9a83f860948059b0273b5cc6d9e43fadad3ebfca..b5ec0c78b521cfa0f276e4d5d830f35b4fa26e91:/src/gtk/app.cpp diff --git a/src/gtk/app.cpp b/src/gtk/app.cpp index a627c8ee22..3754531c01 100644 --- a/src/gtk/app.cpp +++ b/src/gtk/app.cpp @@ -26,14 +26,19 @@ #include #endif -#include "wx/gtk/private.h" #include "wx/apptrait.h" +#include "wx/fontmap.h" #if wxUSE_LIBHILDON #include #endif // wxUSE_LIBHILDON -#include +#if wxUSE_LIBHILDON2 + #include +#endif // wxUSE_LIBHILDON2 + +#include +#include "wx/gtk/private.h" //----------------------------------------------------------------------------- // link GnomeVFS @@ -56,9 +61,9 @@ wx_emission_hook(GSignalInvocationHint*, guint, const GValue*, gpointer data) wxApp* app = wxTheApp; if (app != NULL) app->WakeUpIdle(); - gulong* hook_id = (gulong*)data; + bool* hook_installed = (bool*)data; // record that hook is not installed - *hook_id = 0; + *hook_installed = false; // remove hook return false; } @@ -69,28 +74,30 @@ static void wx_add_idle_hooks() { // "event" hook { - static gulong hook_id = 0; - if (hook_id == 0) + static bool hook_installed; + if (!hook_installed) { - static guint sig_id = 0; + static guint sig_id; if (sig_id == 0) sig_id = g_signal_lookup("event", GTK_TYPE_WIDGET); - hook_id = g_signal_add_emission_hook( - sig_id, 0, wx_emission_hook, &hook_id, NULL); + hook_installed = true; + g_signal_add_emission_hook( + sig_id, 0, wx_emission_hook, &hook_installed, NULL); } } // "size_allocate" hook - // Needed to match the behavior of the old idle system, + // Needed to match the behaviour of the old idle system, // but probably not necessary. { - static gulong hook_id = 0; - if (hook_id == 0) + static bool hook_installed; + if (!hook_installed) { - static guint sig_id = 0; + static guint sig_id; if (sig_id == 0) sig_id = g_signal_lookup("size_allocate", GTK_TYPE_WIDGET); - hook_id = g_signal_add_emission_hook( - sig_id, 0, wx_emission_hook, &hook_id, NULL); + hook_installed = true; + g_signal_add_emission_hook( + sig_id, 0, wx_emission_hook, &hook_installed, NULL); } } } @@ -110,7 +117,7 @@ bool wxApp::DoIdle() // Needed if an idle event handler runs a new event loop, // for example by showing a dialog. #if wxUSE_THREADS - wxMutexLocker lock(*m_idleMutex); + wxMutexLocker lock(m_idleMutex); #endif id_save = m_idleSourceId; m_idleSourceId = 0; @@ -118,7 +125,7 @@ bool wxApp::DoIdle() #if wxDEBUG_LEVEL // don't generate the idle events while the assert modal dialog is shown, - // this matches the behavior of wxMSW + // this matches the behaviour of wxMSW if (m_isInAssert) return false; #endif @@ -134,30 +141,28 @@ bool wxApp::DoIdle() gdk_threads_leave(); #if wxUSE_THREADS - wxMutexLocker lock(*m_idleMutex); + wxMutexLocker lock(m_idleMutex); #endif - // if a new idle source was added during ProcessIdle - if (m_idleSourceId != 0) - { - // remove it - g_source_remove(m_idleSourceId); - m_idleSourceId = 0; - } - // Pending events can be added asynchronously, - // need to keep idle source if any have appeared - needMore = needMore || HasPendingEvents(); - - // if more idle processing requested - if (needMore) + bool keepSource = false; + // if a new idle source has not been added, either as a result of idle + // processing above or by another thread calling WakeUpIdle() + if (m_idleSourceId == 0) { - // keep this source installed - m_idleSourceId = id_save; - return true; + // if more idle processing was requested or pending events have appeared + if (needMore || HasPendingEvents()) + { + // keep this source installed + m_idleSourceId = id_save; + keepSource = true; + } + else // add hooks and remove this source + wx_add_idle_hooks(); } - // add hooks and remove this source - wx_add_idle_hooks(); - return false; + // else remove this source, leave new one installed + // we must keep an idle source, otherwise a wakeup could be lost + + return keepSource; } //----------------------------------------------------------------------------- @@ -185,10 +190,6 @@ IMPLEMENT_DYNAMIC_CLASS(wxApp,wxEvtHandler) wxApp::wxApp() { m_isInAssert = false; - -#if wxUSE_THREADS - m_idleMutex = NULL; -#endif m_idleSourceId = 0; } @@ -198,6 +199,10 @@ wxApp::~wxApp() bool wxApp::SetNativeTheme(const wxString& theme) { +#ifdef __WXGTK3__ + wxUnusedVar(theme); + return false; +#else wxString path; path = gtk_rc_get_theme_dir(); path += "/"; @@ -218,6 +223,7 @@ bool wxApp::SetNativeTheme(const wxString& theme) gtk_rc_reparse_all_for_settings(gtk_settings_get_default(), TRUE); return true; +#endif } bool wxApp::OnInitGui() @@ -225,6 +231,7 @@ bool wxApp::OnInitGui() if ( !wxAppBase::OnInitGui() ) return false; +#ifndef __WXGTK3__ // if this is a wxGLApp (derived from wxApp), and we've already // chosen a specific visual, then derive the GdkVisual from that if ( GetXVisualInfo() ) @@ -262,34 +269,19 @@ bool wxApp::OnInitGui() } } } +#endif -#if wxUSE_LIBHILDON - m_hildonProgram = hildon_program_get_instance(); - if ( !m_hildonProgram ) +#if wxUSE_LIBHILDON || wxUSE_LIBHILDON2 + if ( !GetHildonProgram() ) { wxLogError(_("Unable to initialize Hildon program")); return false; } -#endif // wxUSE_LIBHILDON +#endif // wxUSE_LIBHILDON || wxUSE_LIBHILDON2 return true; } -GdkVisual *wxApp::GetGdkVisual() -{ - GdkVisual *visual = NULL; - - XVisualInfo *xvi = (XVisualInfo *)GetXVisualInfo(); - if ( xvi ) - visual = gdkx_visual_get( xvi->visualid ); - else - visual = gdk_drawable_get_visual( wxGetRootWindow()->window ); - - wxASSERT( visual ); - - return visual; -} - // use unusual names for the parameters to avoid conflict with wxApp::arg[cv] bool wxApp::Initialize(int& argc_, wxChar **argv_) { @@ -307,6 +299,7 @@ bool wxApp::Initialize(int& argc_, wxChar **argv_) // gtk+ 2.0 supports Unicode through UTF-8 strings wxConvCurrent = &wxConvUTF8; +#ifdef __UNIX__ // decide which conversion to use for the file names // (1) this variable exists for the sole purpose of specifying the encoding @@ -316,29 +309,38 @@ bool wxApp::Initialize(int& argc_, wxChar **argv_) if (encName.CmpNoCase(wxT("@locale")) == 0) encName.clear(); encName.MakeUpper(); -#if wxUSE_INTL if (encName.empty()) { +#if wxUSE_INTL // (2) if a non default locale is set, assume that the user wants his // filenames in this locale too encName = wxLocale::GetSystemEncodingName().Upper(); + + // But don't consider ASCII in this case. + if ( !encName.empty() ) + { +#if wxUSE_FONTMAP + wxFontEncoding enc = wxFontMapperBase::GetEncodingFromName(encName); + if ( enc == wxFONTENCODING_DEFAULT ) +#else // !wxUSE_FONTMAP + if ( encName == wxT("US-ASCII") ) +#endif // wxUSE_FONTMAP/!wxUSE_FONTMAP + { + // This means US-ASCII when returned from GetEncodingFromName(). + encName.clear(); + } + } +#endif // wxUSE_INTL + // (3) finally use UTF-8 by default - if (encName.empty() || encName == wxT("US-ASCII")) + if ( encName.empty() ) encName = wxT("UTF-8"); wxSetEnv(wxT("G_FILENAME_ENCODING"), encName); } -#else - if (encName.empty()) - encName = wxT("UTF-8"); - - // if wxUSE_INTL==0 it probably indicates that only "C" locale is supported - // by the program anyhow so prevent GTK+ from calling setlocale(LC_ALL, "") - // from gtk_init_check() as it does by default - gtk_disable_setlocale(); -#endif // wxUSE_INTL static wxConvBrokenFileNames fileconv(encName); wxConvFileName = &fileconv; +#endif // __UNIX__ bool init_result; @@ -356,13 +358,17 @@ bool wxApp::Initialize(int& argc_, wxChar **argv_) int argcGTK = argc_; + // Prevent gtk_init_check() from changing the locale automatically for + // consistency with the other ports that don't do it. If necessary, + // wxApp::SetCLocale() may be explicitly called. + gtk_disable_setlocale(); + #ifdef __WXGPE__ init_result = true; // is there a _check() version of this? gpe_application_init( &argcGTK, &argvGTK ); #else - init_result = gtk_init_check( &argcGTK, &argvGTK ); + init_result = gtk_init_check( &argcGTK, &argvGTK ) != 0; #endif - wxUpdateLocaleIsUtf8(); if ( argcGTK != argc_ ) { @@ -435,18 +441,13 @@ bool wxApp::Initialize(int& argc_, wxChar **argv_) return false; } - // we can not enter threads before gtk_init is done + // we cannot enter threads before gtk_init is done gdk_threads_enter(); - wxSetDetectableAutoRepeat( true ); - #if wxUSE_INTL wxFont::SetDefaultEncoding(wxLocale::GetSystemEncoding()); #endif -#if wxUSE_THREADS - m_idleMutex = new wxMutex; -#endif // make sure GtkWidget type is loaded, idle hooks need it g_type_class_ref(GTK_TYPE_WIDGET); WakeUpIdle(); @@ -465,20 +466,12 @@ void wxApp::CleanUp() gdk_threads_leave(); wxAppBase::CleanUp(); - - // delete this mutex as late as possible as it's used from WakeUpIdle(), in - // particular do it after calling the base class CleanUp() which can result - // in it being called -#if wxUSE_THREADS - delete m_idleMutex; - m_idleMutex = NULL; -#endif } void wxApp::WakeUpIdle() { #if wxUSE_THREADS - wxMutexLocker lock(*m_idleMutex); + wxMutexLocker lock(m_idleMutex); #endif if (m_idleSourceId == 0) m_idleSourceId = g_idle_add_full(G_PRIORITY_LOW, wxapp_idle_callback, NULL, NULL); @@ -489,7 +482,7 @@ void wxApp::WakeUpIdle() bool wxApp::EventsPending() { #if wxUSE_THREADS - wxMutexLocker lock(*m_idleMutex); + wxMutexLocker lock(m_idleMutex); #endif if (m_idleSourceId != 0) { @@ -535,3 +528,31 @@ void wxGUIAppTraits::MutexGuiLeave() gdk_threads_leave(); } #endif // wxUSE_THREADS + +/* static */ +bool wxApp::GTKIsUsingGlobalMenu() +{ + static int s_isUsingGlobalMenu = -1; + if ( s_isUsingGlobalMenu == -1 ) + { + // Currently we just check for this environment variable because this + // is how support for the global menu is implemented under Ubuntu. + // + // If we ever get false positives, we could also check for + // XDG_CURRENT_DESKTOP env var being set to "Unity". + wxString proxy; + s_isUsingGlobalMenu = wxGetEnv("UBUNTU_MENUPROXY", &proxy) && + !proxy.empty() && proxy != "0"; + } + + return s_isUsingGlobalMenu == 1; +} + +#if wxUSE_LIBHILDON || wxUSE_LIBHILDON2 +// Maemo-specific method: get the main program object +HildonProgram *wxApp::GetHildonProgram() +{ + return hildon_program_get_instance(); +} + +#endif // wxUSE_LIBHILDON || wxUSE_LIBHILDON2