[Libreoffice-commits] core.git: Branch 'feature/lok_dialog' - 1575 commits - accessibility/inc accessibility/source android/Bootstrap android/.gitignore android/README android/source apple_remote/source avmedia/Library_avmedia.mk avmedia/Module_avmedia.mk avmedia/source basctl/inc basctl/source basctl/uiconfig basegfx/inc basegfx/source basic/inc basic/qa basic/source bean/com bean/native binaryurp/source bin/lint-ui.py bin/lo-all-static-libs bin/oss-fuzz-build.sh bin/update bin/update_pch bridges/CustomTarget_gcc3_ios_arm.mk bridges/inc bridges/Library_cpp_uno.mk bridges/Module_bridges.mk bridges/source canvas/Library_canvastools.mk canvas/source chart2/inc chart2/qa chart2/source cli_ure/source codemaker/source comphelper/inc comphelper/source compilerplugins/clang compilerplugins/Makefile.mk config_host/config_libepubgen.h.in config_host.mk.in configmgr/inc configmgr/source configure.ac connectivity/inc connectivity/Library_file.mk connectivity/source connectivity/workben cppcanvas/inc cppcanv as/source cppuhelper/source cppu/qa cppu/source cpputools/source cui/inc cui/Library_cui.mk cui/source cui/uiconfig dbaccess/inc dbaccess/Module_dbaccess.mk dbaccess/qa dbaccess/source dbaccess/win32 desktop/Executable_oosplash.mk desktop/inc desktop/qa desktop/source desktop/StaticLibrary_minidump.mk desktop/unx desktop/util desktop/win32 dictionaries distro-configs/LibreOfficeAndroidX86.conf distro-configs/LibreOfficeFlatpak.conf distro-configs/LibreOfficeiOS.conf download.lst drawinglayer/CppunitTest_drawinglayer_border.mk drawinglayer/inc drawinglayer/qa drawinglayer/source dtrans/source dtrans/test editeng/inc editeng/qa editeng/source embeddedobj/source embeddedobj/test embedserv/source emfio/CppunitTest_emfio_wmf_test.mk emfio/inc emfio/qa emfio/source eventattacher/source extensions/source extensions/test external/apache-commons external/beanshell external/boost external/cairo external/coinmp external/collada2gltf external/ct2n external/curl external/epoxy external/firebird external/freetype external/gpgme external/hsqldb external/hunspell external/icu external/jfreereport external/jpeg-turbo external/languagetool external/libcdr external/libcmis external/libepubgen external/libexttextcat external/libfreehand external/libgltf external/libjpeg-turbo external/liblangtag external/libmariadb external/libpng external/libqxp external/libwpd external/libxml2 external/libxmlsec external/libxslt external/libzmf external/mariadb-connector-c external/Module_external.mk external/more_fonts external/mysql-connector-cpp external/mysqlcppconn external/nss external/openldap external/owncloud-android-lib external/pdfium external/poppler external/python3 external/redland external/rhino external/xmlsec extras/source filter/Configuration_filter.mk filter/Library_graphicfilter.mk filter/qa filter/source forms/inc forms/source formula/inc formula/source fpicker/source fpicker/uiconfig framework/inc framework/Library_fwe.mk framework/qa framework/source .git-hooks/pre-commit .gitignore helpcontent2 hwpfilter/inc hwpfilter/qa hwpfilter/source i18nlangtag/qa i18nlangtag/source i18npool/inc i18npool/source icon-themes/breeze icon-themes/breeze_dark icon-themes/breeze_svg icon-themes/crystal icon-themes/elementary icon-themes/galaxy icon-themes/hicontrast icon-themes/oxygen icon-themes/sifr icon-themes/sifr_dark icon-themes/sifr_svg icon-themes/tango idlc/source include/apple_remote include/avmedia include/basegfx include/basic include/canvas include/comphelper include/connectivity include/default.rc include/drawinglayer include/editeng include/filter include/formula include/framework include/i18nlangtag include/LibreOfficeKit include/linguistic include/o3tl include/oox include/opencl include/osl include/prewin.h include/rtl include/sal include/sax include/sfx2 include/sot include/svl include/svtools include/svx include/systools include/test include/toolkit include/tools include/ucbhelper include/unotest include/unotools include/vbahelper include/vcl inclu de/xmloff include/xmlsecurity instsetoo_native/CustomTarget_setup.mk instsetoo_native/inc_openoffice ios/CustomTarget_Lo_Xcconfig.mk ios/experimental io/source javaunohelper/com javaunohelper/test jurt/com jurt/source jvmfwk/plugins jvmfwk/source l10ntools/inc l10ntools/source libreofficekit/Executable_gtktiledviewer.mk libreofficekit/qa libreofficekit/source lingucomponent/source linguistic/source logerrit lotuswordpro/inc lotuswordpro/source m4/libgcrypt.m4 Makefile.fetch Makefile.in mysqlc/Extension_mysql-connector-ooo.mk mysqlc/Library_mysqlc.mk mysqlc/source o3tl/qa odk/CustomTarget_build-examples.mk odk/docs odk/examples odk/source offapi/com officecfg/registry officecfg/util onlineupdate/Executable_test_updater_dialog.mk onlineupdate/Executable_updater.mk onlineupdate/Module_onlineupdate.mk onlineupdate/source onlineupdate/StaticLibrary_libmarverify.mk onlineupdate/workben oovbaapi/ooo oovbaapi/UnoApi_oovbaapi.mk oox/CppunitTest_oox_tokenmap.mk oox/inc oox/Library_oox.mk oox/ source opencl/inc opencl/source package/inc package/source postprocess/CustomTarget_fontconfig.mk postprocess/Module_postprocess.mk postprocess/Package_fontconfig.mk postprocess/qa postprocess/Rdb_services.mk pyuno/source qadevOOo/Jar_OOoRunner.mk qadevOOo/objdsc qadevOOo/tests readlicense_oo/docs readlicense_oo/license README.md registry/source reportbuilder/java reportdesign/inc reportdesign/Library_rptui.mk reportdesign/source reportdesign/util RepositoryExternal.mk Repository.mk ridljar/com sal/cppunittester sal/inc sal/osl sal/qa sal/rtl sal/textenc sal/util sax/qa sax/README sax/source scaddins/source sccomp/CppunitTest_sccomp_lpsolver.mk sccomp/CppunitTest_sccomp_solver.mk sccomp/Module_sccomp.mk sccomp/qa sc/CppunitTest_sc_arealinkobj.mk sc/CppunitTest_sc_datapilotitemobj.mk sc/CppunitTest_sc_macros_test.mk sc/CppunitTest_sc_subsequent_filters_test.mk sc/inc sc/Library_sc.mk sc/Library_vbaobj.mk sc/Module_sc.mk scp2/inc scp2/source sc/qa scripting/source sc/sdi sc/source sc/ uiconfig sc/UIConfig_scalc.mk sc/workben sd/CppunitTest_sd_import_tests_smartart.mk sdext/inc sdext/source sd/inc sd/Module_sd.mk sd/qa sd/source sd/uiconfig sd/xsl setup_native/source sfx2/classification sfx2/inc sfx2/Library_sfx.mk sfx2/qa sfx2/sdi sfx2/source shell/inc shell/qa shell/source slideshow/inc slideshow/source smoketest/libtest.cxx solenv/bin solenv/CompilerTest_compilerplugins_clang.mk solenv/flatpak-manifest.in solenv/gbuild solenv/gcc-wrappers solenv/gdb soltools/cpp soltools/mkdepend sot/inc sot/qa sot/source starmath/inc starmath/source starmath/uiconfig stoc/source stoc/test store/source svgio/inc svgio/qa svgio/source svl/inc svl/Library_svl.mk svl/qa svl/source svtools/inc svtools/Library_svt.mk svtools/qa svtools/source svtools/uiconfig svtools/UIConfig_svt.mk svx/inc svx/Library_svx.mk svx/sdi svx/source svx/uiconfig svx/UIConfig_svx.mk svx/util sw/CppunitTest_sw_rtfimport.mk sw/CppunitTest_sw_ww8export2.mk swext/mediawiki sw/inc sw/JunitTest_sw_complex.mk sw /qa sw/README sw/sdi sw/source sw/uiconfig test/Library_subsequenttest.mk test/source testtools/source toolkit/qa toolkit/source tools/inc tools/Library_tl.mk tools/qa tools/source translations ucbhelper/source ucb/Library_ucpcmis1.mk ucb/Library_ucpimage.mk ucb/Module_ucb.mk ucb/qa ucb/source udkapi/com UnoControls/source unotest/source unotools/inc unotools/source unoxml/inc unoxml/qa unoxml/source uui/inc uui/source vbahelper/inc vbahelper/source vcl/android vcl/backendtest vcl/commonfuzzer.mk vcl/Executable_fodpfuzzer.mk vcl/Executable_fodsfuzzer.mk vcl/Executable_fodtfuzzer.mk vcl/headless vcl/inc vcl/ios vcl/Library_vcl.mk vcl/Module_vcl.mk vcl/null vcl/opengl vcl/osx vcl/qa vcl/quartz vcl/README.scheduler vcl/source vcl/unx vcl/win vcl/workben winaccessibility/inc winaccessibility/Library_uacccom.mk winaccessibility/Library_winaccessibility.mk winaccessibility/source wizards/com wizards/source writerfilter/inc writerfilter/source writerperfect/CppunitTest_writerperfect_epubex port.mk writerperfect/Library_wpftdraw.mk writerperfect/Library_wpftwriter.mk writerperfect/Module_writerperfect.mk writerperfect/qa writerperfect/source writerperfect/uiconfig writerperfect/UIConfig_writerperfect.mk writerperfect/UITest_writerperfect_epubexport.mk xmlhelp/source xmlhelp/util xmloff/inc xmloff/source xmlreader/source xmlscript/inc xmlscript/source xmlsecurity/inc xmlsecurity/Library_xmlsecurity.mk xmlsecurity/Library_xsec_xmlsec.mk xmlsecurity/Module_xmlsecurity.mk xmlsecurity/qa xmlsecurity/source xmlsecurity/uiconfig xmlsecurity/workben

Pranav Kant pranavk at collabora.co.uk
Mon Sep 25 06:14:34 UTC 2017


Rebased ref, commits from common ancestor:
commit 20f04025ca8b5ff60ebb9e46fcbd162b3e30193c
Author: Pranav Kant <pranavk at collabora.co.uk>
Date:   Fri Aug 18 15:26:26 2017 +0530

    lokdialog: lok header changes
    
    Change-Id: I1947dc84c91e2e01072fbff3e97aa94d514ecb5a

diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx
index 10e0f0f199d0..d4e891af218a 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.hxx
+++ b/include/LibreOfficeKit/LibreOfficeKit.hxx
@@ -156,6 +156,25 @@ public:
     }
 
     /**
+     * Renders a dialog with give dialog id and writes the width and height of the rendered dialog
+     *
+     * Client must truncate pBuffer according to the nWidth and nHeight returned after the call.
+     *
+     * @param pDialogId Unique dialog id to be painted
+     * @param pBuffer Buffer with enough memory allocated to render any dialog
+     * @param nWidth output parameter returning the width of the rendered dialog.
+     * @param nHeight output parameter returning the height of the rendered dialog
+     */
+    void paintDialog(const char* pDialogId,
+                     unsigned char* pBuffer,
+                     int& nWidth,
+                     int& nHeight)
+    {
+        return mpDoc->pClass->paintDialog(mpDoc, pDialogId, pBuffer,
+                                          &nWidth, &nHeight);
+    }
+
+    /**
      * Gets the tile mode: the pixel format used for the pBuffer of paintTile().
      *
      * @return an element of the LibreOfficeKitTileMode enum.
@@ -236,6 +255,22 @@ public:
     }
 
     /**
+     * Posts a mouse event to the dialog with given id.
+     *
+     * @param aDialogId Dialog id where mouse event is to be posted
+     * @param nType Event type, like down, move or up.
+     * @param nX horizontal position in document coordinates
+     * @param nY vertical position in document coordinates
+     * @param nCount number of clicks: 1 for single click, 2 for double click
+     * @param nButtons: which mouse buttons: 1 for left, 2 for middle, 4 right
+     * @param nModifier: which keyboard modifier: (see include/vcl/vclenum.hxx for possible values)
+     */
+    void postDialogMouseEvent(const char* pDialogId, int nType, int nX, int nY, int nCount, int nButtons, int nModifier)
+    {
+        mpDoc->pClass->postDialogMouseEvent(mpDoc, pDialogId, nType, nX, nY, nCount, nButtons, nModifier);
+    }
+
+    /**
      * Posts an UNO command to the document.
      *
      * Example argument string:
commit 9b7a0e9860eceeda60e99d2a921e99a2341381c5
Author: Pranav Kant <pranavk at collabora.co.uk>
Date:   Wed Aug 16 08:46:40 2017 +0530

    CD_DIALOG_INVALIDATE -> DIALOG
    
    Change-Id: Ifdda1c868e19700013a0742a0a547c0a4e040fba

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 936c4d13e244..49b2b62639f4 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -782,7 +782,7 @@ void CallbackFlushHandler::queue(const int type, const char* data)
         case LOK_CALLBACK_SET_PART:
         case LOK_CALLBACK_TEXT_VIEW_SELECTION:
         case LOK_CALLBACK_INVALIDATE_HEADER:
-        case LOK_CALLBACK_DIALOG_INVALIDATE:
+        case LOK_CALLBACK_DIALOG:
         {
             const auto& pos = std::find_if(m_queue.rbegin(), m_queue.rend(),
                     [type] (const queue_type::value_type& elem) { return (elem.first == type); });
commit 05bbc0038fcf7e61351c49a5658f34ee39daf7f9
Author: Pranav Kant <pranavk at collabora.co.uk>
Date:   Tue Aug 15 18:54:02 2017 +0530

    lokdialog: Smoother mouse move on floating windows
    
    Do away with an early hack to create the floating window with every
    invalidate.
    
    This gets rid of persistent blinking when moving the mouse over a
    listbox, for example.
    
    Change-Id: Ida9367156605edc9835529f83529363ad97beaee

diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
index ec734a011a88..43c14712646a 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
@@ -598,34 +598,34 @@ void gtv_lok_dialog_child_invalidate(GtvLokDialog* dialog, int nX, int nY)
 
     GtvLokDialogPrivate* priv = getPrivate(dialog);
     // remove any existing floating windows, for now
-    if (priv->pFloatingWin)
-        gtk_widget_destroy(priv->pFloatingWin);
-
-    priv->pFloatingWin = gtk_window_new(GTK_WINDOW_POPUP);
-    GtkWidget* pDrawingArea = gtk_drawing_area_new();
-    gtk_container_add(GTK_CONTAINER(priv->pFloatingWin), pDrawingArea);
-
-    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);
-    gtk_window_set_screen(GTK_WINDOW(priv->pFloatingWin), gtk_window_get_screen(GTK_WINDOW(dialog)));
-
-    gtk_widget_show_all(priv->pFloatingWin);
-    gtk_window_present(GTK_WINDOW(priv->pFloatingWin));
-    gtk_widget_grab_focus(pDrawingArea);
+    if (!priv->pFloatingWin)
+    {
+        priv->pFloatingWin = gtk_window_new(GTK_WINDOW_POPUP);
+        GtkWidget* pDrawingArea = gtk_drawing_area_new();
+        gtk_container_add(GTK_CONTAINER(priv->pFloatingWin), pDrawingArea);
+
+        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);
+        gtk_window_set_screen(GTK_WINDOW(priv->pFloatingWin), gtk_window_get_screen(GTK_WINDOW(dialog)));
+
+        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));
@@ -633,6 +633,8 @@ void gtv_lok_dialog_child_invalidate(GtvLokDialog* dialog, int nX, int nY)
     int nrY = 0;
     gdk_window_get_root_coords(pGdkWin, nX, nY, &nrX, &nrY);
     gtk_window_move(GTK_WINDOW(priv->pFloatingWin), nrX, nrY);
+
+    gtk_widget_queue_draw(priv->pFloatingWin);
 }
 
 void gtv_lok_dialog_child_close(GtvLokDialog* dialog)
commit 724197ffa5f626f19a032efba56271742755c930
Author: Pranav Kant <pranavk at collabora.co.uk>
Date:   Tue Aug 15 18:32:40 2017 +0530

    lokdialog: Forward mouse button up/down events on border window
    
    This now makes selection of items from list box possible.
    
    Change-Id: I71d068aeb5a3933ef3cbec05eeccf39a87fc829a

diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx
index bf58e214ac9d..989c519435aa 100644
--- a/vcl/source/window/dialog.cxx
+++ b/vcl/source/window/dialog.cxx
@@ -919,7 +919,7 @@ void Dialog::LogicMouseButtonDownChild(const MouseEvent& rMouseEvent)
     FloatingWindow* pFirstFloat = pSVData->maWinData.mpFirstFloat;
     if (pFirstFloat && pFirstFloat->GetParentDialog() == this)
     {
-        ImplWindowFrameProc(pFirstFloat, SalEvent::ExternalMouseButtonDown, &rMouseEvent);
+        ImplWindowFrameProc(pFirstFloat->ImplGetBorderWindow(), SalEvent::ExternalMouseButtonDown, &rMouseEvent);
     }
 }
 
@@ -931,7 +931,7 @@ void Dialog::LogicMouseButtonUpChild(const MouseEvent& rMouseEvent)
     FloatingWindow* pFirstFloat = pSVData->maWinData.mpFirstFloat;
     if (pFirstFloat && pFirstFloat->GetParentDialog() == this)
     {
-        ImplWindowFrameProc(pFirstFloat, SalEvent::ExternalMouseButtonUp, &rMouseEvent);
+        ImplWindowFrameProc(pFirstFloat->ImplGetBorderWindow(), SalEvent::ExternalMouseButtonUp, &rMouseEvent);
     }
 }
 
@@ -943,7 +943,7 @@ void Dialog::LogicMouseMoveChild(const MouseEvent& rMouseEvent)
     FloatingWindow* pFirstFloat = pSVData->maWinData.mpFirstFloat;
     if (pFirstFloat && pFirstFloat->GetParentDialog() == this)
     {
-        ImplWindowFrameProc(pFirstFloat, SalEvent::ExternalMouseMove, &rMouseEvent);
+        ImplWindowFrameProc(pFirstFloat->ImplGetBorderWindow(), SalEvent::ExternalMouseMove, &rMouseEvent);
     }
 }
 
commit ba200dacc6ff8cb216613c0dff6b68c34d09974c
Author: Pranav Kant <pranavk at collabora.co.uk>
Date:   Tue Aug 15 14:23:26 2017 +0530

    lokdialog: button press type debug info
    
    Change-Id: I193e0ab82e998905b670f7de73daae784de3ef00

diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
index 76be36f9f948..ec734a011a88 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
@@ -113,7 +113,14 @@ gtv_lok_dialog_signal_button(GtkWidget* pDialogDrawingArea, GdkEventButton* pEve
     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_signal_button: %d, %d (in twips: %d, %d)",
+    std::string aEventType = "unknown";
+    if (pEvent->type == GDK_BUTTON_PRESS)
+        aEventType = "BUTTON_PRESS";
+    else if (pEvent->type == GDK_BUTTON_RELEASE)
+        aEventType = "BUTTON_RELEASE";
+
+    g_info("lok_dialog_signal_button (type: %s): %d, %d (in twips: %d, %d)",
+           aEventType.c_str(),
            (int)pEvent->x, (int)pEvent->y,
            (int)pixelToTwip(pEvent->x),
            (int)pixelToTwip(pEvent->y));
@@ -197,7 +204,7 @@ gtv_lok_dialog_signal_motion(GtkWidget* pDialogDrawingArea, GdkEventButton* pEve
     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_signal_button: %d, %d (in twips: %d, %d)",
+    g_info("lok_dialog_signal_motion: %d, %d (in twips: %d, %d)",
            (int)pEvent->x, (int)pEvent->y,
            (int)pixelToTwip(pEvent->x),
            (int)pixelToTwip(pEvent->y));
@@ -478,7 +485,14 @@ gtv_lok_dialog_floating_win_signal_button(GtkWidget* pDialogChildDrawingArea, Gd
     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)",
+    std::string aEventType = "unknown";
+    if (pEvent->type == GDK_BUTTON_PRESS)
+        aEventType = "BUTTON_PRESS";
+    else if (pEvent->type == GDK_BUTTON_RELEASE)
+        aEventType = "BUTTON_RELEASE";
+
+    g_info("lok_dialog_floating_win_signal_button (type: %s): %d, %d (in twips: %d, %d)",
+           aEventType.c_str(),
            (int)pEvent->x, (int)pEvent->y,
            (int)pixelToTwip(pEvent->x),
            (int)pixelToTwip(pEvent->y));
commit 0c878a641fac631147756b8cb964597c9f019762
Author: Pranav Kant <pranavk at collabora.co.uk>
Date:   Tue Aug 15 14:04:46 2017 +0530

    lokdialog: Proper floating window invalidation on mouse move

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/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/floatwin.cxx b/vcl/source/window/floatwin.cxx
index 44ce96c42843..2d117ca6e7e1 100644
--- a/vcl/source/window/floatwin.cxx
+++ b/vcl/source/window/floatwin.cxx
@@ -585,6 +585,17 @@ bool FloatingWindow::EventNotify( NotifyEvent& rNEvt )
     return bRet;
 }
 
+void FloatingWindow::LogicInvalidate(const tools::Rectangle* /*pRectangle*/)
+{
+    Dialog* pParentDlg = GetParentDialog();
+    SAL_DEBUG("FloatingWindow::LogicInvalidate");
+    if (pParentDlg)
+    {
+        SAL_DEBUG("emitiign FloatingWindow::LogicInvalidate");
+        pParentDlg->InvalidateFloatingWindow(mpImplData->maPos);
+    }
+}
+
 void FloatingWindow::StateChanged( StateChangedType nType )
 {
     if (nType == StateChangedType::InitShow)
@@ -593,7 +604,6 @@ void FloatingWindow::StateChanged( StateChangedType nType )
     }
 
     SystemWindow::StateChanged( nType );
