From b4efd0a0524eaa6c48892fb64f1408a1ee125ead Mon Sep 17 00:00:00 2001 From: Michael Schwendt Date: Sep 12 2009 14:08:26 +0000 Subject: - add wxGTK work-around patches to fix LabelTrack crash (shall fix #520917 and similar race-conditions) --- diff --git a/audacity-1.3.9-labeltrack-crash.patch b/audacity-1.3.9-labeltrack-crash.patch new file mode 100644 index 0000000..cfc8c20 --- /dev/null +++ b/audacity-1.3.9-labeltrack-crash.patch @@ -0,0 +1,270 @@ +diff -Nur audacity-src-1.3.9-orig/src/LabelTrack.cpp audacity-src-1.3.9/src/LabelTrack.cpp +--- audacity-src-1.3.9-orig/src/LabelTrack.cpp 2009-08-31 12:45:38.000000000 +0200 ++++ audacity-src-1.3.9/src/LabelTrack.cpp 2009-09-12 14:59:27.000000000 +0200 +@@ -57,6 +57,97 @@ + #include "Project.h" + #include "commands/CommandManager.h" + ++#if defined(__WXGTK__) ++// As of wxGTK 2.8.9, there is a problem in the wxClipboard class that ++// allows recursive event processing. This problem has been corrected ++// by wxWidgets 2.9+. However, this han't made it into a release yet, ++// so we have to work around it. ++// ++// This is done by pulling/merging in some code from wx29 and creating ++// the following class to capture events while accessing the clipboard ++// to prevent the asynchronous clipboard access from causing recursive ++// event processing. ++ ++#include ++#include ++ ++#include ++ ++extern GtkWidget *wxGetRootWindow(); ++ ++static void main_do_event(GdkEvent *event, wxArrayPtrVoid *queue) ++{ ++ switch (event->type) ++ { ++ case GDK_NOTHING: ++ // Ignore it ++ break; ++ ++ case GDK_SELECTION_REQUEST: ++ case GDK_SELECTION_NOTIFY: ++ case GDK_SELECTION_CLEAR: ++#if GTK_CHECK_VERSION(2,6,0) ++ case GDK_OWNER_CHANGE: ++#endif ++ // process it now ++ gtk_main_do_event(event); ++ break; ++ ++ default: ++ // process it later (but make a copy; the caller will free the event pointer) ++ queue->Add(gdk_event_copy(event)); ++ break; ++ } ++ ++ // don't allow idle callbacks while we're active ++ wxTheApp->SuspendIdleCallback(); ++ ++ return; ++} ++ ++class CaptureEvents ++{ ++ public: ++ CaptureEvents() ++ { ++#if wxUSE_LOG ++ // disable log flushing from here because a call to wxYield() shouldn't ++ // normally result in message boxes popping up &c ++ wxLog::Suspend(); ++#endif ++ ++ // temporarily replace the global GDK event handler with our function ++ gdk_event_handler_set((GdkEventFunc)main_do_event, &queue, NULL); ++ ++ // temporarily suspend idle callbacks ++ wxTheApp->SuspendIdleCallback(); ++ } ++ ++ virtual ~CaptureEvents() ++ { ++ gdk_event_handler_set((GdkEventFunc)gtk_main_do_event, NULL, NULL); ++ ++ // put all unprocessed GDK events back in the queue ++ GdkDisplay* disp = gtk_widget_get_display(wxGetRootWindow()); ++ size_t cnt = queue.GetCount(); ++ for (size_t i = 0; i < cnt; i++) { ++ GdkEvent* event = (GdkEvent*)queue[i]; ++ // NOTE: gdk_display_put_event makes a copy of the event passed to it ++ gdk_display_put_event(disp, event); ++ gdk_event_free(event); ++ } ++ ++#if wxUSE_LOG ++ // let the logs be flashed again ++ wxLog::Resume(); ++#endif ++ } ++ ++ private: ++ wxArrayPtrVoid queue; ++}; ++#endif ++ + wxFont LabelTrack::msFont; + + // static member variables. +@@ -74,13 +165,11 @@ + + int LabelTrack::mFontHeight=-1; + +- + LabelTrack *TrackFactory::NewLabelTrack() + { + return new LabelTrack(mDirManager); + } + +- + LabelTrack::LabelTrack(DirManager * projDirManager): + Track(projDirManager), + mbHitCenter(false), +@@ -969,6 +1058,9 @@ + + // copy data onto clipboard + if (wxTheClipboard->Open()) { ++#if defined(__WXGTK__) ++ CaptureEvents capture; ++#endif + wxTheClipboard->SetData(new wxTextDataObject(data)); + wxTheClipboard->Close(); + } +@@ -1001,6 +1093,9 @@ + + // copy the data on clipboard + if (wxTheClipboard->Open()) { ++#if defined(__WXGTK__) ++ CaptureEvents capture; ++#endif + wxTheClipboard->SetData(new wxTextDataObject(data)); + wxTheClipboard->Close(); + } +@@ -1021,10 +1116,13 @@ + wxString right=wxT(""); + + // if text data is available +- if (wxTheClipboard->IsSupported(wxDF_TEXT)) { ++ if (IsTextClipSupported()) { + if (wxTheClipboard->Open()) { ++#if defined(__WXGTK__) ++ CaptureEvents capture; ++#endif + wxTextDataObject data; +- wxTheClipboard->GetData( data ); ++ wxTheClipboard->GetData(data); + wxTheClipboard->Close(); + text = data.GetText(); + } +@@ -1077,6 +1175,10 @@ + /// @return true if the text data is available in the clipboard, false otherwise + bool LabelTrack::IsTextClipSupported() + { ++#if defined(__WXGTK__) ++ CaptureEvents capture; ++#endif ++ + return wxTheClipboard->IsSupported(wxDF_TEXT); + } + +diff -Nur audacity-src-1.3.9-orig/src/LabelTrack.h audacity-src-1.3.9/src/LabelTrack.h +--- audacity-src-1.3.9-orig/src/LabelTrack.h 2009-08-31 12:45:38.000000000 +0200 ++++ audacity-src-1.3.9/src/LabelTrack.h 2009-09-12 14:59:27.000000000 +0200 +@@ -129,7 +129,7 @@ + bool CutSelectedText(); + bool CopySelectedText(); + bool PasteSelectedText(double sel0, double sel1); +- bool IsTextClipSupported(); ++ static bool IsTextClipSupported(); + + // methods to set flags + void SetDragXPos(const int d) { mDragXPos = d; }; +diff -Nur audacity-src-1.3.9-orig/src/Menus.cpp audacity-src-1.3.9/src/Menus.cpp +--- audacity-src-1.3.9-orig/src/Menus.cpp 2009-08-31 12:45:38.000000000 +0200 ++++ audacity-src-1.3.9/src/Menus.cpp 2009-09-12 15:18:22.150741538 +0200 +@@ -1359,20 +1359,6 @@ + if (lt->IsTextSelected()) { + flags |= CutCopyAvailableFlag; + } +- +- // See AudacityProject::OnUpdateUI() for an explanation +- if (mInIdle) { +- if (lt->IsTextClipSupported()) { +- flags |= TextClipFlag; +- mTextClipFlag = TextClipFlag; +- } +- else { +- mTextClipFlag = 0; +- } +- } +- else { +- flags |= mTextClipFlag; +- } + } + else if (t->GetKind() == Track::Wave) { + flags |= WaveTracksExistFlag; +@@ -1422,6 +1408,9 @@ + if (GetZoom() > gMinZoom && (flags & TracksExistFlag)) + flags |= ZoomOutAvailableFlag; + ++ if ((flags & LabelTracksExistFlag) && LabelTrack::IsTextClipSupported()) ++ flags |= TextClipFlag; ++ + flags |= GetFocusedFrame(); + + if (IsPlayRegionLocked()) +diff -Nur audacity-src-1.3.9-orig/src/Project.cpp audacity-src-1.3.9/src/Project.cpp +--- audacity-src-1.3.9-orig/src/Project.cpp 2009-08-31 12:45:38.000000000 +0200 ++++ audacity-src-1.3.9/src/Project.cpp 2009-09-12 15:18:29.746745064 +0200 +@@ -653,13 +653,12 @@ + const wxSize & size) + : wxFrame(parent, id, wxT("Audacity"), pos, size), + mLastPlayMode(normalPlay), ++ mFreqWindow(NULL), + mRate((double) gPrefs->Read(wxT("/SamplingRate/DefaultProjectSampleRate"), AudioIO::GetOptimalSupportedSampleRate())), + mDefaultFormat((sampleFormat) gPrefs-> + Read(wxT("/SamplingRate/DefaultProjectSampleFormat"), floatSample)), + mSnapTo(0), + mDirty(false), +- mInIdle(false), +- mTextClipFlag(0), + mTrackPanel(NULL), + mTrackFactory(NULL), + mAutoScrolling(false), +@@ -689,8 +688,7 @@ + mWantSaveCompressed(false), + mLastEffect(NULL), + mLastEffectType(0), +- mLastEffectDesc(_("Repeat Last Effect")), +- mFreqWindow(NULL) ++ mLastEffectDesc(_("Repeat Last Effect")) + { + int widths[] = {-1, 130}; + mStatusBar = CreateStatusBar(2); +@@ -1644,19 +1642,7 @@ + + void AudacityProject::OnUpdateUI(wxUpdateUIEvent & event) + { +- // As of wxGTK 2.8.9, there is a problem in the wxClipboard class that +- // allows recursive event processing. This problem has been corrected +- // by wxWidgets changeset #45180. However, this han't made it into a +- // release yet, so we have to work around it. +- // +- // This is done by only checking the wxClipboard contents during an idle +- // event, thus preventing possible recursion during other event processing. +- // +- mInIdle = true; +- + UpdateMenus(); +- +- mInIdle = false; + } + + void AudacityProject::OnActivate(wxActivateEvent & event) +diff -Nur audacity-src-1.3.9-orig/src/Project.h audacity-src-1.3.9/src/Project.h +--- audacity-src-1.3.9-orig/src/Project.h 2009-08-31 12:45:38.000000000 +0200 ++++ audacity-src-1.3.9/src/Project.h 2009-09-12 15:18:26.812745135 +0200 +@@ -431,10 +431,6 @@ + + wxUint32 mLastFlags; + +- // see AudacityProject::OnUpdateUI() for explanation of next two +- bool mInIdle; +- wxUint32 mTextClipFlag; +- + // Window elements + + wxTimer *mTimer; diff --git a/audacity.spec b/audacity.spec index 74ff445..ff56b4b 100644 --- a/audacity.spec +++ b/audacity.spec @@ -5,7 +5,7 @@ Name: audacity Version: 1.3.9 -Release: 0.1.beta%{?dist} +Release: 0.2.beta%{?dist} Summary: Multitrack audio editor Group: Applications/Multimedia License: GPLv2 @@ -18,6 +18,7 @@ Source2: audacity.desktop Patch1: audacity-1.3.7-libmp3lame-default.patch Patch2: audacity-1.3.9-libdir.patch Patch3: audacity-1.3.8-gsocket-conflict.patch +Patch4: audacity-1.3.9-labeltrack-crash.patch Patch6: audacity-1.3.7-vamp-1.3.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -68,6 +69,7 @@ done grep -q -s __RPM_LIB * -R && exit 1 %patch3 -p1 -b .gsocket-conflict +%patch4 -p1 -b .labeltrack-crash %if 0%{?fedora} < 11 %patch6 -p1 -b .vamp-1.3 %endif @@ -146,6 +148,10 @@ update-desktop-database &> /dev/null || : %changelog +* Sat Sep 12 2009 Michael Schwendt - 1.3.9-0.2.beta +- add wxGTK work-around patches to fix LabelTrack crash + (shall fix #520917 and similar race-conditions) + * Thu Sep 3 2009 Michael Schwendt - 1.3.9-0.1.beta - upgrade to 1.3.9-beta - upstream's changes in the device prefs code make the audiodevdefaults