renaissance1: #i107215# Workaround fix for accessibility deadlock on Solaris.

This commit is contained in:
Andre Fischer
2010-06-16 14:35:53 +02:00
parent 9d350375a7
commit a72371004c
3 changed files with 93 additions and 16 deletions

View File

@@ -62,6 +62,14 @@ using namespace ::com::sun::star::accessibility;
namespace accessibility {
/** Inner implementation class of the AccessibleSlideSorterView.
Note that some event broadcasting is done asynchronously because
otherwise it could lead to deadlocks on (at lease) some Solaris
machines. Probably (but unverified) this can happen on all GTK based
systems. The asynchronous broadcasting is just a workaround for a
poorly understood problem.
*/
class AccessibleSlideSorterView::Implementation
: public SfxListener
{
@@ -72,7 +80,7 @@ public:
::Window* pWindow);
~Implementation (void);
void UpdateChildren (void);
void RequestUpdateChildren (void);
void Clear (void);
sal_Int32 GetVisibleChildCount (void) const;
AccessibleSlideSorterObject* GetAccessibleChild (sal_Int32 nIndex);
@@ -83,8 +91,9 @@ public:
void Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint);
DECL_LINK(WindowEventListener, VclWindowEvent*);
DECL_LINK(SelectionChangeListener, void*);
DECL_LINK(BroadcastSelectionChange, void*);
DECL_LINK(FocusChangeListener, void*);
DECL_LINK(VisibilityChangeListener, void*);
DECL_LINK(UpdateChildrenCallback, void*);
private:
AccessibleSlideSorterView& mrAccessibleSlideSorter;
@@ -97,6 +106,10 @@ private:
::Window* mpWindow;
sal_Int32 mnFocusedIndex;
bool mbModelChangeLocked;
ULONG mnUpdateChildrenUserEventId;
ULONG mnSelectionChangeUserEventId;
void UpdateChildren (void);
};
@@ -115,7 +128,6 @@ AccessibleSlideSorterView::AccessibleSlideSorterView(
mnClientId(0),
mpContentWindow(pContentWindow)
{
OSL_TRACE("creating AccessibleSlideSorterView");
}
@@ -771,6 +783,9 @@ sal_Bool AccessibleSlideSorterView::IsDisposed (void)
return (rBHelper.bDisposed || rBHelper.bInDispose);
}
//===== AccessibleSlideSorterView::Implementation =============================
AccessibleSlideSorterView::Implementation::Implementation (
@@ -785,7 +800,9 @@ AccessibleSlideSorterView::Implementation::Implementation (
mbListeningToDocument(false),
mpWindow(pWindow),
mnFocusedIndex(-1),
mbModelChangeLocked(false)
mbModelChangeLocked(false),
mnUpdateChildrenUserEventId(0),
mnSelectionChangeUserEventId(0)
{
ConnectListeners();
UpdateChildren();
@@ -796,6 +813,10 @@ AccessibleSlideSorterView::Implementation::Implementation (
AccessibleSlideSorterView::Implementation::~Implementation (void)
{
if (mnUpdateChildrenUserEventId != 0)
Application::RemoveUserEvent(mnUpdateChildrenUserEventId);
if (mnSelectionChangeUserEventId != 0)
Application::RemoveUserEvent(mnSelectionChangeUserEventId);
ReleaseListeners();
Clear();
}
@@ -803,6 +824,17 @@ AccessibleSlideSorterView::Implementation::~Implementation (void)
void AccessibleSlideSorterView::Implementation::RequestUpdateChildren (void)
{
if (mnUpdateChildrenUserEventId == 0)
mnUpdateChildrenUserEventId = Application::PostUserEvent(
LINK(this, AccessibleSlideSorterView::Implementation,
UpdateChildrenCallback));
}
void AccessibleSlideSorterView::Implementation::UpdateChildren (void)
{
if (mbModelChangeLocked)
@@ -928,7 +960,7 @@ void AccessibleSlideSorterView::Implementation::ConnectListeners (void)
mrSlideSorter.GetController().GetFocusManager().AddFocusChangeListener(
LINK(this,AccessibleSlideSorterView::Implementation,FocusChangeListener));
mrSlideSorter.GetView().AddVisibilityChangeListener(
LINK(this,AccessibleSlideSorterView::Implementation,VisibilityChangeListener));
LINK(this,AccessibleSlideSorterView::Implementation,UpdateChildrenCallback));
}
@@ -941,7 +973,7 @@ void AccessibleSlideSorterView::Implementation::ReleaseListeners (void)
mrSlideSorter.GetController().GetSelectionManager()->RemoveSelectionChangeListener(
LINK(this,AccessibleSlideSorterView::Implementation,SelectionChangeListener));
mrSlideSorter.GetView().RemoveVisibilityChangeListener(
LINK(this,AccessibleSlideSorterView::Implementation,VisibilityChangeListener));
LINK(this,AccessibleSlideSorterView::Implementation,UpdateChildrenCallback));
if (mpWindow != NULL)
mpWindow->RemoveEventListener(
@@ -969,7 +1001,7 @@ void AccessibleSlideSorterView::Implementation::Notify (
switch (rSdrHint.GetKind())
{
case HINT_PAGEORDERCHG:
UpdateChildren();
RequestUpdateChildren();
break;
default:
break;
@@ -986,7 +1018,7 @@ void AccessibleSlideSorterView::Implementation::Notify (
case sd::ViewShellHint::HINT_COMPLEX_MODEL_CHANGE_END:
mbModelChangeLocked = false;
UpdateChildren();
RequestUpdateChildren();
break;
default:
break;
@@ -1003,7 +1035,7 @@ IMPL_LINK(AccessibleSlideSorterView::Implementation, WindowEventListener, VclWin
{
case VCLEVENT_WINDOW_MOVE:
case VCLEVENT_WINDOW_RESIZE:
UpdateChildren();
RequestUpdateChildren();
break;
case VCLEVENT_WINDOW_GETFOCUS:
@@ -1024,6 +1056,18 @@ IMPL_LINK(AccessibleSlideSorterView::Implementation, WindowEventListener, VclWin
IMPL_LINK(AccessibleSlideSorterView::Implementation, SelectionChangeListener, void*, EMPTYARG )
{
if (mnSelectionChangeUserEventId == 0)
mnSelectionChangeUserEventId = Application::PostUserEvent(
LINK(this, AccessibleSlideSorterView::Implementation, BroadcastSelectionChange));
return 1;
}
IMPL_LINK(AccessibleSlideSorterView::Implementation, BroadcastSelectionChange, void*, EMPTYARG )
{
mnSelectionChangeUserEventId = 0;
mrAccessibleSlideSorter.FireAccessibleEvent(
AccessibleEventId::SELECTION_CHANGED,
Any(),
@@ -1067,8 +1111,9 @@ IMPL_LINK(AccessibleSlideSorterView::Implementation, FocusChangeListener, void*,
IMPL_LINK(AccessibleSlideSorterView::Implementation, VisibilityChangeListener, void*, EMPTYARG )
IMPL_LINK(AccessibleSlideSorterView::Implementation, UpdateChildrenCallback, void*, EMPTYARG )
{
mnUpdateChildrenUserEventId = 0;
UpdateChildren();
return 1;

View File

@@ -130,7 +130,9 @@ Clipboard::Clipboard (SlideSorter& rSlideSorter)
maPagesToRemove(),
maPagesToSelect(),
mbUpdateSelectionPending(false),
mpUndoContext()
mpUndoContext(),
mpSelectionObserverContext(),
mnDragFinishedUserEventId(0)
{
}
@@ -139,6 +141,8 @@ Clipboard::Clipboard (SlideSorter& rSlideSorter)
Clipboard::~Clipboard (void)
{
if (mnDragFinishedUserEventId != 0)
Application::RemoveUserEvent(mnDragFinishedUserEventId);
}
@@ -506,16 +510,36 @@ void Clipboard::StartDrag (
void Clipboard::DragFinished (sal_Int8 nDropAction)
{
SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag;
if (pDragTransferable != NULL)
pDragTransferable->SetView (NULL);
if (mnDragFinishedUserEventId == 0)
{
if ( ! Application::PostUserEvent(
mnDragFinishedUserEventId,
LINK(this, Clipboard, ProcessDragFinished),
reinterpret_cast<void*>(nDropAction)))
{
mnDragFinishedUserEventId = 0;
}
}
}
IMPL_LINK(Clipboard, ProcessDragFinished, void*, pUserData)
{
const sal_Int8 nDropAction (static_cast<sal_Int8>(reinterpret_cast<sal_IntPtr>(pUserData)));
mnDragFinishedUserEventId = 0;
// Hide the substitution display and insertion indicator.
::rtl::Reference<SelectionFunction> pFunction (mrController.GetCurrentSelectionFunction());
if (pFunction.is())
pFunction->NotifyDragFinished();
SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag;
if (pDragTransferable != NULL)
pDragTransferable->SetView (NULL);
PageSelector& rSelector (mrController.GetPageSelector());
if ((nDropAction & DND_ACTION_MOVE) != 0
&& ! maPagesToRemove.empty())
@@ -534,6 +558,8 @@ void Clipboard::DragFinished (sal_Int8 nDropAction)
}
mpUndoContext.reset();
mpSelectionObserverContext.reset();
return 1;
}

View File

@@ -137,6 +137,7 @@ private:
::boost::scoped_ptr<UndoContext> mpUndoContext;
::boost::scoped_ptr<SelectionObserver::Context> mpSelectionObserverContext;
ULONG mnDragFinishedUserEventId;
void CreateSlideTransferable (
::Window* pWindow,
@@ -219,6 +220,11 @@ private:
::sd::Window* pTargetWindow,
USHORT nPage,
USHORT nLayer);
/** Asynchronous part of DragFinished. The argument is the sal_Int8
nDropAction, disguised as void*.
*/
DECL_LINK(ProcessDragFinished, void*);
};
} } } // end of namespace ::sd::slidesorter::controller