-
     if (nType == StateChangedType::InitShow && IsVisible())
     {
         Dialog* pParentDlg = GetParentDialog();
commit b5acd982801541683e87e53af5669bc60533aae4
Author: Pranav Kant <pranavk at collabora.co.uk>
Date:   Thu Aug 10 17:24:40 2017 +0530

    lokdialog: Emit dialog close callback upon dialog close
    
    Change-Id: I4ccef76cc3b2926dd8916f825671bb732e101027

diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx
index cea063ecd728..11e0ac7a8bc9 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx
@@ -291,8 +291,8 @@ void LOKDocViewSigHandlers::dialog(LOKDocView* pDocView, gchar* pPayload, gpoint
     std::string aDialogId = aRoot.get<std::string>("dialogId");
     std::string aAction = aRoot.get<std::string>("action");
 
-    // we only understand 'invalidate' as of now
-    if (aAction != "invalidate")
+    // we only understand 'invalidate' and 'close' as of now
+    if (aAction != "invalidate" && aAction != "close")
         return;
 
     // temporary hack to invalidate all open dialogs
@@ -300,43 +300,48 @@ void LOKDocViewSigHandlers::dialog(LOKDocView* pDocView, gchar* pPayload, gpoint
     GList* pIt = nullptr;
     for (pIt = pChildWins; pIt != nullptr; pIt = pIt->next)
     {
-        gtv_lok_dialog_invalidate(GTV_LOK_DIALOG(pIt->data));
+        if (aAction == "close")
+        {
+            gtk_widget_destroy(GTK_WIDGET(pIt->data));
+        }
+        else if (aAction == "invalidate")
+            gtv_lok_dialog_invalidate(GTV_LOK_DIALOG(pIt->data));
     }
 }
 
 void LOKDocViewSigHandlers::dialogChild(LOKDocView* pDocView, gchar* pPayload, gpointer)
 {
-  GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(pDocView)));
-
-  std::stringstream aStream(pPayload);
-  boost::property_tree::ptree aRoot;
-  boost::property_tree::read_json(aStream, aRoot);
-  std::string aDialogId = aRoot.get<std::string>("dialogId");
-  std::string aAction = aRoot.get<std::string>("action");
-  std::string aPos = aRoot.get<std::string>("position");
-  gchar** ppCoordinates = g_strsplit(aPos.c_str(), ", ", 2);
-  gchar** ppCoordinate = ppCoordinates;
-  int nX = 0;
-  int nY = 0;
-
-  if (*ppCoordinate)
-      nX = atoi(*ppCoordinate);
-  ++ppCoordinate;
-  if (*ppCoordinate)
-      nY = atoi(*ppCoordinate);
-
-  g_strfreev(ppCoordinates);
-
-  // temporary hack to invalidate/close floating window of all opened dialogs
-  GList* pChildWins = gtv_application_window_get_all_child_windows(window);
-  GList* pIt = nullptr;
-  for (pIt = pChildWins; pIt != nullptr; pIt = pIt->next)
-  {
-      if (aAction == "invalidate")
-          gtv_lok_dialog_child_invalidate(GTV_LOK_DIALOG(pIt->data), nX, nY);
-      else if (aAction == "close")
-          gtv_lok_dialog_child_close(GTV_LOK_DIALOG(pIt->data));
-  }
+    GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(pDocView)));
+
+    std::stringstream aStream(pPayload);
+    boost::property_tree::ptree aRoot;
+    boost::property_tree::read_json(aStream, aRoot);
+    std::string aDialogId = aRoot.get<std::string>("dialogId");
+    std::string aAction = aRoot.get<std::string>("action");
+    std::string aPos = aRoot.get<std::string>("position");
+    gchar** ppCoordinates = g_strsplit(aPos.c_str(), ", ", 2);
+    gchar** ppCoordinate = ppCoordinates;
+    int nX = 0;
+    int nY = 0;
+
+    if (*ppCoordinate)
+        nX = atoi(*ppCoordinate);
+    ++ppCoordinate;
+    if (*ppCoordinate)
+        nY = atoi(*ppCoordinate);
+
+    g_strfreev(ppCoordinates);
+
+    // temporary hack to invalidate/close floating window of all opened dialogs
+    GList* pChildWins = gtv_application_window_get_all_child_windows(window);
+    GList* pIt = nullptr;
+    for (pIt = pChildWins; pIt != nullptr; pIt = pIt->next)
+    {
+        if (aAction == "invalidate")
+            gtv_lok_dialog_child_invalidate(GTV_LOK_DIALOG(pIt->data), nX, nY);
+        else if (aAction == "close")
+            gtv_lok_dialog_child_close(GTV_LOK_DIALOG(pIt->data));
+    }
 }
 
 gboolean LOKDocViewSigHandlers::configureEvent(GtkWidget* pWidget, GdkEventConfigure* /*pEvent*/, gpointer /*pData*/)
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-signal-handlers.cxx b/libreofficekit/qa/gtktiledviewer/gtv-signal-handlers.cxx
index b871d93667f9..6ca78a61a2b2 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-signal-handlers.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-signal-handlers.cxx
@@ -293,6 +293,16 @@ void changePartMode( GtkWidget* pSelector, gpointer /* pItem */ )
 static gboolean deleteLokDialog(GtkWidget* pWidget, GdkEvent* /*event*/, gpointer userdata)
 {
     GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(userdata);
+    g_info("deletLokDialog");
+    gtv_application_window_unregister_child_window(window, GTK_WINDOW(pWidget));
+
+    return FALSE;
+}
+
+static gboolean destroyLokDialog(GtkWidget* pWidget, gpointer userdata)
+{
+    GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(userdata);
+    g_info("destroyLokDialog");
     gtv_application_window_unregister_child_window(window, GTK_WINDOW(pWidget));
 
     return FALSE;
@@ -304,9 +314,11 @@ void openLokDialog( GtkWidget* pSelector, gpointer /*pItem*/ )
     gchar* pDialogId = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(pSelector));
     GtkWidget* pDialog = gtv_lok_dialog_new(LOK_DOC_VIEW(window->lokdocview), pDialogId);
     gtv_application_window_register_child_window(window, GTK_WINDOW(pDialog));
+    g_signal_connect(pDialog, "destroy", G_CALLBACK(destroyLokDialog), window);
     g_signal_connect(pDialog, "delete-event", G_CALLBACK(deleteLokDialog), window);
     g_free(pDialogId);
 
+    g_info("openLokDialog");
     gtk_window_set_resizable(GTK_WINDOW(pDialog), false);
     gtk_widget_show_all(GTK_WIDGET(pDialog));
     gtk_window_present(GTK_WINDOW(pDialog));
diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx
index eed393f3e298..bf58e214ac9d 100644
--- a/vcl/source/window/dialog.cxx
+++ b/vcl/source/window/dialog.cxx
@@ -588,6 +588,11 @@ void Dialog::dispose()
     xEventBroadcaster->documentEventOccured(aObject);
     UITestLogger::getInstance().log("DialogClosed");
 
+    if (comphelper::LibreOfficeKit::isActive() && mpDialogRenderable)
+    {
+        mpDialogRenderable->notifyDialog(maID, "close");
+    }
+
     SystemWindow::dispose();
 }
 
commit ba2ad3b160ca5df63fca8c1b42baa4f32f2bcdb4
Author: Pranav Kant <pranavk at collabora.co.uk>
Date:   Thu Aug 10 16:44:06 2017 +0530

    Change CB_DIALOG_INVALIDATE to CB_DIALOG
    
    We can specify whether it is an invalidation or something else in the
    payload.
    
    Change-Id: I95c5fc0a0a88b5277eaa93c8d1f9b937bddce7b3

diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h
index 4c70560690da..62b9faf7ecb4 100644
--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h
+++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h
@@ -525,7 +525,7 @@ typedef enum
     /**
      * Dialog invalidation
      */
-    LOK_CALLBACK_DIALOG_INVALIDATE = 36,
+    LOK_CALLBACK_DIALOG = 36,
 
     /**
      * Invalidation corresponding to dialog's children.
diff --git a/include/sfx2/lokhelper.hxx b/include/sfx2/lokhelper.hxx
index b57f30a0ccba..432628c89132 100644
--- a/include/sfx2/lokhelper.hxx
+++ b/include/sfx2/lokhelper.hxx
@@ -40,8 +40,8 @@ public:
     static void notifyOtherViews(SfxViewShell* pThisView, int nType, const OString& rKey, const OString& rPayload);
     /// Same as notifyOtherViews(), but works on a selected "other" view, not on all of them.
     static void notifyOtherView(SfxViewShell* pThisView, SfxViewShell const* pOtherView, int nType, const OString& rKey, const OString& rPayload);
-    /// Emits a LOK_CALLBACK_DIALOG_INVALIDATE
-    static void notifyDialogInvalidation(const OUString& rPayload);
+    /// Emits a LOK_CALLBACK_DIALOG
+    static void notifyDialog(const OUString& rPayload, const OUString& rAction);
     /// Emits a LOK_CALLBACK_DIALOG_CHILD
     static void notifyDialogChild(const OUString& rDialogID, const OUString& rAction, const Point& rPos);
     /// Emits a LOK_CALLBACK_INVALIDATE_TILES, but tweaks it according to setOptionalFeatures() if needed.
diff --git a/include/vcl/IDialogRenderable.hxx b/include/vcl/IDialogRenderable.hxx
index 561f910987c6..02e959ea6fad 100644
--- a/include/vcl/IDialogRenderable.hxx
+++ b/include/vcl/IDialogRenderable.hxx
@@ -46,7 +46,7 @@ public:
                                            int nCount, int nButtons, int nModifier) = 0;
 
     // Callbacks
-    virtual void notifyDialogInvalidation(const DialogID& rDialogID) = 0;
+    virtual void notifyDialog(const DialogID& rDialogID, const OUString& rAction) = 0;
 
     virtual void notifyDialogChild(const DialogID& rDialogID, const OUString& rAction, const Point& rPos) = 0;
 };
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-application-window.cxx b/libreofficekit/qa/gtktiledviewer/gtv-application-window.cxx
index 8a5ff9a56d37..85c5b38466af 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-application-window.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-application-window.cxx
@@ -314,7 +314,7 @@ static void setupDocView(GtvApplicationWindow* window)
     g_signal_connect(window->lokdocview, "formula-changed", G_CALLBACK(LOKDocViewSigHandlers::formulaChanged), nullptr);
     g_signal_connect(window->lokdocview, "password-required", G_CALLBACK(LOKDocViewSigHandlers::passwordRequired), nullptr);
     g_signal_connect(window->lokdocview, "comment", G_CALLBACK(LOKDocViewSigHandlers::comment), nullptr);
-    g_signal_connect(window->lokdocview, "dialog-invalidate", G_CALLBACK(LOKDocViewSigHandlers::dialogInvalidate), nullptr);
+    g_signal_connect(window->lokdocview, "dialog", G_CALLBACK(LOKDocViewSigHandlers::dialog), nullptr);
     g_signal_connect(window->lokdocview, "dialog-child", G_CALLBACK(LOKDocViewSigHandlers::dialogChild), nullptr);
 
     g_signal_connect(window->lokdocview, "configure-event", G_CALLBACK(LOKDocViewSigHandlers::configureEvent), nullptr);
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx
index 1dc1d3a38e23..cea063ecd728 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx
@@ -281,10 +281,19 @@ void LOKDocViewSigHandlers::comment(LOKDocView* pDocView, gchar* pComment, gpoin
     }
 }
 
-void LOKDocViewSigHandlers::dialogInvalidate(LOKDocView* pDocView, gchar* pPayload, gpointer)
+void LOKDocViewSigHandlers::dialog(LOKDocView* pDocView, gchar* pPayload, gpointer)
 {
     GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(pDocView)));
-//    GtkWindow* pDialog = gtv_application_window_get_child_window_by_id(window, pDialogId);
+
+    std::stringstream aStream(pPayload);
+    boost::property_tree::ptree aRoot;
+    boost::property_tree::read_json(aStream, aRoot);
+    std::string aDialogId = aRoot.get<std::string>("dialogId");
+    std::string aAction = aRoot.get<std::string>("action");
+
+    // we only understand 'invalidate' as of now
+    if (aAction != "invalidate")
+        return;
 
     // temporary hack to invalidate all open dialogs
     GList* pChildWins = gtv_application_window_get_all_child_windows(window);
@@ -293,11 +302,6 @@ void LOKDocViewSigHandlers::dialogInvalidate(LOKDocView* pDocView, gchar* pPaylo
     {
         gtv_lok_dialog_invalidate(GTV_LOK_DIALOG(pIt->data));
     }
-/*  if (pDialog)
-    {
-        gtv_lok_dialog_invalidate(GTV_LOK_DIALOG(pDialog));
-    }
-*/
 }
 
 void LOKDocViewSigHandlers::dialogChild(LOKDocView* pDocView, gchar* pPayload, gpointer)
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.hxx b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.hxx
index a455c3f1fc4c..54f54b396bf3 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.hxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.hxx
@@ -25,7 +25,7 @@ namespace LOKDocViewSigHandlers {
     void formulaChanged(LOKDocView* pDocView, char* pPayload, gpointer);
     void passwordRequired(LOKDocView* pDocView, char* pUrl, gboolean bModify, gpointer);
     void comment(LOKDocView* pDocView, gchar* pComment, gpointer);
-    void dialogInvalidate(LOKDocView* pDocView, gchar* pDialogId, gpointer);
+    void dialog(LOKDocView* pDocView, gchar* pDialogId, gpointer);
     void dialogChild(LOKDocView* pDocView, gchar* pPayload, gpointer);
 
     gboolean configureEvent(GtkWidget* pWidget, GdkEventConfigure* pEvent, gpointer pData);
diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx
index 1bdb80c754ed..d2bfefcc089e 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -279,7 +279,7 @@ enum
     PASSWORD_REQUIRED,
     COMMENT,
     RULER,
-    DIALOG_INVALIDATE,
+    DIALOG,
     DIALOG_CHILD,
 
     LAST_SIGNAL
@@ -438,8 +438,8 @@ callbackTypeToString (int nType)
         return "LOK_CALLBACK_COMMENT";
     case LOK_CALLBACK_RULER_UPDATE:
         return "LOK_CALLBACK_RULER_UPDATE";
-    case LOK_CALLBACK_DIALOG_INVALIDATE:
-        return "LOK_CALLBACK_DIALOG_INVALIDATE";
+    case LOK_CALLBACK_DIALOG:
+        return "LOK_CALLBACK_DIALOG";
     case LOK_CALLBACK_DIALOG_CHILD:
         return "LOK_CALLBACK_DIALOG_CHILD";
     }
