You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
371 lines
14 KiB
371 lines
14 KiB
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
|
|
|