summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPranav Kant <pranavk@collabora.co.uk>2017-08-04 11:17:06 +0530
committerJan Holesovsky <kendy@collabora.com>2017-11-15 17:07:12 +0100
commit3b487140f424d3cf515852c1cc12dbf3000b9358 (patch)
tree1a1069d6cecf050434825061a07f7ed3d4afda70
parent1b8c684c0d0e8edf3bb740693bd76c1f2f4ad298 (diff)
lokdialog: Mouse events for dialog floating child windows
Change-Id: I06a081835d246f752e57f8cc289162ed31fc91d4
-rw-r--r--desktop/source/lib/init.cxx24
-rw-r--r--include/LibreOfficeKit/LibreOfficeKit.h10
-rw-r--r--include/vcl/IDialogRenderable.hxx3
-rw-r--r--include/vcl/dialog.hxx3
-rw-r--r--include/vcl/floatwin.hxx1
-rw-r--r--libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx127
-rw-r--r--sw/inc/unotxdoc.hxx3
-rw-r--r--sw/source/uibase/uno/unotxdoc.cxx40
-rw-r--r--vcl/source/control/ctrl.cxx16
-rw-r--r--vcl/source/window/dialog.cxx36
-rw-r--r--vcl/source/window/floatwin.cxx9
11 files changed, 271 insertions, 1 deletions
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 66f340f71df5..8f582b639c69 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -583,6 +583,14 @@ static void doc_postDialogMouseEvent (LibreOfficeKitDocument* pThis,
int nCount,
int nButtons,
int nModifier);
+static void doc_postDialogChildMouseEvent (LibreOfficeKitDocument* pThis,
+ const char* pDialogId,
+ int nType,
+ int nX,
+ int nY,
+ int nCount,
+ int nButtons,
+ int nModifier);
static void doc_postUnoCommand(LibreOfficeKitDocument* pThis,
const char* pCommand,
const char* pArguments,
@@ -655,6 +663,7 @@ LibLODocument_Impl::LibLODocument_Impl(const uno::Reference <css::lang::XCompone
m_pDocumentClass->postDialogKeyEvent = doc_postDialogKeyEvent;
m_pDocumentClass->postMouseEvent = doc_postMouseEvent;
m_pDocumentClass->postDialogMouseEvent = doc_postDialogMouseEvent;
+ m_pDocumentClass->postDialogChildMouseEvent = doc_postDialogChildMouseEvent;
m_pDocumentClass->postUnoCommand = doc_postUnoCommand;
m_pDocumentClass->setTextSelection = doc_setTextSelection;
m_pDocumentClass->getTextSelection = doc_getTextSelection;
@@ -2312,6 +2321,21 @@ static void doc_postDialogMouseEvent(LibreOfficeKitDocument* pThis, const char*
pDoc->postDialogMouseEvent(aDialogID, nType, nX, nY, nCount, nButtons, nModifier);
}
+static void doc_postDialogChildMouseEvent(LibreOfficeKitDocument* pThis, const char* pDialogId, int nType, int nX, int nY, int nCount, int nButtons, int nModifier)
+{
+ SolarMutexGuard aGuard;
+
+ IDialogRenderable* pDoc = getDialogRenderable(pThis);
+ if (!pDoc)
+ {
+ gImpl->maLastExceptionMsg = "Document doesn't support dialog rendering";
+ return;
+ }
+
+ vcl::DialogID aDialogID = OUString::createFromAscii(pDialogId);
+ pDoc->postDialogChildMouseEvent(aDialogID, nType, nX, nY, nCount, nButtons, nModifier);
+}
+
static void doc_setTextSelection(LibreOfficeKitDocument* pThis, int nType, int nX, int nY)
{
SolarMutexGuard aGuard;
diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h
index 52a77407d52f..043c42041af4 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.h
+++ b/include/LibreOfficeKit/LibreOfficeKit.h
@@ -274,6 +274,16 @@ struct _LibreOfficeKitDocumentClass
int nButtons,
int nModifier);
+ /// WIP
+ void (*postDialogChildMouseEvent) (LibreOfficeKitDocument* pThis,
+ const char* pDialogId,
+ int nType,
+ int nX,
+ int nY,
+ int nCount,
+ int nButtons,
+ int nModifier);
+
#endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
};
diff --git a/include/vcl/IDialogRenderable.hxx b/include/vcl/IDialogRenderable.hxx
index 351839e46d02..561f910987c6 100644
--- a/include/vcl/IDialogRenderable.hxx
+++ b/include/vcl/IDialogRenderable.hxx
@@ -42,6 +42,9 @@ public:
virtual void postDialogMouseEvent(const DialogID& rDialogID, int nType, int nX, int nY,
int nCount, int nButtons, int nModifier) = 0;
+ virtual void postDialogChildMouseEvent(const DialogID& rDialogID, int nType, int nX, int nY,
+ int nCount, int nButtons, int nModifier) = 0;
+
// Callbacks
virtual void notifyDialogInvalidation(const DialogID& rDialogID) = 0;
diff --git a/include/vcl/dialog.hxx b/include/vcl/dialog.hxx
index fe500b470cf5..6a92883fa8e7 100644
--- a/include/vcl/dialog.hxx
+++ b/include/vcl/dialog.hxx
@@ -80,6 +80,9 @@ public:
void LogicMouseButtonDown(const MouseEvent& rMouseEvent);
void LogicMouseButtonUp(const MouseEvent& rMouseEvent);
void LogicMouseMove(const MouseEvent& rMouseEvent);
+ void LogicMouseButtonDownChild(const MouseEvent& rMouseEvent);
+ void LogicMouseButtonUpChild(const MouseEvent& rMouseEvent);
+ void LogicMouseMoveChild(const MouseEvent& rMouseEvent);
void LOKKeyInput(const KeyEvent& rKeyEvent);
void LOKKeyUp(const KeyEvent& rKeyEvent);
diff --git a/include/vcl/floatwin.hxx b/include/vcl/floatwin.hxx
index 680cc13131af..da69f7b9cbe7 100644
--- a/include/vcl/floatwin.hxx
+++ b/include/vcl/floatwin.hxx
@@ -129,6 +129,7 @@ public:
SAL_DLLPRIVATE Rectangle& ImplGetItemEdgeClipRect();
SAL_DLLPRIVATE bool ImplIsInPrivatePopupMode() const { return mbInPopupMode; }
virtual void doDeferredInit(WinBits nBits) override;
+ virtual void LogicInvalidate(const Rectangle* pRectangle) override;
public:
explicit FloatingWindow(vcl::Window* pParent, WinBits nStyle);
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
index e37f9f274062..1149f50230b6 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
@@ -34,11 +34,18 @@ struct GtvLokDialogPrivate
GtkWidget* pDialogDrawingArea;
GtkWidget* pFloatingWin;
+ // state for dialog
guint32 m_nLastButtonPressTime;
guint32 m_nLastButtonReleaseTime;
guint32 m_nKeyModifier;
guint32 m_nLastButtonPressed;
+ // state for child floating windows
+ guint32 m_nChildLastButtonPressTime;
+ guint32 m_nChildLastButtonReleaseTime;
+ guint32 m_nChildKeyModifier;
+ guint32 m_nChildLastButtonPressed;
+
gchar* dialogid;
};
@@ -462,6 +469,115 @@ gtv_lok_dialog_invalidate(GtvLokDialog* dialog)
gtk_widget_queue_draw(priv->pDialogDrawingArea);
}
+static gboolean
+gtv_lok_dialog_floating_win_signal_button(GtkWidget* /*pDialogChildDrawingArea*/, GdkEventButton* pEvent, gpointer userdata)
+{
+ GtvLokDialog* pDialog = GTV_LOK_DIALOG(userdata);
+ GtvLokDialogPrivate* priv = getPrivate(pDialog);
+
+ GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(gtk_window_get_transient_for(GTK_WINDOW(pDialog)));
+ LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(LOK_DOC_VIEW(window->lokdocview));
+
+ g_info("lok_dialog_floating_win_signal_button: %d, %d (in twips: %d, %d)",
+ (int)pEvent->x, (int)pEvent->y,
+ (int)pixelToTwip(pEvent->x),
+ (int)pixelToTwip(pEvent->y));
+
+ switch (pEvent->type)
+ {
+ case GDK_BUTTON_PRESS:
+ {
+ int nCount = 1;
+ if ((pEvent->time - priv->m_nChildLastButtonPressTime) < 250)
+ nCount++;
+ priv->m_nChildLastButtonPressTime = pEvent->time;
+ int nEventButton = 0;
+ switch (pEvent->button)
+ {
+ case 1:
+ nEventButton = MOUSE_LEFT;
+ break;
+ case 2:
+ nEventButton = MOUSE_MIDDLE;
+ break;
+ case 3:
+ nEventButton = MOUSE_RIGHT;
+ break;
+ }
+ priv->m_nChildLastButtonPressed = nEventButton;
+ pDocument->pClass->postDialogChildMouseEvent(pDocument,
+ priv->dialogid,
+ LOK_MOUSEEVENT_MOUSEBUTTONDOWN,
+ (pEvent->x),
+ (pEvent->y),
+ nCount,
+ nEventButton,
+ priv->m_nChildKeyModifier);
+
+ break;
+ }
+ case GDK_BUTTON_RELEASE:
+ {
+ int nCount = 1;
+ if ((pEvent->time - priv->m_nChildLastButtonReleaseTime) < 250)
+ nCount++;
+ priv->m_nChildLastButtonReleaseTime = pEvent->time;
+ int nEventButton = 0;
+ switch (pEvent->button)
+ {
+ case 1:
+ nEventButton = MOUSE_LEFT;
+ break;
+ case 2:
+ nEventButton = MOUSE_MIDDLE;
+ break;
+ case 3:
+ nEventButton = MOUSE_RIGHT;
+ break;
+ }
+ priv->m_nChildLastButtonPressed = nEventButton;
+ pDocument->pClass->postDialogChildMouseEvent(pDocument,
+ priv->dialogid,
+ LOK_MOUSEEVENT_MOUSEBUTTONUP,
+ (pEvent->x),
+ (pEvent->y),
+ nCount,
+ nEventButton,
+ priv->m_nChildKeyModifier);
+ break;
+ }
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+static gboolean
+gtv_lok_dialog_floating_win_signal_motion(GtkWidget* /*pDialogDrawingArea*/, GdkEventButton* pEvent, gpointer userdata)
+{
+ GtvLokDialog* pDialog = GTV_LOK_DIALOG(userdata);
+ GtvLokDialogPrivate* priv = getPrivate(pDialog);
+
+ GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(gtk_window_get_transient_for(GTK_WINDOW(pDialog)));
+ LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(LOK_DOC_VIEW(window->lokdocview));
+
+ g_info("lok_dialog_floating_win_signal_motion: %d, %d (in twips: %d, %d)",
+ (int)pEvent->x, (int)pEvent->y,
+ (int)pixelToTwip(pEvent->x),
+ (int)pixelToTwip(pEvent->y));
+
+ pDocument->pClass->postDialogChildMouseEvent(pDocument,
+ priv->dialogid,
+ LOK_MOUSEEVENT_MOUSEMOVE,
+ (pEvent->x),
+ (pEvent->y),
+ 1,
+ priv->m_nChildLastButtonPressed,
+ priv->m_nChildKeyModifier);
+
+ return FALSE;
+}
+
void gtv_lok_dialog_child_invalidate(GtvLokDialog* dialog, int nX, int nY)
{
g_info("Dialog's floating window invalidate");
@@ -477,7 +593,17 @@ void gtv_lok_dialog_child_invalidate(GtvLokDialog* dialog, int nX, int nY)
gtk_window_set_transient_for(GTK_WINDOW(priv->pFloatingWin), GTK_WINDOW(dialog));
gtk_window_set_destroy_with_parent(GTK_WINDOW(priv->pFloatingWin), true);
+
+ gtk_widget_add_events(pDrawingArea,
+ GDK_BUTTON_PRESS_MASK
+ |GDK_POINTER_MOTION_MASK
+ |GDK_BUTTON_RELEASE_MASK
+ |GDK_BUTTON_MOTION_MASK);
+
g_signal_connect(G_OBJECT(pDrawingArea), "draw", G_CALLBACK(gtv_lok_dialog_floating_win_draw), dialog);
+ g_signal_connect(G_OBJECT(pDrawingArea), "button-press-event", G_CALLBACK(gtv_lok_dialog_floating_win_signal_button), dialog);
+ g_signal_connect(G_OBJECT(pDrawingArea), "button-release-event", G_CALLBACK(gtv_lok_dialog_floating_win_signal_button), dialog);
+ g_signal_connect(G_OBJECT(pDrawingArea), "motion-notify-event", G_CALLBACK(gtv_lok_dialog_floating_win_signal_motion), dialog);
gtk_widget_set_size_request(priv->pFloatingWin, 1, 1);
gtk_window_set_type_hint(GTK_WINDOW(priv->pFloatingWin), GDK_WINDOW_TYPE_HINT_POPUP_MENU);
@@ -485,6 +611,7 @@ void gtv_lok_dialog_child_invalidate(GtvLokDialog* dialog, int nX, int nY)
gtk_widget_show_all(priv->pFloatingWin);
gtk_window_present(GTK_WINDOW(priv->pFloatingWin));
+ gtk_widget_grab_focus(pDrawingArea);
// Get the root coords of our new floating window
GdkWindow* pGdkWin = gtk_widget_get_window(GTK_WIDGET(dialog));
diff --git a/sw/inc/unotxdoc.hxx b/sw/inc/unotxdoc.hxx
index 8dbe8584a49b..f80d090273c6 100644
--- a/sw/inc/unotxdoc.hxx
+++ b/sw/inc/unotxdoc.hxx
@@ -460,6 +460,9 @@ public:
void postDialogMouseEvent(const vcl::DialogID& rDialogID, int nType, int nX, int nY,
int nCount, int nButtons, int nModifier) override;
+ void postDialogChildMouseEvent(const vcl::DialogID& rDialogID, int nType, int nX, int nY,
+ int nCount, int nButtons, int nModifier) override;
+
void notifyDialogInvalidation(const vcl::DialogID& rDialogID) override;
void notifyDialogChild(const vcl::DialogID& rDialogID, const OUString& rAction, const Point& rPos) override;
diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx
index 9ccb85598022..c9a5358e22f4 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -3815,6 +3815,46 @@ void SwXTextDocument::postDialogMouseEvent(const vcl::DialogID& rDialogID, int n
}
}
+
+void SwXTextDocument::postDialogChildMouseEvent(const vcl::DialogID& rDialogID, int nType, int nX, int nY,
+ int nCount, int nButtons, int nModifier)
+{
+ SolarMutexGuard aGuard;
+
+ // check if dialog is already open
+ SfxViewFrame* pViewFrame = pDocShell->GetView()->GetViewFrame();
+ SfxSlotPool* pSlotPool = SW_MOD()->GetSlotPool();
+ const SfxSlot* pSlot = pSlotPool->GetUnoSlot(rDialogID);
+ if (!pSlot)
+ {
+ SAL_WARN("lok.dialog", "No slot found for " << rDialogID);
+ return;
+ }
+ SfxChildWindow* pChild = pViewFrame->GetChildWindow(pSlot->GetSlotId());
+ if (pChild)
+ {
+ Dialog* pDialog = static_cast<Dialog*>(pChild->GetWindow());
+ Point aPos(nX , nY);
+ MouseEvent aEvent(aPos, nCount, MouseEventModifiers::SIMPLECLICK, nButtons, nModifier);
+
+ switch (nType)
+ {
+ case LOK_MOUSEEVENT_MOUSEBUTTONDOWN:
+ pDialog->LogicMouseButtonDownChild(aEvent);
+ break;
+ case LOK_MOUSEEVENT_MOUSEBUTTONUP:
+ pDialog->LogicMouseButtonUpChild(aEvent);
+ break;
+ case LOK_MOUSEEVENT_MOUSEMOVE:
+ pDialog->LogicMouseMoveChild(aEvent);
+ break;
+ default:
+ assert(false);
+ break;
+ }
+ }
+}
+
void SwXTextDocument::notifyDialogInvalidation(const vcl::DialogID& rDialogID)
{
SfxLokHelper::notifyDialogInvalidation(rDialogID);
diff --git a/vcl/source/control/ctrl.cxx b/vcl/source/control/ctrl.cxx
index 48f93e045145..909cf170651a 100644
--- a/vcl/source/control/ctrl.cxx
+++ b/vcl/source/control/ctrl.cxx
@@ -24,6 +24,7 @@
#include <vcl/svapp.hxx>
#include <vcl/event.hxx>
#include <vcl/ctrl.hxx>
+#include <vcl/floatwin.hxx>
#include <vcl/decoview.hxx>
#include <vcl/dialog.hxx>
#include <vcl/salnativewidgets.hxx>
@@ -424,7 +425,20 @@ void Control::LogicInvalidate(const Rectangle* /*pRectangle*/)
// ignore all of those
if (comphelper::LibreOfficeKit::isActive() && !comphelper::LibreOfficeKit::isDialogPainting())
{
- // For now just invalidate the whole dialog
+ // If parent is a floating window, trigger an invalidate there
+ vcl::Window* pWindow = this;
+ while (pWindow)
+ {
+ if (pWindow->ImplIsFloatingWindow())
+ {
+ dynamic_cast<FloatingWindow*>(pWindow)->LogicInvalidate(nullptr);
+ return;
+ }
+
+ pWindow = pWindow->GetParent();
+ }
+
+ // otherwise, for now, just invalidate the whole dialog
Dialog* pParentDlg = GetParentDialog();
if (pParentDlg)
pParentDlg->LogicInvalidate(nullptr);
diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx
index 50b79c6d5644..272d18202dd8 100644
--- a/vcl/source/window/dialog.cxx
+++ b/vcl/source/window/dialog.cxx
@@ -914,6 +914,42 @@ Size Dialog::PaintActiveFloatingWindow(VirtualDevice& rDevice)
return aRet;
}
+void Dialog::LogicMouseButtonDownChild(const MouseEvent& rMouseEvent)
+{
+ assert(comphelper::LibreOfficeKit::isActive());
+
+ ImplSVData* pSVData = ImplGetSVData();
+ FloatingWindow* pFirstFloat = pSVData->maWinData.mpFirstFloat;
+ if (pFirstFloat && pFirstFloat->GetParentDialog() == this)
+ {
+ ImplWindowFrameProc(pFirstFloat->ImplGetBorderWindow(), SalEvent::ExternalMouseButtonDown, &rMouseEvent);
+ }
+}
+
+void Dialog::LogicMouseButtonUpChild(const MouseEvent& rMouseEvent)
+{
+ assert(comphelper::LibreOfficeKit::isActive());
+
+ ImplSVData* pSVData = ImplGetSVData();
+ FloatingWindow* pFirstFloat = pSVData->maWinData.mpFirstFloat;
+ if (pFirstFloat && pFirstFloat->GetParentDialog() == this)
+ {
+ ImplWindowFrameProc(pFirstFloat->ImplGetBorderWindow(), SalEvent::ExternalMouseButtonUp, &rMouseEvent);
+ }
+}
+
+void Dialog::LogicMouseMoveChild(const MouseEvent& rMouseEvent)
+{
+ assert(comphelper::LibreOfficeKit::isActive());
+
+ ImplSVData* pSVData = ImplGetSVData();
+ FloatingWindow* pFirstFloat = pSVData->maWinData.mpFirstFloat;
+ if (pFirstFloat && pFirstFloat->GetParentDialog() == this)
+ {
+ ImplWindowFrameProc(pFirstFloat->ImplGetBorderWindow(), SalEvent::ExternalMouseMove, &rMouseEvent);
+ }
+}
+
void Dialog::InvalidateFloatingWindow(const Point& rPos)
{
if (comphelper::LibreOfficeKit::isActive() && mpDialogRenderable && !maID.isEmpty())
diff --git a/vcl/source/window/floatwin.cxx b/vcl/source/window/floatwin.cxx
index f3e4b7c799a6..fd936bcd6610 100644
--- a/vcl/source/window/floatwin.cxx
+++ b/vcl/source/window/floatwin.cxx
@@ -594,6 +594,15 @@ bool FloatingWindow::Notify( NotifyEvent& rNEvt )
return bRet;
}
+void FloatingWindow::LogicInvalidate(const Rectangle* /*pRectangle*/)
+{
+ Dialog* pParentDlg = GetParentDialog();
+ if (pParentDlg)
+ {
+ pParentDlg->InvalidateFloatingWindow(mpImplData->maPos);
+ }
+}
+
void FloatingWindow::StateChanged( StateChangedType nType )
{
if (nType == StateChangedType::InitShow)