@@ -1414,8 +1414,9 @@ callback (gpointer pData)
         break;
     case LOK_CALLBACK_RULER_UPDATE:
         g_signal_emit(pCallback->m_pDocView, doc_view_signals[RULER], 0, pCallback->m_aPayload.c_str());
-    case LOK_CALLBACK_DIALOG_INVALIDATE:
-        g_signal_emit(pCallback->m_pDocView, doc_view_signals[DIALOG_INVALIDATE], 0, pCallback->m_aPayload.c_str());
+        break;
+    case LOK_CALLBACK_DIALOG:
+        g_signal_emit(pCallback->m_pDocView, doc_view_signals[DIALOG], 0, pCallback->m_aPayload.c_str());
         break;
     case LOK_CALLBACK_DIALOG_CHILD:
         g_signal_emit(pCallback->m_pDocView, doc_view_signals[DIALOG_CHILD], 0, pCallback->m_aPayload.c_str());
@@ -3222,8 +3223,8 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass)
      * @pDocView: the #LOKDocView on which the signal is emitted
      * @pDialogId: The uno command for the dialog (dialog ID)
      */
-    doc_view_signals[DIALOG_INVALIDATE] =
-        g_signal_new("dialog-invalidate",
+    doc_view_signals[DIALOG] =
+        g_signal_new("dialog",
                      G_TYPE_FROM_CLASS(pGObjectClass),
                      G_SIGNAL_RUN_FIRST,
                      0,
diff --git a/sfx2/source/view/lokhelper.cxx b/sfx2/source/view/lokhelper.cxx
index c6e9d57027b2..08a89eac49a8 100644
--- a/sfx2/source/view/lokhelper.cxx
+++ b/sfx2/source/view/lokhelper.cxx
@@ -144,15 +144,19 @@ void SfxLokHelper::notifyOtherViews(SfxViewShell* pThisView, int nType, const OS
     }
 }
 
-void SfxLokHelper::notifyDialogInvalidation(const OUString& rDialogID)
+void SfxLokHelper::notifyDialog(const OUString& rDialogID, const OUString& rAction)
 {
     if (SfxLokHelper::getViewsCount() <= 0)
         return;
 
     SfxViewShell* pViewShell = SfxViewShell::GetFirst();
+    const OString aPayload = OString("{ \"dialogId\": \"") + OUStringToOString(rDialogID, RTL_TEXTENCODING_UTF8).getStr() +
+        OString("\", \"action\": \"") + OUStringToOString(rAction, RTL_TEXTENCODING_UTF8).getStr() +
+        + "\" }";
+
     while (pViewShell)
     {
-        pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_DIALOG_INVALIDATE, OUStringToOString(rDialogID, RTL_TEXTENCODING_UTF8).getStr());
+        pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_DIALOG, aPayload.getStr());
         pViewShell = SfxViewShell::GetNext(*pViewShell);
     }
 }
diff --git a/sw/inc/unotxdoc.hxx b/sw/inc/unotxdoc.hxx
index a803a6aa8e16..868dbabbcb72 100644
--- a/sw/inc/unotxdoc.hxx
+++ b/sw/inc/unotxdoc.hxx
@@ -442,7 +442,7 @@ public:
     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 notifyDialog(const vcl::DialogID& rDialogID, const OUString& rAction) 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 ba2adf769732..8b2eda85949e 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -3791,9 +3791,9 @@ void SwXTextDocument::postDialogChildMouseEvent(const vcl::DialogID& rDialogID,
     }
 }
 
-void SwXTextDocument::notifyDialogInvalidation(const vcl::DialogID& rDialogID)
+void SwXTextDocument::notifyDialog(const vcl::DialogID& rDialogID, const OUString& rAction)
 {
-    SfxLokHelper::notifyDialogInvalidation(rDialogID);
+    SfxLokHelper::notifyDialog(rDialogID, rAction);
 }
 
 void SwXTextDocument::notifyDialogChild(const vcl::DialogID& rDialogID, const OUString& rAction, const Point& rPos)
diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx
index 6a2338e33494..eed393f3e298 100644
--- a/vcl/source/window/dialog.cxx
+++ b/vcl/source/window/dialog.cxx
@@ -964,7 +964,7 @@ void Dialog::LogicInvalidate(const tools::Rectangle* /*pRectangle*/)
 {
     if (!comphelper::LibreOfficeKit::isDialogPainting() && mpDialogRenderable && !maID.isEmpty())
     {
-        mpDialogRenderable->notifyDialogInvalidation(maID);
+        mpDialogRenderable->notifyDialog(maID, "invalidate");
     }
 }
 
commit 07e6187608cc0f6df0ae3c2d37774d4e07f7dbbe
Author: Pranav Kant <pranavk at 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 ca1c61cd84b9..936c4d13e244 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -561,6 +561,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,
@@ -633,6 +641,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;
@@ -2286,6 +2295,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/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 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 33ad8c274ec9..ba2adf769732 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -3751,6 +3751,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 b626f7a8cbd6..6a2338e33494 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, 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");
commit 4ddcfe12a8207df8c8d1d63d13c7fd126f409dc7
Author: Pranav Kant <pranavk at collabora.co.uk>
Date:   Fri Aug 4 00:02:48 2017 +0530

    lokdialog: drawing area needs to have focus to capture key events
    
    With this, key events successfully work now.
    
    Change-Id: I6dc6aff91dea08fcbc7ab840a77e2542ab9048ce

diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
index 6b19ddc506c0..e37f9f274062 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
@@ -110,7 +110,7 @@ gtv_lok_dialog_signal_button(GtkWidget* pDialogDrawingArea, GdkEventButton* pEve
            (int)pEvent->x, (int)pEvent->y,
            (int)pixelToTwip(pEvent->x),
            (int)pixelToTwip(pEvent->y));
