desktop/source/lib/init.cxx | 24 +++ include/LibreOfficeKit/LibreOfficeKit.h | 10 + include/vcl/IDialogRenderable.hxx | 3 include/vcl/dialog.hxx | 3 libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx | 127 ++++++++++++++++++++ sw/inc/unotxdoc.hxx | 3 sw/source/uibase/uno/unotxdoc.cxx | 40 ++++++ vcl/source/window/dialog.cxx | 36 +++++ 8 files changed, 246 insertions(+)
New commits: commit fc8be5339ed8d7c9cbf73ea82357904da18d947a Author: Pranav Kant <pran...@collabora.co.uk> Date: Fri Aug 4 11:17:06 2017 +0530 lokdialog: Mouse events for dialog floating child windows It doesn't work as of now. The mosue events seems to hang the floating window completely. Change-Id: I06a081835d246f752e57f8cc289162ed31fc91d4 diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index e69627ba0e99..dc3e58fccf1a 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -556,6 +556,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, @@ -628,6 +636,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; @@ -2267,6 +2276,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 8781b1c78722..0b07c362143e 100644 --- a/include/LibreOfficeKit/LibreOfficeKit.h +++ b/include/LibreOfficeKit/LibreOfficeKit.h @@ -276,6 +276,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 126d358552c3..15bda7e56c59 100644 --- a/include/vcl/dialog.hxx +++ b/include/vcl/dialog.hxx @@ -81,6 +81,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 KeyInput(const KeyEvent& rKeyEvent); void KeyUp(const KeyEvent& rKeyEvent); diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx index e37f9f274062..76be36f9f948 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 5fc7d32c95a2..23e126321e69 100644 --- a/sw/inc/unotxdoc.hxx +++ b/sw/inc/unotxdoc.hxx @@ -434,6 +434,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 830e8acc9629..16c639a46f1a 100644 --- a/sw/source/uibase/uno/unotxdoc.cxx +++ b/sw/source/uibase/uno/unotxdoc.cxx @@ -3657,6 +3657,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/window/dialog.cxx b/vcl/source/window/dialog.cxx index a0e8aebb152e..6edbbbbdc5b2 100644 --- a/vcl/source/window/dialog.cxx +++ b/vcl/source/window/dialog.cxx @@ -896,6 +896,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, 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, 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, SalEvent::ExternalMouseMove, &rMouseEvent); + } +} + void Dialog::InvalidateFloatingWindow(const Point& rPos) { SAL_DEBUG("Dialog:: Invalidate Floating window"); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits