diff options
-rw-r--r-- | desktop/source/lib/init.cxx | 24 | ||||
-rw-r--r-- | include/LibreOfficeKit/LibreOfficeKit.h | 10 | ||||
-rw-r--r-- | include/vcl/IDialogRenderable.hxx | 3 | ||||
-rw-r--r-- | include/vcl/dialog.hxx | 3 | ||||
-rw-r--r-- | include/vcl/floatwin.hxx | 1 | ||||
-rw-r--r-- | libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx | 127 | ||||
-rw-r--r-- | sw/inc/unotxdoc.hxx | 3 | ||||
-rw-r--r-- | sw/source/uibase/uno/unotxdoc.cxx | 40 | ||||
-rw-r--r-- | vcl/source/control/ctrl.cxx | 16 | ||||
-rw-r--r-- | vcl/source/window/dialog.cxx | 36 | ||||
-rw-r--r-- | vcl/source/window/floatwin.cxx | 9 |
11 files changed, 271 insertions, 1 deletions
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index c5ca3666f9e7..c3f44114741b 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -564,6 +564,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, @@ -636,6 +644,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; @@ -2323,6 +2332,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 529a1336ca76..05c8eff15316 100644 --- a/include/LibreOfficeKit/LibreOfficeKit.h +++ b/include/LibreOfficeKit/LibreOfficeKit.h @@ -288,6 +288,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 5ab85be1842e..6cea3b193ec2 100644 --- a/include/vcl/dialog.hxx +++ b/include/vcl/dialog.hxx @@ -91,6 +91,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 fc7df3ada424..f0faa3c3e260 100644 --- a/include/vcl/floatwin.hxx +++ b/include/vcl/floatwin.hxx @@ -129,6 +129,7 @@ public: SAL_DLLPRIVATE tools::Rectangle& ImplGetItemEdgeClipRect(); SAL_DLLPRIVATE bool ImplIsInPrivatePopupMode() const { return mbInPopupMode; } virtual void doDeferredInit(WinBits nBits) override; + virtual void LogicInvalidate(const tools::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 3d269dcadc03..a803a6aa8e16 100644 --- a/sw/inc/unotxdoc.hxx +++ b/sw/inc/unotxdoc.hxx @@ -439,6 +439,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 9ab338fce7a0..c148f09ef873 100644 --- a/sw/source/uibase/uno/unotxdoc.cxx +++ b/sw/source/uibase/uno/unotxdoc.cxx @@ -3743,6 +3743,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 3bd877ea7162..38509814f5b0 100644 --- a/vcl/source/control/ctrl.cxx +++ b/vcl/source/control/ctrl.cxx @@ -23,6 +23,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> @@ -420,7 +421,20 @@ void Control::LogicInvalidate(const tools::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 29400ca55982..c34e9382d16e 100644 --- a/vcl/source/window/dialog.cxx +++ b/vcl/source/window/dialog.cxx @@ -906,6 +906,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 16bcb721a612..46b7b330efee 100644 --- a/vcl/source/window/floatwin.cxx +++ b/vcl/source/window/floatwin.cxx @@ -585,6 +585,15 @@ bool FloatingWindow::EventNotify( NotifyEvent& rNEvt ) return bRet; } +void FloatingWindow::LogicInvalidate(const tools::Rectangle* /*pRectangle*/) +{ + Dialog* pParentDlg = GetParentDialog(); + if (pParentDlg) + { + pParentDlg->InvalidateFloatingWindow(mpImplData->maPos); + } +} + void FloatingWindow::StateChanged( StateChangedType nType ) { if (nType == StateChangedType::InitShow) |