-    gtk_widget_grab_focus(GTK_WIDGET(pDialog));
+    gtk_widget_grab_focus(pDialogDrawingArea);
 
     switch (pEvent->type)
     {
@@ -194,7 +194,6 @@ gtv_lok_dialog_signal_motion(GtkWidget* pDialogDrawingArea, GdkEventButton* pEve
            (int)pEvent->x, (int)pEvent->y,
            (int)pixelToTwip(pEvent->x),
            (int)pixelToTwip(pEvent->y));
-    gtk_widget_grab_focus(GTK_WIDGET(pDialog));
 
     pDocument->pClass->postDialogMouseEvent(pDocument,
                                             priv->dialogid,
@@ -216,6 +215,7 @@ gtv_lok_dialog_signal_key(GtkWidget* pDialogDrawingArea, GdkEventKey* pEvent)
     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_signal_key");
     int nCharCode = 0;
     int nKeyCode = 0;
     priv->m_nKeyModifier &= KEY_MOD2;
@@ -334,12 +334,14 @@ gtv_lok_dialog_init(GtvLokDialog* dialog)
     priv->m_nKeyModifier = 0;
     priv->m_nLastButtonPressed = 0;
 
-    gtk_widget_add_events(GTK_WIDGET(priv->pDialogDrawingArea),
+    gtk_widget_add_events(priv->pDialogDrawingArea,
                           GDK_BUTTON_PRESS_MASK
                           |GDK_BUTTON_RELEASE_MASK
                           |GDK_BUTTON_MOTION_MASK
                           |GDK_KEY_PRESS_MASK
                           |GDK_KEY_RELEASE_MASK);
+    // This is required to be able to capture key events on the drawing area
+    gtk_widget_set_can_focus(priv->pDialogDrawingArea, true);
 
     g_signal_connect(G_OBJECT(priv->pDialogDrawingArea), "draw", G_CALLBACK(gtv_lok_dialog_draw), nullptr);
     g_signal_connect(G_OBJECT(priv->pDialogDrawingArea), "button-press-event", G_CALLBACK(gtv_lok_dialog_signal_button), nullptr);
commit b9886c06054e33a5646100c2c8c4fc3a58dbf2a3
Author: Pranav Kant <pranavk at collabora.co.uk>
Date:   Fri Aug 4 00:02:38 2017 +0530

    lokdialog: Invalid free
    
    Change-Id: I7713b8d025652770e7e46603edbaa86951588871

diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx
index 72916b56f9ce..1dc1d3a38e23 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx
@@ -311,14 +311,15 @@ void LOKDocViewSigHandlers::dialogChild(LOKDocView* pDocView, gchar* pPayload, g
   std::string aAction = aRoot.get<std::string>("action");
   std::string aPos = aRoot.get<std::string>("position");
   gchar** ppCoordinates = g_strsplit(aPos.c_str(), ", ", 2);
+  gchar** ppCoordinate = ppCoordinates;
   int nX = 0;
   int nY = 0;
 
-  if (*ppCoordinates)
-      nX = atoi(*ppCoordinates);
-  ++ppCoordinates;
-  if (*ppCoordinates)
-      nY = atoi(*ppCoordinates);
+  if (*ppCoordinate)
+      nX = atoi(*ppCoordinate);
+  ++ppCoordinate;
+  if (*ppCoordinate)
+      nY = atoi(*ppCoordinate);
 
   g_strfreev(ppCoordinates);
 
commit 602b12f7bcea3217bbc49b24829fb041b26af4ac
Author: Pranav Kant <pranavk at collabora.co.uk>
Date:   Thu Aug 3 22:58:04 2017 +0530

    lokdialog: Move the floating window to its actual position
    
    gtk_window_move them to the position broadcasted to us by vcl
    
    Change-Id: Id27b52a24e721b51d7a153cc7c0e03197a99ee2f

diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
index 1bfb9d538ead..6b19ddc506c0 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
@@ -460,7 +460,7 @@ gtv_lok_dialog_invalidate(GtvLokDialog* dialog)
     gtk_widget_queue_draw(priv->pDialogDrawingArea);
 }
 
-void gtv_lok_dialog_child_invalidate(GtvLokDialog* dialog)
+void gtv_lok_dialog_child_invalidate(GtvLokDialog* dialog, int nX, int nY)
 {
     g_info("Dialog's floating window invalidate");
 
@@ -474,14 +474,22 @@ void gtv_lok_dialog_child_invalidate(GtvLokDialog* dialog)
     gtk_container_add(GTK_CONTAINER(priv->pFloatingWin), pDrawingArea);
 
     gtk_window_set_transient_for(GTK_WINDOW(priv->pFloatingWin), GTK_WINDOW(dialog));
-    gtk_window_set_position(GTK_WINDOW(priv->pFloatingWin), GTK_WIN_POS_MOUSE);
     gtk_window_set_destroy_with_parent(GTK_WINDOW(priv->pFloatingWin), true);
-
     g_signal_connect(G_OBJECT(pDrawingArea), "draw", G_CALLBACK(gtv_lok_dialog_floating_win_draw), 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);
+    gtk_window_set_screen(GTK_WINDOW(priv->pFloatingWin), gtk_window_get_screen(GTK_WINDOW(dialog)));
+
     gtk_widget_show_all(priv->pFloatingWin);
     gtk_window_present(GTK_WINDOW(priv->pFloatingWin));
+
+    // Get the root coords of our new floating window
+    GdkWindow* pGdkWin = gtk_widget_get_window(GTK_WIDGET(dialog));
+    int nrX = 0;
+    int nrY = 0;
+    gdk_window_get_root_coords(pGdkWin, nX, nY, &nrX, &nrY);
+    gtk_window_move(GTK_WINDOW(priv->pFloatingWin), nrX, nrY);
 }
 
 void gtv_lok_dialog_child_close(GtvLokDialog* dialog)
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.hxx b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.hxx
index bce9edbadba1..ba565b4cebb0 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.hxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.hxx
@@ -39,7 +39,7 @@ GtkWidget* gtv_lok_dialog_new(LOKDocView* pDocView, const gchar* dialogId);
 
 void gtv_lok_dialog_invalidate(GtvLokDialog* dialog);
 
-void gtv_lok_dialog_child_invalidate(GtvLokDialog* dialog);
+void gtv_lok_dialog_child_invalidate(GtvLokDialog* dialog, int nX, int nY);
 
 void gtv_lok_dialog_child_close(GtvLokDialog* dialog);
 
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx
index d0778cef473d..72916b56f9ce 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx
@@ -309,6 +309,18 @@ void LOKDocViewSigHandlers::dialogChild(LOKDocView* pDocView, gchar* pPayload, g
   boost::property_tree::read_json(aStream, aRoot);
   std::string aDialogId = aRoot.get<std::string>("dialogId");
   std::string aAction = aRoot.get<std::string>("action");
+  std::string aPos = aRoot.get<std::string>("position");
+  gchar** ppCoordinates = g_strsplit(aPos.c_str(), ", ", 2);
+  int nX = 0;
+  int nY = 0;
+
+  if (*ppCoordinates)
+      nX = atoi(*ppCoordinates);
+  ++ppCoordinates;
+  if (*ppCoordinates)
+      nY = atoi(*ppCoordinates);
+
+  g_strfreev(ppCoordinates);
 
   // temporary hack to invalidate/close floating window of all opened dialogs
   GList* pChildWins = gtv_application_window_get_all_child_windows(window);
@@ -316,7 +328,7 @@ void LOKDocViewSigHandlers::dialogChild(LOKDocView* pDocView, gchar* pPayload, g
   for (pIt = pChildWins; pIt != nullptr; pIt = pIt->next)
   {
       if (aAction == "invalidate")
-          gtv_lok_dialog_child_invalidate(GTV_LOK_DIALOG(pIt->data));
+          gtv_lok_dialog_child_invalidate(GTV_LOK_DIALOG(pIt->data), nX, nY);
       else if (aAction == "close")
           gtv_lok_dialog_child_close(GTV_LOK_DIALOG(pIt->data));
   }
commit d56b39817f3f7b6a9c7b53c03a63efd24bdb0462
Author: Pranav Kant <pranavk at collabora.co.uk>
Date:   Thu Aug 3 14:42:55 2017 +0530

    lokdialog: Support for rendering floating window dialog widgets
    
    Now gtktiledviewer can show floating window dialog widgets when user
    clicks any of such widget in the dialog.
    
    Change-Id: I13d756f236379bc8b2041ed41cb7b502f7fd9b24

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 847fd4dc923a..ca1c61cd84b9 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -603,6 +603,8 @@ static char* doc_getPartHash(LibreOfficeKitDocument* pThis, int nPart);
 
 static void doc_paintDialog(LibreOfficeKitDocument* pThis, const char* pDialogId, unsigned char* pBuffer, int* nWidth, int* nHeight);
 
+static void doc_paintActiveFloatingWindow(LibreOfficeKitDocument* pThis, const char* pDialogId, unsigned char* pBuffer, int* nWidth, int* nHeight);
+
 LibLODocument_Impl::LibLODocument_Impl(const uno::Reference <css::lang::XComponent> &xComponent)
     : mxComponent(xComponent)
 {
@@ -652,6 +654,7 @@ LibLODocument_Impl::LibLODocument_Impl(const uno::Reference <css::lang::XCompone
         m_pDocumentClass->getPartHash = doc_getPartHash;
 
         m_pDocumentClass->paintDialog = doc_paintDialog;
+        m_pDocumentClass->paintActiveFloatingWindow = doc_paintActiveFloatingWindow;
 
         gDocumentClass = m_pDocumentClass;
     }
@@ -3038,6 +3041,24 @@ static void doc_paintDialog(LibreOfficeKitDocument* pThis, const char* pDialogId
     comphelper::LibreOfficeKit::setDialogPainting(false);
 }
 
+static void doc_paintActiveFloatingWindow(LibreOfficeKitDocument* pThis, const char* pDialogId, unsigned char* pBuffer, int* nWidth, int* nHeight)
+{
+    SolarMutexGuard aGuard;
+
+    IDialogRenderable* pDialogRenderable = getDialogRenderable(pThis);
+
+    ScopedVclPtrInstance<VirtualDevice> pDevice(nullptr, Size(1, 1), DeviceFormat::DEFAULT);
+    pDevice->SetBackground(Wallpaper(Color(COL_TRANSPARENT)));
+
+    pDevice->SetOutputSizePixelScaleOffsetAndBuffer(Size(*nWidth, *nHeight), Fraction(1.0), Point(), pBuffer);
+
+    vcl::DialogID aDialogID = OUString::createFromAscii(pDialogId);
+
+    comphelper::LibreOfficeKit::setDialogPainting(true);
+    pDialogRenderable->paintActiveFloatingWindow(aDialogID, *pDevice.get(), *nWidth, *nHeight);
+    comphelper::LibreOfficeKit::setDialogPainting(false);
+}
+
 static char* lo_getError (LibreOfficeKit *pThis)
 {
     SolarMutexGuard aGuard;
diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h
index 5a099f7c7f67..529a1336ca76 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.h
+++ b/include/LibreOfficeKit/LibreOfficeKit.h
@@ -269,6 +269,8 @@ struct _LibreOfficeKitDocumentClass
     /// WIP
     void (*paintDialog) (LibreOfficeKitDocument* pThis, const char* pDialogId, unsigned char* pBuffer, int* nWidth, int* nHeight);
 
+    void (*paintActiveFloatingWindow) (LibreOfficeKitDocument* pThis, const char* pDialogId, unsigned char* pBuffer, int* nWidth, int* nHeight);
+
     /// WIP
     void (*postDialogKeyEvent) (LibreOfficeKitDocument* pThis,
                                 const char* pDialogId,
diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h
index fdad6919e0e1..4c70560690da 100644
--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h
+++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h
@@ -525,8 +525,26 @@ typedef enum
     /**
      * Dialog invalidation
      */
-    LOK_CALLBACK_DIALOG_INVALIDATE = 36
+    LOK_CALLBACK_DIALOG_INVALIDATE = 36,
 
+    /**
+     * Invalidation corresponding to dialog's children.
+     * Eg: Floating window etc.
+     *
+     * Payload example:
+     * {
+     *   "dialogID": "SpellDialog",
+     *   "action": "close"
+     * }
+     *
+     * - dialogID is the UNO command of the dialog
+     * - action can be
+     *   - close, means dialog child window is closed now
+     *   - invalidate, means dialog child window is invalidated
+     *     It also means that dialog child window is created if it's the first
+     *     invalidate
+     */
+    LOK_CALLBACK_DIALOG_CHILD = 37
 }
 LibreOfficeKitCallbackType;
 
diff --git a/include/sfx2/lokhelper.hxx b/include/sfx2/lokhelper.hxx
index b37480df9da1..b57f30a0ccba 100644
--- a/include/sfx2/lokhelper.hxx
+++ b/include/sfx2/lokhelper.hxx
@@ -42,6 +42,8 @@ public:
     static void notifyOtherView(SfxViewShell* pThisView, SfxViewShell const* pOtherView, int nType, const OString& rKey, const OString& rPayload);
     /// Emits a LOK_CALLBACK_DIALOG_INVALIDATE
     static void notifyDialogInvalidation(const OUString& rPayload);
+    /// Emits a LOK_CALLBACK_DIALOG_CHILD
+    static void notifyDialogChild(const OUString& rDialogID, const OUString& rAction, const Point& rPos);
     /// Emits a LOK_CALLBACK_INVALIDATE_TILES, but tweaks it according to setOptionalFeatures() if needed.
     static void notifyInvalidation(SfxViewShell* pThisView, const OString& rPayload);
     /// A special value to signify 'infinity'.
diff --git a/include/vcl/IDialogRenderable.hxx b/include/vcl/IDialogRenderable.hxx
index b2c0dee552cd..351839e46d02 100644
--- a/include/vcl/IDialogRenderable.hxx
+++ b/include/vcl/IDialogRenderable.hxx
@@ -33,6 +33,9 @@ public:
     virtual void paintDialog(const DialogID& rDialogID, VirtualDevice &rDevice,
                              int& nOutputWidth, int& nOutputHeight) = 0;
 
+    virtual void paintActiveFloatingWindow(const DialogID& rDialogID, VirtualDevice &rDevice,
+                                           int& nOutputWidth, int& nOutputHeight) = 0;
+
     virtual void postDialogKeyEvent(const DialogID& rDialogID, int nType,
                                     int nCharCode, int nKeyCode) = 0;
 
@@ -41,6 +44,8 @@ public:
 
     // Callbacks
     virtual void notifyDialogInvalidation(const DialogID& rDialogID) = 0;
+
+    virtual void notifyDialogChild(const DialogID& rDialogID, const OUString& rAction, const Point& rPos) = 0;
 };
 
 } // namespace vcl
diff --git a/include/vcl/dialog.hxx b/include/vcl/dialog.hxx
index ef3bcd5e8099..5ab85be1842e 100644
--- a/include/vcl/dialog.hxx
+++ b/include/vcl/dialog.hxx
@@ -80,6 +80,9 @@ public:
     SAL_DLLPRIVATE bool    IsInClose() const { return mbInClose; }
     virtual        void    doDeferredInit(WinBits nBits) override;
     virtual        void    LogicInvalidate(const tools::Rectangle* pRectangle) override;
+                   void    InvalidateFloatingWindow(const Point& rPos);
+                   void    CloseFloatingWindow();
+                   Size    PaintActiveFloatingWindow(VirtualDevice& rDevice);
 
     /// Necessary to register dialog renderable instance to emit LOK callbacks
     void registerDialogRenderable(vcl::IDialogRenderable* pDialogRenderable);
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-application-window.cxx b/libreofficekit/qa/gtktiledviewer/gtv-application-window.cxx
index 077e2577f384..8a5ff9a56d37 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-application-window.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-application-window.cxx
@@ -315,6 +315,7 @@ static void setupDocView(GtvApplicationWindow* window)
     g_signal_connect(window->lokdocview, "password-required", G_CALLBACK(LOKDocViewSigHandlers::passwordRequired), nullptr);
     g_signal_connect(window->lokdocview, "comment", G_CALLBACK(LOKDocViewSigHandlers::comment), nullptr);
     g_signal_connect(window->lokdocview, "dialog-invalidate", G_CALLBACK(LOKDocViewSigHandlers::dialogInvalidate), nullptr);
+    g_signal_connect(window->lokdocview, "dialog-child", G_CALLBACK(LOKDocViewSigHandlers::dialogChild), nullptr);
 
     g_signal_connect(window->lokdocview, "configure-event", G_CALLBACK(LOKDocViewSigHandlers::configureEvent), nullptr);
 }
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
index bb8800e3d734..1bfb9d538ead 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
@@ -32,6 +32,7 @@ struct GtvLokDialogPrivate
 {
     LOKDocView* lokdocview;
     GtkWidget* pDialogDrawingArea;
+    GtkWidget* pFloatingWin;
 
     guint32 m_nLastButtonPressTime;
     guint32 m_nLastButtonReleaseTime;
@@ -79,6 +80,8 @@ gtv_lok_dialog_draw(GtkWidget* pDialogDrawingArea, cairo_t* pCairo, gpointer)
     GtvLokDialog* pDialog = GTV_LOK_DIALOG(gtk_widget_get_toplevel(pDialogDrawingArea));
     GtvLokDialogPrivate* priv = getPrivate(pDialog);
 
+
+    g_info("panting dialog");
     int nWidth = 1024;
     int nHeight = 768;
     cairo_surface_t* pSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, nWidth, nHeight);
@@ -324,6 +327,7 @@ gtv_lok_dialog_init(GtvLokDialog* dialog)
 
     GtkWidget* pContentArea = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
     priv->pDialogDrawingArea = gtk_drawing_area_new();
+    priv->pFloatingWin = nullptr;
 
     priv->m_nLastButtonPressTime = 0;
     priv->m_nLastButtonReleaseTime = 0;
@@ -421,14 +425,75 @@ gtv_lok_dialog_class_init(GtvLokDialogClass* klass)
     g_object_class_install_properties (G_OBJECT_CLASS(klass), PROP_LAST, properties);
 }
 
+static void
+gtv_lok_dialog_floating_win_draw(GtkWidget* pDrawingArea, cairo_t* pCairo, gpointer userdata)
+{
+    GtvLokDialog* pDialog = GTV_LOK_DIALOG(userdata);
+    GtvLokDialogPrivate* priv = getPrivate(pDialog);
+
+    g_info("gtv_lok_dialog_floating_win_draw triggered");
+    int nWidth = 800;
+    int nHeight = 600;
+    cairo_surface_t* pSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, nWidth, nHeight);
+    unsigned char* pBuffer = cairo_image_surface_get_data(pSurface);
+    LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(LOK_DOC_VIEW(priv->lokdocview));
+    pDocument->pClass->paintActiveFloatingWindow(pDocument, priv->dialogid, pBuffer, &nWidth, &nHeight);
+    g_info("Size of floating window: %d x %d", nWidth, nHeight);
+
+    gtk_widget_set_size_request(GTK_WIDGET(pDrawingArea), nWidth, nHeight);
+    gtk_widget_set_size_request(GTK_WIDGET(pDialog), nWidth, nHeight);
+    gtk_window_resize(GTK_WINDOW(pDialog), nWidth, nHeight);
+
+    cairo_surface_flush(pSurface);
+    cairo_surface_mark_dirty(pSurface);
+
+    cairo_set_source_surface(pCairo, pSurface, 0, 0);
+    cairo_paint(pCairo);
+}
+
 void
 gtv_lok_dialog_invalidate(GtvLokDialog* dialog)
 {
-    // trigger a draw on the drawing area
     GtvLokDialogPrivate* priv = getPrivate(dialog);
+
+    // trigger a draw on the dialog drawing area
     gtk_widget_queue_draw(priv->pDialogDrawingArea);
 }
 
+void gtv_lok_dialog_child_invalidate(GtvLokDialog* dialog)
+{
+    g_info("Dialog's floating window invalidate");
+
+    GtvLokDialogPrivate* priv = getPrivate(dialog);
+    // remove any existing floating windows, for now
+    if (priv->pFloatingWin)
+        gtk_widget_destroy(priv->pFloatingWin);
+
+    priv->pFloatingWin = gtk_window_new(GTK_WINDOW_POPUP);
+    GtkWidget* pDrawingArea = gtk_drawing_area_new();
+    gtk_container_add(GTK_CONTAINER(priv->pFloatingWin), pDrawingArea);
+
+    gtk_window_set_transient_for(GTK_WINDOW(priv->pFloatingWin), GTK_WINDOW(dialog));
+    gtk_window_set_position(GTK_WINDOW(priv->pFloatingWin), GTK_WIN_POS_MOUSE);
+    gtk_window_set_destroy_with_parent(GTK_WINDOW(priv->pFloatingWin), true);
+
+    g_signal_connect(G_OBJECT(pDrawingArea), "draw", G_CALLBACK(gtv_lok_dialog_floating_win_draw), dialog);
+
+    gtk_widget_set_size_request(priv->pFloatingWin, 1, 1);
+    gtk_widget_show_all(priv->pFloatingWin);
+    gtk_window_present(GTK_WINDOW(priv->pFloatingWin));
+}
+
+void gtv_lok_dialog_child_close(GtvLokDialog* dialog)
+{
+    g_info("Dialog's floating window close");
+
+    GtvLokDialogPrivate* priv = getPrivate(dialog);
+    if (priv->pFloatingWin)
+        gtk_widget_destroy(priv->pFloatingWin);
+}
+
+
 GtkWidget*
 gtv_lok_dialog_new(LOKDocView* pDocView, const gchar* dialogId)
 {
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.hxx b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.hxx
index 0205f2ede3f4..bce9edbadba1 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.hxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.hxx
@@ -39,6 +39,10 @@ GtkWidget* gtv_lok_dialog_new(LOKDocView* pDocView, const gchar* dialogId);
 
 void gtv_lok_dialog_invalidate(GtvLokDialog* dialog);
 
+void gtv_lok_dialog_child_invalidate(GtvLokDialog* dialog);
+
+void gtv_lok_dialog_child_close(GtvLokDialog* dialog);
+
 G_END_DECLS
 
 #endif /* GTV_LOK_DIALOG_H */
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx
index 8f86ecd43ca7..d0778cef473d 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx
@@ -281,7 +281,7 @@ void LOKDocViewSigHandlers::comment(LOKDocView* pDocView, gchar* pComment, gpoin
     }
 }
 
-void LOKDocViewSigHandlers::dialogInvalidate(LOKDocView* pDocView, gchar* /*pDialogId*/, gpointer)
+void LOKDocViewSigHandlers::dialogInvalidate(LOKDocView* pDocView, gchar* pPayload, gpointer)
 {
     GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(pDocView)));
 //    GtkWindow* pDialog = gtv_application_window_get_child_window_by_id(window, pDialogId);
@@ -300,6 +300,28 @@ void LOKDocViewSigHandlers::dialogInvalidate(LOKDocView* pDocView, gchar* /*pDia
 */
 }
 
+void LOKDocViewSigHandlers::dialogChild(LOKDocView* pDocView, gchar* pPayload, gpointer)
+{
+  GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(pDocView)));
+
+  std::stringstream aStream(pPayload);
+  boost::property_tree::ptree aRoot;
+  boost::property_tree::read_json(aStream, aRoot);
+  std::string aDialogId = aRoot.get<std::string>("dialogId");
+  std::string aAction = aRoot.get<std::string>("action");
+
+  // temporary hack to invalidate/close floating window of all opened dialogs
+  GList* pChildWins = gtv_application_window_get_all_child_windows(window);
+  GList* pIt = nullptr;
+  for (pIt = pChildWins; pIt != nullptr; pIt = pIt->next)
+  {
+      if (aAction == "invalidate")
+          gtv_lok_dialog_child_invalidate(GTV_LOK_DIALOG(pIt->data));
+      else if (aAction == "close")
+          gtv_lok_dialog_child_close(GTV_LOK_DIALOG(pIt->data));
+  }
+}
+
 gboolean LOKDocViewSigHandlers::configureEvent(GtkWidget* pWidget, GdkEventConfigure* /*pEvent*/, gpointer /*pData*/)
 {
     GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(pWidget)));
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.hxx b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.hxx
index 73bf9c2860ad..a455c3f1fc4c 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.hxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.hxx
@@ -26,6 +26,7 @@ namespace LOKDocViewSigHandlers {
     void passwordRequired(LOKDocView* pDocView, char* pUrl, gboolean bModify, gpointer);
     void comment(LOKDocView* pDocView, gchar* pComment, gpointer);
     void dialogInvalidate(LOKDocView* pDocView, gchar* pDialogId, gpointer);
+    void dialogChild(LOKDocView* pDocView, gchar* pPayload, gpointer);
 
     gboolean configureEvent(GtkWidget* pWidget, GdkEventConfigure* pEvent, gpointer pData);
 }
diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx
index b5fc11d82d9e..1bdb80c754ed 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -280,6 +280,7 @@ enum
     COMMENT,
     RULER,
     DIALOG_INVALIDATE,
+    DIALOG_CHILD,
 
     LAST_SIGNAL
 };
@@ -439,6 +440,8 @@ callbackTypeToString (int nType)
         return "LOK_CALLBACK_RULER_UPDATE";
     case LOK_CALLBACK_DIALOG_INVALIDATE:
         return "LOK_CALLBACK_DIALOG_INVALIDATE";
+    case LOK_CALLBACK_DIALOG_CHILD:
+        return "LOK_CALLBACK_DIALOG_CHILD";
     }
     g_assert(false);
     return nullptr;
@@ -1414,6 +1417,9 @@ callback (gpointer pData)
     case LOK_CALLBACK_DIALOG_INVALIDATE:
         g_signal_emit(pCallback->m_pDocView, doc_view_signals[DIALOG_INVALIDATE], 0, pCallback->m_aPayload.c_str());
         break;
+    case LOK_CALLBACK_DIALOG_CHILD:
+        g_signal_emit(pCallback->m_pDocView, doc_view_signals[DIALOG_CHILD], 0, pCallback->m_aPayload.c_str());
+        break;
     default:
         g_assert(false);
         break;
@@ -3225,6 +3231,37 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass)
                      g_cclosure_marshal_generic,
                      G_TYPE_NONE, 1,
                      G_TYPE_STRING);
+
+    /**
+     * LOKDocView::dialog-child:
+     * @pDocView: the #LOKDocView on which the signal is emitted
+     * @pPayload: JSON described below:
+     *
+     * Invalidation corresponding to dialog's children.
+     * Eg: Floating window etc.
+     *
+     * Payload example:
+     * {
+     *   "dialogID": "SpellDialog",
+     *   "action": "close"
+     * }
+     *
+     * - dialogID is the UNO command of the dialog
+     * - action can be
+     *   - close, means dialog child window is closed now
+     *   - invalidate, means dialog child window is invalidated
+     *     It also means that dialog child window is created if it's the first
+     *     invalidate
+     */
+    doc_view_signals[DIALOG_CHILD] =
+        g_signal_new("dialog-child",
+                     G_TYPE_FROM_CLASS(pGObjectClass),
+                     G_SIGNAL_RUN_FIRST,
+                     0,
+                     nullptr, nullptr,
+                     g_cclosure_marshal_generic,
+                     G_TYPE_NONE, 1,
+                     G_TYPE_STRING);
 }
 
 SAL_DLLPUBLIC_EXPORT GtkWidget*
diff --git a/sfx2/source/view/lokhelper.cxx b/sfx2/source/view/lokhelper.cxx
index 46d736206ddf..c6e9d57027b2 100644
--- a/sfx2/source/view/lokhelper.cxx
+++ b/sfx2/source/view/lokhelper.cxx
@@ -157,6 +157,24 @@ void SfxLokHelper::notifyDialogInvalidation(const OUString& rDialogID)
     }
 }
 
+void SfxLokHelper::notifyDialogChild(const OUString& rDialogID, const OUString& rAction, const Point& rPos)
+{
+    if (SfxLokHelper::getViewsCount() <= 0)
+        return;
+
+    SfxViewShell* pViewShell = SfxViewShell::GetFirst();
+    const OString aPayload = OString("{ \"dialogId\": \"") + OUStringToOString(rDialogID, RTL_TEXTENCODING_UTF8).getStr() +
+        OString("\", \"action\": \"") + OUStringToOString(rAction, RTL_TEXTENCODING_UTF8).getStr() +
+        OString("\", \"position\": \"") + OString::number(rPos.getX()) + OString(", ") + OString::number(rPos.getY()) +
+        + "\" }";
+
+    while (pViewShell)
+    {
+        pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_DIALOG_CHILD, aPayload.getStr());
+        pViewShell = SfxViewShell::GetNext(*pViewShell);
+    }
+}
+
 void SfxLokHelper::notifyInvalidation(SfxViewShell* pThisView, const OString& rPayload)
 {
     OStringBuffer aBuf;
diff --git a/sw/inc/unotxdoc.hxx b/sw/inc/unotxdoc.hxx
index e93173451b3c..3d269dcadc03 100644
--- a/sw/inc/unotxdoc.hxx
+++ b/sw/inc/unotxdoc.hxx
@@ -432,6 +432,7 @@ public:
     OUString getPostIts() override;
 
     void paintDialog(const vcl::DialogID& rDialogID, VirtualDevice& rDevice, int& nWidth, int& nHeight) override;
+    void paintActiveFloatingWindow(const vcl::DialogID& rDialogID, VirtualDevice& rDevice, int& nWidth, int& nHeight) override;
     void postDialogKeyEvent(const vcl::DialogID& rDialogID, int nType,
                             int nCharCode, int nKeyCode) override;
 
@@ -440,6 +441,8 @@ public:
 
     void notifyDialogInvalidation(const vcl::DialogID& rDialogID) override;
 
+    void notifyDialogChild(const vcl::DialogID& rDialogID, const OUString& rAction, const Point& rPos) override;
+
     // css::tiledrendering::XTiledRenderable
     virtual void SAL_CALL paintTile( const ::css::uno::Any& Parent, ::sal_Int32 nOutputWidth, ::sal_Int32 nOutputHeight, ::sal_Int32 nTilePosX, ::sal_Int32 nTilePosY, ::sal_Int32 nTileWidth, ::sal_Int32 nTileHeight ) override;
 
diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx
index e574321c98c0..33ad8c274ec9 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -3756,6 +3756,33 @@ void SwXTextDocument::notifyDialogInvalidation(const vcl::DialogID& rDialogID)
     SfxLokHelper::notifyDialogInvalidation(rDialogID);
 }
 
