parent
4d8151edeb
commit
318686ce75
@ -0,0 +1,370 @@
|
||||
From 28fe78604ca46319ae596d04ddca206e6b2672a7 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
|
||||
Date: Fri, 21 Oct 2016 14:14:10 +0100
|
||||
Subject: [PATCH] catch and rethrow later uno exceptions within glib signals
|
||||
|
||||
after g_main_context_iteration when its safe to do so again
|
||||
|
||||
otherwise if something happens inside the glib signal
|
||||
callback and the exception skips the code waiting
|
||||
for the callback to return, subsequent attempts to
|
||||
show the native gtk3 error dialog will fail
|
||||
|
||||
Change-Id: I271c09f8f1f00c0eca76191fcb63ddf56c10060f
|
||||
---
|
||||
vcl/inc/unx/gtk/gtkdata.hxx | 2 ++
|
||||
vcl/inc/unx/gtk/gtkframe.hxx | 7 ++++
|
||||
vcl/unx/gtk3/gtk3gtkdata.cxx | 4 +++
|
||||
vcl/unx/gtk3/gtk3gtkframe.cxx | 75 ++++++++++++++++++++++++++-----------------
|
||||
4 files changed, 58 insertions(+), 30 deletions(-)
|
||||
|
||||
diff --git a/vcl/inc/unx/gtk/gtkdata.hxx b/vcl/inc/unx/gtk/gtkdata.hxx
|
||||
index f5e1e03..ffb0fb7 100644
|
||||
--- a/vcl/inc/unx/gtk/gtkdata.hxx
|
||||
+++ b/vcl/inc/unx/gtk/gtkdata.hxx
|
||||
@@ -97,6 +97,7 @@ class GtkData : public SalGenericData
|
||||
GSource* m_pUserEvent;
|
||||
osl::Mutex m_aDispatchMutex;
|
||||
oslCondition m_aDispatchCondition;
|
||||
+ css::uno::Any m_aException;
|
||||
bool blockIdleTimeout;
|
||||
|
||||
public:
|
||||
@@ -120,6 +121,7 @@ public:
|
||||
|
||||
inline GtkSalDisplay *GetGtkDisplay() const;
|
||||
bool BlockIdleTimeout() const { return blockIdleTimeout; }
|
||||
+ void setException(const css::uno::Any& rException) { m_aException = rException; }
|
||||
};
|
||||
|
||||
class GtkSalFrame;
|
||||
diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx
|
||||
index 0cdff6c..40ae9e2 100644
|
||||
--- a/vcl/inc/unx/gtk/gtkframe.hxx
|
||||
+++ b/vcl/inc/unx/gtk/gtkframe.hxx
|
||||
@@ -539,6 +539,13 @@ public:
|
||||
sal_uIntPtr GetNativeWindowHandle(GtkWidget *pWidget);
|
||||
virtual sal_uIntPtr GetNativeWindowHandle() override;
|
||||
|
||||
+ //Call the usual SalFrame Callback, but catch uno exceptionss and delegate
|
||||
+ //to GtkData to rethrow them after the gsignal is processed when its safe
|
||||
+ //to do so again in our own code after the g_main_context_iteration call
|
||||
+ //which triggers the gsignals.
|
||||
+ long CallCallbackExc(SalEvent nEvent, const void* pEvent) const;
|
||||
+
|
||||
+
|
||||
static void KeyCodeToGdkKey(const vcl::KeyCode& rKeyCode,
|
||||
guint* pGdkKeyCode, GdkModifierType *pGdkModifiers);
|
||||
|
||||
diff --git a/vcl/unx/gtk3/gtk3gtkdata.cxx b/vcl/unx/gtk3/gtk3gtkdata.cxx
|
||||
index 17cad89f..70f9249 100644
|
||||
--- a/vcl/unx/gtk3/gtk3gtkdata.cxx
|
||||
+++ b/vcl/unx/gtk3/gtk3gtkdata.cxx
|
||||
@@ -51,6 +51,8 @@
|
||||
# include <gdk/gdkx.h>
|
||||
#endif
|
||||
|
||||
+#include <cppuhelper/exc_hlp.hxx>
|
||||
+
|
||||
using namespace vcl_sal;
|
||||
|
||||
/***************************************************************
|
||||
@@ -478,6 +480,8 @@ SalYieldResult GtkData::Yield( bool bWait, bool bHandleAllCurrentEvents )
|
||||
if( wasOneEvent )
|
||||
bWasEvent = true;
|
||||
}
|
||||
+ if (m_aException.hasValue())
|
||||
+ ::cppu::throwException(m_aException);
|
||||
}
|
||||
else if( bWait )
|
||||
{
|
||||
diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx
|
||||
index 9fc972da..e5ddb07 100644
|
||||
--- a/vcl/unx/gtk3/gtk3gtkframe.cxx
|
||||
+++ b/vcl/unx/gtk3/gtk3gtkframe.cxx
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <vcl/svapp.hxx>
|
||||
#include <vcl/window.hxx>
|
||||
#include <vcl/settings.hxx>
|
||||
+#include <cppuhelper/exc_hlp.hxx>
|
||||
|
||||
#include <config_gio.h>
|
||||
|
||||
@@ -453,7 +454,7 @@ void GtkSalFrame::doKeyCallback( guint state,
|
||||
|
||||
if( bDown )
|
||||
{
|
||||
- bool bHandled = CallCallback( SalEvent::KeyInput, &aEvent );
|
||||
+ bool bHandled = CallCallbackExc( SalEvent::KeyInput, &aEvent );
|
||||
// #i46889# copy AlternateKeyCode handling from generic plugin
|
||||
if( ! bHandled )
|
||||
{
|
||||
@@ -463,16 +464,16 @@ void GtkSalFrame::doKeyCallback( guint state,
|
||||
aEvent.mnCode = aAlternate.nKeyCode;
|
||||
if( aAlternate.nCharCode )
|
||||
aEvent.mnCharCode = aAlternate.nCharCode;
|
||||
- CallCallback( SalEvent::KeyInput, &aEvent );
|
||||
+ CallCallbackExc( SalEvent::KeyInput, &aEvent );
|
||||
}
|
||||
}
|
||||
if( bSendRelease && ! aDel.isDeleted() )
|
||||
{
|
||||
- CallCallback( SalEvent::KeyUp, &aEvent );
|
||||
+ CallCallbackExc( SalEvent::KeyUp, &aEvent );
|
||||
}
|
||||
}
|
||||
else
|
||||
- CallCallback( SalEvent::KeyUp, &aEvent );
|
||||
+ CallCallbackExc( SalEvent::KeyUp, &aEvent );
|
||||
}
|
||||
|
||||
GtkSalFrame::GtkSalFrame( SalFrame* pParent, SalFrameStyleFlags nStyle )
|
||||
@@ -2611,7 +2612,7 @@ gboolean GtkSalFrame::signalButton( GtkWidget*, GdkEventButton* pEvent, gpointer
|
||||
|
||||
if (!aDel.isDeleted())
|
||||
{
|
||||
- pThis->CallCallback( nEventType, &aEvent );
|
||||
+ pThis->CallCallbackExc( nEventType, &aEvent );
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -2651,7 +2652,7 @@ gboolean GtkSalFrame::signalScroll(GtkWidget*, GdkEventScroll* pEvent, gpointer
|
||||
if (aEvent.mnScrollLines == 0)
|
||||
aEvent.mnScrollLines = 1;
|
||||
|
||||
- pThis->CallCallback(SalEvent::WheelMouse, &aEvent);
|
||||
+ pThis->CallCallbackExc(SalEvent::WheelMouse, &aEvent);
|
||||
}
|
||||
|
||||
if (pEvent->delta_y != 0.0)
|
||||
@@ -2665,7 +2666,7 @@ gboolean GtkSalFrame::signalScroll(GtkWidget*, GdkEventScroll* pEvent, gpointer
|
||||
if (aEvent.mnScrollLines == 0)
|
||||
aEvent.mnScrollLines = 1;
|
||||
|
||||
- pThis->CallCallback(SalEvent::WheelMouse, &aEvent);
|
||||
+ pThis->CallCallbackExc(SalEvent::WheelMouse, &aEvent);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -2675,7 +2676,7 @@ gboolean GtkSalFrame::signalScroll(GtkWidget*, GdkEventScroll* pEvent, gpointer
|
||||
aEvent.mnNotchDelta = 1;
|
||||
aEvent.mnScrollLines = 3;
|
||||
aEvent.mbHorz = false;
|
||||
- pThis->CallCallback(SalEvent::WheelMouse, &aEvent);
|
||||
+ pThis->CallCallbackExc(SalEvent::WheelMouse, &aEvent);
|
||||
break;
|
||||
|
||||
case GDK_SCROLL_DOWN:
|
||||
@@ -2683,7 +2684,7 @@ gboolean GtkSalFrame::signalScroll(GtkWidget*, GdkEventScroll* pEvent, gpointer
|
||||
aEvent.mnNotchDelta = -1;
|
||||
aEvent.mnScrollLines = 3;
|
||||
aEvent.mbHorz = false;
|
||||
- pThis->CallCallback(SalEvent::WheelMouse, &aEvent);
|
||||
+ pThis->CallCallbackExc(SalEvent::WheelMouse, &aEvent);
|
||||
break;
|
||||
|
||||
case GDK_SCROLL_LEFT:
|
||||
@@ -2691,7 +2692,7 @@ gboolean GtkSalFrame::signalScroll(GtkWidget*, GdkEventScroll* pEvent, gpointer
|
||||
aEvent.mnNotchDelta = 1;
|
||||
aEvent.mnScrollLines = 3;
|
||||
aEvent.mbHorz = true;
|
||||
- pThis->CallCallback(SalEvent::WheelMouse, &aEvent);
|
||||
+ pThis->CallCallbackExc(SalEvent::WheelMouse, &aEvent);
|
||||
break;
|
||||
|
||||
case GDK_SCROLL_RIGHT:
|
||||
@@ -2699,7 +2700,7 @@ gboolean GtkSalFrame::signalScroll(GtkWidget*, GdkEventScroll* pEvent, gpointer
|
||||
aEvent.mnNotchDelta = -1;
|
||||
aEvent.mnScrollLines = 3;
|
||||
aEvent.mbHorz = true;
|
||||
- pThis->CallCallback(SalEvent::WheelMouse, &aEvent);
|
||||
+ pThis->CallCallbackExc(SalEvent::WheelMouse, &aEvent);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2724,7 +2725,7 @@ void GtkSalFrame::gestureSwipe(GtkGestureSwipe* gesture, gdouble velocity_x, gdo
|
||||
aEvent.mnX = x;
|
||||
aEvent.mnY = y;
|
||||
|
||||
- pThis->CallCallback(SalEvent::Swipe, &aEvent);
|
||||
+ pThis->CallCallbackExc(SalEvent::Swipe, &aEvent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2742,7 +2743,7 @@ void GtkSalFrame::gestureLongPress(GtkGestureLongPress* gesture, gpointer frame)
|
||||
aEvent.mnX = x;
|
||||
aEvent.mnY = y;
|
||||
|
||||
- pThis->CallCallback(SalEvent::LongPress, &aEvent);
|
||||
+ pThis->CallCallbackExc(SalEvent::LongPress, &aEvent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2774,7 +2775,7 @@ gboolean GtkSalFrame::signalMotion( GtkWidget*, GdkEventMotion* pEvent, gpointer
|
||||
|
||||
vcl::DeletionListener aDel( pThis );
|
||||
|
||||
- pThis->CallCallback( SalEvent::MouseMove, &aEvent );
|
||||
+ pThis->CallCallbackExc( SalEvent::MouseMove, &aEvent );
|
||||
|
||||
if( ! aDel.isDeleted() )
|
||||
{
|
||||
@@ -2784,7 +2785,7 @@ gboolean GtkSalFrame::signalMotion( GtkWidget*, GdkEventMotion* pEvent, gpointer
|
||||
{
|
||||
pThis->maGeometry.nX = frame_x;
|
||||
pThis->maGeometry.nY = frame_y;
|
||||
- pThis->CallCallback( SalEvent::Move, nullptr );
|
||||
+ pThis->CallCallbackExc( SalEvent::Move, nullptr );
|
||||
}
|
||||
|
||||
if( ! aDel.isDeleted() )
|
||||
@@ -2811,7 +2812,7 @@ gboolean GtkSalFrame::signalCrossing( GtkWidget*, GdkEventCrossing* pEvent, gpoi
|
||||
aEvent.mnCode = GetMouseModCode( pEvent->state );
|
||||
aEvent.mnButton = 0;
|
||||
|
||||
- pThis->CallCallback( (pEvent->type == GDK_ENTER_NOTIFY) ? SalEvent::MouseMove : SalEvent::MouseLeave, &aEvent );
|
||||
+ pThis->CallCallbackExc( (pEvent->type == GDK_ENTER_NOTIFY) ? SalEvent::MouseMove : SalEvent::MouseLeave, &aEvent );
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -2858,7 +2859,7 @@ void GtkSalFrame::sizeAllocated(GtkWidget*, GdkRectangle *pAllocation, gpointer
|
||||
pThis->maGeometry.nWidth = pAllocation->width;
|
||||
pThis->maGeometry.nHeight = pAllocation->height;
|
||||
pThis->AllocateFrame();
|
||||
- pThis->CallCallback( SalEvent::Resize, nullptr );
|
||||
+ pThis->CallCallbackExc( SalEvent::Resize, nullptr );
|
||||
pThis->TriggerPaintEvent();
|
||||
}
|
||||
|
||||
@@ -2891,7 +2892,7 @@ gboolean GtkSalFrame::signalConfigure(GtkWidget*, GdkEventConfigure* pEvent, gpo
|
||||
pThis->updateScreenNumber();
|
||||
|
||||
if (bMoved)
|
||||
- pThis->CallCallback(SalEvent::Move, nullptr);
|
||||
+ pThis->CallCallbackExc(SalEvent::Move, nullptr);
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -2912,7 +2913,7 @@ void GtkSalFrame::TriggerPaintEvent()
|
||||
//that duplicates the amount of drawing and is hideously slow
|
||||
SAL_INFO("vcl.gtk3", "force painting" << 0 << "," << 0 << " " << maGeometry.nWidth << "x" << maGeometry.nHeight);
|
||||
SalPaintEvent aPaintEvt(0, 0, maGeometry.nWidth, maGeometry.nHeight, true);
|
||||
- CallCallback(SalEvent::Paint, &aPaintEvt);
|
||||
+ CallCallbackExc(SalEvent::Paint, &aPaintEvt);
|
||||
gtk_widget_queue_draw(GTK_WIDGET(m_pFixedContainer));
|
||||
}
|
||||
|
||||
@@ -2946,7 +2947,7 @@ gboolean GtkSalFrame::signalFocus( GtkWidget*, GdkEventFocus* pEvent, gpointer f
|
||||
|
||||
// in the meantime do not propagate focus get/lose if floats are open
|
||||
if( m_nFloats == 0 )
|
||||
- pThis->CallCallback( pEvent->in ? SalEvent::GetFocus : SalEvent::LoseFocus, nullptr );
|
||||
+ pThis->CallCallbackExc( pEvent->in ? SalEvent::GetFocus : SalEvent::LoseFocus, nullptr );
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -2955,7 +2956,7 @@ gboolean GtkSalFrame::signalMap(GtkWidget *, GdkEvent*, gpointer frame)
|
||||
{
|
||||
GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame);
|
||||
|
||||
- pThis->CallCallback( SalEvent::Resize, nullptr );
|
||||
+ pThis->CallCallbackExc( SalEvent::Resize, nullptr );
|
||||
pThis->TriggerPaintEvent();
|
||||
|
||||
return false;
|
||||
@@ -2965,7 +2966,7 @@ gboolean GtkSalFrame::signalUnmap( GtkWidget*, GdkEvent*, gpointer frame )
|
||||
{
|
||||
GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame);
|
||||
|
||||
- pThis->CallCallback( SalEvent::Resize, nullptr );
|
||||
+ pThis->CallCallbackExc( SalEvent::Resize, nullptr );
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -3068,7 +3069,7 @@ gboolean GtkSalFrame::signalKey(GtkWidget* pWidget, GdkEventKey* pEvent, gpointe
|
||||
aModEvt.mnTime = pEvent->time;
|
||||
aModEvt.mnModKeyCode = pThis->m_nKeyModifiers;
|
||||
|
||||
- pThis->CallCallback( SalEvent::KeyModChange, &aModEvt );
|
||||
+ pThis->CallCallbackExc( SalEvent::KeyModChange, &aModEvt );
|
||||
|
||||
}
|
||||
else
|
||||
@@ -3101,7 +3102,7 @@ gboolean GtkSalFrame::signalDelete( GtkWidget*, GdkEvent*, gpointer frame )
|
||||
if (bBackDrop)
|
||||
pThis->GetWindow()->Enable();
|
||||
|
||||
- pThis->CallCallback( SalEvent::Close, nullptr );
|
||||
+ pThis->CallCallbackExc( SalEvent::Close, nullptr );
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -3545,13 +3546,13 @@ void GtkSalFrame::IMHandler::deleteIMContext()
|
||||
void GtkSalFrame::IMHandler::doCallEndExtTextInput()
|
||||
{
|
||||
m_aInputEvent.mpTextAttr = nullptr;
|
||||
- m_pFrame->CallCallback( SalEvent::EndExtTextInput, nullptr );
|
||||
+ m_pFrame->CallCallbackExc( SalEvent::EndExtTextInput, nullptr );
|
||||
}
|
||||
|
||||
void GtkSalFrame::IMHandler::updateIMSpotLocation()
|
||||
{
|
||||
SalExtTextInputPosEvent aPosEvent;
|
||||
- m_pFrame->CallCallback( SalEvent::ExtTextInputPos, static_cast<void*>(&aPosEvent) );
|
||||
+ m_pFrame->CallCallbackExc( SalEvent::ExtTextInputPos, static_cast<void*>(&aPosEvent) );
|
||||
GdkRectangle aArea;
|
||||
aArea.x = aPosEvent.mnX;
|
||||
aArea.y = aPosEvent.mnY;
|
||||
@@ -3571,9 +3572,9 @@ void GtkSalFrame::IMHandler::sendEmptyCommit()
|
||||
aEmptyEv.maText.clear();
|
||||
aEmptyEv.mnCursorPos = 0;
|
||||
aEmptyEv.mnCursorFlags = 0;
|
||||
- m_pFrame->CallCallback( SalEvent::ExtTextInput, static_cast<void*>(&aEmptyEv) );
|
||||
+ m_pFrame->CallCallbackExc( SalEvent::ExtTextInput, static_cast<void*>(&aEmptyEv) );
|
||||
if( ! aDel.isDeleted() )
|
||||
- m_pFrame->CallCallback( SalEvent::EndExtTextInput, nullptr );
|
||||
+ m_pFrame->CallCallbackExc( SalEvent::EndExtTextInput, nullptr );
|
||||
}
|
||||
|
||||
void GtkSalFrame::IMHandler::endExtTextInput( EndExtTextInputFlags /*nFlags*/ )
|
||||
@@ -3788,7 +3789,7 @@ void GtkSalFrame::IMHandler::signalIMCommit( GtkIMContext* /*pContext*/, gchar*
|
||||
}
|
||||
if( ! bSingleCommit )
|
||||
{
|
||||
- pThis->m_pFrame->CallCallback( SalEvent::ExtTextInput, static_cast<void*>(&pThis->m_aInputEvent));
|
||||
+ pThis->m_pFrame->CallCallbackExc( SalEvent::ExtTextInput, static_cast<void*>(&pThis->m_aInputEvent));
|
||||
if( ! aDel.isDeleted() )
|
||||
pThis->doCallEndExtTextInput();
|
||||
}
|
||||
@@ -3902,7 +3903,7 @@ void GtkSalFrame::IMHandler::signalIMPreeditChanged( GtkIMContext*, gpointer im_
|
||||
SolarMutexGuard aGuard;
|
||||
vcl::DeletionListener aDel( pThis->m_pFrame );
|
||||
|
||||
- pThis->m_pFrame->CallCallback( SalEvent::ExtTextInput, static_cast<void*>(&pThis->m_aInputEvent));
|
||||
+ pThis->m_pFrame->CallCallbackExc( SalEvent::ExtTextInput, static_cast<void*>(&pThis->m_aInputEvent));
|
||||
if( bEndPreedit && ! aDel.isDeleted() )
|
||||
pThis->doCallEndExtTextInput();
|
||||
if( ! aDel.isDeleted() )
|
||||
@@ -4210,5 +4211,19 @@ void GtkSalFrame::signalDragDataGet(GtkWidget* /*widget*/, GdkDragContext* /*con
|
||||
pThis->m_pDragSource->dragDataGet(data, info);
|
||||
}
|
||||
|
||||
+long GtkSalFrame::CallCallbackExc(SalEvent nEvent, const void* pEvent) const
|
||||
+{
|
||||
+ long nRet = 0;
|
||||
+ try
|
||||
+ {
|
||||
+ nRet = CallCallback(nEvent, pEvent);
|
||||
+ }
|
||||
+ catch (const css::uno::Exception&)
|
||||
+ {
|
||||
+ GtkData *pSalData = static_cast<GtkData*>(GetSalData());
|
||||
+ pSalData->setException(::cppu::getCaughtException());
|
||||
+ }
|
||||
+ return nRet;
|
||||
+}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
--
|
||||
2.9.3
|
||||
|
Loading…
Reference in new issue