renaissance1: #i107215# Workaround fix for accessibility deadlock on Solaris.
This commit is contained in:
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user