+void SwXTextDocument::notifyDialogChild(const vcl::DialogID& rDialogID, const OUString& rAction, const Point& rPos)
+{
+    SfxLokHelper::notifyDialogChild(rDialogID, rAction, rPos);
+}
+
+void SwXTextDocument::paintActiveFloatingWindow(const vcl::DialogID& rDialogID, VirtualDevice& rDevice, int& nWidth, int& nHeight)
+{
+    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)
+        return;
+
+    Dialog* pDlg = static_cast<Dialog*>(pChild->GetWindow());
+    // register the instance so that vcl::Dialog can emit LOK callbacks
+    const Size aSize = pDlg->PaintActiveFloatingWindow(rDevice);
+    SAL_DEBUG("Size of the floating window :  " << aSize);
+    nWidth = aSize.getWidth();
+    nHeight = aSize.getHeight();
+}
+
 void * SAL_CALL SwXTextDocument::operator new( size_t t) throw()
 {
     return SwXTextDocumentBaseClass::operator new(t);
diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx
index e5d784e4f667..b626f7a8cbd6 100644
--- a/vcl/source/window/dialog.cxx
+++ b/vcl/source/window/dialog.cxx
@@ -883,10 +883,51 @@ void Dialog::paintDialog(VirtualDevice& rDevice)
     PaintToDevice(&rDevice, Point(0, 0), Size());
 }
 
-void Dialog::LogicInvalidate(const tools::Rectangle* /*pRectangle*/)
+Size Dialog::PaintActiveFloatingWindow(VirtualDevice& rDevice)
+{
+    Size aRet;
+    ImplSVData* pSVData = ImplGetSVData();
+    FloatingWindow* pFirstFloat = pSVData->maWinData.mpFirstFloat;
+    if (pFirstFloat)
+    {
+        // TODO:: run a while loop here and check all the active floating
+        // windows ( chained together, cf. pFirstFloat->mpNextFloat )
+        // For now just assume that the active floating window is the one we
+        // want to render
+        if (pFirstFloat->GetParentDialog() == this)
+        {
+            pFirstFloat->PaintToDevice(&rDevice, Point(0, 0), Size());
+            aRet = ::isLayoutEnabled(pFirstFloat) ? pFirstFloat->get_preferred_size() : pFirstFloat->GetSizePixel();
+        }
+
+        pFirstFloat = nullptr;
+    }
+
+    return aRet;
+}
+
+void Dialog::InvalidateFloatingWindow(const Point& rPos)
 {
+    SAL_DEBUG("Dialog:: Invalidate Floating window");
     if (comphelper::LibreOfficeKit::isActive() && mpDialogRenderable && !maID.isEmpty())
     {
+        mpDialogRenderable->notifyDialogChild(maID, "invalidate", rPos);
+    }
+}
+
+void Dialog::CloseFloatingWindow()
+{
+    SAL_DEBUG("Dialog:: close Floating window");
+    if (comphelper::LibreOfficeKit::isActive() && mpDialogRenderable && !maID.isEmpty())
+    {
+        mpDialogRenderable->notifyDialogChild(maID, "close", Point(0, 0));
+    }
+}
+
+void Dialog::LogicInvalidate(const tools::Rectangle* /*pRectangle*/)
+{
+    if (!comphelper::LibreOfficeKit::isDialogPainting() && mpDialogRenderable && !maID.isEmpty())
+    {
         mpDialogRenderable->notifyDialogInvalidation(maID);
     }
 }
diff --git a/vcl/source/window/floatwin.cxx b/vcl/source/window/floatwin.cxx
index 23e56ce6e669..44ce96c42843 100644
--- a/vcl/source/window/floatwin.cxx
+++ b/vcl/source/window/floatwin.cxx
@@ -38,6 +38,7 @@ public:
 
     VclPtr<ToolBox> mpBox;
     tools::Rectangle       maItemEdgeClipRect; // used to clip the common edge between a toolbar item and the border of this window
+    Point maPos; // position of the floating window wrt. parent
 };
 
 FloatingWindow::ImplData::ImplData()
@@ -593,6 +594,17 @@ void FloatingWindow::StateChanged( StateChangedType nType )
 
     SystemWindow::StateChanged( nType );
 
+    if (nType == StateChangedType::InitShow && IsVisible())
+    {
+        Dialog* pParentDlg = GetParentDialog();
+        pParentDlg->InvalidateFloatingWindow(mpImplData->maPos);
+    }
+    else if (!IsVisible())
+    {
+        Dialog* pParentDlg = GetParentDialog();
+        pParentDlg->CloseFloatingWindow();
+    }
+
     if ( nType == StateChangedType::ControlBackground )
     {
         ImplInitSettings();
@@ -667,8 +679,8 @@ void FloatingWindow::StartPopupMode( const tools::Rectangle& rRect, FloatWinPopu
 
     // compute window position according to flags and arrangement
     sal_uInt16 nArrangeIndex;
-    Point aPos = ImplCalcPos( this, rRect, nFlags, nArrangeIndex );
-    SetPosPixel( aPos );
+    mpImplData->maPos = ImplCalcPos( this, rRect, nFlags, nArrangeIndex );
+    SetPosPixel( mpImplData->maPos );
 
     // set data and display window
     // convert maFloatRect to absolute device coordinates
@@ -714,10 +726,10 @@ void FloatingWindow::StartPopupMode( ToolBox* pBox, FloatWinPopupFlags nFlags )
 
     // retrieve some data from the ToolBox
     tools::Rectangle aRect = nItemId ? pBox->GetItemRect( nItemId ) : pBox->GetOverflowRect();
-    Point aPos;
+
     // convert to parent's screen coordinates
-    aPos = GetParent()->OutputToScreenPixel( GetParent()->AbsoluteScreenToOutputPixel( pBox->OutputToAbsoluteScreenPixel( aRect.TopLeft() ) ) );
-    aRect.SetPos( aPos );
+    mpImplData->maPos = GetParent()->OutputToScreenPixel( GetParent()->AbsoluteScreenToOutputPixel( pBox->OutputToAbsoluteScreenPixel( aRect.TopLeft() ) ) );
+    aRect.SetPos( mpImplData->maPos );
 
     nFlags |=
         FloatWinPopupFlags::AllMouseButtonClose |
commit c9776f352d038470456cbdbe8a0e82b17eabf674
Author: Pranav Kant <pranavk at collabora.co.uk>
Date:   Thu Aug 3 14:42:21 2017 +0530

    lokdialog: Register IDIalogRenderable with vcl::Dialog
    
    Change-Id: I344f5a9c7167abfde15dcd21c747819cc79b12b1

diff --git a/include/sfx2/basedlgs.hxx b/include/sfx2/basedlgs.hxx
index 7609229db2a6..cb403c78a075 100644
--- a/include/sfx2/basedlgs.hxx
+++ b/include/sfx2/basedlgs.hxx
@@ -105,8 +105,6 @@ public:
     SfxBindings&            GetBindings()
                             { return *pBindings; }
 
-    virtual void            LogicInvalidate(const tools::Rectangle* pRectangle) override;
-
     DECL_LINK(TimerHdl, Timer *, void);
 
 };
diff --git a/include/vcl/IDialogRenderable.hxx b/include/vcl/IDialogRenderable.hxx
index cf9d41e54cde..b2c0dee552cd 100644
--- a/include/vcl/IDialogRenderable.hxx
+++ b/include/vcl/IDialogRenderable.hxx
@@ -38,6 +38,9 @@ public:
 
     virtual void postDialogMouseEvent(const DialogID& rDialogID, int nType, int nX, int nY,
                                       int nCount, int nButtons, int nModifier) = 0;
+
+    // Callbacks
+    virtual void notifyDialogInvalidation(const DialogID& rDialogID) = 0;
 };
 
 } // namespace vcl
diff --git a/include/vcl/dialog.hxx b/include/vcl/dialog.hxx
index 93f2080c8352..ef3bcd5e8099 100644
--- a/include/vcl/dialog.hxx
+++ b/include/vcl/dialog.hxx
@@ -25,7 +25,7 @@
 #include <vcl/dllapi.h>
 #include <vcl/syswin.hxx>
 #include <vcl/vclptr.hxx>
-
+#include <vcl/IDialogRenderable.hxx>
 
 struct DialogImpl;
 class VclBox;
@@ -59,6 +59,8 @@ private:
     VclPtr<VclButtonBox> mpActionArea;
     VclPtr<VclBox>       mpContentArea;
 
+    vcl::IDialogRenderable*   mpDialogRenderable; // to emit LOK callbacks
+
     SAL_DLLPRIVATE void    ImplInitDialogData();
     SAL_DLLPRIVATE void    ImplInitSettings();
 
@@ -77,7 +79,10 @@ protected:
 public:
     SAL_DLLPRIVATE bool    IsInClose() const { return mbInClose; }
     virtual        void    doDeferredInit(WinBits nBits) override;
-    virtual        void    LogicInvalidate(const tools::Rectangle* pRectangle) override { (void)pRectangle; }
+    virtual        void    LogicInvalidate(const tools::Rectangle* pRectangle) override;
+
+    /// Necessary to register dialog renderable instance to emit LOK callbacks
+    void registerDialogRenderable(vcl::IDialogRenderable* pDialogRenderable);
     /// Paints the current dialog to the given virtual device
     void paintDialog(VirtualDevice& rDevice);
     void LogicMouseButtonDown(const MouseEvent& rMouseEvent);
diff --git a/sfx2/source/dialog/basedlgs.cxx b/sfx2/source/dialog/basedlgs.cxx
index 0d2d90d142de..bfc0ac45a39b 100644
--- a/sfx2/source/dialog/basedlgs.cxx
+++ b/sfx2/source/dialog/basedlgs.cxx
@@ -393,14 +393,6 @@ void SfxModelessDialog::FillInfo(SfxChildWinInfo& rInfo) const
         rInfo.nFlags |= SfxChildWindowFlags::ZOOMIN;
 }
 
-
-void SfxModelessDialog::LogicInvalidate(const tools::Rectangle* /*pRectangle*/)
-{
-    if (!comphelper::LibreOfficeKit::isDialogPainting())
-        SfxLokHelper::notifyDialogInvalidation(maID);
-}
-
-
 bool SfxFloatingWindow::EventNotify( NotifyEvent& rEvt )
 
 /*  [Description]
diff --git a/sw/inc/unotxdoc.hxx b/sw/inc/unotxdoc.hxx
index 3df958033c5e..e93173451b3c 100644
--- a/sw/inc/unotxdoc.hxx
+++ b/sw/inc/unotxdoc.hxx
@@ -438,6 +438,8 @@ public:
     void postDialogMouseEvent(const vcl::DialogID& rDialogID, int nType, int nX, int nY,
                               int nCount, int nButtons, int nModifier) override;
 
+    void notifyDialogInvalidation(const vcl::DialogID& rDialogID) override;
+
     // css::tiledrendering::XTiledRenderable
     virtual void SAL_CALL paintTile( const ::css::uno::Any& Parent, ::sal_Int32 nOutputWidth, ::sal_Int32 nOutputHeight, ::sal_Int32 nTilePosX, ::sal_Int32 nTilePosY, ::sal_Int32 nTileWidth, ::sal_Int32 nTileHeight ) override;
 
diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx
index f1a576c37ad3..e574321c98c0 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -31,6 +31,7 @@
 #include <vcl/svapp.hxx>
 #include <vcl/print.hxx>
 #include <sfx2/viewfrm.hxx>
+#include <sfx2/lokhelper.hxx>
 #include <sfx2/sfxbasecontroller.hxx>
 #include <sfx2/docfile.hxx>
 #include <sfx2/msg.hxx>
@@ -3669,6 +3670,8 @@ void SwXTextDocument::paintDialog(const vcl::DialogID& rDialogID, VirtualDevice&
     }
 
     Dialog* pDlg = static_cast<Dialog*>(pChild->GetWindow());
+    // register the instance so that vcl::Dialog can emit LOK callbacks
+    pDlg->registerDialogRenderable(this);
     pDlg->paintDialog(rDevice);
     const Size aSize = pDlg->GetOptimalSize();
     nWidth = aSize.getWidth();
@@ -3748,6 +3751,11 @@ void SwXTextDocument::postDialogMouseEvent(const vcl::DialogID& rDialogID, int n
     }
 }
 
+void SwXTextDocument::notifyDialogInvalidation(const vcl::DialogID& rDialogID)
+{
+    SfxLokHelper::notifyDialogInvalidation(rDialogID);
+}
+
 void * SAL_CALL SwXTextDocument::operator new( size_t t) throw()
 {
     return SwXTextDocumentBaseClass::operator new(t);
diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx
index 3ca7fff70211..e5d784e4f667 100644
--- a/vcl/source/window/dialog.cxx
+++ b/vcl/source/window/dialog.cxx
@@ -348,6 +348,7 @@ struct DialogImpl
 
 void Dialog::ImplInitDialogData()
 {
+    mpDialogRenderable = nullptr;
     mpWindowImpl->mbDialog  = true;
     mpPrevExecuteDlg        = nullptr;
     mbInExecute             = false;
@@ -863,6 +864,14 @@ bool Dialog::selectPageByUIXMLDescription(const OString& /*rUIXMLDescription*/)
     return true;
 }
 
+void Dialog::registerDialogRenderable(vcl::IDialogRenderable* pDialogRenderable)
+{
+    if (pDialogRenderable && !mpDialogRenderable)
+    {
+        mpDialogRenderable = pDialogRenderable;
+    }
+}
+
 void Dialog::paintDialog(VirtualDevice& rDevice)
 {
     setDeferredProperties();
@@ -874,6 +883,14 @@ void Dialog::paintDialog(VirtualDevice& rDevice)
     PaintToDevice(&rDevice, Point(0, 0), Size());
 }
 
+void Dialog::LogicInvalidate(const tools::Rectangle* /*pRectangle*/)
+{
+    if (comphelper::LibreOfficeKit::isActive() && mpDialogRenderable && !maID.isEmpty())
+    {
+        mpDialogRenderable->notifyDialogInvalidation(maID);
+    }
+}
+
 void Dialog::LogicMouseButtonDown(const MouseEvent& rMouseEvent)
 {
     // When we're not doing tiled rendering, then positions must be passed as pixels.
commit 4ef551540920d67e9594a699d72ffa4f96ad1bae
Author: Pranav Kant <pranavk at collabora.co.uk>
Date:   Wed Aug 2 18:01:45 2017 +0530

    Fix a comment
    
    Change-Id: Icbd16aebf3ddabd1b0ffd310f1aab3641d5c40b4

diff --git a/include/sfx2/lokhelper.hxx b/include/sfx2/lokhelper.hxx
index 65cd5964af97..b37480df9da1 100644
--- a/include/sfx2/lokhelper.hxx
+++ b/include/sfx2/lokhelper.hxx
@@ -40,7 +40,7 @@ public:
     static void notifyOtherViews(SfxViewShell* pThisView, int nType, const OString& rKey, const OString& rPayload);
     /// Same as notifyOtherViews(), but works on a selected "other" view, not on all of them.
     static void notifyOtherView(SfxViewShell* pThisView, SfxViewShell const* pOtherView, int nType, const OString& rKey, const OString& rPayload);
-    /// Emits a LOK_CALLBACK_INVALIDATE_TILES, but tweaks it according to setOptionalFeatures() if needed.
+    /// Emits a LOK_CALLBACK_DIALOG_INVALIDATE
     static void notifyDialogInvalidation(const OUString& rPayload);
     /// Emits a LOK_CALLBACK_INVALIDATE_TILES, but tweaks it according to setOptionalFeatures() if needed.
     static void notifyInvalidation(SfxViewShell* pThisView, const OString& rPayload);
commit 76c692b7a440750bf3c7f315b0f8212bf9a75553
Author: Pranav Kant <pranavk at collabora.co.uk>
Date:   Sun Jul 30 06:06:56 2017 +0530

    lokdialog: Handle key events in core
    
    Change-Id: If84aaac87beebf69d92db5446fc713d8cc20421e

diff --git a/include/vcl/dialog.hxx b/include/vcl/dialog.hxx
index a38a6ebc6c6a..93f2080c8352 100644
--- a/include/vcl/dialog.hxx
+++ b/include/vcl/dialog.hxx
@@ -84,6 +84,9 @@ public:
     void LogicMouseButtonUp(const MouseEvent& rMouseEvent);
     void LogicMouseMove(const MouseEvent& rMouseEvent);
 
+    void LOKKeyInput(const KeyEvent& rKeyEvent);
+    void LOKKeyUp(const KeyEvent& rKeyEvent);
+
 protected:
     explicit        Dialog( WindowType nType );
     explicit        Dialog( vcl::Window* pParent, const OUString& rID, const OUString& rUIXMLDescription, WindowType nType, InitFlag eFlag = InitFlag::Default );
diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx
index bcac6c96070e..f1a576c37ad3 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -3675,9 +3675,38 @@ void SwXTextDocument::paintDialog(const vcl::DialogID& rDialogID, VirtualDevice&
     nHeight = aSize.getHeight();
 }
 
-void SwXTextDocument::postDialogKeyEvent(const vcl::DialogID& /*rDialogID*/, int /*nType*/, int /*nCharCode*/, int /*nKeyCode*/)
+void SwXTextDocument::postDialogKeyEvent(const vcl::DialogID& rDialogID, int nType, int nCharCode, int nKeyCode)
 {
+    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());
+        KeyEvent aEvent(nCharCode, nKeyCode, 0);
 
+        switch (nType)
+        {
+        case LOK_KEYEVENT_KEYINPUT:
+            pDialog->KeyInput(aEvent);
+            break;
+        case LOK_KEYEVENT_KEYUP:
+            pDialog->KeyUp(aEvent);
+            break;
+        default:
+            assert(false);
+            break;
+        }
+    }
 }
 
 void SwXTextDocument::postDialogMouseEvent(const vcl::DialogID& rDialogID, int nType, int nX, int nY,
diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx
index 375af4418abc..3ca7fff70211 100644
--- a/vcl/source/window/dialog.cxx
+++ b/vcl/source/window/dialog.cxx
@@ -898,6 +898,20 @@ void Dialog::LogicMouseMove(const MouseEvent& rMouseEvent)
     ImplWindowFrameProc(this, SalEvent::ExternalMouseMove, &rMouseEvent);
 }
 
+void Dialog::LOKKeyInput(const KeyEvent& rKeyEvent)
+{
+    assert(comphelper::LibreOfficeKit::isActive());
+
+    ImplWindowFrameProc(this, SalEvent::ExternalKeyInput, &rKeyEvent);
+}
+
+void Dialog::LOKKeyUp(const KeyEvent& rKeyEvent)
+{
+    assert(comphelper::LibreOfficeKit::isActive());
+
+    ImplWindowFrameProc(this, SalEvent::ExternalKeyUp, &rKeyEvent);
+}
+
 void Dialog::ensureRepaint()
 {
     // ensure repaint
commit 41f0e61c715e22fcbe6754975dfa7343d50f14b9
Author: Pranav Kant <pranavk at collabora.co.uk>
Date:   Sun Jul 30 05:18:33 2017 +0530

    lokdialog: gtv: Forward key events on dialog to core
    
    Change-Id: Icfc210b08c7f1d8ebaf9c731ed64bb128cfc4356

diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
index 7a9fa7712900..bb8800e3d734 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
@@ -8,9 +8,11 @@
  */
 
 #include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
 
 #include <cmath>
 #include <iostream>
+#include <sstream>
 
 #include <LibreOfficeKit/LibreOfficeKitGtk.h>
 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
@@ -136,7 +138,7 @@ gtv_lok_dialog_signal_button(GtkWidget* pDialogDrawingArea, GdkEventButton* pEve
                                                 (pEvent->y),
                                                 nCount,
                                                 nEventButton,
-                                                0/* Modifier */);
+                                                priv->m_nKeyModifier);
 
         break;
     }
@@ -167,7 +169,7 @@ gtv_lok_dialog_signal_button(GtkWidget* pDialogDrawingArea, GdkEventButton* pEve
                                                 (pEvent->y),
                                                 nCount,
                                                 nEventButton,
-                                                0/* Modifier */);
+                                                priv->m_nKeyModifier);
         break;
     }
     default:
@@ -198,7 +200,119 @@ gtv_lok_dialog_signal_motion(GtkWidget* pDialogDrawingArea, GdkEventButton* pEve
                                             (pEvent->y),
                                             1,
                                             priv->m_nLastButtonPressed,
-                                            0/* Modifier */);
+                                            priv->m_nKeyModifier);
+
+    return FALSE;
+}
+
+static gboolean
+gtv_lok_dialog_signal_key(GtkWidget* pDialogDrawingArea, GdkEventKey* pEvent)
+{
+    GtvLokDialog* pDialog = GTV_LOK_DIALOG(gtk_widget_get_toplevel(pDialogDrawingArea));
+    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));
+
+    int nCharCode = 0;
+    int nKeyCode = 0;
+    priv->m_nKeyModifier &= KEY_MOD2;
+    switch (pEvent->keyval)
+    {
+    case GDK_KEY_BackSpace:
+        nKeyCode = com::sun::star::awt::Key::BACKSPACE;
+        break;
+    case GDK_KEY_Delete:
+        nKeyCode = com::sun::star::awt::Key::DELETE;
+        break;
+    case GDK_KEY_Return:
+    case GDK_KEY_KP_Enter:
+        nKeyCode = com::sun::star::awt::Key::RETURN;
+        break;
+    case GDK_KEY_Escape:
+        nKeyCode = com::sun::star::awt::Key::ESCAPE;
+        break;
+    case GDK_KEY_Tab:
+        nKeyCode = com::sun::star::awt::Key::TAB;
+        break;
+    case GDK_KEY_Down:
+        nKeyCode = com::sun::star::awt::Key::DOWN;
+        break;
+    case GDK_KEY_Up:
+        nKeyCode = com::sun::star::awt::Key::UP;
+        break;
+    case GDK_KEY_Left:
+        nKeyCode = com::sun::star::awt::Key::LEFT;
+        break;
+    case GDK_KEY_Right:
+        nKeyCode = com::sun::star::awt::Key::RIGHT;
+        break;
+    case GDK_KEY_Page_Down:
+        nKeyCode = com::sun::star::awt::Key::PAGEDOWN;
+        break;
+    case GDK_KEY_Page_Up:
+        nKeyCode = com::sun::star::awt::Key::PAGEUP;
+        break;
+    case GDK_KEY_Insert:
+        nKeyCode = com::sun::star::awt::Key::INSERT;
+        break;
+    case GDK_KEY_Shift_L:
+    case GDK_KEY_Shift_R:
+        if (pEvent->type == GDK_KEY_PRESS)
+            priv->m_nKeyModifier |= KEY_SHIFT;
+        break;
+    case GDK_KEY_Control_L:
+    case GDK_KEY_Control_R:
+        if (pEvent->type == GDK_KEY_PRESS)
+            priv->m_nKeyModifier |= KEY_MOD1;
+        break;
+    case GDK_KEY_Alt_L:
+    case GDK_KEY_Alt_R:
+        if (pEvent->type == GDK_KEY_PRESS)
+            priv->m_nKeyModifier |= KEY_MOD2;
+        else
+            priv->m_nKeyModifier &= ~KEY_MOD2;
+        break;
+    default:
+        if (pEvent->keyval >= GDK_KEY_F1 && pEvent->keyval <= GDK_KEY_F26)
+            nKeyCode = com::sun::star::awt::Key::F1 + (pEvent->keyval - GDK_KEY_F1);
+        else
+            nCharCode = gdk_keyval_to_unicode(pEvent->keyval);
+    }
+
+    // rsc is not public API, but should be good enough for debugging purposes.
+    // If this is needed for real, then probably a new param of type
+    // css::awt::KeyModifier is needed in postKeyEvent().
+    if (pEvent->state & GDK_SHIFT_MASK)
+        nKeyCode |= KEY_SHIFT;
+

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list